From c45183fe61ba2e6fd7dee66bef9ed5b33569c79a Mon Sep 17 00:00:00 2001 From: Kevin Siegler <17910833+topocount@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:42:06 -0500 Subject: [PATCH] feat(evm): script to deploy and register module bases The module bases and core deploys are all saved to a json file with the `chainid` as the title, which should make for easy to pull the deployed addresses into the sdk --- packages/evm/foundry.toml | 2 +- packages/evm/package.json | 3 +- packages/evm/script/solidity/Deploy.s.sol | 108 +++++--------- .../evm/script/solidity/Deploy_Modules.s.sol | 134 ++++++++++++++++++ packages/evm/script/solidity/Util.s.sol | 27 ++++ 5 files changed, 201 insertions(+), 73 deletions(-) create mode 100644 packages/evm/script/solidity/Deploy_Modules.s.sol create mode 100644 packages/evm/script/solidity/Util.s.sol diff --git a/packages/evm/foundry.toml b/packages/evm/foundry.toml index 4ea68d94..11146ea5 100644 --- a/packages/evm/foundry.toml +++ b/packages/evm/foundry.toml @@ -10,7 +10,7 @@ cache_path = 'cache_forge' libs = ['node_modules', 'lib'] solc_version = '0.8.26' evm_version = 'cancun' -fs_permissions = [{access = "write", path = "./deploys"}] +fs_permissions = [{access = "read-write", path = "./deploys"}] remappings=[ '@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/', '@openzeppelin-upgrades/contracts/=lib/openzeppelin-contracts-upgradeable/contracts/', diff --git a/packages/evm/package.json b/packages/evm/package.json index 3477a73a..49652e01 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -29,7 +29,8 @@ "test": "forge test -vvv && hardhat test", "test:ci": "forge test --summary --detailed -vvv && hardhat test", "coverage": "forge coverage --report lcov --report-file coverage/lcov.info", - "deploy:local": "forge script script/solidity/Deploy.s.sol:Deployer -f http://127.0.0.1:8545 --broadcast --mnemonics \"test test test test test test test test test test test junk\"", + "deploy:core:local": "forge script script/solidity/Deploy.s.sol:CoreDeployer -f http://127.0.0.1:8545 --broadcast --mnemonics \"test test test test test test test test test test test junk\"", + "deploy:modules:local": "forge script script/solidity/Deploy_Modules.s.sol:ModuleBaseDeployer -f http://127.0.0.1:8545 --broadcast --mnemonics \"test test test test test test test test test test test junk\"", "anvil": "anvil" }, "keywords": [], diff --git a/packages/evm/script/solidity/Deploy.s.sol b/packages/evm/script/solidity/Deploy.s.sol index ea819c32..5b9aa22f 100644 --- a/packages/evm/script/solidity/Deploy.s.sol +++ b/packages/evm/script/solidity/Deploy.s.sol @@ -1,79 +1,45 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.24; -import "forge-std/Script.sol"; +import "./Util.s.sol"; import {BoostCore} from "contracts/BoostCore.sol"; import {BoostRegistry} from "contracts/BoostRegistry.sol"; -contract Deployer is Script { - - address BOOST_FEE_RECIPIENT; - - function setUp() external { - BOOST_FEE_RECIPIENT = vm.envAddress("BOOST_FEE_RECIPIENT"); - } - - function run() public { - // 1. Deploy Boost registry - address registry = _deployRegistry(); - address core = _deployCore(registry); - _saveDeployments(registry, core); - } - - function _deployRegistry() internal returns (address registry) { - bytes memory initCode = type(BoostRegistry).creationCode; - registry = _getCreate2Address(initCode, ""); - console.log("BoostRegistry: ", registry); - _deploy2(initCode, ""); - } - - function _deployCore(address registry) internal returns (address core) { - bytes memory initCode = type(BoostCore).creationCode; - bytes memory constructorArgs = abi.encode(registry, BOOST_FEE_RECIPIENT); - core = _getCreate2Address(initCode, constructorArgs); - console.log("BoostCore: ", core); - _deploy2(initCode, constructorArgs); - } - - function _getCreate2Address( - bytes memory creationCode, - bytes memory args - ) internal view returns (address) { - bytes32 salt = keccak256(bytes(vm.envString("BOOST_DEPLOYMENT_SALT"))); - bytes32 codeHash = hashInitCode(creationCode, args); - return vm.computeCreate2Address(salt, codeHash); - } - - function _deploy2( - bytes memory deployCode, - bytes memory args - ) internal { - bytes32 salt = keccak256(bytes(vm.envString("BOOST_DEPLOYMENT_SALT"))); - bytes memory payload = abi.encodePacked(salt, deployCode, args); - // deploy using address configured at the CLI level - vm.broadcast(); - (bool success, ) = CREATE2_FACTORY.call(payload); - if (!success) revert("create2 failed"); - } - - function _saveDeployments(address registry, address core) internal { - string memory deployKey = "deployments"; - - vm.serializeAddress(deployKey, "BoostRegistry", registry); - string memory finalJson = vm.serializeAddress(deployKey, "BoostCore", core); - vm.writeJson( - finalJson, - string( - abi.encodePacked( - vm.projectRoot(), - "/deploys/", - vm.toString(block.chainid), - ".json" - ) - ) - ); - } - +contract CoreDeployer is ScriptUtils { + address BOOST_FEE_RECIPIENT; + + function setUp() external { + BOOST_FEE_RECIPIENT = vm.envAddress("BOOST_FEE_RECIPIENT"); + } + + function run() public { + // 1. Deploy Boost registry + address registry = _deployRegistry(); + address core = _deployCore(registry); + _saveDeployments(registry, core); + } + + function _deployRegistry() internal returns (address registry) { + bytes memory initCode = type(BoostRegistry).creationCode; + registry = _getCreate2Address(initCode, ""); + console.log("BoostRegistry: ", registry); + _deploy2(initCode, ""); + } + + function _deployCore(address registry) internal returns (address core) { + bytes memory initCode = type(BoostCore).creationCode; + bytes memory constructorArgs = abi.encode(registry, BOOST_FEE_RECIPIENT); + core = _getCreate2Address(initCode, constructorArgs); + console.log("BoostCore: ", core); + _deploy2(initCode, constructorArgs); + } + + function _saveDeployments(address registry, address core) internal { + string memory deployKey = "deployments"; + + vm.serializeAddress(deployKey, "BoostRegistry", registry); + string memory finalJson = vm.serializeAddress(deployKey, "BoostCore", core); + vm.writeJson(finalJson, _buildJsonDeployPath()); + } } - diff --git a/packages/evm/script/solidity/Deploy_Modules.s.sol b/packages/evm/script/solidity/Deploy_Modules.s.sol new file mode 100644 index 00000000..0cd7b978 --- /dev/null +++ b/packages/evm/script/solidity/Deploy_Modules.s.sol @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.24; + +import "./Util.s.sol"; + +import {BoostCore} from "contracts/BoostCore.sol"; +import {BoostRegistry} from "contracts/BoostRegistry.sol"; + +import {ManagedBudget} from "contracts/budgets/ManagedBudget.sol"; + +import {EventAction} from "contracts/actions/EventAction.sol"; + +import {ERC20Incentive} from "contracts/incentives/ERC20Incentive.sol"; +import {ERC20VariableIncentive} from "contracts/incentives/ERC20VariableIncentive.sol"; +import {CGDAIncentive} from "contracts/incentives/CGDAIncentive.sol"; +import {PointsIncentive} from "contracts/incentives/PointsIncentive.sol"; +import {AllowListIncentive} from "contracts/incentives/AllowListIncentive.sol"; + +import {SimpleAllowList} from "contracts/allowlists/SimpleAllowList.sol"; +import {SimpleDenyList} from "contracts/allowlists/SimpleDenyList.sol"; + +/// @notice this script deploys and registers budgets, actions, and incentives +contract ModuleBaseDeployer is ScriptUtils { + using stdJson for string; + + string BOOST_DEPLOYMENT_SALT; + + string constant deployJsonKey = "deployJsonKey"; + string deployJson; + + function setUp() external { + BOOST_DEPLOYMENT_SALT = vm.envString("BOOST_DEPLOYMENT_SALT"); + } + + function run() external { + BoostRegistry registry = _getRegistry(); + console.log("Boost Registry: ", address(registry)); + + _deployManagedBudget(registry); + + _deployEventAction(registry); + + _deployERC20Incentive(registry); + _deployERC20VariableIncentive(registry); + _deployCGDAIncentive(registry); + _deployPointsIncentive(registry); + _deployAllowListIncentive(registry); + + _saveJson(); + } + + function _saveJson() internal { + vm.writeJson(deployJson, _buildJsonDeployPath()); + } + + function _getRegistry() internal returns (BoostRegistry registry) { + string memory path = + string(abi.encodePacked(vm.projectRoot(), "/deploys/", vm.toString(block.chainid), ".json")); + deployJson = vm.readFile(path); + deployJson = deployJsonKey.serialize(deployJson); + if (!vm.keyExistsJson(deployJson, ".BoostRegistry")) revert("No registry deployed: run `pnpm deploy:core:local"); + return BoostRegistry(deployJson.readAddress(".BoostRegistry")); + } + + function _deployManagedBudget(BoostRegistry registry) internal returns (address managedBudget) { + bytes memory initCode = type(ManagedBudget).creationCode; + managedBudget = _getCreate2Address(initCode, ""); + console.log("ManagedBudget: ", managedBudget); + deployJson = deployJsonKey.serialize("ManagedBudget", managedBudget); + _deploy2(initCode, ""); + vm.broadcast(); + registry.register(BoostRegistry.RegistryType.BUDGET, "ManagedBudget", managedBudget); + } + + function _deployEventAction(BoostRegistry registry) internal returns (address eventAction) { + bytes memory initCode = type(EventAction).creationCode; + eventAction = _getCreate2Address(initCode, ""); + console.log("EventAction: ", eventAction); + deployJson = deployJsonKey.serialize("EventAction", eventAction); + _deploy2(initCode, ""); + vm.broadcast(); + registry.register(BoostRegistry.RegistryType.ACTION, "EventAction", eventAction); + } + + function _deployERC20Incentive(BoostRegistry registry) internal returns (address erc20Incentive) { + bytes memory initCode = type(ERC20Incentive).creationCode; + erc20Incentive = _getCreate2Address(initCode, ""); + console.log("ERC20Incentive: ", erc20Incentive); + deployJson = deployJsonKey.serialize("ERC20Incentive", erc20Incentive); + _deploy2(initCode, ""); + vm.broadcast(); + registry.register(BoostRegistry.RegistryType.INCENTIVE, "ERC20Incentive", erc20Incentive); + } + + function _deployERC20VariableIncentive(BoostRegistry registry) internal returns (address erc20VariableIncentive) { + bytes memory initCode = type(ERC20VariableIncentive).creationCode; + erc20VariableIncentive = _getCreate2Address(initCode, ""); + console.log("ERC20VariableIncentive: ", erc20VariableIncentive); + deployJson = deployJsonKey.serialize("ERC20VariableIncentive", erc20VariableIncentive); + _deploy2(initCode, ""); + vm.broadcast(); + registry.register(BoostRegistry.RegistryType.INCENTIVE, "ERC20VariableIncentive", erc20VariableIncentive); + } + + function _deployCGDAIncentive(BoostRegistry registry) internal returns (address cgdaIncentive) { + bytes memory initCode = type(CGDAIncentive).creationCode; + cgdaIncentive = _getCreate2Address(initCode, ""); + console.log("CGDAIncentive: ", cgdaIncentive); + deployJson = deployJsonKey.serialize("CGDAIncentive", cgdaIncentive); + _deploy2(initCode, ""); + vm.broadcast(); + registry.register(BoostRegistry.RegistryType.INCENTIVE, "CGDAIncentive", cgdaIncentive); + } + + function _deployPointsIncentive(BoostRegistry registry) internal returns (address pointsIncentive) { + bytes memory initCode = type(PointsIncentive).creationCode; + pointsIncentive = _getCreate2Address(initCode, ""); + console.log("PointsIncentive: ", pointsIncentive); + deployJson = deployJsonKey.serialize("PointsIncentive", pointsIncentive); + _deploy2(initCode, ""); + vm.broadcast(); + registry.register(BoostRegistry.RegistryType.INCENTIVE, "PointsIncentive", pointsIncentive); + } + + function _deployAllowListIncentive(BoostRegistry registry) internal returns (address allowListIncentive) { + bytes memory initCode = type(AllowListIncentive).creationCode; + allowListIncentive = _getCreate2Address(initCode, ""); + console.log("AllowListIncentive: ", allowListIncentive); + deployJson = deployJsonKey.serialize("AllowListIncentive", allowListIncentive); + _deploy2(initCode, ""); + vm.broadcast(); + registry.register(BoostRegistry.RegistryType.INCENTIVE, "AllowListIncentive", allowListIncentive); + } +} diff --git a/packages/evm/script/solidity/Util.s.sol b/packages/evm/script/solidity/Util.s.sol new file mode 100644 index 00000000..b23d0e8f --- /dev/null +++ b/packages/evm/script/solidity/Util.s.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.24; + +import "forge-std/Script.sol"; + +contract ScriptUtils is Script { + using stdJson for string; + + function _getCreate2Address(bytes memory creationCode, bytes memory args) internal view returns (address) { + bytes32 salt = keccak256(bytes(vm.envString("BOOST_DEPLOYMENT_SALT"))); + bytes32 codeHash = hashInitCode(creationCode, args); + return vm.computeCreate2Address(salt, codeHash); + } + + function _deploy2(bytes memory deployCode, bytes memory args) internal { + bytes32 salt = keccak256(bytes(vm.envString("BOOST_DEPLOYMENT_SALT"))); + bytes memory payload = abi.encodePacked(salt, deployCode, args); + // deploy using address configured at the CLI level + vm.broadcast(); + (bool success,) = CREATE2_FACTORY.call(payload); + if (!success) revert("create2 failed"); + } + + function _buildJsonDeployPath() internal view returns (string memory) { + return string(abi.encodePacked(vm.projectRoot(), "/deploys/", vm.toString(block.chainid), ".json")); + } +}