# 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`](https://docs.auctus.org/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)
