OpenMRV Audit Report
Copyright © 2022 by Verilog Solutions. All rights reserved.September 16, 2022
by Verilog Solutions

This report presents our engineering engagement with the OpenMRV dev team on their hashing system on the Celo network.
Project Name | OpenMRV |
---|---|
Repository Link | https://github.com/MRV-Studio/openmrv-contract https://github.com/MRV-Studio/openmrv-server |
Commit Hash | openmrv-contract: 0238e4a; openmrv-server: cf60350; |
Language | Solidity |
Chain | Celo |
About Verilog Solutions
About Verilog Solutions
Founded by a group of cryptography researchers and smart contract engineers in North America, Verilog Solutions elevates the security standards for Web3 ecosystems by being a full-stack Web3 security firm covering smart contract security, consensus security, and operational security for Web3 projects.
Verilog Solutions team works closely with major ecosystems and Web3 projects and applies a quality above quantity approach with a continuous security model. Verilog Solutions onboards the best and most innovative projects and provides the best-in-class advisory services on security needs, including on-chain and off-chain components.
Table of Contents
Table of Contents
Service Scope
Service Scope
Service Stages
Service Stages
- Architecture Consultancy Service
- Protocol Security & Design Discussion Meeting
- As a part of the audit service, the Verilog Solutions team worked closely with the OpenMRV development team to discuss potential vulnerability and smart contract development best practices in a timely fashion. Verilog Solutions team is very appreciative of establishing an efficient and effective communication channel with the OpenMRV team, as new findings were exchanged promptly and fixes were deployed quickly, during the preliminary report stage.
- Protocol Security & Design Discussion Meeting
- Smart Contract Auditing Service
- The Verilog Solutions team analyzed the entire project using a detailed-oriented approach to capture the fundamental logic and suggested improvements to the existing code. Details can be found under Findings & Improvement Suggestions.
Methodology
Methodology
- Code Assessment
- We evaluate the overall quality of the code and comments as well as the architecture of the repository.
- We help the project dev team improve the overall quality of the repository by providing suggestions on refactorization to follow the best practice of Web3 software engineering.
- Code Logic Analysis
- We dive into the data structures and algorithms in the repository and provide suggestions to improve the data structures and algorithms for the lower time and space complexities.
- We analyze the hierarchy among multiple modules and the relations among the source code files in the repository and provide suggestions to improve the code architecture with better readability, reusability, and extensibility.
- Access Control Analysis
- We perform a comprehensive assessment of the special roles of the project, including their authorities and privileges.
- We provide suggestions regarding the best practice of privilege role management according to the standard operating procedures (SOP).
- Off-Chain Components Analysis
- We analyze the off-chain modules that are interacting with the on-chain functionalities and provide suggestions according to the SOP.
- We conduct a comprehensive investigation for potential risks and hacks that may happen on the off-chain components and provide suggestions for patches.
Audit Scope
Audit Scope
File |
openmrv-server/src/controller/*.ts |
openmrv-server/src/exception/*.ts |
openmrv-server/src/interface/*.ts |
openmrv-server/src/middleware/*.ts |
openmrv-server/src/model/*.ts |
openmrv-server/src/service/*.ts |
openmrv-server/src/test/*.ts |
openmrv-server/src/util/*.ts |
openmrv-server/src/http-app.ts |
openmrv-server/src/mongo.ts |
openmrv-server/src/server.ts |
openmrv-contract/contracts/GeodataAnchor.sol |
Project Summary
Project Summary
OpenMRV is a protocol that allows to store the summarized hashes produced by the provider’s input measurement data on the CELO network. The main components of this protocol and their uses are the following:
- openmrv-server is a provider data ingestion layer with authentication and authorization for provider users.
- openmrv-server acts as an adapter layer, normalizing and hashing posted inbound data from providers, storing in MongoDB Atlas time series collection, and returning the hash of measurement data.
- openmrv-anchor runs independently as a daemon to create a summary hash (anchor) of above hashes, stores it in MongoDB Atlas, and on the CELO contract.
- openmrv-validator runs independently as a daemon to validate the anchoring process above, and record results of validation, reporting any exceptions.
- openmrv-query will expose data to consumers, integrated with Ocean protocol.

OpenMRV System Architecture
The OpenMRV protocol is integrated by off-chain (openmrv-server) and on-chain (openmrv-contract) components. The server is able to call the on-chain contract to store the anchors (summarized hashes) on the CELO network. A more detailed description of these two elements can be found below:
openmrv server
contains the logic for the off-chain components.
This component mainly has the following functionality:
- Allow provider users to authenticate and authorize their measurement data to be used.
- Store the time series collection in MongoDB Atlas.
- Create a summary hash (anchor) from the
geots
hashes (contain information about the time series, metadata, measurements, etc).
- Add the anchor to the CELO contract.
- Validate that the anchor meets certain criteria.
contains the logic for the on-chain components.
openmrv contract
This component mainly has the following functionality:
- Add summarized data hashes to the contract on the CELO network.
- Get summarized data hashes that have already been added to the contract.
Use Case Scenario
Use Case Scenario
OpenMRV is a hashing system that allows summarizing measurement data for subsequent analysis and analytics. This protocol is integrated by both on-chain and off-chain logic, it stores the original information in MongoDB Atlas and the summarized data hashes in the smart contract deployed on the CELO network.
Findings & Improvement Suggestions
Findings & Improvement Suggestions
Severity | Total | Acknowledged | Resolved |
High | 0 | 0 | 0 |
Medium | 0 | 0 | 0 |
Low | 1 | 1 | 1 |
Informational | 2 | 2 | 2 |
High
High
None ; )
Medium
Medium
None ; )
Low
Low
- Should add non-zero check for
_hash
Severity Low File GeodataAnchor.sol#L25; Commit 0238e4a; Status Resolved in commit 785ce9f; Description
The function
addAnchor()
does not check if the_hash
is empty. Non-zero check should be added for it.
Exploit Scenario
N/A
Recommendations
add the following require statement.
require(_hash != 0, "Empty hash");
Results
Resolved in commit 785ce9f.
Informational
Informational
memory
can be used ingetAnchor()
Severity Informational File GeodataAnchor.sol#L15; Commit 0238e4a; Status Resolved in commit 785ce9f; Description
memory
can be used ingetAnchor()
to fectch struct from the mapping.getAnchor()
is a view function which does not make changes to the storage of the contract. So Anchor struct can be fetched withmemory
keyword instead ofstorage
.function getAnchor(string memory _id) public view returns (bytes32) { Anchor storage anchor = anchors[_id]; if (anchor.hash == 0) { revert("Anchor not found"); } return anchor.hash; }
Exploit Scenario
N/A
Recommendations
function getAnchor(string memory _id) public view returns (bytes32) { Anchor memory anchor = anchors[_id]; if (anchor.hash == 0) { revert("Anchor not found"); } return anchor.hash; }
Results
Resolved in commit 785ce9f.
- No need to create two instances of Anchor struct in
addAnchor()
Severity Informational File GeodataAnchor.sol#L25; Commit 0238e4a; Status Resolved in commit 785ce9f. Description
The
addAnchor()
function creates two instance of Anchor struct, which can be optimized.function addAnchor(string memory _id, bytes32 _hash) public onlyOwner { // see if anchor already exists Anchor storage anchor = anchors[_id]; require(anchor.hash == 0, "Anchor id already exists"); Anchor memory newAnchor = Anchor(_hash); anchors[_id] = newAnchor; }
Exploit Scenario
N/A
Recommendations
function addAnchor(string memory _id, bytes32 _hash) public onlyOwner { Anchor memory anchor = anchors[_id]; require(anchor.hash == 0, "Anchor id already exists"); require(_hash != 0, "Empty hash"); anchor.hash = _hash; anchors[_id] = anchor; }
Results
Resolved in commit 785ce9f.
Off-Chain OpSec
Off-Chain OpSec
OpenMRV protocol off-chain components are found in the openmrv-server that allows provider users to store their measurement data in the MongoDB Atlas. This off-chain component interacts with the contract on-chain by adding the summarized hashes to the CELO network. There are five main folders that integrate this part, the functionality of each of them is described below:
Controller
contains logic for creating and handling authorization and authentication.
- Allows creating the anchor, validator, and authorization services.
- Allows provider users to register and authenticate.
- Allows to register, disable, and delete users.
- Allows getting users and measurements.
Exception
contains logic for extending exceptions.
- Extends HTTP exceptions to show more information.
- Extends errors to show more information.
Middleware
contains logic for checking access roles.
- Checks for provider role, super role, and validator role.
- Checks for valid tokens and user roles.
- Checks for valid tokens and enabled users.
Model
contains logic for defining objects with a mongoose schema.
- Defines mongoose schema for the anchor.
- Defines mongoose schema with detailed information about the measurements and metadata.
- Defines mongoose schema for
geots
(comprises information about the time series, measurements, metadata, etc.).
- Defines mongoose schema for the provider and user role.
Service
contains logic for the functionality of the services.
- Contains functionality to interact with the authorization service (register and disable users, create tokens, and add roles).
- Contains logic for creating the
geots
hashes.
- Creates a summary hash from the
geots
hashes.
- Adds the anchor to the CELO contract.
- Validates criteria in the summary hashes.
Appendix I: Severity Categories
Appendix I: Severity Categories
Severity | Description |
---|---|
High | Issues that are highly exploitable security vulnerabilities. It may cause direct loss of funds / permanent freezing of funds. All high severity issues should be resolved. |
Medium | Issues that are only exploitable under some conditions or with some privileged access to the system. Users’ yields/rewards/information is at risk. All medium severity issues should be resolved unless there is a clear reason not to. |
Low | Issues that are low risk. Not fixing those issues will not result in the failure of the system. A fix on low severity issues is recommended but subject to the clients’ decisions. |
Informational | Issues that pose no risk to the system and are related to the security best practices. Not fixing those issues will not result in the failure of the system. A fix on informational issues or adoption of those security best practices-related suggestions is recommended but subject to clients’ decision. |
Appendix II: Status Categories
Appendix II: Status Categories
Status | Description |
---|---|
Unresolved | The issue is not acknowledged and not resolved. |
Partially Resolved | The issue has been partially resolved. |
Acknowledged | The Finding / Suggestion is acknowledged but not fixed / not implemented. |
Resolved | The issue has been sufficiently resolved. |
Disclaimer
Disclaimer
Verilog Solutions receives compensation from one or more clients for performing the smart contract and auditing analysis contained in these reports. The report created is solely for Clients and published with their consent. As such, the scope of our audit is limited to a review of code, and only the code we note as being within the scope of our audit is detailed in this report. It is important to note that the Solidity code itself presents unique and unquantifiable risks since the Solidity language itself remains under current development and is subject to unknown risks and flaws. Our sole goal is to help reduce the attack vectors and the high level of variance associated with utilizing new and consistently changing technologies. Thus, Verilog Solutions in no way claims any guarantee of security or functionality of the technology we agree to analyze.
In addition, Verilog Solutions reports do not provide any indication of the technology proprietors, business, business model, or legal compliance. As such, reports do not provide investment advice and should not be used to make decisions about investment or involvement with any particular project. Verilog Solutions has the right to distribute the Report through other means, including via Verilog Solutions publications and other distributions. Verilog Solutions makes the reports available to parties other than the Clients (i.e., “third parties”) – on its website in hopes that it can help the blockchain ecosystem develop technical best practices in this rapidly evolving area of innovation.