Skip to content
Open
Show file tree
Hide file tree
Changes from 8 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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@
[submodule "packages/contracts-bedrock/lib/automate"]
path = packages/contracts-bedrock/lib/automate
url = https://github.com/gelatodigital/automate
[submodule "packages/contracts-bedrock/lib/sp1-contracts"]
path = packages/contracts-bedrock/lib/sp1-contracts
url = https://github.com/lightning-li/sp1-contracts
7 changes: 6 additions & 1 deletion packages/contracts-bedrock/deploy-config/hardhat.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,10 @@
"daChallengeWindow": 100,
"daResolveWindow": 100,
"daBondSize": 1000,
"daResolverRefundPercentage": 50
"daResolverRefundPercentage": 50,
"blockDistance": 3,
"aggregationVkey": "0x0006a81df67f2d5e48048edd5c051a5be0ef9720a2ce130f12f7021256160e73",
"rangeVkeyCommitment": "0x5030974a2d74c494158e4af45836d72e2e0acae55f0f22d73c22bde90c1d6d98",
"sp1VerifierGateway": "0x51d3960c929B27Db3f041eA3c3aD4fF3c2A121C7",
"rollupConfigHash": "0x0b9b35ba1f4265979a10dea49f5501f81b3729b2856165574b1661323678e778"
}
36 changes: 36 additions & 0 deletions packages/contracts-bedrock/deployments/97-deploy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"AddressManager": "0x2e234DAe75C793f67A35089C9d99245E1C58470b",
"AnchorStateRegistry": "0x03D97F75CF5cE8986dc4fF531047AF2D52631aBE",
"AnchorStateRegistryProxy": "0x1aF7f588A501EA2B5bB3feeFA744892aA2CF00e6",
"DelayedWETH": "0x7dB36fC81A5197f84BDc88C9B1237A0fca492Cf4",
"DelayedWETHProxy": "0x756e0562323ADcDA4430d6cb456d9151f605290B",
"DisputeGameFactory": "0xc1B724FAe275423BE62006d7711b4435C31a3Fa2",
"DisputeGameFactoryProxy": "0xDB25A7b768311dE128BBDa7B8426c3f9C74f3240",
"L1CrossDomainMessenger": "0x9c0A33f6b1c5d574a6327101c597b0e792a4DC05",
"L1CrossDomainMessengerProxy": "0xD16d567549A2a2a2005aEACf7fB193851603dd70",
"L1ERC721Bridge": "0xF9A2bc3F5DA471245c57da74cfCF6Cdf5fb8040F",
"L1ERC721BridgeProxy": "0x13aa49bAc059d709dd0a18D6bb63290076a702D7",
"L1StandardBridge": "0x7ad421ef511CB1D0060fC90BBccCcf5735632f74",
"L1StandardBridgeProxy": "0x3D7Ebc40AF7092E3F1C81F2e996cbA5Cae2090d7",
"L2OutputOracle": "0x451CEA9b04c58DBC5770c1b1455a67440111b35f",
"L2OutputOracleProxy": "0x3381cD18e2Fb4dB236BF0525938AB6E43Db0440f",
"Mips": "0x71Fb6e45FA9D2396ffc32cd8605141d1af7ab957",
"OptimismMintableERC20Factory": "0x13E136063f4699eBf276c66125f8eA02adaB4F77",
"OptimismMintableERC20FactoryProxy": "0x96d3F6c20EEd2697647F543fE6C08bC2Fbf39758",
"OptimismPortal": "0x1fF359e524EB80A26D1D63D580B223f53120c65B",
"OptimismPortal2": "0x956486516159D5fDfAC9ee63759676A033A5bC88",
"OptimismPortalProxy": "0x212224D2F2d262cd093eE13240ca4873fcCBbA3C",
"PreimageOracle": "0x194C0E304fCA9281698112f40438bcb0D9F82544",
"ProtocolVersions": "0x3cea74C40CB33ae630e130516097cDd0cd06Cb5E",
"ProtocolVersionsProxy": "0x03A6a84cD762D9707A21605b548aaaB891562aAb",
"ProxyAdmin": "0xF62849F9A0B5Bf2913b396098F7c7019b51A820a",
"SafeProxyFactory": "0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2",
"SafeSingleton": "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552",
"SuperchainConfig": "0x9Fd48Cb6F987Cc0CbEC82A870C51Ec54cA16e599",
"SuperchainConfigProxy": "0xa0Cb889707d426A7A386870A03bc70d1b0697598",
"SystemConfig": "0xcC02cfD0D02e17d2805485f6878aFeE5da00A028",
"SystemConfigProxy": "0x2a07706473244BC757E10F2a9E86fB532828afe3",
"SystemOwnerSafe": "0xf82F7e298c13195A73c702625D49a1BD739cFaaF",
"ZkFaultProofConfig": "0xD384139842Cfff55fB7dC930e782cc09139a1cEe",
"ZkFaultProofConfigProxy": "0xe8dc788818033232EF9772CB2e6622F1Ec8bc840"
}
1 change: 1 addition & 0 deletions packages/contracts-bedrock/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ remappings = [
'@rari-capital/solmate/=lib/solmate',
'@lib-keccak/=lib/lib-keccak/contracts/lib',
'@solady/=lib/solady/src',
"@sp1-contracts/=lib/sp1-contracts/contracts/",
'forge-std/=lib/forge-std/src',
'ds-test/=lib/forge-std/lib/ds-test/src',
'safe-contracts/=lib/safe-contracts/contracts',
Expand Down
1 change: 1 addition & 0 deletions packages/contracts-bedrock/lib/sp1-contracts
Submodule sp1-contracts added at 25b159
66 changes: 65 additions & 1 deletion packages/contracts-bedrock/scripts/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol";
import { PermissionedDisputeGame } from "src/dispute/PermissionedDisputeGame.sol";
import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol";
import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol";
import { ZkFaultProofConfig } from "src/dispute/ZkFaultProofConfig.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { MIPS } from "src/cannon/MIPS.sol";
import { L1ERC721Bridge } from "src/L1/L1ERC721Bridge.sol";
Expand All @@ -58,6 +59,9 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol";
import { Process } from "scripts/libraries/Process.sol";

import { SP1VerifierGateway } from "sp1-contracts/src/SP1VerifierGateway.sol";
import { SP1Verifier } from "sp1-contracts/src/v3.0.0-rc4/SP1VerifierPlonk.sol";

/// @title Deploy
/// @notice Script used to deploy a bedrock system. The entire system is deployed within the `run` function.
/// To add a new contract to the system, add a public function that deploys that individual contract.
Expand Down Expand Up @@ -152,6 +156,7 @@ contract Deploy is Deployer {
DisputeGameFactory: mustGetAddress("DisputeGameFactoryProxy"),
DelayedWETH: mustGetAddress("DelayedWETHProxy"),
AnchorStateRegistry: mustGetAddress("AnchorStateRegistryProxy"),
ZkFaultProofConfig: mustGetAddress("ZkFaultProofConfigProxy"),
OptimismMintableERC20Factory: mustGetAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: mustGetAddress("OptimismPortalProxy"),
OptimismPortal2: mustGetAddress("OptimismPortalProxy"),
Expand All @@ -171,6 +176,7 @@ contract Deploy is Deployer {
DisputeGameFactory: getAddress("DisputeGameFactoryProxy"),
DelayedWETH: getAddress("DelayedWETHProxy"),
AnchorStateRegistry: getAddress("AnchorStateRegistryProxy"),
ZkFaultProofConfig: getAddress("ZkFaultProofConfigProxy"),
OptimismMintableERC20Factory: getAddress("OptimismMintableERC20FactoryProxy"),
OptimismPortal: getAddress("OptimismPortalProxy"),
OptimismPortal2: getAddress("OptimismPortalProxy"),
Expand Down Expand Up @@ -370,6 +376,7 @@ contract Deploy is Deployer {
deployERC1967Proxy("L2OutputOracleProxy");
deployERC1967Proxy("DelayedWETHProxy");
deployERC1967Proxy("AnchorStateRegistryProxy");
deployERC1967Proxy("ZkFaultProofConfigProxy");

transferAddressManagerOwnership(); // to the ProxyAdmin
}
Expand All @@ -392,6 +399,8 @@ contract Deploy is Deployer {
deployPreimageOracle();
deployMips();
deployAnchorStateRegistry();
deployZkFaultProofConfig();
deploySp1VerifierSuite();
}

/// @notice Initialize all of the implementations
Expand All @@ -415,6 +424,7 @@ contract Deploy is Deployer {
initializeDisputeGameFactory();
initializeDelayedWETH();
initializeAnchorStateRegistry();
initializeZkFaultProofConfig();
}

/// @notice Add Plasma setup to the OP chain
Expand Down Expand Up @@ -813,6 +823,29 @@ contract Deploy is Deployer {
addr_ = address(anchorStateRegistry);
}

function deployZkFaultProofConfig() public broadcast returns (address addr_) {
console.log("Deploying ZkFaultProofConfig implementation");
ZkFaultProofConfig config = new ZkFaultProofConfig{ salt: _implSalt() }();
save("ZkFaultProofConfig", address(config));
console.log("ZkFaultProofConfig deployed at %s", address(config));

addr_ = address(config);
}

function deploySp1VerifierSuite() public broadcast returns (address addr_) {
console.log("Deploying SP1VerifierGateway implementation");
SP1VerifierGateway suite = new SP1VerifierGateway();
save("SP1VerifierGateway", address(suite));
console.log("SP1VerifierGateway deployed at %s", address(suite));


addr_ = address(suite);
console.log("Deploying PlonkVerifier implementation");

address verifier = address(new SP1Verifier());
suite.addRoute(verifier);
}

/// @notice Deploy the SystemConfig
function deploySystemConfig() public broadcast returns (address addr_) {
console.log("Deploying SystemConfig implementation");
Expand Down Expand Up @@ -957,7 +990,7 @@ contract Deploy is Deployer {
address anchorStateRegistryProxy = mustGetAddress("AnchorStateRegistryProxy");
address anchorStateRegistry = mustGetAddress("AnchorStateRegistry");

AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](5);
AnchorStateRegistry.StartingAnchorRoot[] memory roots = new AnchorStateRegistry.StartingAnchorRoot[](6);
roots[0] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.CANNON,
outputRoot: OutputRoot({
Expand Down Expand Up @@ -987,6 +1020,13 @@ contract Deploy is Deployer {
})
});
roots[4] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.ZKFAULT,
outputRoot: OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
l2BlockNumber: cfg.faultGameGenesisBlock()
})
});
roots[5] = AnchorStateRegistry.StartingAnchorRoot({
gameType: GameTypes.FAST,
outputRoot: OutputRoot({
root: Hash.wrap(cfg.faultGameGenesisOutputRoot()),
Expand All @@ -1004,6 +1044,30 @@ contract Deploy is Deployer {
console.log("AnchorStateRegistry version: %s", version);
}

function initializeZkFaultProofConfig() public broadcast {
console.log("Upgrading and initializing ZkFaultProofConfig proxy");
address zkFaultProofConfigProxy = mustGetAddress("ZkFaultProofConfigProxy");
address zkFaultProofConfig = mustGetAddress("ZkFaultProofConfig");
address sp1VerifierGateway = mustGetAddress("SP1VerifierGateway");

_upgradeAndCallViaSafe({
_proxy: payable(zkFaultProofConfigProxy),
_implementation: zkFaultProofConfig,
_innerCallData: abi.encodeCall(ZkFaultProofConfig.initialize, (
cfg.finalSystemOwner(),
cfg.blockDistance(),
cfg.l2ChainID(),
cfg.aggregationVkey(),
cfg.rangeVkeyCommitment(),
sp1VerifierGateway,
cfg.rollupConfigHash()
))
});

string memory version = ZkFaultProofConfig(payable(zkFaultProofConfigProxy)).version();
console.log("ZkFaultProofConfig version: %s", version);
}

/// @notice Initialize the SystemConfig
function initializeSystemConfig() public broadcast {
console.log("Upgrading and initializing SystemConfig proxy");
Expand Down
11 changes: 11 additions & 0 deletions packages/contracts-bedrock/scripts/DeployConfig.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ contract DeployConfig is Script {
uint256 public daResolveWindow;
uint256 public daBondSize;
uint256 public daResolverRefundPercentage;
uint256 public blockDistance;
bytes32 public aggregationVkey;
bytes32 public rangeVkeyCommitment;
address public sp1VerifierGateway;
bytes32 public rollupConfigHash;

bool public useCustomGasToken;
address public customGasTokenAddress;
Expand Down Expand Up @@ -155,6 +160,12 @@ contract DeployConfig is Script {
daBondSize = _readOr(_json, "$.daBondSize", 1000000000);
daResolverRefundPercentage = _readOr(_json, "$.daResolverRefundPercentage", 0);

blockDistance = stdJson.readUint(_json, "$.blockDistance");
aggregationVkey = stdJson.readBytes32(_json, "$.aggregationVkey");
rangeVkeyCommitment = stdJson.readBytes32(_json, "$.rangeVkeyCommitment");
sp1VerifierGateway = stdJson.readAddress(_json, "$.sp1VerifierGateway");
rollupConfigHash = stdJson.readBytes32(_json, "$.rollupConfigHash");

useCustomGasToken = _readOr(_json, "$.useCustomGasToken", false);
customGasTokenAddress = _readOr(_json, "$.customGasTokenAddress", address(0));

Expand Down
1 change: 1 addition & 0 deletions packages/contracts-bedrock/scripts/Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ library Types {
address DisputeGameFactory;
address DelayedWETH;
address AnchorStateRegistry;
address ZkFaultProofConfig;
address OptimismMintableERC20Factory;
address OptimismPortal;
address OptimismPortal2;
Expand Down
101 changes: 100 additions & 1 deletion packages/contracts-bedrock/src/dispute/DisputeGameFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,110 @@ contract DisputeGameFactory is OwnableUpgradeable, IDisputeGameFactory, ISemver
emit DisputeGameCreated(address(proxy_), _gameType, _rootClaim);
}

function _prepareExtraData(
uint256 l2BlockNumber,
Claim[] memory claims,
address parentProxy,
bytes memory extraData
) private pure returns (bytes memory) {
// calculate the hash of all _claims
bytes32 claimsHash = keccak256(abi.encodePacked(claims));
return abi.encodePacked(
l2BlockNumber,
claimsHash,
uint32(claims.length),
parentProxy,
extraData
);
}

function _validateGameCreation(
GameType _gameType,
Claim[] calldata _claims,
uint64 _parentGameIndex,
IDisputeGame impl
) private view returns (IDisputeGame parentProxy) {
// If there is no implementation to clone for the given `GameType`, revert.
if (address(impl) == address(0)) revert NoImplementation(_gameType);
// If the required initialization bond is not met, revert.
if (msg.value != initBonds[_gameType]) revert IncorrectBondAmount();
if (_claims.length == 0) revert NoClaims();
// When the parent game index is the maximum value of a uint64, it means that there is no parent game.
// And use the state from anchor state registry.
if (_parentGameIndex != type(uint64).max && _parentGameIndex >= _disputeGameList.length) {
revert InvalidParentGameIndex();
}
if (_parentGameIndex != type(uint64).max) {
(GameType parentGameType, , address proxy) = _disputeGameList[_parentGameIndex].unpack();
parentProxy = IDisputeGame(proxy);
// The parent game must be of the same type as the child game.
if (parentGameType.raw() != _gameType.raw()) revert InvalidParentGameType();
if (parentProxy.status() == GameStatus.CHALLENGER_WINS) {
revert InvalidParentGameStatus();
}
} else {
parentProxy = IDisputeGame(address(0));
}
}
Comment on lines +151 to +178

Check warning

Code scanning / Slither

Unused return

DisputeGameFactory._validateGameCreation(GameType,Claim[],uint64,IDisputeGame) (src/dispute/DisputeGameFactory.sol#151-178) ignores return value by (parentGameType,None,proxy) = _disputeGameList[_parentGameIndex].unpack() (src/dispute/DisputeGameFactory.sol#168)

function createZkFaultDisputeGame(
GameType _gameType,
Claim[] calldata _claims,
uint64 _parentGameIndex,
uint64 _l2BlockNumber,
bytes calldata _extraData
) external
payable
returns (IDisputeGame proxy_)
{
// Grab the implementation contract for the given `GameType`.
IDisputeGame impl = gameImpls[_gameType];
IDisputeGame parentProxy = _validateGameCreation(_gameType, _claims, _parentGameIndex, impl);
// Clone the implementation contract and initialize it with the given parameters.
//
// CWIA Calldata Layout:
// ┌───────────────────────────┬────────────────────────────────────┐
// │ Bytes │ Description │
// ├───────────────────────────┼────────────────────────────────────┤
// │ [0, 20) │ Game creator address │
// | [20, 52) | Root claim |
// │ [52, 84) │ Parent block hash at creation time │
// │ [84, 84+n) │ Extra data │
// | [84, 116) | L2 block number |
// | [116, 148) | Hash of all claims |
// | [148, 152) | The length of claims |
// | [152, 172) | Parent game address |
// └───────────────────────────┴────────────────────────────────────┘
Claim rootClaim = _claims[_claims.length-1];
bytes memory extraData = _prepareExtraData(
_l2BlockNumber,
_claims,
address(parentProxy),
_extraData
);
proxy_ = IDisputeGame(address(impl).clone(abi.encodePacked(msg.sender, rootClaim, blockhash(block.number - 1), extraData)));
proxy_.initialize{ value: msg.value }();

// Compute the unique identifier for the dispute game.
Hash uuid = getGameUUID(_gameType, rootClaim, extraData);
// If a dispute game with the same UUID already exists, revert.
if (GameId.unwrap(_disputeGames[uuid]) != bytes32(0)) revert GameAlreadyExists(uuid);

// Pack the game ID.
GameId id = LibGameId.pack(_gameType, Timestamp.wrap(uint64(block.timestamp)), address(proxy_));

// Store the dispute game id in the mapping & emit the `DisputeGameCreated` event.
_disputeGames[uuid] = id;
_disputeGameList.push(id);
emit DisputeGameCreated(address(proxy_), _gameType, rootClaim);
emit ZkDisputeGameIndexUpdated(_disputeGameList.length - 1);

}
Comment thread Fixed
/// @inheritdoc IDisputeGameFactory
function getGameUUID(
GameType _gameType,
Claim _rootClaim,
bytes calldata _extraData
bytes memory _extraData
)
public
pure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ contract FaultDisputeGame is IFaultDisputeGame, Clone, ISemver {
numRemainingChildren_ = challengeIndicesLen - checkpoint.subgameIndex;
}

/// @inheritdoc IFaultDisputeGame
/// @inheritdoc IDisputeGame
function l2BlockNumber() public pure returns (uint256 l2BlockNumber_) {
l2BlockNumber_ = _getArgUint256(0x54);
}
Expand Down
Loading