# Memorializing an NFT position on the same bucket of a previously memorialized NFT locks redemption

Two users memorializing LP positions in the same Ajna bucket map to one lender address, so redeemPositions reverts with NoAllowance, locking direct redemption.

- Payout: Contest reward
- Severity: medium
- Program: Ajna
- Credited: MalfurionWhitehat
- Disclosed: 2022-12-21
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-ajna-judging/issues/13
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AM-22
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** PositionManager.sol / LenderActions.transferLPs on Ajna pools
**Root cause:** PositionManager centralizes all memorialized LPs under one lender address per pool; LenderActions.transferLPs requires transferring the full lenderLpBalance, so per-NFT redemption of a partial share reverts with NoAllowance.
**Steps:**
1. Alice and Bob each add 3000e18 quote to bucket 2550 of the same pool.
2. Each mints an NFT via PositionManager and calls memorializePositions for index 2550, approving LP ownership to PositionManager.
3. Both positions now map to PositionManager as the single lender for bucket 2550.
4. Either user calls PositionManager.redeemPositions(tokenId, pool, [2550]).
5. pool.transferLPs reverts with NoAllowance because the requested amount is less than the total lenderLpBalance.
**How found:** Code reading of PositionManager's shared-lender model combined with LenderActions.transferLPs exact-balance requirement; confirmed with a Foundry test memorializing two accounts into the same bucket and observing redeem revert.
**Exploitation:** Not an attack; griefing/lock scenario. Users can recover funds only by first calling PositionManager.moveLiquidity to a bucket with no other PositionManager-managed LPs, then redeemPositions.
**Insight:** When a wrapper contract aggregates user positions under one on-chain identity, check every downstream transfer/withdraw path that assumes the caller owns the entire balance — partial-share redemption will break.
