Skip to content

Commit

Permalink
Autoformat Markdown files
Browse files Browse the repository at this point in the history
  • Loading branch information
petejkim committed May 12, 2020
1 parent ac48f00 commit 9343b15
Show file tree
Hide file tree
Showing 10 changed files with 430 additions and 256 deletions.
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"tabWidth": 4,
"explicitTypes": "always"
}
},
{
"files": "*.md",
"options": {
"proseWrap": "always"
}
}
]
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
"[json]": {
"editor.formatOnSave": true
},
"[markdown]": {
"editor.formatOnSave": true
},
"[solidity]": {
"editor.tabSize": 4,
"editor.formatOnSave": true
Expand Down
75 changes: 45 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,74 @@
# centre-tokens

Fiat tokens on the [CENTRE](https://centre.io) network.

# Setup
Tests need node v8.0.0 or higher, as they depend on async/await functionality. Interacting with eth is very async-y so await makes it much easier to write tests.
Depends on truffle and testrpc for testing.

install truffle:
```npm install -g truffle```
Tests need node v8.0.0 or higher, as they depend on async/await functionality.
Interacting with eth is very async-y so await makes it much easier to write
tests. Depends on truffle and testrpc for testing.

install truffle: `npm install -g truffle`

install ganache-cli:
```npm install -g ganache-cli```
install ganache-cli: `npm install -g ganache-cli`

install project npm dependencies:
```npm install```
install project npm dependencies: `npm install`

# Testing
All tests are run with:
```npm run truffle-test```

or run a specific file of tests with:
```npm run truffle-test -- [file]```
All tests are run with: `npm run truffle-test`

to generate test coverage on all tests run:
```npm test```
or run a specific file of tests with: `npm run truffle-test -- [file]`

to generate test coverage on all tests run: `npm test`

# Contracts
The implementation uses 2 separate contracts - a proxy contract (`FiatTokenProxy.sol`)and an implementation contract(`FiatToken.sol`).
This allows upgrading the contract, as a new implementation contact can be deployed and the Proxy updated to point to it.

The implementation uses 2 separate contracts - a proxy contract
(`FiatTokenProxy.sol`)and an implementation contract(`FiatToken.sol`). This
allows upgrading the contract, as a new implementation contact can be deployed
and the Proxy updated to point to it.

## FiatToken
The FiatToken offers a number of capabilities, which briefly are described below. There are more
[detailed design docs](./doc/tokendesign.md) in the `doc` folder.

The FiatToken offers a number of capabilities, which briefly are described
below. There are more [detailed design docs](./doc/tokendesign.md) in the `doc`
folder.

### ERC20 compatible

The FiatToken implements the ERC20 interface.

### Pausable
The entire contract can be frozen, in case a serious bug is found or there is a serious key compromise. No transfers can take place while the contract is paused.
Access to the pause functionality is controlled by the `pauser` address.

The entire contract can be frozen, in case a serious bug is found or there is a
serious key compromise. No transfers can take place while the contract is
paused. Access to the pause functionality is controlled by the `pauser` address.

### Upgradable
A new implementation contract can be deployed, and the proxy contract will forward calls to the new contract.
Access to the upgrade functionality is guarded by a `proxyOwner` address. Only the `proxyOwner` address can change the `proxyOwner` address.

A new implementation contract can be deployed, and the proxy contract will
forward calls to the new contract. Access to the upgrade functionality is
guarded by a `proxyOwner` address. Only the `proxyOwner` address can change the
`proxyOwner` address.

### Blacklist
The contract can blacklist certain addresses which will prevent those addresses from transferring or receiving tokens.
Access to the blacklist functionality is controlled by the `blacklister` address.

The contract can blacklist certain addresses which will prevent those addresses
from transferring or receiving tokens. Access to the blacklist functionality is
controlled by the `blacklister` address.

### Minting/Burning
Tokens can be minted or burned on demand. The contract supports having multiple minters simultaneously. There is a
`masterMinter` address which controls the list of minters and how much each is allowed to mint. The mint allowance is
similar to the ERC20 allowance - as each minter mints new tokens their allowance decreases. When it gets too low they will
need the allowance increased again by the `masterMinter`.

Tokens can be minted or burned on demand. The contract supports having multiple
minters simultaneously. There is a `masterMinter` address which controls the
list of minters and how much each is allowed to mint. The mint allowance is
similar to the ERC20 allowance - as each minter mints new tokens their allowance
decreases. When it gets too low they will need the allowance increased again by
the `masterMinter`.

### Ownable
The contract has an Owner, who can change the `owner`, `pauser`, `blacklister`, or `masterMinter` addresses. The `owner` can not change
the `proxyOwner` address.

The contract has an Owner, who can change the `owner`, `pauser`, `blacklister`,
or `masterMinter` addresses. The `owner` can not change the `proxyOwner`
address.
79 changes: 49 additions & 30 deletions doc/deployment.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# Initial Deployment

This is the process for deploying a new proxy and implementation (as opposed to upgrading an existing proxy).

Since the proxy uses `delegatecall` to forward calls to the implementation initialization of the contracts becomes a little
tricky because we can not initialize fields in the implementation contract via the constructor. Instead there is an initialize
method in the implementation contract, which is publicly available, but can only be called once per proxy.
This is the process for deploying a new proxy and implementation (as opposed to
upgrading an existing proxy).

Since the proxy uses `delegatecall` to forward calls to the implementation
initialization of the contracts becomes a little tricky because we can not
initialize fields in the implementation contract via the constructor. Instead
there is an initialize method in the implementation contract, which is publicly
available, but can only be called once per proxy.

## Deploying the implementation contract

1. Deploy [FiatTokenV1](../contracts/FiatTokenV1.sol)
2. Initialize the fields in FiatToken via the `initialize` method. The values are not important, but this will stop anyone
else initializing the roles and trying to use it as a token or pass it off as a real CENTRE token.
2. Initialize the fields in FiatToken via the `initialize` method. The values
are not important, but this will stop anyone else initializing the roles and
trying to use it as a token or pass it off as a real CENTRE token.
```
initialize(
"",
Expand All @@ -23,38 +27,48 @@ else initializing the roles and trying to use it as a token or pass it off as a
throwawayAddress
)
```
3. Verify that all fields in the FiatToken have been initialized correctly and have the expected values.
See [README.validate.md](../validate/validate.js).
3. Verify that all fields in the FiatToken have been initialized correctly and
have the expected values. See [README.validate.md](../validate/validate.js).

## Deploying a Proxy:

1. Obtain addresses for the various contract roles from CENTRE ops. The keys for these addresses will be stored offline.
The address needed are:
1. Obtain addresses for the various contract roles from CENTRE ops. The keys for
these addresses will be stored offline. The address needed are:

```
admin
masterMinter
pauser
blacklister
owner
```
For details on what these roles can do, see the [Token Design Doc](tokendesign.md)

2. Deploy [FiatTokenProxy](../contracts/FiatTokenProxy.sol), passing the address of the deployed implementation contract
to the constructor, which will initialize the `_implementation` field.
For details on what these roles can do, see the
[Token Design Doc](tokendesign.md)

2. Deploy [FiatTokenProxy](../contracts/FiatTokenProxy.sol), passing the address
of the deployed implementation contract to the constructor, which will
initialize the `_implementation` field.

3. The `admin` of the proxy contract defaults to msg.sender. You must either
change the `admin` now, or send the remaining transactions from a different
address. The `admin` can only see methods in the Proxy, any method calls from
`admin` will not be forwarded to the implementation contract. The `admin`
address can be changed by calling `changeAdmin`. Note that change admin must
be called by the current admin.

3. The `admin` of the proxy contract defaults to msg.sender. You must either change the `admin` now, or send the remaining
transactions from a different address. The `admin` can only see methods in the Proxy, any method calls from `admin` will not
be forwarded to the implementation contract.
The `admin` address can be changed by calling `changeAdmin`. Note that change admin must be called by the current admin.
```
changeAdmin(adminAddress)
```

4. Initialize the proxy, via the `initialize` method. This call will get forwarded to the implementation contract, but since
it is via `delegatecall` it will run in the context of the Proxy contract, so the fields it is initializing will be stored
it the storage of the Proxy. The values passed here are important, especially for the roles that will control the contract.
These addresses should be obtained from CENTRE ops, and the keys will be stored offline.
4. Initialize the proxy, via the `initialize` method. This call will get
forwarded to the implementation contract, but since it is via `delegatecall`
it will run in the context of the Proxy contract, so the fields it is
initializing will be stored it the storage of the Proxy. The values passed
here are important, especially for the roles that will control the contract.
These addresses should be obtained from CENTRE ops, and the keys will be
stored offline.

```
initialize(
Expand All @@ -69,20 +83,25 @@ These addresses should be obtained from CENTRE ops, and the keys will be stored
)
```

5. Verify the fields have been properly initialized. Verification should be performed independently by multiple people to make
sure that the contract has been deployed correctly. The following fields should be verified:
5. Verify the fields have been properly initialized. Verification should be
performed independently by multiple people to make sure that the contract has
been deployed correctly. The following fields should be verified:

- name, symbol, and currency are as expected
- `decimals` is 6
- `masterMinter` is the expected address
- `pauser` is the expected address
- `blacklister` is the expected address
- `owner` is the expected address
- `admin` is the expected address. Note that `admin` is not callable by anyone other than the admin, so this can be verified
by calling `eth.getStorageAt(proxyAddress, 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b)`
- `_implementation` is the address of the implementation contract. Note that `implementation` is not callable by
anyone other than the admin, so this can be verified by calling
`eth.getStorageAt(proxyAddress, 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3)`
- `admin` is the expected address. Note that `admin` is not callable by
anyone other than the admin, so this can be verified by calling
`eth.getStorageAt(proxyAddress, 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b)`
- `_implementation` is the address of the implementation contract. Note that
`implementation` is not callable by anyone other than the admin, so this
can be verified by calling
`eth.getStorageAt(proxyAddress, 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3)`
- `totalSupply` is 0
- `initialized` is `true`

6. If all verification is successful, the contract is deployed and ready to go. If any verification steps failed, restart the process.
6. If all verification is successful, the contract is deployed and ready to go.
If any verification steps failed, restart the process.
Loading

0 comments on commit 9343b15

Please sign in to comment.