Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ERC223WithPermit
- Optimization enabled
- true
- Compiler version
- v0.8.19+commit.7dd6d404
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-09-26T15:31:49.764959Z
Constructor Arguments
0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008456e65726765617200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034e52470000000000000000000000000000000000000000000000000000000000
Arg [0] (string) : Energear
Arg [1] (string) : NRG
Contract source code
// SPDX-License-Identifier: No License (None) pragma solidity 0.8.19; library Address { /** * @dev Returns true if `account` is a contract. * * This test is non-exhaustive, and there may be false-negatives: during the * execution of a contract's constructor, its address will be reported as * not containing a contract. * * > It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. */ function isContract(address account) internal view returns (bool) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } interface IERC223 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the token decimals. */ function decimals() external view returns (uint8); /** * @dev Returns the token symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the token name. */ function name() external view returns (string memory); /** * @dev Returns the token standard. */ function standard() external pure returns (string memory); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer( address recipient, uint256 amount ) external returns (bool); function transfer( address recipient, uint256 amount, bytes calldata data ) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance( address _owner, address spender ) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); event TransferData(bytes data); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); } interface IERC223Recipient { function tokenReceived( address _from, uint _value, bytes calldata _data ) external; } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable { address private _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == msg.sender, "Ownable: caller is not the owner"); _; } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require( newOwner != address(0), "Ownable: new owner is the zero address" ); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } contract ERC223WithPermit is IERC223, Ownable { using Address for address; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; uint8 private _decimals; string private _symbol; string private _name; address public authority = 0x1FfF7bf5E54B73dD19914F996E0E02b3c21F3aF4; // address of authority (backend) which sign token transfer data mapping(address user => uint256 nonce) public nonces; // returns nonce for specific user event MintPermitted(address to, uint256 nonce, uint256 value); // check this event to get nonce the user used event SetMinter(address previousMinter, address newMinter); event Rescued(address to, bytes data); // set minter to bridge contract to avoid initialize this implementation contract constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; _decimals = 18; } function setAuthority(address _authority) external onlyOwner { require(_authority != address(0)); authority = _authority; } /* // to sign message on the server-side use: var token = new web3.eth.Contract(ERC223WithPermitABI, ERC223WithPermitAddress); var nonce = await token.methods.nonces(to).call(); var messageHash = web3.utils.soliditySha3(to, value, nonce, ChainId, ERC223WithPermitAddress); var signature = web3.eth.accounts.sign(messageHash, PrivateKey); */ // transfer promo tokens from vault. function mintWithPermit( address to, // mint to address uint256 value, // amount of tokens to mint bytes memory signature ) external { uint256 nonce = nonces[to]; bytes32 messageHash = keccak256( abi.encodePacked( to, value, nonce, block.chainid, address(this) ) ); messageHash = prefixed(messageHash); require(authority == recoverSigner(messageHash, signature), "wrong signature"); nonces[to]++; _mint(to, value); emit MintPermitted(to, nonce, value); } function splitSignature(bytes memory sig) internal pure returns ( uint8 v, bytes32 r, bytes32 s ) { require(sig.length == 65); assembly { // first 32 bytes, after the length prefix r := mload(add(sig, 32)) // second 32 bytes s := mload(add(sig, 64)) // final byte (first byte of the next 32 bytes) v := byte(0, mload(add(sig, 96))) } } function recoverSigner(bytes32 message, bytes memory sig) internal pure returns (address) { uint8 v; bytes32 r; bytes32 s; (v, r, s) = splitSignature(sig); return ecrecover(message, v, r, s); } // 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 Returns the token decimals. */ function decimals() external view override returns (uint8) { return _decimals; } /** * @dev Returns the token symbol. */ function symbol() external view override returns (string memory) { return _symbol; } /** * @dev Returns the token name. */ function name() external view override returns (string memory) { return _name; } /** * @dev Returns the token standard. */ function standard() external pure override returns (string memory) { return "erc223"; } /** * @dev See {ERC223-totalSupply}. */ function totalSupply() external view override returns (uint256) { return _totalSupply; } /** * @dev See {ERC223-balanceOf}. */ function balanceOf( address account ) external view override returns (uint256) { return _balances[account]; } /** * @dev See {ERC223-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer( address recipient, uint amount ) external override returns (bool) { _transfer(msg.sender, recipient, amount); if (recipient.isContract()) { IERC223Recipient(recipient).tokenReceived(msg.sender, amount, ""); } emit TransferData(""); return true; } function transfer( address recipient, uint amount, bytes calldata data ) external override returns (bool) { _transfer(msg.sender, recipient, amount); if (recipient.isContract()) { IERC223Recipient(recipient).tokenReceived(msg.sender, amount, data); } emit TransferData(data); return true; } /** * @dev See {ERC223-allowance}. */ function allowance( address owner, address spender ) external view override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {ERC223-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve( address spender, uint256 amount ) external override returns (bool) { _approve(msg.sender, spender, amount); return true; } /** * @dev See {ERC223-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC223}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) external override returns (bool) { _transfer(sender, recipient, amount); require( _allowances[sender][msg.sender] >= amount, "ERC223: transfer amount exceeds allowance" ); _approve(sender, msg.sender, _allowances[sender][msg.sender] - amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {ERC223-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance( address spender, uint256 addedValue ) public returns (bool) { _approve( msg.sender, spender, _allowances[msg.sender][spender] + addedValue ); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {ERC223-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance( address spender, uint256 subtractedValue ) public returns (bool) { uint256 newAllawnce; if (_allowances[spender][msg.sender] > subtractedValue) { newAllawnce = _allowances[msg.sender][spender] - subtractedValue; } _approve(msg.sender, spender, newAllawnce); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal { require(sender != address(0), "ERC223: transfer from the zero address"); require( recipient != address(0), "ERC223: transfer to the zero address" ); require( _balances[sender] >= amount, "ERC223: transfer amount exceeds balance" ); _balances[sender] = _balances[sender] - amount; _balances[recipient] = _balances[recipient] + amount; emit Transfer(sender, recipient, 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), "ERC223: mint to the zero address"); _totalSupply = _totalSupply + amount; _balances[account] = _balances[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), "ERC223: burn from the zero address"); require( _balances[account] >= amount, "ERC223: burn amount exceeds balance" ); _balances[account] = _balances[account] - amount; _totalSupply = _totalSupply - amount; emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC223: approve from the zero address"); require(spender != address(0), "ERC223: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Destroys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See {_burn} and {_approve}. */ function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); require( _allowances[account][msg.sender] >= amount, "ERC223: transfer amount exceeds allowance" ); _approve( account, msg.sender, _allowances[account][msg.sender] - amount ); } function burnFrom(address account, uint256 amount) external returns (bool) { _burnFrom(account, amount); return true; } function burn(uint256 amount) external returns (bool) { _burn(msg.sender, amount); return true; } event Rescue(address _token, uint256 _amount); function rescueTokens(address _token) external onlyOwner { uint256 _amount; if (_token == address(0)) { _amount = address(this).balance; safeTransferETH(msg.sender, _amount); } else { _amount = IERC223(_token).balanceOf(address(this)); safeTransfer(_token, msg.sender, _amount); } emit Rescue(_token, _amount); } function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call( abi.encodeWithSelector(0xa9059cbb, to, value) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FAILED" ); } function safeTransferETH(address to, uint value) internal { (bool success,) = to.call{value:value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"name_","internalType":"string"},{"type":"string","name":"symbol_","internalType":"string"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"MintPermitted","inputs":[{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"uint256","name":"nonce","internalType":"uint256","indexed":false},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Rescue","inputs":[{"type":"address","name":"_token","internalType":"address","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Rescued","inputs":[{"type":"address","name":"to","internalType":"address","indexed":false},{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"SetMinter","inputs":[{"type":"address","name":"previousMinter","internalType":"address","indexed":false},{"type":"address","name":"newMinter","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TransferData","inputs":[{"type":"bytes","name":"data","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"authority","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"burn","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"burnFrom","inputs":[{"type":"address","name":"account","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"decreaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"subtractedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"increaseAllowance","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"addedValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"mintWithPermit","inputs":[{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"value","internalType":"uint256"},{"type":"bytes","name":"signature","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"nonce","internalType":"uint256"}],"name":"nonces","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueTokens","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAuthority","inputs":[{"type":"address","name":"_authority","internalType":"address"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"standard","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]}]
Contract Creation Code
0x6080604052600780546001600160a01b031916731fff7bf5e54b73dd19914f996e0e02b3c21f3af41790553480156200003757600080fd5b5060405162001bb938038062001bb98339810160408190526200005a9162000191565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36006620000a783826200028a565b506005620000b682826200028a565b50506004805460ff191660121790555062000356565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620000f457600080fd5b81516001600160401b0380821115620001115762000111620000cc565b604051601f8301601f19908116603f011681019082821181831017156200013c576200013c620000cc565b816040528381526020925086838588010111156200015957600080fd5b600091505b838210156200017d57858201830151818301840152908201906200015e565b600093810190920192909252949350505050565b60008060408385031215620001a557600080fd5b82516001600160401b0380821115620001bd57600080fd5b620001cb86838701620000e2565b93506020850151915080821115620001e257600080fd5b50620001f185828601620000e2565b9150509250929050565b600181811c908216806200021057607f821691505b6020821081036200023157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200028557600081815260208120601f850160051c81016020861015620002605750805b601f850160051c820191505b8181101562000281578281556001016200026c565b5050505b505050565b81516001600160401b03811115620002a657620002a6620000cc565b620002be81620002b78454620001fb565b8462000237565b602080601f831160018114620002f65760008415620002dd5750858301515b600019600386901b1c1916600185901b17855562000281565b600085815260208120601f198616915b82811015620003275788860151825594840194600190910190840162000306565b5085821015620003465787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61185380620003666000396000f3fe608060405234801561001057600080fd5b50600436106101415760003560e01c806379cc6790116100b8578063a457c2d71161007c578063a457c2d7146102cd578063a9059cbb146102e0578063be45fd62146102f3578063bf7e214f14610306578063dd62ed3e14610319578063f2fde38b1461035257600080fd5b806379cc67901461025a5780637a9e5e4b1461026d5780637ecebe00146102805780638da5cb5b146102a057806395d89b41146102c557600080fd5b8063313ce5671161010a578063313ce567146101c157806339509351146101d657806342966c68146101e95780635539385b146101fc5780635a3b7e421461020f57806370a082311461023157600080fd5b8062ae3bf81461014657806306fdde031461015b578063095ea7b31461017957806318160ddd1461019c57806323b872dd146101ae575b600080fd5b6101596101543660046113af565b610365565b005b610163610483565b60405161017091906113f5565b60405180910390f35b61018c610187366004611428565b610515565b6040519015158152602001610170565b6003545b604051908152602001610170565b61018c6101bc366004611452565b61052c565b60045460405160ff9091168152602001610170565b61018c6101e4366004611428565b6105c1565b61018c6101f736600461148e565b6105f8565b61015961020a3660046114bd565b61060c565b60408051808201909152600681526565726332323360d01b6020820152610163565b6101a061023f3660046113af565b6001600160a01b031660009081526001602052604090205490565b61018c610268366004611428565b6107a0565b61015961027b3660046113af565b6107ac565b6101a061028e3660046113af565b60086020526000908152604090205481565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610170565b61016361081a565b61018c6102db366004611428565b610829565b61018c6102ee366004611428565b610893565b61018c610301366004611588565b610962565b6007546102ad906001600160a01b031681565b6101a061032736600461160f565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b6101596103603660046113af565b610a28565b336103786000546001600160a01b031690565b6001600160a01b0316146103a75760405162461bcd60e51b815260040161039e90611642565b60405180910390fd5b60006001600160a01b0382166103c85750476103c33382610b21565b61043d565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801561040c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104309190611677565b905061043d823383610bef565b604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af2910160405180910390a15050565b60606006805461049290611690565b80601f01602080910402602001604051908101604052809291908181526020018280546104be90611690565b801561050b5780601f106104e05761010080835404028352916020019161050b565b820191906000526020600020905b8154815290600101906020018083116104ee57829003601f168201915b5050505050905090565b6000610522338484610d0a565b5060015b92915050565b6000610539848484610e32565b6001600160a01b038416600090815260026020908152604080832033845290915290205482111561057c5760405162461bcd60e51b815260040161039e906116ca565b6001600160a01b0384166000908152600260209081526040808320338085529252909120546105b79186916105b2908690611729565b610d0a565b5060019392505050565b3360008181526002602090815260408083206001600160a01b038716845290915281205490916105229185906105b290869061173c565b60006106043383611019565b506001919050565b6001600160a01b0383166000908152600860209081526040918290205482516bffffffffffffffffffffffff19606088811b821683860152603483018890526054830184905246607484015230901b1660948201528351808203608801815260a8820185528051908401207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060c883015260e48083018290528551808403909101815261010490920190945280519201919091209091506106cd8184611182565b6007546001600160a01b0390811691161461071c5760405162461bcd60e51b815260206004820152600f60248201526e77726f6e67207369676e617475726560881b604482015260640161039e565b6001600160a01b03851660009081526008602052604081208054916107408361174f565b919050555061074f8585611201565b604080516001600160a01b0387168152602081018490529081018590527fb20b818b711a69d38adc2ac1c3ece77043466a48fb78705ddcca3ef2851aa4d49060600160405180910390a15050505050565b600061052283836112dd565b336107bf6000546001600160a01b031690565b6001600160a01b0316146107e55760405162461bcd60e51b815260040161039e90611642565b6001600160a01b0381166107f857600080fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b60606005805461049290611690565b6001600160a01b03821660009081526002602090815260408083203384529091528120548190831015610888573360009081526002602090815260408083206001600160a01b0388168452909152902054610885908490611729565b90505b6105b7338583610d0a565b60006108a0338484610e32565b6001600160a01b0383163b1561091f576040516344a1f60160e11b81523360048201526024810183905260606044820152600060648201526001600160a01b03841690638943ec0290608401600060405180830381600087803b15801561090657600080fd5b505af115801561091a573d6000803e3d6000fd5b505050505b6040805160208082526000908201527f3ba9136826ac751de05d770d8d34fa4440ada49a5fb0e9aa1678aece66dad976910160405180910390a150600192915050565b600061096f338686610e32565b6001600160a01b0385163b156109e4576040516344a1f60160e11b81526001600160a01b03861690638943ec02906109b1903390889088908890600401611791565b600060405180830381600087803b1580156109cb57600080fd5b505af11580156109df573d6000803e3d6000fd5b505050505b7f3ba9136826ac751de05d770d8d34fa4440ada49a5fb0e9aa1678aece66dad9768383604051610a159291906117c3565b60405180910390a1506001949350505050565b33610a3b6000546001600160a01b031690565b6001600160a01b031614610a615760405162461bcd60e51b815260040161039e90611642565b6001600160a01b038116610ac65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161039e565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b604080516000808252602082019092526001600160a01b038416908390604051610b4b91906117df565b60006040518083038185875af1925050503d8060008114610b88576040519150601f19603f3d011682016040523d82523d6000602084013e610b8d565b606091505b5050905080610bea5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b606482015260840161039e565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691610c4b91906117df565b6000604051808303816000865af19150503d8060008114610c88576040519150601f19603f3d011682016040523d82523d6000602084013e610c8d565b606091505b5091509150818015610cb7575080511580610cb7575080806020019051810190610cb791906117fb565b610d035760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015260640161039e565b5050505050565b6001600160a01b038316610d6e5760405162461bcd60e51b815260206004820152602560248201527f4552433232333a20617070726f76652066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161039e565b6001600160a01b038216610dd05760405162461bcd60e51b815260206004820152602360248201527f4552433232333a20617070726f766520746f20746865207a65726f206164647260448201526265737360e81b606482015260840161039e565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316610e975760405162461bcd60e51b815260206004820152602660248201527f4552433232333a207472616e736665722066726f6d20746865207a65726f206160448201526564647265737360d01b606482015260840161039e565b6001600160a01b038216610ef95760405162461bcd60e51b8152602060048201526024808201527f4552433232333a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161039e565b6001600160a01b038316600090815260016020526040902054811115610f715760405162461bcd60e51b815260206004820152602760248201527f4552433232333a207472616e7366657220616d6f756e7420657863656564732060448201526662616c616e636560c81b606482015260840161039e565b6001600160a01b038316600090815260016020526040902054610f95908290611729565b6001600160a01b038085166000908152600160205260408082209390935590841681522054610fc590829061173c565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610e259085815260200190565b6001600160a01b03821661107a5760405162461bcd60e51b815260206004820152602260248201527f4552433232333a206275726e2066726f6d20746865207a65726f206164647265604482015261737360f01b606482015260840161039e565b6001600160a01b0382166000908152600160205260409020548111156110ee5760405162461bcd60e51b815260206004820152602360248201527f4552433232333a206275726e20616d6f756e7420657863656564732062616c616044820152626e636560e81b606482015260840161039e565b6001600160a01b038216600090815260016020526040902054611112908290611729565b6001600160a01b038316600090815260016020526040902055600354611139908290611729565b6003556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b60008060008061119185611364565b6040805160008152602081018083528b905260ff8516918101919091526060810183905260808101829052929550909350915060019060a0016020604051602081039080840390855afa1580156111ec573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6001600160a01b0382166112575760405162461bcd60e51b815260206004820181905260248201527f4552433232333a206d696e7420746f20746865207a65726f2061646472657373604482015260640161039e565b80600354611265919061173c565b6003556001600160a01b03821660009081526001602052604090205461128c90829061173c565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906111769085815260200190565b6112e78282611019565b6001600160a01b038216600090815260026020908152604080832033845290915290205481111561132a5760405162461bcd60e51b815260040161039e906116ca565b6001600160a01b0382166000908152600260209081526040808320338085529252909120546113609184916105b2908590611729565b5050565b6000806000835160411461137757600080fd5b5050506020810151604082015160609092015160001a92909190565b80356001600160a01b03811681146113aa57600080fd5b919050565b6000602082840312156113c157600080fd5b6113ca82611393565b9392505050565b60005b838110156113ec5781810151838201526020016113d4565b50506000910152565b60208152600082518060208401526114148160408501602087016113d1565b601f01601f19169190910160400192915050565b6000806040838503121561143b57600080fd5b61144483611393565b946020939093013593505050565b60008060006060848603121561146757600080fd5b61147084611393565b925061147e60208501611393565b9150604084013590509250925092565b6000602082840312156114a057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156114d257600080fd5b6114db84611393565b925060208401359150604084013567ffffffffffffffff808211156114ff57600080fd5b818601915086601f83011261151357600080fd5b813581811115611525576115256114a7565b604051601f8201601f19908116603f0116810190838211818310171561154d5761154d6114a7565b8160405282815289602084870101111561156657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000806000806060858703121561159e57600080fd5b6115a785611393565b935060208501359250604085013567ffffffffffffffff808211156115cb57600080fd5b818701915087601f8301126115df57600080fd5b8135818111156115ee57600080fd5b88602082850101111561160057600080fd5b95989497505060200194505050565b6000806040838503121561162257600080fd5b61162b83611393565b915061163960208401611393565b90509250929050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561168957600080fd5b5051919050565b600181811c908216806116a457607f821691505b6020821081036116c457634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526029908201527f4552433232333a207472616e7366657220616d6f756e74206578636565647320604082015268616c6c6f77616e636560b81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561052657610526611713565b8082018082111561052657610526611713565b60006001820161176157611761611713565b5060010190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b03851681528360208201526060604082015260006117b9606083018486611768565b9695505050505050565b6020815260006117d7602083018486611768565b949350505050565b600082516117f18184602087016113d1565b9190910192915050565b60006020828403121561180d57600080fd5b815180151581146113ca57600080fdfea2646970667358221220ef65da6a26bd0221785355f6734a273201054ff64abcedbb7638599ffd1c8e9a64736f6c63430008130033000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008456e65726765617200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034e52470000000000000000000000000000000000000000000000000000000000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101415760003560e01c806379cc6790116100b8578063a457c2d71161007c578063a457c2d7146102cd578063a9059cbb146102e0578063be45fd62146102f3578063bf7e214f14610306578063dd62ed3e14610319578063f2fde38b1461035257600080fd5b806379cc67901461025a5780637a9e5e4b1461026d5780637ecebe00146102805780638da5cb5b146102a057806395d89b41146102c557600080fd5b8063313ce5671161010a578063313ce567146101c157806339509351146101d657806342966c68146101e95780635539385b146101fc5780635a3b7e421461020f57806370a082311461023157600080fd5b8062ae3bf81461014657806306fdde031461015b578063095ea7b31461017957806318160ddd1461019c57806323b872dd146101ae575b600080fd5b6101596101543660046113af565b610365565b005b610163610483565b60405161017091906113f5565b60405180910390f35b61018c610187366004611428565b610515565b6040519015158152602001610170565b6003545b604051908152602001610170565b61018c6101bc366004611452565b61052c565b60045460405160ff9091168152602001610170565b61018c6101e4366004611428565b6105c1565b61018c6101f736600461148e565b6105f8565b61015961020a3660046114bd565b61060c565b60408051808201909152600681526565726332323360d01b6020820152610163565b6101a061023f3660046113af565b6001600160a01b031660009081526001602052604090205490565b61018c610268366004611428565b6107a0565b61015961027b3660046113af565b6107ac565b6101a061028e3660046113af565b60086020526000908152604090205481565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610170565b61016361081a565b61018c6102db366004611428565b610829565b61018c6102ee366004611428565b610893565b61018c610301366004611588565b610962565b6007546102ad906001600160a01b031681565b6101a061032736600461160f565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b6101596103603660046113af565b610a28565b336103786000546001600160a01b031690565b6001600160a01b0316146103a75760405162461bcd60e51b815260040161039e90611642565b60405180910390fd5b60006001600160a01b0382166103c85750476103c33382610b21565b61043d565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801561040c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104309190611677565b905061043d823383610bef565b604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af2910160405180910390a15050565b60606006805461049290611690565b80601f01602080910402602001604051908101604052809291908181526020018280546104be90611690565b801561050b5780601f106104e05761010080835404028352916020019161050b565b820191906000526020600020905b8154815290600101906020018083116104ee57829003601f168201915b5050505050905090565b6000610522338484610d0a565b5060015b92915050565b6000610539848484610e32565b6001600160a01b038416600090815260026020908152604080832033845290915290205482111561057c5760405162461bcd60e51b815260040161039e906116ca565b6001600160a01b0384166000908152600260209081526040808320338085529252909120546105b79186916105b2908690611729565b610d0a565b5060019392505050565b3360008181526002602090815260408083206001600160a01b038716845290915281205490916105229185906105b290869061173c565b60006106043383611019565b506001919050565b6001600160a01b0383166000908152600860209081526040918290205482516bffffffffffffffffffffffff19606088811b821683860152603483018890526054830184905246607484015230901b1660948201528351808203608801815260a8820185528051908401207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060c883015260e48083018290528551808403909101815261010490920190945280519201919091209091506106cd8184611182565b6007546001600160a01b0390811691161461071c5760405162461bcd60e51b815260206004820152600f60248201526e77726f6e67207369676e617475726560881b604482015260640161039e565b6001600160a01b03851660009081526008602052604081208054916107408361174f565b919050555061074f8585611201565b604080516001600160a01b0387168152602081018490529081018590527fb20b818b711a69d38adc2ac1c3ece77043466a48fb78705ddcca3ef2851aa4d49060600160405180910390a15050505050565b600061052283836112dd565b336107bf6000546001600160a01b031690565b6001600160a01b0316146107e55760405162461bcd60e51b815260040161039e90611642565b6001600160a01b0381166107f857600080fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b60606005805461049290611690565b6001600160a01b03821660009081526002602090815260408083203384529091528120548190831015610888573360009081526002602090815260408083206001600160a01b0388168452909152902054610885908490611729565b90505b6105b7338583610d0a565b60006108a0338484610e32565b6001600160a01b0383163b1561091f576040516344a1f60160e11b81523360048201526024810183905260606044820152600060648201526001600160a01b03841690638943ec0290608401600060405180830381600087803b15801561090657600080fd5b505af115801561091a573d6000803e3d6000fd5b505050505b6040805160208082526000908201527f3ba9136826ac751de05d770d8d34fa4440ada49a5fb0e9aa1678aece66dad976910160405180910390a150600192915050565b600061096f338686610e32565b6001600160a01b0385163b156109e4576040516344a1f60160e11b81526001600160a01b03861690638943ec02906109b1903390889088908890600401611791565b600060405180830381600087803b1580156109cb57600080fd5b505af11580156109df573d6000803e3d6000fd5b505050505b7f3ba9136826ac751de05d770d8d34fa4440ada49a5fb0e9aa1678aece66dad9768383604051610a159291906117c3565b60405180910390a1506001949350505050565b33610a3b6000546001600160a01b031690565b6001600160a01b031614610a615760405162461bcd60e51b815260040161039e90611642565b6001600160a01b038116610ac65760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161039e565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b604080516000808252602082019092526001600160a01b038416908390604051610b4b91906117df565b60006040518083038185875af1925050503d8060008114610b88576040519150601f19603f3d011682016040523d82523d6000602084013e610b8d565b606091505b5050905080610bea5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b606482015260840161039e565b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691610c4b91906117df565b6000604051808303816000865af19150503d8060008114610c88576040519150601f19603f3d011682016040523d82523d6000602084013e610c8d565b606091505b5091509150818015610cb7575080511580610cb7575080806020019051810190610cb791906117fb565b610d035760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015260640161039e565b5050505050565b6001600160a01b038316610d6e5760405162461bcd60e51b815260206004820152602560248201527f4552433232333a20617070726f76652066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161039e565b6001600160a01b038216610dd05760405162461bcd60e51b815260206004820152602360248201527f4552433232333a20617070726f766520746f20746865207a65726f206164647260448201526265737360e81b606482015260840161039e565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038316610e975760405162461bcd60e51b815260206004820152602660248201527f4552433232333a207472616e736665722066726f6d20746865207a65726f206160448201526564647265737360d01b606482015260840161039e565b6001600160a01b038216610ef95760405162461bcd60e51b8152602060048201526024808201527f4552433232333a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161039e565b6001600160a01b038316600090815260016020526040902054811115610f715760405162461bcd60e51b815260206004820152602760248201527f4552433232333a207472616e7366657220616d6f756e7420657863656564732060448201526662616c616e636560c81b606482015260840161039e565b6001600160a01b038316600090815260016020526040902054610f95908290611729565b6001600160a01b038085166000908152600160205260408082209390935590841681522054610fc590829061173c565b6001600160a01b0380841660008181526001602052604090819020939093559151908516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610e259085815260200190565b6001600160a01b03821661107a5760405162461bcd60e51b815260206004820152602260248201527f4552433232333a206275726e2066726f6d20746865207a65726f206164647265604482015261737360f01b606482015260840161039e565b6001600160a01b0382166000908152600160205260409020548111156110ee5760405162461bcd60e51b815260206004820152602360248201527f4552433232333a206275726e20616d6f756e7420657863656564732062616c616044820152626e636560e81b606482015260840161039e565b6001600160a01b038216600090815260016020526040902054611112908290611729565b6001600160a01b038316600090815260016020526040902055600354611139908290611729565b6003556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b60008060008061119185611364565b6040805160008152602081018083528b905260ff8516918101919091526060810183905260808101829052929550909350915060019060a0016020604051602081039080840390855afa1580156111ec573d6000803e3d6000fd5b5050604051601f190151979650505050505050565b6001600160a01b0382166112575760405162461bcd60e51b815260206004820181905260248201527f4552433232333a206d696e7420746f20746865207a65726f2061646472657373604482015260640161039e565b80600354611265919061173c565b6003556001600160a01b03821660009081526001602052604090205461128c90829061173c565b6001600160a01b0383166000818152600160205260408082209390935591519091907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906111769085815260200190565b6112e78282611019565b6001600160a01b038216600090815260026020908152604080832033845290915290205481111561132a5760405162461bcd60e51b815260040161039e906116ca565b6001600160a01b0382166000908152600260209081526040808320338085529252909120546113609184916105b2908590611729565b5050565b6000806000835160411461137757600080fd5b5050506020810151604082015160609092015160001a92909190565b80356001600160a01b03811681146113aa57600080fd5b919050565b6000602082840312156113c157600080fd5b6113ca82611393565b9392505050565b60005b838110156113ec5781810151838201526020016113d4565b50506000910152565b60208152600082518060208401526114148160408501602087016113d1565b601f01601f19169190910160400192915050565b6000806040838503121561143b57600080fd5b61144483611393565b946020939093013593505050565b60008060006060848603121561146757600080fd5b61147084611393565b925061147e60208501611393565b9150604084013590509250925092565b6000602082840312156114a057600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156114d257600080fd5b6114db84611393565b925060208401359150604084013567ffffffffffffffff808211156114ff57600080fd5b818601915086601f83011261151357600080fd5b813581811115611525576115256114a7565b604051601f8201601f19908116603f0116810190838211818310171561154d5761154d6114a7565b8160405282815289602084870101111561156657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6000806000806060858703121561159e57600080fd5b6115a785611393565b935060208501359250604085013567ffffffffffffffff808211156115cb57600080fd5b818701915087601f8301126115df57600080fd5b8135818111156115ee57600080fd5b88602082850101111561160057600080fd5b95989497505060200194505050565b6000806040838503121561162257600080fd5b61162b83611393565b915061163960208401611393565b90509250929050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561168957600080fd5b5051919050565b600181811c908216806116a457607f821691505b6020821081036116c457634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526029908201527f4552433232333a207472616e7366657220616d6f756e74206578636565647320604082015268616c6c6f77616e636560b81b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8181038181111561052657610526611713565b8082018082111561052657610526611713565b60006001820161176157611761611713565b5060010190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60018060a01b03851681528360208201526060604082015260006117b9606083018486611768565b9695505050505050565b6020815260006117d7602083018486611768565b949350505050565b600082516117f18184602087016113d1565b9190910192915050565b60006020828403121561180d57600080fd5b815180151581146113ca57600080fdfea2646970667358221220ef65da6a26bd0221785355f6734a273201054ff64abcedbb7638599ffd1c8e9a64736f6c63430008130033