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: 67/141
Findings: 2
Award: $103.43
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: berndartmueller
Also found by: 0xA5DF, 0xSky, 0xsanson, ElKu, Kumpa, Treasure-Seeker, TrungOre, cccz, cryptphi, hansfriese, jonatascm, kenzo, minhquanym, s3cunda, shenwilly, smiling_heretic, zzzitron
41.4866 USDC - $41.49
buyFractions
does not follow check effects interaction, opening up reentrancy attack vector. After ERC1155 is sent to a malicious contract and calls INFTReceiver().onERC1155Received
, an attacker could configure the receiving address to buyFractions
again to bypass buyoutInfo[_vault].ethBalance += msg.value;
.
Even though the attacker does not directly benefit from this attack, the attack could distort the value of buyoutInfo[_vault].ethBalance
, causing certain amount of ether to be frozen in the vault.
1.An attacker creates a malicious contract with function onERC1155Received()
that trigger buyFractions
after called
2.An attacker initially calls buyFractions
through a malicious contract and exchange ethers for fractionTokens
3.When IERC1155.safeTransferFrom()
occurs, apart from updating fractionTokens in the malicious contract, it will also call onERC1155Received which initiate reentrancy loop
4.The malicious contract will keep rebuying fractionTokens and buyoutInfo[_vault].ethBalance
will only update the final msg.value that get sent while prior msg.value is bypassed
5.After the aunction ends and buyoutInfo[_vault].state = State.SUCCESS;
. An attacker could quickly cash
to turn their fractionTokens to ethers.
6.Other users that cash
later may not be able to convert their fractionTokens into ethers because the supply of fractionsToken will be more than ethBalance
due to reentrancy buying that bypass the accounting of eth, causing some ethers to be frozen.
1.Use nonreentrant from openzeppelin to prevent reentrancy attack
2.Update ethBalance
before calling external contract to follow check effects interaction pattern
#0 - stevennevins
2022-07-21T18:19:42Z
Duplicate of #428
#1 - HardlyDifficult
2022-08-14T23:58:34Z
🌟 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
61.9406 USDC - $61.94
This could render the vault unfunctioning when the current owner accidently set address(0)
as the new owner. After function is called, noone will be able to relinquish the action and the entire contract will be ungovernable.
Add require (_newOwner != address(0), "address does not exist")
to ensure that address(0)
will not be input.
#0 - HardlyDifficult
2022-08-11T17:27:48Z
A check to help prevent user error may be nice to have here. Lowering sev and converting this into a QA report for the warden.
#1 - HardlyDifficult
2022-08-15T01:09:53Z