Contract 0x1edd419627ef40736ec4f8ceffde671a30803c5e 3

Contract Overview

Balance:
0 MATIC
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xf1a27d0b7f5d707ab0623bf9a146b8beb74b94b4b4262013f8566323c36c81b5Withdraw Tokens232777232021-12-29 14:45:32140 days 4 hrs ago0xe7f9b05b3c68c4393cddd1a25ebfe48ca3f40edc IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.00098112 40
0x7de19561efcec02b9ffe1d460d04074fca0898144496edddea28c0ee46a28feaAdd Token190952072021-09-18 18:31:18242 days 53 mins ago0xda1d30af457b8386083c66c9df7a86269bebfdf8 IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000525362
0x11cb5f3b28e4ed48e3a8cee5d8b56cc2c5d26489745b74a9ef14d21f3cfd2269Map Token131593082021-04-26 16:20:57387 days 3 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0013711830
0x4fb3207bff48c003cebe0717a115bbc8d2e9deef9d7b0f247ec77a176d11a87dMap Token117020562021-03-18 11:17:45426 days 8 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0011429525
0x3132f9a4ecbd7dd5bd8b65a9ed4161ec0391ef27d9e4c6abd9af8a2ee8018c0dMap Token116349032021-03-16 15:54:59428 days 3 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000457181
0x62b9288e5ecbd23a0e7addd5317af45d3d66358ca50b4f0c890415071ade741fMap Token96456212021-01-22 10:28:51481 days 8 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0028674329662.72
0x4e7af2e43d7186980895b6d071f9f79bbf9b7afcba39fb8ecc09ea6397926942Map Token96455062021-01-22 10:24:57481 days 9 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0028674329662.72
0x8cb3dfa406ea1a46a8ec1484a267407e5c1502ff13f1047f396131b3ef455e61Map Token84645352020-12-24 12:45:30510 days 6 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.000064931
0x66ff2c9f95ff020925ebe7c913ccab24ff3eaf2c17b70210e52c46534ad5a65eMap Token84641092020-12-24 12:30:50510 days 6 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000457181
0x3414c64c73c6caebe27d12cb60a495b0c12b96636c223817550ba1cc3fa4f7c5Map Token83396712020-12-21 13:13:18513 days 6 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.000064931
0x4c66fc8ea4506835ed4846f1b57feb76a4454dfe6c027a0a58ae477d587761dfMap Token83396352020-12-21 13:12:02513 days 6 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000457181
0x01a08231dbd66a48aaea084794c539e2816877f88658a0e377a125476ac246b4Map Token81325242020-12-16 14:32:36518 days 4 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000457181
0xe9cc3e6cd7cdc5423cdc9973d1ec935d94d968f0b2efe4d503cfcfeae1e271e3Map Token81324332020-12-16 14:29:30518 days 4 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000649181
0x773f6cebe0f2b92f2c5e00cc4f8ad2aebce625333bc768166370be61c1034d8cMap Token56228352020-10-17 7:10:37578 days 12 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.000064931
0x538c25b977c56058990a9f92ceaf1bbcfcede774cad32131850346b649eaf8a6Map Token54093722020-10-12 4:52:49583 days 14 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000457181
0x785d456fbd571556949413cd5284aeace25a6f95a718b21247c7856c6b855bd9Map Token54093452020-10-12 4:51:55583 days 14 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000457181
0xf239ece3d42c30f75922e0ec4b0099078cffbd029c013c153b9af0bbdd5a5ed9Map Token53010812020-10-09 14:50:19586 days 4 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.000228595
0x516ba02b4f6073be950761f9301c94b019f8ca8e34be08465b97ec1e0e319e08Map Token48745842020-09-29 10:29:19596 days 8 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.000228595
0x57f75af913dcce9deb0f15b75b8b99fcdd08aadbdbe1b91803f091c61f31a513Map Token46205662020-09-23 8:57:27602 days 10 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0000649181
0x8ff1d1dc0c5373d938c7f8f827898db9f99817d62fbf13901387ad0484ce79cfMap Token41267532020-09-11 14:02:37614 days 5 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0009143620
0xdda84f75cae9aecaa8ec23cbed3223952eb53dd2d06a445d17cddb7341ba23b7Map Token38289572020-09-04 11:25:53621 days 7 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.001298620
0xc990d41c6a11dd7e5ee1f943937b3774cff95a9d64d5972aba1d6f1098b57172Map Token38288362020-09-04 11:21:43621 days 8 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0009143620
0x6db01254b272ee09624eea853756486bb0f6133bdf74e3010e1f8dd83a870a9dMap Token38175532020-09-04 4:53:53621 days 14 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0009143620
0xe541040246a884e63f1a41e6ba13ff2374f4cf868c8d6ffe154b34e039270b5dMap Token37540142020-09-02 16:29:43623 days 2 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0006143620
0xd5a28ff62222563713719b2df7d8a8a463df746d216ab72b055186a979e6cdfaMap Token37530712020-09-02 15:57:17623 days 3 hrs ago0x907f2e1f4a477319a700fc9a28374ba47527050e IN  0x1edd419627ef40736ec4f8ceffde671a30803c5e0 MATIC0.0006143620
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x5e08a19b3a2ab8899d12e6bc3f3a0c434f2da0691ee804195c4b960fb7a3f0a634109772020-08-25 11:46:55631 days 7 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xa85bcf44bb917faec927127478825cb7ea2fc01e7e86877324c8d091f77ad63333747282020-08-24 15:00:53632 days 4 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xe1736d48b214826285b21277597b9f1186f5771ee2d0007116b5bad1c37172d133746982020-08-24 14:59:49632 days 4 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x781bbd8a28e71f67d62c8e4a58aa0b326b59ed9ed8e3468ec8f9e06ef7d1c5cd26310272020-08-06 20:56:03649 days 22 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x2c25d88da64c902f2fe4b03dde5110e08134e676c54d85256cbddb31f86b053526309152020-08-06 20:52:15649 days 22 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x7b1265f36ee422e5ac196c3b855d1852a0296a93077951c2983f360d7196e75926302912020-08-06 20:30:47649 days 22 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x0ec044cf44c6c5b21cdff6e5ef6b36db6a2a71b10bcbc62dbec019a8dd1ab7ea26302672020-08-06 20:29:55649 days 22 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xbd1f9478d3a103c5373fbeb89ca10bfeb3c0d3bb1b9858db65411f3144532cb026302302020-08-06 20:28:41649 days 22 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x6280d6882c0b61d566dba68c864f12f4cd58f80b54c838756e47e719af951e9826298912020-08-06 20:17:03649 days 23 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x069dff5eeec34c2f62600e772b8df9a6b655e8b01e8a6ee2324f287b84a1a91826298472020-08-06 20:15:31649 days 23 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xe26d0f40639b75b331cca4d579da1cc79cac907f1047362067818bdfc9c21f5d26296622020-08-06 20:09:09649 days 23 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x2b99230ef35c9e80ae03ff788002153e065ee8d4304106038e0104a25b0462e726294172020-08-06 20:00:43649 days 23 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xa20a35db9c6277356a8e1b12da56f9e400b11b02c1b103346afb2b83e3db967025696112020-08-05 9:44:55651 days 9 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xa4d12fafd590b77c9b7c7859fdb2e6ae6e3e34542cacd1168b0ad8e00230b24925694442020-08-05 9:39:09651 days 9 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xfa1519575aa3c976b9f61508a13ab782e55ac76124a7217bd689627618f6b15625691462020-08-05 9:28:53651 days 9 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xd6126f7261b987ba6d78c504fbcefcb0f2983bf2a31dd9e7a640372fcaa3971525687142020-08-05 9:14:05651 days 10 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x28dd58581a0f992e032afc10648a8c421d2cfea5bf79513ca0ba3f085a9a51a121092772020-07-25 9:59:09662 days 9 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xe2963cf3c34b601a0570ff2ff6c342dce0e926cfd8541142e062d91ba09376ab20330072020-07-23 14:17:21664 days 5 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x54e15a2cb5801e012d622bf6d0c6d5d761aaba0fd9b7f4b474f63f779d97496620326862020-07-23 14:06:19664 days 5 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x92b4c520cd406a0a783ab62170bb2858b00c93fe083a7dbc740c2b30736517fc20325672020-07-23 14:02:13664 days 5 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xb2d2e26fb47fbe3fd4898a78e6bc7590310b9e9c036e10fee6ed05bac29ee0b920319982020-07-23 13:42:39664 days 5 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x002cb370b92ea09952e57f49dc47eb9659c6c73cae666ff0d6ea7694ed372bec20300972020-07-23 12:37:21664 days 6 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0xa6e655c9d0d70218a199a25a5b034452afa96eeddc7e5ac06e9e3b6ae365c54620295082020-07-23 12:17:07664 days 7 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x475d8889432f538e65227454bffef18149e771838c13ddadb9527d7d769b1dc020293202020-07-23 12:10:39664 days 7 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
0x57e9f98dcc0f869c217dba59f1841091b39aa8204dcde662d10ea2fd8691565020289902020-07-23 11:59:15664 days 7 hrs ago 0x1edd419627ef40736ec4f8ceffde671a30803c5e  Contract Creation0 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ChildChain

Compiler Version
v0.5.11+commit.c082d0b4

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2021-07-12
*/

// 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"013881";
  uint256 constant public CHAINID = 80001;
}

// 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 ABI

[{"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"}]

608060405234801561001057600080fd5b50600080546001600160a01b03191633178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600180546001600160a01b03191661100117908190556040516001600160a01b0391909116906000907f98e6a46aa139a033b9c7f3ae4ad1c103ffdce3e7cf509326808ba8c4b5af11c0908290a3737d1afa7b718fb893db30a3abc0cfc608aacfebb060005260026020527fa6b538c9a0f90a58a2d51d8b41372745652182421068cf734937a5df014e586980546001600160a01b031916611010179055614f80806101076000396000f3fe60806040523480156200001157600080fd5b50600436106200010c5760003560e01c8063b02c43d011620000a5578063e117694b116200006f578063e117694b1462000412578063e4860339146200044d578063f2fde38b1462000476578063f4ef4d69146200049f576200010c565b8063b02c43d01462000247578063bb9b9fa21462000267578063daa09e5414620003c0578063df55500714620003e9576200010c565b806355651f7111620000e757806355651f711462000203578063715018a6146200020d5780638da5cb5b14620002175780638f32d59b146200023d576200010c565b806307a06d37146200011157806326c53bea146200015257806355466c3714620001cf575b600080fd5b62000150600480360360808110156200012957600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135620004a9565b005b62000150600480360360408110156200016a57600080fd5b813591908101906040810160208201356401000000008111156200018d57600080fd5b820183602082011115620001a057600080fd5b80359060200191846001830284011164010000000083111715620001c357600080fd5b50909250905062000640565b620001ef60048036036020811015620001e757600080fd5b5035620006d9565b604080519115158252519081900360200190f35b620001ef620006ee565b62000150620006ff565b620002216200075d565b604080516001600160a01b039092168252519081900360200190f35b620001ef6200076c565b620001ef600480360360208110156200025f57600080fd5b50356200077d565b62000221600480360360c08110156200027f57600080fd5b6001600160a01b038235811692602081013590911691810190606081016040820135640100000000811115620002b457600080fd5b820183602082011115620002c757600080fd5b80359060200191846001830284011164010000000083111715620002ea57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156200033e57600080fd5b8201836020820111156200035157600080fd5b803590602001918460018302840111640100000000831117156200037457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505060ff8335169350505060200135151562000792565b620001ef60048036036020811015620003d857600080fd5b50356001600160a01b031662000b1b565b62000150600480360360208110156200040157600080fd5b50356001600160a01b031662000b30565b62000150600480360360608110156200042a57600080fd5b506001600160a01b03813581169160208101359091169060400135151562000be7565b62000221600480360360208110156200046557600080fd5b50356001600160a01b031662000c46565b62000150600480360360208110156200048e57600080fd5b50356001600160a01b031662000c61565b6200022162000c83565b620004b36200076c565b620004bd57600080fd5b60008181526005602052604090205460ff1615620004da57600080fd5b6000818152600560209081526040808320805460ff191660011790556001600160a01b038088168452600290925290912054168062000560576040805162461bcd60e51b815260206004820152601960248201527f6368696c6420746f6b656e206973206e6f74206d617070656400000000000000604482015290519081900360640190fd5b6001600160a01b03851660009081526003602052604081205460ff16156200058a5750806200058d565b50805b806001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015620005d457600080fd5b505af1158015620005e9573d6000803e3d6000fd5b5050604080518781526020810187905281516001600160a01b03808b16955087811694508b16927f7ec90ada0dee6c6d3ea251a8236eb33077411c39b9c26fc24045ae009599def3928290030190a4505050505050565b6200064a620006ee565b620006875760405162461bcd60e51b815260040180806020018281038252603581526020018062004edd6035913960400191505060405180910390fd5b600080600080858560808110156200069e57600080fd5b506001600160a01b03813581169550602082013516935060408101359250606001359050620006d08385848462000c92565b50505050505050565b60056020526000908152604090205460ff1681565b6001546001600160a01b0316331490565b620007096200076c565b6200071357600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b60046020526000908152604090205460ff1681565b60006200079e6200076c565b620007a857600080fd5b6001600160a01b0386811660009081526002602052604090205416156200080d576040805162461bcd60e51b8152602060048201526014602482015273151bdad95b88185b1c9958591e481b585c1c195960621b604482015290519081900360640190fd5b8115620009795786868686604051620008269062000e56565b80856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015620008965781810151838201526020016200087c565b50505050905090810190601f168015620008c45780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620008f9578181015183820152602001620008df565b50505050905090810190601f168015620009275780820380516001836020036101000a031916815260200191505b509650505050505050604051809103906000f0801580156200094d573d6000803e3d6000fd5b506001600160a01b0387166000908152600360205260409020805460ff19166001179055905062000aac565b86868686866040516200098c9062000e64565b6001600160a01b038087168252851660208083019190915260ff8316608083015260a06040830181815286519184019190915285519091606084019160c085019188019080838360005b83811015620009f0578181015183820152602001620009d6565b50505050905090810190601f16801562000a1e5780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b8381101562000a5357818101518382015260200162000a39565b50505050905090810190601f16801562000a815780820380516001836020036101000a031916815260200191505b50975050505050505050604051809103906000f08015801562000aa8573d6000803e3d6000fd5b5090505b6001600160a01b0386811660008181526002602090815260409182902080546001600160a01b0319169486169485179055815160ff8816815291517f9894b680cecb28f00988b0d91ed301a55bba06a8befd7fdb0b1ff36d0d3950ff9281900390910190a39695505050505050565b60036020526000908152604090205460ff1681565b62000b3a6200076c565b62000b4457600080fd5b6001600160a01b03811662000b8b5760405162461bcd60e51b815260040180806020018281038252603a81526020018062004f12603a913960400191505060405180910390fd5b6001546040516001600160a01b038084169216907f98e6a46aa139a033b9c7f3ae4ad1c103ffdce3e7cf509326808ba8c4b5af11c090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b62000bf16200076c565b62000bfb57600080fd5b6001600160a01b03928316600090815260026020908152604080832080546001600160a01b031916959096169490941790945560039093529120805460ff1916911515919091179055565b6002602052600090815260409020546001600160a01b031681565b62000c6b6200076c565b62000c7557600080fd5b62000c808162000de7565b50565b6001546001600160a01b031681565b60008181526004602052604090205460ff161562000caf57600080fd5b6000818152600460209081526040808320805460ff191660011790556001600160a01b038088168452600290925290912054168062000ced57600080fd5b6001600160a01b03851660009081526003602052604081205460ff161562000d1757508062000d1a565b50805b806001600160a01b03166347e7ef2486866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801562000d7b57600080fd5b505af115801562000d90573d6000803e3d6000fd5b5050604080518781526020810187905281516001600160a01b03808b16955087811694508b16927fec3afb067bce33c5a294470ec5b29e6759301cd3928550490c6d48816cdc2f5d928290030190a4505050505050565b6001600160a01b03811662000dfb57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6123b68062000e7383390190565b611cb480620032298339019056fe60806040523480156200001157600080fd5b50604051620023b6380380620023b6833981810160405260808110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b506040819052600080546001600160a01b031916331780825587955086945085935084926001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360405180608001604052806052815260200162002364605291396040516020018082805190602001908083835b60208310620002485780518252601f19909201916020918201910162000227565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092208285018552600d83527f4d61746963204e6574776f726b00000000000000000000000000000000000000928201929092528351808501855260018082527f3100000000000000000000000000000000000000000000000000000000000000918301919091528451808301939093527fd26430275d0d30693378daeb558f6ed30c3a48ba5d665f52c16608e1c41b5cd7838601527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401526201388160808401523060a0808501919091528551808503909101815260c09093019094528151910120909155506200039591507f01ffc9a7000000000000000000000000000000000000000000000000000000009050620004c0565b620003c97f80ac58cd000000000000000000000000000000000000000000000000000000006001600160e01b03620004c016565b620003fd7f780e9d63000000000000000000000000000000000000000000000000000000006001600160e01b03620004c016565b81516200041290600f9060208501906200052d565b508051620004289060109060208401906200052d565b506200045d7f5b5e139f000000000000000000000000000000000000000000000000000000006001600160e01b03620004c016565b505050506001600160a01b038316158015906200048257506001600160a01b03841615155b6200048c57600080fd5b5050600480546001600160a01b039384166001600160a01b03199182161790915560028054929093169116179055620005d2565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620004f057600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600660205260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200057057805160ff1916838001178555620005a0565b82800160010185558215620005a0579182015b82811115620005a057825182559160200191906001019062000583565b50620005ae929150620005b2565b5090565b620005cf91905b80821115620005ae5760008155600101620005b9565b90565b611d8280620005e26000396000f3fe6080604052600436106102045760003560e01c8063715018a611610118578063b789543c116100a0578063e306f7791161006f578063e306f77914610908578063e614d0d61461091d578063e985e9c514610932578063f2fde38b1461096d578063fc0c546a146109a057610204565b8063b789543c146107b1578063b88d4fde146107f6578063c87b56dd146108c9578063cc79f97b146108f357610204565b80639025e64c116100e75780639025e64c1461070d57806395d89b4114610722578063a22cb46514610737578063abceeba214610772578063acd06cb31461078757610204565b8063715018a61461061457806377d32e94146106295780638da5cb5b146106e35780638f32d59b146106f857610204565b80632e1a7d4d1161019b5780634f6ccce71161016a5780634f6ccce71461056357806360f96a8f1461058d5780636352211e146105a25780637019d41a146105cc57806370a08231146105e157610204565b80632e1a7d4d146104915780632f745c59146104ae57806342842e0e146104e757806347e7ef241461052a57610204565b80631499c592116101d75780631499c5921461035c57806318160ddd1461038f57806319d27d9c146103b657806323b872dd1461044e57610204565b806301ffc9a71461020957806306fdde0314610251578063081812fc146102db578063095ea7b314610321575b600080fd5b34801561021557600080fd5b5061023d6004803603602081101561022c57600080fd5b50356001600160e01b0319166109b5565b604080519115158252519081900360200190f35b34801561025d57600080fd5b506102666109d4565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102a0578181015183820152602001610288565b50505050905090810190601f1680156102cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102e757600080fd5b50610305600480360360208110156102fe57600080fd5b5035610a6b565b604080516001600160a01b039092168252519081900360200190f35b34801561032d57600080fd5b5061035a6004803603604081101561034457600080fd5b506001600160a01b038135169060200135610aad565b005b34801561036857600080fd5b5061035a6004803603602081101561037f57600080fd5b50356001600160a01b0316610aed565b34801561039b57600080fd5b506103a4610b39565b60408051918252519081900360200190f35b3480156103c257600080fd5b50610305600480360360a08110156103d957600080fd5b8101906020810181356401000000008111156103f457600080fd5b82018360208201111561040657600080fd5b8035906020019184600183028401116401000000008311171561042857600080fd5b9193509150803590602081013590604081013590606001356001600160a01b0316610b3f565b34801561045a57600080fd5b5061035a6004803603606081101561047157600080fd5b506001600160a01b03813581169160208101359091169060400135610cda565b61035a600480360360208110156104a757600080fd5b5035610d93565b3480156104ba57600080fd5b506103a4600480360360408110156104d157600080fd5b506001600160a01b038135169060200135610e00565b3480156104f357600080fd5b5061035a6004803603606081101561050a57600080fd5b506001600160a01b03813581169160208101359091169060400135610e4e565b34801561053657600080fd5b5061035a6004803603604081101561054d57600080fd5b506001600160a01b038135169060200135610e69565b34801561056f57600080fd5b506103a46004803603602081101561058657600080fd5b5035610ee0565b34801561059957600080fd5b50610305610f14565b3480156105ae57600080fd5b50610305600480360360208110156105c557600080fd5b5035610f23565b3480156105d857600080fd5b50610305610f45565b3480156105ed57600080fd5b506103a46004803603602081101561060457600080fd5b50356001600160a01b0316610f54565b34801561062057600080fd5b5061035a610f8a565b34801561063557600080fd5b506103056004803603604081101561064c57600080fd5b8135919081019060408101602082013564010000000081111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111640100000000831117156106a257600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610fe5945050505050565b3480156106ef57600080fd5b50610305611108565b34801561070457600080fd5b5061023d611117565b34801561071957600080fd5b50610266611128565b34801561072e57600080fd5b50610266611147565b34801561074357600080fd5b5061035a6004803603604081101561075a57600080fd5b506001600160a01b0381351690602001351515610aad565b34801561077e57600080fd5b506103a46111a8565b34801561079357600080fd5b5061023d600480360360208110156107aa57600080fd5b5035611231565b3480156107bd57600080fd5b506103a4600480360360808110156107d457600080fd5b506001600160a01b038135169060208101359060408101359060600135611246565b34801561080257600080fd5b5061035a6004803603608081101561081957600080fd5b6001600160a01b0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561085457600080fd5b82018360208201111561086657600080fd5b8035906020019184600183028401116401000000008311171561088857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611265945050505050565b3480156108d557600080fd5b50610266600480360360208110156108ec57600080fd5b503561128b565b3480156108ff57600080fd5b506103a461133e565b34801561091457600080fd5b506103a4611345565b34801561092957600080fd5b506103a461134b565b34801561093e57600080fd5b5061023d6004803603604081101561095557600080fd5b506001600160a01b0381358116916020013516610a6b565b34801561097957600080fd5b5061035a6004803603602081101561099057600080fd5b50356001600160a01b0316611395565b3480156109ac57600080fd5b506103056113b2565b6001600160e01b03191660009081526006602052604090205460ff1690565b600f8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a605780601f10610a3557610100808354040283529160200191610a60565b820191906000526020600020905b815481529060010190602001808311610a4357829003601f168201915b505050505090505b90565b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b6044820152905160009181900360640190fd5b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b604482015290519081900360640190fd5b6004546001600160a01b03163314610b0457600080fd5b6001600160a01b038116610b1757600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b600d5490565b6000821580610b4e5750824311155b610b96576040805162461bcd60e51b815260206004820152601460248201527314da59db985d1d5c99481a5cc8195e1c1a5c995960621b604482015290519081900360640190fd5b6000610ba433878787611246565b60008181526005602052604090205490915060ff1615610bfd576040805162461bcd60e51b815260206004820152600f60248201526e14da59c819195858dd1a5d985d1959608a1b604482015290519081900360640190fd5b6000818152600560209081526040808320805460ff191660011790558051601f8b01839004830281018301909152898152610c55918491908c908c9081908401838280828437600092019190915250610fe592505050565b9050610c628185896113c1565b610c7d8185896040518060200160405280600081525061141a565b610cce576040805162461bcd60e51b815260206004820152601d60248201527f5f636865636b4f6e4552433732315265636569766564206661696c6564000000604482015290519081900360640190fd5b98975050505050505050565b6003546001600160a01b031615801590610d79575060035460408051631ffb811f60e01b81523360048201526001600160a01b0385811660248301526044820185905291519190921691631ffb811f9160648083019260209291908290030181600087803b158015610d4b57600080fd5b505af1158015610d5f573d6000803e3d6000fd5b505050506040513d6020811015610d7557600080fd5b5051155b15610d8357610d8e565b610d8e8383836113c1565b505050565b33610d9d82610f23565b6001600160a01b031614610db057600080fd5b610dba338261154e565b60025460408051838152905133926001600160a01b0316917f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb919081900360200190a350565b6000610e0b83610f54565b8210610e1657600080fd5b6001600160a01b0383166000908152600b60205260409020805483908110610e3a57fe5b906000526020600020015490505b92915050565b610d8e83838360405180602001604052806000815250611265565b610e71611117565b610e7a57600080fd5b6001600160a01b038216610e8d57600080fd5b610e97828261159a565b6002546040805183815290516001600160a01b038086169316917f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62919081900360200190a35050565b6000610eea610b39565b8210610ef557600080fd5b600d8281548110610f0257fe5b90600052602060002001549050919050565b6003546001600160a01b031681565b6000818152600760205260408120546001600160a01b031680610e4857600080fd5b6004546001600160a01b031681565b60006001600160a01b038216610f6957600080fd5b6001600160a01b0382166000908152600960205260409020610e48906115b7565b610f92611117565b610f9b57600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60008060008084516041146110005760009350505050610e48565b50505060208201516040830151604184015160ff16601b81101561102257601b015b8060ff16601b1415801561103a57508060ff16601c14155b1561104b5760009350505050610e48565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa1580156110a2573d6000803e3d6000fd5b5050604051601f1901519450506001600160a01b0384166110ff576040805162461bcd60e51b815260206004820152601260248201527122b93937b91034b71032b1b932b1b7bb32b960711b604482015290519081900360640190fd5b50505092915050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6040518060400160405280600381526020016201388160e81b81525081565b60108054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a605780601f10610a3557610100808354040283529160200191610a60565b6040518060800160405280605b8152602001611cf3605b91396040516020018082805190602001908083835b602083106111f35780518252601f1990920191602091820191016111d4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020526000908152604090205460ff1681565b600061125c611257868686866115bb565b611674565b95945050505050565b611270848484610cda565b61127c8484848461141a565b61128557600080fd5b50505050565b606061129682611699565b61129f57600080fd5b60008281526011602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156113325780601f1061130757610100808354040283529160200191611332565b820191906000526020600020905b81548152906001019060200180831161131557829003601f168201915b50505050509050919050565b6201388181565b60015481565b604051806080016040528060528152602001611ca160529139604051602001808280519060200190808383602083106111f35780518252601f1990920191602091820191016111d4565b61139d611117565b6113a657600080fd5b6113af816116b6565b50565b6002546001600160a01b031681565b6113cc838383611724565b6002546040805183815290516001600160a01b0380861693878216939116917f6eabe333476233fd382224f233210cb808a7bc4c4de64f9d76628bf63c677b1a9181900360200190a4505050565b600061142e846001600160a01b0316611743565b61143a57506001611546565b604051630a85bd0160e11b815233600482018181526001600160a01b03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156114b457818101518382015260200161149c565b50505050905090810190601f1680156114e15780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b15801561150357600080fd5b505af1158015611517573d6000803e3d6000fd5b505050506040513d602081101561152d57600080fd5b50516001600160e01b031916630a85bd0160e11b149150505b949350505050565b6115588282611749565b600081815260116020526040902054600260001961010060018416150201909116041561159657600081815260116020526040812061159691611c1e565b5050565b6115a48282611775565b6115ae8282611816565b61159681611854565b5490565b6000806040518060800160405280605b8152602001611cf3605b91396040516020018082805190602001908083835b602083106116095780518252601f1990920191602091820191016115ea565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922082526001600160a01b039b909b169a81019a909a5250880196909652505050606084019190915260808301525060a0902090565b60015460405161190160f01b8152600281019190915260228101919091526042902090565b6000908152600760205260409020546001600160a01b0316151590565b6001600160a01b0381166116c957600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b61172f838383611898565b6117398382611978565b610d8e8282611816565b3b151590565b6117538282611a6d565b61175d8282611978565b6000818152600c602052604081205561159681611b12565b6001600160a01b03821661178857600080fd5b61179181611699565b1561179b57600080fd5b600081815260076020908152604080832080546001600160a01b0319166001600160a01b0387169081179091558352600990915290206117da90611bae565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b039091166000908152600b602081815260408084208054868652600c84529185208290559282526001810183559183529091200155565b600d80546000838152600e60205260408120829055600182018355919091527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50155565b826001600160a01b03166118ab82610f23565b6001600160a01b0316146118be57600080fd5b6001600160a01b0382166118d157600080fd5b6118da81611bb7565b6001600160a01b03831660009081526009602052604090206118fb90611bf2565b6001600160a01b038216600090815260096020526040902061191c90611bae565b60008181526007602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b0382166000908152600b60205260408120546119a290600163ffffffff611c0916565b6000838152600c6020526040902054909150808214611a3d576001600160a01b0384166000908152600b602052604081208054849081106119df57fe5b9060005260206000200154905080600b6000876001600160a01b03166001600160a01b031681526020019081526020016000208381548110611a1d57fe5b6000918252602080832090910192909255918252600c9052604090208190555b6001600160a01b0384166000908152600b60205260409020805490611a66906000198301611c62565b5050505050565b816001600160a01b0316611a8082610f23565b6001600160a01b031614611a9357600080fd5b611a9c81611bb7565b6001600160a01b0382166000908152600960205260409020611abd90611bf2565b60008181526007602052604080822080546001600160a01b0319169055518291906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600d54600090611b2990600163ffffffff611c0916565b6000838152600e6020526040812054600d8054939450909284908110611b4b57fe5b9060005260206000200154905080600d8381548110611b6657fe5b6000918252602080832090910192909255828152600e90915260409020829055600d805490611b99906000198301611c62565b505050600091825250600e6020526040812055565b80546001019055565b6000818152600860205260409020546001600160a01b0316156113af57600090815260086020526040902080546001600160a01b0319169055565b8054611c0590600163ffffffff611c0916565b9055565b600082821115611c1857600080fd5b50900390565b50805460018160011615610100020316600290046000825580601f10611c4457506113af565b601f0160209004906000526020600020908101906113af9190611c82565b815481835581811115610d8e57600083815260209020610d8e9181019083015b610a6891905b80821115611c9c5760008155600101611c88565b509056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820adcd9affdc12e67ab4cc9c599a00f9a21d29dbd88b7883cb144daaa23019d00064736f6c634300050b0032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e74726163742960806040523480156200001157600080fd5b5060405162001cb438038062001cb4833981810160405260a08110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b9083019060208201858111156200012b57600080fd5b82516401000000008111828201881017156200014657600080fd5b82525081516020918201929091019080838360005b83811015620001755781810151838201526020016200015b565b50505050905090810190601f168015620001a35780820380516001836020036101000a031916815260200191505b50604081905260209190910151600080546001600160a01b0319163317808255919450869350859285926001600160a01b031691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360405180608001604052806052815260200162001c62605291396040516020018082805190602001908083835b602083106200024b5780518252601f1990920191602091820191016200022a565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f190183528085528251928201929092208285018552600d83527f4d61746963204e6574776f726b00000000000000000000000000000000000000928201929092528351808501855260018082527f3100000000000000000000000000000000000000000000000000000000000000918301919091528451808301939093527fd26430275d0d30693378daeb558f6ed30c3a48ba5d665f52c16608e1c41b5cd7838601527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401526201388160808401523060a0808501919091528551808503909101815260c0909301909452815191810191909120909255508551620003839350600992509086019062000414565b5081516200039990600a90602085019062000414565b50600b805460ff191660ff9290921691909117905550506001600160a01b03841615801590620003d157506001600160a01b03851615155b620003db57600080fd5b5050600480546001600160a01b039485166001600160a01b031991821617909155600280549390941692169190911790915550620004b9565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200045757805160ff191683800117855562000487565b8280016001018555821562000487579182015b82811115620004875782518255916020019190600101906200046a565b506200049592915062000499565b5090565b620004b691905b80821115620004955760008155600101620004a0565b90565b61179980620004c96000396000f3fe6080604052600436106101cd5760003560e01c80638da5cb5b116100f7578063acd06cb311610095578063e306f77911610064578063e306f7791461077c578063e614d0d614610791578063f2fde38b146107a6578063fc0c546a146107d9576101cd565b8063acd06cb3146106bd578063b789543c146106e7578063cc79f97b1461072c578063dd62ed3e14610741576101cd565b806395d89b41116100d157806395d89b4114610621578063a457c2d714610636578063a9059cbb1461066f578063abceeba2146106a8576101cd565b80638da5cb5b146105e25780638f32d59b146105f75780639025e64c1461060c576101cd565b8063313ce5671161016f5780637019d41a1161013e5780637019d41a146104cb57806370a08231146104e0578063715018a61461051357806377d32e9414610528576101cd565b8063313ce56714610419578063395093511461044457806347e7ef241461047d57806360f96a8f146104b6576101cd565b806318160ddd116101ab57806318160ddd146102de57806319d27d9c1461030557806323b872dd146103b95780632e1a7d4d146103fc576101cd565b806306fdde03146101d2578063095ea7b31461025c5780631499c592146102a9575b600080fd5b3480156101de57600080fd5b506101e76107ee565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610221578181015183820152602001610209565b50505050905090810190601f16801561024e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561026857600080fd5b506102956004803603604081101561027f57600080fd5b506001600160a01b038135169060200135610884565b604080519115158252519081900360200190f35b3480156102b557600080fd5b506102dc600480360360208110156102cc57600080fd5b50356001600160a01b03166108c6565b005b3480156102ea57600080fd5b506102f3610912565b60408051918252519081900360200190f35b34801561031157600080fd5b5061039d600480360360a081101561032857600080fd5b81019060208101813564010000000081111561034357600080fd5b82018360208201111561035557600080fd5b8035906020019184600183028401116401000000008311171561037757600080fd5b9193509150803590602081013590604081013590606001356001600160a01b0316610918565b604080516001600160a01b039092168252519081900360200190f35b3480156103c557600080fd5b50610295600480360360608110156103dc57600080fd5b506001600160a01b03813581169160208101359091169060400135610884565b6102dc6004803603602081101561041257600080fd5b5035610a53565b34801561042557600080fd5b5061042e610ae2565b6040805160ff9092168252519081900360200190f35b34801561045057600080fd5b506102956004803603604081101561046757600080fd5b506001600160a01b038135169060200135610aeb565b34801561048957600080fd5b506102dc600480360360408110156104a057600080fd5b506001600160a01b038135169060200135610b36565b3480156104c257600080fd5b5061039d610bbb565b3480156104d757600080fd5b5061039d610bca565b3480156104ec57600080fd5b506102f36004803603602081101561050357600080fd5b50356001600160a01b0316610bd9565b34801561051f57600080fd5b506102dc610bf4565b34801561053457600080fd5b5061039d6004803603604081101561054b57600080fd5b8135919081019060408101602082013564010000000081111561056d57600080fd5b82018360208201111561057f57600080fd5b803590602001918460018302840111640100000000831117156105a157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610c4f945050505050565b3480156105ee57600080fd5b5061039d610d72565b34801561060357600080fd5b50610295610d81565b34801561061857600080fd5b506101e7610d92565b34801561062d57600080fd5b506101e7610db1565b34801561064257600080fd5b506102956004803603604081101561065957600080fd5b506001600160a01b038135169060200135610e12565b34801561067b57600080fd5b506102956004803603604081101561069257600080fd5b506001600160a01b038135169060200135610e4e565b3480156106b457600080fd5b506102f3610f0f565b3480156106c957600080fd5b50610295600480360360208110156106e057600080fd5b5035610f98565b3480156106f357600080fd5b506102f36004803603608081101561070a57600080fd5b506001600160a01b038135169060208101359060408101359060600135610fad565b34801561073857600080fd5b506102f3610fcc565b34801561074d57600080fd5b506102f36004803603604081101561076457600080fd5b506001600160a01b0381358116916020013516610884565b34801561078857600080fd5b506102f3610fd3565b34801561079d57600080fd5b506102f3610fd9565b3480156107b257600080fd5b506102dc600480360360208110156107c957600080fd5b50356001600160a01b0316611023565b3480156107e557600080fd5b5061039d611040565b60098054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561087a5780601f1061084f5761010080835404028352916020019161087a565b820191906000526020600020905b81548152906001019060200180831161085d57829003601f168201915b5050505050905090565b6040805162461bcd60e51b815260206004820152601060248201526f44697361626c6564206665617475726560801b6044820152905160009181900360640190fd5b6004546001600160a01b031633146108dd57600080fd5b6001600160a01b0381166108f057600080fd5b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60085490565b600080851161092657600080fd5b8215806109335750824311155b61097b576040805162461bcd60e51b815260206004820152601460248201527314da59db985d1d5c99481a5cc8195e1c1a5c995960621b604482015290519081900360640190fd5b600061098933878787610fad565b60008181526005602052604090205490915060ff16156109e2576040805162461bcd60e51b815260206004820152600f60248201526e14da59c819195858dd1a5d985d1959608a1b604482015290519081900360640190fd5b600081815260056020908152604091829020805460ff191660011790558151601f8a01829004820281018201909252888252610a3a9183918b908b9081908401838280828437600092019190915250610c4f92505050565b9150610a4782848861104f565b50509695505050505050565b336000610a5f82610bd9565b9050600083118015610a715750828110155b610a7a57600080fd5b610a84828461129c565b6002546001600160a01b0380841691167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610ac087610bd9565b60408051938452602084019290925282820152519081900360600190a3505050565b600b5460ff1690565b3360008181526007602090815260408083206001600160a01b03871684529091528120549091610b2c918590610b27908663ffffffff61134516565b611357565b5060015b92915050565b610b3e610d81565b610b4757600080fd5b600081118015610b5f57506001600160a01b03821615155b610b6857600080fd5b6000610b7383610bd9565b9050610b7f83836113df565b6002546001600160a01b0380851691167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68484610ac088610bd9565b6003546001600160a01b031681565b6004546001600160a01b031681565b6001600160a01b031660009081526006602052604090205490565b610bfc610d81565b610c0557600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000806000808451604114610c6a5760009350505050610b30565b50505060208201516040830151604184015160ff16601b811015610c8c57601b015b8060ff16601b14158015610ca457508060ff16601c14155b15610cb55760009350505050610b30565b6040805160008152602080820180845289905260ff8416828401526060820186905260808201859052915160019260a0808401939192601f1981019281900390910190855afa158015610d0c573d6000803e3d6000fd5b5050604051601f1901519450506001600160a01b038416610d69576040805162461bcd60e51b815260206004820152601260248201527122b93937b91034b71032b1b932b1b7bb32b960711b604482015290519081900360640190fd5b50505092915050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6040518060400160405280600381526020016201388160e81b81525081565b600a8054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561087a5780601f1061084f5761010080835404028352916020019161087a565b3360008181526007602090815260408083206001600160a01b03871684529091528120549091610b2c918590610b27908663ffffffff61148916565b6003546000906001600160a01b031615801590610ef0575060035460408051631ffb811f60e01b81523360048201526001600160a01b0386811660248301526044820186905291519190921691631ffb811f9160648083019260209291908290030181600087803b158015610ec257600080fd5b505af1158015610ed6573d6000803e3d6000fd5b505050506040513d6020811015610eec57600080fd5b5051155b15610efd57506000610b30565b610f0833848461104f565b9392505050565b6040518060800160405280605b815260200161170a605b91396040516020018082805190602001908083835b60208310610f5a5780518252601f199092019160209182019101610f3b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020526000908152604090205460ff1681565b6000610fc3610fbe8686868661149e565b611557565b95945050505050565b6201388181565b60015481565b6040518060800160405280605281526020016116b86052913960405160200180828051906020019080838360208310610f5a5780518252601f199092019160209182019101610f3b565b61102b610d81565b61103457600080fd5b61103d8161157c565b50565b6002546001600160a01b031681565b604080516370a0823160e01b81526001600160a01b03851660048201529051600091829130916370a08231916024808301926020929190829003018186803b15801561109a57600080fd5b505afa1580156110ae573d6000803e3d6000fd5b505050506040513d60208110156110c457600080fd5b5051604080516370a0823160e01b81526001600160a01b0387166004820152905191925060009130916370a08231916024808301926020929190829003018186803b15801561111257600080fd5b505afa158015611126573d6000803e3d6000fd5b505050506040513d602081101561113c57600080fd5b5051905061114b8686866115ea565b600254604080516370a0823160e01b81526001600160a01b03898116600483018190529251818a1694909116917fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c49189918891889130916370a0823191602480820192602092909190829003018186803b1580156111c857600080fd5b505afa1580156111dc573d6000803e3d6000fd5b505050506040513d60208110156111f257600080fd5b5051604080516370a0823160e01b81526001600160a01b038f166004820152905130916370a08231916024808301926020929190829003018186803b15801561123a57600080fd5b505afa15801561124e573d6000803e3d6000fd5b505050506040513d602081101561126457600080fd5b50516040805195865260208601949094528484019290925260608401526080830152519081900360a00190a450600195945050505050565b6001600160a01b0382166112af57600080fd5b6008546112c2908263ffffffff61148916565b6008556001600160a01b0382166000908152600660205260409020546112ee908263ffffffff61148916565b6001600160a01b0383166000818152600660209081526040808320949094558351858152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35050565b600082820183811015610f0857600080fd5b6001600160a01b03821661136a57600080fd5b6001600160a01b03831661137d57600080fd5b6001600160a01b03808416600081815260076020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0382166113f257600080fd5b600854611405908263ffffffff61134516565b6008556001600160a01b038216600090815260066020526040902054611431908263ffffffff61134516565b6001600160a01b03831660008181526006602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60008282111561149857600080fd5b50900390565b6000806040518060800160405280605b815260200161170a605b91396040516020018082805190602001908083835b602083106114ec5780518252601f1990920191602091820191016114cd565b51815160209384036101000a60001901801990921691161790526040805192909401828103601f1901835280855282519282019290922082526001600160a01b039b909b169a81019a909a5250880196909652505050606084019190915260808301525060a0902090565b60015460405161190160f01b8152600281019190915260228101919091526042902090565b6001600160a01b03811661158f57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382166115fd57600080fd5b6001600160a01b038316600090815260066020526040902054611626908263ffffffff61148916565b6001600160a01b03808516600090815260066020526040808220939093559084168152205461165b908263ffffffff61134516565b6001600160a01b0380841660008181526006602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a350505056fe454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a723158206f47f32f4fba2bc5d40ce43b24b7b6f9bb484859be3fdc1d270bccf3926ad62764736f6c634300050b0032454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e74726163742953746174652073796e6365723a2063616c6c6572206973206e6f74207468652073746174652073796e63657220636f6e747261637453746174652073796e6365723a206e65772073746174652073796e636572206164647265737320697320746865207a65726f2061646472657373a265627a7a72315820ebe9a3c1d1795e93dcadf22ef22ed6b3bca33d6febdfd741c02ecc512f007d5964736f6c634300050b0032

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading