false
false
0
The new Blockscout UI is now open source! Learn how to deploy it here
- We're indexing this chain right now. Some of the counts may be inaccurate.

Contract Address Details

0xC989429B6C3f3E870fdB825735c00d2f4EbCd559

Contract Name
Risc0CircuitVerifier
Creator
0xe36c0f–9ad9cb at 0x85ef35–cff656
Balance
0 ETH
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
5607176
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Risc0CircuitVerifier




Optimization enabled
true
Compiler version
v0.8.33+commit.64118f21




Optimization runs
200
EVM Version
shanghai




Verified at
2026-02-24T05:53:10.764758Z

Constructor Arguments

0x000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7d37a5e85c934ec15f7752cfced2f407f40e6c28978dffcb3b895dc100a76acaf8

Arg [0] (address) : 0xd1934807041b168f383870a0d8f565ade2df9d7d
Arg [1] (bytes32) : 37a5e85c934ec15f7752cfced2f407f40e6c28978dffcb3b895dc100a76acaf8

              

src/impl/Risc0CircuitVerifier.sol

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

import {ICircuitVerifier} from "../iface/ICircuitVerifier.sol";
import {IRiscZeroVerifier} from "../iface/IRiscZeroVerifier.sol";

/// @custom:security-contact security@taiko.xyz

/// @notice Adapter that binds Shadow public inputs to a RISC Zero journal and
/// delegates seal verification to a deployed RISC0 verifier contract.
contract Risc0CircuitVerifier is ICircuitVerifier {
    error ZeroVerifier();
    error InvalidPublicInputsLength(uint256 actual);
    error InvalidProofEncoding();
    error InvalidJournalLength(uint256 actual);
    error JournalBlockNumberMismatch(uint256 expected, uint256 actual);
    error JournalChainIdMismatch(uint256 expected, uint256 actual);
    error JournalAmountMismatch(uint256 expected, uint256 actual);
    error JournalBlockHashMismatch(bytes32 expected, bytes32 actual);
    error JournalRecipientMismatch(address expected, address actual);
    error JournalNullifierMismatch(bytes32 expected, bytes32 actual);
    error PublicInputByteOutOfRange(uint256 index, uint256 value);

    IRiscZeroVerifier public immutable risc0Verifier;
    bytes32 public immutable imageId;

    uint256 private constant _PUBLIC_INPUTS_LEN = 87;
    uint256 private constant _IDX_BLOCK_NUMBER = 0;
    uint256 private constant _IDX_BLOCK_HASH = 1;
    uint256 private constant _IDX_CHAIN_ID = 33;
    uint256 private constant _IDX_AMOUNT = 34;
    uint256 private constant _IDX_RECIPIENT = 35;
    uint256 private constant _IDX_NULLIFIER = 55;

    uint256 private constant _JOURNAL_LEN = 116;
    uint256 private constant _OFFSET_BLOCK_NUMBER = 0;
    uint256 private constant _OFFSET_BLOCK_HASH = 8;
    uint256 private constant _OFFSET_CHAIN_ID = 40;
    uint256 private constant _OFFSET_AMOUNT = 48;
    uint256 private constant _OFFSET_RECIPIENT = 64;
    uint256 private constant _OFFSET_NULLIFIER = 84;

    constructor(address _risc0Verifier, bytes32 _imageId) {
        require(_risc0Verifier != address(0), ZeroVerifier());
        risc0Verifier = IRiscZeroVerifier(_risc0Verifier);
        imageId = _imageId;
    }

    /// @notice Decode proof payload `(bytes seal, bytes journal)`.
    function decodeProof(bytes calldata _proof) external pure returns (bytes memory _seal_, bytes memory _journal_) {
        (_seal_, _journal_) = abi.decode(_proof, (bytes, bytes));
    }

    function verifyProof(bytes calldata _proof, uint256[] calldata _publicInputs)
        external
        view
        returns (bool _isValid_)
    {
        bytes memory seal;
        bytes32 journalDigest;
        try this.decodeAndValidateProof(_proof, _publicInputs) returns (
            bytes memory decodedSeal, bytes32 decodedJournalDigest
        ) {
            seal = decodedSeal;
            journalDigest = decodedJournalDigest;
        } catch {
            return false;
        }

        try risc0Verifier.verify(seal, imageId, journalDigest) {
            _isValid_ = true;
        } catch {
            _isValid_ = false;
        }
    }

    /// @notice Decodes and validates proof payload and binding against public inputs.
    /// @dev Intended for internal `try/catch` orchestration in `verifyProof`.
    function decodeAndValidateProof(bytes calldata _proof, uint256[] calldata _publicInputs)
        external
        view
        returns (bytes memory seal_, bytes32 journalDigest_)
    {
        require(_publicInputs.length == _PUBLIC_INPUTS_LEN, InvalidPublicInputsLength(_publicInputs.length));

        bytes memory seal;
        bytes memory journal;
        try this.decodeProof(_proof) returns (bytes memory decodedSeal, bytes memory decodedJournal) {
            seal = decodedSeal;
            journal = decodedJournal;
        } catch {
            require(false, InvalidProofEncoding());
        }

        _requireJournalMatchesPublicInputs(journal, _publicInputs);
        seal_ = seal;
        journalDigest_ = sha256(journal);
    }

    function _requireJournalMatchesPublicInputs(bytes memory _journal, uint256[] calldata _publicInputs) private pure {
        require(_journal.length == _JOURNAL_LEN, InvalidJournalLength(_journal.length));

        uint256 blockNumber = _readLeUint(_journal, _OFFSET_BLOCK_NUMBER, 8);
        require(
            blockNumber == _publicInputs[_IDX_BLOCK_NUMBER],
            JournalBlockNumberMismatch(_publicInputs[_IDX_BLOCK_NUMBER], blockNumber)
        );

        uint256 chainId = _readLeUint(_journal, _OFFSET_CHAIN_ID, 8);
        require(chainId == _publicInputs[_IDX_CHAIN_ID], JournalChainIdMismatch(_publicInputs[_IDX_CHAIN_ID], chainId));

        uint256 amount = _readLeUint(_journal, _OFFSET_AMOUNT, 16);
        require(amount == _publicInputs[_IDX_AMOUNT], JournalAmountMismatch(_publicInputs[_IDX_AMOUNT], amount));

        bytes32 blockHash = _readBytes32(_journal, _OFFSET_BLOCK_HASH);
        bytes32 nullifier = _readBytes32(_journal, _OFFSET_NULLIFIER);
        address recipient = _readAddress(_journal, _OFFSET_RECIPIENT);

        bytes32 expectedBlockHash = _readBytes32FromPublicInputs(_publicInputs, _IDX_BLOCK_HASH);
        require(blockHash == expectedBlockHash, JournalBlockHashMismatch(expectedBlockHash, blockHash));

        address expectedRecipient = _readAddressFromPublicInputs(_publicInputs, _IDX_RECIPIENT);
        require(recipient == expectedRecipient, JournalRecipientMismatch(expectedRecipient, recipient));

        bytes32 expectedNullifier = _readBytes32FromPublicInputs(_publicInputs, _IDX_NULLIFIER);
        require(nullifier == expectedNullifier, JournalNullifierMismatch(expectedNullifier, nullifier));
    }

    function _readLeUint(bytes memory _data, uint256 _offset, uint256 _len) private pure returns (uint256 value_) {
        for (uint256 i = 0; i < _len; ++i) {
            value_ |= uint256(uint8(_data[_offset + i])) << (8 * i);
        }
    }

    function _readBytes32(bytes memory _data, uint256 _offset) private pure returns (bytes32 value_) {
        assembly {
            value_ := mload(add(add(_data, 0x20), _offset))
        }
    }

    function _readAddress(bytes memory _data, uint256 _offset) private pure returns (address addr_) {
        uint256 word;
        for (uint256 i = 0; i < 20; ++i) {
            word = (word << 8) | uint8(_data[_offset + i]);
        }
        addr_ = address(uint160(word));
    }

    function _readBytes32FromPublicInputs(uint256[] calldata _publicInputs, uint256 _offset)
        private
        pure
        returns (bytes32 value_)
    {
        uint256 word;
        for (uint256 i = 0; i < 32; ++i) {
            uint256 b = _publicInputs[_offset + i];
            require(b <= type(uint8).max, PublicInputByteOutOfRange(_offset + i, b));
            word = (word << 8) | b;
        }
        value_ = bytes32(word);
    }

    function _readAddressFromPublicInputs(uint256[] calldata _publicInputs, uint256 _offset)
        private
        pure
        returns (address addr_)
    {
        uint256 word;
        for (uint256 i = 0; i < 20; ++i) {
            uint256 b = _publicInputs[_offset + i];
            require(b <= type(uint8).max, PublicInputByteOutOfRange(_offset + i, b));
            word = (word << 8) | b;
        }
        addr_ = address(uint160(word));
    }
}
        

src/iface/ICircuitVerifier.sol

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

/// @custom:security-contact security@taiko.xyz

interface ICircuitVerifier {
    /// @notice Verifies a proof against public inputs.
    function verifyProof(bytes calldata _proof, uint256[] calldata _publicInputs)
        external
        view
        returns (bool _isValid_);
}
          

src/iface/IRiscZeroVerifier.sol

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

/// @custom:security-contact security@taiko.xyz

interface IRiscZeroVerifier {
    /// @notice Verify a RISC Zero receipt seal for an image ID and journal digest.
    function verify(bytes calldata _seal, bytes32 _imageId, bytes32 _journalDigest) external view;
}
          

Compiler Settings

{"viaIR":true,"remappings":["forge-std/=node_modules/forge-std/src/","@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/","@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/","risc0-ethereum/=lib/risc0-ethereum/contracts/src/","openzeppelin/contracts/=node_modules/@openzeppelin/contracts/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"shanghai"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_risc0Verifier","internalType":"address"},{"type":"bytes32","name":"_imageId","internalType":"bytes32"}]},{"type":"error","name":"InvalidJournalLength","inputs":[{"type":"uint256","name":"actual","internalType":"uint256"}]},{"type":"error","name":"InvalidProofEncoding","inputs":[]},{"type":"error","name":"InvalidPublicInputsLength","inputs":[{"type":"uint256","name":"actual","internalType":"uint256"}]},{"type":"error","name":"JournalAmountMismatch","inputs":[{"type":"uint256","name":"expected","internalType":"uint256"},{"type":"uint256","name":"actual","internalType":"uint256"}]},{"type":"error","name":"JournalBlockHashMismatch","inputs":[{"type":"bytes32","name":"expected","internalType":"bytes32"},{"type":"bytes32","name":"actual","internalType":"bytes32"}]},{"type":"error","name":"JournalBlockNumberMismatch","inputs":[{"type":"uint256","name":"expected","internalType":"uint256"},{"type":"uint256","name":"actual","internalType":"uint256"}]},{"type":"error","name":"JournalChainIdMismatch","inputs":[{"type":"uint256","name":"expected","internalType":"uint256"},{"type":"uint256","name":"actual","internalType":"uint256"}]},{"type":"error","name":"JournalNullifierMismatch","inputs":[{"type":"bytes32","name":"expected","internalType":"bytes32"},{"type":"bytes32","name":"actual","internalType":"bytes32"}]},{"type":"error","name":"JournalRecipientMismatch","inputs":[{"type":"address","name":"expected","internalType":"address"},{"type":"address","name":"actual","internalType":"address"}]},{"type":"error","name":"PublicInputByteOutOfRange","inputs":[{"type":"uint256","name":"index","internalType":"uint256"},{"type":"uint256","name":"value","internalType":"uint256"}]},{"type":"error","name":"ZeroVerifier","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"seal_","internalType":"bytes"},{"type":"bytes32","name":"journalDigest_","internalType":"bytes32"}],"name":"decodeAndValidateProof","inputs":[{"type":"bytes","name":"_proof","internalType":"bytes"},{"type":"uint256[]","name":"_publicInputs","internalType":"uint256[]"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes","name":"_seal_","internalType":"bytes"},{"type":"bytes","name":"_journal_","internalType":"bytes"}],"name":"decodeProof","inputs":[{"type":"bytes","name":"_proof","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"imageId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IRiscZeroVerifier"}],"name":"risc0Verifier","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"_isValid_","internalType":"bool"}],"name":"verifyProof","inputs":[{"type":"bytes","name":"_proof","internalType":"bytes"},{"type":"uint256[]","name":"_publicInputs","internalType":"uint256[]"}]}]
              

Contract Creation Code

0x60c0346100a157601f610c2938819003918201601f19168301916001600160401b038311848410176100a55780849260409485528339810103126100a15780516001600160a01b03811691908290036100a157602001519080156100925760805260a052604051610b6f90816100ba823960805181818161027c01526105c8015260a05181818161037401526106140152f35b634a8bdce360e01b5f5260045ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c806317279047146100645780631e8e1e131461005f5780635c9770c51461005a578063c9d4ef1f146100555763ef3f7dd514610050575f80fd5b61035d565b6102d3565b610267565b610237565b3461012c576100a45f6100763661015e565b9492610089866057819795949714610397565b60405163c9d4ef1f60e01b81529384928392600484016104b3565b0381305afa92835f925f95610102575b50155f036104cf576020926100d06100dc925f949692836107f1565b604051918280926104de565b039060025afa156100fd575f51906100f96040519283928361021b565b0390f35b6104c4565b9094506101229192503d805f833e61011a81836103c5565b81019061044a565b91909193856100b4565b5f80fd5b9181601f8401121561012c5782359167ffffffffffffffff831161012c576020838186019501011161012c57565b90604060031983011261012c5760043567ffffffffffffffff811161012c578261018a91600401610130565b9290929160243567ffffffffffffffff811161012c578260238201121561012c5780600401359267ffffffffffffffff841161012c5760248460051b8301011161012c576024019190565b5f5b8381106101e65750505f910152565b81810151838201526020016101d7565b9060209161020f815180928185528580860191016101d5565b601f01601f1916010190565b9291906102326020916040865260408601906101f6565b930152565b3461012c57602061025361024a3661015e565b9291909161058a565b6040519015158152f35b5f91031261012c57565b3461012c575f36600319011261012c576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b90916102c26102d0936040845260408401906101f6565b9160208184039101526101f6565b90565b3461012c57602036600319011261012c5760043567ffffffffffffffff811161012c57610304903690600401610130565b81019060408183031261012c57803567ffffffffffffffff811161012c578261032e918301610696565b91602082013567ffffffffffffffff811161012c5761034d9201610696565b906100f9604051928392836102ab565b3461012c575f36600319011261012c5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b1561039f5750565b631d75bf0560e01b5f5260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176103e757604052565b6103b1565b67ffffffffffffffff81116103e757601f01601f191660200190565b81601f8201121561012c57805161041e816103ec565b9261042c60405194856103c5565b8184526020828401011161012c576102d091602080850191016101d5565b91909160408184031261012c57805167ffffffffffffffff811161012c5783610474918301610408565b92602082015167ffffffffffffffff811161012c576102d09201610408565b908060209392818452848401375f828201840152601f01601f1916010190565b9160206102d0938181520191610493565b6040513d5f823e3d90fd5b63236bd13760e01b5f5260045ffd5b906104f1602092828151948592016101d5565b0190565b919060408382031261012c57825167ffffffffffffffff811161012c57602091610520918501610408565b92015190565b919061053a91604084526040840191610493565b8181036020909201919091528281526001600160fb1b03831161012c5760209260051b809284830137010190565b610580604092959493956060835260608301906101f6565b9460208201520152565b6105ab5f93946040519586948594631727904760e01b865260048601610526565b0381305afa90815f915f93610670575b506105c65750505f90565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691823b1561012c5760405163ab750e7560e01b8152925f9284928391829161063d917f00000000000000000000000000000000000000000000000000000000000000009060048501610568565b03915afa9081610656575b50610651575f90565b600190565b806106645f61066a936103c5565b8061025d565b5f610648565b90925061068f91503d805f833e61068781836103c5565b8101906104f5565b915f6105bb565b81601f8201121561012c578035906106ad826103ec565b926106bb60405194856103c5565b8284526020838301011161012c57815f926020809301838601378301015290565b634e487b7160e01b5f52603260045260245ffd5b90156106f95790565b6106dc565b90602110156106f9576104200190565b90602210156106f9576104400190565b91908110156106f95760051b0190565b15610737575050565b63e382912560e01b5f5260045260245260445ffd5b15610755575050565b63591c97fb60e11b5f5260045260245260445ffd5b15610773575050565b63f81c222960e01b5f5260045260245260445ffd5b15610791575050565b633a62068960e21b5f5260045260245260445ffd5b156107af575050565b6382238b7760e01b5f9081526001600160a01b039182166004529116602452604490fd5b156107dc575050565b63089d5fad60e31b5f5260045260245260445ffd5b91908251607481036108de575082916108d4916108316108136108dc96610915565b61081d84846106f0565b3561082885856106f0565b3590821461072e565b61085b61083d8561095e565b61084784846106fe565b3561085285856106fe565b3590821461074c565b610885610867856109ae565b610871848461070e565b3561087c858561070e565b3590821461076a565b6108cf60288501516108b161089e6074880151976109fe565b916108a98686610a63565b808214610788565b6108bb8484610af0565b6001600160a01b03828116908216146107a6565b610ab0565b8082146107d3565b565b63b0fe347f60e01b5f5260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b9081518110156106f9570160200190565b905f915f905b60088210610927575050565b90926109338483610904565b5160f81c906001600160fd1b0385168503610959576001918560031b1b1793019061091b565b6108f0565b905f915f905b60088210610970575050565b90928360280180602811610959576109889083610904565b5160f81c906001600160fd1b0385168503610959576001918560031b1b17930190610964565b905f915f905b601082106109c0575050565b90928360300180603011610959576109d89083610904565b5160f81c906001600160fd1b0385168503610959576001918560031b1b179301906109b4565b5f905f905b60148210610a195750506001600160a01b031690565b909182604001908160401161095957610a3460019284610904565b5160f81c9060081b17920190610a03565b15610a4e575050565b639552326f60e01b5f5260045260245260445ffd5b5f915f915b60208310610a765750505090565b909192836001018060011161095957600191610aa3610a9683878761071e565b35809360ff821115610a45565b60081b1793019190610a68565b5f915f915b60208310610ac35750505090565b909192836037018060371161095957600191610ae3610a9683878761071e565b60081b1793019190610ab5565b5f915f915b60148310610b0c575050506001600160a01b031690565b909192836023018060231161095957600191610b2c610a9683878761071e565b60081b1793019190610af556fea264697066735822122052bde3379f70be20252109abe22a9dfeecc739a4f1648a0cf71468a85ce82d7664736f6c63430008210033000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7d37a5e85c934ec15f7752cfced2f407f40e6c28978dffcb3b895dc100a76acaf8

Deployed ByteCode

0x60806040526004361015610011575f80fd5b5f3560e01c806317279047146100645780631e8e1e131461005f5780635c9770c51461005a578063c9d4ef1f146100555763ef3f7dd514610050575f80fd5b61035d565b6102d3565b610267565b610237565b3461012c576100a45f6100763661015e565b9492610089866057819795949714610397565b60405163c9d4ef1f60e01b81529384928392600484016104b3565b0381305afa92835f925f95610102575b50155f036104cf576020926100d06100dc925f949692836107f1565b604051918280926104de565b039060025afa156100fd575f51906100f96040519283928361021b565b0390f35b6104c4565b9094506101229192503d805f833e61011a81836103c5565b81019061044a565b91909193856100b4565b5f80fd5b9181601f8401121561012c5782359167ffffffffffffffff831161012c576020838186019501011161012c57565b90604060031983011261012c5760043567ffffffffffffffff811161012c578261018a91600401610130565b9290929160243567ffffffffffffffff811161012c578260238201121561012c5780600401359267ffffffffffffffff841161012c5760248460051b8301011161012c576024019190565b5f5b8381106101e65750505f910152565b81810151838201526020016101d7565b9060209161020f815180928185528580860191016101d5565b601f01601f1916010190565b9291906102326020916040865260408601906101f6565b930152565b3461012c57602061025361024a3661015e565b9291909161058a565b6040519015158152f35b5f91031261012c57565b3461012c575f36600319011261012c576040517f000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7d6001600160a01b03168152602090f35b90916102c26102d0936040845260408401906101f6565b9160208184039101526101f6565b90565b3461012c57602036600319011261012c5760043567ffffffffffffffff811161012c57610304903690600401610130565b81019060408183031261012c57803567ffffffffffffffff811161012c578261032e918301610696565b91602082013567ffffffffffffffff811161012c5761034d9201610696565b906100f9604051928392836102ab565b3461012c575f36600319011261012c5760206040517f37a5e85c934ec15f7752cfced2f407f40e6c28978dffcb3b895dc100a76acaf88152f35b1561039f5750565b631d75bf0560e01b5f5260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff8211176103e757604052565b6103b1565b67ffffffffffffffff81116103e757601f01601f191660200190565b81601f8201121561012c57805161041e816103ec565b9261042c60405194856103c5565b8184526020828401011161012c576102d091602080850191016101d5565b91909160408184031261012c57805167ffffffffffffffff811161012c5783610474918301610408565b92602082015167ffffffffffffffff811161012c576102d09201610408565b908060209392818452848401375f828201840152601f01601f1916010190565b9160206102d0938181520191610493565b6040513d5f823e3d90fd5b63236bd13760e01b5f5260045ffd5b906104f1602092828151948592016101d5565b0190565b919060408382031261012c57825167ffffffffffffffff811161012c57602091610520918501610408565b92015190565b919061053a91604084526040840191610493565b8181036020909201919091528281526001600160fb1b03831161012c5760209260051b809284830137010190565b610580604092959493956060835260608301906101f6565b9460208201520152565b6105ab5f93946040519586948594631727904760e01b865260048601610526565b0381305afa90815f915f93610670575b506105c65750505f90565b7f000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7d6001600160a01b031691823b1561012c5760405163ab750e7560e01b8152925f9284928391829161063d917f37a5e85c934ec15f7752cfced2f407f40e6c28978dffcb3b895dc100a76acaf89060048501610568565b03915afa9081610656575b50610651575f90565b600190565b806106645f61066a936103c5565b8061025d565b5f610648565b90925061068f91503d805f833e61068781836103c5565b8101906104f5565b915f6105bb565b81601f8201121561012c578035906106ad826103ec565b926106bb60405194856103c5565b8284526020838301011161012c57815f926020809301838601378301015290565b634e487b7160e01b5f52603260045260245ffd5b90156106f95790565b6106dc565b90602110156106f9576104200190565b90602210156106f9576104400190565b91908110156106f95760051b0190565b15610737575050565b63e382912560e01b5f5260045260245260445ffd5b15610755575050565b63591c97fb60e11b5f5260045260245260445ffd5b15610773575050565b63f81c222960e01b5f5260045260245260445ffd5b15610791575050565b633a62068960e21b5f5260045260245260445ffd5b156107af575050565b6382238b7760e01b5f9081526001600160a01b039182166004529116602452604490fd5b156107dc575050565b63089d5fad60e31b5f5260045260245260445ffd5b91908251607481036108de575082916108d4916108316108136108dc96610915565b61081d84846106f0565b3561082885856106f0565b3590821461072e565b61085b61083d8561095e565b61084784846106fe565b3561085285856106fe565b3590821461074c565b610885610867856109ae565b610871848461070e565b3561087c858561070e565b3590821461076a565b6108cf60288501516108b161089e6074880151976109fe565b916108a98686610a63565b808214610788565b6108bb8484610af0565b6001600160a01b03828116908216146107a6565b610ab0565b8082146107d3565b565b63b0fe347f60e01b5f5260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b9081518110156106f9570160200190565b905f915f905b60088210610927575050565b90926109338483610904565b5160f81c906001600160fd1b0385168503610959576001918560031b1b1793019061091b565b6108f0565b905f915f905b60088210610970575050565b90928360280180602811610959576109889083610904565b5160f81c906001600160fd1b0385168503610959576001918560031b1b17930190610964565b905f915f905b601082106109c0575050565b90928360300180603011610959576109d89083610904565b5160f81c906001600160fd1b0385168503610959576001918560031b1b179301906109b4565b5f905f905b60148210610a195750506001600160a01b031690565b909182604001908160401161095957610a3460019284610904565b5160f81c9060081b17920190610a03565b15610a4e575050565b639552326f60e01b5f5260045260245260445ffd5b5f915f915b60208310610a765750505090565b909192836001018060011161095957600191610aa3610a9683878761071e565b35809360ff821115610a45565b60081b1793019190610a68565b5f915f915b60208310610ac35750505090565b909192836037018060371161095957600191610ae3610a9683878761071e565b60081b1793019190610ab5565b5f915f915b60148310610b0c575050506001600160a01b031690565b909192836023018060231161095957600191610b2c610a9683878761071e565b60081b1793019190610af556fea264697066735822122052bde3379f70be20252109abe22a9dfeecc739a4f1648a0cf71468a85ce82d7664736f6c63430008210033