High Risk
https://github.com/Cyfrin/2023-12-the-standard/blob/91132936cb09ef9bf82f38ab1106346e2ad60f91/contracts/SmartVaultManagerV5.sol#L139-L142
When a user mints a vault and the tries to send it, the _afterTokenTransfer
of the ERC721 vault token is invoked. This is shown in the snippet below.
smartVaultIndex.transferTokenId(_from, _to, _tokenId);
if (address(_from) != address(0))
ISmartVault(smartVaultIndex.getVaultAddress(_tokenId)).setOwner(
_to
);
This calls the transferTokenId
function, which actually loops over all the user's owned tokens. It eventually calls removeTokenId
in SmartVaultIndex.sol
as shown below.
uint256[] memory currentIds = tokenIds[_user];
uint256 idsLength = currentIds.length;
delete tokenIds[_user];
for (uint256 i = 0; i < idsLength; i++) {
if (currentIds[i] != _tokenId) tokenIds[_user].push(currentIds[i]);
}
While this function is out of scope, it is being called by the in-scope contract. The function above loops over all the vaults of the user. Thus if the user owns a lot of vaults, this can balloon the gas cost for transfers. Since there is no limit to the amount of vaults a user can own, this can also consume more gas than the eth gas limit and thus always revert.
Further, a malicious user can target a victim and mint and send vault tokens to the victim, inflating their list of vaults. This will inflate the gas costs of the victim, and might even lock them out of transferring the vault erc721 tokens if the gas costs exceed the block limit.
Since this allows an attacker to block transfers of another user, this is of critical severity.
The griefing can be done as follows.
Potential out of gas griefing attack.
Manual Review
Add a limit for the amount of vaults a particular user can own.