-
Notifications
You must be signed in to change notification settings - Fork 11.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Francisco Giordano <frangio.1@gmail.com> Co-authored-by: Santiago Palladino <spalladino@gmail.com>
- Loading branch information
1 parent
03d51c5
commit ecc6671
Showing
12 changed files
with
1,615 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity >=0.6.5 <0.8.0; | ||
|
||
import "../token/ERC20/ERC20.sol"; | ||
import "./IERC20Permit.sol"; | ||
import "../cryptography/ECDSA.sol"; | ||
import "../utils/Counters.sol"; | ||
import "./EIP712.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. | ||
*/ | ||
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 immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); | ||
|
||
/** | ||
* @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) internal EIP712(name, "1") { | ||
} | ||
|
||
/** | ||
* @dev See {IERC20Permit-permit}. | ||
*/ | ||
function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override { | ||
// solhint-disable-next-line not-rely-on-time | ||
require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); | ||
|
||
bytes32 structHash = keccak256( | ||
abi.encode( | ||
_PERMIT_TYPEHASH, | ||
owner, | ||
spender, | ||
amount, | ||
_nonces[owner].current(), | ||
deadline | ||
) | ||
); | ||
|
||
bytes32 hash = _hashTypedDataV4(structHash); | ||
|
||
address signer = ECDSA.recover(hash, v, r, s); | ||
require(signer == owner, "ERC20Permit: invalid signature"); | ||
|
||
_nonces[owner].increment(); | ||
_approve(owner, spender, amount); | ||
} | ||
|
||
/** | ||
* @dev See {IERC20Permit-nonces}. | ||
*/ | ||
function nonces(address owner) public view 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(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity >=0.6.0 <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 `amount` 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 amount, 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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity >=0.6.0 <0.8.0; | ||
|
||
import "../drafts/ERC20Permit.sol"; | ||
|
||
contract ERC20PermitMock is ERC20Permit { | ||
constructor ( | ||
string memory name, | ||
string memory symbol, | ||
address initialAccount, | ||
uint256 initialBalance | ||
) public payable ERC20(name, symbol) ERC20Permit(name) { | ||
_mint(initialAccount, initialBalance); | ||
} | ||
|
||
function getChainId() external pure returns (uint256 chainId) { | ||
// solhint-disable-next-line no-inline-assembly | ||
assembly { | ||
chainId := chainid() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.