Skip to content

fix(open-market): minimum liquidity lock on pool creation (#1675) - #1754

Merged
Olowodarey merged 1 commit into
Arena1X:mainfrom
udeachudivine-spec:fix/issue-1675-minimum-liquidity-lock
Aug 27, 2026
Merged

fix(open-market): minimum liquidity lock on pool creation (#1675)#1754
Olowodarey merged 1 commit into
Arena1X:mainfrom
udeachudivine-spec:fix/issue-1675-minimum-liquidity-lock

Conversation

@udeachudivine-spec

@udeachudivine-spec udeachudivine-spec commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Closes #1642


Fixes the first-depositor share-inflation / full-drain vulnerability in add_liquidity's bootstrap branch.

Changes:

  • Add isqrt_i128() private helper (Babylonian method, i128 flavour of the existing isqrt_u128 used for IL math)
  • Bootstrap branch now computes:
    product = per_outcome_amount.checked_mul(per_outcome_amount)
    initial_liquidity = isqrt_i128(product)
    lp_tokens_to_mint = initial_liquidity - MIN_LIQUIDITY (1_000)
    total_supply is set to initial_liquidity so MIN_LIQUIDITY is
    permanently counted but never credited to any account
  • Dust deposits where isqrt(a*b) <= MIN_LIQUIDITY are rejected with
    StakeTooLow (error enum is at its 50-case XDR cap; no new variant
    can be added — StakeTooLow is semantically the closest fit)
  • All arithmetic uses checked_mul / checked_sub / checked_add only;
    no raw operators, no unwrap/expect

Tests:

  • test_first_deposit_locks_minimum_liquidity (new)
  • test_dust_deposit_rejected (new)
  • test_full_drain_prevented (new)
  • Updated 8 existing tests whose assertions assumed the old 1:1
    bootstrap behaviour; logic is correct, only expected values changed

Fixes the first-depositor share-inflation / full-drain vulnerability
in add_liquidity's bootstrap branch.

Changes:
- Add isqrt_i128() private helper (Babylonian method, i128 flavour of
  the existing isqrt_u128 used for IL math)
- Bootstrap branch now computes:
    product          = per_outcome_amount.checked_mul(per_outcome_amount)
    initial_liquidity = isqrt_i128(product)
    lp_tokens_to_mint = initial_liquidity - MIN_LIQUIDITY  (1_000)
  total_supply is set to initial_liquidity so MIN_LIQUIDITY is
  permanently counted but never credited to any account
- Dust deposits where isqrt(a*b) <= MIN_LIQUIDITY are rejected with
  StakeTooLow (error enum is at its 50-case XDR cap; no new variant
  can be added — StakeTooLow is semantically the closest fit)
- All arithmetic uses checked_mul / checked_sub / checked_add only;
  no raw operators, no unwrap/expect

Tests:
- test_first_deposit_locks_minimum_liquidity  (new)
- test_dust_deposit_rejected                  (new)
- test_full_drain_prevented                   (new)
- Updated 8 existing tests whose assertions assumed the old 1:1
  bootstrap behaviour; logic is correct, only expected values changed
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
insight-arena-4rll Ready Ready Preview Aug 27, 2026 3:37pm

@udeachudivine-spec

Copy link
Copy Markdown
Contributor Author

close #1675

@Olowodarey
Olowodarey merged commit 817f9bf into Arena1X:main Aug 27, 2026
4 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.

[Backend] — User Follows Feed Endpoint

2 participants