Repository navigation
cshld-2160: bind ton transfer comment to memoId in verifyTransaction - #10163
Conversation
|
|
33a4cc5 to
f4b7067
Compare
|
@claude review |
f4b7067 to
fc14129
Compare
|
@claude review and share verdict |
49037e8 to
a25d22b
Compare
|
Confirmed — you were right about the snake decoder. Verified against the spec and the canonical reader, and fixed in a25d22b: Verification of your claim
Fix
Fallout you predicted, handled
All 18 smoke assertions pass through real |
8f6d002 to
1ce3061
Compare
|
Follow-up coverage added in the latest push (1ce3061):
Smoke through real coin objects: |
Ton.verifyTransaction compared only (address, amount) and stripped the ?memoId= suffix, so a prebuild whose on-chain comment differed from the intended memoId verified successfully, enabling exchange-deposit redirection. Verification now binds the parsed transfer comment (plain-send body comment and jetton forward comment) to the declared memoId on both the tton WASM and mainnet TonWeb paths, rejecting different, missing, and extra comments. Explanations expose the comment as outputs[].memo, and the TonWeb jetton parser now accepts the empty forward-payload cell the builder writes for comment-less transfers. Ticket: CSHLD-2160 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1ce3061 to
3bacce9
Compare
mukeshsp
left a comment
There was a problem hiding this comment.
Review verdict: approve (no remaining findings) at 3bacce9. Static review of the diff only; tests were not run locally, so CI (yarn unit-test --scope @bitgo/sdk-coin-ton) remains the gate.
- WASM
extractOutputsnow suppressesDeposit/Withdraw/ single-nominator withdraw-all comments, matching the TonWebtype === Sendgate, so both verify paths agree. - The jetton forward comment is exposed consistently on both paths, and the
custom_payloadref is now consumed so the forward payload is read from the right cell. - The strict
loadCommentand the empty forward-payload handling fail closed on malformed cells. - The
setMessageround-trip test restores builder coverage, and the protocol-text limitation is pinned by a test and documented in the PR description.
Optional follow-up: add a tton (WASM) twin of the new "Deposit as declared memo" test. It currently only runs through mainnetCoin, though the WASM path uses the same guard.
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
Summary
Ton.verifyTransactioncompared only(address, amount)and stripped the?memoId=suffix from recipient addresses, so a prebuilt transaction whose on-chain comment differed from the intended memoId verified successfully — enabling exchange-deposit redirection. This PR binds the parsed transfer comment to the declared memoId on both the tton WASM and mainnet TonWeb paths.Linear: CSHLD-2160
Changes
verifyTransactionnow compares{address, amount, memo}per output on both paths; the expected memo is resolved from the?memoId=address suffix andrecipient.memo(agree-or-reject, empty = absent). A prebuild whose comment is different from, missing from, or extra to the declared memoId fails verification withTx outputs does not match with expected txParams recipients.extractOutputs) and TonWeb explain (Transaction/TokenTransaction) expose the parsed comment asoutputs[].memo— plain-send body comments and jetton forward comments. Protocol payloads (SingleNominator/Whales opcodes) are not exposed as memo.TokenTransferBuilderalways writes for comment-less transfers — previously every comment-less jetton prebuild failed parsing (and thus verification) withinvalid raw transaction.signedSendTransactionForMemoId.txwas byte-identical to the comment-less fixture — it literally demonstrated the vulnerability); the old comment-carrying jetton bytes are preserved assignedTokenSendTransactionWithCommentfor negative tests.bitgo.coin('ton')(TonWeb) describe that previously had zero verify coverage.Test Plan
verifyTransactionontton,ton, andtton:ukwny-us— positives plus all four negative classes (missing/different/extra comment, plain and token), explain memo exposure/absence, and SingleNominator/Whales no-memo-leak regressions: 21/21 pass.yarn unit-test --scope @bitgo/sdk-coin-ton.Behavior notes
recipient.memois now a hard declaration for TON. Verification treats it as the expected on-chain comment (together with the?memoId=address suffix); callers that populatedrecipient.memofor any other purpose will now fail verification withTx outputs does not match with expected txParams recipients.Deposit,Withdraw, or the single-nominator withdraw-all text is classified as a staking protocol comment and suppressed fromoutputs[].memo, so a transfer whose intended memo happens to equal one of those strings cannot pass verification. Pinned by test intest/unit/ton.ts.