Closed code423n4 closed 1 year ago
0xSorryNotSorry marked the issue as high quality report
0xSorryNotSorry marked the issue as duplicate of #881
GalloDaSballo changed the severity to QA (Quality Assurance)
GalloDaSballo marked the issue as grade-c
Lines of code
https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L694-L706 https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L211-L289 https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L301-L373 https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L385-L452
Vulnerability details
Impact
If an NFT fraction has a weight greater than the virtual liquidity, it may become locked until the pool owner increases the virtual reserves to a level that accommodates the weight.
Proof of Concept
Assuming that the virtual liquidity in the pool is as follows:
virtualBaseTokenReserves
= 100e18virtualNftReserves
= 5e18Moreover, in this scenario, the actual reserves match the virtual reserves.
Assuming that Bob chooses to exchange his NFT fraction with a weighting of 2 for another NFT fraction in the same pool with a weighting of 1, there will be no immediate abnormality. However, the change function will fail to record the alteration in reserves.
Following the update, the virtual reserves are now lower than the actual reserves.
If two arbitrary buyers purchase four NFTs with a weight of 1 each from the pool, the NFT that was swapped for one with a lower weight will become stuck in the protocol until the pool owner re-balances the virtual reserves.
If Alice attempts to purchase an NFT with the same or greater weight than the virtual reserves, one of two events may occur: a division by zero error in the case of equivalent amounts, or an arithmetic underflow in the case of an amount greater than the virtual reserves.
A Foundry PoC that demonstrates the scenario of division by zero:
Tools Used
Manual review, Foundry
Recommended Mitigation Steps
virtualBaseTokenReserves
variable to prevent the virtual reserves from becoming smaller than the actual reserves. If the new weight is greater than the previous weight, increment thevirtualBaseTokenReserves
variable.buyQuote
function:It will not allow for division by 0 and will still keep the integrity of the logic in the formula. This resolves a rare scenario that occurs when attempting to purchase the entire reserve of virtual NFTs at once.