Unicrypt  - Smart Contract Audit Report

Summary

Unicrypt Token (UNC) Audit Report UNC is the native token for the Unicrypt platform. It is responsive to market conditions, and for use in the Unicrypt ecosystem of DAPPS, staking, voting and decentralised trading tools.

As a holder of UNC, you have a say in how the UNC funding reserve is used to grow the project. UNC can be used to vote on staking rewards, trading competitions, burns; and decide how to allocate the reserve to developers and promoters.



Note: The Unicrypt Team has since swapped to a new token. Please consider this audit deprecated.

Features of the token contract:
  • Burn tokens to reduce the total/circulating supply. No minting function is present.
  • Utilization of SafeMath to prevent overflows.
Audit Findings Summary
  • Overall, no serious issues were identified.
  • The mulltiTransfer() function technically is vulnerable to an arithmetic overflow, but it would require sending 2256 addresses in a single transaction which is not feasible due to gas requirements.
  • The contract uses an assert check instead of a require check in the multiTransfer() function. This is out of line with Solidity best practices, but in this case the usage poses no issue to the integrity of the contract.

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/UnderflowIn theory it is possible to overflow the multiTransfer()
function but it is far too costly to be feasibly possible.
Warning
Multiple SendsN/APASS
SuicideN/APASS
State Change External CallsN/APass
Unchecked RetvalN/APASS
User Supplied AssertionA user can trigger an assertion violation on the multiTransfer()
function, but their transaction will revert safely.
Warning
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

TRC20 Token Graph

Multi-file Token


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 + [Int] ERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] allowance
    - [Ext] transfer #
    - [Ext] approve #
    - [Ext] approveAndCall #
    - [Ext] transferFrom #

 + [Int] ApproveAndCallFallBack 
    - [Ext] receiveApproval #

 +  Unicrypt (ERC20)
    - [Pub]  #
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] allowance
    - [Pub] transfer #
    - [Pub] multiTransfer #
    - [Pub] approve #
    - [Ext] approveAndCall #
    - [Pub] transferFrom #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #
    - [Ext] burn #

 + ib] SafeMath 
    - [Int] mul
    - [Int] div
    - [Int] sub
    - [Int] add
    - [Int] ceil

  

							

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


/**
 *Submitted for verification at Etherscan.io on 2020-06-25
*/

// Unicrypt is a decentralised liquidity pool running on Uniswap - Powered by Uniswap
// https://Unicrypt.network

pragma solidity ^0.4.25;

interface ERC20 {
  function totalSupply() external view returns (uint256);
  function balanceOf(address who) external view returns (uint256);
  function allowance(address owner, address spender) external view returns (uint256);
  function transfer(address to, uint256 value) external returns (bool);
  function approve(address spender, uint256 value) external returns (bool);
  function approveAndCall(address spender, uint tokens, bytes data) external returns (bool success);
  function transferFrom(address from, address to, uint256 value) external returns (bool);

  event Transfer(address indexed from, address indexed to, uint256 value);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}

interface ApproveAndCallFallBack {
    function receiveApproval(address from, uint256 tokens, address token, bytes data) external;
}


contract Unicrypt is ERC20 {
  using SafeMath for uint256;

  mapping (address => uint256) private balances;
  mapping (address => mapping (address => uint256)) private allowed;
  string public constant name  = "Unicrypt";
  string public constant symbol = "UNC";
  uint8 public constant decimals = 18;

  address owner = msg.sender;

  uint256 _totalSupply = (10 ** 9) * (10 ** 18); // 1 billion supply

  constructor() public {
    balances[msg.sender] = _totalSupply;
    emit Transfer(address(0), msg.sender, _totalSupply);
  }

  function totalSupply() public view returns (uint256) {
    return _totalSupply;
  }

  function balanceOf(address player) public view returns (uint256) {
    return balances[player];
  }

  function allowance(address player, address spender) public view returns (uint256) {
    return allowed[player][spender];
  }


  function transfer(address to, uint256 value) public returns (bool) {
    require(value <= balances[msg.sender]);
    require(to != address(0));

    balances[msg.sender] = balances[msg.sender].sub(value);
    balances[to] = balances[to].add(value);

    emit Transfer(msg.sender, to, value);
    return true;
  }

  function multiTransfer(address[] memory receivers, uint256[] memory amounts) public {
    for (uint256 i = 0; i < receivers.length; i++) {
      transfer(receivers[i], amounts[i]);
    }
  }

  function approve(address spender, uint256 value) public returns (bool) {
    require(spender != address(0));
    allowed[msg.sender][spender] = value;
    emit Approval(msg.sender, spender, value);
    return true;
  }

  function approveAndCall(address spender, uint256 tokens, bytes data) external returns (bool) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
        return true;
    }

  function transferFrom(address from, address to, uint256 value) public returns (bool) {
    require(value <= balances[from]);
    require(value <= allowed[from][msg.sender]);
    require(to != address(0));

    balances[from] = balances[from].sub(value);
    balances[to] = balances[to].add(value);

    allowed[from][msg.sender] = allowed[from][msg.sender].sub(value);

    emit Transfer(from, to, value);
    return true;
  }

  function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
    require(spender != address(0));
    allowed[msg.sender][spender] = allowed[msg.sender][spender].add(addedValue);
    emit Approval(msg.sender, spender, allowed[msg.sender][spender]);
    return true;
  }

  function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
    require(spender != address(0));
    allowed[msg.sender][spender] = allowed[msg.sender][spender].sub(subtractedValue);
    emit Approval(msg.sender, spender, allowed[msg.sender][spender]);
    return true;
  }

  function burn(uint256 amount) external {
    require(amount != 0);
    require(amount <= balances[msg.sender]);
    _totalSupply = _totalSupply.sub(amount);
    balances[msg.sender] = balances[msg.sender].sub(amount);
    emit Transfer(msg.sender, address(0), amount);
  }

}




library SafeMath {
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    require(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) {
    require(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(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);
  }
}