Docile Grey Albatross - Lack of nonReentrant modifier in fillOrder() and modifyOrder() allows attacker to steal funds #421
Labels
Sponsor Confirmed
The sponsor acknowledged this issue is valid
Will Fix
The sponsor confirmed this issue will be fixed
Docile Grey Albatross
High
Lack of nonReentrant modifier in fillOrder() and modifyOrder() allows attacker to steal funds
Description
Root Causes:
txData
.nonReentrant
modifier.nonReentrant
modifier.Attack Path: (Please refer PoC for detailed execution flow)
pendingOrderIds
looks like:Order-N
is by the victim, a naive user. OrdersA1
andA2
are by the attacker.Order-A1
andOrder-A2
recipient is a contract with address say,target
.Order-A1
is in range so they callfillOrder()
with malicioustxData
.fillOrder()
internally callsexecute()
which internally callstarget.call(txData)
where bothtarget
andtxData
are attacker controlled.target
contract (let's say a function namedattack()
), they pull the tokenIn (WETH) ofOrder-A1
as they have the approval.attack()
then sends1 wei
of tokenOut (USDC) or any minimum amount back. The attacker will get this back later.attack()
then callsmodifyOrder(Order-A1)
and decreases the position size to the minimum allowed. They are immediately credited say,M
WETH.attack()
next callsmodifyOrder(Order-A2)
and increases the position size to park thisM
WETH. This is done so that the overall WETH balance of OracelLess contract is not affected by this theft and the following check about over-spend insideexecute()
passes successfully:attack()
andfillOrder()
continues further. The code goes ahead and removesOrder-A1
from the pending order array and sends back the1 wei
USDC totarget
on L141. The attacker is at no loss & no gain right now.Order-A2
and receives theM
WETH back too, thus stealing it from the rightful funds of the victim/protocol.Note: In spite of similar structures, this attack can't be carried out inside
Bracket.sol::performUpkeep()
asBracket.sol::modifyOrder()
is protected by thenonReentrant
modifier.Impact
High. Victim & protocol funds can be stolen at no substantial cost to the attacker.
Proof Of Concept
MaliciousOracleLessTarget.sol
under thecontracts/
directory:View MaliciousOracleLessTarget.sol
2. Second, add the following test case inside `test/triggerV2/happyPath.ts` and run to see it pass:
View Test Case
Output:
Mitigation
Add the
nonReentrant
modifier to bothOracleLess.sol::fillOrder()
andOracleLess.sol::modifyOrder()
.The text was updated successfully, but these errors were encountered: