Commit 320fe936 authored by clabby's avatar clabby Committed by GitHub

feat(ctb): FPAC ops (#8877)

* FPAC ops

* bindings

* Update packages/contracts-bedrock/scripts/fpac/README.md
Co-authored-by: default avatarcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* `just` -> `make`

* @refcell Makefile help

---------
Co-authored-by: default avatarcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
parent 1b5413b8
This diff is collapsed.
This diff is collapsed.
...@@ -46,13 +46,13 @@ ...@@ -46,13 +46,13 @@
"l2GenesisRegolithTimeOffset": "0x0", "l2GenesisRegolithTimeOffset": "0x0",
"l2GenesisDeltaTimeOffset": null, "l2GenesisDeltaTimeOffset": null,
"l2GenesisCanyonTimeOffset": "0x0", "l2GenesisCanyonTimeOffset": "0x0",
"systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98", "faultGameAbsolutePrestate": "0x03c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98",
"faultGameMaxDepth": 44, "faultGameMaxDepth": 44,
"faultGameMaxDuration": 1200, "faultGameMaxDuration": 1200,
"faultGameGenesisBlock": 0, "faultGameGenesisBlock": 0,
"faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameSplitDepth": 14, "faultGameSplitDepth": 14
"systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000"
} }
...@@ -41,5 +41,11 @@ ...@@ -41,5 +41,11 @@
"l2GenesisRegolithTimeOffset": "0x0", "l2GenesisRegolithTimeOffset": "0x0",
"systemConfigStartBlock": 0, "systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000004000000000000000000000001", "requiredProtocolVersion": "0x0000000000000000000000000000000000000004000000000000000000000001",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000004000000000000000000000001" "recommendedProtocolVersion": "0x0000000000000000000000000000000000000004000000000000000000000001",
"faultGameAbsolutePrestate": "0x037bbcc23684afbb7f608024369242c5cdea261a4f63981387efb7cd81763536",
"faultGameMaxDepth": 73,
"faultGameMaxDuration": 86400,
"faultGameGenesisBlock": 0,
"faultGameGenesisOutputRoot": "0x6a2fb9128c8bc82eed49ee590fba3e975bd67fede20535d0d20b3000ea6d99b1",
"faultGameSplitDepth": 32
} }
...@@ -287,8 +287,8 @@ contract Deploy is Deployer { ...@@ -287,8 +287,8 @@ contract Deploy is Deployer {
deployImplementations(); deployImplementations();
initializeImplementations(); initializeImplementations();
setAlphabetFaultGameImplementation(); setAlphabetFaultGameImplementation({ _allowUpgrade: false });
setCannonFaultGameImplementation(); setCannonFaultGameImplementation({ _allowUpgrade: false });
transferDisputeGameFactoryOwnership(); transferDisputeGameFactoryOwnership();
} }
...@@ -553,7 +553,7 @@ contract Deploy is Deployer { ...@@ -553,7 +553,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the DisputeGameFactory /// @notice Deploy the DisputeGameFactory
function deployDisputeGameFactory() public onlyDevnet broadcast returns (address addr_) { function deployDisputeGameFactory() public onlyTestnetOrDevnet broadcast returns (address addr_) {
console.log("Deploying DisputeGameFactory implementation"); console.log("Deploying DisputeGameFactory implementation");
DisputeGameFactory factory = new DisputeGameFactory{ salt: _implSalt() }(); DisputeGameFactory factory = new DisputeGameFactory{ salt: _implSalt() }();
save("DisputeGameFactory", address(factory)); save("DisputeGameFactory", address(factory));
...@@ -582,7 +582,7 @@ contract Deploy is Deployer { ...@@ -582,7 +582,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy the PreimageOracle /// @notice Deploy the PreimageOracle
function deployPreimageOracle() public onlyDevnet broadcast returns (address addr_) { function deployPreimageOracle() public onlyTestnetOrDevnet broadcast returns (address addr_) {
console.log("Deploying PreimageOracle implementation"); console.log("Deploying PreimageOracle implementation");
PreimageOracle preimageOracle = new PreimageOracle{ salt: _implSalt() }(); PreimageOracle preimageOracle = new PreimageOracle{ salt: _implSalt() }();
save("PreimageOracle", address(preimageOracle)); save("PreimageOracle", address(preimageOracle));
...@@ -592,7 +592,7 @@ contract Deploy is Deployer { ...@@ -592,7 +592,7 @@ contract Deploy is Deployer {
} }
/// @notice Deploy Mips /// @notice Deploy Mips
function deployMips() public onlyDevnet broadcast returns (address addr_) { function deployMips() public onlyTestnetOrDevnet broadcast returns (address addr_) {
console.log("Deploying Mips implementation"); console.log("Deploying Mips implementation");
MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle"))); MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle")));
save("Mips", address(mips)); save("Mips", address(mips));
...@@ -704,7 +704,7 @@ contract Deploy is Deployer { ...@@ -704,7 +704,7 @@ contract Deploy is Deployer {
} }
/// @notice Initialize the DisputeGameFactory /// @notice Initialize the DisputeGameFactory
function initializeDisputeGameFactory() public onlyDevnet broadcast { function initializeDisputeGameFactory() public onlyTestnetOrDevnet broadcast {
console.log("Upgrading and initializing DisputeGameFactory proxy"); console.log("Upgrading and initializing DisputeGameFactory proxy");
address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy"); address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy");
address disputeGameFactory = mustGetAddress("DisputeGameFactory"); address disputeGameFactory = mustGetAddress("DisputeGameFactory");
...@@ -952,7 +952,7 @@ contract Deploy is Deployer { ...@@ -952,7 +952,7 @@ contract Deploy is Deployer {
} }
/// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner /// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner
function transferDisputeGameFactoryOwnership() public onlyDevnet broadcast { function transferDisputeGameFactoryOwnership() public onlyTestnetOrDevnet broadcast {
console.log("Transferring DisputeGameFactory ownership to Safe"); console.log("Transferring DisputeGameFactory ownership to Safe");
DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
address owner = disputeGameFactory.owner(); address owner = disputeGameFactory.owner();
...@@ -985,14 +985,14 @@ contract Deploy is Deployer { ...@@ -985,14 +985,14 @@ contract Deploy is Deployer {
); );
} else { } else {
console.log( console.log(
"[Cannon Dispute Game] Using absolute prestate from config: %s", cfg.faultGameAbsolutePrestate() "[Cannon Dispute Game] Using absolute prestate from config: %x", cfg.faultGameAbsolutePrestate()
); );
mipsAbsolutePrestate_ = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate())); mipsAbsolutePrestate_ = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate()));
} }
} }
/// @notice Sets the implementation for the `FAULT` game type in the `DisputeGameFactory` /// @notice Sets the implementation for the `FAULT` game type in the `DisputeGameFactory`
function setCannonFaultGameImplementation() public onlyDevnet broadcast { function setCannonFaultGameImplementation(bool _allowUpgrade) public onlyTestnetOrDevnet broadcast {
console.log("Setting Cannon FaultDisputeGame implementation"); console.log("Setting Cannon FaultDisputeGame implementation");
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
...@@ -1002,12 +1002,13 @@ contract Deploy is Deployer { ...@@ -1002,12 +1002,13 @@ contract Deploy is Deployer {
_gameType: GameTypes.CANNON, _gameType: GameTypes.CANNON,
_absolutePrestate: loadMipsAbsolutePrestate(), _absolutePrestate: loadMipsAbsolutePrestate(),
_faultVm: IBigStepper(mustGetAddress("Mips")), _faultVm: IBigStepper(mustGetAddress("Mips")),
_maxGameDepth: cfg.faultGameMaxDepth() _maxGameDepth: cfg.faultGameMaxDepth(),
_allowUpgrade: _allowUpgrade
}); });
} }
/// @notice Sets the implementation for the `ALPHABET` game type in the `DisputeGameFactory` /// @notice Sets the implementation for the `ALPHABET` game type in the `DisputeGameFactory`
function setAlphabetFaultGameImplementation() public onlyDevnet broadcast { function setAlphabetFaultGameImplementation(bool _allowUpgrade) public onlyDevnet broadcast {
console.log("Setting Alphabet FaultDisputeGame implementation"); console.log("Setting Alphabet FaultDisputeGame implementation");
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy")); DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
...@@ -1018,7 +1019,8 @@ contract Deploy is Deployer { ...@@ -1018,7 +1019,8 @@ contract Deploy is Deployer {
_absolutePrestate: outputAbsolutePrestate, _absolutePrestate: outputAbsolutePrestate,
_faultVm: IBigStepper(new AlphabetVM(outputAbsolutePrestate)), _faultVm: IBigStepper(new AlphabetVM(outputAbsolutePrestate)),
// The max depth for the alphabet trace is always 3. Add 1 because split depth is fully inclusive. // The max depth for the alphabet trace is always 3. Add 1 because split depth is fully inclusive.
_maxGameDepth: cfg.faultGameSplitDepth() + 3 + 1 _maxGameDepth: cfg.faultGameSplitDepth() + 3 + 1,
_allowUpgrade: _allowUpgrade
}); });
} }
...@@ -1028,11 +1030,12 @@ contract Deploy is Deployer { ...@@ -1028,11 +1030,12 @@ contract Deploy is Deployer {
GameType _gameType, GameType _gameType,
Claim _absolutePrestate, Claim _absolutePrestate,
IBigStepper _faultVm, IBigStepper _faultVm,
uint256 _maxGameDepth uint256 _maxGameDepth,
bool _allowUpgrade
) )
internal internal
{ {
if (address(_factory.gameImpls(_gameType)) != address(0)) { if (address(_factory.gameImpls(_gameType)) != address(0) && !_allowUpgrade) {
console.log( console.log(
"[WARN] DisputeGameFactoryProxy: `FaultDisputeGame` implementation already set for game type: %s", "[WARN] DisputeGameFactoryProxy: `FaultDisputeGame` implementation already set for game type: %s",
vm.toString(GameType.unwrap(_gameType)) vm.toString(GameType.unwrap(_gameType))
......
...@@ -103,7 +103,10 @@ contract DeployConfig is Script { ...@@ -103,7 +103,10 @@ contract DeployConfig is Script {
requiredProtocolVersion = stdJson.readUint(_json, "$.requiredProtocolVersion"); requiredProtocolVersion = stdJson.readUint(_json, "$.requiredProtocolVersion");
recommendedProtocolVersion = stdJson.readUint(_json, "$.recommendedProtocolVersion"); recommendedProtocolVersion = stdJson.readUint(_json, "$.recommendedProtocolVersion");
if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) { if (
block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet || block.chainid == Chains.Sepolia
|| block.chainid == Chains.Goerli
) {
faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate"); faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate");
faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth"); faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth");
faultGameSplitDepth = stdJson.readUint(_json, "$.faultGameSplitDepth"); faultGameSplitDepth = stdJson.readUint(_json, "$.faultGameSplitDepth");
......
...@@ -327,6 +327,18 @@ abstract contract Deployer is Script { ...@@ -327,6 +327,18 @@ abstract contract Deployer is Script {
_writeTemp(_name, _deployed); _writeTemp(_name, _deployed);
} }
/// @notice Stubs a deployment retrieved through `get`.
/// @param _name The name of the deployment.
/// @param _addr The mock address of the deployment.
function prankDeployment(string memory _name, address _addr) public {
if (bytes(_name).length == 0) {
revert InvalidDeployment("EmptyName");
}
Deployment memory deployment = Deployment({ name: _name, addr: payable(_addr) });
_namedDeployments[_name] = deployment;
}
/// @notice Reads the temp deployments from disk that were generated /// @notice Reads the temp deployments from disk that were generated
/// by the deploy script. /// by the deploy script.
/// @return An array of deployments. /// @return An array of deployments.
......
prestate-artifacts/
prestate-artifacts.tar.gz
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;
import { Proxy } from "src/universal/Proxy.sol";
import { IDisputeGame } from "src/dispute/interfaces/IDisputeGame.sol";
import { StdAssertions } from "forge-std/StdAssertions.sol";
import "scripts/Deploy.s.sol";
/// @notice Deploys the Fault Proof Alpha Chad contracts. These contracts are currently in-development, and the system
/// is independent of the live protocol. Once the contracts are integrated with the live protocol, this script
/// should be deleted.
contract FPACOPS is Deploy, StdAssertions {
////////////////////////////////////////////////////////////////
// ENTRYPOINTS //
////////////////////////////////////////////////////////////////
function deployFPAC() public {
console.log("Deploying a fresh FPAC system");
// Mock the proxy admin & system owner safe so that the DisputeGameFactory & proxy are governed by the deployer.
prankDeployment("ProxyAdmin", msg.sender);
prankDeployment("SystemOwnerSafe", msg.sender);
// Deploy the DisputeGameFactoryProxy.
deployERC1967Proxy("DisputeGameFactoryProxy");
// Deploy implementations.
deployDisputeGameFactory();
deployPreimageOracle();
deployMips();
// Initialize the DisputeGameFactoryProxy.
initializeDisputeGameFactoryProxy();
// Deploy the Cannon Fault game implementation and set it as game ID = 0.
setCannonFaultGameImplementation({ _allowUpgrade: false });
// Ensure `msg.sender` owns the system.
postDeployAssertions();
// Print overview
printConfigReview();
}
function upgradeGameImpl(address _dgf, address _mips) public {
prankDeployment("DisputeGameFactoryProxy", _dgf);
prankDeployment("Mips", _mips);
setCannonFaultGameImplementation({ _allowUpgrade: true });
}
function updateInitBond(address _dgf, GameType _gameType, uint256 _newBond) public {
vm.startBroadcast(msg.sender);
DisputeGameFactory dgfProxy = DisputeGameFactory(_dgf);
dgfProxy.setInitBond(_gameType, _newBond);
vm.stopBroadcast();
}
////////////////////////////////////////////////////////////////
// HELPERS //
////////////////////////////////////////////////////////////////
/// @notice Initializes the DisputeGameFactoryProxy with the DisputeGameFactory.
function initializeDisputeGameFactoryProxy() internal onlyTestnetOrDevnet broadcast {
address dgfProxy = mustGetAddress("DisputeGameFactoryProxy");
Proxy(payable(dgfProxy)).upgradeToAndCall(
mustGetAddress("DisputeGameFactory"), abi.encodeWithSignature("initialize(address)", msg.sender)
);
}
/// @notice Checks that the deployed system is configured correctly.
function postDeployAssertions() internal {
// Ensure `msg.sender` owns the deployed system.
address proxyAdmin = mustGetAddress("ProxyAdmin");
address dgfProxyAddr = mustGetAddress("DisputeGameFactoryProxy");
DisputeGameFactory dgfProxy = DisputeGameFactory(dgfProxyAddr);
assertEq(dgfProxy.owner(), proxyAdmin);
assertEq(address(uint160(uint256(vm.load(dgfProxyAddr, Constants.PROXY_OWNER_ADDRESS)))), proxyAdmin);
// Check the config elements.
FaultDisputeGame gameImpl = FaultDisputeGame(address(dgfProxy.gameImpls(GameTypes.CANNON)));
assertEq(gameImpl.maxGameDepth(), cfg.faultGameMaxDepth());
assertEq(gameImpl.splitDepth(), cfg.faultGameSplitDepth());
assertEq(gameImpl.gameDuration().raw(), cfg.faultGameMaxDuration());
assertEq(gameImpl.absolutePrestate().raw(), bytes32(cfg.faultGameAbsolutePrestate()));
assertEq(gameImpl.genesisBlockNumber(), cfg.faultGameGenesisBlock());
assertEq(gameImpl.genesisOutputRoot().raw(), cfg.faultGameGenesisOutputRoot());
}
/// @notice Prints a review of the fault proof configuration section of the deploy config.
function printConfigReview() internal view {
console.log(unicode"📖 FaultDisputeGame Config Overview (chainid: %d)", block.chainid);
console.log(" 1. Absolute Prestate: %x", cfg.faultGameAbsolutePrestate());
console.log(" 2. Max Depth: %d", cfg.faultGameMaxDepth());
console.log(" 3. Output / Execution split Depth: %d", cfg.faultGameSplitDepth());
console.log(" 4. Game Duration (seconds): %d", cfg.faultGameMaxDuration());
console.log(" 5. L2 Genesis block number: %d", cfg.faultGameGenesisBlock());
console.log(" 6. L2 Genesis output root: %x", uint256(cfg.faultGameGenesisOutputRoot()));
}
}
# ENV
monorepo_root := "../../../.."
deploy_config_path := "../../deploy-config"
tmp := $(shell mktemp)
# Help menu
.PHONY: help
help: # Show help for each of the Makefile recipes.
@grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done
.PHONY: cannon-prestate
cannon-prestate: # Generate the cannon prestate, and tar the `op-program` + `cannon` binaries + prestate data used to generate it.
cd $(monorepo_root) && make cannon-prestate
@mkdir -p prestate-artifacts
@cp -r $(monorepo_root)/cannon/bin/** prestate-artifacts/
@cp -r $(monorepo_root)/op-program/bin/** prestate-artifacts/
tar -czvf prestate-artifacts.tar.gz prestate-artifacts
@jq ".faultGameAbsolutePrestate = $$(cat prestate-artifacts/prestate-proof.json | jq .pre)" "$(deploy_config_path)/$(chain).json" > $(tmp) && mv $(tmp) "$(deploy_config_path)/$(chain).json"
@echo "-------------------------------------------------------------------------------------------------------------"
@echo "-> Archive of prestate artifacts available at prestate-artifacts.tar.gz"
@echo "-> Set the absolute prestate to $$(cat prestate-artifacts/prestate-proof.json | jq .pre) in the $(chain) deploy config."
@rm -rf prestate-artifacts
.PHONY: deploy-fresh
deploy-fresh: # Deploy a fresh version of the FPAC contracts. Pass `--broadcast` to send to the network.
forge script FPACOPS.sol --sig "deployFPAC()" --chain $(chain) -vvv $(args)
.PHONY: upgrade-game-impl
upgrade-game-impl: # Upgrades a dispute game implementation in the deployed `DisputeGameFactory` contract for the configured chain. Pass `--broadcast` to send to the network.
forge script FPACOPS.sol --sig "upgradeGameImpl(address,address)" --chain $(chain) -vvv $(dgf) $(vm) $(args)
.PHONY: update-init-bond
update-init-bond: # Upgrades a dispute game's init bond in the deployed `DisputeGameFactory` contract for the configured chain. Pass `--broadcast` to send to the network.
forge script FPACOPS.sol --sig "updateInitBond(address,uint8,uint256)" --chain $(chain) -vvv $(dgf) $(game-type) $(new-init-bond) $(args)
# `fpac-deploy`
Chain-ops scripts for the Fault Proof Alpha Chad contracts.
## Usage
### Generating the Cannon prestate and artifacts
*Description*: Generates the cannon prestate, tars the relavent artifacts, and sets the absolute prestate field in the network's deploy config.
```sh
make cannon-prestate chain=<chain-name>
```
### Deploying a fresh system
*Description*: Deploys a fully fresh FPAC system to the passed chain. All args after the `chain-name` are forwarded to `forge script`.
```sh
make deploy-fresh chain=<chain-name> [args=<forge-script-args>]
```
### Upgrading the Game Implementation
*Description*: Upgrades the `CANNON` game type's implementation in the `DisputeGameFactory` that was deployed for the passed `chain-name`. All args after the `chain-name` are forwarded to `forge script`.
```sh
make upgrade-game-impl chain=<chain-name> dgf=<dgf-proxy-address> vm=<vm-address> [args=<forge-script-args>]
```
### Updating Init Bonds
*Description*: Updates the initialization bond for a given game type in the `DisputeGameFactory` that was deployed for the passed `chain-name`. All args after the `chain-name` are forwarded to `forge script`.
```sh
make update-init-bond chain=<chain-name> dgf=<dgf-proxy-address> game-type=<game-type> new-init-bond=<new-init-bond> [args=<forge-script-args>]
```
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment