Repository navigation
feat(contracts): savings inheritance (#439) and savings challenge contracts (#442) - #488
Merged
nayt9 merged 2 commits intoOct 24, 2026
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch had an error being deployed
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 #439
Closes #442
Adds two new Soroban smart-contract features to the savings vault, each following the same patterns (storage, error codes, events, TTL management) established by the existing modules.
Issue #439 — Savings Inheritance
New file:
contracts/savings-vault/src/inheritance.rsLets a flexible-savings account owner designate beneficiaries who can claim the balance if the owner becomes inactive.
Feature breakdown
designate_beneficiary(owner, beneficiary, share_bps)— adds or updates a beneficiary's share. Multiple calls build up a plan; shares must eventually sum to10_000bps (100%) for a claim to succeed.set_inactivity_timeout(owner, timeout_seconds)— configures how long the owner must be inactive before beneficiaries can claim. Zero disables inheritance.inheritance::touch_owneris called byflexible::depositandflexible::withdrawto reset the inactivity clock on every owner interaction.claim_inheritance(claimer, owner)— verifies: plan exists, timeout > 0, elapsed, shares sum to 10 000, caller is a beneficiary. Pays each beneficiary their proportional share atomically and zeros the flexible account.remove_beneficiary(owner, beneficiary)Storage
DataKey::Inheritance(Address)— persistent, TTL bumped on every read/write.Errors used
CooldownActive(timeout not elapsed or zero),InvalidShares(shares ≠ 10 000),Unauthorized(caller not a beneficiary),NotFound,InsufficientBalance,Overflow,DivisionByZero.Events
inherit_benef_set,inherit_benef_rm,inherit_timeout_set,inherit_claimed.Tests (9)
Issue #442 — Savings Challenge Contracts
New file:
contracts/savings-vault/src/challenge.rsA fixed-duration savings competition: participants race to save a target amount by a deadline. First to verify wins the prize pool (sum of all entry fees). No winner → refund.
Feature breakdown
create(creator, target_amount, entry_fee, deadline, min_participants)— creator pays the entry fee and becomes the first participant. Returns challenge id.join(participant, challenge_id)— pays entry fee, adds to participant list. Deadline and duplicate checks enforced.save(participant, challenge_id, amount)— deposits toward the caller's personal target. Tracked per-participant inside theChallengerecord.claim_winner(participant, challenge_id)— verifies on-chain thatparticipant.saved >= target_amountANDparticipants.len() >= min_participants. Pays the full prize pool to the winner.refund_expired(caller, challenge_id)— permissionless after deadline. Returns each participant'sfee_paid + savedindividually.Storage
DataKey::Challenge(u64)— persistent, TTL bumped.DataKey::NextChallengeId— instance counter.Types added
ChallengeStatus(Open/Won/Expired),ChallengeParticipant,Challenge.Errors used
InvalidAmount,InvalidTimestamp,InvalidParameters,NotFound,GroupClosed,OperationExpired,MemberAlreadyExists,NotAMember,GoalNotReached,TimeWindowNotOpen,Overflow.Events
challenge_created,challenge_joined,challenge_saved,challenge_won,challenge_expired.Tests (10)
Files changed
contracts/savings-vault/src/inheritance.rscontracts/savings-vault/src/challenge.rscontracts/savings-vault/src/types.rsBeneficiary,InheritancePlan,ChallengeStatus,ChallengeParticipant,Challengetypes;DataKey::Inheritance,DataKey::Challenge,DataKey::NextChallengeIdvariantscontracts/savings-vault/src/lib.rscontracts/savings-vault/src/events.rs