SoulboundProfileNFT overrides transferFrom() and safeTransferFrom() to revert, but approve() and setApprovalForAll() are inherited from ERC721 without override. Users can set approvals that can never be exercised.
Calling approve(spender, tokenId) and setApprovalForAll(operator, true) both succeed and emit Approval/ApprovalForAll events. The approved spender can never actually transfer the token because transferFrom and safeTransferFrom always revert. The on-chain approval state is misleading — it suggests the token is tradeable when it is not.
Likelihood:
Any token holder can call approve() or setApprovalForAll(). Marketplace integrations or wallets that auto-approve operators (like OpenSea's Seaport) will call these functions as part of their standard flow.
Impact:
Users waste gas on approvals that can never be exercised. Indexers and marketplaces tracking approvals show the token as "approved for transfer" when it is non-transferable, creating misleading on-chain state that conflicts with the soulbound design.
The test shows that both approve() and setApprovalForAll() succeed and update on-chain state, but the approved operator still cannot transfer. The approval is set but useless — gas is wasted and the state is misleading.
Override both functions to revert with the same error used for transfers. This makes the soulbound restriction complete — not just blocking transfers but also blocking the approval step, so users get immediate feedback that the token is non-transferable.
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.