# A Universal Option to Trade
###### tags: option
In our last [article](https://hackmd.io/ZyLNUMd7RTSMzGUEc5QmEg) we discussed about the status quo of options in the DeFi space and we gave a very high level overview on 2 of the most commonly used option protocol. Finally, we introduced the premium price strategy that will allows us to track the option demand in the market.
This article intends to also introduce another feature that our proposed option has, which is to allow options to be sold in the secondary market.
## Revisting the status quo
The current 2 big boys in the option protocol each allows their options to be traded (somewhat).
Opyn relies on a options being fungible and can be traded in an open market to determine their premium price. The options essentially are ERC20 oTokens and are indistinguishable from each other as long as the oTokens are minted from the same vault.
Hegic does not have a unique vault architecture and thus relies on a single pool to provide option liquidity to all the options being sold in the same type and currency (eg. A single ETH Call pool is able to sell options all a variety of strike prices and expiry). The options are minted as an ERC721 and has metadata mainly for accounting purposes. That also means that each option may be slight different from its counterpart, be it its strike price, expiry or even the amount of option being held in the ERC721.
It is possible for the options in Hegic to change hands, however it is not possible to fractionalize it to only sell a portion of its held amount to willing buyers. A bit of an inconvenience if I were to say so.
However unlike Opyn, Hegic combines the liquidity into a single pool which is definitely a merit. A larger pool liquidity will allow more options to be sold at the same time. And options buyer has the flexiblity to purchase options with expiry and strike price that they desire.
## The best of both worlds
We will attempt to have an easy way to trade option (like Opyn) alongside a universal option pool (like Hegic) that allows a variety of options of differing strike prices and expiries to be sold in our implementation.
### Universal pool
In each option class, the pool accepts liquidity in the form of the underlying tokens for call options, or stable coins in general for put options.
Each liquidity provider will be minted a `Tranche` ERC721 for accounting purposes. The tranche records the timestamp for providing liquidity, the owner, how much liquidity was provided initially, as well as the proportion of the pool this tranche owns.
``` solidity
/**
* @param state The state of the liquidity tranche: Invalid, Open, Closed
* @param share The liquidity provider's share in the pool
* @param amount The size of liquidity provided
* @param creationTimestamp The liquidity deposit timestamp
**/
struct Tranche {
TrancheState state;
uint256 share;
uint256 amount;
uint256 creationTimestamp;
}
```
The tranches are stored in an array with and the index of the array will serve as the id of the tranche. Liquidity provider will need to provide the id of the tranche in order to withdraw. It is therefore the responsibily of liquidity provider to keep track of their own ids.
Should a user misplaced his/her Id, it is possible to rely on indexing services or block explorers to retrieve the tranche id from the event logs.
``` solidity
Tranche[] public tranches;
```
The `creationTimestamp` is used to keep a record for when the liquidity were deposited. We introduced a `lockupPeriodForTranches` That will require liquidity providers to at least stay in the pool for a certain period configurable by the admin. This is a first line of defence that helps to mitigate the likelihood that the pool has no profit to pay out to options that have been exercised ITM. The second line of defense will be the `collateralizationRatio` which is used to lock a certain amount of liquidity. This ensures that the pool will at least a certain minumum amount to pay off the profits by option exercisers.
As the premium are automatically reinvested into the pool, the `share` will help to determine the proportion of profits or losses suffered by the pool. A thing to note is that we are introducing a liquidity provider reward and this will be covered in later articles.
Finally the `amount` is used for accounting purposes related to liquidity provider reward and won't be discussed here
### Make it Trade-able!
One property that we would love to have is the ability to trade options as if they are fungible to each other. A bit of an over generalization but we would like to at least have options of the same type (token, call/put, strike price and expiry) to be treated equally with one another.
In order to achieve that, each of the same type is issued a unique Erc20 token. The code snippet demonstrates the ability to deploy a minimal proxy Erc20 contract if the type does not exist in its Erc20 token form yet
```solidity
IOptionErc20 optionErc20 = optionErc20s[expiry][strike];
// deploy this optionErc20 if not found
if (address(optionErc20) == address(0)) {
optionErc20 = deployOptionErc20(expiry, strike);
}
```
The precision of the optionErc20 is the same as the precision of the underlying token of the pool. Meaning for 10 wei of underlying token being specified as the amount, 10 wei of optionErc20 will be minted to represent the option. As such, we are able to trade in a much fine grain manner.
Also, the OptionErc20 is written in such that it is compliant with the Erc20 standard, and mechanisms such as `approval`, `transferFrom` are all already too familiar to all of us.
## Expired options
Our option protocol follows the European option whereby option can only be execised after expire. In EVM land, a state transition will require a transaction. After the option has expired, anyone is able to call the `unlock` function on behalf of the option owner. The profit is determined by the current price from an oracle at the time of unlocking.
The premium that is held by the option is released upon unlock and any profit, is awarded to the option holder whilst the corresponding optionErc20 burnt.
Also, we have the `lockedAmount` concept whereby a certain amount of liquidity will be used as collateral until the option has been unlocked. This ensures that the pool will have a minimum amount of funds to pay out the profit to option holders. (Recall our second line of defence)
``` solidity
function _calculateLockedAmount(uint256 amount)
internal
virtual
returns (uint256)
{
return (amount * collateralizationRatio) / 100;
}
```
However this poses a problem, option holder can wait indefinitely and hope that no one exercises their option on their behalf, only unlocking when the current price is favorable and they will always gain a profit.
The pool is at risk of 1. locked up liquidity and 2. higher risk of being exercised against.
Although anyone is able to call the `unlock` function, it is rather gas inefficient to perform such operation for all users.
And so we introduced a concept of `expiryThreshold` whereby after a certain period after the expiry, anyone is able to call the `unlockOptionErc20` to effectively invalidate the entire optionErc20 of the specific type and unlock all its lockedAmounts and premiums.
Performing this operation will also mean all option holders will be voided of their profit. This will encourge liquidity provider to spend the extra gas to free up the funds that are locked up in the option. It will also serve as a economical insentive for options holders to exercise their own options especially if they have gained a profit.
## To sum it up
We have looked into our strategy in making our option 'universally tradeable'! Also we introduced a strategy that will safeguard the liquidity providers in the form of a forced unlock for all function.
In the next one, we will introduce abit more on our reward mechanism and I'm sure you wouldnt want to miss out on that.