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-04·

Improper use of locked funds as liquidity in `PositionInteractionFacet`

Not reportedoptionsleverageblack-scholes
TL;DR

When someone exercises a Call option, they receive their profit (pnl) in the buyToken.

Severity
HIGH
Method
MManual review
CAT.
02Section · Severity

Severity

Impact: Medium

Likelihood: High

03Section · Description

Description

When someone exercises a Call option, they receive their profit (pnl) in the buyToken. The contract should only use available (not locked) tokens for this payout, or swap assets if needed. The _payout() function attempts to use unclaimed LP rewards (premiums) to cover option payouts:

solidity
function _payout(Position memory pos, PositionClose memory close) internal returns (uint256 pnl) {
--snip--
uint256 availablePayoutToken = strg.ledger.state.rewardsByToken[pos.buyToken].totalRewards;
pnl = close.pnl;
if (pos.opType == OptionType.CALL && availablePayoutToken < pnl) {
uint256 swapOut = pnl - availablePayoutToken;
_swapAssetToAsset(pos.uAsset, pos.buyToken, swapOut);
}
--snip--
strg.ledger.state.poolAmount[pos.buyToken] -= pnl;
_doTransferOut(pos.buyToken, msg.sender, pnl);
}

However, this approach is fundamentally flawed because:

  1. Rewards Are Already Distributed: The reward system works by updating indexes, meaning rewards are considered distributed to users as soon as they're accrued, even if not yet claimed.
  2. No Actual Token Reservation: The contract mistakenly treats rewardsByToken[pos.buyToken].totalRewards as available liquidity when these funds are already allocated to users and some users may even have claimed their rewards.

As a result, when paying out Call options, the contract incorrectly uses part of the buyToken balance (the amount equal to totalRewards) to cover the user’s profit (pnl). However, it does not account for the portion of buyToken that is locked and reserved for fulfilling Put option payouts.

04Section · Recommendations

Recommendations

Multiple solutions can be considered to ensure proper handling of payouts of Call options:

  1. Avoid using the available buyTokens for payouts of Call options; instead, swap the uAssets as needed.
  2. Track both available and locked balances for buyToken.
  3. Incorporate checks for total stablecoin value and lockedUsd, and consider swapping stablecoins to the buyToken as part of the payout process.
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-04