Dexit

CertiKFiles named in the report

CertiK reviewed DeXit on 7 Sep 2022: 34 findings, 2 critical; 29 marked fixed, 5 open.

2 critical findings, fixed
Open the reportOpen DeXit’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings34

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical002
High002
Medium001
Low5024
LowDiscussion of the variable `rewardClaimRecords`Open

The variable `rewardClaimRecords` is used to record the last reward claim time of the validator/delegator. An EOA address can be both validator and delegator due to the lack of restrictions in the contract. As a result, recording the last reward claim time of the validator and delegator in the same variable will make an EOA combining the 2 roles not able to claim the rewards as validator and delegator at the same time.

LowDiscussion on `registerContract()` FunctionOpen

[The glossary of Ethereum](https://ethereum.org/en/glossary/#account) writes that an account can be a contract account or an externally owned account (EOA). The `registerContract` function is used to register a pair of contract-reward recipients. In commit `1c2d45f56eab6a62d0416daf9ac012c79f61e1a7`, a require statement L36 was commented, which means that a pair of EOA-reward recipients could also be registered in the array `rewardAddresses`. ```solidity function registerContract(address contractAddr, address rewardAddr) external virtual returns (bool) { require( contractAddr != address(0x0) && rewardAddr != address(0x0), "0x0 found" ); require( rewardAddresses[contractAddr] == address(0), "Already registered" ); //require(isContract(contractAddr)), "contractAddr isn't contract"); rewardAddresses[contractAddr] = rewardAddr; rewardAmountOwner[rewardAddr] = 0; return true; } ``` However, from the input naming info of the `checkEligible` function that references the `rewardAddresses` array, only contract addresses can be passed in.

LowDiscussion on `stakeValidator` functionOpen

The function `stakeValidator()` is used to stake tokens by any user to become a validator. The `if` statements in L235-L254 already update the array `highestValidators`, but the statements in L265-L279 update the array `highestValidators` again after updating the validator's status and the array `currentValidators`. Is that designed as expected?

LowDiscussion on Governance MechanismOpen

GovHub is the governance contract for `Dexit`, a contract that allows any validator to submit proposals with the initiator address stored in the `proposal.dst` field. \ Once a proposal is initiated, it enters the voting phase, but not all validators can vote, only those in the `highestValidators` array can. \ The `voteProposal` function checks whether `pass[proposals[id].dst]` is `True` or not at L314. \ If the condition is `False`, and if more than 51% of the nodes vote for the proposal, then the `voteProposal` function sets `pass[proposals[id].dst]` to `True` and calls `authchangevalues` to execute the proposal. As long as `pass[proposals[id].dst]` is `True`, the other proposals that the proposer submits can not be executed.\ But there is a particular case for the `highestValidators`. When a validator in `highestValidators` votes on his own proposal and the cumulative `votePowerOfAgree` reaches 51% of `totalVotePower` when he calls `voteProposal()`, the proposal is executed. In this case `proposals[id].dst` and `msg.sender` will be the same. Since `authchangevalues` will reset `pass[msg.sender]` to `False`, `pass[proposals[id].dst]` will also be `False`, meaning other proposals created by those validators will be executed normally, since they will be able to bypass the check L314. ```solidity if (pass[proposals[id].dst] || proposals[id].resultExist) { return true; //Do nothing if dst already passed or rejected. } ``` Is that designed as expected?

LowDiscussion on the function `getStakingInfo()`Open

The function `getStakingInfo()` is a view function that returns the information of the given delegator's stake from the variable `stakingInfo`. In the contract `BSCValidatorSet`, both validator and delegator will be recorded in the variable `stakingInfo`; but to get the actual information of the validator, it is needed to combine the information from the variables `validatorInfo` and `stakingInfo`. As a result, the return value is not correct when calling the function `getStakingInfo()` with the parameter is a validator.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (23)

  • GovHub.sol
  • interface/IRelayerHub.sol
  • interface/ILightClient.sol
  • RewardRegister.sol
  • lib/BytesToTypes.sol
  • System.sol
  • BSCValidatorSet.sol
  • interface/ICrossChain.sol
  • lib/BytesLib.sol
  • lib/Memory.sol
  • lib/SafeMath.sol
  • interface/ISlashIndicator.sol
  • interface/IBSCValidatorSet.sol
  • lib/RLPDecode.sol
  • lib/CmnPkg.sol
  • interface/ISystemReward.sol
  • lib/SizeOf.sol
  • interface/IRewardRegister.sol
  • lib/RLPEncode.sol
  • lib/TypesToBytes.sol
  • interface/IParamSubscriber.sol
  • interface/IApplication.sol
  • SlashIndicator.sol

Part of DeXit’s security record

DeXit
Audits1 audit by 1 firmLast audit Sep 2022, by CertiK.
Critical findingsNo open critical findingsIn that report, 2 critical findings were reported. Each is marked fixed by the firm that reported it.
Open DeXit’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

Something 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