Summary
The LibShortRecord::burnNFT()
emits an incorrect event value.
Vulnerability Details
The burnNFT()
emits an incorrect event value: nft.owner
. Specifically, the nft
variable will point to the storage object specified by the tokenId
. However, the pointing storage object will be deleted before emitting the Transfer
event.
Subsequently, the ERC721::Transfer
event will be emitted with nft.owner
== address(0)
.
function burnNFT(uint256 tokenId) internal {
AppStorage storage s = appStorage();
@> STypes.NFT storage nft = s.nftMapping[tokenId];
if (nft.owner == address(0)) revert Errors.NotMinted();
address asset = s.assetMapping[nft.assetId];
STypes.ShortRecord storage short =
s.shortRecords[asset][nft.owner][nft.shortRecordId];
@> delete s.nftMapping[tokenId];
delete s.getApproved[tokenId];
delete short.tokenId;
@> emit Events.Transfer(nft.owner, address(0), tokenId);
}
Impact
The ERC721::Transfer
is an important event. The incorrect event logs may cause off-chain services to malfunction.
Tools Used
Manual Review
Recommendations
Emit the Transfer
event before the delete
operations.
function burnNFT(uint256 tokenId) internal {
//@dev No need to check downcast tokenId because it is handled in function that calls burnNFT
AppStorage storage s = appStorage();
STypes.NFT storage nft = s.nftMapping[tokenId];
if (nft.owner == address(0)) revert Errors.NotMinted();
address asset = s.assetMapping[nft.assetId];
STypes.ShortRecord storage short =
s.shortRecords[asset][nft.owner][nft.shortRecordId];
+ emit Events.Transfer(nft.owner, address(0), tokenId);
delete s.nftMapping[tokenId];
delete s.getApproved[tokenId];
delete short.tokenId;
- emit Events.Transfer(nft.owner, address(0), tokenId);
}