# 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](https://docs.auctus.org/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`](#exercise) or [`exerciseFrom`](#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`](#exercise) or [`exerciseFrom`](#exercisefrom) functions to exercise this base value must be added by [`maxExercisedAccounts`](#maxexercisedaccounts).
* When using [`exerciseAccounts`](#exerciseaccounts) or [`exerciseAccountsFrom`](#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`](#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`](#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`](#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`](#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)
