Skip to content

fix(factory): add create_pool boundary validations 47-50 - #596

Merged
ritaifeoluwa merged 13 commits into
SmartDropLabs:mainfrom
KidDev88:fix/create-pool-validation-540-543
Oct 22, 2026
Merged

ritaifeoluwa merged 13 commits into
SmartDropLabs:mainfrom
KidDev88:fix/create-pool-validation-540-543

Conversation

@KidDev88

Copy link
Copy Markdown
Contributor

Closes #540, Closes #541, Closes #542, Closes #543

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring (no functional or behavioral changes)
  • Performance improvement
  • Documentation update
  • Build / CI configuration change
  • Dependency update
  • Other:

Summary

create_pool / create_pools_batch still accepted several clearly invalid requests at the API boundary: an absurd negative min_stake_amount magnitude was silently rewritten to the dust default, a pool could be created with its own staking token as admin, a contract answering symbol but not balance passed asset validation, and an empty batch consumed admin auth while creating nothing. This PR adds four fail-fast boundary checks (validations 47–50) so each case returns a typed FactoryError before any conversion or deployment work.

Motivation / Context

Closes #540, Closes #541, Closes #542, Closes #543

These issues report a validation gap in the create_pool operation that can lead to invalid pool creation and put user funds at risk. Invalid input should be refused at the API boundary with a typed error rather than surviving into helper defaulting logic or pool deployment.

Changes

  • soroban/contracts/factory/src/lib.rs
    • Validation 47: reject raw min_stake_amount < -MAX_STAKE_AMOUNT before the non-positive defaulting logic, so i128::MIN and similar corrupt magnitudes are refused rather than silently becoming MIN_STAKE_AMOUNT
    • Validation 48: reject asset == admin — a pool administered by its own staking token cannot authorize pause/upgrade/multiplier changes
    • Validation 49: validate_asset now also probes SEP-41 balance, so a contract that answers only symbol cannot be registered as a stake asset
    • Validation 50: reject an empty create_pools_batch with a typed EmptyBatch error
  • soroban/contracts/factory/src/types.rs: add FactoryError::EmptyBatch = 20
  • soroban/contracts/factory/src/test.rs: SymbolOnlyToken mock (symbol without balance) and one regression test per new check
  • rustfmt applied across workspace crates so cargo fmt --all -- --check passes

Testing

  • cargo test -p factory --lib → 103 passed, 0 failed (98 pre-existing + 5 new)
  • New regression tests (each asserts the typed error and pool_count == 0):
    • test_create_pool_rejects_min_stake_amount_below_negative_max
    • test_create_pool_rejects_i128_min_min_stake_amount
    • test_create_pool_rejects_asset_equal_to_admin
    • test_create_pool_rejects_asset_without_balance_entry_point
    • test_create_pools_batch_rejects_empty_batch
  • cargo clippy -p factory --lib -- -D warnings — clean

Tradeoffs

  • The new checks reuse existing FactoryError variants (InvalidMinStakeAmount, InvalidAsset) except for EmptyBatch, keeping the on-chain error surface stable where possible.
  • Validation 47 bounds the magnitude of negative min_stake_amount at MAX_STAKE_AMOUNT, so small negatives like -5 still map to the documented dust default while i128::MIN is rejected.
  • Validation 48 is defense-in-depth for the transfer_admin path: the public create_pool entry points already validate the stored admin, but the shared create_pool_inner boundary now refuses the asset/admin collision explicitly.

Out of scope

  • The farming-pool WASM currently exceeds Soroban's 128 KiB contract-size limit (135 KiB before size optimization), which is a pre-existing issue on main unrelated to these validations. Tests were verified against a wasm-opt -Oz build of the same sources.
  • Pre-existing stub integration tests under soroban/contracts/factory/tests/ still do not compile (noted in fix(factory): add create_pool boundary validations 43-46 #590) and are unrelated to this change.
  • No change to parameter bounds themselves (MAX_STAKE_AMOUNT, MIN_LOCK_PERIOD, MAX_CREDIT_RATE, …).

Reject clearly out-of-range create_pool inputs at the API boundary with
typed FactoryErrors before any conversion or deployment work:

- Validation 47: reject raw min_stake_amount < -MAX_STAKE_AMOUNT before
  the non-positive defaulting path, so a corrupt magnitude such as
  i128::MIN is refused instead of silently rewritten to the dust default.
- Validation 48: reject a staking asset equal to the pool admin address,
  which would leave the pool administered by its own token contract and
  unable to authorize admin actions.
- Validation 49: require the SEP-41 balance entry point in addition to
  symbol when probing the staking asset, so half-implemented token
  interfaces cannot be registered as pool stake assets.
- Validation 50: reject an empty create_pools_batch request with a typed
  EmptyBatch error instead of consuming admin auth while creating nothing.
Add a SymbolOnlyToken mock that answers symbol but not balance, and one
regression test per new boundary check:

- test_create_pool_rejects_min_stake_amount_below_negative_max
- test_create_pool_rejects_i128_min_min_stake_amount
- test_create_pool_rejects_asset_equal_to_admin
- test_create_pool_rejects_asset_without_balance_entry_point
- test_create_pools_batch_rejects_empty_batch

Each asserts the typed FactoryError and that pool_count stays 0.
Pre-existing formatting drift in farming-pool, vesting-wallet, and the
factory integration-test stubs caused `cargo fmt --all -- --check` to
fail on main. Apply rustfmt so the CI formatting gate passes.
@netlify

netlify Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for sdcontracts ready!

Name Link
🔨 Latest commit dda6ebe
🔍 Latest deploy log https://app.netlify.com/projects/sdcontracts/deploys/6ad9f789bc816a9dc52be789
😎 Deploy Preview https://deploy-preview-596--sdcontracts.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@drips-wave

drips-wave Bot commented Oct 22, 2026

Copy link
Copy Markdown

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

@ritaifeoluwa
ritaifeoluwa merged commit 2960b15 into SmartDropLabs:main Oct 22, 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

2 participants