From 9632693b8a8d57fc8685dbfa319dbf0764d94124 Mon Sep 17 00:00:00 2001 From: openhands Date: Thu, 19 Mar 2026 00:03:59 +0000 Subject: [PATCH 1/3] fix: BootstrapVWAPPhase2.s.sol hardcodes .secret file dependency (#769) Check PRIVATE_KEY env var first in BootstrapVWAPPhase2.s.sol, DeployBase.sol, and BaseDeploy.sol; fall back to .secret seed-phrase file when unset. This allows CI/CD environments to inject keys via environment variables while preserving the existing local .secret workflow unchanged. Co-Authored-By: Claude Sonnet 4.6 --- onchain/script/BaseDeploy.sol | 7 +++++-- onchain/script/BootstrapVWAPPhase2.s.sol | 15 +++++++++++++-- onchain/script/DeployBase.sol | 7 +++++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/onchain/script/BaseDeploy.sol b/onchain/script/BaseDeploy.sol index e8191b9..8748f22 100644 --- a/onchain/script/BaseDeploy.sol +++ b/onchain/script/BaseDeploy.sol @@ -5,8 +5,11 @@ import "forge-std/Script.sol"; contract BaseDeploy is Script { function run() public view { // Base data - string memory seedPhrase = vm.readFile(".secret"); - uint256 privateKey = vm.deriveKey(seedPhrase, 0); + uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); + if (privateKey == 0) { + string memory seedPhrase = vm.readFile(".secret"); + privateKey = vm.deriveKey(seedPhrase, 0); + } address sender = vm.addr(privateKey); console.log(sender); } diff --git a/onchain/script/BootstrapVWAPPhase2.s.sol b/onchain/script/BootstrapVWAPPhase2.s.sol index dcd7f0d..d33953f 100644 --- a/onchain/script/BootstrapVWAPPhase2.s.sol +++ b/onchain/script/BootstrapVWAPPhase2.s.sol @@ -20,6 +20,14 @@ import "forge-std/Script.sol"; * * Usage: * export LM_ADDRESS= + * + * # Option A — env-var key (CI/CD): + * export PRIVATE_KEY=0x + * forge script script/BootstrapVWAPPhase2.s.sol --tc BootstrapVWAPPhase2 \ + * --fork-url $BASE_RPC --broadcast + * + * # Option B — .secret seed-phrase file (local): + * echo "" > .secret * forge script script/BootstrapVWAPPhase2.s.sol --tc BootstrapVWAPPhase2 \ * --fork-url $BASE_RPC --broadcast */ @@ -28,8 +36,11 @@ contract BootstrapVWAPPhase2 is Script { address lmAddress = vm.envAddress("LM_ADDRESS"); LiquidityManager lm = LiquidityManager(payable(lmAddress)); - string memory seedPhrase = vm.readFile(".secret"); - uint256 privateKey = vm.deriveKey(seedPhrase, 0); + uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); + if (privateKey == 0) { + string memory seedPhrase = vm.readFile(".secret"); + privateKey = vm.deriveKey(seedPhrase, 0); + } vm.startBroadcast(privateKey); console.log("Running VWAP bootstrap phase 2 on LiquidityManager:", lmAddress); diff --git a/onchain/script/DeployBase.sol b/onchain/script/DeployBase.sol index 8f66cdf..dc76f5f 100644 --- a/onchain/script/DeployBase.sol +++ b/onchain/script/DeployBase.sol @@ -37,8 +37,11 @@ contract DeployBase is Script { IUniswapV3Pool public pool; function run() public { - string memory seedPhrase = vm.readFile(".secret"); - uint256 privateKey = vm.deriveKey(seedPhrase, 0); + uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); + if (privateKey == 0) { + string memory seedPhrase = vm.readFile(".secret"); + privateKey = vm.deriveKey(seedPhrase, 0); + } vm.startBroadcast(privateKey); address sender = vm.addr(privateKey); From db6abda17e4cb67d9f187979e018d0030d5fddd3 Mon Sep 17 00:00:00 2001 From: openhands Date: Thu, 19 Mar 2026 00:26:04 +0000 Subject: [PATCH 2/3] fix: address review feedback for #769 - Apply PRIVATE_KEY env-var fallback to UpgradeOptimizer.sol (missed in first pass) - Add comment on zero-sentinel silent-fallback behaviour in all four scripts - Remove spurious view modifier from BaseDeploy.run() (violated by vm.readFile) Co-Authored-By: Claude Sonnet 4.6 --- onchain/script/BaseDeploy.sol | 3 ++- onchain/script/BootstrapVWAPPhase2.s.sol | 1 + onchain/script/DeployBase.sol | 1 + onchain/script/UpgradeOptimizer.sol | 12 ++++++++++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/onchain/script/BaseDeploy.sol b/onchain/script/BaseDeploy.sol index 8748f22..9779dfb 100644 --- a/onchain/script/BaseDeploy.sol +++ b/onchain/script/BaseDeploy.sol @@ -3,8 +3,9 @@ pragma solidity ^0.8.19; import "forge-std/Script.sol"; contract BaseDeploy is Script { - function run() public view { + function run() public { // Base data + // PRIVATE_KEY=0 / empty silently falls back to .secret (0 is an invalid secp256k1 key). uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); if (privateKey == 0) { string memory seedPhrase = vm.readFile(".secret"); diff --git a/onchain/script/BootstrapVWAPPhase2.s.sol b/onchain/script/BootstrapVWAPPhase2.s.sol index d33953f..566cdd2 100644 --- a/onchain/script/BootstrapVWAPPhase2.s.sol +++ b/onchain/script/BootstrapVWAPPhase2.s.sol @@ -36,6 +36,7 @@ contract BootstrapVWAPPhase2 is Script { address lmAddress = vm.envAddress("LM_ADDRESS"); LiquidityManager lm = LiquidityManager(payable(lmAddress)); + // PRIVATE_KEY=0 / empty silently falls back to .secret (0 is an invalid secp256k1 key). uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); if (privateKey == 0) { string memory seedPhrase = vm.readFile(".secret"); diff --git a/onchain/script/DeployBase.sol b/onchain/script/DeployBase.sol index dc76f5f..3078d45 100644 --- a/onchain/script/DeployBase.sol +++ b/onchain/script/DeployBase.sol @@ -37,6 +37,7 @@ contract DeployBase is Script { IUniswapV3Pool public pool; function run() public { + // PRIVATE_KEY=0 / empty silently falls back to .secret (0 is an invalid secp256k1 key). uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); if (privateKey == 0) { string memory seedPhrase = vm.readFile(".secret"); diff --git a/onchain/script/UpgradeOptimizer.sol b/onchain/script/UpgradeOptimizer.sol index fc09284..39fe192 100644 --- a/onchain/script/UpgradeOptimizer.sol +++ b/onchain/script/UpgradeOptimizer.sol @@ -12,6 +12,10 @@ import "forge-std/Script.sol"; * OPTIMIZER_PROXY=0x... forge script script/UpgradeOptimizer.sol \ * --rpc-url --broadcast * + * Key injection (checked in order): + * 1. PRIVATE_KEY env var (hex private key — for CI/CD) + * 2. .secret file (BIP-39 seed phrase — for local use) + * * The caller must be the proxy admin (the address that called initialize()). */ contract UpgradeOptimizer is Script { @@ -19,8 +23,12 @@ contract UpgradeOptimizer is Script { address proxyAddress = vm.envAddress("OPTIMIZER_PROXY"); require(proxyAddress != address(0), "OPTIMIZER_PROXY env var required"); - string memory seedPhrase = vm.readFile(".secret"); - uint256 privateKey = vm.deriveKey(seedPhrase, 0); + // PRIVATE_KEY=0 / empty silently falls back to .secret (0 is an invalid secp256k1 key). + uint256 privateKey = vm.envOr("PRIVATE_KEY", uint256(0)); + if (privateKey == 0) { + string memory seedPhrase = vm.readFile(".secret"); + privateKey = vm.deriveKey(seedPhrase, 0); + } vm.startBroadcast(privateKey); address sender = vm.addr(privateKey); From 16af093e993415b62082914d9aa0bf903676da48 Mon Sep 17 00:00:00 2001 From: openhands Date: Thu, 19 Mar 2026 00:36:37 +0000 Subject: [PATCH 3/3] ci: retrigger after infra failure (#769)