You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Add unit tests for pause blocking sell transactions
2
+
3
+
Closes #727
2
4
3
-
Fixes the TTL extension logic so that a `TTL_EXTENDED_EVENT_NAME` event is only emitted when the creator's storage TTL actually needs extension (remaining TTL drops below `TTL_EXTENSION_THRESHOLD`). Adds an integration test confirming no event is emitted when TTL is healthy.
5
+
## Summary
4
6
5
-
Closes #<!-- TODO: insert issue number -->
7
+
Add dedicated integration tests confirming the emergency pause correctly blocks sell transactions and verifies that all contract state remains consistent after blocked sell attempts.
6
8
7
-
## Problem
9
+
## Motivation
8
10
9
-
The `extend_creator_ttl` function unconditionally emitted a `ttl_ext` event on every successful buy or sell, even when the creator's storage TTL was already well above the minimum threshold. This polluted event logs with noisy, unnecessary events that indexers and off-chain consumers had to filter out.
11
+
The emergency pause mechanism was originally tested primarily for buy transactions. While some existing tests touch sell under pause, there was no focused test suite that comprehensively validates the sell-pause lifecycle against all three acceptance criteria from the issue. This PR fills that gap with a dedicated test file.
10
12
11
13
## Changes
12
14
13
-
### `creator-keys/src/lib.rs`
15
+
### New file: `creator-keys/tests/pause_blocks_sell_transactions.rs`
14
16
15
-
-**Added `TTL_EXTENSION_THRESHOLD` constant** (`100` ledgers) — the minimum remaining TTL below which a TTL extension event is emitted.
16
-
-**Added `DataKey::CreatorTtlLiveUntil(creator)`** — a per-creator `u32` recording the absolute live-until ledger the contract last set for the creator profile key. The Soroban SDK does not expose TTL reads to contract code, so this tracked value is what `extend_creator_ttl` uses to decide whether to emit the event.
17
-
-**Modified `extend_creator_ttl`** to:
18
-
1. Derive the remaining TTL from `CreatorTtlLiveUntil` and evaluate `ttl::should_extend(remaining, TTL_EXTENSION_THRESHOLD)`.
19
-
2. Always call `extend_ttl` on all creator-scoped storage keys — the Soroban SDK call is a no-op when TTL is already healthy, preserving the existing on-chain behavior.
20
-
3. Only publish the `TTL_EXTENDED_EVENT_NAME` event when the check above returns `true`, then update the tracked live-until.
21
-
-**Write-time TTL alignment**: new entries start with the network-default TTL, which can be much shorter than `CREATOR_TTL_LEDGERS` on fresh networks. `register_creator` now forces the full `CREATOR_TTL_LEDGERS` window on the creator profile, curve preset, and tracked live-until; `set_key_price`, the buy path, and dividend settlement grant the same full window to `KeyPrice`, `KeyBalance(creator, holder)`, and the dividend checkpoint/pending keys.
17
+
Five new integration tests covering every acceptance criterion:
22
18
23
-
### `creator-keys/tests/ttl_extension_on_buy.rs`
19
+
| Test | Acceptance Criterion |
20
+
|---|---|
21
+
|`test_sell_panics_with_protocol_paused_when_contract_is_paused`| Sell panics with `ProtocolPaused` when paused |
22
+
|`test_sell_succeeds_after_resume`| Sell succeeds immediately after unpause |
23
+
|`test_holder_count_unchanged_after_blocked_sell`| Holder count, supply, and key balance unchanged after blocked sell |
24
+
|`test_supply_unchanged_after_blocked_sell_with_multiple_holders`| Multi-holder variant — both holders' state unchanged after concurrent blocked sells |
-**Added `test_no_ttl_extension_event_when_ttl_healthy`** integration test that:
26
-
- Registers a creator with TTL at max (~6.3M ledgers remaining).
27
-
- Asserts TTL ≥ 2× `TTL_EXTENSION_THRESHOLD`.
28
-
- Executes a buy without advancing the ledger.
29
-
- Asserts **no**`ttl_ext` event is present among emitted events.
30
-
- Asserts a `buy` event **is** present confirming the transaction succeeded.
31
-
- Asserts creator storage TTL is unchanged after the buy.
27
+
## Acceptance Criteria Verification
32
28
33
-
## Acceptance Criteria
29
+
- ✅ **Sell panics with `contract_paused` when paused** — `test_sell_panics_with_protocol_paused_when_contract_is_paused` asserts `Err(Ok(ContractError::ProtocolPaused))` on sell attempt while paused.
30
+
- ✅ **Sell succeeds after resume** — `test_sell_succeeds_after_resume` pauses, unpauses, then confirms sell returns the correct new supply.
31
+
- ✅ **State unchanged after blocked sell** — `test_holder_count_unchanged_after_blocked_sell` and `test_supply_unchanged_after_blocked_sell_with_multiple_holders` snapshot `supply`, `holder_count`, and `key_balance` before the blocked sell and assert all are identical afterward.
34
32
35
-
| Criteria | Status |
36
-
|---|---|
37
-
| No TTL extension event emitted when TTL is above threshold | ✅ |
- They advance the ledger to near expiry before the first buy, so `should_extend` returns `true` and the event is still emitted.
51
-
- The second-buy-same-ledger scenario doesn't assert event presence/absence on the second buy.
52
-
-`extend_ttl` SDK calls happen unconditionally — only event emission is gated.
53
-
54
-
## Checklist
55
-
56
-
-[x] Linked issue or backlog item
57
-
-[x] Added or updated `creator-keys` unit/integration tests for every changed contract behavior, including failure paths for new or reachable `ContractError` variants
58
-
-[ ] Ran `cargo fmt --all -- --check`, `cargo clippy --workspace --all-targets -- -D warnings`, and `cargo test --workspace`, or explained exactly why a command was not run
59
-
-[x] Reviewed persistent storage changes against `docs/storage-key-invariants.md`; any storage layout change includes a migration/backward-compatibility note
60
-
-[x] Confirmed event names, topic order, payload field order, and field meanings remain compatible with `docs/contract-event-conventions.md`, or documented the breaking change and versioning plan
61
-
-[x] Updated docs for any changed public contract interface, read-only method, event schema, storage behavior, fee logic, or deployment workflow
62
-
-[x] Scope stays limited to one contract concern and does not include unrelated formatting, lockfile, generated artifact, or dependency changes
33
+
## CI Pre-Checks
34
+
35
+
All local CI checks pass:
36
+
- ✅ `cargo build` — compiles cleanly
37
+
- ✅ `cargo test` — all tests pass (including the 5 new ones)
38
+
- ✅ `cargo test --test pause_blocks_sell_transactions` — 5/5 passed
39
+
- ✅ No new clippy warnings introduced by this change
0 commit comments