Platform: Code4rena
Start Date: 07/04/2023
Pot Size: $47,000 USDC
Total HM: 20
Participants: 120
Period: 6 days
Judge: GalloDaSballo
Total Solo HM: 4
Id: 230
League: ETH
Rank: 10/120
Findings: 2
Award: $846.91
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Voyvoda
Also found by: AkshaySrivastav, Haipls, aviggiano, teddav
820.1517 USDC - $820.15
https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L244 https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L274
Royalties are computed 2 times: once before the transfer from the user, and again after.
This is a problem: the owner of the NFT contract can basically buy NFTs for free.
The only limitation is this line:
if (royaltyFee > salePrice) revert InvalidRoyaltyFee();
https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L791
So you can only get the NFT for free, but you can’t empty the pool directly.
Flow of attack:
buy()
with all the NFTs in the pool, send a bit of extra ETH to make sure you’re reimbursedmsg.sender
is called (with msg.sender.safeTransferETH
): set royalties to the maximum: salePrice - 1
https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L268
Note: this works if baseToken
is ETH or if it’s an ERC777, in that case the exploiter’s contract will be called on this line: https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L259Don’t use 2 steps to compute and pay royalties, do everything in 1 loop.
#0 - c4-pre-sort
2023-04-20T18:40:34Z
0xSorryNotSorry marked the issue as primary issue
#1 - outdoteth
2023-04-22T08:32:24Z
Possible duplicate of https://github.com/code-423n4/2023-04-caviar-findings/issues/593
#2 - c4-judge
2023-04-30T16:04:10Z
GalloDaSballo marked the issue as duplicate of #593
#3 - c4-judge
2023-04-30T16:04:57Z
GalloDaSballo marked the issue as duplicate of #320
#4 - GalloDaSballo
2023-04-30T16:09:14Z
While the report is short, it captures the condition and impact of the finding, maintaining full awards
#5 - c4-judge
2023-05-01T07:01:33Z
GalloDaSballo marked the issue as satisfactory
26.761 USDC - $26.76
https://github.com/code-423n4/2023-04-caviar/blob/main/src/PrivatePool.sol#L459
It might not be an issue since it seems like this is the way it’s supposed to work. And as long as the user is aware of it, I guess it’s ok…
But owner
of the PrivatePool can basically do whatever they want.
Multiple onlyOwner
functions allow to manipulate the pool: withdraw
, setVirtualReserves
for example.
And execute()
allows the owner to do whatever he wants with the pool
#0 - c4-pre-sort
2023-04-20T16:40:49Z
0xSorryNotSorry marked the issue as duplicate of #184
#1 - c4-judge
2023-05-01T19:20:20Z
GalloDaSballo changed the severity to 3 (High Risk)
#2 - c4-judge
2023-05-01T19:21:19Z
GalloDaSballo marked the issue as satisfactory