-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Description
In the Lesson 5 ZombieOwnership contract, a successful transfer does not clear the token’s per-token approval. As a result, an address that was approved before the transfer can still move the token after it changes hands. This seems worth pointing out so students think about approval clearing when implementing transfers.
Where it happens
ZombieOwnership._transfer updates ownership and emits Transfer, but never resets the approval for the moved tokenId.
Impact
A previously approved address can “steal back” the token after a sale:
Alice owns tokenId = 1, calls approve(Alice, 1).
Alice uses standard transfer to transferFrom(Alice, Bob, 1).
Because approval wasn’t cleared, Alice can immediately call transferFrom(Bob, Alice, 1) and take it back.
A minimal PoC demonstrating this behavior can be found here.
Expected behavior
After any successful transfer the per-token approval for that tokenId is cleared.
Actual behavior
zombieApprovals[tokenId] remains set after transfer, letting the previously approved address transfer the token again.
Suggested fix
Clear the per-token approval inside the transfer logic and emit the reset event (before or after updating ownership, but before exposing the token to new transfers):
function _transfer(address _from, address _to, uint256 _tokenId) internal {
// ... existing checks and logic ...
// Clear per-token approval
if (zombieApprovals[_tokenId] != address(0)) {
zombieApprovals[_tokenId] = address(0);
}
}Curriculum Note
Since CryptoZombies is educational, this could be a short “Gotcha” callout explaining why approvals must be cleared on transfer, or a small exercise where students add the clearing code.