feat(#fuzz): add fuzz targets for set_metadata and mint_tokens#834
Merged
Ejirowebfi merged 1 commit intoJun 24, 2026
Merged
Conversation
Adds fuzz_set_metadata and fuzz_mint_tokens targets to cover the two previously unfuzzed functions that handle user-supplied strings and amounts. Registers both in fuzz/Cargo.toml, wires them into the fuzz-testing.yml CI workflow (60 s each), and updates the README.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add Fuzz Targets for set_metadata and mint_tokens
Background
The token-factory contract already had fuzz coverage for create_token, fee_arithmetic, and burn. Two functions were left uncovered despite both accepting user-supplied inputs that could trigger panics:
set_metadata — accepts an unbounded metadata_uri: String and performs fee comparison arithmetic
mint_tokens — accepts an amount: i128 and runs a checked_add on supply tracking that can overflow
This PR closes that gap by adding one fuzz target per function, wiring them into CI, and documenting them.
What Changed
contracts/token-factory/fuzz/fuzz_targets/fuzz_set_metadata.rs (new)
Fuzzes the logic path inside set_metadata (lib.rs:463–504):
Area What is tested
URI string handling Arbitrary byte sequences are attempted as UTF-8 metadata URIs. Non-UTF-8 inputs return early, mirroring the SDK boundary rejection. Valid UTF-8 of any length and content is exercised.
Fee sufficiency guard fee_payment >= metadata_fee — verifies that when the guard passes, the fee remainder (fee_payment - metadata_fee) is always non-negative.
Duplicate-set path When attempt_duplicate is true, the idempotency branch is taken, confirming no arithmetic runs on the second call.
Fee distribution arithmetic Saturating mul/add operations that mirror distribute_fee are exercised to confirm they never panic.
contracts/token-factory/fuzz/fuzz_targets/fuzz_mint_tokens.rs (new)
Fuzzes the logic path inside mint_tokens (lib.rs:506–566):
Area What is tested
Amount validation amount <= 0 inputs trigger early return, matching the InvalidParameters error path.
Fee sufficiency guard fee_payment >= base_fee — verifies remainder is non-negative on pass.
checked_add overflow current_supply.checked_add(amount) — the exact expression from lib.rs:551. Overflow returns without panic; success path asserts new_total > current and new_total <= cap.
Max-supply cap enforcement Verifies new_total > cap returns before any mint occurs.
Supply monotonicity On the success path, total supply always increases by exactly amount.
Fee split distribution Two-recipient 50/50 split arithmetic (5,000 bps each) is exercised end-to-end with arbitrary fee_payment values to confirm no panic on extreme inputs.
contracts/token-factory/fuzz/Cargo.toml (modified)
Added two [[bin]] entries:
[[bin]]
name = "fuzz_set_metadata"
path = "fuzz_targets/fuzz_set_metadata.rs"
test = false
doc = false
[[bin]]
name = "fuzz_mint_tokens"
path = "fuzz_targets/fuzz_mint_tokens.rs"
test = false
doc = false
.github/workflows/fuzz-testing.yml (modified)
Added two new steps after the existing fuzz_burn step. Both run for 60 seconds with continue-on-error: true, consistent with the existing targets:
name: Run set_metadata fuzz target
working-directory: contracts/token-factory/fuzz
run: cargo +nightly run --release --bin fuzz_set_metadata -- -max_len=10000 -timeout=60 -max_total_time=60
continue-on-error: true
name: Run mint_tokens fuzz target
working-directory: contracts/token-factory/fuzz
run: cargo +nightly run --release --bin fuzz_mint_tokens -- -max_len=1000 -timeout=60 -max_total_time=60
continue-on-error: true
set_metadata uses max_len=10000 because the metadata URI has no length cap in the contract, so longer inputs are worth exercising.
contracts/token-factory/fuzz/README.md (modified)
Updated the overview list from 3 targets to 5
Added full documentation sections for fuzz_set_metadata and fuzz_mint_tokens covering focus area, what is tested, success criteria, and file path
Acceptance Criteria
Both fuzz targets compile under cargo +nightly build --release
Both targets run for 60 seconds without panics (verified locally)
fuzz-testing.yml CI workflow includes all five targets
README documents both new targets
How to Run Locally
cd contracts/token-factory/fuzz
set_metadata
cargo +nightly run --release --bin fuzz_set_metadata -- -max_len=10000 -timeout=60 -max_total_time=60
mint_tokens
cargo +nightly run --release --bin fuzz_mint_tokens -- -max_len=1000 -timeout=60 -max_total_time=60
closes #731