Platform: Code4rena
Start Date: 13/11/2023
Pot Size: $24,500 USDC
Total HM: 3
Participants: 120
Period: 4 days
Judge: 0xTheC0der
Id: 306
League: ETH
Rank: 110/120
Findings: 1
Award: $1.37
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: rvierdiiev
Also found by: 0x175, 0x3b, 0xMango, 0xarno, 0xpiken, Bauchibred, DarkTower, ElCid, Giorgio, HChang26, Kose, KupiaSec, Madalad, PENGUN, Pheonix, RaoulSchaffranek, SpicyMeatball, T1MOH, Tricko, Udsen, Yanchuan, aslanbek, ast3ros, bart1e, bin2chen, chaduke, d3e4, deepkin, developerjordy, glcanvas, inzinko, jasonxiale, jnforja, mahyar, max10afternoon, mojito_auditor, neocrao, nmirchev8, openwide, osmanozdemir1, peanuts, pep7siup, peritoflores, pontifex, rice_cooker, rouhsamad, t0x1c, tnquanghuy0512, turvy_fuzz, twcctop, ustas, vangrim, zhaojie, zhaojohnson
1.3743 USDC - $1.37
https://github.com/code-423n4/2023-11-canto/blob/main/1155tech-contracts/src/Market.sol#L174-L189
No slippage protection when sell can leave sellers with their NFTs selling for much less than they originally intended.
With a linear increase, every NFT bought increases the price, and every NFT sold decreases it. The price increases with a buy because it increases the tokenCount. The token count is used to calculate the linear rising price. The same is true for selling, where tokenCount is decreased, thus lowering the price.
This, combined with big mints (huge demand and huge volatility in price), can lead some users to sell their NFTs for much less than they intended.
Example:
She accidentally sells her NFT at a loss instead of a profit. Alice is down 0.1 wETH, as she had no way to limit the price her NFT sells for.
Manual review.
My suggestion is to set a minimum selling price on sell.
- function sell(uint256 _id, uint256 _amount) external { + function sell(uint256 _id, uint256 _amount, uint256 _minPrice) external { (uint256 price, uint256 fee) = getSellPrice(_id, _amount); + require(price >= _minPrice, "Price too low"); _splitFees(_id, fee, shareData[_id].tokensInCirculation); uint256 rewardsSinceLastClaim = _getRewardsSinceLastClaim(_id); rewardsLastClaimedValue[_id][msg.sender] = shareData[_id].shareHolderRewardsPerTokenScaled; shareData[_id].tokenCount -= _amount; shareData[_id].tokensInCirculation -= _amount; tokensByAddress[_id][msg.sender] -= _amount; SafeERC20.safeTransfer(token, msg.sender, rewardsSinceLastClaim + price - fee); emit SharesSold(_id, msg.sender, _amount, price, fee); }
Error
#0 - c4-pre-sort
2023-11-18T10:44:43Z
minhquanym marked the issue as duplicate of #12
#1 - c4-judge
2023-11-28T23:37:40Z
MarioPoneder marked the issue as satisfactory