Quantum bridge

CertiKFiles named in the report

CertiK reviewed DeFiChain (Quantum bridge) on 10 Mar 2023: 8 findings, 0 critical; 6 marked fixed, 2 open.

No open critical findings
Open the reportOpen DeFiChain’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings8

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

SeverityOpenAcknowledgedFixed
Critical000
High200
Medium001
Low005
MediumPotential Damage Due to Unprotected InitializerFixed

The `bridgeV1` contract does not protect its initialize function. An attacker can call the initializer and assume ownership of the logic contract, whereby he can perform privileged operations that either indirectly break the proxy by destroying the logic contract or trick unsuspecting users into believing that he is the owner of the upgradeable contract. ```solidity=221 function initialize( address _initialAdmin, address _initialOperational, address _relayerAddress, address _communityWallet, uint256 _fee, address _flushReceiveAddress, uint256 _acceptableRemainingDays ) external initializer { __UUPSUpgradeable_init(); __EIP712_init(name, version); _grantRole(DEFAULT_ADMIN_ROLE, _initialAdmin); _grantRole(OPERATIONAL_ROLE, _initialOperational); communityWallet = _communityWallet; relayerAddress = _relayerAddress; transactionFee = _fee; flushReceiveAddress = _flushReceiveAddress; acceptableRemainingDays = _acceptableRemainingDays; }

LowMissing proper sanity checks on `_newResetTimeStFixed

The current implementation lacks proper sanity checks for the function argument `_newResetTimeStamp`. Setting `_newResetTimeStamp` to an excessively large value would cause the `bridgeToDeFiChain` operation to revert due to the `STILL_IN_CHANGE_ALLOWANCE_PERIOD` error. ```solidity=349 function changeDailyAllowance( address _tokenAddress, uint256 _dailyAllowance, uint256 _newResetTimeStamp ) external { if (!checkRoles()) revert NON_AUTHORIZED_ADDRESS(); if (!supportedTokens.contains(_tokenAddress)) revert ONLY_SUPPORTED_TOKENS(); if (_newResetTimeStamp < block.timestamp + 1 days) revert INVALID_RESET_EPOCH_TIME(); tokenAllowances[_tokenAddress].dailyAllowance = _dailyAllowance; uint256 prevTimeStamp = tokenAllowances[_tokenAddress].latestResetTimestamp; tokenAllowances[_tokenAddress].latestResetTimestamp = _newResetTimeStamp; tokenAllowances[_tokenAddress].currentDailyUsage = 0; emit CHANGE_DAILY_ALLOWANCE(_tokenAddress, _dailyAllowance, prevTimeStamp, _newResetTimeStamp); } ```

LowNo Upper Limits for FeesFixed

There are no upper boundaries for transaction fee in function `changeTxFee()` . It is possible to set the total transaction fee rate up to 100%. ```solidity=435 function changeTxFee(uint256 fee) external onlyRole(DEFAULT_ADMIN_ROLE) { uint256 oldTxFee = transactionFee; transactionFee = fee; emit TRANSACTION_FEE_CHANGED(oldTxFee, transactionFee); } ```

LowOut of Scope DependencyFixed

The `BridgeV1` contract serves as the underlying entity to interact with the external dependency `relayer`. The relayer can sign instructions for fund claiming, which users can submit to the blockchain. The scope of the audit treats component that is out of scope as black boxes and assumes their functional correctness.

LowPotential Gas ExhaustionFixed

The computation for each iteration is complex. It could lead to Out-of-gas exception when the number of supported tokens is large. ```solidity=378 function flushFund() external { for (uint256 i = 0; i < supportedTokens.length(); ++i) { address supToken = supportedTokens.at(i); if ( (IERC20(supToken).balanceOf(address(this)) > acceptableRemainingDays * tokenAllowances[supToken].dailyAllowance) && // the same logic as in bridgeToDeFiChain applies here, if we are still // in the period for addingSupport or changingDailyAllowance, we will not flush for that particular token (tokenAllowances[supToken].latestResetTimestamp <= block.timestamp) ) { uint256 amountToFlush = IERC20(supToken).balanceOf(address(this)) - acceptableRemainingDays * tokenAllowances[supToken].dailyAllowance; IERC20(supToken).transfer(flushReceiveAddress, amountToFlush); } } emit FLUSH_FUND(); } ```

LowUnchecked ERC-20 `transfer()`/`transferFrom()` CaFixed

The return value of the transfer()/transferFrom() call is not checked in the following lines. ```solidity=265 IERC20(_tokenAddress).transfer(_to, _amount); ``` --- ```solidity=300 IERC20(_tokenAddress).transferFrom(msg.sender, address(this), netAmountInWei); ``` --- ```solidity=301 IERC20(_tokenAddress).transferFrom(msg.sender, communityWallet, netTxFee); ``` --- ```solidity=370 IERC20(_tokenAddress).transfer(msg.sender, amount); ``` --- ```solidity=391 IERC20(supToken).transfer(flushReceiveAddress, amountToFlush); ```

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 (2)

  • packages/smartcontracts/src/contracts/BridgeV1.sol
  • packages/smartcontracts/src/contracts/BridgeProxy.sol

Part of DeFiChain’s security record

DeFiChain
Audits1 audit by 1 firmLast audit Mar 2023, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open DeFiChain’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