123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v5.0.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);
- }
|