# Development

### Preparation

1. Install truffle

   ```
   npm install -g truffle
   ```
2. Install dependencies

   ```
   npm install
   ```
3. Install `ioctl` - the command-line tool to interact with IoTeX blockchain

install ioctl following the instructions: <https://docs.iotex.io/developer/ioctl/install.html>

### Compile contracts

`npm run build:contract`

### Deploy contracts

* **CycloneToken**

1. Deploy a CycloneToken `ct`

```
ioctl contract deploy bytecode CYCLONETOKEN_BYTECODE ABI_PATH '{"_operator": "OPERATOR_ADDRESS", "_lp": "INITIAL_LP_ADDRESS"}'
```

* **Timelock & GovernorAlpha**

1. Deploy Timelock `tl`

```
ioctl contract deploy bytecode TIMELOCK_BYTECODE TIMELOCK_ABI_PATH '{"admin_": DEPLOY_ADMIN_ADDRESS, "delay_": DELAY_IN_SEC}'
```

&#x20;   2\. Deploy GorvernorAlpha `ga` (e.g., voting duration:3 days)

```
ioctl contract deploy bytecode GORVERNOR_BYTECODE GOVERNOR_ABI_PATH '{"timelock_": TIMELOCK_ADDRESS, "sushi_": CYCTOKEN_ADDRESS, "guardian_": ADMIN_ADDRESS, "votingDuration_": 51840}'
```

&#x20;  3\. Set Timelock's pending admin to GovernorAlpha `ga`

```
 ioctl contract invoke function TIMELOCK_ADDRESS TIMELOCK_ABI_PATH "setPendingAdmin" --with-arguments '{"pendingAdmin_": GOVERNOR_ADDRESS}'
```

&#x20;  4\. Accept Admin from GovernorAlpha `ga` triggered by guardian&#x20;

```
 ioctl contract invoke function GOVERNOR_ADDRESS GOVERNOR_ABI_PATH "__acceptAdmin"
```

* **Aeolus**

1. Add Liquidity for CYC/IOTX on MimoFactory and receive CYC-IOTX LP Token
2. Deploy an Aeolus `as` with `ct` address

```
ioctl contract deploy bytecode AEOLUS_BYTECODE ABI_PATH '{"_cycToken": CYC_TOKEN, "_lpToken" : LP_TOKEN}'
```

&#x20;   3\. Invoke `ct`.addMinter() to set `as` to be minters for CYC token

```
ioctl contract invoke function CYCTOKEN_ADDRESS CYCTOKEN_ABI_PATH "addMinter" --with-arguments '{"_minter": AEOLUS_ADDRESS}'
```

* **CoinCyclone, ERC20Cyclone**

1. Deploy Hasher `hr`

   ```
   ioctl contract deploy bytecode HASHER_BYTECODE
   ```
2. Deploy Verifier `vr`

   ```
   ioctl contract deploy bytecode VERIFIER_BYTECODE
   ```
3. Deploy CoinCyclone `cc`, ERC20Cyclone `ec` linked by Hasher `hr` with `as`, `vr`, `ct`, `mf`and if necessary, XRC20 token address

   ```
   link CoinCyclone_BYTECODE/ERC20Cyclone_BYTECODE with HASHER_ADDRESS (use linker.js)
   ```

   ```
   ioctl contract deploy bytecode CoinCyclone_LINKED_BYTECODE CoinCyclone_ABI_PATH'{"_verifier": VERIFIER_ADDRESS, "_cyctoken": CYCTOKEN_ADDRESS, "_mimoFactory": MIMOFACTORY_ADDRESS, "_aeolus": AEOLUS_ADDRESS, "_initDenomination" : DENOMINATION_AMOUNT, "_denominationRound": DENOMINATION_ROUND, "_merkleTreeHeight" : MERKLETREE_HEIGHT, "_operator": TIMELOCK_ADDRESS}'
   ```

   ```
   ioctl contract deploy bytecode ERC20Cyclone_LINKED_BYTECODE ERC20Cyclone_ABI_PATH '{"_verifier": VERIFIER_ADDRESS, "_cyctoken": CYCTOKEN_ADDRESS, "_mimoFactory": MIMOFACTORY_ADDRESS, "_aeolus": AEOLUS_ADDRESS, "_initDenomination" : DENOMINATION_AMOUNT, "_denominationRound": DENOMINATION_ROUND, "_merkleTreeHeight" : MERKLETREE_HEIGHT, "_operator": TIMELOCK_ADDRESS, "_xrc20Token" : XRC20TOKEN_ADDRESS}'
   ```
4. Invoke `ct.addMinter()` to set `cc` and `ec` to be minters for CYC token

   ```
   ioctl contract invoke function CYCTOKEN_ADDRESS CYCTOKEN_ABI_PATH "addMinter" --with-arguments '{"_minter": CoinCyclone_ADDRESS}'
   ioctl contract invoke function CYCTOKEN_ADDRESS CYCTOKEN_ABI_PATH "addMinter" --with-arguments '{"_minter": ERC20Cyclone_ADDRESS}'  
   ```
5. Invoke `as`.addAddressToWhitelist() to set `cc` and `ec` to be whitelists for Aeolus to invoke `addReward()`&#x20;

   ```
   ioctl contract invoke function AEOLUS_ADDRESS AEOLUS_ABI_PATH "addAddressToWhitelist" --with-arguments '{"addr": CoinCyclone_ADDRESS}'
   ioctl contract invoke function AEOLUS_ADDRESS AEOLUS_ABI_PATH "addAddressToWhitelist" --with-arguments '{"addr": ERC20Cyclone_ADDRESS}'
   ```

### Test contracts

1. node version `nvm use 11.15.0`
2. build zk circuits `npm run build`
3. if you want to use `test` network, just run `npm run test` (default).

   If you want to use `development` network,

   * modify truffle-config.js (uncomment development network)
   * run `ganache-cli i 1337`
   * run `npm run test`

### Interaction with Cyclone contracts \[Anonymity Mining]

1. Requirements
2. `nvm use 11.15.0`
3. `npm install -g npx`
4. Set up .env file
   * `cp .env.example .env`
   * `vi .env` - add your private key, deployed contract address and denomination value
5. Build zk circuits: `npm run build`. Note that if you want to build zk circuits (including verifier.sol, proof/verify-keys) locally, you need to:
   * `npm uninstall websnark`
   * `npm install websnark@"git+https://github.com/tornadocash/websnark.git#2041cfa5fa0b71cd5cca9022a4eeea4afe28c9f7"`
   * `npm run build:local` - It might take more than 10 minutes as it performs the trust-setup locally.
6. Deposit
   * Testnet

     `./client.js deposit IOTX|XRC20 --rpc http://api.testnet.iotex.one:80`
   * Mainnet

     `./client.js deposit IOTX|XRC20 --rpc http://api.iotex.one:80`
7. Withdraw
   * Testnet

     `./client.js withdraw NOTE RECIPIENT_ADDRESS --rpc http://api.testnet.iotex.one:80 --relayer RELAYER_URL`
   * Mainnet

     `./client.js withdraw NOTE RECIPIENT_ADDRESS --rpc http://api.iotex.one:80 --relayer RELAYER_URL`

### Interaction with Aeolus contract \[Liquidity Mining]

1. Add Liquidity for CYC/IOTX on MimoFactory and receive CYC-IOTX LP Token
2. Deposit&#x20;

* Approve CYC-IOTX LP Token

```
ioctl xrc20 approve AEOLUS_ADDRESS AMOUNT -c LPTOKEN_ADDRESS
```

* Deposit CYC-IOTX LP Token

```
ioctl contract invoke function AEOLUS_ADDRESS abi/Aeolus.json "deposit" --with-arguments '{"_amount": AMOUNT}'
```

&#x20;  3\. Withdraw&#x20;

```
ioctl contract invoke function AEOLUS_ADDRESS abi/Aeolus.json "withdraw" --with-arguments '{"_amount": AMOUNT}'
```

### Interaction with GovernorAlpha contract \[Governance]

1. Self-delegate or delegate your CYC token for governance. If you do not delegate your votes, the token will not be considered as voting power.&#x20;

```
ioctl contract invoke function CYCTOKEN_ADDRESS abi/CycloneToken.json "delegate" --with-arguments '{"delegatee": ADDRESS_YOU_WANT_TO_DELEGATE}' -s mainnet -y
```

&#x20;   2\. Propose a new change in cyclone contracts such as updateConfig, changeGovDAO, and updateVerifier. The proposer should have more than 1000 CYC Token. Voting will run for 3 days. -- Use [abi-encoder](https://adibas03.github.io/online-ethereum-abi-encoder-decoder/#/encode) to get encoded argument data.

```
ioctl contract invoke function GOVERNOR_ADDRESS abi/GovernorAlpha.json "propose" --with-arguments '{"targets": [CYCLONE_ADDRESS], "values": [0], "signatures": ["updateConfig(uint256,uint256,uint256,uint256)"], "calldatas": ["..."], "description": "update configs in cyclone contract"}'
```

&#x20;   3\. During the 3 days of voting duration, token holders who self-delegate or delegate can cast votes for a certain proposal.

```
ioctl contract invoke function GOVERNOR_ADDRESS abi/GovernorAlpha.json "castVote" --with-arguments '{"proposalId": 1, "support": true}'
```

&#x20;  4\. After 3 days of voting duration, if the proposal gets more than 4000 CYC votes, the proposer can queue the transaction into Timelock.

```
ioctl contract invoke function GOVERNOR_ADDRESS abi/GovernorAlpha.json "queue" --with-arguments '{"proposalId": 1}'
```

&#x20;  5\. After the timelock delay, the proposer can execute the transaction in timelock.

```
ioctl contract invoke function GOVERNOR_ADDRESS abi/GovernorAlpha.json "execute" --with-arguments '{"proposalId": 1}'
```

###


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cyclone.xyz/korean/development.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
