Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
354 changes: 181 additions & 173 deletions .gas-snapshot

Large diffs are not rendered by default.

57 changes: 15 additions & 42 deletions .github/workflows/manual-sol-artifacts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,18 @@ 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"
description: "The suite to deploy"
required: true
type: choice
options:
- all
- deployment.suite.tables
- deployment.suite.contract
- log-tables
- decimal-float

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
Expand All @@ -65,17 +37,18 @@ 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] || '' }}

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 || '' }}
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 4 additions & 1 deletion foundry.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"rev": "1801b0541f4fda118a10798fd3486bb7051c5dd6"
},
"lib/rain.datacontract": {
"rev": "82590300cf768b6c5efc8b92c64b7f402bd34bee"
"rev": "3bff30782e408386f73b9353c5122e2e0ab24df2"
},
"lib/rain.deploy": {
"rev": "1af8ca2a981c2f67844f343e224f4c7b1969de1c"
},
"lib/rain.math.fixedpoint": {
"rev": "8308cbb6da0e231c6f3437f1861e66eff7ea2b00"
Expand Down
15 changes: 14 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
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}" }
2 changes: 1 addition & 1 deletion lib/rain.datacontract
1 change: 1 addition & 0 deletions lib/rain.deploy
Submodule rain.deploy added at 1af8ca
54 changes: 34 additions & 20 deletions script/Deploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,47 @@
pragma solidity =0.8.25;

import {Script} from "forge-std/Script.sol";
import {DataContractMemoryContainer, LibDataContract} from "rain.datacontract/lib/LibDataContract.sol";
import {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");
bytes32 constant DEPLOYMENT_SUITE_CONTRACT = keccak256("deployment.suite.contract");
bytes32 constant DEPLOYMENT_SUITE_TABLES = keccak256("log-tables");
bytes32 constant DEPLOYMENT_SUITE_CONTRACT = keccak256("decimal-float");

contract Deploy is Script {
using LibDataContract for DataContractMemoryContainer;

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();

vm.startBroadcast(deployerPrivateKey);

if (suite == DEPLOYMENT_SUITE_ALL || suite == DEPLOYMENT_SUITE_TABLES) {
container.writeZoltu();
bytes32 suite = keccak256(bytes(vm.envOr("DEPLOYMENT_SUITE", string("decimal-float"))));
if (suite == DEPLOYMENT_SUITE_TABLES) {
LibRainDeploy.deployAndBroadcastToSupportedNetworks(
vm,
LibRainDeploy.supportedNetworks(),
deployerPrivateKey,
LibDataContract.contractCreationCode(LibDecimalFloatDeploy.combinedTables()),
"",
LibDecimalFloatDeploy.ZOLTU_DEPLOYED_LOG_TABLES_ADDRESS,
LibDecimalFloatDeploy.LOG_TABLES_DATA_CONTRACT_HASH,
new address[](0)
);
} else if (suite == DEPLOYMENT_SUITE_CONTRACT) {
address[] memory decimalFloatDependencies = new address[](1);
decimalFloatDependencies[0] = LibDecimalFloatDeploy.ZOLTU_DEPLOYED_LOG_TABLES_ADDRESS;
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,
decimalFloatDependencies
);
} else {
revert(
"Invalid deployment suite specified. Please set the DEPLOYMENT_SUITE environment variable to either 'log-tables' or 'decimal-float'."
);
}

if (suite == DEPLOYMENT_SUITE_ALL || suite == DEPLOYMENT_SUITE_CONTRACT) {
LibDecimalFloatDeploy.decimalFloatZoltu();
}

vm.stopBroadcast();
}
}
46 changes: 10 additions & 36 deletions src/lib/deploy/LibDecimalFloatDeploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,23 @@ import {LOG_TABLE_DISAMBIGUATOR} from "../table/LibLogTable.sol";
import {WriteError} from "../../error/ErrDecimalFloat.sol";

library LibDecimalFloatDeploy {
/// @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;
/// @dev Address of the log tables deployed via Zoltu's deterministic
/// deployment proxy. This address is the same across all EVM-compatible
/// networks.
address constant ZOLTU_DEPLOYED_LOG_TABLES_ADDRESS = address(0xc51a14251b0dcF0ae24A96b7153991378938f5F5);

/// @dev The expected codehash of the log tables deployed via Zoltu's
/// deterministic deployment proxy.
bytes32 constant LOG_TABLES_DATA_CONTRACT_HASH = 0x2573004ac3a9ee7fc8d73654d76386f1b6b99e34cdf86a689c4691e47143420f;

/// @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;

/// Combines all log and anti-log tables into a single bytes array for
/// deployment. These are using packed encoding to minimize size and remove
Expand All @@ -45,34 +49,4 @@ library LibDecimalFloatDeploy {
LOG_TABLE_DISAMBIGUATOR
);
}

/// Creates a DataContractMemoryContainer containing all log and anti-log
/// tables.
/// @return dataContract The DataContractMemoryContainer containing the
/// tables.
function dataContract() internal pure returns (DataContractMemoryContainer) {
bytes memory tables = combinedTables();
(DataContractMemoryContainer container, Pointer pointer) = LibDataContract.newContainer(tables.length);
LibMemCpy.unsafeCopyBytesTo(LibBytes.dataPointer(tables), pointer, tables.length);
return container;
}

/// Deploys a DecimalFloat contract using Zoltu's deterministic deployment
/// proxy contract. This allows the concrete DecimalFloat contract to be
/// found at a predictable location regardless of the network.
/// Reverts with WriteError if deployment fails.
/// @return deployedAddress The address of the deployed DecimalFloat
/// contract.
function decimalFloatZoltu() internal returns (DecimalFloat deployedAddress) {
//slither-disable-next-line too-many-digits
bytes memory code = type(DecimalFloat).creationCode;
bool success;
address zoltuProxy = ZOLTU_PROXY_ADDRESS;
assembly ("memory-safe") {
mstore(0, 0)
success := call(gas(), zoltuProxy, 0, add(code, 0x20), mload(code), 12, 20)
deployedAddress := mload(0)
}
if (address(deployedAddress) == address(0) || !success) revert WriteError();
}
}
15 changes: 13 additions & 2 deletions test/abstract/LogTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@ abstract contract LogTest is Test {

function logTables() internal returns (address) {
if (sTables == address(0)) {
DataContractMemoryContainer container = LibDecimalFloatDeploy.dataContract();
sTables = container.write();
bytes memory tables = LibDecimalFloatDeploy.combinedTables();
bytes memory creationCode = LibDataContract.contractCreationCode(tables);
address tablesAddress;
assembly ("memory-safe") {
tablesAddress := create(0, add(creationCode, 0x20), mload(creationCode))
}
assertTrue(tablesAddress != address(0), "Failed to deploy tables");
assertEq(
tablesAddress.codehash,
LibDecimalFloatDeploy.LOG_TABLES_DATA_CONTRACT_HASH,
"Deployed tables codehash does not match expected value"
);
sTables = tablesAddress;
}
return sTables;
}
Expand Down
53 changes: 31 additions & 22 deletions test/src/lib/deploy/LibDecimalFloatDeploy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,46 @@
// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd
pragma solidity =0.8.25;

import {Test, console2} from "forge-std/Test.sol";

import {Test} from "forge-std/Test.sol";
import {LibRainDeploy} from "rain.deploy/lib/LibRainDeploy.sol";
import {LibDecimalFloatDeploy, DecimalFloat} from "src/lib/deploy/LibDecimalFloatDeploy.sol";
import {LibDataContract} from "rain.datacontract/lib/LibDataContract.sol";

contract LibDecimalFloatDeployTest is Test {
function testDecimalFloatZoltu() external {
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);
assertTrue(address(deployedAddress).code.length > 0, "Deployed address has no code");

DecimalFloat deployedZoltu = LibDecimalFloatDeploy.decimalFloatZoltu();
assertTrue(address(deployedZoltu) != address(0));
assertEq(address(deployedAddress).codehash, LibDecimalFloatDeploy.DECIMAL_FLOAT_CONTRACT_HASH);
}

DecimalFloat deployedDirect = new DecimalFloat();
function testExpectedCodeHashDecimalFloat() external {
DecimalFloat decimalFloat = new DecimalFloat();

assertEq(address(deployedZoltu).codehash, address(deployedDirect).codehash);
assertEq(address(decimalFloat).codehash, LibDecimalFloatDeploy.DECIMAL_FLOAT_CONTRACT_HASH);
}

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 testDeployAddressLogTables() external {
vm.createSelectFork(vm.envString("CI_FORK_ETH_RPC_URL"));
bytes memory logTables = LibDataContract.contractCreationCode(LibDecimalFloatDeploy.combinedTables());
address deployedAddress = LibRainDeploy.deployZoltu(logTables);

assertEq(deployedAddress, LibDecimalFloatDeploy.ZOLTU_DEPLOYED_LOG_TABLES_ADDRESS);
assertEq(address(deployedAddress).codehash, LibDecimalFloatDeploy.LOG_TABLES_DATA_CONTRACT_HASH);
}

function testExpectedCodeHashLogTables() external {
bytes memory logTables = LibDataContract.contractCreationCode(LibDecimalFloatDeploy.combinedTables());

address deployedAddress;
assembly ("memory-safe") {
deployedAddress := create(0, add(logTables, 0x20), mload(logTables))
}

assertEq(deployedAddress.codehash, LibDecimalFloatDeploy.LOG_TABLES_DATA_CONTRACT_HASH);
assertTrue(address(deployedAddress).code.length > 0, "Deployed address has no code");
}
}