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: 27/88
Findings: 2
Award: $158.70
🌟 Selected for report: 0
🚀 Solo Findings: 0
153.1035 USDC - $153.10
https://github.com/code-423n4/2022-11-size/blob/main/src/SizeSealed.sol#L33-L36 https://github.com/code-423n4/2022-11-size/blob/main/src/SizeSealed.sol#L217 https://github.com/code-423n4/2022-11-size/blob/main/src/SizeSealed.sol#L238 https://github.com/code-423n4/2022-11-size/blob/main/src/SizeSealed.sol#L297
States.Finalized
if data.lowestQuote
of this auction is different from type(uint128).max
. L33-34data.lowestQuote
is assigned to equal clearingQuote
when seller finalize auction. (L238)
This value will be checked by the last data.previousQuotePerBase
(L297-L299):if (data.previousQuotePerBase != FixedPointMathLib.mulDivDown(clearingQuote, type(uint128).max, clearingBase)) { revert InvalidCalldata(); }
lastQuoteAmount
and lastBaseAmount
is quoteToken and baseToken amount of last filled bid -> data.previousQuotePerBase
= FixedPointMathLib.mulDivDown(lastQuoteAmountt, type(uint128).max, lastBaseAmount);
It means clearingQuote * type(uint128).max / clearingBase
must equal to lastQuoteAmount * type(uint128).max / lastBaseAmount
=> If clearingQuote
is type(uint128).max
, it can still pass the check if the ratio clearingQuote
/ clearingBase
is equal to lastQuoteAmount
/ lastBaseAmount
Example: clearingQuote
= clearingBase
= type(uint128).max
, and lastQuoteAmount
/ lastBaseAmount
= 1clearingQuote
= type(uint128).max
, but auction's state will still be States.RevealPeriod
because data.lowestQuote
still be type(uint128).max
.
It allows seller repeat finalize again or cancel auction to steal many quote tokens and base tokens from contract.When lastQuoteAmount
, lastBaseAmount
of auction are satisfied, seller can finalize auction without updating state to State.Finalized
by passing clearingQuote
= type(uint128).max
.
Worse than that, sellers can modify last bids for large auctions (by using other addresses to bid) and exploit this vulnerable (repeat finalize many times without updating state or cancel auction, steal many tokens of contract).
https://gist.github.com/huuducst/d3e496680e6091e417d65bfcec17b77f
You can place this file into /src/test
folder and run it using:
forge test --match-test testFinalizeIssue -vv
VS Code Foundry
Should revert if seller finalize with clearingQuote
== type(uint128).max
(function finalize
)
if (clearingQuote == type(uint128).max) { revert InvalidCalldata(); }
#0 - trust1995
2022-11-08T23:50:08Z
Good find, dup of #252
#1 - c4-judge
2022-11-09T15:01:05Z
0xean marked the issue as duplicate
#2 - c4-judge
2022-12-06T00:22:30Z
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
https://github.com/code-423n4/2022-11-size/blob/main/src/SizeSealed.sol#L157-L159
Because contract did not limit number of bids for each address at 1 auction, attacker can bid many times (same auction) in 1 transaction. If it makes bids.length
increase up to 1000, and other bidders can not bid at this auction.
Contract just limit 1000 number of bids at 1 auction.
See in this condition in function bid()
:
if (bidIndex >= 1000) { revert InvalidState(); }
And contract has no limit of the number of bids for each bidder at 1 auction. So attacker can easily bid up to 1000 times in 1 transaction and prevent bidding from others.
VS Code
Limit number of bids for each bidder at 1 auction or remove limitation of 1000 bids.
#0 - trust1995
2022-11-08T23:48:11Z
This is not considered a DOS as attacker is basically executing 1000 legitimate trades with the seller, as intended. Report does not specify any interesting quirks to make the DOS do any harm to the auction.
#1 - c4-judge
2022-11-09T15:38:07Z
0xean marked the issue as duplicate
#2 - c4-judge
2022-12-06T00:22:29Z
0xean marked the issue as satisfactory