Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- RiscZeroGroth16Verifier
- Optimization enabled
- true
- Compiler version
- v0.8.33+commit.64118f21
- Optimization runs
- 200
- EVM Version
- shanghai
- Verified at
- 2026-02-23T07:42:48.054681Z
Constructor Arguments
0xa54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f5604446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0
Arg [0] (bytes32) : a54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f56
Arg [1] (bytes32) : 04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0
lib/risc0-ethereum/contracts/src/groth16/RiscZeroGroth16Verifier.sol
// Copyright 2024 RISC Zero, Inc.
//
// The RiscZeroGroth16Verifier is a free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The RiscZeroGroth16Verifier is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along with
// the RiscZeroGroth16Verifier. If not, see <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.9;
import {SafeCast} from "openzeppelin/contracts/utils/math/SafeCast.sol";
import {ControlID} from "./ControlID.sol";
import {Groth16Verifier} from "./Groth16Verifier.sol";
import {
ExitCode,
IRiscZeroVerifier,
Output,
OutputLib,
Receipt,
ReceiptClaim,
ReceiptClaimLib,
SystemExitCode,
VerificationFailed
} from "../IRiscZeroVerifier.sol";
import {StructHash} from "../StructHash.sol";
import {reverseByteOrderUint256, reverseByteOrderUint32} from "../Util.sol";
import {IRiscZeroSelectable} from "../IRiscZeroSelectable.sol";
/// @notice A Groth16 seal over the claimed receipt claim.
struct Seal {
uint256[2] a;
uint256[2][2] b;
uint256[2] c;
}
/// @notice Error raised when this verifier receives a receipt with a selector that does not match
/// its own. The selector value is calculated from the verifier parameters, and so this
/// usually indicates a mismatch between the version of the prover and this verifier.
error SelectorMismatch(bytes4 received, bytes4 expected);
/// @notice Groth16 verifier contract for RISC Zero receipts of execution.
contract RiscZeroGroth16Verifier is IRiscZeroVerifier, IRiscZeroSelectable, Groth16Verifier {
using ReceiptClaimLib for ReceiptClaim;
using OutputLib for Output;
using SafeCast for uint256;
/// @notice Semantic version of the RISC Zero system of which this contract is part.
/// @dev This is set to be equal to the version of the risc0-zkvm crate.
string public constant VERSION = "3.0.0";
/// @notice Control root hash binding the set of circuits in the RISC Zero system.
/// @dev This value controls what set of recursion programs (e.g. lift, join, resolve), and
/// therefore what version of the zkVM circuit, will be accepted by this contract. Each
/// instance of this verifier contract will accept a single release of the RISC Zero circuits.
///
/// New releases of RISC Zero's zkVM require updating these values. These values can be
/// calculated from the [risc0 monorepo][1] using: `cargo xtask bootstrap`.
///
/// [1]: https://github.com/risc0/risc0
bytes16 public immutable CONTROL_ROOT_0;
bytes16 public immutable CONTROL_ROOT_1;
bytes32 public immutable BN254_CONTROL_ID;
/// @notice A short key attached to the seal to select the correct verifier implementation.
/// @dev The selector is taken from the hash of the verifier parameters including the Groth16
/// verification key and the control IDs that commit to the RISC Zero circuits. If two
/// receipts have different selectors (i.e. different verifier parameters), then it can
/// generally be assumed that they need distinct verifier implementations. This is used as
/// part of the RISC Zero versioning mechanism.
///
/// A selector is not intended to be collision resistant, in that it is possible to find
/// two preimages that result in the same selector. This is acceptable since it's purpose
/// to a route a request among a set of trusted verifiers, and to make errors of sending a
/// receipt to a mismatching verifiers easier to debug. It is analogous to the ABI
/// function selectors.
bytes4 public immutable SELECTOR;
/// @notice Identifier for the Groth16 verification key encoded into the base contract.
/// @dev This value is computed at compile time.
function verifier_key_digest() internal pure returns (bytes32) {
bytes32[] memory ic_digests = new bytes32[](6);
ic_digests[0] = sha256(abi.encodePacked(IC0x, IC0y));
ic_digests[1] = sha256(abi.encodePacked(IC1x, IC1y));
ic_digests[2] = sha256(abi.encodePacked(IC2x, IC2y));
ic_digests[3] = sha256(abi.encodePacked(IC3x, IC3y));
ic_digests[4] = sha256(abi.encodePacked(IC4x, IC4y));
ic_digests[5] = sha256(abi.encodePacked(IC5x, IC5y));
return sha256(
abi.encodePacked(
// tag
sha256("risc0_groth16.VerifyingKey"),
// down
sha256(abi.encodePacked(alphax, alphay)),
sha256(abi.encodePacked(betax1, betax2, betay1, betay2)),
sha256(abi.encodePacked(gammax1, gammax2, gammay1, gammay2)),
sha256(abi.encodePacked(deltax1, deltax2, deltay1, deltay2)),
StructHash.taggedList(sha256("risc0_groth16.VerifyingKey.IC"), ic_digests),
// down length
uint16(5) << 8
)
);
}
constructor(bytes32 control_root, bytes32 bn254_control_id) {
(CONTROL_ROOT_0, CONTROL_ROOT_1) = splitDigest(control_root);
BN254_CONTROL_ID = bn254_control_id;
SELECTOR = bytes4(
sha256(
abi.encodePacked(
// tag
sha256("risc0.Groth16ReceiptVerifierParameters"),
// down
control_root,
reverseByteOrderUint256(uint256(bn254_control_id)),
verifier_key_digest(),
// down length
uint16(3) << 8
)
)
);
}
/// @notice splits a digest into two 128-bit halves to use as public signal inputs.
/// @dev RISC Zero's Circom verifier circuit takes each of two hash digests in two 128-bit
/// chunks. These values can be derived from the digest by splitting the digest in half and
/// then reversing the bytes of each.
function splitDigest(bytes32 digest) internal pure returns (bytes16, bytes16) {
uint256 reversed = reverseByteOrderUint256(uint256(digest));
return (bytes16(uint128(reversed)), bytes16(uint128(reversed >> 128)));
}
/// @inheritdoc IRiscZeroVerifier
function verify(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) external view {
_verifyIntegrity(seal, ReceiptClaimLib.ok(imageId, journalDigest).digest());
}
/// @inheritdoc IRiscZeroVerifier
function verifyIntegrity(Receipt calldata receipt) external view {
return _verifyIntegrity(receipt.seal, receipt.claimDigest);
}
/// @notice internal implementation of verifyIntegrity, factored to avoid copying calldata bytes to memory.
function _verifyIntegrity(bytes calldata seal, bytes32 claimDigest) internal view {
// Check that the seal has a matching selector. Mismatch generally indicates that the
// prover and this verifier are using different parameters, and so the verification
// will not succeed.
if (SELECTOR != bytes4(seal[:4])) {
revert SelectorMismatch({received: bytes4(seal[:4]), expected: SELECTOR});
}
// Run the Groth16 verify procedure.
(bytes16 claim0, bytes16 claim1) = splitDigest(claimDigest);
Seal memory decodedSeal = abi.decode(seal[4:], (Seal));
bool verified = this.verifyProof(
decodedSeal.a,
decodedSeal.b,
decodedSeal.c,
[
uint256(uint128(CONTROL_ROOT_0)),
uint256(uint128(CONTROL_ROOT_1)),
uint256(uint128(claim0)),
uint256(uint128(claim1)),
uint256(BN254_CONTROL_ID)
]
);
// Revert is verification failed.
if (!verified) {
revert VerificationFailed();
}
}
}
lib/risc0-ethereum/contracts/src/IRiscZeroSelectable.sol
// Copyright 2025 RISC Zero, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.9;
/// @notice Selectable interface for RISC Zero verifier.
interface IRiscZeroSelectable {
/// @notice A short key attached to the seal to select the correct verifier implementation.
/// @dev The selector is taken from the hash of the verifier parameters. If two
/// receipts have different selectors (i.e. different verifier parameters), then it can
/// generally be assumed that they need distinct verifier implementations. This is used as
/// part of the RISC Zero versioning mechanism.
///
/// A selector is not intended to be collision resistant, in that it is possible to find
/// two preimages that result in the same selector. This is acceptable since it's purpose
/// to a route a request among a set of trusted verifiers, and to make errors of sending a
/// receipt to a mismatching verifiers easier to debug. It is analogous to the ABI
/// function selectors.
function SELECTOR() external view returns (bytes4);
}
lib/risc0-ethereum/contracts/src/IRiscZeroVerifier.sol
// Copyright 2025 RISC Zero, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.9;
import {reverseByteOrderUint32} from "./Util.sol";
/// @notice A receipt attesting to a claim using the RISC Zero proof system.
/// @dev A receipt contains two parts: a seal and a claim.
///
/// The seal is a zero-knowledge proof attesting to knowledge of a witness for the claim. The claim
/// is a set of public outputs, and for zkVM execution is the hash of a `ReceiptClaim` struct.
///
/// IMPORTANT: The `claimDigest` field must be a hash computed by the caller for verification to
/// have meaningful guarantees. Treat this similar to verifying an ECDSA signature, in that hashing
/// is a key operation in verification. The most common way to calculate this hash is to use the
/// `ReceiptClaimLib.ok(imageId, journalDigest).digest()` for successful executions.
struct Receipt {
bytes seal;
bytes32 claimDigest;
}
/// @notice Public claims about a zkVM guest execution, such as the journal committed to by the guest.
/// @dev Also includes important information such as the exit code and the starting and ending system
/// state (i.e. the state of memory). `ReceiptClaim` is a "Merkle-ized struct" supporting
/// partial openings of the underlying fields from a hash commitment to the full structure.
struct ReceiptClaim {
/// @notice Digest of the SystemState just before execution has begun.
bytes32 preStateDigest;
/// @notice Digest of the SystemState just after execution has completed.
bytes32 postStateDigest;
/// @notice The exit code for the execution.
ExitCode exitCode;
/// @notice A digest of the input to the guest.
/// @dev This field is currently unused and must be set to the zero digest.
bytes32 input;
/// @notice Digest of the Output of the guest, including the journal
/// and assumptions set during execution.
bytes32 output;
}
library ReceiptClaimLib {
using OutputLib for Output;
using SystemStateLib for SystemState;
bytes32 constant TAG_DIGEST = sha256("risc0.ReceiptClaim");
// Define a constant to ensure hashing is done at compile time. Can't use the
// SystemStateLib.digest method here because the Solidity compiler complains.
bytes32 constant SYSTEM_STATE_ZERO_DIGEST = 0xa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e2;
/// @notice Construct a ReceiptClaim from the given imageId and journalDigest.
/// Returned ReceiptClaim will represent a successful execution of the zkVM, running
/// the program committed by imageId and resulting in the journal specified by
/// journalDigest.
/// @param imageId The identifier for the guest program.
/// @param journalDigest The SHA-256 digest of the journal bytes.
/// @dev Input hash and postStateDigest are set to all-zeros (i.e. no committed input, or
/// final memory state), the exit code is (Halted, 0), and there are no assumptions
/// (i.e. the receipt is unconditional).
function ok(bytes32 imageId, bytes32 journalDigest) internal pure returns (ReceiptClaim memory) {
return ReceiptClaim(
imageId,
SYSTEM_STATE_ZERO_DIGEST,
ExitCode(SystemExitCode.Halted, 0),
bytes32(0),
Output(journalDigest, bytes32(0)).digest()
);
}
function digest(ReceiptClaim memory claim) internal pure returns (bytes32) {
return sha256(
abi.encodePacked(
TAG_DIGEST,
// down
claim.input,
claim.preStateDigest,
claim.postStateDigest,
claim.output,
// data
uint32(claim.exitCode.system) << 24,
uint32(claim.exitCode.user) << 24,
// down.length
uint16(4) << 8
)
);
}
}
/// @notice Commitment to the memory state and program counter (pc) of the zkVM.
/// @dev The "pre" and "post" fields of the ReceiptClaim are digests of the system state at the
/// start are stop of execution. Programs are loaded into the zkVM by creating a memory image
/// of the loaded program, and creating a system state for initializing the zkVM. This is
/// known as the "image ID".
struct SystemState {
/// @notice Program counter.
uint32 pc;
/// @notice Root hash of a merkle tree which confirms the integrity of the memory image.
bytes32 merkle_root;
}
library SystemStateLib {
bytes32 constant TAG_DIGEST = sha256("risc0.SystemState");
function digest(SystemState memory state) internal pure returns (bytes32) {
return sha256(
abi.encodePacked(
TAG_DIGEST,
// down
state.merkle_root,
// data
reverseByteOrderUint32(state.pc),
// down.length
uint16(1) << 8
)
);
}
}
/// @notice Exit condition indicated by the zkVM at the end of the guest execution.
/// @dev Exit codes have a "system" part and a "user" part. Semantically, the system part is set to
/// indicate the type of exit (e.g. halt, pause, or system split) and is directly controlled by the
/// zkVM. The user part is an exit code, similar to exit codes used in Linux, chosen by the guest
/// program to indicate additional information (e.g. 0 to indicate success or 1 to indicate an
/// error).
struct ExitCode {
SystemExitCode system;
uint8 user;
}
/// @notice Exit condition indicated by the zkVM at the end of the execution covered by this proof.
/// @dev
/// `Halted` indicates normal termination of a program with an interior exit code returned from the
/// guest program. A halted program cannot be resumed.
///
/// `Paused` indicates the execution ended in a paused state with an interior exit code set by the
/// guest program. A paused program can be resumed such that execution picks up where it left
/// of, with the same memory state.
///
/// `SystemSplit` indicates the execution ended on a host-initiated system split. System split is
/// mechanism by which the host can temporarily stop execution of the execution ended in a system
/// split has no output and no conclusions can be drawn about whether the program will eventually
/// halt. System split is used in continuations to split execution into individually provable segments.
enum SystemExitCode {
Halted,
Paused,
SystemSplit
}
/// @notice Output field in the `ReceiptClaim`, committing to a claimed journal and assumptions list.
struct Output {
/// @notice Digest of the journal committed to by the guest execution.
bytes32 journalDigest;
/// @notice Digest of the ordered list of `ReceiptClaim` digests corresponding to the
/// calls to `env::verify` and `env::verify_integrity`.
/// @dev Verifying the integrity of a `Receipt` corresponding to a `ReceiptClaim` with a
/// non-empty assumptions list does not guarantee unconditionally any of the claims over the
/// guest execution (i.e. if the assumptions list is non-empty, then the journal digest cannot
/// be trusted to correspond to a genuine execution). The claims can be checked by additional
/// verifying a `Receipt` for every digest in the assumptions list.
bytes32 assumptionsDigest;
}
library OutputLib {
bytes32 constant TAG_DIGEST = sha256("risc0.Output");
function digest(Output memory output) internal pure returns (bytes32) {
return sha256(
abi.encodePacked(
TAG_DIGEST,
// down
output.journalDigest,
output.assumptionsDigest,
// down.length
uint16(2) << 8
)
);
}
}
/// @notice Error raised when cryptographic verification of the zero-knowledge proof fails.
error VerificationFailed();
/// @notice Verifier interface for RISC Zero receipts of execution.
interface IRiscZeroVerifier {
/// @notice Verify that the given seal is a valid RISC Zero proof of execution with the
/// given image ID and journal digest. Reverts on failure.
/// @dev This method additionally ensures that the input hash is all-zeros (i.e. no
/// committed input), the exit code is (Halted, 0), and there are no assumptions (i.e. the
/// receipt is unconditional).
/// @param seal The encoded cryptographic proof (i.e. SNARK).
/// @param imageId The identifier for the guest program.
/// @param journalDigest The SHA-256 digest of the journal bytes.
function verify(bytes calldata seal, bytes32 imageId, bytes32 journalDigest) external view;
/// @notice Verify that the given receipt is a valid RISC Zero receipt, ensuring the `seal` is
/// valid a cryptographic proof of the execution with the given `claim`. Reverts on failure.
/// @param receipt The receipt to be verified.
function verifyIntegrity(Receipt calldata receipt) external view;
}
lib/risc0-ethereum/contracts/src/StructHash.sol
// Copyright 2024 RISC Zero, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.9;
import {SafeCast} from "openzeppelin/contracts/utils/math/SafeCast.sol";
import {reverseByteOrderUint16} from "./Util.sol";
/// @notice Structural hashing routines used for RISC Zero data structures.
/// @dev
/// StructHash implements hashing for structs, incorporating type tags for domain separation.
/// The goals of this library are:
/// * Collision resistance: it should not be possible to find two semantically distinct values that
/// produce the same digest.
/// * Simplicity: implementations should be simple to understand and write, as these methods must
/// be implemented in multiple languages and environments, including zkSNARK circuits.
/// * Incremental openings: it should be possible to incrementally open a nested struct without
/// needing to open (very many) extra fields (i.e. the struct should be "Merkle-ized").
library StructHash {
using SafeCast for uint256;
// @notice Compute the struct digest with the given tag digest and digest fields down.
function taggedStruct(bytes32 tagDigest, bytes32[] memory down) internal pure returns (bytes32) {
bytes memory data = new bytes(0);
return taggedStruct(tagDigest, down, data);
}
// @notice Compute the struct digest with the given tag digest, digest fields down, and data.
function taggedStruct(bytes32 tagDigest, bytes32[] memory down, bytes memory data)
internal
pure
returns (bytes32)
{
uint16 downLen = down.length.toUint16();
// swap the byte order to encode as little-endian.
bytes2 downLenLE = bytes2((downLen << 8) | (downLen >> 8));
return sha256(abi.encodePacked(tagDigest, down, data, downLenLE));
}
// @notice Add an element (head) to the incremental hash of a list (tail).
function taggedListCons(bytes32 tagDigest, bytes32 head, bytes32 tail) internal pure returns (bytes32) {
bytes32[] memory down = new bytes32[](2);
down[0] = head;
down[1] = tail;
return taggedStruct(tagDigest, down);
}
// @notice Hash the list by using taggedListCons to repeatedly add to the head of the list.
function taggedList(bytes32 tagDigest, bytes32[] memory list) internal pure returns (bytes32) {
bytes32 curr = bytes32(0x0000000000000000000000000000000000000000000000000000000000000000);
for (uint256 i = 0; i < list.length; i++) {
curr = taggedListCons(tagDigest, list[list.length - 1 - i], curr);
}
return curr;
}
}
lib/risc0-ethereum/contracts/src/Util.sol
// Copyright 2024 RISC Zero, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.9;
/// @notice reverse the byte order of the uint256 value.
/// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding
/// ensure that the encoded value will be little-endian.
/// Written by k06a. https://ethereum.stackexchange.com/a/83627
function reverseByteOrderUint256(uint256 input) pure returns (uint256 v) {
v = input;
// swap bytes
v = ((v & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8)
| ((v & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF) << 8);
// swap 2-byte long pairs
v = ((v & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16)
| ((v & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) << 16);
// swap 4-byte long pairs
v = ((v & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32)
| ((v & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) << 32);
// swap 8-byte long pairs
v = ((v & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64)
| ((v & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) << 64);
// swap 16-byte long pairs
v = (v >> 128) | (v << 128);
}
/// @notice reverse the byte order of the uint32 value.
/// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding
/// ensure that the encoded value will be little-endian.
/// Written by k06a. https://ethereum.stackexchange.com/a/83627
function reverseByteOrderUint32(uint32 input) pure returns (uint32 v) {
v = input;
// swap bytes
v = ((v & 0xFF00FF00) >> 8) | ((v & 0x00FF00FF) << 8);
// swap 2-byte long pairs
v = (v >> 16) | (v << 16);
}
/// @notice reverse the byte order of the uint16 value.
/// @dev Solidity uses a big-endian ABI encoding. Reversing the byte order before encoding
/// ensure that the encoded value will be little-endian.
/// Written by k06a. https://ethereum.stackexchange.com/a/83627
function reverseByteOrderUint16(uint16 input) pure returns (uint16 v) {
v = input;
// swap bytes
v = (v >> 8) | ((v & 0x00FF) << 8);
}
lib/risc0-ethereum/contracts/src/groth16/ControlID.sol
// Copyright 2025 RISC Zero, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
// This file is automatically generated by:
// cargo xtask bootstrap-groth16
pragma solidity ^0.8.9;
library ControlID {
bytes32 public constant CONTROL_ROOT = hex"a54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f56";
// NOTE: This has the opposite byte order to the value in the risc0 repository.
bytes32 public constant BN254_CONTROL_ID = hex"04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0";
}
lib/risc0-ethereum/contracts/src/groth16/Groth16Verifier.sol
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
contract Groth16Verifier {
// Scalar field size
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
// Base field size
uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
// Verification Key data
uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant deltax1 = 1668323501672964604911431804142266013250380587483576094566949227275849579036;
uint256 constant deltax2 = 12043754404802191763554326994664886008979042643626290185762540825416902247219;
uint256 constant deltay1 = 7710631539206257456743780535472368339139328733484942210876916214502466455394;
uint256 constant deltay2 = 13740680757317479711909903993315946540841369848973133181051452051592786724563;
uint256 constant IC0x = 8446592859352799428420270221449902464741693648963397251242447530457567083492;
uint256 constant IC0y = 1064796367193003797175961162477173481551615790032213185848276823815288302804;
uint256 constant IC1x = 3179835575189816632597428042194253779818690147323192973511715175294048485951;
uint256 constant IC1y = 20895841676865356752879376687052266198216014795822152491318012491767775979074;
uint256 constant IC2x = 5332723250224941161709478398807683311971555792614491788690328996478511465287;
uint256 constant IC2y = 21199491073419440416471372042641226693637837098357067793586556692319371762571;
uint256 constant IC3x = 12457994489566736295787256452575216703923664299075106359829199968023158780583;
uint256 constant IC3y = 19706766271952591897761291684837117091856807401404423804318744964752784280790;
uint256 constant IC4x = 19617808913178163826953378459323299110911217259216006187355745713323154132237;
uint256 constant IC4y = 21663537384585072695701846972542344484111393047775983928357046779215877070466;
uint256 constant IC5x = 6834578911681792552110317589222010969491336870276623105249474534788043166867;
uint256 constant IC5y = 15060583660288623605191393599883223885678013570733629274538391874953353488393;
// Memory data
uint16 constant pVk = 0;
uint16 constant pPairing = 128;
uint16 constant pLastMem = 896;
function verifyProof(
uint256[2] calldata _pA,
uint256[2][2] calldata _pB,
uint256[2] calldata _pC,
uint256[5] calldata _pubSignals
) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
}
// G1 function to multiply a G1 value(x,y) to value in an address
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn, 32), y)
mstore(add(mIn, 64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
mstore(add(mIn, 64), mload(pR))
mstore(add(mIn, 96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
}
function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
let _pPairing := add(pMem, pPairing)
let _pVk := add(pMem, pVk)
mstore(_pVk, IC0x)
mstore(add(_pVk, 32), IC0y)
// Compute the linear combination vk_x
g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))
g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))
g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))
// -A
mstore(_pPairing, calldataload(pA))
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))
// B
mstore(add(_pPairing, 64), calldataload(pB))
mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
mstore(add(_pPairing, 160), calldataload(add(pB, 96)))
// alpha1
mstore(add(_pPairing, 192), alphax)
mstore(add(_pPairing, 224), alphay)
// beta2
mstore(add(_pPairing, 256), betax1)
mstore(add(_pPairing, 288), betax2)
mstore(add(_pPairing, 320), betay1)
mstore(add(_pPairing, 352), betay2)
// vk_x
mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))
// gamma2
mstore(add(_pPairing, 448), gammax1)
mstore(add(_pPairing, 480), gammax2)
mstore(add(_pPairing, 512), gammay1)
mstore(add(_pPairing, 544), gammay2)
// C
mstore(add(_pPairing, 576), calldataload(pC))
mstore(add(_pPairing, 608), calldataload(add(pC, 32)))
// delta2
mstore(add(_pPairing, 640), deltax1)
mstore(add(_pPairing, 672), deltax2)
mstore(add(_pPairing, 704), deltay1)
mstore(add(_pPairing, 736), deltay2)
let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)
isOk := and(success, mload(_pPairing))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, pLastMem))
// Validate that all evaluations â F
checkField(calldataload(add(_pubSignals, 0)))
checkField(calldataload(add(_pubSignals, 32)))
checkField(calldataload(add(_pubSignals, 64)))
checkField(calldataload(add(_pubSignals, 96)))
checkField(calldataload(add(_pubSignals, 128)))
// Validate all evaluations
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)
mstore(0, isValid)
return(0, 0x20)
}
}
}
node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
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":"bytes32","name":"control_root","internalType":"bytes32"},{"type":"bytes32","name":"bn254_control_id","internalType":"bytes32"}]},{"type":"error","name":"SelectorMismatch","inputs":[{"type":"bytes4","name":"received","internalType":"bytes4"},{"type":"bytes4","name":"expected","internalType":"bytes4"}]},{"type":"error","name":"VerificationFailed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"BN254_CONTROL_ID","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes16","name":"","internalType":"bytes16"}],"name":"CONTROL_ROOT_0","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes16","name":"","internalType":"bytes16"}],"name":"CONTROL_ROOT_1","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes4","name":"","internalType":"bytes4"}],"name":"SELECTOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"VERSION","inputs":[]},{"type":"function","stateMutability":"view","outputs":[],"name":"verify","inputs":[{"type":"bytes","name":"seal","internalType":"bytes"},{"type":"bytes32","name":"imageId","internalType":"bytes32"},{"type":"bytes32","name":"journalDigest","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[],"name":"verifyIntegrity","inputs":[{"type":"tuple","name":"receipt","internalType":"struct Receipt","components":[{"type":"bytes","name":"seal","internalType":"bytes"},{"type":"bytes32","name":"claimDigest","internalType":"bytes32"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"verifyProof","inputs":[{"type":"uint256[2]","name":"_pA","internalType":"uint256[2]"},{"type":"uint256[2][2]","name":"_pB","internalType":"uint256[2][2]"},{"type":"uint256[2]","name":"_pC","internalType":"uint256[2]"},{"type":"uint256[5]","name":"_pubSignals","internalType":"uint256[5]"}]}]
Contract Creation Code
0x6101808060405234610c2f57604081611f1780380380916100208285610c33565b833981010312610c2f5780516020918201519091600883811c7eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff169084901b7fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff001617601081811c7dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff1691901b7fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000161780821c7bffffffff00000000ffffffff00000000ffffffff00000000ffffffff16911b7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff000000001617604081811c77ffffffffffffffff0000000000000000ffffffffffffffff1691901b7fffffffffffffffff0000000000000000ffffffffffffffff00000000000000001617608081811c91901b176001600160801b031981811660a052608091821b16905260c08190526040517f72697363302e47726f74683136526563656970745665726966696572506172618152656d657465727360d01b602082810191909152905f9060269060025afa15610a7b575f5190600881811c7eff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff1691901b7fff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff001617601081811c7dffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff1691901b7fffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff00001617602081811c7bffffffff00000000ffffffff00000000ffffffff00000000ffffffff1691901b7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff000000001617604081811c77ffffffffffffffff0000000000000000ffffffffffffffff1691901b7fffffffffffffffff0000000000000000ffffffffffffffff00000000000000001617608081811c91901b179060e0604051916103068284610c33565b60068352601f19820136602085013760205f6103846040517f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be4848201527f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd4604082015260408152610378606082610c33565b60405191828092610c6a565b039060025afa15610a7b575f5161039a84610c93565b5260205f6103fe6040517f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f848201527f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff6642604082015260408152610378606082610c33565b039060025afa15610a7b575f5161041484610ca0565b5260205f6104786040517f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc347848201527f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b604082015260408152610378606082610c33565b039060025afa15610a7b575f51835160021015610afa57606084015260205f6104f76040517f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a7848201527f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd6604082015260408152610378606082610c33565b039060025afa15610a7b575f51835160031015610afa57608084015260205f6105766040517f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d848201527f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e82604082015260408152610378606082610c33565b039060025afa15610a7b575f51835160041015610afa5760a084015260205f6105f56040517f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d493848201527f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e809604082015260408152610378606082610c33565b039060025afa15610a7b575f51835160051015610afa5760c084015260205f601a6040517f72697363305f67726f746831362e566572696679696e674b6579000000000000815260025afa15610a7b575f519460205f6106ab6040517f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e2848201527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d1926604082015260408152610378606082610c33565b039060025afa15610a7b575f519460205f6107686040517f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c848201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab60408201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a760608201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec860808201526080815261037860a082610c33565b039060025afa15610a7b575f519660205f6108256040517f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2848201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed60408201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b60608201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60808201526080815261037860a082610c33565b039060025afa15610a7b575f5160205f6108e16040517f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c848201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e033360408201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d03076260608201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d360808201526080815261037860a082610c33565b039060025afa15610a7b575f519060205f601d6040517f72697363305f67726f746831362e566572696679696e674b65792e4943000000815260025afa15610a7b575f8051610140526101008190526060610120526020610160525b885180610100511015610b22575f19810190808211610b0e576101005190035f1901908111610b0e578951811015610afa57610160519060051b8a010151906040519161098d6101205184610c33565b600283526101605160409036908501376109a683610c93565b526109b082610ca0565b52604051906109c26101605183610c33565b5f8252601f196101605101366101605184013780519061ffff8211610aa45791604051928391610140516101605184015260408301825190926101605101905f905b808210610a865750505092610a1f60029392610a4c95610c6a565b9061ffff60f01b9061ff0060ff8260081c169160081b161760f01b16815203601d19810184520182610c33565b5f60405180610a5f816101605195610c6a565b039060025afa15610a7b575f516101008051600101905261093d565b6040513d5f823e3d90fd5b82518552610160518896509485019490920191600190910190610a04565b60405162461bcd60e51b8152610160516004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203160448201526536206269747360d01b6064820152608490fd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5091908a8a604051956101605187015260408601526060850152608084015260a083015260c0820152600560f81b8582015260c28152610b6360e282610c33565b5f60405180610b76816101605195610c6a565b039060025afa15610a7b575f51916040519361016051850152604084015260608301526080820152600360f81b60a082015260828152610bb760a282610c33565b5f60405180610bca816101605195610c6a565b039060025afa15610a7b575f516001600160e01b03191681526040516112669182610cb183396080518281816105c50152610dc0015260a0518281816105810152610de6015260c0518281816101690152610e1e01525181818160ae0152610d2c0152f35b5f80fd5b601f909101601f19168101906001600160401b03821190821017610c5657604052565b634e487b7160e01b5f52604160045260245ffd5b908151915f5b838110610c80575050015f815290565b8060208092840101518185015201610c70565b805115610afa5760200190565b805160011015610afa576040019056fe60806040526004361015610011575f80fd5b5f3560e01c8063053c238d146100945780631599ead51461008f578063258038e21461008a57806334baeab9146100855780638989fa2e146100805780639181e4b11461007b578063ab750e75146100765763ffa1ad7414610071575f80fd5b61072a565b6105e9565b6105a5565b610561565b6101a7565b610152565b6100db565b346100d7575f3660031901126100d75763ffffffff60e01b7f00000000000000000000000000000000000000000000000000000000000000001660805260206080f35b5f80fd5b346100d75760203660031901126100d75760043567ffffffffffffffff81116100d75780360360406003198201126100d757600482013590602219018112156100d757810160048101359067ffffffffffffffff82116100d7576024019080360382136100d757602461015093013591610d28565b005b346100d7575f3660031901126100d75760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b906004916044116100d757565b9060c491610104116100d757565b346100d7576101a03660031901126100d7576101c23661018c565b3660c4116100d7576101d336610199565b366101a4116100d757604051906103808201604052610104356101f581610786565b610124359361020385610786565b6101443561021081610786565b6101643561021d81610786565b610184359161022b83610786565b60808701977f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be4885260208801957f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd4875261028590896107b7565b61028f9088610843565b61029990876108cf565b6102a3908661095b565b6102ad90856109e7565b803585527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760209182013581030660a085015260443560c085015260643560e085015260843561010085015260a4356101208501527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e26101408501527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266101608501527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101808501527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101a08501527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101c08501527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec86101e0850152835161020085015290516102208401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26102408401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6102608401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102808401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6102a084015281356102c084015201356102e08201527f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c6103008201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e03336103208201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d0307626103408201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d36103609091015280806107cf195a01602092600861030092fa9051165f5260205ff35b346100d7575f3660031901126100d75760206040516001600160801b03197f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100d7575f3660031901126100d75760206040516001600160801b03197f0000000000000000000000000000000000000000000000000000000000000000168152f35b346100d75760603660031901126100d75760043567ffffffffffffffff81116100d757366023820112156100d75780600401359067ffffffffffffffff82116100d75736602483830101116100d757610150916024359060246044359301610a73565b634e487b7160e01b5f52604160045260245ffd5b6040810190811067ffffffffffffffff82111761067c57604052565b61064c565b60a0810190811067ffffffffffffffff82111761067c57604052565b6060810190811067ffffffffffffffff82111761067c57604052565b90601f8019910116810190811067ffffffffffffffff82111761067c57604052565b604051906106ea6040836106b9565b565b604051906106ea60a0836106b9565b906106ea60405192836106b9565b5f5b83811061071a5750505f910152565b818101518382015260200161070b565b346100d7575f3660031901126100d7576107786040805161074a81610660565b6005815260208101640332e302e360dc1b815282519384926020845251809281602086015285850190610709565b601f01601f19168101030190f35b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000111156107af57565b5f805260205ff35b604051917f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f83527f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff664260208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc34783527f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b60208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a783527f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd660208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d83527f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e8260208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d49383527f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e80960208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b91610b28906106ea945f6080604051610a8b81610681565b828152826020820152604051610aa081610660565b83815283602082015260408201528260608201520152610ae1610ac16106db565b915f83525f6020840152610ad36106db565b9081525f60208201526111cf565b90610aea6106ec565b9283527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e2602084015260408301525f60608301526080820152610f61565b91610d28565b906004116100d75790600490565b90929192836004116100d75783116100d757600401916003190190565b356001600160e01b0319811692919060048210610b74575050565b6001600160e01b031960049290920360031b82901b16169150565b9080601f830112156100d75760405191610baa6040846106b9565b8290604081019283116100d757905b828210610bc65750505090565b8135815260209182019101610bb9565b610100818303126100d75760405191610bee8361069d565b610bf88183610b8f565b835280605f830112156100d7576040918251610c1484826106b9565b8060c08301928484116100d75785809101915b848310610c47575050506020850152610c409190610b8f565b9082015290565b602090610c548785610b8f565b8152019101908590610c27565b908160209103126100d7575180151581036100d75790565b905f905b60028210610c8a57505050565b6020806001928551815201930191019091610c7d565b919493929094610cb5836101a0810197610c79565b5f604084015b60028210610cff5750505090610cd86101009260c0830190610c79565b015f905b60058210610ce957505050565b6020806001928551815201930191019091610cdc565b6020604082610d116001948751610c79565b01930191019091610cbb565b6040513d5f823e3d90fd5b90917f0000000000000000000000000000000000000000000000000000000000000000610d6e610d61610d5b8686610b2e565b90610b59565b6001600160e01b03191690565b6001600160e01b0319821603610ebb575090610da2610d9a84610d9260209561104c565b969094610b3c565b810190610bd6565b90610e5d82519160408585015194015195610dbd60a06106fb565b917f000000000000000000000000000000000000000000000000000000000000000060801c83527f000000000000000000000000000000000000000000000000000000000000000060801c8784015260801c604083015260801c60608201527f0000000000000000000000000000000000000000000000000000000000000000608082015260405195869485946334baeab960e01b865260048601610ca0565b0381305afa908115610eb6575f91610e87575b5015610e7857565b63439cc0cd60e01b5f5260045ffd5b610ea9915060203d602011610eaf575b610ea181836106b9565b810190610c61565b5f610e70565b503d610e97565b610d1d565b610eee90610ecc610d5b8686610b2e565b632e2ce35360e21b5f526001600160e01b031990811660045216602452604490565b5ffd5b60031115610efb57565b634e487b7160e01b5f52602160045260245ffd5b60205f60126040517172697363302e52656365697074436c61696d60701b815260025afa15610eb6575f5190565b516003811015610efb5790565b90610f5d60209282815194859201610709565b0190565b5f61103c602092611030610f73610f0f565b611022606084015193805190888101519060406080820151910190610fca610fae610fc48d610fba610fa58751610f3d565b610fae81610ef1565b60181b63ff0000001690565b9551015160ff1690565b60ff1690565b604080518d8101988952602089019a909a52870194909452606086019290925260808501919091526001600160e01b031960e091821b811660a086015291901b1660a4830152600160fa1b60a8830152839160aa0190565b03601f1981018352826106b9565b60405191828092610f4a565b039060025afa15610eb6575f5190565b8060081c9060081b907cff000000ff000000ff000000ff000000ff000000ff000000ff000000ff7dff000000ff000000ff000000ff000000ff000000ff000000ff000000ff007fff000000ff000000ff000000ff000000ff000000ff000000ff000000ff00000084167eff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000084161760101c931691161760101b176111327bffffffff00000000ffffffff00000000ffffffff00000000ffffffff7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000831660201c921660201b90565b17604081811c77ffffffffffffffff0000000000000000ffffffffffffffff169177ffffffffffffffff0000000000000000ffffffffffffffff19911b161761118561117e8260801c90565b9160801b90565b17906111bc6111a36111978460801c90565b6001600160801b031690565b60801b6fffffffffffffffffffffffffffffffff191690565b916001600160801b03199060801b169190565b60205f600c6040516b1c9a5cd8cc0b93dd5d1c1d5d60a21b815260025afa15610eb6575f8051825160209384015160408051808701949094528301919091526060820152600160f91b60808201526062815261103c906110306082826106b956fea264697066735822122080344eff777dbba32930eb085cd30c37bdbf0c9b4206cdf9f3e55b064ba11ecb64736f6c63430008210033a54dc85ac99f851c92d7c96d7318af41dbe7c0194edfcc37eb4d422a998c1f5604446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0
Deployed ByteCode
0x60806040526004361015610011575f80fd5b5f3560e01c8063053c238d146100945780631599ead51461008f578063258038e21461008a57806334baeab9146100855780638989fa2e146100805780639181e4b11461007b578063ab750e75146100765763ffa1ad7414610071575f80fd5b61072a565b6105e9565b6105a5565b610561565b6101a7565b610152565b6100db565b346100d7575f3660031901126100d75763ffffffff60e01b7f73c457ba000000000000000000000000000000000000000000000000000000001660805260206080f35b5f80fd5b346100d75760203660031901126100d75760043567ffffffffffffffff81116100d75780360360406003198201126100d757600482013590602219018112156100d757810160048101359067ffffffffffffffff82116100d7576024019080360382136100d757602461015093013591610d28565b005b346100d7575f3660031901126100d75760206040517f04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac08152f35b906004916044116100d757565b9060c491610104116100d757565b346100d7576101a03660031901126100d7576101c23661018c565b3660c4116100d7576101d336610199565b366101a4116100d757604051906103808201604052610104356101f581610786565b610124359361020385610786565b6101443561021081610786565b6101643561021d81610786565b610184359161022b83610786565b60808701977f12ac9a25dcd5e1a832a9061a082c15dd1d61aa9c4d553505739d0f5d65dc3be4885260208801957f025aa744581ebe7ad91731911c898569106ff5a2d30f3eee2b23c60ee980acd4875261028590896107b7565b61028f9088610843565b61029990876108cf565b6102a3908661095b565b6102ad90856109e7565b803585527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760209182013581030660a085015260443560c085015260643560e085015260843561010085015260a4356101208501527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e26101408501527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d19266101608501527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101808501527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101a08501527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101c08501527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec86101e0850152835161020085015290516102208401527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26102408401527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6102608401527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102808401527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6102a084015281356102c084015201356102e08201527f03b03cd5effa95ac9bee94f1f5ef907157bda4812ccf0b4c91f42bb629f83a1c6103008201527f1aa085ff28179a12d922dba0547057ccaae94b9d69cfaa4e60401fea7f3e03336103208201527f110c10134f200b19f6490846d518c9aea868366efb7228ca5c91d2940d0307626103408201527f1e60f31fcbf757e837e867178318832d0b2d74d59e2fea1c7142df187d3fc6d36103609091015280806107cf195a01602092600861030092fa9051165f5260205ff35b346100d7575f3660031901126100d75760206040516001600160801b03197f561f8c992a424deb37ccdf4e19c0e7db00000000000000000000000000000000168152f35b346100d7575f3660031901126100d75760206040516001600160801b03197f41af18736dc9d7921c859fc95ac84da500000000000000000000000000000000168152f35b346100d75760603660031901126100d75760043567ffffffffffffffff81116100d757366023820112156100d75780600401359067ffffffffffffffff82116100d75736602483830101116100d757610150916024359060246044359301610a73565b634e487b7160e01b5f52604160045260245ffd5b6040810190811067ffffffffffffffff82111761067c57604052565b61064c565b60a0810190811067ffffffffffffffff82111761067c57604052565b6060810190811067ffffffffffffffff82111761067c57604052565b90601f8019910116810190811067ffffffffffffffff82111761067c57604052565b604051906106ea6040836106b9565b565b604051906106ea60a0836106b9565b906106ea60405192836106b9565b5f5b83811061071a5750505f910152565b818101518382015260200161070b565b346100d7575f3660031901126100d7576107786040805161074a81610660565b6005815260208101640332e302e360dc1b815282519384926020845251809281602086015285850190610709565b601f01601f19168101030190f35b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000111156107af57565b5f805260205ff35b604051917f0707b920bc978c02f292fae2036e057be54294114ccc3c8769d883f688a1423f83527f2e32a094b7589554f7bc357bf63481acd2d55555c203383782a4650787ff664260208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f0bca36e2cbe6394b3e249751853f961511011c7148e336f4fd974644850fc34783527f2ede7c9acf48cf3a3729fa3d68714e2a8435d4fa6db8f7f409c153b1fcdf9b8b60208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f1b8af999dbfbb3927c091cc2aaf201e488cbacc3e2c6b6fb5a25f9112e04f2a783527f2b91a26aa92e1b6f5722949f192a81c850d586d81a60157f3e9cf04f679cccd660208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f2b5f494ed674235b8ac1750bdfd5a7615f002d4a1dcefeddd06eda5a076ccd0d83527f2fe520ad2020aab9cbba817fcbb9a863b8a76ff88f14f912c5e71665b2ad5e8260208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b604051917f0f1c3c0d5d9da0fa03666843cde4e82e869ba5252fce3c25d5940320b1c4d49383527f214bfcff74f425f6fe8c0d07b307482d8bc8bb2f3608f68287aa01bd0b69e80960208401526040830190815260408360608160076107cf195a01fa156107af57815190526020810151606083015260409160809060066107cf195a01fa156107af57565b91610b28906106ea945f6080604051610a8b81610681565b828152826020820152604051610aa081610660565b83815283602082015260408201528260608201520152610ae1610ac16106db565b915f83525f6020840152610ad36106db565b9081525f60208201526111cf565b90610aea6106ec565b9283527fa3acc27117418996340b84e5a90f3ef4c49d22c79e44aad822ec9c313e1eb8e2602084015260408301525f60608301526080820152610f61565b91610d28565b906004116100d75790600490565b90929192836004116100d75783116100d757600401916003190190565b356001600160e01b0319811692919060048210610b74575050565b6001600160e01b031960049290920360031b82901b16169150565b9080601f830112156100d75760405191610baa6040846106b9565b8290604081019283116100d757905b828210610bc65750505090565b8135815260209182019101610bb9565b610100818303126100d75760405191610bee8361069d565b610bf88183610b8f565b835280605f830112156100d7576040918251610c1484826106b9565b8060c08301928484116100d75785809101915b848310610c47575050506020850152610c409190610b8f565b9082015290565b602090610c548785610b8f565b8152019101908590610c27565b908160209103126100d7575180151581036100d75790565b905f905b60028210610c8a57505050565b6020806001928551815201930191019091610c7d565b919493929094610cb5836101a0810197610c79565b5f604084015b60028210610cff5750505090610cd86101009260c0830190610c79565b015f905b60058210610ce957505050565b6020806001928551815201930191019091610cdc565b6020604082610d116001948751610c79565b01930191019091610cbb565b6040513d5f823e3d90fd5b90917f73c457ba00000000000000000000000000000000000000000000000000000000610d6e610d61610d5b8686610b2e565b90610b59565b6001600160e01b03191690565b6001600160e01b0319821603610ebb575090610da2610d9a84610d9260209561104c565b969094610b3c565b810190610bd6565b90610e5d82519160408585015194015195610dbd60a06106fb565b917f41af18736dc9d7921c859fc95ac84da50000000000000000000000000000000060801c83527f561f8c992a424deb37ccdf4e19c0e7db0000000000000000000000000000000060801c8784015260801c604083015260801c60608201527f04446e66d300eb7fb45c9726bb53c793dda407a62e9601618bb43c5c14657ac0608082015260405195869485946334baeab960e01b865260048601610ca0565b0381305afa908115610eb6575f91610e87575b5015610e7857565b63439cc0cd60e01b5f5260045ffd5b610ea9915060203d602011610eaf575b610ea181836106b9565b810190610c61565b5f610e70565b503d610e97565b610d1d565b610eee90610ecc610d5b8686610b2e565b632e2ce35360e21b5f526001600160e01b031990811660045216602452604490565b5ffd5b60031115610efb57565b634e487b7160e01b5f52602160045260245ffd5b60205f60126040517172697363302e52656365697074436c61696d60701b815260025afa15610eb6575f5190565b516003811015610efb5790565b90610f5d60209282815194859201610709565b0190565b5f61103c602092611030610f73610f0f565b611022606084015193805190888101519060406080820151910190610fca610fae610fc48d610fba610fa58751610f3d565b610fae81610ef1565b60181b63ff0000001690565b9551015160ff1690565b60ff1690565b604080518d8101988952602089019a909a52870194909452606086019290925260808501919091526001600160e01b031960e091821b811660a086015291901b1660a4830152600160fa1b60a8830152839160aa0190565b03601f1981018352826106b9565b60405191828092610f4a565b039060025afa15610eb6575f5190565b8060081c9060081b907cff000000ff000000ff000000ff000000ff000000ff000000ff000000ff7dff000000ff000000ff000000ff000000ff000000ff000000ff000000ff007fff000000ff000000ff000000ff000000ff000000ff000000ff000000ff00000084167eff000000ff000000ff000000ff000000ff000000ff000000ff000000ff000084161760101c931691161760101b176111327bffffffff00000000ffffffff00000000ffffffff00000000ffffffff7fffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000831660201c921660201b90565b17604081811c77ffffffffffffffff0000000000000000ffffffffffffffff169177ffffffffffffffff0000000000000000ffffffffffffffff19911b161761118561117e8260801c90565b9160801b90565b17906111bc6111a36111978460801c90565b6001600160801b031690565b60801b6fffffffffffffffffffffffffffffffff191690565b916001600160801b03199060801b169190565b60205f600c6040516b1c9a5cd8cc0b93dd5d1c1d5d60a21b815260025afa15610eb6575f8051825160209384015160408051808701949094528301919091526060820152600160f91b60808201526062815261103c906110306082826106b956fea264697066735822122080344eff777dbba32930eb085cd30c37bdbf0c9b4206cdf9f3e55b064ba11ecb64736f6c63430008210033