Introduction
We express our gratitude to the NOYA team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Noya is a DeFi project consisting on different yield-generating vaults that execute strategies on third party DeFi protocols.
| title | content |
|---|---|
| Platform | EVM |
| Language | Solidity |
| Tags | Vault, Crosschain, DEX, EIP712, Oracle |
| Timeline | 26/02/2024 - 29/03/2024 |
| Methodology | https://hackenio.cc/sc_methodology→ |
Review Scope | |
|---|---|
| Repository | https://github.com/Noya-ai/noya-vault-contracts→ |
| Commit | 95fcb52 |
Review Scope
- Commit
- 95fcb52
Audit Summary
10/10
98%
10/10
9/10
The system users should acknowledge all the risks summed up in the risks section of the report
Document Information
This report may contain confidential information about IT systems and the intellectual property of the Customer, as well as information about potential vulnerabilities and methods of their exploitation.
The report can be disclosed publicly after prior consent by another Party. Any subsequent publication of this report shall be without mandatory consent.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for NOYA |
| Audited By | David Camps Novi, Viktor Lavrenenko |
| Approved By | Przemyslaw Swiatowiec |
| Website | https://noya.ai/→ |
| Changelog | 29/03/2024 - Preliminary Report |
| 19/04/2024 - Final Report |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for NOYA
- Audited By
- David Camps Novi, Viktor Lavrenenko
- Approved By
- Przemyslaw Swiatowiec
- Website
- https://noya.ai/→
- Changelog
- 29/03/2024 - Preliminary Report
- 19/04/2024 - Final Report
System Overview
Noya is a yield-generating DeFi protocol based on vaults that execute different strategies.
The project consists of several parts:
AccountingManager: entry-point for users to deposit and withdraw tokens in exchange for shares, generating yield.
NoyaFeeReceiver: contracts receiving the protocol fees to be managed.
Registry.sol: centralized accountability of all vaults and positions in other protocols.
Keepers.sol: multi-signature wallet for the execution of the vault strategies.
NoyaGovernanceBase: defines the access control of the different roles.
TimeLock.sol: time-lock control contract.
Watchers: verifier contract.
LzHelper*: contracts that interact Layer Zero messaging.
Omnichain*: contracts to manage bridging of assets among different protocol chains.
SwapAndBridgeHandler, LifiImplementation: contract that manage swaping and bridging of assets.
ChainlinkOracleConnector: contract to fetch asset prices from the Chainlink protocol.
UniswapValueOracle: TWAP oracle to get asset prices from the Uniswap protocol.
NoyaValueOracle: defines and decides which oracle should be used to retrieve prices of assets.
TVLHelper: contains the functions to calculate the TVL.
Connectors: individual contracts that interact with a specific DeFi protocol (e.g. Aave, Uniswap, Frax).
Privileged roles
Governor: responsible for changing the addresses of others.
Maintainer: in charge of adding a new vault, adding trusted tokens for that vault, and adding trusted positions to the registry.
Keepers: manages execution of the strategies. It’s a multisig contract. Strategy managers can submit their transactions into IPFS in an encrypted way and the keepers will decrypt and execute it.
Watchers: responsible to make sure the execution of noya is going on correctly. If there is any misbehaving (like price manipulation or any suspicious actions from the keepers) the watchers can undo the action.
Emergency: cold wallet that is going to be used in situations that a position is stuck or another role of noya is compromised.
Executive Summary
Documentation quality
The total Documentation Quality score is 9 out of 10.
Functional requirements are sufficient.
Technical description is limited.
NatSpec is not sufficient.
Run instructions are provided.
Technical description is included.
Code quality
The total Code Quality score is 10 out of 10.
The gas modeling is correct.
Best practices are followed.
The development environment is configured.
Test coverage
Code coverage of the project is 98% (branch coverage).
Deployment and basic user interactions are covered with tests.
All contracts are tested.
Negative test coverage is provided.
Security score
Upon auditing, the code was found to contain 0 critical, 2 high, 15 medium, and 10 low severity issues, leading to a security score of 10 out of 10.
All identified issues are detailed in the “Findings” section of this report.
Summary
The comprehensive audit of the customer's smart contract yields an overall score of 9.8. This score reflects the combined evaluation of documentation, code quality, test coverage, and security aspects of the project.
Risks
The project utilizes Solidity version 0.8.20 or higher, which includes the introduction of the PUSH0 (0x5f) opcode. This opcode is currently supported on the Ethereum mainnet but may not be universally supported across other blockchain networks. Consequently, deploying the contract on chains other than the Ethereum mainnet, such as certain Layer 2 (L2) chains or alternative networks, might lead to compatibility issues or execution errors due to the lack of support for the PUSH0 opcode. In scenarios where deployment on various chains is anticipated, selecting an appropriate Ethereum Virtual Machine (EVM) version that is widely supported across these networks is crucial to avoid potential operational disruptions or deployment failures.
The usage of a custom minimumHealthFactor in the following connectors: AaveConnector.sol, CompoundConnector.sol, PrismaConnector.sol, SiloConnector.sol, FraxConnector.sol, MorphoBlueConnector.sol creates a risk that the custom minimumHealthFactor will be improperly set by the onlyMaintainer, which will lead to issues.
The value of the fees implemented by the system can change after a user makes a deposit. Thus it is possible a user will interact with the protocol expecting a specific fee (e.g. 5% withdrawal fee) but pay a higher fee later on (e.g. withdrawal fee increased to 10%).
When performing a deposit into the protocol, some ERC20 tokens shares are minted to the specified receiver address. It should be noted that this address should be able to manage those tokens (e.g. EOA). Else, EOA should not be allowed by the system.
The fees are implemented over the same amounts in a redundant matter: management fees, performance fees and withdrawal fees are applied over the same amounts. Although they have different principles applied, it should be noted that they are redundant.
Any actor can send tokens to the AccountingManager contract in order to increase the TVL, affecting the amount of fees recorded, as well as the amount of shares minted by the user during deposits and the amount of received tokens during withdraw. This is due to the fact that TVL depends on balanceOf the contract.
Both AccountingManager and LifiImplementation include functions that allow the retrieval of all native or ERC20 tokens from the contract. It should be noted, however, that those functions have restrictive access control mechanisms.
The project is highly centralized, since it fully controls the timings of the deposits and withdrawals of the clients. This can result in Denial of Service if the protocol owner is not able to access its account to execute the required methods.
Many of the processes and data used in the protocol are off-chain and thus cannot be audited. One example is the usage of the multi-signature process in the Keepers contract. Another example is the usage of data and additionalData in the holding positions structs. One additional example is the usage of cross-chain communication via Layer Zero and Omnichain.
There is no on-chain method that checks that BridgeRequests are not replayed. Therefore there is a risk that the same bridging action is used repeatedly.
The protocol uses TWAP oracles to retrieve the price of assets. It should be noted that TWAP oracles require a uniform liquidity distribution across the fetched pool in order to provide consistent and precise values. The development team should be very careful that this is the case when retrieving data from such oracles, and monitor the used pools to make sure the quality of the pool data provided is good enough.
It should be noted that TWAP oracles provide “smoothened” data, since it uses a time window of price data to prevent flash loan attacks or other kinds of price manipulations that are typical for AMM pools. Therefore, the selected parameters in the TWAP oracle should be chosen wisely to get the best data possible: a very wide window will be more robust to price manipulation but will not reflect the real-time valuation of assets. Due to this, it is recommended to use TWAP data only in case Chainlink data feeds are not available and, moreover, to only use TWAP for healthy pools and tokens.
Noya interacts with several third-party contracts (such as Aave, Stargate or PancakeSwap) that are not part of this audit scope. Although the consistency within those contracts and with the calls to such external protocols has been reviewed and reported if necessary, it is assumed by the audit team that those third-party protocols are done correctly by the development team (see risk statement below).
The performance fee will only work when the vault underlying tokens valuation increases. The reason is that, when calling collectPerformanceFees, the previous value of storedProfitForFee is assigned to totalProfitCalculated and, therefore, only increasing storedProfitForFee will pass the check.
This audit report focuses exclusively on the security assessment of the contracts within the specified review scope. Interactions with out-of-scope contracts are presumed to be correct and are not examined in this audit. We want to highlight that Interactions with contracts outside the specified scope, such as:
have not been verified or assessed as part of this report. This situation is present in all connector contracts that interact with external protocols.
While we have diligently identified and mitigated potential security risks within the defined scope, it is important to note that our assessment is confined to the isolated contracts within this scope. The overall security of the entire system, including external contracts and integrations beyond our audit scope, cannot be guaranteed.
Users and stakeholders are urged to exercise caution when assessing the security of the broader ecosystem and interactions with external contracts. For a comprehensive evaluation of the entire system, additional audits and assessments outside the scope of this report are necessary.
This report serves as a snapshot of the security status of the audited contracts within the specified scope at the time of the audit. We strongly recommend ongoing security evaluations and continuous monitoring to maintain and enhance the overall system's security.
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2024-1839 | The non-updated totalDepositedAmount causes the incorrect calculation of the profit | fixed | High | |
| F-2024-1538 | onERC721Received callback is never called which leads to loss of liquidity | fixed | High | |
| F-2024-1857 | Uncontrolled loop of storage interactions may lead to Denial Of Service | fixed | Medium | |
| F-2024-1846 | The non-updated totalProfitCalculated causes leads to the incorrect number of fee shares | fixed | Medium | |
| F-2024-1847 | Chainlink’s latestRoundData might return stale or incorrect results | fixed | Medium | |
| F-2024-1846 | USD decimals are incorrectly set | fixed | Medium | |
| F-2024-1837 | Missing call to update holding position results in miscalculated TVL | fixed | Medium | |
| F-2024-1835 | Unlimited allowance is set by default | fixed | Medium | |
| F-2024-1834 | Missing slippage allows front-run in token swaps | mitigated | Medium | |
| F-2024-1814 | Users can receive less tokens than entitled during withdraw | mitigated | Medium |
Appendix 1. Severity Definitions
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, do not affect security score but can affect code quality score. |
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, do not affect security score but can affect code quality score.
Appendix 2. Scope
The scope of the project includes the following smart contracts from the provided repository:
Scope Details | |
|---|---|
| Repository | https://github.com/Noya-ai/noya-vault-contracts→ |
| Audited commit | 95fcb52 |
| Remediation commit | 6f42e71 |
| Whitepaper | https://docs.noya.ai/→ |
| Requirements | https://github.com/Noya-ai/noya-vault-contracts/README.md→ |
| Technical Requirements | https://github.com/Noya-ai/noya-vault-contracts/README.md→ |
Scope Details
- Audited commit
- 95fcb52
- Remediation commit
- 6f42e71
- Whitepaper
- https://docs.noya.ai/→
- Technical Requirements
- https://github.com/Noya-ai/noya-vault-contracts/README.md→