In the world of cryptocurrencies, stablecoins play a crucial role in providing stability and reliability to transactions. The USDC (USD Coin) stablecoin is one such prominent example, known for its backing by US dollars on a 1:1 basis. This article outlines the process of deploying the USDC stablecoin on the XDC blockchain, detailing the steps followed and the resulting output.
Check out the “Deployment.md” file to know the deployment structure in a better way.
Installation (Prerequisites):
1. NVM Installation:
Begin by installing nvm (Node Version Manager), a tool for managing multiple Node.js versions.
Execute the following command in your terminal:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
2. Node and Yarn Installation:
This project requires specific versions of Node.js and Yarn.
Install Node.js version 16.14.0 and Yarn version 1.22.19 using nvm:
nvm install 16.14.0
nvm use 16.14.0
npm install -g yarn@1.22.19
3. Stablecoin-EVM Installation:
Clone the stablecoin-EVM repository and switch to the appropriate branch.
git clone https://github.com/XinFinOrg/stablecoin-evm
cd stablecoin-evm
git checkout xdcnetwork
After configuring the environment and setting up the prerequisites, the deployment process involves several key steps to ensure the stability and functionality of the stablecoin-EVM project. Below are the detailed deployment commands along with their functionalities:
yarn
yarn compile
yarn hardhat typechain
yarn test
4. Configurations:
Create and configure the .env file with the necessary parameters.
echo "[]" > blacklist.remote.json
cp .env.example .env
vi .env
Sample .env Configuration:
DEPLOYER_PRIVATE_KEY="0x......"
TOKEN_NAME=USDC
TOKEN_SYMBOL=USDC
TOKEN_CURRENCY=USD
TOKEN_DECIMALS=6
PROXY_ADMIN_ADDRESS="0x......"
OWNER_ADDRESS="0x......"
MASTER_MINTER_OWNER_ADDRESS="0x......"
GAS_MULTIPLIER=110
BLACKLIST_FILE_NAME=blacklist.remote.json
Note:
- Ensure PROXY_ADMIN_ADDRESS differs from OWNER_ADDRESS.
- PAUSER_ADDRESS is optional, will be OWNER_ADDRESS if not set
- BLACKLISTER_ADDRESS is optional, will be OWNER_ADDRESS if not set
- LOST_AND_FOUND_ADDRESS is optional, will be OWNER_ADDRESS if not set
5. Deployment on Testnet(XDC Apothem):
# forge script -vv --broadcast --legacy scripts/deploy/deploy-fiat-token.s.sol --rpc-url https://earpc.apothem.network/
yarn deploy:xdc:test
Output:
== Return ==
0: contract FiatTokenV2_2 0xC6386Aa0b5d25b7827ed23C7e66865A0CB87c90e
1: contract MasterMinter 0x8983d06244F6E503a4640e36C4d86dB532729F90
2: contract FiatTokenProxy 0xf16f48Ba54282Be2C9D267a56fDA6Caad3329600
Interaction with FiatToken contract
Roles: The FiatToken has a number of roles (addresses) which control different functionality:
masterMinter (0x8983d06244F6E503a4640e36C4d86dB532729F90)
- adds and removes minters and increases their minting allowance minters - create and destroy tokens.
pauser (0x774fc390A602706811F49d826Ec10Bbf1135c8a0)
- pause the contract, which prevents all transfers, minting, and burning.
blacklister (0x2230091cD557A3211296d7A2E8d85E22064945C8)
- prevent all transfers to or from a particular address, and prevents that address from minting or burning.
owner (0x774fc390A602706811F49d826Ec10Bbf1135c8a0)
- re-assign any of the roles except for admin.
admin (0x486a98b0f5d84d265e2403dfbb6ad1abe52ecb91)
- manage the proxy-level functionalities such as switching the implementation contract.
rescuer (0x2230091cD557A3211296d7A2E8d85E22064945C8)
- transfer any ERC-20 tokens that are locked up in the contract Circle will control the address of all roles.
FiatToken Contract Interaction
Owner
The owner of the FiatToken contract can set the masterMinter role to point to the address of the MasterMinter contract. This enables the MasterMinter contract to call minter management functions on the FiatToken contract:
- configureMinter(minter, allowance) - Enables the minter and sets its minting allowance.
- removeMinter(minter) - Disables the minter and sets its minting allowance to 0.
- isMinter(minter) - Returns true if the minter is enabled, and false otherwise.
minterAllowance(minter) - Returns the minting allowance of the minter.
Owner adds and removes controllers, sets the address of the minterManager, and sets the owner. Re-assign any of the roles except for admin
transferOwnership updates the owner role to a new address.
transferOwnership may only be called by the owner role.
transferOwnership(address newOwner) Interaction with FiatTokenProxy contract
Admin
- Manage the proxy-level functionalities such as switching the implementation contract
- changeAdmin updates the admin role to a new address.
- changeAdmin may only be called by the admin role.
- changeAdmin(address newAdmin) Interaction with FiatTokenProxy contract
configureController
- configureController(controller, minter) - The owner assigns the controller to manage the minter. This allows the controller to call configureMinter, incrementMinterAllowance and removeMinter.
- Note: configureController(controller, 0x00) is forbidden because it has the effect of removing the controller.
- controller - each controller manages exactly one minter. A controller can enable/disable its minter, and modify the minting allowance by calling functions on the MasterMinter contract, and MasterMinter will call the appropriate functions on the minterManager.
- When a controller calls a function on MasterMinter, the MasterMinter will call the appropriate function on the FiatToken contract on its behalf. Both the MasterMinter and the FiatToken do their own access control.
- configureController(address _controller, address _worker) Interaction with MasterMinter contract
- https://apothem.blocksscan.io/tx/0x17d854f2f13f1ef6d5769655c1d08c878246a66073e94196a11555f0c6922318
configureMinter
- configureMinter(allowance) - A controller enables its minter and sets its allowance. The MasterMinter contract will call the minterManager contract on the controller's behalf.
- configureMinter(uint256 _newAllowance) Interaction with MasterMinter contract
- https://apothem.blocksscan.io/tx/0x8e9d6ce4b87af03bb5a5eeb97ce3d421b733b531c7995d7d50163fc2bfd0a8b3
Other Function Summary
- removeController(controller) - The owner disables the controller by setting its minter to 0x00.
- setMinterManager(minterManager) - The owner sets a new contract to the minterManager address. This has no effect on the old minterManager contract. If the new minterManager does not implement the MinterManagementInterface or does not give this instance of the MasterMinter contract permission to call minter management functions then the controller calls to configureMinter, incrementMinterAllowance, and removeMinter will throw.
- incrementMinterAllowance - A controller increments the allowance of an enabled minter (incrementMinterAllowance will throw if the minter is disabled). The MasterMinter contract will call the minterManager contract on the controller's behalf.
- removeMinter - A controller disables a minter. The MasterMinter contract will call the minterManager contract on the controller's behalf.
Minting
A minter mints tokens via the mint method. The minter specifies the amount of tokens to create, and a _to address which will own the newly created tokens. A minter may only mint an amount less than or equal to its minterAllowance. The minterAllowance will decrease by the amount of tokens minted, and the balance of the _to address and totalSupply will each increase by amount.
minter - each minter is managed by one or more controller. The minter cannot perform any actions on the MasterMinter contract. It interacts only with the FiatToken contract.
- Only a minter may call mint.
- Minting fails when the contract is paused.
- Minting fails when the minter or _to address is blacklisted.
- Minting emits a Mint(minter, _to, amount) event and a Transfer(0x00, _to, amount) event.
- mint(address _to, uint256 _amount) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0xac92593cd874e48ae8366048784c57489da4e884d892c5cfbf2ce30a3982b2f4
Transfer
- Transfer function is used to transfer token from one address to another.
- A blacklisted address will be unable to call transfer or transferFrom, and will be unable to receive tokens.
- approve was not allowed for blacklisted addresses in FiatToken versions <2.2 but available in versions 2.2+. See "Blacklisting" section for more details.
- transfer, transferFrom, and approve will fail if the contract has been paused.
- transfer(address to, uint256 value) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0xd851a277d3dd7b7026862b309f524714de4307ac39d166eeed885fb6a2c5cc1b
Approve
- approve was not allowed for blacklisted addresses in FiatToken versions <2.2 but available in versions 2.2+. See "Blacklisting" section for more details.
- approve will fail if the contract has been paused.
- approve(address spender, uint256 value) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0xf146cf6e8c2248314e0a28e0e2b49b7cec63b63396ebdd7dc5c74f85d1834249
transferFrom
- A blacklisted address will be unable to call transferFrom, and will be unable to receive tokens.(approve was not allowed for blacklisted addresses in FiatToken versions <2.2 but available in versions 2.2+.)
- transferFrom will fail if the contract has been paused.
- transferFrom(address from, address to, uint256 value) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0x1c8edfe82d18cee41403c12f5c1a92891c327170656cecebdb62b346a095e121
Burning
A minter burns tokens via the burn method. The minter specifies the amount of tokens to burn, and the minter must have a balance greater than or equal to the amount. Burning tokens is restricted to minter addresses to avoid accidental burning of tokens by end users. A minter with a minterAllowance of 0 is allowed to burn tokens.
A minter can only burn tokens which it owns. When a minter burns tokens, its balance and the totalSupply are reduced by amount.
- Burning tokens will not increase the minterAllowance of the address doing the burning.
- Only a minter may call burn.
- Burning fails when the contract is paused.
- Burning fails when the minter is blacklisted.
- Burning emits a Burn(minter, amount) event, and a Transfer(minter, 0x00, amount) event.
- burn(uint256 _amount) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0x9ee433418b91890558b7b2a0f36b419225f204a0762a7079171dd5a33a921bbc
Blacklisting
Addresses can be blacklisted. A blacklisted address will be unable to transfer tokens, mint, or burn tokens.
In FiatToken versions <2.2, A blacklisted address is unable to call approve, increaseAllowance, decreaseAllowance, or authorize future pull payments using permit. Nor can it be authorized to pull payments from other addresses. This has been changed in v2.2 where a blacklisted address can perform the above functions. But they are still blocked from transferring the assets in any way. and therefore any operations on modifying the allowance of blacklisted addresses are considered meaningless.
blacklister
- prevent all transfers to or from a particular address, and prevents that address from minting or burning.
- updateBlacklister(address _account) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0x4c819ab975ba9d5ea34819ecae43e21acc607866a32f785518ff1a719288bb9b
Adding a blacklisted address
- Circle blacklists an address via the blacklist method. The specified account will be added to the blacklist.
- Only the blacklister role may call blacklist.
- Blacklisting emits a Blacklist(account) event
- blacklist(address _account) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0x470f68ec887dcf135b0a715cad4385e0e14915fdb4f502f8deb4afc2a8d8183b
Removing a blacklisted address
- Circle removes an address from the blacklist via the unblacklist method. The specified account will be removed from the blacklist.
- Only the blacklister role may call unblacklist.
- Unblacklisting emits an UnBlacklist(account) event.
- unBlacklist(address _account) Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0xd463a25cf32bfc8c3d9d1aa3d25fccd9ad9f55ddd3b768f411eef53ce5b3d7cd
Pausing
The entire contract can be paused in case a serious bug is found or there is a serious key compromise. All transfers, minting, burning, and adding minters will be prevented while the contract is paused. Other functionality, such as modifying the blacklist, removing minters, changing roles, and upgrading will remain operational as those methods may be required to fix or mitigate the issue that caused Circle to pause the contract.
Pause
- Circle will pause the contract via the pause method. This method will set the paused flag to true.
- Only the pauser role may call pause.
- Pausing emits a Pause() event. Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0x209102ba166bec1f0ce1f4286e975e33b7d05d9bdac8cb4101ff277d581a1637
Unpause
- Circle will unpause the contract via the unpause method. This method will set the paused flag to false. All functionality will be restored when the contract is unpaused.
- Only the pauser role may call unpause.
- Unpausing emits an Unpause() event. Interaction with FiatTokenV2_2 contract
- https://apothem.blocksscan.io/tx/0x8c0d303e34beabb4548cdf4a9a3ca1ccb75b02645a945c7f30381545f0882872
Rescuer
- updateRescuer updates the rescuer role to a new address.
- updateRescuer may only be called by the owner role.
https://apothem.blocksscan.io/tx/0xe7b3882182f90d8eaf8fb015330d52b8bf9cc75c27785c06620fede53a589f66
rescueERC20(address tokenContract, address to, uint256 amount) Interaction with FiatTokenV2_2 contract
https://apothem.blocksscan.io/tx/0xad1c01da0e44b2ef5a756ecaef6066dc4f84e4de12e7a369a17aa76c1e9d3602
In conclusion, deploying the USDC stablecoin on the XDC blockchain opens up new avenues for stable and reliable transactions within the cryptocurrency ecosystem. With a clear understanding of the deployment process and the interaction dynamics outlined above, users can confidently navigate through the steps required to integrate this stablecoin solution.
Discussion (0)