0xedB0...3484

Turn your stories into NFTs

0 Following     0 Follower

Cherry token contract: the code

Here we'll cover the code of the Cherry token smart contract. That's what's interesting with smart contracts: they are deployed on a blockchain. Most of them cannot be updated (this one cannot). In blockchain speech, we say they are immutable.

And if their author published the source code of the smart contract (that was validated by the blockchain scanner site, so the author cannot cheat by submitting a tampered source code), then you can read it line by line.

Why that? Well, it all comes down to trust.

If you read the lines of the smart contract, which are quite easy to understand if you have some basic understanding of programming, then you can figure out how it works. And if you know how it works, then you can trust it.

This is the beauty of the blockchain, and the reason it's a game changer: a contract that will execute no matter what. The author cannot change it any more. This is set in stone.

Unstoppable code, as they say.

The code: initial standard contracts

You can see the full code on FTMscan: the Fantom block explorer.

The first parts are functions that are very common and were mostly written by the Open Zeppelin team, a bunch of blockchain developers that publish well written code for any other person to build their projects upon.

It starts with the Ownable contract. It is just here to attach an owner to the main smart contract.

Then there is the classic ERC-20 token contract. It's the common Open Zeppelin implementation of the ERC-20 standard for token contracts: you can own, transfer, approve, transfert on behalf of someone who approved you, ... etc. Nothing very fancy here, appart that it has these two options:

  1. tokens are burnable: it means that the owner of a cherry token can destroy it.
  2. there is a mint() function: it means that someone can mint() new cherries out of thin air. Hey, that's a bit suspicious don't you think?

The code: the real stuff

Now that Owner and ERC20 have been declared, we have all the tools to create our Cherry token smart contract.

Here is the important code:

// Cherry.sol

// Minimal interface for Minter contract
interface IMinter {
  // returns the token address that the minter wants to mint
  function token() external view returns (address);
}


contract CherryToken is ERC20, Ownable {

  // ==== Constants ====
  uint    constant PERIOD    = 6 hours;
  uint    constant minSupply = 10000 ether;

  // ==== Storage   ====
  bool    public isSealed;
  uint32  public epoch;
  address public minter;


  // ==== Constructor ====
  constructor() ERC20("Cherry", "CHRY") {
      //   10 000 for initial liquidity pool
      // + 10 000 for airdrops and Cherrific team
      _mint(msg.sender, 20000 ether);
  }


  // ==== Governance  ====

  // seal contract for ever
  function seal() external onlyOwner {
    isSealed = true;
  }

  // set minter as long as contract isn't sealed
  function setMinter(address minter_) external onlyOwner {
    // function disabled once contract is sealed
    require( ! isSealed , "Contract is sealed");

    // Safeguard: make sure we set the correct minter
    // If this fails, it means minter is not set correctly
    require( IMinter(minter_).token() == address(this), "Minter not correctly set");

    minter = minter_;
  }


  // ==== Views    ====

  // Current epoch
  function getEpoch() public view returns (uint) {
    return block.timestamp / PERIOD;
  }


  // ==== Mutators ====

  // from OpenZeppelin
  function burn(uint256 amount) external returns (bool) {
    _burn(msg.sender, amount);
    return true;
  }

  // from OpenZeppelin
  function burnFrom(address account, uint256 amount) external returns (bool) {
    _spendAllowance(account, msg.sender, amount);
    _burn(account, amount);
    return true;
  }


  // only minter can mint
  function mint(address recipient_, uint256 amount_) external returns (bool) {

    require(msg.sender == minter, "Only minter can mint");

    uint newEpoch = getEpoch();
    require(newEpoch > epoch, "Mint only once per epoch");

    // all below code can only run once per epoch

    epoch = uint32(newEpoch);

    // make sure we don't mint too much
    uint supply = totalSupply();
    if (supply < minSupply) {
      // during low supply, we don't want to mint up to more than 120% minSupply
      require( supply + amount_ <= (minSupply * 120) / 100, "Minting too much while low supply");
    } else {
      // make sure minter does not go crazy
      // don't mint more than 5% of total supply per epoch
      // +5 if to allow for rounding errors on the minter side
      require( amount_ <= (supply / 20) + 5, "Don't mint > 5% supply per epoch");
    }

    _mint(recipient_, amount_);
    return true;
  }

}

I'll finish this story as soon as I have a few minutes.

I'll explain how this Cherry token contract works, and why it is not a contract that you should fully trust ... yet.

If you want to learn how to write smart contracts (it's not that complicated), then it will be a good example to start with.

Stay tuned.

Reactions are currently disabled. They will return soon.

⏪ Previous Story

0xedB0...3484 avatar

3 Ways to get Cherry token?

Cherry token is the utility token used to contribute to StoryPress.info. There are several ways to get hold ...
by 0xedB0...3484

⏩ Next Story

0xedB0...3484 avatar

v0.11 From Cherrific to StoryPress

This is a huge update and has been an enormous amount of work. The great news: each story you publish is ...
by 0xedB0...3484