This document is a security audit report performed by danbogd, where UNUS SED LEO has been reviewed.
Сommit hash .
or
In total, 7 issues were reported including:
- 1 medium severity issues
- 3 low severity issues
- 3 owner privileges (ability of owner to manipulate contract, may be risky for investors)..
- 0 notes.
No critical security issues were found.
Even if a view function does not need ether for execution when it is called externaly, developers should think about implementing loops inside such functions. Still, such functions may be called by other function as part of on-chain operations and stall those.
In this implementation if the value of checkpoints.length of the function getValueAt will be very large the transfer functions can lead to "Out of Gas" error or to "Block Gas Limit".
LEO_token.sol, line 508.
function getValueAt(Checkpoint[] storage checkpoints, uint _block
) view internal returns (uint) {
if (checkpoints.length == 0) return 0;
// Shortcut for the actual value
if (_block >= checkpoints[checkpoints.length-1].fromBlock)
return checkpoints[checkpoints.length-1].value;
if (_block < checkpoints[0].fromBlock) return 0;
// Binary search of the value in the array
uint min = 0;
uint max = checkpoints.length-1;
uint mid = 0;
while (max > min) {
mid = (max + min + 1)/ 2;
if (checkpoints[mid].fromBlock<=_block) {
min = mid;
} else {
max = mid-1;
}
}
return checkpoints[min].value;
}
Following ERC-20 final description:
"NOTE: To prevent attack vectors like the one described here and discussed here, clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to 0 before setting it to another value for the same spender. THOUGH The contract itself shouldn't enforce it, to allow backwards compatibility with contracts deployed before.
Do not throw in case if the following condition is true require((_amount == 0) || (_allowances[msg.sender][spender] == 0)) and return false, users might not notice that the changes didn't occur, and external contract calls to this function will highlight many other issues.
LEO_token.sol, line 302.
function approve(address _spender, uint256 _amount) public returns (bool success) {
require(transfersEnabled);
require((_amount == 0) || (allowed[msg.sender][_spender] == 0));
if (isContract(controller)) {
require(TokenController(controller).onApprove(msg.sender, _spender, _amount));
}
allowed[msg.sender][_spender] = _amount;
emit Approval(msg.sender, _spender, _amount);
return true;
}
Incoming addresses should be checked for an empty value(0x0 address) to avoid loss of funds or blocking some functionality.
LEO_token.sol, line 76.
function changeController(address _newController) public onlyController {
emit ControlTransferred(controller, _newController);
controller = _newController;
}
-
It is possible to double withdrawal attack. More details here.
-
Lack of transaction handling mechanism issue. WARNING! This is a very common issue and it already caused millions of dollars losses for lots of token users! More details here.
Add into a function transfer(address _to, ... )
following code:
require( _to != address(this) );
Contract owner allow himself to:
enable/disable transfer, transferFrom, approve functions
LEO_token.sol, line 496. function enableTransfers(bool _transfersEnabled) public onlyController { transfersEnabled = _transfersEnabled; }
- upgrade contract and implement any logic in the new contract. And even if the new contract will be audited, at any time possible to change the address of the new contract again to not audited and insecure.
LEO_token.sol, line 698.
function upgradeController(address _newControllerAddress) public onlyOwner {
tokenContract.changeController(_newControllerAddress);
emit UpgradedController(_newControllerAddress);
}
- evacuate all users tokens on owner account.
LEO_token.sol, line 719.
function claimLostTokens(address payable _token) public onlyOwner {
LEO token = LEO(_token);
uint balance = token.balanceOf(address(this));
token.transfer(owner, balance);
emit ClaimedTokens(_token, owner, balance);
}
The review did not show any critical issues, some of medium and low severity issues were found.