Kroma security record

As of 3 Nov 2026, Kroma has 3 audit reports by 1 security firm on Trustblock; the latest is by CertiK, dated 3 Dec 2024. Those reports list no open critical findings. It also holds 1 deployed contract on 1 chain.

Critical findings
No open critical findings
Across 3 reports.
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits and findings, contracts and incidents up to Nov 2026. Trustblock does not review code.

Audits3

Newest first

AuditSecurity firmDateScopeCritical findingsReport
Kroma Network - Token AuditSecurity firm: CertiKDate: Scope: 1 address on EthereumNo open critical findingsOpen · skynet.certik.com
Spectrum Protocol - Audit(Addendum)Security firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com
Spectrum Protocol - AuditSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com

Findings38

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

SeverityOpenAcknowledgedFixed
Critical000
High060
Medium134
Low14010
MediumMissing Check for whether `asset` is a support AsSpectrum Protocol - Audit(Addendum) · CertiK · 13 May 2024Fixed

In the `stake()` and `unstake()` functions, there is no check to ensure that the asset is a supported asset. As a result, a user can stake any asset for the first time (`spTotalSupply == 0`) and receive the `spETH` token. However, if another user attempts to stake with the correct asset, the `stake()` function will revert due to a division by zero error because the contract's asset balance is zero. ```solidity =166 function _getSpectrumFromAsset( SnapGlobal memory gSnap, address asset, uint256 assetAmount ) internal view returns (uint256 spAmount) { CoreSupportAssetInfo memory assetInfo = _getSpectrumCoreStorage().assetInfos[asset]; uint256 spTotalSupply = gSnap.info.spETH.totalSupply(); if (spTotalSupply == 0) return assetAmount; spAmount = (spTotalSupply * _switchAssetEval(assetInfo.id)(assetInfo.assetEvaluator, assetAmount)) / gSnap.spSnap.evalValue; } ```

Open the report
MediumCalling the function `setIndexEvalRate()` fails iSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

In the function `setIndexEvalRate()`, if the `evalRate` is not zero, the function will revert. This means the function only sets the `evalRate` to 0. However, according to the function `setIndexToken()`, if the `evalRate` is set to 0, the `idxAddrs` should be removed from `idxAssetList` and `feeConfigs` should be deleted. ```solidity=158 function setIndexEvalRate(address[] memory idxAddrs, Ubp[] memory evalRates) public onlyAdmin { SpectrumCoreStorage storage $ = _getSpectrumCoreStorage(); if (idxAddrs.length != evalRates.length) revert Spectrum(SpectrumErrors.Length); for (uint256 i; i < idxAddrs.length; i++) { if (!evalRates[i].isZero()) revert Spectrum(SpectrumErrors.RateZero); $.idxAssetConfigs[idxAddrs[i]].evalRate = evalRates[i]; } } ```

Open the report
MediumIncorrect token approveSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

In the function `_stakeReceiveFrom()`, if the `requestedAsset` is `address(0)`, `idxAsset` is assigned the value of `$.underlyingToIdx[$.info.fundUnderlying]`, the function `wrap()` transfers `fundUnderlying` to the `idxAsset` contract while minting `idxAsset` tokens to the contract. Therefore, the contract should increase the allowance of `fundUnderlying` token instead of `idxAsset` token for the `idxAsset` contract. Additionally, the user does not transfer any tokens to the contract. ```solidity=153 if (requestedAsset == address(0)) { idxAsset = $.underlyingToIdx[$.info.fundUnderlying]; IEcoERC20(idxAsset).safeIncreaseAllowance(idxAsset, amount); idxAmount = IidxAssetWrapper(idxAsset).wrap(amount); } ```

Open the report
MediumPotentially, `idxAsset` and `idxAmount` may be ovSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

In the function `_stakeReceiveFrom()`, if the `requestedAsset` is `address(0)`, `idxAsset` is assigned the value of `$.underlyingToIdx[$.info.fundUnderlying]` and `idxAmount` is assigned the value of the `wrap` function of the `idxAsset`'. However, the function is not terminated and returned. Therefore, `idxAsset` may be overridden with `address(0)` if the `$.underlyingToIdx[requestedAsset]` returns `address(0)`. Once the `$.idxAssetList` does not contain `address(0)`, the function will revert. ```solidity=146 function _stakeReceiveFrom( address requestedAsset, address from, uint256 amount ) internal returns (address idxAsset, uint256 idxAmount) { SpectrumCoreStorage storage $ = _getSpectrumCoreStorage(); if (requestedAsset == address(0)) { idxAsset = $.underlyingToIdx[$.info.fundUnderlying]; IEcoERC20(idxAsset).safeIncreaseAllowance(idxAsset, amount); idxAmount = IidxAssetWrapper(idxAsset).wrap(amount); } idxAsset = $.underlyingToIdx[requestedAsset]; if (idxAsset == address(0)) { idxAsset = requestedAsset; idxAmount = amount; if (!$.idxAssetList.contains(idxAsset)) revert Spectrum(SpectrumErrors.NotExist); IEcoERC20(idxAsset).safeTransferFrom(from, address(this), idxAmount); } else { // should wrap IEcoERC20(requestedAsset).safeTransferFrom(from, address(this), amount); IEcoERC20(requestedAsset).safeIncreaseAllowance(idxAsset, amount); idxAmount = IidxAssetWrapper(idxAsset).wrap(amount); } } ```

Open the report
LowMissing Zero Address ValidationKroma Network - Token Audit · CertiK · 3 Dec 2024Fixed

The cited address input is missing a check that it is not `address(0)`.

Open the report
LowMissing Check to verify whether the asset existSpectrum Protocol - Audit(Addendum) · CertiK · 13 May 2024Fixed

The function `updateCoreSupportAsset()` updates asset info, but there is no check to ensure the asset exists. Therefore, if the asset does not exist, it is not added to the `supportAssets`, leading to inconsistency.

Open the report
LowReceived ETH will be lockedSpectrum Protocol - Audit(Addendum) · CertiK · 13 May 2024Fixed

The contract `SpectrumCoreEntry` has a `receive()` function to receive ETH, but there is no function to withdraw them. Thus, every ETH sent to the contract will be lost.

Open the report
LowIncompatibility with Deflationary TokensSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

When 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.

Open the report
LowInefficient Memory ParameterSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

One or more parameters with `memory` data location are never modified in their functions and those functions are never called internally within the contract. Thus, their data location can be changed to `calldata` to avoid gas consumption copying from `calldata` to memory. ```solidity=13 function functionCallWithValue( ``` `functionCallWithValue` has memory location parameters: `data`. --- ```solidity=25 function functionDelegateCall(address target, bytes memory data) external payable returns (bytes memory); ``` `functionDelegateCall` has memory location parameters: `data`.

Open the report
LowInit Functions Are Susceptible To Front-runningSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

The `initialize()` functions below are not called by another contract atomically after the contract is deployed, so it's possible for a malicious user to call `initialize()` which, if it's noticed in time, would require the project to re-deploy the contract in order to properly initialize.

Open the report
Show 4 more
LowMissing Zero Address ValidationSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

Addresses are not validated before assignment or external calls, potentially allowing the use of zero addresses and leading to unexpected behavior or vulnerabilities. For example, transferring tokens to a zero address can result in a permanent loss of those tokens. ```solidity=74 (success, data) = to.call{ value: value }(data); ``` - `to` is not zero-checked before being used.

Open the report
LowPotential Underflow ErrorSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

In the function `checkAscendingAddresses()`, if the `addresses` array is empty, it would cause an underflow error. ```solidity=168 function checkAscendingAddresses(address[] memory addresses) public pure { unchecked { uint256 len = addresses.length - 1; for (uint256 i; i < len; i++) { if (!(addresses[i] < addresses[i + 1])) revert Spectrum(SpectrumErrors.Sort); } } } ```

Open the report
LowTest Code should be RemovedSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

The contracts `TestProxyAdminFail` and `TestEcoOwnable` are named with a prefix of `Test`, which suggests that they may be test codes.

Open the report
LowUnsafe Integer CastSpectrum Protocol - Audit · CertiK · 3 Apr 2024Fixed

Type casting refers to changing an variable of one data type into another. The code contains an unsafe cast between integer types, which may result in unexpected truncation or sign flipping of the value. ```solidity=32 return Ubp.wrap(uint32(Ibp.unwrap(bp))); ``` Casted expression `Ibp.unwrap(bp)` has estimated range [-2147483648, 2147483647] but target type `uint32` has range [0, 4294967295]. --- ```solidity=105 return Ibp.wrap(int32(uint32(underlying))); ``` Casted expression `uint32(underlying)` has estimated range [0, 4294967295] but target type `int32` has range [-2147483648, 2147483647]. --- ```solidity=105 return Ibp.wrap(int32(uint32(underlying))); ``` Casted expression `underlying` has estimated range [0, 115792089237316195423570985008687907853269984665640564039457584007913129639935] but target type `uint32` has range [0, 4294967295]. --- ```solidity=109 return Ibp.wrap(int32(underlying)); ``` Casted expression `underlying` has estimated range [-57896044618658097711785492504343953926634992332820282019728792003956564819968, 57896044618658097711785492504343953926634992332820282019728792003956564819967] but target type `int32` has range [-2147483648, 2147483647]. --- ```solidity=117 return int32(Ubp.unwrap(bp)); ``` Casted expression `Ubp.unwrap(bp)` has estimated range [0, 4294967295] but target type `int32` has range [-2147483648, 2147483647]. --- ```solidity=146 return (unwrap(a) * int256(b)) / IbpBase; ``` Casted expression `b` has estimated range [0, 115792089237316195423570985008687907853269984665640564039457584007913129639935] but target type `int256` has range [-57896044618658097711785492504343953926634992332820282019728792003956564819968, 57896044618658097711785492504343953926634992332820282019728792003956564819967].

Open the report

Contracts1

AddressChainSource code
0xf1af9d897956434e5d7bd875fd231e044890c897Chain: EthereumSource code: Verified source

All 1 address and the files the reports name

Show this on your site

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.

Content

Facts

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.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="kroma-network"
></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