# AuraSpell `openPositionFarm` will revert when the tokens contains `lpToken`

AuraSpell.openPositionFarm shrinks amountsIn via assembly when lpToken is in tokens, mismatching maxAmountsIn length and reverting Balancer joinPool.

- Payout: Contest reward
- Severity: medium
- Program: Blueberry
- Credited: bitsurfer
- Disclosed: 2023-07-12
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-07-blueberry-judging/issues/125
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-07-blueberry%3AM-12
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:dos

**Target:** AuraSpell.openPositionFarm / Balancer vault joinPool
**Root cause:** _getJoinPoolParamsAndApprove builds maxAmountsIn of length tokens.length but truncates amountsIn by one via assembly mstore when lpToken is present, so the two arrays passed to Balancer's joinPool differ in length.
**Steps:**
1. Call AuraSpell.openPositionFarm with a tokens array that includes lpToken.
2. _getJoinPoolParamsAndApprove sets isLPIncluded=true and skips lpToken when filling amountsIn (j index), leaving amountsIn shorter.
3. Assembly `mstore(amountsIn, sub(mload(amountsIn), 1))` further reduces amountsIn length.
4. vault.joinPool receives maxAmountsIn length N and userData-encoded amountsIn length N-1.
5. Balancer's length check reverts, so the position cannot be opened.
**How found:** Code review of the JoinPoolRequest construction; noticed maxAmountsIn and amountsIn are built with different indices and the assembly truncation, then cross-checked Balancer's requirement that both arrays match length.
**Insight:** When a helper builds parallel arrays with a skip-index (j) plus an assembly length truncation, verify every downstream consumer's length invariant; Balancer joinPool requires maxAmountsIn and userData amountsIn to be equal length.
