Skip to content

feat(contracts): implement virtual yield accrual logic#893

Open
Ebenezer199914 wants to merge 1 commit into
Fracverse:masterfrom
Ebenezer199914:feat/virtual-yield-accrual
Open

feat(contracts): implement virtual yield accrual logic#893
Ebenezer199914 wants to merge 1 commit into
Fracverse:masterfrom
Ebenezer199914:feat/virtual-yield-accrual

Conversation

@Ebenezer199914

Copy link
Copy Markdown

Summary

Fixes #831[Contracts] Implement Virtual Yield Accrual Logic

Implements fully on-chain virtual yield accrual for the Soroban inheritance contract. Yield is computed using an APR formula and accrued lazily (at ping time) or projected virtually (at read time) without external vault interactions.

Changes

lib.rs

  • Plan struct: Added accrued_yield: i128 field (initialised to 0 on plan creation).
  • SECS_PER_YEAR constant: 31_536_000 seconds used for APR → per-second conversion.
  • compute_accrued_yield(principal, rate_bps, elapsed_secs): Private helper implementing principal * rate_bps * elapsed / (10_000 * SECS_PER_YEAR) with saturating arithmetic.
  • ping(): Accrues yield since last ping into plan.accrued_yield before resetting last_ping.
  • trigger_payout(): Finalises pending yield at claim time; distributes principal + accrued_yield across beneficiaries.
  • reclaim(): Finalises pending yield and transfers principal + accrued_yield back to the owner.
  • get_plan(): Projects pending yield since last ping into the returned struct without writing to storage (pure read).

test.rs

Nine new yield-specific tests:

Test What it checks
test_yield_not_accrued_when_disabled earn_yield=false keeps accrued_yield=0
test_yield_accrues_over_one_year 10% APR × 1 year × 1000 principal = 100
test_yield_zero_at_creation No yield at t=0
test_ping_accrues_yield Ping persists elapsed yield to storage
test_ping_does_not_accrue_yield_when_disabled Ping is no-op when disabled
test_multiple_pings_accumulate_yield Two half-year pings == one full-year
test_trigger_payout_includes_yield Beneficiary receives principal + yield
test_reclaim_includes_yield Owner reclaims principal + yield
test_get_plan_projects_yield_without_persisting get_plan is idempotent / pure

CI

  • No new clippy warnings (all existing #[allow] attributes preserved).
  • rustfmt-formatted.
  • All 24 existing tests continue to pass; 9 new tests added.

- Add accrued_yield: i128 field to Plan struct
- Add compute_accrued_yield() private helper (APR formula, integer arithmetic)
- ping() accrues yield since last_ping before resetting the timer
- trigger_payout() distributes principal + accrued_yield to beneficiaries
- reclaim() returns principal + accrued_yield to owner
- get_plan() projects pending yield virtually without writing to storage
- Add 9 yield-specific tests covering all paths

Closes Fracverse#831
@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@Ebenezer199914 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

@ONEONUORA

Copy link
Copy Markdown
Contributor

@Ebenezer199914
Pls fix conflict

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.

[Contracts] Implement Virtual Yield Accrual Logic

2 participants