Introduction
We express our gratitude to the Thena team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Thena is a decentralized exchange (DEX). The portion of the protocol being audited is the cross-chain bribing incentives system.
title | content |
---|---|
Platform | EVM |
Language | Solidity |
Tags | DEX |
Timeline | 16/04/2024 - 24/05/2024 |
Methodology | https://hackenio.cc/sc_methodology→ |
Review Scope | |
---|---|
Repository | https://github.com/ThenafiBNB/THENA-V3/tree/HackenAudit→ |
Commit | 4faabb68b7112bfe9451c09b00ac9653ca041f53 |
Review Scope
- Commit
- 4faabb68b7112bfe9451c09b00ac9653ca041f53
Audit Summary
10/10
100%
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 Thena |
Audited By | Niccolò Pozzolini, Kornel Światłowski |
Approved By | Przemyslaw Swiatowiec |
Website | https://thena.fi/→ |
Changelog | 08/05/2024 - Preliminary Report |
24/05/2024 - Second Review |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for Thena
- Audited By
- Niccolò Pozzolini, Kornel Światłowski
- Approved By
- Przemyslaw Swiatowiec
- Website
- https://thena.fi/→
- Changelog
- 08/05/2024 - Preliminary Report
- 24/05/2024 - Second Review
System Overview
GenericLayerZero.sol - serves as a messaging interface for LayerZero, enabling the transfer of $THE token between EVM-compatible chains. It allows for the transmission of messages containing payloads to specified destination contracts on different chains. Additionally, it supports fee estimation and management, ensuring smooth cross-chain communication. Cross-chain communication is performed with the LayerZero EndpointV2 contract.
AutomationEpochDistributorBSC.sol - facilitates automated reward distribution on the Binance Smart Chain (BSC). It monitors the status of the minter contract for necessary updates and, upon confirmation, initiates the distribution process on BSC. Authorized parties can trigger the distribution process, which includes distributing rewards and handling cross-chain fees. The distribution process is performed weekly.
AutomationEpochDistributorOpBNB.sol - automates the distribution process on the opBNB chain of $THE token rewards from the Epoch Distributor contract. It periodically checks if the opBNB distribution is ready and loads the necessary data for distribution. Authorized parties can trigger the distribution process, ensuring timely and efficient reward dissemination. The distribution process is performed weekly.
EpochDistributorBSC.sol - manages the distribution of weekly rewards in $THE tokens to BSC gauges and opBNB. It tracks epoch-wise reward data, including total amounts, opBNB shares, and distribution timestamps. Through the notifyRewardAmount function, it receives weekly $THE rewards from the minter contract and prepares them for distribution. The contract distributes rewards to BSC gauges and initiates opBNB distribution based on predefined shares. Additionally, it supports cross-chain interactions for opBNB distribution, facilitating efficient reward allocation across chains.
EpochDistributorOpBNB.sol - designed to distribute weekly $THE rewards to opBNB. It tracks epoch-wise reward data, including the total amount to distribute, opBNB amounts, and timestamps. Through the executeCrossChainMessage function, it receives opBNB amounts from BSC, mints $THE tokens accordingly, and prepares them for distribution. The contract distributes rewards to opBNB and manages epoch updates based on predefined conditions.
GlobalFactory.sol - serves as a central hub for creating and managing various DeFi components such as gauges, fee vaults, and voting incentives for different types of pools. Its purpose is to streamline the process of setting up and configuring these components while ensuring compatibility and security across different types of pools and associated contracts. Additionally, it provides functionality for token management, pool type configuration, and fee vault management, all under the control of the contract owner.
GaugeFactory.sol - facilitates the creation and management of Gauge contracts. Its primary function is to enable the creation of Gauge contracts with specific configurations, including reward tokens, fee vaults, and voting incentives. Additionally, it provides functionality for managing emergency modes, setting distributions, and adding or removing reward tokens from existing Gauge contracts. The contract ensures control over Gauge creation and configuration while allowing for the automation of fee-claiming and distribution processes.
VotingIncentivesFactory.sol - enables the creation of VotingIncentives contracts with specified configurations, including token pairs, voter contracts, and associated claimers. Through this contract, users can establish VotingIncentives structures tailored to their governance needs, facilitating fair and incentivized participation in decision-making processes. Additionally, it provides functionality for managing default reward tokens, permissions, and recovery of assets in emergency scenarios.
FeeVault.sol - facilitates the collection of fees from the underlying pool and redistributes them to various recipients, including a specified gauge contract and a staking converter contract called theNFT. Through configurable parameters such as fee distribution shares and permission settings, the contract enables flexible fee management strategies.
Gauge.sol - serves as a mechanism for users to deposit assets and receive rewards in return. It manages reward distribution for various tokens, calculates earned rewards based on staked amounts, and facilitates fee claiming from the underlying strategy or LP. Additionally, it supports emergency withdrawal functionalities to safeguard user funds in critical situations.
SchnorrSECP256K1Verifier.sol - provides a method for verifying Schnorr signatures on the Ethereum network. It implements a modified version of the Schnorr signature scheme for the secp256k1 curve.
Voter.sol - serves as a decentralized governance system, allowing veTHE token holders to participate in voting for various proposals within a protocol. It manages votes cast by users on different pools, distributing voting power based on token holdings. The contract ensures transparency and fairness by recording votes securely on-chain and facilitating interactions between voters and voting incentives mechanisms.
VoterOpBNB.sol - facilitates voting for various pools within a decentralized ecosystem. Users can vote with their veTHE tokens, allocating weights to different pools to earn rewards. It supports actions such as voting, revoting, and resetting votes.
VotingEscrowAttach.sol - acts as an intermediary for interacting with the VotingEscrow contract, allowing certain addresses to perform voting actions on behalf of token holders. It enables attaching, detaching, voting, and abstaining functionalities.
VotingEscrowCrossChainManager.sol - facilitates cross-chain operations for Voting Escrow tokens between BNB and opBNB chains. Users can generate or update Voting Escrow positions on the respective chains, ensuring secure token transfers. The contract also handles withdrawals, maintaining consistency and security across chains while leveraging Muon for efficient communication.
VotingIncentivesVotingIncentives.sol - manage incentives for veTHE voters, distributing rewards and fees over a weekly period. It supports multiple reward tokens and interfaces with the veTHE contract and $THE Minter. Users can deposit tokens to vote, withdraw them, and claim rewards. The contract facilitates reward distribution.
Privileged roles
GenericLayerZero.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set the delegate address for the OApp; set chain IDs to Generic Layer Zero contract address; set the chain ID; set the L0 Endpoint; set an address that is allowed to send messages; set as allowed address from which cross-chain message can be received and withdraw any stuck native balance.
AutomationEpochDistributorBSC.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set the address that will be allowed to call performUpkeep(); set a new batch for performUpkeep max loop size; set epoch distributor contract; set voter contract; set minter address and recover the native token balance from contract.
AutomationEpochDistributorOpBNB.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set the address that will be allowed to call performUpkeep(); set a new batch for performUpkeep() max loop size; set epoch distributor contract and set voter contract.
EpochDistributorBSC.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set the opBNB share of the weekly minted THE; set the address allowed to run automation; set the opBNB EpochDistributor contract; set the Generic CCIP contract; set the LayerZero Generic contract; define the cross-chain service to use and recover ERC20 from the contract.
EpochDistributorOpBNB.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set address allowed to run automation; set the cross-chain service and recover ERC20 from the contract.
GaugeFactory.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set a new GlobalFactory contract address and set an automation contract that claims and distributes the fees.
VotingIncentivesFactory.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role or GlobalFactory contract can: create a VotingIncentives contract; set a new GlobalFactory contract address; set the VotingIncetives factory permission registry; remove default reward token; add a reward token to a given VotingIncetives; set a new voter in given VotingIncetivess; set a new minter in given VotingIncetives contract; set a new owner in given VotingIncetives contract; set a new claimer in the VotingIncetives contract; recover a given ERC20 from VotingIncetives contracts.
GlobalFactory.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: whitelist token for gauges creation; ban a token for gauges creation; set an EOA/Contract that can create Type 1 pools; set a Pool Type for gauge creation; set the Voter contract; set the pair factory for solidly pairs; et the pair factory for Algebra pairs; et the GaugeFactory contract; set the VotingIncentives factory; set the theNFT staking converter; set the distribution contract; set the Claimer contract; set a new THENFT address for a given FeeVault contract; set a new share for theNFT; set a new Gauge address for the FeeVault contract; set addresses allowed to call claim fees; set the new underlying pool for the FeeVault and recover a given ERC20 from FeeVault contract.
FeeVault.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set a theNFT staking reward converter address; set theNFT fees share; set the gauge where to send fees; allow an EOA or contract to claims fee; set the underlying pool where to get fees and recover a given ERC20 from the contract.
Gauge.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: set a new claimer contract; set distribution address; set FeeVault address; set the VotingIncentives contract; activate the Emergency Mode; deactivate the Emergency Mode; and add and remove a reward token.
Voter.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can grant given address a manager role. Custom implementation of the manager role can: add pool information to the voter; remove a pool information from the voter; ban a pool from voting; revive a pool from voting; set a new VotingEscrow contract; set a new Minter contract and set a new VotingEscrowAttach contract.
VoterOpBNB.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can grant given address a manager role. Custom implementation of the manager role can: add pool information to the voter; remove a pool information from the voter; ban a pool from voting; revive a pool from voting; set a new VotingEscrow contract; set a new Minter contract and set a new VotingEscrowAttach contract.
VotingEscrowAttach.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can grant given address an allowance privilege. Addresses with this role can: lock veTHE when voting; unlock veTHE when resetting the vote and attach or detach a veTHE.
VotingEscrowCrossChain.sol - This contract uses a custom implementation of an access control mechanism. Address with owner role can: deposit tokens for and lock for a given duration; withdraw all tokens for given tokenId; set the new owner; set the artProxy of this veTHE; set the voter address where this veTHE is used and set the cross-chain manager.
VotingEscrowCrossChainManager.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: force a reset if CC tx fails and veTHE was removed on opBNB; set the Generic CrossChain contract for a given flag; set the CC service flag to be used; set the veThe cross-chain manager on the destination chain; set a new muonAppId if dApp updated; set the new muon gateway if dApp updated; set this ChainID and withdraw any stuck native balance.
VotingEscrowCrossChainManager.sol - This contract uses an Ownable Access Control Mechanism from OpenZeppelin. Address with owner role can: force a reset if CC tx fails and veTHE was removed on opBNB; set the Generic CrossChain contract for a given flag; set the CC service flag to be used; set the veThe cross-chain manager on the destination chain; set a new muonAppId if dApp updated; set the new muon gateway if dApp updated; set this ChainID and withdraw any stuck native balance.
VotingIncentives.sol - This contract uses a custom implementation of an access control mechanism. Address with owner role or VotingIncentivesFactory contract can: add rewards tokens; recover ERC20 from the last bribe; recover some ERC20 from the contract.; set a new Voter address; set a new Minter contract; set a new owner and set a new claimer contract.
Executive Summary
Documentation quality
The total Documentation quality score is 9 out of 10.
Functional requirements are partially missed.
Technical description is provided.
Code quality
The total Code quality score is 10 out of 10.
The development environment is configured.
Test coverage
Code coverage of the project is 100%.
Deployment and basic user interactions are covered with tests.
Security score
Upon auditing, the code was found to contain 0 critical, 1 high, 1 medium, and 4 low severity issues, leading to a security score of 4 out of 10. Upon remediation, all identified issues have been fixed, 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.9. This score reflects the combined evaluation of documentation, code quality, test coverage, and security aspects of the project.
Risks
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:
/contracts/Minter/Minter.sol
/contracts/Crosshain/CCIP/GenericCCIP.sol
/contracts/Factories/SolidlyFactory/PairFactory.sol
/contracts/SolidlyPair/Pair.sol
/contracts/VotingEscrow/VotingEscrow.sol
/contracts/VotingEscrow/IVeArtProxy.sol
have not been verified or assessed as part of this report.
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.
Scope Definition and Security Guarantees: The audit does not cover all code in the repository. Contracts outside the audit scope may introduce vulnerabilities, potentially impacting the overall security due to the interconnected nature of smart contracts.
System Reliance on External Contracts: The functioning of the system significantly relies on specific external contracts. Any flaws or vulnerabilities in these contracts adversely affect the audited project, potentially leading to security breaches or loss of funds.
Coarse-grained Authorization Model Risks: The broad authorization model increases the risk of protocol control loss if any authorized address is compromised, potentially leading to unauthorized actions and significant financial loss.
Single Points of Failure and Control: The project is fully or partially centralized, introducing single points of failure and control. This centralization can lead to vulnerabilities in decision-making and operational processes, making the system more susceptible to targeted attacks or manipulation.
Findings
Code ― | Title | Status | Severity | |
---|---|---|---|---|
F-2024-2105 | Incorrect indexing in distribute functions leads to DoS and wrong distributions | fixed | High | |
F-2024-2197 | Uncleared approval in _removeTokenFrom function may lead to unauthorized control | fixed | Medium | |
F-2024-2155 | Lack of Pausable feature for user facing system contracts | fixed | Low | |
F-2024-2154 | Coarse-grained access control | fixed | Low | |
F-2024-2089 | Unnecessary and potentially dangerous receive() function | fixed | Low | |
F-2024-1985 | Missing update of eidToChainID mapping in GenericLayerZero contract | fixed | Low | |
F-2024-2197 | Best practice violation due to usage of assert() | fixed | Observation | |
F-2024-2196 | Missing method for removing elements from the rewardTokens array | fixed | Observation | |
F-2024-2174 | Some public functions should be declared as external | fixed | Observation | |
F-2024-2160 | Incorrect NatSpec description of the lockend parameter in createlockfor function | fixed | Observation |
Identify vulnerabilities in your smart contracts.
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/ThenafiBNB/THENA-V3/tree/HackenAudit→ |
Commit | 4faabb68b7112bfe9451c09b00ac9653ca041f53 |
Whitepaper | Not provided |
Requirements | https://docs.google.com/document/d/1ySdeWP80z0BYPBxSG20lLcOEP1xTBE2mxFDM0F1sM9Y/edit?usp=sharing→ |
Technical Requirements | https://docs.google.com/document/d/1ySdeWP80z0BYPBxSG20lLcOEP1xTBE2mxFDM0F1sM9Y/edit?usp=sharing→ |
Scope Details
- Commit
- 4faabb68b7112bfe9451c09b00ac9653ca041f53
- Whitepaper
- Not provided