forked from aave-dao/aave-v3-origin
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTestnetERC20.sol
96 lines (86 loc) · 2.8 KB
/
TestnetERC20.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol';
import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol';
import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol';
/**
* @title TestnetERC20
* @dev ERC20 minting logic
*/
contract TestnetERC20 is IERC20WithPermit, ERC20, Ownable {
bytes public constant EIP712_REVISION = bytes('1');
bytes32 internal constant EIP712_DOMAIN =
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');
bytes32 public constant PERMIT_TYPEHASH =
keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');
// Map of address nonces (address => nonce)
mapping(address => uint256) internal _nonces;
bytes32 public DOMAIN_SEPARATOR;
constructor(
string memory name,
string memory symbol,
uint8 decimals,
address owner
) ERC20(name, symbol) {
uint256 chainId = block.chainid;
DOMAIN_SEPARATOR = keccak256(
abi.encode(
EIP712_DOMAIN,
keccak256(bytes(name)),
keccak256(EIP712_REVISION),
chainId,
address(this)
)
);
_setupDecimals(decimals);
require(owner != address(0));
transferOwnership(owner);
}
/// @inheritdoc IERC20WithPermit
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external override {
require(owner != address(0), 'INVALID_OWNER');
//solium-disable-next-line
require(block.timestamp <= deadline, 'INVALID_EXPIRATION');
uint256 currentValidNonce = _nonces[owner];
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline))
)
);
require(owner == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE');
_nonces[owner] = currentValidNonce + 1;
_approve(owner, spender, value);
}
/**
* @dev Function to mint tokens
* @param value The amount of tokens to mint.
* @return A boolean that indicates if the operation was successful.
*/
function mint(uint256 value) public virtual onlyOwner returns (bool) {
_mint(_msgSender(), value);
return true;
}
/**
* @dev Function to mint tokens to address
* @param account The account to mint tokens.
* @param value The amount of tokens to mint.
* @return A boolean that indicates if the operation was successful.
*/
function mint(address account, uint256 value) public virtual onlyOwner returns (bool) {
_mint(account, value);
return true;
}
function nonces(address owner) public view returns (uint256) {
return _nonces[owner];
}
}