fix(swap-verification): value MAYAChain affiliate fee with raw CACAO amount - #53
Conversation
Maya Midgard reports the native CACAO fee in its native 1e10 precision (pool/external assets are 1e8), so the shared Midgard verifier must store feeOut.coins[0].amount raw. It was running the amount through thorchainToNativePrecision (×100 for Maya), inflating on-chain fee USD 100× (e.g. $3.76 vs correct $0.038 for a ~70bps fee on a ~$5 swap). Removed the feeAssetPrecision config; Thorchain is unaffected (RUNE native = 8). Also attribute verified affiliates that collect no fee: hasAffiliate now keys off the affiliate-address match alone (dropping the && feeOut monkey patch), reporting affiliateBps with a '0' fee amount for 0-bps swaps. calculateFeeForSwap guards verifiedBps with === undefined so real 0-bps affiliate swaps aren't skipped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ency Align the MAYAChain verifier naming with the fully-spelled Thorchain convention: verifyMaya -> verifyMayachain, test fixtures maya/ -> mayachain/ (mayaResponse/mayaSwap -> mayachainResponse/mayachainSwap), maya.test.ts -> mayachain.test.ts, and the RUNE/CACAO precision comment. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 27 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR modifies swap affiliate verification logic in swap-verification.service.ts: hasAffiliate now depends solely on memo-matched affiliate address (not requiring a discovered feeOut), and actualAffiliateFeeAmountCryptoBaseUnit always defaults to '0' without precision conversion. Maya verification is renamed to Mayachain, verifiedBps check tightened, and tests updated accordingly. ChangesAffiliate verification and fee logic update
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant SwapVerificationService
participant verifyMayachain
participant verifyMidgardSwap
Caller->>SwapVerificationService: verifySwap(swap)
SwapVerificationService->>verifyMayachain: verifyMayachain(swap)
verifyMayachain->>verifyMidgardSwap: verifyMidgardSwap(swap, config)
verifyMidgardSwap->>verifyMidgardSwap: hasAffiliate = affiliateAddress === config.affiliate
verifyMidgardSwap->>verifyMidgardSwap: actualAffiliateFeeAmountCryptoBaseUnit = feeOut?.coins[0]?.amount ?? '0'
verifyMidgardSwap-->>SwapVerificationService: verification result
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/swap-service/src/swaps/utils.ts (1)
171-201: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winHandle the
0-bps case in thevolumeUsdfallback
affiliateBpscan now be0, and ifsellAmountUsdisnullthisdiv(verifiedBps)path producesNaN/Infinity, which then poisonsvolumeUsdand the aggregated affiliate stats. GuardverifiedBps === 0explicitly here.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/swap-service/src/swaps/utils.ts` around lines 171 - 201, The volume fallback in utils.ts can divide by zero when affiliateVerificationDetails.affiliateBps is 0 and sellAmountUsd is null, causing NaN/Infinity in the affiliate stats path. Update the logic in the swap fee calculation block around verifiedBps, computeSellAmountUsd, and volumeUsd to explicitly handle verifiedBps === 0 before the div(verifiedBps) fallback, and return a safe null/skip behavior instead of producing an invalid volume.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@apps/swap-service/src/swaps/utils.ts`:
- Around line 171-201: The volume fallback in utils.ts can divide by zero when
affiliateVerificationDetails.affiliateBps is 0 and sellAmountUsd is null,
causing NaN/Infinity in the affiliate stats path. Update the logic in the swap
fee calculation block around verifiedBps, computeSellAmountUsd, and volumeUsd to
explicitly handle verifiedBps === 0 before the div(verifiedBps) fallback, and
return a safe null/skip behavior instead of producing an invalid volume.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7d45bd13-1bfc-45b0-ac72-097c8a152fc6
📒 Files selected for processing (6)
apps/swap-service/src/swaps/utils.tsapps/swap-service/src/verification/__tests__/fixtures/mayachain/response.jsonapps/swap-service/src/verification/__tests__/fixtures/mayachain/swap.tsapps/swap-service/src/verification/__tests__/mayachain.test.tsapps/swap-service/src/verification/__tests__/thorchain.test.tsapps/swap-service/src/verification/swap-verification.service.ts
calculateFeeForSwap now lets verifiedBps === 0 through so real 0-bps affiliate swaps aren't skipped. The volumeUsd fallback reconstructs volume from the fee (fee × 10000 ÷ bps), which is NaN/Infinity at 0 bps and poisons aggregated affiliate stats. When the sell price is missing at 0 bps volume is genuinely unknown — record 0 and warn instead. Adds unit tests for the volume branches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ce1b05c to
52fd954
Compare
Description
MAYAChain Midgard reports the native CACAO amount in its native 1e10 precision, unlike pool/external assets which are normalized to 1e8 (Maya docs: "CACAO is the only asset which is expressed in 1e10 format"). The shared Midgard verifier was running the affiliate
feeOutamount throughthorchainToNativePrecision(..., feeAssetPrecision=10), multiplying it by 100. Since the downstream read path (resolveActualFeeUsd) then divides by1e10and prices with the real CACAO price, this inflated on-chain MAYAChain affiliate fee USD by 100×.Example (swap
d16d8a13, ~70 bps on a ~$5 swap): stored329870380000→ $3.76, vs. correct raw3298703800→ $0.038.Confirmed three ways: the Maya docs, an empirical mayanode-vs-Midgard pool-depth cross-check (both report CACAO at ~6.1e16 = 1e10, not 100× apart), and the tx's own numbers reconciling to 70 bps only under the 1e10 interpretation.
Changes:
feeOut.coins[0].amountraw — the affiliate fee is always the chain's native asset (RUNE/CACAO), which Midgard already reports in native precision. Removed thefeeAssetPrecisionconfig. Thorchain is unaffected (RUNE native = 8 =THORCHAIN_PRECISION, previously a no-op).hasAffiliatenow keys off the affiliate-address match alone (dropping the&& !!feeOutgate), reportingaffiliateBpswith a'0'fee amount for genuine 0-bps swaps.calculateFeeForSwapguardsverifiedBpswith=== undefinedso real 0-bps affiliate swaps aren't skipped.verifyMaya→verifyMayachain,maya.test.ts→mayachain.test.ts,fixtures/maya/→fixtures/mayachain/,mayaResponse/mayaSwap→mayachainResponse/mayachainSwap.Testing
yarn test verification/__tests__— 50/50 pass, including updated MAYAChain expectations (raw4237779000;'0'for the affiliate-with-no-payout case) and unchanged Thorchain expectations.Summary by CodeRabbit