Platform: Code4rena
Start Date: 29/06/2022
Pot Size: $50,000 USDC
Total HM: 20
Participants: 133
Period: 5 days
Judge: hickuphh3
Total Solo HM: 1
Id: 142
League: ETH
Rank: 12/133
Findings: 5
Award: $1,443.96
π Selected for report: 0
π Solo Findings: 0
π Selected for report: kirk-baird
Also found by: Lambda, csanuragjain, hansfriese, minhquanym
When a user accepts a counter offer, he does not want that his original order is also exercised. In certain cases (floor options, options for ERC20 tokens), this could lead to situations where a user pays two times or has to deliver the underlying two times.
Bob posts a short put floor option for 2 Bored Apes offchain with a strike of 100 WETH. He then gets a counter offer from attacker Alice (same parameters, but a long put). However, just before he calls acceptCounterOffer
, Alice calls fillOrder
with the order from Bob. The acceptCounterOffer
and fillOrder
goes through and 200 WETH are deducted from Bob, although he only intended to go short on one option with 100 WETH.
Consider checking if the order that will be cancelled was already filled. If that is the case, acceptCounterOffer
should fail. This would also increase the utility of this function, as it would be different to a simple cancel
and fillOrder
(which a user could also do by himself).
#0 - outdoteth
2022-07-06T18:09:19Z
Duplicate: Itβs possible to fill an order twice by accepting a counter offer for an already filled order: https://github.com/code-423n4/2022-06-putty-findings/issues/44
π Selected for report: berndartmueller
227.0813 USDC - $227.08
Judge has assessed an item in Issue #45 as Medium risk. The relevant finding follows:
#0 - HickupHH3
2022-07-11T03:23:43Z
With regards to fees, we have the following possibilities:
dup of #285
π Selected for report: berndartmueller
Also found by: IllIllI, Lambda, TrungOre, auditor0517, hansfriese, sashik_eth, shenwilly
When order.strike
and fee
are both low values, (order.strike * fee) / 1000
can round down to 0, meaning feeAmount
will be 0. A transfer of 0 fails for some ERC20 tokens (https://github.com/d-xo/weird-erc20), meaning that withdraw
will never succeed. While the consequences would be severe (no withdrawal possible), the chances are relatively low in my opinion (combination of a very low strike price or a token with very little decimals, a low fee, and a token that treats 0 transfers in a weird way), so I rate the issue as medium.
For instance with order.strike = 950
and fee = 1
, we have: feeAmount = (950 * 1) / 1000 = 0
.
Consider only initiating the transfer when the value is larger than 0. This is also beneficial if the token does not revert on a zero transfer, as it saves gas in such a case.
#0 - outdoteth
2022-07-07T12:49:34Z
Duplicate: withdraw() can be DOSβd for baseAsset ERC20s that prevent 0 transfers if the calculated feeAmount is 0 due to rounding: https://github.com/code-423n4/2022-06-putty-findings/issues/283
π Selected for report: xiaoming90
Also found by: 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 0xSolus, 0xf15ers, 0xsanson, AmitN, Bnke0x0, BowTiedWardens, Chom, David_, ElKu, Funen, GalloDaSballo, GimelSec, Hawkeye, IllIllI, JC, JohnSmith, Kaiziron, Kenshin, Lambda, Limbooo, MadWookie, Metatron, MiloTruck, Nethermind, Picodes, ReyAdmirado, Sneakyninja0129, StErMi, TomJ, Treasure-Seeker, TrungOre, Waze, Yiko, _Adam, __141345__, antonttc, async, aysha, catchup, cccz, cryptphi, csanuragjain, danb, datapunk, defsec, delfin454000, dirk_y, doddle0x, durianSausage, exd0tpy, fatherOfBlocks, gogo, hake, hansfriese, horsefacts, hubble, itsmeSTYJ, joestakey, oyc_109, pedroais, peritoflores, rajatbeladiya, reassor, robee, rokinot, samruna, saneryee, sashik_eth, shenwilly, shung, simon135, sseefried, unforgiven, zer0dot, zzzitron
48.5107 USDC - $48.51
Order
, although some of them do not even matter for his buying decision (e.g., he should not have to care which nonce
was used for the original Order
).balanceOf
to type(uint256).max
is a deliberate design decision according to the docs, but can have negative consequences for NFT markets where the Putty
NFTs are traded. If they use balanceOf
internally (because they assume that the ERC721 standard is implemented according to the specifications), transfers may fail or the behaviour of the market place may be wrong._transferERC20sIn
, it is checked if the token is a contract, which is not done for _transferERC721sIn
and _transferFloorsIn
. Consider to check this either for all or none of the transfers.#0 - kartoonjoy
2022-07-03T13:39:50Z
Per warden Lambda, the text of this finding has been updated with what was in their gist's help desk request.
#1 - outdoteth
2022-07-07T19:21:52Z
My initial assumption, before reading the code, was that there is also a fee deducted from the exerciser when a put option is exercised.
Duplicate: Fees are only applied on puts if they are expired: https://github.com/code-423n4/2022-06-putty-findings/issues/269
π Selected for report: GalloDaSballo
Also found by: 0v3rf10w, 0x1f8b, 0xA5DF, 0xDjango, 0xHarry, 0xKitsune, 0xNazgul, 0xNineDec, 0xc0ffEE, 0xf15ers, 0xkatana, 0xsanson, ACai, Aymen0909, Bnke0x0, BowTiedWardens, Chom, ElKu, Fitraldys, Funen, Haruxe, Hawkeye, IllIllI, JC, JohnSmith, Kaiziron, Kenshin, Lambda, Limbooo, MadWookie, Metatron, MiloTruck, Picodes, PwnedNoMore, Randyyy, RedOneN, ReyAdmirado, Ruhum, Sm4rty, StErMi, StyxRave, TerrierLover, TomJ, Tomio, UnusualTurtle, Waze, Yiko, _Adam, __141345__, ajtra, ak1, apostle0x01, asutorufos, c3phas, cRat1st0s, catchup, codetilda, cryptphi, datapunk, defsec, delfin454000, durianSausage, exd0tpy, fatherOfBlocks, gogo, grrwahrr, hake, hansfriese, horsefacts, ignacio, jayfromthe13th, joestakey, ladboy233, m_Rassska, mektigboy, minhquanym, mrpathfindr, natzuu, oyc_109, rajatbeladiya, reassor, rfa, robee, rokinot, sach1r0, saian, sashik_eth, simon135, slywaters, swit, z3s, zeesaw, zer0dot
21.1705 USDC - $21.17
for
loop and the i++
can be unchecked
to save gas:
feeAmount
is per definition always lower than order.strike
.