Donation attack can cause loss of users liquidity or undesired tick rebalance by price manipulation.
Proof of Concept
An attacker can cause constant rebalancing, instability, and along with the vulnerability of slot0 in the getTokenAmountsExcludingFees function, manipulation of ticks and prices by sending a different token since it is not validated that the token sent to the withdraw function is one of the valid GeVault tokens.
If the attacker manipulates the uniswap pool with a flashloan/flashswap in conjunction with the slot0 vulnerability in the function getTokenAmountsExcludingFees it can cause unwanted rebalancing of undesired prices.
Scenario 2:
A user mistakenly transfers a token other than token0 and token1 or an attacker transfers an amount of several different tokens.
If a normal user wants to withdraw his liquidity and mistakenly sends the address of another token (one of the tokens sent in the previous step).
this user would be losing/burning their liquidity and getting an unwanted token that could be worth less than their liquidity.
function withdraw(uint liquidity, address token) public nonReentrant returns (uint amount) {
require(poolMatchesOracle(), "GEV: Oracle Error");
if (liquidity == 0) liquidity = balanceOf(msg.sender);
require(liquidity <= balanceOf(msg.sender), "GEV: Insufficient Balance");
require(liquidity > 0, "GEV: Withdraw Zero");
uint vaultValueX8 = getTVL();
uint valueX8 = vaultValueX8 * liquidity / totalSupply();
amount = valueX8 * 10**ERC20(token).decimals() / oracle.getAssetPrice(token);
uint fee = amount * getAdjustedBaseFee(token == address(token1)) / 1e4;
_burn(msg.sender, liquidity);
removeFromAllTicks();
ERC20(token).safeTransfer(treasury, fee);
uint bal = amount - fee;
if (token == address(WETH)){
WETH.withdraw(bal);
payable(msg.sender).transfer(bal);
}
else {
ERC20(token).safeTransfer(msg.sender, bal);
}
// if pool enabled, deploy assets in ticks, otherwise just let assets sit here until totally withdrawn
if (isEnabled) deployAssets();
emit Withdraw(msg.sender, token, amount, liquidity);
}
Tools Used
Manual Analysis
Recommended Mitigation Steps
Validate at the beginning of the function that the address sent by the user is one of the valid tokens for the vault (token0 or token1)
Lines of code
https://github.com/GoodEntry-io/ge/blob/8a2686b14114edbd1ec523d79304ed678cc2e915/contracts/GeVault.sol#L214-L241
Vulnerability details
Impact
Donation attack can cause loss of users liquidity or undesired tick rebalance by price manipulation.
Proof of Concept
An attacker can cause constant rebalancing, instability, and along with the vulnerability of slot0 in the getTokenAmountsExcludingFees function, manipulation of ticks and prices by sending a different token since it is not validated that the token sent to the withdraw function is one of the valid GeVault tokens.
Scenario 1:
Scenario 2:
Tools Used
Manual Analysis
Recommended Mitigation Steps
Validate at the beginning of the function that the address sent by the user is one of the valid tokens for the vault (token0 or token1)
Assessed type
Other