This repository has been archived by the owner on Jan 7, 2024. It is now read-only.
xiaoming90 - Lack of segregation between users' assets and collected fees resulting in loss of funds for the users #48
Labels
Has Duplicates
A valid issue with 1+ other issues describing the same vulnerability
High
A valid High severity issue
Reward
A payout will be made for this issue
Will Fix
The sponsor confirmed this issue will be fixed
xiaoming90
high
Lack of segregation between users' assets and collected fees resulting in loss of funds for the users
Summary
The users' assets are wrongly sent to the owner due to a lack of segregation between users' assets and collected fees, which might result in an irreversible loss of assets for the victims.
Vulnerability Detail
GLX uses the Chainlink Automation to execute the
LimitOrderRegistry.performUpkeep
function when there are orders that need to be fulfilled. TheLimitOrderRegistry
contract must be funded with LINK tokens to keep the operation running.To ensure the LINK tokens are continuously replenished and funded, users must pay a fee denominated in Native ETH or ERC20 WETH tokens on orders claiming as shown below. The collected ETH fee will be stored within the
LimitOrderRegistry
contract.https://github.com/sherlock-audit/2023-06-gfx/blob/main/uniswap-v3-limit-orders/src/LimitOrderRegistry.sol#L696
To retrieve the ETH fee collected, the owner will call the
LimitOrderRegistry.withdrawNative
function that will send all the Native ETH and ERC20 WETH tokens within theLimitOrderRegistry
contract to the owner's address. After executing this function, the Native ETH and ERC20 WETH tokens on this contract will be zero and wiped out.https://github.com/sherlock-audit/2023-06-gfx/blob/main/uniswap-v3-limit-orders/src/LimitOrderRegistry.sol#L505
Most owners will automate replenishing the
LimitOrderRegistry
contract with LINK tokens to ensure its balance does not fall below zero and for ease of maintenance. For instance, a certain percentage of the collected ETH fee (e.g., 50%) will be swapped immediately to LINK tokens on a DEX upon collection and transferred the swapped LINK tokens back to theLimitOrderRegistry
contract. The remaining will be spent to cover operation and maintenance costs.However, the issue is that there are many Uniswap V3 pools where their token pair consists of ETH/WETH. In fact, most large pools in Uniswap V3 will consist of ETH/WETH. For instance, the following Uniswap pools consist of ETH/WETH as one of the pool tokens:
Assume that the owner has configured and setup the
LimitOrderRegistry
contract to work with the Uniswap DAI/ETH pool, and the current price of the DAI/ETH pool is 1,500 DAI/ETH.Bob submit a new Buy Limit Order swapping DAI to ETH at the price of 1,000 DAI/ETH. Bob would deposit 1,000,000 DAI to the
LimitOrderRegistry
contract.When Bob's Buy Limit Order is ITM and fulfilled, 1000 ETH/WETH will be sent to and stored within the
LimitOrderRegistry
contract.The next step that Bob must do to claim the swapped 1000 ETH/WETH is to call the
LimitOrderRegistry.claimOrder
function, which will collect the fee and transfer the swapped 1000 ETH/WETH to Bob.Unfortunately, before Bob could claim his swapped ETH/WETH, the
LimitOrderRegistry.withdrawNative
function is triggered by the owner or the owner's bots. As noted earlier, when theLimitOrderRegistry.withdrawNative
function is triggered, all the Native ETH and ERC20 WETH tokens on this contract will be transferred to the owner's address. As a result, Bob's 1000 swapped ETH/WETH stored within theLimitOrderRegistry
contract are sent to the owner's address, and the balance of ETH/WETH in theLimitOrderRegistry
contract is zero.When Bob calls the
LimitOrderRegistry.claimOrder
function, the transaction will revert because insufficient ETH/WETH is left in theLimitOrderRegistry
contract.Unfortunately for Bob, there is no way to recover back his ETH/WETH that is sent to the owner's address. Following outline some of the possible scenarios where this could happen:
LimitOrderRegistry
contract, and there is no way to retrieve the deposited LINK tokens from theLimitOrderRegistry
contract even if the owner wishes to do so as there is no function within the contract to allow this action.Impact
Loss of assets for the users
Code Snippet
https://github.com/sherlock-audit/2023-06-gfx/blob/main/uniswap-v3-limit-orders/src/LimitOrderRegistry.sol#L505
Tool used
Manual Review
Recommendation
Consider implementing one of the following solutions to mitigate the issue:
Solution 1 - Only accept Native ETH as fee
Uniswap V3 pool stored ETH as Wrapped ETH (WETH) ERC20 token internally. When the
collect
function is called against the pool, WETH ERC20 tokens are returned to the caller. Thus, the most straightforward way to mitigate this issue is to update the contract to collect the fee in Native ETH only.In this case, there will be a clear segregation between users' assets (WETH) and owner's fee (Native ETH)
Solution 2 - Define state variables to keep track of the collected fee
Consider defining state variables to keep track of the collected fee so that the fee will not mix up with users' assets.
The text was updated successfully, but these errors were encountered: