feat(farming-pool): support partial unstake (#14)#55
Open
storm-beyndtech wants to merge 1 commit into
Open
Conversation
unstake() previously withdrew the entire staked balance and always removed the stake record, unlike unlock_assets() which supports partial withdrawal via an amount parameter. Add an `amount: i128` parameter to unstake: - validate amount > 0 (PoolError::InvalidAmount) and amount <= stake.amount (PoolError::InsufficientStake), returning typed errors instead of panicking - checkpoint before mutating so credits accrue against the full balance up to the unstake ledger - remove the stake on full exit, persist the reduced stake on partial - return credits_snapshot in both cases (per spec) - emit (pool, unstaked) -> (user, amount, credits_snapshot) Also upgrade the missing-stake path from .expect() to a typed PoolError::NoActiveStake. Tests: partial unstake (remaining balance + banked credits), full unstake clears storage, insufficient balance and non-positive amount return typed errors, and event emission. Existing unstake call sites updated for the new signature.
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.
Closes #14.
What
unstake()previously withdrew the entire staked balance and alwaysremoved the stake record — unlike
unlock_assets(), which already supportspartial withdrawal via an
amountparameter. This makes the stake/boost pathsymmetric with the lock/unlock path.
Changes
amount: i128tounstake(env, from, amount).amount > 0→PoolError::InvalidAmountandamount <= stake.amount→PoolError::InsufficientStake, returning typederrors instead of panicking (two new
PoolErrorvariants added).checkpointbefore mutatingamount, so credits accrue against the fullstaked balance up to the unstake ledger.
(pool, unstaked)→(user, amount, credits_snapshot)..expect("no active stake")to a typed
PoolError::NoActiveStake(the variant already existed).Tests (all green —
cargo test --workspace, 79 passed)InsufficientStakeInvalidAmountunstakecall sites updated for the new signatureVerified the release WASM still builds:
cargo build --target wasm32v1-none --release.Decisions / open questions
credits_snapshot(banked credits at unstake time) on both partial and fullexit. Trivial to flip to "return only on full exit" if you'd prefer that.
PoolErrors for validation per theacceptance criteria. Note
unlock_assetsstill usesassert!for its amountchecks — I kept this change scoped and didn't refactor it; happy to align both
separately.
env.events().publish(...)to match every other event inthe contract. The SDK now deprecates this in favor of
#[contractevent]—happy to migrate the whole file in a separate PR rather than make
unstaketheodd one out here.
Note (out of scope, possible follow-up issue)
make buildtargetswasm32-unknown-unknown, which soroban-sdk 25.3.1 rejectsoutright (requires
wasm32v1-none, which is what CI uses). The Makefile's buildtarget is broken against the current SDK — flagging it for a separate fix.