Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Integer Over/Underflow | In theory it is possible to overflow the multiTransfer() function but it is far too costly to be feasibly possible. | Warning |
Multiple Sends | N/A | PASS |
Suicide | N/A | PASS |
State Change External Calls | N/A | Pass |
Unchecked Retval | N/A | PASS |
User Supplied Assertion | A user can trigger an assertion violation on the multiTransfer() function, but their transaction will revert safely. | Warning |
Critical Solidity Compiler | N/A | PASS |
Overall Contract Safety | PASS |
Unicrypt - Smart Contract Audit Report
Summary
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:Audit Findings Summary
- Burn tokens to reduce the total/circulating supply. No minting function is present.
- Utilization of SafeMath to prevent overflows.
- 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 arequire
check in themultiTransfer()
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.
($) = 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 #
+ [Lib] 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);
}
}