Skip to content

Lesson 5 ZombieOwnership: per-token approval is not cleared on transfer (enables post-sale transfer by prior approved address) #59

@VHenriksson

Description

@VHenriksson

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions