diff --git a/.github/workflows/manual-sol-artifacts.yaml b/.github/workflows/manual-sol-artifacts.yaml index f85e854..8b7bfb8 100644 --- a/.github/workflows/manual-sol-artifacts.yaml +++ b/.github/workflows/manual-sol-artifacts.yaml @@ -2,46 +2,11 @@ name: Manual sol artifacts on: workflow_dispatch: inputs: - network: - description: 'Network to deploy to' - required: true - type: choice - options: - - arbitrum - - arbitrum_sepolia - - avalanche - - base - - bsc - - ethereum - - flare - - mumbai - - oasis_sapphire - - polygon - - sepolia - - songbird - - suite: - description: "Suite to deploy" - required: true - type: choice - options: - - all - - deployment.suite.tables - - deployment.suite.contract jobs: deploy: runs-on: ubuntu-latest steps: - - run: | - network=${{ inputs.network }} - echo "etherscan_api_key_secret_name=CI_DEPLOY_${network^^}_ETHERSCAN_API_KEY" >> $GITHUB_ENV - echo "rpc_secret_name=CI_DEPLOY_${network^^}_RPC_URL" >> $GITHUB_ENV - echo "verify_secret_name=CI_DEPLOY_${network^^}_VERIFY" >> $GITHUB_ENV - echo "verifier_secret_name=CI_DEPLOY_${network^^}_VERIFIER" >> $GITHUB_ENV - echo "verifier_url_secret_name=CI_DEPLOY_${network^^}_VERIFIER_URL" >> $GITHUB_ENV - echo "metaboard_address_secret_name=CI_DEPLOY_${network^^}_METABOARD_ADDRESS" >> $GITHUB_ENV - - uses: actions/checkout@v4 with: submodules: recursive @@ -65,17 +30,17 @@ jobs: gc-max-store-size-linux: 1G - run: nix develop -c rainix-sol-prelude - - name: deploy to ${{ inputs.network }} - run: nix develop -c rainix-sol-artifacts + - run: nix develop -c forge selectors up --all + - run: nix develop -c forge script script/Deploy.sol:Deploy -vvvvv --slow --broadcast --verify env: - DEPLOYMENT_SUITE: ${{ inputs.suite }} - DEPLOY_BROADCAST: '1' DEPLOYMENT_KEY: ${{ github.ref == 'refs/heads/main' && secrets.PRIVATE_KEY || secrets.PRIVATE_KEY_DEV }} - ETH_RPC_URL: ${{ secrets[env.rpc_secret_name] || vars[env.rpc_secret_name] || '' }} - CI_FORK_ETH_RPC_URL: ${{ secrets.RPC_URL_ETHEREUM_FORK || vars.RPC_URL_ETHEREUM_FORK || '' }} - CI_FORK_FLARE_RPC_URL: ${{ secrets.RPC_URL_FLARE_FORK || vars.RPC_URL_FLARE_FORK || '' }} - ETHERSCAN_API_KEY: ${{ secrets[env.etherscan_api_key_secret_name] || vars[env.etherscan_api_key_secret_name] || ''}} - DEPLOY_VERIFY: ${{ secrets[env.verify_secret_name] || vars[env.verify_secret_name] || '' }} - DEPLOY_VERIFIER: ${{ secrets[env.verifier_secret_name] || vars[env.verifier_secret_name] || '' }} - DEPLOY_VERIFIER_URL: ${{ secrets[env.verifier_url_secret_name] || vars[env.verifier_url_secret_name] || '' }} - DEPLOY_METABOARD_ADDRESS: ${{ secrets[env.metaboard_address_secret_name] || vars[env.metaboard_address_secret_name] || '' }} \ No newline at end of file + + CI_DEPLOY_ARBITRUM_RPC_URL: ${{ secrets.CI_DEPLOY_ARBITRUM_RPC_URL || vars.CI_DEPLOY_ARBITRUM_RPC_URL || '' }} + CI_DEPLOY_BASE_RPC_URL: ${{ secrets.CI_DEPLOY_BASE_RPC_URL || vars.CI_DEPLOY_BASE_RPC_URL || '' }} + CI_DEPLOY_FLARE_RPC_URL: ${{ secrets.CI_DEPLOY_FLARE_RPC_URL || vars.CI_DEPLOY_FLARE_RPC_URL || '' }} + CI_DEPLOY_POLYGON_RPC_URL: ${{ secrets.CI_DEPLOY_POLYGON_RPC_URL || vars.CI_DEPLOY_POLYGON_RPC_URL || '' }} + + CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY: ${{ secrets.CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY || vars.CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY || '' }} + CI_DEPLOY_BASE_ETHERSCAN_API_KEY: ${{ secrets.CI_DEPLOY_BASE_ETHERSCAN_API_KEY || vars.CI_DEPLOY_BASE_ETHERSCAN_API_KEY || '' }} + CI_DEPLOY_FLARE_ETHERSCAN_API_KEY: ${{ secrets.CI_DEPLOY_FLARE_ETHERSCAN_API_KEY || vars.CI_DEPLOY_FLARE_ETHERSCAN_API_KEY || '' }} + CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY: ${{ secrets.CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY || vars.CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY || '' }} \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 54ad4b1..b90fb11 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "lib/rain.math.fixedpoint"] path = lib/rain.math.fixedpoint url = https://github.com/rainlanguage/rain.math.fixedpoint +[submodule "lib/rain.deploy"] + path = lib/rain.deploy + url = https://github.com/rainlanguage/rain.deploy diff --git a/foundry.toml b/foundry.toml index 06fc2bf..505c7a6 100644 --- a/foundry.toml +++ b/foundry.toml @@ -30,7 +30,20 @@ fs_permissions = [ remappings = [ "rain.solmem/=lib/rain.datacontract/lib/rain.solmem/src/", "openzeppelin-contracts/=lib/rain.math.fixedpoint/lib/openzeppelin-contracts/", + "rain.deploy/=lib/rain.deploy/src/" ] [fuzz] -runs = 5096 \ No newline at end of file +runs = 5096 + +[rpc_endpoints] +arbitrum = "${CI_DEPLOY_ARBITRUM_RPC_URL}" +base = "${CI_DEPLOY_BASE_RPC_URL}" +flare = "${CI_DEPLOY_FLARE_RPC_URL}" +polygon = "${CI_DEPLOY_POLYGON_RPC_URL}" + +[etherscan] +arbitrum = { key = "${CI_DEPLOY_ARBITRUM_ETHERSCAN_API_KEY}" } +base = { key = "${CI_DEPLOY_BASE_ETHERSCAN_API_KEY}" } +flare = { key = "${CI_DEPLOY_FLARE_ETHERSCAN_API_KEY}" } +polygon = { key = "${CI_DEPLOY_POLYGON_ETHERSCAN_API_KEY}" } \ No newline at end of file diff --git a/lib/rain.deploy b/lib/rain.deploy new file mode 160000 index 0000000..1120ee3 --- /dev/null +++ b/lib/rain.deploy @@ -0,0 +1 @@ +Subproject commit 1120ee36cfb74e228a4aa6fbba02b515fe14f172 diff --git a/script/Deploy.sol b/script/Deploy.sol index a7898db..77dca52 100644 --- a/script/Deploy.sol +++ b/script/Deploy.sol @@ -5,6 +5,8 @@ pragma solidity =0.8.25; import {Script} from "forge-std/Script.sol"; import {DataContractMemoryContainer, LibDataContract} from "rain.datacontract/lib/LibDataContract.sol"; import {LibDecimalFloatDeploy} from "../src/lib/deploy/LibDecimalFloatDeploy.sol"; +import {LibRainDeploy} from "rain.deploy/lib/LibRainDeploy.sol"; +import {DecimalFloat} from "../src/concrete/DecimalFloat.sol"; bytes32 constant DEPLOYMENT_SUITE_ALL = keccak256("all"); bytes32 constant DEPLOYMENT_SUITE_TABLES = keccak256("deployment.suite.tables"); @@ -15,21 +17,33 @@ contract Deploy is Script { function run() external { uint256 deployerPrivateKey = vm.envUint("DEPLOYMENT_KEY"); - string memory suiteString = vm.envOr("DEPLOYMENT_SUITE", string("all")); - bytes32 suite = keccak256(bytes(suiteString)); - DataContractMemoryContainer container = LibDecimalFloatDeploy.dataContract(); + LibRainDeploy.deployAndBroadcastToSupportedNetworks( + vm, + LibRainDeploy.supportedNetworks(), + deployerPrivateKey, + type(DecimalFloat).creationCode, + "src/concrete/DecimalFloat.sol:DecimalFloat", + LibDecimalFloatDeploy.ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS, + LibDecimalFloatDeploy.DECIMAL_FLOAT_CONTRACT_HASH, + new address[](0) + ); - vm.startBroadcast(deployerPrivateKey); + // string memory suiteString = vm.envOr("DEPLOYMENT_SUITE", string("all")); + // bytes32 suite = keccak256(bytes(suiteString)); - if (suite == DEPLOYMENT_SUITE_ALL || suite == DEPLOYMENT_SUITE_TABLES) { - container.writeZoltu(); - } + // DataContractMemoryContainer container = LibDecimalFloatDeploy.dataContract(); - if (suite == DEPLOYMENT_SUITE_ALL || suite == DEPLOYMENT_SUITE_CONTRACT) { - LibDecimalFloatDeploy.decimalFloatZoltu(); - } + // vm.startBroadcast(deployerPrivateKey); - vm.stopBroadcast(); + // if (suite == DEPLOYMENT_SUITE_ALL || suite == DEPLOYMENT_SUITE_TABLES) { + // container.writeZoltu(); + // } + + // if (suite == DEPLOYMENT_SUITE_ALL || suite == DEPLOYMENT_SUITE_CONTRACT) { + // LibDecimalFloatDeploy.decimalFloatZoltu(); + // } + + // vm.stopBroadcast(); } } diff --git a/src/lib/deploy/LibDecimalFloatDeploy.sol b/src/lib/deploy/LibDecimalFloatDeploy.sol index eb73668..c2fd8ba 100644 --- a/src/lib/deploy/LibDecimalFloatDeploy.sol +++ b/src/lib/deploy/LibDecimalFloatDeploy.sol @@ -17,6 +17,10 @@ import {LOG_TABLE_DISAMBIGUATOR} from "../table/LibLogTable.sol"; import {WriteError} from "../../error/ErrDecimalFloat.sol"; library LibDecimalFloatDeploy { + /// Thrown when failing to ensure the DecimalFloat contract is deployed at + /// the expected address or the codehash does not match the expected value. + error DecimalFloatNotDeployed(); + /// @dev Zoltu deterministic deployment proxy address. /// https://github.com/Zoltu/deterministic-deployment-proxy?tab=readme-ov-file#proxy-address address constant ZOLTU_PROXY_ADDRESS = 0x7A0D94F55792C434d74a40883C6ed8545E406D12; @@ -24,12 +28,20 @@ library LibDecimalFloatDeploy { /// @dev Address of the DecimalFloat contract deployed via Zoltu's /// deterministic deployment proxy. /// This address is the same across all EVM-compatible networks. - address constant ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS = address(0x6421E8a23cdEe2E6E579b2cDebc8C2A514843593); + address constant ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS = address(0x12A66eFbE556e38308A17e34cC86f21DcA1CDB73); /// @dev The expected codehash of the DecimalFloat contract deployed via /// Zoltu's deterministic deployment proxy. - bytes32 constant DECIMAL_FLOAT_DATA_CONTRACT_HASH = - 0x2573004ac3a9ee7fc8d73654d76386f1b6b99e34cdf86a689c4691e47143420f; + bytes32 constant DECIMAL_FLOAT_CONTRACT_HASH = 0x705cdef2ed9538557152f86cd0988c748e0bd647a49df00b3e4f100c3544a583; + + function ensureDeployed() internal view { + if ( + address(ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS).code.length == 0 + || address(ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS).codehash != DECIMAL_FLOAT_CONTRACT_HASH + ) { + revert DecimalFloatNotDeployed(); + } + } /// Combines all log and anti-log tables into a single bytes array for /// deployment. These are using packed encoding to minimize size and remove diff --git a/test/src/lib/deploy/LibDecimalFloatDeploy.t.sol b/test/src/lib/deploy/LibDecimalFloatDeploy.t.sol index b5e2c93..492dc6b 100644 --- a/test/src/lib/deploy/LibDecimalFloatDeploy.t.sol +++ b/test/src/lib/deploy/LibDecimalFloatDeploy.t.sol @@ -3,10 +3,24 @@ pragma solidity =0.8.25; import {Test, console2} from "forge-std/Test.sol"; - +import {LibRainDeploy} from "rain.deploy/lib/LibRainDeploy.sol"; import {LibDecimalFloatDeploy, DecimalFloat} from "src/lib/deploy/LibDecimalFloatDeploy.sol"; contract LibDecimalFloatDeployTest is Test { + function testDeployAddress() external { + vm.createSelectFork(vm.envString("CI_FORK_ETH_RPC_URL")); + address deployedAddress = LibRainDeploy.deployZoltu(type(DecimalFloat).creationCode); + assertEq(deployedAddress, LibDecimalFloatDeploy.ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS); + + LibDecimalFloatDeploy.ensureDeployed(); + } + + function testExpectedCodeHash() external { + DecimalFloat decimalFloat = new DecimalFloat(); + + assertEq(address(decimalFloat).codehash, LibDecimalFloatDeploy.DECIMAL_FLOAT_CONTRACT_HASH); + } + function testDecimalFloatZoltu() external { vm.createSelectFork(vm.envString("CI_FORK_ETH_RPC_URL")); @@ -18,21 +32,21 @@ contract LibDecimalFloatDeployTest is Test { assertEq(address(deployedZoltu).codehash, address(deployedDirect).codehash); } - function testDecimalFloatZoltuProd() external { - string[] memory forkRpcUrls = new string[](3); - forkRpcUrls[0] = "CI_FORK_FLARE_RPC_URL"; - forkRpcUrls[1] = "CI_FORK_BASE_RPC_URL"; - forkRpcUrls[2] = "CI_FORK_ARB_RPC_URL"; - - for (uint256 i = 0; i < forkRpcUrls.length; i++) { - console2.log("Testing fork:", forkRpcUrls[i]); - vm.createSelectFork(vm.envString(forkRpcUrls[i])); - - assertEq( - LibDecimalFloatDeploy.DECIMAL_FLOAT_DATA_CONTRACT_HASH, - LibDecimalFloatDeploy.ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS.codehash, - forkRpcUrls[i] - ); - } - } + // function testDecimalFloatZoltuProd() external { + // string[] memory forkRpcUrls = new string[](3); + // forkRpcUrls[0] = "CI_FORK_FLARE_RPC_URL"; + // forkRpcUrls[1] = "CI_FORK_BASE_RPC_URL"; + // forkRpcUrls[2] = "CI_FORK_ARB_RPC_URL"; + + // for (uint256 i = 0; i < forkRpcUrls.length; i++) { + // console2.log("Testing fork:", forkRpcUrls[i]); + // vm.createSelectFork(vm.envString(forkRpcUrls[i])); + + // assertEq( + // LibDecimalFloatDeploy.DECIMAL_FLOAT_DATA_CONTRACT_HASH, + // LibDecimalFloatDeploy.ZOLTU_DEPLOYED_DECIMAL_FLOAT_ADDRESS.codehash, + // forkRpcUrls[i] + // ); + // } + // } }