Skip to content

Commit

Permalink
feat(ctb): Support OptimismPortal2 in kontrol tests (#10429)
Browse files Browse the repository at this point in the history
* feat(ctb): Support `OptimismPortal2` in kontrol tests

Adds a second `DeploymentSummary` to `kontrol` for fault proofs, and
ports the existing `OptimismPortal` proofs with the `OptimismPortal2`.

* summary tests

* Update packages/contracts-bedrock/test/kontrol/README.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* tests

* Update `check-snapshots`

* Update packages/contracts-bedrock/test/kontrol/README.md

Co-authored-by: Matt Solomon <matt@mattsolomon.dev>

* Separate snapshot gen

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Matt Solomon <matt@mattsolomon.dev>
  • Loading branch information
3 people committed May 13, 2024
1 parent eb8fb14 commit 0ad342a
Show file tree
Hide file tree
Showing 13 changed files with 1,058 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1643,7 +1643,7 @@ jobs:
command: make submodules
- check-changed:
no_go_deps: "true"
patterns: contracts-bedrock/test/kontrol,contracts-bedrock/src/L1/OptimismPortal\.sol,contracts-bedrock/src/L1/L1CrossDomainMessenger\.sol,contracts-bedrock/src/L1/L1ERC721Bridge\.sol,contracts-bedrock/src/L1/L1StandardBridge\.sol,contracts-bedrock/src/L1/ResourceMetering\.sol,contracts-bedrock/src/universal/StandardBridge\.sol,contracts-bedrock/src/universal/ERC721Bridge\.sol,contracts-bedrock/src/universal/CrossDomainMessenger\.sol
patterns: contracts-bedrock/test/kontrol,contracts-bedrock/src/L1/OptimismPortal\.sol,contracts-bedrock/src/L1/OptimismPortal2\.sol,contracts-bedrock/src/L1/L1CrossDomainMessenger\.sol,contracts-bedrock/src/L1/L1ERC721Bridge\.sol,contracts-bedrock/src/L1/L1StandardBridge\.sol,contracts-bedrock/src/L1/ResourceMetering\.sol,contracts-bedrock/src/universal/StandardBridge\.sol,contracts-bedrock/src/universal/ERC721Bridge\.sol,contracts-bedrock/src/universal/CrossDomainMessenger\.sol
- setup_remote_docker:
docker_layer_caching: true
- run:
Expand Down
2 changes: 2 additions & 0 deletions packages/contracts-bedrock/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ deployments/1337
deployments/31337-deploy.json
deployments/kontrol.json
deployments/kontrol.jsonReversed
deployments/kontrol-fp.json
deployments/kontrol-fp.jsonReversed
snapshots/state-diff/Kontrol-31337.json

# Devnet config which changes with each 'make devnet-up'
Expand Down
4 changes: 3 additions & 1 deletion packages/contracts-bedrock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"gas-snapshot:no-build": "forge snapshot --match-contract GasBenchMark",
"statediff": "./scripts/statediff.sh && git diff --exit-code",
"gas-snapshot": "pnpm build:go-ffi && pnpm gas-snapshot:no-build",
"snapshots": "forge build && npx tsx scripts/autogen/generate-snapshots.ts && ./test/kontrol/scripts/make-summary-deployment.sh",
"kontrol-summary": "./test/kontrol/scripts/make-summary-deployment.sh",
"kontrol-summary-fp": "KONTROL_FP_DEPLOYMENT=true pnpm kontrol-summary",
"snapshots": "forge build && npx tsx scripts/autogen/generate-snapshots.ts && pnpm kontrol-summary && pnpm kontrol-summary-fp",
"snapshots:check": "./scripts/checks/check-snapshots.sh",
"semver-lock": "forge script scripts/SemverLock.s.sol",
"validate-deploy-configs": "./scripts/checks/check-deploy-configs.sh",
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts-bedrock/test/L1/OptimismPortal2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import "src/libraries/PortalErrors.sol";
contract OptimismPortal2_Test is CommonTest {
address depositor;

function setUp() public override {
function setUp() public virtual override {
super.enableFaultProofs();
super.setUp();

Expand Down
3 changes: 3 additions & 0 deletions packages/contracts-bedrock/test/kontrol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ First, generate a deployment summary contract from the deploy script in [`Kontro
./test/kontrol/scripts/make-summary-deployment.sh [container|local|dev]
```

> [!NOTE]
> To create a fault proof summary deployment, set `KONTROL_FP_DEPLOYMENT=true` and run the script `./test/kontrol/scripts/make-summary-deployment.sh`.
The [`make-summary-deployment.sh`](./scripts/make-summary-deployment.sh) supports the same execution modes as `run-kontrol.sh` below.

[`KontrolDeployment.sol`](./deployment/KontrolDeployment.sol) contains the minimal deployment sequence required by the proofs.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

// Libraries
import { Constants } from "src/libraries/Constants.sol";
import { Predeploys } from "src/libraries/Predeploys.sol";

// Target contract dependencies
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { SystemConfig } from "src/L1/SystemConfig.sol";
import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { DeploymentSummaryFaultProofs } from "../proofs/utils/DeploymentSummaryFaultProofs.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { LegacyMintableERC20 } from "src/legacy/LegacyMintableERC20.sol";

// Tests
import { L1CrossDomainMessenger_Test } from "test/L1/L1CrossDomainMessenger.t.sol";
import { OptimismPortal2_Test } from "test/L1/OptimismPortal2.t.sol";
import { L1ERC721Bridge_Test, TestERC721 } from "test/L1/L1ERC721Bridge.t.sol";
import {
L1StandardBridge_Getter_Test,
L1StandardBridge_Initialize_Test,
L1StandardBridge_Pause_Test
} from "test/L1/L1StandardBridge.t.sol";

/// @dev Contract testing the deployment summary correctness
contract DeploymentSummaryFaultProofs_TestOptimismPortal is DeploymentSummaryFaultProofs, OptimismPortal2_Test {
/// @notice super.setUp is not called on purpose
function setUp() public override {
// Recreate Deployment Summary state changes
DeploymentSummaryFaultProofs deploymentSummary = new DeploymentSummaryFaultProofs();
deploymentSummary.recreateDeployment();

// Set summary addresses
optimismPortal2 = OptimismPortal2(payable(optimismPortalProxyAddress));
superchainConfig = SuperchainConfig(superchainConfigProxyAddress);
disputeGameFactory = DisputeGameFactory(disputeGameFactoryProxyAddress);
systemConfig = SystemConfig(systemConfigProxyAddress);

// Set up utilized addresses
depositor = makeAddr("depositor");
alice = makeAddr("alice");
bob = makeAddr("bob");
vm.deal(alice, 10000 ether);
vm.deal(bob, 10000 ether);
}

/// @dev Skips the first line of `super.test_constructor_succeeds` because
/// we're not exercising the `Deploy` logic in these tests. However,
/// the remaining assertions of the test are important to check
function test_constructor_succeeds() external view override {
// OptimismPortal opImpl = OptimismPortal(payable(deploy.mustGetAddress("OptimismPortal")));
OptimismPortal2 opImpl = OptimismPortal2(payable(optimismPortal2Address));
assertEq(address(opImpl.disputeGameFactory()), address(0));
assertEq(address(opImpl.systemConfig()), address(0));
assertEq(address(opImpl.superchainConfig()), address(0));
assertEq(opImpl.l2Sender(), Constants.DEFAULT_L2_SENDER);
}

/// @dev Skips the first line of `super.test_initialize_succeeds` because
/// we're not exercising the `Deploy` logic in these tests. However,
/// the remaining assertions of the test are important to check
function test_initialize_succeeds() external view override {
// address guardian = deploy.cfg().superchainConfigGuardian();
address guardian = superchainConfig.guardian();
assertEq(address(optimismPortal2.disputeGameFactory()), address(disputeGameFactory));
assertEq(address(optimismPortal2.systemConfig()), address(systemConfig));
assertEq(optimismPortal2.guardian(), guardian);
assertEq(address(optimismPortal2.superchainConfig()), address(superchainConfig));
assertEq(optimismPortal2.l2Sender(), Constants.DEFAULT_L2_SENDER);
assertEq(optimismPortal2.paused(), false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,46 @@ contract KontrolDeployment is Deploy {
initializeL1CrossDomainMessenger();
initializeOptimismPortal();
}

function runKontrolDeploymentFaultProofs() public stateDiff {
deploySafe("SystemOwnerSafe");
setupSuperchain();

// deployProxies();
deployERC1967Proxy("OptimismPortalProxy");
deployERC1967Proxy("DisputeGameFactoryProxy");
deployERC1967Proxy("AnchorStateRegistryProxy");
deployERC1967Proxy("DelayedWETHProxy");
deployERC1967Proxy("SystemConfigProxy");
deployL1StandardBridgeProxy();
deployL1CrossDomainMessengerProxy();
deployERC1967Proxy("L1ERC721BridgeProxy");
transferAddressManagerOwnership(); // to the ProxyAdmin

// deployImplementations();
deployOptimismPortal2();
deployL1CrossDomainMessenger();
deploySystemConfig();
deployL1StandardBridge();
deployL1ERC721Bridge();
deployDisputeGameFactory();
deployDelayedWETH();
deployPreimageOracle();
deployMips();
deployAnchorStateRegistry();

// initializeImplementations();
initializeSystemConfig();
initializeL1StandardBridge();
initializeL1ERC721Bridge();
initializeL1CrossDomainMessenger();
initializeDisputeGameFactory();
initializeDelayedWETH();
initializeAnchorStateRegistry();
initializeOptimismPortal2();

// Set dispute game implementations in DGF
setCannonFaultGameImplementation({ _allowUpgrade: false });
setPermissionedCannonFaultGameImplementation({ _allowUpgrade: false });
}
}
202 changes: 202 additions & 0 deletions packages/contracts-bedrock/test/kontrol/proofs/OptimismPortal2.k.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import { DeploymentSummaryFaultProofs } from "./utils/DeploymentSummaryFaultProofs.sol";
import { KontrolUtils } from "./utils/KontrolUtils.sol";
import { Types } from "src/libraries/Types.sol";
import {
IOptimismPortal as OptimismPortal,
ISuperchainConfig as SuperchainConfig
} from "./interfaces/KontrolInterfaces.sol";
import "src/libraries/PortalErrors.sol";

contract OptimismPortal2Kontrol is DeploymentSummaryFaultProofs, KontrolUtils {
OptimismPortal optimismPortal;
SuperchainConfig superchainConfig;

/// @dev Inlined setUp function for faster Kontrol performance
/// Tracking issue: https://github.com/runtimeverification/kontrol/issues/282
function setUpInlined() public {
optimismPortal = OptimismPortal(payable(optimismPortalProxyAddress));
superchainConfig = SuperchainConfig(superchainConfigProxyAddress);
}

function prove_finalizeWithdrawalTransaction_paused(Types.WithdrawalTransaction calldata _tx) external {
setUpInlined();

// Pause Optimism Portal
vm.prank(optimismPortal.guardian());
superchainConfig.pause("identifier");

// We need to encode the error selector as bytes instead of bytes4 because the bytes4 signature
// it's not currently supported
// Tracking issue: https://github.com/runtimeverification/kontrol/issues/466
vm.expectRevert(abi.encodeWithSelector(CallPaused.selector));
optimismPortal.finalizeWithdrawalTransaction(_tx);
}

/// @dev Function containing the logic for prove_proveWithdrawalTransaction_paused
/// The reason for this is that we want the _withdrawalProof to range in size from
/// 0 to 10. These 11 proofs will exercise the same logic, which is contained in this function
function prove_proveWithdrawalTransaction_paused_internal(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] memory _withdrawalProof
)
internal
{
setUpInlined();

// Pause Optimism Portal
vm.prank(optimismPortal.guardian());
superchainConfig.pause("identifier");

// We need to encode the error selector as bytes instead of bytes4 because the bytes4 signature
// it's not currently supported
// Tracking issue: https://github.com/runtimeverification/kontrol/issues/466
vm.expectRevert(abi.encodeWithSelector(CallPaused.selector));
optimismPortal.proveWithdrawalTransaction(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 10,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused10(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 9,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused9(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 8,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused8(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 7,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused7(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 6,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused6(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 5,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused5(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 4,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused4(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 3,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused3(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 2,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused2(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

/// @custom:kontrol-array-length-equals _withdrawalProof: 1,
/// @custom:kontrol-bytes-length-equals _withdrawalProof: 600,
function prove_proveWithdrawalTransaction_paused1(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof,
bytes[] calldata _withdrawalProof
)
external
{
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}

function prove_proveWithdrawalTransaction_paused0(
Types.WithdrawalTransaction memory _tx,
uint256 _l2OutputIndex,
Types.OutputRootProof calldata _outputRootProof
)
external
{
bytes[] memory _withdrawalProof = new bytes[](0);
prove_proveWithdrawalTransaction_paused_internal(_tx, _l2OutputIndex, _outputRootProof, _withdrawalProof);
}
}

0 comments on commit 0ad342a

Please sign in to comment.