Normal behavior:
SoulboundProfileNFT is intended to be an ERC721 soulbound, so it cannot be moved in any way once minted. The profile identity must remain permanently tied to one address.
Issues:
The contract does not override the entire ERC721 transfer path. One of the safeTransferFrom overloads is still active, so tokens can still be transferred, making the NFTs not truly soulbound and violating the identity invariant.
Likelihood:
Reason 1: Any ERC721 holder can call safeTransferFrom(address,address,uint256) directly, because this function is publicly available from OpenZeppelin ERC721.
Reason 2: The transfer will be successful because there is no revert to the overload.
Impact:
Impact 1: The profile NFT can be moved to another address, so it is no longer soulbound.
Impact 2: The “1 address = 1 immutable profile identity” invariant is broken, potentially breaking identity assumptions in other contracts that rely on this NFT.
Explanation:
SoulboundProfileNFT only partially blocks ERC721 transfer paths.
Even though transferFrom and one overload safeTransferFrom have been overridden to always revert, the other overload safeTransferFrom(address,address,uint256) is still available from the OpenZeppelin ERC721 implementation and is not blocked.
As a result, the token owner can still move the profile NFT using the overload, so the token is not truly soulbound and the identity invariant is broken.
Why This Works:
OpenZeppelin ERC721 exposes two overloads of safeTransferFrom
The contract only overrides:
The overload below remains callable and does not revert:
To effectively make the NFT soulbound, all transfer paths (including both safeTransferFrom overloads and transferFrom) must be blocked. Since the contract uses OpenZeppelin v5.x logic, the most robust way to do this is by overriding the internal _update function:
Note: This single override replaces the need for manual overrides of transferFrom and both safeTransferFrom overloads.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.