Skip to content

test: cover buy/sell total supply updates and KeysSold event supply (#736, #738, #739) - #746

Open
Yunusabdul38 wants to merge 3 commits into
accesslayerorg:mainfrom
Yunusabdul38:test/supply-and-keysold-event-736-738-739
Open

test: cover buy/sell total supply updates and KeysSold event supply (#736, #738, #739)#746
Yunusabdul38 wants to merge 3 commits into
accesslayerorg:mainfrom
Yunusabdul38:test/supply-and-keysold-event-736-738-739

Conversation

@Yunusabdul38

Copy link
Copy Markdown
Contributor

Description

Three Stellar Wave supply/event issues in this repo, one PR. Separate from #744 (issue #737), which is already open.

Contract change (#736)

KeysSoldEvent was the only trade event without a new_supply field — both KeysBoughtEvent and KeysBoughtBackEvent carry one. An indexer rebuilding supply from the trade stream therefore had nothing to read on a sell, so the field is added and populated from the post-sell profile supply.

That is the only production change in this PR; #738 and #739 are tests only.

Two places the issues and the contract disagree

Both are covered on whichever entrypoint actually enforces the rule, and called out in the test module docs:

"sell of 3 keys" / "buying 5 keys"buy_key and sell_key each move exactly one key per call; there is no amount parameter. So these are 3 and 5 calls, and quantity in the event stays 1.

#738's insufficient_supplysell_key cannot be asked for more than the supply, because it takes no amount; the balance guard fires first and returns InsufficientBalance, and selling past zero is refused rather than wrapping the u32. The contract's InsufficientSupply belongs to buyback, the sell-side path that does take an amount and rejects amount > supply. The tests assert both, so "cannot remove more keys than exist" is covered either way.

Test coverage

file tests covers
sell_event_seller_and_supply.rs 5 sells 3 of 10 and asserts the event's seller and new_supply (7) against both sell_key's return value and get_total_key_supply; a full sell-down to zero; the event not being attributed to an uninvolved holder; no event emitted on a sell rejected on balance or on slippage
buy_updates_total_supply.rs 8 1 key from supply 0 → 1; 5 buys on supply 10 → 15; sequential and interleaved buys across wallets; supply unchanged after buys rejected on underpayment, non-positive payment, the supply cap, and an unregistered creator
sell_updates_total_supply.rs 9 1 key from supply 5 → 4; full sell-down from 10 → 0; sells across two holders; selling past zero refused without underflow; buyback beyond supply rejected with InsufficientSupply; supply unchanged after sells rejected on balance, slippage, and an unregistered creator

Every supply case asserts the view against the value the call returned, after each individual call rather than only at the end.

Overlap with existing coverage

Worth being straight about: total_supply_per_creator.rs, key_supply.rs and supply_invariants.rs already cover parts of the happy paths in #738/#739. The genuinely uncovered gaps these add are the failed-buy supply invariance (supply_unchanged_after_failed_sell.rs covered only the sell side), the new_supply event field (previously only checkable via the return value), and the InsufficientSupply burn path.

Verification

step result
cargo fmt --all -- --check ✅ clean
cargo clippy --workspace --all-targets -- -D warnings ✅ no warnings
cargo test --workspace ✅ 177 test binaries, 0 failures (22 new tests)

…accesslayerorg#736)

`KeysSoldEvent` was the only trade event without a `new_supply` field —
`KeysBoughtEvent` and `KeysBoughtBackEvent` both carry one. An indexer
rebuilding supply from the trade stream therefore had nothing to read on a
sell, so this adds the field and asserts it against chain state.

The new integration test sells 3 of 10 keys and checks the event names the
selling wallet and reports supply 7, agreeing with both `sell_key`'s return
value and `get_total_key_supply`. It also walks a full sell-down to zero,
confirms the event is not attributed to an uninvolved holder, and confirms
no event is emitted when a sell is rejected on balance or on slippage.

`sell_key` sells one key per call, so the issue's 'sell of 3 keys' is three
calls and `quantity` stays 1.

Closes accesslayerorg#736
…rorg#739)

Adds a dedicated suite for the supply field `buy_key` writes: one key from
zero supply lands on 1, five buys on a supply of ten land on 15, and
sequential and interleaved buys from different wallets keep accumulating the
same counter. Every case asserts `get_total_key_supply` agrees with the
value `buy_key` returned, after each individual call.

The failed-buy half was the real gap — `supply_unchanged_after_failed_sell`
covers the sell side, but nothing covered the buy side. Supply is now
asserted unchanged after a buy rejected on underpayment, non-positive
payment, the supply cap and an unregistered creator.

`buy_key` buys one key per call, so 'buying 5 keys' is five calls. The
supply cap can only be set at registration, so the cap case registers its
own creator.

Closes accesslayerorg#739
…g#738)

Adds a dedicated suite for the supply field `sell_key` writes: one key from
a supply of five lands on 4, a full sell-down from ten lands on 0, and
supply drops on whichever holder sells. Every case asserts
`get_total_key_supply` agrees with the value `sell_key` returned. Supply is
also asserted unchanged after sells rejected on balance, on slippage and for
an unregistered creator.

On the issue's `insufficient_supply` criterion: `sell_key` takes no amount
and sells one key per call, so a wallet cannot ask it for more than the
supply — the balance guard fires first with `InsufficientBalance`, and
selling past zero is refused rather than wrapping the u32 supply. The
contract's `InsufficientSupply` belongs to `buyback`, the sell-side path
that does take an amount and rejects `amount > supply`. Both errors are
asserted so the 'cannot remove more keys than exist' rule is covered on
whichever entrypoint enforces it.

Closes accesslayerorg#738
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant