feat(wrapper): track pending (not-yet-compounded) rewards (#718) - #841
Open
ASIDISG wants to merge 1 commit into
Open
feat(wrapper): track pending (not-yet-compounded) rewards (#718)#841ASIDISG wants to merge 1 commit into
ASIDISG wants to merge 1 commit into
Conversation
|
@ASIDISG 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! 🚀 |
Contributor
|
@ASIDISG please resolve conflicts |
) Adds a PendingRewards instance-storage slot to the wrapper contract, synced in distribute_rewards() after the reward transfer: it accumulates the cumulative amount distributed that has not yet been compounded, as a running total separate from total_assets/share price. The sync uses checked_add and releases the reentrancy lock before returning on overflow, matching the early-return pattern used elsewhere in this file for guards that fire after acquire_lock(). Adds a pending_rewards() getter (mirroring total_assets()/supply()'s style) and a matching TypeScript SDK getPendingRewards() method. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ASIDISG
force-pushed
the
feature/issue-718-pending-rewards-storage
branch
from
August 27, 2026 11:58
fca0b03 to
8a29244
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #718.
Adds a
PendingRewardsstorage slot to the wrapper (vault) contract, per the epic's storage-bucket scope: "Storepending_rewards. Sync variable after fee wrappers distribute yield."DataKey::PendingRewards(contracts/wrapper/src/lib.rs): instance-storagei128, defaulting to 0 when never written, mirroring the existingSupplyslot's read/write helper pattern.distribute_rewards(): after the reward transfer completes,pending_rewardsis incremented by the distributedamountviachecked_add. This is a running total tracking cumulative not-yet-compounded rewards, kept separate fromtotal_assets/calculate_share_price(which already reflect the transfer immediately via the underlying token balance, unchanged by this PR) — it exists for whatever compounding step the epic adds in a later issue. Nothing in this PR consumes or resets it.pending_rewards()getter: mirrorstotal_assets()/supply()'s existing style (plaini128, panics viaensure_initializedwhen uninitialized).checked_addreleases the reentrancy lock before returningInvalidAmounton overflow — matching the early-return-after-acquire_lock()pattern already used bywrap()/unwrap()/withdraw()in this file, so a guard firing after the lock is held can never leave it stuck.getPendingRewards()method toWrapperClientfor parity withgetTotalAssets()/calculateSharePrice().Acceptance criteria (from #718)
pending_rewardsstored and synced afterdistribute_rewardsTest plan
Added 7 Rust unit tests in
contracts/wrapper/src/test.rs:distribute_rewardscallwrap/unwrap/withdraw(only reward distributions move it)distribute_rewardsis rejected (invalid amount, or paused) — and confirms the reentrancy lock isn't left stuck by either rejected call, by successfully distributing again afterwardtest_uninitialized_access_panicsto also coverpending_rewards()Plus a TypeScript SDK surface test confirming
getPendingRewardsis exposed onWrapperClient.Verified locally:
cargo check -p bc-forge-wrapper --tests— cleancargo fmt -p bc-forge-wrapper -- --check— cleancargo clippy -p bc-forge-wrapper --all-targets --all-features -- -D warnings— cleannpm test(sdk) — 23/23 passingnpx eslinton the two changed SDK files — no new issues (the same two pre-existing issues from the [Math] Pro-rata reward calculation #727 PR — a CRLF/prettier diff in untouchedwithdraw()and an unusedkeypairvar in an untouched test — are still present and still predate this change)Note: this dev machine's native Rust linker is broken for both the GNU and MSVC toolchains (confirmed unrelated to any of these changes — it also fails on the pre-existing, untouched
bc-forge-rate-limitcrate), socargo testcouldn't be run to completion locally;cargo check --teststype-checks the full test module against the real Soroban SDK, and CI runs onubuntu-latestwith a working linker.