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-03-07T07:15:48.159126Z
Constructor Arguments
0x000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7daf4308af319ff3e33d9b28eeca70b77a970c175b1563af52eaee3d41a04b217a
Arg [0] (address) : 0xd1934807041b168f383870a0d8f565ade2df9d7d
Arg [1] (bytes32) : af4308af319ff3e33d9b28eeca70b77a970c175b1563af52eaee3d41a04b217a
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 JournalTokenMismatch(address expected, address actual);
error PublicInputByteOutOfRange(uint256 index, uint256 value);
error OnlyInternal();
IRiscZeroVerifier public immutable risc0Verifier;
bytes32 public immutable imageId;
uint256 private constant _PUBLIC_INPUTS_LEN = 107;
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 _IDX_TOKEN = 87;
uint256 private constant _JOURNAL_LEN = 136;
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;
uint256 private constant _OFFSET_TOKEN = 116;
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(msg.sender == address(this), OnlyInternal());
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 {
revert 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));
address token = _readAddress(_journal, _OFFSET_TOKEN);
address expectedToken = _readAddressFromPublicInputs(_publicInputs, _IDX_TOKEN);
require(token == expectedToken, JournalTokenMismatch(expectedToken, token));
}
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/","erc4626-tests/=lib/risc0-ethereum/lib/openzeppelin-contracts/lib/erc4626-tests/","halmos-cheatcodes/=lib/risc0-ethereum/lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/risc0-ethereum/lib/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":"JournalTokenMismatch","inputs":[{"type":"address","name":"expected","internalType":"address"},{"type":"address","name":"actual","internalType":"address"}]},{"type":"error","name":"OnlyInternal","inputs":[]},{"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
0x60c0346100a157601f610d3738819003918201601f19168301916001600160401b038311848410176100a55780849260409485528339810103126100a15780516001600160a01b03811691908290036100a157602001519080156100925760805260a052604051610c7d90816100ba823960805181818161029301526105e6015260a05181818161038b01526106320152f35b634a8bdce360e01b5f5260045ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c806317279047146100645780631e8e1e131461005f5780635c9770c51461005a578063c9d4ef1f146100555763ef3f7dd514610050575f80fd5b610374565b6102ea565b61027e565b61024e565b34610143576100af5f61007636610175565b9492610087949291943033146103ae565b61009486606b81146103c4565b60405163c9d4ef1f60e01b81529384928392600484016104e0565b0381305afa92835f925f95610119575b506100d35763236bd13760e01b5f5260045ffd5b6020926100e76100f3925f94969283610856565b604051918280926104fc565b039060025afa15610114575f519061011060405192839283610232565b0390f35b6104f1565b9094506101399192503d805f833e61013181836103f2565b810190610477565b91909193856100bf565b5f80fd5b9181601f840112156101435782359167ffffffffffffffff8311610143576020838186019501011161014357565b9060406003198301126101435760043567ffffffffffffffff811161014357826101a191600401610147565b9290929160243567ffffffffffffffff811161014357826023820112156101435780600401359267ffffffffffffffff84116101435760248460051b83010111610143576024019190565b5f5b8381106101fd5750505f910152565b81810151838201526020016101ee565b90602091610226815180928185528580860191016101ec565b601f01601f1916010190565b92919061024960209160408652604086019061020d565b930152565b3461014357602061026a61026136610175565b929190916105a8565b6040519015158152f35b5f91031261014357565b34610143575f366003190112610143576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b90916102d96102e79360408452604084019061020d565b91602081840391015261020d565b90565b346101435760203660031901126101435760043567ffffffffffffffff81116101435761031b903690600401610147565b81019060408183031261014357803567ffffffffffffffff811161014357826103459183016106b4565b91602082013567ffffffffffffffff81116101435761036492016106b4565b90610110604051928392836102c2565b34610143575f3660031901126101435760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b156103b557565b63a1ed4da360e01b5f5260045ffd5b156103cc5750565b631d75bf0560e01b5f5260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761041457604052565b6103de565b67ffffffffffffffff811161041457601f01601f191660200190565b81601f8201121561014357805161044b81610419565b9261045960405194856103f2565b81845260208284010111610143576102e791602080850191016101ec565b91909160408184031261014357805167ffffffffffffffff811161014357836104a1918301610435565b92602082015167ffffffffffffffff8111610143576102e79201610435565b908060209392818452848401375f828201840152601f01601f1916010190565b9160206102e79381815201916104c0565b6040513d5f823e3d90fd5b9061050f602092828151948592016101ec565b0190565b919060408382031261014357825167ffffffffffffffff81116101435760209161053e918501610435565b92015190565b9190610558916040845260408401916104c0565b8181036020909201919091528281526001600160fb1b0383116101435760209260051b809284830137010190565b61059e6040929594939560608352606083019061020d565b9460208201520152565b6105c95f93946040519586948594631727904760e01b865260048601610544565b0381305afa90815f915f9361068e575b506105e45750505f90565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691823b156101435760405163ab750e7560e01b8152925f9284928391829161065b917f00000000000000000000000000000000000000000000000000000000000000009060048501610586565b03915afa9081610674575b5061066f575f90565b600190565b806106825f610688936103f2565b80610274565b5f610666565b9092506106ad91503d805f833e6106a581836103f2565b810190610513565b915f6105d9565b81601f82011215610143578035906106cb82610419565b926106d960405194856103f2565b8284526020838301011161014357815f926020809301838601378301015290565b156107025750565b63b0fe347f60e01b5f5260045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b90156107315790565b610714565b9060211015610731576104200190565b9060221015610731576104400190565b91908110156107315760051b0190565b1561076f575050565b63e382912560e01b5f5260045260245260445ffd5b1561078d575050565b63591c97fb60e11b5f5260045260245260445ffd5b156107ab575050565b63f81c222960e01b5f5260045260245260445ffd5b156107c9575050565b633a62068960e21b5f5260045260245260445ffd5b156107e7575050565b6382238b7760e01b5f9081526001600160a01b039182166004529116602452604490fd5b15610814575050565b63089d5fad60e31b5f5260045260245260445ffd5b15610832575050565b63fc80f9b960e01b5f9081526001600160a01b039182166004529116602452604490fd5b61096c926109526109589261086f8151608881146106fa565b61089961087b82610993565b6108858588610728565b356108908689610728565b35908214610766565b6108c36108a5826109dc565b6108af8588610736565b356108ba8689610736565b35908214610784565b6108ed6108cf82610a2c565b6108d98588610746565b356108e48689610746565b359082146107a2565b61094d602882015161093b60748401519161091d61090a86610a7c565b91610915898c610b28565b8082146107c0565b610927878a610bb5565b6001600160a01b03828116908216146107de565b6109458588610b75565b80821461080b565b610ac3565b92610bfe565b6001600160a01b0382811690821614610829565b565b634e487b7160e01b5f52601160045260245ffd5b908151811015610731570160200190565b905f915f905b600882106109a5575050565b90926109b18483610982565b5160f81c906001600160fd1b03851685036109d7576001918560031b1b17930190610999565b61096e565b905f915f905b600882106109ee575050565b909283602801806028116109d757610a069083610982565b5160f81c906001600160fd1b03851685036109d7576001918560031b1b179301906109e2565b905f915f905b60108210610a3e575050565b909283603001806030116109d757610a569083610982565b5160f81c906001600160fd1b03851685036109d7576001918560031b1b17930190610a32565b5f905f905b60148210610a975750506001600160a01b031690565b90918260400190816040116109d757610ab260019284610982565b5160f81c9060081b17920190610a81565b5f905f905b60148210610ade5750506001600160a01b031690565b90918260740190816074116109d757610af960019284610982565b5160f81c9060081b17920190610ac8565b15610b13575050565b639552326f60e01b5f5260045260245260445ffd5b5f915f915b60208310610b3b5750505090565b90919283600101806001116109d757600191610b68610b5b838787610756565b35809360ff821115610b0a565b60081b1793019190610b2d565b5f915f915b60208310610b885750505090565b90919283603701806037116109d757600191610ba8610b5b838787610756565b60081b1793019190610b7a565b5f915f915b60148310610bd1575050506001600160a01b031690565b90919283602301806023116109d757600191610bf1610b5b838787610756565b60081b1793019190610bba565b5f915f915b60148310610c1a575050506001600160a01b031690565b90919283605701806057116109d757600191610c3a610b5b838787610756565b60081b1793019190610c0356fea26469706673582212206c856e6491440243cde8a5d708ff00c24ad4b45d9d3efaf1dec2ddfb9a416ff064736f6c63430008210033000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7daf4308af319ff3e33d9b28eeca70b77a970c175b1563af52eaee3d41a04b217a
Deployed ByteCode
0x60806040526004361015610011575f80fd5b5f3560e01c806317279047146100645780631e8e1e131461005f5780635c9770c51461005a578063c9d4ef1f146100555763ef3f7dd514610050575f80fd5b610374565b6102ea565b61027e565b61024e565b34610143576100af5f61007636610175565b9492610087949291943033146103ae565b61009486606b81146103c4565b60405163c9d4ef1f60e01b81529384928392600484016104e0565b0381305afa92835f925f95610119575b506100d35763236bd13760e01b5f5260045ffd5b6020926100e76100f3925f94969283610856565b604051918280926104fc565b039060025afa15610114575f519061011060405192839283610232565b0390f35b6104f1565b9094506101399192503d805f833e61013181836103f2565b810190610477565b91909193856100bf565b5f80fd5b9181601f840112156101435782359167ffffffffffffffff8311610143576020838186019501011161014357565b9060406003198301126101435760043567ffffffffffffffff811161014357826101a191600401610147565b9290929160243567ffffffffffffffff811161014357826023820112156101435780600401359267ffffffffffffffff84116101435760248460051b83010111610143576024019190565b5f5b8381106101fd5750505f910152565b81810151838201526020016101ee565b90602091610226815180928185528580860191016101ec565b601f01601f1916010190565b92919061024960209160408652604086019061020d565b930152565b3461014357602061026a61026136610175565b929190916105a8565b6040519015158152f35b5f91031261014357565b34610143575f366003190112610143576040517f000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7d6001600160a01b03168152602090f35b90916102d96102e79360408452604084019061020d565b91602081840391015261020d565b90565b346101435760203660031901126101435760043567ffffffffffffffff81116101435761031b903690600401610147565b81019060408183031261014357803567ffffffffffffffff811161014357826103459183016106b4565b91602082013567ffffffffffffffff81116101435761036492016106b4565b90610110604051928392836102c2565b34610143575f3660031901126101435760206040517faf4308af319ff3e33d9b28eeca70b77a970c175b1563af52eaee3d41a04b217a8152f35b156103b557565b63a1ed4da360e01b5f5260045ffd5b156103cc5750565b631d75bf0560e01b5f5260045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff82111761041457604052565b6103de565b67ffffffffffffffff811161041457601f01601f191660200190565b81601f8201121561014357805161044b81610419565b9261045960405194856103f2565b81845260208284010111610143576102e791602080850191016101ec565b91909160408184031261014357805167ffffffffffffffff811161014357836104a1918301610435565b92602082015167ffffffffffffffff8111610143576102e79201610435565b908060209392818452848401375f828201840152601f01601f1916010190565b9160206102e79381815201916104c0565b6040513d5f823e3d90fd5b9061050f602092828151948592016101ec565b0190565b919060408382031261014357825167ffffffffffffffff81116101435760209161053e918501610435565b92015190565b9190610558916040845260408401916104c0565b8181036020909201919091528281526001600160fb1b0383116101435760209260051b809284830137010190565b61059e6040929594939560608352606083019061020d565b9460208201520152565b6105c95f93946040519586948594631727904760e01b865260048601610544565b0381305afa90815f915f9361068e575b506105e45750505f90565b7f000000000000000000000000d1934807041b168f383870a0d8f565ade2df9d7d6001600160a01b031691823b156101435760405163ab750e7560e01b8152925f9284928391829161065b917faf4308af319ff3e33d9b28eeca70b77a970c175b1563af52eaee3d41a04b217a9060048501610586565b03915afa9081610674575b5061066f575f90565b600190565b806106825f610688936103f2565b80610274565b5f610666565b9092506106ad91503d805f833e6106a581836103f2565b810190610513565b915f6105d9565b81601f82011215610143578035906106cb82610419565b926106d960405194856103f2565b8284526020838301011161014357815f926020809301838601378301015290565b156107025750565b63b0fe347f60e01b5f5260045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b90156107315790565b610714565b9060211015610731576104200190565b9060221015610731576104400190565b91908110156107315760051b0190565b1561076f575050565b63e382912560e01b5f5260045260245260445ffd5b1561078d575050565b63591c97fb60e11b5f5260045260245260445ffd5b156107ab575050565b63f81c222960e01b5f5260045260245260445ffd5b156107c9575050565b633a62068960e21b5f5260045260245260445ffd5b156107e7575050565b6382238b7760e01b5f9081526001600160a01b039182166004529116602452604490fd5b15610814575050565b63089d5fad60e31b5f5260045260245260445ffd5b15610832575050565b63fc80f9b960e01b5f9081526001600160a01b039182166004529116602452604490fd5b61096c926109526109589261086f8151608881146106fa565b61089961087b82610993565b6108858588610728565b356108908689610728565b35908214610766565b6108c36108a5826109dc565b6108af8588610736565b356108ba8689610736565b35908214610784565b6108ed6108cf82610a2c565b6108d98588610746565b356108e48689610746565b359082146107a2565b61094d602882015161093b60748401519161091d61090a86610a7c565b91610915898c610b28565b8082146107c0565b610927878a610bb5565b6001600160a01b03828116908216146107de565b6109458588610b75565b80821461080b565b610ac3565b92610bfe565b6001600160a01b0382811690821614610829565b565b634e487b7160e01b5f52601160045260245ffd5b908151811015610731570160200190565b905f915f905b600882106109a5575050565b90926109b18483610982565b5160f81c906001600160fd1b03851685036109d7576001918560031b1b17930190610999565b61096e565b905f915f905b600882106109ee575050565b909283602801806028116109d757610a069083610982565b5160f81c906001600160fd1b03851685036109d7576001918560031b1b179301906109e2565b905f915f905b60108210610a3e575050565b909283603001806030116109d757610a569083610982565b5160f81c906001600160fd1b03851685036109d7576001918560031b1b17930190610a32565b5f905f905b60148210610a975750506001600160a01b031690565b90918260400190816040116109d757610ab260019284610982565b5160f81c9060081b17920190610a81565b5f905f905b60148210610ade5750506001600160a01b031690565b90918260740190816074116109d757610af960019284610982565b5160f81c9060081b17920190610ac8565b15610b13575050565b639552326f60e01b5f5260045260245260445ffd5b5f915f915b60208310610b3b5750505090565b90919283600101806001116109d757600191610b68610b5b838787610756565b35809360ff821115610b0a565b60081b1793019190610b2d565b5f915f915b60208310610b885750505090565b90919283603701806037116109d757600191610ba8610b5b838787610756565b60081b1793019190610b7a565b5f915f915b60148310610bd1575050506001600160a01b031690565b90919283602301806023116109d757600191610bf1610b5b838787610756565b60081b1793019190610bba565b5f915f915b60148310610c1a575050506001600160a01b031690565b90919283605701806057116109d757600191610c3a610b5b838787610756565b60081b1793019190610c0356fea26469706673582212206c856e6491440243cde8a5d708ff00c24ad4b45d9d3efaf1dec2ddfb9a416ff064736f6c63430008210033