Improper use of locked funds as liquidity in `PositionInteractionFacet`
When someone exercises a Call option, they receive their profit (pnl) in the buyToken.
Severity
Impact: Medium
Likelihood: High
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:
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:
- 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.
- No Actual Token Reservation: The contract mistakenly treats
rewardsByToken[pos.buyToken].totalRewardsas 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.
Recommendations
Multiple solutions can be considered to ensure proper handling of payouts of Call options:
- Avoid using the available
buyTokens for payouts of Call options; instead, swap theuAssetsas needed. - Track both available and locked balances for
buyToken. - Incorporate checks for
total stablecoin valueandlockedUsd, and consider swapping stablecoins to thebuyTokenas part of the payout process.
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.