First Flight #12: Kitty Connect

First Flight #12: Kitty Connect
Beginner FriendlyFoundryNFTGameFi
100 EXP
View results
Submission Details
Severity: high
Valid

The function `KittyConnect::_updateOwnershipInfo` doesn't update the `KittyConnect::s_ownerToCatsTokenId` for new owner

Summary

The function KittyConnect::_updateOwnershipInfo is utilized within the execution of KittyConnect::safeTransferFrom to update data in both the KittyConnect::s_ownerToCatsTokenId and KittyConnect::s_catInfo. However, it fails to remove the tokenId from the s_ownerToCatsTokenId[currCatOwner] array.

Vulnerability Details

The vulnerability resides within the KittyConnect contract, specifically in the _updateOwnershipInfo function, where there is no provision to update the s_ownerToCatsTokenId array for the currCatOwner.
The s_ownerToCatsTokenId array is intended to track the complete list of token IDs belonging to a specific user. It is expected that after invoking this function, the tokenId would be removed from the s_ownerToCatsTokenId array of the current owner. However, this removal does not occur.

Impact

Following the invocation of safeTransferFrom, the tokenId persists within the current user array within s_ownerToCatsTokenId, rendering the utilization of s_ownerToCatsTokenId redundant.

Tools Used

Manual review and forge were employed.
To identify this issue, execute the existing test within test/KittyTest.t.sol:

forge test --mt test_safetransferCatToNewOwner

This test suite fails due to the following assertion failure:

assertEq(kittyConnect.getCatsTokenIdOwnedBy(user).length, 0);

Recommendations

It is advised to incorporate code to properly handle the s_ownerToCatsTokenId for currCatOwner:

function _updateOwnershipInfo(address currCatOwner, address newOwner, uint256 tokenId) internal {
s_catInfo[tokenId].prevOwner.push(currCatOwner);
+ uint256 prevIdx = s_catInfo[tokenId].idx;
s_catInfo[tokenId].idx = s_ownerToCatsTokenId[newOwner].length;
s_ownerToCatsTokenId[newOwner].push(tokenId);
+
+ uint256 latestIdx = s_ownerToCatsTokenId[currCatOwner].length - 1;
+ if (prevIdx != latestIdx) {
+ uint256 lastItem = s_ownerToCatsTokenId[currCatOwner][latestIdx];
+ s_ownerToCatsTokenId[currCatOwner][prevIdx] = lastItem;
+ }
+ s_ownerToCatsTokenId[currCatOwner].pop();
}

These changes ensure proper management of s_ownerToCatsTokenId for currCatOwner, thereby addressing the identified issue.

Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Improper token ownership update in `_updateOwnershipInfo`

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.