Using the ERC 3009 permit nonce for intent witness data

I am interested in soliciting feedback from the community, particularly from anyone who has a lot of experience with token permitting and intents. I understand there are other permit/intent/meta-TX solutions; feel free to mention them, but in this thread I mainly want to discuss this one. This idea could either be brilliant or dangerous, and so I do not want to rely on my own limited understanding.

Intended behavior

In ERC 3009, the nonce is a free variable. The only restriction on it is that it cannot match a previous nonce, and the recommended usage is for the nonce to be random.

Limitation

ERC 3009 cannot convey the intent for a payment, and so must sign twice, once for the permit, and once for the intent.

Goal

In order to reduce the number of user signatures, I would like to pack a full user intent into the token permit, in the style of Permit2 witness data. Then another actor, such as a paymaster, could fulfill the intent from just a permit signature.

Method

For ERC 3009 permits, the nonce can pack witness data for the recipient, including another nonce field, so the recipient contract could verify the user’s intent.

For example, if the ERC 3009 recipient were a DEX, the ERC 3009 nonce might be structured like

struct BuyIntent {
    IERC20 token;
    uint256 minOut;
    bytes32 nonce;
};
bytes32 erc3009Nonce = keccak256(abi.encode(BUY_INTENT_TYPEHASH, buyIntent.token, buyIntent.minOut, buyIntent.nonce));

Thereby the DEX could reconstruct the nonce before receiveWithAuthorization, and know that the permit nonce was generated with those parameters. The intent, a limit order in this case, is conveyed in the ERC3009 nonce field.

Security Considerations

A malicious client may prompt the user without conveying how the nonce is generated. While they would still know which token they were approving and how much, the intent could be malicious. This category of attacks is called Signature Phishing. Its scope can be limited by encouraging users only to use official client software, preferably with checksums and content-addressing, but there are plenty of ways users can compromise themselves. The danger is amplified because the field in the ERC3009 typeHash is merely called nonce and might look fine. However once you are compromised to this extent, there may be better ways to steal your assets.

1 Like

Indeed, I’ve seen this used:

I agree that this is not ideal. Something that could be interesting is for a protocol to only accept this kind of signature for small USDC amounts (for the UX benefits of single signature flows), and to force larger amounts or other tokens through Permit2 or a scheme that provides full transparency in the wallet of what’s being signed.

Obviously another way to abuse ERC-3009 signatures for phishing is to place a malicious address in the to parameter, and with the current sad state of wallets and their implementation of EIP-712 I don’t think that would raise more alarms than a malicious nonce. In an ideal world, the to parameter would be shown next to some sort of security score at the moment of signing to mitigate that attack vector, which is not possible/easy with the nonce.

3 Likes