Remove the draft prefix to ERC20Permit (#3793)

Co-authored-by: Francisco <frangio.1@gmail.com>
pull/3802/head
Hadrien Croubois 2 years ago committed by GitHub
parent 88a3f95715
commit 0b6becd49f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CHANGELOG.md
  2. 8
      contracts/interfaces/IERC2612.sol
  3. 5
      contracts/interfaces/draft-IERC2612.sol
  4. 2
      contracts/mocks/ERC20PermitMock.sol
  5. 2
      contracts/mocks/SafeERC20Helper.sol
  6. 12
      contracts/token/ERC20/README.adoc
  7. 95
      contracts/token/ERC20/extensions/ERC20Permit.sol
  8. 2
      contracts/token/ERC20/extensions/ERC20Votes.sol
  9. 60
      contracts/token/ERC20/extensions/IERC20Permit.sol
  10. 92
      contracts/token/ERC20/extensions/draft-ERC20Permit.sol
  11. 57
      contracts/token/ERC20/extensions/draft-IERC20Permit.sol
  12. 2
      contracts/token/ERC20/utils/SafeERC20.sol
  13. 4
      docs/modules/ROOT/pages/governance.adoc
  14. 7
      scripts/migrate-imports.js

@ -6,6 +6,10 @@
* `ERC20Votes`: optimize by using unchecked arithmetic. ([#3748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3748)) * `ERC20Votes`: optimize by using unchecked arithmetic. ([#3748](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3748))
* `Initializable`: optimize `_disableInitializers` by using `!=` instead of `<`. ([#3787](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3787)) * `Initializable`: optimize `_disableInitializers` by using `!=` instead of `<`. ([#3787](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3787))
### Deprecations
* `ERC20Permit`: Added the file `IERC20Permit.sol` and `ERC20Permit.sol` and deprecated `draft-IERC20Permit.sol` and `draft-ERC20Permit.sol` since [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) is no longer a Draft. Developers are encouraged to update their imports. ([#3793](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3793))
## Unreleased ## Unreleased
* `TimelockController`: Added a new `admin` constructor parameter that is assigned the admin role instead of the deployer account. ([#3722](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3722)) * `TimelockController`: Added a new `admin` constructor parameter that is assigned the admin role instead of the deployer account. ([#3722](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3722))

@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC2612.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/extensions/IERC20Permit.sol";
interface IERC2612 is IERC20Permit {}

@ -1,8 +1,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/draft-IERC2612.sol)
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/extensions/draft-IERC20Permit.sol"; // EIP-2612 is Final as of 2022-11-01. This file is deprecated.
interface IERC2612 is IERC20Permit {} import "./IERC2612.sol";

@ -2,7 +2,7 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import "../token/ERC20/extensions/draft-ERC20Permit.sol"; import "../token/ERC20/extensions/ERC20Permit.sol";
contract ERC20PermitMock is ERC20Permit { contract ERC20PermitMock is ERC20Permit {
constructor( constructor(

@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
import "../utils/Context.sol"; import "../utils/Context.sol";
import "../token/ERC20/IERC20.sol"; import "../token/ERC20/IERC20.sol";
import "../token/ERC20/extensions/draft-ERC20Permit.sol"; import "../token/ERC20/extensions/ERC20Permit.sol";
import "../token/ERC20/utils/SafeERC20.sol"; import "../token/ERC20/utils/SafeERC20.sol";
contract ERC20ReturnFalseMock is Context { contract ERC20ReturnFalseMock is Context {

@ -31,10 +31,6 @@ Finally, there are some utilities to interact with ERC20 contracts in various wa
* {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values. * {SafeERC20}: a wrapper around the interface that eliminates the need to handle boolean return values.
* {TokenTimelock}: hold tokens for a beneficiary until a specified time. * {TokenTimelock}: hold tokens for a beneficiary until a specified time.
The following related EIPs are in draft status.
- {ERC20Permit}
NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as <<ERC20-_mint-address-uint256-,`_mint`>>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc20.adoc#Presets[ERC20 Presets] (such as {ERC20PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts. NOTE: This core set of contracts is designed to be unopinionated, allowing developers to access the internal functions in ERC20 (such as <<ERC20-_mint-address-uint256-,`_mint`>>) and expose them as external functions in the way they prefer. On the other hand, xref:ROOT:erc20.adoc#Presets[ERC20 Presets] (such as {ERC20PresetMinterPauser}) are designed using opinionated patterns to provide developers with ready to use, deployable contracts.
== Core == Core
@ -53,6 +49,8 @@ NOTE: This core set of contracts is designed to be unopinionated, allowing devel
{{ERC20Pausable}} {{ERC20Pausable}}
{{ERC20Permit}}
{{ERC20Snapshot}} {{ERC20Snapshot}}
{{ERC20Votes}} {{ERC20Votes}}
@ -65,12 +63,6 @@ NOTE: This core set of contracts is designed to be unopinionated, allowing devel
{{ERC4626}} {{ERC4626}}
== Draft EIPs
The following EIPs are still in Draft status. Due to their nature as drafts, the details of these contracts may change and we cannot guarantee their xref:ROOT:releases-stability.adoc[stability]. Minor releases of OpenZeppelin Contracts may contain breaking changes for the contracts in this directory, which will be duly announced in the https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md[changelog]. The EIPs included here are used by projects in production and this may make them less likely to change significantly.
{{ERC20Permit}}
== Presets == Presets
These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code. These contracts are preconfigured combinations of the above features. They can be used through inheritance or as models to copy and paste their source code.

@ -0,0 +1,95 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Permit.sol)
pragma solidity ^0.8.0;
import "./IERC20Permit.sol";
import "../ERC20.sol";
import "../../../utils/cryptography/ECDSA.sol";
import "../../../utils/cryptography/EIP712.sol";
import "../../../utils/Counters.sol";
/**
* @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 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.
*
* _Available since v3.4._
*/
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
using Counters for Counters.Counter;
mapping(address => Counters.Counter) private _nonces;
// solhint-disable-next-line var-name-mixedcase
bytes32 private constant _PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
/**
* @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
* However, to ensure consistency with the upgradeable transpiler, we will continue
* to reserve a slot.
* @custom:oz-renamed-from _PERMIT_TYPEHASH
*/
// solhint-disable-next-line var-name-mixedcase
bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;
/**
* @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
*
* It's a good idea to use the same `name` that is defined as the ERC20 token name.
*/
constructor(string memory name) EIP712(name, "1") {}
/**
* @dev See {IERC20Permit-permit}.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, v, r, s);
require(signer == owner, "ERC20Permit: invalid signature");
_approve(owner, spender, value);
}
/**
* @dev See {IERC20Permit-nonces}.
*/
function nonces(address owner) public view virtual override returns (uint256) {
return _nonces[owner].current();
}
/**
* @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view override returns (bytes32) {
return _domainSeparatorV4();
}
/**
* @dev "Consume a nonce": return the current value and increment.
*
* _Available since v4.1._
*/
function _useNonce(address owner) internal virtual returns (uint256 current) {
Counters.Counter storage nonce = _nonces[owner];
current = nonce.current();
nonce.increment();
}
}

@ -3,7 +3,7 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import "./draft-ERC20Permit.sol"; import "./ERC20Permit.sol";
import "../../../utils/math/Math.sol"; import "../../../utils/math/Math.sol";
import "../../../governance/utils/IVotes.sol"; import "../../../governance/utils/IVotes.sol";
import "../../../utils/math/SafeCast.sol"; import "../../../utils/math/SafeCast.sol";

@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 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.
*/
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].
*/
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);
}

@ -1,95 +1,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import "./draft-IERC20Permit.sol"; // EIP-2612 is Final as of 2022-11-01. This file is deprecated.
import "../ERC20.sol";
import "../../../utils/cryptography/ECDSA.sol";
import "../../../utils/cryptography/EIP712.sol";
import "../../../utils/Counters.sol";
/** import "./ERC20Permit.sol";
* @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 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.
*
* _Available since v3.4._
*/
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {
using Counters for Counters.Counter;
mapping(address => Counters.Counter) private _nonces;
// solhint-disable-next-line var-name-mixedcase
bytes32 private constant _PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
/**
* @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.
* However, to ensure consistency with the upgradeable transpiler, we will continue
* to reserve a slot.
* @custom:oz-renamed-from _PERMIT_TYPEHASH
*/
// solhint-disable-next-line var-name-mixedcase
bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;
/**
* @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
*
* It's a good idea to use the same `name` that is defined as the ERC20 token name.
*/
constructor(string memory name) EIP712(name, "1") {}
/**
* @dev See {IERC20Permit-permit}.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= deadline, "ERC20Permit: expired deadline");
bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, v, r, s);
require(signer == owner, "ERC20Permit: invalid signature");
_approve(owner, spender, value);
}
/**
* @dev See {IERC20Permit-nonces}.
*/
function nonces(address owner) public view virtual override returns (uint256) {
return _nonces[owner].current();
}
/**
* @dev See {IERC20Permit-DOMAIN_SEPARATOR}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view override returns (bytes32) {
return _domainSeparatorV4();
}
/**
* @dev "Consume a nonce": return the current value and increment.
*
* _Available since v4.1._
*/
function _useNonce(address owner) internal virtual returns (uint256 current) {
Counters.Counter storage nonce = _nonces[owner];
current = nonce.current();
nonce.increment();
}
}

@ -1,60 +1,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
/** // EIP-2612 is Final as of 2022-11-01. This file is deprecated.
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 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.
*/
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].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/** import "./IERC20Permit.sol";
* @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);
}

@ -4,7 +4,7 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import "../IERC20.sol"; import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol"; import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol"; import "../../../utils/Address.sol";
/** /**

@ -45,7 +45,7 @@ The voting power of each account in our governance setup will be determined by a
pragma solidity ^0.8.2; pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
contract MyToken is ERC20, ERC20Permit, ERC20Votes { contract MyToken is ERC20, ERC20Permit, ERC20Votes {
@ -83,7 +83,7 @@ If your project already has a live token that does not include ERC20Votes and is
pragma solidity ^0.8.2; pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Wrapper.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Wrapper.sol";

@ -10,8 +10,8 @@ const pathUpdates = {
'cryptography/ECDSA.sol': 'utils/cryptography/ECDSA.sol', 'cryptography/ECDSA.sol': 'utils/cryptography/ECDSA.sol',
'cryptography/MerkleProof.sol': 'utils/cryptography/MerkleProof.sol', 'cryptography/MerkleProof.sol': 'utils/cryptography/MerkleProof.sol',
'drafts/EIP712.sol': 'utils/cryptography/EIP712.sol', 'drafts/EIP712.sol': 'utils/cryptography/EIP712.sol',
'drafts/ERC20Permit.sol': 'token/ERC20/extensions/draft-ERC20Permit.sol', 'drafts/ERC20Permit.sol': 'token/ERC20/extensions/ERC20Permit.sol',
'drafts/IERC20Permit.sol': 'token/ERC20/extensions/draft-IERC20Permit.sol', 'drafts/IERC20Permit.sol': 'token/ERC20/extensions/IERC20Permit.sol',
'GSN/Context.sol': 'utils/Context.sol', 'GSN/Context.sol': 'utils/Context.sol',
// 'GSN/GSNRecipientERC20Fee.sol': undefined, // 'GSN/GSNRecipientERC20Fee.sol': undefined,
// 'GSN/GSNRecipientSignature.sol': undefined, // 'GSN/GSNRecipientSignature.sol': undefined,
@ -87,6 +87,9 @@ const pathUpdates = {
'utils/ReentrancyGuard.sol': 'security/ReentrancyGuard.sol', 'utils/ReentrancyGuard.sol': 'security/ReentrancyGuard.sol',
'utils/SafeCast.sol': 'utils/math/SafeCast.sol', 'utils/SafeCast.sol': 'utils/math/SafeCast.sol',
// 'utils/Strings.sol': undefined, // 'utils/Strings.sol': undefined,
'utils/cryptography/draft-EIP712.sol': 'utils/cryptography/EIP712.sol',
'token/ERC20/extensions/draft-ERC20Permit.sol': 'token/ERC20/extensions/ERC20Permit.sol',
'token/ERC20/extensions/draft-IERC20Permit.sol': 'token/ERC20/extensions/IERC20Permit.sol',
}; };
async function main (paths = [ 'contracts' ]) { async function main (paths = [ 'contracts' ]) {

Loading…
Cancel
Save