# RiskEngine::_getRequiredCollateralAtTickSinglePosition() fails to accumulate credits across multiple legs, leading to potential erroneous liquidations

RiskEngine overwrote instead of accumulating credits across multiple long width-0 legs, undercounting margin and causing solvent accounts to be wrongly liquidated.

- Payout: Contest reward
- Severity: medium
- Program: Panoptic
- Credited: joicygiore
- Disclosed: 2026-03-09
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-12-panoptic-next-core#m-02
- Library page: https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AM-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:liquidation

**Target:** RiskEngine.sol _getRequiredCollateralAtTickSinglePosition collateral/margin calculation
**Root cause:** The credits variable is assigned (=) inside the per-leg loop instead of accumulated (+=), so only the last qualifying leg's credit survives and earlier legs' credits are discarded.
**Steps:**
1. Construct a tokenId with multiple legs where more than one leg has width(index)==0 && isLong(index)==1 and matching tokenType.
2. Call _getRequiredCollateralAtTickSinglePosition (or isAccountSolvent) on that tokenId.
3. Observe credits equals only the last matching leg's amountsMoved slot rather than the sum.
4. Compare against expected summed credits to confirm undercount, then verify isAccountSolvent misclassifies a solvent account as insolvent.
**How found:** Code review of the per-leg loop in _getRequiredCollateralAtTickSinglePosition, noticing the credits assignment uses '=' rather than '+=' across iterations.
**Exploitation:** No direct attacker extraction described; the undercounted credits propagate through isAccountSolvent → _getMargin → _getTotalRequiredCollateral, causing solvent multi-leg accounts to be flagged insolvent and liquidated.
**Insight:** In per-leg/per-asset loops, audit every accumulator for overwrite-vs-accumulate bugs; a single '=' where '+=' is intended silently drops earlier contributions and skews downstream solvency math.
