Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deploy-config/local.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"multiproofIntermediateBlockInterval": 10,
"multiproofGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000001",
"nitroEnclaveVerifier": "0x0000000000000000000000000000000000000000",
"nitroValidator": "0x0000000000000000000000000000000000000000",
"operatorFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"operatorFeeVaultRecipient": "0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec",
"operatorFeeVaultWithdrawalNetwork": 0,
Expand Down
1 change: 1 addition & 0 deletions deploy-config/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"multiproofGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000001",
"multiproofIntermediateBlockInterval": 30,
"nitroEnclaveVerifier": "0x0000000000000000000000000000000000000000",
"nitroValidator": "0x0000000000000000000000000000000000000000",
"operatorFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"operatorFeeVaultRecipient": "0xa3d596EAfaB6B13Ab18D40FaE1A962700C84ADEa",
"operatorFeeVaultWithdrawalNetwork": 0,
Expand Down
1 change: 1 addition & 0 deletions deploy-config/sepolia.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"multiproofGenesisOutputRoot": "0xbc273d5876d1858ecd5aaf4ce4eaf16c73f0187ca4271b774ed5da7d2254ba79",
"multiproofIntermediateBlockInterval": 30,
"nitroEnclaveVerifier": "0x77461a6434fFE3435206B19658F33274f3104e07",
"nitroValidator": "0x0000000000000000000000000000000000000000",
"operatorFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"operatorFeeVaultRecipient": "0xfd1D2e729aE8eEe2E146c033bf4400fE75284301",
"operatorFeeVaultWithdrawalNetwork": 0,
Expand Down
32 changes: 32 additions & 0 deletions interfaces/L1/proofs/tee/INitroValidator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import { CborElement } from "lib/nitro-validator/src/CborDecode.sol";

interface INitroValidator {
/// @notice Pointers to fields in a validated Nitro attestation's TBS bytes.
struct Ptrs {
CborElement moduleID;
uint64 timestamp;
CborElement digest;
CborElement[] pcrs;
CborElement cert;
CborElement[] cabundle;
CborElement publicKey;
CborElement userData;
CborElement nonce;
}

/// @notice Validates a Nitro attestation using offchain inverse hints.
/// @param attestationTbs The COSE Sign1 to-be-signed bytes.
/// @param signature The 96-byte P-384 attestation signature.
/// @param attestationSigHints Offchain inverse hints for the attestation signature.
/// @return ptrs Pointers to the validated attestation fields.
function validateAttestationWithHints(
bytes calldata attestationTbs,
bytes calldata signature,
bytes calldata attestationSigHints
)
external
returns (Ptrs memory ptrs);
}
6 changes: 3 additions & 3 deletions interfaces/L1/proofs/tee/ITEEProverRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
pragma solidity ^0.8.0;

import { IDisputeGameFactory } from "interfaces/L1/proofs/IDisputeGameFactory.sol";
import { INitroEnclaveVerifier } from "interfaces/L1/proofs/tee/INitroEnclaveVerifier.sol";
import { INitroValidator } from "interfaces/L1/proofs/tee/INitroValidator.sol";
import { GameType } from "src/libraries/bridge/Types.sol";

interface ITEEProverRegistry {
function NITRO_VERIFIER() external view returns (INitroEnclaveVerifier);
function NITRO_VALIDATOR() external view returns (INitroValidator);
function DISPUTE_GAME_FACTORY() external view returns (IDisputeGameFactory);
function gameType() external view returns (GameType);
function isRegisteredSigner(address signer) external view returns (bool);
Expand All @@ -17,7 +17,7 @@ interface ITEEProverRegistry {

function setProposer(address proposer, bool isValid) external;
function setGameType(GameType gameType_) external;
function registerSigner(bytes calldata output, bytes calldata proofBytes) external;
function registerSigner(bytes calldata attestationTbs, bytes calldata signature, bytes calldata hints) external;
function deregisterSigner(address signer) external;
function isValidSigner(address signer) external view returns (bool);
function getRegisteredSigners() external view returns (address[] memory);
Expand Down
4 changes: 3 additions & 1 deletion scripts/deploy/DeployConfig.s.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { Script } from "lib/forge-std/src/Script.sol";
import { console } from "lib/forge-std/src/console.sol";
import { Script } from "lib/forge-std/src/Script.sol";
import { stdJson } from "lib/forge-std/src/StdJson.sol";

/// @title DeployConfig
Expand All @@ -15,6 +15,7 @@ contract DeployConfig is Script {
address public finalSystemOwner;
address public l1FeeVaultRecipient;
address public nitroEnclaveVerifier;
address public nitroValidator;
address public operatorFeeVaultRecipient;
address public p2pSequencerAddress;
address public proxyAdminOwner;
Expand Down Expand Up @@ -71,6 +72,7 @@ contract DeployConfig is Script {
finalSystemOwner = _json.readAddress("$.finalSystemOwner");
l1FeeVaultRecipient = _json.readAddress("$.l1FeeVaultRecipient");
nitroEnclaveVerifier = _json.readAddress("$.nitroEnclaveVerifier");
nitroValidator = _json.readAddress("$.nitroValidator");
operatorFeeVaultRecipient = _json.readAddress("$.operatorFeeVaultRecipient");
p2pSequencerAddress = _json.readAddress("$.p2pSequencerAddress");
proxyAdminOwner = _json.readAddress("$.proxyAdminOwner");
Expand Down
33 changes: 22 additions & 11 deletions scripts/deploy/SystemDeploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import { VmSafe } from "lib/forge-std/src/Vm.sol";
import { console2 as console } from "lib/forge-std/src/console2.sol";
import { Script } from "lib/forge-std/src/Script.sol";
import { VmSafe } from "lib/forge-std/src/Vm.sol";

import { Artifacts } from "scripts/Artifacts.s.sol";
import { Config } from "scripts/libraries/Config.sol";
Expand All @@ -27,6 +27,8 @@ import { IDelayedWETH } from "interfaces/L1/proofs/IDelayedWETH.sol";
import { IDisputeGame } from "interfaces/L1/proofs/IDisputeGame.sol";
import { IDisputeGameFactory } from "interfaces/L1/proofs/IDisputeGameFactory.sol";
import { IVerifier } from "interfaces/L1/proofs/IVerifier.sol";
import { INitroEnclaveVerifier } from "interfaces/L1/proofs/tee/INitroEnclaveVerifier.sol";
import { INitroValidator } from "interfaces/L1/proofs/tee/INitroValidator.sol";
import { ITEEProverRegistry } from "interfaces/L1/proofs/tee/ITEEProverRegistry.sol";
import { IOptimismMintableERC20Factory } from "interfaces/universal/IOptimismMintableERC20Factory.sol";
import { IProxy } from "interfaces/universal/IProxy.sol";
Expand All @@ -36,7 +38,6 @@ import { AddressManager } from "src/legacy/AddressManager.sol";
import { AggregateVerifier } from "src/L1/proofs/AggregateVerifier.sol";
import { TEEProverRegistry } from "src/L1/proofs/tee/TEEProverRegistry.sol";
import { TEEVerifier } from "src/L1/proofs/tee/TEEVerifier.sol";
import { INitroEnclaveVerifier } from "interfaces/L1/proofs/tee/INitroEnclaveVerifier.sol";
import { ISP1Verifier } from "interfaces/L1/proofs/zk/ISP1Verifier.sol";
import { ZKVerifier } from "src/L1/proofs/zk/ZKVerifier.sol";
import { Constants } from "src/libraries/Constants.sol";
Expand Down Expand Up @@ -78,6 +79,7 @@ contract SystemDeploy is Script {
bytes32 multiproofConfigHash;
uint256 multiproofGameType;
address nitroEnclaveVerifier;
address nitroValidator;
AggregateVerifier.ScheduleConfig scheduleConfig;
uint256 multiproofBlockInterval;
uint256 multiproofIntermediateBlockInterval;
Expand Down Expand Up @@ -266,6 +268,7 @@ contract SystemDeploy is Script {
multiproofConfigHash: cfg.multiproofConfigHash(),
multiproofGameType: cfg.multiproofGameType(),
nitroEnclaveVerifier: cfg.nitroEnclaveVerifier(),
nitroValidator: cfg.nitroValidator(),
scheduleConfig: _configuredScheduleConfig(),
multiproofBlockInterval: cfg.multiproofBlockInterval(),
multiproofIntermediateBlockInterval: cfg.multiproofIntermediateBlockInterval(),
Expand Down Expand Up @@ -564,6 +567,7 @@ contract SystemDeploy is Script {
output_.zkVerifier = multiproof.zkVerifier;
output_.nitroEnclaveVerifier = INitroEnclaveVerifier(_implementationsInput.nitroEnclaveVerifier);
output_.sp1Verifier = _implementationsInput.sp1Verifier;
output_.nitroValidator = INitroValidator(_implementationsInput.nitroValidator);
}

_transferOwnership(address(output_.disputeGameFactoryProxy), _input.roles.opChainProxyAdminOwner);
Expand Down Expand Up @@ -709,6 +713,11 @@ contract SystemDeploy is Script {
if (address(currentGameImpl) == address(0)) return;

if (_impls.teeProverRegistryImpl != address(0)) {
TEEProverRegistry newTEEProverRegistry = TEEProverRegistry(_impls.teeProverRegistryImpl);
require(
address(newTEEProverRegistry.DISPUTE_GAME_FACTORY()) == address(_disputeGameFactory),
"SystemDeploy: TEEProverRegistry factory mismatch"
);
AggregateVerifier currentAggregateVerifier = AggregateVerifier(address(currentGameImpl));
TEEProverRegistry teeProverRegistry =
TEEVerifier(address(currentAggregateVerifier.TEE_VERIFIER())).TEE_PROVER_REGISTRY();
Expand Down Expand Up @@ -993,9 +1002,9 @@ contract SystemDeploy is Script {
GameType gameType = GameType.wrap(uint32(_input.multiproofGameType));

vm.broadcast(msg.sender);
output_.teeProverRegistryImpl = new TEEProverRegistry(
INitroEnclaveVerifier(_input.nitroEnclaveVerifier), _output.disputeGameFactoryProxy
);
output_.teeProverRegistryImpl = new TEEProverRegistry({
nitroValidator: INitroValidator(_input.nitroValidator), factory: _output.disputeGameFactoryProxy
});

output_.teeProverRegistryProxy =
TEEProverRegistry(_deployProxy(_opChainInput, _output.opChainProxyAdmin, "TEEProverRegistry"));
Expand All @@ -1017,12 +1026,6 @@ contract SystemDeploy is Script {
)
);

INitroEnclaveVerifier nitroVerifier = INitroEnclaveVerifier(_input.nitroEnclaveVerifier);
if (nitroVerifier.proofSubmitter() != address(output_.teeProverRegistryProxy)) {
vm.broadcast(msg.sender);
nitroVerifier.setProofSubmitter(address(output_.teeProverRegistryProxy));
}

vm.broadcast(msg.sender);
output_.teeVerifier =
IVerifier(address(new TEEVerifier(output_.teeProverRegistryProxy, _output.anchorStateRegistryProxy)));
Expand Down Expand Up @@ -1112,8 +1115,10 @@ contract SystemDeploy is Script {
require(_input.scheduleConfig.blockTime != 0, "SystemDeploy: L2 block time not set");
require(_input.scheduleConfig.genesisTimestamp != 0, "SystemDeploy: L2 genesis timestamp not set");
require(_input.nitroEnclaveVerifier != address(0), "SystemDeploy: nitroEnclaveVerifier not set");
require(_input.nitroValidator != address(0), "SystemDeploy: nitroValidator not set");
require(address(_input.sp1Verifier) != address(0), "SystemDeploy: sp1Verifier not set");
DeployUtils.assertValidContractAddress(_input.nitroEnclaveVerifier);
DeployUtils.assertValidContractAddress(_input.nitroValidator);
DeployUtils.assertValidContractAddress(address(_input.sp1Verifier));
require(_input.multiproofBlockInterval != 0, "SystemDeploy: multiproof block interval not set");
require(
Expand All @@ -1140,6 +1145,11 @@ contract SystemDeploy is Script {
DeployUtils.assertValidContractAddress(_impls.anchorStateRegistryImpl);
DeployUtils.assertValidContractAddress(_impls.delayedWETHImpl);
DeployUtils.assertValidContractAddress(_impls.protocolVersionsImpl);
if (_impls.teeProverRegistryImpl != address(0)) {
TEEProverRegistry teeProverRegistryImpl = TEEProverRegistry(_impls.teeProverRegistryImpl);
DeployUtils.assertValidContractAddress(address(teeProverRegistryImpl));
DeployUtils.assertValidContractAddress(address(teeProverRegistryImpl.NITRO_VALIDATOR()));
}
}

function _implementationsEmpty(Types.Implementations memory _impls) internal pure returns (bool) {
Expand Down Expand Up @@ -1170,6 +1180,7 @@ contract SystemDeploy is Script {
_saveIfSet("TEEProverRegistryProxy", address(chain.teeProverRegistryProxy));
_saveIfSet("TEEProverRegistry", address(chain.teeProverRegistryProxy));
_saveIfSet("NitroEnclaveVerifier", address(chain.nitroEnclaveVerifier));
_saveIfSet("NitroValidator", address(chain.nitroValidator));
_saveIfSet("SP1Verifier", address(chain.sp1Verifier));
}

Expand Down
2 changes: 2 additions & 0 deletions scripts/libraries/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IDelayedWETH } from "interfaces/L1/proofs/IDelayedWETH.sol";
import { IAnchorStateRegistry } from "interfaces/L1/proofs/IAnchorStateRegistry.sol";
import { IVerifier } from "interfaces/L1/proofs/IVerifier.sol";
import { INitroEnclaveVerifier } from "interfaces/L1/proofs/tee/INitroEnclaveVerifier.sol";
import { INitroValidator } from "interfaces/L1/proofs/tee/INitroValidator.sol";
import { ITEEProverRegistry } from "interfaces/L1/proofs/tee/ITEEProverRegistry.sol";
import { ISP1Verifier } from "interfaces/L1/proofs/zk/ISP1Verifier.sol";
import { IAddressManager } from "interfaces/legacy/IAddressManager.sol";
Expand Down Expand Up @@ -62,6 +63,7 @@ library Types {
IVerifier zkVerifier;
INitroEnclaveVerifier nitroEnclaveVerifier;
ISP1Verifier sp1Verifier;
INitroValidator nitroValidator;
}

/// @notice The latest implementation contracts for the OP Stack.
Expand Down
11 changes: 6 additions & 5 deletions scripts/multiproof/DeployDevNoNitro.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ pragma solidity 0.8.15;

import { console2 as console } from "lib/forge-std/src/console2.sol";

import { INitroEnclaveVerifier } from "interfaces/L1/proofs/tee/INitroEnclaveVerifier.sol";
import { IDisputeGameFactory } from "interfaces/L1/proofs/IDisputeGameFactory.sol";
import { INitroValidator } from "interfaces/L1/proofs/tee/INitroValidator.sol";
import { DevTEEProverRegistry } from "test/mocks/MockDevTEEProverRegistry.sol";

import { DeployDevBase } from "./DeployDevBase.s.sol";
Expand Down Expand Up @@ -34,10 +34,11 @@ contract DeployDevNoNitro is DeployDevBase {
}

function _deployTEERegistryImpl() internal override returns (address) {
return
address(
new DevTEEProverRegistry(INitroEnclaveVerifier(address(0)), IDisputeGameFactory(disputeGameFactory))
);
return address(
new DevTEEProverRegistry({
nitroValidator: INitroValidator(address(0)), factory: IDisputeGameFactory(disputeGameFactory)
})
);
}

function _logHeader() internal view override {
Expand Down
39 changes: 21 additions & 18 deletions scripts/multiproof/DeployDevWithNitro.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,26 @@ pragma solidity 0.8.15;

import { console2 as console } from "lib/forge-std/src/console2.sol";

import { INitroEnclaveVerifier } from "interfaces/L1/proofs/tee/INitroEnclaveVerifier.sol";
import { IDisputeGameFactory } from "interfaces/L1/proofs/IDisputeGameFactory.sol";
import { INitroValidator } from "interfaces/L1/proofs/tee/INitroValidator.sol";
import { TEEProverRegistry } from "src/L1/proofs/tee/TEEProverRegistry.sol";

import { DeployDevBase } from "./DeployDevBase.s.sol";

/// @title DeployDevWithNitro
/// @notice Development deployment WITH AWS Nitro attestation validation. Uses the real
/// TEEProverRegistry, so signer registration requires a ZK proof of a valid AWS
/// Nitro attestation (no addDevSigner bypass).
/// @dev Prerequisite: deploy the RISC Zero verifier stack and NitroEnclaveVerifier via
/// DeployRiscZeroStack.s.sol first (those contracts need Solidity ^0.8.20, while this
/// script is pinned to =0.8.15), then set `nitroEnclaveVerifier` in the deploy config.
/// Note: AWS Nitro attestations are only valid for 60 minutes — generate the ZK proof
/// and submit registerSigner() within that window.
/// TEEProverRegistry, so signer registration requires a hinted AWS Nitro attestation
/// (no addDevSigner bypass).
/// @dev Prerequisite: deploy the hinted validator stack via DeployNitroValidatorStack.s.sol,
/// then set `nitroValidator` in the deploy config. AWS Nitro attestations are only valid
/// for 60 minutes, and the certificate chain must be cached before registerSigner() is called.
contract DeployDevWithNitro is DeployDevBase {
uint256 public constant BLOCK_INTERVAL = 600;
uint256 public constant INTERMEDIATE_BLOCK_INTERVAL = 30;
uint256 public constant INIT_BOND = 0.00001 ether;

address public nitroEnclaveVerifierAddr;
address public nitroValidatorAddr;

function _blockInterval() internal pure override returns (uint256) {
return BLOCK_INTERVAL;
Expand All @@ -44,22 +43,24 @@ contract DeployDevWithNitro is DeployDevBase {
function _preflight() internal override {
super._preflight();
nitroEnclaveVerifierAddr = cfg.nitroEnclaveVerifier();
nitroValidatorAddr = cfg.nitroValidator();
require(
nitroEnclaveVerifierAddr != address(0),
"nitroEnclaveVerifier must be set in config (deploy via DeployRiscZeroStack.s.sol first)"
nitroValidatorAddr != address(0),
"nitroValidator must be set in config (deploy via DeployNitroValidatorStack.s.sol first)"
);
}

function _deployTEERegistryImpl() internal override returns (address) {
return address(
new TEEProverRegistry(
INitroEnclaveVerifier(nitroEnclaveVerifierAddr), IDisputeGameFactory(disputeGameFactory)
)
new TEEProverRegistry({
nitroValidator: INitroValidator(nitroValidatorAddr), factory: IDisputeGameFactory(disputeGameFactory)
})
);
}

function _serializeExtra(string memory key) internal override {
vm.serializeAddress(key, "NitroEnclaveVerifier", nitroEnclaveVerifierAddr);
vm.serializeAddress(key, "NitroValidator", nitroValidatorAddr);
}

function _logHeader() internal view override {
Expand All @@ -69,17 +70,19 @@ contract DeployDevWithNitro is DeployDevBase {
console.log("TEE Proposer:", cfg.teeProposer());
console.log("TEE Challenger:", cfg.teeChallenger());
console.log("Game Type:", cfg.multiproofGameType());
console.log("NitroEnclaveVerifier:", nitroEnclaveVerifierAddr);
console.log("NitroValidator:", nitroValidatorAddr);
console.log("NitroEnclaveVerifier (rollback):", nitroEnclaveVerifierAddr);
console.log("");
console.log("NOTE: Using REAL TEEProverRegistry - ZK attestation proof REQUIRED.");
console.log("NOTE: Using REAL TEEProverRegistry - hinted attestation REQUIRED.");
}

function _printSummary() internal view override {
console.log("\n========================================");
console.log(" DEV DEPLOYMENT COMPLETE (WITH NITRO)");
console.log("========================================");
console.log("\nTEE Contracts:");
console.log(" NitroEnclaveVerifier:", nitroEnclaveVerifierAddr);
console.log(" NitroValidator:", nitroValidatorAddr);
console.log(" NitroEnclaveVerifier (rollback):", nitroEnclaveVerifierAddr);
console.log(" TEEProverRegistry:", teeProverRegistryProxy);
console.log(" TEEVerifier:", teeVerifier);
console.log("\nInfrastructure:");
Expand All @@ -92,9 +95,9 @@ contract DeployDevWithNitro is DeployDevBase {
console.log(" TEE Image Hash:", vm.toString(cfg.teeImageHash()));
console.log(" Config Hash:", vm.toString(cfg.multiproofConfigHash()));
console.log("========================================");
console.log("\n>>> NEXT STEP: Register signer with ZK attestation proof <<<");
console.log("\n>>> NEXT STEP: Cache certificates, then register the signer <<<");
console.log("\n cast send", teeProverRegistryProxy);
console.log(' "registerSigner(bytes,bytes)" <ZK_OUTPUT> <ZK_PROOF_BYTES>');
console.log(' "registerSigner(bytes,bytes,bytes)" <ATTESTATION_TBS> <SIGNATURE> <HINTS>');
console.log(" --private-key <OWNER_OR_MANAGER_KEY> --rpc-url <RPC>");
console.log("\n========================================\n");
}
Expand Down
Loading
Loading