Pieces Protocol

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

The `TokenDivider::sellErc20` function allows the `price` parameter to be zero, making the protocol not able to collect any fees on these purchases.

Description

The TokenDivider::sellErc20 function doesn't have a check to confirm price parameter is greater than zero.

Impact

By allowing tokens to be listed for free the protocol is not able to collect fees on these sales.

Proof of Concepts

Add the following test to TokenDividerTest.t.sol file:

function testSellPriceCanBeSetToZero() public nftDivided{
ERC20Mock erc20Mock = ERC20Mock(tokenDivider.getErc20InfoFromNft(address(erc721Mock)).erc20Address);
vm.startPrank(USER);
erc20Mock.approve(address(tokenDivider), AMOUNT);
tokenDivider.sellErc20(address(erc721Mock), 0, AMOUNT);
vm.stopPrank();
assertEq(tokenDivider.getOrderPrice(USER,0), 0);
}

Tools Used

  • Foundry, Manual analysis

Recommended mitigation

Add the following changes to the contract:

error TokenDivider__NotFromNftOwner();
error TokenDivider__NotEnoughErc20Balance();
error TokenDivider__NftTransferFailed();
error TokenDivider__InsuficientBalance();
error TokenDivider__CantTransferToAddressZero();
error TokenDivider__TransferFailed();
error TokenDivider__NftAddressIsZero();
error TokenDivider__AmountCantBeZero();
error TokenDivider__InvalidSeller();
error TokenDivier__InvalidAmount();
error TokenDivider__IncorrectEtherAmount();
error TokenDivider__InsuficientEtherForFees();
+ error TokenDivider__PriceCantBeZero();
...
function sellErc20(address nftPegged, uint256 price,uint256 amount) external {
if(nftPegged == address(0)) {
revert TokenDivider__NftAddressIsZero();
}
+ if( amount == 0) {
+ revert TokenDivider__PriceCantBeZero();
+ }
if( amount == 0) {
revert TokenDivider__AmountCantBeZero();
}
ERC20Info memory tokenInfo = nftToErc20Info[nftPegged];
if(balances[msg.sender][tokenInfo.erc20Address] < amount) {
revert TokenDivider__InsuficientBalance();
}
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);
IERC20(tokenInfo.erc20Address).transferFrom(msg.sender,address(this), amount);
}
Updates

Lead Judging Commences

fishy Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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