Stub verifiers report SUCCESS with hasAffiliate from the swap's own claim

Open Beginner friendly
#64 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
backend

Research direction

Start in apps/swap-service/src/verification/swap-verification.service.ts and inspect verifyCetus, verifySunio, verifyAvnu, verifyStonfi, and verifyAcross alongside the no-op verifier branches. Check how swaps.service.ts and scripts/affiliate-payouts/utils.ts consume the result; done means these unimplemented verifiers cannot mark a swap as affiliate-verified or payable.

Written by the indexing model from the issue text.

Description

Description

Five verifiers in apps/swap-service/src/verification/swap-verification.service.ts are stubs — each carries a // TODO: Implement on-chain/API verification and makes no network call — but they return verificationStatus: 'SUCCESS' with hasAffiliate derived from the row's own claimed bps:

// TODO: Implement on-chain/API verification for Cetus
const affiliateBps = swap.affiliateBps
const hasAffiliate = affiliateBps > 0

return { verificationStatus: 'SUCCESS', hasAffiliate, ... }

Affected: verifyCetus, verifySunio, verifyAvnu, verifyStonfi, verifyAcross.

That feeds straight into the payout gate:

// swaps.service.ts:467
const isAffiliateVerified = verificationResult.verificationStatus === 'SUCCESS' && verificationResult.hasAffiliate
// scripts/affiliate-payouts/utils.ts:122
if (!row.isAffiliateVerified) { ... }   // excluded, otherwise payable

So a swap on one of these five is marked affiliate-verified on the strength of its own payload, and becomes payable, with nothing checked. The gate that exists to keep unverified swaps out of revenue reports them as verified.

Contrast with the honest no-ops in the same switch — BobGateway, Debridge, Test return noAffiliateResult('SUCCESS', 'Verification not implemented'), and verifyArbitrumBridge returns hasAffiliate: false. All four yield isAffiliateVerified = false and are correctly excluded. That is the behaviour the five stubs should have.

Not currently exploitable: none of the five is in public-api's ENABLED_SWAPPER_NAMES, so no quote can be minted for them today. But swap-service will verify such a row if one arrives by any route, and enabling any of these swappers would open the path silently.

Suggested fix

Short term, make the five behave like the other unimplemented ones — return hasAffiliate: false (or noAffiliateResult('SUCCESS', 'Verification not implemented')) so they cannot set isAffiliateVerified. One line each.

Longer term, implement real verification per swapper, or add a compile-time guard so a new SwapperName cannot default into a self-certifying branch.

Related

  • 0x (verifyZrx) calls /trade-analytics/swap?txHash=… assuming it filters. It does not — the endpoint returns a paginated feed of ~200 recent trades across all chains plus a nextCursor, which the verifier never follows. So a 0x swap verifies only while it remains on the first page; older ones hit the not-found branch, which returns PENDING, leaving the swap re-polled every 30s indefinitely. Separate bug, same file.
  • CowSwap, Portals, Bebop, ButterSwap do make real calls and are not part of this issue.
Dominant language
TypeScript
Stars
0
Forks
0
Avg merge
9h 59m
Merged PRs (30d)
12

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from shapeshift/microservices

All issues in shapeshift/microservices

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.