# Improper precision of strike price calculation can result in broken protocol

Dopex's roundUp with 1e6 precision rounds the 25% OTM rDPX put strike back to spot, making options ITM and overcharging bonders' premiums.

- Payout: Contest reward
- Severity: high
- Program: Dopex
- Credited: Toshii
- Disclosed: 2023-12-29
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-08-dopex-findings/issues/2083
- Library page: https://bugbountylibrary.com/r/c4%3A2023-08-dopex%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:precision-loss

**Target:** RdpxV2Core / PerpetualAtlanticVault Solidity contracts
**Root cause:** roundUp uses roundingPrecision=1e6 on an 8-decimal ETH/rDPX price, so 75% of a ~1e6 spot price (75e4) rounds up to 1e6, equal to spot rather than 25% OTM.
**Steps:**
1. Note rdpxPrice is ETH/rDPX in 8 decimals; at $2000/ETH and $20/rDPX it equals 1e6.
2. Call bond() -> calculateBondCost() computes strike = roundUp(rdpxPrice - rdpxPrice/4) = roundUp(75e4).
3. roundUp: 75e4 % 1e6 != 0, returns 75e4 - 75e4 + 1e6 = 1e6.
4. Strike 1e6 equals spot, so the put is ITM; calculatePremium(strike, rdpxRequired, timeToExpiry, 0) charges a much higher premium than intended.
**How found:** Code reading of calculateBondCost and roundUp; noticed roundingPrecision=1e6 is comparable to the 8-decimal price scale, then tested with realistic ETH/rDPX prices.
**Insight:** When a rounding granularity is the same order of magnitude as the scaled price itself, rounding can silently erase the intended discount/multiplier; check roundUp/roundDown precision against realistic token price magnitudes.
