TRIPLX (XXX) Token - Smart Contract Audit Report

Summary

TRIPLX (XXX) is an ERC20 token with a variable burn rate based on the token's total supply. After deployment, the supply of TRIPLX can only decrease while a percent of the token is burned on each transfer. As the total supply decreases, the burn rate increases.

Features of the token contract:
  • TRIPLX token is only minted when deployed. The deployer dictates what address receives all of the tokens.
  • The token starts with a 2% burn fee, increasing gradually to a maximum of 10% as the total supply decreases.
  • Utilization of SafeMath to prevent overflows.
Audit Findings Summary
  • Overall, no serious issues were identified.
  • Date: November 13th, 2020.


Date: November 13th, 2020
Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Deprecated OpcodesN/APASS
Ether ThiefN/APASS
ExceptionsN/APASS
External CallsN/APASS
Integer Over/UnderflowN/APASS
Multiple SendsN/APASS
SuicideN/APASS
State Change External CallsN/APass
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

ERC20 Token Graph

Token Inheritance


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 + [Lib] SafeMath 
    - [Int] mul
    - [Int] div
    - [Int] sub
    - [Int] add
    - [Int] ceil

 + [Int] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 +  XXX (IERC20)
    - [Pub]  #
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] allowance
    - [Pub] approve #
    - [Pub] transferFrom #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #
    - [Int] _transfer #
    - [Int] _approve #
    - [Pub] updateBurnRate #
    - [Pub] _calculateTokenToBurn #
	
							

Click here to download the source code as a .sol file.


pragma solidity 0.5.10;



library SafeMath {

  function mul(uint256 a, uint256 b) internal pure returns (uint256) {

    if (a == 0) {

      return 0;

    }

    uint256 c = a * b;

    assert(c / a == b);

    return c;

  }



  function div(uint256 a, uint256 b) internal pure returns (uint256) {

    uint256 c = a / b;

    return c;

  }



  function sub(uint256 a, uint256 b) internal pure returns (uint256) {

    assert(b <= a);

    return a - b;

  }



  function add(uint256 a, uint256 b) internal pure returns (uint256) {

    uint256 c = a + b;

    assert(c >= a);

    return c;

  }



  function ceil(uint256 a, uint256 m) internal pure returns (uint256) {

    uint256 c = add(a,m);

    uint256 d = sub(c,1);

    return mul(div(d,m),m);

  }

}





interface IERC20 {



    function totalSupply() external view returns (uint256);



    function balanceOf(address account) external view returns (uint256);



    function transfer(address recipient, uint256 amount) external returns (bool);



    function allowance(address owner, address spender) external view returns (uint256);



    function approve(address spender, uint256 amount) external returns (bool);



    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);



    event Transfer(address indexed from, address indexed to, uint256 value);



    event Approval(address indexed owner, address indexed spender, uint256 value);

}





contract XXX is IERC20 {

    using SafeMath for uint256;



    mapping (address => uint256) private _balances;



    mapping (address => mapping (address => uint256)) private _allowances;



    uint256 public _burnRate;

    uint256 private _totalSupply;

    



    string public constant name = "TRIPLX";

    string public constant symbol = "XXX";

    uint256 public constant decimals = 18;



    uint256 public constant INITIAL_SUPPLY = 50000 * 10**18;



  /**

   * @dev Contructor

   */

  constructor() public {

    _totalSupply = INITIAL_SUPPLY;

    _balances[0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 ] = INITIAL_SUPPLY;

    emit Transfer(address(0), 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 ,_totalSupply);

    updateBurnRate();

  }





    function totalSupply() public view returns (uint256) {

        return _totalSupply;

    }





    function balanceOf(address account) public view returns (uint256) {

        return _balances[account];

    }



    function transfer(address recipient, uint256 amount) public returns (bool) {

        _transfer(msg.sender, recipient, amount);

        return true;

    }





    function allowance(address owner, address spender) public view returns (uint256) {

        return _allowances[owner][spender];

    }





    function approve(address spender, uint256 value) public returns (bool) {

        _approve(msg.sender, spender, value);

        return true;

    }



    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {

        _transfer(sender, recipient, amount);

        _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));

        return true;

    }





    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {

        _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));

        return true;

    }





    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {

        _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));

        return true;

    }





    function _transfer(address sender, address recipient, uint256 amount) internal {

        require(sender != address(0), "ERC20: transfer from the zero address");

        require(recipient != address(0), "ERC20: transfer to the zero address");

        

        

        uint256 tokensToBurn = _calculateTokenToBurn(amount);

        uint256 tokensToTransfer = amount.sub(tokensToBurn);

        

        _balances[sender] = _balances[sender].sub(amount);

        _balances[recipient] = _balances[recipient].add(tokensToTransfer);



        _totalSupply = _totalSupply.sub(tokensToBurn);

        

        emit Transfer(sender, recipient, tokensToTransfer);

        emit Transfer(sender, address(0), tokensToBurn);

    }

    



    function _approve(address owner, address spender, uint256 value) internal {

        require(owner != address(0), "ERC20: approve from the zero address");

        require(spender != address(0), "ERC20: approve to the zero address");



        _allowances[owner][spender] = value;

        emit Approval(owner, spender, value);

    }



    

    function updateBurnRate() public returns(uint256) {

        if (_totalSupply > 49999999999999999999999) {

            _burnRate = 2;

        } else if(_totalSupply <= 48000000000000000000000 && _totalSupply > 46000000000000000000000) {

            _burnRate = 4;

        } else if(_totalSupply <= 46000000000000000000000 && _totalSupply > 44000000000000000000000) {

            _burnRate = 6;

        } else if(_totalSupply <= 44000000000000000000000 && _totalSupply > 42000000000000000000000) {

            _burnRate = 8;

        } else if(_totalSupply <= 42000000000000000000000 && _totalSupply > 1) {

            _burnRate = 10;

        }

        

        return _burnRate;

    }



    

    function _calculateTokenToBurn(uint256 value) public returns(uint256){ 

        uint256 _burnerRate = updateBurnRate();

        uint256 roundValue = value.ceil(_burnerRate);

        uint256 _myTokensToBurn = roundValue.mul(_burnerRate).div(100);

        return _myTokensToBurn;

    }

    

}