Pieces Protocol

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

[M-4] Missing Revert Error on Transfer Failure in TokenDivider::sellErc20

Summary

The sellErc20 function calls IERC20(tokenInfo.erc20Address).transferFrom to transfer ERC20 tokens but does not provide a descriptive revert error if the transfer fails. This can lead to silent failures, making it difficult to diagnose issues and potentially leaving the contract in an inconsistent state.

IERC20(tokenInfo.erc20Address).transferFrom(msg.sender, address(this), amount); // No revert error

Vulnerability Details

In the sellErc20 function, the transferFrom call is used to transfer ERC20 tokens from the seller to the contract. However, the function does not check the return value of transferFrom or provide a descriptive revert error if the transfer fails. This can result in silent failures, where the contract state (e.g., balances and sell orders) is updated even though the token transfer was unsuccessful.

Impact

Medium Impact: Funds are indirectly at risk if the transfer fails silently. The contract's state (balances and sell orders) may become inconsistent if the transfer fails but the state is already updated.

State Inconsistency: Users may lose funds if the transfer fails without a clear error message, and the contract state may not reflect the actual token balances.

Diagnostic Challenges: Silent failures make it difficult to diagnose issues, leading to poor user experience and potential financial losses.

Tools Used

Manual Review, Foundry

Recommendations

Add a descriptive revert error to handle transfer failures and ensure the contract state remains consistent. For example:

function sellErc20(address nftPegged, uint256 price, uint256 amount) external {
// ... (checks omitted for brevity)
balances[msg.sender][tokenInfo.erc20Address] -= amount;
s_userToSellOrders[msg.sender].push(
SellOrder({
seller: msg.sender,
erc20Address: tokenInfo.erc20Address,
price: price,
amount: amount
})
);
emit OrderPublished(amount, msg.sender, nftPegged);
// Check the return value of transferFrom and revert on failure
bool success = IERC20(tokenInfo.erc20Address).transferFrom(msg.sender, address(this), amount);
if (!success) {
revert TokenDivider__TransferFailed(); // Revert with custom error if the transfer fails
}
}

Additional Considerations:

Use OpenZeppelin's SafeERC20 library to handle non-compliant ERC20 tokens and ensure safe transfers.

Emit an event for failed transfers to improve transparency and debugging.

Updates

Lead Judging Commences

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.