Skip to content

docs(dev4): R20 Task B — mainnet Uniswap swap runbook for Daniel - #460

Merged
B2JK-Industry merged 1 commit into
mainfrom
agent/dev4/r20-task-b-uniswap-runbook
May 3, 2026
Merged

docs(dev4): R20 Task B — mainnet Uniswap swap runbook for Daniel#460
B2JK-Industry merged 1 commit into
mainfrom
agent/dev4/r20-task-b-uniswap-runbook

Conversation

@B2JK-Industry

Copy link
Copy Markdown
Owner

Summary

Single-doc runbook for one live mainnet ETH→USDC swap via the SBO3L policy-guarded sbo3l uniswap swap --broadcast flow. The captured tx hash becomes the live evidence row in the Uniswap bounty submission.

Daniel-side workflow (~10 min)

Step Action Cost
0 Pre-flight: balance + dry-run quoter sanity $0
1 --dry-run to inspect quote + receipt + decision $0
2 --broadcast with SBO3L_ALLOW_MAINNET_TX=1 $8-15 gas
3 Etherscan + cast tx verify $0
4 Paste tx hash → I run 5-min follow-up PR

Total budget: 0.005 ETH swap + ~$15 gas = $25. Wallet has 0.014 ETH (~$50). Sufficient.

Includes

  • Pre-flight read-only checks (no gas)
  • Inspect-the-envelope step before broadcast
  • Troubleshooting matrix (5 common symptoms + fixes)
  • Explicit irreversibility warning
  • Post-swap PR follow-up plan (etherscan-link-pack + bounty narrative + memory)

Why this matters

Uniswap track jumps from "Sepolia demo" → "live mainnet activity at <tx-hash>." Pairs with the upstream Universal Router PR for the "proposed the pattern + shipped live" narrative.

🤖 Generated with Claude Code

Single-doc runbook for one live mainnet ETH→USDC swap via the
SBO3L policy-guarded `sbo3l uniswap swap --broadcast` flow. The
captured tx hash becomes the live evidence row in the Uniswap
bounty submission.

Steps (Daniel runs):
  STEP 0  pre-flight: verify wallet > 0.013 ETH + dry-run
          quoter sanity (~$0)
  STEP 1  --dry-run to inspect quote + signed receipt + decision
          (~$0)
  STEP 2  --broadcast with SBO3L_ALLOW_MAINNET_TX=1 (~$8-15 gas)
  STEP 3  Etherscan + cast verify
  STEP 4  paste tx hash to me; I run 5-min PR adding the row to
          etherscan-link-pack.md + bounty narrative + memory

Cost ceiling: 0.005 ETH swap input + ~$8-15 gas = $25 total
budget. Daniel's wallet has 0.014 ETH (~$50) — sufficient for
Task B + STEP 1+2 of Task A's mainnet OR deploy.

Includes troubleshooting matrix (5 common symptoms + fixes) and
explicit irreversibility warning — no rollback for a confirmed
mainnet swap; dry-run is the only mitigation.

Why this matters: Uniswap track jumps from "Sepolia demo" to
"live mainnet activity at <tx-hash>." Pairs with upstream
Universal Router PR (Uniswap/universal-router#477) for the
"proposed the pattern + shipped live" narrative.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@B2JK-Industry
B2JK-Industry enabled auto-merge (squash) May 3, 2026 07:35
@vercel

vercel Bot commented May 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sbo3l-ccip Ready Ready Preview, Comment May 3, 2026 7:37am
sbo3l-marketing Ready Ready Preview, Comment May 3, 2026 7:37am
sbo3l-playground-api Ready Ready Preview, Comment May 3, 2026 7:37am

Request Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a9181de1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +29 to +34
--network mainnet \
--amount-in 0.005ETH \
--token-out USDC \
--recipient "$DANIEL_WALLET" \
--rpc-url "$MAINNET_RPC_URL" \
--dry-run

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Set mainnet gate before any --network mainnet step

The pre-flight commands run sbo3l uniswap swap --network mainnet before exporting SBO3L_ALLOW_MAINNET_TX=1, but the CLI rejects all mainnet invocations (including dry-runs) without that env var. In cmd_uniswap_swap, the gate check runs before quoting/envelope generation, so Step 0/1 will fail immediately and the runbook cannot be followed as written.

Useful? React with 👍 / 👎.

Comment on lines +54 to +57
> /tmp/sbo3l-swap-envelope.json

# Inspect the envelope:
jq '.quote, .receipt.decision, .receipt.policy_hash' /tmp/sbo3l-swap-envelope.json

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Emit real envelope JSON before running jq checks

This step redirects stdout to a .json file and then queries .quote/.receipt.*, but sbo3l uniswap swap prints a human-readable summary to stdout and only writes JSON when --out is provided; additionally, the envelope schema uses top-level fields like amount_in_wei/amount_out_minimum and has no quote or receipt object. As written, the verification command fails (or returns nulls) and can let operators proceed to broadcast without validating the actual safety-critical envelope fields.

Useful? React with 👍 / 👎.

| `eth_chainId mismatch` | RPC chain id doesn't match `--network mainnet` | Verify `MAINNET_RPC_URL` actually returns `1` (`cast chain-id`) |
| `insufficient funds for gas * price + value` | Wallet ETH < 0.005 + gas | Top up before retry; pre-flight 0.1 should have caught this |
| Tx pending > 60s | Gas price too low for current congestion | Wait or bump gas via Etherscan's "Speed Up" UI |
| Swap output < quote minimum | Slippage on confirm > slippage tolerance | Tx will revert atomically; no funds lost (only gas). Retry with higher `--max-slippage-bps` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Replace unsupported slippage flag with the real CLI option

The troubleshooting guidance tells users to retry with --max-slippage-bps, but the Uniswap swap command exposes --slippage-bps (as documented by the clap args/tests). In a live incident this remediation path will fail at argument parsing, so users cannot apply the intended fix from this runbook.

Useful? React with 👍 / 👎.

@B2JK-Industry
B2JK-Industry merged commit b9906fc into main May 3, 2026
41 checks passed
@B2JK-Industry
B2JK-Industry deleted the agent/dev4/r20-task-b-uniswap-runbook branch May 3, 2026 07:38
B2JK-Industry added a commit that referenced this pull request May 3, 2026
…face (#474)

Three real bugs in docs/dev4/mainnet-uniswap-swap-runbook.md
caught by Codex on PR #460 (after merge). Each would fail
Daniel mid-flow if he tried to run the runbook as written.

Bug 1 (P1) — mainnet gate fires before quoter, even on --dry-run
=================================================================

The CLI rejects EVERY `--network mainnet` invocation (including
--dry-run quoter sanity calls) without `SBO3L_ALLOW_MAINNET_TX=1`.
The gate check is at uniswap_swap.rs:581, BEFORE the quoter
call at line 596+. So my STEP 0.2 + STEP 1 fail immediately at
the gate.

Fix: export `SBO3L_ALLOW_MAINNET_TX=1` at the top of STEP 0,
before any --network mainnet invocation, with an explanatory
comment about why it's needed even for dry-runs.

Bug 2 (P1) — stdout is human-readable, JSON requires --out
==========================================================

`sbo3l uniswap swap` prints a `key: value` summary to stdout via
`print_envelope`. JSON output requires `--out <path>` flag (see
uniswap_swap.rs:747-752). My runbook redirected stdout
(`> /tmp/envelope.json`) and ran jq against it — would fail
with "not valid JSON".

Also the envelope is FLAT — top-level keys `amount_in_wei`,
`expected_amount_out`, `amount_out_minimum`, `slippage_bps`,
`quote_source`, `deadline_unix` (see SwapEnvelope struct at
uniswap_swap.rs:516). My jq queries against
`.quote.input_amount` / `.receipt.decision` /
`.receipt.policy_hash` would all return null because no such
nested objects exist.

Fix: STEP 1 now uses `--out /tmp/sbo3l-swap-envelope.json`
explicitly. jq queries against actual top-level fields. Also
clarified that the dry-run envelope does NOT include a signed
receipt or `decision` — those live at the policy-engine layer
(separate flow); the envelope is pure swap calldata + quote
metadata. Daniel's policy decision happens by inspecting the
envelope and choosing whether to invoke `--broadcast`.

Bug 3 (P2) — wrong slippage flag name
======================================

Troubleshooting matrix said to retry with `--max-slippage-bps`,
but the CLI flag is `--slippage-bps` (see SwapArgs.slippage_bps
at uniswap_swap.rs:106). User in the slippage-revert incident
would hit "unknown argument" and be stuck.

Fix: renamed to `--slippage-bps` + added concrete bump example
("default 50 = 0.5%; bump to 100 for 1%").

Two trailing prose references ("Token Transferred: USDC ≥
quote.output_amount_minimum", "increased by ≥
quote.output_amount_minimum") also fixed to use the actual
field name `amount_out_minimum`.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant