Should a user accidentally send ETH to the NestedFactory, anyone can utilise it to their own benefit by calling processOutputOrders() / processInputAndOutputOrders(). This is possible because:
receive() has no restriction on the sender
processOutputOrders() does not check msg.value, and rightly so, because funds are expected to come from reserve.
transferInputTokens() does not handle the case where ETH could be specified as an address by the user for an output order.
Hence, the attack vector is simple. Should a user accidentally send ETH to the contract, create an output Order with token being ETH and amount corresponding to the NestedFactory’s ETH balance.
Recommended Mitigation Steps
Since plain / directETH transfers are only expected to come from weth (excluding payable functions), we recommend restricting the sender to be weth, like how it is done in [FeeSplitter](https://github.com/code-423n4/2022-02-nested/blob/main/contracts/FeeSplitter.sol#L101-L104). Also, from what we see, plain ETH transfers are also not expected to come from other sources like NestedReserve or operators.
Lines of code
https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L71 https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L286-L296 https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L370-L375 https://github.com/code-423n4/2022-02-nested/blob/main/contracts/NestedFactory.sol#L482-L492
Vulnerability details
Impact
Should a user accidentally send ETH to the
NestedFactory
, anyone can utilise it to their own benefit by callingprocessOutputOrders()
/processInputAndOutputOrders()
. This is possible because:receive()
has no restriction on the senderprocessOutputOrders()
does not checkmsg.value
, and rightly so, because funds are expected to come fromreserve
.transferInputTokens()
does not handle the case whereETH
could be specified as an address by the user for an output order.Hence, the attack vector is simple. Should a user accidentally send ETH to the contract, create an output
Order
withtoken
beingETH
and amount corresponding to the NestedFactory’s ETH balance.Recommended Mitigation Steps
ETH
transfers are only expected to come fromweth
(excluding payable functions), we recommend restricting the sender to beweth
, like how it is done in[FeeSplitter](https://github.com/code-423n4/2022-02-nested/blob/main/contracts/FeeSplitter.sol#L101-L104)
. Also, from what we see, plain ETH transfers are also not expected to come from other sources likeNestedReserve
or operators.P.S we are aware that this was raised previously here: https://github.com/code-423n4/2021-11-nested-findings/issues/188 and would like to add that you can have
payable
functions without the existence of thereceive()
function._fromReserve
is false in the scenarioaddress(_inputToken) == ETH
.