Latest 25 from a total of 81,140,543 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Deposit | 81491823 | 3 secs ago | IN | 0.0005342 BNB | 0 | ||||
| Deposit | 81491822 | 3 secs ago | IN | 0.00122771 BNB | 0 | ||||
| Deposit | 81491821 | 4 secs ago | IN | 0.00076087 BNB | 0 | ||||
| Deposit | 81491820 | 4 secs ago | IN | 0.00168159 BNB | 0 | ||||
| Deposit | 81491819 | 4 secs ago | IN | 0.00070536 BNB | 0 | ||||
| Deposit | 81491818 | 5 secs ago | IN | 0.00163514 BNB | 0 | ||||
| Deposit | 81491817 | 5 secs ago | IN | 0.00053135 BNB | 0 | ||||
| Deposit | 81491816 | 6 secs ago | IN | 0.00048777 BNB | 0 | ||||
| Deposit | 81491815 | 6 secs ago | IN | 0.00066123 BNB | 0 | ||||
| Deposit | 81491814 | 7 secs ago | IN | 0.00229852 BNB | 0 | ||||
| Deposit | 81491813 | 7 secs ago | IN | 0.00105989 BNB | 0 | ||||
| Deposit | 81491812 | 8 secs ago | IN | 0.00109656 BNB | 0 | ||||
| Deposit | 81491811 | 8 secs ago | IN | 0.00066406 BNB | 0 | ||||
| Deposit | 81491810 | 8 secs ago | IN | 0.00114093 BNB | 0 | ||||
| Deposit | 81491809 | 9 secs ago | IN | 0.00156753 BNB | 0 | ||||
| Deposit | 81491808 | 9 secs ago | IN | 0.00124657 BNB | 0 | ||||
| Deposit | 81491807 | 10 secs ago | IN | 0.00115711 BNB | 0 | ||||
| Deposit | 81491806 | 10 secs ago | IN | 0.0006004 BNB | 0 | ||||
| Deposit | 81491805 | 11 secs ago | IN | 0.00152275 BNB | 0 | ||||
| Deposit | 81491804 | 11 secs ago | IN | 0.00096706 BNB | 0 | ||||
| Deposit | 81491803 | 12 secs ago | IN | 0.00056052 BNB | 0 | ||||
| Deposit | 81491802 | 12 secs ago | IN | 0.00073703 BNB | 0 | ||||
| Deposit | 81491801 | 13 secs ago | IN | 0.00057913 BNB | 0 | ||||
| Distribute Final... | 81491800 | 13 secs ago | IN | 0 BNB | 0 | ||||
| Deposit | 81491800 | 13 secs ago | IN | 0.00310673 BNB | 0 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 81491821 | 4 secs ago | 0.00007608 BNB | ||||
| 81491821 | 4 secs ago | 0.00004755 BNB | ||||
| 81491820 | 4 secs ago | 0.00016815 BNB | ||||
| 81491820 | 4 secs ago | 0.00010509 BNB | ||||
| 81491819 | 4 secs ago | 0.00007053 BNB | ||||
| 81491819 | 4 secs ago | 0.00004408 BNB | ||||
| 81491818 | 5 secs ago | 0.00016351 BNB | ||||
| 81491818 | 5 secs ago | 0.00010219 BNB | ||||
| 81491817 | 5 secs ago | 0.00005313 BNB | ||||
| 81491817 | 5 secs ago | 0.0000332 BNB | ||||
| 81491816 | 6 secs ago | 0.00004877 BNB | ||||
| 81491816 | 6 secs ago | 0.00003048 BNB | ||||
| 81491815 | 6 secs ago | 0.00006612 BNB | ||||
| 81491815 | 6 secs ago | 0.00004132 BNB | ||||
| 81491814 | 7 secs ago | 0.00022985 BNB | ||||
| 81491814 | 7 secs ago | 0.00014365 BNB | ||||
| 81491813 | 7 secs ago | 0.00010598 BNB | ||||
| 81491813 | 7 secs ago | 0.00006624 BNB | ||||
| 81491812 | 8 secs ago | 0.00010965 BNB | ||||
| 81491812 | 8 secs ago | 0.00006853 BNB | ||||
| 81491811 | 8 secs ago | 0.0000664 BNB | ||||
| 81491811 | 8 secs ago | 0.0000415 BNB | ||||
| 81491810 | 8 secs ago | 0.00011409 BNB | ||||
| 81491810 | 8 secs ago | 0.0000713 BNB | ||||
| 81491809 | 9 secs ago | 0.00015675 BNB |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BSCValidatorSet
Compiler Version
v0.6.4+commit.1dca32f3
Contract Source Code (Solidity)
/** *Submitted for verification at BscScan.com on 2020-09-02 */ pragma solidity =0.6.4; pragma experimental ABIEncoderV2; // contracts/lib/0.6.x/BytesLib.sol /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * Copyright (c) 2016-2020 zpouladzade/Seriality * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ library BytesLib { function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore( 0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. ) ) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes_slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes_slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes_slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes_slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) { require(_bytes.length >= (_start + _length)); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= (_start + 20)); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= (_start + 1)); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= (_start + 2)); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= (_start + 4)); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= (_start + 8)); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= (_start + 12)); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= (_start + 16)); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= (_start + 32)); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= (_start + 32)); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) } // the next line is the loop condition: // while (uint(mc < end) + cb == 2) eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes_slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes_slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while (uint(mc < end) + cb == 2) for { } eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } } // contracts/lib/0.6.x/BytesToTypes.sol /** * @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(uint256 _offst, bytes memory _input) internal pure returns (address _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToBool(uint256 _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(uint256 _offst, bytes memory _input) internal pure returns (uint256 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(uint256 _offst, bytes memory _input, bytes memory _output) internal pure { uint256 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(uint256 _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(uint256 _offst, bytes memory _input) internal pure returns (int8 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt16(uint256 _offst, bytes memory _input) internal pure returns (int16 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt24(uint256 _offst, bytes memory _input) internal pure returns (int24 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt32(uint256 _offst, bytes memory _input) internal pure returns (int32 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt40(uint256 _offst, bytes memory _input) internal pure returns (int40 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt48(uint256 _offst, bytes memory _input) internal pure returns (int48 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt56(uint256 _offst, bytes memory _input) internal pure returns (int56 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt64(uint256 _offst, bytes memory _input) internal pure returns (int64 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt72(uint256 _offst, bytes memory _input) internal pure returns (int72 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt80(uint256 _offst, bytes memory _input) internal pure returns (int80 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt88(uint256 _offst, bytes memory _input) internal pure returns (int88 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt96(uint256 _offst, bytes memory _input) internal pure returns (int96 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt104(uint256 _offst, bytes memory _input) internal pure returns (int104 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt112(uint256 _offst, bytes memory _input) internal pure returns (int112 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt120(uint256 _offst, bytes memory _input) internal pure returns (int120 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt128(uint256 _offst, bytes memory _input) internal pure returns (int128 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt136(uint256 _offst, bytes memory _input) internal pure returns (int136 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt144(uint256 _offst, bytes memory _input) internal pure returns (int144 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt152(uint256 _offst, bytes memory _input) internal pure returns (int152 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt160(uint256 _offst, bytes memory _input) internal pure returns (int160 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt168(uint256 _offst, bytes memory _input) internal pure returns (int168 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt176(uint256 _offst, bytes memory _input) internal pure returns (int176 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt184(uint256 _offst, bytes memory _input) internal pure returns (int184 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt192(uint256 _offst, bytes memory _input) internal pure returns (int192 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt200(uint256 _offst, bytes memory _input) internal pure returns (int200 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt208(uint256 _offst, bytes memory _input) internal pure returns (int208 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt216(uint256 _offst, bytes memory _input) internal pure returns (int216 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt224(uint256 _offst, bytes memory _input) internal pure returns (int224 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt232(uint256 _offst, bytes memory _input) internal pure returns (int232 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt240(uint256 _offst, bytes memory _input) internal pure returns (int240 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt248(uint256 _offst, bytes memory _input) internal pure returns (int248 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToInt256(uint256 _offst, bytes memory _input) internal pure returns (int256 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint8(uint256 _offst, bytes memory _input) internal pure returns (uint8 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint16(uint256 _offst, bytes memory _input) internal pure returns (uint16 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint24(uint256 _offst, bytes memory _input) internal pure returns (uint24 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint32(uint256 _offst, bytes memory _input) internal pure returns (uint32 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint40(uint256 _offst, bytes memory _input) internal pure returns (uint40 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint48(uint256 _offst, bytes memory _input) internal pure returns (uint48 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint56(uint256 _offst, bytes memory _input) internal pure returns (uint56 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint64(uint256 _offst, bytes memory _input) internal pure returns (uint64 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint72(uint256 _offst, bytes memory _input) internal pure returns (uint72 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint80(uint256 _offst, bytes memory _input) internal pure returns (uint80 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint88(uint256 _offst, bytes memory _input) internal pure returns (uint88 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint96(uint256 _offst, bytes memory _input) internal pure returns (uint96 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint104(uint256 _offst, bytes memory _input) internal pure returns (uint104 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint112(uint256 _offst, bytes memory _input) internal pure returns (uint112 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint120(uint256 _offst, bytes memory _input) internal pure returns (uint120 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint128(uint256 _offst, bytes memory _input) internal pure returns (uint128 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint136(uint256 _offst, bytes memory _input) internal pure returns (uint136 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint144(uint256 _offst, bytes memory _input) internal pure returns (uint144 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint152(uint256 _offst, bytes memory _input) internal pure returns (uint152 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint160(uint256 _offst, bytes memory _input) internal pure returns (uint160 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint168(uint256 _offst, bytes memory _input) internal pure returns (uint168 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint176(uint256 _offst, bytes memory _input) internal pure returns (uint176 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint184(uint256 _offst, bytes memory _input) internal pure returns (uint184 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint192(uint256 _offst, bytes memory _input) internal pure returns (uint192 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint200(uint256 _offst, bytes memory _input) internal pure returns (uint200 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint208(uint256 _offst, bytes memory _input) internal pure returns (uint208 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint216(uint256 _offst, bytes memory _input) internal pure returns (uint216 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint224(uint256 _offst, bytes memory _input) internal pure returns (uint224 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint232(uint256 _offst, bytes memory _input) internal pure returns (uint232 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint240(uint256 _offst, bytes memory _input) internal pure returns (uint240 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint248(uint256 _offst, bytes memory _input) internal pure returns (uint248 _output) { assembly { _output := mload(add(_input, _offst)) } } function bytesToUint256(uint256 _offst, bytes memory _input) internal pure returns (uint256 _output) { assembly { _output := mload(add(_input, _offst)) } } } // contracts/interface/0.6.x/IApplication.sol 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; } // contracts/interface/0.6.x/IBSCValidatorSet.sol interface IBSCValidatorSet { function misdemeanor(address validator) external; function felony(address validator) external; function isCurrentValidator(address validator) external view returns (bool); function getLivingValidators() external view returns (address[] memory, bytes[] memory); function getMiningValidators() external view returns (address[] memory, bytes[] memory); function isMonitoredForMaliciousVote(bytes calldata voteAddr) external view returns (bool); } // contracts/interface/0.6.x/ILightClient.sol 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); } // contracts/interface/0.6.x/IParamSubscriber.sol interface IParamSubscriber { function updateParam(string calldata key, bytes calldata value) external; } // contracts/interface/0.6.x/IRelayerHub.sol interface IRelayerHub { function isRelayer(address sender) external view returns (bool); } // contracts/interface/0.6.x/ISlashIndicator.sol interface ISlashIndicator { function clean() external; function downtimeSlash(address validator, uint256 count, bool shouldRevert) external; function sendFelonyPackage(address validator) external; function getSlashThresholds() external view returns (uint256, uint256); } // contracts/interface/0.6.x/IStakeHub.sol interface IStakeHub { function downtimeSlash(address validator) external; function maliciousVoteSlash(bytes calldata voteAddress) external; function doubleSignSlash(address validator) external; function voteToOperator(bytes calldata voteAddress) external view returns (address); function consensusToOperator(address validator) external view returns (address); function getValidatorConsensusAddress(address validator) external view returns (address); function getValidatorCreditContract(address validator) external view returns (address); function getValidatorVoteAddress(address validator) external view returns (bytes memory); function maxElectedValidators() external view returns (uint256); function distributeReward(address validator) external payable; } // contracts/interface/0.6.x/ISystemReward.sol interface ISystemReward { function claimRewards(address payable to, uint256 amount) external returns (uint256 actualAmount); } // contracts/lib/0.6.x/Memory.sol library Memory { // Size of a word, in bytes. uint256 internal constant WORD_SIZE = 32; // Size of the header of a 'bytes' array. uint256 internal constant BYTES_HEADER_SIZE = 32; // Address of the free memory pointer. uint256 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(uint256 addr, uint256 addr2, uint256 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(uint256 addr, uint256 len, bytes memory bts) internal pure returns (bool equal) { require(bts.length >= len); uint256 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(uint256 src, uint256 dest, uint256 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 uint256 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 (uint256 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 (uint256 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 (uint256 addr, uint256 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(uint256 addr, uint256 len) internal pure returns (bytes memory bts) { bts = new bytes(len); uint256 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(uint256 addr) internal pure returns (uint256 n) { assembly { n := mload(addr) } } // Get the word stored at memory address 'addr' as a 'bytes32'. function toBytes32(uint256 addr) internal pure returns (bytes32 bts) { assembly { bts := mload(addr) } } } // contracts/lib/0.6.x/RLPDecode.sol 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 { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 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) { uint256 memPtr; assembly { memPtr := add(self, 0x20) } return RLPItem(self.length, memPtr); } function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } function payloadLen(RLPItem memory item) internal pure returns (uint256) { return item.len - _payloadOffset(item.memPtr); } function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 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; uint256 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; uint256 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); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } if (result == 0 || result == STRING_SHORT_START) { return false; } else { return 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 (uint256) { require(item.len > 0 && item.len <= 33); uint256 offset = _payloadOffset(item.memPtr); require(item.len >= offset, "length is less than offset"); uint256 len = item.len - offset; uint256 result; uint256 memPtr = item.memPtr + offset; assembly { result := mload(memPtr) // shift to the correct location if necessary 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 (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); uint256 offset = _payloadOffset(item.memPtr); uint256 len = item.len - offset; // data length bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(item.memPtr + offset, destPtr, len); return result; } function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item ++count; } return count; } function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 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) { uint256 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 { uint256 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(uint256 memPtr) private pure returns (uint256) { uint256 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(uint256 src, uint256 dest, uint256 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 uint256 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)) } } } // contracts/lib/0.6.x/SafeMath.sol /** * 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; } } // contracts/System.sol contract System { bool public alreadyInit; uint32 public constant CODE_OK = 0; uint16 public constant 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; address public constant STAKING_CONTRACT_ADDR = 0x0000000000000000000000000000000000002001; address public constant STAKE_HUB_ADDR = 0x0000000000000000000000000000000000002002; address public constant STAKE_CREDIT_ADDR = 0x0000000000000000000000000000000000002003; address public constant GOVERNOR_ADDR = 0x0000000000000000000000000000000000002004; address public constant GOV_TOKEN_ADDR = 0x0000000000000000000000000000000000002005; address public constant TIMELOCK_ADDR = 0x0000000000000000000000000000000000002006; address public constant TOKEN_RECOVER_PORTAL_ADDR = 0x0000000000000000000000000000000000003000; modifier onlyCoinbase() { require(msg.sender == block.coinbase, "the message sender must be the block producer"); _; } modifier onlyZeroGasPrice() { require(tx.gasprice == 0, "gasprice is not zero"); _; } 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"); _; } modifier onlyStakeHub() { require(msg.sender == STAKE_HUB_ADDR, "the msg sender must be stakeHub"); _; } modifier onlyGovernorTimelock() { require(msg.sender == TIMELOCK_ADDR, "the msg sender must be governor timelock contract"); _; } modifier onlyTokenRecoverPortal() { require(msg.sender == TOKEN_RECOVER_PORTAL_ADDR, "the msg sender must be token recover portal"); _; } // Not reliable, do not use when need strong verify function isContract(address addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return size > 0; } } // contracts/BSCValidatorSet.sol contract BSCValidatorSet is IBSCValidatorSet, System, IParamSubscriber, IApplication { using SafeMath for uint256; using RLPDecode for *; bytes public constant INIT_VALIDATORSET_BYTES = hex"f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000"; uint256 public constant INIT_NUM_OF_CABINETS = 21; /*----------------- state of the contract -----------------*/ Validator[] public currentValidatorSet; uint256 public expireTimeSecondGap; // @dev deprecated 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; // @dev deprecated uint256 public constant BLOCK_FEES_RATIO_SCALE = 10000; address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD; uint256 public constant INIT_BURN_RATIO = 1000; uint256 public burnRatio; bool public burnRatioInitialized; // @dev deprecated // BEP-127 Temporary Maintenance uint256 public constant INIT_MAX_NUM_OF_MAINTAINING = 3; uint256 public constant INIT_MAINTAIN_SLASH_SCALE = 2; uint256 public maxNumOfMaintaining; uint256 public numOfMaintaining; uint256 public maintainSlashScale; // Corresponds strictly to currentValidatorSet // validatorExtraSet[index] = the `ValidatorExtra` info of currentValidatorSet[index] ValidatorExtra[] public validatorExtraSet; // BEP-131 candidate validator uint256 public numOfCabinets; uint256 public maxNumOfCandidates; uint256 public maxNumOfWorkingCandidates; // BEP-126 Fast Finality uint256 public constant INIT_SYSTEM_REWARD_RATIO = 625; // 625/10000 is 1/16 uint256 public constant MAX_SYSTEM_REWARD_BALANCE = 100 ether; uint256 public systemRewardBaseRatio; uint256 public previousHeight; uint256 public previousBalanceOfSystemReward; // @dev deprecated bytes[] public previousVoteAddrFullSet; bytes[] public currentVoteAddrFullSet; bool public isSystemRewardIncluded; // BEP-294 BC-fusion Validator[] private _tmpMigratedValidatorSet; // @dev deprecated bytes[] private _tmpMigratedVoteAddrs; // @dev deprecated // BEP-341 Validators can produce consecutive blocks uint256 public turnLength; // Consecutive number of blocks a validator receives priority for block production uint256 public systemRewardAntiMEVRatio; struct Validator { address consensusAddress; address payable feeAddress; address BBCFeeAddress; uint64 votingPower; // only in state bool jailed; uint256 incoming; } struct ValidatorExtra { // BEP-127 Temporary Maintenance uint256 enterMaintenanceHeight; // the height from where the validator enters Maintenance bool isMaintaining; // BEP-126 Fast Finality bytes voteAddress; // reserve for future use uint256[19] slots; } struct ValidatorSetPackage { uint8 packageType; Validator[] validatorSet; bytes[] voteAddrs; } /*----------------- modifiers -----------------*/ modifier noEmptyDeposit() { require(msg.value > 0, "deposit value is zero"); _; } modifier initValidatorExtraSet() { if (validatorExtraSet.length == 0) { ValidatorExtra memory validatorExtra; // init validatorExtraSet uint256 validatorsNum = currentValidatorSet.length; for (uint256 i; i < validatorsNum; ++i) { validatorExtraSet.push(validatorExtra); } } _; } modifier oncePerBlock() { require(block.number > previousHeight, "can not do this twice in one block"); _; previousHeight = block.number; } /*----------------- events -----------------*/ event validatorSetUpdated(); event systemTransfer(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 paramChange(string key, bytes value); event feeBurned(uint256 amount); event validatorEnterMaintenance(address indexed validator); event validatorExitMaintenance(address indexed validator); event finalityRewardDeposit(address indexed validator, uint256 amount); event deprecatedFinalityRewardDeposit(address indexed validator, uint256 amount); event validatorJailed(address indexed validator); // @dev deprecated event validatorEmptyJailed(address indexed validator); // @dev deprecated event batchTransfer(uint256 amount); // @dev deprecated event batchTransferFailed(uint256 indexed amount, string reason); // @dev deprecated event batchTransferLowerFailed(uint256 indexed amount, bytes reason); // @dev deprecated event directTransfer(address payable indexed validator, uint256 amount); // @dev deprecated event directTransferFail(address payable indexed validator, uint256 amount); // @dev deprecated event failReasonWithStr(string message); // @dev deprecated event unexpectedPackage(uint8 channelId, bytes msgBytes); // @dev deprecated event tmpValidatorSetUpdated(uint256 validatorsNum); // @dev deprecated /*----------------- init -----------------*/ function init() external onlyNotInit { (ValidatorSetPackage memory validatorSetPkg, bool valid) = decodeValidatorSet(INIT_VALIDATORSET_BYTES); require(valid, "failed to parse init validatorSet"); for (uint256 i; i < validatorSetPkg.validatorSet.length; ++i) { currentValidatorSet.push(validatorSetPkg.validatorSet[i]); currentValidatorSetMap[validatorSetPkg.validatorSet[i].consensusAddress] = i + 1; } alreadyInit = true; } receive() external payable { } /*----------------- Cross Chain App Implement -----------------*/ function handleSynPackage( uint8, bytes calldata msgBytes ) external override onlyInit onlyCrossChainContract initValidatorExtraSet returns (bytes memory responsePayload) { revert("deprecated"); } function handleAckPackage(uint8 channelId, bytes calldata msgBytes) external override onlyCrossChainContract { revert("deprecated"); } function handleFailAckPackage(uint8 channelId, bytes calldata msgBytes) external override onlyCrossChainContract { revert("deprecated"); } /*----------------- External Functions -----------------*/ /** * @dev Update validator set method after fusion fork. */ function updateValidatorSetV2( address[] memory _consensusAddrs, uint64[] memory _votingPowers, bytes[] memory _voteAddrs ) public onlyCoinbase onlyZeroGasPrice { uint256 _length = _consensusAddrs.length; Validator[] memory _validatorSet = new Validator[](_length); for (uint256 i; i < _length; ++i) { _validatorSet[i] = Validator({ consensusAddress: _consensusAddrs[i], feeAddress: payable(address(0)), BBCFeeAddress: address(0), votingPower: _votingPowers[i], jailed: false, incoming: 0 }); } // step 0: force all maintaining validators to exit `Temporary Maintenance` // - 1. validators exit maintenance // - 2. clear all maintainInfo // - 3. get unjailed validators from validatorSet (Validator[] memory validatorSetTemp, bytes[] memory voteAddrsTemp) = _forceMaintainingValidatorsExit(_validatorSet, _voteAddrs); // step 1: distribute incoming for (uint256 i; i < currentValidatorSet.length; ++i) { uint256 incoming = currentValidatorSet[i].incoming; if (incoming != 0) { currentValidatorSet[i].incoming = 0; IStakeHub(STAKE_HUB_ADDR).distributeReward{ value: incoming }(currentValidatorSet[i].consensusAddress); } } // step 2: do dusk transfer if (address(this).balance > 0) { emit systemTransfer(address(this).balance); address(uint160(SYSTEM_REWARD_ADDR)).transfer(address(this).balance); } // step 3: do update validator set state totalInComing = 0; if (validatorSetTemp.length != 0) { doUpdateState(validatorSetTemp, voteAddrsTemp); } // step 3: clean slash contract ISlashIndicator(SLASH_CONTRACT_ADDR).clean(); emit validatorSetUpdated(); } /** * @dev Collect all fee of transactions from the current block and deposit it to the contract * * @param valAddr The validator address who produced the current block */ function deposit(address valAddr) external payable onlyCoinbase onlyInit noEmptyDeposit onlyZeroGasPrice { uint256 value = msg.value; uint256 index = currentValidatorSetMap[valAddr]; if (isSystemRewardIncluded == false) { systemRewardBaseRatio = INIT_SYSTEM_REWARD_RATIO; burnRatio = INIT_BURN_RATIO; isSystemRewardIncluded = true; } uint256 systemRewardRatio = systemRewardBaseRatio; if (turnLength > 1 && systemRewardAntiMEVRatio > 0) { systemRewardRatio += systemRewardAntiMEVRatio * (block.number % turnLength) / (turnLength - 1); } if (value > 0 && systemRewardRatio > 0) { uint256 toSystemReward = msg.value.mul(systemRewardRatio).div(BLOCK_FEES_RATIO_SCALE); if (toSystemReward > 0) { address(uint160(SYSTEM_REWARD_ADDR)).transfer(toSystemReward); emit systemTransfer(toSystemReward); value = value.sub(toSystemReward); } } if (value > 0 && burnRatio > 0) { uint256 toBurn = msg.value.mul(burnRatio).div(BLOCK_FEES_RATIO_SCALE); if (toBurn > 0) { address(uint160(BURN_ADDRESS)).transfer(toBurn); emit feeBurned(toBurn); value = value.sub(toBurn); } } 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 distributeFinalityReward( address[] calldata valAddrs, uint256[] calldata weights ) external onlyCoinbase oncePerBlock onlyZeroGasPrice onlyInit { uint256 totalValue; uint256 balanceOfSystemReward = address(SYSTEM_REWARD_ADDR).balance; if (balanceOfSystemReward > MAX_SYSTEM_REWARD_BALANCE) { // when a slash happens, theres will no rewards in some finalityReward intervals, // it's tolerated because slash happens rarely totalValue = balanceOfSystemReward.sub(MAX_SYSTEM_REWARD_BALANCE); } else { return; } totalValue = ISystemReward(SYSTEM_REWARD_ADDR).claimRewards(payable(address(this)), totalValue); if (totalValue == 0) { return; } uint256 totalWeight; for (uint256 i; i < weights.length; ++i) { totalWeight += weights[i]; } if (totalWeight == 0) { return; } uint256 value; address valAddr; uint256 index; for (uint256 i; i < valAddrs.length; ++i) { value = (totalValue * weights[i]) / totalWeight; valAddr = valAddrs[i]; index = currentValidatorSetMap[valAddr]; if (index > 0) { Validator storage validator = currentValidatorSet[index - 1]; if (validator.jailed) { emit deprecatedFinalityRewardDeposit(valAddr, value); } else { totalInComing = totalInComing.add(value); validator.incoming = validator.incoming.add(value); emit finalityRewardDeposit(valAddr, value); } } else { // get incoming from deprecated validator; emit deprecatedFinalityRewardDeposit(valAddr, value); } } } /*----------------- View Functions -----------------*/ /** * @notice Return the vote address and consensus address of the validators in `currentValidatorSet` that are not jailed */ function getLivingValidators() external view override returns (address[] memory, bytes[] memory) { uint256 n = currentValidatorSet.length; uint256 living; for (uint256 i; i < n; ++i) { if (!currentValidatorSet[i].jailed) { living++; } } address[] memory consensusAddrs = new address[](living); bytes[] memory voteAddrs = new bytes[](living); living = 0; if (validatorExtraSet.length == n) { for (uint256 i; i < n; ++i) { if (!currentValidatorSet[i].jailed) { consensusAddrs[living] = currentValidatorSet[i].consensusAddress; voteAddrs[living] = validatorExtraSet[i].voteAddress; living++; } } } else { for (uint256 i; i < n; ++i) { if (!currentValidatorSet[i].jailed) { consensusAddrs[living] = currentValidatorSet[i].consensusAddress; living++; } } } return (consensusAddrs, voteAddrs); } /** * @notice Return the vote address and consensus address of mining validators * * Mining validators are block producers in the current epoch * including most of the cabinets and a few of the candidates */ function getMiningValidators() external view override returns (address[] memory, bytes[] memory) { uint256 _maxNumOfWorkingCandidates = maxNumOfWorkingCandidates; uint256 _numOfCabinets = numOfCabinets > 0 ? numOfCabinets : INIT_NUM_OF_CABINETS; uint256 _shuffleInterval = 200; address[] memory validators = getValidators(); bytes[] memory voteAddrs = getVoteAddresses(validators); if (validators.length <= _numOfCabinets) { return (validators, voteAddrs); } if ((validators.length - _numOfCabinets) < _maxNumOfWorkingCandidates) { _maxNumOfWorkingCandidates = validators.length - _numOfCabinets; } if (_maxNumOfWorkingCandidates > 0) { uint256 shuffleNumber = block.number / _shuffleInterval; shuffle( validators, voteAddrs, shuffleNumber, _numOfCabinets - _maxNumOfWorkingCandidates, 0, _maxNumOfWorkingCandidates, _numOfCabinets ); shuffle( validators, voteAddrs, shuffleNumber, _numOfCabinets - _maxNumOfWorkingCandidates, _numOfCabinets - _maxNumOfWorkingCandidates, _maxNumOfWorkingCandidates, validators.length - _numOfCabinets + _maxNumOfWorkingCandidates ); } address[] memory miningValidators = new address[](_numOfCabinets); bytes[] memory miningVoteAddrs = new bytes[](_numOfCabinets); for (uint256 i; i < _numOfCabinets; ++i) { miningValidators[i] = validators[i]; miningVoteAddrs[i] = voteAddrs[i]; } return (miningValidators, miningVoteAddrs); } /** * @notice Return the consensus address of the validators in `currentValidatorSet` that are not jailed and not maintaining */ function getValidators() public view returns (address[] memory) { uint256 n = currentValidatorSet.length; uint256 valid = 0; for (uint256 i; i < n; ++i) { if (isWorkingValidator(i)) { ++valid; } } address[] memory consensusAddrs = new address[](valid); valid = 0; for (uint256 i; i < n; ++i) { if (isWorkingValidator(i)) { consensusAddrs[valid] = currentValidatorSet[i].consensusAddress; ++valid; } } return consensusAddrs; } /** * @notice Return the current incoming of the validator */ function getIncoming(address validator) external view returns (uint256) { uint256 index = currentValidatorSetMap[validator]; if (index <= 0) { return 0; } return currentValidatorSet[index - 1].incoming; } /** * @notice Return whether the validator is a working validator(not jailed or maintaining) by index * * @param index The index of the validator in `currentValidatorSet`(from 0 to `currentValidatorSet.length-1`) */ function isWorkingValidator(uint256 index) public view returns (bool) { if (index >= currentValidatorSet.length) { return false; } // validatorExtraSet[index] should not be used before it has been init. if (index >= validatorExtraSet.length) { return !currentValidatorSet[index].jailed; } return !currentValidatorSet[index].jailed && !validatorExtraSet[index].isMaintaining; } /** * @notice Return whether the validator is a working validator(not jailed or maintaining) by consensus address * Will return false if the validator is not in `currentValidatorSet` */ function isCurrentValidator(address validator) external view override returns (bool) { uint256 index = currentValidatorSetMap[validator]; if (index <= 0) { return false; } // the actual index index = index - 1; return isWorkingValidator(index); } /** * @notice Return the index of the validator in `currentValidatorSet`(from 0 to `currentValidatorSet.length-1`) */ function getCurrentValidatorIndex(address validator) public view returns (uint256) { uint256 index = currentValidatorSetMap[validator]; require(index > 0, "only current validators"); // the actual index return index - 1; } /** * @notice Return the number of mining validators. * The function name is misleading, it should be `getMiningValidatorCount`. But it's kept for compatibility. */ function getWorkingValidatorCount() public view returns (uint256 workingValidatorCount) { workingValidatorCount = getValidators().length; uint256 _numOfCabinets = numOfCabinets > 0 ? numOfCabinets : INIT_NUM_OF_CABINETS; if (workingValidatorCount > _numOfCabinets) { workingValidatorCount = _numOfCabinets; } if (workingValidatorCount == 0) { workingValidatorCount = 1; } } /*----------------- For slash -----------------*/ function misdemeanor(address validator) external override onlySlash initValidatorExtraSet { uint256 validatorIndex = _misdemeanor(validator); if (canEnterMaintenance(validatorIndex)) { _enterMaintenance(validator, validatorIndex); } } function felony(address validator) external override initValidatorExtraSet { require(msg.sender == SLASH_CONTRACT_ADDR || msg.sender == STAKE_HUB_ADDR, "only slash or stakeHub contract"); uint256 index = currentValidatorSetMap[validator]; if (index <= 0) { return; } // the actual index index = index - 1; bool isMaintaining = validatorExtraSet[index].isMaintaining; if (_felony(validator, index) && isMaintaining) { --numOfMaintaining; } } function removeTmpMigratedValidator(address validator) external onlyStakeHub { revert("deprecated"); } /*----------------- For Temporary Maintenance -----------------*/ /** * @notice Return whether the validator at index could enter maintenance */ function canEnterMaintenance(uint256 index) public view returns (bool) { if (index >= currentValidatorSet.length) { return false; } if ( currentValidatorSet[index].consensusAddress == address(0) // - 0. check if empty validator || (maxNumOfMaintaining == 0 || maintainSlashScale == 0) // - 1. check if not start || numOfMaintaining >= maxNumOfMaintaining // - 2. check if reached upper limit || !isWorkingValidator(index) // - 3. check if not working(not jailed and not maintaining) || validatorExtraSet[index].enterMaintenanceHeight > 0 // - 5. check if has Maintained during current 24-hour period // current validators are selected every 24 hours(from 00:00:00 UTC to 23:59:59 UTC) || getValidators().length <= 1 // - 6. check num of remaining working validators ) { return false; } return true; } /** * @dev Enter maintenance for current validators. refer to https://github.com/bnb-chain/BEPs/blob/master/BEP127.md */ function enterMaintenance() external initValidatorExtraSet { // check maintain config if (maxNumOfMaintaining == 0) { maxNumOfMaintaining = INIT_MAX_NUM_OF_MAINTAINING; } if (maintainSlashScale == 0) { maintainSlashScale = INIT_MAINTAIN_SLASH_SCALE; } uint256 index = getCurrentValidatorIndex(msg.sender); require(canEnterMaintenance(index), "can not enter Temporary Maintenance"); _enterMaintenance(msg.sender, index); } /** * @dev Exit maintenance for current validators. refer to https://github.com/bnb-chain/BEPs/blob/master/BEP127.md */ function exitMaintenance() external { uint256 index = getCurrentValidatorIndex(msg.sender); // jailed validators are allowed to exit maintenance require(validatorExtraSet[index].isMaintaining, "not in maintenance"); uint256 miningValidatorCount = getWorkingValidatorCount(); _exitMaintenance(msg.sender, index, miningValidatorCount, true); } /*----------------- Param update -----------------*/ function updateParam(string calldata key, bytes calldata value) external override onlyInit onlyGov { if (Memory.compareStrings(key, "burnRatio")) { require(value.length == 32, "length of burnRatio mismatch"); uint256 newBurnRatio = BytesToTypes.bytesToUint256(32, value); require( newBurnRatio.add(systemRewardBaseRatio).add(systemRewardAntiMEVRatio) <= BLOCK_FEES_RATIO_SCALE, "the burnRatio plus systemRewardBaseRatio and systemRewardAntiMEVRatio must be no greater than 10000" ); burnRatio = newBurnRatio; } else if (Memory.compareStrings(key, "maxNumOfMaintaining")) { require(value.length == 32, "length of maxNumOfMaintaining mismatch"); uint256 newMaxNumOfMaintaining = BytesToTypes.bytesToUint256(32, value); uint256 _numOfCabinets = numOfCabinets; if (_numOfCabinets == 0) { _numOfCabinets = INIT_NUM_OF_CABINETS; } require(newMaxNumOfMaintaining < _numOfCabinets, "the maxNumOfMaintaining must be less than numOfCabinets"); maxNumOfMaintaining = newMaxNumOfMaintaining; } else if (Memory.compareStrings(key, "maintainSlashScale")) { require(value.length == 32, "length of maintainSlashScale mismatch"); uint256 newMaintainSlashScale = BytesToTypes.bytesToUint256(32, value); require( newMaintainSlashScale > 0 && newMaintainSlashScale < 10, "the maintainSlashScale must be greater than 0 and less than 10" ); maintainSlashScale = newMaintainSlashScale; } else if (Memory.compareStrings(key, "maxNumOfWorkingCandidates")) { require(value.length == 32, "length of maxNumOfWorkingCandidates mismatch"); uint256 newMaxNumOfWorkingCandidates = BytesToTypes.bytesToUint256(32, value); require( newMaxNumOfWorkingCandidates <= maxNumOfCandidates, "the maxNumOfWorkingCandidates must be not greater than maxNumOfCandidates" ); maxNumOfWorkingCandidates = newMaxNumOfWorkingCandidates; } else if (Memory.compareStrings(key, "maxNumOfCandidates")) { require(value.length == 32, "length of maxNumOfCandidates mismatch"); uint256 newMaxNumOfCandidates = BytesToTypes.bytesToUint256(32, value); maxNumOfCandidates = newMaxNumOfCandidates; if (maxNumOfWorkingCandidates > maxNumOfCandidates) { maxNumOfWorkingCandidates = maxNumOfCandidates; } } else if (Memory.compareStrings(key, "numOfCabinets")) { require(value.length == 32, "length of numOfCabinets mismatch"); uint256 newNumOfCabinets = BytesToTypes.bytesToUint256(32, value); require(newNumOfCabinets > 0, "the numOfCabinets must be greater than 0"); uint256 maxElectedValidators = IStakeHub(STAKE_HUB_ADDR).maxElectedValidators(); require( newNumOfCabinets <= maxElectedValidators, "the numOfCabinets must be less than maxElectedValidators" ); numOfCabinets = newNumOfCabinets; } else if (Memory.compareStrings(key, "systemRewardBaseRatio")) { require(value.length == 32, "length of systemRewardBaseRatio mismatch"); uint256 newSystemRewardBaseRatio = BytesToTypes.bytesToUint256(32, value); require( newSystemRewardBaseRatio.add(burnRatio).add(systemRewardAntiMEVRatio) <= BLOCK_FEES_RATIO_SCALE, "the systemRewardBaseRatio plus burnRatio and systemRewardAntiMEVRatio must be no greater than 10000" ); systemRewardBaseRatio = newSystemRewardBaseRatio; } else if (Memory.compareStrings(key, "systemRewardAntiMEVRatio")) { require(value.length == 32, "length of systemRewardAntiMEVRatio mismatch"); uint256 newSystemRewardAntiMEVRatio = BytesToTypes.bytesToUint256(32, value); require( newSystemRewardAntiMEVRatio.add(burnRatio).add(systemRewardBaseRatio) <= BLOCK_FEES_RATIO_SCALE, "the systemRewardAntiMEVRatio plus burnRatio and systemRewardBaseRatio must be no greater than 10000" ); systemRewardAntiMEVRatio = newSystemRewardAntiMEVRatio; } else if (Memory.compareStrings(key, "turnLength")) { require(value.length == 32, "length of turnLength mismatch"); uint256 newTurnLength = BytesToTypes.bytesToUint256(32, value); require( newTurnLength >= 3 && newTurnLength <= 64 || newTurnLength == 1, "the turnLength should be in [3,64] or equal to 1" ); turnLength = newTurnLength; } else { require(false, "unknown param"); } emit paramChange(key, value); } /*----------------- Internal Functions -----------------*/ function doUpdateState(Validator[] memory newValidatorSet, bytes[] memory newVoteAddrs) private { uint256 n = currentValidatorSet.length; uint256 m = newValidatorSet.length; // delete stale validators for (uint256 i; i < n; ++i) { bool stale = true; Validator memory oldValidator = currentValidatorSet[i]; for (uint256 j; j < m; ++j) { if (oldValidator.consensusAddress == newValidatorSet[j].consensusAddress) { stale = false; break; } } if (stale) { delete currentValidatorSetMap[oldValidator.consensusAddress]; } } // if old validator set is larger than new validator set, pop the extra validators if (n > m) { for (uint256 i = m; i < n; ++i) { currentValidatorSet.pop(); validatorExtraSet.pop(); } } uint256 k = n < m ? n : m; for (uint256 i; i < k; ++i) { // if the validator is not the same, update the validator set directly if (!isSameValidator(newValidatorSet[i], currentValidatorSet[i])) { currentValidatorSetMap[newValidatorSet[i].consensusAddress] = i + 1; currentValidatorSet[i] = newValidatorSet[i]; validatorExtraSet[i].voteAddress = newVoteAddrs[i]; validatorExtraSet[i].isMaintaining = false; validatorExtraSet[i].enterMaintenanceHeight = 0; } else { currentValidatorSet[i].votingPower = newValidatorSet[i].votingPower; // update the vote address if it is different if (!BytesLib.equal(newVoteAddrs[i], validatorExtraSet[i].voteAddress)) { validatorExtraSet[i].voteAddress = newVoteAddrs[i]; } } } if (m > n) { ValidatorExtra memory _validatorExtra; for (uint256 i = n; i < m; ++i) { _validatorExtra.voteAddress = newVoteAddrs[i]; currentValidatorSet.push(newValidatorSet[i]); validatorExtraSet.push(_validatorExtra); currentValidatorSetMap[newValidatorSet[i].consensusAddress] = i + 1; } } // update vote addr full set setPreviousVoteAddrFullSet(); setCurrentVoteAddrFullSet(); // make sure all new validators are cleared maintainInfo // should not happen, still protect numOfMaintaining = 0; n = currentValidatorSet.length; for (uint256 i; i < n; ++i) { validatorExtraSet[i].isMaintaining = false; validatorExtraSet[i].enterMaintenanceHeight = 0; } } /** * @dev With each shuffle interval blocks, there will be a partial rotation between cabinets and candidates. Rotation is determined by this function */ function shuffle( address[] memory validators, bytes[] memory voteAddrs, uint256 shuffleNumber, uint256 startIdx, uint256 offset, uint256 limit, uint256 modNumber ) internal pure { for (uint256 i; i < limit; ++i) { uint256 random = uint256(keccak256(abi.encodePacked(shuffleNumber, startIdx + i))) % modNumber; if ((startIdx + i) != (offset + random)) { address tmpAddr = validators[startIdx + i]; bytes memory tmpBLS = voteAddrs[startIdx + i]; validators[startIdx + i] = validators[offset + random]; validators[offset + random] = tmpAddr; voteAddrs[startIdx + i] = voteAddrs[offset + random]; voteAddrs[offset + random] = tmpBLS; } } } /** * @dev Check if two validators are the same * * Vote address is not considered */ 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; } function getVoteAddresses(address[] memory validators) internal view returns (bytes[] memory) { uint256 n = currentValidatorSet.length; uint256 length = validators.length; bytes[] memory voteAddrs = new bytes[](length); // check if validatorExtraSet has been initialized if (validatorExtraSet.length != n) { return voteAddrs; } for (uint256 i; i < length; ++i) { voteAddrs[i] = validatorExtraSet[currentValidatorSetMap[validators[i]] - 1].voteAddress; } return voteAddrs; } function getTurnLength() external view returns (uint256) { if (turnLength == 0) { return 1; } return turnLength; } function setPreviousVoteAddrFullSet() private { uint256 n = previousVoteAddrFullSet.length; uint256 m = currentVoteAddrFullSet.length; if (n > m) { for (uint256 i = m; i < n; ++i) { previousVoteAddrFullSet.pop(); } } uint256 k = n < m ? n : m; for (uint256 i; i < k; ++i) { if (!BytesLib.equal(previousVoteAddrFullSet[i], currentVoteAddrFullSet[i])) { previousVoteAddrFullSet[i] = currentVoteAddrFullSet[i]; } } if (m > n) { for (uint256 i = n; i < m; ++i) { previousVoteAddrFullSet.push(currentVoteAddrFullSet[i]); } } } function setCurrentVoteAddrFullSet() private { uint256 n = currentVoteAddrFullSet.length; uint256 m = validatorExtraSet.length; if (n > m) { for (uint256 i = m; i < n; ++i) { currentVoteAddrFullSet.pop(); } } uint256 k = n < m ? n : m; for (uint256 i; i < k; ++i) { if (!BytesLib.equal(currentVoteAddrFullSet[i], validatorExtraSet[i].voteAddress)) { currentVoteAddrFullSet[i] = validatorExtraSet[i].voteAddress; } } if (m > n) { for (uint256 i = n; i < m; ++i) { currentVoteAddrFullSet.push(validatorExtraSet[i].voteAddress); } } } function isMonitoredForMaliciousVote(bytes calldata voteAddr) external view override returns (bool) { uint256 m = currentVoteAddrFullSet.length; for (uint256 i; i < m; ++i) { if (BytesLib.equal(voteAddr, currentVoteAddrFullSet[i])) { return true; } } uint256 n = previousVoteAddrFullSet.length; for (uint256 i; i < n; ++i) { if (BytesLib.equal(voteAddr, previousVoteAddrFullSet[i])) { return true; } } return false; } function _misdemeanor(address validator) private returns (uint256) { uint256 index = currentValidatorSetMap[validator]; if (index <= 0) { return ~uint256(0); } // 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 index; } // averageDistribute*rest may less than income, but it is ok, the dust income will go to system reward eventually. uint256 averageDistribute = income / rest; if (averageDistribute != 0) { for (uint256 i; i < index; ++i) { currentValidatorSet[i].incoming = currentValidatorSet[i].incoming.add(averageDistribute); } uint256 n = currentValidatorSet.length; for (uint256 i = index + 1; i < n; ++i) { currentValidatorSet[i].incoming = currentValidatorSet[i].incoming.add(averageDistribute); } } return index; } function _felony(address validator, uint256 index) private returns (bool) { uint256 income = currentValidatorSet[index].incoming; uint256 rest = currentValidatorSet.length - 1; if (getValidators().length <= 1) { // will not remove the validator if it is the only one validator. currentValidatorSet[index].incoming = 0; return false; } emit validatorFelony(validator, income); // remove the validator from currentValidatorSet delete currentValidatorSetMap[validator]; // remove felony validator for (uint256 i = index; i < (currentValidatorSet.length - 1); ++i) { currentValidatorSet[i] = currentValidatorSet[i + 1]; validatorExtraSet[i] = validatorExtraSet[i + 1]; currentValidatorSetMap[currentValidatorSet[i].consensusAddress] = i + 1; } currentValidatorSet.pop(); validatorExtraSet.pop(); // averageDistribute*rest may less than income, but it is ok, the dust income will go to system reward eventually. uint256 averageDistribute = income / rest; if (averageDistribute != 0) { uint256 n = currentValidatorSet.length; for (uint256 i; i < n; ++i) { currentValidatorSet[i].incoming = currentValidatorSet[i].incoming.add(averageDistribute); } } return true; } function _forceMaintainingValidatorsExit( Validator[] memory _validatorSet, bytes[] memory _voteAddrs ) private returns (Validator[] memory unjailedValidatorSet, bytes[] memory unjailedVoteAddrs) { uint256 numOfFelony = 0; address validator; bool isFelony; // 1. validators exit maintenance uint256 i; // caution: it must calculate miningValidatorCount before _exitMaintenance loop // because the miningValidatorCount will be changed in _exitMaintenance uint256 miningValidatorCount = getWorkingValidatorCount(); // caution: it must loop from the endIndex to startIndex in currentValidatorSet // because the validators order in currentValidatorSet may be changed by _felony(validator) for (uint256 index = currentValidatorSet.length; index > 0; --index) { i = index - 1; // the actual index if (!validatorExtraSet[i].isMaintaining) { continue; } // only maintaining validators validator = currentValidatorSet[i].consensusAddress; // exit maintenance isFelony = _exitMaintenance(validator, i, miningValidatorCount, false); if (!isFelony) { continue; } // get the latest consensus address address latestConsensusAddress; address operatorAddress = IStakeHub(STAKE_HUB_ADDR).consensusToOperator(validator); if (operatorAddress != address(0)) { latestConsensusAddress = IStakeHub(STAKE_HUB_ADDR).getValidatorConsensusAddress(operatorAddress); } // record the jailed validator in validatorSet for (uint256 j; j < _validatorSet.length; ++j) { if ( _validatorSet[j].consensusAddress == validator || _validatorSet[j].consensusAddress == latestConsensusAddress ) { _validatorSet[j].jailed = true; break; } } } // count the number of felony validators for (uint256 k; k < _validatorSet.length; ++k) { if (_validatorSet[k].jailed || _validatorSet[k].consensusAddress == address(0)) { ++numOfFelony; } } // 2. get unjailed validators from validatorSet if (numOfFelony >= _validatorSet.length) { // make sure there is at least one validator unjailedValidatorSet = new Validator[](1); unjailedVoteAddrs = new bytes[](1); unjailedValidatorSet[0] = _validatorSet[0]; unjailedVoteAddrs[0] = _voteAddrs[0]; unjailedValidatorSet[0].jailed = false; } else { unjailedValidatorSet = new Validator[](_validatorSet.length - numOfFelony); unjailedVoteAddrs = new bytes[](_validatorSet.length - numOfFelony); i = 0; for (uint256 index; index < _validatorSet.length; ++index) { if (!_validatorSet[index].jailed && _validatorSet[index].consensusAddress != address(0)) { unjailedValidatorSet[i] = _validatorSet[index]; unjailedVoteAddrs[i] = _voteAddrs[index]; ++i; } } } return (unjailedValidatorSet, unjailedVoteAddrs); } function _enterMaintenance(address validator, uint256 index) private { ++numOfMaintaining; validatorExtraSet[index].isMaintaining = true; validatorExtraSet[index].enterMaintenanceHeight = block.number; emit validatorEnterMaintenance(validator); } function _exitMaintenance( address validator, uint256 index, uint256 miningValidatorCount, bool shouldRevert ) private returns (bool isFelony) { if (maintainSlashScale == 0 || miningValidatorCount == 0 || numOfMaintaining == 0) { // should not happen, still protect return false; } // step 0: modify numOfMaintaining --numOfMaintaining; // step 1: calculate slashCount uint256 slashCount = block.number.sub(validatorExtraSet[index].enterMaintenanceHeight).div(miningValidatorCount) .div(maintainSlashScale); // step 2: clear isMaintaining info validatorExtraSet[index].isMaintaining = false; // step 3: slash the validator (uint256 misdemeanorThreshold, uint256 felonyThreshold) = ISlashIndicator(SLASH_CONTRACT_ADDR).getSlashThresholds(); isFelony = false; if (slashCount >= felonyThreshold) { _felony(validator, index); ISlashIndicator(SLASH_CONTRACT_ADDR).downtimeSlash(validator, slashCount, shouldRevert); isFelony = true; } else if (slashCount >= misdemeanorThreshold) { _misdemeanor(validator); } emit validatorExitMaintenance(validator); } function decodeValidatorSet(bytes memory msgBytes) internal pure returns (ValidatorSetPackage memory, bool) { ValidatorSetPackage 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); validatorSetPkg.voteAddrs = new bytes[](items.length); for (uint256 j; j < items.length; ++j) { (Validator memory val, bytes memory voteAddr, bool ok) = decodeValidator(items[j]); if (!ok) { return (validatorSetPkg, false); } validatorSetPkg.validatorSet[j] = val; validatorSetPkg.voteAddrs[j] = voteAddr; } success = true; } else { break; } ++idx; } return (validatorSetPkg, success); } function decodeValidator(RLPDecode.RLPItem memory itemValidator) internal pure returns (Validator memory, bytes memory, bool) { Validator memory validator; bytes memory voteAddr; 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 if (idx == 4) { voteAddr = iter.next().toBytes(); } else { break; } ++idx; } return (validator, voteAddr, success); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "batchTransfer","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "uint256","name": "amount","type": "uint256"},{"indexed": false,"internalType": "string","name": "reason","type": "string"}],"name": "batchTransferFailed","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "uint256","name": "amount","type": "uint256"},{"indexed": false,"internalType": "bytes","name": "reason","type": "bytes"}],"name": "batchTransferLowerFailed","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "deprecatedDeposit","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "deprecatedFinalityRewardDeposit","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address payable","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "directTransfer","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address payable","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "directTransferFail","type": "event"},{"anonymous": false,"inputs": [{"indexed": false,"internalType": "string","name": "message","type": "string"}],"name": "failReasonWithStr","type": "event"},{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "feeBurned","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "finalityRewardDeposit","type": "event"},{"anonymous": false,"inputs": [{"indexed": false,"internalType": "string","name": "key","type": "string"},{"indexed": false,"internalType": "bytes","name": "value","type": "bytes"}],"name": "paramChange","type": "event"},{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "systemTransfer","type": "event"},{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint256","name": "validatorsNum","type": "uint256"}],"name": "tmpValidatorSetUpdated","type": "event"},{"anonymous": false,"inputs": [{"indexed": false,"internalType": "uint8","name": "channelId","type": "uint8"},{"indexed": false,"internalType": "bytes","name": "msgBytes","type": "bytes"}],"name": "unexpectedPackage","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "validatorDeposit","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"}],"name": "validatorEmptyJailed","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"}],"name": "validatorEnterMaintenance","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"}],"name": "validatorExitMaintenance","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "validatorFelony","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"}],"name": "validatorJailed","type": "event"},{"anonymous": false,"inputs": [{"indexed": true,"internalType": "address","name": "validator","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "validatorMisdemeanor","type": "event"},{"anonymous": false,"inputs": [],"name": "validatorSetUpdated","type": "event"},{"inputs": [],"name": "BLOCK_FEES_RATIO_SCALE","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "BURN_ADDRESS","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "CODE_OK","outputs": [{"internalType": "uint32","name": "","type": "uint32"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "CROSS_CHAIN_CONTRACT_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "GOVERNOR_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "GOV_HUB_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "GOV_TOKEN_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "INCENTIVIZE_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "INIT_BURN_RATIO","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "INIT_MAINTAIN_SLASH_SCALE","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "INIT_MAX_NUM_OF_MAINTAINING","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "INIT_NUM_OF_CABINETS","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "INIT_SYSTEM_REWARD_RATIO","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "INIT_VALIDATORSET_BYTES","outputs": [{"internalType": "bytes","name": "","type": "bytes"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "LIGHT_CLIENT_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "MAX_SYSTEM_REWARD_BALANCE","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "RELAYERHUB_CONTRACT_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "SLASH_CONTRACT_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "STAKE_CREDIT_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "STAKE_HUB_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "STAKING_CONTRACT_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "SYSTEM_REWARD_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "TIMELOCK_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "TOKEN_HUB_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "TOKEN_MANAGER_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "TOKEN_RECOVER_PORTAL_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "VALIDATOR_CONTRACT_ADDR","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "alreadyInit","outputs": [{"internalType": "bool","name": "","type": "bool"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "bscChainID","outputs": [{"internalType": "uint16","name": "","type": "uint16"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "burnRatio","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "burnRatioInitialized","outputs": [{"internalType": "bool","name": "","type": "bool"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "uint256","name": "index","type": "uint256"}],"name": "canEnterMaintenance","outputs": [{"internalType": "bool","name": "","type": "bool"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "uint256","name": "","type": "uint256"}],"name": "currentValidatorSet","outputs": [{"internalType": "address","name": "consensusAddress","type": "address"},{"internalType": "address payable","name": "feeAddress","type": "address"},{"internalType": "address","name": "BBCFeeAddress","type": "address"},{"internalType": "uint64","name": "votingPower","type": "uint64"},{"internalType": "bool","name": "jailed","type": "bool"},{"internalType": "uint256","name": "incoming","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "","type": "address"}],"name": "currentValidatorSetMap","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "uint256","name": "","type": "uint256"}],"name": "currentVoteAddrFullSet","outputs": [{"internalType": "bytes","name": "","type": "bytes"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "valAddr","type": "address"}],"name": "deposit","outputs": [],"stateMutability": "payable","type": "function"},{"inputs": [{"internalType": "address[]","name": "valAddrs","type": "address[]"},{"internalType": "uint256[]","name": "weights","type": "uint256[]"}],"name": "distributeFinalityReward","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [],"name": "enterMaintenance","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [],"name": "exitMaintenance","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [],"name": "expireTimeSecondGap","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "validator","type": "address"}],"name": "felony","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [{"internalType": "address","name": "validator","type": "address"}],"name": "getCurrentValidatorIndex","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "validator","type": "address"}],"name": "getIncoming","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "getLivingValidators","outputs": [{"internalType": "address[]","name": "","type": "address[]"},{"internalType": "bytes[]","name": "","type": "bytes[]"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "getMiningValidators","outputs": [{"internalType": "address[]","name": "","type": "address[]"},{"internalType": "bytes[]","name": "","type": "bytes[]"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "getTurnLength","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "getValidators","outputs": [{"internalType": "address[]","name": "","type": "address[]"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "getWorkingValidatorCount","outputs": [{"internalType": "uint256","name": "workingValidatorCount","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "uint8","name": "channelId","type": "uint8"},{"internalType": "bytes","name": "msgBytes","type": "bytes"}],"name": "handleAckPackage","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [{"internalType": "uint8","name": "channelId","type": "uint8"},{"internalType": "bytes","name": "msgBytes","type": "bytes"}],"name": "handleFailAckPackage","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [{"internalType": "uint8","name": "","type": "uint8"},{"internalType": "bytes","name": "msgBytes","type": "bytes"}],"name": "handleSynPackage","outputs": [{"internalType": "bytes","name": "responsePayload","type": "bytes"}],"stateMutability": "nonpayable","type": "function"},{"inputs": [],"name": "init","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [{"internalType": "address","name": "validator","type": "address"}],"name": "isCurrentValidator","outputs": [{"internalType": "bool","name": "","type": "bool"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "bytes","name": "voteAddr","type": "bytes"}],"name": "isMonitoredForMaliciousVote","outputs": [{"internalType": "bool","name": "","type": "bool"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "isSystemRewardIncluded","outputs": [{"internalType": "bool","name": "","type": "bool"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "uint256","name": "index","type": "uint256"}],"name": "isWorkingValidator","outputs": [{"internalType": "bool","name": "","type": "bool"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "maintainSlashScale","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "maxNumOfCandidates","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "maxNumOfMaintaining","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "maxNumOfWorkingCandidates","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "validator","type": "address"}],"name": "misdemeanor","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [],"name": "numOfCabinets","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "numOfJailed","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "numOfMaintaining","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "previousBalanceOfSystemReward","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "previousHeight","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "uint256","name": "","type": "uint256"}],"name": "previousVoteAddrFullSet","outputs": [{"internalType": "bytes","name": "","type": "bytes"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "validator","type": "address"}],"name": "removeTmpMigratedValidator","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [],"name": "systemRewardAntiMEVRatio","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "systemRewardBaseRatio","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "totalInComing","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [],"name": "turnLength","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "string","name": "key","type": "string"},{"internalType": "bytes","name": "value","type": "bytes"}],"name": "updateParam","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [{"internalType": "address[]","name": "_consensusAddrs","type": "address[]"},{"internalType": "uint64[]","name": "_votingPowers","type": "uint64[]"},{"internalType": "bytes[]","name": "_voteAddrs","type": "bytes[]"}],"name": "updateValidatorSetV2","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [{"internalType": "uint256","name": "","type": "uint256"}],"name": "validatorExtraSet","outputs": [{"internalType": "uint256","name": "enterMaintenanceHeight","type": "uint256"},{"internalType": "bool","name": "isMaintaining","type": "bool"},{"internalType": "bytes","name": "voteAddress","type": "bytes"}],"stateMutability": "view","type": "function"},{"stateMutability": "payable","type": "receive"}]Contract Creation Code
6080604052600436106104405760003560e01c80638b5ad0c911610234578063c81b16621161012e578063e1c7392a116100b6578063f92eb86b1161007a578063f92eb86b14610b3f578063f9a2bbc714610b54578063fccc281314610b69578063fd4ad81f14610b7e578063fd6a687914610bad57610447565b8063e1c7392a14610ac2578063e40716a114610ad7578063ea321e4914610aec578063eb57e20214610b0c578063f340fa0114610b2c57610447565b8063d58918ae116100fd578063d58918ae14610a59578063d68fb56a14610a6e578063daacdb6614610a83578063dc927faf14610a98578063df8079e914610aad57610447565b8063c81b166214610a0f578063c8509d81146107e6578063cb75a59214610a24578063ce910b0c14610a3957610447565b8063aa82dce1116101bc578063aef198a911610180578063aef198a914610999578063b7ab4db5146109ae578063b8cf4ef1146109d0578063c466689d146109e5578063c6d33945146109fa57610447565b8063aa82dce11461090d578063aad5606314610922578063ab51bb9614610937578063ac43175114610959578063ad3c9da61461097957610447565b80639dc09262116102035780639dc09262146108a45780639fe0f816146108b9578063a1a11bf5146108ce578063a5422d5c146108e3578063a78abc16146108f857610447565b80638b5ad0c9146108455780638c5d749d1461085a5780638d19a4101461086f5780639369d7de1461088f57610447565b80634df6e0c3116103455780636e47b482116102cd578063820dcaa811610291578063820dcaa8146107d1578063831d65d1146107e6578063862498821461080657806388b32f111461081b5780638a7beb011461083057610447565b80636e47b4821461076857806375d47a0a1461077d57806378dfed4a146107925780637a84ca2a146107a75780637e434d54146107bc57610447565b806355614fcc1161031457806355614fcc146106c1578063565c56b3146106e157806360eba4fe1461070157806362b72cf5146107215780636969a25c1461073657610447565b80634df6e0c31461066d5780635192c82c1461068257806351b4dce31461069757806351e80672146106ac57610447565b80632a0ffb6e116103c857806335409f7f1161039757806335409f7f146105de5780633b071dcc146105fe57806343756e5c1461062157806345cf9daf14610636578063493279b11461064b57610447565b80632a0ffb6e1461055e578063300c35671461057e578063321d398a1461059e5780633365af3a146105be57610447565b8063152ad3b81161040f578063152ad3b8146104dd5780631bd14ed8146104ff5780631e4c1524146105145780631ff1806914610534578063280870281461054957610447565b806304c4fec61461044c57806307a56847146104635780630e2374a51461048e5780631182b875146104b057610447565b3661044757005b600080fd5b34801561045857600080fd5b50610461610bc2565b005b34801561046f57600080fd5b50610478610c36565b6040516104859190616d89565b60405180910390f35b34801561049a57600080fd5b506104a3610c3c565b604051610485919061613e565b3480156104bc57600080fd5b506104d06104cb366004616024565b610c42565b604051610485919061625e565b3480156104e957600080fd5b506104f2610d5e565b6040516104859190616253565b34801561050b57600080fd5b50610478610d67565b34801561052057600080fd5b5061046161052f366004615e52565b610d6d565b34801561054057600080fd5b506104786110a1565b34801561055557600080fd5b506104a36110a7565b34801561056a57600080fd5b50610461610579366004615db2565b6110ad565b34801561058a57600080fd5b50610461610599366004615dea565b6110ce565b3480156105aa57600080fd5b506104f26105b9366004615fd1565b611417565b3480156105ca57600080fd5b506104f26105d9366004615fd1565b6114e6565b3480156105ea57600080fd5b506104616105f9366004615db2565b611597565b34801561060a57600080fd5b506106136116fc565b6040516104859291906161e3565b34801561062d57600080fd5b506104a36119d8565b34801561064257600080fd5b506104786119de565b34801561065757600080fd5b506106606119e4565b6040516104859190616d7a565b34801561067957600080fd5b506106136119e9565b34801561068e57600080fd5b50610478611b83565b3480156106a357600080fd5b506104a3611b89565b3480156106b857600080fd5b506104a3611b8f565b3480156106cd57600080fd5b506104f26106dc366004615db2565b611b95565b3480156106ed57600080fd5b506104786106fc366004615db2565b611bd1565b34801561070d57600080fd5b506104d061071c366004615fd1565b611c22565b34801561072d57600080fd5b50610478611cc8565b34801561074257600080fd5b50610756610751366004615fd1565b611cce565b6040516104859695949392919061616b565b34801561077457600080fd5b506104a3611d32565b34801561078957600080fd5b506104a3611d38565b34801561079e57600080fd5b50610478611d3e565b3480156107b357600080fd5b50610478611d44565b3480156107c857600080fd5b506104a3611d4a565b3480156107dd57600080fd5b50610478611d50565b3480156107f257600080fd5b50610461610801366004616024565b611d56565b34801561081257600080fd5b50610478611d77565b34801561082757600080fd5b50610478611d7d565b34801561083c57600080fd5b506104f2611d83565b34801561085157600080fd5b50610478611d8c565b34801561086657600080fd5b50610478611d92565b34801561087b57600080fd5b5061047861088a366004615db2565b611daf565b34801561089b57600080fd5b50610461611def565b3480156108b057600080fd5b506104a3611f03565b3480156108c557600080fd5b50610478611f09565b3480156108da57600080fd5b506104a3611f0e565b3480156108ef57600080fd5b506104d0611f14565b34801561090457600080fd5b506104f2611f33565b34801561091957600080fd5b506104a3611f3c565b34801561092e57600080fd5b506104a3611f42565b34801561094357600080fd5b5061094c611f48565b6040516104859190616dbc565b34801561096557600080fd5b50610461610974366004615f75565b611f4d565b34801561098557600080fd5b50610478610994366004615db2565b6129b6565b3480156109a557600080fd5b506104786129c8565b3480156109ba57600080fd5b506109c36129d5565b60405161048591906161d0565b3480156109dc57600080fd5b50610478612ac0565b3480156109f157600080fd5b50610478612ac5565b348015610a0657600080fd5b50610478612acb565b348015610a1b57600080fd5b506104a3612ad0565b348015610a3057600080fd5b50610478612ad6565b348015610a4557600080fd5b506104d0610a54366004615fd1565b612adc565b348015610a6557600080fd5b50610478612ae9565b348015610a7a57600080fd5b50610478612aef565b348015610a8f57600080fd5b50610478612b2e565b348015610aa457600080fd5b506104a3612b34565b348015610ab957600080fd5b506104a3612b3a565b348015610ace57600080fd5b50610461612b40565b348015610ae357600080fd5b50610478612ce9565b348015610af857600080fd5b506104f2610b07366004615f36565b612cef565b348015610b1857600080fd5b50610461610b27366004615db2565b612e75565b610461610b3a366004615db2565b612f7d565b348015610b4b57600080fd5b50610478613333565b348015610b6057600080fd5b506104a3613339565b348015610b7557600080fd5b506104a361333f565b348015610b8a57600080fd5b50610b9e610b99366004615fd1565b613345565b60405161048593929190616d92565b348015610bb957600080fd5b506104a3613407565b6000610bcd33611daf565b9050600b8181548110610bdc57fe5b600091825260209091206001601690920201015460ff16610c185760405162461bcd60e51b8152600401610c0f90616a30565b60405180910390fd5b6000610c22612aef565b9050610c31338383600161340d565b505050565b60095481565b61200181565b60005460609060ff16610c675760405162461bcd60e51b8152600401610c0f90616443565b3361200014610c885760405162461bcd60e51b8152600401610c0f90616b42565b600b54610d4657610c9761595e565b60015460005b81811015610d4257600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794610d1e93600080516020616e7483398151915290910192019061598d565b506060820151610d349060038301906013615a07565b505050806001019050610c9d565b5050505b60405162461bcd60e51b8152600401610c0f90616695565b60075460ff1681565b600f5481565b334114610d8c5760405162461bcd60e51b8152600401610c0f90616b91565b3a15610daa5760405162461bcd60e51b8152600401610c0f9061696f565b8251604080518281526020808402820101909152606090828015610de857816020015b610dd5615a34565b815260200190600190039081610dcd5790505b50905060005b82811015610e92576040518060c00160405280878381518110610e0d57fe5b60200260200101516001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001868381518110610e4f57fe5b60200260200101516001600160401b031681526020016000151581526020016000815250828281518110610e7f57fe5b6020908102919091010152600101610dee565b50606080610ea083866135ff565b9150915060005b600154811015610f9657600060018281548110610ec057fe5b906000526020600020906004020160030154905080600014610f8d57600060018381548110610eeb57fe5b9060005260206000209060040201600301819055506120026001600160a01b031663092193ab8260018581548110610f1f57fe5b60009182526020909120600491820201546040516001600160e01b031960e086901b168152610f5a926001600160a01b03909216910161613e565b6000604051808303818588803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b50505050505b50600101610ea7565b504715611004577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051610fcc9190616d89565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015611002573d6000803e3d6000fd5b505b600060035581511561101a5761101a8282613ae9565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561105757600080fd5b505af115801561106b573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a150505050505050565b60035481565b61200581565b3361200214610d465760405162461bcd60e51b8152600401610c0f90616d43565b3341146110ed5760405162461bcd60e51b8152600401610c0f90616b91565b601054431161110e5760405162461bcd60e51b8152600401610c0f906165bf565b3a1561112c5760405162461bcd60e51b8152600401610c0f9061696f565b60005460ff1661114e5760405162461bcd60e51b8152600401610c0f90616443565b60006110023168056bc75e2d631000008111156111855761117e8168056bc75e2d6310000063ffffffff6142d816565b915061118c565b505061140d565b6040516309a99b4f60e41b815261100290639a99b4f0906111b39030908690600401616152565b602060405180830381600087803b1580156111cd57600080fd5b505af11580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190615fe9565b91508161121357505061140d565b6000805b848110156112415785858281811061122b57fe5b9050602002013582019150806001019050611217565b508061124f5750505061140d565b6000806000805b89811015611405578489898381811061126b57fe5b9050602002013588028161127b57fe5b0493508a8a8281811061128a57fe5b905060200201602081019061129f9190615db2565b6001600160a01b038116600090815260046020526040902054909350915081156113bb5760006001808403815481106112d457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561134157836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85866040516113349190616d89565b60405180910390a26113b5565b600354611354908663ffffffff61431a16565b600390815581015461136c908663ffffffff61431a16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906113ac908890616d89565b60405180910390a25b506113fd565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85856040516113f49190616d89565b60405180910390a25b600101611256565b505050505050505b5050436010555050565b600154600090821061142b575060006114e1565b60006001600160a01b03166001838154811061144357fe5b60009182526020909120600490910201546001600160a01b03161480611473575060085415806114735750600a54155b80611482575060085460095410155b806114935750611491826114e6565b155b806114bc57506000600b83815481106114a857fe5b906000526020600020906016020160000154115b806114d0575060016114cc6129d5565b5111155b156114dd575060006114e1565b5060015b919050565b60015460009082106114fa575060006114e1565b600b548210611537576001828154811061151057fe5b9060005260206000209060040201600201601c9054906101000a900460ff161590506114e1565b6001828154811061154457fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156115915750600b828154811061157857fe5b600091825260209091206001601690920201015460ff16155b92915050565b600b54611655576115a661595e565b60015460005b8181101561165157600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff191691151591909117905560408601518051879461162d93600080516020616e7483398151915290910192019061598d565b5060608201516116439060038301906013615a07565b5050508060010190506115ac565b5050505b336110011480611666575033612002145b6116825760405162461bcd60e51b8152600401610c0f9061647a565b6001600160a01b038116600090815260046020526040902054806116a657506116f9565b6001810390506000600b82815481106116bb57fe5b600091825260209091206001601690920201015460ff1690506116de838361433f565b80156116e75750805b15610c31576009805460001901905550505b50565b60015460609081906000805b8281101561174f576001818154811061171d57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611747576001909101905b600101611708565b5060608160405190808252806020026020018201604052801561177c578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156117b557816020015b60608152602001906001900390816117a05790505b50600b54600094509091508414156119305760005b8481101561192a57600181815481106117df57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611922576001818154811061180f57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061183a57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061186757fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156118ff5780601f106118d4576101008083540402835291602001916118ff565b820191906000526020600020905b8154815290600101906020018083116118e257829003601f168201915b505050505082858151811061191057fe5b60209081029190910101526001909301925b6001016117ca565b506119cc565b60005b848110156119ca576001818154811061194857fe5b9060005260206000209060040201600201601c9054906101000a900460ff166119c2576001818154811061197857fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106119a357fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611933565b505b909450925050505b9091565b61100181565b60085481565b603881565b6060806000600e549050600080600c5411611a05576015611a09565b600c545b905060c86060611a176129d5565b90506060611a2482614702565b905083825111611a3c5790955093506119d492505050565b84848351031015611a4e578382510394505b8415611a8e576000834381611a5f57fe5b049050611a7483838389890360008b8b614870565b611a8c8383838989038a8a038b8c8c8b510301614870565b505b606084604051908082528060200260200182016040528015611aba578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611af357816020015b6060815260200190600190039081611ade5790505b50905060005b86811015611b7457848181518110611b0d57fe5b6020026020010151838281518110611b2157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611b4d57fe5b6020026020010151828281518110611b6157fe5b6020908102919091010152600101611af9565b50909750955050505050509091565b60065481565b61200681565b61200081565b6001600160a01b03811660009081526004602052604081205480611bbd5760009150506114e1565b60001901611bca816114e6565b9392505050565b6001600160a01b03811660009081526004602052604081205480611bf95760009150506114e1565b600180820381548110611c0857fe5b906000526020600020906004020160030154915050919050565b60128181548110611c2f57fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815293509091830182828015611cc05780601f10611c9557610100808354040283529160200191611cc0565b820191906000526020600020905b815481529060010190602001808311611ca357829003601f168201915b505050505081565b60105481565b60018181548110611cdb57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b61100881565b6103e881565b600c5481565b61200381565b61271081565b3361200014610d465760405162461bcd60e51b8152600401610c0f90616b42565b60025481565b60115481565b60145460ff1681565b600a5481565b600060175460001415611da757506001611dac565b506017545b90565b6001600160a01b03811660009081526004602052604081205480611de55760405162461bcd60e51b8152600401610c0f90616aca565b6000190192915050565b600b54611ead57611dfe61595e565b60015460005b81811015611ea957600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794611e8593600080516020616e7483398151915290910192019061598d565b506060820151611e9b9060038301906013615a07565b505050806001019050611e04565b5050505b600854611eba5760036008555b600a54611ec7576002600a555b6000611ed233611daf565b9050611edd81611417565b611ef95760405162461bcd60e51b8152600401610c0f906168eb565b6116f933826149c7565b61100781565b600381565b61100681565b6040518061062001604052806105ef8152602001616e946105ef913981565b60005460ff1681565b61200281565b61300081565b600081565b60005460ff16611f6f5760405162461bcd60e51b8152600401610c0f90616443565b3361100714611f905760405162461bcd60e51b8152600401610c0f9061699d565b611ff084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b60208201529150614a5f9050565b156120a557602081146120155760405162461bcd60e51b8152600401610c0f906162a3565b604080516020601f840181900481028201810190925282815260009161205391858580838501838280828437600092019190915250614ab892505050565b905061271061207f601854612073600f548561431a90919063ffffffff16565b9063ffffffff61431a16565b111561209d5760405162461bcd60e51b8152600401610c0f906166b9565b600655612973565b61210f84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b60208201529150614a5f9050565b156121a957602081146121345760405162461bcd60e51b8152600401610c0f906162da565b604080516020601f840181900481028201810190925282815260009161217291858580838501838280828437600092019190915250614ab892505050565b600c5490915080612181575060155b8082106121a05760405162461bcd60e51b8152600401610c0f90616601565b50600855612973565b61221284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b60208201529150614a5f9050565b156122ab57602081146122375760405162461bcd60e51b8152600401610c0f906163c9565b604080516020601f840181900481028201810190925282815260009161227591858580838501838280828437600092019190915250614ab892505050565b90506000811180156122875750600a81105b6122a35760405162461bcd60e51b8152600401610c0f90616c26565b600a55612973565b61231f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e646964617465730000000000000060208201529150614a5f9050565b156123ae57602081146123445760405162461bcd60e51b8152600401610c0f9061637d565b604080516020601f840181900481028201810190925282815260009161238291858580838501838280828437600092019190915250614ab892505050565b9050600d548111156123a65760405162461bcd60e51b8152600401610c0f906167c2565b600e55612973565b61241784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b60208201529150614a5f9050565b15612499576020811461243c5760405162461bcd60e51b8152600401610c0f906169eb565b604080516020601f840181900481028201810190925282815260009161247a91858580838501838280828437600092019190915250614ab892505050565b600d819055600e5490915081101561249357600d54600e555b50612973565b6124fd84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b60208201529150614a5f9050565b1561262257602081146125225760405162461bcd60e51b8152600401610c0f9061640e565b604080516020601f840181900481028201810190925282815260009161256091858580838501838280828437600092019190915250614ab892505050565b9050600081116125825760405162461bcd60e51b8152600401610c0f90616577565b60006120026001600160a01b031663c473318f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125bf57600080fd5b505afa1580156125d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f79190615fe9565b9050808211156126195760405162461bcd60e51b8152600401610c0f90616320565b50600c55612973565b61268e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527473797374656d52657761726442617365526174696f60581b60208201529150614a5f9050565b1561273757602081146126b35760405162461bcd60e51b8152600401610c0f90616bde565b604080516020601f84018190048102820181019092528281526000916126f191858580838501838280828437600092019190915250614ab892505050565b90506127106127116018546120736006548561431a90919063ffffffff16565b111561272f5760405162461bcd60e51b8152600401610c0f906164e8565b600f55612973565b6127ab84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f73797374656d526577617264416e74694d4556526174696f000000000000000060208201529150614a5f9050565b1561285457602081146127d05760405162461bcd60e51b8152600401610c0f90616748565b604080516020601f840181900481028201810190925282815260009161280e91858580838501838280828437600092019190915250614ab892505050565b905061271061282e600f546120736006548561431a90919063ffffffff16565b111561284c5760405162461bcd60e51b8152600401610c0f9061685c565b601855612973565b6128b584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a8152690e8eae4dc98cadccee8d60b31b60208201529150614a5f9050565b1561295b57602081146128da5760405162461bcd60e51b8152600401610c0f9061665e565b604080516020601f840181900481028201810190925282815260009161291891858580838501838280828437600092019190915250614ab892505050565b90506003811015801561292c575060408111155b806129375750806001145b6129535760405162461bcd60e51b8152600401610c0f90616c83565b601755612973565b60405162461bcd60e51b8152600401610c0f90616cd3565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040516129a89493929190616271565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b82811015612a04576129f0816114e6565b156129fc578160010191505b6001016129df565b50606081604051908082528060200260200182016040528015612a31578160200160208202803683370190505b5090506000915060005b83811015612ab857612a4c816114e6565b15612ab05760018181548110612a5e57fe5b600091825260209091206004909102015482516001600160a01b0390911690839085908110612a8957fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612a3b565b509250505090565b601581565b61027181565b600281565b61100281565b60175481565b60138181548110611c2f57fe5b60185481565b6000612af96129d5565b519050600080600c5411612b0e576015612b12565b600c545b905080821115612b20578091505b81612b2a57600191505b5090565b60055481565b61100381565b61200481565b60005460ff1615612b635760405162461bcd60e51b8152600401610c0f90616a5c565b612b6b615a69565b6000612b916040518061062001604052806105ef8152602001616e946105ef9139614abd565b9150915080612bb25760405162461bcd60e51b8152600401610c0f90616b01565b60005b826020015151811015612cd757600183602001518281518110612bd457fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a090930151600390930192909255918601518051918501939185908110612caa57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612bb5565b50506000805460ff1916600117905550565b600d5481565b601354600090815b81811015612df857612de085858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601380549092508591508110612d4857fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b820191906000526020600020905b815481529060010190602001808311612db957829003601f168201915b5050505050614c79565b15612df057600192505050611591565b600101612cf7565b5060125460005b81811015612e6957612e5086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601280549092508591508110612d4857fe5b15612e615760019350505050611591565b600101612dff565b50600095945050505050565b3361100114612e965760405162461bcd60e51b8152600401610c0f90616cfa565b600b54612f5457612ea561595e565b60015460005b81811015612f5057600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794612f2c93600080516020616e7483398151915290910192019061598d565b506060820151612f429060038301906013615a07565b505050806001019050612eab565b5050505b6000612f5f82614cdd565b9050612f6a81611417565b15612f7957612f7982826149c7565b5050565b334114612f9c5760405162461bcd60e51b8152600401610c0f90616b91565b60005460ff16612fbe5760405162461bcd60e51b8152600401610c0f90616443565b60003411612fde5760405162461bcd60e51b8152600401610c0f90616793565b3a15612ffc5760405162461bcd60e51b8152600401610c0f9061696f565b6001600160a01b03811660009081526004602052604090205460145434919060ff1661303c57610271600f556103e86006556014805460ff191660011790555b600f54601754600110801561305357506000601854115b1561307857600160175403601754438161306957fe5b06601854028161307557fe5b04015b6000831180156130885750600081115b156131355760006130b16127106130a5348563ffffffff614e6016565b9063ffffffff614e9a16565b90508015613133576040516110029082156108fc029083906000818181858888f193505050501580156130e8573d6000803e3d6000fd5b507f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d816040516131189190616d89565b60405180910390a1613130848263ffffffff6142d816565b93505b505b60008311801561314757506000600654115b156131ed5760006131696127106130a560065434614e6090919063ffffffff16565b905080156131eb5760405161dead9082156108fc029083906000818181858888f193505050501580156131a0573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee5816040516131d09190616d89565b60405180910390a16131e8848263ffffffff6142d816565b93505b505b81156132eb57600060018084038154811061320457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561327157846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4856040516132649190616d89565b60405180910390a26132e5565b600354613284908563ffffffff61431a16565b600390815581015461329c908563ffffffff61431a16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055906132dc908790616d89565b60405180910390a25b5061332d565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4846040516133249190616d89565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b818154811061335257fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff909116949192918301828280156133fd5780601f106133d2576101008083540402835291602001916133fd565b820191906000526020600020905b8154815290600101906020018083116133e057829003601f168201915b5050505050905083565b61100481565b6000600a546000148061341e575082155b806134295750600954155b15613436575060006135f7565b60096000815460019003919050819055506000613481600a546130a5866130a5600b8a8154811061346357fe5b6000918252602090912060169091020154439063ffffffff6142d816565b90506000600b868154811061349257fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b1580156134f757600080fd5b505afa15801561350b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352f9190616001565b91509150600093508083106135ad57613548888861433f565b506040516328aa02b160e01b8152611001906328aa02b190613572908b9087908a906004016161ad565b600060405180830381600087803b15801561358c57600080fd5b505af11580156135a0573d6000803e3d6000fd5b50505050600193506135bf565b8183106135bf576135bd88614cdd565b505b6040516001600160a01b038916907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050505b949350505050565b606080600080808080613610612aef565b6001549091505b801561384257600181039250600b838154811061363057fe5b600091825260209091206001601690920201015460ff1661365057613839565b6001838154811061365d57fe5b600091825260208220600490910201546001600160a01b031695506136879086908590859061340d565b93508361369357613839565b60405163436aa28360e11b81526000908190612002906386d54506906136bd908a9060040161613e565b60206040518083038186803b1580156136d557600080fd5b505afa1580156136e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370d9190615dce565b90506001600160a01b03811615613796576040516302ceee9160e11b81526120029063059ddd229061374390849060040161613e565b60206040518083038186803b15801561375b57600080fd5b505afa15801561376f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137939190615dce565b91505b60005b8c5181101561383557876001600160a01b03168d82815181106137b857fe5b6020026020010151600001516001600160a01b031614806138015750826001600160a01b03168d82815181106137ea57fe5b6020026020010151600001516001600160a01b0316145b1561382d5760018d828151811061381457fe5b6020908102919091010151901515608090910152613835565b600101613799565b5050505b60001901613617565b5060005b89518110156138af5789818151811061385b57fe5b6020026020010151608001518061389b575060006001600160a01b03168a828151811061388457fe5b6020026020010151600001516001600160a01b0316145b156138a7578560010195505b600101613846565b50885185106139975760408051600180825281830190925290816020015b6138d5615a34565b8152602001906001900390816138cd575050604080516001808252818301909252919850602082015b60608152602001906001900390816138fe5790505095508860008151811061392257fe5b60200260200101518760008151811061393757fe5b60200260200101819052508760008151811061394f57fe5b60200260200101518660008151811061396457fe5b602002602001018190525060008760008151811061397e57fe5b6020908102919091010151901515608090910152613adc565b848951036040519080825280602002602001820160405280156139d457816020015b6139c1615a34565b8152602001906001900390816139b95790505b50965084895103604051908082528060200260200182016040528015613a0e57816020015b60608152602001906001900390816139f95790505b5095506000915060005b8951811015613ada57898181518110613a2d57fe5b602002602001015160800151158015613a70575060006001600160a01b03168a8281518110613a5857fe5b6020026020010151600001516001600160a01b031614155b15613ad257898181518110613a8157fe5b6020026020010151888481518110613a9557fe5b6020026020010181905250888181518110613aac57fe5b6020026020010151878481518110613ac057fe5b60200260200101819052508260010192505b600101613a18565b505b50505050505b9250929050565b600154825160005b82811015613c06576001613b03615a34565b60018381548110613b1057fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015613bda57878181518110613ba057fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415613bd25760009250613bda565b600101613b8c565b508115613bfc5780516001600160a01b03166000908152600460205260408120555b5050600101613af1565b5080821115613cc557805b82811015613cc3576001805480613c2457fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b805480613c7757fe5b60008281526020812060166000199093019283020181815560018101805460ff1916905590613ca96002830182615a8d565b613cb7600383016000615ad1565b50509055600101613c11565b505b6000818310613cd45781613cd6565b825b905060005b8181101561407a57613d88868281518110613cf257fe5b602002602001015160018381548110613d0757fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152614edc565b613f3c578060010160046000888481518110613da057fe5b6020026020010151600001516001600160a01b03166001600160a01b0316815260200190815260200160002081905550858181518110613ddc57fe5b602002602001015160018281548110613df157fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a0909101516003909101558451859082908110613eac57fe5b6020026020010151600b8281548110613ec157fe5b90600052602060002090601602016002019080519060200190613ee592919061598d565b506000600b8281548110613ef557fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b805483908110613f2657fe5b6000918252602090912060169091020155614072565b858181518110613f4857fe5b60200260200101516060015160018281548110613f6157fe5b906000526020600020906004020160020160146101000a8154816001600160401b0302191690836001600160401b03160217905550614027858281518110613fa557fe5b6020026020010151600b8381548110613fba57fe5b600091825260209182902060026016909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b6140725784818151811061403757fe5b6020026020010151600b828154811061404c57fe5b9060005260206000209060160201600201908051906020019061407092919061598d565b505b600101613cdb565b50828211156142525761408b61595e565b835b8381101561424f578581815181106140a157fe5b6020026020010151826040018190525060018782815181106140bf57fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616e548339815191528101918255858301516000805160206174838339815191528201805491151560ff19909216919091179055928501518051869492936141f593600080516020616e748339815191520192019061598d565b50606082015161420b9060038301906013615a07565b505050806001016004600089848151811061422257fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161408d565b50505b61425a614f38565b61426261511a565b6000600981905560015493505b838110156142d0576000600b828154811061428657fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106142b757fe5b600091825260209091206016909102015560010161426f565b505050505050565b6000611bca83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615308565b600082820183811015611bca5760405162461bcd60e51b8152600401610c0f906164b1565b6000806001838154811061434f57fe5b906000526020600020906004020160030154905060006001808054905003905060016143796129d5565b51116143ae5760006001858154811061438e57fe5b906000526020600020906004020160030181905550600092505050611591565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516143e79190616d89565b60405180910390a26001600160a01b038516600090815260046020526040812055835b600154600019018110156145d4576001816001018154811061442857fe5b90600052602060002090600402016001828154811061444357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b80549091830190811061450457fe5b9060005260206000209060160201600b828154811061451f57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614576938386019390821615610100026000190190911604615ae0565b5061458960038281019084016013615b55565b509050508060010160046000600184815481106145a257fe5b600091825260208083206004909202909101546001600160a01b0316835282019290925260400190205560010161440a565b5060018054806145e057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061463357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906146656002830182615a8d565b614673600383016000615ad1565b50509055600081838161468257fe5b04905080156146f65760015460005b818110156146f3576146ca83600183815481106146aa57fe5b90600052602060002090600402016003015461431a90919063ffffffff16565b600182815481106146d757fe5b6000918252602090912060036004909202010155600101614691565b50505b50600195945050505050565b60015481516040805182815260208084028201019091526060929190839082801561474157816020015b606081526020019060019003908161472c5790505b50600b5490915083146147585792506114e1915050565b60005b8281101561486757600b60016004600089858151811061477757fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205403815481106147ab57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156148435780601f1061481857610100808354040283529160200191614843565b820191906000526020600020905b81548152906001019060200180831161482657829003601f168201915b505050505082828151811061485457fe5b602090810291909101015260010161475b565b50949350505050565b60005b828110156149bd5760008287838801604051602001614893929190616130565b6040516020818303038152906040528051906020012060001c816148b357fe5b069050808501828701146149b457600089838801815181106148d157fe5b60200260200101519050606089848901815181106148eb57fe5b602002602001015190508a8388018151811061490357fe5b60200260200101518b858a018151811061491957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b8489018151811061494857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061497657fe5b60200260200101518a858a018151811061498c57fe5b6020026020010181905250808a848901815181106149a657fe5b602002602001018190525050505b50600101614873565b5050505050505050565b600980546001908101909155600b8054839081106149e157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b8281548110614a1757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b600081604051602001614a729190616114565b6040516020818303038152906040528051906020012083604051602001614a999190616114565b6040516020818303038152906040528051906020012014905092915050565b015190565b614ac5615a69565b6000614acf615a69565b614ad7615b7f565b614ae8614ae386615334565b615359565b90506000805b614af7836153a3565b15614c6b5780614b1c57614b12614b0d846153c4565b615412565b60ff168452614c63565b8060011415614c5e576060614b38614b33856153c4565b615492565b90508051604051908082528060200260200182016040528015614b7557816020015b614b62615a34565b815260200190600190039081614b5a5790505b5085602001819052508051604051908082528060200260200182016040528015614bb357816020015b6060815260200190600190039081614b9e5790505b50604086015260005b8151811015614c5357614bcd615a34565b60606000614bed858581518110614be057fe5b6020026020010151615563565b92509250925080614c0d578860009a509a50505050505050505050614c74565b8289602001518581518110614c1e57fe5b60200260200101819052508189604001518581518110614c3a57fe5b6020026020010181905250505050806001019050614bbc565b506001925050614c63565b614c6b565b600101614aee565b50919350909150505b915091565b815181516000916001918114808314614c955760009250614cd3565b600160208701838101602088015b600284838510011415614cce578051835114614cc25760009650600093505b60209283019201614ca3565b505050505b5090949350505050565b6001600160a01b03811660009081526004602052604081205480614d06575060001990506114e1565b600181039050600060018281548110614d1b57fe5b9060005260206000209060040201600301549050600060018381548110614d3e57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614d97908590616d89565b60405180910390a280614daf578293505050506114e1565b6000818381614dba57fe5b0490508015614e565760005b84811015614e0857614ddf82600183815481106146aa57fe5b60018281548110614dec57fe5b6000918252602090912060036004909202010155600101614dc6565b50600180549085015b81811015614e5357614e2a83600183815481106146aa57fe5b60018281548110614e3757fe5b6000918252602090912060036004909202010155600101614e11565b50505b5091949350505050565b600082614e6f57506000611591565b82820282848281614e7c57fe5b0414611bca5760405162461bcd60e51b8152600401610c0f9061692e565b6000611bca83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061567d565b805182516000916001600160a01b039182169116148015614f16575081602001516001600160a01b031683602001516001600160a01b0316145b8015611bca5750506040908101519101516001600160a01b0390811691161490565b60125460135480821115614f8357805b82811015614f81576012805480614f5b57fe5b600190038181906000526020600020016000614f779190615a8d565b9055600101614f48565b505b6000818310614f925781614f94565b825b905060005b818110156150ac5761505160128281548110614fb157fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561503f5780601f106150145761010080835404028352916020019161503f565b820191906000526020600020905b81548152906001019060200180831161502257829003601f168201915b505050505060138381548110612d4857fe5b6150a4576013818154811061506257fe5b906000526020600020016012828154811061507957fe5b9060005260206000200190805460018160011615610100020316600290046150a2929190615ae0565b505b600101614f99565b5082821115610c3157825b8281101561332d576012601382815481106150ce57fe5b6000918252602080832084546001818101875595855291909320929091018054615111949390920192909160026101009282161592909202600019011604615ae0565b506001016150b7565b601354600b548082111561516557805b8281101561516357601380548061513d57fe5b6001900381819060005260206000200160006151599190615a8d565b905560010161512a565b505b60008183106151745781615176565b825b905060005b81811015615295576152336013828154811061519357fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156152215780601f106151f657610100808354040283529160200191615221565b820191906000526020600020905b81548152906001019060200180831161520457829003601f168201915b5050505050600b8381548110613fba57fe5b61528d57600b818154811061524457fe5b90600052602060002090601602016002016013828154811061526257fe5b90600052602060002001908054600181600116156101000203166002900461528b929190615ae0565b505b60010161517b565b5082821115610c3157825b8281101561332d576013600b82815481106152b757fe5b6000918252602080832084546001808201875595855291909320601692909202909201600290810180546152ff95939094019390926000199082161561010002011604615ae0565b506001016152a0565b6000818484111561532c5760405162461bcd60e51b8152600401610c0f919061625e565b505050900390565b61533c615b9f565b506040805180820190915281518152602082810190820152919050565b615361615b7f565b61536a826156b4565b61537357600080fd5b600061538283602001516156ee565b60208085015160408051808201909152868152920190820152915050919050565b60006153ad615b9f565b505080518051602091820151919092015191011190565b6153cc615b9f565b6153d5826153a3565b6153de57600080fd5b602082015160006153ee82615751565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061542757508151602110155b61543057600080fd5b600061543f83602001516156ee565b905080836000015110156154655760405162461bcd60e51b8152600401610c0f90616a93565b82516020808501518301805192849003929183101561486757506020919091036101000a90049392505050565b606061549d826156b4565b6154a657600080fd5b60006154b183615832565b90506060816040519080825280602002602001820160405280156154ef57816020015b6154dc615b9f565b8152602001906001900390816154d45790505b509050600061550185602001516156ee565b60208601510190506000805b848110156155585761551e83615751565b915060405180604001604052808381526020018481525084828151811061554157fe5b60209081029190910101529181019160010161550d565b509195945050505050565b61556b615a34565b60606000615577615a34565b6060615581615b7f565b61558a87615359565b90506000805b615599836153a3565b1561566e57806155c4576155b46155af846153c4565b61588e565b6001600160a01b03168552615666565b80600114156155ec576155d96155af846153c4565b6001600160a01b03166020860152615666565b8060021415615614576156016155af846153c4565b6001600160a01b03166040860152615666565b806003141561564057615629614b0d846153c4565b6001600160401b0316606086015260019150615666565b80600414156156615761565a615655846153c4565b6158a8565b9350615666565b61566e565b600101615590565b50929791965091945092505050565b6000818361569e5760405162461bcd60e51b8152600401610c0f919061625e565b5060008385816156aa57fe5b0495945050505050565b80516000906156c5575060006114e1565b6020820151805160001a9060c08210156156e4576000925050506114e1565b5060019392505050565b8051600090811a60808110156157085760009150506114e1565b60b8811080615723575060c08110801590615723575060f881105b156157325760019150506114e1565b60c08110156157465760b5190190506114e1565b60f5190190506114e1565b80516000908190811a608081101561576c576001915061582b565b60b881101561578157607e198101915061582b565b60c08110156157d257600060b78203600186019550806020036101000a8651049150600181018201935050808310156157cc5760405162461bcd60e51b8152600401610c0f90616831565b5061582b565b60f88110156157e75760be198101915061582b565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158295760405162461bcd60e51b8152600401610c0f90616831565b505b5092915050565b8051600090615843575060006114e1565b6000809050600061585784602001516156ee565b602085015185519181019250015b808210156158855761587682615751565b82019150826001019250615865565b50909392505050565b805160009060151461589f57600080fd5b61159182615412565b80516060906158b657600080fd5b60006158c583602001516156ee565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156158fc576020820181803683370190505b50905060008160200190506148678487602001510182858061591d57610c31565b5b6020811061593d578251825260209283019290910190601f190161591e565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615988615bb9565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106159ce57805160ff19168380011785556159fb565b828001600101855582156159fb579182015b828111156159fb5782518255916020019190600101906159e0565b50612b2a929150615bd8565b82601381019282156159fb57916020028201828111156159fb5782518255916020019190600101906159e0565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518060600160405280600060ff16815260200160608152602001606081525090565b50805460018160011615610100020316600290046000825580601f10615ab357506116f9565b601f0160209004906000526020600020908101906116f99190615bd8565b506116f9906013810190615bd8565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615b1957805485556159fb565b828001600101855582156159fb57600052602060002091601f016020900482015b828111156159fb578254825591600101919060010190615b3a565b82601381019282156159fb57918201828111156159fb578254825591600101919060010190615b3a565b6040518060400160405280615b92615b9f565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b611dac91905b80821115612b2a5760008155600101615bde565b803561159181616e3e565b60008083601f840112615c0e578182fd5b5081356001600160401b03811115615c24578182fd5b6020830191508360208083028501011115613ae257600080fd5b6000601f8381840112615c4f578182fd5b8235615c62615c5d82616df3565b616dcd565b818152925060208084019085810160005b84811015615cf4578135880189603f820112615c8e57600080fd5b838101356001600160401b03811115615ca657600080fd5b615cb7818901601f19168601616dcd565b81815260408c81848601011115615ccd57600080fd5b82818501888401375060009181018601919091528552509282019290820190600101615c73565b50505050505092915050565b600082601f830112615d10578081fd5b8135615d1e615c5d82616df3565b818152915060208083019084810181840286018201871015615d3f57600080fd5b6000805b85811015615cf45782356001600160401b0381168114615d61578283fd5b85529383019391830191600101615d43565b60008083601f840112615d84578182fd5b5081356001600160401b03811115615d9a578182fd5b602083019150836020828501011115613ae257600080fd5b600060208284031215615dc3578081fd5b8135611bca81616e3e565b600060208284031215615ddf578081fd5b8151611bca81616e3e565b60008060008060408587031215615dff578283fd5b84356001600160401b0380821115615e15578485fd5b615e2188838901615bfd565b90965094506020870135915080821115615e39578384fd5b50615e4687828801615bfd565b95989497509550505050565b600080600060608486031215615e66578283fd5b83356001600160401b0380821115615e7c578485fd5b81860187601f820112615e8d578586fd5b80359250615e9d615c5d84616df3565b80848252602080830192508084018b828389028701011115615ebd57898afd5b8994505b86851015615ee757615ed38c82615bf2565b845260019490940193928101928101615ec1565b509097508801359350505080821115615efe578384fd5b615f0a87838801615d00565b93506040860135915080821115615f1f578283fd5b50615f2c86828701615c3e565b9150509250925092565b60008060208385031215615f48578182fd5b82356001600160401b03811115615f5d578283fd5b615f6985828601615d73565b90969095509350505050565b60008060008060408587031215615f8a578384fd5b84356001600160401b0380821115615fa0578586fd5b615fac88838901615d73565b90965094506020870135915080821115615fc4578384fd5b50615e4687828801615d73565b600060208284031215615fe2578081fd5b5035919050565b600060208284031215615ffa578081fd5b5051919050565b60008060408385031215616013578182fd5b505080516020909101519092909150565b600080600060408486031215616038578081fd5b833560ff81168114616048578182fd5b925060208401356001600160401b03811115616062578182fd5b61606e86828701615d73565b9497909650939450505050565b6000815180845260208085019450808401835b838110156160b35781516001600160a01b03168752958201959082019060010161608e565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452616100816020860160208601616e12565b601f01601f19169290920160200192915050565b60008251616126818460208701616e12565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b600060208252611bca602083018461607b565b6000604082526161f6604083018561607b565b602083820381850152818551808452828401915082838202850101838801865b8381101561624457601f198784030185526162328383516160e8565b94860194925090850190600101616216565b50909998505050505050505050565b901515815260200190565b600060208252611bca60208301846160e8565b6000604082526162856040830186886160be565b82810360208401526162988185876160be565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526038908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e206d6178456c656374656456616c696461746f72730000000000000000606082015260800190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601f908201527f6f6e6c7920736c617368206f72207374616b6548756220636f6e747261637400604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526063908201527f7468652073797374656d52657761726442617365526174696f20706c7573206260408201527f75726e526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252601d908201527f6c656e677468206f66207475726e4c656e677468206d69736d61746368000000604082015260600190565b6020808252600a908201526919195c1c9958d85d195960b21b604082015260600190565b60208082526063908201527f746865206275726e526174696f20706c75732073797374656d5265776172644260408201527f617365526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b6020808252602b908201527f6c656e677468206f662073797374656d526577617264416e74694d455652617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526063908201527f7468652073797374656d526577617264416e74694d4556526174696f20706c7560408201527f73206275726e526174696f20616e642073797374656d5265776172644261736560608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b60208082526028908201527f6c656e677468206f662073797374656d52657761726442617365526174696f206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b60208082526030908201527f746865207475726e4c656e6774682073686f756c6420626520696e205b332c3660408201526f345d206f7220657175616c20746f203160801b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b6020808252601f908201527f746865206d73672073656e646572206d757374206265207374616b6548756200604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152616db360608301846160e8565b95945050505050565b63ffffffff91909116815260200190565b6040518181016001600160401b0381118282101715616deb57600080fd5b604052919050565b60006001600160401b03821115616e08578081fd5b5060209081020190565b60005b83811015616e2d578181015183820152602001616e15565b8381111561332d5750506000910152565b6001600160a01b03811681146116f957600080fdfe0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbbf905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a20000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa164736f6c6343000604000a
Deployed Bytecode
0x6080604052600436106104405760003560e01c80638b5ad0c911610234578063c81b16621161012e578063e1c7392a116100b6578063f92eb86b1161007a578063f92eb86b14610b3f578063f9a2bbc714610b54578063fccc281314610b69578063fd4ad81f14610b7e578063fd6a687914610bad57610447565b8063e1c7392a14610ac2578063e40716a114610ad7578063ea321e4914610aec578063eb57e20214610b0c578063f340fa0114610b2c57610447565b8063d58918ae116100fd578063d58918ae14610a59578063d68fb56a14610a6e578063daacdb6614610a83578063dc927faf14610a98578063df8079e914610aad57610447565b8063c81b166214610a0f578063c8509d81146107e6578063cb75a59214610a24578063ce910b0c14610a3957610447565b8063aa82dce1116101bc578063aef198a911610180578063aef198a914610999578063b7ab4db5146109ae578063b8cf4ef1146109d0578063c466689d146109e5578063c6d33945146109fa57610447565b8063aa82dce11461090d578063aad5606314610922578063ab51bb9614610937578063ac43175114610959578063ad3c9da61461097957610447565b80639dc09262116102035780639dc09262146108a45780639fe0f816146108b9578063a1a11bf5146108ce578063a5422d5c146108e3578063a78abc16146108f857610447565b80638b5ad0c9146108455780638c5d749d1461085a5780638d19a4101461086f5780639369d7de1461088f57610447565b80634df6e0c3116103455780636e47b482116102cd578063820dcaa811610291578063820dcaa8146107d1578063831d65d1146107e6578063862498821461080657806388b32f111461081b5780638a7beb011461083057610447565b80636e47b4821461076857806375d47a0a1461077d57806378dfed4a146107925780637a84ca2a146107a75780637e434d54146107bc57610447565b806355614fcc1161031457806355614fcc146106c1578063565c56b3146106e157806360eba4fe1461070157806362b72cf5146107215780636969a25c1461073657610447565b80634df6e0c31461066d5780635192c82c1461068257806351b4dce31461069757806351e80672146106ac57610447565b80632a0ffb6e116103c857806335409f7f1161039757806335409f7f146105de5780633b071dcc146105fe57806343756e5c1461062157806345cf9daf14610636578063493279b11461064b57610447565b80632a0ffb6e1461055e578063300c35671461057e578063321d398a1461059e5780633365af3a146105be57610447565b8063152ad3b81161040f578063152ad3b8146104dd5780631bd14ed8146104ff5780631e4c1524146105145780631ff1806914610534578063280870281461054957610447565b806304c4fec61461044c57806307a56847146104635780630e2374a51461048e5780631182b875146104b057610447565b3661044757005b600080fd5b34801561045857600080fd5b50610461610bc2565b005b34801561046f57600080fd5b50610478610c36565b6040516104859190616d89565b60405180910390f35b34801561049a57600080fd5b506104a3610c3c565b604051610485919061613e565b3480156104bc57600080fd5b506104d06104cb366004616024565b610c42565b604051610485919061625e565b3480156104e957600080fd5b506104f2610d5e565b6040516104859190616253565b34801561050b57600080fd5b50610478610d67565b34801561052057600080fd5b5061046161052f366004615e52565b610d6d565b34801561054057600080fd5b506104786110a1565b34801561055557600080fd5b506104a36110a7565b34801561056a57600080fd5b50610461610579366004615db2565b6110ad565b34801561058a57600080fd5b50610461610599366004615dea565b6110ce565b3480156105aa57600080fd5b506104f26105b9366004615fd1565b611417565b3480156105ca57600080fd5b506104f26105d9366004615fd1565b6114e6565b3480156105ea57600080fd5b506104616105f9366004615db2565b611597565b34801561060a57600080fd5b506106136116fc565b6040516104859291906161e3565b34801561062d57600080fd5b506104a36119d8565b34801561064257600080fd5b506104786119de565b34801561065757600080fd5b506106606119e4565b6040516104859190616d7a565b34801561067957600080fd5b506106136119e9565b34801561068e57600080fd5b50610478611b83565b3480156106a357600080fd5b506104a3611b89565b3480156106b857600080fd5b506104a3611b8f565b3480156106cd57600080fd5b506104f26106dc366004615db2565b611b95565b3480156106ed57600080fd5b506104786106fc366004615db2565b611bd1565b34801561070d57600080fd5b506104d061071c366004615fd1565b611c22565b34801561072d57600080fd5b50610478611cc8565b34801561074257600080fd5b50610756610751366004615fd1565b611cce565b6040516104859695949392919061616b565b34801561077457600080fd5b506104a3611d32565b34801561078957600080fd5b506104a3611d38565b34801561079e57600080fd5b50610478611d3e565b3480156107b357600080fd5b50610478611d44565b3480156107c857600080fd5b506104a3611d4a565b3480156107dd57600080fd5b50610478611d50565b3480156107f257600080fd5b50610461610801366004616024565b611d56565b34801561081257600080fd5b50610478611d77565b34801561082757600080fd5b50610478611d7d565b34801561083c57600080fd5b506104f2611d83565b34801561085157600080fd5b50610478611d8c565b34801561086657600080fd5b50610478611d92565b34801561087b57600080fd5b5061047861088a366004615db2565b611daf565b34801561089b57600080fd5b50610461611def565b3480156108b057600080fd5b506104a3611f03565b3480156108c557600080fd5b50610478611f09565b3480156108da57600080fd5b506104a3611f0e565b3480156108ef57600080fd5b506104d0611f14565b34801561090457600080fd5b506104f2611f33565b34801561091957600080fd5b506104a3611f3c565b34801561092e57600080fd5b506104a3611f42565b34801561094357600080fd5b5061094c611f48565b6040516104859190616dbc565b34801561096557600080fd5b50610461610974366004615f75565b611f4d565b34801561098557600080fd5b50610478610994366004615db2565b6129b6565b3480156109a557600080fd5b506104786129c8565b3480156109ba57600080fd5b506109c36129d5565b60405161048591906161d0565b3480156109dc57600080fd5b50610478612ac0565b3480156109f157600080fd5b50610478612ac5565b348015610a0657600080fd5b50610478612acb565b348015610a1b57600080fd5b506104a3612ad0565b348015610a3057600080fd5b50610478612ad6565b348015610a4557600080fd5b506104d0610a54366004615fd1565b612adc565b348015610a6557600080fd5b50610478612ae9565b348015610a7a57600080fd5b50610478612aef565b348015610a8f57600080fd5b50610478612b2e565b348015610aa457600080fd5b506104a3612b34565b348015610ab957600080fd5b506104a3612b3a565b348015610ace57600080fd5b50610461612b40565b348015610ae357600080fd5b50610478612ce9565b348015610af857600080fd5b506104f2610b07366004615f36565b612cef565b348015610b1857600080fd5b50610461610b27366004615db2565b612e75565b610461610b3a366004615db2565b612f7d565b348015610b4b57600080fd5b50610478613333565b348015610b6057600080fd5b506104a3613339565b348015610b7557600080fd5b506104a361333f565b348015610b8a57600080fd5b50610b9e610b99366004615fd1565b613345565b60405161048593929190616d92565b348015610bb957600080fd5b506104a3613407565b6000610bcd33611daf565b9050600b8181548110610bdc57fe5b600091825260209091206001601690920201015460ff16610c185760405162461bcd60e51b8152600401610c0f90616a30565b60405180910390fd5b6000610c22612aef565b9050610c31338383600161340d565b505050565b60095481565b61200181565b60005460609060ff16610c675760405162461bcd60e51b8152600401610c0f90616443565b3361200014610c885760405162461bcd60e51b8152600401610c0f90616b42565b600b54610d4657610c9761595e565b60015460005b81811015610d4257600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794610d1e93600080516020616e7483398151915290910192019061598d565b506060820151610d349060038301906013615a07565b505050806001019050610c9d565b5050505b60405162461bcd60e51b8152600401610c0f90616695565b60075460ff1681565b600f5481565b334114610d8c5760405162461bcd60e51b8152600401610c0f90616b91565b3a15610daa5760405162461bcd60e51b8152600401610c0f9061696f565b8251604080518281526020808402820101909152606090828015610de857816020015b610dd5615a34565b815260200190600190039081610dcd5790505b50905060005b82811015610e92576040518060c00160405280878381518110610e0d57fe5b60200260200101516001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001868381518110610e4f57fe5b60200260200101516001600160401b031681526020016000151581526020016000815250828281518110610e7f57fe5b6020908102919091010152600101610dee565b50606080610ea083866135ff565b9150915060005b600154811015610f9657600060018281548110610ec057fe5b906000526020600020906004020160030154905080600014610f8d57600060018381548110610eeb57fe5b9060005260206000209060040201600301819055506120026001600160a01b031663092193ab8260018581548110610f1f57fe5b60009182526020909120600491820201546040516001600160e01b031960e086901b168152610f5a926001600160a01b03909216910161613e565b6000604051808303818588803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b50505050505b50600101610ea7565b504715611004577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051610fcc9190616d89565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015611002573d6000803e3d6000fd5b505b600060035581511561101a5761101a8282613ae9565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561105757600080fd5b505af115801561106b573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a150505050505050565b60035481565b61200581565b3361200214610d465760405162461bcd60e51b8152600401610c0f90616d43565b3341146110ed5760405162461bcd60e51b8152600401610c0f90616b91565b601054431161110e5760405162461bcd60e51b8152600401610c0f906165bf565b3a1561112c5760405162461bcd60e51b8152600401610c0f9061696f565b60005460ff1661114e5760405162461bcd60e51b8152600401610c0f90616443565b60006110023168056bc75e2d631000008111156111855761117e8168056bc75e2d6310000063ffffffff6142d816565b915061118c565b505061140d565b6040516309a99b4f60e41b815261100290639a99b4f0906111b39030908690600401616152565b602060405180830381600087803b1580156111cd57600080fd5b505af11580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190615fe9565b91508161121357505061140d565b6000805b848110156112415785858281811061122b57fe5b9050602002013582019150806001019050611217565b508061124f5750505061140d565b6000806000805b89811015611405578489898381811061126b57fe5b9050602002013588028161127b57fe5b0493508a8a8281811061128a57fe5b905060200201602081019061129f9190615db2565b6001600160a01b038116600090815260046020526040902054909350915081156113bb5760006001808403815481106112d457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561134157836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85866040516113349190616d89565b60405180910390a26113b5565b600354611354908663ffffffff61431a16565b600390815581015461136c908663ffffffff61431a16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906113ac908890616d89565b60405180910390a25b506113fd565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85856040516113f49190616d89565b60405180910390a25b600101611256565b505050505050505b5050436010555050565b600154600090821061142b575060006114e1565b60006001600160a01b03166001838154811061144357fe5b60009182526020909120600490910201546001600160a01b03161480611473575060085415806114735750600a54155b80611482575060085460095410155b806114935750611491826114e6565b155b806114bc57506000600b83815481106114a857fe5b906000526020600020906016020160000154115b806114d0575060016114cc6129d5565b5111155b156114dd575060006114e1565b5060015b919050565b60015460009082106114fa575060006114e1565b600b548210611537576001828154811061151057fe5b9060005260206000209060040201600201601c9054906101000a900460ff161590506114e1565b6001828154811061154457fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156115915750600b828154811061157857fe5b600091825260209091206001601690920201015460ff16155b92915050565b600b54611655576115a661595e565b60015460005b8181101561165157600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff191691151591909117905560408601518051879461162d93600080516020616e7483398151915290910192019061598d565b5060608201516116439060038301906013615a07565b5050508060010190506115ac565b5050505b336110011480611666575033612002145b6116825760405162461bcd60e51b8152600401610c0f9061647a565b6001600160a01b038116600090815260046020526040902054806116a657506116f9565b6001810390506000600b82815481106116bb57fe5b600091825260209091206001601690920201015460ff1690506116de838361433f565b80156116e75750805b15610c31576009805460001901905550505b50565b60015460609081906000805b8281101561174f576001818154811061171d57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611747576001909101905b600101611708565b5060608160405190808252806020026020018201604052801561177c578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156117b557816020015b60608152602001906001900390816117a05790505b50600b54600094509091508414156119305760005b8481101561192a57600181815481106117df57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611922576001818154811061180f57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061183a57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061186757fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156118ff5780601f106118d4576101008083540402835291602001916118ff565b820191906000526020600020905b8154815290600101906020018083116118e257829003601f168201915b505050505082858151811061191057fe5b60209081029190910101526001909301925b6001016117ca565b506119cc565b60005b848110156119ca576001818154811061194857fe5b9060005260206000209060040201600201601c9054906101000a900460ff166119c2576001818154811061197857fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106119a357fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611933565b505b909450925050505b9091565b61100181565b60085481565b603881565b6060806000600e549050600080600c5411611a05576015611a09565b600c545b905060c86060611a176129d5565b90506060611a2482614702565b905083825111611a3c5790955093506119d492505050565b84848351031015611a4e578382510394505b8415611a8e576000834381611a5f57fe5b049050611a7483838389890360008b8b614870565b611a8c8383838989038a8a038b8c8c8b510301614870565b505b606084604051908082528060200260200182016040528015611aba578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611af357816020015b6060815260200190600190039081611ade5790505b50905060005b86811015611b7457848181518110611b0d57fe5b6020026020010151838281518110611b2157fe5b60200260200101906001600160a01b031690816001600160a01b031681525050838181518110611b4d57fe5b6020026020010151828281518110611b6157fe5b6020908102919091010152600101611af9565b50909750955050505050509091565b60065481565b61200681565b61200081565b6001600160a01b03811660009081526004602052604081205480611bbd5760009150506114e1565b60001901611bca816114e6565b9392505050565b6001600160a01b03811660009081526004602052604081205480611bf95760009150506114e1565b600180820381548110611c0857fe5b906000526020600020906004020160030154915050919050565b60128181548110611c2f57fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815293509091830182828015611cc05780601f10611c9557610100808354040283529160200191611cc0565b820191906000526020600020905b815481529060010190602001808311611ca357829003601f168201915b505050505081565b60105481565b60018181548110611cdb57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b61100881565b6103e881565b600c5481565b61200381565b61271081565b3361200014610d465760405162461bcd60e51b8152600401610c0f90616b42565b60025481565b60115481565b60145460ff1681565b600a5481565b600060175460001415611da757506001611dac565b506017545b90565b6001600160a01b03811660009081526004602052604081205480611de55760405162461bcd60e51b8152600401610c0f90616aca565b6000190192915050565b600b54611ead57611dfe61595e565b60015460005b81811015611ea957600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794611e8593600080516020616e7483398151915290910192019061598d565b506060820151611e9b9060038301906013615a07565b505050806001019050611e04565b5050505b600854611eba5760036008555b600a54611ec7576002600a555b6000611ed233611daf565b9050611edd81611417565b611ef95760405162461bcd60e51b8152600401610c0f906168eb565b6116f933826149c7565b61100781565b600381565b61100681565b6040518061062001604052806105ef8152602001616e946105ef913981565b60005460ff1681565b61200281565b61300081565b600081565b60005460ff16611f6f5760405162461bcd60e51b8152600401610c0f90616443565b3361100714611f905760405162461bcd60e51b8152600401610c0f9061699d565b611ff084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b60208201529150614a5f9050565b156120a557602081146120155760405162461bcd60e51b8152600401610c0f906162a3565b604080516020601f840181900481028201810190925282815260009161205391858580838501838280828437600092019190915250614ab892505050565b905061271061207f601854612073600f548561431a90919063ffffffff16565b9063ffffffff61431a16565b111561209d5760405162461bcd60e51b8152600401610c0f906166b9565b600655612973565b61210f84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b60208201529150614a5f9050565b156121a957602081146121345760405162461bcd60e51b8152600401610c0f906162da565b604080516020601f840181900481028201810190925282815260009161217291858580838501838280828437600092019190915250614ab892505050565b600c5490915080612181575060155b8082106121a05760405162461bcd60e51b8152600401610c0f90616601565b50600855612973565b61221284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b60208201529150614a5f9050565b156122ab57602081146122375760405162461bcd60e51b8152600401610c0f906163c9565b604080516020601f840181900481028201810190925282815260009161227591858580838501838280828437600092019190915250614ab892505050565b90506000811180156122875750600a81105b6122a35760405162461bcd60e51b8152600401610c0f90616c26565b600a55612973565b61231f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e646964617465730000000000000060208201529150614a5f9050565b156123ae57602081146123445760405162461bcd60e51b8152600401610c0f9061637d565b604080516020601f840181900481028201810190925282815260009161238291858580838501838280828437600092019190915250614ab892505050565b9050600d548111156123a65760405162461bcd60e51b8152600401610c0f906167c2565b600e55612973565b61241784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b60208201529150614a5f9050565b15612499576020811461243c5760405162461bcd60e51b8152600401610c0f906169eb565b604080516020601f840181900481028201810190925282815260009161247a91858580838501838280828437600092019190915250614ab892505050565b600d819055600e5490915081101561249357600d54600e555b50612973565b6124fd84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b60208201529150614a5f9050565b1561262257602081146125225760405162461bcd60e51b8152600401610c0f9061640e565b604080516020601f840181900481028201810190925282815260009161256091858580838501838280828437600092019190915250614ab892505050565b9050600081116125825760405162461bcd60e51b8152600401610c0f90616577565b60006120026001600160a01b031663c473318f6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125bf57600080fd5b505afa1580156125d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125f79190615fe9565b9050808211156126195760405162461bcd60e51b8152600401610c0f90616320565b50600c55612973565b61268e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527473797374656d52657761726442617365526174696f60581b60208201529150614a5f9050565b1561273757602081146126b35760405162461bcd60e51b8152600401610c0f90616bde565b604080516020601f84018190048102820181019092528281526000916126f191858580838501838280828437600092019190915250614ab892505050565b90506127106127116018546120736006548561431a90919063ffffffff16565b111561272f5760405162461bcd60e51b8152600401610c0f906164e8565b600f55612973565b6127ab84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f73797374656d526577617264416e74694d4556526174696f000000000000000060208201529150614a5f9050565b1561285457602081146127d05760405162461bcd60e51b8152600401610c0f90616748565b604080516020601f840181900481028201810190925282815260009161280e91858580838501838280828437600092019190915250614ab892505050565b905061271061282e600f546120736006548561431a90919063ffffffff16565b111561284c5760405162461bcd60e51b8152600401610c0f9061685c565b601855612973565b6128b584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a8152690e8eae4dc98cadccee8d60b31b60208201529150614a5f9050565b1561295b57602081146128da5760405162461bcd60e51b8152600401610c0f9061665e565b604080516020601f840181900481028201810190925282815260009161291891858580838501838280828437600092019190915250614ab892505050565b90506003811015801561292c575060408111155b806129375750806001145b6129535760405162461bcd60e51b8152600401610c0f90616c83565b601755612973565b60405162461bcd60e51b8152600401610c0f90616cd3565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040516129a89493929190616271565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b82811015612a04576129f0816114e6565b156129fc578160010191505b6001016129df565b50606081604051908082528060200260200182016040528015612a31578160200160208202803683370190505b5090506000915060005b83811015612ab857612a4c816114e6565b15612ab05760018181548110612a5e57fe5b600091825260209091206004909102015482516001600160a01b0390911690839085908110612a8957fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612a3b565b509250505090565b601581565b61027181565b600281565b61100281565b60175481565b60138181548110611c2f57fe5b60185481565b6000612af96129d5565b519050600080600c5411612b0e576015612b12565b600c545b905080821115612b20578091505b81612b2a57600191505b5090565b60055481565b61100381565b61200481565b60005460ff1615612b635760405162461bcd60e51b8152600401610c0f90616a5c565b612b6b615a69565b6000612b916040518061062001604052806105ef8152602001616e946105ef9139614abd565b9150915080612bb25760405162461bcd60e51b8152600401610c0f90616b01565b60005b826020015151811015612cd757600183602001518281518110612bd457fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a090930151600390930192909255918601518051918501939185908110612caa57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612bb5565b50506000805460ff1916600117905550565b600d5481565b601354600090815b81811015612df857612de085858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601380549092508591508110612d4857fe5b600091825260209182902001805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b820191906000526020600020905b815481529060010190602001808311612db957829003601f168201915b5050505050614c79565b15612df057600192505050611591565b600101612cf7565b5060125460005b81811015612e6957612e5086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601280549092508591508110612d4857fe5b15612e615760019350505050611591565b600101612dff565b50600095945050505050565b3361100114612e965760405162461bcd60e51b8152600401610c0f90616cfa565b600b54612f5457612ea561595e565b60015460005b81811015612f5057600b80546001810182556000919091528351600080516020616e5483398151915260169092029182019081556020808601516000805160206174838339815191528401805460ff1916911515919091179055604086015180518794612f2c93600080516020616e7483398151915290910192019061598d565b506060820151612f429060038301906013615a07565b505050806001019050612eab565b5050505b6000612f5f82614cdd565b9050612f6a81611417565b15612f7957612f7982826149c7565b5050565b334114612f9c5760405162461bcd60e51b8152600401610c0f90616b91565b60005460ff16612fbe5760405162461bcd60e51b8152600401610c0f90616443565b60003411612fde5760405162461bcd60e51b8152600401610c0f90616793565b3a15612ffc5760405162461bcd60e51b8152600401610c0f9061696f565b6001600160a01b03811660009081526004602052604090205460145434919060ff1661303c57610271600f556103e86006556014805460ff191660011790555b600f54601754600110801561305357506000601854115b1561307857600160175403601754438161306957fe5b06601854028161307557fe5b04015b6000831180156130885750600081115b156131355760006130b16127106130a5348563ffffffff614e6016565b9063ffffffff614e9a16565b90508015613133576040516110029082156108fc029083906000818181858888f193505050501580156130e8573d6000803e3d6000fd5b507f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d816040516131189190616d89565b60405180910390a1613130848263ffffffff6142d816565b93505b505b60008311801561314757506000600654115b156131ed5760006131696127106130a560065434614e6090919063ffffffff16565b905080156131eb5760405161dead9082156108fc029083906000818181858888f193505050501580156131a0573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee5816040516131d09190616d89565b60405180910390a16131e8848263ffffffff6142d816565b93505b505b81156132eb57600060018084038154811061320457fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561327157846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4856040516132649190616d89565b60405180910390a26132e5565b600354613284908563ffffffff61431a16565b600390815581015461329c908563ffffffff61431a16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055906132dc908790616d89565b60405180910390a25b5061332d565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4846040516133249190616d89565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b818154811061335257fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff909116949192918301828280156133fd5780601f106133d2576101008083540402835291602001916133fd565b820191906000526020600020905b8154815290600101906020018083116133e057829003601f168201915b5050505050905083565b61100481565b6000600a546000148061341e575082155b806134295750600954155b15613436575060006135f7565b60096000815460019003919050819055506000613481600a546130a5866130a5600b8a8154811061346357fe5b6000918252602090912060169091020154439063ffffffff6142d816565b90506000600b868154811061349257fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b1580156134f757600080fd5b505afa15801561350b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061352f9190616001565b91509150600093508083106135ad57613548888861433f565b506040516328aa02b160e01b8152611001906328aa02b190613572908b9087908a906004016161ad565b600060405180830381600087803b15801561358c57600080fd5b505af11580156135a0573d6000803e3d6000fd5b50505050600193506135bf565b8183106135bf576135bd88614cdd565b505b6040516001600160a01b038916907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050505b949350505050565b606080600080808080613610612aef565b6001549091505b801561384257600181039250600b838154811061363057fe5b600091825260209091206001601690920201015460ff1661365057613839565b6001838154811061365d57fe5b600091825260208220600490910201546001600160a01b031695506136879086908590859061340d565b93508361369357613839565b60405163436aa28360e11b81526000908190612002906386d54506906136bd908a9060040161613e565b60206040518083038186803b1580156136d557600080fd5b505afa1580156136e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061370d9190615dce565b90506001600160a01b03811615613796576040516302ceee9160e11b81526120029063059ddd229061374390849060040161613e565b60206040518083038186803b15801561375b57600080fd5b505afa15801561376f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137939190615dce565b91505b60005b8c5181101561383557876001600160a01b03168d82815181106137b857fe5b6020026020010151600001516001600160a01b031614806138015750826001600160a01b03168d82815181106137ea57fe5b6020026020010151600001516001600160a01b0316145b1561382d5760018d828151811061381457fe5b6020908102919091010151901515608090910152613835565b600101613799565b5050505b60001901613617565b5060005b89518110156138af5789818151811061385b57fe5b6020026020010151608001518061389b575060006001600160a01b03168a828151811061388457fe5b6020026020010151600001516001600160a01b0316145b156138a7578560010195505b600101613846565b50885185106139975760408051600180825281830190925290816020015b6138d5615a34565b8152602001906001900390816138cd575050604080516001808252818301909252919850602082015b60608152602001906001900390816138fe5790505095508860008151811061392257fe5b60200260200101518760008151811061393757fe5b60200260200101819052508760008151811061394f57fe5b60200260200101518660008151811061396457fe5b602002602001018190525060008760008151811061397e57fe5b6020908102919091010151901515608090910152613adc565b848951036040519080825280602002602001820160405280156139d457816020015b6139c1615a34565b8152602001906001900390816139b95790505b50965084895103604051908082528060200260200182016040528015613a0e57816020015b60608152602001906001900390816139f95790505b5095506000915060005b8951811015613ada57898181518110613a2d57fe5b602002602001015160800151158015613a70575060006001600160a01b03168a8281518110613a5857fe5b6020026020010151600001516001600160a01b031614155b15613ad257898181518110613a8157fe5b6020026020010151888481518110613a9557fe5b6020026020010181905250888181518110613aac57fe5b6020026020010151878481518110613ac057fe5b60200260200101819052508260010192505b600101613a18565b505b50505050505b9250929050565b600154825160005b82811015613c06576001613b03615a34565b60018381548110613b1057fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015613bda57878181518110613ba057fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415613bd25760009250613bda565b600101613b8c565b508115613bfc5780516001600160a01b03166000908152600460205260408120555b5050600101613af1565b5080821115613cc557805b82811015613cc3576001805480613c2457fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b805480613c7757fe5b60008281526020812060166000199093019283020181815560018101805460ff1916905590613ca96002830182615a8d565b613cb7600383016000615ad1565b50509055600101613c11565b505b6000818310613cd45781613cd6565b825b905060005b8181101561407a57613d88868281518110613cf257fe5b602002602001015160018381548110613d0757fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152614edc565b613f3c578060010160046000888481518110613da057fe5b6020026020010151600001516001600160a01b03166001600160a01b0316815260200190815260200160002081905550858181518110613ddc57fe5b602002602001015160018281548110613df157fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a0909101516003909101558451859082908110613eac57fe5b6020026020010151600b8281548110613ec157fe5b90600052602060002090601602016002019080519060200190613ee592919061598d565b506000600b8281548110613ef557fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b805483908110613f2657fe5b6000918252602090912060169091020155614072565b858181518110613f4857fe5b60200260200101516060015160018281548110613f6157fe5b906000526020600020906004020160020160146101000a8154816001600160401b0302191690836001600160401b03160217905550614027858281518110613fa557fe5b6020026020010151600b8381548110613fba57fe5b600091825260209182902060026016909202018101805460408051601f600019610100600186161502019093169490940491820185900485028401850190528083529192909190830182828015612dd65780601f10612dab57610100808354040283529160200191612dd6565b6140725784818151811061403757fe5b6020026020010151600b828154811061404c57fe5b9060005260206000209060160201600201908051906020019061407092919061598d565b505b600101613cdb565b50828211156142525761408b61595e565b835b8381101561424f578581815181106140a157fe5b6020026020010151826040018190525060018782815181106140bf57fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616e548339815191528101918255858301516000805160206174838339815191528201805491151560ff19909216919091179055928501518051869492936141f593600080516020616e748339815191520192019061598d565b50606082015161420b9060038301906013615a07565b505050806001016004600089848151811061422257fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161408d565b50505b61425a614f38565b61426261511a565b6000600981905560015493505b838110156142d0576000600b828154811061428657fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106142b757fe5b600091825260209091206016909102015560010161426f565b505050505050565b6000611bca83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615308565b600082820183811015611bca5760405162461bcd60e51b8152600401610c0f906164b1565b6000806001838154811061434f57fe5b906000526020600020906004020160030154905060006001808054905003905060016143796129d5565b51116143ae5760006001858154811061438e57fe5b906000526020600020906004020160030181905550600092505050611591565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516143e79190616d89565b60405180910390a26001600160a01b038516600090815260046020526040812055835b600154600019018110156145d4576001816001018154811061442857fe5b90600052602060002090600402016001828154811061444357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b80549091830190811061450457fe5b9060005260206000209060160201600b828154811061451f57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614576938386019390821615610100026000190190911604615ae0565b5061458960038281019084016013615b55565b509050508060010160046000600184815481106145a257fe5b600091825260208083206004909202909101546001600160a01b0316835282019290925260400190205560010161440a565b5060018054806145e057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061463357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906146656002830182615a8d565b614673600383016000615ad1565b50509055600081838161468257fe5b04905080156146f65760015460005b818110156146f3576146ca83600183815481106146aa57fe5b90600052602060002090600402016003015461431a90919063ffffffff16565b600182815481106146d757fe5b6000918252602090912060036004909202010155600101614691565b50505b50600195945050505050565b60015481516040805182815260208084028201019091526060929190839082801561474157816020015b606081526020019060019003908161472c5790505b50600b5490915083146147585792506114e1915050565b60005b8281101561486757600b60016004600089858151811061477757fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205403815481106147ab57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156148435780601f1061481857610100808354040283529160200191614843565b820191906000526020600020905b81548152906001019060200180831161482657829003601f168201915b505050505082828151811061485457fe5b602090810291909101015260010161475b565b50949350505050565b60005b828110156149bd5760008287838801604051602001614893929190616130565b6040516020818303038152906040528051906020012060001c816148b357fe5b069050808501828701146149b457600089838801815181106148d157fe5b60200260200101519050606089848901815181106148eb57fe5b602002602001015190508a8388018151811061490357fe5b60200260200101518b858a018151811061491957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b8489018151811061494857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061497657fe5b60200260200101518a858a018151811061498c57fe5b6020026020010181905250808a848901815181106149a657fe5b602002602001018190525050505b50600101614873565b5050505050505050565b600980546001908101909155600b8054839081106149e157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b8281548110614a1757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b600081604051602001614a729190616114565b6040516020818303038152906040528051906020012083604051602001614a999190616114565b6040516020818303038152906040528051906020012014905092915050565b015190565b614ac5615a69565b6000614acf615a69565b614ad7615b7f565b614ae8614ae386615334565b615359565b90506000805b614af7836153a3565b15614c6b5780614b1c57614b12614b0d846153c4565b615412565b60ff168452614c63565b8060011415614c5e576060614b38614b33856153c4565b615492565b90508051604051908082528060200260200182016040528015614b7557816020015b614b62615a34565b815260200190600190039081614b5a5790505b5085602001819052508051604051908082528060200260200182016040528015614bb357816020015b6060815260200190600190039081614b9e5790505b50604086015260005b8151811015614c5357614bcd615a34565b60606000614bed858581518110614be057fe5b6020026020010151615563565b92509250925080614c0d578860009a509a50505050505050505050614c74565b8289602001518581518110614c1e57fe5b60200260200101819052508189604001518581518110614c3a57fe5b6020026020010181905250505050806001019050614bbc565b506001925050614c63565b614c6b565b600101614aee565b50919350909150505b915091565b815181516000916001918114808314614c955760009250614cd3565b600160208701838101602088015b600284838510011415614cce578051835114614cc25760009650600093505b60209283019201614ca3565b505050505b5090949350505050565b6001600160a01b03811660009081526004602052604081205480614d06575060001990506114e1565b600181039050600060018281548110614d1b57fe5b9060005260206000209060040201600301549050600060018381548110614d3e57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614d97908590616d89565b60405180910390a280614daf578293505050506114e1565b6000818381614dba57fe5b0490508015614e565760005b84811015614e0857614ddf82600183815481106146aa57fe5b60018281548110614dec57fe5b6000918252602090912060036004909202010155600101614dc6565b50600180549085015b81811015614e5357614e2a83600183815481106146aa57fe5b60018281548110614e3757fe5b6000918252602090912060036004909202010155600101614e11565b50505b5091949350505050565b600082614e6f57506000611591565b82820282848281614e7c57fe5b0414611bca5760405162461bcd60e51b8152600401610c0f9061692e565b6000611bca83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061567d565b805182516000916001600160a01b039182169116148015614f16575081602001516001600160a01b031683602001516001600160a01b0316145b8015611bca5750506040908101519101516001600160a01b0390811691161490565b60125460135480821115614f8357805b82811015614f81576012805480614f5b57fe5b600190038181906000526020600020016000614f779190615a8d565b9055600101614f48565b505b6000818310614f925781614f94565b825b905060005b818110156150ac5761505160128281548110614fb157fe5b600091825260209182902001805460408051601f600260001961010060018716150201909416939093049283018590048502810185019091528181529283018282801561503f5780601f106150145761010080835404028352916020019161503f565b820191906000526020600020905b81548152906001019060200180831161502257829003601f168201915b505050505060138381548110612d4857fe5b6150a4576013818154811061506257fe5b906000526020600020016012828154811061507957fe5b9060005260206000200190805460018160011615610100020316600290046150a2929190615ae0565b505b600101614f99565b5082821115610c3157825b8281101561332d576012601382815481106150ce57fe5b6000918252602080832084546001818101875595855291909320929091018054615111949390920192909160026101009282161592909202600019011604615ae0565b506001016150b7565b601354600b548082111561516557805b8281101561516357601380548061513d57fe5b6001900381819060005260206000200160006151599190615a8d565b905560010161512a565b505b60008183106151745781615176565b825b905060005b81811015615295576152336013828154811061519357fe5b600091825260209182902001805460408051601f60026000196101006001871615020190941693909304928301859004850281018501909152818152928301828280156152215780601f106151f657610100808354040283529160200191615221565b820191906000526020600020905b81548152906001019060200180831161520457829003601f168201915b5050505050600b8381548110613fba57fe5b61528d57600b818154811061524457fe5b90600052602060002090601602016002016013828154811061526257fe5b90600052602060002001908054600181600116156101000203166002900461528b929190615ae0565b505b60010161517b565b5082821115610c3157825b8281101561332d576013600b82815481106152b757fe5b6000918252602080832084546001808201875595855291909320601692909202909201600290810180546152ff95939094019390926000199082161561010002011604615ae0565b506001016152a0565b6000818484111561532c5760405162461bcd60e51b8152600401610c0f919061625e565b505050900390565b61533c615b9f565b506040805180820190915281518152602082810190820152919050565b615361615b7f565b61536a826156b4565b61537357600080fd5b600061538283602001516156ee565b60208085015160408051808201909152868152920190820152915050919050565b60006153ad615b9f565b505080518051602091820151919092015191011190565b6153cc615b9f565b6153d5826153a3565b6153de57600080fd5b602082015160006153ee82615751565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061542757508151602110155b61543057600080fd5b600061543f83602001516156ee565b905080836000015110156154655760405162461bcd60e51b8152600401610c0f90616a93565b82516020808501518301805192849003929183101561486757506020919091036101000a90049392505050565b606061549d826156b4565b6154a657600080fd5b60006154b183615832565b90506060816040519080825280602002602001820160405280156154ef57816020015b6154dc615b9f565b8152602001906001900390816154d45790505b509050600061550185602001516156ee565b60208601510190506000805b848110156155585761551e83615751565b915060405180604001604052808381526020018481525084828151811061554157fe5b60209081029190910101529181019160010161550d565b509195945050505050565b61556b615a34565b60606000615577615a34565b6060615581615b7f565b61558a87615359565b90506000805b615599836153a3565b1561566e57806155c4576155b46155af846153c4565b61588e565b6001600160a01b03168552615666565b80600114156155ec576155d96155af846153c4565b6001600160a01b03166020860152615666565b8060021415615614576156016155af846153c4565b6001600160a01b03166040860152615666565b806003141561564057615629614b0d846153c4565b6001600160401b0316606086015260019150615666565b80600414156156615761565a615655846153c4565b6158a8565b9350615666565b61566e565b600101615590565b50929791965091945092505050565b6000818361569e5760405162461bcd60e51b8152600401610c0f919061625e565b5060008385816156aa57fe5b0495945050505050565b80516000906156c5575060006114e1565b6020820151805160001a9060c08210156156e4576000925050506114e1565b5060019392505050565b8051600090811a60808110156157085760009150506114e1565b60b8811080615723575060c08110801590615723575060f881105b156157325760019150506114e1565b60c08110156157465760b5190190506114e1565b60f5190190506114e1565b80516000908190811a608081101561576c576001915061582b565b60b881101561578157607e198101915061582b565b60c08110156157d257600060b78203600186019550806020036101000a8651049150600181018201935050808310156157cc5760405162461bcd60e51b8152600401610c0f90616831565b5061582b565b60f88110156157e75760be198101915061582b565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158295760405162461bcd60e51b8152600401610c0f90616831565b505b5092915050565b8051600090615843575060006114e1565b6000809050600061585784602001516156ee565b602085015185519181019250015b808210156158855761587682615751565b82019150826001019250615865565b50909392505050565b805160009060151461589f57600080fd5b61159182615412565b80516060906158b657600080fd5b60006158c583602001516156ee565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156158fc576020820181803683370190505b50905060008160200190506148678487602001510182858061591d57610c31565b5b6020811061593d578251825260209283019290910190601f190161591e565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615988615bb9565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106159ce57805160ff19168380011785556159fb565b828001600101855582156159fb579182015b828111156159fb5782518255916020019190600101906159e0565b50612b2a929150615bd8565b82601381019282156159fb57916020028201828111156159fb5782518255916020019190600101906159e0565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b6040518060600160405280600060ff16815260200160608152602001606081525090565b50805460018160011615610100020316600290046000825580601f10615ab357506116f9565b601f0160209004906000526020600020908101906116f99190615bd8565b506116f9906013810190615bd8565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615b1957805485556159fb565b828001600101855582156159fb57600052602060002091601f016020900482015b828111156159fb578254825591600101919060010190615b3a565b82601381019282156159fb57918201828111156159fb578254825591600101919060010190615b3a565b6040518060400160405280615b92615b9f565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b611dac91905b80821115612b2a5760008155600101615bde565b803561159181616e3e565b60008083601f840112615c0e578182fd5b5081356001600160401b03811115615c24578182fd5b6020830191508360208083028501011115613ae257600080fd5b6000601f8381840112615c4f578182fd5b8235615c62615c5d82616df3565b616dcd565b818152925060208084019085810160005b84811015615cf4578135880189603f820112615c8e57600080fd5b838101356001600160401b03811115615ca657600080fd5b615cb7818901601f19168601616dcd565b81815260408c81848601011115615ccd57600080fd5b82818501888401375060009181018601919091528552509282019290820190600101615c73565b50505050505092915050565b600082601f830112615d10578081fd5b8135615d1e615c5d82616df3565b818152915060208083019084810181840286018201871015615d3f57600080fd5b6000805b85811015615cf45782356001600160401b0381168114615d61578283fd5b85529383019391830191600101615d43565b60008083601f840112615d84578182fd5b5081356001600160401b03811115615d9a578182fd5b602083019150836020828501011115613ae257600080fd5b600060208284031215615dc3578081fd5b8135611bca81616e3e565b600060208284031215615ddf578081fd5b8151611bca81616e3e565b60008060008060408587031215615dff578283fd5b84356001600160401b0380821115615e15578485fd5b615e2188838901615bfd565b90965094506020870135915080821115615e39578384fd5b50615e4687828801615bfd565b95989497509550505050565b600080600060608486031215615e66578283fd5b83356001600160401b0380821115615e7c578485fd5b81860187601f820112615e8d578586fd5b80359250615e9d615c5d84616df3565b80848252602080830192508084018b828389028701011115615ebd57898afd5b8994505b86851015615ee757615ed38c82615bf2565b845260019490940193928101928101615ec1565b509097508801359350505080821115615efe578384fd5b615f0a87838801615d00565b93506040860135915080821115615f1f578283fd5b50615f2c86828701615c3e565b9150509250925092565b60008060208385031215615f48578182fd5b82356001600160401b03811115615f5d578283fd5b615f6985828601615d73565b90969095509350505050565b60008060008060408587031215615f8a578384fd5b84356001600160401b0380821115615fa0578586fd5b615fac88838901615d73565b90965094506020870135915080821115615fc4578384fd5b50615e4687828801615d73565b600060208284031215615fe2578081fd5b5035919050565b600060208284031215615ffa578081fd5b5051919050565b60008060408385031215616013578182fd5b505080516020909101519092909150565b600080600060408486031215616038578081fd5b833560ff81168114616048578182fd5b925060208401356001600160401b03811115616062578182fd5b61606e86828701615d73565b9497909650939450505050565b6000815180845260208085019450808401835b838110156160b35781516001600160a01b03168752958201959082019060010161608e565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452616100816020860160208601616e12565b601f01601f19169290920160200192915050565b60008251616126818460208701616e12565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b6001600160a01b0393909316835260208301919091521515604082015260600190565b600060208252611bca602083018461607b565b6000604082526161f6604083018561607b565b602083820381850152818551808452828401915082838202850101838801865b8381101561624457601f198784030185526162328383516160e8565b94860194925090850190600101616216565b50909998505050505050505050565b901515815260200190565b600060208252611bca60208301846160e8565b6000604082526162856040830186886160be565b82810360208401526162988185876160be565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526038908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e206d6178456c656374656456616c696461746f72730000000000000000606082015260800190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601f908201527f6f6e6c7920736c617368206f72207374616b6548756220636f6e747261637400604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526063908201527f7468652073797374656d52657761726442617365526174696f20706c7573206260408201527f75726e526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252601d908201527f6c656e677468206f66207475726e4c656e677468206d69736d61746368000000604082015260600190565b6020808252600a908201526919195c1c9958d85d195960b21b604082015260600190565b60208082526063908201527f746865206275726e526174696f20706c75732073797374656d5265776172644260408201527f617365526174696f20616e642073797374656d526577617264416e74694d455660608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b6020808252602b908201527f6c656e677468206f662073797374656d526577617264416e74694d455652617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526063908201527f7468652073797374656d526577617264416e74694d4556526174696f20706c7560408201527f73206275726e526174696f20616e642073797374656d5265776172644261736560608201527f526174696f206d757374206265206e6f2067726561746572207468616e20313060808201526203030360ec1b60a082015260c00190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b60208082526028908201527f6c656e677468206f662073797374656d52657761726442617365526174696f206040820152670dad2e6dac2e8c6d60c31b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b60208082526030908201527f746865207475726e4c656e6774682073686f756c6420626520696e205b332c3660408201526f345d206f7220657175616c20746f203160801b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b6020808252601f908201527f746865206d73672073656e646572206d757374206265207374616b6548756200604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152616db360608301846160e8565b95945050505050565b63ffffffff91909116815260200190565b6040518181016001600160401b0381118282101715616deb57600080fd5b604052919050565b60006001600160401b03821115616e08578081fd5b5060209081020190565b60005b83811015616e2d578181015183820152602001616e15565b8381111561332d5750506000910152565b6001600160a01b03811681146116f957600080fdfe0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbbf905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a20000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa164736f6c6343000604000a
Loading...
Loading
Loading...
Loading
Net Worth in USD
$364,245,648.66
Net Worth in BNB
Token Allocations
MON
99.99%
BNB
0.01%
BABYAPE
0.00%
Others
0.00%
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| MONAD | 99.99% | $0.023637 | 15,408,074,525.7531 | $364,204,326.51 | |
| BSC | $616.33 | 50.9609 | $31,408.54 | ||
| BSC | $0.000007 | 543,696,662.5298 | $3,617.11 | ||
| BSC | $0.000316 | 8,836,000 | $2,791.36 | ||
| BSC | $0.999586 | 1,119.8403 | $1,119.38 | ||
| BSC | 3,000,002,149.9083 | $917.7 | |||
| BSC | $0.00 | 10,000 | $0.00 | ||
| BSC | $0.529638 | 99.5 | $52.7 | ||
| BSC | $0.281277 | 113.0589 | $31.8 | ||
| BSC | 200,000,000 | $26.68 | |||
| BSC | $1.19 | 20 | $23.7 | ||
| BSC | 4,773,420,336.5833 | $11.93 | |||
| BSC | $0.000212 | 55,060.3604 | $11.67 | ||
| BSC | 30,594,611.7785 | $10.44 | |||
| BSC | $99 | 0.084 | $8.31 | ||
| BSC | 296,563,535,086,066,180 | $7.71 | |||
| BSC | $0.000411 | 12,700 | $5.22 | ||
| BSC | $0.001982 | 1,800.003 | $3.57 | ||
| BSC | $0.32422 | 10 | $3.24 | ||
| BSC | $0.000311 | 10,154.5313 | $3.16 | ||
| BSC | $0.999822 | 1.927 | $1.93 | ||
| BSC | 12,158,029,036.5489 | $1.22 | |||
| BSC | $0.084691 | 11.2975 | $0.9568 | ||
| BSC | $615.64 | 0.0013202 | $0.8127 | ||
| BSC | $1.47 | 0.441 | $0.6482 | ||
| BSC | $0.477939 | 1 | $0.4779 | ||
| BSC | $0.299275 | 1.0748 | $0.3216 | ||
| BSC | $68,660.22 | 0.0000041 | $0.2815 | ||
| BSC | $0.138427 | 1.8356 | $0.254 | ||
| BSC | $0.245587 | 1 | $0.2455 | ||
| BSC | 37,146,798.1564 | $0.2064 | |||
| BSC | $0.141697 | 0.833 | $0.118 | ||
| BSC | $0.97115 | 0.107 | $0.1038 | ||
| ETH | $0.9996 | 961.0158 | $960.63 | ||
| ETH | $1,965.84 | 0.00237207 | $4.66 | ||
| ETH | $616.09 | 0.000672 | $0.414 | ||
| HYPEREVM | $30.25 | 1.13 | $34.18 | ||
| OP | $1,965.69 | 0.001 | $1.97 | ||
| BASE | $1,965.84 | 0.00071646 | $1.41 | ||
| ARB | $1,965.3 | 0.00038754 | $0.761631 | ||
| OPBNB | $616.18 | 0.000002 | $0.001233 | ||
| LINEA | $1,965.84 | 0.0000002 | $0.000393 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.
${zeroWidthWarningMessage} Check the actual text at SPACE ID.
`;
}
const ensOnL2NoteHtml = ensOnL2Note != "" ? `Additional Info
Full Name:
${ensNameForkIconSrc}
Note:
- Name tag is displayed due to forward and reverse resolution. Find out more.
- A Domain Name is not necessarily held by a person popularly associated with the name. ${ensOnL2NoteHtml}
Other names resolving to this address:
${listOtherENSNames}
${moreOtherENSNames}
`;
return result;
}
function removeSpecificDomain(url, domain) {
return url.replace(new RegExp(domain + '$'), '');
}
// ===== UD name tag
const displayUDName = '';
const primaryUDName = '';
const showUDPublicNote = 'false';
let otherUDNamesHtml = "";
function initUDNamePopOver() {
//required to allow bootstrap popover to support table
$.fn.popover.Constructor.Default.allowList.table = [];
$.fn.popover.Constructor.Default.allowList.tr = [];
$.fn.popover.Constructor.Default.allowList.td = [];
$.fn.popover.Constructor.Default.allowList.th = [];
$.fn.popover.Constructor.Default.allowList.div = [];
$.fn.popover.Constructor.Default.allowList.tbody = [];
$.fn.popover.Constructor.Default.allowList.thead = [];
//allowList my inline styling for bootstrap
$.fn.popover.Constructor.Default.allowList['*'].push('style')
let unicodeWarningHtml = "";
if ($("#hdnIsUDContainUnicodeChars").val() == "true") {
unicodeWarningHtml =
`
${unicodeWarningMessage} Check the actual text at Unstoppable Domains.
`;
}
let zeroWidthWarningHtml = "";
if ($("#hdnIsUDContainZeroWidthChars").val() == "true") {
zeroWidthWarningHtml =
`
${unicodeWarningMessage} Check the actual text at Unstoppable Domains.
`;
}
const contentHtml =
`Additional Info
Full Name:
Note:
- Name tag is displayed due to forward and reverse resolution. Find out more
- A Domain Name is not necessarily held by a person popularly associated with the name.
Other names resolving to this address:
${listOtherUDNames}
${moreOtherUDNames}
`;
return result;
}
// ===== end UD name tag
const tooltipForTokenHolding = 'More than 112 tokens found, listing and displaying the total balance of the first 100 tokens only. Click on the Coins icon to see the full list and balance.';
var adjustPosition = 0;
$(document).ready(function () {
switchAmountToValue(document.getElementById("headerAmountValue"), 'Value (USD)', 'Amount', true);
switchAmountToValue(document.getElementById("headerIntAmountValue"), 'Value (USD)', 'Amount', true);
switchMethodColumn(document.getElementById("headerMethod"), 'Method', 'Action', true);
onDocumentReady();
$("[rel='tooltip']").tooltip();
$("[data-bs-toggle-second='tooltip']").tooltip({ trigger: 'hover' });
$("[rel='tooltipEns']").each(function () {
$(this).tooltip({ title: $(this).attr("tooltip-title") });
});
if (hash != '') {
activaTab(hash);
};
onAddressDocReady();
// Note: this is causing "Copied" tooltip not showing when copy button is clicked in V3, and seems like not applicable to v3, comment out first in case there is issue
//$('[data-bs-toggle="tooltip"]').click(function () {
// $('[data-bs-toggle="tooltip"]').tooltip("hide");
//});
document.getElementById("copyaddressbutton").classList.remove("disabled");
if ($("#txtSearchContract").length) {
initialiseKeyupOnDocReady();
}
if (!!$('#ensName')[0]) {
initEnsNamePopOver();
}
if (!!$("#udName")[0]) {
initUDNamePopOver();
}
handleToggle();
if (window.matchMedia("(max-width: 767px)").matches) {
// Mobile
adjustPosition = 90;
} else {
// Others
adjustPosition = 50;
}
if (tooltipForTokenHolding) {
const dropdownMenuBalance = document.getElementById("dropdownMenuBalance");
if (dropdownMenuBalance) {
const dropdownWrapper = dropdownMenuBalance.closest(".dropdown");
if (dropdownWrapper) {
dropdownWrapper.setAttribute("title", tooltipForTokenHolding);
new bootstrap.Tooltip(dropdownWrapper);
}
}
}
});
function displayAudit() {
$('html, body').animate({
scrollTop: $("#auditReportId").offset().top - adjustPosition
});
}
var cThemeMode = getCookie('displaymode');
function handleToggle() {
var className = document.getElementsByClassName('editor');
var classNameCount = className.length;
for (var j = 0; j t.innerWidth()) {
if (mb + d > tb) {
t.css('padding-bottom', ((mb + d) - tb));
}
}
else {
t.css('overflow', 'visible');
}
}).on('hidden.bs.dropdown', function () {
$(this).css({ 'padding-bottom': '', 'overflow': '' });
});
var btn_ERC20_sort = {
count: 0,
reminder_count: 2,
list: [],
default_list: [],
ERC20_sort_start: function (count) {
if (document.getElementsByClassName('list-custom-divider-ERC20')[0]) {
var self = this
if (count != undefined) {
self.count = count
}
var before_el = document.getElementsByClassName('list-custom-divider-ERC20')[0]
var parent_el = before_el.parentNode
var element_selector = parent_el.querySelectorAll(".list-custom-ERC20");
if (self.list.length == 0) {
element_selector.forEach(function (e) {
self.list.push(e);
self.default_list.push(e);
});
}
$(".list-custom-ERC20").remove()
var type = self.count % self.reminder_count
self.sortList(type, parent_el, before_el);
self.count++
}
},
sortList: function (type, parent_el, before_el) {
var self = this
var sorted_list = []
var icon_el = $(before_el).find('button').find('i')
switch (type) {
case 1:
icon_el.attr("class", "fad fa-sort-up")
sorted_list = self.sortUsdAsc()
break;
default:
icon_el.attr("class", "fad fa-sort-down")
sorted_list = self.sortUsdDesc()
}
for (var i = sorted_list.length - 1; i >= 0; i--) {
before_el.insertAdjacentElement('afterend', sorted_list[i])
}
},
sortUsdAsc: function () {
var self = this
var sort_list = self.list
sort_list.sort(function (a, b) {
var target_a_value = self.formatCurrencyToNumber(a.querySelector('.list-usd-value').textContent.trim() || -1);
var target_b_value = self.formatCurrencyToNumber(b.querySelector('.list-usd-value').textContent.trim() || -1);
if (target_a_value == -1 || target_b_value == -1) {
return 1;
}
if (target_a_value target_b_value) {
return 1;
}
return 0
});
return sort_list
},
sortUsdDesc: function () {
var self = this
var sort_list = self.list
sort_list.sort(function (a, b) {
var target_a_value = self.formatCurrencyToNumber(a.querySelector('.list-usd-value').textContent.trim() || -1);
var target_b_value = self.formatCurrencyToNumber(b.querySelector('.list-usd-value').textContent.trim() || -1);
if (target_a_value target_b_value) {
return -1;
}
return 0
});
return sort_list
},
formatCurrencyToNumber: function (strCurrency) {
if (typeof strCurrency == "number")
return strCurrency
else
return Number(strCurrency.replace(/[^0-9.-]+/g, ""));
},
}
function hrefTokenHolding() {
var location = "/tokenholdings?a=0x0000000000000000000000000000000000001000"
var queryString = $("input.form-control.form-control-xs.search.mb-3")[0].value
if (queryString) {
location += "&q=" + queryString
}
window.location.href = location
}
$(document).ready(function () {
$("#btn_ERC20_sort").on("click", function (event) {
event.preventDefault();
setTimeout(function () {
btn_ERC20_sort.ERC20_sort_start()
}, 10)
})
btn_ERC20_sort.ERC20_sort_start()
var mainAddress = $("#hdnAddress").val();
// user search for method filters
var searchFuncTimeOut;
$("#ContentPlaceHolder1_inputMethodName").on("keyup", function ($event) {
if (searchFuncTimeOut) {
clearTimeout(searchFuncTimeOut)
}
var searchTerm = $(this).val();
searchFuncTimeOut = setTimeout(function () {
searchFunctions(searchTerm);
}, 350);
});
var isSearchFunctions = false;
$("#dropdownMethod").on("click", function (e) {
if (isSearchFunctions === false) {
searchFunctions('');
isSearchFunctions = true;
}
});
const litDefaultMethodFilterHtml = '';
function searchFunctions(searchTerm) {
if (searchTerm === '' || searchTerm.length > 3) {
const curPath = encodeURIComponent(window.location.search);
$.ajax({
type: 'Get',
url: `/functionSearchHandler.ashx?ca=${mainAddress}&func=${searchTerm ?? ''}&curPath=${curPath}`,
success: function (response) {
$("#searchFunctionResult").html('');
if (response && response.length > 0) {
for (var i = 0; i
${response[i].name}
${response[i].methodId}
`
);
}
$("[data-bs-toggle='tooltip']").tooltip();
}
else {
$("#searchFunctionResult").append(
`