Introduction
We express our gratitude to the Re Protocol team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Re's NAV Oracle is a Chainlink Functions-based oracle for calculating and delivering Net Asset Value (NAV) data for on-chain financial products. The NAV Oracle provides on-chain access to verified Net Asset Value (NAV) data for financial applications. It leverages Chainlink Functions to perform off-chain calculations and securely deliver the results on-chain, where they can be used by financial protocols.
Document | |
---|---|
Name | Smart Contract Code Review and Security Analysis Report for Re Protocol |
Audited By | Seher Saylik, David Camps |
Approved By | Ataberk Yavuzer |
Website | https://re.xyz/→ |
Changelog | 27/03/2025 - Preliminary Report |
11/04/2025 - Final Report | |
Platform | Ethereum, Avalanche, Arbitrum |
Language | Solidity |
Tags | Oracle |
Methodology | https://hackenio.cc/sc_methodology→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for Re Protocol
- Audited By
- Seher Saylik, David Camps
- Approved By
- Ataberk Yavuzer
- Website
- https://re.xyz/→
- Changelog
- 27/03/2025 - Preliminary Report
- 11/04/2025 - Final Report
- Platform
- Ethereum, Avalanche, Arbitrum
- Language
- Solidity
- Tags
- Oracle
- Methodology
- https://hackenio.cc/sc_methodology→
Review Scope | |
---|---|
Repository | https://github.com/resilience-foundation/nav-oracle/→ |
Commit | ee7e98c2081b30769f2f8fe9451495e8f7d0b940 |
Remediation Commit | e3dd86ef7ad7c5c8f878e2cc87084e5a4b26d5f5 |
Review Scope
- Commit
- ee7e98c2081b30769f2f8fe9451495e8f7d0b940
- Remediation Commit
- e3dd86ef7ad7c5c8f878e2cc87084e5a4b26d5f5
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
Documentation quality
Functional requirements are partially provided.
Technical description is not provided.
Code quality
The development environment is configured.
Test coverage
Code coverage of the project is 95.83% (branch coverage).
Deployment and basic user interactions are covered with tests.
Some negative cases coverage is missed.
System Overview
Re's NAV Oracle is a Chainlink Functions-based oracle for calculating and delivering Net Asset Value (NAV) data for on-chain financial products. The NAV Oracle provides on-chain access to verified Net Asset Value (NAV) data for financial applications. It leverages Chainlink Functions to perform off-chain calculations and securely deliver the results on-chain, where they can be used by financial protocols.
The system is composed by the following contracts:
NAVConsumer -NAV Consumer Contract with Automation. This contract receives, stores NAV data and automatically triggers daily updates. Implements both Chainlink Functions consumer and Chainlink Automation for scheduled updates
INAVReceiver - Standard interface that consuming protocols implement to receive NAV updates
Privileged roles
ADMIN_ROLE: Full contract configuration access
Can configure Chainlink Functions parameters
Can modify automation settings
Can update deviation check parameters
Can set NAV receivers
DEFAULTADMINROLE with ability to grant/revoke all roles
pause/unpause the contract
UPDATER_ROLE: Can trigger normal NAV updates
Limited to requesting oracle-based updates
Cannot modify contract configuration
Typically assigned to automated services or operations team
EMERGENCY_UPDATER_ROLE: Can force-set NAV values (time-limited)
Can bypass oracle with direct NAV updates
Must provide reason string for auditability
Subject to 4-hour time restriction
Typically assigned to trusted operators for emergency scenarios
Potential Risks
If an emergency updater role acts maliciously, the forceNAVUpdate()
function could be exploited to arbitrarily manipulate the NAV value, undermining the protocol's integrity and affecting all dependent systems.
The protocol implements a deviation check in the fulfillRequest()
method for automated updates of the NAV data feed. This means that, during periods of high volatility, the system is not going to report real or accurate price data. During such periods, the system relies on the EMERGENCY_UPDATE_ROLE
to act as expected and manually feed the data into the system via forceNAVUpdate()
. However, there is no guarantee that the fed data is correct or under control. Additionally, the forceNAVUpdate()
method has a limit of 4 hours
between updates, meaning during a long period of high volatility, the system will not work correctly.
Misconfigured automation parameters, insufficient gas allocated for the callback function, or network delays could result in delayed NAV updates or update requests to fail, causing users to rely on stale data.
The system implements Chainlink Functions, a new method developed by Chainlink Labs in its Beta Stage. As described in their warning →, the development team should exercise active vigilance regarding the updates of such integration: “Chainlink Functions is likely to evolve and improve. Breaking changes might occur while the service is in BETA. Monitor these docs to stay updated on feature improvements along with interface and contract changes.”
The implemented Chainlink Functions logic in the NAVConsumer
contract highly depends on external contracts not covered by the audit. This reliance introduces risks if these external contracts are compromised or contain vulnerabilities, affecting the audited project's integrity.
The INAVReceiver
interface is a standard interface that consuming protocols implement to receive NAV updates. As such, the system is implementing additional security measures to be resilient to malicious Receivers introduced by third parties implementing the NAV technology. However, the NAVReceiver
implementation logic falls out of the scope of this audit, which should be considered when interacting with the system: users must perform their due diligence before interacting with the integration of this system by third parties or stay vigilant to future security assessments for such integrations to make sure the contracts are safe.
Findings
Code ― | Title | Status | Severity | |
---|---|---|---|---|
F-2025-9474 | Missing Access Control in performUpkeep() Allow Unintended Interactions | fixed | Medium | |
F-2025-9444 | Lack of Request ID Verification in the Callback | fixed | Medium | |
F-2025-9445 | Lack of a Pausing Mechanism | fixed | Low | |
F-2025-9473 | Calculations in getPercentageChange() may Revert due to Overflow | fixed | Observation | |
F-2025-9453 | Checks-Effects-Interactions Pattern Violation | fixed | Observation | |
F-2025-9449 | Redundant manualTriggerUpdate Function | fixed | Observation | |
F-2025-9447 | Missing Event Emitting for Configuration Changes | fixed | Observation | |
F-2025-9432 | Floating Pragma | fixed | Observation |
Identify vulnerabilities in your smart contracts.
Appendix 1. Definitions
Severities
When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.
Reference on how risk scoring is done is available through the repository in our Github organization:
Severity | Description |
---|---|
Critical | Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation. |
High | High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation. |
Medium | Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category. |
Low | Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution. |
Severity
- Critical
Description
- Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.
Severity
- High
Description
- High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.
Severity
- Medium
Description
- Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.
Severity
- Low
Description
- Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
Potential Risks
The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.
Appendix 2. Scope
The scope of the project includes the following smart contracts from the provided repository:
Scope Details | |
---|---|
Repository | https://github.com/resilience-foundation/nav-oracle/→ |
Commit | ee7e98c2081b30769f2f8fe9451495e8f7d0b940 |
Remediation Commit | e3dd86ef7ad7c5c8f878e2cc87084e5a4b26d5f5 |
Whitepaper | N/A |
Requirements | https://github.com/resilience-foundation/nav-oracle/README.md→ |
Technical Requirements | N/A |
Scope Details
- Commit
- ee7e98c2081b30769f2f8fe9451495e8f7d0b940
- Remediation Commit
- e3dd86ef7ad7c5c8f878e2cc87084e5a4b26d5f5
- Whitepaper
- N/A
- Technical Requirements
- N/A
Assets in Scope
INavConsumer.sol
NavConsumer.sol
Appendix 3. Additional Valuables
Verification of System Invariants
During the audit of Re's NAV Oracle, Hacken followed its methodology by performing fuzz-testing on the project's main functions. Foundry, a tool used for fuzz-testing, was employed to check how the protocol behaves under various inputs. Due to the complex and dynamic interactions within the protocol, unexpected edge cases might arise. Therefore, it was important to use fuzz-testing to ensure that several system invariants hold true in all situations.
Fuzz-testing allows the input of many random data points into the system, helping to identify issues that regular testing might miss. A specific Echidna fuzzing suite was prepared for this task, and throughout the assessment, 12 invariants were tested over 17k runs. This thorough testing ensured that the system works correctly even with unexpected or unusual inputs.
Invariant | Test Result | Run Count |
---|---|---|
getPercentageChange output | Failed | 1000 |
force update - latestTimestamp ≥ previousTimestamp if previousTimestamp != 0 | Passed | 1000 |
force update - latestNAV should never be zero after first valid update | Passed | 1000 |
Time between force updates must be ≥ 4 hours | Passed | 2000 |
manual update - latestTimestamp ≥ previousTimestamp if previousTimestamp != 0 | Passed | 1000 |
manual update - latestNAV should never be zero after first valid update | Passed | 1000 |
manual update - If deviationCheckEnabled and latestNAV > 0, new NAV must be within maxDeviationBps of current NAV | Passed | 1000 |
automatic update - latestTimestamp ≥ previousTimestamp if previousTimestamp != 0 | Passed | 1000 |
automatic update - latestNAV should never be zero after first valid update | Passed | 1000 |
automatic update - If deviationCheckEnabled and latestNAV > 0, new NAV must be within maxDeviationBps of current NAV | Passed | 1000 |
Time between automated updates must be ≥ 20 hours | Passed | 3000 |
lastAutomatedUpdateTimestamp should advance monotonically | Passed | 3000 |
Invariant
- getPercentageChange output
Test Result
- Failed
Run Count
- 1000
Invariant
- force update - latestTimestamp ≥ previousTimestamp if previousTimestamp != 0
Test Result
- Passed
Run Count
- 1000
Invariant
- force update - latestNAV should never be zero after first valid update
Test Result
- Passed
Run Count
- 1000
Invariant
- Time between force updates must be ≥ 4 hours
Test Result
- Passed
Run Count
- 2000
Invariant
- manual update - latestTimestamp ≥ previousTimestamp if previousTimestamp != 0
Test Result
- Passed
Run Count
- 1000
Invariant
- manual update - latestNAV should never be zero after first valid update
Test Result
- Passed
Run Count
- 1000
Invariant
- manual update - If deviationCheckEnabled and latestNAV > 0, new NAV must be within maxDeviationBps of current NAV
Test Result
- Passed
Run Count
- 1000
Invariant
- automatic update - latestTimestamp ≥ previousTimestamp if previousTimestamp != 0
Test Result
- Passed
Run Count
- 1000
Invariant
- automatic update - latestNAV should never be zero after first valid update
Test Result
- Passed
Run Count
- 1000
Invariant
- automatic update - If deviationCheckEnabled and latestNAV > 0, new NAV must be within maxDeviationBps of current NAV
Test Result
- Passed
Run Count
- 1000
Invariant
- Time between automated updates must be ≥ 20 hours
Test Result
- Passed
Run Count
- 3000
Invariant
- lastAutomatedUpdateTimestamp should advance monotonically
Test Result
- Passed
Run Count
- 3000
Additional Recommendations
The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.
To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:
Detecting changes to ownership or critical permissions.
Monitoring large or unexpected transactions and minting events.
Pausing operations when irregularities are identified.
These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.