Skip to content

test(drive-abci): add token supply edge-case coverage#3849

Open
thephez wants to merge 5 commits into
v3.1-devfrom
test/token-supply-edge-cases
Open

test(drive-abci): add token supply edge-case coverage#3849
thephez wants to merge 5 commits into
v3.1-devfrom
test/token-supply-edge-cases

Conversation

@thephez

@thephez thephez commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Issue being fixed or feature implemented

Token supply handling lacked coverage for several edge cases (exact max_supply boundary, burning below base_supply, burning to zero, destroy-frozen-funds supply accounting, zero/i64::MAX base_supply, etc.). While adding that coverage, two real gaps surfaced:

  1. base_supply > max_supply is accepted at contract creation. There is no creation-time guard comparing the two (only base_supply > i64::MAX is rejected). The token is born already over its cap, base_supply is immutable, so every subsequent mint is permanently blocked by TokenMintPastMaxSupplyError. Tracked in base_supply > max_supply is accepted at token contract creation, permanently blocking mints #3850
  2. Minting past i64::MAX on a token with max_supply == None returns an InternalError instead of a graceful consensus error. The mint validation's supply check is wrapped in if let Some(max_supply) = ..., so the uncapped case has no validation-layer guard and is only caught by the low-level Drive checked_add. Tracked in Minting past i64::MAX on an uncapped token returns InternalError instead of a consensus error #3848.

This PR is tests only — no production behavior changes. The two gaps are documented (see below) for follow-up fixes.

What was done?

Added ABCI state-transition tests under .../batch/tests/token/:

  • Mint: mint to exactly max_supply (succeeds), one over (fails, full TokenMintPastMaxSupplyError payload asserted), unbounded mint when max_supply == None, mint from zero base_supply, mint from zero to exact max.
  • Burn: burn below base_supply (allowed by design), burn entire supply to zero then mint again.
  • Destroy frozen funds: total supply reduced to zero, and decremented by exactly the destroyed amount (existing tests never asserted total supply).
  • Config update: set max_supply equal to current supply (boundary, succeeds), raise max_supply then mint into the new headroom.

Documenting the two gaps:

  • test_data_contract_creation_with_base_supply_over_max_supply_should_cause_error (in data_contract_create) — runs a real DataContractCreateTransition and asserts the intended rejection. #[ignore]d because it fails on current code; it is the regression target for adding the creation-time guard.
  • test_token_mint_with_max_i64_base_supply_then_overflow_returns_internal_error_without_mutating_supply
    — a characterization test pinning the current InternalError-without-mutation behavior (gap feat: enable mainnet for dashmate #2). Named to make clear it is not the desired long-term API; it should break (intentionally) when the validation guard is added.

How Has This Been Tested?

  • cargo test -p drive-abci for the token and data_contract_create::tests::tokens modules: all executable tests pass (200 + 21), with exactly one #[ignore]d test (the creation-guard regression target).
  • Verified the ignored test fails as intended under --ignored (proving the gap is real and the assertion non-vacuous).
  • cargo fmt -p drive-abci clean.

Breaking Changes

None — tests only.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • Tests
    • Added token burn tests covering burns below base supply and burning entire supply then minting.
    • Added token config update tests for setting max supply to current supply and raising max supply then minting.
    • Added tests for destroying frozen funds with total-supply adjustments and account state checks.
    • Added extensive token mint boundary tests (max supply limits, None max, base_supply edge cases, overflow).
    • Added ignored regression test for invalid supply-config creation.

thephez and others added 2 commits June 10, 2026 13:04
Add ABCI state-transition tests for token supply edge cases that were previously untested: exact max_supply boundary (mint to exactly the cap and one over), unbounded minting when max_supply is None, minting from a zero base_supply, burning below base_supply, burning the entire supply then minting again, and destroy-frozen-funds reducing total supply to zero and by the destroyed amount.

Add config-update coverage for setting max_supply equal to the current supply and for the raise-max-then-mint-into-headroom lifecycle, with full TokenMintPastMaxSupplyError payload assertions.

Document two real gaps via #[ignore]d tests asserting intended behavior: base_supply > max_supply is accepted at contract creation (no creation-time guard; the token is born over its cap and base_supply is immutable, so every mint is then blocked), and minting past i64::MAX on a max_supply=None token surfaces as an InternalError from the Drive checked_add guard rather than a graceful consensus rejection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename the i64::MAX mint-overflow test to advertise that it characterizes current behavior (returns InternalError without mutating supply) rather than asserting a desired long-term API. Add a CHARACTERIZATION TEST note explaining that when a validation-layer guard for max_supply=None is added, this test is expected to break as the signal to update it to the graceful-rejection behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thephez thephez requested a review from QuantumExplorer as a code owner June 10, 2026 17:17
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe03a322-7e87-4edd-9924-d94cc22a23ca

📥 Commits

Reviewing files that changed from the base of the PR and between 8c1fedf and 6354960.

📒 Files selected for processing (1)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs

📝 Walkthrough

Walkthrough

Adds multiple new token tests: minting boundary cases, burning invariants, config-update scenarios, frozen-funds destruction tests, and an ignored data-contract creation regression. No production code changes.

Changes

Token Operations Test Coverage

Layer / File(s) Summary
Token minting boundary conditions
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/mint/mod.rs
Six tests covering mint to exact max_supply, one-over-max rejection (TokenMintPastMaxSupplyError), unbounded minting when max_supply == None, base_supply == 0 initialization and minting, mint-to-max-from-zero then one-over rejection, and overflow characterization when base_supply == i64::MAX.
Token burning edge cases
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/burn/mod.rs
Two tests: burning below original base_supply updates both identity balance and total supply (can drop below base), and burning entire supply leaves total supply as Some(0) so subsequent minting restores supply and balances.
Token configuration updates
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/config_update/mod.rs
Two tests: setting max_supply equal to current total supply succeeds and persists, and raising max_supply after hitting cap enables a subsequent mint into the new headroom (while a prior mint at cap fails).
Frozen funds destruction
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/destroy_frozen_funds/mod.rs
Imports expanded and two tests added: destroying frozen funds to zero total supply and destroying frozen funds that decrement total supply; Adds private process_and_commit_success test helper.
Data contract creation validation
packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs
Ignored regression test added that constructs a contract with base_supply > max_supply, processes the creation transition expecting consensus rejection, commits, and verifies the token was not created (fetch_token_total_supply == None).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Suggested reviewers

  • thepastaclaw
  • QuantumExplorer

Poem

🐰
I hopped through tests both big and small,
Burned and minted, watched totals fall,
Froze some funds, then swept them clean,
Edge cases checked in every scene —
A rabbit cheers for coverage all!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test(drive-abci): add token supply edge-case coverage' directly and concisely describes the main change: adding new tests for token supply edge cases across multiple test modules in the drive-abci package.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/token-supply-edge-cases

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@thepastaclaw

thepastaclaw commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

✅ Review complete (commit 2c653ce)

@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.73%. Comparing base (f4ed60f) to head (2c653ce).
⚠️ Report is 2 commits behind head on v3.1-dev.

Additional details and impacted files
@@            Coverage Diff            @@
##           v3.1-dev    #3849   +/-   ##
=========================================
  Coverage     70.73%   70.73%           
=========================================
  Files            20       20           
  Lines          2788     2788           
=========================================
  Hits           1972     1972           
  Misses          816      816           
Components Coverage Δ
dpp ∅ <ø> (∅)
drive ∅ <ø> (∅)
drive-abci ∅ <ø> (∅)
sdk ∅ <ø> (∅)
dapi-client ∅ <ø> (∅)
platform-version ∅ <ø> (∅)
platform-value ∅ <ø> (∅)
platform-wallet ∅ <ø> (∅)
drive-proof-verifier ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Tests-only PR adding well-targeted token supply edge-case coverage and two characterization tests for documented gaps (#3848, #3850). Verified the new tests against the production code: assertions match current behavior and the helpers mirror the established patterns. One in-scope suggestion: the ignored regression test for base_supply > max_supply should narrow its assertion to UnpaidConsensusError(BasicError(_)) so it actually enforces the intended validation stage when the fix lands.

🟡 1 suggestion(s)

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs`:
- [SUGGESTION] packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs:1764-1768: Ignored regression test accepts too broad a class of errors
  `test_data_contract_creation_with_base_supply_over_max_supply_should_cause_error` is the regression target for a future creation-time guard, but the assertion accepts either `UnpaidConsensusError` or any `PaidConsensusError`. A `base_supply > max_supply` violation is a contract-shape problem that the future guard should reject at basic structure validation (alongside the existing `base_supply > i64::MAX` check noted in the comment), which produces `UnpaidConsensusError(BasicError(_))`. As written, this test would still pass even if the fix only rejected the contract later in the paid execution path, defeating the regression intent. The `total_supply == None` assertion below proves the token was not created but not that rejection happened in the right stage.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Tests-only PR adding token supply edge-case coverage in drive-abci. The single prior finding from 8c1fedf (overly broad assertion in the ignored regression test) is FIXED at 6354960 — the assertion now requires UnpaidConsensusError(ConsensusError::BasicError(_)), locking the future fix to basic-structure validation. No new in-scope issues; documented production gaps (#3848, #3850) are explicitly tracked as out-of-scope follow-ups.

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.

Minting past i64::MAX on an uncapped token returns InternalError instead of a consensus error

2 participants