This thread is intended for an upcoming ERC based around EIP-2612-style approvals for ERC721 NFTs. The development work has been done by @dievardump , and is a result of conversation’s in @anett 's NFT Standards Working Group. There’s a tentative implementation here.
ERC2612 accomplishes this by creating a signed message involving the addresses of the owner and proposed spender of an ERC20 token, in addition to the amount being approved, a deadline, and a signature. This ERC (despite being Stagnant
at the time of this writing) enjoys a large amount of traction, and, for example, is leveraged by Uniswap wherever available.
There are a few things we’d like community feedback on regarding the best way to set this up for ERC721 NFTs.
1) owner
-based or tokenId
-based nonces
While trying to apply this formula to ERC721 NFTs, there is an additional optimization allowing for more flexibility than ERC2612 owing to the unique architecture of ERC721. ERC2612 takes the value being approved as an argument, and increments a nonce after each call to the permit
function in order to prevent replay attacks. Since each ERC721 token is discrete, it allows for having the nonce based not on the owner
's address or calls to permit
, but rather to tie the nonce to tokenId
and to increment on each transfer of the NFT. One gain from this pattern is that allows an owner to create multiple permits for the same NFT, since the nonce will only be incremented if the NFT is transferred.
(For comparison, 2612 needs to focus on the owner, and the owner needs to either only give one permit at a time, or make sure that they are used sequentially.)
Another advantage to this setup is that 2612 permits can only be signed by the owner of the tokens, but not by parties approved by the owner. This setup should allow approved parties to create permits for NFTs that they have been approved on too.
tokenId
seems to us to be the best way to handle nonces, though otoh 2612 is owner
-based, as are Uniswap v3’s position NFTs. We’re interested in community feedback about this!
2) v,r,s
vs full signatures
EIP2612 takes v
, r
, and s
arguments, which are the three parts of a signature. The full signature is needed to verify the message, though. The author of 2612, Martin Lundfall, told me that his reasoning was that v
, r
, and s
are all fixed length (uint8
, bytes32
, and bytes32
), whereas the full signature would need to be a dynamically-sized array (if I understood him right, apologies if I missed something there), though if we kept v
, r
, and s
as arguments (as in 2612), likely every function would need to concatenate them (using abi.encodePacked
) in order to use ecrecover
to verify.
@Amxx has a repo with a singleton contract that “wraps” ERC20, 721, or 1155 tokens in a permit structure which was a big inspiration in this project here, and you can see his use of OZ utilities for verification - all of which take a full signature.
We’d like to keep things as similar to 2612 as possible, but are interested in community feedback if there’s a preference towards keeping the three elements separate or maybe towards ingesting the signature whole.
There are likely other major conversation points here, this is meant to kick things off, and we’re looking forward to what people say!