@cartesi/token
Version:
Cartesi ERC-20 Token - CTSI
87 lines (50 loc) • 8.2 kB
Markdown
> :warning: The Cartesi team keeps working internally on the next version of this repository, following its regular development roadmap. Whenever there's a new version ready or important fix, these are published to the public source tree as new releases.
# Token
Cartesi Token is an ERC20, with the following attributes:
- NAME = "CartesiToken";
- SYMBOL = "CTSI";
- DECIMALS = 18;
- INITIAL_SUPPLY = 1000000000 \* (10 \*\* 18) (1 Billion)
The code imports two [Open Zeppelin](https://github.com/OpenZeppelin/) libraries:
[ERC20Detailed v2.5](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20Detailed.sol)
and
[ERC20Mintable v2.5](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20Mintable.sol)
The ERC20Mintable code implements the basic ERC20 standard, following the same definitions of the Open Zeppeling [ERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20.sol) code - including [Safe Math](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/math/SafeMath.sol), for sound mathematical operations. Being a mintable token means that the total supply of CTSIs can increase - as opposed to the capped version of ERC20. This minting behavior is implemented using the [MinterRole](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/access/roles/MinterRole.sol) library, also provided by OpenZeppelin. The minter is defined, initially, as the deployer of the token contract - and it has the power to create new tokens, add a new minter or renounce it's privileges.
The ability to create new Cartesi Tokens will be paramount to the network, it is a relevant part of the incentive layer/macroeconomics planned. The minting of new tokens will be entirely managed, in a decentralized way, by the macroeconomics smart contracts. In the beggining, while these smart contracts are not yet available, the Cartesi Token contract will have its minting blocked - by an override in its `mint function`. The amount of time that the minting privilege will be blocked for can be extended by calling the `extendMintLockTime` function - which will emit an `mint locktime extended` event (only the minter can call this function).
The decentralized minting process will be implemented and audited before the mintng locktime mechanism is released.
# Vesting
The Cartesi vesting will use the design available in the [TokenTimelock v2.5](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/TokenTimelock.sol) contract, also provided by OpenZeppelin. This contract implements a simple token timelock, in which a certain amount of token is transferred to a deployed version of this contract and becomes available to a beneficiary after an amount of time - both of which are defined in the deployment. This version of vesting differs from the [TokenVesting v2.5](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/drafts/TokenVesting.sol) in the way tokens are released. The TokenVesting contract offers a continuous and linear vesting procedure which was not a desired feature. In Cartesi we opted for a vesting design in which the tokens are vested following a step function - the total amount of tokens will be divided into a number of time periods and will be paid in full as these time periods expire. For instance, with vesting duration of one year, with a time period of 6 months, half the tokens would be vested at the same time after the first 6 months and then the other half when the 12 months finish. As opposed to having a tiny amount of tokens being released linearly every second.
Part of Cartesi's tokens (CTSI) will be reserved for the so-called mine, which defines a decentralized incentive structure that pays workers for performing certain tasks on Cartesi network. The specifics of the mine contract are still being defined, so we created a special TokenTimelock version for it. It is very similar to the timelock mechanism defined above, differing in the sense that this version allows for a change in the beneficiary address - only callable by the owner. The idea is that the tokens will be locked from the beggining but the real beneficiary , the decentralized mine contract, will be set when its ready.
We chose [OpenZeppelin v2.5](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v2.5.0) for both the token and vesting because it is the last stable release (v3 is still beta) and it includes specific purpose contracts - like MinterRole, which will be substituted by more general purpose ones (i.e AccessControl) in the next version release.
# Faucet
For test purposes we created a SimpleFaucet contract that transfers 100,000 CTSI to any address, once every 4 weeks. This faucet is deployed to all supported testnets.
# Bridges
We deployed bridges of the Cartesi Token to some L2 networks:
## Polygon Mainnet
We manually requested the creation of a bridged token following the [Mapping Request](https://docs.polygon.technology/docs/develop/ethereum-polygon/submit-mapping-request) procedure documented in the Polygon Documentation website.
The token was deployed to [0x2727Ab1c2D22170ABc9b595177B2D5C6E1Ab7B7B](https://polygonscan.com/address/0x2727Ab1c2D22170ABc9b595177B2D5C6E1Ab7B7B)
## Polygon Mumbai
We manually requested the creation of a bridged token following the [Mapping Request](https://docs.polygon.technology/docs/develop/ethereum-polygon/submit-mapping-request) procedure documented in the Polygon Documentation website.
The token was deployed to [0x8B3ae9F9E61Ed278c17d45517fEFb52191ab2683](https://mumbai.polygonscan.com/address/0x8B3ae9F9E61Ed278c17d45517fEFb52191ab2683)
## Optimism Goerli
The Optimism documentation provides instructions on how to [deploy a token](https://community.optimism.io/docs/guides/token-dev/#deploying-your-token). As of today, it's outdated because it refers to the Optimism Kovan network, which will be deprecated in the near future.
However the procedure still partially applies to the Optimism Goerli network, which is already running, but doesn't have an Etherscan service available yet.
For that reason we used an Ethereum command line tool to communicate with the [L2StandardTokenFactory](https://blockscout.com/optimism/goerli/address/0x4200000000000000000000000000000000000012/coin-balances#address-tabs) smart contract.
First we installed [eth-cli](https://github.com/protofire/eth-cli).
Then we imported the `L2StandardTokenFactory` ABI by creating a json file extracted from the [Optimism GitHub project](https://github.com/ethereum-optimism/optimism/tree/develop/packages/contracts) and executing the following command:
```shell
eth abi:add L2StandardTokenFactory ./L2StandardTokenFactory.json
```
Then we sent a transaction to the `createStandardL2Token` of the `L2StandardTokenFactory` contract, by specifying the command below:
```shell
eth contract:send L2StandardTokenFactory@0x4200000000000000000000000000000000000012 'createStandardL2Token("0x9d2133302B0beB040d2E86D1fbC78Da1Dea9Fa3e","Cartesi","CTSI")' --network=https://goerli.optimism.io --pk=<PRIVATE_KEY_REDACTED>
```
The transaction was [executed](https://blockscout.com/optimism/goerli/tx/0x5927171af1763d679cc6df1216e20b0a983024c26d3c7aa8f1932489931e9f14).
To get the address of the bridged token we queried the events by sending the following command, and searching for the Cartesi Token goerli address:
```shell
eth event:get --network=https://goerli.optimism.io L2StandardTokenFactory@0x4200000000000000000000000000000000000012 StandardL2TokenCreated
```
The briged token was deployed to [0x3bB4445D30AC020a84c1b5A8A2C6248ebC9779D0](https://blockscout.com/optimism/goerli/address/0x3bB4445D30AC020a84c1b5A8A2C6248ebC9779D0)
## Arbitrum Goerli
We manually deployed the bridged token by using the official UI for [Arbitrum Bridge](https://bridge.arbitrum.io/).
The token was deployed to [0x0905a95fa1ce6A11bf399c8958fd782BbeCe8a4D](https://testnet.arbiscan.io/address/0x0905a95fa1ce6a11bf399c8958fd782bbece8a4d)