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 →
M-07·

Rounding error in put option price reduces safety margin

Not reportedoptionsleverageblack-scholes
TL;DR

The protocol applies the same strike price rounding logic to both CALL and PUT options.

Severity
MEDIUM
Method
MManual review
CAT.
02Section · Severity

Severity

Impact: Medium

Likelihood: Medium

03Section · Description

Description

The protocol applies the same strike price rounding logic to both CALL and PUT options. While this works in favor of the protocol for CALL options, it reduces safety for PUT options.

Specifically, the strike price is first computed by applying a relative discount to the current price (for PUTs), and then passed to _roundPrice(), which rounds upward if the remainder exceeds the midpoint. This pushes the strike closer to or into the money, reducing the out-of-the-money (OTM) buffer intended for PUT options.

solidity
function _calculateStrike(uint256 preciseCurrentPrice, uint256 relativeStrike) internal view returns (uint256) {
uint256 calculatedStrike = preciseCurrentPrice - ((preciseCurrentPrice * relativeStrike) / 100);
@> return _roundPrice(calculatedStrike);
}
solidity
function _roundPrice(uint256 price) internal view returns (uint256) {
RoundingOption currentRoundingOption_ = StrategyStorage.layout().setUp.base.currentRoundingOption;
uint256 remainder;
uint256 roundedDown;
if (currentRoundingOption_ == RoundingOption.NEAREST_HUNDRED) {
remainder = price % (100 * 1e18);
roundedDown = price - remainder;
@> if (remainder >= 50 * 1e18) return roundedDown + (100 * 1e18);
else return roundedDown;
} else if (currentRoundingOption_ == RoundingOption.NEAREST_TEN) {
remainder = price % (10 * 1e18);
roundedDown = price - remainder;
@> if (remainder >= 5 * 1e18) return roundedDown + (10 * 1e18);
else return roundedDown;
} else {
return price;
}
}

Consider this scenario with NEAREST_HUNDRED rounding: Scenario 1:

  • Spot price: 1000 USD.
  • Relative strike: 5%.
  • Raw PUT strike = 950 USD.
  • Rounded strike = 1000 USD (ATM instead of OTM).

Scenario 2:

  • Spot price: 3500 USD.
  • Relative strike: 10%.
  • Raw PUT strike = 3150 USD.
  • Rounded strike = 3200 USD (300 (~8.25% relative strike) OTM instead of 350 OTM).

In both cases, upward rounding reduces the distance between the strike and spot price for PUT positions.

04Section · Recommendation

Recommendation

Use different rounding directions for CALL and PUT options to reflect their opposite risk implications:

  • For CALL options, keep rounding strike prices up, since that makes them more out-of-the-money and benefits the protocol.
  • For PUT options, round down instead, so the strike stays further from the current price and doesn’t unintentionally favor the trader.
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.

M-07