More Info
Private Name Tags
ContractCreator
Latest 20 from a total of 20 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer Ownersh... | 55561517 | 247 days ago | IN | 0 POL | 0.00158947 | ||||
Transfer Ownersh... | 55561517 | 247 days ago | IN | 0 POL | 0.0015108 | ||||
Transfer Ownersh... | 55561517 | 247 days ago | IN | 0 POL | 0.00154824 | ||||
Map Token | 53812693 | 292 days ago | IN | 0 POL | 0.00233317 | ||||
Renounce Ownersh... | 36215989 | 742 days ago | IN | 0 POL | 0.00070455 | ||||
Withdraw Tokens | 34914969 | 774 days ago | IN | 0 POL | 0.0012318 | ||||
Transfer Ownersh... | 30988317 | 873 days ago | IN | 0 POL | 0.00071595 | ||||
Add Token | 23781301 | 1059 days ago | IN | 0 POL | 0.0007848 | ||||
Transfer Ownersh... | 23141538 | 1076 days ago | IN | 0 POL | 0.00071595 | ||||
Transfer Ownersh... | 23137596 | 1076 days ago | IN | 0 POL | 0.00372528 | ||||
Add Token | 22074715 | 1103 days ago | IN | 0 POL | 0.00086288 | ||||
Withdraw Tokens | 19393584 | 1175 days ago | IN | 0 POL | 0.0000476 | ||||
Map Token | 10023863 | 1415 days ago | IN | 0 POL | 0.00411462 | ||||
Map Token | 2896425 | 1586 days ago | IN | 0 POL | 0.00318078 | ||||
Map Token | 2798738 | 1588 days ago | IN | 0 POL | 0.00453654 | ||||
Map Token | 2411001 | 1597 days ago | IN | 0 POL | 0.0013094 | ||||
Map Token | 929 | 1655 days ago | IN | 0 POL | 0.00003425 | ||||
Add Token | 905 | 1655 days ago | IN | 0 POL | 0.001824 | ||||
Add Token | 897 | 1655 days ago | IN | 0 POL | 0.0014389 | ||||
Add Token | 882 | 1655 days ago | IN | 0 POL | 0.0014389 |
Latest 3 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
905 | 1655 days ago | Contract Creation | 0 POL | |||
897 | 1655 days ago | Contract Creation | 0 POL | |||
882 | 1655 days ago | Contract Creation | 0 POL |
Loading...
Loading
Contract Name:
ChildChain
Compiler Version
v0.5.11+commit.c082d0b4
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2021-05-18 */ // File: openzeppelin-solidity/contracts/ownership/Ownable.sol pragma solidity ^0.5.2; /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /** * @return the address of the owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner()); _; } /** * @return true if `msg.sender` is the owner of the contract. */ function isOwner() public view returns (bool) { return msg.sender == _owner; } /** * @dev Allows the current owner to relinquish control of the contract. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. * @notice Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param newOwner The address to transfer ownership to. */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0)); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/child/bor/StateSyncerVerifier.sol pragma solidity ^0.5.2; contract StateSyncerVerifier is Ownable { address public stateSyncer; event StateSyncerAddressChanged( address indexed previousAddress, address indexed newAddress ); /** * @dev Throws if called by any account other than state syncer */ modifier onlyStateSyncer() { require( isOnlyStateSyncerContract(), "State syncer: caller is not the state syncer contract" ); _; } // initial setup constructor() public { // default state syncer contract stateSyncer = 0x0000000000000000000000000000000000001001; // emit event for first change emit StateSyncerAddressChanged(address(0), stateSyncer); } /** * @dev Returns true if the caller is the state syncer contract * TODO: replace onlyOwner ownership with 0x1000 for validator majority */ function isOnlyStateSyncerContract() public view returns (bool) { return msg.sender == stateSyncer; } // change state syncer address function changeStateSyncerAddress(address newAddress) public onlyOwner { require( newAddress != address(0), "State syncer: new state syncer address is the zero address" ); emit StateSyncerAddressChanged(stateSyncer, newAddress); stateSyncer = newAddress; } } // File: contracts/child/bor/StateReceiver.sol pragma solidity ^0.5.2; // StateReceiver represents interface to receive state interface StateReceiver { function onStateReceive(uint256 id, bytes calldata data) external; } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.2; /** * @title SafeMath * @dev Unsigned math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: contracts/common/mixin/ChainIdMixin.sol pragma solidity ^0.5.2; contract ChainIdMixin { bytes constant public networkId = hex"89"; uint256 constant public CHAINID = 137; } // File: contracts/child/misc/EIP712.sol pragma solidity ^0.5.2; contract LibEIP712Domain is ChainIdMixin { string internal constant EIP712_DOMAIN_SCHEMA = "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"; bytes32 public constant EIP712_DOMAIN_SCHEMA_HASH = keccak256( abi.encodePacked(EIP712_DOMAIN_SCHEMA) ); string internal constant EIP712_DOMAIN_NAME = "Matic Network"; string internal constant EIP712_DOMAIN_VERSION = "1"; uint256 internal constant EIP712_DOMAIN_CHAINID = CHAINID; bytes32 public EIP712_DOMAIN_HASH; constructor() public { EIP712_DOMAIN_HASH = keccak256( abi.encode( EIP712_DOMAIN_SCHEMA_HASH, keccak256(bytes(EIP712_DOMAIN_NAME)), keccak256(bytes(EIP712_DOMAIN_VERSION)), EIP712_DOMAIN_CHAINID, address(this) ) ); } function hashEIP712Message(bytes32 hashStruct) internal view returns (bytes32 result) { bytes32 domainHash = EIP712_DOMAIN_HASH; // Assembly for more efficient computing: // keccak256(abi.encode( // EIP191_HEADER, // domainHash, // hashStruct // )); assembly { // Load free memory pointer let memPtr := mload(64) mstore( memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000 ) // EIP191 header mstore(add(memPtr, 2), domainHash) // EIP712 domain hash mstore(add(memPtr, 34), hashStruct) // Hash of struct // Compute hash result := keccak256(memPtr, 66) } return result; } } // File: contracts/child/misc/LibTokenTransferOrder.sol pragma solidity ^0.5.2; contract LibTokenTransferOrder is LibEIP712Domain { string internal constant EIP712_TOKEN_TRANSFER_ORDER_SCHEMA = "TokenTransferOrder(address spender,uint256 tokenIdOrAmount,bytes32 data,uint256 expiration)"; bytes32 public constant EIP712_TOKEN_TRANSFER_ORDER_SCHEMA_HASH = keccak256( abi.encodePacked(EIP712_TOKEN_TRANSFER_ORDER_SCHEMA) ); struct TokenTransferOrder { address spender; uint256 tokenIdOrAmount; bytes32 data; uint256 expiration; } function getTokenTransferOrderHash( address spender, uint256 tokenIdOrAmount, bytes32 data, uint256 expiration ) public view returns (bytes32 orderHash) { orderHash = hashEIP712Message( hashTokenTransferOrder(spender, tokenIdOrAmount, data, expiration) ); } function hashTokenTransferOrder( address spender, uint256 tokenIdOrAmount, bytes32 data, uint256 expiration ) internal pure returns (bytes32 result) { bytes32 schemaHash = EIP712_TOKEN_TRANSFER_ORDER_SCHEMA_HASH; // Assembly for more efficiently computing: // return keccak256(abi.encode( // schemaHash, // spender, // tokenIdOrAmount, // data, // expiration // )); assembly { // Load free memory pointer let memPtr := mload(64) mstore(memPtr, schemaHash) // hash of schema mstore( add(memPtr, 32), and(spender, 0xffffffffffffffffffffffffffffffffffffffff) ) // spender mstore(add(memPtr, 64), tokenIdOrAmount) // tokenIdOrAmount mstore(add(memPtr, 96), data) // hash of data mstore(add(memPtr, 128), expiration) // expiration // Compute hash result := keccak256(memPtr, 160) } return result; } } // File: contracts/child/ChildToken.sol pragma solidity ^0.5.2; contract ChildToken is Ownable, LibTokenTransferOrder { using SafeMath for uint256; // ERC721/ERC20 contract token address on root chain address public token; address public parent; address public parentOwner; mapping(bytes32 => bool) public disabledHashes; modifier isParentOwner() { require(msg.sender == parentOwner); _; } function deposit(address user, uint256 amountOrTokenId) public; function withdraw(uint256 amountOrTokenId) public payable; function setParent(address _parent) public; event LogFeeTransfer( address indexed token, address indexed from, address indexed to, uint256 amount, uint256 input1, uint256 input2, uint256 output1, uint256 output2 ); function ecrecovery(bytes32 hash, bytes memory sig) public pure returns (address result) { bytes32 r; bytes32 s; uint8 v; if (sig.length != 65) { return address(0x0); } assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := and(mload(add(sig, 65)), 255) } // https://github.com/ethereum/go-ethereum/issues/2053 if (v < 27) { v += 27; } if (v != 27 && v != 28) { return address(0x0); } // get address out of hash and signature result = ecrecover(hash, v, r, s); // ecrecover returns zero on error require(result != address(0x0), "Error in ecrecover"); } } // File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.2; /** * @title ERC20 interface * @dev see https://eips.ethereum.org/EIPS/eip-20 */ interface IERC20 { function transfer(address to, uint256 value) external returns (bool); function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function totalSupply() external view returns (uint256); function balanceOf(address who) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.2; /** * @title ERC20Detailed token * @dev The decimals are only for visualization purposes. * All the operations are done using the smallest and indivisible token unit, * just as on Ethereum all the operations are done in wei. */ contract ERC20Detailed is IERC20 { string private _name; string private _symbol; uint8 private _decimals; constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; _decimals = decimals; } /** * @return the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @return the symbol of the token. */ function symbol() public view returns (string memory) { return _symbol; } /** * @return the number of decimals of the token. */ function decimals() public view returns (uint8) { return _decimals; } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol pragma solidity ^0.5.2; /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://eips.ethereum.org/EIPS/eip-20 * Originally based on code by FirstBlood: * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol * * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for * all accounts just by listening to said events. Note that this isn't required by the specification, and other * compliant implementations may not do it. */ contract ERC20 is IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowed; uint256 private _totalSupply; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev Gets the balance of the specified address. * @param owner The address to query the balance of. * @return A uint256 representing the amount owned by the passed address. */ function balanceOf(address owner) public view returns (uint256) { return _balances[owner]; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param owner address The address which owns the funds. * @param spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowed[owner][spender]; } /** * @dev Transfer token to a specified address * @param to The address to transfer to. * @param value The amount to be transferred. */ function transfer(address to, uint256 value) public returns (bool) { _transfer(msg.sender, to, value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * 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 * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. */ function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); return true; } /** * @dev Transfer tokens from one address to another. * Note that while this function emits an Approval event, this is not required as per the specification, * and other compliant implementations may not emit the event. * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param value uint256 the amount of tokens to be transferred */ function transferFrom(address from, address to, uint256 value) public returns (bool) { _transfer(from, to, value); _approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); return true; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param addedValue The amount of tokens to increase the allowance by. */ function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when _allowed[msg.sender][spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * Emits an Approval event. * @param spender The address which will spend the funds. * @param subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); return true; } /** * @dev Transfer token for a specified addresses * @param from The address to transfer from. * @param to The address to transfer to. * @param value The amount to be transferred. */ function _transfer(address from, address to, uint256 value) internal { require(to != address(0)); _balances[from] = _balances[from].sub(value); _balances[to] = _balances[to].add(value); emit Transfer(from, to, value); } /** * @dev Internal function that mints an amount of the token and assigns it to * an account. This encapsulates the modification of balances such that the * proper events are emitted. * @param account The account that will receive the created tokens. * @param value The amount that will be created. */ function _mint(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.add(value); _balances[account] = _balances[account].add(value); emit Transfer(address(0), account, value); } /** * @dev Internal function that burns an amount of the token of a given * account. * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burn(address account, uint256 value) internal { require(account != address(0)); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /** * @dev Approve an address to spend another addresses' tokens. * @param owner The address that owns the tokens. * @param spender The address that will spend the tokens. * @param value The number of tokens that can be spent. */ function _approve(address owner, address spender, uint256 value) internal { require(spender != address(0)); require(owner != address(0)); _allowed[owner][spender] = value; emit Approval(owner, spender, value); } /** * @dev Internal function that burns an amount of the token of a given * account, deducting from the sender's allowance for said account. Uses the * internal burn function. * Emits an Approval event (reflecting the reduced allowance). * @param account The account whose tokens will be burnt. * @param value The amount that will be burnt. */ function _burnFrom(address account, uint256 value) internal { _burn(account, value); _approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); } } // File: contracts/child/BaseERC20.sol pragma solidity ^0.5.2; contract BaseERC20 is ChildToken { event Deposit( address indexed token, address indexed from, uint256 amount, uint256 input1, uint256 output1 ); event Withdraw( address indexed token, address indexed from, uint256 amount, uint256 input1, uint256 output1 ); event LogTransfer( address indexed token, address indexed from, address indexed to, uint256 amount, uint256 input1, uint256 input2, uint256 output1, uint256 output2 ); constructor() public {} function transferWithSig( bytes calldata sig, uint256 amount, bytes32 data, uint256 expiration, address to ) external returns (address from) { require(amount > 0); require( expiration == 0 || block.number <= expiration, "Signature is expired" ); bytes32 dataHash = getTokenTransferOrderHash( msg.sender, amount, data, expiration ); require(disabledHashes[dataHash] == false, "Sig deactivated"); disabledHashes[dataHash] = true; from = ecrecovery(dataHash, sig); _transferFrom(from, address(uint160(to)), amount); } function balanceOf(address account) external view returns (uint256); function _transfer(address sender, address recipient, uint256 amount) internal; /// @param from Address from where tokens are withdrawn. /// @param to Address to where tokens are sent. /// @param value Number of tokens to transfer. /// @return Returns success of function call. function _transferFrom(address from, address to, uint256 value) internal returns (bool) { uint256 input1 = this.balanceOf(from); uint256 input2 = this.balanceOf(to); _transfer(from, to, value); emit LogTransfer( token, from, to, value, input1, input2, this.balanceOf(from), this.balanceOf(to) ); return true; } } // File: contracts/child/misc/IParentToken.sol pragma solidity ^0.5.2; //interface for parent contract of any child token interface IParentToken { function beforeTransfer(address sender, address to, uint256 value) external returns (bool); } // File: contracts/child/ChildERC20.sol pragma solidity ^0.5.2; contract ChildERC20 is BaseERC20, ERC20, ERC20Detailed { constructor( address _owner, address _token, string memory _name, string memory _symbol, uint8 _decimals ) public ERC20Detailed(_name, _symbol, _decimals) { require(_token != address(0x0) && _owner != address(0x0)); parentOwner = _owner; token = _token; } function setParent(address _parent) public isParentOwner { require(_parent != address(0x0)); parent = _parent; } /** * Deposit tokens * * @param user address for address * @param amount token balance */ function deposit(address user, uint256 amount) public onlyOwner { // check for amount and user require(amount > 0 && user != address(0x0)); // input balance uint256 input1 = balanceOf(user); // increase balance _mint(user, amount); // deposit events emit Deposit(token, user, amount, input1, balanceOf(user)); } /** * Withdraw tokens * * @param amount tokens */ function withdraw(uint256 amount) public payable { address user = msg.sender; // input balance uint256 input = balanceOf(user); // check for amount require(amount > 0 && input >= amount); // decrease balance _burn(user, amount); // withdraw event emit Withdraw(token, user, amount, input, balanceOf(user)); } /// @dev Function that is called when a user or another contract wants to transfer funds. /// @param to Address of token receiver. /// @param value Number of tokens to transfer. /// @return Returns success of function call. function transfer(address to, uint256 value) public returns (bool) { if ( parent != address(0x0) && !IParentToken(parent).beforeTransfer(msg.sender, to, value) ) { return false; } return _transferFrom(msg.sender, to, value); } function allowance(address, address) public view returns (uint256) { revert("Disabled feature"); } function approve(address, uint256) public returns (bool) { revert("Disabled feature"); } function transferFrom(address, address, uint256) public returns (bool) { revert("Disabled feature"); } } // File: openzeppelin-solidity/contracts/introspection/IERC165.sol pragma solidity ^0.5.2; /** * @title IERC165 * @dev https://eips.ethereum.org/EIPS/eip-165 */ interface IERC165 { /** * @notice Query if a contract implements an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721.sol pragma solidity ^0.5.2; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721 is IERC165 { event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function balanceOf(address owner) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner); function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function transferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public; } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol pragma solidity ^0.5.2; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract IERC721Receiver { /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `safeTransfer`. This function MUST return the function selector, * otherwise the caller will revert the transaction. The selector to be * returned can be obtained as `this.onERC721Received.selector`. This * function MAY throw to revert and reject the transfer. * Note: the ERC721 contract address is always the message sender. * @param operator The address which called `safeTransferFrom` function * @param from The address which previously owned the token * @param tokenId The NFT identifier which is being transferred * @param data Additional data with no specified format * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data) public returns (bytes4); } // File: openzeppelin-solidity/contracts/utils/Address.sol pragma solidity ^0.5.2; /** * Utility library of inline functions on addresses */ library Address { /** * Returns whether the target address is a contract * @dev This function will return false if invoked during the constructor of a contract, * as the code is not actually created until after the constructor finishes. * @param account address of the account to check * @return whether the target address is a contract */ function isContract(address account) internal view returns (bool) { uint256 size; // XXX Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: openzeppelin-solidity/contracts/drafts/Counters.sol pragma solidity ^0.5.2; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the SafeMath * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } } // File: openzeppelin-solidity/contracts/introspection/ERC165.sol pragma solidity ^0.5.2; /** * @title ERC165 * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract ERC165 is IERC165 { bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /* * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) private _supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor () internal { _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 interfaceId) external view returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev internal method for registering an interface */ function _registerInterface(bytes4 interfaceId) internal { require(interfaceId != 0xffffffff); _supportedInterfaces[interfaceId] = true; } } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721.sol pragma solidity ^0.5.2; /** * @title ERC721 Non-Fungible Token Standard basic implementation * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721 is ERC165, IERC721 { using SafeMath for uint256; using Address for address; using Counters for Counters.Counter; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Mapping from token ID to owner mapping (uint256 => address) private _tokenOwner; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to number of owned token mapping (address => Counters.Counter) private _ownedTokensCount; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ constructor () public { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); } /** * @dev Gets the balance of the specified address * @param owner address to query the balance of * @return uint256 representing the amount owned by the passed address */ function balanceOf(address owner) public view returns (uint256) { require(owner != address(0)); return _ownedTokensCount[owner].current(); } /** * @dev Gets the owner of the specified token ID * @param tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ function ownerOf(uint256 tokenId) public view returns (address) { address owner = _tokenOwner[tokenId]; require(owner != address(0)); return owner; } /** * @dev Approves another address to transfer the given token ID * The zero address indicates there is no approved address. * There can only be one approved address per token at a given time. * Can only be called by the token owner or an approved operator. * @param to address to be approved for the given token ID * @param tokenId uint256 ID of the token to be approved */ function approve(address to, uint256 tokenId) public { address owner = ownerOf(tokenId); require(to != owner); require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); _tokenApprovals[tokenId] = to; emit Approval(owner, to, tokenId); } /** * @dev Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. * @param tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ function getApproved(uint256 tokenId) public view returns (address) { require(_exists(tokenId)); return _tokenApprovals[tokenId]; } /** * @dev Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf * @param to operator address to set the approval * @param approved representing the status of the approval to be set */ function setApprovalForAll(address to, bool approved) public { require(to != msg.sender); _operatorApprovals[msg.sender][to] = approved; emit ApprovalForAll(msg.sender, to, approved); } /** * @dev Tells whether an operator is approved by a given owner * @param owner owner address which you want to query the approval of * @param operator operator address which you want to query the approval of * @return bool whether the given operator is approved by the given owner */ function isApprovedForAll(address owner, address operator) public view returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev Transfers the ownership of a given token ID to another address * Usage of this method is discouraged, use `safeTransferFrom` whenever possible * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function transferFrom(address from, address to, uint256 tokenId) public { require(_isApprovedOrOwner(msg.sender, tokenId)); _transferFrom(from, to, tokenId); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function safeTransferFrom(address from, address to, uint256 tokenId) public { safeTransferFrom(from, to, tokenId, ""); } /** * @dev Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * the transfer is reverted. * Requires the msg.sender to be the owner, approved, or operator * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public { transferFrom(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data)); } /** * @dev Returns whether the specified token exists * @param tokenId uint256 ID of the token to query the existence of * @return bool whether the token exists */ function _exists(uint256 tokenId) internal view returns (bool) { address owner = _tokenOwner[tokenId]; return owner != address(0); } /** * @dev Returns whether the given spender can transfer a given token ID * @param spender address of the spender to query * @param tokenId uint256 ID of the token to be transferred * @return bool whether the msg.sender is approved for the given token ID, * is an operator of the owner, or is the owner of the token */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) { address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to The address that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { require(to != address(0)); require(!_exists(tokenId)); _tokenOwner[tokenId] = to; _ownedTokensCount[to].increment(); emit Transfer(address(0), to, tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead. * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { require(ownerOf(tokenId) == owner); _clearApproval(tokenId); _ownedTokensCount[owner].decrement(); _tokenOwner[tokenId] = address(0); emit Transfer(owner, address(0), tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * @param tokenId uint256 ID of the token being burned */ function _burn(uint256 tokenId) internal { _burn(ownerOf(tokenId), tokenId); } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { require(ownerOf(tokenId) == from); require(to != address(0)); _clearApproval(tokenId); _ownedTokensCount[from].decrement(); _ownedTokensCount[to].increment(); _tokenOwner[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Internal function to invoke `onERC721Received` on a target address * The call is not executed if the target address is not a contract * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) internal returns (bool) { if (!to.isContract()) { return true; } bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); return (retval == _ERC721_RECEIVED); } /** * @dev Private function to clear current approval of a given token ID * @param tokenId uint256 ID of the token to be transferred */ function _clearApproval(uint256 tokenId) private { if (_tokenApprovals[tokenId] != address(0)) { _tokenApprovals[tokenId] = address(0); } } } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Enumerable.sol pragma solidity ^0.5.2; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Enumerable is IERC721 { function totalSupply() public view returns (uint256); function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId); function tokenByIndex(uint256 index) public view returns (uint256); } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721Enumerable.sol pragma solidity ^0.5.2; /** * @title ERC-721 Non-Fungible Token with optional enumeration extension logic * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721Enumerable is ERC165, ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => uint256[]) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /* * 0x780e9d63 === * bytes4(keccak256('totalSupply()')) ^ * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ * bytes4(keccak256('tokenByIndex(uint256)')) */ /** * @dev Constructor function */ constructor () public { // register the supported interface to conform to ERC721Enumerable via ERC165 _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev Gets the token ID at a given index of the tokens list of the requested owner * @param owner address owning the tokens list to be accessed * @param index uint256 representing the index to be accessed of the requested tokens list * @return uint256 token ID at the given index of the tokens list owned by the requested address */ function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) { require(index < balanceOf(owner)); return _ownedTokens[owner][index]; } /** * @dev Gets the total amount of tokens stored by the contract * @return uint256 representing the total amount of tokens */ function totalSupply() public view returns (uint256) { return _allTokens.length; } /** * @dev Gets the token ID at a given index of all the tokens in this contract * Reverts if the index is greater or equal to the total number of tokens * @param index uint256 representing the index to be accessed of the tokens list * @return uint256 token ID at the given index of the tokens list */ function tokenByIndex(uint256 index) public view returns (uint256) { require(index < totalSupply()); return _allTokens[index]; } /** * @dev Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. * @param from current owner of the token * @param to address to receive the ownership of the given token ID * @param tokenId uint256 ID of the token to be transferred */ function _transferFrom(address from, address to, uint256 tokenId) internal { super._transferFrom(from, to, tokenId); _removeTokenFromOwnerEnumeration(from, tokenId); _addTokenToOwnerEnumeration(to, tokenId); } /** * @dev Internal function to mint a new token * Reverts if the given token ID already exists * @param to address the beneficiary that will own the minted token * @param tokenId uint256 ID of the token to be minted */ function _mint(address to, uint256 tokenId) internal { super._mint(to, tokenId); _addTokenToOwnerEnumeration(to, tokenId); _addTokenToAllTokensEnumeration(tokenId); } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); _removeTokenFromOwnerEnumeration(owner, tokenId); // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund _ownedTokensIndex[tokenId] = 0; _removeTokenFromAllTokensEnumeration(tokenId); } /** * @dev Gets the list of token IDs of the requested owner * @param owner address owning the tokens * @return uint256[] List of token IDs owned by the requested address */ function _tokensOfOwner(address owner) internal view returns (uint256[] storage) { return _ownedTokens[owner]; } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { _ownedTokensIndex[tokenId] = _ownedTokens[to].length; _ownedTokens[to].push(tokenId); } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the _ownedTokensIndex mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _ownedTokens[from].length.sub(1); uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array _ownedTokens[from].length--; // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by // lastTokenId, or just over the end of the array if the token was the last one). } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length.sub(1); uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array _allTokens.length--; _allTokensIndex[tokenId] = 0; } } // File: openzeppelin-solidity/contracts/token/ERC721/IERC721Metadata.sol pragma solidity ^0.5.2; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ contract IERC721Metadata is IERC721 { function name() external view returns (string memory); function symbol() external view returns (string memory); function tokenURI(uint256 tokenId) external view returns (string memory); } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721Metadata.sol pragma solidity ^0.5.2; contract ERC721Metadata is ERC165, ERC721, IERC721Metadata { // Token name string private _name; // Token symbol string private _symbol; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * 0x5b5e139f === * bytes4(keccak256('name()')) ^ * bytes4(keccak256('symbol()')) ^ * bytes4(keccak256('tokenURI(uint256)')) */ /** * @dev Constructor function */ constructor (string memory name, string memory symbol) public { _name = name; _symbol = symbol; // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721_METADATA); } /** * @dev Gets the token name * @return string representing the token name */ function name() external view returns (string memory) { return _name; } /** * @dev Gets the token symbol * @return string representing the token symbol */ function symbol() external view returns (string memory) { return _symbol; } /** * @dev Returns an URI for a given token ID * Throws if the token ID does not exist. May return an empty string. * @param tokenId uint256 ID of the token to query */ function tokenURI(uint256 tokenId) external view returns (string memory) { require(_exists(tokenId)); return _tokenURIs[tokenId]; } /** * @dev Internal function to set the token URI for a given token * Reverts if the token ID does not exist * @param tokenId uint256 ID of the token to set its URI * @param uri string URI to assign */ function _setTokenURI(uint256 tokenId, string memory uri) internal { require(_exists(tokenId)); _tokenURIs[tokenId] = uri; } /** * @dev Internal function to burn a specific token * Reverts if the token does not exist * Deprecated, use _burn(uint256) instead * @param owner owner of the token to burn * @param tokenId uint256 ID of the token being burned by the msg.sender */ function _burn(address owner, uint256 tokenId) internal { super._burn(owner, tokenId); // Clear metadata (if any) if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } } // File: openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol pragma solidity ^0.5.2; /** * @title Full ERC721 Token * This implementation includes all the required and some optional functionality of the ERC721 standard * Moreover, it includes approve all functionality using operator terminology * @dev see https://eips.ethereum.org/EIPS/eip-721 */ contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata { constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) { // solhint-disable-previous-line no-empty-blocks } } // File: contracts/child/ChildERC721.sol pragma solidity ^0.5.2; contract ChildERC721 is ChildToken, ERC721Full { event Deposit(address indexed token, address indexed from, uint256 tokenId); event Withdraw( address indexed token, address indexed from, uint256 tokenId ); event LogTransfer( address indexed token, address indexed from, address indexed to, uint256 tokenId ); constructor( address _owner, address _token, string memory name, string memory symbol ) public ERC721Full(name, symbol) { require(_token != address(0x0) && _owner != address(0x0)); parentOwner = _owner; token = _token; } function transferWithSig( bytes calldata sig, uint256 tokenId, bytes32 data, uint256 expiration, address to ) external returns (address) { require( expiration == 0 || block.number <= expiration, "Signature is expired" ); bytes32 dataHash = getTokenTransferOrderHash( msg.sender, tokenId, data, expiration ); require(disabledHashes[dataHash] == false, "Sig deactivated"); disabledHashes[dataHash] = true; // recover address and send tokens address from = ecrecovery(dataHash, sig); _transferFrom(from, to, tokenId); require( _checkOnERC721Received(from, to, tokenId, ""), "_checkOnERC721Received failed" ); return from; } function setParent(address _parent) public isParentOwner { require(_parent != address(0x0)); parent = _parent; } function approve(address to, uint256 tokenId) public { revert("Disabled feature"); } function getApproved(uint256 tokenId) public view returns (address operator) { revert("Disabled feature"); } function setApprovalForAll(address operator, bool _approved) public { revert("Disabled feature"); } function isApprovedForAll(address owner, address operator) public view returns (bool) { revert("Disabled feature"); } /** * @notice Deposit tokens * @param user address for deposit * @param tokenId tokenId to mint to user's account */ function deposit(address user, uint256 tokenId) public onlyOwner { require(user != address(0x0)); _mint(user, tokenId); emit Deposit(token, user, tokenId); } /** * @notice Withdraw tokens * @param tokenId tokenId of the token to be withdrawn */ function withdraw(uint256 tokenId) public payable { require(ownerOf(tokenId) == msg.sender); _burn(msg.sender, tokenId); emit Withdraw(token, msg.sender, tokenId); } /** * @dev Overriding the inherited method so that it emits LogTransfer */ function transferFrom(address from, address to, uint256 tokenId) public { if ( parent != address(0x0) && !IParentToken(parent).beforeTransfer(msg.sender, to, tokenId) ) { return; } _transferFrom(from, to, tokenId); } function _transferFrom(address from, address to, uint256 tokenId) internal { super._transferFrom(from, to, tokenId); emit LogTransfer(token, from, to, tokenId); } } // File: contracts/child/ChildChain.sol pragma solidity ^0.5.2; contract ChildChain is Ownable, StateSyncerVerifier, StateReceiver { // mapping for (root token => child token) mapping(address => address) public tokens; mapping(address => bool) public isERC721; mapping(uint256 => bool) public deposits; mapping(uint256 => bool) public withdraws; event NewToken( address indexed rootToken, address indexed token, uint8 _decimals ); event TokenDeposited( address indexed rootToken, address indexed childToken, address indexed user, uint256 amount, uint256 depositCount ); event TokenWithdrawn( address indexed rootToken, address indexed childToken, address indexed user, uint256 amount, uint256 withrawCount ); constructor() public { //Mapping matic Token tokens[0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0] = 0x0000000000000000000000000000000000001010; } function onStateReceive( uint256, /* id */ bytes calldata data ) external onlyStateSyncer { (address user, address rootToken, uint256 amountOrTokenId, uint256 depositId) = abi .decode(data, (address, address, uint256, uint256)); depositTokens(rootToken, user, amountOrTokenId, depositId); } function addToken( address _owner, address _rootToken, string memory _name, string memory _symbol, uint8 _decimals, bool _isERC721 ) public onlyOwner returns (address token) { // check if root token already exists require(tokens[_rootToken] == address(0x0), "Token already mapped"); // create new token contract if (_isERC721) { token = address( new ChildERC721(_owner, _rootToken, _name, _symbol) ); isERC721[_rootToken] = true; } else { token = address( new ChildERC20(_owner, _rootToken, _name, _symbol, _decimals) ); } // add mapping with root token tokens[_rootToken] = token; // broadcast new token's event emit NewToken(_rootToken, token, _decimals); } // for testnet updates remove for mainnet function mapToken(address rootToken, address token, bool isErc721) public onlyOwner { tokens[rootToken] = token; isERC721[rootToken] = isErc721; } function withdrawTokens( address rootToken, address user, uint256 amountOrTokenId, uint256 withdrawCount ) public onlyOwner { // check if withdrawal happens only once require(withdraws[withdrawCount] == false); // set withdrawal flag withdraws[withdrawCount] = true; // retrieve child tokens address childToken = tokens[rootToken]; // check if child token is mapped require(childToken != address(0x0), "child token is not mapped"); ChildToken obj; if (isERC721[rootToken]) { obj = ChildERC721(childToken); } else { obj = ChildERC20(childToken); } // withdraw tokens obj.withdraw(amountOrTokenId); // Emit TokenWithdrawn event emit TokenWithdrawn( rootToken, childToken, user, amountOrTokenId, withdrawCount ); } function depositTokens( address rootToken, address user, uint256 amountOrTokenId, uint256 depositId ) internal { // check if deposit happens only once require(deposits[depositId] == false); // set deposit flag deposits[depositId] = true; // retrieve child tokens address childToken = tokens[rootToken]; // check if child token is mapped require(childToken != address(0x0)); ChildToken obj; if (isERC721[rootToken]) { obj = ChildERC721(childToken); } else { obj = ChildERC20(childToken); } // deposit tokens obj.deposit(user, amountOrTokenId); // Emit TokenDeposited event emit TokenDeposited( rootToken, childToken, user, amountOrTokenId, depositId ); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":false,"inputs":[{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amountOrTokenId","type":"uint256"},{"internalType":"uint256","name":"withdrawCount","type":"uint256"}],"name":"withdrawTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onStateReceive","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdraws","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOnlyStateSyncerContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"deposits","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_rootToken","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"bool","name":"_isERC721","type":"bool"}],"name":"addToken","outputs":[{"internalType":"address","name":"token","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"changeStateSyncerAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"rootToken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"isErc721","type":"bool"}],"name":"mapToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokens","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stateSyncer","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rootToken","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint8","name":"_decimals","type":"uint8"}],"name":"NewToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rootToken","type":"address"},{"indexed":true,"internalType":"address","name":"childToken","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"depositCount","type":"uint256"}],"name":"TokenDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rootToken","type":"address"},{"indexed":true,"internalType":"address","name":"childToken","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withrawCount","type":"uint256"}],"name":"TokenWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousAddress","type":"address"},{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"StateSyncerAddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]
Contract Creation Code
608060405234801561001057600080fd5b50600080546001600160a01b03191633178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600180546001600160a01b03191661100117908190556040516001600160a01b0391909116906000907f98e6a46aa139a033b9c7f3ae4ad1c103ffdce3e7cf509326808ba8c4b5af11c0908290a3737d1afa7b718fb893db30a3abc0cfc608aacfebb060005260026020527fa6b538c9a0f90a58a2d51d8b41372745652182421068cf734937a5df014e586980546001600160a01b031916611010179055614f74806101076000396000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c8063b02c43d011620000a5578063e117694b116200006f578063e117694b1462000412578063e4860339146200044d578063f2fde38b1462000476578063f4ef4d69146200049f576200010c565b8063b02c43d01462000247578063bb9b9fa21462000267578063daa09e5414620003c0578063df55500714620003e9576200010c565b806355651f7111620000e757806355651f711462000203578063715018a6146200020d5780638da5cb5b14620002175780638f32d59b146200023d576200010c565b806307a06d37146200011157806326c53bea146200015257806355466c3714620001cf575b600080fd5b62000150600480360360808110156200012957600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135620004a9565b005b62000150600480360360408110156200016a57600080fd5b813591908101906040810160208201356401000000008111156200018d57600080fd5b820183602082011115620001a057600080fd5b80359060200191846001830284011164010000000083111715620001c357600080fd5b50909250905062000640565b620001ef60048036036020811015620001e757600080fd5b5035620006d9565b604080519115158252519081900360200190f35b620001ef620006ee565b62000150620006ff565b620002216200075d565b604080516001600160a01b039092168252519081900360200190f35b620001ef6200076c565b620001ef600480360360208110156200025f57600080fd5b50356200077d565b62000221600480360360c08110156200027f57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135640100000000811115620002b457600080fd5b820183602082011115620002c757600080fd5b80359060200191846001830284011164010000000083111715620002ea57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156200033e57600080fd5b8201836020820111156200035157600080fd5b803590602001918460018302840111640100000000831117156200037457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505060ff8335169350505060200135151562000792565b620001ef60048036036020811015620003d857600080fd5b50356001600160a01b031662000b1b565b62000150600480360360208110156200040157600080fd5b50356001600160a01b031662000b30565b62000150600480360360608110156200042a57600080fd5b506001600160a01b03813581169160208101359091169060400135151562000be7565b62000221600480360360208110156200046557600080fd5b50356001600160a01b031662000c46565b62000150600480360360208110156200048e57600080fd5b50356001600160a01b031662000c61565b6200022162000c83565b620004b36200076c565b620004bd57600080fd5b60008181526005602052604090205460ff1615620004da57600080fd5b6000818152600560209081526040808320805460ff191660011790556001600160a01b038088168452600290925290912054168062000560576040805162461bcd60e51b815260206004820152601960248201527f6368696c6420746f6b656e206973206e6f74206d617070656400000000000000604482015290519081900360640190fd5b6001600160a01b03851660009081526003602052604081205460ff16156200058a5750806200058d565b50805b806001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015620005d457600080fd5b505af1158015620005e9573d6000803e3d6000fd5b5050604080518781526020810187905281516001600160a01b03808b16955087811694508b16927f7ec90ada0dee6c6d3ea251a8236eb33077411c39b9c26fc24045ae009599def3928290030190a4505050505050565b6200064a620006ee565b620006875760405162461bcd60e51b815260040180806020018281038252603581526020018062004ed16035913960400191505060405180910390fd5b600080600080858560808110156200069e57600080fd5b506001600160a01b03813581169550602082013516935060408101359250606001359050620006d08385848462000c92565b50505050505050565b60056020526000908152604090205460ff1681565b6001546001600160a01b0316331490565b620007096200076c565b6200071357600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b60046020526000908152604090205460ff1681565b60006200079e6200076c565b620007a857600080fd5b6001600160a01b0386811660009081526002602052604090205416156200080d576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88185b1c9958591e481b585c1c195960621b604482015290519081900360640190fd5b8115620009795786868686604051620008269062000e56565b80856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015620008965781810151838201526020016200087c565b50505050905090810190601f168015620008c45780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620008f9578181015183820152602001620008df565b50505050905090810190601f168015620009275780820380516001836020036101000a031916815260200191505b509650505050505050604051809103906000f0801580156200094d573d6000803e3d6000fd5b506001600160a01b0387166000908152600360205260409020805460ff19166001179055905062000aac565b86868686866040516200098c9062000e64565b6001600160a01b038087168252851660208083019190915260ff8316608083015260a06040830181815286519184019190915285519091606084019160c085019188019080838360005b83811015620009f0578181015183820152602001620009d6565b50505050905090810190601f16801562000a1e5780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b8381101562000a5357818101518382015260200162000a39565b50505050905090810190601f16801562000a815780820380516001836020036101000a031916815260200191505b50975050505050505050604051809103906000f08015801562000aa8573d6000803e3d6000fd5b5090505b6001600160a01b0386811660008181526002602090815260409182902080546001600160a01b0319169486169485179055815160ff8816815291517f9894b680cecb28f00988b0d91ed301a55bba06a8befd7fdb0b1ff36d0d3950ff9281900390910190a39695505050505050565b60036020526000908152604090205460ff1681565b62000b3a6200076c565b62000b4457600080fd5b6001600160a01b03811662000b8b5760405162461bcd60e51b815260040180806020018281038252603a81526020018062004f06603a913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f98e6a46aa139a033b9c7f3ae4ad1c103ffdce3e7cf509326808ba8c4b5af11c090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000bf16200076c565b62000bfb57600080fd5b6001600160a01b03928316600090815260026020908152604080832080546001600160a01b031916959096169490941790945560039093529120805460ff1916911515919091179055565b6002602052600090815260409020546001600160a01b031681565b62000c6b6200076c565b62000c7557600080fd5b62000c808162000de7565b50565b6001546001600160a01b031681565b60008181526004602052604090205460ff161562000caf57600080fd5b6000818152600460209081526040808320805460ff191660011790556001600160a01b038088168452600290925290912054168062000ced57600080fd5b6001600160a01b03851660009081526003602052604081205460ff161562000d1757508062000d1a565b50805b806001600160a01b03166347e7ef2486866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801562000d7b57600080fd5b505af115801562000d90573d6000803e3d6000fd5b5050604080518781526020810187905281516001600160a01b03808b16955087811694508b16927fec3afb067bce33c5a294470ec5b29e6759301cd3928550490c6d48816cdc2f5d928290030190a4505050505050565b6001600160a01b03811662000dfb57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6123b08062000e7383390190565b611cae80620032238339019056fe60806040523480156200001157600080fd5b50604051620023b0380380620023b0833981810160405260808110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b506040819052600080546001600160a01b031916331780825587955086945085935084926001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36040518060800160405280605281526020016200235e605291396040516020018082805190602001908083835b60208310620002485780518252601f19909201916020918201910162000227565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092208285018552600d83527f4d61746963204e6574776f726b00000000000000000000000000000000000000928201929092528351808501855260018082527f3100000000000000000000000000000000000000000000000000000000000000918301919091528451808301939093527fd26430275d0d30693378daeb558f6ed30c3a48ba5d665f52c16608e1c41b5cd7838601527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060840152608960808401523060a0808501919091528551808503909101815260c09093019094528151910120909155506200039391507f01ffc9a7000000000000000000000000000000000000000000000000000000009050620004be565b620003c77f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03620004be16565b620003fb7f780e9d63000000000000000000000000000000000000000000000000000000006001600160e01b03620004be16565b81516200041090600f9060208501906200052b565b508051620004269060109060208401906200052b565b506200045b7f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03620004be16565b505050506001600160a01b038316158015906200048057506001600160a01b03841615155b6200048a57600080fd5b5050600480546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055620005d0565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620004ee57600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600660205260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200056e57805160ff19168380011785556200059e565b828001600101855582156200059e579182015b828111156200059e57825182559160200191906001019062000581565b50620005ac929150620005b0565b5090565b620005cd91905b80821115620005ac5760008155600101620005b7565b90565b611d7e80620005e06000396000f3fe6080604052600436106102045760003560e01c8063715018a611610118578063b789543c116100a0578063e306f7791161006f578063e306f77914610908578063e614d0d61461091d578063e985e9c514610932578063f2fde38b1461096d578063fc0c546a146109a057610204565b8063b789543c146107b1578063b88d4fde146107f6578063c87b56dd146108c9578063cc79f97b146108f357610204565b80639025e64c116100e75780639025e64c1461070d57806395d89b4114610722578063a22cb46514610737578063abceeba214610772578063acd06cb31461078757610204565b8063715018a61461061457806377d32e94146106295780638da5cb5b146106e35780638f32d59b146106f857610204565b80632e1a7d4d1161019b5780634f6ccce71161016a5780634f6ccce71461056357806360f96a8f1461058d5780636352211e146105a25780637019d41a146105cc57806370a08231146105e157610204565b80632e1a7d4d146104915780632f745c59146104ae57806342842e0e146104e757806347e7ef241461052a57610204565b80631499c592116101d75780631499c5921461035c57806318160ddd1461038f57806319d27d9c146103b657806323b872dd1461044e57610204565b806301ffc9a71461020957806306fdde0314610251578063081812fc146102db578063095ea7b314610321575b600080fd5b34801561021557600080fd5b5061023d6004803603602081101561022c57600080fd5b50356001600160e01b0319166109b5565b604080519115158252519081900360200190f35b34801561025d57600080fd5b506102666109d4565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102a0578181015183820152602001610288565b50505050905090810190601f1680156102cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102e757600080fd5b50610305600480360360208110156102fe57600080fd5b5035610a6b565b604080516001600160a01b039092168252519081900360200190f35b34801561032d57600080fd5b5061035a6004803603604081101561034457600080fd5b506001600160a01b038135169060200135610aad565b005b34801561036857600080fd5b5061035a6004803603602081101561037f57600080fd5b50356001600160a01b0316610aed565b34801561039b57600080fd5b506103a4610b39565b60408051918252519081900360200190f35b3480156103c257600080fd5b50610305600480360360a08110156103d957600080fd5b8101906020810181356401000000008111156103f457600080fd5b82018360208201111561040657600080fd5b8035906020019184600183028401116401000000008311171561042857600080fd5b9193509150803590602081013590604081013590606001356001600160a01b0316610b3f565b34801561045a57600080fd5b5061035a6004803603606081101561047157600080fd5b506001600160a01b03813581169160208101359091169060400135610cda565b61035a600480360360208110156104a757600080fd5b5035610d93565b3480156104ba57600080fd5b506103a4600480360360408110156104d157600080fd5b506001600160a01b038135169060200135610e00565b3480156104f357600080fd5b5061035a6004803603606081101561050a57600080fd5b506001600160a01b03813581169160208101359091169060400135610e4e565b34801561053657600080fd5b5061035a6004803603604081101561054d57600080fd5b506001600160a01b038135169060200135610e69565b34801561056f57600080fd5b506103a46004803603602081101561058657600080fd5b5035610ee0565b34801561059957600080fd5b50610305610f14565b3480156105ae57600080fd5b50610305600480360360208110156105c557600080fd5b5035610f23565b3480156105d857600080fd5b50610305610f45565b3480156105ed57600080fd5b506103a46004803603602081101561060457600080fd5b50356001600160a01b0316610f54565b34801561062057600080fd5b5061035a610f8a565b34801561063557600080fd5b506103056004803603604081101561064c57600080fd5b8135919081019060408101602082013564010000000081111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111640100000000831117156106a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610fe5945050505050565b3480156106ef57600080fd5b50610305611108565b34801561070457600080fd5b5061023d611117565b34801561071957600080fd5b50610266611128565b34801561072e57600080fd5b50610266611145565b34801561074357600080fd5b5061035a6004803603604081101561075a57600080fd5b506001600160a01b0381351690602001351515610aad565b34801561077e57600080fd5b506103a46111a6565b34801561079357600080fd5b5061023d600480360360208110156107aa57600080fd5b503561122f565b3480156107bd57600080fd5b506103a4600480360360808110156107d457600080fd5b506001600160a01b038135169060208101359060408101359060600135611244565b34801561080257600080fd5b5061035a6004803603608081101561081957600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561085457600080fd5b82018360208201111561086657600080fd5b8035906020019184600183028401116401000000008311171561088857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611263945050505050565b3480156108d557600080fd5b50610266600480360360208110156108ec57600080fd5b5035611289565b3480156108ff57600080fd5b506103a461133c565b34801561091457600080fd5b506103a4611341565b34801561092957600080fd5b506103a4611347565b34801561093e57600080fd5b5061023d6004803603604081101561095557600080fd5b506001600160a01b0381358116916020013516610a6b565b34801561097957600080fd5b5061035a6004803603602081101561099057600080fd5b50356001600160a01b0316611391565b3480156109ac57600080fd5b506103056113ae565b6001600160e01b03191660009081526006602052604090205460ff1690565b600f8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a605780601f10610a3557610100808354040283529160200191610a60565b820191906000526020600020905b815481529060010190602001808311610a4357829003601f168201915b505050505090505b90565b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b6044820152905160009181900360640190fd5b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b604482015290519081900360640190fd5b6004546001600160a01b03163314610b0457600080fd5b6001600160a01b038116610b1757600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600d5490565b6000821580610b4e5750824311155b610b96576040805162461bcd60e51b815260206004820152601460248201527314da59db985d1d5c99481a5cc8195e1c1a5c995960621b604482015290519081900360640190fd5b6000610ba433878787611244565b60008181526005602052604090205490915060ff1615610bfd576040805162461bcd60e51b815260206004820152600f60248201526e14da59c819195858dd1a5d985d1959608a1b604482015290519081900360640190fd5b6000818152600560209081526040808320805460ff191660011790558051601f8b01839004830281018301909152898152610c55918491908c908c9081908401838280828437600092019190915250610fe592505050565b9050610c628185896113bd565b610c7d81858960405180602001604052806000815250611416565b610cce576040805162461bcd60e51b815260206004820152601d60248201527f5f636865636b4f6e4552433732315265636569766564206661696c6564000000604482015290519081900360640190fd5b98975050505050505050565b6003546001600160a01b031615801590610d79575060035460408051631ffb811f60e01b81523360048201526001600160a01b0385811660248301526044820185905291519190921691631ffb811f9160648083019260209291908290030181600087803b158015610d4b57600080fd5b505af1158015610d5f573d6000803e3d6000fd5b505050506040513d6020811015610d7557600080fd5b5051155b15610d8357610d8e565b610d8e8383836113bd565b505050565b33610d9d82610f23565b6001600160a01b031614610db057600080fd5b610dba338261154a565b60025460408051838152905133926001600160a01b0316917f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb919081900360200190a350565b6000610e0b83610f54565b8210610e1657600080fd5b6001600160a01b0383166000908152600b60205260409020805483908110610e3a57fe5b906000526020600020015490505b92915050565b610d8e83838360405180602001604052806000815250611263565b610e71611117565b610e7a57600080fd5b6001600160a01b038216610e8d57600080fd5b610e978282611596565b6002546040805183815290516001600160a01b038086169316917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62919081900360200190a35050565b6000610eea610b39565b8210610ef557600080fd5b600d8281548110610f0257fe5b90600052602060002001549050919050565b6003546001600160a01b031681565b6000818152600760205260408120546001600160a01b031680610e4857600080fd5b6004546001600160a01b031681565b60006001600160a01b038216610f6957600080fd5b6001600160a01b0382166000908152600960205260409020610e48906115b3565b610f92611117565b610f9b57600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60008060008084516041146110005760009350505050610e48565b50505060208201516040830151604184015160ff16601b81101561102257601b015b8060ff16601b1415801561103a57508060ff16601c14155b1561104b5760009350505050610e48565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa1580156110a2573d6000803e3d6000fd5b5050604051601f1901519450506001600160a01b0384166110ff576040805162461bcd60e51b815260206004820152601260248201527122b93937b91034b71032b1b932b1b7bb32b960711b604482015290519081900360640190fd5b50505092915050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b604051806040016040528060018152602001608960f81b81525081565b60108054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a605780601f10610a3557610100808354040283529160200191610a60565b6040518060800160405280605b8152602001611cef605b91396040516020018082805190602001908083835b602083106111f15780518252601f1990920191602091820191016111d2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020526000908152604090205460ff1681565b600061125a611255868686866115b7565b611670565b95945050505050565b61126e848484610cda565b61127a84848484611416565b61128357600080fd5b50505050565b606061129482611695565b61129d57600080fd5b60008281526011602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156113305780601f1061130557610100808354040283529160200191611330565b820191906000526020600020905b81548152906001019060200180831161131357829003601f168201915b50505050509050919050565b608981565b60015481565b604051806080016040528060528152602001611c9d60529139604051602001808280519060200190808383602083106111f15780518252601f1990920191602091820191016111d2565b611399611117565b6113a257600080fd5b6113ab816116b2565b50565b6002546001600160a01b031681565b6113c8838383611720565b6002546040805183815290516001600160a01b0380861693878216939116917f6eabe333476233fd382224f233210cb808a7bc4c4de64f9d76628bf63c677b1a9181900360200190a4505050565b600061142a846001600160a01b031661173f565b61143657506001611542565b604051630a85bd0160e11b815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156114b0578181015183820152602001611498565b50505050905090810190601f1680156114dd5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156114ff57600080fd5b505af1158015611513573d6000803e3d6000fd5b505050506040513d602081101561152957600080fd5b50516001600160e01b031916630a85bd0160e11b149150505b949350505050565b6115548282611745565b600081815260116020526040902054600260001961010060018416150201909116041561159257600081815260116020526040812061159291611c1a565b5050565b6115a08282611771565b6115aa8282611812565b61159281611850565b5490565b6000806040518060800160405280605b8152602001611cef605b91396040516020018082805190602001908083835b602083106116055780518252601f1990920191602091820191016115e6565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922082526001600160a01b039b909b169a81019a909a5250880196909652505050606084019190915260808301525060a0902090565b60015460405161190160f01b8152600281019190915260228101919091526042902090565b6000908152600760205260409020546001600160a01b0316151590565b6001600160a01b0381166116c557600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b61172b838383611894565b6117358382611974565b610d8e8282611812565b3b151590565b61174f8282611a69565b6117598282611974565b6000818152600c602052604081205561159281611b0e565b6001600160a01b03821661178457600080fd5b61178d81611695565b1561179757600080fd5b600081815260076020908152604080832080546001600160a01b0319166001600160a01b0387169081179091558352600990915290206117d690611baa565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b039091166000908152600b602081815260408084208054868652600c84529185208290559282526001810183559183529091200155565b600d80546000838152600e60205260408120829055600182018355919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50155565b826001600160a01b03166118a782610f23565b6001600160a01b0316146118ba57600080fd5b6001600160a01b0382166118cd57600080fd5b6118d681611bb3565b6001600160a01b03831660009081526009602052604090206118f790611bee565b6001600160a01b038216600090815260096020526040902061191890611baa565b60008181526007602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b0382166000908152600b602052604081205461199e90600163ffffffff611c0516565b6000838152600c6020526040902054909150808214611a39576001600160a01b0384166000908152600b602052604081208054849081106119db57fe5b9060005260206000200154905080600b6000876001600160a01b03166001600160a01b031681526020019081526020016000208381548110611a1957fe5b6000918252602080832090910192909255918252600c9052604090208190555b6001600160a01b0384166000908152600b60205260409020805490611a62906000198301611c5e565b5050505050565b816001600160a01b0316611a7c82610f23565b6001600160a01b031614611a8f57600080fd5b611a9881611bb3565b6001600160a01b0382166000908152600960205260409020611ab990611bee565b60008181526007602052604080822080546001600160a01b0319169055518291906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600d54600090611b2590600163ffffffff611c0516565b6000838152600e6020526040812054600d8054939450909284908110611b4757fe5b9060005260206000200154905080600d8381548110611b6257fe5b6000918252602080832090910192909255828152600e90915260409020829055600d805490611b95906000198301611c5e565b505050600091825250600e6020526040812055565b80546001019055565b6000818152600860205260409020546001600160a01b0316156113ab57600090815260086020526040902080546001600160a01b0319169055565b8054611c0190600163ffffffff611c0516565b9055565b600082821115611c1457600080fd5b50900390565b50805460018160011615610100020316600290046000825580601f10611c4057506113ab565b601f0160209004906000526020600020908101906113ab9190611c7e565b815481835581811115610d8e57600083815260209020610d8e9181019083015b610a6891905b80821115611c985760008155600101611c84565b509056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820cfd2a416aed881196d49d5fc9a692c56f295e98633796916f3f52b051691bf3164736f6c634300050b0032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e74726163742960806040523480156200001157600080fd5b5060405162001cae38038062001cae833981810160405260a08110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b50604081905260209190910151600080546001600160a01b0319163317808255919450869350859285926001600160a01b031691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360405180608001604052806052815260200162001c5c605291396040516020018082805190602001908083835b602083106200024b5780518252601f1990920191602091820191016200022a565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092208285018552600d83527f4d61746963204e6574776f726b00000000000000000000000000000000000000928201929092528351808501855260018082527f3100000000000000000000000000000000000000000000000000000000000000918301919091528451808301939093527fd26430275d0d30693378daeb558f6ed30c3a48ba5d665f52c16608e1c41b5cd7838601527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060840152608960808401523060a0808501919091528551808503909101815260c0909301909452815191810191909120909255508551620003819350600992509086019062000412565b5081516200039790600a90602085019062000412565b50600b805460ff191660ff9290921691909117905550506001600160a01b03841615801590620003cf57506001600160a01b03851615155b620003d957600080fd5b5050600480546001600160a01b039485166001600160a01b031991821617909155600280549390941692169190911790915550620004b7565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200045557805160ff191683800117855562000485565b8280016001018555821562000485579182015b828111156200048557825182559160200191906001019062000468565b506200049392915062000497565b5090565b620004b491905b808211156200049357600081556001016200049e565b90565b61179580620004c76000396000f3fe6080604052600436106101cd5760003560e01c80638da5cb5b116100f7578063acd06cb311610095578063e306f77911610064578063e306f7791461077c578063e614d0d614610791578063f2fde38b146107a6578063fc0c546a146107d9576101cd565b8063acd06cb3146106bd578063b789543c146106e7578063cc79f97b1461072c578063dd62ed3e14610741576101cd565b806395d89b41116100d157806395d89b4114610621578063a457c2d714610636578063a9059cbb1461066f578063abceeba2146106a8576101cd565b80638da5cb5b146105e25780638f32d59b146105f75780639025e64c1461060c576101cd565b8063313ce5671161016f5780637019d41a1161013e5780637019d41a146104cb57806370a08231146104e0578063715018a61461051357806377d32e9414610528576101cd565b8063313ce56714610419578063395093511461044457806347e7ef241461047d57806360f96a8f146104b6576101cd565b806318160ddd116101ab57806318160ddd146102de57806319d27d9c1461030557806323b872dd146103b95780632e1a7d4d146103fc576101cd565b806306fdde03146101d2578063095ea7b31461025c5780631499c592146102a9575b600080fd5b3480156101de57600080fd5b506101e76107ee565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610221578181015183820152602001610209565b50505050905090810190601f16801561024e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561026857600080fd5b506102956004803603604081101561027f57600080fd5b506001600160a01b038135169060200135610884565b604080519115158252519081900360200190f35b3480156102b557600080fd5b506102dc600480360360208110156102cc57600080fd5b50356001600160a01b03166108c6565b005b3480156102ea57600080fd5b506102f3610912565b60408051918252519081900360200190f35b34801561031157600080fd5b5061039d600480360360a081101561032857600080fd5b81019060208101813564010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b9193509150803590602081013590604081013590606001356001600160a01b0316610918565b604080516001600160a01b039092168252519081900360200190f35b3480156103c557600080fd5b50610295600480360360608110156103dc57600080fd5b506001600160a01b03813581169160208101359091169060400135610884565b6102dc6004803603602081101561041257600080fd5b5035610a53565b34801561042557600080fd5b5061042e610ae2565b6040805160ff9092168252519081900360200190f35b34801561045057600080fd5b506102956004803603604081101561046757600080fd5b506001600160a01b038135169060200135610aeb565b34801561048957600080fd5b506102dc600480360360408110156104a057600080fd5b506001600160a01b038135169060200135610b36565b3480156104c257600080fd5b5061039d610bbb565b3480156104d757600080fd5b5061039d610bca565b3480156104ec57600080fd5b506102f36004803603602081101561050357600080fd5b50356001600160a01b0316610bd9565b34801561051f57600080fd5b506102dc610bf4565b34801561053457600080fd5b5061039d6004803603604081101561054b57600080fd5b8135919081019060408101602082013564010000000081111561056d57600080fd5b82018360208201111561057f57600080fd5b803590602001918460018302840111640100000000831117156105a157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610c4f945050505050565b3480156105ee57600080fd5b5061039d610d72565b34801561060357600080fd5b50610295610d81565b34801561061857600080fd5b506101e7610d92565b34801561062d57600080fd5b506101e7610daf565b34801561064257600080fd5b506102956004803603604081101561065957600080fd5b506001600160a01b038135169060200135610e10565b34801561067b57600080fd5b506102956004803603604081101561069257600080fd5b506001600160a01b038135169060200135610e4c565b3480156106b457600080fd5b506102f3610f0d565b3480156106c957600080fd5b50610295600480360360208110156106e057600080fd5b5035610f96565b3480156106f357600080fd5b506102f36004803603608081101561070a57600080fd5b506001600160a01b038135169060208101359060408101359060600135610fab565b34801561073857600080fd5b506102f3610fca565b34801561074d57600080fd5b506102f36004803603604081101561076457600080fd5b506001600160a01b0381358116916020013516610884565b34801561078857600080fd5b506102f3610fcf565b34801561079d57600080fd5b506102f3610fd5565b3480156107b257600080fd5b506102dc600480360360208110156107c957600080fd5b50356001600160a01b031661101f565b3480156107e557600080fd5b5061039d61103c565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561087a5780601f1061084f5761010080835404028352916020019161087a565b820191906000526020600020905b81548152906001019060200180831161085d57829003601f168201915b5050505050905090565b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b6044820152905160009181900360640190fd5b6004546001600160a01b031633146108dd57600080fd5b6001600160a01b0381166108f057600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60085490565b600080851161092657600080fd5b8215806109335750824311155b61097b576040805162461bcd60e51b815260206004820152601460248201527314da59db985d1d5c99481a5cc8195e1c1a5c995960621b604482015290519081900360640190fd5b600061098933878787610fab565b60008181526005602052604090205490915060ff16156109e2576040805162461bcd60e51b815260206004820152600f60248201526e14da59c819195858dd1a5d985d1959608a1b604482015290519081900360640190fd5b600081815260056020908152604091829020805460ff191660011790558151601f8a01829004820281018201909252888252610a3a9183918b908b9081908401838280828437600092019190915250610c4f92505050565b9150610a4782848861104b565b50509695505050505050565b336000610a5f82610bd9565b9050600083118015610a715750828110155b610a7a57600080fd5b610a848284611298565b6002546001600160a01b0380841691167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610ac087610bd9565b60408051938452602084019290925282820152519081900360600190a3505050565b600b5460ff1690565b3360008181526007602090815260408083206001600160a01b03871684529091528120549091610b2c918590610b27908663ffffffff61134116565b611353565b5060015b92915050565b610b3e610d81565b610b4757600080fd5b600081118015610b5f57506001600160a01b03821615155b610b6857600080fd5b6000610b7383610bd9565b9050610b7f83836113db565b6002546001600160a01b0380851691167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68484610ac088610bd9565b6003546001600160a01b031681565b6004546001600160a01b031681565b6001600160a01b031660009081526006602052604090205490565b610bfc610d81565b610c0557600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000806000808451604114610c6a5760009350505050610b30565b50505060208201516040830151604184015160ff16601b811015610c8c57601b015b8060ff16601b14158015610ca457508060ff16601c14155b15610cb55760009350505050610b30565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015610d0c573d6000803e3d6000fd5b5050604051601f1901519450506001600160a01b038416610d69576040805162461bcd60e51b815260206004820152601260248201527122b93937b91034b71032b1b932b1b7bb32b960711b604482015290519081900360640190fd5b50505092915050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b604051806040016040528060018152602001608960f81b81525081565b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561087a5780601f1061084f5761010080835404028352916020019161087a565b3360008181526007602090815260408083206001600160a01b03871684529091528120549091610b2c918590610b27908663ffffffff61148516565b6003546000906001600160a01b031615801590610eee575060035460408051631ffb811f60e01b81523360048201526001600160a01b0386811660248301526044820186905291519190921691631ffb811f9160648083019260209291908290030181600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b505050506040513d6020811015610eea57600080fd5b5051155b15610efb57506000610b30565b610f0633848461104b565b9392505050565b6040518060800160405280605b8152602001611706605b91396040516020018082805190602001908083835b60208310610f585780518252601f199092019160209182019101610f39565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020526000908152604090205460ff1681565b6000610fc1610fbc8686868661149a565b611553565b95945050505050565b608981565b60015481565b6040518060800160405280605281526020016116b46052913960405160200180828051906020019080838360208310610f585780518252601f199092019160209182019101610f39565b611027610d81565b61103057600080fd5b61103981611578565b50565b6002546001600160a01b031681565b604080516370a0823160e01b81526001600160a01b03851660048201529051600091829130916370a08231916024808301926020929190829003018186803b15801561109657600080fd5b505afa1580156110aa573d6000803e3d6000fd5b505050506040513d60208110156110c057600080fd5b5051604080516370a0823160e01b81526001600160a01b0387166004820152905191925060009130916370a08231916024808301926020929190829003018186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b505190506111478686866115e6565b600254604080516370a0823160e01b81526001600160a01b03898116600483018190529251818a1694909116917fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c49189918891889130916370a0823191602480820192602092909190829003018186803b1580156111c457600080fd5b505afa1580156111d8573d6000803e3d6000fd5b505050506040513d60208110156111ee57600080fd5b5051604080516370a0823160e01b81526001600160a01b038f166004820152905130916370a08231916024808301926020929190829003018186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d602081101561126057600080fd5b50516040805195865260208601949094528484019290925260608401526080830152519081900360a00190a450600195945050505050565b6001600160a01b0382166112ab57600080fd5b6008546112be908263ffffffff61148516565b6008556001600160a01b0382166000908152600660205260409020546112ea908263ffffffff61148516565b6001600160a01b0383166000818152600660209081526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b600082820183811015610f0657600080fd5b6001600160a01b03821661136657600080fd5b6001600160a01b03831661137957600080fd5b6001600160a01b03808416600081815260076020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0382166113ee57600080fd5b600854611401908263ffffffff61134116565b6008556001600160a01b03821660009081526006602052604090205461142d908263ffffffff61134116565b6001600160a01b03831660008181526006602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60008282111561149457600080fd5b50900390565b6000806040518060800160405280605b8152602001611706605b91396040516020018082805190602001908083835b602083106114e85780518252601f1990920191602091820191016114c9565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922082526001600160a01b039b909b169a81019a909a5250880196909652505050606084019190915260808301525060a0902090565b60015460405161190160f01b8152600281019190915260228101919091526042902090565b6001600160a01b03811661158b57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382166115f957600080fd5b6001600160a01b038316600090815260066020526040902054611622908263ffffffff61148516565b6001600160a01b038085166000908152600660205260408082209390935590841681522054611657908263ffffffff61134116565b6001600160a01b0380841660008181526006602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a350505056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820cdee303f60cbc312cac2e0024791c9e0621b667b98c763fc412ba12ca0ea58d564736f6c634300050b0032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e74726163742953746174652073796e6365723a2063616c6c6572206973206e6f74207468652073746174652073796e63657220636f6e747261637453746174652073796e6365723a206e65772073746174652073796e636572206164647265737320697320746865207a65726f2061646472657373a265627a7a723158201ca5629a98a6b0838352447a0329baa2d73e7ea2aea1807648349084a1fd2e6364736f6c634300050b0032
Deployed Bytecode
0x60806040523480156200001157600080fd5b50600436106200010c5760003560e01c8063b02c43d011620000a5578063e117694b116200006f578063e117694b1462000412578063e4860339146200044d578063f2fde38b1462000476578063f4ef4d69146200049f576200010c565b8063b02c43d01462000247578063bb9b9fa21462000267578063daa09e5414620003c0578063df55500714620003e9576200010c565b806355651f7111620000e757806355651f711462000203578063715018a6146200020d5780638da5cb5b14620002175780638f32d59b146200023d576200010c565b806307a06d37146200011157806326c53bea146200015257806355466c3714620001cf575b600080fd5b62000150600480360360808110156200012957600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135620004a9565b005b62000150600480360360408110156200016a57600080fd5b813591908101906040810160208201356401000000008111156200018d57600080fd5b820183602082011115620001a057600080fd5b80359060200191846001830284011164010000000083111715620001c357600080fd5b50909250905062000640565b620001ef60048036036020811015620001e757600080fd5b5035620006d9565b604080519115158252519081900360200190f35b620001ef620006ee565b62000150620006ff565b620002216200075d565b604080516001600160a01b039092168252519081900360200190f35b620001ef6200076c565b620001ef600480360360208110156200025f57600080fd5b50356200077d565b62000221600480360360c08110156200027f57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135640100000000811115620002b457600080fd5b820183602082011115620002c757600080fd5b80359060200191846001830284011164010000000083111715620002ea57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156200033e57600080fd5b8201836020820111156200035157600080fd5b803590602001918460018302840111640100000000831117156200037457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505060ff8335169350505060200135151562000792565b620001ef60048036036020811015620003d857600080fd5b50356001600160a01b031662000b1b565b62000150600480360360208110156200040157600080fd5b50356001600160a01b031662000b30565b62000150600480360360608110156200042a57600080fd5b506001600160a01b03813581169160208101359091169060400135151562000be7565b62000221600480360360208110156200046557600080fd5b50356001600160a01b031662000c46565b62000150600480360360208110156200048e57600080fd5b50356001600160a01b031662000c61565b6200022162000c83565b620004b36200076c565b620004bd57600080fd5b60008181526005602052604090205460ff1615620004da57600080fd5b6000818152600560209081526040808320805460ff191660011790556001600160a01b038088168452600290925290912054168062000560576040805162461bcd60e51b815260206004820152601960248201527f6368696c6420746f6b656e206973206e6f74206d617070656400000000000000604482015290519081900360640190fd5b6001600160a01b03851660009081526003602052604081205460ff16156200058a5750806200058d565b50805b806001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015620005d457600080fd5b505af1158015620005e9573d6000803e3d6000fd5b5050604080518781526020810187905281516001600160a01b03808b16955087811694508b16927f7ec90ada0dee6c6d3ea251a8236eb33077411c39b9c26fc24045ae009599def3928290030190a4505050505050565b6200064a620006ee565b620006875760405162461bcd60e51b815260040180806020018281038252603581526020018062004ed16035913960400191505060405180910390fd5b600080600080858560808110156200069e57600080fd5b506001600160a01b03813581169550602082013516935060408101359250606001359050620006d08385848462000c92565b50505050505050565b60056020526000908152604090205460ff1681565b6001546001600160a01b0316331490565b620007096200076c565b6200071357600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b60046020526000908152604090205460ff1681565b60006200079e6200076c565b620007a857600080fd5b6001600160a01b0386811660009081526002602052604090205416156200080d576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88185b1c9958591e481b585c1c195960621b604482015290519081900360640190fd5b8115620009795786868686604051620008269062000e56565b80856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015620008965781810151838201526020016200087c565b50505050905090810190601f168015620008c45780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620008f9578181015183820152602001620008df565b50505050905090810190601f168015620009275780820380516001836020036101000a031916815260200191505b509650505050505050604051809103906000f0801580156200094d573d6000803e3d6000fd5b506001600160a01b0387166000908152600360205260409020805460ff19166001179055905062000aac565b86868686866040516200098c9062000e64565b6001600160a01b038087168252851660208083019190915260ff8316608083015260a06040830181815286519184019190915285519091606084019160c085019188019080838360005b83811015620009f0578181015183820152602001620009d6565b50505050905090810190601f16801562000a1e5780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b8381101562000a5357818101518382015260200162000a39565b50505050905090810190601f16801562000a815780820380516001836020036101000a031916815260200191505b50975050505050505050604051809103906000f08015801562000aa8573d6000803e3d6000fd5b5090505b6001600160a01b0386811660008181526002602090815260409182902080546001600160a01b0319169486169485179055815160ff8816815291517f9894b680cecb28f00988b0d91ed301a55bba06a8befd7fdb0b1ff36d0d3950ff9281900390910190a39695505050505050565b60036020526000908152604090205460ff1681565b62000b3a6200076c565b62000b4457600080fd5b6001600160a01b03811662000b8b5760405162461bcd60e51b815260040180806020018281038252603a81526020018062004f06603a913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f98e6a46aa139a033b9c7f3ae4ad1c103ffdce3e7cf509326808ba8c4b5af11c090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000bf16200076c565b62000bfb57600080fd5b6001600160a01b03928316600090815260026020908152604080832080546001600160a01b031916959096169490941790945560039093529120805460ff1916911515919091179055565b6002602052600090815260409020546001600160a01b031681565b62000c6b6200076c565b62000c7557600080fd5b62000c808162000de7565b50565b6001546001600160a01b031681565b60008181526004602052604090205460ff161562000caf57600080fd5b6000818152600460209081526040808320805460ff191660011790556001600160a01b038088168452600290925290912054168062000ced57600080fd5b6001600160a01b03851660009081526003602052604081205460ff161562000d1757508062000d1a565b50805b806001600160a01b03166347e7ef2486866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801562000d7b57600080fd5b505af115801562000d90573d6000803e3d6000fd5b5050604080518781526020810187905281516001600160a01b03808b16955087811694508b16927fec3afb067bce33c5a294470ec5b29e6759301cd3928550490c6d48816cdc2f5d928290030190a4505050505050565b6001600160a01b03811662000dfb57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6123b08062000e7383390190565b611cae80620032238339019056fe60806040523480156200001157600080fd5b50604051620023b0380380620023b0833981810160405260808110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b506040819052600080546001600160a01b031916331780825587955086945085935084926001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36040518060800160405280605281526020016200235e605291396040516020018082805190602001908083835b60208310620002485780518252601f19909201916020918201910162000227565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092208285018552600d83527f4d61746963204e6574776f726b00000000000000000000000000000000000000928201929092528351808501855260018082527f3100000000000000000000000000000000000000000000000000000000000000918301919091528451808301939093527fd26430275d0d30693378daeb558f6ed30c3a48ba5d665f52c16608e1c41b5cd7838601527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060840152608960808401523060a0808501919091528551808503909101815260c09093019094528151910120909155506200039391507f01ffc9a7000000000000000000000000000000000000000000000000000000009050620004be565b620003c77f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03620004be16565b620003fb7f780e9d63000000000000000000000000000000000000000000000000000000006001600160e01b03620004be16565b81516200041090600f9060208501906200052b565b508051620004269060109060208401906200052b565b506200045b7f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03620004be16565b505050506001600160a01b038316158015906200048057506001600160a01b03841615155b6200048a57600080fd5b5050600480546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055620005d0565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620004ee57600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600660205260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200056e57805160ff19168380011785556200059e565b828001600101855582156200059e579182015b828111156200059e57825182559160200191906001019062000581565b50620005ac929150620005b0565b5090565b620005cd91905b80821115620005ac5760008155600101620005b7565b90565b611d7e80620005e06000396000f3fe6080604052600436106102045760003560e01c8063715018a611610118578063b789543c116100a0578063e306f7791161006f578063e306f77914610908578063e614d0d61461091d578063e985e9c514610932578063f2fde38b1461096d578063fc0c546a146109a057610204565b8063b789543c146107b1578063b88d4fde146107f6578063c87b56dd146108c9578063cc79f97b146108f357610204565b80639025e64c116100e75780639025e64c1461070d57806395d89b4114610722578063a22cb46514610737578063abceeba214610772578063acd06cb31461078757610204565b8063715018a61461061457806377d32e94146106295780638da5cb5b146106e35780638f32d59b146106f857610204565b80632e1a7d4d1161019b5780634f6ccce71161016a5780634f6ccce71461056357806360f96a8f1461058d5780636352211e146105a25780637019d41a146105cc57806370a08231146105e157610204565b80632e1a7d4d146104915780632f745c59146104ae57806342842e0e146104e757806347e7ef241461052a57610204565b80631499c592116101d75780631499c5921461035c57806318160ddd1461038f57806319d27d9c146103b657806323b872dd1461044e57610204565b806301ffc9a71461020957806306fdde0314610251578063081812fc146102db578063095ea7b314610321575b600080fd5b34801561021557600080fd5b5061023d6004803603602081101561022c57600080fd5b50356001600160e01b0319166109b5565b604080519115158252519081900360200190f35b34801561025d57600080fd5b506102666109d4565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102a0578181015183820152602001610288565b50505050905090810190601f1680156102cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102e757600080fd5b50610305600480360360208110156102fe57600080fd5b5035610a6b565b604080516001600160a01b039092168252519081900360200190f35b34801561032d57600080fd5b5061035a6004803603604081101561034457600080fd5b506001600160a01b038135169060200135610aad565b005b34801561036857600080fd5b5061035a6004803603602081101561037f57600080fd5b50356001600160a01b0316610aed565b34801561039b57600080fd5b506103a4610b39565b60408051918252519081900360200190f35b3480156103c257600080fd5b50610305600480360360a08110156103d957600080fd5b8101906020810181356401000000008111156103f457600080fd5b82018360208201111561040657600080fd5b8035906020019184600183028401116401000000008311171561042857600080fd5b9193509150803590602081013590604081013590606001356001600160a01b0316610b3f565b34801561045a57600080fd5b5061035a6004803603606081101561047157600080fd5b506001600160a01b03813581169160208101359091169060400135610cda565b61035a600480360360208110156104a757600080fd5b5035610d93565b3480156104ba57600080fd5b506103a4600480360360408110156104d157600080fd5b506001600160a01b038135169060200135610e00565b3480156104f357600080fd5b5061035a6004803603606081101561050a57600080fd5b506001600160a01b03813581169160208101359091169060400135610e4e565b34801561053657600080fd5b5061035a6004803603604081101561054d57600080fd5b506001600160a01b038135169060200135610e69565b34801561056f57600080fd5b506103a46004803603602081101561058657600080fd5b5035610ee0565b34801561059957600080fd5b50610305610f14565b3480156105ae57600080fd5b50610305600480360360208110156105c557600080fd5b5035610f23565b3480156105d857600080fd5b50610305610f45565b3480156105ed57600080fd5b506103a46004803603602081101561060457600080fd5b50356001600160a01b0316610f54565b34801561062057600080fd5b5061035a610f8a565b34801561063557600080fd5b506103056004803603604081101561064c57600080fd5b8135919081019060408101602082013564010000000081111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111640100000000831117156106a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610fe5945050505050565b3480156106ef57600080fd5b50610305611108565b34801561070457600080fd5b5061023d611117565b34801561071957600080fd5b50610266611128565b34801561072e57600080fd5b50610266611145565b34801561074357600080fd5b5061035a6004803603604081101561075a57600080fd5b506001600160a01b0381351690602001351515610aad565b34801561077e57600080fd5b506103a46111a6565b34801561079357600080fd5b5061023d600480360360208110156107aa57600080fd5b503561122f565b3480156107bd57600080fd5b506103a4600480360360808110156107d457600080fd5b506001600160a01b038135169060208101359060408101359060600135611244565b34801561080257600080fd5b5061035a6004803603608081101561081957600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561085457600080fd5b82018360208201111561086657600080fd5b8035906020019184600183028401116401000000008311171561088857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611263945050505050565b3480156108d557600080fd5b50610266600480360360208110156108ec57600080fd5b5035611289565b3480156108ff57600080fd5b506103a461133c565b34801561091457600080fd5b506103a4611341565b34801561092957600080fd5b506103a4611347565b34801561093e57600080fd5b5061023d6004803603604081101561095557600080fd5b506001600160a01b0381358116916020013516610a6b565b34801561097957600080fd5b5061035a6004803603602081101561099057600080fd5b50356001600160a01b0316611391565b3480156109ac57600080fd5b506103056113ae565b6001600160e01b03191660009081526006602052604090205460ff1690565b600f8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a605780601f10610a3557610100808354040283529160200191610a60565b820191906000526020600020905b815481529060010190602001808311610a4357829003601f168201915b505050505090505b90565b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b6044820152905160009181900360640190fd5b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b604482015290519081900360640190fd5b6004546001600160a01b03163314610b0457600080fd5b6001600160a01b038116610b1757600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600d5490565b6000821580610b4e5750824311155b610b96576040805162461bcd60e51b815260206004820152601460248201527314da59db985d1d5c99481a5cc8195e1c1a5c995960621b604482015290519081900360640190fd5b6000610ba433878787611244565b60008181526005602052604090205490915060ff1615610bfd576040805162461bcd60e51b815260206004820152600f60248201526e14da59c819195858dd1a5d985d1959608a1b604482015290519081900360640190fd5b6000818152600560209081526040808320805460ff191660011790558051601f8b01839004830281018301909152898152610c55918491908c908c9081908401838280828437600092019190915250610fe592505050565b9050610c628185896113bd565b610c7d81858960405180602001604052806000815250611416565b610cce576040805162461bcd60e51b815260206004820152601d60248201527f5f636865636b4f6e4552433732315265636569766564206661696c6564000000604482015290519081900360640190fd5b98975050505050505050565b6003546001600160a01b031615801590610d79575060035460408051631ffb811f60e01b81523360048201526001600160a01b0385811660248301526044820185905291519190921691631ffb811f9160648083019260209291908290030181600087803b158015610d4b57600080fd5b505af1158015610d5f573d6000803e3d6000fd5b505050506040513d6020811015610d7557600080fd5b5051155b15610d8357610d8e565b610d8e8383836113bd565b505050565b33610d9d82610f23565b6001600160a01b031614610db057600080fd5b610dba338261154a565b60025460408051838152905133926001600160a01b0316917f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb919081900360200190a350565b6000610e0b83610f54565b8210610e1657600080fd5b6001600160a01b0383166000908152600b60205260409020805483908110610e3a57fe5b906000526020600020015490505b92915050565b610d8e83838360405180602001604052806000815250611263565b610e71611117565b610e7a57600080fd5b6001600160a01b038216610e8d57600080fd5b610e978282611596565b6002546040805183815290516001600160a01b038086169316917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62919081900360200190a35050565b6000610eea610b39565b8210610ef557600080fd5b600d8281548110610f0257fe5b90600052602060002001549050919050565b6003546001600160a01b031681565b6000818152600760205260408120546001600160a01b031680610e4857600080fd5b6004546001600160a01b031681565b60006001600160a01b038216610f6957600080fd5b6001600160a01b0382166000908152600960205260409020610e48906115b3565b610f92611117565b610f9b57600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60008060008084516041146110005760009350505050610e48565b50505060208201516040830151604184015160ff16601b81101561102257601b015b8060ff16601b1415801561103a57508060ff16601c14155b1561104b5760009350505050610e48565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa1580156110a2573d6000803e3d6000fd5b5050604051601f1901519450506001600160a01b0384166110ff576040805162461bcd60e51b815260206004820152601260248201527122b93937b91034b71032b1b932b1b7bb32b960711b604482015290519081900360640190fd5b50505092915050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b604051806040016040528060018152602001608960f81b81525081565b60108054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a605780601f10610a3557610100808354040283529160200191610a60565b6040518060800160405280605b8152602001611cef605b91396040516020018082805190602001908083835b602083106111f15780518252601f1990920191602091820191016111d2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020526000908152604090205460ff1681565b600061125a611255868686866115b7565b611670565b95945050505050565b61126e848484610cda565b61127a84848484611416565b61128357600080fd5b50505050565b606061129482611695565b61129d57600080fd5b60008281526011602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156113305780601f1061130557610100808354040283529160200191611330565b820191906000526020600020905b81548152906001019060200180831161131357829003601f168201915b50505050509050919050565b608981565b60015481565b604051806080016040528060528152602001611c9d60529139604051602001808280519060200190808383602083106111f15780518252601f1990920191602091820191016111d2565b611399611117565b6113a257600080fd5b6113ab816116b2565b50565b6002546001600160a01b031681565b6113c8838383611720565b6002546040805183815290516001600160a01b0380861693878216939116917f6eabe333476233fd382224f233210cb808a7bc4c4de64f9d76628bf63c677b1a9181900360200190a4505050565b600061142a846001600160a01b031661173f565b61143657506001611542565b604051630a85bd0160e11b815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156114b0578181015183820152602001611498565b50505050905090810190601f1680156114dd5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156114ff57600080fd5b505af1158015611513573d6000803e3d6000fd5b505050506040513d602081101561152957600080fd5b50516001600160e01b031916630a85bd0160e11b149150505b949350505050565b6115548282611745565b600081815260116020526040902054600260001961010060018416150201909116041561159257600081815260116020526040812061159291611c1a565b5050565b6115a08282611771565b6115aa8282611812565b61159281611850565b5490565b6000806040518060800160405280605b8152602001611cef605b91396040516020018082805190602001908083835b602083106116055780518252601f1990920191602091820191016115e6565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922082526001600160a01b039b909b169a81019a909a5250880196909652505050606084019190915260808301525060a0902090565b60015460405161190160f01b8152600281019190915260228101919091526042902090565b6000908152600760205260409020546001600160a01b0316151590565b6001600160a01b0381166116c557600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b61172b838383611894565b6117358382611974565b610d8e8282611812565b3b151590565b61174f8282611a69565b6117598282611974565b6000818152600c602052604081205561159281611b0e565b6001600160a01b03821661178457600080fd5b61178d81611695565b1561179757600080fd5b600081815260076020908152604080832080546001600160a01b0319166001600160a01b0387169081179091558352600990915290206117d690611baa565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b039091166000908152600b602081815260408084208054868652600c84529185208290559282526001810183559183529091200155565b600d80546000838152600e60205260408120829055600182018355919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50155565b826001600160a01b03166118a782610f23565b6001600160a01b0316146118ba57600080fd5b6001600160a01b0382166118cd57600080fd5b6118d681611bb3565b6001600160a01b03831660009081526009602052604090206118f790611bee565b6001600160a01b038216600090815260096020526040902061191890611baa565b60008181526007602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b0382166000908152600b602052604081205461199e90600163ffffffff611c0516565b6000838152600c6020526040902054909150808214611a39576001600160a01b0384166000908152600b602052604081208054849081106119db57fe5b9060005260206000200154905080600b6000876001600160a01b03166001600160a01b031681526020019081526020016000208381548110611a1957fe5b6000918252602080832090910192909255918252600c9052604090208190555b6001600160a01b0384166000908152600b60205260409020805490611a62906000198301611c5e565b5050505050565b816001600160a01b0316611a7c82610f23565b6001600160a01b031614611a8f57600080fd5b611a9881611bb3565b6001600160a01b0382166000908152600960205260409020611ab990611bee565b60008181526007602052604080822080546001600160a01b0319169055518291906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600d54600090611b2590600163ffffffff611c0516565b6000838152600e6020526040812054600d8054939450909284908110611b4757fe5b9060005260206000200154905080600d8381548110611b6257fe5b6000918252602080832090910192909255828152600e90915260409020829055600d805490611b95906000198301611c5e565b505050600091825250600e6020526040812055565b80546001019055565b6000818152600860205260409020546001600160a01b0316156113ab57600090815260086020526040902080546001600160a01b0319169055565b8054611c0190600163ffffffff611c0516565b9055565b600082821115611c1457600080fd5b50900390565b50805460018160011615610100020316600290046000825580601f10611c4057506113ab565b601f0160209004906000526020600020908101906113ab9190611c7e565b815481835581811115610d8e57600083815260209020610d8e9181019083015b610a6891905b80821115611c985760008155600101611c84565b509056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820cfd2a416aed881196d49d5fc9a692c56f295e98633796916f3f52b051691bf3164736f6c634300050b0032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e74726163742960806040523480156200001157600080fd5b5060405162001cae38038062001cae833981810160405260a08110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b50604081905260209190910151600080546001600160a01b0319163317808255919450869350859285926001600160a01b031691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360405180608001604052806052815260200162001c5c605291396040516020018082805190602001908083835b602083106200024b5780518252601f1990920191602091820191016200022a565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092208285018552600d83527f4d61746963204e6574776f726b00000000000000000000000000000000000000928201929092528351808501855260018082527f3100000000000000000000000000000000000000000000000000000000000000918301919091528451808301939093527fd26430275d0d30693378daeb558f6ed30c3a48ba5d665f52c16608e1c41b5cd7838601527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060840152608960808401523060a0808501919091528551808503909101815260c0909301909452815191810191909120909255508551620003819350600992509086019062000412565b5081516200039790600a90602085019062000412565b50600b805460ff191660ff9290921691909117905550506001600160a01b03841615801590620003cf57506001600160a01b03851615155b620003d957600080fd5b5050600480546001600160a01b039485166001600160a01b031991821617909155600280549390941692169190911790915550620004b7565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200045557805160ff191683800117855562000485565b8280016001018555821562000485579182015b828111156200048557825182559160200191906001019062000468565b506200049392915062000497565b5090565b620004b491905b808211156200049357600081556001016200049e565b90565b61179580620004c76000396000f3fe6080604052600436106101cd5760003560e01c80638da5cb5b116100f7578063acd06cb311610095578063e306f77911610064578063e306f7791461077c578063e614d0d614610791578063f2fde38b146107a6578063fc0c546a146107d9576101cd565b8063acd06cb3146106bd578063b789543c146106e7578063cc79f97b1461072c578063dd62ed3e14610741576101cd565b806395d89b41116100d157806395d89b4114610621578063a457c2d714610636578063a9059cbb1461066f578063abceeba2146106a8576101cd565b80638da5cb5b146105e25780638f32d59b146105f75780639025e64c1461060c576101cd565b8063313ce5671161016f5780637019d41a1161013e5780637019d41a146104cb57806370a08231146104e0578063715018a61461051357806377d32e9414610528576101cd565b8063313ce56714610419578063395093511461044457806347e7ef241461047d57806360f96a8f146104b6576101cd565b806318160ddd116101ab57806318160ddd146102de57806319d27d9c1461030557806323b872dd146103b95780632e1a7d4d146103fc576101cd565b806306fdde03146101d2578063095ea7b31461025c5780631499c592146102a9575b600080fd5b3480156101de57600080fd5b506101e76107ee565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610221578181015183820152602001610209565b50505050905090810190601f16801561024e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561026857600080fd5b506102956004803603604081101561027f57600080fd5b506001600160a01b038135169060200135610884565b604080519115158252519081900360200190f35b3480156102b557600080fd5b506102dc600480360360208110156102cc57600080fd5b50356001600160a01b03166108c6565b005b3480156102ea57600080fd5b506102f3610912565b60408051918252519081900360200190f35b34801561031157600080fd5b5061039d600480360360a081101561032857600080fd5b81019060208101813564010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b9193509150803590602081013590604081013590606001356001600160a01b0316610918565b604080516001600160a01b039092168252519081900360200190f35b3480156103c557600080fd5b50610295600480360360608110156103dc57600080fd5b506001600160a01b03813581169160208101359091169060400135610884565b6102dc6004803603602081101561041257600080fd5b5035610a53565b34801561042557600080fd5b5061042e610ae2565b6040805160ff9092168252519081900360200190f35b34801561045057600080fd5b506102956004803603604081101561046757600080fd5b506001600160a01b038135169060200135610aeb565b34801561048957600080fd5b506102dc600480360360408110156104a057600080fd5b506001600160a01b038135169060200135610b36565b3480156104c257600080fd5b5061039d610bbb565b3480156104d757600080fd5b5061039d610bca565b3480156104ec57600080fd5b506102f36004803603602081101561050357600080fd5b50356001600160a01b0316610bd9565b34801561051f57600080fd5b506102dc610bf4565b34801561053457600080fd5b5061039d6004803603604081101561054b57600080fd5b8135919081019060408101602082013564010000000081111561056d57600080fd5b82018360208201111561057f57600080fd5b803590602001918460018302840111640100000000831117156105a157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610c4f945050505050565b3480156105ee57600080fd5b5061039d610d72565b34801561060357600080fd5b50610295610d81565b34801561061857600080fd5b506101e7610d92565b34801561062d57600080fd5b506101e7610daf565b34801561064257600080fd5b506102956004803603604081101561065957600080fd5b506001600160a01b038135169060200135610e10565b34801561067b57600080fd5b506102956004803603604081101561069257600080fd5b506001600160a01b038135169060200135610e4c565b3480156106b457600080fd5b506102f3610f0d565b3480156106c957600080fd5b50610295600480360360208110156106e057600080fd5b5035610f96565b3480156106f357600080fd5b506102f36004803603608081101561070a57600080fd5b506001600160a01b038135169060208101359060408101359060600135610fab565b34801561073857600080fd5b506102f3610fca565b34801561074d57600080fd5b506102f36004803603604081101561076457600080fd5b506001600160a01b0381358116916020013516610884565b34801561078857600080fd5b506102f3610fcf565b34801561079d57600080fd5b506102f3610fd5565b3480156107b257600080fd5b506102dc600480360360208110156107c957600080fd5b50356001600160a01b031661101f565b3480156107e557600080fd5b5061039d61103c565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561087a5780601f1061084f5761010080835404028352916020019161087a565b820191906000526020600020905b81548152906001019060200180831161085d57829003601f168201915b5050505050905090565b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b6044820152905160009181900360640190fd5b6004546001600160a01b031633146108dd57600080fd5b6001600160a01b0381166108f057600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60085490565b600080851161092657600080fd5b8215806109335750824311155b61097b576040805162461bcd60e51b815260206004820152601460248201527314da59db985d1d5c99481a5cc8195e1c1a5c995960621b604482015290519081900360640190fd5b600061098933878787610fab565b60008181526005602052604090205490915060ff16156109e2576040805162461bcd60e51b815260206004820152600f60248201526e14da59c819195858dd1a5d985d1959608a1b604482015290519081900360640190fd5b600081815260056020908152604091829020805460ff191660011790558151601f8a01829004820281018201909252888252610a3a9183918b908b9081908401838280828437600092019190915250610c4f92505050565b9150610a4782848861104b565b50509695505050505050565b336000610a5f82610bd9565b9050600083118015610a715750828110155b610a7a57600080fd5b610a848284611298565b6002546001600160a01b0380841691167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610ac087610bd9565b60408051938452602084019290925282820152519081900360600190a3505050565b600b5460ff1690565b3360008181526007602090815260408083206001600160a01b03871684529091528120549091610b2c918590610b27908663ffffffff61134116565b611353565b5060015b92915050565b610b3e610d81565b610b4757600080fd5b600081118015610b5f57506001600160a01b03821615155b610b6857600080fd5b6000610b7383610bd9565b9050610b7f83836113db565b6002546001600160a01b0380851691167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68484610ac088610bd9565b6003546001600160a01b031681565b6004546001600160a01b031681565b6001600160a01b031660009081526006602052604090205490565b610bfc610d81565b610c0557600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000806000808451604114610c6a5760009350505050610b30565b50505060208201516040830151604184015160ff16601b811015610c8c57601b015b8060ff16601b14158015610ca457508060ff16601c14155b15610cb55760009350505050610b30565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015610d0c573d6000803e3d6000fd5b5050604051601f1901519450506001600160a01b038416610d69576040805162461bcd60e51b815260206004820152601260248201527122b93937b91034b71032b1b932b1b7bb32b960711b604482015290519081900360640190fd5b50505092915050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b604051806040016040528060018152602001608960f81b81525081565b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561087a5780601f1061084f5761010080835404028352916020019161087a565b3360008181526007602090815260408083206001600160a01b03871684529091528120549091610b2c918590610b27908663ffffffff61148516565b6003546000906001600160a01b031615801590610eee575060035460408051631ffb811f60e01b81523360048201526001600160a01b0386811660248301526044820186905291519190921691631ffb811f9160648083019260209291908290030181600087803b158015610ec057600080fd5b505af1158015610ed4573d6000803e3d6000fd5b505050506040513d6020811015610eea57600080fd5b5051155b15610efb57506000610b30565b610f0633848461104b565b9392505050565b6040518060800160405280605b8152602001611706605b91396040516020018082805190602001908083835b60208310610f585780518252601f199092019160209182019101610f39565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020526000908152604090205460ff1681565b6000610fc1610fbc8686868661149a565b611553565b95945050505050565b608981565b60015481565b6040518060800160405280605281526020016116b46052913960405160200180828051906020019080838360208310610f585780518252601f199092019160209182019101610f39565b611027610d81565b61103057600080fd5b61103981611578565b50565b6002546001600160a01b031681565b604080516370a0823160e01b81526001600160a01b03851660048201529051600091829130916370a08231916024808301926020929190829003018186803b15801561109657600080fd5b505afa1580156110aa573d6000803e3d6000fd5b505050506040513d60208110156110c057600080fd5b5051604080516370a0823160e01b81526001600160a01b0387166004820152905191925060009130916370a08231916024808301926020929190829003018186803b15801561110e57600080fd5b505afa158015611122573d6000803e3d6000fd5b505050506040513d602081101561113857600080fd5b505190506111478686866115e6565b600254604080516370a0823160e01b81526001600160a01b03898116600483018190529251818a1694909116917fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c49189918891889130916370a0823191602480820192602092909190829003018186803b1580156111c457600080fd5b505afa1580156111d8573d6000803e3d6000fd5b505050506040513d60208110156111ee57600080fd5b5051604080516370a0823160e01b81526001600160a01b038f166004820152905130916370a08231916024808301926020929190829003018186803b15801561123657600080fd5b505afa15801561124a573d6000803e3d6000fd5b505050506040513d602081101561126057600080fd5b50516040805195865260208601949094528484019290925260608401526080830152519081900360a00190a450600195945050505050565b6001600160a01b0382166112ab57600080fd5b6008546112be908263ffffffff61148516565b6008556001600160a01b0382166000908152600660205260409020546112ea908263ffffffff61148516565b6001600160a01b0383166000818152600660209081526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b600082820183811015610f0657600080fd5b6001600160a01b03821661136657600080fd5b6001600160a01b03831661137957600080fd5b6001600160a01b03808416600081815260076020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0382166113ee57600080fd5b600854611401908263ffffffff61134116565b6008556001600160a01b03821660009081526006602052604090205461142d908263ffffffff61134116565b6001600160a01b03831660008181526006602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60008282111561149457600080fd5b50900390565b6000806040518060800160405280605b8152602001611706605b91396040516020018082805190602001908083835b602083106114e85780518252601f1990920191602091820191016114c9565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922082526001600160a01b039b909b169a81019a909a5250880196909652505050606084019190915260808301525060a0902090565b60015460405161190160f01b8152600281019190915260228101919091526042902090565b6001600160a01b03811661158b57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382166115f957600080fd5b6001600160a01b038316600090815260066020526040902054611622908263ffffffff61148516565b6001600160a01b038085166000908152600660205260408082209390935590841681522054611657908263ffffffff61134116565b6001600160a01b0380841660008181526006602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a350505056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820cdee303f60cbc312cac2e0024791c9e0621b667b98c763fc412ba12ca0ea58d564736f6c634300050b0032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e74726163742953746174652073796e6365723a2063616c6c6572206973206e6f74207468652073746174652073796e63657220636f6e747261637453746174652073796e6365723a206e65772073746174652073796e636572206164647265737320697320746865207a65726f2061646472657373a265627a7a723158201ca5629a98a6b0838352447a0329baa2d73e7ea2aea1807648349084a1fd2e6364736f6c634300050b0032
Deployed Bytecode Sourcemap
62140:4517:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62140:4517:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64674:1013;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;64674:1013:0;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;63144:349;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;63144:349:0;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;63144:349:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;63144:349:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;63144:349:0;;-1:-1:-1;63144:349:0;-1:-1:-1;63144:349:0;:::i;62404:41::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62404:41:0;;:::i;:::-;;;;;;;;;;;;;;;;;;3315:115;;;:::i;1539:140::-;;;:::i;749:79::-;;;:::i;:::-;;;;-1:-1:-1;;;;;749:79:0;;;;;;;;;;;;;;1084:92;;;:::i;62357:40::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62357:40:0;;:::i;63501:918::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;63501:918:0;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;63501:918:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;63501:918:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;63501:918:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63501:918:0;;;;;;;;-1:-1:-1;63501:918:0;;-1:-1:-1;;21:11;5:28;;2:2;;;46:1;43;36:12;2:2;63501:918:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;63501:918:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;63501:918:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;63501:918:0;;-1:-1:-1;;63501:918:0;;;;;-1:-1:-1;;;63501:918:0;;;;;;:::i;62310:40::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62310:40:0;-1:-1:-1;;;;;62310:40:0;;:::i;3474:323::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3474:323:0;-1:-1:-1;;;;;3474:323:0;;:::i;64474:192::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;64474:192:0;;;;;;;;;;;;;;;;;;;:::i;62262:41::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62262:41:0;-1:-1:-1;;;;;62262:41:0;;:::i;1856:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;1856:109:0;-1:-1:-1;;;;;1856:109:0;;:::i;2441:26::-;;;:::i;64674:1013::-;961:9;:7;:9::i;:::-;953:18;;;;;;64908:24;;;;:9;:24;;;;;;;;:33;64900:42;;;;;;64987:24;;;;:9;:24;;;;;;;;:31;;-1:-1:-1;;64987:31:0;65014:4;64987:31;;;-1:-1:-1;;;;;65086:17:0;;;;;:6;:17;;;;;;;;65167:26;65159:64;;;;;-1:-1:-1;;;65159:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65267:19:0;;65236:14;65267:19;;;:8;:19;;;;;;;;65263:142;;;-1:-1:-1;65321:10:0;65263:142;;;-1:-1:-1;65382:10:0;65263:142;65443:3;-1:-1:-1;;;;;65443:12:0;;65456:15;65443:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65443:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;65528:151:0;;;;;;;;;;;;;;-1:-1:-1;;;;;65528:151:0;;;;-1:-1:-1;65528:151:0;;;;-1:-1:-1;65528:151:0;;;;;;;;;;;982:1;;64674:1013;;;;:::o;63144:349::-;2745:27;:25;:27::i;:::-;2723:130;;;;-1:-1:-1;;;2723:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63269:12;63283:17;63302:23;63327:17;63373:4;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;63348:68:0;;;;;-1:-1:-1;63348:68:0;;;;;;-1:-1:-1;63348:68:0;;;;;-1:-1:-1;63348:68:0;;;;-1:-1:-1;63427:58:0;63348:68;;;;63427:13;:58::i;:::-;2864:1;;;;63144:349;;;:::o;62404:41::-;;;;;;;;;;;;;;;:::o;3315:115::-;3411:11;;-1:-1:-1;;;;;3411:11:0;3397:10;:25;;3315:115::o;1539:140::-;961:9;:7;:9::i;:::-;953:18;;;;;;1638:1;1622:6;;1601:40;;-1:-1:-1;;;;;1622:6:0;;;;1601:40;;1638:1;;1601:40;1669:1;1652:19;;-1:-1:-1;;;;;;1652:19:0;;;1539:140::o;749:79::-;787:7;814:6;-1:-1:-1;;;;;814:6:0;749:79;:::o;1084:92::-;1124:4;1162:6;-1:-1:-1;;;;;1162:6:0;1148:10;:20;;1084:92::o;62357:40::-;;;;;;;;;;;;;;;:::o;63501:918::-;63719:13;961:9;:7;:9::i;:::-;953:18;;;;;;-1:-1:-1;;;;;63800:18:0;;;63830:3;63800:18;;;:6;:18;;;;;;;:34;63792:67;;;;;-1:-1:-1;;;63792:67:0;;;;;;;;;;;;-1:-1:-1;;;63792:67:0;;;;;;;;;;;;;;;63914:9;63910:327;;;63990:6;63998:10;64010:5;64017:7;63974:51;;;;;:::i;:::-;;;-1:-1:-1;;;;;63974:51:0;-1:-1:-1;;;;;63974:51:0;;;;;;-1:-1:-1;;;;;63974:51:0;-1:-1:-1;;;;;63974:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;63974:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63974:51:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;63974:51:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;;;;;64055:20:0;;;;;;:8;:20;;;;;:27;;-1:-1:-1;;64055:27:0;64078:4;64055:27;;;63940:100;-1:-1:-1;63910:327:0;;;64164:6;64172:10;64184:5;64191:7;64200:9;64149:61;;;;;:::i;:::-;-1:-1:-1;;;;;64149:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;64149:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64149:61:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;64149:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64149:61:0;64115:110;;63910:327;-1:-1:-1;;;;;64289:18:0;;;;;;;:6;:18;;;;;;;;;:26;;-1:-1:-1;;;;;;64289:26:0;;;;;;;;;64373:38;;;;;;;;;;;;;;;;;;;63501:918;;;;;;;;:::o;62310:40::-;;;;;;;;;;;;;;;:::o;3474:323::-;961:9;:7;:9::i;:::-;953:18;;;;;;-1:-1:-1;;;;;3578:24:0;;3556:132;;;;-1:-1:-1;;;3556:132:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3730:11;;3704:50;;-1:-1:-1;;;;;3704:50:0;;;;3730:11;;3704:50;;3730:11;;3704:50;3765:11;:24;;-1:-1:-1;;;;;;3765:24:0;-1:-1:-1;;;;;3765:24:0;;;;;;;;;;3474:323::o;64474:192::-;961:9;:7;:9::i;:::-;953:18;;;;;;-1:-1:-1;;;;;64592:17:0;;;;;;;:6;:17;;;;;;;;:25;;-1:-1:-1;;;;;;64592:25:0;;;;;;;;;;;;64628:8;:19;;;;;:30;;-1:-1:-1;;64628:30:0;;;;;;;;;;64474:192::o;62262:41::-;;;;;;;;;;;;-1:-1:-1;;;;;62262:41:0;;:::o;1856:109::-;961:9;:7;:9::i;:::-;953:18;;;;;;1929:28;1948:8;1929:18;:28::i;:::-;1856:109;:::o;2441:26::-;;;-1:-1:-1;;;;;2441:26:0;;:::o;65695:957::-;65913:19;;;;:8;:19;;;;;;;;:28;65905:37;;;;;;65984:19;;;;:8;:19;;;;;;;;:26;;-1:-1:-1;;65984:26:0;66006:4;65984:26;;;-1:-1:-1;;;;;66078:17:0;;;;;:6;:17;;;;;;;;66159:26;66151:35;;;;;;-1:-1:-1;;;;;66230:19:0;;66199:14;66230:19;;;:8;:19;;;;;;;;66226:142;;;-1:-1:-1;66284:10:0;66226:142;;;-1:-1:-1;66345:10:0;66226:142;66407:3;-1:-1:-1;;;;;66407:11:0;;66419:4;66425:15;66407:34;;;;;;;;;;;;;-1:-1:-1;;;;;66407:34:0;-1:-1:-1;;;;;66407:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66407:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;66497:147:0;;;;;;;;;;;;;;-1:-1:-1;;;;;66497:147:0;;;;-1:-1:-1;66497:147:0;;;;-1:-1:-1;66497:147:0;;;;;;;;;;;65695:957;;;;;;:::o;2115:187::-;-1:-1:-1;;;;;2189:22:0;;2181:31;;;;;;2249:6;;;2228:38;;-1:-1:-1;;;;;2228:38:0;;;;2249:6;;;2228:38;;;2277:6;:17;;-1:-1:-1;;;;;;2277:17:0;-1:-1:-1;;;;;2277:17:0;;;;;;;;;;2115:187::o;62140:4517::-;;;;;;;;:::o;:::-;;;;;;;;:::o
Swarm Source
bzzr://1ca5629a98a6b0838352447a0329baa2d73e7ea2aea1807648349084a1fd2e63
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.