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
createOptionsContractfrom 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
createOptionsContracttransaction and grabbing the address from the second event, which is theOptionsContractCreatedevent - Approve YFI collateral to the oToken
- Go to the options contract you created and call
createERC20CollateralOptionvia 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
removeUnderlyingvia 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
redeemVaultBalancevia 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!