Skip to content

feat(#827): add slippage_check_passed event for non-None bounds - #846

Open
dedukpe wants to merge 2 commits into
accesslayerorg:mainfrom
dedukpe:feat/slippage-check-passed-event-827
Open

feat(#827): add slippage_check_passed event for non-None bounds#846
dedukpe wants to merge 2 commits into
accesslayerorg:mainfrom
dedukpe:feat/slippage-check-passed-event-827

Conversation

@dedukpe

@dedukpe dedukpe commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a SlippageCheckPassedEvent that is emitted when a buy or sell with a non-None max_price / min_proceeds bound passes the slippage check, giving downstream indexers visibility into slippage guard behavior.

Closes #827

Changes

New Event (slp_ok)

  • SLIPPAGE_CHECK_PASSED_EVENT_NAMEsymbol_short!("slp_ok")
  • SlippageCheckPassedEvent struct with fields:
    • creator_id: Address — creator whose key was traded
    • actual_amount: i128 — bonding-curve price (buy) or post-fee proceeds (sell) that was validated
    • bound: i128 — the caller-specified upper/lower bound that was satisfied
    • ledger: u32 — ledger sequence at the time of the trade

Emission Points

  • assert_buy_price_slippage — emits after a successful check when max_price is Some
  • assert_sell_proceeds_slippage — emits after a successful check when min_proceeds is Some
  • When the bound is None, no event is emitted (no performance cost)

Tests Added

Test Verifies
test_buy_emits_slippage_check_passed_when_bound_provided Event fires on buy with non-None max_price
test_buy_skips_slippage_event_when_bound_is_none No event on buy with None bound
test_sell_emits_slippage_check_passed_when_bound_provided Event fires on sell with non-None min_proceeds
test_sell_skips_slippage_event_when_bound_is_none No event on sell with None bound

Pre-existing Fixes

The main branch had a pre-existing unclosed delimiter in buy_key_with_referrer that masked ~75 compilation errors from incomplete merges. This PR also:

  • Re-indents the circuit breaker if block inside the else branch
  • Removes duplicate DataKey variants (RoyaltyConfig, CurveExponent)
  • Removes duplicate storage functions (holder_cap_bps, last_buy_timestamp)
  • Removes duplicate credit_staking_rewards_pool implementation
  • Adds minimal type stubs for incomplete staking/auction merges (AuctionConfig, StakingRewardsState, StakePosition, etc.)

Acceptance Criteria

  • Buy panics with SlippageExceeded when execution price exceeds max_price
  • Buy succeeds when execution price is at or below max_price
  • Sell panics with SlippageExceeded when execution price is below min_proceeds
  • Sell succeeds when execution price is at or above min_proceeds
  • None bounds skip the check entirely with no performance cost
  • slippage_check_passed event is emitted when a non-None bound is satisfied

Test Results

running 13 tests
test test_buy_emits_slippage_check_passed_when_bound_provided ... ok
test test_buy_skips_slippage_event_when_bound_is_none ... ok
test test_buy_slippage_max_price_u128_max_always_succeeds ... ok
test test_buy_slippage_boundary_exact_cost_and_exceeded_by_one_stroop ... ok
test test_buy_slippage_reverts_when_price_exceeds_max_price ... ok
test test_sell_emits_slippage_check_passed_when_bound_provided ... ok
test test_buy_slippage_max_price_zero_panics_unless_key_is_free ... ok
test test_sell_slippage_succeeds_when_proceeds_meet_or_exceed_min_proceeds ... ok
test test_slippage_exceeded_discriminant_is_16 ... ok
test test_sell_slippage_reverts_when_proceeds_below_min_proceeds ... ok
test test_buy_slippage_succeeds_when_price_at_or_below_max_price ... ok
test test_sell_skips_slippage_event_when_bound_is_none ... ok
test test_slippage_none_passthrough_preserves_existing_behavior ... ok
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

running 4 tests (boundary regression)
test test_buy_reverts_when_max_price_is_one_stroop_below ... ok
test test_buy_succeeds_when_max_price_equals_actual_price ... ok
test test_sell_succeeds_when_min_proceeds_equals_actual_proceeds ... ok
test test_sell_reverts_when_min_proceeds_is_one_stroop_above ... ok
test result: ok. 4 passed; 0 failed

dedukpe and others added 2 commits August 31, 2026 14:40
…e bounds

When a buy or sell with a non-None max_price/min_proceeds bound passes the
slippage check, emit a SlippageCheckPassedEvent so downstream indexers can
track that the caller's slippage guard was satisfied.

- Add SLIPPAGE_CHECK_PASSED_EVENT_NAME ("slp_ok") event constant
- Add SlippageCheckPassedEvent struct (creator_id, actual_amount, bound, ledger)
- Emit event in assert_buy_price_slippage and assert_sell_proceeds_slippage
- None bounds skip the event (and the check) entirely with no performance cost

Also fixes pre-existing compilation issues exposed by unclosed delimiter:
- Re-indent circuit breaker block inside else branch
- Remove duplicate DataKey variants (RoyaltyConfig, CurveExponent, etc.)
- Remove duplicate storage key functions (holder_cap_bps, last_buy_timestamp)
- Remove duplicate credit_staking_rewards_pool implementation
- Add missing type stubs for incomplete staking/auction merges
- Add 4 new tests verifying event emission behavior

Closes accesslayerorg#827

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

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

❌ CI Failed — verify (Contracts CI)

The verify check is failing on the slippage event feature.

Likely causes:

  • slippage_check_passed event struct not derived with the correct Soroban attributes (#[contracttype])
  • Event emitted inside a view function which is not allowed (view functions cannot write events)
  • Missing field in the event struct

Steps to fix:

  1. Confirm the event is emitted only in state-mutating functions (buy/sell), not view functions
  2. Ensure the event struct has #[contracttype] and #[derive(Clone)]
  3. Run cargo build and push

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 slippage protection parameter to the buy and sell functions preventing execution at worse-than-expected prices

2 participants