Feat/cross chain usdc sushi bridge#131
Merged
Merged
Conversation
Add SushiSwapStampsRouter contract that swaps any Gnosis token → BZZ via SushiSwap V3 and atomically creates/tops up a Swarm stamp batch in a single transaction. Eliminates Relay dependency for same-chain swaps. - contracts/SushiSwapStampsRouter.sol: new router with single-hop, multi-hop (callback chaining), native xDAI support, and quote functions callable via eth_call - deploy/02_deploy_sushi_stamps_router.ts: deploy + auto-verify script (GnosisScan + Sourcify v2) - scripts/verify_router.ts, verify_registry.ts: standalone post-deploy verification scripts for both contracts - SushiQuotes.ts: frontend module for route discovery, quoting, and execution via the new router - constants.ts: add SUSHI_STAMPS_ROUTER_ADDRESS, SUSHI_FACTORY_ABI, SUSHI_STAMPS_ROUTER_ABI, GNOSIS_USDC_ADDRESS - SwapComponent.tsx: add Branch 2 (Gnosis + non-BZZ → SushiSwap); cross-chain traffic stays on Relay unchanged - hardhat.config.ts: enable viaIR and Sourcify v2 verification
The BZZ/USDC pool fee was hardcoded as 10000 (1%) which caused quoteSingleHop to revert because the Quoter looks up the pool via factory.getPool(tokenIn, BZZ, fee) — wrong fee = pool not found. - Read pool.fee() directly from the known pool address at runtime - Keep the pool address constant (BZZ_USDC_POOL_ADDRESS) but never assume the fee tier - Fall back to factory scan if the known address doesn't respond - Reorder FEE_TIERS to try 3000/500 before 10000 (more common tiers first) - Fix fee display: divide by 10000 not 100 (10000 bps = 1%, not 100%)
Two bugs in findSushiRoute broke non-BZZ Gnosis token routing: 1. ReferenceError: KNOWN_BZZ_POOLS reference was missed when renaming to bzzPoolCache in the previous commit — crashed immediately for any two-hop route (e.g. GBPe). 2. Case 3 (tokenIn → WXDAI → BZZ) used findWxdaiUsdcPool() for the tokenIn→WXDAI leg, which looked up a WXDAI/USDC pool instead of a tokenIn/WXDAI pool — completely wrong fee and path for any token that isn't USDC. - Replace findWxdaiUsdcPool() with generic findPoolBetween(tokenA, tokenB) that scans all fee tiers for any pair, with pair-keyed caching - Case 2: use findPoolBetween(tokenIn, USDC) + findDirectBzzPool(USDC) in parallel — both legs discovered correctly - Case 3: use findPoolBetween(tokenIn, WXDAI) + findDirectBzzPool(WXDAI) in parallel — both legs discovered correctly - Tokens like GBPe that route through WXDAI or USDC now work properly
The project tsconfig.json uses moduleResolution: bundler (Next.js), which ts-node can't handle, causing all `hardhat run scripts/*.ts` commands to fail with ERR_UNKNOWN_FILE_EXTENSION on Node 22. - Add tsconfig.hardhat.json with module: CommonJS / moduleResolution: node scoped to deploy/ and scripts/ only, leaving the Next.js tsconfig untouched - Set ts-node.project in package.json to point at the new tsconfig - Add npm scripts (verify:router, verify:registry, deploy:router) that set TS_NODE_PROJECT=tsconfig.hardhat.json automatically so plain `npm run verify:router` just works - Update script usage comments to show both the npm shortcut and the direct command with the required env var
- Filter Gnosis "from" tokens with findSushiRoute after LiFi balances; clear selection when nothing spendable remains. - Require V3 pool liquidity() > 0 in discovery so empty pools (e.g. COW/USDC) are not treated as routable; Quoter no longer reverts on those paths. - Add findSushiRoutes and try each candidate in getSushiQuote until a quote succeeds. - Export gnosisFromTokenCanReachBzz (BZZ direct or Sushi path to BZZ).
Relay has reliable routes to USDC on every major chain but poor BZZ
routes. The existing SushiSwapStampsRouter already handles any
Gnosis token→BZZ→stamp atomically.
New flow for cross-chain users:
1. Relay bridges source token → USDC on Gnosis (EXACT_OUTPUT)
2. Relay's Multicaller executes two destination txs atomically:
a. USDC.approve(sushiRouter, maxUsdcIn)
b. sushiRouter.createBatch / topUp(path, maxUsdcIn, bzzOut, ...)
3. SushiRouter swaps USDC → BZZ via SushiSwap V3 and calls registry
No new contract needed — the deployed SushiSwapStampsRouter already
supports any ERC-20 payer (Relay's Multicaller in this case).
Changes:
- constants.ts: add RELAY_BRIDGE_TOKEN_ON_GNOSIS (default USDC),
RELAY_BRIDGE_TOKEN_DECIMALS and RELAY_BRIDGE_TOKEN_SYMBOL —
all overridable via env vars for future flexibility.
- RelayQuotes.ts: add getRelayCrossChainWithSushiQuote() that
chains a Sushi quote (USDC→BZZ) with a Relay EXACT_OUTPUT quote
(source→USDC) and builds the two-tx calldata bundle for Relay.
- SwapComponent.tsx: price estimation and handleSwap Branch 3 now
use the new USDC+Sushi path when the router is deployed; legacy
Relay→BZZ path kept as fallback when router address is empty.
… bridging RELAY_BRIDGE_TOKEN_ON_GNOSIS was pointing at the old Ethereum-bridged USDC (0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83) which Relay cannot route to. Relay only has solver liquidity for the native Circle USDC on Gnosis (0x2a22f9c3b484c3629090feed35f17ff8f88f76f0). The SushiSwapStampsRouter still works because there is a Sushi V3 fee-100 pool between the two USDC tokens (liq ~2.4T) and the existing findSushiRoute logic already checks token → GNOSIS_USDC_ADDRESS (bridged) → BZZ, producing the two-hop path: native USDC → bridged USDC → BZZ. Verified manually: Relay accepts the small failing amount ($1.85) with the correct address from Base, Ethereum, Arbitrum, Optimism, and Polygon.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Added a new preferred path for cross-chain stamp purchases. Instead of asking Relay to bridge directly to BZZ (poor liquidity), the flow now bridges the source token to native Circle USDC on Gnosis via Relay, then atomically calls the SushiSwapStampsRouter (from PR #130) on the destination side to swap that USDC to BZZ and create/top-up the stamp — all in one Relay transaction bundle.