Repository navigation
docs(bridge-core): correct the fee-free-return rationale — it describes a deleted design - #93
Conversation
…es a deleted design `assertFeeFreeReturn`'s comment (and its maxFee error message) explains the guard by `ledger[commitment]`, `receive_and_bind` crediting the GROSS burned amount, and the claim reverting INSUFFICIENT_CLAIMABLE. None of those exist any more. That design was live when the guard was added (eeed7e03, 2026-07-07) and was removed the next day by the claim-fold rewrite (d77edee2). Its sibling commit adapted the *test* but nobody updated the *rationale*, so the comment has described a deleted mechanism since. What actually happens now: InboundAnonymizer snapshots balance_of, calls receive_message, and hands the pool `after - before`; the pool asserts only non-zero / note-exists / token-match, and the proof carries no amount (the Open sentinel). So a per-call CCTP fee does NOT revert the claim — it silently credits a SMALLER note. The guard is still correct and stays as-is; only its reason changes. A caller asking to return N must get N or an error, never N - fee. Two readers were misled by this paragraph. #703 forced Fast finality globally and noted "the return leg is unaffected — it self-enforces Standard finality", taking the stale rationale as given; and an audit in the consuming repo built a "forcing Fast is dangerous because the proof pins the amount" argument on it before verification refuted it. Also records what the investigation established: this costs nothing today, because Circle sells no Fast tier from Polygon (standard attestation ~8s) and quotes 0 bps on both tiers for this route — and that "fee-free" is live-quoted state rather than a protocol constant, since CCTP v2 documents a per-deployment TokenMessengerV2 fee switch that can impose a minimum fee on STANDARD transfers. Comments and message strings only; no behavior change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PR SummaryLow Risk Overview The rationale is rewritten because it still described the removed ledger / gross-amount / New comment notes: Polygon route is effectively fee-free today (no Fast tier, 0 bps quoted); “fee-free” is live CCTP config, not a constant — if Circle enables a standard-tier minimum fee, failing closed at the return entry points is intentional. Reviewed by Cursor Bugbot for commit a0b18ef. Bugbot is set up for automated code reviews on this repo. Configure here. |
assertFeeFreeReturn's comment, and itsmaxFeeerror message, justify the guard withledger[commitment],receive_and_bindcrediting the GROSS burned amount, and the claim revertingINSUFFICIENT_CLAIMABLE.None of those exist any more.
How the drift happened
eeed7e03d77edee2ledger[commitment]/receive_and_bind3da04702#703So the comment has described a deleted mechanism for over a month.
What actually happens now
InboundAnonymizersnapshotsbalance_of, callsreceive_message, and hands the poolafter - before. The pool asserts only non-zero / note-exists / open-salt / not-already-deposited / token-match — no comparison to any proven or burned amount — and the proof carries no amount at all (theOpensentinel).So a per-call CCTP fee does not revert the claim. It silently credits a SMALLER note.
What changes, and what doesn't
The guard stays exactly as-is. It is still correct, and still the right direction: a caller asking to return N must get N or an error, never N − fee. Only the reason changes, from "the claim would revert" to "the note would silently shrink".
Also recorded, from an investigation in the consuming repo:
TokenMessengerV2fee switch that can impose a minimum fee on STANDARD transfers. If it is ever set for this route, this guard fails the leg closed rather than shrinking the note — which is the intended direction, and worth stating so nobody "optimizes" the check away.Why it is worth a PR
This is load-bearing documentation on a fund-safety guard, and it has now demonstrably misled two independent readers:
#703above, and an audit in the consuming repo that built a "forcing Fast is dangerous because the proof pins the amount" argument on this paragraph before verification refuted it. The guard's behavior was never wrong; the explanation was, and the explanation is what people reason from.The test file's header comment repeated the same false claim, so it is corrected too.
Verification
Comments and message strings only — no behavior change. The existing assertion is
/fee-?free|maxFee|per-call fee/i, which the reworded message still satisfies.Run locally in
packages/bridge-core:tsc --noEmit— cleantsc(build) — cleanvitest run src/core/returnIn.feeFree.test.ts src/core/returnIn.test.ts src/core/avnuPaymaster.test.ts— 43/43 passedavnuPaymasteris included deliberately: it usesINSUFFICIENT_CLAIMABLEas a fixture for its felt-decoder, which is unrelated to the return path's ledger design and is intentionally left untouched.This change is