Repository navigation
feat: uniswap-trading AI-agent skill (D3 skeleton) - #478
TimeToBuildBob wants to merge 7 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #478 +/- ##
=======================================
Coverage 70.61% 70.61%
=======================================
Files 14 14
Lines 4302 4302
=======================================
Hits 3038 3038
Misses 1264 1264 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Greptile SummaryThe PR adds an agent-oriented Uniswap trading skill with a subprocess CLI, safety gates, documentation, an offline test suite, and a Sepolia demo scaffold.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the current balance path rejects absent, malformed, and zero wallet addresses before constructing the client. Important Files Changed
Reviews (3): Last reviewed commit: "fix(skill): validate balance wallet addr..." | Re-trigger Greptile |
|
@greptileai review |
|
@greptileai review |
CI failure analysis (session b7c3)The 3 failing tests are pre-existing failures unrelated to this PR: Root cause: Evidence these are pre-existing:
Suggested fix: Mark these v1 ETH-UNI output price tests with |
|
Folded in corrections from a cross-agent dogfood round (Gordon, a trading-focused agent on our infra, ran the branch end-to-end: clean install, all tests passing, working mainnet v3/v4 quotes plus Polygon v3 quoting on the 0.05% WETH/USDC.e pool — and plans to replace ~150 LOC of his own swap tooling with this once released):
Tests 18 → 28; verified live against public RPCs (mainnet quote with human fields, Sepolia refusal, single-arm broadcast refusal). The dogfood run itself doubles as early adoption evidence for the D3 baseline: two independent agent integrations (gptme, plus Gordon's trading stack) across two chains. |
|
Follow-up for the red |
3bcc0c2 to
c5f495f
Compare
Agent-facing integration surface for uniswap-python: an Anthropic-format SKILL.md plus a subprocess CLI (quote/swap/balance/approve/status) with JSON output and safety gates (dry-run by default, testnet-only broadcast, slippage ceiling). Offline tests for the gates; demo script verified live against mainnet v3+v4 quoters via public RPCs. Groundwork for UF grant deliverable D3 (AI-agent integration + testnet demo). Sepolia broadcast is blocked on library-side Sepolia enablement — documented in the README with the official v4 Sepolia addresses. Co-Authored-By: Bob <[email protected]> Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Four corrections from Gordon's dogfood run (trading-agent perspective): - Human-readable amounts: quote/swap/balance outputs now carry advisory <field>_human + decimals_<field> companions (best-effort ERC-20 decimals; omitted, never fatal, when the lookup fails) - Deterministic v3-testnet refusal: v3 on testnets exits 2 (safety, don't retry) instead of surfacing the library's mainnet-hardcoded contracts as a retryable-looking runtime error - Setup docs install from the PR branch until a release contains the skill - Non-testnet broadcast is now double-armed: UNISWAP_AGENT_ALLOW_MAINNET=1 (operator standing decision) AND --allow-mainnet (per-call confirmation) Tests 18 -> 28; verified live: mainnet quote with human fields, Sepolia v3 refusal, single-arm mainnet broadcast refused. Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
c5f495f to
2cdf77f
Compare
|
Rebased onto current master (post-#491). The five CI/test-fix commits that used to sit under the skill were #479's content and are superseded by #491, so this PR now carries only the five skill commits: |
…reset Git-Session-Id: 4dfa6bdf-a702-43e1-b0bf-4a7e07461cdb
v4 uses deprecated Node.js 20 (forced to Node.js 24 in recent runners) which causes intermittent upload failures that block otherwise-green CI. v5 is the supported release. fail_ci_if_error=false: coverage upload is instrumentation, not a correctness gate — transient Codecov outages should not fail the test run. Git-Session-Id: 80b13aa8-1c0d-4abb-82f2-2eda9d90539b
Sepolia failure list (from running the demo against a real Sepolia fork)Per the "Known gap" section above, here is the concrete list of where the Sepolia path fails, reproduced empirically. This is the scope for the library PR. Setup: 1. v4 is hard-blocked on chain 11155111.
2. The existing position_descriptor_address = _position_descriptor_contract_addresses_v4[self.net_name]
reserves_lens_address = _reserves_lens_contract_addresses_v4[self.net_name]A 3. v3 uses mainnet addresses on every chain. 4. Sepolia does have a real v3 deployment — the fix is per-chain addresses, not a new deployment:
( 5. A v4 Sepolia swap additionally needs a live pool. Also: Scope for the library PR
OwnershipI have not opened the library PR for this. The grant notes list Sepolia enablement as D2-adjacent (Yohan's) work, and the two optional-contract choices in (3) are design calls in that area — so this should be picked up by Yohan with Erik reviewing, rather than landing as a parallel branch. Flagging here so the scope is not rediscovered. @liquid-8 @ErikBjare — is the library PR yours, and should I rebase this skill PR onto it once it lands? (For reference, the full write-up with commands and receipts is in Bob's workspace: |
|
One correction/addition to the scope above: the v3 Quoter on Sepolia is still unlocated.
So scope item 2 is not fully specified until that one address is found. Anyone with the Sepolia v3 deployment artifact (a Uniswap interface config, or a v3-periphery deployment JSON for chain 11155111) can close it in a minute — happy to do it myself if you point me at one. |
|
Follow-up: the quoter gap is closed, and it turned up a second library requirement I didn't have before. Full Sepolia v3 deployment (found by walking the factory's deployer
Second finding: Sepolia runs QuoterV2, the library ships the v1 quoter ABI. Verified against the Sepolia fork: the v2 struct call returns a real quote. QuoterV2 quote 0.001 WETH -> USDC (fee 3000) = 49735253 (49.73 USDC)Revised final scope for the library PR (6 items):
Items 1–5 are enough for a working v3 Sepolia tx demo. Item 6 is only needed for v4. Still my question from the previous comment: is the library PR yours (@liquid-8) with @ErikBjare reviewing, or should I take it? Say the word and I'll implement all five and rebase this PR onto it. |
Root cause found: the Sepolia router is an early v3-periphery SwapRouter02 — and the v3 swap now worksTwo follow-ups to the scope above. The first is a root cause for the swap revert; the second changes the scope from 6 items to 7. 1. The swap revert was a selector mismatch, not a pool problemThe revert signature was the clue: empty revert data, no sub-calls at all, tiny gas. That is a call that matched no function and fell through to the fallback — not a swap that failed. Checked against the deployed bytecode of
The verified source explains it: Sepolia's only v3 router is the early v3-periphery struct ExactInputSingleParams {
address tokenIn; address tokenOut; uint24 fee; address recipient;
uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96;
} // 7 fields — vs. the modern 8-field struct with `deadline`The library ships the modern 8-field ABI ( Also visible in the verified function list, consistent with the early release: Correction to my earlier note: the "degenerate pool reserves" theory was wrong. The fee-3000 WETH/USDC pool 2. The v3 Sepolia swap is now provenCalling the early 7-field eth_call → amountOut = 49735064 (49.7351 USDC)
tx → 0xf51c7019e9b1bd26d54653fa35276b2dda4bca4492a91961e52923bead539a23
status 1, gasUsed 123072
acct USDC → 249,735,064 (200,000,000 before + 49,735,064 received)So: address + QuoterV2 + early router ABI → the v3 Sepolia swap works. The only thing still missing for a real Sepolia tx hash is a funded key (no faucet ETH reachable from here). 3. Scope item 7 — the library needs per-chain router ABI selection, not just per-chain addressesOne ABI cannot serve both chains, because the selector differs and the wrong one silently falls through to the fallback:
This is the same defect class as the QuoterV2 finding: the library hardcodes one chain's ABI, and Sepolia runs different versions of both the quoter and the router. Items 5 and 7 together mean the library cannot speak to Sepolia without a per-chain ABI selection mechanism. Final scope: 7 items (v4 map entries; chain-dependent v3 addresses; optional Ownership question still stands: is the library PR yours (Yohan) or mine? I've deliberately not opened one. Happy to implement all 7 items if it's mine — the scope is now fully specified with receipts. |
What
Skeleton for the AI-agent integration (grant deliverable D3): a `skills/uniswap-trading/` directory containing
Verified
Known gap (for the Sepolia tx demo)
The testnet demo can't broadcast yet because v0.8.0 has no Sepolia path:
That enablement is D2-adjacent library work — leaving it out of this PR deliberately.
Status
Draft skeleton for @liquid-8 to take over, extend, or rewrite as part of the funded D3 work — no attachment to any of it. TODO list in `skills/uniswap-trading/README.md`.