feat(contracts): implement fractional asset wrapping module - #617
Merged
github-actions[bot] merged 1 commit intoAug 21, 2026
Merged
Conversation
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.
3 tasks
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.
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) ──────────────────────────────────────────────────────────────
7a. prop_wrap_deterministic — same input → same shares
7b. prop_unwrap_deterministic — same input → same assets
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