Options Liquidity Mining (OLM)
Contract that implements an epoch-based liquidity mining reward system using oTokens
Contract that implements an epoch-based liquidity mining reward system using oTokens
Options Liquidity Mining allows the protocol to re-capture some of the value from liquidity mining rewards when LPs realize profit. Additionally, it can cap the amount of sell pressure on a protocols token in a down market by limiting the profitability of exercising option tokens to above the strike price.
The OLM contract implements a version of this using fixed strike call options. Protocols can deploy an OLM contract with their specific configuration of staked token and option parameters. The contract implements epoch-based staking rewards to issue new option tokens at fixed time intervals and at a new strike price based on the configuration when an epoch transitions. The stakedToken
and option payoutToken
are fixed when the OLM contract is deployed. The owner of the contract can update the other staking and option token parameters over time to adjust their rewards program. The owner can also optionally designate an Allowlist contract to limit which users can can stake in the contract. The allowlist should conform to the IAllowlist
interface.
Protocols can choose between two implementations of the OLM contract: Manual Strike or Oracle Strike.
Manual Strike: Owners must manually update the strike price to change it over time.
Oracle Strike: Strike price is automatically updated based on an oracle and discount. A minimum strike price can be set on the Oracle Strike version to prevent it from going too low.
Users can deposit the configured stakedToken
into the contract to earn rewards. Rewards are continuously accrued based on the configured reward rate and the total balance of staked tokens in the contract. Any user action updates the reward calculations. Additionally, user actions can trigger a new epoch start, which will earn them additional option tokens in the form of the epoch transition reward for paying the extra gas. Users can claim their outstanding rewards from all epochs or from the next unclaimed epoch. If the option token for a specific epoch has expired, the user will not receive any rewards for that period since they are now worthless.
Setting up an OLM requires three steps.
Deploy an OLM contract from a factory.
Fund the OLM contract with payoutTokens
to pay rewards with (via a simple ERC20 transfer). Owners must monitor the balance of payoutTokens
in the contract to ensure that users can claim their rewards.
Initialize the OLM contract, including inputting the remaining options and staking parameters.
Step three of this process is accomplished by calling initialize
on this contract.
Token that is staked in the OLM contract
Whether users can deposit staking tokens into the OLM contract at the current time
Whether the OLM contract has been initialized
No settings can be changed or tokens deposited before the OLM contract is initialized
(Optional) Address of the allowlist contract which determines which addresses are allowed to interact with the OLM contract
Option Teller contract that is used to deploy and create option tokens
Token that stakers receive call options for
Token that stakers must pay to exercise the call options they receive
Amount of time (in seconds) from option token deployment to when it can be exercised
Amount of time (in seconds) from when the option token is eligible to when it expires
Address that will receive the quote tokens when an option is exercised.
IMPORTANT: This address is the only one that can reclaim the payoutToken collateral for expired option tokens. Make sure this address can call reclaim
on the FixedStrikeOptionTeller contract for any option token address.
Current staking epoch
Staking epoch duration
Timestamp of the start of the current staking epoch
Amount of time (in seconds) that the reward rate is distributed over
Timestamp when the stored rewards per token was last updated
Amount of option tokens rewarded per reward period
Global reward distribution variable, used to calculate user rewards
Amount of option tokens that are rewarded for starting a new epoch
Rewards Per Token value at the start of each epoch
Total amount of staked tokens currently in the contract
Mapping of staker address to their staked balance
Mapping of staker address to the rewards per token they have claimed
Mapping of staker address to the last epoch they claimed rewards for
Mapping of epochs to the option tokens that was rewarded for that epoch
Modifier that updates the stored rewards per token before a function is executed
This modifier should be placed on any function where rewards are claimed or staked tokens are deposited/withdrawn.
Additionally, it should be placed on any functions that modify the reward parameters of the OLM contract.
Modifier that tries to start a new epoch before a function is executed and rewards the caller for doing so
Modifier that requires the OLM contract to be initialized before a function is executed
Deposit staking tokens into the contract to earn rewards
Only callable if deposits are enabled
Only callable if the user is allowed to stake per the allowlist
May receive reward if calling triggers new epoch
Parameters
amount_
uint256
Amount of staking tokens to deposit
proof_
bytes
Optional proof data for specific allowlist implementations
Withdraw staking tokens from the contract
May receive reward if calling triggers new epoch
Parameters
amount_
uint256
Amount of staking tokens to withdraw
Withdraw entire balance of staking tokens from the contract
May receive reward if calling triggers new epoch
Withdraw entire balance of staking tokens without updating or claiming outstanding rewards.
Rewards will be lost if stake is withdrawn using this function. Only for emergency use.
Claim all outstanding rewards for the user across epochs
May receive reward if calling triggers new epoch
Claim all outstanding rewards for the user for the next unclaimed epoch (and any remaining rewards from the previously claimed epoch)
May receive reward if calling triggers new epoch
Returns the current rewards per token value updated to the second
Returns the strike price that would be used if a new epoch started right now
Initializes the OLM contract
Only owner
This function can only be called once.
When the function completes, the contract is live. Users can start staking and claiming rewards.
quoteToken_
ERC20
Token that stakers must pay to exercise the call options they receive
timeUntilEligible_
uint48
Amount of time (in seconds) from option token deployment to when it can be exercised
eligibleDuration_
uint48
Amount of time (in seconds) from when the option token is eligible to when it expires
receiver_
address
Address that will receive the quote tokens when an option is exercised IMPORTANT: receiver is the only address that can retrieve payout token collateral from expired options. It must be able to call the reclaim
function on the Option Teller contract.
epochDuration_
uint48
Staking epoch duration (in seconds)
epochTransitionReward_
uint256
Amount of option tokens that are rewarded for starting a new epoch
rewardRate_
uint256
Amount of option tokens rewarded per reward period (1 day)
allowlist_
IAllowlist
Address of the allowlist contract that can be used to restrict who can stake in the OLM contract. If the zero address, then no allow list is used.
allowlistParams_
bytes
Parameters that are passed to the allowlist contract when this contract registers with it
other_
bytes
Toggle whether deposits are enabled
Only owner
Parameters
depositsEnabled_
bool
Whether deposits should be enabled
Manually start a new epoch
Only owner
Withdraw payout tokens that were deposited to the contract for rewards
Only owner
Parameters
to_
address
The address to withdraw to
amount_
uint256
The amount to withdraw
Set the staking reward rate
Only owner
Parameters
rewardRate_
uint256
Amount of option tokens rewarded per reward period (1 day)
Set the epoch duration
Only owner
Parameters
epochDuration_
uint48
Staking epoch duration (in seconds)
Set the epoch transition reward
Only owner
Parameters
amount_
uint256
Amount of option tokens that are rewarded for starting a new epoch
Set the option receiver
Only owner
Parameters
receiver_
address
Address that will receive the quote tokens when an option is exercised IMPORTANT: receiver is the only address that can retrieve payout token collateral from expired options. It must be able to call the reclaim
function on the Option Teller contract.
Set the option duration
Only owner
Parameters
timeUntilEligible_
uint48
Amount of time (in seconds) from option token deployment to when it can be exercised
eligibleDuration_
uint48
Amount of time (in seconds) from when the option token is eligible to when it expire
Set the quote token that is used for the option tokens
Only owner
Parameters
quoteToken_
ERC20
Token that stakers must pay to exercise the call options they receive
Additional parameters that are required by specific implementations of the OLM contract. Must be abi-encoded. See or for details on what each expects here.