fix: address review feedback on mainnet-bootstrap runbook (#728)

- docs/mainnet-bootstrap.md: fix Step 4c to use SwapRouter02 7-field
  struct (no deadline field); the 8-field ABI was for SwapRouter v1 but
  the address is SwapRouter02
- docs/mainnet-bootstrap.md: correct Step 1 to no longer falsely claim
  that pre-bootstrap transactions succeed when Forge aborts on simulation
  failure; Step 1 now reflects the try/catch behaviour added below
- docs/mainnet-bootstrap.md: Step 6 drops --private-key flag (Foundry
  ignores it when vm.startBroadcast(privateKey) is called internally)
  and documents that the .secret seed-phrase file must be present
- docs/mainnet-bootstrap.md: remove no-op `export LM_ADDRESS="$LM_ADDRESS"`
- docs/mainnet-bootstrap.md: cite exact line range (101-145) in
  Troubleshooting workaround instead of informal marker description
- onchain/script/DeployBase.sol: wrap liquidityManager.recenter() and
  seed buy in try/catch so a fresh-pool TWAP revert skips the inline
  bootstrap with a warning rather than aborting the entire simulation
- onchain/script/DeployBase.sol: fix --fork-url to --rpc-url in the
  post-deploy console.log hint

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-14 18:35:48 +00:00
parent 973caff062
commit 4d16a51650
2 changed files with 28 additions and 21 deletions

View file

@ -128,17 +128,24 @@ contract DeployBase is Script {
console.log("feeDestination set to", feeDest);
// Step 2: Fund LM and place initial bootstrap positions.
// NOTE: recenter() requires TWAP history (>= 300s since pool init).
// On Base mainnet this call will revert if the pool is too fresh.
// recenter() requires TWAP history (>= 300s since pool init).
// On a fresh mainnet pool this will revert; the try/catch allows the
// deploy to succeed and the operator completes the bootstrap manually
// by following docs/mainnet-bootstrap.md.
(bool funded,) = address(liquidityManager).call{ value: SEED_LM_ETH }("");
require(funded, "Failed to fund LM for seed bootstrap");
liquidityManager.recenter();
console.log("First recenter complete -> positions placed, cumulativeVolume still 0");
try liquidityManager.recenter() {
console.log("First recenter complete -> positions placed, cumulativeVolume still 0");
// Step 3: Seed buy -> generates a non-zero fee in the anchor position.
SeedSwapper seedSwapper = new SeedSwapper(weth, address(pool), token0isWeth);
seedSwapper.executeSeedBuy{ value: SEED_SWAP_ETH }(sender);
console.log("Seed buy executed -> fee generated in anchor position");
// Step 3: Seed buy -> generates a non-zero fee in the anchor position.
SeedSwapper seedSwapper = new SeedSwapper(weth, address(pool), token0isWeth);
seedSwapper.executeSeedBuy{ value: SEED_SWAP_ETH }(sender);
console.log("Seed buy executed -> fee generated in anchor position");
} catch {
console.log("WARNING: recenter() reverted - inline bootstrap skipped.");
console.log(" Pool likely has < 300 s of TWAP history.");
console.log(" Follow docs/mainnet-bootstrap.md (Phase 2 steps) to complete.");
}
// Step 4: Second recenter records VWAP (bootstrap path + ethFee > 0).
// Cannot be called in the same Forge broadcast as Step 2 recenter() enforces a
@ -153,7 +160,7 @@ contract DeployBase is Script {
console.log("Optimizer:", optimizerAddress);
console.log("\nPost-deploy steps:");
console.log(" 1. Wait >= 60 s after this script finishes.");
console.log(" 2. Run: forge script script/BootstrapVWAPPhase2.s.sol --tc BootstrapVWAPPhase2 --fork-url <RPC> --broadcast");
console.log(" 2. Run: forge script script/BootstrapVWAPPhase2.s.sol --tc BootstrapVWAPPhase2 --rpc-url <RPC> --broadcast");
console.log(" This performs the second recenter that records cumulativeVolume > 0.");
console.log(" 3. Fund LiquidityManager with operational ETH.");
console.log(" 4. recenter() is permissionless - any address (e.g. txnBot) can call it.");