IERC20Permit
*Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in
https://eips.ethereum.org/EIPS/eip-2612[ERC-2612].
Adds the permit method, which can be used to change an account's ERC-20 allowance (see {IERC20-allowance}) by
presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
need to send a transaction, and thus is not required to hold Ether at all.
==== Security Considerations
There are two important considerations concerning the use of permit
. The first is that a valid permit signature
expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
considered as an intention to spend the allowance in any specific way. The second is that because permits have
built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
take this into consideration and allow a permit
call to fail. Combining these two aspects, a pattern that may be
generally recommended is:
function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
doThing(..., value);
}
function doThing(..., uint256 value) public {
token.safeTransferFrom(msg.sender, address(this), value);
...
}
Observe that: 1) msg.sender
is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
try/catch
allows the permit to fail and makes the code tolerant to frontrunning. (See also
{SafeERC20-safeTransferFrom}).
Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
contracts should have entry points that don't rely on permit.*
Functions
permit
*Sets value
as the allowance of spender
over owner
's tokens,
given owner
's signed approval.
IMPORTANT: The same issues IERC20-approve has related to transaction
ordering also apply here.
Emits an {Approval} event.
Requirements:
spender
cannot be the zero address.deadline
must be a timestamp in the future.v
,r
ands
must be a validsecp256k1
signature fromowner
over the EIP712-formatted function arguments.- the signature must use
owner
's current nonce (see {nonces}). For more information on the signature format, see the https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section]. CAUTION: See Security Considerations above.*
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external;
nonces
Returns the current nonce for owner
. This value must be
included whenever a signature is generated for permit.
Every successful call to {permit} increases owner
's nonce by one. This
prevents a signature from being used multiple times.
function nonces(address owner) external view returns (uint256);
DOMAIN_SEPARATOR
Returns the domain separator used in the encoding of the signature for permit, as defined by {EIP712}.
function DOMAIN_SEPARATOR() external view returns (bytes32);