Edge Matrix Computing security record

Arbitrum, BNB Chain, Ethereumemc.networkXGitHub

As of 3 Nov 2026, Edge Matrix Computing has 2 audit reports by 1 security firm on Trustblock; the latest is by CertiK, dated 15 Oct 2024. Those reports list no open critical findings.

Critical findings
No open critical findings
Across the 2 reports, 2 critical findings were reported. Each is marked fixed by the firm that reported it. See the findings
Open the latest report
Your label, live
Get the label for your site

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

Audits2

Newest first

AuditSecurity firmDateScopeCritical findingsReport
EMC Finance & BridgeSecurity firm: CertiKDate: Scope: Files named in the report1 critical finding, fixedOpen · skynet.certik.com
EdgeMatrix Computing Protocol 2(EMC 2)Security firm: CertiKDate: Scope: Files named in the report1 critical finding, fixedOpen · skynet.certik.com

Findings61

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

SeverityOpenAcknowledgedFixed
Critical002
High144
Medium034
Low13030
CriticalNFT can be stolen during bridgingEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

```sol=68 function burnERC721(address tokenAddress, uint256 tokenID) internal { ERC721MinterBurnerPauser erc721 = ERC721MinterBurnerPauser(tokenAddress); erc721.burn(tokenID); } ``` `ERC721Safe.burnERC721(tokenAddress, tokenID)` is called by `ERC721Handler.deposit()` if `_burnList[tokenAddress]`. It successfully burns NFT if `ERC721Handler` was approved by the token owner to transfer that NFT. However, after the user calls `ERC721.approve(ERC721Handler, tokenID)` the malicious actor can call `Bridge.deposit()` for that tokenID. As a result, the NFT will be burnt in favor of the malicious actor. So, all the bridged burnable NFT can be stolen.

Open the report
CriticalWeak Signature VerificationEdgeMatrix Computing Protocol 2(EMC 2) · CertiK · 2 Feb 2024Fixed

According to the design, anyone holding a signature issued by the manager can bind to a node and become the beneficiary of that node. Beneficiaries can deposit into the node and create vesting schedules for anyone. However, the current signature verification design cannot determine uniqueness and may have the following potential risks: 1. Signed messages are not properly verified with the current chain ID, thus allowing attackers to perform replay attacks across chains. Hardcoded or cached chain ID values are also vulnerable since a hard fork may occur and change the chain ID in the future. 2. The `_nodeId` is not used as a parameter, and there is no check to verify whether the node is already bound to a beneficiary. Although hackers cannot get more tokens out because stakers can only withdraw their own quota. However, this issue can be exploited to disrupt the normal stake/withdraw operations of the protocol. ```solidity modifier verifyAddressSigner(string memory nonce, bytes memory signature) { require(!verifiedState[nonce], "signature validation failed"); bytes32 messageHash = keccak256(abi.encodePacked(msg.sender, nonce)); require( manager == messageHash.toEthSignedMessageHash().recover(signature), "signature validation failed" ); verifiedState[nonce] = true; _; } ```

Open the report
High`fundERC721()` and `fundERC20()` allow blocking oEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

```solidity=21 function fundERC721(address tokenAddress, address owner, uint tokenID) public { IERC721 erc721 = IERC721(tokenAddress); erc721.transferFrom(owner, address(this), tokenID); } ``` `ERC721Safe.fundERC721()` and `ERC20Safe.fundERC20()` allow any person to transfer someone's tokens to the Handler address, if the user has approved the Handler contract. Since normal Bridge work requires the user to approve the Handler contract before tokens are deposited, this can be used by the malicious actor to block the Bridge functioning.

Open the report
HighToo small `quorumVotes()` and `proposalThreshold(EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

EMCFI token has `totalSupply` of 100 million tokens. ```sol=9 function quorumVotes() public pure returns (uint) { return 400000e18; } // 400,000 = 4% of Finance /// @notice The number of votes required in order for a voter to become a proposer function proposalThreshold() public pure returns (uint) { return 100000e18; } // 100,000 = 1% of Finance ``` 400_000e18 tokens is only 0.4% of the `totalSupply`, that is too little for quorum. The comment is also misleading.

Open the report
HighWrong Copy Size in assembly codeEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The copy size of calldata used in assembly of the function `ERC20Handler.deposit()` to copy the data of `recipientAddress` is mistakenly using the 0xE. Since the `recipientAddress` is placed at the end of calldata, so the correct copy size should be the `calldatasize - 0xE4`. `GenericHandler.deposit()` uses 0xC4 as a base metadata. However, the correct value is 0xA4 since the function has 4 arguments and the fifth is a dynamic data. `GenericHandler.executeProposal()` uses 0x64 as a base metadata. However, the correct value is 0x44 since the function has 1 argument and the second is a dynamic data. Wrong data parsing can lead to unexpected behavior including funds loss. The code comments are outdated and misleading.

Open the report
HighWrong result of `getFinanceAddress()`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

```sol=1334 function getFinanceAddress() public view returns (address) { // return 0xc00e94Cb662C3520282E6f5717214004A7f26888; } ``` `FinancetrollerG7.getFinanceAddress()` doesn't return a value.

Open the report
Medium`_deposit2()` logic differs from `deposit()`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

`Bridge.fallback()` permits deposits of native tokens. However: 1. Using `fallback()` instead of a function with a declared signature is not recommended. 2. The method approves the `erc20HandlerAddress` to transfer tokens, but subsequently uses `_resourceIDToHandlerAddress[resourceID]` as the handler. The `erc20HandlerAddress` is never validated and can be arbitrary. 3. The `fallback()` function can be invoked `whenPaused`, unlike `deposit()`. 4. Since `fallback()` uses `address(this)` as the sender/depositor, the Bridge's address is recorded in `_depositRecords` of the Handler instead of the `msg.sender`. 5. The logic within `fallback()` differs for testnet chain IDs as compared to `deposit()`. These issues can lead to unexpected behavior and potential security vulnerabilities.

Open the report
MediumERC721 Token May Be Transferred To A Contract ThaEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The [EIP-721 standard](https://github.com/ethereum/EIPs/blob/78e2c297611f5e92b6a5112819ab71f74041ff25/EIPS/eip-721.md?plain=1#L103-L113) says the following about `transferFrom()`: ```solidity /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE /// THEY MAY BE PERMANENTLY LOST /// @dev Throws unless `msg.sender` is the current owner, an authorized /// operator, or the approved address for this NFT. Throws if `_from` is /// not the current owner. Throws if `_to` is the zero address. Throws if /// `_tokenId` is not a valid NFT. /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer function transferFrom(address _from, address _to, uint256 _tokenId) external payable; ``` The function `lockERC721` transfers an ERC721 token to the input address via `transferFrom()`. This method does not check that the `recipient` is a contract, it is designed to support ERC721 tokens. If the `recipient` is a smart contract not designed to handle ERC721 tokens, they can become locked in the contract forever.

Open the report
MediumIncorrect `blocksPerYear` constant across chainsEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The constant like `blocksPerYear` inside the contract is often used for calculation on a per-block basis. But since different chain has different block interval, this constant should be different across chains and a careful check is required on this. `blocksPerYear = 2102400` means one block per 15 seconds. Expected value for Ethereum chain. The EMC chain produces a block every 2 seconds. ```sol=21 function votingPeriod() virtual public pure returns (uint) { return 17280; } // ~3 days in blocks (assuming 15s blocks) ``` Voting period and the comment are incorrect.

Open the report
MediumPotential Incorrect Start TimeEdgeMatrix Computing Protocol 2(EMC 2) · CertiK · 2 Feb 2024Fixed

According to the design, the node's beneficiary could create the vesting schedule through the `releaser` contract. The start time of the schedule is 15 minutes after the schedule is created. ```solidity releaser.createVestingSchedule( _beneficiary, block.timestamp + 15 * 60, 1, DurationUnits.Days30, _amount); ``` However, according to the design of contract `ReleaseVesingV1`, when `minStartDays` is greater than 0, the schedule will not be created successfully. ```solidity function createVestingSchedule( address _beneficiary, uint256 _start, uint256 _duration, DurationUnits _durationUnits, uint256 _amountTotal ) external { ... require( _start >= block.timestamp + minStartDays * 1 days, string.concat("VestingContract: invalid start time") ); ... } ```

Open the report
Show 10 more
Low`CentrifugeAsset` is never usedEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

`CentrifugeAsset` is never used. `store()` is unprotected and can be called by anyone.

Open the report
Low`ERC721Safe` should be `abstract`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

Contracts `HandlerHelpers`, `ERC721Safe`, and `ERC20Safe` are not supposed to be deployed. That is why they should be marked as `abstract`. ```sol=63 function withdraw(address tokenAddress, address recipient, uint256 amountOrTokenID) external virtual override {} ``` Empty function should be removed from the abstract class.

Open the report
Low`GenericHandler` should inherit from `IDepositExeEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The `GenericHandler` contract implements the `IDepositExecute` interface but does not inherit from it.

Open the report
Low`ProposalStatus` is casted to `uint`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

```sol=411 require(uint(proposal._status) <= 1, "proposal already passed/executed/cancelled"); ... if (uint(proposal._status) == 0) { ``` Casting `ProposalStatus` to uint is redundant and potentially misleading. We recommend directly using the enum values for clarity: * `require(proposal._status == ProposalStatus.Inactive || proposal._status == ProposalStatus.Active)` * `if (proposal._status == ProposalStatus.Inactive)`

Open the report
LowBad code adaptationEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

`FinancePriceOracle.financeareStrings()` and `FinanceLens.financeareStrings()` are supposed to be `compareStrings()`. ```sol=46 require(whitelisted[msg.sender], "Asset not whitelisted"); ``` The function is not called by the asset. ```sol=7 * @title Compound's CErc20Immutable Contract * @notice CTokens which wrap an EIP-20 underlying and are immutable * @author Compound ``` The comment is outdated. ```sol=174 case 32 { // This is a financeliant ERC-20 ``` "financeliant" is supposed to be "compliant".

Open the report
LowDeprecated Usage of `Counters.sol`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The linked contracts import and use OpenZeppelin's `Counters` contract. OpenZeppelin has deprecated the usage of the `Counters` contract: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/4233. `Counters` is also unused.

Open the report
LowIncorrect Role ManagementEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The direct usage of `grantRole` and `revokeRole` functions from the [AccessControl](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol) contract in functions with additional access control logic can lead to conflicts or redundant permissions. This is due to the requirement that the caller must have the admin role for the corresponding role to invoke these functions successfully. If the caller's role permissions are not properly set and synchronized with the role administration logic, it can result in inconsistencies and unintended access rights.

Open the report
LowInefficient Loop Over Memory Array in Contract `EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The `constructor` performs a loop over its supplied `initialRelayers` memory array while retrieving the length of the array over each iteration, which is inefficient: ```solidity for (uint256 i; i < initialRelayers.length; i++) { ``` The `transferFunds()` function performs a loop over its supplied `addrs` memory array while retrieving the length of the array over each iteration, which is inefficient: ```solidity for (uint i = 0; i < addrs.length; i++) { ```

Open the report
LowInefficient Memory ParameterEMC Finance & Bridge · CertiK · 15 Oct 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 the gas consumption copying from calldata to memory. ```solidity=44 function mint(address to, uint256 tokenId, string memory _data) public { ``` `mint` has memory location parameters: `_data`.

Open the report
LowLack Validation for Array LengthEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

There is no validation to check whether `addrs.length` and `amounts.length` are the same

Open the report
Show 10 more
LowLocal Variable ShadowingEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

Arguments `name`, `symbol`, `baseURI` are shadowing state fields in the base class. This means that when the contract accesses the variable by its name, it will use the one defined locally, not the one defined in the other place. The use of the variable may lead to unexpected results and unintended behavior. ```solidity=24 constructor(string memory name, string memory symbol, string memory baseURI) public ERC721(name, symbol) { ```

Open the report
LowMissing Check for Duplicate Role Assignment in BrEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The loop that assigns the `RELAYER_ROLE` to `initialRelayers` lacks a check to prevent reassigning the role to the same address multiple times. This could lead to an inaccurate count of relayers, as the `_totalRelayers` variable is incremented without verifying whether the address has already been assigned the role.

Open the report
LowMissing ChecksEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

### HandlerHelpers - The function `setResource()` does not check that `_resourceIDToContractAddress[resourceID]` and `_contractAddressToResourceID[contractAddress]` are not already set. - The function `setBurnable()` does not check if `_burnList[contractAddress]` is already true. ### GenericHandler - The function `setResource()` does not check that `_resourceIDToContractAddress[resourceID]`, `_contractAddressToResourceID[contractAddress]`, ` _contractAddressToDepositFunctionSignature[contractAddress]`, and `_contractAddressToExecuteFunctionSignature[contractAddress]` are not already set. - The functions `deposit()` and `executeProposal()` make a low level call to the `contractAddress`. While these are set via privileged roles, these contracts may self destructor or be set accidentally to EOA's, in which case the low level call will return true without executing any functionality. We recommend adding a check that the `contractAddress` is a contract. ### Bridges - The function `adminChangeRelayerThreshold()` does not check that the input `newThreshold` is greater than or equal to some minimum. In particular, the threshold should always be at least one, as a proposal must be proposed (which yields one yes vote). - The function `setHandlerAdress()` does not check if the input `_handlerAddress` is different from the zero address. - The function `adminChangeFee()` does not check that the input `newFee` is within some bounds. In particular, if a fee should always be charged the input should be greater than zero and the fee may not want to exceed a theoretical maximum amount. - In the `Bridge.executeProposal()` function, the potential expiration of a proposal is not checked. If `proposal._status == ProposalStatus.Passed` and `block.number - proposal._proposedBlock > _expiry`. A relayer can decide to execute a proposal. - In the `Bridge.cancelProposal()` function, the potential execution of a proposal is not checked. If `block.number - proposal._proposedBlock > _expiry`. A relayer or the admin can decide to cancel an already executed proposal. - The functions `adminSetResource()` and `adminSetGenericResource()` don't check that the `handlerAddress` was not yet set for `resourceID`.

Open the report
LowMissing Zero Address ValidationEMC Finance & Bridge · CertiK · 15 Oct 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=167 erc20HandlerAddress = _handlerAddress; ``` - `_handlerAddress` is not zero-checked before being used. ```solidity=122 WETH_ADDRESS = wethAddress; ``` - `wethAddress` is not zero-checked before being used. ```solidity=122 WEMC_ADDRESS = wemcAddress; ``` - `wemcAddress` is not zero-checked before being used. ```solidity=50 _bridgeAddress = bridgeAddress; ``` - `bridgeAddress` is not zero-checked before being used. ```solidity=81 _bridgeAddress = bridgeAddress; ``` - `bridgeAddress` is not zero-checked before being used. ```solidity=57 _bridgeAddress = bridgeAddress; ``` - `bridgeAddress` is not zero-checked before being used.

Open the report
LowOptimization in `Bridge.executeProposal()`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

In `Bridge.executeProposal()`, the following checks: ```solidity=495 require(proposal._status != ProposalStatus.Inactive, "proposal is not active"); require(proposal._status == ProposalStatus.Passed, "proposal already transferred"); ``` are both checking the status of a proposal, since a proposal cannot be `Inactive` and `Passed` the first **require** statement is redundant. Moreover, a proposal not passed can be `Inactive`, `Active`, `Executed` or `Cancelled`, therefore the error message `"proposal already transferred"` is not always accurate.

Open the report
LowPotential Inconsistency In `_totalRelayers`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

In the contract `Bridge.sol`, state variable `_totalRelayers` is supposed to reflect the numbers of current relayers in the contract. However, it is possible to update the relayer without accurately updating `_totalRelayers` leading to inconsistencies.

Open the report
LowPotential Underflow/OverflowEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

In `Bridge.adminRemoveRelayer()`, `_totalRelayers` is decremented. Due to potential inconsistency between `_totalRelayers` and the real number of relayers, an underflow can occur.

Open the report
LowRedundant codeEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

- `FinanceLens.Double` declaration is never used. ```sol=768 struct Exp { uint mantissa; } mapping(address => FinanceMarketState) public financeSupplyState; mapping(address => mapping(address => uint)) public financeSupplierIndex; uint224 public constant financeInitialIndex = 1e36; ``` The fields and the `FinanceMarketState` declaration are not used.

Open the report
LowRisk of Losing Admin Access If The Input New AdmiEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

If the address `newAdmin` to be set as the admin role is the same as the current admin `msg.sender`, it will result in the admin role losing its administration authorization over the contract. This vulnerability arises because the function first grants the admin role to the new owner's address and then revokes the admin role from the current admin's address. However, suppose the new owner's address is the same as the current one. In that case, the admin role will be revoked, leading to the admin losing the authorization for contract administration.

Open the report
LowTyposEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

There are typos and outdated comments: - "custoday" is supposed to be "custody" - "delegatecall" is supposed to be "call" ```sol=457 @notice Executes a deposit proposal that is considered passed using a specified handler contract. @notice Only callable by relayers when Bridge is not paused. ``` - In fact the `cancelProposal()` cancels the proposal, not executes. It can also be called by admin, not only relayers. It can be called even if Bridge is paused. - "amonuts" is supposed to be "amounts"

Open the report
Show 10 more
LowUnnecessary modifierEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

In functions `Bridge.renounceAdmin()`, `Bridge.adminAddRelayer()`, `Bridge.adminRemoveRelayer()` the use of `onlyAdmin` modifier is redundant since the same check is made by functions inherited from `AccessControl`.

Open the report
LowUnsafe Type CastingEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

Type casting refers to changing a variable of one data type into another. The code contains an unsafe cast between integer types, which may result in unexpected truncation of the recipient address. ```sol=151 uint8(lenDestinationRecipientAddress), uint8(destinationChainID), ``` ```sol=175 recipientAddress := mload(add(destinationRecipientAddress, 0x20)) ``` The `destinationRecipientAddress` is implicitly truncated to `bytes20`. No data size check is performed.

Open the report
LowUsage of `transfer()` for sending EtherEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

It is not recommended to use Solidity's `transfer()` and `send()` functions for transferring native tokens, since some contracts may not be able to receive the funds. Those functions forward only a fixed amount of gas (2300 specifically) and the receiving contracts may run out of gas before finishing the transfer. Also, EVM instructions' gas costs may increase in the future. Thus, some contracts that can receive now may stop working in the future due to the gas limitation. ```solidity=36 msg.sender.transfer(amount); ``` - `WETH.withdraw` uses `transfer()`. ```solidity=34 payable(msg.sender).transfer(amount); ``` - `WEMC.withdraw` uses `transfer()`. ```solidity=515 addrs[i].transfer(amounts[i]); ``` - `Bridge.transferFunds` uses `transfer()`.

Open the report
LowUse `_safeMint` instead of `_mint`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

According to openzepplin's ERC721, the use of `_mint` is discouraged, use _safeMint whenever possible.

Open the report
LowUseless `_noVotes` in Struct `Proposal`EMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

When the relayers vote for the proposals, they can only vote `yes`. So it is useless to have a `_noVotes`. ```solidity struct Proposal { bytes32 _resourceID; bytes32 _dataHash; address[] _yesVotes; address[] _noVotes; ProposalStatus _status; uint256 _proposedBlock; } ```

Open the report
LowUser-Defined GettersEMC Finance & Bridge · CertiK · 15 Oct 2024Fixed

The linked functions are equivalent to the compiler-generated getter functions for the respective variables.

Open the report
LowCheck-Effects-Interactions Pattern ViolationEdgeMatrix Computing Protocol 2(EMC 2) · CertiK · 2 Feb 2024Fixed

This [Checks-Effects-Interactions Pattern](https://docs.soliditylang.org/en/latest/security-considerations.html#use-the-checks-effects-interactions-pattern) is a best practice for writing secure smart contracts that involves performing all state changes before making any external function calls. ### External call(s) ```solidity=168 token.safeTransferFrom(msg.sender, address(this), _amount); ``` * This function call executes the following external call(s). * In `SafeERC20._callOptionalReturn`, * `returndata = address(token).functionCall(data,"SafeERC20: low-level call failed")` * In `Address.functionCallWithValue`, * `(success,returndata) = target.call{value: value}(data)` ### State variables written after the call(s) ```solidity=169 node.amount = node.amount.add(_amount); ``` ```solidity=170 node.accumulated = node.accumulated.add(_amount); ``` --- ### External call(s) ```solidity=217 SafeERC20.safeIncreaseAllowance(token, releaseContract, _amount); ``` * This function call executes the following external call(s). * In `SafeERC20._callOptionalReturn`, * `returndata = address(token).functionCall(data,"SafeERC20: low-level call failed")` * In `Address.functionCallWithValue`, * `(success,returndata) = target.call{value: value}(data)` ```solidity=219 releaser.createVestingSchedule( _beneficiary, block.timestamp + 15 * 60, 1, DurationUnits.Days30, _amount ); ``` ### State variables written after the call(s) ```solidity=227 node.amount = node.amount.sub(_amount); ``` ```solidity=229 node.debt = node.debt.add(_amount); ```

Open the report
LowIncompatible with USDT transferEdgeMatrix Computing Protocol 2(EMC 2) · CertiK · 2 Feb 2024Fixed

`USDT` is a non-standard `ERC20` token, its `transfer` and `transferFrom` functions do not yield a return value. If the input token refers to `USDT`, any attempt to transfer `USDT` using these functions will result in a revert.

Open the report
LowLack of Sanity ChecksEdgeMatrix Computing Protocol 2(EMC 2) · CertiK · 2 Feb 2024Fixed

The `setLimit()` function lacks of sanity check, the `minLimit` represents minimum amount of a single deposit, and `maxLimit` represents the upper limit of the node balance (if `maxLimit` is 0, it means there is no limit). If `maxLimit` is set less than `minLimit` (maxLimit is not 0), deposits will not be possible. ```solidity function setLimit(uint256 _minLimit, uint256 _maxLimit) public onlyManager { minLimit = _minLimit; maxLimit = _maxLimit; } ```

Open the report
LowMissing Zero Address ValidationEdgeMatrix Computing Protocol 2(EMC 2) · CertiK · 2 Feb 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. **MerkleClaim.sol** ```solidity=468 token = token_; ``` - `token_` is not zero-checked before being used. **NodeStake.sol** ```solidity=122 token = IERC20(_token); ``` - `_token` is not zero-checked before being used. --- ```solidity=123 releaseContract = _releaseContract; ``` - `_releaseContract` is not zero-checked before being used. --- ```solidity=124 manager = _manager; ``` --- ```solidity=143 manager = _manager; ``` - `_manager` is not zero-checked before being used, the signature verification fails because `ECDSA.recover()` never returns a 0 address.

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and 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="edge-matrix-chain"
></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