Pieces Protocol

First Flight #32
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

`TokenDivider::claimNft` does not follow CEI pattern, leading to potential reentrancy attacks

Description:
Every function in the smart contract should follow the CEI (Checks-Effects-Interactions) pattern, in order to avoid potential reentrancy attack from malicious actors. The CEI pattern is one of the best practices to follow when writing a smart contract, which provides that state variables should be updated before any interactions with external contracts.

Impact:
Reentrancy attacks are one of the most common attack vectors in smart contracts. An attacker could create a malicious smart contract which has some custom logic in the receive or fallback function, which are triggered when receiving native tokens. It is crucial to avoid smart contracts to reenter functions before their completion.

Tools Used:
Slither, manual review

Recommended Mitigation:
It is recommended to rephrase the code of TokenDivider::claimNft function, in order to relfect the above mentioned CEI pattern.

function claimNft(address nftAddress) external {
if(nftAddress == address(0)) {
revert TokenDivider__NftAddressIsZero();
}
ERC20Info storage tokenInfo = nftToErc20Info[nftAddress];
if(balances[msg.sender][tokenInfo.erc20Address] < erc20ToMintedAmount[tokenInfo.erc20Address]) {
revert TokenDivider__NotEnoughErc20Balance();
}
- ERC20ToGenerateNftFraccion(tokenInfo.erc20Address).burnFrom(msg.sender, erc20ToMintedAmount[tokenInfo.erc20Address]);
balances[msg.sender][tokenInfo.erc20Address] = 0;
erc20ToMintedAmount[tokenInfo.erc20Address] = 0;
+ ERC20ToGenerateNftFraccion(tokenInfo.erc20Address).burnFrom(msg.sender, erc20ToMintedAmount[tokenInfo.erc20Address]);
- emit NftClaimed(nftAddress);
IERC721(nftAddress).safeTransferFrom(address(this), msg.sender, tokenInfo.tokenId);
+ emit NftClaimed(nftAddress);
}

Additionally, to increase the security level of the contract, TokenDivider could inherit from ReentrancyGuard contract from OpenZeppelin, which already has a battle-tested nonReentrant modifier approved by the community to be added in TokenDivider::claimNft.

For reference, see ReentrancyGuard.sol

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.9.5/contracts/security/ReentrancyGuard.sol

Updates

Lead Judging Commences

fishy Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Reentrancy

Appeal created

fishy Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Reentrancy

fishy Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Reentrancy

fishy Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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