aave-protocol-v2/contracts/mocks/tokens/MintableERC20.sol
2021-04-06 14:55:39 +02:00

82 lines
2.1 KiB
Solidity

// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol';
/**
* @title ERC20Mintable
* @dev ERC20 minting logic
*/
contract MintableERC20 is ERC20 {
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)');
mapping(address => uint256) public _nonces;
bytes32 public DOMAIN_SEPARATOR;
constructor(
string memory name,
string memory symbol,
uint8 decimals
) public ERC20(name, symbol) {
uint256 chainId;
assembly {
chainId := chainid()
}
DOMAIN_SEPARATOR = keccak256(
abi.encode(
EIP712_DOMAIN,
keccak256(bytes(name)),
keccak256(EIP712_REVISION),
chainId,
address(this)
)
);
_setupDecimals(decimals);
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
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.add(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 returns (bool) {
_mint(_msgSender(), value);
return true;
}
}