You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
3.7 KiB
90 lines
3.7 KiB
// SPDX-License-Identifier: MIT
|
|
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Permit.sol)
|
|
|
|
pragma solidity ^0.8.20;
|
|
|
|
/**
|
|
* @dev 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:
|
|
*
|
|
* ```solidity
|
|
* 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.
|
|
*/
|
|
interface IERC20Permit {
|
|
/**
|
|
* @dev 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` and `s` must be a valid `secp256k1` signature from `owner`
|
|
* 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;
|
|
|
|
/**
|
|
* @dev 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);
|
|
|
|
/**
|
|
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
|
|
*/
|
|
// solhint-disable-next-line func-name-mixedcase
|
|
function DOMAIN_SEPARATOR() external view returns (bytes32);
|
|
}
|
|
|