Skip to content

test(token): cover storage collisions during initialization - #650

Open
Rufai-Ahmed wants to merge 1 commit into
BCPathway:mainfrom
Rufai-Ahmed:test/486-storage-collisions-initialization
Open

test(token): cover storage collisions during initialization#650
Rufai-Ahmed wants to merge 1 commit into
BCPathway:mainfrom
Rufai-Ahmed:test/486-storage-collisions-initialization

Conversation

@Rufai-Ahmed

Copy link
Copy Markdown
Contributor

Closes #486

What this adds

contracts/token/src/storage_collisions.rs, a test-only module with 9 tests proving that initializing BcForgeToken cannot alias a storage slot. The only production change is the one #[cfg(test)] mod storage_collisions; line in lib.rs.

Coverage:

  • Re-initialization is rejected and leaves every slot intact. The second initialize is also called directly inside env.as_contract because a failed client invocation has its storage rolled back by the host, so the client-only version of these assertions passes even against an implementation that overwrites everything before returning the error.
  • initialize writes only its documented slots, enumerated across all four key enums in both the instance and persistent namespaces.
  • The frozen slot-name set. DataKey keys encode as the variant name plus arguments, so renaming a variant remaps a stored entry. DATA_KEY_SLOT_NAMES pins all 13 names against standalone literals, and the exhaustive data_key_name match makes adding or removing a variant a compile error.
  • The cross-module admin alias. crate::DataKey::Admin and bc_forge_admin::AdminKey::Admin are the same instance slot, covered in both the read and the write direction.
  • The guard slot. Guarded entry points write a bare Symbol into persistent storage via reentrancy_guard!, the one key family that is not a #[contracttype] enum. initialize takes no guard, which is why the role grant is its only persistent write.

Verification

Every test was mutation-checked rather than assumed correct. Mutations applied to production code and confirmed to break the suite, then reverted:

Mutation Tests that fail
has_admin re-init guard removed from initialize reinitialize
initialize gutted to a no-op 7 of 9
initialize also writes DataKey::Treasury documented-slots
initialize also writes to persistent storage documented-slots
DataKey::Treasury renamed, identifiers propagated frozen-set (sole killer)
AdminKey::Admin renamed both alias tests
LifecycleKey::Paused renamed to collide with DataKey::Supply cross-module overlap
write_allowance builds Allowance(from, from) per-address independence
GuardExit::drop stops releasing the guard guard slot

cargo test -p bc-forge-token 41 passed, cargo fmt --all -- --check clean, cargo clippy -p bc-forge-token --all-targets --all-features -- -D warnings clean.

Two things worth your call, no code changed for either

  1. contracts/token/src/lib.rs:46 says DataKey::PendingAdmin is "retained to preserve storage discriminant order". A #[contracttype] enum key encodes as the variant name, not a discriminant, so reordering variants is safe and it is renaming that is dangerous. Verified: moving a variant's position produced a byte-identical ledger key. Keeping PendingAdmin costs nothing, but the stated reason is misleading.

  2. contracts/admin/src/lib.rs states "The AdminKey enum is a distinct type from any other contract's DataKey enum, ensuring zero slot overlap". That is not true for the token: DataKey::Admin and AdminKey::Admin resolve to the same instance slot. The tests document the current behaviour rather than change it. The same unused DataKey::Admin exists in wrapper and vesting.

Both look like separate issues rather than drive-by edits here.

Adds a test-only module proving initialization cannot alias a storage
slot. Covers re-initialization leaving every slot intact, the frozen set
of DataKey slot names, the DataKey::Admin / AdminKey::Admin cross-module
alias, and the instance/persistent namespace split.

Closes BCPathway#486
@drips-wave

drips-wave Bot commented Aug 24, 2026

Copy link
Copy Markdown

@Rufai-Ahmed 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

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.

[Testing] Test: Storage collisions during initialization

1 participant