Skip to main content

Operator

Git Source

Inherits: IOperator, Policy, RolesConsumer, ReentrancyGuard

Olympus Range Operator (Policy) Contract

The Olympus Range Operator performs market operations to enforce OlympusDAO's OHM price range guidance policies against a specific reserve asset. The Operator is maintained by a keeper-triggered function on the Olympus Heart contract, which orchestrates state updates in the correct order to ensure market operations use up to date information. When the price of OHM against the reserve asset exceeds the cushion spread, the Operator deploys bond markets to support the price. The Operator also offers zero slippage swaps at prices dictated by the wall spread from the moving average. These market operations are performed up to a specific capacity before the market must stabilize to regenerate the capacity.

State Variables

_status

Status internal _status;

_config

Config internal _config;

initialized

Whether the Operator has been initialized

bool public initialized;

active

Whether the Operator is active

bool public active;

PRICE

PRICEv1 internal PRICE;

RANGE

RANGEv2 internal RANGE;

TRSRY

TRSRYv1 internal TRSRY;

MINTR

MINTRv1 internal MINTR;

auctioneer

Auctioneer contract used for cushion bond market deployments

IBondSDA public auctioneer;

callback

Callback contract used for cushion bond market payouts

IBondCallback public callback;

ohm

OHM token contract

ERC20 public immutable ohm;

_ohmDecimals

uint8 internal immutable _ohmDecimals;

reserve

Reserve token contract

ERC20 public immutable reserve;

_reserveDecimals

uint8 internal immutable _reserveDecimals;

_oracleDecimals

uint8 internal _oracleDecimals;

sReserve

_sReserveDecimals == _reserveDecimals

ERC4626 public immutable sReserve;

oldReserve

ERC20 public immutable oldReserve;

ONE_HUNDRED_PERCENT

uint32 internal constant ONE_HUNDRED_PERCENT = 100e2;

OPERATOR_POLICY_ROLE

bytes32 internal constant OPERATOR_POLICY_ROLE = "operator_policy";

OPERATOR_ADMIN_ROLE

bytes32 internal constant OPERATOR_ADMIN_ROLE = "operator_admin";

Functions

constructor

constructor(
Kernel kernel_,
IBondSDA auctioneer_,
IBondCallback callback_,
address[4] memory tokens_,
uint32[8] memory configParams
) Policy(kernel_);

configureDependencies

Define module dependencies for this policy.

function configureDependencies() external override returns (Keycode[] memory dependencies);

Returns

NameTypeDescription
dependenciesKeycode[]- Keycode array of module dependencies.

requestPermissions

Function called by kernel to set module function permissions.

function requestPermissions() external view override returns (Permissions[] memory requests);

Returns

NameTypeDescription
requestsPermissions[]- Array of keycodes and function selectors for requested permissions.

_onlyWhileActive

Checks to see if the policy is active and ensures the range data isn't stale before performing market operations. This check is different from the price feed staleness checks in the PRICE module. The PRICE module checks new price feed data for staleness when storing a new observations, whereas this check ensures that the range data is using a recent observation.

function _onlyWhileActive() internal view;

operate

Executes market operations logic.

This function is triggered by a keeper on the Heart contract.

function operate() external override onlyRole("heart");

swap

Swap at the current wall prices

function swap(ERC20 tokenIn_, uint256 amountIn_, uint256 minAmountOut_)
external
override
nonReentrant
returns (uint256 amountOut);

Parameters

NameTypeDescription
tokenIn_ERC20- Token to swap into the wall - OHM: swap at the low wall price for Reserve - Reserve: swap at the high wall price for OHM
amountIn_uint256- Amount of tokenIn to swap
minAmountOut_uint256- Minimum amount of opposite token to receive

Returns

NameTypeDescription
amountOutuint256- Amount of opposite token received

bondPurchase

Records a bond purchase and updates capacity correctly

Access restricted (BondCallback)

function bondPurchase(uint256 id_, uint256 amountOut_) external onlyRole("operator_reporter");

Parameters

NameTypeDescription
id_uint256ID of the bond market
amountOut_uint256Amount of capacity expended

_activate

Activate a cushion by deploying a bond market

function _activate(bool high_) internal;

Parameters

NameTypeDescription
high_boolWhether the cushion is for the high or low side of the range (true = high, false = low)

_deactivate

Deactivate a cushion by closing a bond market (if it is active)

function _deactivate(bool high_) internal;

Parameters

NameTypeDescription
high_boolWhether the cushion is for the high or low side of the range (true = high, false = low)

_getPriceDecimals

Helper function to calculate number of price decimals based on the value returned from the price feed.

function _getPriceDecimals(uint256 price_) internal view returns (int8);

Parameters

NameTypeDescription
price_uint256The price to calculate the number of decimals for

Returns

NameTypeDescription
<none>int8The number of decimals

_updateCapacity

Update the capacity on the RANGE module.

function _updateCapacity(bool high_, uint256 reduceBy_) internal;

Parameters

NameTypeDescription
high_boolWhether to update the high side or low side capacity (true = high, false = low).
reduceBy_uint256The amount to reduce the capacity by (OHM tokens for high side, Reserve tokens for low side).

_updateRangePrices

Update the prices on the RANGE module

function _updateRangePrices() internal;

_addObservation

Add an observation to the regeneration status variables for each side

function _addObservation() internal;

_updateRegenOnObservation

function _updateRegenOnObservation(Regen storage regen_, bool positive_, uint32 observe_) internal;

_regenerate

Regenerate the wall for a side

function _regenerate(bool high_) internal;

Parameters

NameTypeDescription
high_boolWhether to regenerate the high side or low side (true = high, false = low)

_checkCushion

Takes down cushions (if active) when a wall is taken down or if available capacity drops below cushion capacity

function _checkCushion(bool high_) internal;

Parameters

NameTypeDescription
high_boolWhether to check the high side or low side cushion (true = high, false = low)

setSpreads

Set the wall and cushion spreads

Interface for externally setting these values on the RANGE module

function setSpreads(bool high_, uint256 cushionSpread_, uint256 wallSpread_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
high_bool- Whether to set the spreads for the high or low side (true = high, false = low)
cushionSpread_uint256- Percent spread to set the cushions at above/below the moving average, assumes 2 decimals (i.e. 1000 = 10%)
wallSpread_uint256- Percent spread to set the walls at above/below the moving average, assumes 2 decimals (i.e. 1000 = 10%)

setThresholdFactor

Set the threshold factor for when a wall is considered "down"

Interface for externally setting this value on the RANGE module

function setThresholdFactor(uint256 thresholdFactor_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
thresholdFactor_uint256- Percent of capacity that the wall should close below, assumes 2 decimals (i.e. 1000 = 10%)

setCushionFactor

Set the cushion factor

function setCushionFactor(uint32 cushionFactor_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
cushionFactor_uint32- Percent of wall capacity that the operator will deploy in the cushion, assumes 2 decimals (i.e. 1000 = 10%)

setCushionParams

Set the parameters used to deploy cushion bond markets

function setCushionParams(uint32 duration_, uint32 debtBuffer_, uint32 depositInterval_)
external
onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
duration_uint32- Duration of cushion bond markets in seconds
debtBuffer_uint32- Percentage over the initial debt to allow the market to accumulate at any one time. Percent with 3 decimals, e.g. 1_000 = 1 %. See IBondSDA for more info.
depositInterval_uint32- Target frequency of deposits in seconds. Determines max payout of the bond market. See IBondSDA for more info.

setReserveFactor

Set the reserve factor

function setReserveFactor(uint32 reserveFactor_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
reserveFactor_uint32- Percent of treasury reserves to deploy as capacity for market operations, assumes 2 decimals (i.e. 1000 = 10%)

setRegenParams

Set the wall regeneration parameters

We must see Threshold number of price points that meet our criteria within the last Observe number of price points to regenerate a wall.

function setRegenParams(uint32 wait_, uint32 threshold_, uint32 observe_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
wait_uint32- Minimum duration to wait to reinstate a wall in seconds
threshold_uint32- Number of price points on other side of moving average to reinstate a wall
observe_uint32- Number of price points to observe to determine regeneration

setBondContracts

Set the contracts that the Operator deploys bond markets with.

function setBondContracts(IBondSDA auctioneer_, IBondCallback callback_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
auctioneer_IBondSDA- Address of the bond auctioneer to use.
callback_IBondCallback- Address of the callback to use.

initialize

Initialize the Operator to begin market operations

This function executes actions required to start operations that cannot be done prior to the Operator policy being approved by the Kernel.

function initialize() external onlyRole(OPERATOR_ADMIN_ROLE);

regenerate

Regenerate the wall for a side

This function is an escape hatch to trigger out of cycle regenerations and may be useful when doing migrations of Treasury funds

function regenerate(bool high_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
high_boolWhether to regenerate the high side or low side (true = high, false = low)

activate

Activate the Operator

Restart function for the Operator after a pause.

function activate() external onlyRole(OPERATOR_POLICY_ROLE);

deactivate

Deactivate the Operator

Emergency pause function for the Operator. Prevents market operations from occurring.

function deactivate() external onlyRole(OPERATOR_POLICY_ROLE);

deactivateCushion

Manually close a cushion bond market

Emergency shutdown function for Cushions

function deactivateCushion(bool high_) external onlyRole(OPERATOR_POLICY_ROLE);

Parameters

NameTypeDescription
high_boolWhether to deactivate the high or low side cushion (true = high, false = low)

_checkFactor

function _checkFactor(uint32 factor_) internal pure;

getAmountOut

Returns the amount to be received from a swap

function getAmountOut(ERC20 tokenIn_, uint256 amountIn_) public view returns (uint256);

Parameters

NameTypeDescription
tokenIn_ERC20- Token to swap into the wall - If OHM: swap at the low wall price for Reserve - If Reserve: swap at the high wall price for OHM
amountIn_uint256- Amount of tokenIn to swap

Returns

NameTypeDescription
<none>uint256Amount of opposite token received

fullCapacity

Returns the full capacity of the specified wall (if it was regenerated now)

Calculates the capacity to deploy for a wall based on the amount of reserves owned by the treasury and the reserve factor.

function fullCapacity(bool high_) public view override returns (uint256);

Parameters

NameTypeDescription
high_bool- Whether to return the full capacity for the high or low wall

status

Returns the status variable of the Operator as a Status struct

function status() external view override returns (Status memory);

config

Returns the config variable of the Operator as a Config struct

function config() external view override returns (Config memory);