Pre-auditThree days of senior audit time for $1,500, credited in full toward your Zealynx audit.3 audit days, credited toward your auditSee how →
H-06·

`payOff()` underflow in `OperationalTreasury` locks assets permanently

Not reportedoptionsleverageblack-scholes
TL;DR

The payOff() function in the OperationalTreasury contract calculates feesUSD based on the full position size and current price, without considering the actual profit (pnl).

Severity
HIGH
Method
MManual review
CAT.
02Section · Severity

Severity

Impact: High

Likelihood: Medium

03Section · Description

Description

The payOff() function in the OperationalTreasury contract calculates feesUSD based on the full position size and current price, without considering the actual profit (pnl). Specifically:

  • feesUSD = positionAmount × FeePercentage × CurrentPrice
  • pnl = positionAmount × (CurrentPrice - StrikePrice)

This means that for positions where CurrentPrice is only slightly above StrikePrice, the calculated feesUSD may exceed the pnl. In such cases,the netAmount = pnl - feesUSD line will underflow:

solidity
function payOff(uint256 positionID, address account) external override nonReentrant whenNotPaused {
--snip--
@2> IPositionInteraction(baseSetUp.pool).exerciseOrLiquidatePosition(close);
uint256 feesUSD = _calculateFeesUSD(uAsset, uint256(amount)).toDecimals(18, baseSetUp.token.decimals());
@1> uint256 netAmount = pnl - feesUSD;
// fees deduced from PnL
strg.ledger.collectedFees[address(baseSetUp.token)] += feesUSD;
--snip--
}

When payOff() reverts due to the underflow at @1>, the call to exerciseOrLiquidatePosition() at @2> is not executed. As a result, the underlying assets in the pool remain locked forever.

04Section · Recommendations

Recommendations

Cap the fees to be no greater than the actual pnl to prevent underflow and allow position closure:

solidity
uint256 feesUSD = _calculateFeesUSD(...);
if (feesUSD > pnl) {
feesUSD = pnl;
}
uint256 netAmount = pnl - feesUSD;
05Section · Report provenance

Report provenance

Published by Pashov Audit Group, with Carlos (Bloqarl) participating as a contractor. The source report states that its fixes review was not fully completed; no final remediation disposition is recorded for this finding. Read the full report.

H-06