Skip to content

Fix five remaining bugs from security review#265

Merged
joshuahannan merged 2 commits intomasterfrom
fix-remaining-bugs
Mar 12, 2026
Merged

Fix five remaining bugs from security review#265
joshuahannan merged 2 commits intomasterfrom
fix-remaining-bugs

Conversation

@joshuahannan
Copy link
Copy Markdown
Contributor

@joshuahannan joshuahannan commented Mar 11, 2026

Summary

  • setup_account_from_address.cdc — Added early-return guard before storage.save so the transaction is idempotent (previously panicked if called on an account that already had a collection). Also adds unpublish before publish and the missing BorrowValue entitlement.
  • NFTForwarding.cdc — Removed redundant ?? nil from borrowRecipientCollection; Capability.borrow() already returns an optional, making the nil-coalescing a dead no-op.
  • ExampleNFT.cdc — Added explicit type guard to createEmptyCollection so callers passing an unsupported nftType get a clear panic message instead of silently receiving an ExampleNFT.Collection.
  • ExampleNFT.cdc — Commented out the emitNFTUpdated block in deposit that was already marked "testing only". The code is preserved as a commented example so the pattern is still visible.
  • MaliciousNFT.cdc — Added a clear comment to the intentional path/type collision in resolveContractView explaining which vulnerability class the contract is meant to demonstrate.

Test plan

  • testSetupAccountFromAddressIsIdempotent — calls setup_account_from_address.cdc twice on the same account and verifies it succeeds both times
  • testCreateEmptyCollectionRejectsWrongType — verifies createEmptyCollection panics with a descriptive message when passed an unsupported type
  • All 24 Cadence tests pass (make ci)
  • All Go tests pass

🤖 Generated with Claude Code

Comment thread contracts/ExampleNFT.cdc
Comment on lines +290 to +292
panic("ExampleNFT.createEmptyCollection: The requested nftType <"
.concat(nftType.identifier)
.concat("> is not supported by this contract. Only ExampleNFT.NFT tokens are supported."))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe use string interpolation here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm planning on making another PR to update all the strings to use interpolation. 👍

Comment thread transactions/setup_account_from_address.cdc Outdated
1. setup_account_from_address.cdc: add early-return guard before
   storage.save so the transaction is idempotent. Without this it
   panicked when called on an account that already had a collection.
   Also adds unpublish before publish and the BorrowValue entitlement.

2. NFTForwarding.cdc: remove redundant `?? nil` from
   borrowRecipientCollection — Capability.borrow() already returns
   an optional, making the nil-coalescing a no-op.

3. ExampleNFT.cdc: add explicit type guard to createEmptyCollection
   so callers passing an unsupported nftType get a clear panic message
   instead of silently receiving an ExampleNFT.Collection.

4. ExampleNFT.cdc: comment out the emitNFTUpdated call in deposit
   that was marked "testing only". Leaves the code as a commented
   example so the pattern is visible but inactive by default.

5. MaliciousNFT.cdc: add an explicit comment explaining the
   intentional path/type collision in NFTCollectionData so it is
   clear to readers what vulnerability class the contract demonstrates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@joshuahannan joshuahannan merged commit 27e494f into master Mar 12, 2026
2 checks passed
@joshuahannan joshuahannan deleted the fix-remaining-bugs branch March 12, 2026 16:09
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.

2 participants