SP1VerificationSwitch

Description:

Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/verification/SP1VerificationSwitch.sol": {
      "content": "// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.28;

import {Verifier} from "./interfaces/Verifier.sol";
import {ISP1Verifier} from "succinctlabs-sp1-contracts/src/ISP1Verifier.sol";

/**
 * @title SP1VerificationSwitch
 * @notice Switch contract for verifying SP1 zero-knowledge proofs with domain separation
 * @dev This contract acts as a wrapper around the SP1 verifier, providing dual verification
 *      for both program proofs and domain-specific proofs. It implements the Verifier interface
 *      and delegates actual verification to the SP1Verifier contract.
 */
contract SP1VerificationSwitch is Verifier {
    /// @notice Address of the SP1 verifier contract
    /// @dev This should be a valid SP1Verifier contract address
    address public sp1Verifier;

    /// @notice Domain verification key used for domain-specific proof verification
    /// @dev This is a 32-byte verification key for the domain circuit
    bytes32 public domainVK;

    /**
     * @notice Returns the verifier cast to the ISP1Verifier interface
     * @return The verifier as an ISP1Verifier interface
     * @dev This is a convenience function for type casting
     */
    function getVerifier() public view returns (ISP1Verifier) {
        return ISP1Verifier(sp1Verifier);
    }

    /**
     * @notice Constructs the SP1VerificationSwitch
     * @param _sp1Verifier Address of the SP1 verifier contract
     * @param _domainVK Domain verification key (32 bytes)
     * @dev The SP1 verifier address must not be the zero address
     */
    constructor(address _sp1Verifier, bytes32 _domainVK) {
        // Check that verifier is a valid address
        require(_sp1Verifier != address(0), "Invalid SP1 verifier address");

        sp1Verifier = _sp1Verifier;
        domainVK = _domainVK;
    }

    /**
     * @notice Verifies both program and domain proofs using the SP1 verifier
     * @param vk The verification key for the program proof (must be 32 bytes because SP1 uses a 32-byte hash)
     * @param proof The program proof to verify
     * @param inputs The public inputs for the program proof
     * @param payload The domain proof payload
     * @return bool True if both proofs are valid, reverts otherwise
     * @dev This function performs dual verification:
     *      1. Verifies the program proof using the provided vk
     *      2. Verifies the domain proof using the stored domainVK and first 32 bytes of inputs
     * @custom:verification The function uses the first 32 bytes of inputs as the coprocessor root for domain verification
     */
    function verify(bytes calldata vk, bytes calldata proof, bytes calldata inputs, bytes calldata payload)
        external
        view
        override
        returns (bool)
    {
        // Validation
        require(vk.length == 32, "VK must be 32 bytes");

        // Convert to bytes32 - we've already checked the length above so it won't truncate
        bytes32 vkBytes32 = bytes32(vk);

        // Get verifier
        ISP1Verifier _sp1Verifier = getVerifier();

        // Verify program proofs
        _sp1Verifier.verifyProof(vkBytes32, inputs, proof);

        // Build the domain inputs by getting the first 32 bytes of the inputs (coprocessor root)
        bytes memory domainInputs = bytes(inputs[0:32]);

        // Verify the domain proof
        _sp1Verifier.verifyProof(domainVK, domainInputs, payload);

        return true;
    }
}
"
    },
    "src/verification/interfaces/Verifier.sol": {
      "content": "// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.28;

/**
 * @title Verifier
 * @dev Common interface for a verifier contract that can verify zk proofs.
 *
 * This interface is used to abstract the verification process, allowing different implementations
 * to be used without changing the code that relies on it.
 */
interface Verifier {
    /**
     * @dev Verifies a proof against the given inputs with a given VK.
     * @param vk The verification key to use for the proof.
     * @param proof The proof to verify.
     * @param inputs The inputs to verify against.
     * @param payload Additional payload, which in first version will be the domain proof to be validated against the domain VK.
     * @return True if the proof is valid, false otherwise.
     */
    function verify(bytes calldata vk, bytes calldata proof, bytes calldata inputs, bytes calldata payload)
        external
        view
        returns (bool);
}
"
    },
    "dependencies/succinctlabs-sp1-contracts-4.0.0/contracts/src/ISP1Verifier.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @title SP1 Verifier Interface
/// @author Succinct Labs
/// @notice This contract is the interface for the SP1 Verifier.
interface ISP1Verifier {
    /// @notice Verifies a proof with given public values and vkey.
    /// @dev It is expected that the first 4 bytes of proofBytes must match the first 4 bytes of
    /// target verifier's VERIFIER_HASH.
    /// @param programVKey The verification key for the RISC-V program.
    /// @param publicValues The public values encoded as bytes.
    /// @param proofBytes The proof of the program execution the SP1 zkVM encoded as bytes.
    function verifyProof(
        bytes32 programVKey,
        bytes calldata publicValues,
        bytes calldata proofBytes
    ) external view;
}

interface ISP1VerifierWithHash is ISP1Verifier {
    /// @notice Returns the hash of the verifier.
    function VERIFIER_HASH() external pure returns (bytes32);
}
"
    }
  },
  "settings": {
    "remappings": [
      "@layerzerolabs/lz-evm-oapp-v2/=dependencies/@layerzerolabs-lz-evm-oapp-v2-3.0.81/",
      "@layerzerolabs/lz-evm-protocol-v2/=dependencies/@layerzerolabs-lz-evm-protocol-v2-3.0.81/",
      "@openzeppelin-contracts-upgradeable/=dependencies/@openzeppelin-contracts-upgradeable-5.2.0/",
      "@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.2.0/",
      "@stargatefinance/stg-evm-v2/=dependencies/@stargatefinance-stg-evm-v2-2.0.2/",
      "aave-v3-origin/=dependencies/aave-v3-origin-3.3.0/src/contracts/",
      "forge-std/=dependencies/forge-std-1.9.4/",
      "hyperlane/=dependencies/hyperlane-5.8.3/solidity/contracts/",
      "succinctlabs-sp1-contracts/=dependencies/succinctlabs-sp1-contracts-4.0.0/contracts/",
      "@layerzerolabs-lz-evm-oapp-v2-3.0.81/=dependencies/@layerzerolabs-lz-evm-oapp-v2-3.0.81/contracts/",
      "@layerzerolabs-lz-evm-protocol-v2-3.0.81/=dependencies/@layerzerolabs-lz-evm-protocol-v2-3.0.81/contracts/",
      "@openzeppelin-contracts-5.2.0/=dependencies/@openzeppelin-contracts-5.2.0/",
      "@openzeppelin-contracts-upgradeable-5.2.0/=dependencies/@openzeppelin-contracts-upgradeable-5.2.0/",
      "@stargatefinance-stg-evm-v2-2.0.2/=dependencies/@stargatefinance-stg-evm-v2-2.0.2/src/",
      "aave-v3-origin-3.3.0/=dependencies/aave-v3-origin-3.3.0/src/",
      "ds-test/=dependencies/aave-v3-origin-3.3.0/lib/forge-std/lib/ds-test/src/",
      "forge-std-1.9.4/=dependencies/forge-std-1.9.4/src/",
      "hyperlane-5.8.3/=dependencies/hyperlane-5.8.3/",
      "openzeppelin-contracts-upgradeable/=dependencies/aave-v3-origin-3.3.0/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/",
      "openzeppelin-contracts/=dependencies/aave-v3-origin-3.3.0/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/",
      "solidity-utils/=dependencies/aave-v3-origin-3.3.0/lib/solidity-utils/src/",
      "succinctlabs-sp1-contracts-4.0.0/=dependencies/succinctlabs-sp1-contracts-4.0.0/"
    ],
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "metadata": {
      "useLiteralContent": false,
      "bytecodeHash": "ipfs",
      "appendCBOR": true
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "evmVersion": "cancun",
    "viaIR": true
  }
}}

Tags:
Proxy, Upgradeable, Factory|addr:0x528f6c0fc4b2d0857b7e4fdab25907d0d0aaa3cf|verified:true|block:23449756|tx:0xc4dfe550a0111ee6a0399caedcb385b8490d4bf505ff60f1cbad5fce56caf1ba|first_check:1758962759

Submitted on: 2025-09-27 10:46:00

Comments

Log in to comment.

No comments yet.