Skip to content

fix(contract): remove redundant TotalByAsset storage key - #1082

Merged
OlaGreat merged 2 commits into
OlaGreat:mainfrom
precious-akpan:fix/1038-remove-redundant-storage-key
Aug 31, 2026
Merged

fix(contract): remove redundant TotalByAsset storage key#1082
OlaGreat merged 2 commits into
OlaGreat:mainfrom
precious-akpan:fix/1038-remove-redundant-storage-key

Conversation

@precious-akpan

@precious-akpan precious-akpan commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • RecipientTotal(Address, Address) and TotalByAsset(Address, Address) were both keyed by (recipient, asset) and updated with the exact same increment/decrement in support()/withdraw().
  • Every support() call wrote two persistent ledger entries (plus two extend_ttl calls) holding the same value, doubling storage rent/fees for zero informational benefit.
  • Removed the TotalByAsset DataKey variant and its writes in support().
  • withdraw()'s existence/balance check and decrement now operate on RecipientTotal directly (previously used TotalByAsset for this).
  • get_total_by_asset() is now a thin wrapper over get_recipient_total() — public behavior is unchanged, and this matches contract/ABI.md's existing description of get_recipient_total as "mirror[ing] get_total_by_asset and read[ing] from the same RecipientTotal storage key."
  • Updated one test that poked DataKey::TotalByAsset directly in storage to use DataKey::RecipientTotal instead, since that's now the key withdraw() reads.

Closes #1038

Also fixed: 3 pre-existing test failures unrelated to #1038, blocking this PR's CI

main's Contract CI has been red since #1040's reentrancy fix merged (moves the external balance() check to the very start of withdraw(), ahead of the RecipientNotFound/ZeroBalance/WithdrawAmountExceedsBalance checks — correct per #1040's design, but it left over_withdraw, withdraw_with_no_balance, and withdraw_again_after_full_withdrawal_... asserting the wrong error, since their scenarios also happen to leave the contract's real token balance below the requested amount). Added a second commit that funds the contract directly via the token admin (bypassing support()) in each of those 3 tests, so the external balance check passes and the intended application-level check is what actually gets exercised. Confirmed this reproduces identically on unmodified main (i.e., it's not something my #1038 change introduced).

Test plan

@drips-wave

drips-wave Bot commented Aug 30, 2026

Copy link
Copy Markdown

@precious-akpan 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

…reat#1038)

RecipientTotal and TotalByAsset were both keyed by (recipient, asset)
and updated with the exact same increment/decrement in support() and
withdraw(), so every support() call wrote two persistent ledger entries
(plus two extend_ttl calls) holding the same value — doubling storage
rent for zero informational benefit.

Drop the TotalByAsset key and its writes; withdraw()'s existence/balance
check now reads RecipientTotal directly. get_total_by_asset() becomes a
thin wrapper over get_recipient_total() so its public behavior (and the
ABI.md docs, which already described it as mirroring RecipientTotal) is
unchanged.

Test snapshots updated to reflect the now-smaller ledger footprint (one
fewer contract_data read/write entry per support()/withdraw() call).
's reentrancy fix

main's Contract CI has been red since the OlaGreat#1040 fix merged: it moved the
external token balance() check to the very start of withdraw(), ahead of
the RecipientNotFound/ZeroBalance/WithdrawAmountExceedsBalance checks —
correct per OlaGreat#1040 (checks-effects-interactions), but it left over_withdraw,
withdraw_with_no_balance, and withdraw_again_after_full_withdrawal_...
asserting the wrong error: their scenarios also happen to leave the
contract's real token balance below the requested amount, so
InsufficientContractBalance now fires first instead of the app-level error
each test means to exercise.

Fund the contract directly via the token admin (bypassing support()) in
each test, so the external balance() check passes and the intended
application-level check is what actually gets exercised.
@precious-akpan
precious-akpan force-pushed the fix/1038-remove-redundant-storage-key branch from 7788f22 to 418c641 Compare August 31, 2026 00:17
@OlaGreat
OlaGreat merged commit 7917959 into OlaGreat:main Aug 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Contract] RecipientTotal and TotalByAsset are now fully redundant, doubling storage writes and rent per call

2 participants