An ERC20 Token is a set of rules that define how a cryptocurrency can be created, held and traded between two addresses on a blockchain. The ERC20 standard is specifically for the Ethereum blockchain.
The original contract for this: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol
I had already been usign Openzeppelin's contracts to inherit from and implement my own smart contracts using Solidity. It worked for most of the projects but then came a question: How do the experts at openzeppelin structure their contracts? How do they think about building these system essentially?
In this implementation, I have made use of RareSkill's Solidity style guide: https://rareskills.io/post/solidity-style-guide
I had been writing smart contracts but never thought much about writing code cleanly, I am not the most proud of my code but with this project, I've been able to better my understanding of the ERC20 token standard and the code style conventions of solidity.
The following functionalities are included in this project:
- Contract deployment with args: name, symbol.
- Mint New Tokens.
- Burn Tokens.
- Transfer Tokens.
- Approve Token Spending.
- Read functions: balanceOf, name, symbol, decimals, totalSupply, allowance.
- Clone the repo:
git clone https://github.com/vjbhandari61/erc20-token-implementation.git
- Install the node_modules:
npm install
- Run the tests:
npx hardhat test
- Update the hardhat config for your desired blockchain:
hardhat.config.ts
- Build the contract:
npx hardhat build
- Deploy contract:
npx hardhat run scripts/deploy.ts --network {YOUR_DESIRED_NETWORK}
- Each ERC20 contract must have a name, symbol and totalSupply.
- Every mint must increase the balance of beneficiary and the totalSupply by the mint amount.
- Every burn must decrease the balance of beneficiary and the totalSupply by the burn amount.
- Each transfer between two valid addresses must decrease the amount from the balance of sender and increase the amount in the balance of receiver.
- Each spender should have an allowance that is more than or equal to the amount to be spent.
These check if the token contract is set up correctly when created:
- Checks that a "TokenCreated" event is emitted when contract deploys
- Verifies token name is correctly set to "MockERC20"
- Verifies token symbol is correctly set to "mERC20"
- Confirms initial total supply is 0 tokens
- Confirms decimals are set to 18 (standard for most tokens)
These test the mint function that creates new tokens:
- Creates 20 tokens for address1 and verifies address1 receives them
- Confirms total supply increases by 20 tokens after minting
- Ensures minting fails if sent to zero address (invalid address)
- Verifies minting only increases balance of the target address, not other addresses
These test the burn function that destroys tokens:
- Burns 10 tokens from address1 and verifies balance becomes 0
- Prevents address2 from burning tokens belonging to address1
- Burns 5 tokens from address1 and verifies balance reduces from 10 to 5
- Confirms total supply reduces by 5 tokens after burning
- Ensures burning fails if sent from zero address
These test token approvals (allowing others to spend your tokens):
- Allows address1 to approve address2 to spend 2 tokens on their behalf
These test direct token transfers:
- Transfers 10 tokens from address1 to address2 successfully
- Prevents transfers if sender doesn't have enough tokens
- Prevents transfers to zero address (invalid address)