# Comptroller._setUniV3LpVault will always cause in-use uniswapV3 positions to become stuck in UniV3LpVault

Admin changing Comptroller.uniV3LpVault orphans existing UniswapV3 NFT positions, blocking collateral valuation, withdrawal and liquidation for those tokens.

- Payout: Audit contest
- Severity: medium
- Program: Duality Focus
- Found by: rayn
- Disclosed: 2022-05-26
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2022-04-dualityfocus#m-02
- Library page: http://bugbountylibrary.com/r/c4%3A2022-04-dualityfocus%3AM-02
- Tags: area:web3 domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Comptroller / UniV3LpVault collateral accounting
**Root cause:** Comptroller.addNFTCollateral reads positions only from the current uniV3LpVault, so replacing the vault makes previously deposited NFTs invisible to liquidity checks; UniV3LpVault.withdrawToken's avoidsShortfall modifier then reverts.
**Steps:**
1. Admin calls `_setUniV3LpVault(newVault)`, overwriting `uniV3LpVault`.
2. User with existing NFT collateral calls `UniV3LpVault.withdrawToken(...)`.
3. `avoidsShortfall` calls `comptroller.getAccountLiquidity(msg.sender)`, which iterates `uniV3LpVault.getUserTokensLength(account)` on the new vault.
4. Old NFTs are not counted, shortfall computed incorrectly, require fails or liquidation path breaks.
**How found:** Code reading of the mutual dependency between Comptroller's collateral valuation and UniV3LpVault's shortfall modifier; noticed the settable vault address breaks the invariant that both contracts reference the same vault.
**Insight:** When two contracts must agree on a shared registry address for accounting, any admin setter that can change one side silently orphans state; check every mutable pointer used inside valuation/liquidation loops.

