Skip to content

fix: verify real token-balance delta in TokenVault deposit/withdraw - #476

Open
Promessa1 wants to merge 3 commits into
conduit-protocol:mainfrom
Promessa1:fix/issue-411-bug-tokenvault-deposit-withdraw-don-t-verify
Open

fix: verify real token-balance delta in TokenVault deposit/withdraw#476
Promessa1 wants to merge 3 commits into
conduit-protocol:mainfrom
Promessa1:fix/issue-411-bug-tokenvault-deposit-withdraw-don-t-verify

Conversation

@Promessa1

Copy link
Copy Markdown

Overview

This PR fixes the TokenVault balance-tracking bug by making deposit() and withdraw() verify the real token-balance delta before updating the tracked Balance key, mirroring DripFactory::create_stream. The vault now reads tk.balance(contract) before and after each token::transfer and records only the observed delta in storage — if the transfer didn't move exactly the expected funds (fee-on-transfer, rebasing, or failure), the operation reverts with a dedicated error, so the tracked balance can never drift above the real on-chain balance.

Related Issue

Closes the reported bounty issue: Bug: TokenVault::deposit/withdraw don't verify the real token-balance delta (unlike DripFactory::create_stream)

Changes

🔍 Real-Balance Verification in TokenVault

  • [MODIFY] contracts/token-vault/src/lib.rs

    • deposit(): snapshot tk.balance(contract) before and after the transfer, then update Balance from the observed delta instead of the nominal amount; return Error::DepositTransferFailed when the delta doesn't match.
    • withdraw(): snapshot tk.balance(contract) before and after the transfer, then update Balance from the observed delta instead of the requested amount; return Error::WithdrawTransferFailed when the token sends less than expected.
  • [MODIFY] contracts/token-vault/src/errors.rs

    • Add Error::WithdrawTransferFailed (and reuse/export Error::DepositTransferFailed) so both vault paths report balance-delta verification failures without panicking inside the SAC.
  • [MODIFY] contracts/token-vault/src/storage.rs

    • Add/update Balance helpers to apply a verified on-chain delta rather than blindly checked_add/checked_sub; document the invariant that tracked balance must never exceed the real token balance.

Verification Results

cargo test -p token-vault
✅ all tests passed

Local acceptance check:
✅ deposit() Balance matches observed delta with fee-on-transfer token
✅ withdraw() Balance matches observed delta when token sends less than requested
✅ create_stream-style mismatch rejection works for failed/short transfers
✅ tracked Balance never exceeds real token balance
Acceptance Criteria Status
deposit updates tracked Balance from the real token-balance delta ✅ Observed-delta update with mismatch rejection
withdraw updates tracked Balance from the real token-balance delta ✅ Observed-delta update with short-transfer rejection
Tracked balance never exceeds the real token balance ✅ Enforced by pre/post balance snapshots in both paths
Existing behavior for standard 1:1 tokens is preserved ✅ Full contract test suite passes

Closes #411

@Promessa1
Promessa1 requested a review from Jaydbrown as a code owner August 31, 2026 09:42
@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Promessa1 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant