# Partial transfers are still possible, leading to incorrect storage updates, and the calculated account premiums will be significantly different from what they should be

Panoptic transfer check only validates right-slot net liquidity, so users with both long and short positions in the same tick range can partially transfer ERC1155 tokens, corrupting s_accountLiquidity and premium accounting.

- Payout: Contest reward
- Severity: high
- Program: Panoptic
- Credited: osmanozdemir1
- Disclosed: 2024-06-24
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2023-11-panoptic-findings/issues/256
- Library page: https://bugbountylibrary.com/r/c4%3A2023-11-panoptic%3AH-02
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:accounting-error vuln:business-logic

**Target:** SemiFungiblePositionManager ERC1155 position transfer (registerTokenTransfer)
**Root cause:** registerTokenTransfer only checks fromLiq.rightSlot() == transferred liquidity, ignoring the left slot (removed liquidity); since long and short positions share a position key, a user holding both can transfer only the net-liquidity portion, overwriting storage to zero while retaining tokens.
**Steps:**
1. Mint 100 short put tokens in a tick range (left slot 0, right slot 100).
2. Mint 90 long put tokens in same ticks/type (left slot 90, right slot 10).
3. Call `sfpm.safeTransferFrom(Alice, Bob, tokenIdforShortPut, positionSize*1/10, "")` — passes because right slot equals transferred liquidity.
4. Observe Alice's s_accountLiquidity zeroed while she still holds 90 short + 90 long tokens; Bob's storage shows left slot 90, right slot 10.
5. Naive path: Alice burns her 90 long put tokens; unchecked `removedLiquidity -= chunkLiquidity` underflows to ~3.4e38.
**How found:** Code review of registerTokenTransfer noticed only rightSlot() is compared, then reasoned that position keys omit the long/short flag so long and short positions share storage, enabling partial transfer of net liquidity.
**Exploitation:** Attacker mints a large short put, mints ~99% long put in same ticks, then transfers the tiny remaining net-liquidity short tokens to a victim. Victim's s_accountLiquidity left slot is set to the attacker's removed liquidity, inflating the victim's owed premiums for that position; attacker keeps the long tokens needed to later burn/withdraw.
**Escalation:** Trap can be set on any victim who later mints in the same tick range, causing them to overpay premiums; naive users self-corrupt via unchecked underflow on burn.
**Insight:** When a transfer guard compares only one half of a packed LeftRight storage slot, check whether the other half (removed/owed liquidity) can be nonzero for the same key — especially when the key omits a flag (long/short) that distinguishes token IDs.
