v10.2 Update
Changelog
Summary
The depth bands feature replaces the simple "1% depth" price impact model with a 30-band system that provides granular control over price impact curves. This enhancement allows for more realistic market depth modeling.
Added
New Features
30 configurable bands (0-29) representing different liquidity depths
Piecewise calculation using trapezoidal rule for smooth price impact curves
Linear extrapolation beyond 100% depth for very large trades
Separate depth configurations for longs (above) and shorts (below)
Efficient storage packing: all band data in 2 slots per direction
Non-decreasing validation for band liquidity/offset values
New Data Structures
IPriceImpact.PairDepthBands
- Stores depth band liquidity configuration for each pair (4 slots: above/below Γ slot1/slot2)IPriceImpact.DepthBandsMapping
- Global mapping of band indices to band percentage offsets from mid price (2 slots)IPriceImpact.DepthBandParameters
- Working struct for depth band calculations
New Functions
initializeDepthBandsMapping(uint256 slot1, uint256 slot2)
- Initialize global bands offset mapping (reinitializer(25))setPairDepthBands(uint256[] indices, PairDepthBands[] depthBands)
- Set depth bands liquidity for multiple pairssetDepthBandsMapping(uint256 slot1, uint256 slot2)
- Configure global bands offset valuesgetPairDepthBands(uint256 pairIndex)
- Get single pair's encoded depth bandsgetPairDepthBands(uint256[] indices)
- Get multiple pairs' encoded depth bands (array version)getPairDepthBandsDecoded(uint256 pairIndex)
- Get single pair's decoded depth bandsgetPairDepthBandsDecoded(uint256[] indices)
- Get multiple pairs' decoded depth bands (array version)getDepthBandsMapping()
- Get global bands encoded mappinggetDepthBandsMappingDecoded()
- Get global bands decoded mapping
New Internal Functions
_getDepthBandsPriceImpactP()
- New price impact getter using depth bands_getTotalDepthUsd()
- Extract total depth usd from encoded slot_getBandValue()
- Extract band value from encoded slots (returns ppm for mappings, bps for depths)_calculateDepthBandsPriceImpact()
- Core calculation using trapezoidal rule for average fill price
New Constants
DEPTH_BANDS_COUNT = 30
- Total number of depth bandsDEPTH_BANDS_PER_SLOT1 = 14
- Number of bands stored in slot1HUNDRED_P_BPS = 1e4
- 100% in bps
Changed
Libraries
PriceImpactUtils
is now external and has been adjusted for the new bands feature
Modified Functions
getTradeCumulVolPriceImpactP()
- Now forwards to_getDepthBandsPriceImpactP
implementation using depth bands
Storage Updates
IPriceImpact.PriceImpactStorage
struct updated:Added
mapping(uint256 => PairDepthBands) pairDepthBands
Added
DepthBandsMapping depthBandsMapping
Reduced
__gap
array to [36] to accommodate new storage
Deprecated
Storage
pairDepths
- Replaced bypairDepthBands
Removed
Functions
setPairDepths()
- Replaced bysetPairDepthBands()
getPairDepth()
- Replaced bygetPairDepthBands()
getPairDepths()
- Replaced by array version ofgetPairDepthBands()
Technical Details
Band Structure
PairDepthBands (per-pair liquidity configuration):
Defines the actual liquidity distribution for each trading pair
30 bands representing cumulative percentages of total depth (0-100%)
Each band liquidity percentage stored as basis points (bps), e.g., 2500 = 25% of total depth
Separate configurations for above/below market price
Storage encoding per direction:
Slot1: totalDepthUsd (32 bits) + bands 0-13 (16 bits each)
Slot2: bands 14-29 (16 bits each)
DepthBandsMapping (global offset configuration):
Defines the cumulative offset from mid price at each band boundary
Values stored as parts per million (ppm), e.g., 130 = 0.013% offset from mid price
Storage encoding:
Slot1: bands 0-13 offsets (16 bits each, first 32 bits unused)
Slot2: bands 14-29 offsets (16 bits each)
Calculation Method
Iterate through bands until trade size is consumed
Use trapezoidal rule for average impact within each band
Weight each band's contribution by depth consumed
Support linear extrapolation beyond 100% for large trades
Variable Naming Conventions
Variables ending in
Usd
represent USD-denominated values (1e18)Variables ending in
Ppm
represent parts per million (1e6) => percentage with 4 decimalsVariables ending in
Bps
represent basis points (1e4) => percentage with 2 decimalspriceImpactP
represents price impact percentage in 1e10 precision
Migration Path
Initialize global depth bands mapping using
initializeDepthBandsMapping()
Migrate existing pairs from old depth model to depth bands
New pairs should use
setPairDepthBands()
directlyBetween deployment and setting bands, dynamic price impact will be 0
Monitor and adjust band configurations as needed
Key Specifications
Backwards Compatibility
Fully backwards compatible: The new depth bands system produces identical results to the previous linear formula when configured with linear bands and the same depth values
Validation Requirements
Pair depth bands: Must include the value 100% (10,000 bps) as one of the band values and it must be the maximum value
Pair depth bands: Must be non-decreasing across bands since they are cumulative (each band value β₯ previous band value)
Global depth offsets: Must be non-decreasing across bands since they are cumulative (each offset β₯ previous offset)
Trade Splitting Protection
Cumulative volume price impact: Has 2x weight in the calculation to ensure trade splitting remains unprofitable
This design choice prevents traders from gaming the system by splitting large trades into smaller ones
Gas Optimization
Efficient storage packing reduces reads to 2 slots per direction + 2 slots for global offsets => 4 slots total
Early exit from loop when trade size has been consumed
Last updated
Was this helpful?