As of 21 Oct 2026, Chronos has 3 audit reports by 2 security firms on Trustblock; the latest is by PeckShield, dated 16 Aug 2023. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Chronos: MaGaugeV2Upgradeable && ChronosMarketplac | Security firm: PeckShield | Date: | Scope: Not recorded (see the report) | 2 critical findings, fixed | Open · GitHub |
| Chronos Exchange Audit | Security firm: CertiK | Date: | Scope: Files named in the report | No open critical findings | Open · skynet.certik.com |
| Chronos Audit 2 | Security firm: CertiK | Date: | Scope: Files named in the report | No open critical findings | Open · skynet.certik.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 2 |
| High | 0 | 0 | 5 |
| Medium | 0 | 2 | 7 |
| Low | 13 | 0 | 13 |
There should always be events emitted in the sensitive functions that are controlled by centralization roles.
Open the reportThe function doesn't verify if the supplied `baseURI_` is a valid IPFS location.
Open the reportThe 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.
Open the reportPerforming integer division before multiplication truncates the low bits, losing the precision of calculation. ```solidity=235 rewardRate = reward.div(DURATION); ``` ```solidity=238 uint256 leftover = remaining.mul(rewardRate); ``` --- ```solidity=649 block_slope = (MULTIPLIER * (block.number - last_point.blk)) / (block.timestamp - last_point.ts); ``` ```solidity=679 last_point.blk = initial_last_point.blk + (block_slope * (t_i - initial_last_point.ts)) / MULTIPLIER; ``` --- ```solidity=778 _bonusPercent = minBonusPercent + ((maxBonusPercent - minBonusPercent)*(_bonusTime*PRECISSION/maxBonusTime))/PRECISSION; ``` --- ```solidity=100 uint _amountPerNFT = totalAirdrop/_totalSupply; ``` ```solidity=101 uint _amount = _ogMints * _amountPerNFT; ``` --- ```solidity=119 uint claimablePercent = (timeElapsedSinceStart*PRECISION)/VESTING_PERIOD; ``` ```solidity=121 userInfo.CHRClaimable = _totalCHR*claimablePercent/PRECISION - claimedCHR[_who]; ```
Open the reportIt is expected that calls of the form `transfer(recipient, amount)` and `transferFrom(from, dest, amount)` fail if the recipient address is zero address.
Open the reportThe contract `AirdropClaimChrNFT` imports `IERC20` interface from openzeppelin, however the contract `VotingEscrow` imports the same interface from "./interfaces/IERC20.sol". Thus, compiling contracts encounters an error: "DeclarationError: Identifier already declared.".
Open the reportWhen transferring deflationary ERC20 tokens, the input amount may not be equal to the received amount due to the charged transaction fee. For example, if a user sends 100 deflationary tokens (with a 10% transaction fee), only 90 tokens actually arrived to the contract. However, a failure to discount such fees may allow the same user to withdraw 100 tokens from the contract, which causes the contract to lose 10 tokens in such a transaction. Reference: https://thoreum-finance.medium.com/what-exploit-happened-today-for-gocerberus-and-garuda-also-for-lokum-ybear-piggy-caramelswap-3943ee23a39f ```solidity=225 IERC20(_rewardsToken).safeTransferFrom(msg.sender,address(this),reward); ``` - Transferring tokens by `reward`. ```solidity=235 rewardData[_rewardsToken][_startTimestamp].rewardsPerEpoch = _lastReward + reward; ``` - The `reward` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=156 _deposit(amount, msg.sender); ``` - Transferring tokens by `amount`. - This function call executes the following operation. - In `GaugeV2._deposit`, - `TOKEN.safeTransferFrom(account, address(this), amount);` ```solidity=156 _deposit(amount, msg.sender); ``` - This function call executes the following operation. - In `GaugeV2._deposit`, - `_totalSupply = _totalSupply.add(amount);` - In `SafeMath.add`, - `return a + b;` - The `amount` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=232 rewardToken.safeTransferFrom(DISTRIBUTION, address(this), reward); ``` - Transferring tokens by `reward`. ```solidity=239 rewardRate = reward.add(leftover).div(DURATION); ``` - This function call executes the following operation. - In `SafeMath.add`, - `return a + b;` - The `reward` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=809 assert(IERC20(token).transferFrom(from, address(this), _value)); ``` - Transferring tokens by `_value`. ```solidity=819 emit Supply(supply_before, supply_before + _value); ``` - The `_value` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=842 _deposit_for(_tokenId, _value, 0, _locked, DepositType.DEPOSIT_FOR_TYPE); ``` - Transferring tokens by `_value`. - This function call executes the following operation. - In `VotingEscrow._deposit_for`, - `assert(IERC20(token).transferFrom(from, address(this), _value));` ```solidity=842 _deposit_for(_tokenId, _value, 0, _locked, DepositType.DEPOSIT_FOR_TYPE); ``` - This function call executes the following operation. - In `VotingEscrow._deposit_for`, - `emit Supply(supply_before, supply_before + _value);` - The `_value` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=860 _deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.CREATE_LOCK_TYPE); ``` - Transferring tokens by `_value`. - This function call executes the following operation. - In `VotingEscrow._deposit_for`, - `assert(IERC20(token).transferFrom(from, address(this), _value));` ```solidity=860 _deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.CREATE_LOCK_TYPE); ``` - This function call executes the following operation. - In `VotingEscrow._deposit_for`, - `emit Supply(supply_before, supply_before + _value);` - The `_value` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=869 return _create_lock(_value, _lock_duration, msg.sender); ``` - Transferring tokens by `_value`. - This function call executes the following operation. - In `VotingEscrow._create_lock`, - `_deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.CREATE_LOCK_TYPE);` - In `VotingEscrow._deposit_for`, - `assert(IERC20(token).transferFrom(from, address(this), _value));` ```solidity=869 return _create_lock(_value, _lock_duration, msg.sender); ``` - This function call executes the following operation. - In `VotingEscrow._create_lock`, - `_deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.CREATE_LOCK_TYPE);` - In `VotingEscrow._deposit_for`, - `emit Supply(supply_before, supply_before + _value);` - The `_value` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=877 return _create_lock(_value, _lock_duration, _to); ``` - Transferring tokens by `_value`. - This function call executes the following operation. - In `VotingEscrow._create_lock`, - `_deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.CREATE_LOCK_TYPE);` - In `VotingEscrow._deposit_for`, - `assert(IERC20(token).transferFrom(from, address(this), _value));` ```solidity=877
Open the reportThe function `createPair` can be called by anyone as it has no access restriction. This enables anyone to call this and create a swap pair. In addition, there isn't a whitelist to control swap token types. The swap pool does not support deflationary tokens, users may create a swap pool for deflationary tokens by mistake. Furthermore, malicious users may create swap pools for scam tokens.
Open the reportThe `_transfer` function lacks a check to ensure the token sender has sufficient balance. Therefore, if the sender's balance is insufficient, the token transfer process will be reverted with the error message "Arithmetic over/underflow", which does not accurately describe the issue.
Open the reportThe contract is serving as the underlying entity to interact with one or more third party protocols. The scope of the audit treats third party entities as black boxes and assume their functional correctness. However, in the real world, third parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of third parties can possibly create severe impacts, such as increasing fees of third parties, migrating to new LP pools, etc. ```solidity=38 address public gaugeRewarder; ``` - The contract `GaugeV2` interacts with third party contract with `IRewarder` interface via `gaugeRewarder`. --- ```solidity=38 IRewardsDistributor public _rewards_distributor; ``` - The contract `MinterUpgradeable` interacts with third party contract with `IRewardsDistributor` interface via `_rewards_distributor`. --- ```solidity=35 address public immutable token0; ``` - The contract `Pair` interacts with third party contract with `IERC20` interface via `token0`. --- ```solidity=36 address public immutable token1; ``` - The contract `Pair` interacts with third party contract with `IERC20` interface via `token1`.
Open the reportThe `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=27 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `GaugeV2` contract. ```solidity=134 return rewardPerTokenStored.add(lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply)); ``` - `SafeMath.sub` is called in `rewardPerToken` function of `GaugeV2` contract. *Note: Only a sample of 2 `SafeMath` library usage in this contract (out of 23) are shown above.* --- ```solidity=13 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `MasterChef` contract. ```solidity=118 uint256 timeLeft = lastDistributedTime.sub(block.timestamp); ``` - `SafeMath.sub` is called in `setDistributionRate` function of `MasterChef` contract. *Note: Only a sample of 2 `SafeMath` library usage in this contract (out of 21) are shown above.*
Open the reportOne or more logic contracts do not protect their initializers. An attacker can call the initializer and assume ownership of the logic contract, whereby he can perform privileged operations that trick unsuspecting users into believing that he is the owner of the upgradeable contract. ```solidity=15 contract MinterUpgradeable is IMinter, OwnableUpgradeable { ``` - `MinterUpgradeable` is an upgradeable contract that does not protect its initializer. ```solidity=44 function initialize( ``` - `initialize` is an unprotected initializer function. --- ```solidity=21 contract VoterV2_1 is IVoter, OwnableUpgradeable, ReentrancyGuardUpgradeable { ``` - `VoterV2_1` is an upgradeable contract that does not protect its initializer. ```solidity=69 function initialize(address __ve, address _factory, address _gauges, address _bribes) initializer public { ``` - `initialize` is an unprotected initializer function. --- ```solidity=21 contract VotingEscrow is Initializable, IERC721Upgradeable, IERC721MetadataUpgradeable, IVotesUpgradeable { ``` - `VotingEscrow` is an upgradeable contract that does not protect its initializer. ```solidity=111 function initialize( ``` - `initialize` is an unprotected initializer function. --- ```solidity=12 contract BribeFactoryV2 is OwnableUpgradeable { ``` - `BribeFactoryV2` is an upgradeable contract that does not protect its initializer. ```solidity=17 function initialize(address _voter) initializer public { ``` - `initialize` is an unprotected initializer function. --- ```solidity=13 contract GaugeFactoryV2 is IGaugeFactory, OwnableUpgradeable { ``` - `GaugeFactoryV2` is an upgradeable contract that does not protect its initializer. ```solidity=18 function initialize() initializer public { ``` - `initialize` is an unprotected initializer function. --- ```solidity=9 contract PairFactoryUpgradeable is IPairFactory, OwnableUpgradeable { ``` - `PairFactoryUpgradeable` is an upgradeable contract that does not protect its initializer. ```solidity=40 function initialize() initializer public { ``` - `initialize` is an unprotected initializer function.
Open the reportThe 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.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="chronos-exchange"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
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