The following instructions go step-by-step through how to create vesting call options, similar to equity options that startups typically use to incentivize employees.
H/t @Fubuloubu, who approached us about creating these for the Yearn team to potentially use! This allows Yearn or similar projects (on-chain DAOs) to grant vesting options to any contributor.
We'll use YFI call options as an example.
- Call
createOptionsContract
from the OptionFactory via Etherscan- To create a $0.50 YFI call option, parameters as follows:
- collateralType:
0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e
(YFI) - collateralExp:
-18
- underlyingType:
0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
(USDC) - underlyingExp:
-6
- oTokenExchangeExp:
-6
- strikePrice:
2000000
(2) - strikeExp:
-6
- strikeAsset:
0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e
(YFI) - expiry:
1685545200
(5/31/23 8:00AM UTC) - windowSize:
1685545200
(5/31/23 8:00AM UTC)
- collateralType:
- To create a $0.50 YFI call option, parameters as follows:
- Note that each oToken has a multiplier for calls. So in this case 0.5 oTokens = 1 call option.
- See below for a detailed explanation of the parameters
- Find the address of options contract you just created by going to the event logs of your
createOptionsContract
transaction and grabbing the address from the second event, which is theOptionsContractCreated
event - Approve YFI collateral to the oToken
- Go to the options contract you created and call
createERC20CollateralOption
via Etherscan, parameters as follows:- amtToCreate:
2000000
- Amount of oTokens to create, here 2 oTokens
- amtCollateral:
1000000000000000000
- Amount of YFI to use as collateral, here 1 YFI
- receiver:
0x…
- Address to receive the oTokens you created
- amtToCreate:
- Now that you’ve received the oTokens to your wallet, you can use them in your vesting contract, following the instructions here
- In order to exercise, you will need to send oTokens and USDC to the options contract and in return you will receive YFI. Continuing with our same example parameters, to exercise 2 call options, you would send 1 oToken and 1 USDC and receive 2 YFI.
- Approve USDC to the oToken
- Make sure you have enough USDC otherwise txn will revert eg. 1000000 USDC for 1000000 oToken including decimals
- Go to the options contract address and call exercise via Etherscan, parameters as follows:
- oTokensToExercise:
1000000
- 1 oToken
- vaultsToExerciseFrom:
[“0x….”, “0x….”]
- Insert the address or addresses of vault holders to exercise from
- You should provide these addresses to contributors when they are exercising. These addresses should be the EOAs or smart contracts you used to mint oTokens
- oTokensToExercise:
- If someone exercises before expiry, you can go to the options contract address and redeem the underlying by calling
removeUnderlying
via Etherscan, just by clicking “write” and confirming txn. - To redeem your remaining vault balance after expiry, you can go to the options contract address call
redeemVaultBalance
via Etherscan, just by clicking “write” and confirming txn.
- In Opyn v1, call options are inverse puts. For example, a YFI-USDC put would have YFI as underlying and USDC as collateral. To create a call option we simply have YFI as collateral and USDC as underlying.
- This means that each oToken has a multiplier, where strikePrice oTokens = 1 call option. For example, for a $100,000 YFI Call, 100,000 oTokens = 1 call option.
- This would be YFI, which has 18 decimals, thus collateralExp = -18
- Since calls are inverse puts, this would be USDC, which has 6 decimals, thus underlyingExp = -6
- The oToken exchange exponent refers to the smallest unit of underlying we can have an option on. In every above example, because USDC has 6 decimals we are limited by 6, so the oTokenExchangeExp = -6.
- Example 1: Since calls are inverse puts, to get the strike price, you must invert your desired strike. For example for a $0.50 strike price, I am getting 0.50 USDC for every 1 YFI I have a call option on. Inverting this, such that my option is denominated in 1 unit of underlying (in this case the underlying is USDC), for every 1 USDC, I get 2 YFI. Thus my strike price is 2.
- Example 2: Let’s take another example where I want a $32 strike YFI call option. Here I am getting 1 YFI for 32 USDC, so inverting this to get in terms of 1 USDC, I am getting 1/32 YFI for 1 USDC. 1/32 = 0.03125. To represent this as a nicer strike price, I can use 3125 and adjust the strike exponent (discussed in the next section).
- Note that we advise not using strikes where inverting gives repeating decimals as this results in calculations being off by small amounts
- The strike exponent is the number of decimals of the strike price. We’ll expand on the same examples from above to explain.
- Example 1: We are getting 2 YFI for every 1 USDC. Because USDC has 6 decimals, that is the max precision we can support. So here expanding out to include decimals, we get 2 * (10^-6) YFI for every 1 * (10^-6) USDC. The exponent of our strike price, 2, is -6, which is our strike exponent.
- Example 2: Here we are getting 0.03125 YFI for every 1 USDC. Expanding to include decimals, we get 0.03125 * (10^-6) YFI for every 1 * (10^-6) USDC. We can express this as a nicer strike price by using 3125 * (10^-11) YFI for every 1 * (10^-6) USDC. The exponent of our strike price 3125, is -11, which is our strike exponent.
- This would be YFI, which has 18 decimals
- UTC unix time you’d like the option to expire
- If you’d like to create a European option you can set an exercise window using this parameter by setting it to the UTC unix time of when people can start exercising before expiry.
- If you’d like to create an American option (anyone can exercise at anytime), simply set the windowSize to the same UTC unix time as expiry.
- In order to create safe oTokens by preventing overflows, your oTokens must satisfy the below conditions
- abs(oTokenExchangeExp - underlyingExp) < 19
- max(abs(strikeExp + liqIncentiveExp - collateralExp), abs(strikeExp - collateralExp)) <= 9
- LiqIncentiveExp should be 0 here. This is only used if you are using parameters that require liquidations eg. ETH collateralized puts on cDAI
- You can make a copy of this spreadsheet and use it to check these safety conditions.
Feel free to reach out on discord to cross check parameters or for any other help + questions!