WithdrawManager

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/child/BaseERC20.sol": {
      "content": "pragma solidity ^0.5.2;

import "./ChildToken.sol";

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 = hashEIP712MessageWithAddress(
            hashTokenTransferOrder(msg.sender, amount, data, expiration),
            address(this)
        );

        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;
    }
}
"
    },
    "contracts/child/bor/StateReceiver.sol": {
      "content": "pragma solidity ^0.5.2;

// StateReceiver represents interface to receive state
interface StateReceiver {
    function onStateReceive(uint256 id, bytes calldata data) external;
}
"
    },
    "contracts/child/bor/StateSyncerVerifier.sol": {
      "content": "pragma solidity ^0.5.2;

import {Ownable} from "openzeppelin-solidity/contracts/ownership/Ownable.sol";

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;
    }
}
"
    },
    "contracts/child/ChildChain.sol": {
      "content": "pragma solidity ^0.5.2;

import {Ownable} from "openzeppelin-solidity/contracts/ownership/Ownable.sol";

import {StateSyncerVerifier} from "./bor/StateSyncerVerifier.sol";
import {StateReceiver} from "./bor/StateReceiver.sol";

import "./ChildToken.sol";
import "./ChildERC20.sol";
import "./ChildERC721.sol";

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
        );
    }

}
"
    },
    "contracts/child/ChildERC20.sol": {
      "content": "pragma solidity ^0.5.2;

import {ERC20Detailed} from "./ERC20Detailed.sol";
import {ERC20} from "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

import {StateSyncerVerifier} from "./bor/StateSyncerVerifier.sol";
import {StateReceiver} from "./bor/StateReceiver.sol";
import "./BaseERC20.sol";
import "./misc/IParentToken.sol";

contract ChildERC20 is BaseERC20, ERC20, ERC20Detailed, StateSyncerVerifier, StateReceiver {
    constructor(
        address /* ignoring parent owner, use contract owner instead */,
        address _token,
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) public ERC20Detailed(_name, _symbol, _decimals) {
        require(_token != address(0x0));
        token = _token;
    }

    /**
   * Deposit tokens
   *
   * @param user address for address
   * @param amount token balance
   */
    function deposit(address user, uint256 amount) public onlyChildChain {
        // 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 {
        _withdraw(msg.sender, amount);
    }

    function onStateReceive(
        uint256, /* id */
        bytes calldata data
    ) external onlyStateSyncer {
        (address user, uint256 burnAmount) = abi.decode(data, (address, uint256));
        uint256 balance = balanceOf(user);
        if (balance < burnAmount) {
            burnAmount = balance;
        }
        _withdraw(user, burnAmount);
    }

    function _withdraw(address user, uint256 amount) internal {
        uint256 input = balanceOf(user);
        _burn(user, amount);
        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");
    }
}
"
    },
    "contracts/child/ChildERC721.sol": {
      "content": "pragma solidity ^0.5.2;

import {ERC721Full} from "openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol";

import "./ChildToken.sol";
import "./misc/IParentToken.sol";

import {StateSyncerVerifier} from "./bor/StateSyncerVerifier.sol";
import {StateReceiver} from "./bor/StateReceiver.sol";

contract ChildERC721 is ChildToken, ERC721Full, StateSyncerVerifier, StateReceiver {
    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 /* ignoring parent owner, use contract owner instead */,
        address _token,
        string memory name,
        string memory symbol
    ) public ERC721Full(name, symbol) {
        require(_token != address(0x0));
        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 = hashEIP712MessageWithAddress(
            hashTokenTransferOrder(msg.sender, tokenId, data, expiration),
            address(this)
        );
        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 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 onlyChildChain {
        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);
    }

    function onStateReceive(
        uint256, /* id */
        bytes calldata data
    ) external onlyStateSyncer {
        (address user, uint256 tokenId) = abi.decode(data, (address, uint256));
        _burn(user, tokenId);
        emit Withdraw(token, user, 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);
    }
}
"
    },
    "contracts/child/ChildERC721Mintable.sol": {
      "content": "pragma solidity ^0.5.2;

import "openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol";
import "openzeppelin-solidity/contracts/token/ERC721/ERC721MetadataMintable.sol";

import {ChildERC721} from "./ChildERC721.sol";

contract ChildERC721Mintable is
    ChildERC721,
    ERC721Mintable,
    ERC721MetadataMintable
{
    constructor(address rootToken, string memory name, string memory symbol)
        public
        ChildERC721(
            msg.sender, /* _owner */
            rootToken,
            name,
            symbol
        )
    {}
}
"
    },
    "contracts/child/ChildToken.sol": {
      "content": "pragma solidity ^0.5.2;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

import "./misc/LibTokenTransferOrder.sol";

contract ChildToken is Ownable, LibTokenTransferOrder {
    using SafeMath for uint256;

    // ERC721/ERC20 contract token address on root chain
    address public token;
    address public childChain;
    address public parent;

    mapping(bytes32 => bool) public disabledHashes;

    modifier onlyChildChain() {
        require(
            msg.sender == childChain,
            "Child token: caller is not the child chain contract"
        );
        _;
    }

    event LogFeeTransfer(
        address indexed token,
        address indexed from,
        address indexed to,
        uint256 amount,
        uint256 input1,
        uint256 input2,
        uint256 output1,
        uint256 output2
    );

    event ChildChainChanged(
        address indexed previousAddress,
        address indexed newAddress
    );

    event ParentChanged(
        address indexed previousAddress,
        address indexed newAddress
    );

    function deposit(address user, uint256 amountOrTokenId) public;
    function withdraw(uint256 amountOrTokenId) public payable;

    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");
    }

    // change child chain address
    function changeChildChain(address newAddress) public onlyOwner {
        require(
            newAddress != address(0),
            "Child token: new child address is the zero address"
        );
        emit ChildChainChanged(childChain, newAddress);
        childChain = newAddress;
    }

    // change parent address
    function setParent(address newAddress) public onlyOwner {
        require(
            newAddress != address(0),
            "Child token: new parent address is the zero address"
        );
        emit ParentChanged(parent, newAddress);
        parent = newAddress;
    }
}
"
    },
    "contracts/child/ERC20Detailed.sol": {
      "content": "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 {
    string internal _name;
    string internal _symbol;
    uint8 internal _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;
    }
}
"
    },
    "contracts/child/misc/EIP712.sol": {
      "content": "pragma solidity ^0.5.2;

import {ChainIdMixin} from "../../common/mixin/ChainIdMixin.sol";

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)
    {
        return _hashEIP712Message(hashStruct, EIP712_DOMAIN_HASH);
    }

    function hashEIP712MessageWithAddress(bytes32 hashStruct, address add)
        internal
        view
        returns (bytes32 result)
    {
        bytes32 domainHash = keccak256(
            abi.encode(
                EIP712_DOMAIN_SCHEMA_HASH,
                keccak256(bytes(EIP712_DOMAIN_NAME)),
                keccak256(bytes(EIP712_DOMAIN_VERSION)),
                EIP712_DOMAIN_CHAINID,
                add
            )
        );
        return _hashEIP712Message(hashStruct, domainHash);
    }

    function _hashEIP712Message(bytes32 hashStruct, bytes32 domainHash)
        internal
        pure
        returns (bytes32 result)
    {
        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)
        }
    }
}
"
    },
    "contracts/child/misc/IParentToken.sol": {
      "content": "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);
}
"
    },
    "contracts/child/misc/LibTokenTransferOrder.sol": {
      "content": "pragma solidity ^0.5.2;

import {LibEIP712Domain} from "./EIP712.sol";

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;
    }
}
"
    },
    "contracts/child/misc/ParentTokenMock.sol": {
      "content": "pragma solidity ^0.5.2;

import "openzeppelin-solidity/contracts/ownership/Ownable.sol";

import "./IParentToken.sol";
// demo token parent contract

contract ParentTokenMock is IParentToken, Ownable {
    mapping(address => bool) isAllowed;
    function beforeTransfer(address sender, address to, uint256 value)
        external
        returns (bool)
    {
        return isAllowed[sender];
    }

    function updatePermission(address user) public onlyOwner {
        require(user != address(0x0));
        isAllowed[user] = !isAllowed[user];
    }
}
"
    },
    "contracts/child/MRC20.sol": {
      "content": "pragma solidity ^0.5.11;

import "./BaseERC20.sol";

/**
 * @title Bone token contract
 * @notice This contract is an ECR20 like wrapper over native ether (bone token) transfers on the shibarium chain
 * @dev ERC20 methods have been made payable while keeping their method signature same as other ChildERC20s on shibarium
 */
contract MRC20 is BaseERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);

    uint256 public currentSupply = 0;
    uint8 private constant DECIMALS = 18;
    bool isInitialized;
    uint256 locked = 0;

    modifier nonReentrant() {
        require(locked == 0, "reentrancy");
        locked = 1;
        _;
        locked = 0;
    }

    constructor() public {}

    function initialize(address _childChain, address _token) public {
        require(!isInitialized, "The contract is already initialized");
        isInitialized = true;
        token = _token;
        _transferOwnership(_childChain);
    }

    function setParent(address) public {
        revert("Disabled feature");
    }

    function deposit(address user, uint256 amount) public onlyOwner {
        // check for amount and user
        require(
            amount > 0 && user != address(0x0),
            "Insufficient amount or invalid user"
        );

        // input balance
        uint256 input1 = balanceOf(user);
        currentSupply = currentSupply.add(amount);

        // transfer amount to user
        // not reenterant since this method is only called by commitState on StateReceiver which is onlySystem
        _nativeTransfer(user, amount);

        // deposit events
        emit Deposit(token, user, amount, input1, balanceOf(user));
    }

    function withdraw(uint256 amount) public payable {
        address user = msg.sender;
        // input balance
        uint256 input = balanceOf(user);

        currentSupply = currentSupply.sub(amount);
        // check for amount
        require(amount > 0 && msg.value == amount, "Insufficient amount");

        // withdraw event
        emit Withdraw(token, user, amount, input, balanceOf(user));
    }

    function name() public pure returns (string memory) {
        return "Bone Token";
    }

    function symbol() public pure returns (string memory) {
        return "BONE";
    }

    function decimals() public pure returns (uint8) {
        return DECIMALS;
    }

    function totalSupply() public pure returns (uint256) {
        return 250000000 * 10 ** uint256(DECIMALS);
    }

    function balanceOf(address account) public view returns (uint256) {
        return account.balance;
    }

    /// @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 payable returns (bool) {
        if (msg.value != value) {
            return false;
        }
        return _transferFrom(msg.sender, to, value);
    }

    /**
     * @dev _transfer is invoked by _transferFrom method that is inherited from BaseERC20.
     * This enables us to transfer Bone between users while keeping the interface same as that of an ERC20 Token.
     */
    function _transfer(
        address sender,
        address recipient,
        uint256 amount
    ) internal {
        require(recipient != address(this), "can't send to MRC20");
        _nativeTransfer(recipient, amount);
        emit Transfer(sender, recipient, amount);
    }

    // @notice method to transfer native asset to receiver (nonReentrant)
    // @dev 5000 gas is forwarded in the call to receiver
    // @dev msg.value checks (if req), emitting logs are handled seperately
    // @param receiver address to transfer native token to
    // @param amount amount of native token to transfer
    function _nativeTransfer(
        address receiver,
        uint256 amount
    ) internal nonReentrant {
        uint256 txGasLimit = 5000;
        (bool success, bytes memory ret) = receiver.call.value(amount).gas(
            txGasLimit
        )("");
        if (!success) {
            assembly {
                revert(add(ret, 0x20), mload(ret)) // bubble up revert
            }
        }
    }
}
"
    },
    "contracts/child/proxifiedChildToken/ChildERC20Proxified.sol": {
      "content": "pragma solidity ^0.5.2;

import {Initializable} from "../../common/mixin/Initializable.sol";
import "../ChildERC20.sol";

contract ChildERC20Proxified is ChildERC20, Initializable {
    constructor() public ChildERC20(address(0x1), address(0x1), "", "", 18) {}

    function initialize(
        address _token,
        string calldata name,
        string calldata symbol,
        uint8 decimals
    ) external initializer {
        require(_token != address(0x0));
        token = _token;
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

    // Overriding isOwner from Ownable.sol because owner() and transferOwnership() have been overridden by UpgradableProxy
    function isOwner() public view returns (bool) {
        address _owner;
        bytes32 position = keccak256("matic.network.proxy.owner");
        assembly {
            _owner := sload(position)
        }
        return msg.sender == _owner;
    }
}
"
    },
    "contracts/child/proxifiedChildToken/ChildERC721Proxified.sol": {
      "content": "pragma solidity ^0.5.2;

import {Initializable} from "../../common/mixin/Initializable.sol";
import "../ChildERC721.sol";

contract ChildERC721Proxified is ChildERC721, Initializable {
    string public name;
    string public symbol;

    constructor() public ChildERC721(address(0x1), address(0x1), "", "") {}

    function initialize(
        address _token,
        string calldata _name,
        string calldata _symbol
    ) external initializer {
        require(_token != address(0x0));
        token = _token;
        name = _name;
        symbol = _symbol;
    }

    // Overriding isOwner from Ownable.sol because owner() and transferOwnership() have been overridden by UpgradableProxy
    function isOwner() public view returns (bool) {
        address _owner;
        bytes32 position = keccak256("matic.network.proxy.owner");
        assembly {
            _owner := sload(position)
        }
        return msg.sender == _owner;
    }
}
"
    },
    "contracts/child/proxifiedChildToken/ChildTokenProxy.sol": {
      "content": "pragma solidity ^0.5.2;

import {UpgradableProxy} from "../../common/misc/UpgradableProxy.sol";

contract ChildTokenProxy is UpgradableProxy {
    constructor(address _proxyTo) public UpgradableProxy(_proxyTo) {}
}
"
    },
    "contracts/common/governance/Governable.sol": {
      "content": "pragma solidity ^0.5.2;

import {IGovernance} from "./IGovernance.sol";

contract Governable {
    IGovernance public governance;

    constructor(address _governance) public {
        governance = IGovernance(_governance);
    }

    modifier onlyGovernance() {
        _assertGovernance();
        _;
    }

    function _assertGovernance() private view {
        require(
            msg.sender == address(governance),
            "Only governance contract is authorized"
        );
    }
}
"
    },
    "contracts/common/governance/Governance.sol": {
      "content": "pragma solidity ^0.5.2;

import {ProxyStorage} from "../misc/ProxyStorage.sol";
import {IGovernance} from "./IGovernance.sol";


contract Governance is ProxyStorage, IGovernance {
    function update(address target, bytes memory data) public onlyOwner {
        (bool success, ) = target.call(data); /* bytes memory returnData */
        require(success, "Update failed");
    }
}
"
    },
    "contracts/common/governance/GovernanceProxy.sol": {
      "content": "pragma solidity ^0.5.2;

import {Proxy} from "../misc/Proxy.sol";

contract GovernanceProxy is Proxy {
    constructor(address _proxyTo) public Proxy(_proxyTo) {}
}
"
    },
    "contracts/common/governance/IGovernance.sol": {
      "content": "pragma solidity ^0.5.2;

interface IGovernance {
    function update(address target, bytes calldata data) external;
}
"
    },
    "contracts/common/lib/BytesLib.sol": {
      "content": "pragma solidity ^0.5.2;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";

library BytesLib {
    function concat(bytes memory _preBytes, bytes memory _postBytes)
        internal
        pure
        returns (bytes memory)
    {
        bytes memory tempBytes;
        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(
                0x40,
                and(
                    add(add(end, iszero(add(length, mload(_preBytes)))), 31),
                    not(31) // Round down to the nearest 32 bytes.
                )
            )
        }
        return tempBytes;
    }

    function slice(bytes memory _bytes, uint256 _start, uint256 _length)
        internal
        pure
        returns (bytes memory)
    {
        require(_bytes.length >= (_start + _length));
        bytes memory tempBytes;
        assembly {
            switch iszero(_length)
                case 0 {
                    // Get a location of some free memory and store it in tempBytes as
                    // Solidity does for memory variables.
                    tempBytes := mload(0x40)

                    // The first word of the slice result is potentially a partial
                    // word read from the original array. To read it, we calculate
                    // the length of that partial word and start copying that many
                    // bytes into the array. The first word we copy will start with
                    // data we don't care about, but the last `lengthmod` bytes will
                    // land at the beginning of the contents of the new array. When
                    // we're done copying, we overwrite the full first word with
                    // the actual length of the slice.
                    let lengthmod := and(_length, 31)

                    // The multiplication in the next line is necessary
                    // because when slicing multiples of 32 bytes (lengthmod == 0)
                    // the following copy loop was copying the origin's length
                    // and then ending prematurely not copying everything it should.
                    let mc := add(
                        add(tempBytes, lengthmod),
                        mul(0x20, iszero(lengthmod))
                    )
                    let end := add(mc, _length)

                    for {
                        // The multiplication in the next line has the same exact purpose
                        // as the one above.
                        let cc := add(
                            add(
                                add(_bytes, lengthmod),
                                mul(0x20, iszero(lengthmod))
                            ),
                            _start
                        )
                    } lt(mc, end) {
                        mc := add(mc, 0x20)
                        cc := add(cc, 0x20)
                    } {
                        mstore(mc, mload(cc))
                    }

                    mstore(tempBytes, _length)

                    //update free-memory pointer
                    //allocating the array padded to 32 bytes like the compiler does now
                    mstore(0x40, and(add(mc, 31), not(31)))
                }
                //if we want a zero-length slice let's just return a zero-length array
                default {
                    tempBytes := mload(0x40)
                    mstore(0x40, add(tempBytes, 0x20))
                }
        }

        return tempBytes;
    }

    // Pad a bytes array to 32 bytes
    function leftPad(bytes memory _bytes) internal pure returns (bytes memory) {
        // may underflow if bytes.length < 32. Hence using SafeMath.sub
        bytes memory newBytes = new bytes(SafeMath.sub(32, _bytes.length));
        return concat(newBytes, _bytes);
    }

    function toBytes32(bytes memory b) internal pure returns (bytes32) {
        require(b.length >= 32, "Bytes array should atleast be 32 bytes");
        bytes32 out;
        for (uint256 i = 0; i < 32; i++) {
            out |= bytes32(b[i] & 0xFF) >> (i * 8);
        }
        return out;
    }

    function toBytes4(bytes memory b) internal pure returns (bytes4 result) {
        assembly {
            result := mload(add(b, 32))
        }
    }

    function fromBytes32(bytes32 x) internal pure returns (bytes memory) {
        bytes memory b = new bytes(32);
        for (uint256 i = 0; i < 32; i++) {
            b[i] = bytes1(uint8(uint256(x) / (2**(8 * (31 - i)))));
        }
        return b;
    }

    function fromUint(uint256 _num) internal pure returns (bytes memory _ret) {
        _ret = new bytes(32);
        assembly {
            mstore(add(_ret, 32), _num)
        }
    }

    function toUint(bytes memory _bytes, uint256 _start)
        internal
        pure
        returns (uint256)
    {
        require(_bytes.length >= (_start + 32));
        uint256 tempUint;
        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }
        return tempUint;
    }

    function toAddress(bytes memory _bytes, uint256 _start)
        internal
        pure
        returns (address)
    {
        require(_bytes.length >= (_start + 20));
        address tempAddress;
        assembly {
            tempAddress := div(
                mload(add(add(_bytes, 0x20), _start)),
                0x1000000000000000000000000
            )
        }

        return tempAddress;
    }
}
"
    },
    "contracts/common/lib/Common.sol": {
      "content": "pragma solidity ^0.5.2;

import "./BytesLib.sol";

library Common {
    function getV(bytes memory v, uint16 chainId) public pure returns (uint8) {
        if (chainId > 0) {
            return
                uint8(
                    BytesLib.toUint(BytesLib.leftPad(v), 0) - (chainId * 2) - 8
                );
        } else {
            return uint8(BytesLib.toUint(BytesLib.leftPad(v), 0));
        }
    }

    //assemble the given address bytecode. If bytecode exists then the _addr is a contract.
    function isContract(address _addr) public view returns (bool) {
        uint256 length;
        assembly {
            //retrieve the size of the code on target address, this needs assembly
            length := extcodesize(_addr)
        }
        return (length > 0);
    }

    // convert bytes to uint8
    function toUint8(bytes memory _arg) public pure returns (uint8) {
        return uint8(_arg[0]);
    }

    function toUint16(bytes memory _arg) public pure returns (uint16) {
        return (uint16(uint8(_arg[0])) << 8) | uint16(uint8(_arg[1]));
    }
}
"
    },
    "contracts/common/lib/ECVerify.sol": {
      "content": "pragma solidity ^0.5.2;


library ECVerify {
    function ecrecovery(bytes32 hash, uint[3] memory sig)
        internal
        pure
        returns (address)
    {
        bytes32 r;
        bytes32 s;
        uint8 v;

        assembly {
            r := mload(sig)
            s := mload(add(sig, 32))
            v := byte(31, mload(add(sig, 64)))
        }

        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return address(0x0);
        }

        // 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
        address result = ecrecover(hash, v, r, s);

        // ecrecover returns zero on error
        require(result != address(0x0));

        return result;
    }

    function ecrecovery(bytes32 hash, bytes memory sig)
        internal
        pure
        returns (address)
    {
        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
        address result = ecrecover(hash, v, r, s);

        // ecrecover returns zero on error
        require(result != address(0x0));

        return result;
    }

    function ecrecovery(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        pure
        returns (address)
    {
        // get address out of hash and signature
        address result = ecrecover(hash, v, r, s);

        // ecrecover returns zero on error
        require(result != address(0x0), "signature verification failed");

        return result;
    }

    function ecverify(bytes32 hash, bytes memory sig, address signer)
        internal
        pure
        returns (bool)
    {
        return signer == ecrecovery(hash, sig);
    }
}
"
    },
    "contracts/common/lib/ExitPayloadReader.sol": {
      "content": "pragma solidity 0.5.17;

import {RLPReader} from "./RLPReader.sol";
import {BytesLib} from "./BytesLib.sol";

library ExitPayloadReader {
  using RLPReader for bytes;
  using RLPReader for RLPReader.RLPItem;

  uint8 constant WORD_SIZE = 32;

  struct ExitPayload {
    RLPReader.RLPItem[] data;
  }

  struct Receipt {
    RLPReader.RLPItem[] data;
    bytes raw;
    uint256 logIndex;
  }

  struct Log {
    RLPReader.RLPItem data;
    RLPReader.RLPItem[] list;
  }

  struct LogTopics {
    RLPReader.RLPItem[] data;
  }

  function toExitPayload(bytes memory data)
        internal
        pure
        returns (ExitPayload memory)
    {
        RLPReader.RLPItem[] memory payloadData = data
            .toRlpItem()
            .toList();

        return ExitPayload(payloadData);
    }

    function copy(uint src, uint dest, uint len) private pure {
        if (len == 0) return;

        // copy as many word sizes as possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }

            src += WORD_SIZE;
            dest += WORD_SIZE;
        }

        // left over bytes. Mask is used to remove unwanted bytes from the word
        uint mask = 256 ** (WORD_SIZE - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask)) // zero out src
            let destpart := and(mload(dest), mask) // retrieve the bytes
            mstore(dest, or(destpart, srcpart))
        }
    }

    function getHeaderNumber(ExitPayload memory payload) internal pure returns(uint256) {
      return payload.data[0].toUint();
    }

    function getBlockProof(ExitPayload memory payload) internal pure returns(bytes memory) {
      return payload.data[1].toBytes();
    }

    function getBlockNumber(ExitPayload memory payload) internal pure returns(uint256) {
      return payload.data[2].toUint();
    }

    function getBlockTime(ExitPayload memory payload) internal pure returns(uint256) {
      return payload.data[3].toUint();
    }

    function getTxRoot(ExitPayload memory payload) internal pure returns(bytes32) {
      return bytes32(payload.data[4].toUint());
    }

    function getReceiptRoot(ExitPayload memory payload) internal pure returns(bytes32) {
      return bytes32(payload.data[5].toUint());
    }

    function getReceipt(ExitPayload memory payload) internal pure returns(Receipt memory receipt) {
      receipt.raw = payload.data[6].toBytes();
      RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();

      if (receiptItem.isList()) {
          // legacy tx
          receipt.data = receiptItem.toList();
      } else {
          // pop first byte before parsting receipt
          bytes memory typedBytes = receipt.raw;
          bytes memory result = new bytes(typedBytes.length - 1);
          uint256 srcPtr;
          uint256 destPtr;
          assembly {
              srcPtr := add(33, typedBytes)
              destPtr := add(0x20, result)
          }

          copy(srcPtr, destPtr, result.length);
          receipt.data = result.toRlpItem().toList();
      }

      receipt.logIndex = getReceiptLogIndex(payload);
      return receipt;
    }

    function getReceiptProof(ExitPayload memory payload) internal pure returns(bytes memory) {
      return payload.data[7].toBytes();
    }

    function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns(bytes memory) {
      return payload.data[8].toBytes();
    }

    function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns(uint256) {
      return payload.data[8].toUint();
    }

    function getReceiptLogIndex(ExitPayload memory payload) internal pure returns(uint256) {
      return payload.data[9].toUint();
    }

    function getTx(ExitPayload memory payload) internal pure returns(bytes memory) {
      return payload.data[10].toBytes();
    }

    function getTxProof(ExitPayload memory payload) internal pure returns(bytes memory) {
      return payload.data[11].toBytes();
    }
    
    // Receipt methods
    function toBytes(Receipt memory receipt) internal pure returns(bytes memory) {
        return receipt.raw;
    }

    function getLog(Receipt memory receipt) internal pure returns(Log memory) {
        RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];
        return Log(logData, logData.toList());
    }

    // Log methods
    function getEmitter(Log memory log) internal pure returns(address) {
      return RLPReader.toAddress(log.list[0]);
    }

    function getTopics(Log memory log) internal pure returns(LogTopics memory) {
        return LogTopics(log.list[1].toList());
    }

    function getData(Log memory log) internal pure returns(bytes memory) {
        return log.list[2].toBytes();
    }

    function toRlpBytes(Log memory log) internal pure returns(bytes memory) {
      return log.data.toRlpBytes();
    }

    // LogTopics methods
    function getField(LogTopics memory topics, uint256 index) internal pure returns(RLPReader.RLPItem memory) {
      return topics.data[index];
    }
}"
    },
    "contracts/common/lib/Merkle.sol": {
      "content": "pragma solidity ^0.5.2;

library Merkle {
    function checkMembership(
        bytes32 leaf,
        uint256 index,
        bytes32 rootHash,
        bytes memory proof
    ) internal pure returns (bool) {
        require(proof.length % 32 == 0, "Invalid proof length");
        uint256 proofHeight = proof.length / 32;
        // Proof of size n means, height of the tree is n+1.
        // In a tree of height n+1, max #leafs possible is 2 ^ n
        require(index < 2 ** proofHeight, "Leaf index is too big");

        bytes32 proofElement;
        bytes32 computedHash = leaf;
        for (uint256 i = 32; i <= proof.length; i += 32) {
            assembly {
                proofElement := mload(add(proof, i))
            }

            if (index % 2 == 0) {
                computedHash = keccak256(
                    abi.encodePacked(computedHash, proofElement)
                );
            } else {
                computedHash = keccak256(
                    abi.encodePacked(proofElement, computedHash)
                );
            }

            index = index / 2;
        }
        return computedHash == rootHash;
    }
}
"
    },
    "contracts/common/lib/MerklePatriciaProof.sol": {
      "content": "pragma solidity ^0.5.2;

import {RLPReader} from "./RLPReader.sol";

library MerklePatriciaProof {
    /*
   * @dev Verifies a merkle patricia proof.
   * @param value The terminating value in the trie.
   * @param encodedPath The path in the trie leading to value.
   * @param rlpParentNodes The rlp encoded stack of nodes.
   * @param root The root hash of the trie.
   * @return The boolean validity of the proof.
   */
    function verify(
        bytes memory value,
        bytes memory encodedPath,
        bytes memory rlpParentNodes,
        bytes32 root
    ) internal pure returns (bool) {
        RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes);
        RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item);

        bytes memory currentNode;
        RLPReader.RLPItem[] memory currentNodeList;

        bytes32 nodeKey = root;
        uint256 pathPtr = 0;

        bytes memory path = _getNibbleArray(encodedPath);
        if (path.length == 0) {
            return false;
        }

        for (uint256 i = 0; i < parentNodes.length; i++) {
            if (pathPtr > path.length) {
                return false;
            }

            currentNode = RLPReader.toRlpBytes(parentNodes[i]);
            if (nodeKey != keccak256(currentNode)) {
                return false;
            }
            currentNodeList = RLPReader.toList(parentNodes[i]);

            if (currentNodeList.length == 17) {
                if (pathPtr == path.length) {
                    if (
                        keccak256(RLPReader.toBytes(currentNodeList[16])) ==
                        keccak256(value)
                    ) {
                        return true;
                    } else {
                        return false;
                    }
                }

                uint8 nextPathNibble = uint8(path[pathPtr]);
                if (nextPathNibble > 16) {
                    return false;
                }
                nodeKey = bytes32(
                    RLPReader.toUintStrict(currentNodeList[nextPathNibble])
                );
                pathPtr += 1;
            } else if (currentNodeList.length == 2) {
                bytes memory nodeValue = RLPReader.toBytes(currentNodeList[0]);
                uint256 traversed = _nibblesToTraverse(
                    nodeValue,
                    path,
                    pathPtr
                );
                //enforce correct nibble
                bytes1 prefix = _getNthNibbleOfBytes(0, nodeValue);
                if (pathPtr + traversed == path.length) {
                    //leaf node
                    if (
                        keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value) && 
                        (prefix == bytes1(uint8(2)) || prefix == bytes1(uint8(3)))
                    ) {
                        return true;
                    } else {
                        return false;
                    }
                }
                //extension node
                if (traversed == 0 || (prefix != bytes1(uint8(0)) && prefix != bytes1(uint8(1)))) {
                    return false;
                }

                pathPtr += traversed;
                nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1]));

            } else {
                return false;
            }
        }
    }

    function _nibblesToTraverse(
        bytes memory encodedPartialPath,
        bytes memory path,
        uint256 pathPtr
    ) private pure returns (uint256) {
        uint256 len;
        // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath
        // and slicedPath have elements that are each one hex character (1 nibble)
        bytes memory partialPath = _getNibbleArray(encodedPartialPath);
        bytes memory slicedPath = new bytes(partialPath.length);

        // pathPtr counts nibbles in path
        // partialPath.length is a number of nibbles
        for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {
            bytes1 pathNibble = path[i];
            slicedPath[i - pathPtr] = pathNibble;
        }

        if (keccak256(partialPath) == keccak256(slicedPath)) {
            len = partialPath.length;
        } else {
            len = 0;
        }
        return len;
    }

    // bytes b must be hp encoded
    function _getNibbleArray(bytes memory b)
        private
        pure
        returns (bytes memory)
    {
        bytes memory nibbles;
        if (b.length > 0) {
            uint8 offset;
            uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b));
            if (hpNibble == 1 || hpNibble == 3) {
                nibbles = new bytes(b.length * 2 - 1);
                bytes1 oddNibble = _getNthNibbleOfBytes(1, b);
                nibbles[0] = oddNibble;
                offset = 1;
            } else {
                nibbles = new bytes(b.length * 2 - 2);
                offset = 0;
            }

            for (uint256 i = offset; i < nibbles.length; i++) {
                nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b);
            }
        }
        return nibbles;
    }

    function _getNthNibbleOfBytes(uint256 n, bytes memory str)
        private
        pure
        returns (bytes1)
    {
        return
            bytes1(
                n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10
            );
    }
}"
    },
    "contracts/common/lib/PriorityQueue.sol": {
      "content": "pragma solidity ^0.5.2;

import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import {SafeMath} from "openzeppelin-solidity/contracts/math/SafeMath.sol";

/**
 * @title PriorityQueue
 * @dev A priority queue implementation.
 */
contract PriorityQueue is Ownable {
    using SafeMath for uint256;

    uint256[] heapList;
    uint256 public currentSize;

    constructor() public {
        heapList = [0];
    }

    /**
  * @dev Inserts an element into the priority queue.
  * @param _priority Priority to insert.
  * @param _value Some additional value.
  */
    function insert(uint256 _priority, uint256 _value) public onlyOwner {
        uint256 element = (_priority << 128) | _value;
        heapList.push(element);
        currentSize = currentSize.add(1);
        _percUp(currentSize);
    }

    /**
  * @dev Returns the top element of the heap.
  * @return The smallest element in the priority queue.
  */
    function getMin() public view returns (uint256, uint256) {
        return _splitElement(heapList[1]);
    }

    /**
  * @dev Deletes the top element of the heap and shifts everything up.
  * @return The smallest element in the priorty queue.
  */
    function delMin() public onlyOwner returns (uint256, uint256) {
        uint256 retVal = heapList[1];
        heapList[1] = heapList[currentSize];
        delete heapList[currentSize];
        currentSize = currentSize.sub(1);
        _percDown(1);
        heapList.length = heapList.length.sub(1);
        return _splitElement(retVal);
    }

    /**
  * @dev Determines the minimum child of a given node in the tree.
  * @param _index Index of the node in the tree.
  * @return The smallest child node.
  */
    function _minChild(uint256 _index) private view returns (uint256) {
        if (_index.mul(2).add(1) > currentSize) {
            return _index.mul(2);
        } else {
            if (heapList[_index.mul(2)] < heapList[_index.mul(2).add(1)]) {
                return _index.mul(2);
            } else {
                return _index.mul(2).add(1);
            }
        }
    }

    /**
   * @dev Bubbles the element at some index up.
   */
    function _percUp(uint256 _index) private {
        uint256 index = _index;
        uint256 j = index;
        uint256 newVal = heapList[index];

        while (newVal < heapList[index.div(2)]) {
            heapList[index] = heapList[index.div(2)];
            index = index.div(2);
        }

        if (index != j) {
            heapList[index] = newVal;
        }
    }

    /**
   * @dev Bubbles the element at some index down.
   */
    function _percDown(uint256 _index) private {
        uint256 index = _index;
        uint256 j = index;
        uint256 newVal = heapList[index];
        uint256 mc = _minChild(index);
        while (mc <= currentSize && newVal > heapList[mc]) {
            heapList[index] = heapList[mc];
            index = mc;
            mc = _minChild(index);
        }

        if (index != j) {
            heapList[index] = newVal;
        }
    }

    /**
   * @dev Split an element into its priority and value.
   * @param _element Element to decode.
   * @return A tuple containing the priority and value.
   */
    function _splitElement(uint256 _element)
        private
        pure
        returns (uint256, uint256)
    {
        uint256 priority = _element >> 128;
        uint256 value = uint256(uint128(_element));
        return (priority, value);
    }
}
"
    },
    "contracts/common/lib/RLPEncode.sol": {
      "content": "// Library for RLP encoding a list of bytes arrays.
// Modeled after ethereumjs/rlp (https://github.com/ethereumjs/rlp)
// [Very] modified version of Sam Mayo's library.
pragma solidity ^0.5.2;

import "./BytesLib.sol";

library RLPEncode {
    // Encode an item (bytes memory)
    function encodeItem(bytes memory self)
        internal
        pure
        returns (bytes memory)
    {
        bytes memory encoded;
        if (self.length == 1 && uint8(self[0] & 0xFF) < 0x80) {
            encoded = new bytes(1);
            encoded = self;
        } else {
            encoded = BytesLib.concat(encodeLength(self.length, 128), self);
        }
        return encoded;
    }

    // Encode a list of items
    function encodeList(bytes[] memory self)
        internal
        pure
        returns (bytes memory)
    {
        bytes memory encoded;
        for (uint256 i = 0; i < self.length; i++) {
            encoded = BytesLib.concat(encoded, encodeItem(self[i]));
        }
        return BytesLib.concat(encodeLength(encoded.length, 192), encoded);
    }

    // Hack to encode nested lists. If you have a list as an item passed here, included
    // pass = true in that index. E.g.
    // [item, list, item] --> pass = [false, true, false]
    // function encodeListWithPasses(bytes[] memory self, bool[] pass) internal pure returns (bytes memory) {
    //   bytes memory encoded;
    //   for (uint i=0; i < self.length; i++) {
    // 		if (pass[i] == true) {
    // 			encoded = BytesLib.concat(encoded, self[i]);
    // 		} else {
    // 			encoded = BytesLib.concat(encoded, encodeItem(self[i]));
    // 		}
    //   }
    //   return BytesLib.concat(encodeLength(encoded.length, 192), encoded);
    // }

    // Generate the prefix for an item or the entire list based on RLP spec
    function encodeLength(uint256 L, uint256 offset)
        internal
        pure
        returns (bytes memory)
    {
        if (L < 56) {
            bytes memory prefix = new bytes(1);
            prefix[0] = bytes1(uint8(L + offset));
            return prefix;
        } else {
            // lenLen is the length of the hex representation of the data length
            uint256 lenLen;
            uint256 i = 0x1;

            while (L / i != 0) {
                le

Tags:
ERC20, ERC721, ERC165, Multisig, Mintable, Burnable, Non-Fungible, Swap, Staking, Voting, Upgradeable, Multi-Signature, Factory|addr:0xd12b1d5f28736ce0bfd9330f5595d3ffe6e01a97|verified:true|block:23569678|tx:0xcc4d491ac10127780cc186827eb971ba5467ba4cc1afba522aabfb8495c5660c|first_check:1760372876

Submitted on: 2025-10-13 18:27:56

Comments

Log in to comment.

No comments yet.