CertiK reviewed Chiliz on 23 Dec 2022: 19 findings, 1 critical; 10 marked fixed, 9 open.
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 | 1 |
| High | 3 | 0 | 1 |
| Medium | 1 | 0 | 6 |
| Low | 5 | 0 | 2 |
The identified loop logic in `_claimDelegatorRewardsAndPendingUndelegates()` and `_calcDelegatorRewardsAndPendingUndelegates()` may exceed block gas limit when parameter `beforeEpochExclude`/`beforeEpoch` is far bigger than the epoch of last processed delegation. It can happen if functions `redelegateDelegatorFee()`/`claimDelegatorFee()`/`claimDelegatorFeeAtEpoch()` have not been called by a delegator for a long time. This is especially critical for `StakingPool` because it does not use `claimDelegatorFeeAtEpoch()` to process delegation little by little. Thus the modifier `advanceStakingRewards()` in `StakingPool` may always fail due to the use of `_claimDelegatorRewardsAndPendingUndelegates()`/`_calcDelegatorRewardsAndPendingUndelegates()`. Then the functions `stake()`/`unstake()`/`claim()` in `StakingPool` will always fail and users' funds are locked in the contract and lost.
In the contract `ChainConfig`, the role `Governance` has authority over the following functions: - setActiveValidatorsLength() - setEpochBlockInterval() - setMisdemeanorThreshold() - setFelonyThreshold() - setValidatorJailEpochLength() - setUndelegatePeriod() - setMinValidatorStakeAmount() - setMinStakingAmount() Any compromise to the `Governance` account may allow a hacker to take advantage of this authority and consensus params. In the contract `DeployerProxy`, the role `Governance` has authority over the following functions: - addDeployer() - removeDeployer() - banDeployer() - unbanDeployer() - disableContract() - enableContract() Any compromise to the `Governance` account may allow a hacker to take advantage of this authority and - add/remove/ban/unban deployer - disable/enable the contract Any compromise to the `Governance` account may allow a hacker to take advantage of this authority and consensus params. In the contract `DeployerProxy`, the role `Coinbase` has authority over the following functions: - registerDeployedContract() Any compromise to the `Coinbase` account may allow a hacker to take advantage of this authority and register deployed contract In the contract `Governance`, the role `Governance` has authority over the following functions: - addProposer() - removeProposer() - activateProposerRegistry() Any compromise to the `Governance` account may allow a hacker to take advantage of this authority and - add/remove the proposer - activate the proposer registry In the contract `Governance`, the role `Proposer` has authority over the following functions: - proposeWithCustomVotingPeriod() - propose() - execute() Any compromise to the `Proposer` account may allow a hacker to take advantage of this authority and propose a new proposal and execute the proposal In the contract `RuntimeUpgrade`, the role `Governance` has authority over the following functions: - upgradeSystemSmartContract() - deploySystemSmartContract() Any compromise to the `Governance` account may allow a hacker to take advantage of this authority and upgrade/deploy system smart contract In the contract `SlashingIndicator`, the role `Coinbase` has authority over the following functions: - registerDeployedContract() Any compromise to the `Coinbase` account may allow a hacker to take advantage of this authority and slash the validator In the contract `SystemReward`, the role `Governance` has authority over the following functions: - updateDistributionShare() Any compromise to the `Governance` account may allow a hacker to take advantage of this authority and update distribution share In the contract `Staking` the role `Governance` has authority over the functions: - addValidator() - removeValidator() - activateValidator() - disableValidator() Any compromise to the `Governance` account may allow the hacker to take advantage of this authority and - adds a validator - removes a validator - activates a validator - disables a validator In the contract `Staking` the owner of the validator has authority over the functions: - changeValidatorCommissionRate() - changeValidatorOwner() - releaseValidatorFromJail() - claimValidatorFee() - claimValidatorFeeAtEpoch() Any compromise to the owner of the validator may allow the hacker to take advantage of this authority and - changes the commission rate of himself/herself - changes the owner of the validator - release himself/herself from jail - claims validator fee
If a validator with non-zero delegation or pending validator rewards is removed, the functions `undelegate()`/`claimValidatorFee()`/`claimValidatorFeeAtEpoch()` will malfunction and revert when called by users/validator who still have funds left in the removed validator account. Thus users/validators' funds can not be withdrawn and lost.
Deploying new contracts and upgrading existing contracts use different bytecodes. Deploying new contracts run `contract creation bytecode` which runs constructor code and returns the actual runtime bytecode. Upgrading existing contracts involves using new runtime bytecode to replace existing runtime bytecode. The function `_upgradeSystemSmartContract()` does not run constructor code at all which is required by deploying new contracts. Thus any new contract with non-empty constructor will not initialize properly and malfunction afterwards. See https://docs.soliditylang.org/en/latest/contracts.html#immutable
The function `checkContractActive()` is used to check that the contract is active, but the function only checks that the contract is not disabled, it does not check that the contract exists.
One or more state variables are used without being initialized in the constructor. ```solidity=29 address internal _systemTreasury; ``` - `_systemTreasury` is never initialized, but used in `SystemReward._claimSystemFee`.
One or more logic contracts do not protect their initializers. An attacker can call the initializer and assume ownership of the logic contract, whereby she can perform privileged operations that trick unsuspecting users into believing that she is the owner of the upgradeable contract. ```solidity=11 contract StakingPool is InjectorContextHolder, IStakingPool { ``` - `StakingPool` is an upgradeable contract that does not protect its initializer. ```solidity=62 function init() external initializer { ``` - `init` is an unprotected initializer function.
```solidity=236 return uint64(block.number / _chainConfigContract.getEpochBlockInterval() + 0); ``` - The type conversion `uint64(block.number / _chainConfigContract.getEpochBlockInterval() + 0)` from larger type uint256 to smaller type uint64 may truncate data. --- ```solidity=291 validatorSnapshot.totalDelegated += uint112(amount / BALANCE_COMPACT_PRECISION); ``` - The type conversion `uint112(amount / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=302 recentDelegateOp.amount += uint112(amount / BALANCE_COMPACT_PRECISION); ``` - The type conversion `uint112(amount / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=304 delegation.delegateQueue.push(DelegationOpDelegate({epoch : atEpoch, amount : recentDelegateOp.amount + uint112(amount / BALANCE_COMPACT_PRECISION)})); ``` - The type conversion `uint112(amount / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=308 delegation.delegateQueue.push(DelegationOpDelegate({epoch : atEpoch, amount : uint112(amount / BALANCE_COMPACT_PRECISION)})); ``` - The type conversion `uint112(amount / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=327 validatorSnapshot.totalDelegated -= uint112(amount / BALANCE_COMPACT_PRECISION); ``` - The type conversion `uint112(amount / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=336 uint112 nextDelegatedAmount = recentDelegateOp.amount - uint112(amount / BALANCE_COMPACT_PRECISION); ``` - The type conversion `uint112(amount / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=345 delegation.undelegateQueue.push(DelegationOpUndelegate({amount : uint112(amount / BALANCE_COMPACT_PRECISION), epoch : beforeEpoch + _chainConfigContract.getUndelegatePeriod()})); ``` - The type conversion `uint112(amount / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=534 _validatorSnapshots[validatorAddress][sinceEpoch] = ValidatorSnapshot(0, uint112(initialStake / BALANCE_COMPACT_PRECISION), 0, commissionRate); ``` - The type conversion `uint112(initialStake / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=538 delegation.delegateQueue.push(DelegationOpDelegate(uint112(initialStake / BALANCE_COMPACT_PRECISION), sinceEpoch)); ``` - The type conversion `uint112(initialStake / BALANCE_COMPACT_PRECISION)` from larger type uint256 to smaller type uint112 may truncate data. --- ```solidity=552 indexOf = int256(i); ``` - The type conversion `int256(i)` from type uint256 to type int256 may flip the value's sign. --- ```solidity=689 currentSnapshot.totalRewards += uint96(msg.value); ``` - The type conversion `uint96(msg.value)` from larger type uint256 to smaller type uint96 may truncate data.
One or more state variables are never used in the codebase. Variable `__reserved` in `InjectorContextHolder` is never used in `ChainConfig`. ```solidity=55 uint256[100 - 8] private __reserved; ``` ```solidity=6 contract ChainConfig is InjectorContextHolder, IChainConfig { ```
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (9)
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