Skip to content
Closed
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
362 changes: 186 additions & 176 deletions .gas-snapshot

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions .storage-layout
Original file line number Diff line number Diff line change
Expand Up @@ -25,47 +25,47 @@
"type": "t_mapping(t_bytes32,t_struct(RoleData)22_storage)"
},
{
"astId": 1058,
"astId": 1067,
"contract": "src/StateOracle.sol:StateOracle",
"label": "assertionAdopters",
"offset": 0,
"slot": "3",
"type": "t_mapping(t_address,t_struct(AssertionAdopter)979_storage)"
},
{
"astId": 1064,
"astId": 1073,
"contract": "src/StateOracle.sol:StateOracle",
"label": "adminVerifiers",
"offset": 0,
"slot": "4",
"type": "t_mapping(t_contract(IAdminVerifier)2524,t_bool)"
"type": "t_mapping(t_contract(IAdminVerifier)2650,t_bool)"
},
{
"astId": 1070,
"astId": 1079,
"contract": "src/StateOracle.sol:StateOracle",
"label": "daVerifiers",
"offset": 0,
"slot": "5",
"type": "t_mapping(t_contract(IDAVerifier)2553,t_bool)"
"type": "t_mapping(t_contract(IDAVerifier)2679,t_bool)"
},
{
"astId": 1075,
"astId": 1084,
"contract": "src/StateOracle.sol:StateOracle",
"label": "whitelist",
"offset": 0,
"slot": "6",
"type": "t_mapping(t_address,t_bool)"
},
{
"astId": 1078,
"astId": 1087,
"contract": "src/StateOracle.sol:StateOracle",
"label": "whitelistEnabled",
"offset": 0,
"slot": "7",
"type": "t_bool"
},
{
"astId": 1081,
"astId": 1090,
"contract": "src/StateOracle.sol:StateOracle",
"label": "maxAssertionsPerAA",
"offset": 1,
Expand All @@ -89,12 +89,12 @@
"label": "bytes32",
"numberOfBytes": "32"
},
"t_contract(IAdminVerifier)2524": {
"t_contract(IAdminVerifier)2650": {
"encoding": "inplace",
"label": "contract IAdminVerifier",
"numberOfBytes": "20"
},
"t_contract(IDAVerifier)2553": {
"t_contract(IDAVerifier)2679": {
"encoding": "inplace",
"label": "contract IDAVerifier",
"numberOfBytes": "20"
Expand Down Expand Up @@ -127,16 +127,16 @@
"numberOfBytes": "32",
"value": "t_struct(RoleData)22_storage"
},
"t_mapping(t_contract(IAdminVerifier)2524,t_bool)": {
"t_mapping(t_contract(IAdminVerifier)2650,t_bool)": {
"encoding": "mapping",
"key": "t_contract(IAdminVerifier)2524",
"key": "t_contract(IAdminVerifier)2650",
"label": "mapping(contract IAdminVerifier => bool)",
"numberOfBytes": "32",
"value": "t_bool"
},
"t_mapping(t_contract(IDAVerifier)2553,t_bool)": {
"t_mapping(t_contract(IDAVerifier)2679,t_bool)": {
"encoding": "mapping",
"key": "t_contract(IDAVerifier)2553",
"key": "t_contract(IDAVerifier)2679",
"label": "mapping(contract IDAVerifier => bool)",
"numberOfBytes": "32",
"value": "t_bool"
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
.PHONY: check-storage-layout update-storage-layout
.PHONY: check-storage-layout deploy update-storage-layout

check-storage-layout:
@bash shell/check_storage_layout.sh

update-storage-layout:
forge inspect StateOracle storage-layout --json > .storage-layout
@echo "Storage layout snapshot updated."

deploy:
./shell/deploy_wizard.sh
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,33 @@ State Oracle Implementation deployed at <address>
State Oracle Proxy deployed at <address>
```

### Interactive deployment wizard

Run the terminal wizard from the repository root:

```sh
make deploy
```

The wizard uses `DeployCore` as its deployment backend and guides you through:

- production or testing mode, plus an optional staging State Oracle;
- admin verifier selection and assignment to the production and/or staging oracle;
- ECDSA and/or on-chain DA verification, independently assigned to each State Oracle;
- initial State Oracle whitelist state and addresses;
- optional explorer verification using `ETHERSCAN_API_KEY`;
- all State Oracle limits, timelocks, admins, and verifier-specific addresses; and
- a Foundry keystore account selected from `cast wallet list`.

The wallet password and explorer API key are read without echoing. The password is checked before
deployment and stored only in a temporary mode-`600` file that is removed when the wizard exits.
Before broadcasting, the wizard prints a redacted Forge command and a complete configuration
summary. After broadcasting, it reads Foundry's receipt file and prints every deployment address,
block number, transaction hash, and proxy admin address.

Testing mode also exposes the `Super Admin` and `Always Approve` admin verifiers. These options are
rejected by the Solidity deployment backend unless testing mode is explicitly enabled.

## Installation

1. Clone the repository:
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"scripts": {
"prepare": "./shell/create_artifacts.sh",
"test": "forge test",
"test:deploy-wizard": "python3 test/shell/test_deploy_wizard.py",
"build": "forge build",
"deploy:wizard": "./shell/deploy_wizard.sh",
"format": "forge fmt",
"clean": "forge clean"
},
Expand Down
1 change: 1 addition & 0 deletions script/DeployCore.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ contract DeployCore is Script {
}

function _deployWhitelistAdminVerifier() internal virtual returns (address verifier) {
require(whitelistAdmin != address(0), "Invalid whitelist admin");
verifier = address(new AdminVerifierWhitelist(whitelistAdmin));
console2.log("Admin Verifier (Whitelist) deployed at", verifier);
return verifier;
Expand Down
109 changes: 109 additions & 0 deletions script/DeployTestingAdminVerifiers.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.28;

import {StateOracle} from "../src/StateOracle.sol";
import {IAdminVerifier} from "../src/interfaces/IAdminVerifier.sol";
import {AdminVerifierAlwaysApprove} from "../src/verification/admin/AdminVerifierAlwaysApprove.sol";
import {AdminVerifierSuperAdmin} from "../src/verification/admin/AdminVerifierSuperAdmin.sol";
import {console2} from "forge-std/console2.sol";
import {Script} from "forge-std/Script.sol";

contract DeployTestingAdminVerifiers is Script {
address stateOracle;
address superAdmin;
bool deploySuperAdminVerifierEnabled;
bool deployAlwaysApproveVerifierEnabled;
bool addToStateOracle;

function setUp() public virtual {
stateOracle = vm.envOr("TEST_STATE_ORACLE_ADDRESS", address(0));
superAdmin = vm.envOr("TEST_ADMIN_VERIFIER_SUPER_ADMIN_ADDRESS", address(0));
deploySuperAdminVerifierEnabled = vm.envOr("DEPLOY_TEST_ADMIN_VERIFIER_SUPER_ADMIN", false);
deployAlwaysApproveVerifierEnabled = vm.envOr("DEPLOY_TEST_ADMIN_VERIFIER_ALWAYS_APPROVE", false);
addToStateOracle = vm.envOr("ADD_TEST_ADMIN_VERIFIERS_TO_STATE_ORACLE", false);
}

modifier broadcast() {
vm.startBroadcast();
_;
vm.stopBroadcast();
}

function run() public broadcast {
_run();
}

function deploySuperAdminVerifier(address _superAdmin) public broadcast returns (address) {
return _deploySuperAdminVerifier(_superAdmin);
}

function deployAlwaysApproveAdminVerifier() public broadcast returns (address) {
return _deployAlwaysApproveAdminVerifier();
}

function deployAndAddSuperAdminVerifier(address _stateOracle, address _superAdmin)
public
broadcast
returns (address verifier)
{
verifier = _deploySuperAdminVerifier(_superAdmin);
_addAdminVerifier(_stateOracle, verifier);
}

function deployAndAddAlwaysApproveAdminVerifier(address _stateOracle) public broadcast returns (address verifier) {
verifier = _deployAlwaysApproveAdminVerifier();
_addAdminVerifier(_stateOracle, verifier);
}

function addAdminVerifier(address _stateOracle, address verifier) public broadcast {
_addAdminVerifier(_stateOracle, verifier);
}

function _run() internal returns (address[] memory deployments) {
deployments = _deployEnabledAdminVerifiers();
if (addToStateOracle) {
_addAdminVerifiers(stateOracle, deployments);
}
}

function _deployEnabledAdminVerifiers() internal returns (address[] memory deployments) {
uint256 count;
if (deploySuperAdminVerifierEnabled) count++;
if (deployAlwaysApproveVerifierEnabled) count++;
require(count > 0, "No test verifiers enabled");

deployments = new address[](count);
uint256 index;
if (deploySuperAdminVerifierEnabled) {
deployments[index++] = _deploySuperAdminVerifier(superAdmin);
}
if (deployAlwaysApproveVerifierEnabled) {
deployments[index++] = _deployAlwaysApproveAdminVerifier();
}
}

function _deploySuperAdminVerifier(address _superAdmin) internal virtual returns (address verifier) {
require(_superAdmin != address(0), "Invalid super admin");
verifier = address(new AdminVerifierSuperAdmin(_superAdmin));
console2.log("Testing Admin Verifier (Super Admin) deployed at", verifier);
}

function _deployAlwaysApproveAdminVerifier() internal virtual returns (address verifier) {
verifier = address(new AdminVerifierAlwaysApprove());
console2.log("Testing Admin Verifier (Always Approve) deployed at", verifier);
}

function _addAdminVerifiers(address _stateOracle, address[] memory verifiers) internal {
require(_stateOracle != address(0), "Invalid state oracle");
for (uint256 i = 0; i < verifiers.length; i++) {
_addAdminVerifier(_stateOracle, verifiers[i]);
}
}

function _addAdminVerifier(address _stateOracle, address verifier) internal {
require(_stateOracle != address(0), "Invalid state oracle");
require(verifier != address(0), "Invalid admin verifier");
StateOracle(_stateOracle).addAdminVerifier(IAdminVerifier(verifier));
console2.log("Testing admin verifier added to StateOracle", verifier);
}
}
Loading