Skip to content

feat: add graduated bonding curve with supply milestones (#829) - #849

Open
ayomustap wants to merge 3 commits into
accesslayerorg:mainfrom
ayomustap:Add-graduated-bonding-curve
Open

feat: add graduated bonding curve with supply milestones (#829)#849
ayomustap wants to merge 3 commits into
accesslayerorg:mainfrom
ayomustap:Add-graduated-bonding-curve

Conversation

@ayomustap

Copy link
Copy Markdown

Summary

Implements a graduated bonding curve (issue #829): a configurable pricing schedule where the bonding curve exponent switches at configurable supply milestones, allowing creators to steepen price growth as supply grows.

Closes #829

What changed

Graduated curve feature

  • set_graduated_curve(env, creator, milestones) — a creator-authorized entrypoint that configures the curve as a list of (supply_threshold, exponent) milestone pairs.
    • Requires the key creator's auth.
    • Requires the creator to be registered.
    • Panics with CurveConfigError::CurveAlreadyActive if any keys have already been sold (read_creator_supply != 0), enforcing that the curve must be set before sales start.
    • Validates exponents are in 1..=5 (InvalidExponent).
    • Validates milestones are in strictly ascending supply-threshold order (InvalidMilestoneOrder).
    • Rejects an empty milestone list (EmptyMilestones).
    • Rejects an unregistered creator (NotRegistered).
  • get_graduated_curve(env, creator) — read-only view; returns the configured milestones or an empty vector.
  • Pricing integrationcompute_bonding_curve_price now takes the graduated curve into account (highest precedence): it selects the exponent for the current supply via graduated_exponent_for_supply (using the last milestone whose threshold <= supply, otherwise the base exponent 1) before falling back to the existing CurveExponent/preset path.
  • CurveConfigError — a new error enum because ContractError was already at Soroban's 50-variant cap. Variants are appended at the end of their enum to preserve ABI discriminants.
  • Eventgraduated_curve_configured (GRADUATED_CURVE_CONFIGURED_EVENT_NAME) emitted with payload GraduatedCurveConfiguredEvent { creator, milestones, ledger }. Event fields are appended (not reordered) for schema stability.
  • StorageDataKey::GraduatedCurve(Address) variant with a graduated_curve(creator) storage helper.

Tests

  • Added creator-keys/src/test_graduated_curve.rs with acceptance tests covering:
    • Configuration by the creator and successful milestone-based price stepping.
    • CurveAlreadyActive panic when configuration is attempted after a sale has occurred (test sets a high circuit-breaker threshold before buying so supply becomes > 0).
    • Validation failures: invalid exponent, non-ascending milestones, empty milestones.
    • get_graduated_curve view + the graduated_curve_configured event emission.
    • The graduated-curve price override vs. the base curve.

Build/completeness repair (required to build & test the feature)

The base branch (f251b81) did not compile — it had an unclosed delimiter plus many pre-existing compile errors from a corrupted merge. These had to be repaired for the feature to build and be validated without regressions:

  • Closed the unclosed brace in the buy_key_with_referrer circuit-breaker block (root cause of the unclosed delimiter).
  • Restored the threshold_pct read (unwrap_or(30)) in the circuit-breaker logic.
  • Removed duplicated definitions: FEE_COLLECTED_EVENT_NAME/LOCKUP_BLOCKED_EVENT_NAME and their topic/event types, duplicate RoyaltyConfig/CurveExponent DataKey variants, duplicate holder_cap_bps/last_buy_timestamp storage helpers, and the first duplicate credit_staking_rewards_pool.
  • Added missing items: ContractError::GlobalTradingHalted/FreezeQuantityExceedsBalance, several DataKey variants, structs (StakingKey, StakePosition, StakingRewardsState, StakeExit, StakeRewardClaim, AuctionConfig), storage helpers, AuctionPurchaseEvent, and the StakingKey import.
  • Reconciles the staking rewards pool storage to consistently use StakingRewardsState between fee crediting (credit_staking_rewards_pool) and the staking entrypoints, which previously wrote/read conflicting types to the same key.
  • Added use soroban_sdk::testutils::Ledger to tests/launch_penalty.rs (a pre-existing compile fix unrelated to the feature).

Verification

  • cargo build -p creator-keys — compiles (only a pre-existing final_proceeds unused-assignment warning remains, untouched/out of scope).
  • cargo test -p creator-keys --lib134 passed, 0 failed, including the new test_graduated_curve tests and the previously-failing staking lifecycle test.

Note on remaining pre-existing breakage

Some integration tests under creator-keys/tests/ (co_creator_removal, prelaunch_auction, auction_bonding_curve_transition, staking_reward_claim) still fail to compile because they reference features (e.g. remove_co_creator, configure_auction, get_stake_unlock_ledger, and related event types) that were never implemented/merged into lib.rs in the base. These are pre-existing, out of scope for this issue, and were already non-compiling at the baseline.

…org#829)

Implement a configurable graduated bonding curve where the pricing exponent
switches at configurable supply milestones. Adds:

- set_graduated_curve: creator-authorized config of (supply_threshold, exponent)
  milestone pairs; panics with CurveAlreadyActive once sales have started.
- get_graduated_curve: read-only view of configured milestones.
- compute_bonding_curve_price now prefers the graduated curve and selects the
  exponent for the current supply before falling back to CurveExponent/presets.
- CurveConfigError enum (CurveAlreadyActive, InvalidExponent, InvalidMilestoneOrder,
  EmptyMilestones, NotRegistered).
- GRADUATED_CURVE_CONFIGURED_EVENT_NAME + GraduatedCurveConfiguredEvent +
  graduated_curve_configured_topics.
- test_graduated_curve acceptance tests.

Also repairs the non-compiling baseline in lib.rs/events.rs so the feature
can build: closes the unclosed brace in the buy circuit breaker, restores the
threshold_pct read, removes duplicate definitions (events, DataKey variants,
storage helpers, credit_staking_rewards_pool), adds missing ContractError
variants, DataKey variants, structs, storage helpers, and events, and adds
missing testutils::Ledger imports. Reconciles the staking rewards pool storage
(StakingRewardsState) between fee crediting and the staking entrypoints.
@drips-wave

drips-wave Bot commented Sep 1, 2026

Copy link
Copy Markdown

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

@Chucks1093

Copy link
Copy Markdown
Member

Fix MC

@ayomustap

Copy link
Copy Markdown
Author

@Chucks1093 fixed

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.

Add a graduated bonding curve that switches steepness at configurable supply milestones

2 participants