Deployment

Amplify protocol

Development Environment

  • solidity ^0.5.16

  • nodejs 12+

Installation

yarn

Solc Installation

sudo -H pip3 install solc-select
solc-select install 0.5.16
solc-select use 0.5.16

Compilation

npx saddle compile

Deployment

The bellow instruction uses rinkeby ntework. When deploying to production, follow the same instruction but change to mainnet

Prepare Environment

  1. Ensure your deployment wallet has ETH to pay gas fee.

  2. Create ~/.ethereum/rinkeby file with Ethereum wallet private key as content.

    There will be several variables needed during deployment, we can set them via ENV vars instead of copying them all over, but you can also set them in each.

  3. Assign variables in your terminal (using bash):

    1. ETHSCAN_API_KEY={key} - API key from Etherescan.io

    2. ADMIN_ADDRESS={address} - administrator's address for cTokens and Timelock

    3. OPERATOR_ADDRESS={address} - operator address for GovernorAlpha

    4. AMPT_RECIPIENT={address} - initial AMPT token recipient address

Deploy AMPT token

AMPT

  1. Deploy

    npx saddle deploy AMPT "$AMPT_RECIPIENT" -n rinkeby
  2. Assign variable using the address from the previous deployment command

    AMPT={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$AMPT" AMPT "$AMPT_RECIPIENT" -n rinkeby

Deploy Ampttroller

  1. Update getAmptAddress function Inside Ampttroller.sol insert

    function getAmptAddress() public view returns (address) {
    return /*{AMPT token contract address}*/;
    }
  2. Recompile & deploy

    npx saddle compile && npx saddle deploy Ampttroller -n rinkeby
  3. Assign variable using the address from the previous deployment command

    AMPTTROLLER={address}
  4. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$AMPTTROLLER" Ampttroller -n rinkeby

Transfer some AMPT to Ampttroller

Transfer AMPT which will be distributed as a reward to Ampttroller address.

Deploy FaucetToken tokens

WTBC

  1. Deploy

    npx saddle deploy FaucetToken 100000000000000000000000000 "WBTC" 18 "WBTC" -n rinkeby
  2. Assign variable using the address from the previous deployment command

    WBTC={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$WBTC" FaucetToken 100000000000000000000000000 "WBTC" 18 "WBTC" -n rinkeby

USDT

  1. Deploy

    npx saddle deploy FaucetToken 100000000000000000000000000 "USDT" 18 "USDT" -n rinkeby
  2. Assign variable using the address from the previous deployment command

    USDT={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$USDT" FaucetToken 100000000000000000000000000 "USDT" 18 "USDT" -n rinkeby

USDC

  1. Deploy

    npx saddle deploy FaucetToken 100000000000000000000000000 "USDC" 18 "USDC" -n rinkeby
  2. Assign variable using the address from the previous deployment command

    USDC={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$USDC" FaucetToken 100000000000000000000000000 "USDC" 18 "USDC" -n rinkeby

DAI

  1. Deploy

    npx saddle deploy FaucetToken 100000000000000000000000000 "DAI" 18 "DAI" -n rinkeby
  2. Assign variable using the address from the previous deployment command

    DAI={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$DAI" FaucetToken 100000000000000000000000000 "DAI" 18 "DAI" -n rinkeby

Deploy InterestRate

InterestRate contract is the implementation of interest rate calculation model. For example: the base interest rate is 5%, and the multipler interest rate is 12%.

  1. Deploy

    npx saddle deploy WhitePaperInterestRateModel 50000000000000000 120000000000000000 -n rinkeby
  2. Assign variable using the address from the previous deployment command

    INTEREST_RATE={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$INTEREST_RATE" WhitePaperInterestRateModel 50000000000000000 120000000000000000 -n rinkeby

Deploy cTokens

Ctoken is the proof of deposit.

cETH

  1. Deploy

    npx saddle deploy CEther "$AMPTTROLLER" "$INTEREST_RATE" "2000000000000000000" "AMPLIFY cETH" "cETH" "8" "$ADMIN_ADDRESS" -n rinkeby
  2. Add environment variable

    CETH={address}

cWBTC

Deploy

npx saddle -n rinkeby script token:deploy '{
"underlying": "'"$WBTC"'",
"ampttroller": "'"$AMPTTROLLER"'",
"interestRateModel": "'"$INTEREST_RATE"'",
"initialExchangeRateMantissa": "2.0e18",
"name": "AMPLIFY WBTC",
"symbol": "cWBTC",
"decimals": "8",
"admin": "'"$ADMIN_ADDRESS"'"
}'

cUSDT

Deploy

npx saddle -n rinkeby script token:deploy '{
"underlying": "'"$USDT"'",
"ampttroller": "'"$AMPTTROLLER"'",
"interestRateModel": "'"$INTEREST_RATE"'",
"initialExchangeRateMantissa": "2.0e18",
"name": "AMPLIFY USDT",
"symbol": "cUSDT",
"decimals": "8",
"admin": "'"$ADMIN_ADDRESS"'"
}'

cUSDC

Deploy

npx saddle -n rinkeby script token:deploy '{
"underlying": "'"$USDC"'",
"ampttroller": "'"$AMPTTROLLER"'",
"interestRateModel": "'"$INTEREST_RATE"'",
"initialExchangeRateMantissa": "2.0e18",
"name": "AMPLIFY USDC",
"symbol": "cUSDC",
"decimals": "8",
"admin": "'"$ADMIN_ADDRESS"'"
}'

cDAI

Deploy

npx saddle -n rinkeby script token:deploy '{
"underlying": "'"$DAI"'",
"ampttroller": "'"$AMPTTROLLER"'",
"interestRateModel": "'"$INTEREST_RATE"'",
"initialExchangeRateMantissa": "2.0e18",
"name": "AMPLIFY DAI",
"symbol": "cDAI",
"decimals": "8",
"admin": "'"$ADMIN_ADDRESS"'"
}'

cAMPT

Deploy

npx saddle -n rinkeby script token:deploy '{
"underlying": "'"$AMPT"'",
"ampttroller": "'"$AMPTTROLLER"'",
"interestRateModel": "'"$INTEREST_RATE"'",
"initialExchangeRateMantissa": "2.0e18",
"name": "AMPLIFY AMPT",
"symbol": "cAMPT",
"decimals": "8",
"admin": "'"$ADMIN_ADDRESS"'"
}'

Deploy PriceOracle

We use the Oracle anchored by uniswap in mainnet, first obtain the token price from Coinbase or other exchanges, submit it to the smart contract, and use the price of uniswap as the verification. See in the project: amplify-open-oracle

Deploy SimplePriceOracle

Simpleprice Oracle can be released for testing. It can be launched in the early stage in order to avoid Oracle attack.

  1. Deploy

    npx saddle deploy SimplePriceOracle -n rinkeby
  2. Add environmemnt variable

    SIMPLE_PRICE_ORACLE={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$SIMPLE_PRICE_ORACLE" SimplePriceOracle -n rinkeby

Set price for each cToken

If using SimplePriceOracle, each cToken listed must has it's corresponding token price set via SimplePriceOracle contract.

Call setUnderlyingPrice method using Etherscan.io for each cToken:

Parameter

Type

Comments

Example

cToken

address

cToken contract address

0xd3569eC8AF83Bed92b369b83B90Ff17e27d1cdC2

underlyingPriceMantissa

uint

Price for cToken corresponding token, in USD, the value need to be multiplied with 1e18, for example, 1 USD should be 1000000000000000000

1000000000000000000

Configure Oracle address and markets.

These are Ampttroller contract methods.

  1. _setPriceOracle - set Price Oracle address

  2. _setMaxAssets - set maxAssets with value 20

  3. _supportMarket - set supported markets to add cTokens to the token list.

    Call this method for each cToken.

  4. _addAmptMarkets - add markets (cTokens) that reward with Ampt to the token list.

  5. _setCollateralFactor - set collateral factor for each market (cToken). Call this method for each cToken.

  6. _setAmptRate - set the amount of distributed AMPT Tokens for one block the value needs to be multiplied with 1e18

  7. refreshAmptSpeeds - trigger the update for tokens speeds

Deploy AmplifyLens

AmplifyLens is used for data calculation and query

  1. Deploy

    npx saddle deploy AmplifyLens -n rinkeby
  2. Set variable

    AMPLIFY_LENS={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$AMPLIFY_LENS" AmplifyLens -n rinkeby

Deploy Maximillion

  1. Deploy

    npx saddle deploy Maximillion "$CETH" -n rinkeby
  2. Add variable

    MAXMILLION={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$MAXMILLION" Maximillion "$CETH" -n rinkeby

Deploy Timelock Contract

Timelock is the contract for decentralized governance

  1. Deploy

    npx saddle deploy Timelock "$ADMIN_ADDRESS" 600 -n rinkeby
  2. Set variable

    TIMELOCK={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$TIMELOCK" Timelock "$ADMIN_ADDRESS" 600 -n rinkeby

Deploy GvernorAlpha Contract

GvernorAlpha is the contract of vote.

  1. Deploy

    npx saddle deploy GovernorAlpha "$TIMELOCK" "$AMPT" "$OPERATOR_ADDRESS" -n rinkeby
  2. Set variable

    GOVERNOR_ALPHA={address}
  3. Verify on Etherscan.io

    npx saddle verify "$ETHSCAN_API_KEY" "$GOVERNOR_ALPHA" GovernorAlpha "$TIMELOCK" "$AMPT" "$OPERATOR_ADDRESS" -n rinkeby

Set Timelock as the administrator of each governed contract

  • This step is to set TimeLock contract as administrator for all contracts deployed

  • At the early stage, setting admin when deploying contracts with a privately > owned account, will be easier for debugging and adjusting

  • Change admin to TimeLock at the mature stage to make everything more decentralized

  1. _setPendingAdmin - as an administrator, call this method in each governed contract to set the timelock contract as pendingAdmin.

  2. By calling queueTransaction and executeTransaction methods of timelock, let timelock contract invoke _acceptAdmin method of governed contracts so that a new administrator of governed contracts can be set.

Set GovernorAlpha as the administrator of Timelock

Same as above step, use private address as admin at early stage.

  1. Use queueTransaction and executetransaction methods of the Timelock contract to invoke TimeLock contract's setPendingAdmin method.

  2. Invoke _acceptAdmin method of GovernorAlpha contract so that it will be an admin for TimeLock contract.