TS-20200211

Token Standards Intermediate February 11, 2020

Back to All Tasks

Problem Statement

Create a custom ERC-20 token named 'EduCoin' that includes the following functionalities:

1. The contract should have a mint function accessible only by the contract owner to issue tokens.
2. Implement a burn functionality that allows users to destroy their own tokens, with a maximum of 5% of their total balance at any one time.
3. Ensure that the token has a total supply of 10 million EduCoins and each token should be divisible up to 6 decimal places.
4. The contract should include an event that is emitted whenever tokens are burned.

Concepts

  • ERC-20
  • Smart Contracts
  • Solidity

Constraints

  • The mint function must check for the caller's role as the owner before issuing new tokens.
  • The burn functionality must enforce the 5% limit on the amount of tokens a user can burn at once.
  • Ensure proper error handling and revert transactions when necessary.

Security Notes

  • Always validate inputs to prevent unexpected behavior or attacks.
  • Consider using OpenZeppelin's SafeMath library for arithmetic operations to avoid overflows and underflows.
  • Ensure that minting and burning functionalities are secured against unauthorized access.

Solutions

C Solution

pragma solidity ^0.8.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol";

contract EduCoin is ERC20, Ownable {
    using SafeMath for uint256;

    // Constructor to initialize the token with a total supply of 10 million EduCoins and 6 decimal places
    constructor() ERC20("EduCoin", "EDU") {
        _mint(msg.sender, 10 * (10 ** 7) * (10 ** uint256(decimals())));
    }

    // Mint function accessible only by the contract owner to issue tokens
    function mint(address account, uint256 amount) public onlyOwner {
        require(account != address(0), "EduCoin: mint to the zero address");
        _mint(account, amount);
    }

    // Burn functionality that allows users to destroy their own tokens with a maximum of 5% at any one time
    function burn(uint256 amount) public {
        require(amount > 0, "EduCoin: burn amount must be greater than zero");
        uint256 maxBurnAmount = balanceOf(msg.sender).mul(5).div(100);
        require(amount <= maxBurnAmount, "EduCoin: burn amount exceeds the allowed limit");

        _burn(msg.sender, amount);
        emit Burned(msg.sender, amount);
    }

    // Event emitted whenever tokens are burned
    event Burned(address indexed burner, uint256 value);
}

This Solidity smart contract implements a custom ERC-20 token named EduCoin. It inherits from the ERC20 and Ownable contracts provided by OpenZeppelin, which offer standard functionalities for tokens and ownership management respectively. The SafeMath library is used to handle arithmetic operations safely, preventing overflows and underflows.
The constructor initializes the total supply of EduCoin to 10 million with 6 decimal places using the _mint function. Only the contract owner can call this function to mint new tokens via the public mint method, ensuring that token issuance is controlled.
The burn functionality allows any user to destroy their own tokens but enforces a restriction that they can only burn up to 5% of their total balance at one time. This is achieved by calculating the maximum allowable burn amount and checking if the requested burn amount exceeds this limit before proceeding with the _burn function call. An event named Burned is emitted each time tokens are burned, providing transparency and allowing for tracking on blockchain explorers.
Security practices include validating inputs to prevent unexpected behavior or attacks, using OpenZeppelin's well-audited libraries for arithmetic operations, and securing minting and burning functionalities against unauthorized access through the use of the onlyOwner modifier.