Repository navigation
feat(debridge): add tracker; never count treasury swap output as fees - #42
Conversation
…nd DlnSource deBridge pays our affiliate fee on the sell chain to the per-chain treasury: same-chain swaps through DeBridgeRouter during the swap, cross-chain DLN orders through DlnSource when the order is unlocked. Its stats API can't attribute either (no affiliate-recipient filter, no same-chain list endpoint), so scan the 8 unchained treasuries for transfers from those two contracts. Maps the deBridge swapper for partner reconciliation and registers the service in the dashboard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…vices Same-chain deBridge fees arrive in the buy token (verified on-chain), not the sell token. Service colors now come from each swapper's logo, or its site's accent where the logo is too dark for the dashboard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… revenue Same-chain: skip any tx in which the treasury spends (nonzero token out, net native out, or sends the tx), since swap output can only land in the same tx the treasury paid for it. Native is judged on net flow because some Safes forward each receipt to their singleton. Cross-chain: trackers can pass isOwnSwap, checked only on txs that pay a fee. Across uses it to skip fills whose FilledRelay depositor is a DAO treasury, reading the receipt through a new getReceiptLogs on the log client. Verified against all four scanner trackers over full history (Across, CoW, deBridge, ButterSwap): row-for-row identical to before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A native payment from the treasury to a sender is a spend even when an inflow in the same tx nets it out (WETH unwrap logs no Transfer). - Compare token values as strings so a malformed NFT value can't throw. - Ignore undecodable logs that share the FilledRelay topic. - List every DAO treasury constant in DAO_TREASURIES. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p check Mocks unchained history across two pages and the Alchemy client, and checks that isOwnSwap runs only on fee txs, receives the scanner's client, and drops exactly the txs it flags, alongside the same-chain spend rule and the status/window filters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 49 minutes. View limit details
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Treasury fee classification apps/revenue-api/src/affiliateRevenue/utils/treasuryFees.ts, apps/revenue-api/src/affiliateRevenue/utils/evmLogClient.ts, apps/revenue-api/src/affiliateRevenue/across/*, apps/revenue-api/src/affiliateRevenue/constants.ts, apps/revenue-api/src/affiliateRevenue/utils/*test.ts |
The shared scanner identifies treasury-funded transactions and supports an optional isOwnSwap callback. Across checks receipt logs for FilledRelay events whose depositor matches a DAO treasury. Tests cover fee extraction, spend filtering, and Across fill detection. |
deBridge API collection and reconciliation apps/revenue-api/src/affiliateRevenue/debridge/*, apps/revenue-api/src/affiliateRevenue/index.ts, apps/revenue-api/src/affiliateRevenue/reconcileRevenue*, apps/revenue-api/src/types.ts |
The API fetches and enriches fees for configured deBridge chains and senders. The provider registry and service type include deBridge. Reconciliation uses the configured chain coverage, with tests for payable deductions and an unsupported chain. |
deBridge dashboard and provider listing README.md, apps/revenue-dashboard/src/constants/services.ts |
The README lists deBridge as a DEX provider. The dashboard adds its service label, color, and stack order. |
Priority:
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Feature
Sequence Diagram(s)
sequenceDiagram
participant providers
participant getFees
participant getCachedFees
participant USDPriceEnrichment
providers->>getFees: Request deBridge fees
getFees->>getCachedFees: Fetch fees for configured chains and senders
getCachedFees-->>getFees: Return per-chain fees
getFees->>USDPriceEnrichment: Enrich combined fees
USDPriceEnrichment-->>getFees: Return fees with USD prices
Possibly related PRs
- shapeshift/revenue-dashboard#41: Both changes modify shared treasury-fee classification and use the optional own-swap check.
Merge Risk: 
Minimal · previous review e1bb0
-
The change is mergeable after normal checks. Mixed Across batches can still omit some user fees, but no broader failure was established.
Pre-merge checks: 
5
-
Full details: Docstring Coverage
-
Explanation
No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 15 files. (1 skipped: 1 unsupported.)
-
Finishing Touches
-
📝 Generate docstrings
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
A rabbit checks the treasury flow,
Across logs reveal which fills to know.
DeBridge fees join the chain-wide sweep,
While dashboard labels mark their keep.
I nibble greens and hop away,
With tidy totals for the day.
Comment @coderabbitai help to get the list of available commands.
…ised fill Every handler payout happens inside a SpokePool fill, so a fee tx whose receipt has no fill event we can decode means Across changed its event. Skip it with a warning rather than risk counting a treasury bridge's output as a fee. The current SpokePool ABI still declares the address-typed FilledV3Relay, so decode it alongside FilledRelay. Full-history Across run: 201 -> 201 fees, no warnings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds a deBridge tracker, and makes the shared treasury scanner never count the treasury's own swap or bridge output as fee revenue.
deBridge
0x663dc15d: same-chain swaps, paid in the buy token during the swap.0xef4fb24a: cross-chain orders, paid in the order's input token when a solver unlocks the order.deBridgeswapper for partner reconciliation. swap-service doesn't verify deBridge swaps yet, so no deBridge swap is netted today; the mapping is there for later.unclaimedAffiliateETHFees): 0.0006 ETH. They count once withdrawn.Treasury's own swaps (shared scanner: Across, CoW, ButterSwap, deBridge)
Swap output must never count as fee revenue. Fees on the treasury's own swaps are skipped along with the output.
isOwnSwap(txid, client)check runs only on transactions that paid a fee.eth_getTransactionReceipt, no traces) and skips fills whoseFilledRelaydepositor is a DAO treasury.FilledRelayand the olderFilledV3Relay. A fee transaction with no recognisable fill event is skipped with a warning, so a future Across event change costs a few fees instead of booking a bridge as revenue.Dashboard
Verification
tsc --noEmit, eslint andbun test: 137 pass.treasuryFees.test.ts,getTreasuryFees.test.ts(end to end over two mocked unchained pages, mutation-checked) andacross.test.ts(encodedFilledRelayandFilledV3Relayevents, plus the fail-safe).Follow-ups
SWAPPER_FEE_STRATEGY[Debridge] = 'sell_asset'is wrong for same-chain swaps, where the fee is in the buy token. Fix it before adding deBridge partner verification.🤖 Generated with Claude Code