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
9 changes: 9 additions & 0 deletions .github/workflows/manual-broadcast.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ on:
# `base`.
- 'base'
- 'ethereum'
- 'hyperevm'
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Dispatches an operational broadcast script from `script/` and sends the
# resulting transactions from the CI deploy key (`secrets.PRIVATE_KEY`,
# the same secret `manual-sol-artifacts.yaml` uses for Zoltu impl deploys).
Expand Down Expand Up @@ -76,6 +77,7 @@ jobs:
# one foundry.toml resolves via its `[rpc_endpoints]` aliases.
BASE_RPC_URL: ${{ secrets.RPC_URL_BASE_FORK }}
ETHEREUM_RPC_URL: ${{ secrets.RPC_URL_ETHEREUM_FORK }}
HYPEREVM_RPC_URL: ${{ secrets.RPC_URL_HYPEREVM_FORK }}
# Pass the choice inputs via env rather than template-expanding them
# into the command, so the dispatched values are used as literal
# arguments and cannot inject shell.
Expand All @@ -86,7 +88,14 @@ jobs:
# persist it anywhere else.
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
run: |
# HyperEVM's RPC rejects forge's EIP-1559 fee-history estimation;
# type-0 transactions work on every network.
LEGACY_ARGS=()
if [[ "${NETWORK}" == "hyperevm" ]]; then
LEGACY_ARGS+=(--legacy)
fi
nix develop --command forge script "script/${SCRIPT}.s.sol" \
"${LEGACY_ARGS[@]}" \
--sig 'run()' \
--rpc-url "${NETWORK}" \
--no-storage-caching \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
name: Manual sol artifacts (Ethereum 0.1.1)
name: Manual sol artifacts (0.1.1 bootstrap)
# Least-privilege: the broadcast authenticates via `secrets.PRIVATE_KEY`, so
# the ambient GITHUB_TOKEN needs nothing beyond read.
permissions:
contents: read
on:
workflow_dispatch:
inputs:
Expand All @@ -8,8 +12,9 @@ on:
type: choice
options:
# ===================================================================
# The audited 0.1.1 production set, shipped to Ethereum mainnet only
# via script/DeployProdV4_0_1_1.sol (stored 0.1.1 creation bytecode).
# The audited 0.1.1 production set, shipped to the selected bootstrap
# network via script/DeployProdV4_0_1_1.sol (stored 0.1.1 creation
# bytecode).
# The orchestrator (introduced at 0.1.2) is not part of this set.
#
# Deploy in the listed order; later entries reference earlier ones via
Expand All @@ -33,20 +38,34 @@ on:
- stox-offchain-asset-receipt-vault-beacon-set-deployer
# 5. Unified deployer (depends on the two set-deployers above).
- stox-unified-deployer
network:
description: 'Bootstrap network to ship the 0.1.1 set to'
required: true
type: choice
options:
# Closed set of vetted bootstrap networks — mirrored by the deploy
# script's `bootstrapNetwork()` guard.
- 'ethereum'
- 'hyperevm'
jobs:
deploy:
uses: rainlanguage/rainix/.github/workflows/rainix-manual-sol-artifacts.yaml@main
with:
suite: ${{ inputs.suite }}
network: ${{ inputs.network }}
# HyperEVM's RPC rejects forge's EIP-1559 fee-history estimation;
# type-0 transactions work on every bootstrap network.
legacy: ${{ inputs.network == 'hyperevm' }}
# Ship the stored 0.1.1 creation bytecode, not current source.
script: script/DeployProdV4_0_1_1.sol:Deploy
# The 0.1.1 bytecode of the contracts that changed by 0.1.3 does not match
# current source, so Etherscan verification against current source would
# fail the run. Deploy unverified; verify manually from the 0.1.1 tag.
verify: false
# This script targets Ethereum only and runs unverified, so it needs only the
# deployer key and the Ethereum RPC. The reusable declares every other secret
# as optional and falls back to `|| vars.* || ''` for any it isn't given.
# Runs unverified, so it needs only the deployer key and the bootstrap
# networks' RPCs. The reusable declares every other secret as optional and
# falls back to `|| vars.* || ''` for any it isn't given.
secrets:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
RPC_URL_ETHEREUM_FORK: ${{ secrets.RPC_URL_ETHEREUM_FORK }}
RPC_URL_HYPEREVM_FORK: ${{ secrets.RPC_URL_HYPEREVM_FORK }}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ base = "${BASE_RPC_URL}"
base_sepolia = "${BASE_SEPOLIA_RPC_URL}"
ethereum = "${ETHEREUM_RPC_URL}"
flare = "${FLARE_RPC_URL}"
hyperevm = "${HYPEREVM_RPC_URL}"
polygon = "${POLYGON_RPC_URL}"

[etherscan]
Expand Down
42 changes: 33 additions & 9 deletions script/DeployProdV4_0_1_1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ import {LibStoxDeployNetworks} from "../src/lib/LibStoxDeployNetworks.sol";
/// suite.
error UnknownDeploymentSuite(bytes32 suite);

/// @dev Error thrown when the DEPLOYMENT_NETWORK env var does not match any
/// supported bootstrap network.
error UnknownDeploymentNetwork(string network);

// One suite per contract to avoid Zoltu factory nonce issues.
//
// This script ships the audited 0.1.1 production set to Ethereum mainnet only.
// Unlike `script/Deploy.sol`, which deploys the CURRENT source (the 0.1.3 pins)
// This script ships the audited 0.1.1 production set to one bootstrap network
// per dispatch, selected by `DEPLOYMENT_NETWORK`. Unlike
// `script/Deploy.sol`, which deploys the CURRENT source (the 0.1.3 pins)
// to `LibStoxDeployNetworks.supportedNetworks()`, each suite here deploys the
// stored `LibProdDeployV4.*_CREATION_CODE_0_1_1` bytecode — the exact bytes the
// 0.1.1 audit covers — and asserts against the `_0_1_1` address/codehash pins.
Expand All @@ -42,8 +47,9 @@ bytes32 constant DEPLOYMENT_SUITE_STOX_OFFCHAIN_ASSET_RECEIPT_VAULT_PAYMENT_MINT
bytes32 constant DEPLOYMENT_SUITE_STOX_CORPORATE_ACTIONS_FACET = keccak256("stox-corporate-actions-facet");

contract Deploy is Script {
/// @dev Broadcasts a single contract via the Zoltu deterministic deployer on
/// Ethereum mainnet. Reads `DEPLOYMENT_KEY` from the environment, logs
/// @dev Broadcasts a single contract via the Zoltu deterministic deployer
/// on the selected bootstrap network. Reads `DEPLOYMENT_KEY` from the
/// environment, logs
/// diagnostic information (expected address, codehash, dependency state),
/// then delegates to `LibRainDeploy.deployAndBroadcast`.
/// @param creationCode The creation bytecode of the contract to deploy.
Expand All @@ -53,8 +59,8 @@ contract Deploy is Script {
/// to.
/// @param expectedCodeHash The expected codehash of the deployed runtime
/// bytecode.
/// @param dependencies Addresses of contracts that must already be deployed
/// on Ethereum before this contract is deployed.
/// @param dependencies Addresses of contracts that must already be
/// deployed on the selected network before this contract is deployed.
function deploySuite(
bytes memory creationCode,
string memory contractPath,
Expand All @@ -63,7 +69,7 @@ contract Deploy is Script {
address[] memory dependencies
) internal {
string[] memory networks = new string[](1);
networks[0] = LibStoxDeployNetworks.ETHEREUM;
networks[0] = bootstrapNetwork();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
uint256 deployerPrivateKey = vm.envUint("DEPLOYMENT_KEY");

console2.log("Suite deploying (0.1.1):", contractPath);
Expand Down Expand Up @@ -92,11 +98,29 @@ contract Deploy is Script {
);
}

/// @notice Entry point for the 0.1.1 Ethereum deployment script.
/// @notice The bootstrap network the suite broadcasts to, from the
/// `DEPLOYMENT_NETWORK` env var, validated against the supported set.
/// No default: an unset network reverts rather than silently picking a
/// chain.
/// @return network The validated `foundry.toml` rpc alias.
function bootstrapNetwork() internal view returns (string memory network) {
network = vm.envOr("DEPLOYMENT_NETWORK", string(""));
bytes32 networkHash = keccak256(bytes(network));
if (
networkHash != keccak256(bytes(LibStoxDeployNetworks.ETHEREUM))
&& networkHash != keccak256(bytes(LibStoxDeployNetworks.HYPEREVM))
) {
revert UnknownDeploymentNetwork(network);
}
}

/// @notice Entry point for the 0.1.1 bootstrap deployment script.
/// @dev Requires env vars:
/// - `DEPLOYMENT_KEY`: private key for the deployer account.
/// - `DEPLOYMENT_SUITE`: which contract to deploy (e.g. "stox-receipt").
/// One contract per run.
/// - `DEPLOYMENT_NETWORK`: bootstrap network to ship to — `ethereum` or
/// `hyperevm`.
function run() public {
bytes32 suite = keccak256(bytes(vm.envString("DEPLOYMENT_SUITE")));
address[] memory noDeps = new address[](0);
Expand All @@ -114,7 +138,7 @@ contract Deploy is Script {
// hardcoded corporate-actions facet, and a delegatecall to a
// code-less address silently no-ops — so the facet must already be
// on-chain. Declared as a dependency so LibRainDeploy reverts
// MissingDependency if the facet is not yet deployed on Ethereum.
// MissingDependency if the facet is not yet deployed on the network.
address[] memory deps = new address[](1);
deps[0] = LibProdDeployV4.STOX_CORPORATE_ACTIONS_FACET_0_1_1;
deploySuite(
Expand Down
8 changes: 8 additions & 0 deletions src/lib/LibStoxDeployNetworks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ library LibStoxDeployNetworks {
/// deploys work unchanged.
string internal constant ETHEREUM = "ethereum";

/// @notice HyperEVM mainnet network name, matching the `[rpc_endpoints]`
/// alias in `foundry.toml` (resolved from `HYPEREVM_RPC_URL`).
/// @dev The Zoltu factory is deployed on HyperEVM at the canonical
/// `LibRainDeploy.ZOLTU_FACTORY` address, so deterministic deploys work
/// unchanged. Not in `supportedNetworks()`: HyperEVM carries the audited
/// 0.1.1 set, not the current source `script/Deploy.sol` ships.
string internal constant HYPEREVM = "hyperevm";

/// @notice The networks each suite in `script/Deploy.sol` is broadcast to.
/// @return networks The list of network names (Base + Ethereum mainnet).
function supportedNetworks() internal pure returns (string[] memory networks) {
Expand Down
Loading