# Then getAmountsForDelta function at Underlying.sol is implemented incorrectly

Arrakis Underlying.getAmountsForDelta used <= instead of < for the lower-bound tick check, so at price==lower tick it requested only token0 while Uniswap required both tokens.

- Payout: Contest reward
- Severity: medium
- Program: Arrakis
- Credited: 0x007
- Disclosed: 2023-06-05
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-06-arrakis-judging/issues/8
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-arrakis%3AM-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** Solidity library Underlying.sol (Uniswap V3 liquidity math)
**Root cause:** The left-out-of-range branch used `sqrtRatioX96 <= sqrtRatioAX96`, treating price equal to the lower tick as outside the range, whereas Uniswap V3 only treats it as outside when strictly below (`tick < tickLower`).
**Steps:**
1. Read `Underlying.getAmountsForDelta` in v2-core/contracts/libraries/Underlying.sol around L311.
2. Note branch `if (sqrtRatioX96 <= sqrtRatioAX96)` returns only amount0 via `SqrtPriceMath.getAmount0Delta(sqrtRatioAX96, sqrtRatioBX96, liquidity)`.
3. Compare to UniswapV3Pool.mint: `if (_slot0.tick < params.tickLower)` computes amount0 only; equality falls into the in-range branch requiring both tokens.
4. Set current price exactly equal to the range's lower tick and call the Arrakis add-liquidity path; observe only token0 requested from user while pool pulls both.
5. Fix: change `<=` to `<`.
**How found:** Code-reading comparison of Arrakis's liquidity-delta math against the canonical Uniswap V3 pool mint logic, spotting the boundary inequality mismatch at the lower tick.
**Exploitation:** Not a theft primitive: attacker must supply equivalent token0; when price equals the lower tick the pool pulls token1 from Arrakis's own balance to cover the shortfall, so the protocol (not the attacker) loses the token1 amount, bounded by pool balance and slippage checks.
**Insight:** When reimplementing Uniswap V3 liquidity math, diff every boundary comparison against the reference pool: equality at tickLower/tickUpper belongs to the in-range branch, and an off-by-one there silently shifts which token the protocol subsidizes.
