Here is a draft proposal for monkeypatching EIP-2612 support on ERC-20. This is by no means a complete proposal.
ApprovalTarget is an immutable contract that accepts token approvals from users across various ERC-20s, then enables anyone with a valid user signature to transfer those tokens. You can think of it like monkeypatching EIP-2612 support on all ERC-20 compliant tokens.
To use ERC-20 tokens in dApps, approving is needed, which is expensive.
Design a ApprovalTarget contract to create a single signed approval flow for ERC-20 tokens. This allows users to send approval transaction only once.
EIP-2612 allows abstraction in the ERC-20
approve method. But some of ERC-20 tokens do not have a
permit function. Introducing ApprovalTarget indirectly allows approval by signature for all ERC-20 compliant tokens.
In addition ApprovalTarget replaces
approve transaction with a signed approve and will improves UX.
ApprovalTarget has three functions.
function nonces(address owner) external view returns (uint) function PERMIT_AND_TRANSFER_FROM_TYPEHASH() external view returns (bytes32) function permitAndTransferFrom(address erc20, address owner, address recipient, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external
The semantics of which are as follows:
For all addresses
s, a call to
permitAndTransferFrom(erc20, owner, recipient, value, deadline, v, r, s) will call
transferFrom(owner, recipient, value), increment
nonces[owner] by 1. If and only if the following conditions are met:
- The current blocktime is less than or equal to
erc20is not the zero address. this address must be ERC-20 compliant token address.
owneris not the zero address.
nonces[owner](before the state update) is equal to
vis a valid
ownerof the message:
spender in the provided signature must be the same as
recipient isn’t attested by a signature from
owner, and is instead chosen by
msg.sender, attested in the signature as
If any of these conditions are not met, the
permitAndTransferFrom call must revert.
keccak256(abi.encodePacked( hex"1901", DOMAIN_SEPARATOR, keccak256(abi.encode( keccak256("PermitAndTransferFrom(address erc20,address owner,address spender,value,uint256 nonce,uint256 deadline)"), erc20, owner, msg.sender, // NOTE: spender value, nonce, deadline)) ))
DOMAIN_SEPARATOR is defined according to EIP-712.
In summary the caller of the
permitAndTransferFrom function must be
spender can choose
spender is not provided in
permitAndTransferFrom paramters. If
spender is not
msg.sender, the transaction will revert.
recipient is provided by not the
owner but the
spender. So, the
recipient isn’t attested by a signature.
More details here GitHub - massun-onibakuchi/approval-target