# Getting started

## **Protocol Introduction**

Auctus is a decentralized non-custodial options protocol built on top of Ethereum that allows users to trade, mint and exercise call or put options, in a trustless and decentralized manner without having to rely on any third party.

Each option series is integrated through an ACOToken contract, which is ERC20-compliant, making options transferable, fungible, and ready for further DeFi integrations.

## **ACO tokens (Auctus Crypto Options)**

ACO (Auctus Crypto Options) tokens are tokenized options that convey to its holder the right, but not the obligation, to buy (in the case of a call) or sell (in the case of a put) an underlying cryptoasset at a specified price (Strike Price) at any time before or at expiration.

ACO tokens are American-style options, allowing the holder to exercise any time before its expiration date. Exercise is not automatic and the settlement is "physical" since the underlying asset is transferred and delivered.

### ACO Token Symbol

Each ACO token option has its own smart contract and the symbol contains key information about its option.

The ACO tokens’ symbol consists of four parts:

1. Symbol of the underlying asset
2. Strike price & Strike Asset
3. Option type, either P or C, for put or call
4. Expiration&#x20;

### **Example: ETH Call Option**

```
ACO ETH-200USDC-C-26JUN20-0800UTC
```

The above symbol represents a call option on ETH, expiring on 26 June 2020 08:00 UTC, with a strike price of 200 USDC.

#### Call Option Buyer

The buyer of one “ACO ETH-200USDC-C-26JUN20-0800UTC” token has the right, but not the obligation, to buy one ETH for 200 USDC any time before 26 June 2020. This can be done directly with the smart contract, by sending this token and 200 USDC, he will receive one Ether.

#### **Call Option Writer**

On the other hand, anyone can become an option writer and mint one “ACO ETH-200USDC-C-26JUN20-0800UTC” token by locking 1 Ether as collateral into the smart contract, then this token can be sold for a premium. In exchange for the premium, the option writer takes on an obligation to sell 1 ETH for 200 USDC.&#x20;

After transferring or selling the token minted, at any time before 26 June 2020, if this position gets assigned, the option writer will be forced to sell his 1 Ether for 200 USDC. If it's not assigned, he can redeem back the 1 Ether after expiration. Alternatively, if the writer wants to redeem the collateral back before expiration, he can buy back one token and burn it.

### **Example: ETH Put Option**

```
 ACO ETH-160USDC-P-26JUN20-0800UTC
```

The above symbol represents a put option on ETH, expiring at 26 June 2020 08:00 UTC, with a strike price of 160 USDC.

#### **Put Option Buyer**

The buyer of one  “ACO ETH-160USDC-P-26JUN20-0800UTC” token has the right to sell one ETH for 160 USDC any time before  26 June 2020 08:00 UTC. This can be done directly with the smart contract, by sending this token and 1 ETHER, he will receive 160 USDC.<br>

#### **Put Option Writer**

On the other hand, anyone can become an option writer and mint one “ACO ETH-160USDC-P-26JUN20-0800UTC” token by locking 160 USDC as collateral into the smart contract, then this token can be sold for a premium. In exchange for the premium, the option writer takes on an obligation to buy 1 ETH for 160 USDC any time before  26 June 2020 08:00 UTC.

After transferring or selling the token minted, at any time before  26 June 2020 08:00 UTC, if this position gets assigned, the option writer will be forced to buy 1 Ether for 160 USDC. If it's not assigned, he can redeem back the 160 USDC after expiration. Alternatively, if the writer wants to redeem the collateral back before expiration, he can buy back one token and burn it.


# Security

The security of Auctus protocol is our highest priority. To ensure top-notch security, Auctus protocol smart contracts were audited by Open Zeppelin and have undergone rigorous internal testing. We also have an ongoing bug bounty program where community members can report any bugs or vulnerabilities.

## Audits

ACO has completed a full audit with Open Zeppelin. The link to the audit report can be found below.

[OpenZeppelin Audit](https://blog.openzeppelin.com/aco-protocol-audit/)

## Bug Bounty

The bug bounty covers any of the core smart contracts deployed on mainnet. The code can be found at: <https://github.com/AuctusProject/aco>

### Rewards

The bounty program will pay out rewards according to the severity of a vulnerability. The final reward amount is at the sole discretion of Auctus.

| Reward               | Severity | Examples                                                                                                                                     |
| -------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **$5,000 - $15,000** | Critical | <ul><li>Stealing collateral assets</li><li>Permanently freezing collateral assets</li></ul>                                                  |
| **$2,000 - $5,000**  | High     | <ul><li>Severe rounding errors where an attacker can steal significant collateral in excess of any gas costs</li></ul>                       |
| **$1,000 - $2,000**  | Medium   | <ul><li>Minor rounding errors that allow an attacker to slowly manipulate collateral to their advantage in excess of any gas costs</li></ul> |
| **$0 - $1,000**      | Low      | <ul><li>Informational and code quality based disclosures</li></ul>                                                                           |

### Reporting / Disclosures

Please report any findings **only to** <contact@auctus.org> with full details about any vulnerability and steps / code to reproduce. Allow us time to review and remediate any findings before public disclosure.&#x20;

### Ineligible Findings

* Duplicate vulnerabilities. Only the first reporter will be rewarded.
* Findings already known as part of a formal audit
* Front end bugs;
* DDOS attack;
* Spamming;
* Automated tools
* Compromising or misusing third party systems or services.


# FAQ


# Basics

### What are ACO tokens (Auctus Crypto options)?

ACO tokens are tokenized options that convey to its holders the right, but not the obligation, to buy or sell an underlying cryptoasset at a specified price (Strike Price) at any time before or at expiration.

### What is the difference between put and call?

With a call option, the buyer has the right to buy the underlying asset at a specified price at any time before or at expiration.

With a put option, the buyer has the right to sell the underlying asset at a specified price at any time before or at expiration.

### How to read an ACO token symbol?

The components of an ACO token symbol are:&#x20;

1. Symbol of the underlying asset
2. Strike price & Strike Asset
3. Option type, either P or C, for put or call
4. Expiration&#x20;

Example: `ACO ETH-200USDC-C-26JUN20-0800UTC`

| Component            | Value           | Location in symbol                    |
| -------------------- | --------------- | ------------------------------------- |
| Underlying asset     | ETH             | ACO **ETH**-200USDC-C-26JUN20-0800UTC |
| Strike Price & Asset | 200 USDC        | ACO ETH-**200USDC**-C-26JUN20-0800UTC |
| Option Type          | CALL            | ACO ETH-200USDC-**C**-26JUN20-0800UTC |
| Expiration           | 26JUN20-0800UTC | ACO ETH-200USDC-C-**26JUN20-0800UTC** |

{% hint style="info" %}
The above symbol represents a call option on ETH, expiring on 26 June 2020 08:00 UTC, with a strike price of 200 USDC. &#x20;

**One token "ACO ETH-200USDC-C-26JUN20-0800UTC"** gives the owner the **right to buy 1 ETH f**or **200 USDC** (that's the strike price), regardless of the market price of ETH, **until the expiration time.**
{% endhint %}


# Exercising Options

### How to Exercise a Call Option? ( traditional )

"Exercising a call" means you are demanding to buy the crypto asset at the strike price. In order to exercise the option, you must send the tokens and the corresponding amount of the strike price, before the expiration. This can be done by accessing "Manage" in the top menu of your dashboard.\
\
Example: Exercising  2 "ACO ETH-**2000USDC**-**C**-26JUN20-0800UTC"

| Action         | Amount               |
| -------------- | -------------------- |
| You send       | 2 tokens + 4000 USDC |
| You'll receive | 2 ETH                |

### How to Exercise a Call Option? ( Flash Exercise )

By using Flash Exercise to exercise call options, instead of sending the amount required to exercise, this amount is covered using Uniswap V2 Flash Swaps and you'll receive the remaining amount (intrinsic value) in ETH.\
\
Net Profit = Number of Options \* (( Uniswap Price - Strike Price ) / Uniswap Price )\
\
Example: Exercising  2 "ACO ETH-**2000USDC**-**C**-26JUN20-0800UTC" and Uniswap Price  = 2500 USDC.&#x20;

| Action                        | Amount                        |
| ----------------------------- | ----------------------------- |
| You send                      | 2 tokens                      |
| You'll receive (total profit) | 0.4 ETH (2\*(2500-2000)/2500) |

### How to Exercise a Put Option?

"Exercising a put" means  you are demanding to sell  the crypto asset at the strike price. In order to exercise the option, go to you must send the tokens and the corresponding amount of the underlying asset, before the expiration. This can be done by accessing "Manage" in the top menu of your dashboard.\
\
Example: Exercising  2 "ACO ETH-**2000USDC**-**P**-26JUN20-0800UTC"

| Action         | Amount           |
| -------------- | ---------------- |
| You send       | 2 tokens + 2 ETH |
| You'll receive | 4000 USDC        |

### How to Exercise a Put Option? ( Flash Exercise )

By using Flash Exercise to exercise put options, instead of sending the amount required to exercise, this amount is covered using Uniswap V2 Flash Swaps and you'll receive the remaining amount (intrinsic value) in USDC.\
\
Net Profit = Number of Options \* ( Strike Price  - Uniswap Price )\
\
Example: Exercising  2 "ACO ETH-**3000USDC**-**C**-26JUN20-0800UTC" and Uniswap Price  = 2500 USDC.&#x20;

| Action         | Amount                     |
| -------------- | -------------------------- |
| You send       | 2 tokens                   |
| You'll receive | 1000 USDC (2\*(3000-2500)) |

### What happens to my option if I never sell or exercise it?

Once an options contract expires, the token itself is worthless. If you own an option and it expires unexercised, you no longer have any of the rights inherent in that contract and you lose the premium you paid for it.

### **Do I have to manually exercise the options?**&#x20;

**YES.** Options are not exercised automatically.


# Minting Options

Writing - Minting and Selling options

### What is Writing an Option? <a href="#mntl-sc-block_1-0" id="mntl-sc-block_1-0"></a>

Traders write an option by selling someone the right to buy or sell a crypto asset at a specific price (strike price) before or at a specific date (expiration date).&#x20;

### How to sell a Call Option using limit orders?

To mint one call option, you need to lock the underlying asset as collateral into the smart contract, then this token can be sold for a premium. This can be done by accessing "[Mint](https://app.auctus.org/advanced/mint/ETH_USDC)" in the top menu of your dashboard and then going to [Trade ](https://app.auctus.org/advanced/trade/ETH_USDC)to sell the minted tokens.&#x20;

Example: Writing  2 "ACO ETH-2000USDC-**C**-26JUN20-0800UTC"

| Action         | Amount                                     |
| -------------- | ------------------------------------------ |
| You lock       | 2 ETH                                      |
| You'll receive | 2 "ACO ETH-2000USDC-**C**-26JUN20-0800UTC" |

After minting, you can go to Trade and sell those tokens for any price you would be willing to accept for assuming the obligation to sell 2 ETH for 4000 USDC.&#x20;

{% hint style="warning" %}
Only write a call option if you’d be comfortable selling the underlying asset at the strike price.
{% endhint %}

### How to sell a Put Option using limit orders?

To mint one put option, you need to lock the strike price as collateral into the smart contract, then this token can be sold for a premium. This can be done by accessing "[Mint](https://aco.finance/mint)" in the top menu of your dashboard and then going to [Trade ](https://aco.finance/trade)to sell the minted tokens.&#x20;

Example: Writing  2 "ACO ETH-2000USDC-**P**-26JUN20-0800UTC"

| Action         | Amount                                          |
| -------------- | ----------------------------------------------- |
| You lock       | 4000 USDC                                       |
| You'll receive | 2 "ACO ETH-2000USDC-**P-**&#x32;6JUN20-0800UTC" |

After minting, you can go to Trade and sell those tokens for any price you would be willing to accept for assuming the obligation to sell 2 ETH for 4000 USDC

{% hint style="warning" %}
Only write a put option if you’d be comfortable buying the underlying asset at the strike price.
{% endhint %}

### When can you be assigned?

While the minted tokens remain on your wallet, you can't be assigned, but if you transfer or sell the tokens, you can be assigned at any time before expiration.

### How can the writer of an option cancel the obligation before exercise or expiration?&#x20;

If you have written an option and have not been assigned yet, you can cancel the obligation by buying back the same amount of tokens that were not assigned. You can't be assigned while the tokens remain in your wallet. If you want, you can remove your collateral before expiration by burning the ACO tokens. This can be done by accessing "[Mint](https://aco.finance/mint)" in the top menu, and then, on the bottom section, clicking on "Burn to redeem collateral".<br>

### What happens if I am assigned?

As a writer of a call option, you are obligated to sell to the holder of the call option, the underlying asset at the strike price upon exercise. The corresponding amount of the strike price is sent directly to your wallet.

\
**Example Call Assignment:** Assignment of  2 "ACO ETH-2000USDC-**C**-26JUN20-0800UTC"\
\
You'll receive 4000 USDC and 2 ETH from your collateral will be sent to the holder exercising it.

**Example Put Assignment:** Assignment of  2 "ACO ETH-2000USDC-**P**-26JUN20-0800UTC"\
\
You'll receive 2 ETH and 4000 USDC from your collateral will be sent to the holder exercising it.

### What happens if I am never assigned? How can I redeem my collateral back?

If you have written an option and are not assigned an exercise before it expires, you no longer have any of the obligations inherent in that contract, you are free to remove the collateral you supplied. This can be done by accessing "[Mint](https://aco.finance/mint)" in the top menu, and then, on the bottom section, clicking on "Redeem collateral".


# Security, Fees and Governance

### Is Auctus Safe? Has Auctus been audited?

The security of Auctus protocol is our highest priority. To ensure top-notch security, Auctus protocol smart contracts were audited by [**Open Zeppelin**](https://blog.openzeppelin.com/aco-protocol-audit/) and have undergone rigorous internal testing. We also have an ongoing **bug bounty program** where community members can report any bugs or vulnerabilities.

### Who controls the Auctus protocol?

The Auctus protocol allows a single address to modify parameters, create new options series, add new strike assets and change the template for tokens that will be created in the future. For the existing tokens, there is no admin key, meaning the protocol is noncustodial and only you have access to your funds.\
\
The admin key is currently administered by the Auctus team, but our goal is transitioning the control from our core team to the AUC token holders.&#x20;

### **Are there fees on Auctus?**

**Trading fees: 2.5% of premium**

**Settlement: 0.03% of the underlying (Settlement at exercise)**

\
**Other fees:**\
ACO utilizes the 0x Protocol for decentralized exchange functionality, currently 0x charges *150,000 \* gasPrice* per order.

### How do I get involved?&#x20;

Join our community on [Discord](https://discord.gg/9JqeMxs) to learn more about ACO, participate in discussions with the team, and contribute to the future of decentralized options.

## I have more questions ...&#x20;

Feel free to reach out to us on [Discord](https://discord.gg/9JqeMxs) or email at <contact@aco.finance>


# POOLS

Become a liquidity provider and receive premiums by automatically selling covered options.

## **Summary of Pools available:**

### WRITE ETH CALL OPTIONS

**Deposit:** ETH \
**Return:** Earn premium and accumulate more ETH with the premium of options sold during times ETH doesn't skyrocket.\
**Risk:** The main risk is missing out on ETH appreciation, in exchange for the premium which is used to buy more ETH. The pool can lose a significant amount of ETH if the price of ETH skyrockets.

### WRITE ETH PUT OPTIONS

**Deposit:** USDC\
**Return:** Earn interest on USDC deposit on AAVE (aUSDC) and accumulate more aUSDC with the premium of options sold during times ETH doesn't fall abruptly.\
**Risk:** The pool can lose a significant amount of USDC if the price of ETH falls abruptly.

### WRITE WBTC CALL OPTIONS

**Deposit:** WBTC\
**Return:** Earn premium and accumulate more WBTCwith the premium of options sold during times WBTC doesn't skyrocket.\
**Risk:** The main risk is missing out on WBTC appreciation, in exchange for the premium which is used to buy more WBTC. The pool can lose a significant amount of WBTC if the price of WBTC skyrockets.

### WRITE WBTC PUT OPTIONS

**Deposit:** USDC\
**Return:** Earn interest on USDC deposit on AAVE and accumulate more aUSDC with the premium of options sold during times WBTC doesn't fall abruptly.\
**Risk:** The pool can lose a significant amount of USDC if the price of WBTC falls abruptly.

## **How does Auctus Pool work**?

#### Which options are sold by the pools?

Currently, all public pools sell options with maximum expiration of 30 days from the day of purchase.&#x20;

#### How options are priced?

The premium is calculated using the Black-Scholes model, the implied volatility is manually updated on the smart contracts and displayed on the pools section, we are working to add implied volatility oracles in the future.

**What happens when the pool option positions are exercised?**

For write call pools, the pool will receive the equivalent of the strike price for each option exercised. For write put pools, the pool will receive 1 WBTC/ETH for each option exercised. This amount is converted back to the deposit asset (ETH/WBTC for call pools and aUSDC for put pools) using Uniswap liquidity at any time and then can be used to sell again options.

#### How to withdraw my liquidit&#x79;**? Can I withdraw anytime?**

There are two ways to withdrawal your liquidity:

1\) Withdraw (Normal)\
This one is equivalent to receiving your pro-rata share of free liquidity and the equivalent net value of open positions (CollateralOnOpenPositions-TotalCurrentValueOfOptionsSold\*1.1). It is similar to buying back the options sold by the pool.

If you own 10% of the liquidity tokens, you will receive:

10% of liquidity free on the pools (ETH or WBTC+USDC) + the amount of deposit asset equivalent to 10% of the net value of open positions which is calculated with the total value of collateral locked on open positions - the current price of all options\*1.1 . This 10% fee on top of the current price of the options is charged to exit open positions.

For example, considering the Write ETH Pool has:\
\
**Free Liquidity**

| Asset | Quantity |
| ----- | -------- |
| ETH   | 300      |
| USDC  | 1000     |

**Open Position**

| OPTION                             | OPEN POSITION | <p>OPTION VALUE in ETH<br>(Calculated using BS with current IV and price of ETH + 10%)</p> | COLLATERAL LOCKED | <p>NET VALUE</p><p>(COLLATERAL LOCKED-OPTIONS VALUE)</p> |
| ---------------------------------- | ------------- | ------------------------------------------------------------------------------------------ | ----------------- | -------------------------------------------------------- |
| ACO ETH-2500USDC-C-23APR21-0800UTC | -2.2019       | -0.03 ETH                                                                                  | 2.2019 ETH        | 2.1719 ETH                                               |

If you own 10% of liquidity tokens, you would receive: 10% of Free liquidity (30 ETH + 100 USDC) + 10% of net value of open positions (0.21719 ETH)  = 30.21719 ETH + 100 USDC

2\) Transferring Open Positions&#x20;

If there is not enough liquidity to use the first withdrawal method, you can wait until there is free liquidity, or you can withdraw your pro-rata share of free liquidity and transfer the pro-rata share of open positions to your wallet. If you choose this method, if they are exercised, you will receive the amount in your wallet directly, but if they expire without being exercised, you will need to manually withdraw the collateral back after expiration by accessing the Manage tab.&#x20;

Considering the example used above, you would receive 30ETH + 100 USDC and an open position of - 0.22019 ACO ETH-2500USDC-C-23APR21-0800UTC would be transferred to your wallet. After expiration, if the option is not exercised, you can redeem back the collateral amount for this open position ( 0.22019 ETH ). And if the option is exercised, you would receive 0.22019\*2500(Amount Of options \* Strike Price)= 550.475 USDC directly in your wallet.


# Auctus Vaults

Automated strategies using interest-earning protocols and options

Vaults represent a passive-investing strategy combining interest-earning protocols and options. Some vaults offer capital protection and so can be adapted to all risk profiles. While some vaults offer principal protection, they still face smart contracts risks. Vaults benefit users by socializing gas costs and automating the allocation strategies.

**USDC 3POOL-ETHCALL**

3POOL - ETHCALL is the first vault available and it provides ETH exposure with principal protection. The yields generated from CRV farmed are automatically used to purchase ETH call options.

Summary:

* Deposit asset: USDC
* Principal allocation: Curve 3Pool
* Yield allocation: Farming rewards are used to purchase ETH CALL options&#x20;
* Automatic exercise before expiration if the options purchased are in-the-money.&#x20;
* Fees: Perfomance (Harvest) - 10% , Withdrawal - 0.2%


# Buying ETH call options

Using ETH call options to take advantage of leverage.

By purchasing a call option instead of ETH, you are taking advantage of leverage; allowing you to use less money to gain positive exposure to ETH rather than using more money to purchase ETH directly.

You can profit if Ethereum price rises, without taking on all of the downside risk that would result from owning ETH. Your losses are limited to only what you paid for the call versus the potentially larger losses equaling the total decline in ETH price had you just bought ETH directly.

If ETH price remains even, you lose some (or all) of the premium you paid for the call. Then you can decide to sell the call for a loss. However, if ETH price goes higher, you profit from the increase. Then you have to decide whether you want to exercise your right to buy ETH at the lower price or just sell the call and collect your profit.

### Example&#x20;

Let’s assume ETH is currently trading for $200. You would like to buy 200 ETH. You could buy 200 ETH and have $40,000 of risk in the market. Or, you could buy 200 ETH calls with a $200 strike price for $9.00 and have a similar exposure but do so with only $1,800 ($9 X 200 = $1,800).

By purchasing the cal you are saying that by expiration you anticipate ETH to have risen above the break-even point: $209, $200 strike price + $9.00 (the option premium paid). The profit potential is unlimited as ETH price continues to rise above $209. The risk for the call purchase is limited entirely to the total premium paid, $1,800, no matter how low ETH price declines.

Before expiration, if the call purchase becomes profitable you are free to exercise the right to buy ETH at $200 or to sell the option to realize the gain. On the other hand, if your bullish outlook proves incorrect, the call might be sold to realize a loss less than the maximum.


# Writing ETH call options

If you'd like to generate some additional income from your ETH, writing ETH calls may be the strategy you're looking for.

Do you have a target price at which you will sell if the ETH rises? You might use a limit order to sell the ETH at a higher price, and then wait to see if you get a fill. But there’s another way you could consider. Using options, you can receive money today for your willingness to sell your ETH at a higher price.\
\
If the ETH price remains unchanged, you keep your ETH and the premium you received from selling the call. If the ETH  price declines, and the loss is greater than the premium you received, you keep your ETH as well as the premium.

Remember, as the owner of ETH, you still have all the downside risk associated with the price of ETH. However, if the ETH price rises above the strike price before expiration, you can be obligated to sell your ETH at the strike price, and keep the premium received.

### Example&#x20;

Let’s assume ETH is currently trading for $190. You would like to sell 200 ETH if it rises to $200. You could place a limit order to sell 200 ETH at $200 and wait to see if you sell your ETH. Or, you could sell 200 options with a $200 strike price at a $9 premium and collect $1,800 on your willingness to sell your 200 ETH at $200. By selling the covered call, you will generate income on ETH by collecting premiums for your willingness to be obligated to sell your ETH at $200.<br>


# Buying ETH put options

There is an options strategy that may help you to protect against a decline in  ETH price but doesn’t limit your upside potential if ETH price were to go higher.

This is called the protective put strategy. Buying a protective put involves buying one put for every ETH already owned. This put guarantees the owner the right, but not the obligation, to sell ETH at the strike price at any time until the option expires, no matter how low ETH declines in value. And just as with other forms of insurance the owner pays a premium for this protection, the premium paid for the put.

### Example

Let’s assume ETH is currently trading at $208. You own 300 ETH and you don’t necessarily want to sell your ETH, but you want to limit your losses if it were to drop below $200. To hedge this position, you could buy 300 puts with a $200 strike price for $3 and pay $900 to have the ability to sell your 300 ETH at $200 if the price of ETH were to drop below that amount. With the protective put, you pay a premium to have the right to sell your ETH in case the price declined or there was a dip in the markets before the expiration.\
\
There are two things to keep in mind when buying put options to protect an ETH position. First, you can wait and see how ETH price performs for as long as you want, up to the end of the life of your option. Second, even if ETH drops below $200, you may not want to sell it right away. You can wait to see if the price rebounds. That’s something you can’t do with stop orders.\
\
However, keep in mind that the security does come at a cost since you pay a premium to own the put.<br>


# Writing ETH put options

If you'd like to generate some additional income while waiting to buy ETH at a price below the current, writing ETH puts may be the strategy you're looking for.

Do you use limit orders to bid for ETH below the current price? After deciding that you are going to buy ETH, you can place a bid below the current market price, hoping for a dip in ETH price. This way, you would feel comfortable if you end up buying the ETH.

Rather than waiting for ETH to hit your target price, you might consider using options to collect money today for being willing to assume the obligation of buying ETH if it moves to the lower price that you choose. It may seem a little counter-intuitive, but you can use write ETH puts to buy ETH.

### Example

Let’s assume ETH is currently trading for $208. You would like to buy 200 ETH if it drops to $200. You could place a limit order to buy 200 ETH at $200 and wait to see if you buy. Or, you could write 200 ETH puts with a $200 strike at $4 and collect $800 on your willingness to buy 200 ETH at $200.&#x20;

By using this strategy, you can generate additional returns in your stablecoin holdings by collecting a premium for your willingness to be obligated to buy ETH at a price that is below the current price.


# Factory

## Introduction

ACO Factory is an implementation of an upgradable proxy that follows the [EIP-897](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-897.md). The proxy code is available in [`ACOProxy.sol`](https://github.com/AuctusProject/aco/blob/master/smart-contracts/contracts/core/ACOProxy.sol). The implementation of the factory is responsible to **create all the ACO tokens**. The factory serves as a public registry and is used to look up all ACO tokens added to the system. It is also used to set the ACO tokens' implementation address used to deploy a new one. It also contains logic to turn on the protocol charge. At the moment there are no protocol fees.&#x20;

## Code

[`ACOFactory.sol`](https://github.com/AuctusProject/aco/blob/master/smart-contracts/contracts/core/ACOFactory.sol)

## Address

The proxy for `ACOFactory.sol` is deployed at [`0x176b98ab38d1aE8fF3F30bF07f9B93E26F559C17`](https://etherscan.io/address/0x176b98ab38d1aE8fF3F30bF07f9B93E26F559C17) on the Ethereum mainnet.&#x20;

## Events

### SetFactoryAdmin

`event SetFactoryAdmin(address indexed previousFactoryAdmin, address indexed newFactoryAdmin);`

&#x20;Emitted when the factory admin address has been changed.

* `previousFactoryAdmin` Address of the previous factory admin.
* `newFactoryAdmin` Address of the new factory admin.

### SetAcoTokenImplementation

`event SetAcoTokenImplementation(address indexed previousAcoTokenImplementation, address indexed newAcoTokenImplementation);`

Emitted when the ACO token implementation has been changed.

* `previousAcoTokenImplementation` Address of the previous ACO token implementation.
* `newAcoTokenImplementation` Address of the new ACO token implementation.

### SetAcoFee

`event SetAcoFee(uint256 indexed previousAcoFee, uint256 indexed newAcoFee);`

Emitted when the ACO fee has been changed.

* `previousAcoFee` Value of the previous ACO fee.
* `newAcoFee` Value of the new ACO fee.

### SetAcoFeeDestination

`event SetAcoFeeDestination(address indexed previousAcoFeeDestination, address indexed newAcoFeeDestination);`

Emitted when the ACO fee destination address has been changed.

* `previousAcoFeeDestination` Address of the previous ACO fee destination.
* `newAcoFeeDestination` Address of the new ACO fee destination.

### NewAcoToken

`event NewAcoToken(address indexed underlying, address indexed strikeAsset, bool indexed isCall, uint256 strikePrice, uint256 expiryTime, address acoToken, address acoTokenImplementation);`

Emitted when a new ACO token has been created.

* `underlying` Address of the underlying asset (`address(0)` for Ethereum).
* `strikeAsset` Address of the strike asset (`address(0)` for Ethereum).
* `isCall` True if the type is CALL, false for PUT.
* `strikePrice` The strike price with the strike asset precision.
* `expiryTime` The UNIX time for the ACO token expiration.
* `acoToken` Address of the new ACO token created.
* `acoTokenImplementation` Address of the ACO token implementation used on creation.

## Read-Only Functions

### factoryAdmin

`function factoryAdmin() external view returns(address);`

Returns the factory admin address.

### acoTokenImplementation

`function acoTokenImplementation() external view returns(address);`

Returns the ACO token implementation address.

### acoFee

`function acoFee() external view returns(uint256);`

Returns the ACO fee value used on creating new ACO tokens. It is a percentage value (100000 is 100%).

{% hint style="info" %}
Check each specific ACO token fee using its respective [`acoFee`](/smart-contracts/token#acofee) function .
{% endhint %}

### acoFeeDestination

`function acoFeeDestination() external view returns(address);`

Returns the ACO fee destination address used on creating new ACO tokens.

## State-Changing Functions <a href="#state-changing-functions" id="state-changing-functions"></a>

### init

`function init(address _factoryAdmin, address _acoTokenImplementation, uint256 _acoFee, address _acoFeeDestination) external;`

Function to initialize the contract. It should be called through the `data` argument when creating the proxy implementation. It must be called only once. The `assert` is to guarantee that behavior.

### setFactoryAdmin

`function setFactoryAdmin(address newFactoryAdmin) external;`

Function to set the factory admin address. Only can be called by the factory admin.

* `newFactoryAdmin` Address of the new factory admin.

### setAcoTokenImplementation

`function setAcoTokenImplementation(address newAcoTokenImplementation) external;`

Function to set the ACO token implementation address. Only can be called by the factory admin.

* `newAcoTokenImplementation` Address of the new ACO token implementation.

### setAcoFee

`function setAcoFee(uint256 newAcoFee) external;`

Function to set the ACO fee. Only can be called by the factory admin.

* `newAcoFee` Value of the new ACO fee. It is a percentage value (100000 is 100%).

### setAcoFeeDestination

`function setAcoFeeDestination(address newAcoFeeDestination) external;`

Function to set the ACO fee destination address. Only can be called by the factory admin.

* `newAcoFeeDestination` Address of the new ACO fee destination.

### createAcoToken

`function createAcoToken( address underlying, address strikeAsset, bool isCall, uint256 strikePrice, uint256 expiryTime, uint256 maxExercisedAccounts ) external;`

Function to create a new ACO token. It deploys a minimal proxy for the ACO token implementation address. Currently, only can be called by the factory admin.

* `underlying` Address of the underlying asset (0x0 for Ethereum).
* `strikeAsset` Address of the strike asset (0x0 for Ethereum).
* `isCall` Whether the ACO token is the Call type. (False for Put)
* `strikePrice` The strike price with the strike asset precision.
* `expiryTime` The UNIX time for the ACO token expiration.
* `maxExercisedAccounts` The maximum number of accounts that can be exercised by a transaction.

## ABI

[JSON](http://api.etherscan.io/api?module=contract\&action=getabi\&address=0x33EaC966f2B4058F42782Fd13a762d14c28A3259\&format=raw)


# Token

## Introduction

Each option series is integrated through an ACOToken contract, which is ERC20-compliant, making options transferable, fungible, and ready for further DeFi integrations. It inherits from an [`ERC20.sol`](https://github.com/AuctusProject/aco/blob/master/smart-contracts/contracts/core/ERC20.sol) base implementation. Like traditional options, after expiration, the token itself is worthless.&#x20;

## Code

[`ACOToken.sol`](https://github.com/AuctusProject/aco/blob/master/smart-contracts/contracts/core/ACOToken.sol)

## Address

Each ACO token has its own address. To check the available tokens, access <https://aco.finance/#available-options>.

## Events

### Transfer

`event Transfer(address indexed from, address indexed to, uint256 value);`

Emitted when tokens are moved from one account to another.

* `from` The sender of the tokens.
* `to` The destination of the tokens.
* `value` The token amount.

### Approval

`event Approval(address indexed owner, address indexed spender, uint256 value);`

Emitted when the allowance of a `spender` for an `owner` is set.

* `owner` The owner of the tokens.
* `spender` Who receives the allowance.
* `value` The token amount authorized.

### CollateralDeposit

`event CollateralDeposit(address indexed account, uint256 amount);`

Emitted when collateral is deposited on the contract.

* `account` Address of the collateral owner.
* `amount` Amount of collateral deposited.

### CollateralWithdraw

`event CollateralWithdraw(address indexed account, address indexed recipient, uint256 amount, uint256 fee);`

Emitted when collateral is withdrawn from the contract.

* `account` Address of the account.&#x20;
* `recipient` Address of the collateral destination.&#x20;
* `amount` Amount of collateral withdrawn.&#x20;
* `fee` The fee amount charged on the withdrawal.

### Assigned

`event Assigned(address indexed from, address indexed to, uint256 paidAmount, uint256 tokenAmount);`

Emitted when the collateral is used on an assignment.

* `from` Address of the account of the collateral owner.&#x20;
* `to` Address of the account that exercises tokens to get the collateral.&#x20;
* `paidAmount` Amount paid to the collateral owner.&#x20;
* `tokenAmount` Amount of tokens used to exercise.

## Read-Only Functions

### name

`function name() external view returns(string memory);`

Function to get the token name, that it is equal to the symbol.

### symbol

`function symbol() external view returns(string memory);`&#x20;

Function to get the token symbol, see [here](/faq/basics#how-to-read-an-aco-token-symbol) for details about how it is defined.

### decimals

`function decimals() external view returns(uint8);`

Function to get the token decimals, that it is equal to the underlying asset decimals.

### totalSupply

`function totalSupply() external view returns(uint256);`&#x20;

Function to get the total supply of ACO tokens.

### balanceOf

`function balanceOf(address account) external view returns(uint256);`&#x20;

Function to get the ACO tokens balance from an account. &#x20;

* `account` The account to check the balance.&#x20;

### allowance

`function allowance(address owner, address spender) external view returns(uint256);`

Function to get the allowance set for an account to another.

* `owner` Who set the allowance.
* `spender` The authorized spender.

{% hint style="info" %}
Be aware you must trust all addresses that you set an allowance on your ACO tokens.
{% endhint %}

### underlying

`function underlying() external view returns(address);`

Returns the ERC20 token address for the underlying asset (`address(0)` for Ethereum).

### strikeAsset

`function strikeAsset() external view returns(address);`

The ERC20 token address for the strike asset (`address(0)` for Ethereum).

### strikePrice

`function strikePrice() external view returns(uint256);`

Returns the strike price for the ACO token with the strike asset precision.

### isCall

`function isCall() external view returns(bool);`

Returns true if the option type is CALL, false for PUT.

### expiryTime

`function expiryTime() external view returns(uint256);`

Returns the UNIX time for the ACO token expiration.

### acoFee

`function acoFee() external view returns(uint256);`

Returns the ACO token fee value. It is a percentage value (100000 is 100%) that is charged on the token exercise.

### feeDestination

`function feeDestination() external view returns(address);`

Returns the address of the fee destination charged on the exercise.

### underlyingSymbol

`function underlyingSymbol() external view returns(string memory);`

Returns the symbol of the underlying asset.

### strikeAssetSymbol

`function strikeAssetSymbol() external view returns(string memory);`

Returns the symbol of the strike asset.

### underlyingDecimals

`function underlyingDecimals() external view returns(uint8);`

Returns the decimals for the underlying asset.

### strikeAssetDecimals

`function strikeAssetDecimals() external view returns(uint8);`

Returns the decimals for the strike asset.

### maxExercisedAccounts

`function maxExercisedAccounts() external view returns(uint256);`

Returns the maximum number of accounts that can be exercised by transaction using the [`exercise`](/smart-contracts/token#exercise) or [`exerciseFrom`](/smart-contracts/token#exercisefrom) functions.

### collateral

`function collateral() external view returns(address);`

Function to get the collateral asset. It is the underlying asset when is a CALL option or the strike asset when it is a PUT option.

### totalCollateral

`function totalCollateral() external view returns(uint256);`

Returns the total amount of collateral on the contract.

### numberOfAccountsWithCollateral

`function numberOfAccountsWithCollateral() external view returns(uint256);`

Function to get the number of addresses that have collateral deposited.

### currentCollateral

`function currentCollateral(address account) external view returns(uint256);`

Function to get the current amount of collateral for an account.

* `account` Address of the account.

### unassignableCollateral

`function unassignableCollateral(address account) external view returns(uint256);`

Function to get the current amount of unassignable collateral for an account. After expiration, the unassignable collateral is equal to the account's collateral balance.

* `account` Address of the account.

### assignableCollateral

`function assignableCollateral(address account) external view returns(uint256);`

Function to get the current amount of assignable collateral for an account. After expiration, the assignable collateral is zero.

* `account` Address of the account.

### currentCollateralizedTokens

`function currentCollateralizedTokens(address account) external view returns(uint256);`

Function to get the current amount of collateralized ACO tokens for an account.

* `account` Address of the account.

### unassignableTokens

`function unassignableTokens(address account) external view returns(uint256);`

Function to get the current amount of unassignable ACO tokens for an account. After expiration, the unassignable tokens is equal to the account's collateralized tokens.

* `account` Address of the account.

### assignableTokens

`function assignableTokens(address account) external view returns(uint256);`

Function to get the current amount of assignable ACO tokens for an account. After expiration, the assignable tokens is zero.

* `account` Address of the account.

### getCollateralAmount

`function getCollateralAmount(uint256 tokenAmount) external view returns(uint256);`

Function to get the equivalent collateral amount for an ACO token amount.

* `tokenAmount` Amount of tokens.

### getTokenAmount

`function getTokenAmount(uint256 collateralAmount) external view returns(uint256);`

Function to get the equivalent token amount for a collateral amount.

* `collateralAmount` Amount of collateral.

### getBaseExerciseData

`function getBaseExerciseData(uint256 tokenAmount) external view returns(address, uint256);`

Function to get the base data for exercise of an amount of ACO tokens. It returns the asset address and the respective base amount that should be sent to get the collateral on exercise.&#x20;

* `tokenAmount` Amount of ACO tokens that intends to exercise.

{% hint style="info" %}
The returned value is a base amount because to call the exercise this base value must be added as follow:

* When using [`exercise`](/smart-contracts/token#exercise) or [`exerciseFrom`](/smart-contracts/token#exercisefrom) functions to exercise this base value must be added by [`maxExercisedAccounts`](/smart-contracts/token#maxexercisedaccounts).
* When using [`exerciseAccounts`](/smart-contracts/token#exerciseaccounts) or [`exerciseAccountsFrom`](/smart-contracts/token#exerciseaccountsfrom) functions to exercise this base value must be added by the number of accounts presented on the array sent as the function argument.
  {% endhint %}

### getCollateralOnExercise

`function getCollateralOnExercise(uint256 tokenAmount) external view returns(uint256, uint256);`

Function to get the collateral to be received on an exercise and the respective fee to be charged. The first return is the collateral amount and the second the fee.

* `tokenAmount` Amount of ACO tokens that intends to exercise.

## State-Changing Functions

### transfer

`function transfer(address recipient, uint256 amount) external returns(bool);`&#x20;

Function to transfer ACO tokens from the transaction sender to an address. Returns always true otherwise, an exception occurred.

* `recipient` The destination address.
* `amount` The token amount to be transferred.

### transferFrom

`function transferFrom(address sender, address recipient, uint256 amount) external returns(bool);`&#x20;

Function to transfer ACO tokens from an address to another. Allowance must be respected. Returns always true otherwise, an exception occurred.

* `sender` The owner of the tokens.
* `recipient` The destination address.
* `amount` The token amount to be transferred.

### approve

`function approve(address spender, uint256 amount) external returns(bool);`&#x20;

Function for the transaction sender set an allowance. Returns always true otherwise, an exception occurred.

* `spender` Who receives the allowance.
* `amount` The token amount authorized.

{% hint style="info" %}
Be aware you must trust all addresses that you set an allowance on your ACO tokens.
{% endhint %}

### increaseAllowance

`function increaseAllowance(address spender, uint256 amount) external returns(bool);`&#x20;

Function for the transaction sender increases an allowance. Returns always true otherwise, an exception occurred.

* `spender` Who receives the allowance.
* `amount` The token amount that will be increased to the allowance.

{% hint style="info" %}
Be aware you must trust all addresses that you set an allowance on your ACO tokens.
{% endhint %}

### decreaseAllowance

`function decreaseAllowance(address spender, uint256 amount) external returns(bool);`

Function for the transaction sender decreases an allowance. Returns always true otherwise, an exception occurred.

* `spender` Who receives the allowance.
* `amount` The token amount that will be decreased to the allowance.

{% hint style="info" %}
Be aware you must trust all addresses that you set an allowance on your ACO tokens.
{% endhint %}

### init

`function init(address _underlying, address _strikeAsset, bool _isCall, uint256 _strikePrice, uint256 _expiryTime, uint256 _acoFee, address payable _feeDestination, uint256 _maxExercisedAccounts) external;`

Function to initialize the contract. It is called when creating the ACO token by the ACO Factory. It must be called only once. The first `require` is to guarantee that behavior.

* `_underlying` Address of the underlying asset (`address(0)` for Ethereum).&#x20;
* `_strikeAsset` Address of the strike asset (`address(0)` for Ethereum).&#x20;
* `_isCall` True if the type is CALL, false for PUT.&#x20;
* `_strikePrice` The strike price with the strike asset precision.&#x20;
* `_expiryTime` The UNIX time for the token expiration.&#x20;
* `_acoFee` Value of the ACO fee. It is a percentage value (100000 is 100%).&#x20;
* `_feeDestination` Address of the fee destination charged on the exercise.&#x20;
* `_maxExercisedAccounts` The maximum number of accounts that can be exercised by transaction.

### mintPayable

`function mintPayable() external payable;`&#x20;

Function to mint ACO tokens when Ether is required as collateral. The transaction sender will receive the equivalent amount of tokens to the Ether deposited.

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### mintToPayable

`function mintToPayable(address account) external payable;`&#x20;

Function to mint ACO tokens when Ether is required as collateral but this collateral ownership is set to a specific account. The transaction sender, not the account informed, will receive the equivalent amount of tokens to the Ether deposited.

* `account` The account that will be considered as the owner of the collateral deposited.

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### mint

`function mint(uint256 collateralAmount) external;`&#x20;

Function to mint ACO tokens when an ERC20 token is required as collateral. The transaction sender will receive the equivalent amount of tokens to the asset deposited.

* `collateralAmount` Amount of collateral to be deposited.

{% hint style="info" %}
Allowance to ACO token contract on the ERC20 collateral asset is required.&#x20;
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### mintTo

`function mintTo(address account, uint256 collateralAmount) external;`&#x20;

Function to mint ACO tokens when an ERC20 asset is required as collateral but this collateral ownership is set to a specific account. The transaction sender, not the account informed, will receive the equivalent amount of tokens to the asset deposited.

* `account` The account that will be considered as the owner of the collateral deposited.
* `collateralAmount` Amount of collateral to be deposited.

{% hint style="info" %}
Allowance to ACO token contract on the ERC20 collateral asset is required.&#x20;
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### burn

`function burn(uint256 tokenAmount) external;`&#x20;

Function to burn ACO tokens and get the equivalent collateral amount, not assigned, back. The transaction sender must have collateral deposited besides the ACO tokens.

* `tokenAmount` Amount of tokens to be burned.

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### burnFrom

`function burnFrom(address account, uint256 tokenAmount) external;`&#x20;

Function to burn ACO tokens from a specific account and get the equivalent collateral amount, not assigned, back. The informed account must have collateral deposited besides the ACO tokens. The collateral is sent to the transaction sender, not to the account informed.

* `account` Address of the account that has the ACO tokens and collateral deposited.
* `tokenAmount` Amount of tokens to be burned.

{% hint style="info" %}
The ACO token allowance must be respected.
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### exercise

`function exercise(uint256 tokenAmount, uint256 salt) external payable;`&#x20;

Function to exercise the ACO tokens, paying to get the equivalent collateral. The paid amount is sent to the collateral owners that were assigned. See [`getBaseExerciseData`](/smart-contracts/token#getbaseexercisedata) to check which asset and the amount that should be paid.&#x20;

* `tokenAmount` Amount of ACO tokens to be exercised.
* `salt` A random number used to calculate the start index of the array of accounts to be exercised.

{% hint style="info" %}
When the asset that should be paid on exercise is not Ether the allowance to ACO token contract on the respective ERC20 asset is required.&#x20;
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### exerciseFrom

`function exerciseFrom(address account, uint256 tokenAmount, uint256 salt) external payable;`&#x20;

Function to exercise the tokens from an account, paying to get the equivalent collateral. The paid amount is sent to the collateral owners that were assigned. The collateral is transferred to the transaction sender, not to the account informed. See [`getBaseExerciseData`](/smart-contracts/token#getbaseexercisedata) to check which asset and the amount that should be paid.

* `account` Address of the account that has the ACO tokens.
* `tokenAmount` Amount of ACO tokens to be exercised.
* `salt` A random number used to calculate the start index of the array of accounts to be exercised.

{% hint style="info" %}
The ACO token allowance must be respected.
{% endhint %}

{% hint style="info" %}
When the asset that should be paid on exercise is not Ether the allowance to ACO token contract on the respective ERC20 asset is required.
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### exerciseAccounts

`function exerciseAccounts(uint256 tokenAmount, address[] calldata accounts) external payable;`&#x20;

Function to exercise the ACO tokens, paying to get the equivalent collateral. The paid amount is sent to the collateral owners that were assigned. See [`getBaseExerciseData`](/smart-contracts/token#getbaseexercisedata) to check which asset and the amount that should be paid.&#x20;

* `tokenAmount` Amount of ACO tokens to be exercised.
* `accounts` The array of addresses to try to exercise and get collateral from.

{% hint style="info" %}
When the asset that should be paid on exercise is not Ether the allowance to ACO token contract on the respective ERC20 asset is required.
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### exerciseAccountsFrom

`function exerciseAccountsFrom(address account, uint256 tokenAmount, address[] calldata accounts) external payable;`

Function to exercise the tokens from an account, paying to get the equivalent collateral. The paid amount is sent to the collateral owners (on accounts array) that were assigned. The collateral is transferred to the transaction sender, not to the account informed. See [`getBaseExerciseData`](/smart-contracts/token#getbaseexercisedata) to check which asset and the amount that should be paid.

* `account` Address of the account that has the ACO tokens.
* `tokenAmount` Amount of ACO tokens to be exercised.
* `accounts` The array of addresses to try to exercise and get collateral from.

{% hint style="info" %}
The ACO token allowance must be respected.
{% endhint %}

{% hint style="info" %}
When the asset that should be paid on exercise is not Ether the allowance to ACO token contract on the respective ERC20 asset is required.
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### redeem

`function redeem() external;`&#x20;

Function to the transaction sender gets all the collateral deposited, not assigned, back.

{% hint style="info" %}
The function only works when the ACO token **IS** expired.
{% endhint %}

### redeemFrom

`function redeemFrom(address account) external;`&#x20;

Function to get all the collateral deposited from a specific account, not assigned, back. The collateral is sent to the transaction sender, not to the account informed.

* `account` Address of the account that has the collateral deposited.

{% hint style="info" %}
The ACO token allowance must be respected.
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token **IS** expired.
{% endhint %}

## ABI

[JSON](http://api.etherscan.io/api?module=contract\&action=getabi\&address=0x88169c589e699a44776c6CC3d6E213c60cAD43d0\&format=raw)


# Flash Exercise

## Introduction

It is a contract to exercise ACO tokens without sending the amount required to exercise besides the ACO tokens. You send only the ACO tokens and the collateral to be obtained on exercise is partially used to buy the asset and pay the writers the expected amount, the user exercising receives the remaining amount (intrinsic value)  This functionality on a unique transaction is possible due to [Uniswap Flash Swap](https://uniswap.org/docs/v2/smart-contract-integration/using-flash-swaps/). It is only possible to flash exercise an ACO token whether there is the respective pair underlying / strike asset on Uniswap V2.

## Code

[`ACOFlashExercise.sol`](https://github.com/AuctusProject/aco/blob/master/smart-contracts/contracts/periphery/ACOFlashExercise.sol)

## Address

`ACOFlashExercise.sol` is deployed at [`0x8992eea8B6D388af1Df04800E69e66b2d8799895` ](https://etherscan.io/address/0x8992eea8B6D388af1Df04800E69e66b2d8799895)on the Ethereum mainnet.&#x20;

## Read-Only Functions

### uniswapFactory

`function uniswapFactory() external view returns(address);`

The Uniswap V2 factory address.

### uniswapRouter

`function uniswapRouter() external view returns(address);`

The Uniswap V2 router address.

### weth

`function weth() external view returns(address);`

The WETH address used on Uniswap V2.

### getUniswapPair

`function getUniswapPair(address acoToken) external view returns(address);`

Function to get the Uniswap V2 pair for an ACO token.

* `acoToken` Address of the ACO token.

### getExerciseData

`function getExerciseData(address acoToken, uint256 tokenAmount, address[] calldata accounts) external view returns(uint256, uint256);`

Function to get the required amount of collateral to be paid to Uniswap V2 as the first return and the expected amount to exercise the ACO token as the second return.

* `acoToken` Address of the ACO token.
* `tokenAmount` Amount of tokens to be exercised.
* `accounts` The array of addresses to be exercised. Whether the array is empty the exercise will be considered as executed using the methods [`exercise`](/smart-contracts/token#exercise) or [`exerciseFrom`](/smart-contracts/token#exercisefrom).

### getEstimatedReturn

`function getEstimatedReturn(address acoToken, uint256 tokenAmount) external view returns(uint256);`

Function to get the estimated collateral to be received through a flash exercise using the methods [`exercise`](/smart-contracts/token#exercise) or [`exerciseFrom`](/smart-contracts/token#exercisefrom).

* `acoToken` Address of the ACO token.
* `tokenAmount` Amount of tokens to be exercised.

## State-Changing Functions

### flashExercise

`function flashExercise(address acoToken, uint256 tokenAmount, uint256 minimumCollateral, uint256 salt) external;`

Function to flash exercise ACO tokens. No asset is required to exercise the ACO token because the own collateral redeemed is used to fulfill the terms of the contract. The transaction sender will receive the remaining collateral.

* `acoToken` Address of the ACO token.&#x20;
* `tokenAmount` Amount of tokens to be exercised.&#x20;
* `minimumCollateral` The minimum amount of collateral accepted to be received on the flash exercise.&#x20;
* `salt` A random number used to calculate the start index of the array of accounts to be exercised.

{% hint style="info" %}
Allowance to the flash exercise contract on the ACO tokens is required.&#x20;
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

### flashExerciseAccounts

`function flashExerciseAccounts(address acoToken, uint256 tokenAmount, uint256 minimumCollateral, address[] calldata accounts) external;`

Function to flash exercise ACO tokens using a list of accounts to be exercised. No asset is required to exercise the ACO token because the own collateral redeemed is used to fulfill the terms of the contract. The transaction sender will receive the remaining collateral.

* `acoToken` Address of the ACO token.&#x20;
* `tokenAmount` Amount of tokens to be exercised.&#x20;
* `minimumCollateral` The minimum amount of collateral accepted to be received on the flash exercise.&#x20;
* `accounts` The array of addresses to try to exercise and get collateral from.

{% hint style="info" %}
Allowance to the flash exercise contract on the ACO tokens is required.
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

## ABI

[JSON](http://api.etherscan.io/api?module=contract\&action=getabi\&address=0x8992eea8B6D388af1Df04800E69e66b2d8799895\&format=raw)


# Writer

## Introduction

It is a contract to write ACO tokens. Through the data obtained on 0x protocol to market sell ACO tokens is possible to mint and market sell the tokens in only one step.

## Code

[`ACOWriter.sol`](https://github.com/AuctusProject/aco/blob/master/smart-contracts/contracts/periphery/ACOWriter.sol)

## Address

`ACOWriter.sol` is deployed at [`0xE7597F774fD0a15A617894dc39d45A28B97AFa4f`](https://etherscan.io/address/0xE7597F774fD0a15A617894dc39d45A28B97AFa4f) on the Ethereum mainnet.&#x20;

## Read-Only Functions

### weth

`function weth() external view returns(address);`

The WETH address 0x.

### erc20proxy

`function erc20proxy() external view returns(address);`

Address for 0x ERC20 proxy.

## State-Changing Functions

### write

`function write(address acoToken, uint256 collateralAmount, address exchangeAddress, bytes calldata exchangeData) external payable;`

Function to write ACO tokens. The tokens are minted then sold on the 0x exchange. The transaction sender receives the premium.

* `acoToken` Address of the ACO token.&#x20;
* `collateralAmount` Amount of collateral to be deposited.&#x20;
* `exchangeAddress` Address to sell the tokens returned by 0x API.&#x20;
* `exchangeData` Data to be sent to the 0x exchange.

{% hint style="info" %}
When the asset that should be collateralized is not Ether the allowance to the writer contract on the respective ERC20 asset is required.&#x20;
{% endhint %}

{% hint style="info" %}
The function only works when the ACO token is **NOT** expired yet.
{% endhint %}

## ABI

[JSON](http://api.etherscan.io/api?module=contract\&action=getabi\&address=0xE7597F774fD0a15A617894dc39d45A28B97AFa4f\&format=raw)


