-
-
Save zhaojun-sh/8a1bffbd4dcb473f40e1f78fb48a4886 to your computer and use it in GitHub Desktop.
| // SPDX-License-Identifier: GPL-3.0-or-later | |
| pragma solidity 0.8.2; | |
| /** | |
| * @dev Interface of the ERC20 standard as defined in the EIP. | |
| */ | |
| interface IERC20 { | |
| function totalSupply() external view returns (uint256); | |
| function decimals() external view returns (uint8); | |
| function balanceOf(address account) external view returns (uint256); | |
| function transfer(address recipient, uint256 amount) external returns (bool); | |
| function allowance(address owner, address spender) external view returns (uint256); | |
| function approve(address spender, uint256 amount) external returns (bool); | |
| function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); | |
| function permit(address target, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; | |
| function transferWithPermit(address target, address to, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external returns (bool); | |
| event Transfer(address indexed from, address indexed to, uint256 value); | |
| event Approval(address indexed owner, address indexed spender, uint256 value); | |
| } | |
| /** | |
| * @dev Interface of the ERC2612 standard as defined in the EIP. | |
| * | |
| * Adds the {permit} method, which can be used to change one's | |
| * {IERC20-allowance} without having to send a transaction, by signing a | |
| * message. This allows users to spend tokens without having to hold Ether. | |
| * | |
| * See https://eips.ethereum.org/EIPS/eip-2612. | |
| */ | |
| interface IERC2612 { | |
| /** | |
| * @dev Returns the current ERC2612 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 Wrapped ERC-20 v10 (AnyswapV3ERC20) is an ERC-20 ERC-20 wrapper. You can `deposit` ERC-20 and obtain an AnyswapV3ERC20 balance which can then be operated as an ERC-20 token. You can | |
| /// `withdraw` ERC-20 from AnyswapV3ERC20, which will then burn AnyswapV3ERC20 token in your wallet. The amount of AnyswapV3ERC20 token in any wallet is always identical to the | |
| /// balance of ERC-20 deposited minus the ERC-20 withdrawn with that specific wallet. | |
| interface IAnyswapV3ERC20 is IERC20, IERC2612 { | |
| /// @dev Sets `value` as allowance of `spender` account over caller account's AnyswapV3ERC20 token, | |
| /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. | |
| /// Emits {Approval} event. | |
| /// Returns boolean value indicating whether operation succeeded. | |
| /// For more information on approveAndCall format, see https://github.com/ethereum/EIPs/issues/677. | |
| function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); | |
| /// @dev Moves `value` AnyswapV3ERC20 token from caller's account to account (`to`), | |
| /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. | |
| /// A transfer to `address(0)` triggers an ERC-20 withdraw matching the sent AnyswapV3ERC20 token in favor of caller. | |
| /// Emits {Transfer} event. | |
| /// Returns boolean value indicating whether operation succeeded. | |
| /// Requirements: | |
| /// - caller account must have at least `value` AnyswapV3ERC20 token. | |
| /// For more information on transferAndCall format, see https://github.com/ethereum/EIPs/issues/677. | |
| function transferAndCall(address to, uint value, bytes calldata data) external returns (bool); | |
| } | |
| interface ITransferReceiver { | |
| function onTokenTransfer(address, uint, bytes calldata) external returns (bool); | |
| } | |
| interface IApprovalReceiver { | |
| function onTokenApproval(address, uint, bytes calldata) external returns (bool); | |
| } | |
| library Address { | |
| function isContract(address account) internal view returns (bool) { | |
| bytes32 codehash; | |
| bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; | |
| // solhint-disable-next-line no-inline-assembly | |
| assembly { codehash := extcodehash(account) } | |
| return (codehash != 0x0 && codehash != accountHash); | |
| } | |
| } | |
| library SafeERC20 { | |
| using Address for address; | |
| function safeTransfer(IERC20 token, address to, uint value) internal { | |
| callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); | |
| } | |
| function safeTransferFrom(IERC20 token, address from, address to, uint value) internal { | |
| callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); | |
| } | |
| function safeApprove(IERC20 token, address spender, uint value) internal { | |
| require((value == 0) || (token.allowance(address(this), spender) == 0), | |
| "SafeERC20: approve from non-zero to non-zero allowance" | |
| ); | |
| callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); | |
| } | |
| function callOptionalReturn(IERC20 token, bytes memory data) private { | |
| require(address(token).isContract(), "SafeERC20: call to non-contract"); | |
| // solhint-disable-next-line avoid-low-level-calls | |
| (bool success, bytes memory returndata) = address(token).call(data); | |
| require(success, "SafeERC20: low-level call failed"); | |
| if (returndata.length > 0) { // Return data is optional | |
| // solhint-disable-next-line max-line-length | |
| require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); | |
| } | |
| } | |
| } | |
| contract AnyswapV4ERC20 is IAnyswapV3ERC20 { | |
| using SafeERC20 for IERC20; | |
| string public name; | |
| string public symbol; | |
| uint8 public immutable override decimals; | |
| address public immutable underlying; | |
| bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); | |
| bytes32 public constant TRANSFER_TYPEHASH = keccak256("Transfer(address owner,address to,uint256 value,uint256 nonce,uint256 deadline)"); | |
| bytes32 public immutable DOMAIN_SEPARATOR; | |
| /// @dev Records amount of AnyswapV3ERC20 token owned by account. | |
| mapping (address => uint256) public override balanceOf; | |
| uint256 private _totalSupply; | |
| // init flag for setting immediate vault, needed for CREATE2 support | |
| bool private _init; | |
| // flag to enable/disable swapout vs vault.burn so multiple events are triggered | |
| bool private _vaultOnly; | |
| // configurable delay for timelock functions | |
| uint public delay = 2*24*3600; | |
| // set of minters, can be this bridge or other bridges | |
| mapping(address => bool) public isMinter; | |
| address[] public minters; | |
| // primary controller of the token contract | |
| address public vault; | |
| address public pendingMinter; | |
| uint public delayMinter; | |
| address public pendingVault; | |
| uint public delayVault; | |
| uint public pendingDelay; | |
| uint public delayDelay; | |
| modifier onlyAuth() { | |
| require(isMinter[msg.sender], "AnyswapV4ERC20: FORBIDDEN"); | |
| _; | |
| } | |
| modifier onlyVault() { | |
| require(msg.sender == mpc(), "AnyswapV3ERC20: FORBIDDEN"); | |
| _; | |
| } | |
| function owner() public view returns (address) { | |
| return mpc(); | |
| } | |
| function mpc() public view returns (address) { | |
| if (block.timestamp >= delayVault) { | |
| return pendingVault; | |
| } | |
| return vault; | |
| } | |
| function setVaultOnly(bool enabled) external onlyVault { | |
| _vaultOnly = enabled; | |
| } | |
| function initVault(address _vault) external onlyVault { | |
| require(_init); | |
| vault = _vault; | |
| pendingVault = _vault; | |
| isMinter[_vault] = true; | |
| minters.push(_vault); | |
| delayVault = block.timestamp; | |
| _init = false; | |
| } | |
| function setMinter(address _auth) external onlyVault { | |
| pendingMinter = _auth; | |
| delayMinter = block.timestamp + delay; | |
| } | |
| function setVault(address _vault) external onlyVault { | |
| pendingVault = _vault; | |
| delayVault = block.timestamp + delay; | |
| } | |
| function applyVault() external onlyVault { | |
| require(block.timestamp >= delayVault); | |
| vault = pendingVault; | |
| } | |
| function applyMinter() external onlyVault { | |
| require(block.timestamp >= delayMinter); | |
| isMinter[pendingMinter] = true; | |
| minters.push(pendingMinter); | |
| } | |
| // No time delay revoke minter emergency function | |
| function revokeMinter(address _auth) external onlyVault { | |
| isMinter[_auth] = false; | |
| } | |
| function getAllMinters() external view returns (address[] memory) { | |
| return minters; | |
| } | |
| function changeVault(address newVault) external onlyVault returns (bool) { | |
| require(newVault != address(0), "AnyswapV3ERC20: address(0x0)"); | |
| pendingVault = newVault; | |
| delayVault = block.timestamp + delay; | |
| emit LogChangeVault(vault, pendingVault, delayVault); | |
| return true; | |
| } | |
| function changeMPCOwner(address newVault) public onlyVault returns (bool) { | |
| require(newVault != address(0), "AnyswapV3ERC20: address(0x0)"); | |
| pendingVault = newVault; | |
| delayVault = block.timestamp + delay; | |
| emit LogChangeMPCOwner(vault, pendingVault, delayVault); | |
| return true; | |
| } | |
| function mint(address to, uint256 amount) external onlyAuth returns (bool) { | |
| _mint(to, amount); | |
| return true; | |
| } | |
| function burn(address from, uint256 amount) external onlyAuth returns (bool) { | |
| require(from != address(0), "AnyswapV3ERC20: address(0x0)"); | |
| _burn(from, amount); | |
| return true; | |
| } | |
| function Swapin(bytes32 txhash, address account, uint256 amount) public onlyAuth returns (bool) { | |
| _mint(account, amount); | |
| emit LogSwapin(txhash, account, amount); | |
| return true; | |
| } | |
| function Swapout(uint256 amount, string memory bindaddr) public returns (bool) { | |
| verifyBindAddr(bindaddr); | |
| require(!_vaultOnly, "AnyswapV4ERC20: onlyAuth"); | |
| _burn(msg.sender, amount); | |
| emit LogSwapout(msg.sender, amount, bindaddr); | |
| return true; | |
| } | |
| function verifyBindAddr(string memory bindaddr) pure internal { | |
| uint length = bytes(bindaddr).length; | |
| require(length >= 26, "address length is too short"); | |
| bytes1 ch = bytes(bindaddr)[0]; | |
| bytes1 ch2 = bytes(bindaddr)[1]; | |
| bytes1 ch3 = bytes(bindaddr)[2]; | |
| bytes1 ch4 = bytes(bindaddr)[3]; | |
| bytes1 ch5 = bytes(bindaddr)[4]; | |
| bytes1 ch6 = bytes(bindaddr)[5]; | |
| // Mainnet | |
| // p2pkh base58 0x1a B 34 | |
| // p2sh base58 0x1c C 34 | |
| // p2wpkh bech32 0x06 block1q 45 | |
| // p2wsh bech32 0x0A block1q 65 | |
| if (ch == 'B' || ch == 'C') { | |
| require(length <= 34, "mainnet address length is too long"); | |
| } else if (ch6 == '1' && ch == 'b' && ch2 == 'l' && ch3 == 'o' && ch4 == 'c' && ch5 == 'k') { | |
| require(length == 45 || length == 65, "segwit address length is not 45 or 65"); | |
| } else { | |
| require(false, "unsupported address leading symbol"); | |
| } | |
| } | |
| /// @dev Records current ERC2612 nonce for account. This value must be included whenever signature is generated for {permit}. | |
| /// Every successful call to {permit} increases account's nonce by one. This prevents signature from being used multiple times. | |
| mapping (address => uint256) public override nonces; | |
| /// @dev Records number of AnyswapV3ERC20 token that account (second) will be allowed to spend on behalf of another account (first) through {transferFrom}. | |
| mapping (address => mapping (address => uint256)) public override allowance; | |
| event LogChangeVault(address indexed oldVault, address indexed newVault, uint indexed effectiveTime); | |
| event LogChangeMPCOwner(address indexed oldOwner, address indexed newOwner, uint indexed effectiveHeight); | |
| event LogSwapin(bytes32 indexed txhash, address indexed account, uint amount); | |
| event LogSwapout(address indexed account, uint amount, string bindaddr); | |
| event LogAddAuth(address indexed auth, uint timestamp); | |
| constructor(string memory _name, string memory _symbol, uint8 _decimals, address _underlying, address _vault) { | |
| name = _name; | |
| symbol = _symbol; | |
| decimals = _decimals; | |
| underlying = _underlying; | |
| if (_underlying != address(0x0)) { | |
| require(_decimals == IERC20(_underlying).decimals()); | |
| } | |
| // Use init to allow for CREATE2 accross all chains | |
| _init = true; | |
| // Disable/Enable swapout for v1 tokens vs mint/burn for v3 tokens | |
| _vaultOnly = false; | |
| vault = _vault; | |
| pendingVault = _vault; | |
| delayVault = block.timestamp; | |
| uint256 chainId; | |
| assembly {chainId := chainid()} | |
| DOMAIN_SEPARATOR = keccak256( | |
| abi.encode( | |
| keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), | |
| keccak256(bytes(name)), | |
| keccak256(bytes("1")), | |
| chainId, | |
| address(this))); | |
| } | |
| /// @dev Returns the total supply of AnyswapV3ERC20 token as the ETH held in this contract. | |
| function totalSupply() external view override returns (uint256) { | |
| return _totalSupply; | |
| } | |
| function depositWithPermit(address target, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s, address to) external returns (uint) { | |
| IERC20(underlying).permit(target, address(this), value, deadline, v, r, s); | |
| IERC20(underlying).safeTransferFrom(target, address(this), value); | |
| return _deposit(value, to); | |
| } | |
| function depositWithTransferPermit(address target, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s, address to) external returns (uint) { | |
| IERC20(underlying).transferWithPermit(target, address(this), value, deadline, v, r, s); | |
| return _deposit(value, to); | |
| } | |
| function deposit() external returns (uint) { | |
| uint _amount = IERC20(underlying).balanceOf(msg.sender); | |
| IERC20(underlying).safeTransferFrom(msg.sender, address(this), _amount); | |
| return _deposit(_amount, msg.sender); | |
| } | |
| function deposit(uint amount) external returns (uint) { | |
| IERC20(underlying).safeTransferFrom(msg.sender, address(this), amount); | |
| return _deposit(amount, msg.sender); | |
| } | |
| function deposit(uint amount, address to) external returns (uint) { | |
| IERC20(underlying).safeTransferFrom(msg.sender, address(this), amount); | |
| return _deposit(amount, to); | |
| } | |
| function depositVault(uint amount, address to) external onlyVault returns (uint) { | |
| return _deposit(amount, to); | |
| } | |
| function _deposit(uint amount, address to) internal returns (uint) { | |
| require(underlying != address(0x0) && underlying != address(this)); | |
| _mint(to, amount); | |
| return amount; | |
| } | |
| function withdraw() external returns (uint) { | |
| return _withdraw(msg.sender, balanceOf[msg.sender], msg.sender); | |
| } | |
| function withdraw(uint amount) external returns (uint) { | |
| return _withdraw(msg.sender, amount, msg.sender); | |
| } | |
| function withdraw(uint amount, address to) external returns (uint) { | |
| return _withdraw(msg.sender, amount, to); | |
| } | |
| function withdrawVault(address from, uint amount, address to) external onlyVault returns (uint) { | |
| return _withdraw(from, amount, to); | |
| } | |
| function _withdraw(address from, uint amount, address to) internal returns (uint) { | |
| _burn(from, amount); | |
| IERC20(underlying).safeTransfer(to, amount); | |
| return amount; | |
| } | |
| /** @dev Creates `amount` tokens and assigns them to `account`, increasing | |
| * the total supply. | |
| * | |
| * Emits a {Transfer} event with `from` set to the zero address. | |
| * | |
| * Requirements | |
| * | |
| * - `to` cannot be the zero address. | |
| */ | |
| function _mint(address account, uint256 amount) internal { | |
| require(account != address(0), "ERC20: mint to the zero address"); | |
| _totalSupply += amount; | |
| balanceOf[account] += amount; | |
| emit Transfer(address(0), account, amount); | |
| } | |
| /** | |
| * @dev Destroys `amount` tokens from `account`, reducing the | |
| * total supply. | |
| * | |
| * Emits a {Transfer} event with `to` set to the zero address. | |
| * | |
| * Requirements | |
| * | |
| * - `account` cannot be the zero address. | |
| * - `account` must have at least `amount` tokens. | |
| */ | |
| function _burn(address account, uint256 amount) internal { | |
| require(account != address(0), "ERC20: burn from the zero address"); | |
| balanceOf[account] -= amount; | |
| _totalSupply -= amount; | |
| emit Transfer(account, address(0), amount); | |
| } | |
| /// @dev Sets `value` as allowance of `spender` account over caller account's AnyswapV3ERC20 token. | |
| /// Emits {Approval} event. | |
| /// Returns boolean value indicating whether operation succeeded. | |
| function approve(address spender, uint256 value) external override returns (bool) { | |
| // _approve(msg.sender, spender, value); | |
| allowance[msg.sender][spender] = value; | |
| emit Approval(msg.sender, spender, value); | |
| return true; | |
| } | |
| /// @dev Sets `value` as allowance of `spender` account over caller account's AnyswapV3ERC20 token, | |
| /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. | |
| /// Emits {Approval} event. | |
| /// Returns boolean value indicating whether operation succeeded. | |
| /// For more information on approveAndCall format, see https://github.com/ethereum/EIPs/issues/677. | |
| function approveAndCall(address spender, uint256 value, bytes calldata data) external override returns (bool) { | |
| // _approve(msg.sender, spender, value); | |
| allowance[msg.sender][spender] = value; | |
| emit Approval(msg.sender, spender, value); | |
| return IApprovalReceiver(spender).onTokenApproval(msg.sender, value, data); | |
| } | |
| /// @dev Sets `value` as allowance of `spender` account over `owner` account's AnyswapV3ERC20 token, given `owner` account's signed approval. | |
| /// Emits {Approval} event. | |
| /// Requirements: | |
| /// - `deadline` must be timestamp in future. | |
| /// - `v`, `r` and `s` must be valid `secp256k1` signature from `owner` account over EIP712-formatted function arguments. | |
| /// - the signature must use `owner` account's current nonce (see {nonces}). | |
| /// - the signer cannot be zero address and must be `owner` account. | |
| /// For more information on signature format, see https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP section]. | |
| /// AnyswapV3ERC20 token implementation adapted from https://github.com/albertocuestacanada/ERC20Permit/blob/master/contracts/ERC20Permit.sol. | |
| function permit(address target, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external override { | |
| require(block.timestamp <= deadline, "AnyswapV3ERC20: Expired permit"); | |
| bytes32 hashStruct = keccak256( | |
| abi.encode( | |
| PERMIT_TYPEHASH, | |
| target, | |
| spender, | |
| value, | |
| nonces[target]++, | |
| deadline)); | |
| require(verifyEIP712(target, hashStruct, v, r, s) || verifyPersonalSign(target, hashStruct, v, r, s)); | |
| // _approve(owner, spender, value); | |
| allowance[target][spender] = value; | |
| emit Approval(target, spender, value); | |
| } | |
| function transferWithPermit(address target, address to, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external override returns (bool) { | |
| require(block.timestamp <= deadline, "AnyswapV3ERC20: Expired permit"); | |
| bytes32 hashStruct = keccak256( | |
| abi.encode( | |
| TRANSFER_TYPEHASH, | |
| target, | |
| to, | |
| value, | |
| nonces[target]++, | |
| deadline)); | |
| require(verifyEIP712(target, hashStruct, v, r, s) || verifyPersonalSign(target, hashStruct, v, r, s)); | |
| require(to != address(0) || to != address(this)); | |
| uint256 balance = balanceOf[target]; | |
| require(balance >= value, "AnyswapV3ERC20: transfer amount exceeds balance"); | |
| balanceOf[target] = balance - value; | |
| balanceOf[to] += value; | |
| emit Transfer(target, to, value); | |
| return true; | |
| } | |
| function verifyEIP712(address target, bytes32 hashStruct, uint8 v, bytes32 r, bytes32 s) internal view returns (bool) { | |
| bytes32 hash = keccak256( | |
| abi.encodePacked( | |
| "\x19\x01", | |
| DOMAIN_SEPARATOR, | |
| hashStruct)); | |
| address signer = ecrecover(hash, v, r, s); | |
| return (signer != address(0) && signer == target); | |
| } | |
| function verifyPersonalSign(address target, bytes32 hashStruct, uint8 v, bytes32 r, bytes32 s) internal pure returns (bool) { | |
| bytes32 hash = prefixed(hashStruct); | |
| address signer = ecrecover(hash, v, r, s); | |
| return (signer != address(0) && signer == target); | |
| } | |
| // Builds a prefixed hash to mimic the behavior of eth_sign. | |
| function prefixed(bytes32 hash) internal pure returns (bytes32) { | |
| return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); | |
| } | |
| /// @dev Moves `value` AnyswapV3ERC20 token from caller's account to account (`to`). | |
| /// A transfer to `address(0)` triggers an ETH withdraw matching the sent AnyswapV3ERC20 token in favor of caller. | |
| /// Emits {Transfer} event. | |
| /// Returns boolean value indicating whether operation succeeded. | |
| /// Requirements: | |
| /// - caller account must have at least `value` AnyswapV3ERC20 token. | |
| function transfer(address to, uint256 value) external override returns (bool) { | |
| require(to != address(0) || to != address(this)); | |
| uint256 balance = balanceOf[msg.sender]; | |
| require(balance >= value, "AnyswapV3ERC20: transfer amount exceeds balance"); | |
| balanceOf[msg.sender] = balance - value; | |
| balanceOf[to] += value; | |
| emit Transfer(msg.sender, to, value); | |
| return true; | |
| } | |
| /// @dev Moves `value` AnyswapV3ERC20 token from account (`from`) to account (`to`) using allowance mechanism. | |
| /// `value` is then deducted from caller account's allowance, unless set to `type(uint256).max`. | |
| /// A transfer to `address(0)` triggers an ETH withdraw matching the sent AnyswapV3ERC20 token in favor of caller. | |
| /// Emits {Approval} event to reflect reduced allowance `value` for caller account to spend from account (`from`), | |
| /// unless allowance is set to `type(uint256).max` | |
| /// Emits {Transfer} event. | |
| /// Returns boolean value indicating whether operation succeeded. | |
| /// Requirements: | |
| /// - `from` account must have at least `value` balance of AnyswapV3ERC20 token. | |
| /// - `from` account must have approved caller to spend at least `value` of AnyswapV3ERC20 token, unless `from` and caller are the same account. | |
| function transferFrom(address from, address to, uint256 value) external override returns (bool) { | |
| require(to != address(0) || to != address(this)); | |
| if (from != msg.sender) { | |
| // _decreaseAllowance(from, msg.sender, value); | |
| uint256 allowed = allowance[from][msg.sender]; | |
| if (allowed != type(uint256).max) { | |
| require(allowed >= value, "AnyswapV3ERC20: request exceeds allowance"); | |
| uint256 reduced = allowed - value; | |
| allowance[from][msg.sender] = reduced; | |
| emit Approval(from, msg.sender, reduced); | |
| } | |
| } | |
| uint256 balance = balanceOf[from]; | |
| require(balance >= value, "AnyswapV3ERC20: transfer amount exceeds balance"); | |
| balanceOf[from] = balance - value; | |
| balanceOf[to] += value; | |
| emit Transfer(from, to, value); | |
| return true; | |
| } | |
| /// @dev Moves `value` AnyswapV3ERC20 token from caller's account to account (`to`), | |
| /// after which a call is executed to an ERC677-compliant contract with the `data` parameter. | |
| /// A transfer to `address(0)` triggers an ETH withdraw matching the sent AnyswapV3ERC20 token in favor of caller. | |
| /// Emits {Transfer} event. | |
| /// Returns boolean value indicating whether operation succeeded. | |
| /// Requirements: | |
| /// - caller account must have at least `value` AnyswapV3ERC20 token. | |
| /// For more information on transferAndCall format, see https://github.com/ethereum/EIPs/issues/677. | |
| function transferAndCall(address to, uint value, bytes calldata data) external override returns (bool) { | |
| require(to != address(0) || to != address(this)); | |
| uint256 balance = balanceOf[msg.sender]; | |
| require(balance >= value, "AnyswapV3ERC20: transfer amount exceeds balance"); | |
| balanceOf[msg.sender] = balance - value; | |
| balanceOf[to] += value; | |
| emit Transfer(msg.sender, to, value); | |
| return ITransferReceiver(to).onTokenTransfer(msg.sender, value, data); | |
| } | |
| } |
zhaojun-sh
commented
Apr 9, 2021
60e06040526202a3006005553480156200001857600080fd5b50604051620033ba380380620033ba8339810160408190526200003b91620003c5565b8451620000509060009060208801906200023d565b508351620000669060019060208701906200023d565b507fff0000000000000000000000000000000000000000000000000000000000000060f884901b166080526001600160601b0319606083901b1660a0526001600160a01b038216156200013a57816001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620000ed57600080fd5b505afa15801562000102573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000128919062000464565b60ff168360ff16146200013a57600080fd5b6004805461ff001960ff19909116600117169055600880546001600160a01b0383166001600160a01b03199182168117909255600b8054909116909117905542600c5560405146907f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f90620001b29060009062000488565b60408051918290038220828201825260018352603160f81b6020938401528151928301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018290523060a082015260c00160408051601f19818403018152919052805160209091012060c052506200057e945050505050565b8280546200024b906200052b565b90600052602060002090601f0160209004810192826200026f5760008555620002ba565b82601f106200028a57805160ff1916838001178555620002ba565b82800160010185558215620002ba579182015b82811115620002ba5782518255916020019190600101906200029d565b50620002c8929150620002cc565b5090565b5b80821115620002c85760008155600101620002cd565b80516001600160a01b0381168114620002fb57600080fd5b919050565b600082601f83011262000311578081fd5b81516001600160401b03808211156200032e576200032e62000568565b604051601f8301601f19908116603f0116810190828211818310171562000359576200035962000568565b8160405283815260209250868385880101111562000375578485fd5b8491505b8382101562000398578582018301518183018401529082019062000379565b83821115620003a957848385830101525b9695505050505050565b805160ff81168114620002fb57600080fd5b600080600080600060a08688031215620003dd578081fd5b85516001600160401b0380821115620003f4578283fd5b6200040289838a0162000300565b9650602088015191508082111562000418578283fd5b50620004278882890162000300565b9450506200043860408701620003b3565b92506200044860608701620002e3565b91506200045860808701620002e3565b90509295509295909350565b60006020828403121562000476578081fd5b6200048182620003b3565b9392505050565b8154600090819060028104600180831680620004a557607f831692505b6020808410821415620004c657634e487b7160e01b87526022600452602487fd5b818015620004dd5760018114620004ef576200051d565b60ff198616895284890196506200051d565b60008a815260209020885b86811015620005155781548b820152908501908301620004fa565b505084890196505b509498975050505050505050565b6002810460018216806200054057607f821691505b602082108114156200056257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60805160f81c60a05160601c60c051612db9620006016000396000818161048c0152611dcb01526000818161057d0152818161128a015281816112d601528181611356015281816116360152818161184b015281816118d401528181611ba101528181611cbe01528181611fb50152611fe8015260006104530152612db96000f3fe608060405234801561001057600080fd5b506004361061033f5760003560e01c806381a37c18116101b8578063bebbf4d011610104578063d93f2445116100a2578063f75c26641161007c578063f75c266414610774578063f954734e1461077c578063fbfa77cf1461078f578063fca3b5aa146107a25761033f565b8063d93f24451461072e578063dd62ed3e14610736578063ec126c77146107615761033f565b8063cae9ca51116100de578063cae9ca51146106ed578063cfbd488514610700578063d0e30db014610713578063d505accf1461071b5761033f565b8063bebbf4d0146106be578063c3081240146106d1578063c4b740f5146106da5761033f565b80639dc29fac11610171578063a9059cbb1161014b578063a9059cbb14610662578063aa271e1a14610675578063ad54056d14610698578063b6b55f25146106ab5761033f565b80639dc29fac14610631578063a045442c14610644578063a29dff72146106595761033f565b806381a37c18146105df5780638623ec7b146105f257806387689e28146106055780638da5cb5b1461060e57806391c5df491461061657806395d89b41146106295761033f565b80633ccfd60b1161029257806360e232a9116102305780636e553f651161020a5780636e553f65146105655780636f307dc31461057857806370a082311461059f5780637ecebe00146105bf5761033f565b806360e232a9146105365780636817031b146105495780636a42b8f81461055c5761033f565b80634ca8f0ed1161026c5780634ca8f0ed146104dc57806352113ba7146104e55780635f9b105d14610510578063605629d6146105235761033f565b80633ccfd60b146104ae5780634000aea0146104b657806340c10f19146104c95761033f565b806318160ddd116102ff5780632ebe3fbb116102d95780632ebe3fbb1461041457806330adf81f14610427578063313ce5671461044e5780633644e515146104875761033f565b806318160ddd146103e657806323b872dd146103ee5780632e1a7d4d146104015761033f565b806239d6ec14610344578062bf26f41461036a578062f714ce1461039157806306fdde03146103a4578063095ea7b3146103b95780630d707df8146103dc575b600080fd5b61035761035236600461278d565b6107b5565b6040519081526020015b60405180910390f35b6103577f42ce63790c28229c123925d83266e77c04d28784552ab68b350a9003226cbd5981565b61035761039f36600461293f565b61080b565b6103ac61081f565b6040516103619190612b35565b6103cc6103c7366004612764565b6108ad565b6040519015158152602001610361565b6103e4610907565b005b6103576109c3565b6103cc6103fc3660046126c0565b6109ca565b61035761040f36600461290f565b610bb5565b6103e4610422366004612674565b610bca565b6103577f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6104757f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610361565b6103577f000000000000000000000000000000000000000000000000000000000000000081565b610357610ca1565b6103cc6104c43660046127c8565b610cc2565b6103cc6104d7366004612764565b610e1b565b610357600d5481565b600b546104f8906001600160a01b031681565b6040516001600160a01b039091168152602001610361565b6103cc61051e366004612674565b610e5d565b6103cc6105313660046126fb565b610f31565b6103cc610544366004612674565b611141565b6103e4610557366004612674565b611215565b61035760055481565b61035761057336600461293f565b61127b565b6104f87f000000000000000000000000000000000000000000000000000000000000000081565b6103576105ad366004612674565b60026020526000908152604090205481565b6103576105cd366004612674565b600f6020526000908152604090205481565b6103576105ed36600461284a565b6112bc565b6104f861060036600461290f565b611396565b610357600c5481565b6104f86113c0565b6009546104f8906001600160a01b031681565b6103ac6113ca565b6103cc61063f366004612764565b6113d7565b61064c611436565b6040516103619190612ae8565b610357600e5481565b6103cc610670366004612764565b611498565b6103cc610683366004612674565b60066020526000908152604090205460ff1681565b6103cc6106a6366004612961565b61156e565b6103576106b936600461290f565b611627565b6103576106cc36600461293f565b611668565b610357600a5481565b6103e46106e83660046128b3565b6116a2565b6103cc6106fb3660046127c8565b6116f4565b6103e461070e366004612674565b6117d0565b610357611829565b6103e46107293660046126fb565b61190c565b6103e4611a7a565b61035761074436600461268e565b601060209081526000928352604080842090915290825290205481565b6103cc61076f3660046128eb565b611ae5565b6104f8611b5a565b61035761078a36600461284a565b611b87565b6008546104f8906001600160a01b031681565b6103e46107b0366004612674565b611c3f565b60006107bf611b5a565b6001600160a01b0316336001600160a01b0316146107f85760405162461bcd60e51b81526004016107ef90612b48565b60405180910390fd5b610803848484611ca5565b949350505050565b6000610818338484611ca5565b9392505050565b6000805461082c90612cb0565b80601f016020809104026020016040519081016040528092919081815260200182805461085890612cb0565b80156108a55780601f1061087a576101008083540402835291602001916108a5565b820191906000526020600020905b81548152906001019060200180831161088857829003601f168201915b505050505081565b3360008181526010602090815260408083206001600160a01b03871680855292528083208590555191929091600080516020612d64833981519152906108f69086815260200190565b60405180910390a350600192915050565b61090f611b5a565b6001600160a01b0316336001600160a01b03161461093f5760405162461bcd60e51b81526004016107ef90612b48565b600a5442101561094e57600080fd5b600980546001600160a01b039081166000908152600660205260408120805460ff1916600190811790915592546007805494850181559091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68890920180546001600160a01b03191692909116919091179055565b6003545b90565b60006001600160a01b0383161515806109ec57506001600160a01b0383163014155b6109f557600080fd5b6001600160a01b0384163314610aef576001600160a01b03841660009081526010602090815260408083203384529091529020546000198114610aed5782811015610a945760405162461bcd60e51b815260206004820152602960248201527f416e7973776170563345524332303a2072657175657374206578636565647320604482015268616c6c6f77616e636560b81b60648201526084016107ef565b6000610aa08483612c6d565b6001600160a01b03871660008181526010602090815260408083203380855290835292819020859055518481529394509092600080516020612d64833981519152910160405180910390a3505b505b6001600160a01b03841660009081526002602052604090205482811015610b285760405162461bcd60e51b81526004016107ef90612bb6565b610b328382612c6d565b6001600160a01b038087166000908152600260205260408082209390935590861681529081208054859290610b68908490612c55565b92505081905550836001600160a01b0316856001600160a01b0316600080516020612d4483398151915285604051610ba291815260200190565b60405180910390a3506001949350505050565b6000610bc2338333611ca5565b90505b919050565b610bd2611b5a565b6001600160a01b0316336001600160a01b031614610c025760405162461bcd60e51b81526004016107ef90612b48565b60045460ff16610c1157600080fd5b600880546001600160a01b039092166001600160a01b03199283168117909155600b80548316821790556000818152600660205260408120805460ff1990811660019081179092556007805492830181559092527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801805490931690911790915542600c55600480549091169055565b336000818152600260205260408120549091610cbd9181611ca5565b905090565b60006001600160a01b038516151580610ce457506001600160a01b0385163014155b610ced57600080fd5b3360009081526002602052604090205484811015610d1d5760405162461bcd60e51b81526004016107ef90612bb6565b610d278582612c6d565b33600090815260026020526040808220929092556001600160a01b03881681529081208054879290610d5a908490612c55565b90915550506040518581526001600160a01b038716903390600080516020612d448339815191529060200160405180910390a3604051635260769b60e11b81526001600160a01b0387169063a4c0ed3690610dbf903390899089908990600401612aa0565b602060405180830381600087803b158015610dd957600080fd5b505af1158015610ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1191906128cf565b9695505050505050565b3360009081526006602052604081205460ff16610e4a5760405162461bcd60e51b81526004016107ef90612c05565b610e548383611ced565b50600192915050565b6000610e67611b5a565b6001600160a01b0316336001600160a01b031614610e975760405162461bcd60e51b81526004016107ef90612b48565b6001600160a01b038216610ebd5760405162461bcd60e51b81526004016107ef90612b7f565b600b80546001600160a01b0319166001600160a01b038416179055600554610ee59042612c55565b600c819055600b546008546040516001600160a01b0392831692909116907f1d065115f314fb9bad9557bd5460b9e3c66f7223b1dd04e73e828f0bb5afe89f90600090a4506001919050565b600084421115610f835760405162461bcd60e51b815260206004820152601e60248201527f416e7973776170563345524332303a2045787069726564207065726d6974000060448201526064016107ef565b6001600160a01b0388166000908152600f6020526040812080547f42ce63790c28229c123925d83266e77c04d28784552ab68b350a9003226cbd59918b918b918b919086610fd083612ceb565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012090506110318982878787611dbb565b8061104457506110448982878787611eab565b61104d57600080fd5b6001600160a01b03881615158061106d57506001600160a01b0388163014155b61107657600080fd5b6001600160a01b038916600090815260026020526040902054878110156110af5760405162461bcd60e51b81526004016107ef90612bb6565b6110b98882612c6d565b6001600160a01b03808c1660009081526002602052604080822093909355908b16815290812080548a92906110ef908490612c55565b92505081905550886001600160a01b03168a6001600160a01b0316600080516020612d448339815191528a60405161112991815260200190565b60405180910390a35060019998505050505050505050565b600061114b611b5a565b6001600160a01b0316336001600160a01b03161461117b5760405162461bcd60e51b81526004016107ef90612b48565b6001600160a01b0382166111a15760405162461bcd60e51b81526004016107ef90612b7f565b600b80546001600160a01b0319166001600160a01b0384161790556005546111c99042612c55565b600c819055600b546008546040516001600160a01b0392831692909116907f5c364079e7102c27c608f9b237c735a1b7bfa0b67f27c2ad26bad447bf965cac90600090a4506001919050565b61121d611b5a565b6001600160a01b0316336001600160a01b03161461124d5760405162461bcd60e51b81526004016107ef90612b48565b600b80546001600160a01b0319166001600160a01b0383161790556005546112759042612c55565b600c5550565b60006112b26001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086611f40565b6108188383611fb1565b60405163d505accf60e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d505accf90611317908b9030908c908c908c908c908c90600401612a5f565b600060405180830381600087803b15801561133157600080fd5b505af1158015611345573d6000803e3d6000fd5b506113809250506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016905089308a611f40565b61138a8783611fb1565b98975050505050505050565b600781815481106113a657600080fd5b6000918252602090912001546001600160a01b0316905081565b6000610cbd611b5a565b6001805461082c90612cb0565b3360009081526006602052604081205460ff166114065760405162461bcd60e51b81526004016107ef90612c05565b6001600160a01b03831661142c5760405162461bcd60e51b81526004016107ef90612b7f565b610e54838361202e565b6060600780548060200260200160405190810160405280929190818152602001828054801561148e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611470575b5050505050905090565b60006001600160a01b0383161515806114ba57506001600160a01b0383163014155b6114c357600080fd5b33600090815260026020526040902054828110156114f35760405162461bcd60e51b81526004016107ef90612bb6565b6114fd8382612c6d565b33600090815260026020526040808220929092556001600160a01b03861681529081208054859290611530908490612c55565b90915550506040518381526001600160a01b038516903390600080516020612d44833981519152906020015b60405180910390a35060019392505050565b600061157982612100565b600454610100900460ff16156115d15760405162461bcd60e51b815260206004820152601860248201527f416e7973776170563445524332303a206f6e6c7941757468000000000000000060448201526064016107ef565b6115db338461202e565b336001600160a01b03167f9c92ad817e5474d30a4378deface765150479363a897b0590fbb12ae9d89396b8484604051611616929190612c3c565b60405180910390a250600192915050565b600061165e6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333085611f40565b610bc28233611fb1565b6000611672611b5a565b6001600160a01b0316336001600160a01b0316146112b25760405162461bcd60e51b81526004016107ef90612b48565b6116aa611b5a565b6001600160a01b0316336001600160a01b0316146116da5760405162461bcd60e51b81526004016107ef90612b48565b600480549115156101000261ff0019909216919091179055565b3360008181526010602090815260408083206001600160a01b03891680855292528083208790555191929091600080516020612d648339815191529061173d9088815260200190565b60405180910390a360405162ba451f60e01b81526001600160a01b0386169062ba451f90611775903390889088908890600401612aa0565b602060405180830381600087803b15801561178f57600080fd5b505af11580156117a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c791906128cf565b95945050505050565b6117d8611b5a565b6001600160a01b0316336001600160a01b0316146118085760405162461bcd60e51b81526004016107ef90612b48565b6001600160a01b03166000908152600660205260409020805460ff19169055565b6040516370a0823160e01b815233600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b15801561188d57600080fd5b505afa1580156118a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118c59190612927565b90506118fc6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084611f40565b6119068133611fb1565b91505090565b8342111561195c5760405162461bcd60e51b815260206004820152601e60248201527f416e7973776170563345524332303a2045787069726564207065726d6974000060448201526064016107ef565b6001600160a01b0387166000908152600f6020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866119a983612ceb565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050611a0a8882868686611dbb565b80611a1d5750611a1d8882868686611eab565b611a2657600080fd5b6001600160a01b038881166000818152601060209081526040808320948c16808452948252918290208a90559051898152600080516020612d64833981519152910160405180910390a35050505050505050565b611a82611b5a565b6001600160a01b0316336001600160a01b031614611ab25760405162461bcd60e51b81526004016107ef90612b48565b600c54421015611ac157600080fd5b600b54600880546001600160a01b0319166001600160a01b03909216919091179055565b3360009081526006602052604081205460ff16611b145760405162461bcd60e51b81526004016107ef90612c05565b611b1e8383611ced565b826001600160a01b0316847f05d0634fe981be85c22e2942a880821b70095d84e152c3ea3c17a4e4250d9d618460405161155c91815260200190565b6000600c544210611b775750600b546001600160a01b03166109c7565b506008546001600160a01b031690565b60405163302b14eb60e11b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063605629d690611be2908b9030908c908c908c908c908c90600401612a5f565b602060405180830381600087803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3491906128cf565b5061138a8783611fb1565b611c47611b5a565b6001600160a01b0316336001600160a01b031614611c775760405162461bcd60e51b81526004016107ef90612b48565b600980546001600160a01b0319166001600160a01b038316179055600554611c9f9042612c55565b600a5550565b6000611cb1848461202e565b611ce56001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168385612459565b509092915050565b6001600160a01b038216611d435760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016107ef565b8060036000828254611d559190612c55565b90915550506001600160a01b03821660009081526002602052604081208054839290611d82908490612c55565b90915550506040518181526001600160a01b03831690600090600080516020612d44833981519152906020015b60405180910390a35050565b60405161190160f01b60208201527f0000000000000000000000000000000000000000000000000000000000000000602282015260428101859052600090819060620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0015b6020604051602081039080840390855afa158015611e6a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381161580159061138a5750876001600160a01b0316816001600160a01b03161498975050505050505050565b600080611f05866040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b6040805160008082526020820180845284905260ff89169282019290925260608101879052608081018690529192509060019060a001611e48565b6040516001600160a01b0380851660248301528316604482015260648101829052611fab9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261248e565b50505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161580159061201457507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163014155b61201d57600080fd5b6120278284611ced565b5090919050565b6001600160a01b03821661208e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016107ef565b6001600160a01b038216600090815260026020526040812080548392906120b6908490612c6d565b9250508190555080600360008282546120cf9190612c6d565b90915550506040518181526000906001600160a01b03841690600080516020612d4483398151915290602001611daf565b8051601a8110156121535760405162461bcd60e51b815260206004820152601b60248201527f61646472657373206c656e67746820697320746f6f2073686f7274000000000060448201526064016107ef565b60008260008151811061217657634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b90506000836001815181106121a657634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b90506000846002815181106121d657634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b905060008560038151811061220657634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b905060008660048151811061223657634e487b7160e01b600052603260045260246000fd5b602001015160f81c60f81b905060008760058151811061226657634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b03199081169150602160f91b908716148061229a5750604360f81b6001600160f81b03198716145b156123005760228711156122fb5760405162461bcd60e51b815260206004820152602260248201527f6d61696e6e65742061646472657373206c656e67746820697320746f6f206c6f6044820152616e6760f01b60648201526084016107ef565b61244f565b603160f81b6001600160f81b0319821614801561232a5750603160f91b6001600160f81b03198716145b80156123435750601b60fa1b6001600160f81b03198616145b801561235c5750606f60f81b6001600160f81b03198516145b80156123755750606360f81b6001600160f81b03198416145b801561238e5750606b60f81b6001600160f81b03198316145b156123fc5786602d14806123a25750866041145b6122fb5760405162461bcd60e51b815260206004820152602560248201527f7365677769742061646472657373206c656e677468206973206e6f74203435206044820152646f7220363560d81b60648201526084016107ef565b60405162461bcd60e51b815260206004820152602260248201527f756e737570706f727465642061646472657373206c656164696e672073796d626044820152611bdb60f21b60648201526084016107ef565b5050505050505050565b6040516001600160a01b03831660248201526044810182905261248990849063a9059cbb60e01b90606401611f74565b505050565b6124a0826001600160a01b0316612615565b6124ec5760405162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e74726163740060448201526064016107ef565b600080836001600160a01b0316836040516125079190612a43565b6000604051808303816000865af19150503d8060008114612544576040519150601f19603f3d011682016040523d82523d6000602084013e612549565b606091505b50915091508161259b5760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656460448201526064016107ef565b805115611fab57808060200190518101906125b691906128cf565b611fab5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107ef565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906108035750141592915050565b80356001600160a01b0381168114610bc557600080fd5b803560ff81168114610bc557600080fd5b600060208284031215612685578081fd5b6108188261264c565b600080604083850312156126a0578081fd5b6126a98361264c565b91506126b76020840161264c565b90509250929050565b6000806000606084860312156126d4578081fd5b6126dd8461264c565b92506126eb6020850161264c565b9150604084013590509250925092565b600080600080600080600060e0888a031215612715578283fd5b61271e8861264c565b965061272c6020890161264c565b9550604088013594506060880135935061274860808901612663565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215612776578182fd5b61277f8361264c565b946020939093013593505050565b6000806000606084860312156127a1578283fd5b6127aa8461264c565b9250602084013591506127bf6040850161264c565b90509250925092565b600080600080606085870312156127dd578384fd5b6127e68561264c565b935060208501359250604085013567ffffffffffffffff80821115612809578384fd5b818701915087601f83011261281c578384fd5b81358181111561282a578485fd5b88602082850101111561283b578485fd5b95989497505060200194505050565b600080600080600080600060e0888a031215612864578283fd5b61286d8861264c565b9650602088013595506040880135945061288960608901612663565b93506080880135925060a088013591506128a560c0890161264c565b905092959891949750929550565b6000602082840312156128c4578081fd5b813561081881612d32565b6000602082840312156128e0578081fd5b815161081881612d32565b6000806000606084860312156128ff578081fd5b833592506126eb6020850161264c565b600060208284031215612920578081fd5b5035919050565b600060208284031215612938578081fd5b5051919050565b60008060408385031215612951578182fd5b823591506126b76020840161264c565b60008060408385031215612973578182fd5b82359150602083013567ffffffffffffffff80821115612991578283fd5b818501915085601f8301126129a4578283fd5b8135818111156129b6576129b6612d1c565b604051601f8201601f19908116603f011681019083821181831017156129de576129de612d1c565b816040528281528860208487010111156129f6578586fd5b82602086016020830137856020848301015280955050505050509250929050565b60008151808452612a2f816020860160208601612c84565b601f01601f19169290920160200192915050565b60008251612a55818460208701612c84565b9190910192915050565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6001600160a01b0385168152602081018490526060604082018190528101829052600082846080840137818301608090810191909152601f909201601f191601019392505050565b6020808252825182820181905260009190848201906040850190845b81811015612b295783516001600160a01b031683529284019291840191600101612b04565b50909695505050505050565b6000602082526108186020830184612a17565b60208082526019908201527f416e7973776170563345524332303a20464f5242494444454e00000000000000604082015260600190565b6020808252601c908201527f416e7973776170563345524332303a2061646472657373283078302900000000604082015260600190565b6020808252602f908201527f416e7973776170563345524332303a207472616e7366657220616d6f756e742060408201526e657863656564732062616c616e636560881b606082015260800190565b60208082526019908201527f416e7973776170563445524332303a20464f5242494444454e00000000000000604082015260600190565b6000838252604060208301526108036040830184612a17565b60008219821115612c6857612c68612d06565b500190565b600082821015612c7f57612c7f612d06565b500390565b60005b83811015612c9f578181015183820152602001612c87565b83811115611fab5750506000910152565b600281046001821680612cc457607f821691505b60208210811415612ce557634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612cff57612cff612d06565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114612d4057600080fd5b5056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a2646970667358221220c686a5ff757ed9ed4e77d8017624df7ef5c850524a82b43e8d9a849fede71aaa64736f6c63430008020033
[
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "string",
"name": "_symbol",
"type": "string"
},
{
"internalType": "uint8",
"name": "_decimals",
"type": "uint8"
},
{
"internalType": "address",
"name": "_underlying",
"type": "address"
},
{
"internalType": "address",
"name": "_vault",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "auth",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "LogAddAuth",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oldOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "effectiveHeight",
"type": "uint256"
}
],
"name": "LogChangeMPCOwner",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oldVault",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newVault",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "effectiveTime",
"type": "uint256"
}
],
"name": "LogChangeVault",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "txhash",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "LogSwapin",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "string",
"name": "bindaddr",
"type": "string"
}
],
"name": "LogSwapout",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [],
"name": "DOMAIN_SEPARATOR",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "PERMIT_TYPEHASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "txhash",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "Swapin",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "string",
"name": "bindaddr",
"type": "string"
}
],
"name": "Swapout",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "TRANSFER_TYPEHASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "applyMinter",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "applyVault",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "approveAndCall",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "burn",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newVault",
"type": "address"
}
],
"name": "changeMPCOwner",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newVault",
"type": "address"
}
],
"name": "changeVault",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "delay",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "delayDelay",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "delayMinter",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "delayVault",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "deposit",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "deposit",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "deposit",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "depositVault",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "depositWithPermit",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "depositWithTransferPermit",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getAllMinters",
"outputs": [
{
"internalType": "address[]",
"name": "",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_vault",
"type": "address"
}
],
"name": "initVault",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isMinter",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "mint",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "minters",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "mpc",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "nonces",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingDelay",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingMinter",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendingVault",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "permit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_auth",
"type": "address"
}
],
"name": "revokeMinter",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_auth",
"type": "address"
}
],
"name": "setMinter",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_vault",
"type": "address"
}
],
"name": "setVault",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "enabled",
"type": "bool"
}
],
"name": "setVaultOnly",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "transferAndCall",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "target",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "transferWithPermit",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "underlying",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "vault",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "withdraw",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdraw",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "withdrawVault",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]