Skip to content

feat(contracts): implement fractional asset wrapping module - #617

Merged
github-actions[bot] merged 1 commit into
Sahara-Pay:mainfrom
godwinishaku506-hub:feat/fractional-asset-wrapping
Aug 21, 2026
Merged

feat(contracts): implement fractional asset wrapping module#617
github-actions[bot] merged 1 commit into
Sahara-Pay:mainfrom
godwinishaku506-hub:feat/fractional-asset-wrapping

Conversation

@godwinishaku506-hub

@godwinishaku506-hub godwinishaku506-hub commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Add packages/contracts/src/fractional_wrap.rs — a self-contained, #![no_std]-compatible module that provides the pure-math kernel for deterministic SAC token wrapping/unwrapping on Stellar Soroban.

Key additions
─────────────
• compute_wrap() — validated deposit → shares conversion (rounds DOWN,
favors pool; rejects zero-share deposits).
• compute_unwrap() — validated shares → asset conversion (rounds UP,
favors pool; rejects excess-share burns).
• preview_wrap() — pure, Env-free preview returning Option.
• preview_unwrap() — pure, Env-free preview returning Option.
• proportional_share() — floor-rounded proportional allocation helper
using safe_mul_div from rounding.rs.
• WrapResult / UnwrapResult domain types carrying all state-update values
so contract dispatch code never re-derives them.

Security properties
───────────────────
• ERC-4626-style +1 virtual share/asset offset defeats inflation attacks. • Rounding direction is explicit and auditable at every call site. • WRAP_MAX_AMOUNT constant prevents i128 overflow in intermediate products. • Zero-share guard blocks donation-vector share-price manipulation. • All arithmetic uses checked_add / checked_mul — no silent overflow.

Proptest invariant suite (11 property tests, 2 000 cases each) ──────────────────────────────────────────────────────────────

  1. prop_no_inflation_attack — wrap → immediate unwrap ≤ deposit
  2. prop_share_fair_value — shares × (ta+1) ≤ assets × (ts+1)
  3. prop_pool_ceiling_on_unwrap — returned ≤ total_assets
  4. prop_pool_monotone_after_unwrap — pool never grows on unwrap
  5. prop_wrap_monotone — larger deposit → ≥ shares
  6. prop_unwrap_monotone — more shares → ≥ assets
    7a. prop_wrap_deterministic — same input → same shares
    7b. prop_unwrap_deterministic — same input → same assets
  7. prop_preview_wrap_truncation_invariant
  8. prop_two_holder_allocation_bounded
  9. prop_zero_share_deposit_math_consistency
  10. prop_round_trip_never_profits_large — extended large-scale variant

Module wiring
─────────────
• pub mod fractional_wrap; added to lib.rs.
• No changes to existing contract entry points — additive only.

Build
─────
• cargo check passes cleanly with rust 1.88.0 (4 pre-existing warnings
unrelated to this change).
• cargo test blocked by a pre-existing soroban-env-host rand_core version
conflict that exists on main before this commit.

Closes #[fractional-asset-wrapping]
Execution limit: O(1) arithmetic well under the 30 M instruction cap.

closes #519

Add packages/contracts/src/fractional_wrap.rs — a self-contained,
#![no_std]-compatible module that provides the pure-math kernel for
deterministic SAC token wrapping/unwrapping on Stellar Soroban.

Key additions
─────────────
• compute_wrap()   — validated deposit → shares conversion (rounds DOWN,
                     favors pool; rejects zero-share deposits).
• compute_unwrap() — validated shares → asset conversion (rounds UP,
                     favors pool; rejects excess-share burns).
• preview_wrap()   — pure, Env-free preview returning Option<i128>.
• preview_unwrap() — pure, Env-free preview returning Option<i128>.
• proportional_share() — floor-rounded proportional allocation helper
                         using safe_mul_div from rounding.rs.
• WrapResult / UnwrapResult domain types carrying all state-update values
  so contract dispatch code never re-derives them.

Security properties
───────────────────
• ERC-4626-style +1 virtual share/asset offset defeats inflation attacks.
• Rounding direction is explicit and auditable at every call site.
• WRAP_MAX_AMOUNT constant prevents i128 overflow in intermediate products.
• Zero-share guard blocks donation-vector share-price manipulation.
• All arithmetic uses checked_add / checked_mul — no silent overflow.

Proptest invariant suite (11 property tests, 2 000 cases each)
──────────────────────────────────────────────────────────────
1.  prop_no_inflation_attack        — wrap → immediate unwrap ≤ deposit
2.  prop_share_fair_value           — shares × (ta+1) ≤ assets × (ts+1)
3.  prop_pool_ceiling_on_unwrap     — returned ≤ total_assets
4.  prop_pool_monotone_after_unwrap — pool never grows on unwrap
5.  prop_wrap_monotone              — larger deposit → ≥ shares
6.  prop_unwrap_monotone            — more shares → ≥ assets
7a. prop_wrap_deterministic         — same input → same shares
7b. prop_unwrap_deterministic       — same input → same assets
8.  prop_preview_wrap_truncation_invariant
9.  prop_two_holder_allocation_bounded
10. prop_zero_share_deposit_math_consistency
11. prop_round_trip_never_profits_large — extended large-scale variant

Module wiring
─────────────
• pub mod fractional_wrap; added to lib.rs.
• No changes to existing contract entry points — additive only.

Build
─────
• cargo check passes cleanly with rust 1.88.0 (4 pre-existing warnings
  unrelated to this change).
• cargo test blocked by a pre-existing soroban-env-host rand_core version
  conflict that exists on main before this commit.

Closes #[fractional-asset-wrapping]
Execution limit: O(1) arithmetic well under the 30 M instruction cap.
@github-actions
github-actions Bot merged commit 9aa1ad5 into Sahara-Pay:main Aug 21, 2026
2 checks passed
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.

Implement fractional asset wrapping for tokenized fractional assets

1 participant