Platform: Code4rena
Start Date: 07/07/2022
Pot Size: $75,000 USDC
Total HM: 32
Participants: 141
Period: 7 days
Judge: HardlyDifficult
Total Solo HM: 4
Id: 144
League: ETH
Rank: 95/141
Findings: 2
Award: $63.42
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, Amithuddar, Avci, BowTiedWardens, Kthere, Limbooo, MEP, Ruhum, StyxRave, TomJ, Treasure-Seeker, TrungOre, Tutturu, Waze, bardamu, c3phas, cccz, codexploder, cryptphi, hake, horsefacts, hyh, oyc_109, pashov, peritoflores, scaraven, simon135, slywaters, sseefried, tofunmi, xiaoming90
1.3977 USDC - $1.40
It might be impossible for some addresses to receive ETH via transfer()
because receiver address might have methods that exceed 2300 gas, ultimately leading to frozen funds.
Native transfer()
function has a limit of 2300 gas, which might not be enough when the receiving end has gas expensive operations, leading the transaction to revert.
payable(msg.sender).transfer(ethAmount);
Manual Review
Use call()
instead of transfer()
and make sure to implement a boolean return check on call()
Other instance: https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/modules/Migration.sol#L325-L326
#0 - stevennevins
2022-07-19T21:39:11Z
Duplicate of #325
#1 - HardlyDifficult
2022-07-28T15:45:13Z
Duping to #504
🌟 Selected for report: xiaoming90
Also found by: 0x1f8b, 0x29A, 0x52, 0xA5DF, 0xDjango, 0xNazgul, 0xNineDec, 0xf15ers, 0xsanson, 0xsolstars, 242, 8olidity, Amithuddar, Aymen0909, Bnke0x0, BowTiedWardens, David_, Deivitto, ElKu, Funen, Hawkeye, IllIllI, JC, Kaiziron, Keen_Sheen, Kthere, Kulk0, Kumpa, Lambda, MEP, ReyAdmirado, Rohan16, Ruhum, Sm4rty, TomJ, Tomio, Treasure-Seeker, TrungOre, Tutturu, Viksaa39, Waze, _Adam, __141345__, ak1, apostle0x01, asutorufos, async, ayeslick, aysha, bbrho, benbaessler, berndartmueller, c3phas, cccz, chatch, cloudjunky, codexploder, cryptphi, delfin454000, dipp, durianSausage, dy, exd0tpy, fatherOfBlocks, hake, hansfriese, horsefacts, hubble, joestakey, jonatascm, kebabsec, kenzo, kyteg, mektigboy, neumo, oyc_109, pashov, pedr02b2, peritoflores, rajatbeladiya, rbserver, robee, rokinot, s3cunda, sach1r0, sahar, sashik_eth, scaraven, shenwilly, simon135, sorrynotsorry, sseefried, svskaushik, unforgiven, z3s, zzzitron
62.0165 USDC - $62.02
Funds might be automatically frozen via _sendEthOrWeth()
.
buyFractions()
does not provide the option to pay with WETH
, therefore the receiving address
of sellFractions()
wouldn't expect to receive WETH
instead of ETH
.
If for some unexpected reason the native ETH
transfer fails, WETH
will be sent to the receiver that might not be able to handle ERC20s, leading to the funds being frozen.
function _sendEthOrWeth(address _to, uint256 _value) internal { if (!_attemptETHTransfer(_to, _value)) { WETH(WETH_ADDRESS).deposit{value: _value}(); WETH(WETH_ADDRESS).transfer(_to, _value); } }
Manual Review
Simply revert if native ETH
transfer is not successful instead of attempting WETH
transfer.
Other instance: https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/modules/Buyout.sol#L235-L236
#0 - itsmetechjay
2022-07-15T14:12:38Z
Warden submitted this as a high-risk severity by mistake, so we are updating it to medium severity.
#1 - mehtaculous
2022-07-20T21:03:47Z
0 (Not bug)
WETH is used in the event that the receiving address is not an EOA and it has not implemented a payable receive function to receive eth. This is not an issue.
#2 - HardlyDifficult
2022-08-04T17:43:58Z
There's some validity to the warden's point here. Where it wouldn't lead to assets getting trapped in the contract, reverting could be a safer solution than falling back to WETH. Lowing risk and converting into a QA report for the warden.
#3 - HardlyDifficult
2022-08-07T15:42:40Z