# Fixed Strike Option Teller

### Overview

Option Teller contracts handle the deployment, creation, and exercise of option tokens. oTokens are ERC20 tokens that represent the right to buy (call) or sell (put) a fixed amount of an asset (payout token) for an amount of another asset (quote token) between two timestamps (eligible and expiry). oTokens are denominated in units of the payout token and are created at a 1:1 ratio for the amount of payout tokens to buy or sell. The amount of quote tokens required to exercise (call) or collateralize (put) an oToken is called the strike price. Strike prices are denominated in units of the quote token.&#x20;

The Fixed Strike Option Teller implementation creates option tokens that have a fixed strike price that is set at the time of creation.&#x20;

<figure><img src="https://content.gitbook.com/content/RLNHGppzWLIBhbHOvrRS/blobs/6PBR8NK8skU7mHri4LlH/Fixed%20Strike%20Option%20Teller%20Inheritance.jpeg" alt=""><figcaption></figcaption></figure>

### Deploy and Creating oTokens

In order to create oTokens, an issuer must [deploy](#deploy) the specific token configuration on the teller, and then provide collateral to the teller to [create](#create) option tokens. The collateral is required to guarantee that the oTokens can be exercised. The collateral required depends on the option type.

* For call options, the collateral required is an amount of payout tokens equivalent to the amount of option tokens being minted.
* For put options, the collateral required is an amount of quote tokens equivalent to the amount of option tokens being minted multiplied by the strike price.&#x20;

As the name "option" suggests, the holder of an option token has the right, but not the obligation, to exercise the oToken within the eligible time window. If the oToken is not exercised, the designated "receiver" of the oToken exercise proceeds can reclaim the collateral after the expiry timestamp. If an oToken is exercised, the holder receives the collateral and the receiver receives the exercise proceeds.

## FixedStrikeOptionTeller

[Git Source](https://github.com/Bond-Protocol/option-contracts/blob/master/src/fixed-strike/FixedStrikeOptionTeller.sol)

## State Variables

### protocolFee

Fee paid to protocol when options are exercised in basis points (3 decimal places).

```solidity
uint48 public protocolFee;
```

### FEE\_DECIMALS

Base value used to scale fees. 1e5 = 100%

```solidity
uint48 public constant FEE_DECIMALS = 1e5;
```

### optionTokenImplementation

FixedStrikeOptionToken reference implementation (deployed on creation to clone from)

```solidity
FixedStrikeOptionToken public immutable optionTokenImplementation;
```

### minOptionDuration

Minimum duration an option must be eligible to exercise (in seconds)

```solidity
uint48 public minOptionDuration;
```

### fees

Fees earned by protocol, by token

```solidity
mapping(ERC20 => uint256) public fees;
```

### optionTokens

Fixed strike option tokens (hash of parameters to address)

```solidity
mapping(bytes32 => FixedStrikeOptionToken) public optionTokens;
```

### collateralClaimed

Whether the receiver of an option token has reclaimed the collateral

```solidity
mapping(FixedStrikeOptionToken => bool) public collateralClaimed;
```

## User Functions

### deploy

Deploy a new ERC20 fixed strike option token and return its address

*If an option token already exists for the parameters, it returns that address*

```solidity
function deploy(
    ERC20 payoutToken_,
    ERC20 quoteToken_,
    uint48 eligible_,
    uint48 expiry_,
    address receiver_,
    bool call_,
    uint256 strikePrice_
) external override nonReentrant returns (FixedStrikeOptionToken);
```

**Parameters**

| Name           | Type      | Description                                                                                                                                   |
| -------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `payoutToken_` | `ERC20`   | ERC20 token that the purchaser will receive on execution                                                                                      |
| `quoteToken_`  | `ERC20`   | ERC20 token used that the purchaser will need to provide on execution                                                                         |
| `eligible_`    | `uint48`  | Timestamp at which the option token can first be executed (gets rounded down to nearest day)                                                  |
| `expiry_`      | `uint48`  | Timestamp at which the option token can no longer be executed (gets rounded down to nearest day)                                              |
| `receiver_`    | `address` | Address that will receive the proceeds when option tokens are exercised. Also the address that can claim collateral from unexercised options. |
| `call_`        | `bool`    | Whether the option token is a call (true) or a put (false)                                                                                    |
| `strikePrice_` | `uint256` | Strike price of the option token (in units of quoteToken per payoutToken)                                                                     |

**Returns**

| Name     | Type                     | Description                                                  |
| -------- | ------------------------ | ------------------------------------------------------------ |
| `oToken` | `FixedStrikeOptionToken` | Address of the ERC20 fixed strike option token being created |

### create

Deposit an ERC20 token and mint an ERC20 fixed strike option token

```solidity
function create(FixedStrikeOptionToken optionToken_, uint256 amount_) external override nonReentrant;
```

**Parameters**

| Name           | Type                     | Description                                                                                 |
| -------------- | ------------------------ | ------------------------------------------------------------------------------------------- |
| `optionToken_` | `FixedStrikeOptionToken` | Fixed strike option token to mint                                                           |
| `amount_`      | `uint256`                | Amount of option tokens to mint (also the number of payout tokens required to be deposited) |

### exercise

Exercise an ERC20 fixed strike option token. Provide required quote tokens and receive amount of payout tokens.

*Amount of quote tokens required to exercise is return from the exerciseCost() function*

```solidity
function exercise(FixedStrikeOptionToken optionToken_, uint256 amount_) external override nonReentrant;
```

**Parameters**

| Name           | Type                     | Description                                                                       |
| -------------- | ------------------------ | --------------------------------------------------------------------------------- |
| `optionToken_` | `FixedStrikeOptionToken` | Fixed strike option token to exercise                                             |
| `amount_`      | `uint256`                | Amount of option tokens to exercise (also the number of payout tokens to receive) |

### reclaim

Reclaim collateral from expired option tokens

```solidity
function reclaim(FixedStrikeOptionToken optionToken_) external override nonReentrant;
```

**Parameters**

| Name           | Type                     | Description                                          |
| -------------- | ------------------------ | ---------------------------------------------------- |
| `optionToken_` | `FixedStrikeOptionToken` | Fixed strike option token to reclaim collateral from |

## View Functions

### exerciseCost

Get the cost to exercise an amount of fixed strike option tokens

```solidity
function exerciseCost(FixedStrikeOptionToken optionToken_, uint256 amount_) external view returns (ERC20, uint256);
```

**Parameters**

| Name           | Type                     | Description                           |
| -------------- | ------------------------ | ------------------------------------- |
| `optionToken_` | `FixedStrikeOptionToken` | Fixed strike option token to exercise |
| `amount_`      | `uint256`                | Amount of option tokens to exercise   |

**Returns**

| Name     | Type      | Description                                                           |
| -------- | --------- | --------------------------------------------------------------------- |
| `token_` | `ERC20`   | Token required to exercise (quoteToken for call, payoutToken for put) |
| `cost_`  | `uint256` | Amount of `token_` required to exercise                               |

### getOptionToken

Get the FixedStrikeOptionToken contract corresponding to the params, reverts if no token exists

```solidity
function getOptionToken(
    ERC20 payoutToken_,
    ERC20 quoteToken_,
    uint48 eligible_,
    uint48 expiry_,
    address receiver_,
    bool call_,
    uint256 strikePrice_
) public view returns (FixedStrikeOptionToken);
```

**Parameters**

| Name           | Type      | Description                                                                                                                                   |
| -------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `payoutToken_` | `ERC20`   | ERC20 token that the purchaser will receive on execution                                                                                      |
| `quoteToken_`  | `ERC20`   | ERC20 token used that the purchaser will need to provide on execution                                                                         |
| `eligible_`    | `uint48`  | Timestamp at which the option token can first be executed (gets rounded to nearest day)                                                       |
| `expiry_`      | `uint48`  | Timestamp at which the option token can no longer be executed (gets rounded to nearest day)                                                   |
| `receiver_`    | `address` | Address that will receive the proceeds when option tokens are exercised. Also the address that can claim collateral from unexercised options. |
| `call_`        | `bool`    | Whether the option token is a call (true) or a put (false)                                                                                    |
| `strikePrice_` | `uint256` | Strike price of the option token (in units of quoteToken per payoutToken)                                                                     |

**Returns**

| Name            | Type                     | Description                             |
| --------------- | ------------------------ | --------------------------------------- |
| \`optionToken\` | `FixedStrikeOptionToken` | FixedStrikeOptionToken contract address |

### getOptionTokenHash

Get the hash ID of the fixed strike option token with these parameters

```solidity
function getOptionTokenHash(
    ERC20 payoutToken_,
    ERC20 quoteToken_,
    uint48 eligible_,
    uint48 expiry_,
    address receiver_,
    bool call_,
    uint256 strikePrice_
) external pure returns (bytes32);
```

**Parameters**

| Name           | Type      | Description                                                                                                                                   |
| -------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `payoutToken_` | `ERC20`   | ERC20 token that the purchaser will receive on execution                                                                                      |
| `quoteToken_`  | `ERC20`   | ERC20 token used that the purchaser will need to provide on execution                                                                         |
| `eligible_`    | `uint48`  | Timestamp at which the option token can first be executed (gets rounded to nearest day)                                                       |
| `expiry_`      | `uint48`  | Timestamp at which the option token can no longer be executed (gets rounded to nearest day)                                                   |
| `receiver_`    | `address` | Address that will receive the proceeds when option tokens are exercised. Also the address that can claim collateral from unexercised options. |
| `call_`        | `bool`    | Whether the option token is a call (true) or a put (false)                                                                                    |
| `strikePrice_` | `uint256` | Strike price of the option token (in units of quoteToken per payoutToken)                                                                     |

**Returns**

| Name         | Type      | Description                                                    |
| ------------ | --------- | -------------------------------------------------------------- |
| `optionHash` | `bytes32` | Hash ID of the fixed strike option token with these parameters |

## Admin Functions

### setMinOptionDuration

Set minimum duration to exercise option

*Absolute minimum is 1 day (86400 seconds) due to timestamp rounding of eligible and expiry parameters*

```solidity
function setMinOptionDuration(uint48 duration_) external override requiresAuth;
```

**Parameters**

| Name        | Type     | Description                 |
| ----------- | -------- | --------------------------- |
| `duration_` | `uint48` | Minimum duration in seconds |

### setProtocolFee

Set protocol fee

```solidity
function setProtocolFee(uint48 fee_) external override requiresAuth;
```

**Parameters**

| Name   | Type     | Description                                     |
| ------ | -------- | ----------------------------------------------- |
| `fee_` | `uint48` | Protocol fee in basis points (3 decimal places) |

### claimFees

Claim fees accrued by protocol in the input tokens and sends them to the provided address

```solidity
function claimFees(ERC20[] memory tokens_, address to_) external override nonReentrant requiresAuth;
```

**Parameters**

| Name      | Type      | Description                       |
| --------- | --------- | --------------------------------- |
| `tokens_` | `ERC20[]` | Array of tokens to claim fees for |
| `to_`     | `address` | Address to send fees to           |

## Events

### WroteOption

```solidity
event WroteOption(uint256 indexed id, address indexed referrer, uint256 amount, uint256 payout);
```

### OptionTokenCreated

```solidity
event OptionTokenCreated(
    FixedStrikeOptionToken optionToken,
    ERC20 indexed payoutToken,
    ERC20 quoteToken,
    uint48 eligible,
    uint48 indexed expiry,
    address indexed receiver,
    bool call,
    uint256 strikePrice
);
```

## Errors

### Teller\_NotAuthorized

```solidity
error Teller_NotAuthorized();
```

### Teller\_TokenDoesNotExist

```solidity
error Teller_TokenDoesNotExist(bytes32 optionHash);
```

### Teller\_UnsupportedToken

```solidity
error Teller_UnsupportedToken(address token);
```

### Teller\_InvalidParams

```solidity
error Teller_InvalidParams(uint256 index, bytes value);
```

### Teller\_OptionExpired

```solidity
error Teller_OptionExpired(uint48 expiry);
```

### Teller\_NotEligible

```solidity
error Teller_NotEligible(uint48 eligible);
```

### Teller\_NotExpired

```solidity
error Teller_NotExpired(uint48 expiry);
```

### Teller\_AlreadyReclaimed

```solidity
error Teller_AlreadyReclaimed(FixedStrikeOptionToken optionToken);
```

### Teller\_PriceOutOfBounds

```solidity
error Teller_PriceOutOfBounds();
```

### Teller\_InvalidAmount

```solidity
error Teller_InvalidAmount();
```
