All work
Case 01 · Concept

Readable signing

A wallet signing screen that tells you what you're approving before it costs you money.

RoleProduct design, solo
TypeSelf-initiated concept
Timeline[3 weeks]
FocusToken approvals, EVM
Uapp.uniswap.orgVerified site
Allow Uniswap to spend your USDC

This lets Uniswap's contract move USDC from your wallet when you swap. Nothing leaves your wallet right now.

SpenderUniswap Permit2 Verified
Contract0x0000…8BA3
Network fee≈ $0.38

Tap Before and After to compare. On the redesign, try the amount options: the warning and the button update to match.

Context

Most DeFi actions start with a signature nobody can read

Before you can swap a token, a wallet asks you to approve a contract to spend it. The prompt shows a function name, a hex string and, very often, a 78-digit number, which is the maximum possible amount. People approve anyway because they can't tell what it means, and unlimited approvals stay live long after the swap is done.

That's the gap drainers exploit. The information needed to decide safely is already in the transaction. It's just not written for humans.

Constraints

What makes this hard

  • Signatures are irreversible. There's no undo and no support refund.
  • The wallet only sees raw calldata, so meaning has to be decoded and matched to known contracts.
  • Users are mid-task and want to swap, not read. Every extra line costs attention.
  • Too many warnings and people learn to ignore all of them.
Key decisions

Four choices, and what I rejected

01

Lead with the outcome, hide the method

The title says what happens in plain words ("Allow Uniswap to spend your USDC"). Raw data sits behind a link for the people who want it.

Rejected: annotating the hex inline. Accurate, but still unreadable.

02

Default to the exact amount

"Unlimited" becomes a choice the user makes, not the default. The swap amount is pre-selected, and the approve button repeats it, so the action matches the words.

Rejected: blocking unlimited approvals. Power users need them, and blocking pushes those users to other wallets.

03

Say what changes now vs later

"Nothing leaves your wallet right now" answers the question people are actually afraid of. The risk is what the permission allows later.

Rejected: a full balance-change table for approvals. Useful for transfers, empty and confusing for approvals.

04

Risk shown by shape and words, not only colour

Every risk level has an icon, a label and a sentence that explains it. It works for colour-blind users and on bad screens.

Rejected: a numeric risk score. People don't know what "62" means.

Risk levels

Three levels, three different amounts of friction

States

After the tap: every state designed

The signing screen is only the start. Here's what the user sees next in each outcome.

Measuring it

What I'd track if this shipped

↓Share of approvals granted as unlimited
↓Support tickets about unexpected transfers
→Signing drop-off. It must not rise, or the friction is too high.
Next

With more time

Extend the same pattern to Permit2 signatures and setApprovalForAll for NFTs, and add an approvals page that lists every live permission with one-tap revoke.

Next case
Crypto trading platform