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 cannot
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.
-
Deploy FiatTokenV2_2
-
Initialize the fields in FiatTokenV2_2 via the
initialize*methods. 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 Circle token.initialize( "", "", "", 0, THROWAWAY_ADDRESS, THROWAWAY_ADDRESS, THROWAWAY_ADDRESS, THROWAWAY_ADDRESS ); initializeV2(""); initializeV2_1(THROWAWAY_ADDRESS); initializeV2_2([], "");
-
Verify that all fields in the FiatToken have been initialized correctly and have the expected values. See README.validate.md.
-
Obtain addresses for the following contract roles. Ensure that the keys for these addresses are securely stored.
admin masterMinter pauser blacklister ownerFor details on what these roles can do, see the Token Design Doc
-
Deploy FiatTokenProxy, passing the address of the deployed implementation contract to the constructor, which will initialize the
_implementationfield. -
The
adminof the proxy contract defaults tomsg.sender. You must either change theadminnow, or send the remaining transactions from a different address. Theadmincan only see methods in the Proxy, any method calls fromadminwill not be forwarded to the implementation contract. Theadminaddress can be changed by callingchangeAdmin. Note that change admin must be called by the current admin.changeAdmin(adminAddress) -
Initialize the proxy via the
initialize*methods. This call will get forwarded to the implementation contract, but since it is viadelegatecallit will run in the context of the Proxy contract, so the fields it is initializing will be stored in the storage of the Proxy. The values passed here are important, especially for the roles that will control the contract.initialize( tokenName, tokenSymbol, tokenCurrency, tokenDecimals, masterMinterAddress, pauserAddress, blacklisterAddress, ownerAddress ); initializeV2(newTokenName); initializeV2_1(lostAndFoundAddress); initializeV2_2(accountsToBlacklist, newTokenSymbol);
-
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:
adminis the expected addressimplementationis the address of the implementation contractname,symbol,currencyanddecimalsare as expectedversionis 2owner,masterMinter,pauser,blacklisterare the expected addressestotalSupplyis 0initializedistrue
-
If all verification is successful, the contract is deployed and ready to go. If any verification steps failed, restart the process.