Open code423n4 opened 2 years ago
Duplicate of many other issues
When an order is filled using ETH, the exchange collects fees by holding them in the contract for later withdraw. However the only withdraw mechanism does not work so that ETH becomes trapped forever.
This is a High risk issue since some ETH is lost with each ETH based trade.
Accepting this as the primary submission for its clear description of the relevance.
Lines of code
https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityExchange.sol#L1228-L1232
Vulnerability details
ETH fees accumulated from takeOrders() and takeMultipleOneOrders() operations are permanently frozen within the contract as there is only one way designed to retrieve them, a rescueETH() function, and it will work as intended, not being able to access ETH balance of the contract.
Setting the severity as high as the case is a violation of system's core logic and a permanent freeze of ETH revenue of the project.
Proof of Concept
Fees are accrued in user-facing takeOrders() and takeMultipleOneOrders() via the following call sequences:
While token fees are transferred right away, ETH fees are kept with the InfinityExchange contract:
https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityExchange.sol#L1119-L1141
I.e. when
currency
is ETH the fee part of the amount,protocolFee
, is left with the InfinityExchange contract.The only way to retrieve ETH from the contract is rescueETH() function:
https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/core/InfinityExchange.sol#L1228-L1232
However, it cannot reach ETH on the contract balance as
msg.value
is used as the amount to be sent over. I.e. only ETH attached to the rescueETH() call is transferred fromowner
todestination
. ETH funds that InfinityExchange contract holds remain inaccessible.Recommended Mitigation Steps
Consider adding contract balance to the funds transferred: