CertiK reviewed Zescoin (Seclab - ZESC) on 10 Apr 2023: 9 findings, 0 critical; all marked fixed.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 1 |
| Medium | 0 | 0 | 0 |
| Low | 0 | 0 | 8 |
Tokens are sent to `ZESC` when deploying the contract. This could be a centralization risk as the `ZESC` can distribute tokens without obtaining the consensus of the community.
A boolean is compared to a boolean constant as shown below: ```solidity=209 require(_isTimeLockedAddress[sender] == false, "TimeLocked account"); ``` ```solidity=265 require(_isTimeLockedAddress[newTarget] == false, "Timelocked account"); ``` ```solidity=276 require(_isTimeLockedAddress[target] == true, "Not timelocked address"); ``` ```solidity=317 require(_isTimeLockedAddress[sender] == false, "TimeLocked account"); ``` ```solidity=331 require(burnFlag == true, "Burn function is locked"); ``` Boolean constants can be used directly and do not need to be compared to true or false.
It is expected that invocations of the form `transfer(recipient, amount)` succeed and return `true` if * The address in `recipient` is not the zero address, * `amount` does not exceed the balance of address `msg.sender`, * transferring `amount` to the address `recipient` does not lead to an overflow of the recipient's balance, and * the supplied gas suffices to complete the call. Nevertheless, the `transfer` function of `ZESC` fails in some of those admissible cases.
It is expected that invocations of the form `transfer(recipient, amount)` where the address in `recipient` equals the address in `msg.sender` (i.e. self-transfers) succeed and return `true` if * The value in `amount` does not exceed the balance of `msg.sender` and * the supplied gas suffices to complete the call. Nevertheless, the `transfer` function of `ZESC` fails in some of those admissible cases.
It is expected that invocations of `transferFrom(from, dest, amount)` succeed and return `true` if * the value of `amount` does not exceed the balance of address `from`, * the value of `amount` does not exceed the allowance of `msg.sender` for address `from`, * transferring a value of `amount` to the address in `dest` does not lead to an overflow of the recipient's balance, and * the supplied gas suffices to complete the call. Nevertheless, the `transferFrom` function of `ZESC` fails in some of those admissible cases.
It is expected that invocations of `transferFrom(from, dest, amount)` where the address in `dest` equals the address in `from` (i.e. self-transfers) succeed and return `true` if: * The value of `amount` does not exceed the balance of address `from`, * the value of `amount` does not exceed the allowance of `msg.sender` for address `from`, and * the supplied gas suffices to complete the call. Nevertheless, the `transferFrom` function of `ZESC` fails for some self-transfers in these admissible cases.
```solidity=304 function burn() external onlyOwner returns (bool) { _burn(_msgSender(), burnAmount); burnFlag = false; return true; } ``` ```solidity=328 function _burn(address account, uint256 amount) internal { require(account != address(0), "BEP20: burn from the zero address"); require(msg.sender == owner(), "only owner"); require(burnFlag == true, "Burn function is locked"); _balances[account] = _balances[account].sub( amount, "BEP20: burn amount exceeds balance" ); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } ``` In the function `_burn()`, `require(msg.sender == owner(), "only owner");` validation checks whether the caller of the function is the `owner()` address. However, this validation is redundant because `_burn()` is an internal function and its only public wrapper function is `burn()` has `onlyOwner` modifier which already checks whether the caller of `burn()` is from address `owner()`.
The `SafeMath` library is used unnecessarily. With Solidity compiler versions 0.8.0 or newer, arithmetic operations will automatically revert in case of integer overflow or underflow. ```solidity=47 library SafeMath { ``` - An implementation of `SafeMath` library is found. --- ```solidity=131 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `ZESC` contract. ```solidity=211 _approve( sender, _msgSender(), _allowances[sender][_msgSender()].sub( amount, "BEP20: transfer amount exceeds allowance" ) ); ``` - `SafeMath.sub` is called in `transferFrom` function of `ZESC` contract. *Note: Only a sample of 2 `SafeMath` library usage in this contract (out of 8) are shown above.*
The linked variables assigned in the constructor can be declared as `immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since they will not be stored in storage.
| Address | Chain | Source code |
|---|---|---|
| 0x3fef…23bd0x3fef6bcf3449cdf9279e8baa152613df629e23bd | Chain: BNB Chain | Source code: Verified source |
| 0xf4ab…bcab0xf4aba4bcc413f38e4d8fc195a1d3bf560570bcab | Chain: BNB Chain | Source code: Verified source |
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us