Contract 0x0000000000000000000000000000000000001000 9

 

Contract Overview

BSC: Validator Set
Balance:
1,622.752312468082803082 BNB

BNB Value:
$611,631.57 (@ $376.91/BNB)

Token:
My Name Tag:
Not Available, login to update

ContractCreator:
GENESIS at txn GENESIS_0000000000000000000000000000000000001000
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xa02fcb6dc4331c7091e53b4df02e9715664c0a38bc542053152dba2a456e5cfdDeposit111615822021-09-23 9:44:168 secs agoValidator: Defibit IN  BSC: Validator Set0.233554609408856 BNB0
0xba089e835915e9d3d7359dad33d57f075282fe066667daa7bc885db72fe839abDeposit111615812021-09-23 9:44:1311 secs agoValidator: HashQuark IN  BSC: Validator Set0.204655173430344 BNB0
0xeeafb676496bddc458a0d2e58747c6c954dac553dcaa807b8f6d39632f0e9c70Deposit111615802021-09-23 9:44:1014 secs agoValidator: MathWallet IN  BSC: Validator Set0.194112156530511 BNB0
0xba14f8ae35950a719787a0fffeabcf20b90fdd35abff57fdc47ff1318520a5b3Deposit111615792021-09-23 9:44:0717 secs agoValidator: Pexmons IN  BSC: Validator Set0.222272227761163 BNB0
0x1f8f5f7f79d6315f56e7dd17d4294841e0271ecaf74199edcd401b6261a51dc3Deposit111615782021-09-23 9:44:0420 secs agoValidator: Certik IN  BSC: Validator Set0.138398550969225 BNB0
0x603bd045bfd13351a06c4d365f3f57a523b4c51e0841f69160c1879d757389bcDeposit111615772021-09-23 9:44:0123 secs agoValidator: Coinlix IN  BSC: Validator Set0.104548307173217 BNB0
0x613c2f57c95c271fe8201d08e31a6c37a10af28fc97462be266a8a406c20c706Deposit111615762021-09-23 9:43:5826 secs agoValidator: Alan Turing IN  BSC: Validator Set0.118151127018563 BNB0
0x691e76a6ef82bad84f70167829881b70e57a13f1a3c3edff97dc66f89ac419f2Deposit111615752021-09-23 9:43:5529 secs agoValidator: Avengers IN  BSC: Validator Set0.152373715112987 BNB0
0x4d5ece7a74e6bbb9477c8665cf7c3fbf9330b8dc14f9b74bc04e406a5b8957abDeposit111615742021-09-23 9:43:5232 secs agoValidator: Ankr IN  BSC: Validator Set0.121021057230028 BNB0
0xa38bf148901307171e339e93babe2fe17bbd7760a1516676c11fab4304c0510eDeposit111615732021-09-23 9:43:4935 secs agoValidator: Stake2me IN  BSC: Validator Set0.083176151664015 BNB0
0x8ee0465497276a3ffb097eff1661fedc31e327902ded50beb8364f8d2866b908Deposit111615722021-09-23 9:43:4638 secs agoValidator: Legend III IN  BSC: Validator Set0.187302349685163 BNB0
0xe424bf0439b9f3188f7c0ce1edb64317c8514d66b532024bd620251fc17afb5aDeposit111615712021-09-23 9:43:4341 secs agoValidator: Fuji IN  BSC: Validator Set0.144999706439377 BNB0
0x9de2da641fcaa52f9a559ca7943a4f1049d237c3d5d1552e35817f22fbaf278aDeposit111615702021-09-23 9:43:4044 secs agoValidator: BscScan IN  BSC: Validator Set0.104885251152497 BNB0
0x41a3311cf5b55bcb82dcc3f3bd9edc9575393a019fd4823e44a663af4f01cc5bDeposit111615692021-09-23 9:43:3747 secs agoValidator: Namelix IN  BSC: Validator Set0.124149617370688 BNB0
0x6bc12be05a3687177db32750681d399991ea4d397beea786568b3a2dd901b14dDeposit111615682021-09-23 9:43:3450 secs agoValidator: Ciscox IN  BSC: Validator Set0.190256578991605 BNB0
0x705e805fae6e28e5cf6fc600df9e976a171e7aae4ce62300df6065103f0d7c2eDeposit111615672021-09-23 9:43:3153 secs agoValidator: Legend II IN  BSC: Validator Set0.158646912559667 BNB0
0x13fa9aac55ac92838e0fe94149306f4fad01f14e809592949b7ec986df40d311Deposit111615662021-09-23 9:43:2856 secs agoValidator: NodeReal IN  BSC: Validator Set0.102966251775472 BNB0
0xc8a90f1e1a8678c3bbc216c58d6c1547b15ee299ba145f59f24ff885480c46c9Deposit111615652021-09-23 9:43:2559 secs agoValidator: CREAM IN  BSC: Validator Set0.167584713139063 BNB0
0xeace0ad19aa47651d14d2aeffe5db597155dede2c4af3fe91b1c3c1a1e17396cDeposit111615642021-09-23 9:43:221 min agoValidator: Legend IN  BSC: Validator Set0.13104925581 BNB0
0xb588db6c038d53c61939a49b005e6757036b068b4b55a8058567001cc01fabe5Deposit111615632021-09-23 9:43:191 min agoValidator: TW Staking IN  BSC: Validator Set0.139966472336111 BNB0
0x416c3768a53903cfd1cd556493db1d6ffc171f7a40f27db5dcfd67717d649a74Deposit111615622021-09-23 9:43:161 min agoValidator: InfStones IN  BSC: Validator Set0.127119671451881 BNB0
0x56ac335df26bc04bf449da4ac31fb3b0e9a68097b5353b8ee4c878cda7001c98Deposit111615612021-09-23 9:43:131 min agoValidator: Defibit IN  BSC: Validator Set0.136847276252649 BNB0
0x481b0ea78b10f5b23c4efdeb9f9bb0bf06056382908a3cec50c91987892623cdDeposit111615602021-09-23 9:43:101 min agoValidator: HashQuark IN  BSC: Validator Set0.217798992280405 BNB0
0x209a5be61424599bab1f908e4bf2e08327d8e10ca3c37d2ce64a3523e1c8f9d8Deposit111615592021-09-23 9:43:071 min agoValidator: MathWallet IN  BSC: Validator Set0.218281385554951 BNB0
0xd406121e2e4b74c3d36ab65031f45047c532ea4993197607eebdf49925da3ba2Deposit111615582021-09-23 9:43:041 min agoValidator: Pexmons IN  BSC: Validator Set0.159404529347301 BNB0
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x675f743fee926c7609cc24c4a8c709ef8201323984d2549519d868d6d3b5bd83111499892021-09-23 0:00:489 hrs 43 mins ago BSC: Validator Set BSC: System Reward0.000000118798812999 BNB
0x675f743fee926c7609cc24c4a8c709ef8201323984d2549519d868d6d3b5bd83111499892021-09-23 0:00:489 hrs 43 mins ago BSC: Validator Set BSC: Token Hub4,505.82457799 BNB
0xc1cc5b2fea53e6c5b495ec29a585db5ac01051f032d2f2cc997c8a2109825a0f111214082021-09-22 0:00:411 day 9 hrs ago BSC: Validator Set BSC: System Reward0.000000119577490418 BNB
0xc1cc5b2fea53e6c5b495ec29a585db5ac01051f032d2f2cc997c8a2109825a0f111214082021-09-22 0:00:411 day 9 hrs ago BSC: Validator Set BSC: Token Hub4,873.73809461 BNB
0x5e624bad3f01896092d45284232ea318582ce4f32b83cc86cf871fe69ec6f9bb110927882021-09-21 0:00:502 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000111544646997 BNB
0x5e624bad3f01896092d45284232ea318582ce4f32b83cc86cf871fe69ec6f9bb110927882021-09-21 0:00:502 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,776.2193313 BNB
0xb6b13c70b51403f02c4c09161e208b71f4e3af6937445e5c06d11665285f689e110640632021-09-20 0:01:213 days 9 hrs ago BSC: Validator Set BSC: System Reward0.00000010739166773 BNB
0xb6b13c70b51403f02c4c09161e208b71f4e3af6937445e5c06d11665285f689e110640632021-09-20 0:01:213 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,325.86454409 BNB
0x0059e654cb113365a1bc23802a65558d880dd85f34f145c0b9c6a4a2880bca49110355442021-09-19 0:00:404 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000124923405911 BNB
0x0059e654cb113365a1bc23802a65558d880dd85f34f145c0b9c6a4a2880bca49110355442021-09-19 0:00:404 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,592.94421122 BNB
0xc706482d6d3dc3064c4a79cfe5b650482732f1c7673476278611970a3e78db87110068332021-09-18 0:00:525 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000116079246171 BNB
0xc706482d6d3dc3064c4a79cfe5b650482732f1c7673476278611970a3e78db87110068332021-09-18 0:00:525 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,346.59522327 BNB
0x84ec7ffacfc70c6db3d7711f4521e57a84cc1498bab768e655b4a36f9526f0d4109780592021-09-17 0:00:456 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000125980480527 BNB
0x84ec7ffacfc70c6db3d7711f4521e57a84cc1498bab768e655b4a36f9526f0d4109780592021-09-17 0:00:456 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,924.06414604 BNB
0xf54ed918b663ffd8bf8bc5ea3274c3df3e3c73a0681dcdd6c93b768c076fca18109493252021-09-16 0:00:507 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000114480557032 BNB
0xf54ed918b663ffd8bf8bc5ea3274c3df3e3c73a0681dcdd6c93b768c076fca18109493252021-09-16 0:00:507 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,289.92824611 BNB
0xaf94c2452e75e2f750ad70682daaba9799f37ed87e3479d6e6a08a3bebaf4361109206542021-09-15 0:00:538 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000105697304651 BNB
0xaf94c2452e75e2f750ad70682daaba9799f37ed87e3479d6e6a08a3bebaf4361109206542021-09-15 0:00:538 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,520.33125205 BNB
0xbcec22cda2a6c17972f653614b84b79b000e9bbcf04b66e3da8d3c39c4c59808108919222021-09-14 0:00:479 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000112794420116 BNB
0xbcec22cda2a6c17972f653614b84b79b000e9bbcf04b66e3da8d3c39c4c59808108919222021-09-14 0:00:479 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,126.20271378 BNB
0xf1cb0e25302584f557c347d4b88419808fd1cf2e4e9ef41ed87272c0731dd71c108631802021-09-13 0:00:3810 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000093750300781 BNB
0xf1cb0e25302584f557c347d4b88419808fd1cf2e4e9ef41ed87272c0731dd71c108631802021-09-13 0:00:3810 days 9 hrs ago BSC: Validator Set BSC: Token Hub4,141.53427491 BNB
0xb6c8f818685a23ccea97ff877145ce7c441f399ea1af187dfdfb45c72c7cdbd7108344082021-09-12 0:00:4211 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000111935967283 BNB
0xb6c8f818685a23ccea97ff877145ce7c441f399ea1af187dfdfb45c72c7cdbd7108344082021-09-12 0:00:4211 days 9 hrs ago BSC: Validator Set BSC: Token Hub3,670.36591001 BNB
0xf50dab9ee8cffdf71f40953454731fc1ff3634f9a0860214ffa65ce764ac9135108059012021-09-11 0:00:5112 days 9 hrs ago BSC: Validator Set BSC: System Reward0.000000094776703428 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BSCValidatorSet

Compiler Version
v0.6.4+commit.1dca32f3

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at BscScan.com on 2020-09-02
*/

// File: contracts/interface/ISystemReward.sol

pragma solidity 0.6.4;

interface ISystemReward {
  function claimRewards(address payable to, uint256 amount) external returns(uint256 actualAmount);
}

// File: contracts/interface/IRelayerHub.sol

pragma solidity 0.6.4;

interface IRelayerHub {
  function isRelayer(address sender) external view returns (bool);
}

// File: contracts/interface/ILightClient.sol

pragma solidity 0.6.4;

interface ILightClient {

  function isHeaderSynced(uint64 height) external view returns (bool);

  function getAppHash(uint64 height) external view returns (bytes32);

  function getSubmitter(uint64 height) external view returns (address payable);

}

// File: contracts/System.sol

pragma solidity 0.6.4;




contract System {

  bool public alreadyInit;

  uint32 public constant CODE_OK = 0;
  uint32 public constant ERROR_FAIL_DECODE = 100;

  uint8 constant public BIND_CHANNELID = 0x01;
  uint8 constant public TRANSFER_IN_CHANNELID = 0x02;
  uint8 constant public TRANSFER_OUT_CHANNELID = 0x03;
  uint8 constant public STAKING_CHANNELID = 0x08;
  uint8 constant public GOV_CHANNELID = 0x09;
  uint8 constant public SLASH_CHANNELID = 0x0b;
  uint16 constant public bscChainID = 0x0038;

  address public constant VALIDATOR_CONTRACT_ADDR = 0x0000000000000000000000000000000000001000;
  address public constant SLASH_CONTRACT_ADDR = 0x0000000000000000000000000000000000001001;
  address public constant SYSTEM_REWARD_ADDR = 0x0000000000000000000000000000000000001002;
  address public constant LIGHT_CLIENT_ADDR = 0x0000000000000000000000000000000000001003;
  address public constant TOKEN_HUB_ADDR = 0x0000000000000000000000000000000000001004;
  address public constant INCENTIVIZE_ADDR=0x0000000000000000000000000000000000001005;
  address public constant RELAYERHUB_CONTRACT_ADDR = 0x0000000000000000000000000000000000001006;
  address public constant GOV_HUB_ADDR = 0x0000000000000000000000000000000000001007;
  address public constant TOKEN_MANAGER_ADDR = 0x0000000000000000000000000000000000001008;
  address public constant CROSS_CHAIN_CONTRACT_ADDR = 0x0000000000000000000000000000000000002000;


  modifier onlyCoinbase() {
    require(msg.sender == block.coinbase, "the message sender must be the block producer");
    _;
  }

  modifier onlyNotInit() {
    require(!alreadyInit, "the contract already init");
    _;
  }

  modifier onlyInit() {
    require(alreadyInit, "the contract not init yet");
    _;
  }

  modifier onlySlash() {
    require(msg.sender == SLASH_CONTRACT_ADDR, "the message sender must be slash contract");
    _;
  }

  modifier onlyTokenHub() {
    require(msg.sender == TOKEN_HUB_ADDR, "the message sender must be token hub contract");
    _;
  }

  modifier onlyGov() {
    require(msg.sender == GOV_HUB_ADDR, "the message sender must be governance contract");
    _;
  }

  modifier onlyValidatorContract() {
    require(msg.sender == VALIDATOR_CONTRACT_ADDR, "the message sender must be validatorSet contract");
    _;
  }

  modifier onlyCrossChainContract() {
    require(msg.sender == CROSS_CHAIN_CONTRACT_ADDR, "the message sender must be cross chain contract");
    _;
  }

  modifier onlyRelayerIncentivize() {
    require(msg.sender == INCENTIVIZE_ADDR, "the message sender must be incentivize contract");
    _;
  }

  modifier onlyRelayer() {
    require(IRelayerHub(RELAYERHUB_CONTRACT_ADDR).isRelayer(msg.sender), "the msg sender is not a relayer");
    _;
  }

  modifier onlyTokenManager() {
    require(msg.sender == TOKEN_MANAGER_ADDR, "the msg sender must be tokenManager");
    _;
  }

  // Not reliable, do not use when need strong verify
  function isContract(address addr) internal view returns (bool) {
    uint size;
    assembly { size := extcodesize(addr) }
    return size > 0;
  }
}

// File: contracts/lib/BytesToTypes.sol

pragma solidity 0.6.4;

/**
 * @title BytesToTypes
 * Copyright (c) 2016-2020 zpouladzade/Seriality
 * @dev The BytesToTypes contract converts the memory byte arrays to the standard solidity types
 * @author [email protected]
 */

library BytesToTypes {


    function bytesToAddress(uint _offst, bytes memory _input) internal pure returns (address _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToBool(uint _offst, bytes memory _input) internal pure returns (bool _output) {

        uint8 x;
        assembly {
            x := mload(add(_input, _offst))
        }
        x==0 ? _output = false : _output = true;
    }

    function getStringSize(uint _offst, bytes memory _input) internal pure returns(uint size) {

        assembly{

            size := mload(add(_input,_offst))
            let chunk_count := add(div(size,32),1) // chunk_count = size/32 + 1

            if gt(mod(size,32),0) {// if size%32 > 0
                chunk_count := add(chunk_count,1)
            }

             size := mul(chunk_count,32)// first 32 bytes reseves for size in strings
        }
    }

    function bytesToString(uint _offst, bytes memory _input, bytes memory _output) internal pure {

        uint size = 32;
        assembly {

            let chunk_count

            size := mload(add(_input,_offst))
            chunk_count := add(div(size,32),1) // chunk_count = size/32 + 1

            if gt(mod(size,32),0) {
                chunk_count := add(chunk_count,1)  // chunk_count++
            }

            for { let index:= 0 }  lt(index , chunk_count) { index := add(index,1) } {
                mstore(add(_output,mul(index,32)),mload(add(_input,_offst)))
                _offst := sub(_offst,32)           // _offst -= 32
            }
        }
    }

    function bytesToBytes32(uint _offst, bytes memory  _input, bytes32 _output) internal pure {

        assembly {
            mstore(_output , add(_input, _offst))
            mstore(add(_output,32) , add(add(_input, _offst),32))
        }
    }

    function bytesToInt8(uint _offst, bytes memory  _input) internal pure returns (int8 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt16(uint _offst, bytes memory _input) internal pure returns (int16 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt24(uint _offst, bytes memory _input) internal pure returns (int24 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt32(uint _offst, bytes memory _input) internal pure returns (int32 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt40(uint _offst, bytes memory _input) internal pure returns (int40 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt48(uint _offst, bytes memory _input) internal pure returns (int48 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt56(uint _offst, bytes memory _input) internal pure returns (int56 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt64(uint _offst, bytes memory _input) internal pure returns (int64 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt72(uint _offst, bytes memory _input) internal pure returns (int72 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt80(uint _offst, bytes memory _input) internal pure returns (int80 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt88(uint _offst, bytes memory _input) internal pure returns (int88 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt96(uint _offst, bytes memory _input) internal pure returns (int96 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToInt104(uint _offst, bytes memory _input) internal pure returns (int104 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt112(uint _offst, bytes memory _input) internal pure returns (int112 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt120(uint _offst, bytes memory _input) internal pure returns (int120 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt128(uint _offst, bytes memory _input) internal pure returns (int128 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt136(uint _offst, bytes memory _input) internal pure returns (int136 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt144(uint _offst, bytes memory _input) internal pure returns (int144 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt152(uint _offst, bytes memory _input) internal pure returns (int152 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt160(uint _offst, bytes memory _input) internal pure returns (int160 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt168(uint _offst, bytes memory _input) internal pure returns (int168 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt176(uint _offst, bytes memory _input) internal pure returns (int176 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt184(uint _offst, bytes memory _input) internal pure returns (int184 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt192(uint _offst, bytes memory _input) internal pure returns (int192 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt200(uint _offst, bytes memory _input) internal pure returns (int200 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt208(uint _offst, bytes memory _input) internal pure returns (int208 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt216(uint _offst, bytes memory _input) internal pure returns (int216 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt224(uint _offst, bytes memory _input) internal pure returns (int224 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt232(uint _offst, bytes memory _input) internal pure returns (int232 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt240(uint _offst, bytes memory _input) internal pure returns (int240 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt248(uint _offst, bytes memory _input) internal pure returns (int248 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToInt256(uint _offst, bytes memory _input) internal pure returns (int256 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint8(uint _offst, bytes memory _input) internal pure returns (uint8 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint16(uint _offst, bytes memory _input) internal pure returns (uint16 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint24(uint _offst, bytes memory _input) internal pure returns (uint24 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint32(uint _offst, bytes memory _input) internal pure returns (uint32 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint40(uint _offst, bytes memory _input) internal pure returns (uint40 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint48(uint _offst, bytes memory _input) internal pure returns (uint48 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint56(uint _offst, bytes memory _input) internal pure returns (uint56 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint64(uint _offst, bytes memory _input) internal pure returns (uint64 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint72(uint _offst, bytes memory _input) internal pure returns (uint72 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint80(uint _offst, bytes memory _input) internal pure returns (uint80 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint88(uint _offst, bytes memory _input) internal pure returns (uint88 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint96(uint _offst, bytes memory _input) internal pure returns (uint96 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

        function bytesToUint104(uint _offst, bytes memory _input) internal pure returns (uint104 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint112(uint _offst, bytes memory _input) internal pure returns (uint112 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint120(uint _offst, bytes memory _input) internal pure returns (uint120 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint128(uint _offst, bytes memory _input) internal pure returns (uint128 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint136(uint _offst, bytes memory _input) internal pure returns (uint136 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint144(uint _offst, bytes memory _input) internal pure returns (uint144 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint152(uint _offst, bytes memory _input) internal pure returns (uint152 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint160(uint _offst, bytes memory _input) internal pure returns (uint160 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint168(uint _offst, bytes memory _input) internal pure returns (uint168 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint176(uint _offst, bytes memory _input) internal pure returns (uint176 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint184(uint _offst, bytes memory _input) internal pure returns (uint184 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint192(uint _offst, bytes memory _input) internal pure returns (uint192 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint200(uint _offst, bytes memory _input) internal pure returns (uint200 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint208(uint _offst, bytes memory _input) internal pure returns (uint208 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint216(uint _offst, bytes memory _input) internal pure returns (uint216 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint224(uint _offst, bytes memory _input) internal pure returns (uint224 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint232(uint _offst, bytes memory _input) internal pure returns (uint232 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint240(uint _offst, bytes memory _input) internal pure returns (uint240 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint248(uint _offst, bytes memory _input) internal pure returns (uint248 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

    function bytesToUint256(uint _offst, bytes memory _input) internal pure returns (uint256 _output) {

        assembly {
            _output := mload(add(_input, _offst))
        }
    }

}

// File: contracts/lib/Memory.sol

pragma solidity 0.6.4;

library Memory {

    // Size of a word, in bytes.
    uint internal constant WORD_SIZE = 32;
    // Size of the header of a 'bytes' array.
    uint internal constant BYTES_HEADER_SIZE = 32;
    // Address of the free memory pointer.
    uint internal constant FREE_MEM_PTR = 0x40;

    // Compares the 'len' bytes starting at address 'addr' in memory with the 'len'
    // bytes starting at 'addr2'.
    // Returns 'true' if the bytes are the same, otherwise 'false'.
    function equals(uint addr, uint addr2, uint len) internal pure returns (bool equal) {
        assembly {
            equal := eq(keccak256(addr, len), keccak256(addr2, len))
        }
    }

    // Compares the 'len' bytes starting at address 'addr' in memory with the bytes stored in
    // 'bts'. It is allowed to set 'len' to a lower value then 'bts.length', in which case only
    // the first 'len' bytes will be compared.
    // Requires that 'bts.length >= len'
    function equals(uint addr, uint len, bytes memory bts) internal pure returns (bool equal) {
        require(bts.length >= len);
        uint addr2;
        assembly {
            addr2 := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
        return equals(addr, addr2, len);
    }

    function compareStrings(string memory a, string memory b) internal pure returns (bool) {
        return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
    }

    // Copy 'len' bytes from memory address 'src', to address 'dest'.
    // This function does not check the or destination, it only copies
    // the bytes.
    function copy(uint src, uint dest, uint len) internal pure {
        // Copy word-length chunks while possible
        for (; len >= WORD_SIZE; len -= WORD_SIZE) {
            assembly {
                mstore(dest, mload(src))
            }
            dest += WORD_SIZE;
            src += WORD_SIZE;
        }

        // Copy remaining bytes
        uint mask = 256 ** (WORD_SIZE - len) - 1;
        assembly {
            let srcpart := and(mload(src), not(mask))
            let destpart := and(mload(dest), mask)
            mstore(dest, or(destpart, srcpart))
        }
    }

    // Returns a memory pointer to the provided bytes array.
    function ptr(bytes memory bts) internal pure returns (uint addr) {
        assembly {
            addr := bts
        }
    }

    // Returns a memory pointer to the data portion of the provided bytes array.
    function dataPtr(bytes memory bts) internal pure returns (uint addr) {
        assembly {
            addr := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
    }

    // This function does the same as 'dataPtr(bytes memory)', but will also return the
    // length of the provided bytes array.
    function fromBytes(bytes memory bts) internal pure returns (uint addr, uint len) {
        len = bts.length;
        assembly {
            addr := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
    }

    // Creates a 'bytes memory' variable from the memory address 'addr', with the
    // length 'len'. The function will allocate new memory for the bytes array, and
    // the 'len bytes starting at 'addr' will be copied into that new memory.
    function toBytes(uint addr, uint len) internal pure returns (bytes memory bts) {
        bts = new bytes(len);
        uint btsptr;
        assembly {
            btsptr := add(bts, /*BYTES_HEADER_SIZE*/32)
        }
        copy(addr, btsptr, len);
    }

    // Get the word stored at memory address 'addr' as a 'uint'.
    function toUint(uint addr) internal pure returns (uint n) {
        assembly {
            n := mload(addr)
        }
    }

    // Get the word stored at memory address 'addr' as a 'bytes32'.
    function toBytes32(uint addr) internal pure returns (bytes32 bts) {
        assembly {
            bts := mload(addr)
        }
    }
}

// File: contracts/interface/ISlashIndicator.sol

pragma solidity 0.6.4;

interface ISlashIndicator {
  function clean() external;
}

// File: contracts/interface/ITokenHub.sol

pragma solidity 0.6.4;

interface ITokenHub {

  function getMiniRelayFee() external view returns(uint256);

  function getContractAddrByBEP2Symbol(bytes32 bep2Symbol) external view returns(address);

  function getBep2SymbolByContractAddr(address contractAddr) external view returns(bytes32);

  function bindToken(bytes32 bep2Symbol, address contractAddr, uint256 decimals) external;

  function unbindToken(bytes32 bep2Symbol, address contractAddr) external;

  function transferOut(address contractAddr, address recipient, uint256 amount, uint64 expireTime)
    external payable returns (bool);

  /* solium-disable-next-line */
  function batchTransferOutBNB(address[] calldata recipientAddrs, uint256[] calldata amounts, address[] calldata refundAddrs,
    uint64 expireTime) external payable returns (bool);

}

// File: contracts/interface/IParamSubscriber.sol

pragma solidity 0.6.4;

interface IParamSubscriber {
    function updateParam(string calldata key, bytes calldata value) external;
}

// File: contracts/interface/IBSCValidatorSet.sol

pragma solidity 0.6.4;

interface IBSCValidatorSet {
  function misdemeanor(address validator) external;
  function felony(address validator)external;
}

// File: contracts/interface/IApplication.sol

pragma solidity 0.6.4;

interface IApplication {
    /**
     * @dev Handle syn package
     */
    function handleSynPackage(uint8 channelId, bytes calldata msgBytes) external returns(bytes memory responsePayload);

    /**
     * @dev Handle ack package
     */
    function handleAckPackage(uint8 channelId, bytes calldata msgBytes) external;

    /**
     * @dev Handle fail ack package
     */
    function handleFailAckPackage(uint8 channelId, bytes calldata msgBytes) external;
}

// File: contracts/lib/SafeMath.sol

pragma solidity 0.6.4;

/**
 * Copyright (c) 2016-2019 zOS Global Limited
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot 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-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// File: contracts/lib/RLPDecode.sol

pragma solidity 0.6.4;

library RLPDecode {
    uint8 constant STRING_SHORT_START = 0x80;
    uint8 constant STRING_LONG_START  = 0xb8;
    uint8 constant LIST_SHORT_START   = 0xc0;
    uint8 constant LIST_LONG_START    = 0xf8;

    uint8 constant WORD_SIZE = 32;

    struct RLPItem {
        uint len;
        uint memPtr;
    }

    struct Iterator {
        RLPItem item;   // Item that's being iterated over.
        uint nextPtr;   // Position of the next item in the list.
    }

    function next(Iterator memory self) internal pure returns (RLPItem memory) {
        require(hasNext(self));

        uint ptr = self.nextPtr;
        uint itemLength = _itemLength(ptr);
        self.nextPtr = ptr + itemLength;

        return RLPItem(itemLength, ptr);
    }

    function hasNext(Iterator memory self) internal pure returns (bool) {
        RLPItem memory item = self.item;
        return self.nextPtr < item.memPtr + item.len;
    }

    function toRLPItem(bytes memory self) internal pure returns (RLPItem memory) {
        uint memPtr;
        assembly {
            memPtr := add(self, 0x20)
        }

        return RLPItem(self.length, memPtr);
    }

    function iterator(RLPItem memory self) internal pure returns (Iterator memory) {
        require(isList(self));

        uint ptr = self.memPtr + _payloadOffset(self.memPtr);
        return Iterator(self, ptr);
    }

    function rlpLen(RLPItem memory item) internal pure returns (uint) {
        return item.len;
    }

    function payloadLen(RLPItem memory item) internal pure returns (uint) {
        return item.len - _payloadOffset(item.memPtr);
    }

    function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {
        require(isList(item));

        uint items = numItems(item);
        RLPItem[] memory result = new RLPItem[](items);

        uint memPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint dataLen;
        for (uint i = 0; i < items; i++) {
            dataLen = _itemLength(memPtr);
            result[i] = RLPItem(dataLen, memPtr);
            memPtr = memPtr + dataLen;
        }

        return result;
    }

    function isList(RLPItem memory item) internal pure returns (bool) {
        if (item.len == 0) return false;

        uint8 byte0;
        uint memPtr = item.memPtr;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < LIST_SHORT_START)
            return false;
        return true;
    }

    function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
        bytes memory result = new bytes(item.len);
        if (result.length == 0) return result;

        uint ptr;
        assembly {
            ptr := add(0x20, result)
        }

        copy(item.memPtr, ptr, item.len);
        return result;
    }

    function toBoolean(RLPItem memory item) internal pure returns (bool) {
        require(item.len == 1);
        uint result;
        uint memPtr = item.memPtr;
        assembly {
            result := byte(0, mload(memPtr))
        }

        return result == 0 ? false : true;
    }

    function toAddress(RLPItem memory item) internal pure returns (address) {
        // 1 byte for the length prefix
        require(item.len == 21);

        return address(toUint(item));
    }

    function toUint(RLPItem memory item) internal pure returns (uint) {
        require(item.len > 0 && item.len <= 33);

        uint offset = _payloadOffset(item.memPtr);
        require(item.len >= offset, "length is less than offset");
        uint len = item.len - offset;

        uint result;
        uint memPtr = item.memPtr + offset;
        assembly {
            result := mload(memPtr)

        // shfit to the correct location if neccesary
            if lt(len, 32) {
                result := div(result, exp(256, sub(32, len)))
            }
        }

        return result;
    }

    // enforces 32 byte length
    function toUintStrict(RLPItem memory item) internal pure returns (uint) {
        // one byte prefix
        require(item.len == 33);

        uint result;
        uint memPtr = item.memPtr + 1;
        assembly {
            result := mload(memPtr)
        }

        return result;
    }

    function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
        require(item.len > 0);

        uint offset = _payloadOffset(item.memPtr);
        uint len = item.len - offset; // data length
        bytes memory result = new bytes(len);

        uint destPtr;
        assembly {
            destPtr := add(0x20, result)
        }

        copy(item.memPtr + offset, destPtr, len);
        return result;
    }

    function numItems(RLPItem memory item) private pure returns (uint) {
        if (item.len == 0) return 0;

        uint count = 0;
        uint currPtr = item.memPtr + _payloadOffset(item.memPtr);
        uint endPtr = item.memPtr + item.len;
        while (currPtr < endPtr) {
            currPtr = currPtr + _itemLength(currPtr); // skip over an item
            count++;
        }

        return count;
    }

    function _itemLength(uint memPtr) private pure returns (uint) {
        uint itemLen;
        uint byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START)
            itemLen = 1;

        else if (byte0 < STRING_LONG_START)
            itemLen = byte0 - STRING_SHORT_START + 1;

        else if (byte0 < LIST_SHORT_START) {
            uint dataLen;
            assembly {
                let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is
                memPtr := add(memPtr, 1) // skip over the first byte

                /* 32 byte word size */
                dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
                itemLen := add(dataLen, add(byteLen, 1))
            }
            require(itemLen >= dataLen, "addition overflow");
        }

        else if (byte0 < LIST_LONG_START) {
            itemLen = byte0 - LIST_SHORT_START + 1;
        }

        else {
            uint dataLen;
            assembly {
                let byteLen := sub(byte0, 0xf7)
                memPtr := add(memPtr, 1)

                dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
                itemLen := add(dataLen, add(byteLen, 1))
            }
            require(itemLen >= dataLen, "addition overflow");
        }

        return itemLen;
    }

    // @return number of bytes until the data
    function _payloadOffset(uint memPtr) private pure returns (uint) {
        uint byte0;
        assembly {
            byte0 := byte(0, mload(memPtr))
        }

        if (byte0 < STRING_SHORT_START)
            return 0;
        else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))
            return 1;
        else if (byte0 < LIST_SHORT_START)  // being explicit
            return byte0 - (STRING_LONG_START - 1) + 1;
        else
            return byte0 - (LIST_LONG_START - 1) + 1;
    }

    /*
    * @param src Pointer to source
    * @param dest Pointer to destination
    * @param len Amount of memory to copy from the source
    */
    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))
        }
    }
}

// File: contracts/lib/RLPEncode.sol

pragma solidity 0.6.4;

library RLPEncode {

    uint8 constant STRING_OFFSET = 0x80;
    uint8 constant LIST_OFFSET = 0xc0;

    /**
     * @notice Encode string item
     * @param self The string (ie. byte array) item to encode
     * @return The RLP encoded string in bytes
     */
    function encodeBytes(bytes memory self) internal pure returns (bytes memory) {
        if (self.length == 1 && self[0] <= 0x7f) {
            return self;
        }
        return mergeBytes(encodeLength(self.length, STRING_OFFSET), self);
    }

    /**
     * @notice Encode address
     * @param self The address to encode
     * @return The RLP encoded address in bytes
     */
    function encodeAddress(address self) internal pure returns (bytes memory) {
        bytes memory b;
        assembly {
            let m := mload(0x40)
            mstore(add(m, 20), xor(0x140000000000000000000000000000000000000000, self))
            mstore(0x40, add(m, 52))
            b := m
        }
        return encodeBytes(b);
    }

    /**
     * @notice Encode uint
     * @param self The uint to encode
     * @return The RLP encoded uint in bytes
     */
    function encodeUint(uint self) internal pure returns (bytes memory) {
        return encodeBytes(toBinary(self));
    }

    /**
     * @notice Encode int
     * @param self The int to encode
     * @return The RLP encoded int in bytes
     */
    function encodeInt(int self) internal pure returns (bytes memory) {
        return encodeUint(uint(self));
    }

    /**
     * @notice Encode bool
     * @param self The bool to encode
     * @return The RLP encoded bool in bytes
     */
    function encodeBool(bool self) internal pure returns (bytes memory) {
        bytes memory rs = new bytes(1);
        if (self) {
            rs[0] = bytes1(uint8(1));
        }
        return rs;
    }

    /**
     * @notice Encode list of items
     * @param self The list of items to encode, each item in list must be already encoded
     * @return The RLP encoded list of items in bytes
     */
    function encodeList(bytes[] memory self) internal pure returns (bytes memory) {
        if (self.length == 0) {
            return new bytes(0);
        }
        bytes memory payload = self[0];
        for (uint i = 1; i < self.length; i++) {
            payload = mergeBytes(payload, self[i]);
        }
        return mergeBytes(encodeLength(payload.length, LIST_OFFSET), payload);
    }

    /**
     * @notice Concat two bytes arrays
     * @param _preBytes The first bytes array
     * @param _postBytes The second bytes array
     * @return The merged bytes array
     */
    function mergeBytes(
        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;
    }

    /**
     * @notice Encode the first byte, followed by the `length` in binary form if `length` is more than 55.
     * @param length The length of the string or the payload
     * @param offset `STRING_OFFSET` if item is string, `LIST_OFFSET` if item is list
     * @return RLP encoded bytes
     */
    function encodeLength(uint length, uint offset) internal pure returns (bytes memory) {
        require(length < 256**8, "input too long");
        bytes memory rs = new bytes(1);
        if (length <= 55) {
            rs[0] = byte(uint8(length + offset));
            return rs;
        }
        bytes memory bl = toBinary(length);
        rs[0] = byte(uint8(bl.length + offset + 55));
        return mergeBytes(rs, bl);
    }

    /**
     * @notice Encode integer in big endian binary form with no leading zeroes
     * @param x The integer to encode
     * @return RLP encoded bytes
     */
    function toBinary(uint x) internal pure returns (bytes memory) {
        bytes memory b = new bytes(32);
        assembly {
            mstore(add(b, 32), x)
        }
        uint i;
        if (x & 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 == 0) {
            i = 24;
        } else if (x & 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000 == 0) {
            i = 16;
        } else {
            i = 0;
        }
        for (; i < 32; i++) {
            if (b[i] != 0) {
                break;
            }
        }
        uint length = 32 - i;
        bytes memory rs = new bytes(length);
        assembly {
            mstore(add(rs, length), x)
            mstore(rs, length)
        }
        return rs;
    }
}

// File: contracts/lib/CmnPkg.sol

pragma solidity 0.6.4;



library CmnPkg {

    using RLPEncode for *;
    using RLPDecode for *;


    struct CommonAckPackage {
        uint32 code;
    }

    function encodeCommonAckPackage(uint32 code) internal pure returns (bytes memory) {
        bytes[] memory elements = new bytes[](1);
        elements[0] = uint256(code).encodeUint();
        return elements.encodeList();
    }

    function decodeCommonAckPackage(bytes memory msgBytes) internal pure returns (CommonAckPackage memory, bool) {
        CommonAckPackage memory ackPkg;
        RLPDecode.Iterator memory iter = msgBytes.toRLPItem().iterator();

        bool success = false;
        uint256 idx=0;
        while (iter.hasNext()) {
            if (idx == 0) {
                ackPkg.code = uint32(iter.next().toUint());
                success = true;
            } else {
                break;
            }
            idx++;
        }
        return (ackPkg, success);
    }
}

// File: contracts/BSCValidatorSet.sol

pragma solidity 0.6.4;















contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplication {

  using SafeMath for uint256;

  using RLPDecode for *;

  // will not transfer value less than 0.1 BNB for validators
  uint256 constant public DUSTY_INCOMING = 1e17;

  uint8 public constant JAIL_MESSAGE_TYPE = 1;
  uint8 public constant VALIDATORS_UPDATE_MESSAGE_TYPE = 0;

  // the precision of cross chain value transfer.
  uint256 public constant PRECISION = 1e10;
  uint256 public constant EXPIRE_TIME_SECOND_GAP = 1000;
  uint256 public constant MAX_NUM_OF_VALIDATORS = 41;

  bytes public constant INIT_VALIDATORSET_BYTES = hex"f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000";

  uint32 public constant ERROR_UNKNOWN_PACKAGE_TYPE = 101;
  uint32 public constant ERROR_FAIL_CHECK_VALIDATORS = 102;
  uint32 public constant ERROR_LEN_OF_VAL_MISMATCH = 103;
  uint32 public constant ERROR_RELAYFEE_TOO_LARGE = 104;


  /*********************** state of the contract **************************/
  Validator[] public currentValidatorSet;
  uint256 public expireTimeSecondGap;
  uint256 public totalInComing;

  // key is the `consensusAddress` of `Validator`,
  // value is the index of the element in `currentValidatorSet`.
  mapping(address =>uint256) public currentValidatorSetMap;
  uint256 public numOfJailed;

  struct Validator{
    address consensusAddress;
    address payable feeAddress;
    address BBCFeeAddress;
    uint64  votingPower;

    // only in state
    bool jailed;
    uint256 incoming;
  }

  /*********************** cross chain package **************************/
  struct IbcValidatorSetPackage {
    uint8  packageType;
    Validator[] validatorSet;
  }

  /*********************** modifiers **************************/
  modifier noEmptyDeposit() {
    require(msg.value > 0, "deposit value is zero");
    _;
  }

  /*********************** events **************************/
  event validatorSetUpdated();
  event validatorJailed(address indexed validator);
  event validatorEmptyJailed(address indexed validator);
  event batchTransfer(uint256 amount);
  event batchTransferFailed(uint256 indexed amount, string reason);
  event batchTransferLowerFailed(uint256 indexed amount, bytes reason);
  event systemTransfer(uint256 amount);
  event directTransfer(address payable indexed validator, uint256 amount);
  event directTransferFail(address payable indexed validator, uint256 amount);
  event deprecatedDeposit(address indexed validator, uint256 amount);
  event validatorDeposit(address indexed validator, uint256 amount);
  event validatorMisdemeanor(address indexed validator, uint256 amount);
  event validatorFelony(address indexed validator, uint256 amount);
  event failReasonWithStr(string message);
  event unexpectedPackage(uint8 channelId, bytes msgBytes);
  event paramChange(string key, bytes value);

  /*********************** init **************************/
  function init() external onlyNotInit{
    (IbcValidatorSetPackage memory validatorSetPkg, bool valid)= decodeValidatorSetSynPackage(INIT_VALIDATORSET_BYTES);
    require(valid, "failed to parse init validatorSet");
    for (uint i = 0;i<validatorSetPkg.validatorSet.length;i++) {
      currentValidatorSet.push(validatorSetPkg.validatorSet[i]);
      currentValidatorSetMap[validatorSetPkg.validatorSet[i].consensusAddress] = i+1;
    }
    expireTimeSecondGap = EXPIRE_TIME_SECOND_GAP;
    alreadyInit = true;
  }

  /*********************** Cross Chain App Implement **************************/
  function handleSynPackage(uint8, bytes calldata msgBytes) onlyInit onlyCrossChainContract external override returns(bytes memory responsePayload) {
    (IbcValidatorSetPackage memory validatorSetPackage, bool ok) = decodeValidatorSetSynPackage(msgBytes);
    if (!ok) {
      return CmnPkg.encodeCommonAckPackage(ERROR_FAIL_DECODE);
    }
    uint32 resCode;
    if (validatorSetPackage.packageType == VALIDATORS_UPDATE_MESSAGE_TYPE) {
      resCode = updateValidatorSet(validatorSetPackage.validatorSet);
    } else if (validatorSetPackage.packageType == JAIL_MESSAGE_TYPE) {
      if (validatorSetPackage.validatorSet.length != 1) {
        emit failReasonWithStr("length of jail validators must be one");
        resCode = ERROR_LEN_OF_VAL_MISMATCH;
      } else {
        resCode = jailValidator(validatorSetPackage.validatorSet[0]);
      }
    } else {
      resCode = ERROR_UNKNOWN_PACKAGE_TYPE;
    }
    if (resCode == CODE_OK) {
      return new bytes(0);
    } else {
      return CmnPkg.encodeCommonAckPackage(resCode);
    }
  }

  function handleAckPackage(uint8 channelId, bytes calldata msgBytes) external onlyCrossChainContract override {
    // should not happen
    emit unexpectedPackage(channelId, msgBytes);
  }

  function handleFailAckPackage(uint8 channelId, bytes calldata msgBytes) external onlyCrossChainContract override {
    // should not happen
    emit unexpectedPackage(channelId, msgBytes);
  }

  /*********************** External Functions **************************/
  function deposit(address valAddr) external payable onlyCoinbase onlyInit noEmptyDeposit{
    uint256 value = msg.value;
    uint256 index = currentValidatorSetMap[valAddr];
    if (index>0) {
      Validator storage validator = currentValidatorSet[index-1];
      if (validator.jailed) {
        emit deprecatedDeposit(valAddr,value);
      } else {
        totalInComing = totalInComing.add(value);
        validator.incoming = validator.incoming.add(value);
        emit validatorDeposit(valAddr,value);
      }
    } else {
      // get incoming from deprecated validator;
      emit deprecatedDeposit(valAddr,value);
    }
  }

  function jailValidator(Validator memory v) internal returns (uint32) {
    uint256 index = currentValidatorSetMap[v.consensusAddress];
    if (index==0 || currentValidatorSet[index-1].jailed) {
      emit validatorEmptyJailed(v.consensusAddress);
      return CODE_OK;
    }
    uint n = currentValidatorSet.length;
    bool shouldKeep = (numOfJailed >= n-1);
    // will not jail if it is the last valid validator
    if (shouldKeep) {
      emit validatorEmptyJailed(v.consensusAddress);
      return CODE_OK;
    }
    numOfJailed ++;
    currentValidatorSet[index-1].jailed = true;
    emit validatorJailed(v.consensusAddress);
    return CODE_OK;
  }

  function updateValidatorSet(Validator[] memory validatorSet) internal returns (uint32) {
    // do verify.
    (bool valid, string memory errMsg) = checkValidatorSet(validatorSet);
    if (!valid) {
      emit failReasonWithStr(errMsg);
      return ERROR_FAIL_CHECK_VALIDATORS;
    }

    //step 1: do calculate distribution, do not make it as an internal function for saving gas.
    uint crossSize;
    uint directSize;
    for (uint i = 0;i<currentValidatorSet.length;i++) {
      if (currentValidatorSet[i].incoming >= DUSTY_INCOMING) {
        crossSize ++;
      } else if (currentValidatorSet[i].incoming > 0) {
        directSize ++;
      }
    }

    //cross transfer
    address[] memory crossAddrs = new address[](crossSize);
    uint256[] memory crossAmounts = new uint256[](crossSize);
    uint256[] memory crossIndexes = new uint256[](crossSize);
    address[] memory crossRefundAddrs = new address[](crossSize);
    uint256 crossTotal;
    // direct transfer
    address payable[] memory directAddrs = new address payable[](directSize);
    uint256[] memory directAmounts = new uint256[](directSize);
    crossSize = 0;
    directSize = 0;
    Validator[] memory validatorSetTemp = validatorSet; // fix error: stack too deep, try removing local variables
    uint256 relayFee = ITokenHub(TOKEN_HUB_ADDR).getMiniRelayFee();
    if (relayFee > DUSTY_INCOMING) {
      emit failReasonWithStr("fee is larger than DUSTY_INCOMING");
      return ERROR_RELAYFEE_TOO_LARGE;
    }
    for (uint i = 0;i<currentValidatorSet.length;i++) {
      if (currentValidatorSet[i].incoming >= DUSTY_INCOMING) {
        crossAddrs[crossSize] = currentValidatorSet[i].BBCFeeAddress;
        uint256 value = currentValidatorSet[i].incoming - currentValidatorSet[i].incoming % PRECISION;
        crossAmounts[crossSize] = value.sub(relayFee);
        crossRefundAddrs[crossSize] = currentValidatorSet[i].BBCFeeAddress;
        crossIndexes[crossSize] = i;
        crossTotal = crossTotal.add(value);
        crossSize ++;
      } else if (currentValidatorSet[i].incoming > 0) {
        directAddrs[directSize] = currentValidatorSet[i].feeAddress;
        directAmounts[directSize] = currentValidatorSet[i].incoming;
        directSize ++;
      }
    }

    //step 2: do cross chain transfer
    bool failCross = false;
    if (crossTotal > 0) {
      try ITokenHub(TOKEN_HUB_ADDR).batchTransferOutBNB{value:crossTotal}(crossAddrs, crossAmounts, crossRefundAddrs, uint64(block.timestamp + expireTimeSecondGap)) returns (bool success) {
        if (success) {
           emit batchTransfer(crossTotal);
        } else {
           emit batchTransferFailed(crossTotal, "batch transfer return false");
        }
      }catch Error(string memory reason) {
        failCross = true;
        emit batchTransferFailed(crossTotal, reason);
      }catch (bytes memory lowLevelData) {
        failCross = true;
        emit batchTransferLowerFailed(crossTotal, lowLevelData);
      }
    }

    if (failCross) {
      for (uint i = 0; i< crossIndexes.length;i++) {
        uint idx = crossIndexes[i];
        bool success = currentValidatorSet[idx].feeAddress.send(currentValidatorSet[idx].incoming);
        if (success) {
          emit directTransfer(currentValidatorSet[idx].feeAddress, currentValidatorSet[idx].incoming);
        } else {
          emit directTransferFail(currentValidatorSet[idx].feeAddress, currentValidatorSet[idx].incoming);
        }
      }
    }

    // step 3: direct transfer
    if (directAddrs.length>0) {
      for (uint i = 0;i<directAddrs.length;i++) {
        bool success = directAddrs[i].send(directAmounts[i]);
        if (success) {
          emit directTransfer(directAddrs[i], directAmounts[i]);
        } else {
          emit directTransferFail(directAddrs[i], directAmounts[i]);
        }
      }
    }

    // step 4: do dusk transfer
    if (address(this).balance>0) {
      emit systemTransfer(address(this).balance);
      address(uint160(SYSTEM_REWARD_ADDR)).transfer(address(this).balance);
    }
    // step 5: do update validator set state
    totalInComing = 0;
    numOfJailed = 0;
    if (validatorSetTemp.length>0) {
      doUpdateState(validatorSetTemp);
    }

    // step 6: clean slash contract
    ISlashIndicator(SLASH_CONTRACT_ADDR).clean();
    emit validatorSetUpdated();
    return CODE_OK;
  }

  function getValidators()external view returns(address[] memory) {
    uint n = currentValidatorSet.length;
    uint valid = 0;
    for (uint i = 0;i<n;i++) {
      if (!currentValidatorSet[i].jailed) {
        valid ++;
      }
    }
    address[] memory consensusAddrs = new address[](valid);
    valid = 0;
    for (uint i = 0;i<n;i++) {
      if (!currentValidatorSet[i].jailed) {
        consensusAddrs[valid] = currentValidatorSet[i].consensusAddress;
        valid ++;
      }
    }
    return consensusAddrs;
  }

  function getIncoming(address validator)external view returns(uint256) {
    uint256 index = currentValidatorSetMap[validator];
    if (index<=0) {
      return 0;
    }
    return currentValidatorSet[index-1].incoming;
  }

  /*********************** For slash **************************/
  function misdemeanor(address validator)external onlySlash override{
    uint256 index = currentValidatorSetMap[validator];
    if (index <= 0) {
      return;
    }
    // the actually index
    index = index - 1;
    uint256 income = currentValidatorSet[index].incoming;
    currentValidatorSet[index].incoming = 0;
    uint256 rest = currentValidatorSet.length - 1;
    emit validatorMisdemeanor(validator,income);
    if (rest==0) {
      // should not happen, but still protect
      return;
    }
    uint256 averageDistribute = income/rest;
    if (averageDistribute!=0) {
      for (uint i=0;i<index;i++) {
        currentValidatorSet[i].incoming = currentValidatorSet[i].incoming + averageDistribute;
      }
      uint n = currentValidatorSet.length;
      for (uint i=index+1;i<n;i++) {
        currentValidatorSet[i].incoming = currentValidatorSet[i].incoming + averageDistribute;
      }
    }
    // averageDistribute*rest may less than income, but it is ok, the dust income will go to system reward eventually.
  }

  function felony(address validator)external onlySlash override{
    uint256 index = currentValidatorSetMap[validator];
    if (index <= 0) {
      return;
    }
    // the actually index
    index = index - 1;
    uint256 income = currentValidatorSet[index].incoming;
    uint256 rest = currentValidatorSet.length - 1;
    if (rest==0) {
      // will not remove the validator if it is the only one validator.
      currentValidatorSet[index].incoming = 0;
      return;
    }
    emit validatorFelony(validator,income);
    delete currentValidatorSetMap[validator];
    // It is ok that the validatorSet is not in order.
    if (index != currentValidatorSet.length-1) {
      currentValidatorSet[index] = currentValidatorSet[currentValidatorSet.length-1];
      currentValidatorSetMap[currentValidatorSet[index].consensusAddress] = index + 1;
    }
    currentValidatorSet.pop();
    uint256 averageDistribute = income/rest;
    if (averageDistribute!=0) {
      uint n = currentValidatorSet.length;
      for (uint i=0;i<n;i++) {
        currentValidatorSet[i].incoming = currentValidatorSet[i].incoming + averageDistribute;
      }
    }
    // averageDistribute*rest may less than income, but it is ok, the dust income will go to system reward eventually.
  }

  /*********************** Param update ********************************/
  function updateParam(string calldata key, bytes calldata value) override external onlyInit onlyGov{
    if (Memory.compareStrings(key, "expireTimeSecondGap")) {
      require(value.length == 32, "length of expireTimeSecondGap mismatch");
      uint256 newExpireTimeSecondGap = BytesToTypes.bytesToUint256(32, value);
      require(newExpireTimeSecondGap >=100 && newExpireTimeSecondGap <= 1e5, "the expireTimeSecondGap is out of range");
      expireTimeSecondGap = newExpireTimeSecondGap;
    } else {
      require(false, "unknown param");
    }
    emit paramChange(key, value);
  }

  /*********************** Internal Functions **************************/

  function checkValidatorSet(Validator[] memory validatorSet) private pure returns(bool, string memory) {
    if (validatorSet.length > MAX_NUM_OF_VALIDATORS){
      return (false, "the number of validators exceed the limit");
    }
    for (uint i = 0;i<validatorSet.length;i++) {
      for (uint j = 0;j<i;j++) {
        if (validatorSet[i].consensusAddress == validatorSet[j].consensusAddress) {
          return (false, "duplicate consensus address of validatorSet");
        }
      }
    }
    return (true,"");
  }

  function doUpdateState(Validator[] memory validatorSet) private{
    uint n = currentValidatorSet.length;
    uint m = validatorSet.length;

    for (uint i = 0;i<n;i++) {
      bool stale = true;
      Validator memory oldValidator = currentValidatorSet[i];
      for (uint j = 0;j<m;j++) {
        if (oldValidator.consensusAddress == validatorSet[j].consensusAddress) {
          stale = false;
          break;
        }
      }
      if (stale) {
        delete currentValidatorSetMap[oldValidator.consensusAddress];
      }
    }

    if (n>m) {
      for (uint i = m;i<n;i++) {
        currentValidatorSet.pop();
      }
    }
    uint k = n < m ? n:m;
    for (uint i = 0;i<k;i++) {
      if (!isSameValidator(validatorSet[i], currentValidatorSet[i])) {
        currentValidatorSetMap[validatorSet[i].consensusAddress] = i+1;
        currentValidatorSet[i] = validatorSet[i];
      } else {
        currentValidatorSet[i].incoming = 0;
      }
    }
    if (m>n) {
      for (uint i = n;i<m;i++) {
        currentValidatorSet.push(validatorSet[i]);
        currentValidatorSetMap[validatorSet[i].consensusAddress] = i+1;
      }
    }
  }

  function isSameValidator(Validator memory v1, Validator memory v2) private pure returns(bool) {
    return v1.consensusAddress == v2.consensusAddress && v1.feeAddress == v2.feeAddress && v1.BBCFeeAddress == v2.BBCFeeAddress && v1.votingPower == v2.votingPower;
  }

  //rlp encode & decode function
  function decodeValidatorSetSynPackage(bytes memory msgBytes) internal pure returns (IbcValidatorSetPackage memory, bool) {
    IbcValidatorSetPackage memory validatorSetPkg;

    RLPDecode.Iterator memory iter = msgBytes.toRLPItem().iterator();
    bool success = false;
    uint256 idx=0;
    while (iter.hasNext()) {
      if (idx == 0) {
        validatorSetPkg.packageType = uint8(iter.next().toUint());
      } else if (idx == 1) {
        RLPDecode.RLPItem[] memory items = iter.next().toList();
        validatorSetPkg.validatorSet =new Validator[](items.length);
        for (uint j = 0;j<items.length;j++) {
          (Validator memory val, bool ok) = decodeValidator(items[j]);
          if (!ok) {
            return (validatorSetPkg, false);
          }
          validatorSetPkg.validatorSet[j] = val;
        }
        success = true;
      } else {
        break;
      }
      idx++;
    }
    return (validatorSetPkg, success);
  }

  function decodeValidator(RLPDecode.RLPItem memory itemValidator) internal pure returns(Validator memory, bool) {
    Validator memory validator;
    RLPDecode.Iterator memory iter = itemValidator.iterator();
    bool success = false;
    uint256 idx=0;
    while (iter.hasNext()) {
      if (idx == 0) {
        validator.consensusAddress = iter.next().toAddress();
      } else if (idx == 1) {
        validator.feeAddress = address(uint160(iter.next().toAddress()));
      } else if (idx == 2) {
        validator.BBCFeeAddress = iter.next().toAddress();
      } else if (idx == 3) {
        validator.votingPower = uint64(iter.next().toUint());
        success = true;
      } else {
        break;
      }
      idx++;
    }
    return (validator, success);
  }
}

Contract Security Audit

Contract ABI

[{"type":"event","name":"batchTransfer","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"batchTransferFailed","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":true},{"type":"string","name":"reason","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"batchTransferLowerFailed","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":true},{"type":"bytes","name":"reason","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"deprecatedDeposit","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"directTransfer","inputs":[{"type":"address","name":"validator","internalType":"address payable","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"directTransferFail","inputs":[{"type":"address","name":"validator","internalType":"address payable","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"failReasonWithStr","inputs":[{"type":"string","name":"message","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"paramChange","inputs":[{"type":"string","name":"key","internalType":"string","indexed":false},{"type":"bytes","name":"value","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"systemTransfer","inputs":[{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"unexpectedPackage","inputs":[{"type":"uint8","name":"channelId","internalType":"uint8","indexed":false},{"type":"bytes","name":"msgBytes","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"validatorDeposit","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"validatorEmptyJailed","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"validatorFelony","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"validatorJailed","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"validatorMisdemeanor","inputs":[{"type":"address","name":"validator","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"validatorSetUpdated","inputs":[],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"BIND_CHANNELID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"CODE_OK","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"CROSS_CHAIN_CONTRACT_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"DUSTY_INCOMING","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"ERROR_FAIL_CHECK_VALIDATORS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"ERROR_FAIL_DECODE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"ERROR_LEN_OF_VAL_MISMATCH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"ERROR_RELAYFEE_TOO_LARGE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"ERROR_UNKNOWN_PACKAGE_TYPE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"EXPIRE_TIME_SECOND_GAP","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"GOV_CHANNELID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"GOV_HUB_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"INCENTIVIZE_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"INIT_VALIDATORSET_BYTES","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"JAIL_MESSAGE_TYPE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"LIGHT_CLIENT_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_NUM_OF_VALIDATORS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"PRECISION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"RELAYERHUB_CONTRACT_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"SLASH_CHANNELID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"SLASH_CONTRACT_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"STAKING_CHANNELID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"SYSTEM_REWARD_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"TOKEN_HUB_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"TOKEN_MANAGER_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"TRANSFER_IN_CHANNELID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"TRANSFER_OUT_CHANNELID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"VALIDATORS_UPDATE_MESSAGE_TYPE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"VALIDATOR_CONTRACT_ADDR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"alreadyInit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"bscChainID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"consensusAddress","internalType":"address"},{"type":"address","name":"feeAddress","internalType":"address payable"},{"type":"address","name":"BBCFeeAddress","internalType":"address"},{"type":"uint64","name":"votingPower","internalType":"uint64"},{"type":"bool","name":"jailed","internalType":"bool"},{"type":"uint256","name":"incoming","internalType":"uint256"}],"name":"currentValidatorSet","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentValidatorSetMap","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"deposit","inputs":[{"type":"address","name":"valAddr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"expireTimeSecondGap","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"felony","inputs":[{"type":"address","name":"validator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getIncoming","inputs":[{"type":"address","name":"validator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getValidators","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"handleAckPackage","inputs":[{"type":"uint8","name":"channelId","internalType":"uint8"},{"type":"bytes","name":"msgBytes","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"handleFailAckPackage","inputs":[{"type":"uint8","name":"channelId","internalType":"uint8"},{"type":"bytes","name":"msgBytes","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"responsePayload","internalType":"bytes"}],"name":"handleSynPackage","inputs":[{"type":"uint8","name":"","internalType":"uint8"},{"type":"bytes","name":"msgBytes","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"init","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"misdemeanor","inputs":[{"type":"address","name":"validator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"numOfJailed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalInComing","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateParam","inputs":[{"type":"string","name":"key","internalType":"string"},{"type":"bytes","name":"value","internalType":"bytes"}]}]

0x60806040526004361061027d5760003560e01c80639dc092621161014f578063c8509d81116100c1578063eb57e2021161007a578063eb57e20214610940578063eda5868c14610973578063f340fa0114610988578063f9a2bbc7146109ae578063fc3e5908146109c3578063fd6a6879146109d85761027d565b8063c8509d8114610609578063d86222d5146108d7578063daacdb66146108ec578063dc927faf14610901578063e086c7b114610916578063e1c7392a1461092b5761027d565b8063ab51bb9611610113578063ab51bb961461074a578063ac4317511461075f578063ad3c9da61461082a578063b7ab4db51461085d578063bf9f49951461041b578063c81b1662146108c25761027d565b80639dc09262146106cd578063a1a11bf5146106e2578063a5422d5c146106f7578063a78abc161461070c578063aaf5eb68146107355761027d565b80635667515a116101f35780637942fd05116101ac5780637942fd05146105df57806381650b62146105f4578063831d65d114610609578063853230aa1461068e57806386249882146106a357806396713da9146106b85761027d565b80635667515a146105005780635d77156c146105155780636969a25c1461052a5780636e47b482146105a057806370fd5bad146105b557806375d47a0a146105ca5761027d565b80633dffc387116102455780633dffc3871461041b57806343756e5c14610446578063493279b1146104775780634bf6c882146104a357806351e80672146104b8578063565c56b3146104cd5761027d565b80630bee7a67146102825780631182b875146102b05780631ff18069146103aa578063219f22d5146103d157806335409f7f146103e6575b600080fd5b34801561028e57600080fd5b506102976109ed565b6040805163ffffffff9092168252519081900360200190f35b3480156102bc57600080fd5b50610335600480360360408110156102d357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102f757600080fd5b82018360208201111561030957600080fd5b803590602001918460018302840111600160201b8311171561032a57600080fd5b5090925090506109f2565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036f578181015183820152602001610357565b50505050905090810190601f16801561039c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b657600080fd5b506103bf610bdf565b60408051918252519081900360200190f35b3480156103dd57600080fd5b50610297610be5565b3480156103f257600080fd5b506104196004803603602081101561040957600080fd5b50356001600160a01b0316610bea565b005b34801561042757600080fd5b50610430610efe565b6040805160ff9092168252519081900360200190f35b34801561045257600080fd5b5061045b610f03565b604080516001600160a01b039092168252519081900360200190f35b34801561048357600080fd5b5061048c610f09565b6040805161ffff9092168252519081900360200190f35b3480156104af57600080fd5b50610430610f0e565b3480156104c457600080fd5b5061045b610f13565b3480156104d957600080fd5b506103bf600480360360208110156104f057600080fd5b50356001600160a01b0316610f19565b34801561050c57600080fd5b50610430610f6b565b34801561052157600080fd5b50610297610f70565b34801561053657600080fd5b506105546004803603602081101561054d57600080fd5b5035610f75565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b3480156105ac57600080fd5b5061045b610fd9565b3480156105c157600080fd5b50610430610fdf565b3480156105d657600080fd5b5061045b610fe4565b3480156105eb57600080fd5b50610430610fea565b34801561060057600080fd5b50610297610fef565b34801561061557600080fd5b506104196004803603604081101561062c57600080fd5b60ff8235169190810190604081016020820135600160201b81111561065057600080fd5b82018360208201111561066257600080fd5b803590602001918460018302840111600160201b8311171561068357600080fd5b509092509050610ff4565b34801561069a57600080fd5b506103bf6110a7565b3480156106af57600080fd5b506103bf6110ad565b3480156106c457600080fd5b506104306110b3565b3480156106d957600080fd5b5061045b6110b8565b3480156106ee57600080fd5b5061045b6110be565b34801561070357600080fd5b506103356110c4565b34801561071857600080fd5b506107216110e3565b604080519115158252519081900360200190f35b34801561074157600080fd5b506103bf6110ec565b34801561075657600080fd5b50610297610f6b565b34801561076b57600080fd5b506104196004803603604081101561078257600080fd5b810190602081018135600160201b81111561079c57600080fd5b8201836020820111156107ae57600080fd5b803590602001918460018302840111600160201b831117156107cf57600080fd5b919390929091602081019035600160201b8111156107ec57600080fd5b8201836020820111156107fe57600080fd5b803590602001918460018302840111600160201b8311171561081f57600080fd5b5090925090506110f5565b34801561083657600080fd5b506103bf6004803603602081101561084d57600080fd5b50356001600160a01b031661139c565b34801561086957600080fd5b506108726113ae565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156108ae578181015183820152602001610896565b505050509050019250505060405180910390f35b3480156108ce57600080fd5b5061045b6114d4565b3480156108e357600080fd5b506103bf6114da565b3480156108f857600080fd5b506103bf6114e6565b34801561090d57600080fd5b5061045b6114ec565b34801561092257600080fd5b506103bf6114f2565b34801561093757600080fd5b506104196114f7565b34801561094c57600080fd5b506104196004803603602081101561096357600080fd5b50356001600160a01b03166116fa565b34801561097f57600080fd5b506102976118c9565b6104196004803603602081101561099e57600080fd5b50356001600160a01b03166118ce565b3480156109ba57600080fd5b5061045b611b04565b3480156109cf57600080fd5b50610430611b0a565b3480156109e457600080fd5b5061045b611b0f565b606481565b60005460609060ff16610a48576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a885760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b610a90613d69565b6000610ad185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b1592505050565b9150915080610aed57610ae46064611c6e565b92505050610bd8565b815160009060ff16610b0d57610b068360200151611ccf565b9050610ba4565b825160ff1660011415610ba057826020015151600114610b7a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613e6c6025913960400191505060405180910390a1506067610b9b565b610b068360200151600081518110610b8e57fe5b6020026020010151612ad5565b610ba4565b5060655b63ffffffff8116610bc95750506040805160008152602081019091529150610bd89050565b610bd281611c6e565b93505050505b9392505050565b60035481565b606881565b3361100114610c2a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610c4e5750610efb565b600181039050600060018281548110610c6357fe5b60009182526020909120600360049092020101546001549091506000190180610cb257600060018481548110610c9557fe5b906000526020600020906004020160030181905550505050610efb565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610e3457600180546000198101908110610d2957fe5b906000526020600020906004020160018481548110610d4457fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610e0957fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610e3f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610e9257fe5b0490508015610ef65760015460005b81811015610ef3578260018281548110610eb757fe5b9060005260206000209060040201600301540160018281548110610ed757fe5b6000918252602090912060036004909202010155600101610ea1565b50505b505050505b50565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610f41576000915050610f66565b600180820381548110610f5057fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610f8257fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b33612000146110345760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b6040518061062001604052806105ef8152602001613f276105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611148576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146111885760405162461bcd60e51b815260040180806020018281038252602e815260200180613e91602e913960400191505060405180910390fd5b6111f284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c4c9050565b156112cd57602081146112365760405162461bcd60e51b8152600401808060200182810382526026815260200180613ee06026913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161127491858580838501838280828437600092019190915250612d3492505050565b90506064811015801561128a5750620186a08111155b6112c55760405162461bcd60e51b8152600401808060200182810382526027815260200180613e456027913960400191505060405180910390fd5b60025561130a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b828110156113ff57600181815481106113cd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166113f7576001909101905b6001016113b8565b5060608160405190808252806020026020018201604052801561142c578160200160208202803683370190505b50600092509050815b838110156114cc576001818154811061144a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166114c4576001818154811061147a57fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106114a557fe5b6001600160a01b03909216602092830291909101909101526001909201915b600101611435565b509250505090565b61100281565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff161561154f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611557613d69565b600061157d6040518061062001604052806105ef8152602001613f276105ef9139611b15565b91509150806115bd5760405162461bcd60e51b8152600401808060200182810382526021815260200180613f066021913960400191505060405180910390fd5b60005b8260200151518110156116e2576001836020015182815181106115df57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106116b557fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016115c0565b50506103e8600255506000805460ff19166001179055565b336110011461173a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061175e5750610efb565b60018103905060006001828154811061177357fe5b906000526020600020906004020160030154905060006001838154811061179657fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061180557505050610efb565b600081838161181057fe5b0490508015610ef65760005b8481101561186e57816001828154811061183257fe5b906000526020600020906004020160030154016001828154811061185257fe5b600091825260209091206003600490920201015560010161181c565b50600180549085015b81811015610ef357826001828154811061188d57fe5b90600052602060002090600402016003015401600182815481106118ad57fe5b6000918252602090912060036004909202010155600101611877565b606581565b33411461190c5760405162461bcd60e51b815260040180806020018281038252602d815260200180614545602d913960400191505060405180910390fd5b60005460ff1661195f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116119ac576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205434908015611abf5760006001808303815481106119de57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611a49576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a2611ab9565b600354611a5c908463ffffffff612d3916565b6003908155810154611a74908463ffffffff612d3916565b60038201556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611aff565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611b1d613d69565b6000611b27613d69565b611b2f613d81565b611b40611b3b86612d93565b612db8565b90506000805b611b4f83612e02565b15611c605780611b7457611b6a611b6584612e23565b612e71565b60ff168452611c58565b8060011415611c53576060611b90611b8b85612e23565b612f28565b90508051604051908082528060200260200182016040528015611bcd57816020015b611bba613da1565b815260200190600190039081611bb25790505b50602086015260005b8151811015611c4857611be7613da1565b6000611c05848481518110611bf857fe5b6020026020010151612ff9565b9150915080611c2257876000995099505050505050505050611c69565b8188602001518481518110611c3357fe5b60209081029190910101525050600101611bd6565b506001925050611c58565b611c60565b600101611b46565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611c88579050509050611cae8363ffffffff166130d6565b81600081518110611cbb57fe5b6020026020010181905250610bd8816130e9565b6000806060611cdd84613173565b9150915081611d8a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d45578181015183820152602001611d2d565b50505050905090810190601f168015611d725780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610f66565b600080805b600154811015611e075767016345785d8a000060018281548110611daf57fe5b90600052602060002090600402016003015410611dd157600190920191611dff565b600060018281548110611de057fe5b9060005260206000209060040201600301541115611dff576001909101905b600101611d8f565b50606082604051908082528060200260200182016040528015611e34578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611e63578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611e92578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ec1578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611ef2578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611f21578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611f6e57600080fd5b505afa158015611f82573d6000803e3d6000fd5b505050506040513d6020811015611f9857600080fd5b5051905067016345785d8a000081111561200d577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613ebf6021913960400191505060405180910390a160689d5050505050505050505050505050610f66565b60005b6001548110156122805767016345785d8a00006001828154811061203057fe5b906000526020600020906004020160030154106121b6576001818154811061205457fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d8151811061208557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be400600183815481106120ba57fe5b906000526020600020906004020160030154816120d357fe5b06600183815481106120e157fe5b906000526020600020906004020160030154039050612109838261325590919063ffffffff16565b8a8e8151811061211557fe5b6020026020010181815250506001828154811061212e57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061215f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e8151811061218c57fe5b60209081029190910101526121a7878263ffffffff612d3916565b6001909d019c96506122789050565b6000600182815481106121c557fe5b906000526020600020906004020160030154111561227857600181815481106121ea57fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061221b57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061224857fe5b906000526020600020906004020160030154848c8151811061226657fe5b60209081029190910101526001909a01995b600101612010565b50600085156126be576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b838110156123125781810151838201526020016122fa565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015612351578181015183820152602001612339565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015612390578181015183820152602001612378565b505050509050019750505050505050506020604051808303818588803b1580156123b957600080fd5b505af1935050505080156123df57506040513d60208110156123da57600080fd5b505160015b61261a576040516000815260443d10156123fb57506000612496565b60046000803e60005160e01c6308c379a0811461241c576000915050612496565b60043d036004833e81513d60248201116001600160401b038211171561244757600092505050612496565b80830180516001600160401b03811115612468576000945050505050612496565b8060208301013d860181111561248657600095505050505050612496565b601f01601f191660405250925050505b806124a15750612545565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125055781810151838201526020016124ed565b50505050905090810190601f1680156125325780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612615565b3d80801561256f576040519150601f19603f3d011682016040523d82523d6000602084013e612574565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125d95781810151838201526020016125c1565b50505050905090810190601f1680156126065780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6126be565b8015612658576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16126bc565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156128745760005b88518110156128725760008982815181106126de57fe5b602002602001015190506000600182815481106126f757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061272857fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f19350505050905080156127e4576001828154811061276957fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106127b857fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612868565b600182815481106127f157fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061284057fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016126c7565b505b8451156129be5760005b85518110156129bc57600086828151811061289557fe5b60200260200101516001600160a01b03166108fc8784815181106128b557fe5b60200260200101519081150290604051600060405180830381858888f193505050509050801561294b578682815181106128eb57fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061292957fe5b60200260200101516040518082815260200191505060405180910390a26129b3565b86828151811061295757fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d87848151811061299557fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161287e565b505b4715612a27576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612a25573d6000803e3d6000fd5b505b60006003819055600555825115612a4157612a4183613297565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a7e57600080fd5b505af1158015612a92573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b80516001600160a01b0316600090815260046020526040812054801580612b265750600180820381548110612b0657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15612b6c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000915050610f66565b600154600554600019820111801590612bc25784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a260009350505050610f66565b600580546001908101909155805481906000198601908110612be057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000816040516020018082805190602001908083835b60208310612c815780518252601f199092019160209182019101612c62565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612cef5780518252601f199092019160209182019101612cd0565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b600082820183811015610bd8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b612d9b613dd6565b506040805180820190915281518152602082810190820152919050565b612dc0613d81565b612dc98261375e565b612dd257600080fd5b6000612de18360200151613798565b60208085015160408051808201909152868152920190820152915050919050565b6000612e0c613dd6565b505080518051602091820151919092015191011190565b612e2b613dd6565b612e3482612e02565b612e3d57600080fd5b60208201516000612e4d826137fb565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e8657508151602110155b612e8f57600080fd5b6000612e9e8360200151613798565b90508083600001511015612ef9576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015612f1f57826020036101000a820491505b50949350505050565b6060612f338261375e565b612f3c57600080fd5b6000612f478361392e565b9050606081604051908082528060200260200182016040528015612f8557816020015b612f72613dd6565b815260200190600190039081612f6a5790505b5090506000612f978560200151613798565b60208601510190506000805b84811015612fee57612fb4836137fb565b9150604051806040016040528083815260200184815250848281518110612fd757fe5b602090810291909101015291810191600101612fa3565b509195945050505050565b613001613da1565b600061300b613da1565b613013613d81565b61301c85612db8565b90506000805b61302b83612e02565b15611c6057806130565761304661304184612e23565b61398a565b6001600160a01b031684526130ce565b806001141561307e5761306b61304184612e23565b6001600160a01b031660208501526130ce565b80600214156130a65761309361304184612e23565b6001600160a01b031660408501526130ce565b8060031415611c53576130bb611b6584612e23565b6001600160401b03166060850152600191505b600101613022565b6060612d2e6130e4836139a4565b613a8a565b606081516000141561310a5750604080516000815260208101909152610f66565b60608260008151811061311957fe5b602002602001015190506000600190505b835181101561315a576131508285838151811061314357fe5b6020026020010151613adc565b915060010161312a565b50610bd861316d825160c060ff16613b59565b82613adc565b600060606029835111156131a5576000604051806060016040528060298152602001613df16029913991509150611c69565b60005b835181101561323b5760005b81811015613232578481815181106131c857fe5b6020026020010151600001516001600160a01b03168583815181106131e957fe5b6020026020010151600001516001600160a01b0316141561322a5760006040518060600160405280602b8152602001613e1a602b9139935093505050611c69565b6001016131b4565b506001016131a8565b505060408051602081019091526000815260019150915091565b6000610bd883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613c51565b600154815160005b828110156133b45760016132b1613da1565b600183815481106132be57fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156133885786818151811061334e57fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156133805760009250613388565b60010161333a565b5081156133aa5780516001600160a01b03166000908152600460205260408120555b505060010161329f565b508082111561342957805b828110156134275760018054806133d257fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b03191690556003909101919091559155016133bf565b505b6000818310613438578161343a565b825b905060005b81811015613634576134ec85828151811061345657fe5b60200260200101516001838154811061346b57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ce8565b61360757806001016004600087848151811061350457fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061354057fe5b60200260200101516001828154811061355557fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015561362c565b60006001828154811061361657fe5b9060005260206000209060040201600301819055505b60010161343f565b508282111561375857825b82811015610ef657600185828151811061365557fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061372b57fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161363f565b50505050565b805160009061376f57506000610f66565b6020820151805160001a9060c082101561378e57600092505050610f66565b5060019392505050565b8051600090811a60808110156137b2576000915050610f66565b60b88110806137cd575060c081108015906137cd575060f881105b156137dc576001915050610f66565b60c08110156137f05760b519019050610f66565b60f519019050610f66565b80516000908190811a60808110156138165760019150613927565b60b881101561382b57607e1981019150613927565b60c08110156138a557600060b78203600186019550806020036101000a86510491506001810182019350508083101561389f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613927565b60f88110156138ba5760be1981019150613927565b600060f78203600186019550806020036101000a865104915060018101820193505080831015613925576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061393f57506000610f66565b600080905060006139538460200151613798565b602085015185519181019250015b8082101561398157613972826137fb565b60019093019290910190613961565b50909392505050565b805160009060151461399b57600080fd5b612d2e82612e71565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166139e857506018613a0c565b6fffffffffffffffffffffffffffffffff198416613a0857506010613a0c565b5060005b6020811015613a4257818181518110613a2157fe5b01602001516001600160f81b03191615613a3a57613a42565b600101613a0c565b60008160200390506060816040519080825280601f01601f191660200182016040528015613a77576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613abc5750607f60f81b82600081518110613aaa57fe5b01602001516001600160f81b03191611155b15613ac8575080610f66565b612d2e613ada8351608060ff16613b59565b835b6060806040519050835180825260208201818101602087015b81831015613b0d578051835260209283019201613af5565b50855184518101855292509050808201602086015b81831015613b3a578051835260209283019201613b22565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613ba9576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613c035782840160f81b81600081518110613be557fe5b60200101906001600160f81b031916908160001a9053509050612d2e565b6060613c0e856139a4565b90508381510160370160f81b82600081518110613c2757fe5b60200101906001600160f81b031916908160001a905350613c488282613adc565b95945050505050565b60008184841115613ce05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ca5578181015183820152602001613c8d565b50505050905090810190601f168015613cd25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613d22575081602001516001600160a01b031683602001516001600160a01b0316145b8015613d47575081604001516001600160a01b031683604001516001600160a01b0316145b8015610bd85750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613d94613dd6565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe746865206e756d626572206f662076616c696461746f72732065786365656420746865206c696d69746475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d617463686661696c656420746f20706172736520696e69742076616c696461746f72536574f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a2646970667358221220f4016eb3755efa2abde797b21f8695280d971b0fea37198122d2e5867516da0464736f6c63430006040033

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.