Skip to content

Feature/spend save yield integration - #46

Open
Peolite001 wants to merge 2 commits into
Lokt-In:stagingfrom
Peolite001:feature/spend_save_yield_integration
Open

Peolite001 wants to merge 2 commits into
Lokt-In:stagingfrom
Peolite001:feature/spend_save_yield_integration

Conversation

@Peolite001

Copy link
Copy Markdown

Title

feat(spend_save): implement yield integration (#42)

Description

This PR integrates the spend_save contract with the loktin-yield pool (#37), ensuring that idle saved balances can now actively earn yield while they sit in the contract. It ports the yield integration pattern already established in the locked_in and target_savings contracts and implements a full share-based accounting system for positions.

Key Changes

  • Yield Integration & Pool Interface:
    • Implemented the PoolClient interface in lib.rs and wired it into deposit_to_blend, withdraw_from_blend, and blend_position.
    • Nested pool operations now use env.authorize_as_current_contract to correctly process USDC transfers.
    • Added set_pool and pool admin functions for configuration.
  • Shares Accounting:
    • Upgraded SpendSavePosition to hold shares alongside saved_balance.
    • When users spend, their saved USDC is converted into proportional shares based on the pool's total assets. Zero-share mints are explicitly rejected (Error::ZeroShares).
    • During withdrawal, shares are burned proportionally to retrieve requested USDC. The contract dynamically pulls liquidity from the pool if its idle balance is short.
  • Accounting Fixes & Cleanups:
    • Fixed total_spent_lifetime to accumulate the actual total_amount pulled from the user (previously under-reported by only counting the forwarded sent amount).
    • Fixed usdc_token() panicking on .unwrap() to properly return a typed Result<Address, Error>, maintaining consistency with admin().
  • Testing:
    • Added test_zero_share_mint_rejected to explicitly verify protections against zero-share inflation vulnerabilities.
    • Added test_multi_user_spend_and_withdraw using the standard harness to simulate multiple users interacting, earning simulated yield, and withdrawing on the 28th, ensuring the contract never runs short on liquidity.

Related Issues

Closes #42

Acceptance Criteria

  • deposit_to_blend actually supplies USDC to the pool.
  • withdraw_from_blend actually withdraws from the pool.
  • blend_position reports the real aggregate position.
  • set_pool / pool present and admin-gated.
  • Positions track proportional shares; zero-share mint rejected with a test.
  • Multi-user regression test verifies multiple enrolls, spends, and withdrawals without shortfalls.
  • Withdrawal-day restriction (28th UTC) enforced.
  • Panics removed from usdc_token() helper.
  • total_spent_lifetime now accurately reflects total spent.
  • cargo test --workspace passes cleanly.

Deployment Notes

  • set_pool must be called by the admin after deploying to set the target pool address before deposit_to_blend or withdraw_from_blend can be utilized.

@drips-wave

drips-wave Bot commented Sep 24, 2026

Copy link
Copy Markdown

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

This branch has not been deployed

No deployments
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.

feat(spend_save): implement yield integration

1 participant