Skip to content

fix: unclosed delimiter in circuit breaker code (creator-keys) - #841

Open
Ajibose wants to merge 4 commits into
accesslayerorg:mainfrom
Ajibose:fix/circuit-breaker-unclosed-delimiter
Open

fix: unclosed delimiter in circuit breaker code (creator-keys)#841
Ajibose wants to merge 4 commits into
accesslayerorg:mainfrom
Ajibose:fix/circuit-breaker-unclosed-delimiter

Conversation

@Ajibose

@Ajibose Ajibose commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Closes #838

Summary

cargo fmt --all -- --check failed on main with an unclosed-delimiter parse error in creator-keys/src/lib.rs, originating in the circuit breaker block inside buy_key_with_referrer. Two bugs, both introduced by PR #813, caused it:

  1. threshold_pct was referenced but never declared.
  2. The if pre_price > 0 && post_price > pre_price { ... } block was not properly nested inside the else branch of the let price = if in_auction { ... } else { ... }; expression, unbalancing the braces.

Changes

Modified files

  • creator-keys/src/lib.rs — in buy_key_with_referrer (circuit breaker block, ~line 2595):
    • Added the missing threshold_pct: u32 read from constants::storage::CIRCUIT_BREAKER_THRESHOLD, defaulting to 30 when unset (matching the existing set_circuit_breaker_threshold admin setter and its doc comment).
    • Fixed indentation/brace nesting so the price-jump check sits inside the else branch, alongside pre_price's computation, and does not run during the fixed-price auction phase (in_auction branch) — consistent with the existing comment above the if in_auction arm that the breaker only guards bonding-curve movement.

New files

  • creator-keys/tests/circuit_breaker_threshold.rs — integration test suite for the fix (see below).

Implementation details

The circuit breaker compares the bonding-curve price just before a buy (pre_price, at current supply) against the price just after (post_price, at supply + 1). If post_price > pre_price and the relative increase is >= threshold_pct percent, the trade is rejected with ContractError::CircuitBreakerTriggered and a CircuitBreakerTriggeredEvent { pre_price, post_price } is published. The threshold is admin-configurable via set_circuit_breaker_threshold (already present on main) and defaults to 30% when never set. Auction-phase buys (fixed auction price, in the if in_auction arm) are unaffected since the check only exists in the bonding-curve else arm.

Tests added (creator-keys/tests/circuit_breaker_threshold.rs)

  • test_circuit_breaker_default_threshold_blocks_large_price_jump — a 40% jump is rejected under the default 30% threshold, and supply is unchanged after the rejected call.
  • test_circuit_breaker_default_threshold_allows_small_price_jump — a 1% jump succeeds under the default threshold.
  • test_circuit_breaker_flat_curve_never_triggers — with no curve slope configured (flat price), several sequential buys all succeed since post_price > pre_price never holds.
  • test_circuit_breaker_custom_threshold_relaxes_a_previously_blocked_jump — a 40% jump is blocked by default, then succeeds once the admin raises the threshold to 50% via set_circuit_breaker_threshold.
  • test_circuit_breaker_custom_threshold_still_blocks_larger_jumps — a 60% jump is still blocked even after raising the threshold to 50%.
  • test_circuit_breaker_exact_threshold_boundary_triggers — an exact price_change * 100 == pre_price * threshold_pct match still triggers (the comparison is >=).
  • test_circuit_breaker_just_below_threshold_boundary_allows — one slope unit below that exact boundary passes.
  • test_circuit_breaker_triggered_event_reports_pre_and_post_price — asserts the emitted CircuitBreakerTriggeredEvent carries the correct pre_price/post_price payload.
  • test_circuit_breaker_does_not_block_second_buy_after_supply_advances_past_jump — two sequential small-jump buys both succeed, confirming the breaker re-evaluates per trade.

This complements the existing test_circuit_breaker_threshold_configuration_and_trigger in creator-keys/src/test_new_features.rs, which already exercised set_circuit_breaker_threshold and depended on threshold_pct being defined — it could not previously compile due to this bug.

How to test

cd creator-keys
cargo fmt --all -- --check   # no longer errors with "unclosed delimiter"
cargo test --test circuit_breaker_threshold

Known pre-existing issue (out of scope for this PR)

While verifying this fix I ran cargo build -p creator-keys (not just cargo fmt) and found the crate does not currently compile on main for reasons unrelated to this issue: duplicate definitions in creator-keys/src/events.rs (FeeCollectedEvent, LockupBlockedEvent, and their spec XDR) and creator-keys/src/lib.rs (credit_staking_rewards_pool, duplicate DataKey::RoyaltyConfig/CurveExponent variants), plus several types (AuctionConfig, StakingRewardsState, StakePosition, etc.) referenced in lib.rs without being in scope, and the configure_auction/cancel_auction/get_auction_config entrypoints (used by tests/prelaunch_auction.rs) being entirely absent from current lib.rs. This appears to stem from a bad merge resolution around PR #813 and predates this change — cargo fmt only parses syntax, so it never surfaced these. I did not attempt to fix it here since it's unrelated to the circuit breaker bug and is a much larger change; recommend filing a separate issue so cargo build/cargo test can be restored for the whole crate.

accesslayerorg#838)

The circuit breaker block in buy_key_with_referrer referenced an
undeclared threshold_pct variable and had the if-block improperly
nested outside the else branch of the auction/bonding-curve price
match, producing an unclosed delimiter that broke `cargo fmt --all --
check` on main.

Reads threshold_pct from CIRCUIT_BREAKER_THRESHOLD storage (defaulting
to 30) and nests the price-jump check correctly inside the else
branch so it only runs for bonding-curve buys, matching the existing
auction-bypass comment.
@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Ajibose 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 this PR.

Likely causes:

  • Compile error or missing function argument in the new implementation
  • cargo fmt not run before pushing
  • Clippy lint warning treated as a hard error

Steps to fix:

  1. Run cargo build locally and fix all errors
  2. Run cargo fmt --all and commit
  3. Push — CI will re-run

Ajibose and others added 3 commits September 3, 2026 23:17
CI's `cargo fmt --all -- --check` was failing on this branch due to
pre-existing unformatted code in events.rs, lib.rs,
test_staking_lifecycle.rs, and two integration test files (whitespace
only, no logic changes). Unblocks the verify workflow's Format check
step, which was flagged as red on PR accesslayerorg#841.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwmAGkhfFKYSaG6fmWxofz
The branch was based on a main commit that predates several later
merges. cargo fmt --all -- --check on CI runs against the merge of
this branch with the current main tip, which introduced two more
unformatted files (events.rs, test_issues_778_779_781_782.rs) not
present on the branch's original base. Format-only, no logic changes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SwmAGkhfFKYSaG6fmWxofz
@Ajibose

Ajibose commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the CI failure flagged above:

  • Format check: fixed. cargo fmt --all -- --check was failing on pre-existing unformatted code (whitespace only, no logic changes) — some of it already on the branch's base, some introduced because CI merges this branch against the live main tip, which had drifted since this branch was created (I merged current main in to pick that up too). Both fixed in 8f4414e and ff1c95f.
  • While investigating, confirmed current main (independent of this PR) currently has the same unclosed-delimiter/threshold_pct bug this PR fixes, just relocated by later merges — i.e. main is presently broken until this PR (or cargo fmt --check on main - unclosed delimiter in circuit breaker code #838) lands.
  • Clippy/Test: still red, but for a separate, pre-existing reason already called out in the PR description: creator-keys doesn't compile on main (100+ errors — duplicate event/type definitions, several ContractError/DataKey variants referenced but never declared, and the configure_auction/cancel_auction/get_auction_config entrypoints used by tests/prelaunch_auction.rs missing from lib.rs). This predates and is unrelated to the circuit breaker fix, and is out of scope here — recommend tracking it as a separate issue so cargo build/cargo test can be restored for the whole crate.

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.

cargo fmt --check on main - unclosed delimiter in circuit breaker code

2 participants