false
false

Contract Address Details

0xa0743BfB163b628842E4d25e60AeFE78DFBb845B

Contract Name
SupraSValueFeedVerifier
Creator
0x1241f4–923734 at 0x537b89–76debd
Balance
0 SYS ( )
Tokens
Fetching tokens...
Transactions
28,874 Transactions
Transfers
0 Transfers
Gas Used
13,381,134,916
Last Balance Update
793293
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
SupraSValueFeedVerifier




Optimization enabled
true
Compiler version
v0.8.19+commit.7dd6d404




Optimization runs
200
EVM Version
default




Verified at
2023-06-29T05:47:00.683275Z

Constructor Arguments

b2b5ca56968e81bf5845ee0e6c6888aff023d02790943f6947a389b2e2892ea50000000000000000000000008a358f391d93f7558d5f5e61bdf533e2cc3cf7a32db4607bd0a726aa5aaee95a28f2139b7d7cc7895ccf02aea2d01efda69014ed113b9e1f6557a92f5b3139a233a80f30a26949e7c74caa91c763f995ba22f5a30d4fedc4e0ea8d205c2f2d58c01a2c47f690c493ae2625d18150cd9340db07090e9860693ee0589849d34b85e832d4c89c3ad58fb85c463a09f17f1b28931260000000000000000000000000000000000000000000000000000000000001b9ed
              

Contract source code

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

library ModexpInverse {
    function run(uint256 t2) internal pure returns (uint256 t0) {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            let
                n
            := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
            t0 := mulmod(t2, t2, n)
            let t5 := mulmod(t0, t2, n)
            let t1 := mulmod(t5, t0, n)
            let t3 := mulmod(t5, t5, n)
            let t8 := mulmod(t1, t0, n)
            let t4 := mulmod(t3, t5, n)
            let t6 := mulmod(t3, t1, n)
            t0 := mulmod(t3, t3, n)
            let t7 := mulmod(t8, t3, n)
            t3 := mulmod(t4, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t7, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t7, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t7, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
        }
    }
}

library ModexpSqrt {
    function run(uint256 t6) internal pure returns (uint256 t0) {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            let
                n
            := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47

            t0 := mulmod(t6, t6, n)
            let t4 := mulmod(t0, t6, n)
            let t2 := mulmod(t4, t0, n)
            let t3 := mulmod(t4, t4, n)
            let t8 := mulmod(t2, t0, n)
            let t1 := mulmod(t3, t4, n)
            let t5 := mulmod(t3, t2, n)
            t0 := mulmod(t3, t3, n)
            let t7 := mulmod(t8, t3, n)
            t3 := mulmod(t1, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t7, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t7, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t8, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t7, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t6, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t5, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t4, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t3, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t2, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t0, n)
            t0 := mulmod(t0, t1, n)
            t0 := mulmod(t0, t0, n)
        }
    }
}

contract BNPairingPrecompileCostEstimator {
    uint256 public baseCost;
    uint256 public perPairCost;

    uint256 private constant G1_X = 1;
    uint256 private constant G1_Y = 2;

    uint256 private constant G2_X0 =
        10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 private constant G2_X1 =
        11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 private constant G2_Y0 =
        8495653923123431417604973247489272438418190587263600148770280649306958101930;
    uint256 private constant G2_Y1 =
        4082367875863433681332203403145435568316851327593401208105741076214120093531;
    uint256 private constant N_G2_Y0 =
        13392588948715843804641432497768002650278120570034223513918757245338268106653;
    uint256 private constant N_G2_Y1 =
        17805874995975841540914202342111839520379459829704422454583296818431106115052;

    function run() external {
        _run();
    }

    function getGasCost(uint256 pairCount) external view returns (uint256) {
        return pairCount * perPairCost + baseCost;
    }

    function _run() internal {
        uint256 gasCost1Pair = _gasCost1Pair();
        uint256 gasCost2Pair = _gasCost2Pair();
        perPairCost = gasCost2Pair - gasCost1Pair;
        baseCost = gasCost1Pair - perPairCost;
    }

    function _gasCost1Pair() internal view returns (uint256) {
        uint256[6] memory input = [G1_X, G1_Y, G2_X1, G2_X0, G2_Y1, G2_Y0];
        uint256[1] memory out;
        bool callSuccess;
        uint256 suppliedGas = gasleft() - 2000;
        require(
            gasleft() > 2000,
            "BNPairingPrecompileCostEstimator: not enough gas, single pair"
        );
        uint256 gasT0 = gasleft();

        assembly {
            callSuccess := staticcall(suppliedGas, 8, input, 192, out, 0x20)
        }
        uint256 gasCost = gasT0 - gasleft();
        require(
            callSuccess,
            "BNPairingPrecompileCostEstimator: single pair call is failed"
        );
        require(
            out[0] == 0,
            "BNPairingPrecompileCostEstimator: single pair call result must be 0"
        );
        return gasCost;
    }

    function _gasCost2Pair() internal view returns (uint256) {
        uint256[12] memory input = [
            G1_X,
            G1_Y,
            G2_X1,
            G2_X0,
            G2_Y1,
            G2_Y0,
            G1_X,
            G1_Y,
            G2_X1,
            G2_X0,
            N_G2_Y1,
            N_G2_Y0
        ];
        uint256[1] memory out;
        bool callSuccess;
        uint256 suppliedGas = gasleft() - 2000;
        require(
            gasleft() > 2000,
            "BNPairingPrecompileCostEstimator: not enough gas, couple pair"
        );
        uint256 gasT0 = gasleft();

        assembly {
            callSuccess := staticcall(suppliedGas, 8, input, 384, out, 0x20)
        }
        uint256 gasCost = gasT0 - gasleft();
        require(
            callSuccess,
            "BNPairingPrecompileCostEstimator: couple pair call is failed"
        );
        require(
            out[0] == 1,
            "BNPairingPrecompileCostEstimator: couple pair call result must be 1"
        );
        return gasCost;
    }
}

library BLS {
    uint256 private constant N =
        21888242871839275222246405745257275088696311157297823662689037894645226208583;
    uint256 private constant N_G2_X1 =
        11559732032986387107991004021392285783925812861821192530917403151452391805634;
    uint256 private constant N_G2_X0 =
        10857046999023057135944570762232829481370756359578518086990519993285655852781;
    uint256 private constant N_G2_Y1 =
        17805874995975841540914202342111839520379459829704422454583296818431106115052;
    uint256 private constant N_G2_Y0 =
        13392588948715843804641432497768002650278120570034223513918757245338268106653;
    uint256 private constant Z0 =
        0x0000000000000000b3c4d79d41a91759a9e4c7e359b6b89eaec68e62effffffd;
    uint256 private constant Z1 =
        0x000000000000000059e26bcea0d48bacd4f263f1acdb5c4f5763473177fffffe;
    uint256 private constant T24 =
        0x1000000000000000000000000000000000000000000000000;
    uint256 private constant MASK24 =
        0xffffffffffffffffffffffffffffffffffffffffffffffff;

    address private constant COST_ESTIMATOR_ADDRESS =
        0x079d8077C465BD0BF0FC502aD2B846757e415661;

    function verifySingle(
        uint256[2] memory signature,
        uint256[4] memory pubkey,
        uint256[2] memory message,
        uint256 precompileGasCost
    ) internal view returns (bool, bool) {
        uint256[12] memory input = [
            signature[0],
            signature[1],
            N_G2_X1,
            N_G2_X0,
            N_G2_Y1,
            N_G2_Y0,
            message[0],
            message[1],
            pubkey[1],
            pubkey[0],
            pubkey[3],
            pubkey[2]
        ];
        uint256[1] memory out;

        // uint256 precompileGasCost =
        //     BNPairingPrecompileCostEstimator(COST_ESTIMATOR_ADDRESS).getGasCost(
        //         2
        //     );

        bool callSuccess;
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            callSuccess := staticcall(
                precompileGasCost,
                8,
                input,
                384,
                out,
                0x20
            )
        }
        if (!callSuccess) {
            return (false, false);
        }
        return (out[0] != 0, true);
    }

    function verifyMultiple(
        uint256[2] memory signature,
        uint256[4][] memory pubkeys,
        uint256[2][] memory messages
    ) internal view returns (bool checkResult, bool callSuccess) {
        uint256 size = pubkeys.length;
        require(size > 0, "BLS: number of public key is zero");
        require(
            size == messages.length,
            "BLS: number of public keys and messages must be equal"
        );
        uint256 inputSize = (size + 1) * 6;
        uint256[] memory input = new uint256[](inputSize);
        input[0] = signature[0];
        input[1] = signature[1];
        input[2] = N_G2_X1;
        input[3] = N_G2_X0;
        input[4] = N_G2_Y1;
        input[5] = N_G2_Y0;
        for (uint256 i = 0; i < size; i++) {
            input[i * 6 + 6] = messages[i][0];
            input[i * 6 + 7] = messages[i][1];
            input[i * 6 + 8] = pubkeys[i][1];
            input[i * 6 + 9] = pubkeys[i][0];
            input[i * 6 + 10] = pubkeys[i][3];
            input[i * 6 + 11] = pubkeys[i][2];
        }
        uint256[1] memory out;

        uint256 precompileGasCost = BNPairingPrecompileCostEstimator(
            COST_ESTIMATOR_ADDRESS
        ).getGasCost(size + 1);
        assembly {
            callSuccess := staticcall(
                precompileGasCost,
                8,
                add(input, 0x20),
                mul(inputSize, 0x20),
                out,
                0x20
            )
        }
        if (!callSuccess) {
            return (false, false);
        }
        return (out[0] != 0, true);
    }

    function hashToPoint(bytes32 domain, bytes memory message)
        internal
        view
        returns (uint256[2] memory)
    {
        uint256[2] memory u = hashToField(domain, message);
        uint256[2] memory p0 = mapToPoint(u[0]);
        uint256[2] memory p1 = mapToPoint(u[1]);
        uint256[4] memory bnAddInput;
        bnAddInput[0] = p0[0];
        bnAddInput[1] = p0[1];
        bnAddInput[2] = p1[0];
        bnAddInput[3] = p1[1];
        bool success;

        assembly {
            success := staticcall(sub(gas(), 2000), 6, bnAddInput, 128, p0, 64)
            switch success
            case 0 {
                invalid()
            }
        }
        require(success, "BLS: bn add call failed");
        return p0;
    }

    function mapToPoint(uint256 _x)
        internal
        pure
        returns (uint256[2] memory p)
    {
        require(_x < N, "mapToPointFT: invalid field element");
        uint256 x = _x;

        (, bool decision) = sqrt(x);

        uint256 a0 = mulmod(x, x, N);
        a0 = addmod(a0, 4, N);
        uint256 a1 = mulmod(x, Z0, N);
        uint256 a2 = mulmod(a1, a0, N);
        a2 = inverse(a2);
        a1 = mulmod(a1, a1, N);
        a1 = mulmod(a1, a2, N);

        // x1
        a1 = mulmod(x, a1, N);
        x = addmod(Z1, N - a1, N);
        // check curve
        a1 = mulmod(x, x, N);
        a1 = mulmod(a1, x, N);
        a1 = addmod(a1, 3, N);
        bool found;
        (a1, found) = sqrt(a1);
        if (found) {
            if (!decision) {
                a1 = N - a1;
            }
            return [x, a1];
        }

        // x2
        x = N - addmod(x, 1, N);
        // check curve
        a1 = mulmod(x, x, N);
        a1 = mulmod(a1, x, N);
        a1 = addmod(a1, 3, N);
        (a1, found) = sqrt(a1);
        if (found) {
            if (!decision) {
                a1 = N - a1;
            }
            return [x, a1];
        }

        // x3
        x = mulmod(a0, a0, N);
        x = mulmod(x, x, N);
        x = mulmod(x, a2, N);
        x = mulmod(x, a2, N);
        x = addmod(x, 1, N);
        // must be on curve
        a1 = mulmod(x, x, N);
        a1 = mulmod(a1, x, N);
        a1 = addmod(a1, 3, N);
        (a1, found) = sqrt(a1);
        require(found, "BLS: bad ft mapping implementation");
        if (!decision) {
            a1 = N - a1;
        }
        return [x, a1];
    }

    function isValidSignature(uint256[2] memory signature)
        internal
        pure
        returns (bool)
    {
        if ((signature[0] >= N) || (signature[1] >= N)) {
            return false;
        } else {
            return isOnCurveG1(signature);
        }
    }

    function isOnCurveG1(uint256[2] memory point)
        internal
        pure
        returns (bool _isOnCurve)
    {
        assembly {
            let t0 := mload(point)
            let t1 := mload(add(point, 32))
            let t2 := mulmod(t0, t0, N)
            t2 := mulmod(t2, t0, N)
            t2 := addmod(t2, 3, N)
            t1 := mulmod(t1, t1, N)
            _isOnCurve := eq(t1, t2)
        }
    }

    function isOnCurveG2(uint256[4] memory point)
        internal
        pure
        returns (bool _isOnCurve)
    {
        assembly {
            // x0, x1
            let t0 := mload(point)
            let t1 := mload(add(point, 32))
            // x0 ^ 2
            let t2 := mulmod(t0, t0, N)
            // x1 ^ 2
            let t3 := mulmod(t1, t1, N)
            // 3 * x0 ^ 2
            let t4 := add(add(t2, t2), t2)
            // 3 * x1 ^ 2
            let t5 := addmod(add(t3, t3), t3, N)
            // x0 * (x0 ^ 2 - 3 * x1 ^ 2)
            t2 := mulmod(add(t2, sub(N, t5)), t0, N)
            // x1 * (3 * x0 ^ 2 - x1 ^ 2)
            t3 := mulmod(add(t4, sub(N, t3)), t1, N)

            // x ^ 3 + b
            t0 := addmod(
                t2,
                0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5,
                N
            )
            t1 := addmod(
                t3,
                0x009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2,
                N
            )

            // y0, y1
            t2 := mload(add(point, 64))
            t3 := mload(add(point, 96))

            t4 := mulmod(addmod(t2, t3, N), addmod(t2, sub(N, t3), N), N)
            t3 := mulmod(shl(1, t2), t3, N)

            _isOnCurve := and(eq(t0, t4), eq(t1, t3))
        }
    }

    function sqrt(uint256 xx) internal pure returns (uint256 x, bool hasRoot) {
        x = ModexpSqrt.run(xx);
        hasRoot = mulmod(x, x, N) == xx;
    }

    function inverse(uint256 a) internal pure returns (uint256) {
        return ModexpInverse.run(a);
    }

    function hashToField(bytes32 domain, bytes memory messages)
        internal
        pure
        returns (uint256[2] memory)
    {
        bytes memory _msg = expandMsgTo96(domain, messages);
        uint256 u0;
        uint256 u1;
        uint256 a0;
        uint256 a1;
        assembly {
            let p := add(_msg, 24)
            u1 := and(mload(p), MASK24)
            p := add(_msg, 48)
            u0 := and(mload(p), MASK24)
            a0 := addmod(mulmod(u1, T24, N), u0, N)
            p := add(_msg, 72)
            u1 := and(mload(p), MASK24)
            p := add(_msg, 96)
            u0 := and(mload(p), MASK24)
            a1 := addmod(mulmod(u1, T24, N), u0, N)
        }
        return [a0, a1];
    }

    function expandMsgTo96(bytes32 domain, bytes memory message)
        internal
        pure
        returns (bytes memory)
    {
        uint256 t0 = message.length;
        bytes memory msg0 = new bytes(32 + t0 + 64 + 4);
        bytes memory out = new bytes(96);

        assembly {
            let p := add(msg0, 96)
            for {
                let z := 0
            } lt(z, t0) {
                z := add(z, 32)
            } {
                mstore(add(p, z), mload(add(message, add(z, 32))))
            }
            p := add(p, t0)

            mstore8(p, 0)
            p := add(p, 1)
            mstore8(p, 96)
            p := add(p, 1)
            mstore8(p, 0)
            p := add(p, 1)

            mstore(p, domain)
            p := add(p, 32)
            mstore8(p, 32)
        }
        bytes32 b0 = sha256(msg0);
        bytes32 bi;
        t0 = 32 + 34;

        assembly {
            mstore(msg0, t0)
        }
        assembly {
            mstore(add(msg0, 32), b0)
            mstore8(add(msg0, 64), 1)
            mstore(add(msg0, 65), domain)
            mstore8(add(msg0, add(32, 65)), 32)
        }

        bi = sha256(msg0);

        assembly {
            mstore(add(out, 32), bi)
        }
        assembly {
            let t := xor(b0, bi)
            mstore(add(msg0, 32), t)
            mstore8(add(msg0, 64), 2)
            mstore(add(msg0, 65), domain)
            mstore8(add(msg0, add(32, 65)), 32)
        }

        bi = sha256(msg0);

        assembly {
            mstore(add(out, 64), bi)
        }
        assembly {
            let t := xor(b0, bi)
            mstore(add(msg0, 32), t)
            mstore8(add(msg0, 64), 3)
            mstore(add(msg0, 65), domain)
            mstore8(add(msg0, add(32, 65)), 32)
        }

        bi = sha256(msg0);

        assembly {
            mstore(add(out, 96), bi)
        }

        return out;
    }
}

// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() {
        _transferOwnership(_msgSender());
    }

    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    function owner() public view virtual returns (address) {
        return _owner;
    }

    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Returns the address of the pending owner.
     */
    function pendingOwner() public view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
        _transferOwnership(sender);
    }
}

interface ISupraSValueFeed {
    function restrictedSetSupraStorage(uint64 _index, bytes32 _bytes) external;

    function restrictedSetTimestamp(uint256 _tradingPair, uint256 timestamp)
        external;

    function getTimestamp(uint256 _tradingPair) external view returns (uint256);

    function getSvalue(uint64 _pairIndex) external view returns (bytes32, bool);

    function getSvalues(uint64[] memory _pairIndexes)
        external
        view
        returns (bytes32[] memory, bool[] memory);
}

/// @title Supra SMR Block Utilities
/// @notice This library contains the data structures and functions for hashing SMR blocks.
/// @dev This library is primarily used by the SupraSValueFeedVerifier contract.
library Smr {
    /// @notice A vote is a block with a round number.
    /// @dev The library assumes the round number is passed in little endian format
    struct Vote {
        MinBlock smrBlock;
        // SPEC: smrBlock.round.to_le_bytes()
        bytes8 roundLE;
    }

    /// @notice A partial SMR block containing the bare-minimum for hashing
    struct MinBlock {
        uint64 round;
        uint128 timestamp;
        bytes32 author;
        bytes32 qcHash;
        bytes32[] batchHashes;
    }

    /// @notice An SMR Transaction
    struct MinTxn {
        bytes32[] clusterHashes;
        bytes32 sender;
        bytes10 protocol;
        bytes1 tx_sub_type;
    }

    /// @notice A partial SMR batch containing the bare-minimum for hashing
    /// @dev The library assumes that txnHashes is a list of keccak256 hashes of abi encoded SMR transaction
    struct MinBatch {
        bytes10 protocol;
        // SPEC: List of keccak256(Txn.clusterHashes, Txn.sender, Txn.protocol, Txn.tx_sub_type)
        bytes32[] txnHashes;
    }

    /// @notice An SMR Signed Coherent Cluster
    struct SignedCoherentCluster {
        CoherentCluster cc;
        bytes qc;
        uint256 round;
        Origin origin;
    }

    /// @notice An SMR Coherent Cluster containing the price data
    struct CoherentCluster {
        bytes32 dataHash;
        uint256[] pair;
        uint256[] prices;
        uint256[] timestamp;
        uint256[] decimals;
    }

    /// @notice An SMR Txn Sender
    struct Origin {
        bytes32 _publicKeyIdentity;
        uint256 _pubMemberIndex;
        uint256 _committeeIndex;
    }

    /// @notice Hash of a Signed Cluster for EVM
    /// @param scc The Signed Cluster to hash
    /// @return Hash of the Signed Cluster
    function hashCluster(SignedCoherentCluster memory scc)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(abi.encode(scc));
    }

    /// @notice Hash an SMR Transaction
    /// @param txn The SMR transaction to hash
    /// @return Hash of the SMR Transaction
    function hashTxn(MinTxn memory txn) internal pure returns (bytes32) {
        bytes memory clustersConcat = abi.encodePacked(txn.clusterHashes);
        return
            keccak256(
                abi.encodePacked(
                    clustersConcat,
                    txn.sender,
                    txn.protocol,
                    txn.tx_sub_type
                )
            );
    }

    /// @notice Hash an SMR Batch
    /// @param batch The SMR batch to hash
    /// @return Hash of the SMR Batch
    function hashBatch(MinBatch memory batch) internal pure returns (bytes32) {
        bytes32 txnsHash = keccak256(abi.encodePacked(batch.txnHashes));
        return keccak256(abi.encodePacked(batch.protocol, txnsHash));
    }

    /// @notice Hash an SMR Vote
    /// @param vote The SMR vote to hash
    /// @return Hash of the SMR Vote
    function hashVote(Vote memory vote) internal pure returns (bytes32) {
        bytes32 batchesHash = keccak256(
            abi.encodePacked(vote.smrBlock.batchHashes)
        );
        bytes32 blockHash = keccak256(
            abi.encodePacked(
                vote.smrBlock.round,
                vote.smrBlock.timestamp,
                vote.smrBlock.author,
                vote.smrBlock.qcHash,
                batchesHash
            )
        );
        return keccak256(abi.encodePacked(blockHash, vote.roundLE));
    }
}

/// @title Supra Oracle Value Feed Verifier Contract
/// @notice This contract verifies Oracle SMR Transactions using BLS Signatures and stores the price data
/// @dev The storage is done in a separate contract called `SupraSValueFeedStorage`
contract SupraSValueFeedVerifier is Ownable2Step {
    /// @notice It is identification that is common for both client and contract
    /// @dev It is BLS signature verification dependency mostly keccak256 hash of some input
    bytes32 domain;

    /// @notice The current contract authority
    /// @dev It is the BN254 public key of the committee
    uint256[4] publicKey;

    ISupraSValueFeed public immutable supraSValueFeedStorage;

    /// @dev Set of verified votes to minimize computation
    mapping(bytes32 => bool) verifiedVotes;
    /// @dev Set of processed transactions to prevent replay attacks
    mapping(bytes32 => bool) processedTxns;

    uint256 internal immutable blsPrecompileGasCost;

    constructor(
        bytes32 _domain,
        address _supraSValueFeedStorage,
        uint256[4] memory _publicKey,
        uint256 _blsPrecompileGasCost
    ) {
        domain = _domain;
        supraSValueFeedStorage = ISupraSValueFeed(_supraSValueFeedStorage);
        publicKey = _publicKey;
        blsPrecompileGasCost = _blsPrecompileGasCost;
    }

    error InvalidBatch();
    error InvalidTransaction();
    error DuplicateCluster();
    error ClusterNotVerified();
    error BLSInvalidPubllicKeyorSignaturePoints();
    error BLSIncorrectInputMessaage();

    event PublicKeyUpdated(uint256[4] publicKey);

    /// @notice Verify and mark a vote as verified.
    /// @param vote The vote to be verified.
    /// @param sig The signature associated with the vote.
    /// @dev This function verifies the given vote by checking if it has already been verified or if the signature is valid.
    ///      If the vote is verified, it is marked as verified by updating the `verifiedVotes` mapping.
    function requireVoteVerified(Smr.Vote memory vote, uint256[2] calldata sig)
        internal
    {
        bytes32 smrVoteHash = Smr.hashVote(vote);
        if (verifiedVotes[smrVoteHash]) {
            return;
        }

        requireHashVerified(bytes.concat(smrVoteHash), sig);
        verifiedVotes[smrVoteHash] = true;
    }

    /// @notice Verify and process an Oracle Transaction
    /// @dev The vote hash is cached to avoid re-verifying BLS signatures
    /// @dev Each transaction contains price data for multiple pairs
    /// @dev The price data is stored in a separate contract
    /// @dev Stale price data is ignored
    /// @param vote The SMR Vote the transaction is part of
    /// @param smrBatch The SMR Batch the transaction is part of
    /// @param smrTxn The SMR Transaction
    /// @param scc The Signed Coherent Cluster containing the price data
    /// @param batchIdx The index of the batch in the vote
    /// @param txnIdx The index of the transaction in the batch
    /// @param clusterIdx the index of the EVM cluster hash in the transaction
    /// @param sig The BLS signature of the vote, signed by the contract's authority
    function processCluster(
        Smr.Vote memory vote,
        Smr.MinBatch memory smrBatch,
        Smr.MinTxn memory smrTxn,
        Smr.SignedCoherentCluster memory scc,
        uint256 batchIdx,
        uint256 txnIdx,
        uint256 clusterIdx,
        uint256[2] calldata sig
    ) external {
        requireVoteVerified(vote, sig);
        bytes32 batchHash = Smr.hashBatch(smrBatch);
        if (vote.smrBlock.batchHashes[batchIdx] != batchHash) {
            revert InvalidBatch();
        }
        bytes32 txnHash = Smr.hashTxn(smrTxn);
        if (smrBatch.txnHashes[txnIdx] != txnHash) {
            revert InvalidTransaction();
        }
        if (processedTxns[txnHash]) {
            revert DuplicateCluster();
        }
        processedTxns[txnHash] = true;
        bytes32 sccHash = Smr.hashCluster(scc);

        if (smrTxn.clusterHashes[clusterIdx] != sccHash) {
            revert ClusterNotVerified();
        }
        Smr.CoherentCluster memory cluster = scc.cc;
        uint256 round = scc.round;

        for (uint256 i = 0; i < cluster.pair.length; i++) {
            uint256 pair = cluster.pair[i];
            uint256 timestamp = cluster.timestamp[i];
            uint256 prevTimestamp = supraSValueFeedStorage.getTimestamp(pair);
            if (prevTimestamp > timestamp) {
                continue;
            }
            supraSValueFeedStorage.restrictedSetTimestamp(pair, timestamp);
            packData(
                pair,
                round,
                cluster.decimals[i],
                timestamp,
                cluster.prices[i]
            );
        }
    }

    function packData(
        uint256 _pair,
        uint256 _round,
        uint256 _decimals,
        uint256 _time,
        uint256 _price
    ) internal {
        bytes8 r = bytes8(bytes32(uint256(_round)) << 192);
        bytes1 d = bytes1(bytes32(uint256(_decimals)) << 248);
        bytes8 t = bytes8(bytes32(uint256(_time)) << 192);
        bytes12 p = bytes12(bytes32(uint256(_price)) << 160);
        supraSValueFeedStorage.restrictedSetSupraStorage(
            uint64(_pair),
            bytes32(abi.encodePacked(r, d, t, p))
        );
    }

    /// @dev Requires the provided message to be verified using the contract's authority public key and BLS signature.
    /// @param _message The message to be verified.
    /// @param _signature The BLS signature of the message.
    /// @dev This function verifies the BLS signature by calling the BLS precompile contract and checks if the message matches the provided signature.
    /// @dev If the signature verification fails or if there is an issue with the BLS precompile contract call, the function reverts with an error.
    function requireHashVerified(
        bytes memory _message,
        uint256[2] calldata _signature
    ) internal view {
        bool callSuccess;
        bool checkSuccess;
        (checkSuccess, callSuccess) = BLS.verifySingle(
            _signature,
            publicKey,
            BLS.hashToPoint(domain, _message),
            blsPrecompileGasCost
        );
        if (!callSuccess) {
            revert BLSInvalidPubllicKeyorSignaturePoints();
        }
        if (!checkSuccess) {
            revert BLSIncorrectInputMessaage();
        }
    }

    /// @notice Update the contract authority
    /// @dev WARN: The validity of the public key is not verfied
    /// @param _publicKey The new contract authority (BN254 public key)
    // TODO: should be signed by old public key instead
    function updatePublicKey(uint256[4] memory _publicKey) public onlyOwner {
        publicKey = _publicKey;

        emit PublicKeyUpdated(_publicKey);
    }

    /// @notice get the current contract authority
    /// @dev The BN254 public key of the Oracle Committee
    /// @return The current contract authority
    function checkPublicKey() external view returns (uint256[4] memory) {
        return publicKey;
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"bytes32","name":"_domain","internalType":"bytes32"},{"type":"address","name":"_supraSValueFeedStorage","internalType":"address"},{"type":"uint256[4]","name":"_publicKey","internalType":"uint256[4]"},{"type":"uint256","name":"_blsPrecompileGasCost","internalType":"uint256"}]},{"type":"error","name":"BLSIncorrectInputMessaage","inputs":[]},{"type":"error","name":"BLSInvalidPubllicKeyorSignaturePoints","inputs":[]},{"type":"error","name":"ClusterNotVerified","inputs":[]},{"type":"error","name":"DuplicateCluster","inputs":[]},{"type":"error","name":"InvalidBatch","inputs":[]},{"type":"error","name":"InvalidTransaction","inputs":[]},{"type":"event","name":"OwnershipTransferStarted","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PublicKeyUpdated","inputs":[{"type":"uint256[4]","name":"publicKey","internalType":"uint256[4]","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[4]","name":"","internalType":"uint256[4]"}],"name":"checkPublicKey","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"processCluster","inputs":[{"type":"tuple","name":"vote","internalType":"struct Smr.Vote","components":[{"type":"tuple","name":"smrBlock","internalType":"struct Smr.MinBlock","components":[{"type":"uint64","name":"round","internalType":"uint64"},{"type":"uint128","name":"timestamp","internalType":"uint128"},{"type":"bytes32","name":"author","internalType":"bytes32"},{"type":"bytes32","name":"qcHash","internalType":"bytes32"},{"type":"bytes32[]","name":"batchHashes","internalType":"bytes32[]"}]},{"type":"bytes8","name":"roundLE","internalType":"bytes8"}]},{"type":"tuple","name":"smrBatch","internalType":"struct Smr.MinBatch","components":[{"type":"bytes10","name":"protocol","internalType":"bytes10"},{"type":"bytes32[]","name":"txnHashes","internalType":"bytes32[]"}]},{"type":"tuple","name":"smrTxn","internalType":"struct Smr.MinTxn","components":[{"type":"bytes32[]","name":"clusterHashes","internalType":"bytes32[]"},{"type":"bytes32","name":"sender","internalType":"bytes32"},{"type":"bytes10","name":"protocol","internalType":"bytes10"},{"type":"bytes1","name":"tx_sub_type","internalType":"bytes1"}]},{"type":"tuple","name":"scc","internalType":"struct Smr.SignedCoherentCluster","components":[{"type":"tuple","name":"cc","internalType":"struct Smr.CoherentCluster","components":[{"type":"bytes32","name":"dataHash","internalType":"bytes32"},{"type":"uint256[]","name":"pair","internalType":"uint256[]"},{"type":"uint256[]","name":"prices","internalType":"uint256[]"},{"type":"uint256[]","name":"timestamp","internalType":"uint256[]"},{"type":"uint256[]","name":"decimals","internalType":"uint256[]"}]},{"type":"bytes","name":"qc","internalType":"bytes"},{"type":"uint256","name":"round","internalType":"uint256"},{"type":"tuple","name":"origin","internalType":"struct Smr.Origin","components":[{"type":"bytes32","name":"_publicKeyIdentity","internalType":"bytes32"},{"type":"uint256","name":"_pubMemberIndex","internalType":"uint256"},{"type":"uint256","name":"_committeeIndex","internalType":"uint256"}]}]},{"type":"uint256","name":"batchIdx","internalType":"uint256"},{"type":"uint256","name":"txnIdx","internalType":"uint256"},{"type":"uint256","name":"clusterIdx","internalType":"uint256"},{"type":"uint256[2]","name":"sig","internalType":"uint256[2]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ISupraSValueFeed"}],"name":"supraSValueFeedStorage","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updatePublicKey","inputs":[{"type":"uint256[4]","name":"_publicKey","internalType":"uint256[4]"}]}]
              

Contract Creation Code

0x60c06040523480156200001157600080fd5b506040516200302a3803806200302a83398101604081905262000034916200014c565b6200003f336200006e565b60028490556001600160a01b038316608052620000606003836004620000dc565b5060a0525062000200915050565b600180546001600160a01b031916905562000089816200008c565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82600481019282156200010d579160200282015b828111156200010d578251825591602001919060010190620000f0565b506200011b9291506200011f565b5090565b5b808211156200011b576000815560010162000120565b634e487b7160e01b600052604160045260246000fd5b60008060008060e085870312156200016357600080fd5b8451602080870151919550906001600160a01b03811681146200018557600080fd5b9350605f860187136200019757600080fd5b604051608081016001600160401b0381118282101715620001bc57620001bc62000136565b6040528060c0880189811115620001d257600080fd5b604089015b81811015620001f05780518352918401918401620001d7565b5051969995985090965050505050565b60805160a051612df06200023a6000396000610a7d01526000818160b0015281816103eb015281816104a701526108190152612df06000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b14610107578063c1b8252714610118578063e30c39781461012b578063f2fde38b1461013c57600080fd5b80631f3ac9581461008d5780636a4e3e39146100ab5780637861c629146100ea57806379ba5097146100ff575b600080fd5b61009561014f565b6040516100a29190612419565b60405180910390f35b6100d27f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100a2565b6100fd6100f83660046124fc565b61018a565b005b6100fd6101da565b6000546001600160a01b03166100d2565b6100fd6101263660046129c7565b610259565b6001546001600160a01b03166100d2565b6100fd61014a366004612aa2565b610578565b61015761236c565b6040805160808101918290529060039060049082845b81548152602001906001019080831161016d575050505050905090565b6101926105e9565b61019f600382600461238a565b507f2158ce0319864975538049b324ba4f745f079dd8f5e32d5923585df31d3f4523816040516101cf9190612419565b60405180910390a150565b60015433906001600160a01b0316811461024d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61025681610645565b50565b610263888261065e565b600061026e886106d0565b905080896000015160800151868151811061028b5761028b612ad2565b6020026020010151146102b1576040516333b094a160e01b815260040160405180910390fd5b60006102bc8861073f565b905080896020015186815181106102d5576102d5612ad2565b6020026020010151146102fb5760405163280503e760e11b815260040160405180910390fd5b60008181526008602052604090205460ff161561032b576040516333984a1960e01b815260040160405180910390fd5b6000818152600860205260408120805460ff1916600117905561034d8861078b565b9050808960000151868151811061036657610366612ad2565b60200260200101511461038c5760405163e522226b60e01b815260040160405180910390fd5b8751604089015160005b826020015151811015610568576000836020015182815181106103bb576103bb612ad2565b602002602001015190506000846060015183815181106103dd576103dd612ad2565b6020026020010151905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b633620c846040518263ffffffff1660e01b815260040161043791815260200190565b602060405180830381865afa158015610454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104789190612ae8565b90508181111561048a57505050610556565b604051630305b81160e21b815260048101849052602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630c16e04490604401600060405180830381600087803b1580156104f357600080fd5b505af1158015610507573d6000803e3d6000fd5b5050505061055283868860800151878151811061052657610526612ad2565b6020026020010151858a60400151898151811061054557610545612ad2565b60200260200101516107bb565b5050505b8061056081612b17565b915050610396565b5050505050505050505050505050565b6105806105e9565b600180546001600160a01b0383166001600160a01b031990911681179091556105b16000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000546001600160a01b031633146106435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610244565b565b600180546001600160a01b0319169055610256816108c6565b600061066983610916565b60008181526007602052604090205490915060ff161561068857505050565b6106b38160405160200161069e91815260200190565b60405160208183030381529060405283610a17565b6000908152600760205260409020805460ff191660011790555050565b60008082602001516040516020016106e89190612b30565b60408051601f1981840301815290829052805160209182012085516001600160b01b03191691830191909152602a82018190529150604a015b60405160208183030381529060405280519060200120915050919050565b60008082600001516040516020016107579190612b30565b6040516020818303038152906040529050808360200151846040015185606001516040516020016107219493929190612b8a565b60008160405160200161079e9190612c34565b604051602081830303815290604052805190602001209050919050565b60405160c085811b6001600160c01b0319818116602085015260f887901b6001600160f81b0319811660288601529286901b908116602985015260a085901b6001600160a01b03198116603186015291939091906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639b0bb736908b90603d0160405160208183030381529060405261085d90612d1b565b6040516001600160e01b031960e085901b1681526001600160401b0390921660048301526024820152604401600060405180830381600087803b1580156108a357600080fd5b505af11580156108b7573d6000803e3d6000fd5b50505050505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000808260000151608001516040516020016109329190612b30565b60408051601f1981840301815282825280516020918201208651805181840151948201516060909201519296506000956109b695919491939188910160c09590951b6001600160c01b031916855260809390931b6fffffffffffffffffffffffffffffffff1916600885015260188401919091526038830152605882015260780190565b6040516020818303038152906040528051906020012090508084602001516040516020016109f89291909182526001600160c01b031916602082015260280190565b6040516020818303038152906040528051906020012092505050919050565b6040805180820182526000918291610aa1918590600290839083908082843760009201919091525050604080516080810191829052915060039060049082845b815481526020019060010190808311610a57575050505050610a7b60025488610ae7565b7f0000000000000000000000000000000000000000000000000000000000000000610bbf565b9250905081610ac357604051636cc2939360e11b815260040160405180910390fd5b80610ae157604051632246067560e01b815260040160405180910390fd5b50505050565b610aef6123c8565b6000610afb8484610d8f565b90506000610b0f82825b6020020151610e4a565b90506000610b1e836001610b05565b9050610b2861236c565b825181526020808401518282015282516040808401919091529083015160608301526000908460808460066107d05a03fa90508080610b6357fe5b5080610bb15760405162461bcd60e51b815260206004820152601760248201527f424c533a20626e206164642063616c6c206661696c65640000000000000000006044820152606401610244565b509193505050505b92915050565b600080600060405180610180016040528088600060028110610be357610be3612ad2565b6020020151815260200188600160028110610c0057610c00612ad2565b602002015181526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec81526020017f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d815260200186600060028110610cb557610cb5612ad2565b6020020151815260200186600160028110610cd257610cd2612ad2565b6020020151815260200187600160048110610cef57610cef612ad2565b6020020151815260200187600060048110610d0c57610d0c612ad2565b6020020151815260200187600360048110610d2957610d29612ad2565b6020020151815260200187600260048110610d4657610d46612ad2565b602002015190529050610d576123e6565b60006020826101808560088afa905080610d7a5760008094509450505050610d86565b50511515925060019150505b94509492505050565b610d976123c8565b6000610da38484611220565b9050600080600080601885016001600160c01b0381511693506030860190506001600160c01b038151169450600080516020612d9b83398151915285600080516020612d9b833981519152600160c01b870908604887015160608801516001600160c01b0390811697501694509250600080516020612d9b83398151915290508481600160c01b860908604080518082019091529283526020830152509695505050505050565b610e526123c8565b600080516020612d9b8339815191528210610ebb5760405162461bcd60e51b815260206004820152602360248201527f6d6170546f506f696e7446543a20696e76616c6964206669656c6420656c656d604482015262195b9d60ea1b6064820152608401610244565b816000610ec7826114bc565b9150506000600080516020612d9b83398151915280610ee857610ee8612d42565b8384099050600080516020612d9b8339815191526004820890506000600080516020612d9b83398151915277b3c4d79d41a91759a9e4c7e359b6b89eaec68e62effffffd850990506000600080516020612d9b8339815191528383099050610f4f816114e5565b9050600080516020612d9b8339815191528283099150600080516020612d9b8339815191528183099150600080516020612d9b8339815191528286099150600080516020612d9b833981519152610fb483600080516020612d9b833981519152612d58565b7759e26bcea0d48bacd4f263f1acdb5c4f5763473177fffffe089450600080516020612d9b8339815191528586099150600080516020612d9b8339815191528583099150600080516020612d9b8339815191526003830891506000611018836114bc565b9093509050801561106057846110435761104083600080516020612d9b833981519152612d58565b92505b505060408051808201909152938452602084015250909392505050565b600080516020612d9b8339815191526001870861108b90600080516020612d9b833981519152612d58565b9550600080516020612d9b8339815191528687099250600080516020612d9b8339815191528684099250600080516020612d9b8339815191526003840892506110d3836114bc565b909350905080156110fb57846110435761104083600080516020612d9b833981519152612d58565b600080516020612d9b8339815191528485099550600080516020612d9b8339815191528687099550600080516020612d9b8339815191528287099550600080516020612d9b8339815191528287099550600080516020612d9b833981519152600187089550600080516020612d9b8339815191528687099250600080516020612d9b8339815191528684099250600080516020612d9b8339815191526003840892506111a6836114bc565b9093509050806112035760405162461bcd60e51b815260206004820152602260248201527f424c533a20626164206674206d617070696e6720696d706c656d656e7461746960448201526137b760f11b6064820152608401610244565b846110435761104083600080516020612d9b833981519152612d58565b80516060906000611232826020612d6b565b61123d906040612d6b565b611248906004612d6b565b6001600160401b0381111561125f5761125f61244a565b6040519080825280601f01601f191660200182016040528015611289576020820181803683370190505b5060408051606080825260808201909252919250600091906020820181803683370190505090506060820160005b848110156112d157602081880181015183830152016112b7565b50830160008153600101606081536001016000815360018101879052602101602081535060006002836040516113079190612d7e565b602060405180830381855afa158015611324573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906113479190612ae8565b905060006042945084845281602085015260016040850153604184018890526020606185015360028460405161137d9190612d7e565b602060405180830381855afa15801561139a573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906113bd9190612ae8565b9050806020840152808218806020860152506002604085015360418401889052602060618501536002846040516113f49190612d7e565b602060405180830381855afa158015611411573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906114349190612ae8565b90508060408401528082188060208601525060036040850153604184018890526020606185015360028460405161146b9190612d7e565b602060405180830381855afa158015611488573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906114ab9190612ae8565b606084015250909695505050505050565b6000806114c8836114f0565b915082600080516020612d9b833981519152838409149050915091565b6000610bb982611c25565b6000600080516020612d9b8339815191528083840991508083830981838209828283098385830984848309858484098684850997508684840987858409945087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087838a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985050868889099750868889099750868889099750868889099750868889099750868889099750868489099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868689099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868189099750508587880996508587880996508587880996508585880996508587880996508587880996508587880996508585880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508583880996508587880996508587880996508587880996508587880996508581880996508587880996508587880996508587880996508587880996508583880996508587880996508587880996508587880996508584880996508587880996508587880996508587880996508587880996508587880996508581880996505050505050808283099392505050565b6000600080516020612d9b8339815191528083840991508083830981838209828283098385830984848309858484098684850997508684840987858409945087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087838a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985050868889099750868889099750868889099750868889099750868889099750868889099750868489099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868689099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868189099750508587880996508587880996508587880996508585880996508587880996508587880996508587880996508585880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508583880996508587880996508587880996508587880996508587880996508581880996505050838586099450838586099450838586099450838586099450838186099450508284850993508284850993508284850993508281850993508284850993508284850993508285850993508284850993508284850993508284850993508284850993508284850993508284850993508281850995945050505050565b60405180608001604052806004906020820280368337509192915050565b82600481019282156123b8579160200282015b828111156123b857825182559160200191906001019061239d565b506123c4929150612404565b5090565b60405180604001604052806002906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b808211156123c45760008155600101612405565b60808101818360005b6004811015612441578151835260209283019290910190600101612422565b50505092915050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156124825761248261244a565b60405290565b604080519081016001600160401b03811182821017156124825761248261244a565b60405160a081016001600160401b03811182821017156124825761248261244a565b604051601f8201601f191681016001600160401b03811182821017156124f4576124f461244a565b604052919050565b60006080828403121561250e57600080fd5b82601f83011261251d57600080fd5b612525612460565b80608084018581111561253757600080fd5b845b81811015612551578035845260209384019301612539565b509095945050505050565b600082601f83011261256d57600080fd5b813560206001600160401b038211156125885761258861244a565b8160051b6125978282016124cc565b92835284810182019282810190878511156125b157600080fd5b83870192505b848310156125d0578235825291830191908301906125b7565b979650505050505050565b80356001600160c01b0319811681146125f357600080fd5b919050565b60006040828403121561260a57600080fd5b612612612488565b905081356001600160401b038082111561262b57600080fd5b9083019060a0828603121561263f57600080fd5b6126476124aa565b8235828116811461265757600080fd5b815260208301356fffffffffffffffffffffffffffffffff8116811461267c57600080fd5b8060208301525060408301356040820152606083013560608201526080830135828111156126a957600080fd5b6126b58782860161255c565b6080830152508352506126cc9050602083016125db565b602082015292915050565b80356001600160b01b0319811681146125f357600080fd5b60006040828403121561270157600080fd5b612709612488565b9050612714826126d7565b815260208201356001600160401b0381111561272f57600080fd5b61273b8482850161255c565b60208301525092915050565b60006080828403121561275957600080fd5b612761612460565b905081356001600160401b0381111561277957600080fd5b6127858482850161255c565b8252506020820135602082015261279e604083016126d7565b604082015260608201356001600160f81b0319811681146127be57600080fd5b606082015292915050565b600082601f8301126127da57600080fd5b81356001600160401b038111156127f3576127f361244a565b612806601f8201601f19166020016124cc565b81815284602083860101111561281b57600080fd5b816020850160208301376000918101602001919091529392505050565b60006060828403121561284a57600080fd5b604051606081018181106001600160401b038211171561286c5761286c61244a565b80604052508091508235815260208301356020820152604083013560408201525092915050565b600060c082840312156128a557600080fd5b6128ad612460565b905081356001600160401b03808211156128c657600080fd5b9083019060a082860312156128da57600080fd5b6128e26124aa565b823581526020830135828111156128f857600080fd5b6129048782860161255c565b60208301525060408301358281111561291c57600080fd5b6129288782860161255c565b60408301525060608301358281111561294057600080fd5b61294c8782860161255c565b60608301525060808301358281111561296457600080fd5b6129708782860161255c565b6080830152508352602084013591508082111561298c57600080fd5b50612999848285016127c9565b602083015250604082013560408201526127be8360608401612838565b8060408101831015610bb957600080fd5b600080600080600080600080610120898b0312156129e457600080fd5b88356001600160401b03808211156129fb57600080fd5b612a078c838d016125f8565b995060208b0135915080821115612a1d57600080fd5b612a298c838d016126ef565b985060408b0135915080821115612a3f57600080fd5b612a4b8c838d01612747565b975060608b0135915080821115612a6157600080fd5b50612a6e8b828c01612893565b9550506080890135935060a0890135925060c08901359150612a938a60e08b016129b6565b90509295985092959890939650565b600060208284031215612ab457600080fd5b81356001600160a01b0381168114612acb57600080fd5b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612afa57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201612b2957612b29612b01565b5060010190565b815160009082906020808601845b83811015612b5a57815185529382019390820190600101612b3e565b50929695505050505050565b60005b83811015612b81578181015183820152602001612b69565b50506000910152565b60008551612b9c818460208a01612b66565b91909101938452506001600160b01b03199190911660208301526001600160f81b031916602a820152602b01919050565b600081518084526020808501945080840160005b83811015612bfd57815187529582019590820190600101612be1565b509495945050505050565b60008151808452612c20816020860160208601612b66565b601f01601f19169290920160200192915050565b602081526000825160c06020840152805160e0840152602081015160a0610100850152612c65610180850182612bcd565b9050604082015160df198086840301610120870152612c848383612bcd565b9250606084015191508086840301610140870152612ca28383612bcd565b92506080840151935080868403016101608701525050612cc28183612bcd565b9150506020840151601f19848303016040850152612ce08282612c08565b915050604084015160608401526060840151612d1360808501828051825260208082015190830152604090810151910152565b509392505050565b80516020808301519190811015612d3c576000198160200360031b1b821691505b50919050565b634e487b7160e01b600052601260045260246000fd5b81810381811115610bb957610bb9612b01565b80820180821115610bb957610bb9612b01565b60008251612d90818460208701612b66565b919091019291505056fe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47a2646970667358221220d8058479b55748e685303b1f2db5127da227eb9ebc2b465d64c3237cfe4e27d764736f6c63430008130033b2b5ca56968e81bf5845ee0e6c6888aff023d02790943f6947a389b2e2892ea50000000000000000000000008a358f391d93f7558d5f5e61bdf533e2cc3cf7a32db4607bd0a726aa5aaee95a28f2139b7d7cc7895ccf02aea2d01efda69014ed113b9e1f6557a92f5b3139a233a80f30a26949e7c74caa91c763f995ba22f5a30d4fedc4e0ea8d205c2f2d58c01a2c47f690c493ae2625d18150cd9340db07090e9860693ee0589849d34b85e832d4c89c3ad58fb85c463a09f17f1b28931260000000000000000000000000000000000000000000000000000000000001b9ed

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100885760003560e01c80638da5cb5b1161005b5780638da5cb5b14610107578063c1b8252714610118578063e30c39781461012b578063f2fde38b1461013c57600080fd5b80631f3ac9581461008d5780636a4e3e39146100ab5780637861c629146100ea57806379ba5097146100ff575b600080fd5b61009561014f565b6040516100a29190612419565b60405180910390f35b6100d27f0000000000000000000000008a358f391d93f7558d5f5e61bdf533e2cc3cf7a381565b6040516001600160a01b0390911681526020016100a2565b6100fd6100f83660046124fc565b61018a565b005b6100fd6101da565b6000546001600160a01b03166100d2565b6100fd6101263660046129c7565b610259565b6001546001600160a01b03166100d2565b6100fd61014a366004612aa2565b610578565b61015761236c565b6040805160808101918290529060039060049082845b81548152602001906001019080831161016d575050505050905090565b6101926105e9565b61019f600382600461238a565b507f2158ce0319864975538049b324ba4f745f079dd8f5e32d5923585df31d3f4523816040516101cf9190612419565b60405180910390a150565b60015433906001600160a01b0316811461024d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61025681610645565b50565b610263888261065e565b600061026e886106d0565b905080896000015160800151868151811061028b5761028b612ad2565b6020026020010151146102b1576040516333b094a160e01b815260040160405180910390fd5b60006102bc8861073f565b905080896020015186815181106102d5576102d5612ad2565b6020026020010151146102fb5760405163280503e760e11b815260040160405180910390fd5b60008181526008602052604090205460ff161561032b576040516333984a1960e01b815260040160405180910390fd5b6000818152600860205260408120805460ff1916600117905561034d8861078b565b9050808960000151868151811061036657610366612ad2565b60200260200101511461038c5760405163e522226b60e01b815260040160405180910390fd5b8751604089015160005b826020015151811015610568576000836020015182815181106103bb576103bb612ad2565b602002602001015190506000846060015183815181106103dd576103dd612ad2565b6020026020010151905060007f0000000000000000000000008a358f391d93f7558d5f5e61bdf533e2cc3cf7a36001600160a01b031663b633620c846040518263ffffffff1660e01b815260040161043791815260200190565b602060405180830381865afa158015610454573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104789190612ae8565b90508181111561048a57505050610556565b604051630305b81160e21b815260048101849052602481018390527f0000000000000000000000008a358f391d93f7558d5f5e61bdf533e2cc3cf7a36001600160a01b031690630c16e04490604401600060405180830381600087803b1580156104f357600080fd5b505af1158015610507573d6000803e3d6000fd5b5050505061055283868860800151878151811061052657610526612ad2565b6020026020010151858a60400151898151811061054557610545612ad2565b60200260200101516107bb565b5050505b8061056081612b17565b915050610396565b5050505050505050505050505050565b6105806105e9565b600180546001600160a01b0383166001600160a01b031990911681179091556105b16000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6000546001600160a01b031633146106435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610244565b565b600180546001600160a01b0319169055610256816108c6565b600061066983610916565b60008181526007602052604090205490915060ff161561068857505050565b6106b38160405160200161069e91815260200190565b60405160208183030381529060405283610a17565b6000908152600760205260409020805460ff191660011790555050565b60008082602001516040516020016106e89190612b30565b60408051601f1981840301815290829052805160209182012085516001600160b01b03191691830191909152602a82018190529150604a015b60405160208183030381529060405280519060200120915050919050565b60008082600001516040516020016107579190612b30565b6040516020818303038152906040529050808360200151846040015185606001516040516020016107219493929190612b8a565b60008160405160200161079e9190612c34565b604051602081830303815290604052805190602001209050919050565b60405160c085811b6001600160c01b0319818116602085015260f887901b6001600160f81b0319811660288601529286901b908116602985015260a085901b6001600160a01b03198116603186015291939091906001600160a01b037f0000000000000000000000008a358f391d93f7558d5f5e61bdf533e2cc3cf7a31690639b0bb736908b90603d0160405160208183030381529060405261085d90612d1b565b6040516001600160e01b031960e085901b1681526001600160401b0390921660048301526024820152604401600060405180830381600087803b1580156108a357600080fd5b505af11580156108b7573d6000803e3d6000fd5b50505050505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000808260000151608001516040516020016109329190612b30565b60408051601f1981840301815282825280516020918201208651805181840151948201516060909201519296506000956109b695919491939188910160c09590951b6001600160c01b031916855260809390931b6fffffffffffffffffffffffffffffffff1916600885015260188401919091526038830152605882015260780190565b6040516020818303038152906040528051906020012090508084602001516040516020016109f89291909182526001600160c01b031916602082015260280190565b6040516020818303038152906040528051906020012092505050919050565b6040805180820182526000918291610aa1918590600290839083908082843760009201919091525050604080516080810191829052915060039060049082845b815481526020019060010190808311610a57575050505050610a7b60025488610ae7565b7f000000000000000000000000000000000000000000000000000000000001b9ed610bbf565b9250905081610ac357604051636cc2939360e11b815260040160405180910390fd5b80610ae157604051632246067560e01b815260040160405180910390fd5b50505050565b610aef6123c8565b6000610afb8484610d8f565b90506000610b0f82825b6020020151610e4a565b90506000610b1e836001610b05565b9050610b2861236c565b825181526020808401518282015282516040808401919091529083015160608301526000908460808460066107d05a03fa90508080610b6357fe5b5080610bb15760405162461bcd60e51b815260206004820152601760248201527f424c533a20626e206164642063616c6c206661696c65640000000000000000006044820152606401610244565b509193505050505b92915050565b600080600060405180610180016040528088600060028110610be357610be3612ad2565b6020020151815260200188600160028110610c0057610c00612ad2565b602002015181526020017f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c281526020017f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed81526020017f275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec81526020017f1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d815260200186600060028110610cb557610cb5612ad2565b6020020151815260200186600160028110610cd257610cd2612ad2565b6020020151815260200187600160048110610cef57610cef612ad2565b6020020151815260200187600060048110610d0c57610d0c612ad2565b6020020151815260200187600360048110610d2957610d29612ad2565b6020020151815260200187600260048110610d4657610d46612ad2565b602002015190529050610d576123e6565b60006020826101808560088afa905080610d7a5760008094509450505050610d86565b50511515925060019150505b94509492505050565b610d976123c8565b6000610da38484611220565b9050600080600080601885016001600160c01b0381511693506030860190506001600160c01b038151169450600080516020612d9b83398151915285600080516020612d9b833981519152600160c01b870908604887015160608801516001600160c01b0390811697501694509250600080516020612d9b83398151915290508481600160c01b860908604080518082019091529283526020830152509695505050505050565b610e526123c8565b600080516020612d9b8339815191528210610ebb5760405162461bcd60e51b815260206004820152602360248201527f6d6170546f506f696e7446543a20696e76616c6964206669656c6420656c656d604482015262195b9d60ea1b6064820152608401610244565b816000610ec7826114bc565b9150506000600080516020612d9b83398151915280610ee857610ee8612d42565b8384099050600080516020612d9b8339815191526004820890506000600080516020612d9b83398151915277b3c4d79d41a91759a9e4c7e359b6b89eaec68e62effffffd850990506000600080516020612d9b8339815191528383099050610f4f816114e5565b9050600080516020612d9b8339815191528283099150600080516020612d9b8339815191528183099150600080516020612d9b8339815191528286099150600080516020612d9b833981519152610fb483600080516020612d9b833981519152612d58565b7759e26bcea0d48bacd4f263f1acdb5c4f5763473177fffffe089450600080516020612d9b8339815191528586099150600080516020612d9b8339815191528583099150600080516020612d9b8339815191526003830891506000611018836114bc565b9093509050801561106057846110435761104083600080516020612d9b833981519152612d58565b92505b505060408051808201909152938452602084015250909392505050565b600080516020612d9b8339815191526001870861108b90600080516020612d9b833981519152612d58565b9550600080516020612d9b8339815191528687099250600080516020612d9b8339815191528684099250600080516020612d9b8339815191526003840892506110d3836114bc565b909350905080156110fb57846110435761104083600080516020612d9b833981519152612d58565b600080516020612d9b8339815191528485099550600080516020612d9b8339815191528687099550600080516020612d9b8339815191528287099550600080516020612d9b8339815191528287099550600080516020612d9b833981519152600187089550600080516020612d9b8339815191528687099250600080516020612d9b8339815191528684099250600080516020612d9b8339815191526003840892506111a6836114bc565b9093509050806112035760405162461bcd60e51b815260206004820152602260248201527f424c533a20626164206674206d617070696e6720696d706c656d656e7461746960448201526137b760f11b6064820152608401610244565b846110435761104083600080516020612d9b833981519152612d58565b80516060906000611232826020612d6b565b61123d906040612d6b565b611248906004612d6b565b6001600160401b0381111561125f5761125f61244a565b6040519080825280601f01601f191660200182016040528015611289576020820181803683370190505b5060408051606080825260808201909252919250600091906020820181803683370190505090506060820160005b848110156112d157602081880181015183830152016112b7565b50830160008153600101606081536001016000815360018101879052602101602081535060006002836040516113079190612d7e565b602060405180830381855afa158015611324573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906113479190612ae8565b905060006042945084845281602085015260016040850153604184018890526020606185015360028460405161137d9190612d7e565b602060405180830381855afa15801561139a573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906113bd9190612ae8565b9050806020840152808218806020860152506002604085015360418401889052602060618501536002846040516113f49190612d7e565b602060405180830381855afa158015611411573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906114349190612ae8565b90508060408401528082188060208601525060036040850153604184018890526020606185015360028460405161146b9190612d7e565b602060405180830381855afa158015611488573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906114ab9190612ae8565b606084015250909695505050505050565b6000806114c8836114f0565b915082600080516020612d9b833981519152838409149050915091565b6000610bb982611c25565b6000600080516020612d9b8339815191528083840991508083830981838209828283098385830984848309858484098684850997508684840987858409945087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087838a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985050868889099750868889099750868889099750868889099750868889099750868889099750868489099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868689099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868189099750508587880996508587880996508587880996508585880996508587880996508587880996508587880996508585880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508583880996508587880996508587880996508587880996508587880996508581880996508587880996508587880996508587880996508587880996508583880996508587880996508587880996508587880996508584880996508587880996508587880996508587880996508587880996508587880996508581880996505050505050808283099392505050565b6000600080516020612d9b8339815191528083840991508083830981838209828283098385830984848309858484098684850997508684840987858409945087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087878a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a09985087898a09985087898a09985087898a09985087838a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087828a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087848a09985087898a09985087898a09985087898a09985087898a09985087898a09985087868a09985087898a09985087898a099850878a8a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087898a09985087818a09985050868889099750868889099750868889099750868889099750868889099750868889099750868489099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868889099750868989099750868889099750868889099750868889099750868889099750868889099750868689099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868889099750868189099750508587880996508587880996508587880996508585880996508587880996508587880996508587880996508585880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508587880996508583880996508587880996508587880996508587880996508587880996508581880996505050838586099450838586099450838586099450838586099450838186099450508284850993508284850993508284850993508281850993508284850993508284850993508285850993508284850993508284850993508284850993508284850993508284850993508284850993508281850995945050505050565b60405180608001604052806004906020820280368337509192915050565b82600481019282156123b8579160200282015b828111156123b857825182559160200191906001019061239d565b506123c4929150612404565b5090565b60405180604001604052806002906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b808211156123c45760008155600101612405565b60808101818360005b6004811015612441578151835260209283019290910190600101612422565b50505092915050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156124825761248261244a565b60405290565b604080519081016001600160401b03811182821017156124825761248261244a565b60405160a081016001600160401b03811182821017156124825761248261244a565b604051601f8201601f191681016001600160401b03811182821017156124f4576124f461244a565b604052919050565b60006080828403121561250e57600080fd5b82601f83011261251d57600080fd5b612525612460565b80608084018581111561253757600080fd5b845b81811015612551578035845260209384019301612539565b509095945050505050565b600082601f83011261256d57600080fd5b813560206001600160401b038211156125885761258861244a565b8160051b6125978282016124cc565b92835284810182019282810190878511156125b157600080fd5b83870192505b848310156125d0578235825291830191908301906125b7565b979650505050505050565b80356001600160c01b0319811681146125f357600080fd5b919050565b60006040828403121561260a57600080fd5b612612612488565b905081356001600160401b038082111561262b57600080fd5b9083019060a0828603121561263f57600080fd5b6126476124aa565b8235828116811461265757600080fd5b815260208301356fffffffffffffffffffffffffffffffff8116811461267c57600080fd5b8060208301525060408301356040820152606083013560608201526080830135828111156126a957600080fd5b6126b58782860161255c565b6080830152508352506126cc9050602083016125db565b602082015292915050565b80356001600160b01b0319811681146125f357600080fd5b60006040828403121561270157600080fd5b612709612488565b9050612714826126d7565b815260208201356001600160401b0381111561272f57600080fd5b61273b8482850161255c565b60208301525092915050565b60006080828403121561275957600080fd5b612761612460565b905081356001600160401b0381111561277957600080fd5b6127858482850161255c565b8252506020820135602082015261279e604083016126d7565b604082015260608201356001600160f81b0319811681146127be57600080fd5b606082015292915050565b600082601f8301126127da57600080fd5b81356001600160401b038111156127f3576127f361244a565b612806601f8201601f19166020016124cc565b81815284602083860101111561281b57600080fd5b816020850160208301376000918101602001919091529392505050565b60006060828403121561284a57600080fd5b604051606081018181106001600160401b038211171561286c5761286c61244a565b80604052508091508235815260208301356020820152604083013560408201525092915050565b600060c082840312156128a557600080fd5b6128ad612460565b905081356001600160401b03808211156128c657600080fd5b9083019060a082860312156128da57600080fd5b6128e26124aa565b823581526020830135828111156128f857600080fd5b6129048782860161255c565b60208301525060408301358281111561291c57600080fd5b6129288782860161255c565b60408301525060608301358281111561294057600080fd5b61294c8782860161255c565b60608301525060808301358281111561296457600080fd5b6129708782860161255c565b6080830152508352602084013591508082111561298c57600080fd5b50612999848285016127c9565b602083015250604082013560408201526127be8360608401612838565b8060408101831015610bb957600080fd5b600080600080600080600080610120898b0312156129e457600080fd5b88356001600160401b03808211156129fb57600080fd5b612a078c838d016125f8565b995060208b0135915080821115612a1d57600080fd5b612a298c838d016126ef565b985060408b0135915080821115612a3f57600080fd5b612a4b8c838d01612747565b975060608b0135915080821115612a6157600080fd5b50612a6e8b828c01612893565b9550506080890135935060a0890135925060c08901359150612a938a60e08b016129b6565b90509295985092959890939650565b600060208284031215612ab457600080fd5b81356001600160a01b0381168114612acb57600080fd5b9392505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215612afa57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060018201612b2957612b29612b01565b5060010190565b815160009082906020808601845b83811015612b5a57815185529382019390820190600101612b3e565b50929695505050505050565b60005b83811015612b81578181015183820152602001612b69565b50506000910152565b60008551612b9c818460208a01612b66565b91909101938452506001600160b01b03199190911660208301526001600160f81b031916602a820152602b01919050565b600081518084526020808501945080840160005b83811015612bfd57815187529582019590820190600101612be1565b509495945050505050565b60008151808452612c20816020860160208601612b66565b601f01601f19169290920160200192915050565b602081526000825160c06020840152805160e0840152602081015160a0610100850152612c65610180850182612bcd565b9050604082015160df198086840301610120870152612c848383612bcd565b9250606084015191508086840301610140870152612ca28383612bcd565b92506080840151935080868403016101608701525050612cc28183612bcd565b9150506020840151601f19848303016040850152612ce08282612c08565b915050604084015160608401526060840151612d1360808501828051825260208082015190830152604090810151910152565b509392505050565b80516020808301519190811015612d3c576000198160200360031b1b821691505b50919050565b634e487b7160e01b600052601260045260246000fd5b81810381811115610bb957610bb9612b01565b80820180821115610bb957610bb9612b01565b60008251612d90818460208701612b66565b919091019291505056fe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47a2646970667358221220d8058479b55748e685303b1f2db5127da227eb9ebc2b465d64c3237cfe4e27d764736f6c63430008130033