From f55eaae230e243d9e6c0e5012d2e37b5c9aee12a Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 14 Mar 2026 07:28:27 +0000 Subject: [PATCH 1/3] fix: ENVIRONMENT.md describes Anvil as Base Sepolia but backtesting scripts use Base mainnet addresses (#729) - Clarify that the dev Anvil defaults to Base Sepolia but can be overridden with FORK_URL (confirmed from containers/anvil-entrypoint.sh) - Add "Network Contexts" section distinguishing three distinct Anvil usages: 1. Dev stack Anvil (docker-compose): Base Sepolia by default 2. red-team.sh: requires FORK_URL=mainnet because it uses Base mainnet periphery addresses (V3_FACTORY, SwapRouter02, NPM) 3. FitnessEvaluator.t.sol: independent mainnet fork via BASE_RPC_URL, unrelated to the docker-compose stack Co-Authored-By: Claude Sonnet 4.6 --- docs/ENVIRONMENT.md | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 11bd220..cee577a 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -8,7 +8,7 @@ Docker Compose services (in startup order): | Service | Purpose | Port | Health Check | |---------|---------|------|-------------| -| **anvil** | Local Ethereum fork (Base Sepolia) | 8545 | JSON-RPC response | +| **anvil** | Local Ethereum fork (Base Sepolia by default; override with `FORK_URL`) | 8545 | JSON-RPC response | | **postgres** | Ponder database | 5432 | pg_isready | | **bootstrap** | Deploys contracts to anvil | — | One-shot, exits 0 | | **ponder** | On-chain indexer + GraphQL API | 42069 | HTTP /ready or GraphQL | @@ -18,6 +18,44 @@ Docker Compose services (in startup order): | **caddy** | Reverse proxy / TLS | 80/443 | — | | **otterscan** | Block explorer | 5100 | — | +## Network Contexts + +Two distinct Anvil contexts are in use; they target different networks. + +### Dev stack Anvil (docker-compose) + +The `anvil` service in `docker-compose.yml` runs `containers/anvil-entrypoint.sh`, which forks: + +``` +${FORK_URL:-https://sepolia.base.org} +``` + +**Default: Base Sepolia.** Uniswap V3 contracts are re-deployed fresh by the `bootstrap` service at start-up, so the fork target only affects block history and chain-id context. The bootstrap deploys all protocol contracts (Kraiken, Stake, LiquidityManager, OptimizerProxy) at addresses written to `tmp/containers/contracts.env`. + +To fork Base mainnet instead (required for red-team / backtesting — see below): + +```bash +FORK_URL=https://mainnet.base.org docker compose up -d +``` + +### Backtesting / red-team Anvil (`scripts/harb-evaluator/red-team.sh`) + +`red-team.sh` boots the docker-compose stack and then calls protocol operations using **Base mainnet** addresses for the Uniswap V3 periphery (V3_FACTORY, SwapRouter02, NonfungiblePositionManager). These addresses are only valid on a mainnet fork. Before running red-team.sh, set: + +```bash +export FORK_URL=https://mainnet.base.org +``` + +### FitnessEvaluator (`onchain/test/FitnessEvaluator.t.sol`) + +`FitnessEvaluator.t.sol` is completely independent of the dev Anvil. It forks Base mainnet once per `forge test` run using the `BASE_RPC_URL` environment variable and has no relationship to the docker-compose stack: + +```bash +BASE_RPC_URL=https://mainnet.base.org \ +FITNESS_MANIFEST_DIR=/tmp/manifest \ +forge test --match-contract FitnessEvaluator -vv +``` + ## Quick Start ```bash From 5b4e867c4bfe4953bd49b6dcd17d03771475978c Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 14 Mar 2026 08:10:40 +0000 Subject: [PATCH 2/3] fix: address AI review feedback on ENVIRONMENT.md Network Contexts section - Fix factual error: bootstrap deploys KRAIKEN protocol contracts and uses the existing V3 Factory; it does not re-deploy Uniswap V3 infrastructure - Fix count/characterisation: intro now says "two network contexts" (dev Anvil + backtesting tools) and clarifies FitnessEvaluator uses revm in-process, not Anvil - Fix sudo env-stripping hazard: replace bare `export FORK_URL` instruction with `FORK_URL=... sudo -E bash red-team.sh` so the variable is not silently dropped by sudo - Nit: add --match-test testBatchEvaluate to the FitnessEvaluator example to match the test file's own documented usage Co-Authored-By: Claude Sonnet 4.6 --- docs/ENVIRONMENT.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index cee577a..3d2dcfa 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -20,7 +20,7 @@ Docker Compose services (in startup order): ## Network Contexts -Two distinct Anvil contexts are in use; they target different networks. +Two network contexts are relevant: the dev-stack Anvil (docker-compose) and the backtesting tools that require Base mainnet. ### Dev stack Anvil (docker-compose) @@ -30,7 +30,7 @@ The `anvil` service in `docker-compose.yml` runs `containers/anvil-entrypoint.sh ${FORK_URL:-https://sepolia.base.org} ``` -**Default: Base Sepolia.** Uniswap V3 contracts are re-deployed fresh by the `bootstrap` service at start-up, so the fork target only affects block history and chain-id context. The bootstrap deploys all protocol contracts (Kraiken, Stake, LiquidityManager, OptimizerProxy) at addresses written to `tmp/containers/contracts.env`. +**Default: Base Sepolia.** The `bootstrap` service deploys all KRAIKEN protocol contracts (Kraiken, Stake, Optimizer, LiquidityManager) and creates a new KRK/WETH pool using the existing Uniswap V3 Factory already present on the forked network. Addresses are written to `tmp/containers/contracts.env`. To fork Base mainnet instead (required for red-team / backtesting — see below): @@ -38,22 +38,24 @@ To fork Base mainnet instead (required for red-team / backtesting — see below) FORK_URL=https://mainnet.base.org docker compose up -d ``` -### Backtesting / red-team Anvil (`scripts/harb-evaluator/red-team.sh`) +### Backtesting / red-team (`scripts/harb-evaluator/red-team.sh`) -`red-team.sh` boots the docker-compose stack and then calls protocol operations using **Base mainnet** addresses for the Uniswap V3 periphery (V3_FACTORY, SwapRouter02, NonfungiblePositionManager). These addresses are only valid on a mainnet fork. Before running red-team.sh, set: +`red-team.sh` boots the docker-compose stack and then calls protocol operations using **Base mainnet** addresses for the Uniswap V3 periphery (V3_FACTORY, SwapRouter02, NonfungiblePositionManager). These addresses are only valid on a mainnet fork. + +`red-team.sh` calls `sudo docker compose up -d` internally, and `sudo` strips environment variables by default. Pass `FORK_URL` inline with `-E` to preserve it: ```bash -export FORK_URL=https://mainnet.base.org +FORK_URL=https://mainnet.base.org sudo -E bash scripts/harb-evaluator/red-team.sh ``` ### FitnessEvaluator (`onchain/test/FitnessEvaluator.t.sol`) -`FitnessEvaluator.t.sol` is completely independent of the dev Anvil. It forks Base mainnet once per `forge test` run using the `BASE_RPC_URL` environment variable and has no relationship to the docker-compose stack: +`FitnessEvaluator.t.sol` does **not** use Anvil. It uses Foundry's native revm backend (`vm.createSelectFork`) to fork Base mainnet in-process — no docker-compose dependency: ```bash BASE_RPC_URL=https://mainnet.base.org \ FITNESS_MANIFEST_DIR=/tmp/manifest \ -forge test --match-contract FitnessEvaluator -vv +forge test --match-contract FitnessEvaluator --match-test testBatchEvaluate -vv ``` ## Quick Start From 52ed8ef233c73ef0b8d9ed730eb917e40f17f44f Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 14 Mar 2026 08:30:49 +0000 Subject: [PATCH 3/3] fix: red-team.sh sudo strips FORK_URL before docker compose sees it (#729) red-team.sh called bare `sudo docker compose up/down` which applies env_reset and drops FORK_URL before anvil-entrypoint.sh can read it. Change both calls to `sudo -E` so the caller's FORK_URL override is propagated to docker-compose and into the anvil container. Update ENVIRONMENT.md to reflect that a plain `FORK_URL=... bash red-team.sh` invocation now works correctly. Co-Authored-By: Claude Sonnet 4.6 --- docs/ENVIRONMENT.md | 4 ++-- scripts/harb-evaluator/red-team.sh | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 3d2dcfa..2340696 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -42,10 +42,10 @@ FORK_URL=https://mainnet.base.org docker compose up -d `red-team.sh` boots the docker-compose stack and then calls protocol operations using **Base mainnet** addresses for the Uniswap V3 periphery (V3_FACTORY, SwapRouter02, NonfungiblePositionManager). These addresses are only valid on a mainnet fork. -`red-team.sh` calls `sudo docker compose up -d` internally, and `sudo` strips environment variables by default. Pass `FORK_URL` inline with `-E` to preserve it: +`red-team.sh` calls `sudo docker compose up -d` internally. The script uses `sudo -E` so that `FORK_URL` is preserved across the sudo boundary: ```bash -FORK_URL=https://mainnet.base.org sudo -E bash scripts/harb-evaluator/red-team.sh +FORK_URL=https://mainnet.base.org bash scripts/harb-evaluator/red-team.sh ``` ### FitnessEvaluator (`onchain/test/FitnessEvaluator.t.sol`) diff --git a/scripts/harb-evaluator/red-team.sh b/scripts/harb-evaluator/red-team.sh index 8b51d81..9d8e784 100755 --- a/scripts/harb-evaluator/red-team.sh +++ b/scripts/harb-evaluator/red-team.sh @@ -63,11 +63,13 @@ cd "$REPO_ROOT" sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches' 2>/dev/null || true # Tear down completely (volumes too — clean anvil state) -sudo docker compose down -v >/dev/null 2>&1 || true +sudo -E docker compose down -v >/dev/null 2>&1 || true sleep 3 # Bring up -sudo docker compose up -d >/dev/null 2>&1 \ +# -E preserves FORK_URL (and other env vars) across the sudo boundary so that +# anvil-entrypoint.sh honours the caller's FORK_URL override. +sudo -E docker compose up -d >/dev/null 2>&1 \ || die "docker compose up -d failed" # Wait for bootstrap to complete (max 120s)