Closed code423n4 closed 1 year ago
0xSorryNotSorry marked the issue as primary issue
An exploit is not given here. I am quite sure there is no risk of user funds, and the xyk invariant is still held.
Example:
After all is done, the net total difference in virtual base token reserves and virtual nft reserves from before and after the attack is 0. i.e. there is no exploit or loss of funds. happy to accept this issue though, if an actual exploit where user funds can be stolen is given.
outdoteth marked the issue as sponsor disputed
I believe that the Warden has shown a way to manipulate the price, but in doing so they are maintaining the Pools Invariant, meaning that the attacker is just paying fees
I'll ask for more details in the POC but this doesn't look sufficient
GalloDaSballo marked the issue as unsatisfactory: Insufficient proof
Lines of code
https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L211 https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L240
Vulnerability details
Impact
The reentrancy vulnerability in this contract allows a user to manipulate the NFT reserves(virtualNftReserves), which can result in invalid price calculations. If the attacker chooses to exploit this vulnerability, they can sell their NFT back to the protocol at a higher price, given the manipulation of the reserves.
Proof of Concept
The execution of this exploit is requires the malicious contract deployed by attacker.
Steps of exploit:
-The attacker created a malicious contract that includes an ERC712Receiver and a
buy()
function, with the intention of using it to purchase ERC721 NFTs. -The attacker then called thePrivatePool.buy()
function through the malicious contract. -Thebuy()
function attempted to transfer the ERC721 NFTs to themsg.sender
usingERC721(nft).safeTransferFrom(msg.sender, address(this), tokenIds[i]);
. -However, due to the lack of re-entrancy protection, the malicious contract was able to repeatedly execute thebuy()
function within the ERC721Receiver function, thus sending received tokens to the PrivatePool contract and causing thevirtualNftReserves
variable to decreasing while increasing thevirtualBaseTokenReserves
variable. This ultimately broke the price calculation.The following POC illustrates the Re-Entrancy attack
POC screenshots (https://i.ibb.co/LhpPz53/Screen-Shot-2023-04-13-at-10-07-56-PM.png) (https://i.ibb.co/pJvyWtp/Screen-Shot-2023-04-13-at-10-13-25-PM.png)
As a result of the attacker's actions, the outputAmount calculation has been broken, and the PrivatePool contract's sell() function is using the sellQuote() function to determine the output amount. This vulnerability means that the attacker can sell their NFTs back to the PrivatePool contract at a higher price, leading to potential loss of funds.
Tool Used
Foundry
Recommended Mitigation Steps
Implement reentrancyGuard from OpenZeppelin to remove the risk of reentrant calls .