Smart Contract Analysis #1: Mithril (ERC20 tokens)

Introduction to Mithril

Screen Shot 2018-05-01 at 9.46.17 PM.png

Image taken from mithril official website

Mithril are a decentralized social media platform that rewards all content creators, and the token is build on top of Ethereum Network with the standard ERC20 tokens.

The following video explain what is mithril.

I had use one of the DAPP build with Mithril which is called Lit, and my opinion it is like a SnapChat clone, and you get reward in terms of mithril token when you post images.




In this post, I will be analyzing the smart contract which is available on EtherScan. The TLDR version will be at conclusion. (Scroll to the bottom)

Disclaimer: This is not a financial advise.

Disclaimer: This is just me analysing the smart contract from EtherScan, and shared some thoughts about it, I might be wrong in some part of the analysis.

In the smart contract

Contract header

On line 1, This line state the version of solidity used.

pragma solidity ^0.4.18;

Safe Math

On line 7, Mithril used SafeMath library, which is an essential library to used for building Smart Contract on top of Ethereum Virtual Network. This library will prevent the overflow of data type.

library SafeMath {

Owner Contract

This is the owner contract, where only the owner address can carry out operation. This contract is also important to check through because the owner can setup a backdoor access forthe contract. Since smart contract are open up, we can check the contract easily on this owner contract.

on line 25, Mithril token started the contract called Owned. The variable owner are address type which is used to store the owner address, can be accessed outside of the contract. OwnershipTransfered event will be fired when there is a transfer of ownership from owner to another party.

contract Owned {
    address public owner;
    event OwnershipTransfered(address indexed owner);

On line 30, Owned() function is created, which is the constructor of the contract (meaning it only run once). The owner variable is set to the sender of the initializer. Therefore, during deployment of Mithril, the owner use it's address to deploy, and the contract will belongs to the owner, and this happens only once.

function Owned() public {
    owner = msg.sender;
}

On line 34, there is a modifier called onlyOwner. Which means when a function contains onlyOwner, it will run an assert require(msg.sender == owner) to check wether the sender is owner. If he/she is not, the contract will throw an error.

modifier onlyOwner {
    require(msg.sender == owner);
    _;
}

On line 39, there is a function to do ownership transfer. The function is called transferOwnership which can be called outside of the contract and can used by the owner address only, the function required 1 parameters, which is the new owner's address newOwner. Then, the function will declare the new owner address in the owner variable. OwnershipTransfered event is fired.

function transferOwnership(address newOwner) onlyOwner public {
    owner = newOwner;
    OwnershipTransfered(owner);
}

ERC20 tokens

Mithril is an ERC20 tokens, where it follows the standard on functions of ERC 20 tokens.

On line 49, the contract called ERC20token is declared, and uint256 will be using SafeMath library.

contract ERC20Token {
    using SafeMath for uint256;

On line 53, the contract follows ERC20 tokens, declared all the necessary variables.

  • name - name of the contract
  • symbol - short name of the contract
  • decimals - Ether itself has 18 decimals, most ERC 20 tokens follow this standard. [1]
  • totalSupply - To check the total supply of Mithril token
  • balanceOf - To store tokens (type: uint256) into an address, store in a mapping data type.
  • allowance - To allow for 2 address to create repeated unidirectional transfer. [2]
  • Transfer - Setup Event for Transfer (Event happen when Transfer token from one body to another)
  • Approval - Setup Event for Approval (Event happen when One body approved a transactions of another body)
string public constant name = "Mithril Token";
string public constant symbol = "MITH";
uint8 public constant decimals = 18;
uint256 public totalSupply;
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed from, uint256 value, address indexed to, bytes extraData);

On line 64, the contract initialize itself (constructor)

function ERC20Token() public {
}

On line 70, we create an internal function called _transfer which transfer money from one body to another. The code checks for wether the sender has enough balance, and some safe net, by checking previous balance (wether it matches the current balance).

function _transfer(address from, address to, uint256 value) internal {
    // Check if the sender has enough balance
    require(balanceOf[from] >= value);
    // Check for overflow
    require(balanceOf[to] + value > balanceOf[to]);
    // Save this for an amount double check assertion
    uint256 previousBalances = balanceOf[from].add(balanceOf[to]);
    balanceOf[from] = balanceOf[from].sub(value);
    balanceOf[to] = balanceOf[to].add(value);
    Transfer(from, to, value);
    // Asserts for duplicate check. Should never fail.
    assert(balanceOf[from].add(balanceOf[to]) == previousBalances);
}

On line 97, is a function to transfer mithril token from the sender address to a receiver address, and passing in the amount of token.

function transfer(address to, uint256 value) public {
    _transfer(msg.sender, to, value);
}

On line 110, This functions allows the allowance receiver to transfer mithril token from one party to another. But, it needs to match the allowance data type, meaning if there is no such setup on allowance, the user are not allowed to carry out the operation. (Read the next function on setting up allowance)

function transferFrom(address from, address to, uint256 value) public returns (bool success) {
    require(value <= allowance[from][msg.sender]);
    allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
    _transfer(from, to, value);
    return true;
}

On line 126, You can setup for someone (with an address) on how much you want to let him/her spend. The function approve, allows extraData, which I assume can be used to send memo, like "Happy birthday Johnny!".

function approve(address spender, uint256 value, bytes extraData) public returns (bool success) {
    allowance[msg.sender][spender] = value;
    Approval(msg.sender, value, spender, extraData);
    return true;
}

Main contract

After setting up ERC20 Token standard Contract and Owner Contract, the contract setup with a contract called "MithrilToken".

On line 137, The main contract is called MithrilToken which inherits from Owned Contract and ERC20Token Contract.

contract MithrilToken is Owned, ERC20Token {

On line 139, setup a public vault address and wallet address.

// Address where funds are collected.
address public vault;
address public wallet;

On line 143, the contract initialize.

function MithrilToken() public {
}

On line 146, there is an init function which can only be called by the owner, which I assume are called only once (because the first 2 lines check the vault address, wether is it 0x0, which is the initial state). Total Supply, wallet address, and vault's token are set in this function.

function init(uint256 _supply, address _vault, address _wallet) public onlyOwner {
    require(vault == 0x0);
    require(_vault != 0x0);
    totalSupply = _supply;
    vault = _vault;
    wallet = _wallet;
    balanceOf[vault] = totalSupply;
}

On line 156, there is a noname function with a payable modifier. According to stackexchange, there is a no name function to accept ether to be sent to a contract which is called a fallback function. [3]

function () payable public {
    wallet.transfer(msg.value);
}

Code

I have copied the code from EtherScan to a Github Gist.

Conclusion

Overall, Mithril did use the best practise on building an Ethereum Blockchain, they use Smart Math library to prevent data overflow, Owned Contract to do Ownership operation, and make use the standard ERC20 token to apply their contract. So, Mithril Token, can do transfer of token from one body to another, check balance and market supply. One thing which is new to me is that they have a feature call allowance, where you can set an amount for an address to transfer a certain limit tokens from your account. In addition to that, the main contract has an initialize function which allow it to setup the total supply of the blockchain, based on my observation, the supply is a fixed amount.

Reference

[1] https://ethereum.stackexchange.com/questions/38704/why-most-erc-20-tokens-have-18-decimals
[2] https://coincentral.com/understanding-erc20/
[3] https://ethereum.stackexchange.com/questions/20874/payable-function-in-solidity

H2
H3
H4
3 columns
2 columns
1 column
18 Comments