false
false
5713000

Contract Address Details

0x7f70d0047Ae63131ab77F179a90F1a41CeEA93Aa

Contract Name
RapidityLibV4
Creator
0xdb1388–e98779 at 0xa2c2da–37c646
Balance
0 PUNDIAI
Tokens
Fetching tokens...
Transactions
0 Transactions
Transfers
0 Transfers
Gas Used
Fetching gas used...
Last Balance Update
22386122
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
RapidityLibV4




Optimization enabled
true
Compiler version
v0.4.26+commit.4563c3fc




Optimization runs
200
EVM Version
byzantium




Verified at
2023-04-20T02:39:08.328226Z

Contract source code

// File: openzeppelin-eth/contracts/math/SafeMath.sol

pragma solidity ^0.4.24;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, 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 numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts when dividing by 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 numbers, 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 numbers, 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 numbers 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/crossApproach/lib/HTLCTxLib.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;
pragma experimental ABIEncoderV2;


library HTLCTxLib {
    using SafeMath for uint;

    /**
     *
     * ENUMS
     *
     */

    /// @notice tx info status
    /// @notice uninitialized,locked,redeemed,revoked
    enum TxStatus {None, Locked, Redeemed, Revoked, AssetLocked, DebtLocked}

    /**
     *
     * STRUCTURES
     *
     */

    /// @notice struct of HTLC user mint lock parameters
    struct HTLCUserParams {
        bytes32 xHash;                  /// hash of HTLC random number
        bytes32 smgID;                  /// ID of storeman group which user has selected
        uint tokenPairID;               /// token pair id on cross chain
        uint value;                     /// exchange token value
        uint lockFee;                   /// exchange token value
        uint lockedTime;                /// HTLC lock time
    }

    /// @notice HTLC(Hashed TimeLock Contract) tx info
    struct BaseTx {
        bytes32 smgID;                  /// HTLC transaction storeman ID
        uint lockedTime;                /// HTLC transaction locked time
        uint beginLockedTime;           /// HTLC transaction begin locked time
        TxStatus status;                /// HTLC transaction status
    }

    /// @notice user  tx info
    struct UserTx {
        BaseTx baseTx;
        uint tokenPairID;
        uint value;
        uint fee;
        address userAccount;            /// HTLC transaction sender address for the security check while user's revoke
    }
    /// @notice storeman  tx info
    struct SmgTx {
        BaseTx baseTx;
        uint tokenPairID;
        uint value;
        address  userAccount;          /// HTLC transaction user address for the security check while user's redeem
    }
    /// @notice storeman  debt tx info
    struct DebtTx {
        BaseTx baseTx;
        bytes32 srcSmgID;              /// HTLC transaction sender(source storeman) ID
    }

    struct Data {
        /// @notice mapping of hash(x) to UserTx -- xHash->htlcUserTxData
        mapping(bytes32 => UserTx) mapHashXUserTxs;

        /// @notice mapping of hash(x) to SmgTx -- xHash->htlcSmgTxData
        mapping(bytes32 => SmgTx) mapHashXSmgTxs;

        /// @notice mapping of hash(x) to DebtTx -- xHash->htlcDebtTxData
        mapping(bytes32 => DebtTx) mapHashXDebtTxs;

    }

    /**
     *
     * MANIPULATIONS
     *
     */

    /// @notice                     add user transaction info
    /// @param params               parameters for user tx
    function addUserTx(Data storage self, HTLCUserParams memory params)
        public
    {
        UserTx memory userTx = self.mapHashXUserTxs[params.xHash];
        // UserTx storage userTx = self.mapHashXUserTxs[params.xHash];
        // require(params.value != 0, "Value is invalid");
        require(userTx.baseTx.status == TxStatus.None, "User tx exists");

        userTx.baseTx.smgID = params.smgID;
        userTx.baseTx.lockedTime = params.lockedTime;
        userTx.baseTx.beginLockedTime = now;
        userTx.baseTx.status = TxStatus.Locked;
        userTx.tokenPairID = params.tokenPairID;
        userTx.value = params.value;
        userTx.fee = params.lockFee;
        userTx.userAccount = msg.sender;

        self.mapHashXUserTxs[params.xHash] = userTx;
    }

    /// @notice                     refund coins from HTLC transaction, which is used for storeman redeem(outbound)
    /// @param x                    HTLC random number
    function redeemUserTx(Data storage self, bytes32 x)
        external
        returns(bytes32 xHash)
    {
        xHash = sha256(abi.encodePacked(x));

        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        require(userTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now < userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime), "Redeem timeout");

        userTx.baseTx.status = TxStatus.Redeemed;

        return xHash;
    }

    /// @notice                     revoke user transaction
    /// @param  xHash               hash of HTLC random number
    function revokeUserTx(Data storage self, bytes32 xHash)
        external
    {
        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        require(userTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now >= userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime), "Revoke is not permitted");

        userTx.baseTx.status = TxStatus.Revoked;
    }

    /// @notice                    function for get user info
    /// @param xHash               hash of HTLC random number
    /// @return smgID              ID of storeman which user has selected
    /// @return tokenPairID        token pair ID of cross chain
    /// @return value              exchange value
    /// @return fee                exchange fee
    /// @return userAccount        HTLC transaction sender address for the security check while user's revoke
    function getUserTx(Data storage self, bytes32 xHash)
        external
        view
        returns (bytes32, uint, uint, uint, address)
    {
        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        return (userTx.baseTx.smgID, userTx.tokenPairID, userTx.value, userTx.fee, userTx.userAccount);
    }

    /// @notice                     add storeman transaction info
    /// @param  xHash               hash of HTLC random number
    /// @param  smgID               ID of the storeman which user has selected
    /// @param  tokenPairID         token pair ID of cross chain
    /// @param  value               HTLC transfer value of token
    /// @param  userAccount            user account address on the destination chain, which is used to redeem token
    function addSmgTx(Data storage self, bytes32 xHash, bytes32 smgID, uint tokenPairID, uint value, address userAccount, uint lockedTime)
        external
    {
        SmgTx memory smgTx = self.mapHashXSmgTxs[xHash];
        // SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        require(value != 0, "Value is invalid");
        require(smgTx.baseTx.status == TxStatus.None, "Smg tx exists");

        smgTx.baseTx.smgID = smgID;
        smgTx.baseTx.status = TxStatus.Locked;
        smgTx.baseTx.lockedTime = lockedTime;
        smgTx.baseTx.beginLockedTime = now;
        smgTx.tokenPairID = tokenPairID;
        smgTx.value = value;
        smgTx.userAccount = userAccount;

        self.mapHashXSmgTxs[xHash] = smgTx;
    }

    /// @notice                     refund coins from HTLC transaction, which is used for users redeem(inbound)
    /// @param x                    HTLC random number
    function redeemSmgTx(Data storage self, bytes32 x)
        external
        returns(bytes32 xHash)
    {
        xHash = sha256(abi.encodePacked(x));

        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        require(smgTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now < smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime), "Redeem timeout");

        smgTx.baseTx.status = TxStatus.Redeemed;

        return xHash;
    }

    /// @notice                     revoke storeman transaction
    /// @param  xHash               hash of HTLC random number
    function revokeSmgTx(Data storage self, bytes32 xHash)
        external
    {
        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        require(smgTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(now >= smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime), "Revoke is not permitted");

        smgTx.baseTx.status = TxStatus.Revoked;
    }

    /// @notice                     function for get smg info
    /// @param xHash                hash of HTLC random number
    /// @return smgID               ID of storeman which user has selected
    /// @return tokenPairID         token pair ID of cross chain
    /// @return value               exchange value
    /// @return userAccount            user account address for redeem
    function getSmgTx(Data storage self, bytes32 xHash)
        external
        view
        returns (bytes32, uint, uint, address)
    {
        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        return (smgTx.baseTx.smgID, smgTx.tokenPairID, smgTx.value, smgTx.userAccount);
    }

    /// @notice                     add storeman transaction info
    /// @param  xHash               hash of HTLC random number
    /// @param  srcSmgID            ID of source storeman group
    /// @param  destSmgID           ID of the storeman which will take over of the debt of source storeman group
    /// @param  lockedTime          HTLC lock time
    /// @param  status              Status, should be 'Locked' for asset or 'DebtLocked' for debt
    function addDebtTx(Data storage self, bytes32 xHash, bytes32 srcSmgID, bytes32 destSmgID, uint lockedTime, TxStatus status)
        external
    {
        DebtTx memory debtTx = self.mapHashXDebtTxs[xHash];
        // DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        require(debtTx.baseTx.status == TxStatus.None, "Debt tx exists");

        debtTx.baseTx.smgID = destSmgID;
        debtTx.baseTx.status = status;//TxStatus.Locked;
        debtTx.baseTx.lockedTime = lockedTime;
        debtTx.baseTx.beginLockedTime = now;
        debtTx.srcSmgID = srcSmgID;

        self.mapHashXDebtTxs[xHash] = debtTx;
    }

    /// @notice                     refund coins from HTLC transaction
    /// @param x                    HTLC random number
    /// @param status               Status, should be 'Locked' for asset or 'DebtLocked' for debt
    function redeemDebtTx(Data storage self, bytes32 x, TxStatus status)
        external
        returns(bytes32 xHash)
    {
        xHash = sha256(abi.encodePacked(x));

        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        // require(debtTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(debtTx.baseTx.status == status, "Status is not locked");
        require(now < debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime), "Redeem timeout");

        debtTx.baseTx.status = TxStatus.Redeemed;

        return xHash;
    }

    /// @notice                     revoke debt transaction, which is used for source storeman group
    /// @param  xHash               hash of HTLC random number
    /// @param  status              Status, should be 'Locked' for asset or 'DebtLocked' for debt
    function revokeDebtTx(Data storage self, bytes32 xHash, TxStatus status)
        external
    {
        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        // require(debtTx.baseTx.status == TxStatus.Locked, "Status is not locked");
        require(debtTx.baseTx.status == status, "Status is not locked");
        require(now >= debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime), "Revoke is not permitted");

        debtTx.baseTx.status = TxStatus.Revoked;
    }

    /// @notice                     function for get debt info
    /// @param xHash                hash of HTLC random number
    /// @return srcSmgID            ID of source storeman
    /// @return destSmgID           ID of destination storeman
    function getDebtTx(Data storage self, bytes32 xHash)
        external
        view
        returns (bytes32, bytes32)
    {
        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        return (debtTx.srcSmgID, debtTx.baseTx.smgID);
    }

    function getLeftTime(uint endTime) private view returns (uint) {
        if (now < endTime) {
            return endTime.sub(now);
        }
        return 0;
    }

    /// @notice                     function for get debt info
    /// @param xHash                hash of HTLC random number
    /// @return leftTime            the left lock time
    function getLeftLockedTime(Data storage self, bytes32 xHash)
        external
        view
        returns (uint)
    {
        UserTx storage userTx = self.mapHashXUserTxs[xHash];
        if (userTx.baseTx.status != TxStatus.None) {
            return getLeftTime(userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime));
        }
        SmgTx storage smgTx = self.mapHashXSmgTxs[xHash];
        if (smgTx.baseTx.status != TxStatus.None) {
            return getLeftTime(smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime));
        }
        DebtTx storage debtTx = self.mapHashXDebtTxs[xHash];
        if (debtTx.baseTx.status != TxStatus.None) {
            return getLeftTime(debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime));
        }
        require(false, 'invalid xHash');
    }
}

// File: contracts/interfaces/ISignatureVerifier.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity 0.4.26;

interface ISignatureVerifier {
  function verify(
        uint curveId,
        bytes32 signature,
        bytes32 groupKeyX,
        bytes32 groupKeyY,
        bytes32 randomPointX,
        bytes32 randomPointY,
        bytes32 message
    ) external returns (bool);
}

// File: contracts/interfaces/ITokenManager.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity 0.4.26;

interface ITokenManager {
    function getTokenPairInfo(uint id) external view
      returns (uint origChainID, bytes tokenOrigAccount, uint shadowChainID, bytes tokenShadowAccount);

    function getTokenPairInfoSlim(uint id) external view
      returns (uint origChainID, bytes tokenOrigAccount, uint shadowChainID);

    function getAncestorInfo(uint id) external view
      returns (bytes account, string name, string symbol, uint8 decimals, uint chainId);

    function mintToken(address tokenAddress, address to, uint value) external;

    function burnToken(address tokenAddress, address from, uint value) external;

    function mapTokenPairType(uint tokenPairID) external view
      returns (uint8 tokenPairType);

    // erc1155
    function mintNFT(uint tokenCrossType, address tokenAddress, address to, uint[] ids, uint[] values, bytes data) public;
    function burnNFT(uint tokenCrossType, address tokenAddress, address from, uint[] ids, uint[] values) public;
}

// File: contracts/interfaces/IStoremanGroup.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.24;

interface IStoremanGroup {
    function getSelectedSmNumber(bytes32 groupId) external view returns(uint number);
    function getStoremanGroupConfig(bytes32 id) external view returns(bytes32 groupId, uint8 status, uint deposit, uint chain1, uint chain2, uint curve1, uint curve2,  bytes gpk1, bytes gpk2, uint startTime, uint endTime);
    function getDeposit(bytes32 id) external view returns(uint);
    function getStoremanGroupStatus(bytes32 id) external view returns(uint8 status, uint startTime, uint endTime);
    function setGpk(bytes32 groupId, bytes gpk1, bytes gpk2) external;
    function setInvalidSm(bytes32 groupId, uint[] indexs, uint8[] slashTypes) external returns(bool isContinue);
    function getThresholdByGrpId(bytes32 groupId) external view returns (uint);
    function getSelectedSmInfo(bytes32 groupId, uint index) external view returns(address wkAddr, bytes PK, bytes enodeId);
    function recordSmSlash(address wk) external;
}

// File: contracts/interfaces/IQuota.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity 0.4.26;

interface IQuota {
  function userLock(uint tokenId, bytes32 storemanGroupId, uint value) external;
  function userBurn(uint tokenId, bytes32 storemanGroupId, uint value) external;

  function smgRelease(uint tokenId, bytes32 storemanGroupId, uint value) external;
  function smgMint(uint tokenId, bytes32 storemanGroupId, uint value) external;

  function upgrade(bytes32 storemanGroupId) external;

  function transferAsset(bytes32 srcStoremanGroupId, bytes32 dstStoremanGroupId) external;
  function receiveDebt(bytes32 srcStoremanGroupId, bytes32 dstStoremanGroupId) external;

  function getUserMintQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);
  function getSmgMintQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);

  function getUserBurnQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);
  function getSmgBurnQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint);

  function getAsset(uint tokenId, bytes32 storemanGroupId) external view returns (uint asset, uint asset_receivable, uint asset_payable);
  function getDebt(uint tokenId, bytes32 storemanGroupId) external view returns (uint debt, uint debt_receivable, uint debt_payable);

  function isDebtClean(bytes32 storemanGroupId) external view returns (bool);
}

// File: contracts/interfaces/IRC20Protocol.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;

interface IRC20Protocol {
    function transfer(address, uint) external returns (bool);
    function transferFrom(address, address, uint) external returns (bool);
    function balanceOf(address _owner) external view returns (uint);
}
// File: contracts/crossApproach/lib/RapidityTxLib.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;

library RapidityTxLib {

    /**
     *
     * ENUMS
     *
     */

    /// @notice tx info status
    /// @notice uninitialized,Redeemed
    enum TxStatus {None, Redeemed}

    /**
     *
     * STRUCTURES
     *
     */
    struct Data {
        /// @notice mapping of uniqueID to TxStatus -- uniqueID->TxStatus
        mapping(bytes32 => TxStatus) mapTxStatus;

    }

    /**
     *
     * MANIPULATIONS
     *
     */

    /// @notice                     add user transaction info
    /// @param  uniqueID            Rapidity random number
    function addRapidityTx(Data storage self, bytes32 uniqueID)
        internal
    {
        TxStatus status = self.mapTxStatus[uniqueID];
        require(status == TxStatus.None, "Rapidity tx exists");
        self.mapTxStatus[uniqueID] = TxStatus.Redeemed;
    }
}

// File: contracts/crossApproach/lib/CrossTypesV1.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;








library CrossTypesV1 {
    using SafeMath for uint;

    /**
     *
     * STRUCTURES
     *
     */

    struct Data {

        /// map of the htlc transaction info
        HTLCTxLib.Data htlcTxData;

        /// map of the rapidity transaction info
        RapidityTxLib.Data rapidityTxData;

        /// quota data of storeman group
        IQuota quota;

        /// token manager instance interface
        ITokenManager tokenManager;

        /// storemanGroup admin instance interface
        IStoremanGroup smgAdminProxy;

        /// storemanGroup fee admin instance address
        address smgFeeProxy;

        ISignatureVerifier sigVerifier;

        /// @notice transaction fee, smgID => fee
        mapping(bytes32 => uint) mapStoremanFee;

        /// @notice transaction fee, origChainID => shadowChainID => fee
        mapping(uint => mapping(uint =>uint)) mapContractFee;

        /// @notice transaction fee, origChainID => shadowChainID => fee
        mapping(uint => mapping(uint =>uint)) mapAgentFee;

    }

    /**
     *
     * MANIPULATIONS
     *
     */

    // /// @notice       convert bytes32 to address
    // /// @param b      bytes32
    // function bytes32ToAddress(bytes32 b) internal pure returns (address) {
    //     return address(uint160(bytes20(b))); // high
    //     // return address(uint160(uint256(b))); // low
    // }

    /// @notice       convert bytes to address
    /// @param b      bytes
    function bytesToAddress(bytes b) internal pure returns (address addr) {
        assembly {
            addr := mload(add(b,20))
        }
    }

    function transfer(address tokenScAddr, address to, uint value)
        internal
        returns(bool)
    {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        // IRC20Protocol(tokenScAddr).transfer(to, value);
        tokenScAddr.call(bytes4(keccak256("transfer(address,uint256)")), to, value);
        afterBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        return afterBalance == beforeBalance.add(value);
    }

    function transferFrom(address tokenScAddr, address from, address to, uint value)
        internal
        returns(bool)
    {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        // IRC20Protocol(tokenScAddr).transferFrom(from, to, value);
        tokenScAddr.call(bytes4(keccak256("transferFrom(address,address,uint256)")), from, to, value);
        afterBalance = IRC20Protocol(tokenScAddr).balanceOf(to);
        return afterBalance == beforeBalance.add(value);
    }
}

// File: contracts/crossApproach/lib/RapidityLibV4.sol

/*

  Copyright 2019 Wanchain Foundation.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

//                            _           _           _
//  __      ____ _ _ __   ___| |__   __ _(_)_ __   __| | _____   __
//  \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / /
//   \ V  V / (_| | | | | (__| | | | (_| | | | | | (_| |  __/\ V /
//    \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/
//
//

pragma solidity ^0.4.26;





library RapidityLibV4 {
    using SafeMath for uint;
    using RapidityTxLib for RapidityTxLib.Data;

    enum TokenCrossType {ERC20, ERC721, ERC1155}

    /**
    *
    * STRUCTURES
    *
    */

    /// @notice struct of Rapidity storeman mint lock parameters
    struct RapidityUserLockParams {
        bytes32 smgID;                    /// ID of storeman group which user has selected
        uint tokenPairID;                 /// token pair id on cross chain
        uint value;                       /// exchange token value
        uint currentChainID;              /// current chain ID
        uint tokenPairContractFee;        /// fee of token pair
        bytes destUserAccount;            /// account of shadow chain, used to receive token
        address smgFeeProxy;              /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity storeman mint lock parameters
    struct RapiditySmgMintParams {
        bytes32 uniqueID;                 /// Rapidity random number
        bytes32 smgID;                    /// ID of storeman group which user has selected
        uint tokenPairID;                 /// token pair id on cross chain
        uint value;                       /// exchange token value
        uint fee;                         /// exchange token fee
        address destTokenAccount;         /// shadow token account
        address destUserAccount;          /// account of shadow chain, used to receive token
        address smgFeeProxy;              /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity user burn lock parameters
    struct RapidityUserBurnParams {
        bytes32 smgID;                  /// ID of storeman group which user has selected
        uint tokenPairID;               /// token pair id on cross chain
        uint value;                     /// exchange token value
        uint currentChainID;            /// current chain ID
        uint fee;                       /// exchange token fee
        uint tokenPairContractFee;      /// fee of token pair
        address srcTokenAccount;        /// shadow token account
        bytes destUserAccount;          /// account of token destination chain, used to receive token
        address smgFeeProxy;            /// address of the proxy to store fee for storeman group
    }

    /// @notice struct of Rapidity user burn lock parameters
    struct RapiditySmgReleaseParams {
        bytes32 uniqueID;               /// Rapidity random number
        bytes32 smgID;                  /// ID of storeman group which user has selected
        uint tokenPairID;               /// token pair id on cross chain
        uint value;                     /// exchange token value
        uint fee;                       /// exchange token fee
        address destTokenAccount;       /// original token/coin account
        address destUserAccount;        /// account of token original chain, used to receive token
        address smgFeeProxy;            /// address of the proxy to store fee for storeman group
    }

    /**
     *
     * EVENTS
     *
     **/


    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param tokenAccount             Rapidity original token account
    /// @param value                    Rapidity value
    /// @param userAccount              account of shadow chain, used to receive token
    event UserLockLogger(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, uint value, uint contractFee, bytes userAccount);

    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param tokenAccount             Rapidity shadow token account
    /// @param value                    Rapidity value
    /// @param userAccount              account of shadow chain, used to receive token
    event UserBurnLogger(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, uint value, uint contractFee, uint fee, bytes userAccount);

    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param uniqueID                 unique random number
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param value                    Rapidity value
    /// @param tokenAccount             Rapidity shadow token account
    /// @param userAccount              account of original chain, used to receive token
    event SmgMintLogger(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, uint value, address tokenAccount, address userAccount);
    event SmgMint(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values);

    /// @notice                         event of exchange WRC-20 token with original chain token request
    /// @notice                         event invoked by storeman group
    /// @param uniqueID                 unique random number
    /// @param smgID                    ID of storemanGroup
    /// @param tokenPairID              token pair ID of cross chain token
    /// @param value                    Rapidity value
    /// @param tokenAccount             Rapidity original token account
    /// @param userAccount              account of original chain, used to receive token
    event SmgReleaseLogger(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, uint value, address tokenAccount, address userAccount);
    event SmgRelease(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values);

    /**
    *
    * MANIPULATIONS
    *
    */

    /// @notice                         mintBridge, user lock token on token original chain
    /// @notice                         event invoked by user mint lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for user mint lock token on token original chain
    function userLock(CrossTypesV1.Data storage storageData, RapidityUserLockParams memory params)
    public
    {
        ITokenManager tokenManager = storageData.tokenManager;
        uint fromChainID;
        uint toChainID;
        bytes memory fromTokenAccount;
        bytes memory toTokenAccount;
        (fromChainID,fromTokenAccount,toChainID,toTokenAccount) = tokenManager.getTokenPairInfo(params.tokenPairID);
        require(fromChainID != 0, "Token does not exist");

        uint contractFee = params.tokenPairContractFee;
        address tokenScAddr;
        if (params.currentChainID == fromChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[fromChainID][toChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(fromTokenAccount);
        } else if (params.currentChainID == toChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[toChainID][fromChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(toTokenAccount);
        } else {
            require(false, "Invalid token pair");
        }
        if (contractFee > 0) {
            params.smgFeeProxy.transfer(contractFee);
        }

        uint left;
        if (tokenScAddr == address(0)) {
            left = (msg.value).sub(params.value).sub(contractFee);
        } else {
            left = (msg.value).sub(contractFee);

            uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID);
            require(tokenCrossType == uint8(TokenCrossType.ERC20), "Not support");
            require(CrossTypesV1.transferFrom(tokenScAddr, msg.sender, address(this), params.value), "Lock token failed");
        }
        if (left != 0) {
            (msg.sender).transfer(left);
        }
        emit UserLockLogger(params.smgID, params.tokenPairID, tokenScAddr, params.value, contractFee, params.destUserAccount);
    }

    /// @notice                         burnBridge, user lock token on token original chain
    /// @notice                         event invoked by user burn lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for user burn lock token on token original chain
    function userBurn(CrossTypesV1.Data storage storageData, RapidityUserBurnParams memory params)
    public
    {
        ITokenManager tokenManager = storageData.tokenManager;
        uint fromChainID;
        uint toChainID;
        bytes memory fromTokenAccount;
        bytes memory toTokenAccount;
        (fromChainID,fromTokenAccount,toChainID,toTokenAccount) = tokenManager.getTokenPairInfo(params.tokenPairID);
        require(fromChainID != 0, "Token does not exist");

        uint256 contractFee = params.tokenPairContractFee;
        address tokenScAddr;
        if (params.currentChainID == toChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[toChainID][fromChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(toTokenAccount);
        } else if (params.currentChainID == fromChainID) {
            if (contractFee == 0) {
                contractFee = storageData.mapContractFee[fromChainID][toChainID];
            }
            tokenScAddr = CrossTypesV1.bytesToAddress(fromTokenAccount);
        } else {
            require(false, "Invalid token pair");
        }
        require(params.srcTokenAccount == tokenScAddr, "Invalid token account");

        // Reuse variable fromChainID as tokenCrossType; burn token by tokenCrossType
        fromChainID = tokenManager.mapTokenPairType(params.tokenPairID);
        require(fromChainID == uint8(TokenCrossType.ERC20), "Not support");
        require(burnShadowToken(tokenManager, tokenScAddr, msg.sender, params.value), "Burn failed");

        if (contractFee > 0) {
            params.smgFeeProxy.transfer(contractFee);
        }

        uint left = (msg.value).sub(contractFee);
        if (left != 0) {
            (msg.sender).transfer(left);
        }

        emit UserBurnLogger(params.smgID, params.tokenPairID, tokenScAddr, params.value, contractFee, params.fee, params.destUserAccount);
    }

    /// @notice                         mintBridge, storeman mint lock token on token shadow chain
    /// @notice                         event invoked by user mint lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for storeman mint lock token on token shadow chain
    function smgMint(CrossTypesV1.Data storage storageData, RapiditySmgMintParams memory params)
    public
    {
        storageData.rapidityTxData.addRapidityTx(params.uniqueID);

        ITokenManager tokenManager = storageData.tokenManager;
        uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID);
        require(tokenCrossType == uint8(TokenCrossType.ERC20), "Not support");
        if (params.fee > 0) {
            require(mintShadowToken(tokenManager, params.destTokenAccount, params.smgFeeProxy, params.fee), "Mint fee failed");
        }
        require(mintShadowToken(tokenManager, params.destTokenAccount, params.destUserAccount, params.value), "Mint failed");

        string[] memory keys = new string[](4);
        bytes[] memory values = new bytes[](4);
        keys[0] = "value:uint256";
        values[0] = abi.encodePacked(params.value);
        keys[1] = "tokenAccount:address";
        values[1] = abi.encodePacked(params.destTokenAccount);
        keys[2] = "userAccount:address";
        values[2] = abi.encodePacked(params.destUserAccount);
        keys[3] = "fee:uint256";
        values[3] = abi.encodePacked(params.fee);
        emit SmgMint(params.uniqueID, params.smgID, params.tokenPairID, keys, values);
        emit SmgMintLogger(params.uniqueID, params.smgID, params.tokenPairID, params.value, params.destTokenAccount, params.destUserAccount);
    }

    /// @notice                         burnBridge, storeman burn lock token on token shadow chain
    /// @notice                         event invoked by user burn lock
    /// @param storageData              Cross storage data
    /// @param params                   parameters for storeman burn lock token on token shadow chain
    function smgRelease(CrossTypesV1.Data storage storageData, RapiditySmgReleaseParams memory params)
    public
    {
        storageData.rapidityTxData.addRapidityTx(params.uniqueID);

        if (params.destTokenAccount == address(0)) {
            (params.destUserAccount).transfer(params.value);
            if (params.fee > 0) {
                params.smgFeeProxy.transfer(params.fee);
            }
        } else {
            uint8 tokenCrossType = storageData.tokenManager.mapTokenPairType(params.tokenPairID);
            require(tokenCrossType == uint8(TokenCrossType.ERC20), "Not support");
            if (params.fee > 0) {
                require(CrossTypesV1.transfer(params.destTokenAccount, params.smgFeeProxy, params.fee), "Transfer token fee failed");
            }
            require(CrossTypesV1.transfer(params.destTokenAccount, params.destUserAccount, params.value), "Transfer token failed");
        }

        string[] memory keys = new string[](4);
        bytes[] memory values = new bytes[](4);
        keys[0] = "value:uint256";
        values[0] = abi.encodePacked(params.value);
        keys[1] = "tokenAccount:address";
        values[1] = abi.encodePacked(params.destTokenAccount);
        keys[2] = "userAccount:address";
        values[2] = abi.encodePacked(params.destUserAccount);
        keys[3] = "fee:uint256";
        values[3] = abi.encodePacked(params.fee);
        emit SmgRelease(params.uniqueID, params.smgID, params.tokenPairID, keys, values);
        emit SmgReleaseLogger(params.uniqueID, params.smgID, params.tokenPairID, params.value, params.destTokenAccount, params.destUserAccount);
    }

    function burnShadowToken(address tokenManager, address tokenAddress, address userAccount, uint value) private returns (bool) {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);

        ITokenManager(tokenManager).burnToken(tokenAddress, userAccount, value);

        afterBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);
        return afterBalance == beforeBalance.sub(value);
    }

    function mintShadowToken(address tokenManager, address tokenAddress, address userAccount, uint value) private returns (bool) {
        uint beforeBalance;
        uint afterBalance;
        beforeBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);

        ITokenManager(tokenManager).mintToken(tokenAddress, userAccount, value);

        afterBalance = IRC20Protocol(tokenAddress).balanceOf(userAccount);
        return afterBalance == beforeBalance.add(value);
    }
}
        

Contract ABI

[{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"userBurn","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256","name":"value"},{"type":"uint256","name":"currentChainID"},{"type":"uint256","name":"fee"},{"type":"uint256","name":"tokenPairContractFee"},{"type":"address","name":"srcTokenAccount"},{"type":"bytes","name":"destUserAccount"},{"type":"address","name":"smgFeeProxy"}]}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"smgRelease","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"uniqueID"},{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256","name":"value"},{"type":"uint256","name":"fee"},{"type":"address","name":"destTokenAccount"},{"type":"address","name":"destUserAccount"},{"type":"address","name":"smgFeeProxy"}]}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"smgMint","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"uniqueID"},{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256","name":"value"},{"type":"uint256","name":"fee"},{"type":"address","name":"destTokenAccount"},{"type":"address","name":"destUserAccount"},{"type":"address","name":"smgFeeProxy"}]}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"userLock","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256","name":"value"},{"type":"uint256","name":"currentChainID"},{"type":"uint256","name":"tokenPairContractFee"},{"type":"bytes","name":"destUserAccount"},{"type":"address","name":"smgFeeProxy"}]}],"constant":false},{"type":"event","name":"UserLockLogger","inputs":[{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"address","name":"tokenAccount","indexed":true},{"type":"uint256","name":"value","indexed":false},{"type":"uint256","name":"contractFee","indexed":false},{"type":"bytes","name":"userAccount","indexed":false}],"anonymous":false},{"type":"event","name":"UserBurnLogger","inputs":[{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"address","name":"tokenAccount","indexed":true},{"type":"uint256","name":"value","indexed":false},{"type":"uint256","name":"contractFee","indexed":false},{"type":"uint256","name":"fee","indexed":false},{"type":"bytes","name":"userAccount","indexed":false}],"anonymous":false},{"type":"event","name":"SmgMintLogger","inputs":[{"type":"bytes32","name":"uniqueID","indexed":true},{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"uint256","name":"value","indexed":false},{"type":"address","name":"tokenAccount","indexed":false},{"type":"address","name":"userAccount","indexed":false}],"anonymous":false},{"type":"event","name":"SmgMint","inputs":[{"type":"bytes32","name":"uniqueID","indexed":true},{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"string[]","name":"keys","indexed":false},{"type":"bytes[]","name":"values","indexed":false}],"anonymous":false},{"type":"event","name":"SmgReleaseLogger","inputs":[{"type":"bytes32","name":"uniqueID","indexed":true},{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"uint256","name":"value","indexed":false},{"type":"address","name":"tokenAccount","indexed":false},{"type":"address","name":"userAccount","indexed":false}],"anonymous":false},{"type":"event","name":"SmgRelease","inputs":[{"type":"bytes32","name":"uniqueID","indexed":true},{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"string[]","name":"keys","indexed":false},{"type":"bytes[]","name":"values","indexed":false}],"anonymous":false}]
              

Contract Creation Code

0x6123f9610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f300730000000000000000000000000000000000000000301460806040526004361061005f5763ffffffff60e060020a6000350416630f9a9c9a811461006457806360b10a2914610086578063b3f78be0146100a6578063bbb71abb146100c6575b600080fd5b81801561007057600080fd5b5061008461007f366004611cc6565b6100e6565b005b81801561009257600080fd5b506100846100a1366004611c8b565b610482565b8180156100b257600080fd5b506100846100c1366004611c8b565b610a0a565b8180156100d257600080fd5b506100846100e1366004611d0e565b610eee565b600582015460208201516040517fb9073276000000000000000000000000000000000000000000000000000000008152600160a060020a039092169160009182916060918291849182918291899163b9073276916101469160040161225b565b600060405180830381600087803b15801561016057600080fd5b505af1158015610174573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261019c9190810190611d7c565b9299509750955093508615156101d05760405160e560020a62461bcd0281526004016101c7906121eb565b60405180910390fd5b8860a001519250858960600151141561021957821515610209576000868152600a8b01602090815260408083208a845290915290205492505b61021284611267565b915061026f565b86896060015114156102545782151561024b576000878152600a8b016020908152604080832089845290915290205492505b61021285611267565b60405160e560020a62461bcd0281526004016101c7906121db565b81600160a060020a03168960c00151600160a060020a03161415156102a95760405160e560020a62461bcd0281526004016101c7906121cb565b602089015160405160e060020a6375d2e27d028152600160a060020a038a16916375d2e27d916102dc919060040161225b565b602060405180830381600087803b1580156102f657600080fd5b505af115801561030a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061032e9190810190611e0d565b60ff16965086156103545760405160e560020a62461bcd0281526004016101c79061223b565b6103648883338c6040015161126e565b15156103855760405160e560020a62461bcd0281526004016101c7906121fb565b60008311156103ce57886101000151600160a060020a03166108fc849081150290604051600060405180830381858888f193505050501580156103cc573d6000803e3d6000fd5b505b6103de348463ffffffff61141016565b9050801561041557604051339082156108fc029083906000818181858888f19350505050158015610413573d6000803e3d6000fd5b505b81600160a060020a031689602001518a60000151600019167fe314e23175856b9484e39ab0547753cf1b5cd0cbe3b0d7018c953d31f23fc7678c60400151878e608001518f60e0015160405161046e94939291906122c7565b60405180910390a450505050505050505050565b60006060806104a184600001518660030161142790919063ffffffff16565b60a0840151600160a060020a0316151561054c578360c00151600160a060020a03166108fc85606001519081150290604051600060405180830381858888f193505050501580156104f6573d6000803e3d6000fd5b50600084608001511115610547578360e00151600160a060020a03166108fc85608001519081150290604051600060405180830381858888f19350505050158015610545573d6000803e3d6000fd5b505b610679565b6005850154604080860151905160e060020a6375d2e27d028152600160a060020a03909216916375d2e27d916105849160040161225b565b602060405180830381600087803b15801561059e57600080fd5b505af11580156105b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105d69190810190611e0d565b925060ff8316156105fc5760405160e560020a62461bcd0281526004016101c79061223b565b600084608001511115610641576106208460a001518560e001518660800151611483565b15156106415760405160e560020a62461bcd0281526004016101c79061222b565b6106588460a001518560c001518660600151611483565b15156106795760405160e560020a62461bcd0281526004016101c7906121ab565b60408051600480825260a0820190925290816020015b606081526020019060019003908161068f57505060408051600480825260a08201909252919350602082015b60608152602001906001900390816106bb5790505090506040805190810160405280600d81526020017f76616c75653a75696e743235360000000000000000000000000000000000000081525082600081518110151561071757fe5b9060200190602002018190525083606001516040516020018082815260200191505060405160208183030381529060405281600081518110151561075757fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a616464726573730000000000000000000000008152508260018151811015156107a957fe5b906020019060200201819052508360a001516040516020018082600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140191505060405160208183030381529060405281600181518110151561080a57fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a616464726573730000000000000000000000000081525082600281518110151561085c57fe5b906020019060200201819052508360c001516040516020018082600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040528160028151811015156108bd57fe5b906020019060200201819052506040805190810160405280600b81526020017f6665653a75696e7432353600000000000000000000000000000000000000000081525082600381518110151561090f57fe5b9060200190602002018190525083608001516040516020018082815260200191505060405160208183030381529060405281600381518110151561094f57fe5b602090810290910181019190915260408086015191860151865191519091907f9b6eb2cafadf787e6afa45af20d7b3e7cbfab81b468152083b29bf659874572f9061099d9087908790612186565b60405180910390a483604001518460200151600019168560000151600019167f74a78f7a58df75c2eb07666a6e572aa46ec8fe8f2cd090e41cfca63178dafa2f87606001518860a001518960c001516040516109fb93929190612269565b60405180910390a45050505050565b600080606080610a2a85600001518760030161142790919063ffffffff16565b6005860154604080870151905160e060020a6375d2e27d028152600160a060020a03909216955085916375d2e27d91610a659160040161225b565b602060405180830381600087803b158015610a7f57600080fd5b505af1158015610a93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ab79190810190611e0d565b925060ff831615610add5760405160e560020a62461bcd0281526004016101c79061223b565b600085608001511115610b2357610b02848660a001518760e00151886080015161163b565b1515610b235760405160e560020a62461bcd0281526004016101c79061224b565b610b3b848660a001518760c00151886060015161163b565b1515610b5c5760405160e560020a62461bcd0281526004016101c7906121bb565b60408051600480825260a0820190925290816020015b6060815260200190600190039081610b7257505060408051600480825260a08201909252919350602082015b6060815260200190600190039081610b9e5790505090506040805190810160405280600d81526020017f76616c75653a75696e7432353600000000000000000000000000000000000000815250826000815181101515610bfa57fe5b90602001906020020181905250846060015160405160200180828152602001915050604051602081830303815290604052816000815181101515610c3a57fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a61646472657373000000000000000000000000815250826001815181101515610c8c57fe5b906020019060200201819052508460a001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816001815181101515610ced57fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a6164647265737300000000000000000000000000815250826002815181101515610d3f57fe5b906020019060200201819052508460c001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816002815181101515610da057fe5b906020019060200201819052506040805190810160405280600b81526020017f6665653a75696e74323536000000000000000000000000000000000000000000815250826003815181101515610df257fe5b90602001906020020181905250846080015160405160200180828152602001915050604051602081830303815290604052816003815181101515610e3257fe5b602090810290910181019190915260408087015191870151875191519091907fcfa91e1b502283be81bcd35b1d709a0d87a2045d6230837e2396892cf81411d990610e809087908790612186565b60405180910390a484604001518560200151600019168660000151600019167f4419a30cc235fa47055246d53f2629b5687ca327b92dcde015fcebe0cc17ffab88606001518960a001518a60c00151604051610ede93929190612269565b60405180910390a4505050505050565b600582015460208201516040517fb9073276000000000000000000000000000000000000000000000000000000008152600160a060020a03909216916000918291606091829184918291829182918a9163b907327691610f51919060040161225b565b600060405180830381600087803b158015610f6b57600080fd5b505af1158015610f7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fa79190810190611d7c565b929a50985096509450871515610fd25760405160e560020a62461bcd0281526004016101c7906121eb565b89608001519350878a60600151141561101b5783151561100b576000888152600a8c01602090815260408083208a845290915290205493505b61101486611267565b9250611056565b868a6060015114156102545783151561104d576000878152600a8c01602090815260408083208b845290915290205493505b61101485611267565b600084111561109e578960c00151600160a060020a03166108fc859081150290604051600060405180830381858888f1935050505015801561109c573d6000803e3d6000fd5b505b600160a060020a03831615156110dc576110d5846110c98c604001513461141090919063ffffffff16565b9063ffffffff61141016565b91506111ca565b6110ec348563ffffffff61141016565b60208b015160405160e060020a6375d2e27d028152919350600160a060020a038b16916375d2e27d916111219160040161225b565b602060405180830381600087803b15801561113b57600080fd5b505af115801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111739190810190611e0d565b905060ff8116156111995760405160e560020a62461bcd0281526004016101c79061223b565b6111a98333308d604001516117d2565b15156111ca5760405160e560020a62461bcd0281526004016101c79061221b565b81156111ff57604051339083156108fc029084906000818181858888f193505050501580156111fd573d6000803e3d6000fd5b505b82600160a060020a03168a602001518b60000151600019167f43eb196c5950c738b34cd1760941e0876559e4fb835498fe19016bc039ad61a98d60400151888f60a0015160405161125293929190612291565b60405180910390a45050505050505050505050565b6014015190565b600080600085600160a060020a03166370a08231866040518263ffffffff1660e060020a0281526004016112a2919061214a565b602060405180830381600087803b1580156112bc57600080fd5b505af11580156112d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112f49190810190611d56565b6040517f3416794d000000000000000000000000000000000000000000000000000000008152909250600160a060020a03881690633416794d906113409089908990899060040161215e565b600060405180830381600087803b15801561135a57600080fd5b505af115801561136e573d6000803e3d6000fd5b505060405160e060020a6370a08231028152600160a060020a03891692506370a0823191506113a190889060040161214a565b602060405180830381600087803b1580156113bb57600080fd5b505af11580156113cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113f39190810190611d56565b9050611405828563ffffffff61141016565b149695505050505050565b6000808383111561142057600080fd5b5050900390565b60008181526020839052604081205460ff169081600181111561144657fe5b146114665760405160e560020a62461bcd0281526004016101c79061220b565b50600090815260209190915260409020805460ff19166001179055565b600080600085600160a060020a03166370a08231866040518263ffffffff1660e060020a0281526004016114b7919061214a565b602060405180830381600087803b1580156114d157600080fd5b505af11580156114e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115099190810190611d56565b915085600160a060020a031660405180807f7472616e7366657228616464726573732c75696e7432353629000000000000008152506019019050604051809103902060e060020a900486866040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a03168152602001828152602001925050506000604051808303816000875af1505060405160e060020a6370a08231028152600160a060020a03891692506370a0823191506115cd90889060040161214a565b602060405180830381600087803b1580156115e757600080fd5b505af11580156115fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061161f9190810190611d56565b9050611631828563ffffffff61193516565b1495945050505050565b600080600085600160a060020a03166370a08231866040518263ffffffff1660e060020a02815260040161166f919061214a565b602060405180830381600087803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116c19190810190611d56565b6040517f6bec32da000000000000000000000000000000000000000000000000000000008152909250600160a060020a03881690636bec32da9061170d9089908990899060040161215e565b600060405180830381600087803b15801561172757600080fd5b505af115801561173b573d6000803e3d6000fd5b505060405160e060020a6370a08231028152600160a060020a03891692506370a08231915061176e90889060040161214a565b602060405180830381600087803b15801561178857600080fd5b505af115801561179c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117c09190810190611d56565b9050611405828563ffffffff61193516565b600080600086600160a060020a03166370a08231866040518263ffffffff1660e060020a028152600401611806919061214a565b602060405180830381600087803b15801561182057600080fd5b505af1158015611834573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118589190810190611d56565b604080517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f74323536290000000000000000000000000000000000000000000000000000006020820152815190819003602501812063ffffffff60e060020a918290049081169091028252600160a060020a038a811660048401528981166024840152604483018990529251939550918a16926064808301926000929190829003018183875af1505060405160e060020a6370a08231028152600160a060020a038a1692506370a08231915061176e90889060040161214a565b60008282018381101561194757600080fd5b9392505050565b60006119478235612364565b60006119478235612370565b6000601f8201831361197757600080fd5b813561198a61198582612332565b61230b565b915080825260208301602083018583830111156119a657600080fd5b6119b1838284612379565b50505092915050565b6000601f820183136119cb57600080fd5b81516119d961198582612332565b915080825260208301602083018583830111156119f557600080fd5b6119b1838284612385565b60006101008284031215611a1357600080fd5b611a1e61010061230b565b90506000611a2c848461195a565b8252506020611a3d8484830161195a565b6020830152506040611a518482850161195a565b6040830152506060611a658482850161195a565b6060830152506080611a798482850161195a565b60808301525060a0611a8d8482850161194e565b60a08301525060c0611aa18482850161194e565b60c08301525060e0611ab58482850161194e565b60e08301525092915050565b60006101208284031215611ad457600080fd5b611adf61012061230b565b90506000611aed848461195a565b8252506020611afe8484830161195a565b6020830152506040611b128482850161195a565b6040830152506060611b268482850161195a565b6060830152506080611b3a8482850161195a565b60808301525060a0611b4e8482850161195a565b60a08301525060c0611b628482850161194e565b60c08301525060e082013567ffffffffffffffff811115611b8257600080fd5b611b8e84828501611966565b60e083015250610100611ba38482850161194e565b6101008301525092915050565b600060e08284031215611bc257600080fd5b611bcc60e061230b565b90506000611bda848461195a565b8252506020611beb8484830161195a565b6020830152506040611bff8482850161195a565b6040830152506060611c138482850161195a565b6060830152506080611c278482850161195a565b60808301525060a082013567ffffffffffffffff811115611c4757600080fd5b611c5384828501611966565b60a08301525060c0611c678482850161194e565b60c08301525092915050565b60006119478251612370565b60006119478251612373565b6000806101208385031215611c9f57600080fd5b6000611cab858561195a565b9250506020611cbc85828601611a00565b9150509250929050565b60008060408385031215611cd957600080fd5b6000611ce5858561195a565b925050602083013567ffffffffffffffff811115611d0257600080fd5b611cbc85828601611ac1565b60008060408385031215611d2157600080fd5b6000611d2d858561195a565b925050602083013567ffffffffffffffff811115611d4a57600080fd5b611cbc85828601611bb0565b600060208284031215611d6857600080fd5b6000611d748484611c73565b949350505050565b60008060008060808587031215611d9257600080fd5b6000611d9e8787611c73565b945050602085015167ffffffffffffffff811115611dbb57600080fd5b611dc7878288016119ba565b9350506040611dd887828801611c73565b925050606085015167ffffffffffffffff811115611df557600080fd5b611e01878288016119ba565b91505092959194509250565b600060208284031215611e1f57600080fd5b6000611d748484611c7f565b611e3481612364565b82525050565b6000611e4582612360565b80845260208401935083602082028501611e5e8561235a565b60005b84811015611e95578383038852611e79838351611efc565b9250611e848261235a565b602098909801979150600101611e61565b50909695505050505050565b6000611eac82612360565b80845260208401935083602082028501611ec58561235a565b60005b84811015611e95578383038852611ee0838351611efc565b9250611eeb8261235a565b602098909801979150600101611ec8565b6000611f0782612360565b808452611f1b816020860160208601612385565b611f24816123b5565b9093016020019392505050565b601581527f5472616e7366657220746f6b656e206661696c65640000000000000000000000602082015260400190565b600b81527f4d696e74206661696c6564000000000000000000000000000000000000000000602082015260400190565b601581527f496e76616c696420746f6b656e206163636f756e740000000000000000000000602082015260400190565b601281527f496e76616c696420746f6b656e20706169720000000000000000000000000000602082015260400190565b601481527f546f6b656e20646f6573206e6f74206578697374000000000000000000000000602082015260400190565b600b81527f4275726e206661696c6564000000000000000000000000000000000000000000602082015260400190565b601281527f5261706964697479207478206578697374730000000000000000000000000000602082015260400190565b601181527f4c6f636b20746f6b656e206661696c6564000000000000000000000000000000602082015260400190565b601981527f5472616e7366657220746f6b656e20666565206661696c656400000000000000602082015260400190565b600b81527f4e6f7420737570706f7274000000000000000000000000000000000000000000602082015260400190565b600f81527f4d696e7420666565206661696c65640000000000000000000000000000000000602082015260400190565b611e3481612370565b602081016121588284611e2b565b92915050565b6060810161216c8286611e2b565b6121796020830185611e2b565b611d746040830184612141565b604080825281016121978185611ea1565b90508181036020830152611d748184611e3a565b6020808252810161215881611f31565b6020808252810161215881611f61565b6020808252810161215881611f91565b6020808252810161215881611fc1565b6020808252810161215881611ff1565b6020808252810161215881612021565b6020808252810161215881612051565b6020808252810161215881612081565b60208082528101612158816120b1565b60208082528101612158816120e1565b6020808252810161215881612111565b602081016121588284612141565b606081016122778286612141565b6122846020830185611e2b565b611d746040830184611e2b565b6060810161229f8286612141565b6122ac6020830185612141565b81810360408301526122be8184611efc565b95945050505050565b608081016122d58287612141565b6122e26020830186612141565b6122ef6040830185612141565b81810360608301526123018184611efc565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561232a57600080fd5b604052919050565b600067ffffffffffffffff82111561234957600080fd5b506020601f91909101601f19160190565b60200190565b5190565b600160a060020a031690565b90565b60ff1690565b82818337506000910152565b60005b838110156123a0578181015183820152602001612388565b838111156123af576000848401525b50505050565b601f01601f1916905600a265627a7a72305820b65d55edb52daba31dd5bc1bb6edaad4a4e19153807c1b80967d94d0c52dca366c6578706572696d656e74616cf50037

Deployed ByteCode

0x737f70d0047ae63131ab77f179a90f1a41ceea93aa301460806040526004361061005f5763ffffffff60e060020a6000350416630f9a9c9a811461006457806360b10a2914610086578063b3f78be0146100a6578063bbb71abb146100c6575b600080fd5b81801561007057600080fd5b5061008461007f366004611cc6565b6100e6565b005b81801561009257600080fd5b506100846100a1366004611c8b565b610482565b8180156100b257600080fd5b506100846100c1366004611c8b565b610a0a565b8180156100d257600080fd5b506100846100e1366004611d0e565b610eee565b600582015460208201516040517fb9073276000000000000000000000000000000000000000000000000000000008152600160a060020a039092169160009182916060918291849182918291899163b9073276916101469160040161225b565b600060405180830381600087803b15801561016057600080fd5b505af1158015610174573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261019c9190810190611d7c565b9299509750955093508615156101d05760405160e560020a62461bcd0281526004016101c7906121eb565b60405180910390fd5b8860a001519250858960600151141561021957821515610209576000868152600a8b01602090815260408083208a845290915290205492505b61021284611267565b915061026f565b86896060015114156102545782151561024b576000878152600a8b016020908152604080832089845290915290205492505b61021285611267565b60405160e560020a62461bcd0281526004016101c7906121db565b81600160a060020a03168960c00151600160a060020a03161415156102a95760405160e560020a62461bcd0281526004016101c7906121cb565b602089015160405160e060020a6375d2e27d028152600160a060020a038a16916375d2e27d916102dc919060040161225b565b602060405180830381600087803b1580156102f657600080fd5b505af115801561030a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061032e9190810190611e0d565b60ff16965086156103545760405160e560020a62461bcd0281526004016101c79061223b565b6103648883338c6040015161126e565b15156103855760405160e560020a62461bcd0281526004016101c7906121fb565b60008311156103ce57886101000151600160a060020a03166108fc849081150290604051600060405180830381858888f193505050501580156103cc573d6000803e3d6000fd5b505b6103de348463ffffffff61141016565b9050801561041557604051339082156108fc029083906000818181858888f19350505050158015610413573d6000803e3d6000fd5b505b81600160a060020a031689602001518a60000151600019167fe314e23175856b9484e39ab0547753cf1b5cd0cbe3b0d7018c953d31f23fc7678c60400151878e608001518f60e0015160405161046e94939291906122c7565b60405180910390a450505050505050505050565b60006060806104a184600001518660030161142790919063ffffffff16565b60a0840151600160a060020a0316151561054c578360c00151600160a060020a03166108fc85606001519081150290604051600060405180830381858888f193505050501580156104f6573d6000803e3d6000fd5b50600084608001511115610547578360e00151600160a060020a03166108fc85608001519081150290604051600060405180830381858888f19350505050158015610545573d6000803e3d6000fd5b505b610679565b6005850154604080860151905160e060020a6375d2e27d028152600160a060020a03909216916375d2e27d916105849160040161225b565b602060405180830381600087803b15801561059e57600080fd5b505af11580156105b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105d69190810190611e0d565b925060ff8316156105fc5760405160e560020a62461bcd0281526004016101c79061223b565b600084608001511115610641576106208460a001518560e001518660800151611483565b15156106415760405160e560020a62461bcd0281526004016101c79061222b565b6106588460a001518560c001518660600151611483565b15156106795760405160e560020a62461bcd0281526004016101c7906121ab565b60408051600480825260a0820190925290816020015b606081526020019060019003908161068f57505060408051600480825260a08201909252919350602082015b60608152602001906001900390816106bb5790505090506040805190810160405280600d81526020017f76616c75653a75696e743235360000000000000000000000000000000000000081525082600081518110151561071757fe5b9060200190602002018190525083606001516040516020018082815260200191505060405160208183030381529060405281600081518110151561075757fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a616464726573730000000000000000000000008152508260018151811015156107a957fe5b906020019060200201819052508360a001516040516020018082600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140191505060405160208183030381529060405281600181518110151561080a57fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a616464726573730000000000000000000000000081525082600281518110151561085c57fe5b906020019060200201819052508360c001516040516020018082600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040528160028151811015156108bd57fe5b906020019060200201819052506040805190810160405280600b81526020017f6665653a75696e7432353600000000000000000000000000000000000000000081525082600381518110151561090f57fe5b9060200190602002018190525083608001516040516020018082815260200191505060405160208183030381529060405281600381518110151561094f57fe5b602090810290910181019190915260408086015191860151865191519091907f9b6eb2cafadf787e6afa45af20d7b3e7cbfab81b468152083b29bf659874572f9061099d9087908790612186565b60405180910390a483604001518460200151600019168560000151600019167f74a78f7a58df75c2eb07666a6e572aa46ec8fe8f2cd090e41cfca63178dafa2f87606001518860a001518960c001516040516109fb93929190612269565b60405180910390a45050505050565b600080606080610a2a85600001518760030161142790919063ffffffff16565b6005860154604080870151905160e060020a6375d2e27d028152600160a060020a03909216955085916375d2e27d91610a659160040161225b565b602060405180830381600087803b158015610a7f57600080fd5b505af1158015610a93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610ab79190810190611e0d565b925060ff831615610add5760405160e560020a62461bcd0281526004016101c79061223b565b600085608001511115610b2357610b02848660a001518760e00151886080015161163b565b1515610b235760405160e560020a62461bcd0281526004016101c79061224b565b610b3b848660a001518760c00151886060015161163b565b1515610b5c5760405160e560020a62461bcd0281526004016101c7906121bb565b60408051600480825260a0820190925290816020015b6060815260200190600190039081610b7257505060408051600480825260a08201909252919350602082015b6060815260200190600190039081610b9e5790505090506040805190810160405280600d81526020017f76616c75653a75696e7432353600000000000000000000000000000000000000815250826000815181101515610bfa57fe5b90602001906020020181905250846060015160405160200180828152602001915050604051602081830303815290604052816000815181101515610c3a57fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a61646472657373000000000000000000000000815250826001815181101515610c8c57fe5b906020019060200201819052508460a001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816001815181101515610ced57fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a6164647265737300000000000000000000000000815250826002815181101515610d3f57fe5b906020019060200201819052508460c001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816002815181101515610da057fe5b906020019060200201819052506040805190810160405280600b81526020017f6665653a75696e74323536000000000000000000000000000000000000000000815250826003815181101515610df257fe5b90602001906020020181905250846080015160405160200180828152602001915050604051602081830303815290604052816003815181101515610e3257fe5b602090810290910181019190915260408087015191870151875191519091907fcfa91e1b502283be81bcd35b1d709a0d87a2045d6230837e2396892cf81411d990610e809087908790612186565b60405180910390a484604001518560200151600019168660000151600019167f4419a30cc235fa47055246d53f2629b5687ca327b92dcde015fcebe0cc17ffab88606001518960a001518a60c00151604051610ede93929190612269565b60405180910390a4505050505050565b600582015460208201516040517fb9073276000000000000000000000000000000000000000000000000000000008152600160a060020a03909216916000918291606091829184918291829182918a9163b907327691610f51919060040161225b565b600060405180830381600087803b158015610f6b57600080fd5b505af1158015610f7f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fa79190810190611d7c565b929a50985096509450871515610fd25760405160e560020a62461bcd0281526004016101c7906121eb565b89608001519350878a60600151141561101b5783151561100b576000888152600a8c01602090815260408083208a845290915290205493505b61101486611267565b9250611056565b868a6060015114156102545783151561104d576000878152600a8c01602090815260408083208b845290915290205493505b61101485611267565b600084111561109e578960c00151600160a060020a03166108fc859081150290604051600060405180830381858888f1935050505015801561109c573d6000803e3d6000fd5b505b600160a060020a03831615156110dc576110d5846110c98c604001513461141090919063ffffffff16565b9063ffffffff61141016565b91506111ca565b6110ec348563ffffffff61141016565b60208b015160405160e060020a6375d2e27d028152919350600160a060020a038b16916375d2e27d916111219160040161225b565b602060405180830381600087803b15801561113b57600080fd5b505af115801561114f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111739190810190611e0d565b905060ff8116156111995760405160e560020a62461bcd0281526004016101c79061223b565b6111a98333308d604001516117d2565b15156111ca5760405160e560020a62461bcd0281526004016101c79061221b565b81156111ff57604051339083156108fc029084906000818181858888f193505050501580156111fd573d6000803e3d6000fd5b505b82600160a060020a03168a602001518b60000151600019167f43eb196c5950c738b34cd1760941e0876559e4fb835498fe19016bc039ad61a98d60400151888f60a0015160405161125293929190612291565b60405180910390a45050505050505050505050565b6014015190565b600080600085600160a060020a03166370a08231866040518263ffffffff1660e060020a0281526004016112a2919061214a565b602060405180830381600087803b1580156112bc57600080fd5b505af11580156112d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112f49190810190611d56565b6040517f3416794d000000000000000000000000000000000000000000000000000000008152909250600160a060020a03881690633416794d906113409089908990899060040161215e565b600060405180830381600087803b15801561135a57600080fd5b505af115801561136e573d6000803e3d6000fd5b505060405160e060020a6370a08231028152600160a060020a03891692506370a0823191506113a190889060040161214a565b602060405180830381600087803b1580156113bb57600080fd5b505af11580156113cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113f39190810190611d56565b9050611405828563ffffffff61141016565b149695505050505050565b6000808383111561142057600080fd5b5050900390565b60008181526020839052604081205460ff169081600181111561144657fe5b146114665760405160e560020a62461bcd0281526004016101c79061220b565b50600090815260209190915260409020805460ff19166001179055565b600080600085600160a060020a03166370a08231866040518263ffffffff1660e060020a0281526004016114b7919061214a565b602060405180830381600087803b1580156114d157600080fd5b505af11580156114e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115099190810190611d56565b915085600160a060020a031660405180807f7472616e7366657228616464726573732c75696e7432353629000000000000008152506019019050604051809103902060e060020a900486866040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a03168152602001828152602001925050506000604051808303816000875af1505060405160e060020a6370a08231028152600160a060020a03891692506370a0823191506115cd90889060040161214a565b602060405180830381600087803b1580156115e757600080fd5b505af11580156115fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061161f9190810190611d56565b9050611631828563ffffffff61193516565b1495945050505050565b600080600085600160a060020a03166370a08231866040518263ffffffff1660e060020a02815260040161166f919061214a565b602060405180830381600087803b15801561168957600080fd5b505af115801561169d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506116c19190810190611d56565b6040517f6bec32da000000000000000000000000000000000000000000000000000000008152909250600160a060020a03881690636bec32da9061170d9089908990899060040161215e565b600060405180830381600087803b15801561172757600080fd5b505af115801561173b573d6000803e3d6000fd5b505060405160e060020a6370a08231028152600160a060020a03891692506370a08231915061176e90889060040161214a565b602060405180830381600087803b15801561178857600080fd5b505af115801561179c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506117c09190810190611d56565b9050611405828563ffffffff61193516565b600080600086600160a060020a03166370a08231866040518263ffffffff1660e060020a028152600401611806919061214a565b602060405180830381600087803b15801561182057600080fd5b505af1158015611834573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506118589190810190611d56565b604080517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f74323536290000000000000000000000000000000000000000000000000000006020820152815190819003602501812063ffffffff60e060020a918290049081169091028252600160a060020a038a811660048401528981166024840152604483018990529251939550918a16926064808301926000929190829003018183875af1505060405160e060020a6370a08231028152600160a060020a038a1692506370a08231915061176e90889060040161214a565b60008282018381101561194757600080fd5b9392505050565b60006119478235612364565b60006119478235612370565b6000601f8201831361197757600080fd5b813561198a61198582612332565b61230b565b915080825260208301602083018583830111156119a657600080fd5b6119b1838284612379565b50505092915050565b6000601f820183136119cb57600080fd5b81516119d961198582612332565b915080825260208301602083018583830111156119f557600080fd5b6119b1838284612385565b60006101008284031215611a1357600080fd5b611a1e61010061230b565b90506000611a2c848461195a565b8252506020611a3d8484830161195a565b6020830152506040611a518482850161195a565b6040830152506060611a658482850161195a565b6060830152506080611a798482850161195a565b60808301525060a0611a8d8482850161194e565b60a08301525060c0611aa18482850161194e565b60c08301525060e0611ab58482850161194e565b60e08301525092915050565b60006101208284031215611ad457600080fd5b611adf61012061230b565b90506000611aed848461195a565b8252506020611afe8484830161195a565b6020830152506040611b128482850161195a565b6040830152506060611b268482850161195a565b6060830152506080611b3a8482850161195a565b60808301525060a0611b4e8482850161195a565b60a08301525060c0611b628482850161194e565b60c08301525060e082013567ffffffffffffffff811115611b8257600080fd5b611b8e84828501611966565b60e083015250610100611ba38482850161194e565b6101008301525092915050565b600060e08284031215611bc257600080fd5b611bcc60e061230b565b90506000611bda848461195a565b8252506020611beb8484830161195a565b6020830152506040611bff8482850161195a565b6040830152506060611c138482850161195a565b6060830152506080611c278482850161195a565b60808301525060a082013567ffffffffffffffff811115611c4757600080fd5b611c5384828501611966565b60a08301525060c0611c678482850161194e565b60c08301525092915050565b60006119478251612370565b60006119478251612373565b6000806101208385031215611c9f57600080fd5b6000611cab858561195a565b9250506020611cbc85828601611a00565b9150509250929050565b60008060408385031215611cd957600080fd5b6000611ce5858561195a565b925050602083013567ffffffffffffffff811115611d0257600080fd5b611cbc85828601611ac1565b60008060408385031215611d2157600080fd5b6000611d2d858561195a565b925050602083013567ffffffffffffffff811115611d4a57600080fd5b611cbc85828601611bb0565b600060208284031215611d6857600080fd5b6000611d748484611c73565b949350505050565b60008060008060808587031215611d9257600080fd5b6000611d9e8787611c73565b945050602085015167ffffffffffffffff811115611dbb57600080fd5b611dc7878288016119ba565b9350506040611dd887828801611c73565b925050606085015167ffffffffffffffff811115611df557600080fd5b611e01878288016119ba565b91505092959194509250565b600060208284031215611e1f57600080fd5b6000611d748484611c7f565b611e3481612364565b82525050565b6000611e4582612360565b80845260208401935083602082028501611e5e8561235a565b60005b84811015611e95578383038852611e79838351611efc565b9250611e848261235a565b602098909801979150600101611e61565b50909695505050505050565b6000611eac82612360565b80845260208401935083602082028501611ec58561235a565b60005b84811015611e95578383038852611ee0838351611efc565b9250611eeb8261235a565b602098909801979150600101611ec8565b6000611f0782612360565b808452611f1b816020860160208601612385565b611f24816123b5565b9093016020019392505050565b601581527f5472616e7366657220746f6b656e206661696c65640000000000000000000000602082015260400190565b600b81527f4d696e74206661696c6564000000000000000000000000000000000000000000602082015260400190565b601581527f496e76616c696420746f6b656e206163636f756e740000000000000000000000602082015260400190565b601281527f496e76616c696420746f6b656e20706169720000000000000000000000000000602082015260400190565b601481527f546f6b656e20646f6573206e6f74206578697374000000000000000000000000602082015260400190565b600b81527f4275726e206661696c6564000000000000000000000000000000000000000000602082015260400190565b601281527f5261706964697479207478206578697374730000000000000000000000000000602082015260400190565b601181527f4c6f636b20746f6b656e206661696c6564000000000000000000000000000000602082015260400190565b601981527f5472616e7366657220746f6b656e20666565206661696c656400000000000000602082015260400190565b600b81527f4e6f7420737570706f7274000000000000000000000000000000000000000000602082015260400190565b600f81527f4d696e7420666565206661696c65640000000000000000000000000000000000602082015260400190565b611e3481612370565b602081016121588284611e2b565b92915050565b6060810161216c8286611e2b565b6121796020830185611e2b565b611d746040830184612141565b604080825281016121978185611ea1565b90508181036020830152611d748184611e3a565b6020808252810161215881611f31565b6020808252810161215881611f61565b6020808252810161215881611f91565b6020808252810161215881611fc1565b6020808252810161215881611ff1565b6020808252810161215881612021565b6020808252810161215881612051565b6020808252810161215881612081565b60208082528101612158816120b1565b60208082528101612158816120e1565b6020808252810161215881612111565b602081016121588284612141565b606081016122778286612141565b6122846020830185611e2b565b611d746040830184611e2b565b6060810161229f8286612141565b6122ac6020830185612141565b81810360408301526122be8184611efc565b95945050505050565b608081016122d58287612141565b6122e26020830186612141565b6122ef6040830185612141565b81810360608301526123018184611efc565b9695505050505050565b60405181810167ffffffffffffffff8111828210171561232a57600080fd5b604052919050565b600067ffffffffffffffff82111561234957600080fd5b506020601f91909101601f19160190565b60200190565b5190565b600160a060020a031690565b90565b60ff1690565b82818337506000910152565b60005b838110156123a0578181015183820152602001612388565b838111156123af576000848401525b50505050565b601f01601f1916905600a265627a7a72305820b65d55edb52daba31dd5bc1bb6edaad4a4e19153807c1b80967d94d0c52dca366c6578706572696d656e74616cf50037