The pricing engine uses on-demand Monte Carlo simulation to compute risk-adjusted LTV and APR for each quote request.
Overview
The pricing engine answers three questions for every loan request:
How much can they borrow? - LTV and maximum loan amount
At what cost? - APR
What is the risk? - Probability of loss, expected PnL, VaR
Unlike pool-based protocols that use utilization curves or pre-calibrated LTV tables, the pricing engine simulates thousands of price paths for every quote. This provides position-specific pricing with transparent risk metrics.
Monte Carlo simulation
Price simulation model
Price paths are simulated using Geometric Brownian Motion with Student-t innovations:
S_{t+1} = S_t × exp(-σ²/2 × Δt + σ × √Δt × Z)
Where:
S_t = price at time t
σ = annualized volatility (with buffer applied)
Δt = time step in years
Z = Student-t random variable (df=5)
Student-t distribution with 5 degrees of freedom captures the fat tails observed empirically in crypto price movements. Normal distribution underestimates tail risk.
Simulation parameters
Parameter
Default
Description
n_paths
10,000
Number of simulated price paths
time_steps
100
Steps per path
volatility_buffer
1.1-1.2
Multiply observed volatility
The volatility buffer provides margin against volatility estimation error.
LTV optimization
Binary search
The engine finds the highest LTV satisfying policy constraints via binary search:
Each iteration runs the full Monte Carlo simulation at the candidate LTV and checks if policy constraints are satisfied.
Policy constraints
The search finds the highest LTV where:
P(loss) ≤ max_loss_probability (e.g., 2%)
E[PnL] ≥ -max_expected_shortfall (e.g., -30% of loan)
Liquidation modeling
Health factor
For each simulated path, the engine checks if the loan becomes undercollateralized:
Liquidation delay
Liquidation does not execute instantly when triggered. The engine models the delay between trigger and execution:
During this delay, a 2-sigma adverse price shock is applied:
Where τ is the delay duration in years.
Slippage calculation
Slippage is calculated by walking through actual Uniswap V3 tick data:
The stress_factor (default: 2.0) accounts for liquidity evaporation during market stress.
Risk metrics
Every simulation produces:
Metric
Formula
Description
P(Loss)
count(loss) / n_paths
Probability of losing money
P(Profit)
1 - P(Loss)
Probability of making money
E[PnL]
mean(all_outcomes)
Expected profit/loss
E[Loss|Loss]
mean(losses)
Average loss when loss occurs
VaR 99%
percentile(outcomes, 1)
Worst 1% outcome
APR calculation
Mode A: Competitive pricing
When a reference money market exists (ETH, WBTC on Aave):
This ensures competitive rates while maintaining a minimum based on actual costs.
Mode B: Synthetic pricing
When no reference market exists (governance tokens, long-tail assets):
Black-Scholes risk premium
The risk premium represents the cost of insuring against collateral dropping below the liquidation price:
Inventory adjustment
APR increases when lending capital is scarce:
This can add up to 10% premium at full utilization.
Policy parameters
Parameter
Default
Description
max_loss_probability
0.02
Maximum acceptable P(loss)
max_expected_shortfall
0.30
Maximum E[Loss] as fraction of loan
liquidation_delay_seconds
24
Time between trigger and execution
volatility_buffer
1.1
Multiply observed volatility
liquidity_stress_factor
2.0
Divide tick liquidity by this
Data sources
The pricing engine requires current market data:
Data
Source
Update frequency
Spot prices
Uniswap V3
Real-time
Tick liquidity
Uniswap V3
Hourly
Realized volatility
Computed from prices
Hourly
Reference rates
Aave V3
Hourly
Data freshness affects quote accuracy. Stale data can result in mispriced risk.
Performance
Operation
Time
Market data fetch
~100ms
Monte Carlo (10k paths)
~500ms
LTV optimization (15 iterations)
~7s
Total quote time
~8 seconds
For OTC lending, this latency is acceptable. The tradeoff provides significantly better accuracy and transparency compared to static curves.