Platform: Code4rena
Start Date: 04/11/2022
Pot Size: $42,500 USDC
Total HM: 9
Participants: 88
Period: 4 days
Judge: 0xean
Total Solo HM: 2
Id: 180
League: ETH
Rank: 76/88
Findings: 2
Award: $14.14
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: neko_nyaa
Also found by: 0x52, 0xSmartContract, 0xc0ffEE, Josiah, KingNFT, Lambda, R2, RaymondFam, Ruhum, TomJ, Trust, TwelveSec, __141345__, c7e7eff, cccz, cryptostellar5, fs0c, hansfriese, horsefacts, ladboy233, minhtrng, pashov, rvierdiiev, sashik_eth, tonisives, wagmi
8.5414 USDC - $8.54
In function createAuction()
, it has checked for tax tokens when transferring baseToken
from seller to contract
// Passes https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol#L9 // Transfer base tokens to auction contract and check for tax tokens uint256 balanceBeforeTransfer = ERC20(auctionParams.baseToken).balanceOf(address(this)); SafeTransferLib.safeTransferFrom( ERC20(auctionParams.baseToken), msg.sender, address(this), auctionParams.totalBaseAmount ); uint256 balanceAfterTransfer = ERC20(auctionParams.baseToken).balanceOf(address(this)); if (balanceAfterTransfer - balanceBeforeTransfer != auctionParams.totalBaseAmount) { revert UnexpectedBalanceChange(); }
However, in function bid()
, similar check is lacking for quoteToken
. It will create a problem when seller cannot finalize the auction and bidder cannot refund cause actual balance is less than expected.
It did not check for tax tokens in bid()
function
SafeTransferLib.safeTransferFrom(ERC20(a.params.quoteToken), msg.sender, address(this), quoteAmount); emit Bid( msg.sender, auctionId, bidIndex, quoteAmount, commitment, pubKey, encryptedMessage, encryptedPrivateKey );
Manual Review
Consider adding similar check for pre and after balance of quoteToken
like in the function createAuction()
#0 - c4-judge
2022-11-09T19:55:27Z
0xean marked the issue as duplicate
#1 - c4-judge
2022-12-06T00:22:14Z
0xean marked the issue as satisfactory
🌟 Selected for report: Trust
Also found by: 0x1f8b, 0xdapper, HE1M, KIntern_NA, Lambda, Picodes, RaymondFam, RedOneN, TomJ, V_B, __141345__, c7e7eff, chaduke, codexploder, corerouter, cryptonue, fs0c, gz627, hihen, joestakey, ktg, ladboy233, minhtrng, rvierdiiev, simon135, skyle, slowmoses, wagmi, yixxas
5.604 USDC - $5.60
In the function bid()
, number of bids is limited to 1000 to avoid out of gas in finalize()
. However, it can be abused by attacker to spam bid()
function to 1000 bids, block other users from bidding this auction.
Maximum number of bids is 1000 in bid()
:
uint256 bidIndex = a.bids.length; // Max of 1000 bids on an auction to prevent DOS if (bidIndex >= 1000) { // @audit bidder can always spam if merkle proof is not used revert InvalidState(); }
Since bids are sealed, price is kept private, so attacker can just place bids that has the price lower than reserveQuotePerBase
. It will effectively create the DOS attack without having to buy any baseToken
// Only fill if above reserve price if (quotePerBase < data.reserveQuotePerBase) continue;
Manual Review
Actually I cannot find any solution for this issues that do not change the design choice.
However considering the design, I recommend to add fee for bidders when they bid()
. This way will limit number of bids that attacker can place since they have to lose something now.
#0 - trust1995
2022-11-08T23:31:44Z
Dup of #237
#1 - c4-judge
2022-11-09T15:36:27Z
0xean marked the issue as duplicate
#2 - c4-judge
2022-12-06T00:22:15Z
0xean marked the issue as satisfactory