Platform: Code4rena
Start Date: 10/05/2022
Pot Size: $50,000 USDC
Total HM: 13
Participants: 100
Period: 5 days
Judge: HardlyDifficult
Total Solo HM: 1
Id: 122
League: ETH
Rank: 94/100
Findings: 2
Award: $25.14
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x52, 0xf15ers, 0xsanson, Bludya, BondiPestControl, Czar102, GimelSec, Kumpa, _Adam, berndartmueller, catchup, crispymangoes, eccentricexit, ellahi, hake, horsefacts, pedroais, peritoflores, reassor, shenwilly, shung, smiling_heretic, sseefried, throttle
8.1655 USDC - $8.17
Malicious owner can steal all ETH of a sell.
The function setFee#CallyNFT.sol
is critical as it set the amount of ETH that the protocol will receive. A malicious owner can set the fee to 1e18 and all ETH after exercise
will go to the owner of the contract.
if (feeRate > 0) { #CallyNFT.sol#L288 fee = (msg.value * feeRate) / 1e18; protocolUnclaimedFees += fee; }
The seller (or beneficiary) will receive 0 ETH.
In addition to the emitted event I would introduce a maximum fee to add transparency.
Ideally every time the fee changes it should only affect the new auction but not the previous. For example with a timelock. Although this requires much more work, maybe an idea could be to put fee as a parameter of the vault which is completed with the current fee.
#0 - outdoteth
2022-05-15T14:35:14Z
Renamed issue to be more clear
#1 - outdoteth
2022-05-15T19:26:35Z
owner can change fee at any time; https://github.com/code-423n4/2022-05-cally-findings/issues/47 owner can set fee greater than 100%: https://github.com/code-423n4/2022-05-cally-findings/issues/48
16.9712 USDC - $16.97
https://github.com/code-423n4/2022-05-cally/blob/1849f9ee12434038aa80753266ce6a2f2b082c59/contracts/src/Cally.sol#L295 https://github.com/code-423n4/2022-05-cally/blob/1849f9ee12434038aa80753266ce6a2f2b082c59/contracts/src/Cally.sol#L431-L453
Buyers can accidentally lose their NFT if they send to incorrect address.
When the buyer decide to call exercise
the NFT is transfered using transferFrom
. This is risky because if the destination (msg.sender
) is a contract and it is unable to handle NFT then it will be locked forever. This function in my opinion is Ok when you transfer to your contract.
vault.tokenType == TokenType.ERC721 ? ERC721(vault.token).transferFrom(address(this), msg.sender, vault.tokenIdOrAmount) : ERC20(vault.token).safeTransfer(msg.sender, vault.tokenIdOrAmount);
https://github.com/code-423n4/2022-04-backed-findings/issues/83
Implement safeTransferFrom
#0 - outdoteth
2022-05-15T20:49:36Z
use safeTransferFrom to prevent stuck NFTs: https://github.com/code-423n4/2022-05-cally-findings/issues/38