LiquidityPool.sol

General Overview

The Liquidity Pool holds most core functionality for the Rysk Dynamic Hedging Vault, it is responsible for managing all funds. It uses several libraries and contracts which have been explained in other docs.

Throughout the contract there are conversions between decimals, there are three decimals to be aware of e6 (USDC decimals) or collateral decimals, e8 otoken decimals and e18 share value, eth, and options calculation decimals. Where each decimal type is used is commented in each function.

Oracle use

The contract uses Chainlink Price feed oracles. The contract also makes use of the Portfolio values feed request response oracle and may in the future make use of a volatility feed oracle. These are documented in the oracle documentation.

Descriptions

Most variables and functions if not mentioned here can be fully explained by their natspec in the contracts so have been left out

hedgingReactors

This variable is an array that stores hedging reactor addresses. Each hedging reactor can be referenced by its index in rebalancePortfolioDelta or each hedging reactor is referenced by iterating over the array, for example in completeWithdraw() or getPortfolioDelta(). When a hedging reactor is added it is added to the last place of the array, when removed the array should be shifted so as not to leave any array elements as zero addresses.

pauses

There is pause and unpause functionality which pauses all state changing functionality. There is also pause and unpause trading which pauses any options buying or selling activity from the pool. This pause functionality can be executed by Guardians or above.

optionParams

This is a struct that contains variables that pertain to the min and max call strike which are the minimum and maximum strikes that can be written for calls by the pool and the min and max put strikes. The min and max expiry are also stored which are the minimum and maximum length options that the pool can write. These variables can be updated by management or above and helps with managing pool exposure depending on the market outlook.

max price and time deviation thresholds

These values are used to set the time and price thresholds for when an oracle update becomes stale. For example, if an oracle update was done at 600 and the threshold is 10 if the time is now 611 the oracle update is stale and the pool will not do anything until the oracle is updated again. This is to deal with the value of the pool changing due to price and time movement and thus the liability value and delta value being off.

handler

These are contracts that have the authority to issue, write, and buyback options from the liquidityPool. They must be authorised. This architecture allows for multiple handlers and upgradeability on the handlers.

Mutual fund system (deposit(), redeem(), initiateWithdraw(), completeWithdraw(), pauseTradingAndRequest(), executeEpochCalculations())

An explainer of the mutual fund system or how deposits/withdraws/redeems/pauseTradingAndRequest and executeEpochCalculation work can be seen here: Deposit and Withdraw Mechanism

rebalancePortfolioDelta()

This function uses hedging reactors to hedge off a specified delta. The manager (or above) will specify the delta to hedge and the index of the reactor in the hedgingReactors array. The hedging reactor can be anything that implements the IHedgingReactor interface, it is used for accessing alternate derivatives that can be used for delta hedging. Currently only spot and perps are implemented but any derivative or asset can be implemented in the future.

adjustCollateral()

This function is used by the option registry to update the collateralAllocated in the LiquidityPool when funds are moved around. If the option registry is moving funds back into the LiquidityPool then it will decrease collateralAllocated. If the option registry is moving funds from the LiquidityPool then it will get a safe approval and will increase the collateralAllocated. Collateral allocated should never drop below negative because the balance of option registry should not go up beyond what it is allocated (because it generates no profits from providing collateral)(it can only go down, say if an option gets exercised).

settleVault()

This function is used to settle a vault and move collateral between the registry and the vault when an option expires.

getPortfolioDelta()

This function is used to get the portfolio delta. This first retrieves the delta from the portfolio value feed oracle (making sure it isnt stale), it then gets the delta from all hedging reactors finally it gets the ephemeralDelta that has been recorded between a request and response.

Normal Distribution approximation library

Reference for implementation:

https://www.johndcook.com/blog/2021/11/05/normal-tail-estimate/

https://www.johndcook.com/blog/2009/01/19/stand-alone-error-function-erf/

Black scholes library

Reference for implementation:

http://www.quantacademy.com/2014/09/options-greeks-calculation-with-python/

Contract used as the Dynamic Hedging Vault for storing funds, issuing shares and processing options transactions

Interacts with the OptionRegistry for options behaviour, Interacts with hedging reactors for alternative derivatives Interacts with Handlers for periphary user options interactions. Interacts with Chainlink price feeds throughout. Interacts with Volatility Feed via getImpliedVolatility(), interacts with a chainlink PortfolioValues external adaptor oracle via PortfolioValuesFeed.

immutable variables ///

protocol

contract Protocol protocol

strikeAsset

address strikeAsset

underlyingAsset

address underlyingAsset

collateralAsset

address collateralAsset

collateralAllocated

uint256 collateralAllocated

dynamic variables ///

ephemeralLiabilities

int256 ephemeralLiabilities

ephemeralDelta

int256 ephemeralDelta

depositEpoch

uint256 depositEpoch

withdrawalEpoch

uint256 withdrawalEpoch

depositEpochPricePerShare

mapping(uint256 => uint256) depositEpochPricePerShare

withdrawalEpochPricePerShare

mapping(uint256 => uint256) withdrawalEpochPricePerShare

depositReceipts

mapping(address => struct IAccounting.DepositReceipt) depositReceipts

withdrawalReceipts

mapping(address => struct IAccounting.WithdrawalReceipt) withdrawalReceipts

pendingDeposits

uint256 pendingDeposits

pendingWithdrawals

uint256 pendingWithdrawals

partitionedFunds

uint256 partitionedFunds

bufferPercentage

uint256 bufferPercentage

governance settable variables ///

hedgingReactors

address[] hedgingReactors

collateralCap

uint256 collateralCap

maxDiscount

uint256 maxDiscount

bidAskIVSpread

uint256 bidAskIVSpread

optionParams

struct Types.OptionParams optionParams

riskFreeRate

uint256 riskFreeRate

handler

mapping(address => bool) handler

isTradingPaused

bool isTradingPaused

maxTimeDeviationThreshold

uint256 maxTimeDeviationThreshold

maxPriceDeviationThreshold

uint256 maxPriceDeviationThreshold

belowThresholdGradient

uint256 belowThresholdGradient

aboveThresholdGradient

uint256 aboveThresholdGradient

aboveThresholdYIntercept

uint256 aboveThresholdYIntercept

utilizationFunctionThreshold

uint256 utilizationFunctionThreshold

keeper

mapping(address => bool) keeper

MAX_BPS

uint256 MAX_BPS

constant variables ///

DepositEpochExecuted

event DepositEpochExecuted(uint256 epoch)

structs && events ///

WithdrawalEpochExecuted

event WithdrawalEpochExecuted(uint256 epoch)

Withdraw

event Withdraw(address recipient, uint256 amount, uint256 shares)

Deposit

event Deposit(address recipient, uint256 amount, uint256 epoch)

Redeem

event Redeem(address recipient, uint256 amount, uint256 epoch)

InitiateWithdraw

event InitiateWithdraw(address recipient, uint256 amount, uint256 epoch)

WriteOption

event WriteOption(address series, uint256 amount, uint256 premium, uint256 escrow, address buyer)

SettleVault

event SettleVault(address series, uint256 collateralReturned, uint256 collateralLost, address closer)

BuybackOption

event BuybackOption(address series, uint256 amount, uint256 premium, uint256 escrowReturned, address seller)

constructor

constructor(address _protocol, address _strikeAsset, address _underlyingAsset, address _collateralAsset, uint256 rfr, string name, string symbol, struct Types.OptionParams _optionParams, address _authority) public

pause

function pause() external

setters ///

pauseUnpauseTrading

function pauseUnpauseTrading(bool _pause) external

unpause

function unpause() external

setHedgingReactorAddress

function setHedgingReactorAddress(address _reactorAddress) external

set a new hedging reactor

only governance can call this function

NameTypeDescription

_reactorAddress

address

append a new hedging reactor

removeHedgingReactorAddress

function removeHedgingReactorAddress(uint256 _index, bool _override) external

remove a new hedging reactor by index

only governance can call this function

NameTypeDescription

_index

uint256

remove a hedging reactor

_override

bool

whether to override whether the reactor is wound down (THE REACTOR SHOULD BE WOUND DOWN SEPERATELY)

setNewOptionParams

function setNewOptionParams(uint128 _newMinCallStrike, uint128 _newMaxCallStrike, uint128 _newMinPutStrike, uint128 _newMaxPutStrike, uint128 _newMinExpiry, uint128 _newMaxExpiry) external

update all optionParam variables for max and min strikes and max and min expiries for options that the DHV can issue

only management or above can call this function

setBidAskSpread

function setBidAskSpread(uint256 _bidAskSpread) external

set the bid ask spread used to price option buying

only management or above can call this function

NameTypeDescription

_bidAskSpread

uint256

the bid ask spread to update to

setMaxDiscount

function setMaxDiscount(uint256 _maxDiscount) external

set the maximum percentage discount for an option

only management or above can call this function

NameTypeDescription

_maxDiscount

uint256

of the option as a percentage in 1e18 format. ie: 1*e18 == 1%

setCollateralCap

function setCollateralCap(uint256 _collateralCap) external

set the maximum collateral amount allowed in the pool

only governance can call this function

NameTypeDescription

_collateralCap

uint256

of the collateral held

setBufferPercentage

function setBufferPercentage(uint256 _bufferPercentage) external

update the liquidity pool buffer limit

only governance can call this function

NameTypeDescription

_bufferPercentage

uint256

the minimum balance the liquidity pool must have as a percentage of collateral allocated to options. (for 20% enter 2000)

setRiskFreeRate

function setRiskFreeRate(uint256 _riskFreeRate) external

update the liquidity pool risk free rate

NameTypeDescription

_riskFreeRate

uint256

the risk free rate of the market

setMaxTimeDeviationThreshold

function setMaxTimeDeviationThreshold(uint256 _maxTimeDeviationThreshold) external

update the max oracle time deviation threshold

setMaxPriceDeviationThreshold

function setMaxPriceDeviationThreshold(uint256 _maxPriceDeviationThreshold) external

update the max oracle price deviation threshold

changeHandler

function changeHandler(address _handler, bool auth) external

change the status of a handler

setKeeper

function setKeeper(address _keeper, bool _auth) external

change the status of a keeper

setUtilizationSkewParams

function setUtilizationSkewParams(uint256 _belowThresholdGradient, uint256 _aboveThresholdGradient, uint256 _utilizationFunctionThreshold) external

@notice sets the parameters for the function that determines the utilization price factor The function is made up of two parts, both linear. The line to the left of the utilisation threshold has a low gradient while the gradient to the right of the threshold is much steeper. The aim of this function is to make options much more expensive near full utilization while not having much effect at low utilizations. @param _belowThresholdGradient the gradient of the function where utiization is below function threshold. e18 @param _aboveThresholdGradient the gradient of the line above the utilization threshold. e18 @param _utilizationFunctionThreshold the percentage utilization above which the function moves from its shallow line to its steep line

rebalancePortfolioDelta

function rebalancePortfolioDelta(int256 delta, uint256 reactorIndex) external

function for hedging portfolio delta through external means

NameTypeDescription

delta

int256

the current portfolio delta

reactorIndex

uint256

the index of the reactor in the hedgingReactors array to use

adjustCollateral

function adjustCollateral(uint256 lpCollateralDifference, bool addToLpBalance) external

adjust the collateral held in a specific vault because of health

called by the option registry only

NameTypeDescription

lpCollateralDifference

uint256

amount of collateral taken from or given to the liquidity pool in collateral decimals

addToLpBalance

bool

true if collateral is returned to liquidity pool, false if collateral is withdrawn from liquidity pool

settleVault

function settleVault(address seriesAddress) external returns (uint256)

closes an oToken vault, returning collateral (minus ITM option expiry value) back to the pool

NameTypeDescription

seriesAddress

address

the address of the oToken vault to close

NameTypeDescription

[0]

uint256

collatReturned the amount of collateral returned to the liquidity pool, assumes in collateral decimals

handlerIssue

function handlerIssue(struct Types.OptionSeries optionSeries) external returns (address)

issue an option

only callable by a handler contract

NameTypeDescription

optionSeries

struct Types.OptionSeries

the series detail of the option - strike decimals in e18

handlerWriteOption

function handlerWriteOption(struct Types.OptionSeries optionSeries, address seriesAddress, uint256 amount, contract IOptionRegistry optionRegistry, uint256 premium, int256 delta, address recipient) external returns (uint256)

write an option that already exists

only callable by a handler contract

NameTypeDescription

optionSeries

struct Types.OptionSeries

the series detail of the option - strike decimals in e8

seriesAddress

address

the series address of the oToken

amount

uint256

the number of options to write - in e18

optionRegistry

contract IOptionRegistry

the registry used for options writing

premium

uint256

the premium of the option - in collateral decimals

delta

int256

the delta of the option - in e18

recipient

address

the receiver of the option

handlerIssueAndWriteOption

function handlerIssueAndWriteOption(struct Types.OptionSeries optionSeries, uint256 amount, uint256 premium, int256 delta, address recipient) external returns (uint256, address)

write an option that doesnt exist

only callable by a handler contract

NameTypeDescription

optionSeries

struct Types.OptionSeries

the series detail of the option - strike decimals in e18

amount

uint256

the number of options to write - in e18

premium

uint256

the premium of the option - in collateral decimals

delta

int256

the delta of the option - in e18

recipient

address

the receiver of the option

handlerBuybackOption

function handlerBuybackOption(struct Types.OptionSeries optionSeries, uint256 amount, contract IOptionRegistry optionRegistry, address seriesAddress, uint256 premium, int256 delta, address seller) external returns (uint256)

buy back an option that already exists

only callable by a handler contract

NameTypeDescription

optionSeries

struct Types.OptionSeries

the series detail of the option - strike decimals in e8

amount

uint256

the number of options to buyback - in e18

optionRegistry

contract IOptionRegistry

the registry used for options writing

seriesAddress

address

the series address of the oToken

premium

uint256

the premium of the option - in collateral decimals

delta

int256

the delta of the option - in e18

seller

address

the receiver of the option

resetEphemeralValues

function resetEphemeralValues() external

reset the temporary portfolio and delta values that have been changed since the last oracle update

only callable by the portfolio values feed oracle contract

pauseTradingAndRequest

function pauseTradingAndRequest() external returns (bytes32)

reset the temporary portfolio and delta values that have been changed since the last oracle update

this function must be called in order to execute an epoch calculation

executeEpochCalculation

function executeEpochCalculation() external

execute the epoch and set all the price per shares

this function must be called in order to execute an epoch calculation and batch a mutual fund epoch

deposit

function deposit(uint256 _amount) external returns (bool)

function for adding liquidity to the options liquidity pool

entry point to provide liquidity to dynamic hedging vault

NameTypeDescription

_amount

uint256

amount of the strike asset to deposit

NameTypeDescription

[0]

bool

success

redeem

function redeem(uint256 _shares) external returns (uint256)

function for allowing a user to redeem their shares from a previous epoch

NameTypeDescription

_shares

uint256

the number of shares to redeem

NameTypeDescription

[0]

uint256

the number of shares actually returned

initiateWithdraw

function initiateWithdraw(uint256 _shares) external

function for initiating a withdraw request from the pool

entry point to remove liquidity to dynamic hedging vault

NameTypeDescription

_shares

uint256

amount of shares to return

completeWithdraw

function completeWithdraw(uint256 _shares) external returns (uint256)

function for completing the withdraw from a pool

entry point to remove liquidity to dynamic hedging vault

NameTypeDescription

_shares

uint256

amount of shares to return

_getNormalizedBalance

function _getNormalizedBalance(address asset) internal view returns (uint256 normalizedBalance)

Returning balance in 1e18 format

NameTypeDescription

asset

address

address of the asset to get balance and normalize

NameTypeDescription

normalizedBalance

uint256

balance in 1e18 format

getBalance

function getBalance(address asset) public view returns (uint256)

Returning balance in 1e6 format

NameTypeDescription

asset

address

address of the asset to get balance

NameTypeDescription

[0]

uint256

balance of the address accounting for partitionedFunds

getExternalDelta

function getExternalDelta() public view returns (int256 externalDelta)

get the delta of the hedging reactors

NameTypeDescription

externalDelta

int256

hedging reactor delta in e18 format

getPortfolioDelta

function getPortfolioDelta() public view returns (int256)

get the delta of the portfolio

NameTypeDescription

[0]

int256

portfolio delta

quotePriceWithUtilizationGreeks

function quotePriceWithUtilizationGreeks(struct Types.OptionSeries optionSeries, uint256 amount, bool toBuy) external view returns (uint256 quote, int256 delta)

get the quote price and delta for a given option

NameTypeDescription

optionSeries

struct Types.OptionSeries

option type to quote - strike assumed in e18

amount

uint256

the number of options to mint - assumed in e18

toBuy

bool

whether the protocol is buying the option

NameTypeDescription

quote

uint256

the price of the options - returns in e18

delta

int256

the delta of the options - returns in e18

addUtilizationPremium

function addUtilizationPremium(struct Types.UtilizationState quoteState, struct Types.OptionSeries optionSeries, uint256 amount, bool toBuy) internal view

applies a utilization premium when the protocol is selling options. Stores the utilization price in quoteState.utilizationPrice for use in quotePriceWithUtilizationGreeks

NameTypeDescription

quoteState

struct Types.UtilizationState

the struct created in quoteStateWithUtilizationGreeks to store memory variables

optionSeries

struct Types.OptionSeries

the option type for which we are quoting a price

amount

uint256

the amount of options. e18

toBuy

bool

whether we are buying an option. False if selling

applyDeltaPremium

function applyDeltaPremium(struct Types.UtilizationState quoteState, bool toBuy) internal view returns (uint256 quote)

Applies a discount or premium based on the liquidity pool's delta exposure Gives discount if the transaction results in a lower delta exposure for the liquidity pool. Prices option more richly if the transaction results in higher delta exposure for liquidity pool.

NameTypeDescription

quoteState

struct Types.UtilizationState

the struct created in quoteStateWithUtilizationGreeks to store memory variables

toBuy

bool

whether we are buying an option. False if selling

NameTypeDescription

quote

uint256

the quote for the option with the delta skew applied

getImpliedVolatility

function getImpliedVolatility(bool isPut, uint256 underlyingPrice, uint256 strikePrice, uint256 expiration) public view returns (uint256)

get the current implied volatility from the feed

NameTypeDescription

isPut

bool

Is the option a call or put?

underlyingPrice

uint256

The underlying price - assumed in e18

strikePrice

uint256

The strike price of the option - assumed in e18

expiration

uint256

expiration timestamp of option as a PRBMath Float

NameTypeDescription

[0]

uint256

Implied volatility adjusted for volatility surface - assumed in e18

getAssets

function getAssets() external view returns (uint256)

getNAV

function getNAV() external view returns (uint256)

_redeem

function _redeem(uint256 _shares) internal returns (uint256)

functionality for allowing a user to redeem their shares from a previous epoch

NameTypeDescription

_shares

uint256

the number of shares to redeem

NameTypeDescription

[0]

uint256

toRedeem the number of shares actually returned

_getNAV

function _getNAV() internal view returns (uint256)

get the Net Asset Value

NameTypeDescription

[0]

uint256

Net Asset Value in e18 decimal format

_getAssets

function _getAssets() internal view returns (uint256 assets)

get the Asset Value

NameTypeDescription

assets

uint256

Asset Value in e18 decimal format

_getLiabilities

function _getLiabilities() internal view returns (int256 liabilities)

checkBuffer

function checkBuffer() public view returns (uint256 bufferRemaining)

calculates amount of liquidity that can be used before hitting buffer

NameTypeDescription

bufferRemaining

uint256

the amount of liquidity available before reaching buffer in e6

_issue

function _issue(struct Types.OptionSeries optionSeries, contract IOptionRegistry optionRegistry) internal returns (address series)

create the option contract in the options registry

NameTypeDescription

optionSeries

struct Types.OptionSeries

option type to mint - option series strike in e18

optionRegistry

contract IOptionRegistry

interface for the options issuer

NameTypeDescription

series

address

the address of the option series minted

_writeOption

function _writeOption(struct Types.OptionSeries optionSeries, address seriesAddress, uint256 amount, contract IOptionRegistry optionRegistry, uint256 premium, int256 delta, uint256 bufferRemaining, address recipient) internal returns (uint256)

write a number of options for a given OptionSeries

NameTypeDescription

optionSeries

struct Types.OptionSeries

option type to mint - strike in e8

seriesAddress

address

the address of the options series

amount

uint256

the amount to be written - in e18

optionRegistry

contract IOptionRegistry

the option registry of the pool

premium

uint256

the premium to charge the user - in collateral decimals

delta

int256

the delta of the option position - in e18

bufferRemaining

uint256

the amount of buffer that can be used - in e6

recipient

address

NameTypeDescription

[0]

uint256

the amount that was written

_buybackOption

function _buybackOption(struct Types.OptionSeries optionSeries, uint256 amount, contract IOptionRegistry optionRegistry, address seriesAddress, uint256 premium, int256 delta, address seller) internal returns (uint256)

buys a number of options back and burns the tokens

NameTypeDescription

optionSeries

struct Types.OptionSeries

the option token series to buyback - strike passed in as e8

amount

uint256

the number of options to buyback expressed in 1e18

optionRegistry

contract IOptionRegistry

the registry

seriesAddress

address

the series being sold

premium

uint256

the premium to be sent back to the owner (in collat decimals)

delta

int256

the delta of the option

seller

address

the address

NameTypeDescription

[0]

uint256

the number of options burned in e18

_adjustVariables

function _adjustVariables(uint256 collateralAmount, uint256 optionsValue, int256 delta, bool isSale) internal

adjust the variables of the pool

NameTypeDescription

collateralAmount

uint256

the amount of collateral transferred to change on collateral allocated in collateral decimals

optionsValue

uint256

the value of the options in e18 decimals

delta

int256

the delta of the options in e18 decimals

isSale

bool

whether the action was an option sale or not

_getVolatilityFeed

function _getVolatilityFeed() internal view returns (contract VolatilityFeed)

get the volatility feed used by the liquidity pool

NameTypeDescription

[0]

contract VolatilityFeed

the volatility feed contract interface

_getPortfolioValuesFeed

function _getPortfolioValuesFeed() internal view returns (contract IPortfolioValuesFeed)

get the portfolio values feed used by the liquidity pool

NameTypeDescription

[0]

contract IPortfolioValuesFeed

the portfolio values feed contract

_getAccounting

function _getAccounting() internal view returns (contract IAccounting)

get the DHV accounting calculations contract used by the liquidity pool

NameTypeDescription

[0]

contract IAccounting

the Accounting contract

_getOptionRegistry

function _getOptionRegistry() internal view returns (contract IOptionRegistry)

get the option registry used for storing and managing the options

NameTypeDescription

[0]

contract IOptionRegistry

the option registry contract

_getUnderlyingPrice

function _getUnderlyingPrice(address underlying, address _strikeAsset) internal view returns (uint256)

get the underlying price with just the underlying asset and strike asset

NameTypeDescription

underlying

address

the asset that is used as the reference asset

_strikeAsset

address

the asset that the underlying value is denominated in

NameTypeDescription

[0]

uint256

the underlying price

_isTradingNotPaused

function _isTradingNotPaused() internal view

_isHandler

function _isHandler() internal view

_isKeeper

function _isKeeper() internal view

keepers, managers or governors can access

Last updated