Introduction
We express our gratitude to the Paribus team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Paribus is a cross-chain borrowing and lending protocol for NFTs, liquidity positions, synthetic assets and real world assets.
Document | |
---|---|
Name | Smart Contract Code Review and Security Analysis Report for Paribus |
Audited By | Ivan Bondar, Viktor Lavrenenko, David Camps Novi |
Approved By | Grzegorz Trawinski |
Website | https://paribus.io/→ |
Changelog | 09/08/2024 - Preliminary Report; 03/09/2024 - Final Report |
Platform | Arbitrum, Polygon, Ethereum |
Language | Solidity |
Tags | Fungible Token; Non-fungible Token; Lending Platform; Oracle; Centralization |
Methodology | https://hackenio.cc/sc_methodology→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for Paribus
- Audited By
- Ivan Bondar, Viktor Lavrenenko, David Camps Novi
- Approved By
- Grzegorz Trawinski
- Website
- https://paribus.io/→
- Changelog
- 09/08/2024 - Preliminary Report; 03/09/2024 - Final Report
- Platform
- Arbitrum, Polygon, Ethereum
- Language
- Solidity
- Tags
- Fungible Token; Non-fungible Token; Lending Platform; Oracle; Centralization
- Methodology
- https://hackenio.cc/sc_methodology→
Review Scope | |
---|---|
Repository | https://github.com/paribus/paribus-protocol→ |
Commit | 56e0ba2 |
Review Scope
- Commit
- 56e0ba2
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
Documentation quality
Functional requirements are present, but only at a high-level.
The project overview provides a basic understanding but lacks depth.
All roles in the system are described.
Requirements and System description can be found in Paribus Documentation →.
Technical description is robust.
Run instructions are provided.
Technical specification is provided.
NatSpec is sufficient.
Code quality
The development environment is configured.
Solidity Style Guide violations.
Best practice violations.
Test coverage
Code coverage of the project is 99.57% (branch coverage).
Deployment and basic user interactions are covered with tests.
Negative coverage is provided.
Interactions by several users are tested.
System Overview
Paribus is a decentralized, cross-chain lending and borrowing protocol designed to leverage the value of digitizable assets. The protocol supports a wide range of asset types, including NFTs, liquidity positions (LP tokens), synthetics, and other yield-bearing assets. By representing the value of these assets on-chain, Paribus allows users to unlock their full potential and generate passive income.
Paribus aims to provide a flexible and innovative DeFi solution that taps into the value of both conventional and unconventional crypto-assets.
The files in the scope:
./contracts/ErrorReporter.sol - defines an error reporting mechanism for the Comptroller and other related contracts. It includes an Error enum to categorize different error types and a fail function to emit failure events when errors occur.
./contracts/Comptroller/ComptrollerInterfaces.sol - defines several interfaces for the Comptroller, which is a key component in the Paribus protocol responsible for managing the markets, setting parameters, and ensuring the stability of the system. The interfaces include methods for managing assets, setting policies, and handling administrative functions.
./contracts/Comptroller/ComptrollerStorage.sol - defines the storage structures used by the Comptroller, which include parameters and mappings for managing markets, collateral factors, PBX distributions, and various administrative controls.
./contracts/PNFTToken/PNFTToken.sol - defines the base for Paribus Non-Fungible Tokens (PNFTs), implementing various functions to handle the initialization, transfers, minting, redemption, and liquidation of PNFTs. It integrates with external contracts such as the Comptroller, Price Oracle, and several interfaces for handling underlying assets.
./contracts/PNFTToken/PNFTTokenInterfaces.sol - contains several contract interfaces and storage structures for the Paribus Non-Fungible Token (PNFT) system. These interfaces define the core functionalities and storage layout for PNFT contracts, including delegation, admin controls, and ERC-721 compatibility.
./contracts/PToken/PToken.sol - defines the PToken contract, which is an abstract base for Paribus tokens (PTokens). PTokens are used within the Paribus protocol to represent assets and handle various financial operations such as minting, redeeming, borrowing, repaying, and liquidating assets.
./contracts/PToken/PTokenInterfaces.sol - defines various interfaces and storage structures for PTokens within the Paribus protocol. These interfaces are used to standardize and implement the functionality of PTokens, which represent assets and manage their respective operations such as transfers, minting, redeeming, borrowing, repaying, and liquidations.
./contracts/PToken/PErc20/PErc20.sol - is an implementation of the PToken interface for ERC-20 tokens. It extends the
PToken
base contract, providing functionality for interacting with an underlying ERC-20 token../contracts/PToken/PErc20/PErc20Delegate.sol - extends the
PErc20
contract and implements the PTokenDelegateInterface. It is designed to be used with a delegator contract that can delegate function calls to this implementation../contracts/PToken/PErc20/PErc20DelegateV2.sol - extends the
PErc20Delegate
contract and adds a borrowable flag, which can be set during initialization. This flag determines if the market supports borrowing, specifically useful for LP token markets../contracts/PriceOracle/ArbitrumPriceOracle.sol - contains multiple contracts for handling price oracles on the Arbitrum network, both for the mainnet and testnet environments.
./contracts/PriceOracle/PriceOracleInterfaces.sol - contains several interfaces (
IOracle
,IOracleNFT
,ISourceOracle
,INFPOracle
) for different types of price oracles used within the Paribus protocol. These interfaces are used to fetch and verify the prices of various types of assets, including tokens, NFTs, and specific positions:./contracts/PriceOracle/Impl/AggregatorOracle.sol - aggregates multiple source price oracles along with an NFT oracle to provide a unified price feed.
./contracts/PriceOracle/Impl/AlgebraV1PriceOracle.sol - oracle for obtaining prices from Algebra V1.
./contracts/PriceOracle/Impl/Api3PriceOracle.sol - oracle for obtaining prices from the API3 data feed.
./contracts/PriceOracle/Impl/ChainlinkPriceOracle.sol - oracle for obtaining prices from Chainlink data feeds.
./contracts/PriceOracle/Impl/SourceOracle.sol - base and derived contract for oracles that provide price data for tokens and NFTs.
./contracts/PriceOracle/Impl/UniV2PriceOracle.sol - provides a price oracle for Uniswap V2 liquidity pool tokens.
./contracts/PriceOracle/Impl/UniV3PriceOracle.sol - provides a price oracle for Uniswap V3 non-fungible positions.
./contracts/InterestRateModels/InterestRateModelInterface.sol - defines the interface for the Interest Rate Model, which is responsible for calculating the current interest rates for borrowing and supplying assets within the Paribus protocol.
./contracts/Interfaces/AlgebraV1Interfaces.sol - defines interfaces for interacting with Algebra V1.
./contracts/Interfaces/Api3Interfaces.sol - defines interfaces for interacting with the API3 protoco.
./contracts/Interfaces/ChainlinkInterfaces.sol - defines interfaces for interacting with Chainlink's decentralized oracle network, which provides reliable and tamper-proof data feeds.
./contracts/Interfaces/LPInterfaces.sol - defines interfaces for interacting with liquidity pool (LP) tokens.
./contracts/Interfaces/NFTXInterfaces.sol - defines interfaces for interacting with NFTX.
./contracts/Interfaces/ParibusOracleInterface.sol - defines the interface for interacting with the Paribus Oracle, which provides price data.
./contracts/Interfaces/SudoswapInterfaces.sol - defines interfaces for interacting with Sudoswap.
./contracts/Interfaces/UniswapV2Interfaces.sol - contains interfaces for interacting with Uniswap V2.
./contracts/Interfaces/UniswapV3Interfaces.sol - contains interfaces for interacting with Uniswap V3.
./contracts/Utils/ExponentialNoError.sol - exponential module for storing fixed-precision decimals.
Privileged roles
The admin of the
PNFTToken
can do the following:initialize the contract using
PNFTToken::initialize()
.set the pending admin using
PNFTToken::_setPendingAdmin()
.change the address of the nft comptroller via
PNFTToken::_setComptroller()
.change the id of the NFTXioVault using
PNFTToken::_setNFTXioVaultId()
.change the address of the
SudoswapLSSVM
pairPNFTToken::_setSudoswapLSSVMPairAddress()
.
The pendingAdmin of the
PNFTToken
can accept their admin role viaPNFTToken::_acceptAdmin()
.The admin of the
AggregatorOracle
can do the following:change the address of the pending admin via
AggregatorOracle::_setPendingAdmin()
.add a UniswapV2 pair using
AggregatorOracle::setUniV2SupportedPair()
.
The pendingAdmin of the
AggregatorOracle
can accept their admin role viaAggregatorOracle::_acceptAdmin()
.The owner of the
UniV2PriceOracle
can add a new supported pair viaUniV2PriceOracle::setSupportedPair()
.The admin of the
PErc20Delegate
andPErc20DelegateV2
is allowed to call_becomeImplementation()
and_resignImplementation()
functions.The admin of the
PToken
can do the following:initialize the contract using
PToken::initialize()
.set the address of the pendingAdmin using
PToken::_setPendingAdmin()
.set the address of the comptroller via
PToken::_setComptroller()
.set the protocolSeizeShareMantissa via
PToken::_setProtocolSeizeShareMantissa()
.set the reserve factor via
PToken::_setReserveFactor()
.reduce the reserves by calling
PToken::_reduceReserves()
.set the address of the interest rate model using
PToken::_setInterestRateModel()
.
The pendingAdmin of the
PToken
can accept their admin role viaPToken::_acceptAdmin()
.
Risks
Scope Definition and Security Guarantees: The audit does not include the Comptroller contracts, which are critical for governance and risk management. Excluding these contracts may leave significant vulnerabilities unaddressed, potentially compromising the protocol's overall security and stability. 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. Although interactions with the aforementioned contracts could not be reviewed in this audit, further security reviews were performed by Hacken → and Zokyo →.
Governance and Market Integrity: The Comptroller controls key parameters like collateral factors and interest rates. Any undetected flaws could lead to market manipulation, mismanagement of liquidations, or incorrect asset listings. Comptroller key parameters will be controlled through governance, Key contracts like JumpRateModelV2 are already controlled via governance on Arbitrum mainnet. The governance forum can be found here → and in the official governance portal. →
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.
Interactions with External DeFi Protocols: Dependence on external DeFi protocols inherits their risks and vulnerabilities. This might lead to direct financial losses if these protocols are exploited, indirectly affecting the audited project.
Owner's Unrestricted State Modification: The absence of restrictions on state variable modifications by the owner leads to arbitrary changes, affecting contract integrity and user trust, especially during critical operations.
Single Points of Failure and Control: The project is 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.
Centralized Upgrade Authority and Risks in Contract Upgrades: The ecosystem grants a single entity the authority to implement upgrades or changes to the contracts, introducing significant risks. This centralization of power can lead to unilateral decisions that may not align with community or stakeholder interests, undermining trust and security. The upgradable nature of the contracts allows for flexibility in addressing issues and evolving the project, but it also increases the risk of unauthorized or poorly managed changes. The absence of upgrade window constraints further exacerbates this risk, as immediate upgrades can be deployed without a mandatory review period, potentially leading to the rapid deployment of malicious or flawed code, compromising the system's integrity and user assets.
Current implemented Chainlink Oracles use specific latestRoundData() function calls that return roundID, price, updatedAt, timeStamp and answeredInRound parameters. Those parameters are correct for such implementations, with their corresponding checks. However, it should be noted that not all data feeds use the same parameters and may require different validations and checks. Thus, if new feeds were added into the system, it should be confirmed if a different implementation would be required. For example, as it can be seen in Chainlink's Documentation →, newer data feed implementations do not use answeredInRound and it is deprecated.
The contract SourceOracle uses the function subabs() in order to calculate the absolute value of a difference. This is being used to check the freshness of oracles' data, which will take the difference between the current block.timestamp and the update time of the oracle. It should be noted that block.timestap should always be higher or equal than the oracles' provided timestamp, in which case the function subabs() would work normally. However, if anything was wrong and a misplaced value was provided by the oracles, the function would not catch that inconsistency, and the price calculation would be corrupted.
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:
BaseJumpRateModelV2.sol
ComptrollerCommonImpl.sol
ComptrollerNFTPart1.sol
ComptrollerNFTPart2.sol
ComptrollerNoNFTPart1.sol
ComptrollerNoNFTPart2.sol
FlashloanLiquidator.sol
FullMath.sol
GovernorDelegate.sol
GovernorDelegator.sol
GovernorInterfaces.sol
GovernorModerator.sol
JumpRateModelV2.sol
LiquidityAmounts.sol
Maximillion.sol
MilkomedaOpenOracle.sol
PBXToken.sol
PCryptoPunks.sol
PCryptoPunksImmutable.sol
PCryptopunksDelegate.sol
PErc20Delegator.sol
PErc20Immutable.sol
PErc721.sol
PErc721Delegate.sol
PErc721Immutable.sol
PEther.sol
PEtherDelegate.sol
PEtherDelegator.sol
PEtherImmutable.sol
PWBTokenDelegate.sol
ParibusDataFetcher.sol
ParibusFaucet.sol
ParibusOracleDelegate.sol
ParibusOracleDelegator.sol
ParibusSupplier.sol
TickMath.sol
Timelock.sol
Unitroller.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.
Findings
Code ― | Title | Status | Severity | |
---|---|---|---|---|
F-2024-4910 | Incorrect ExactInputSingleParams Struct | fixed | Medium | |
F-2024-4895 | Lack of Fee Inclusion in NFT Position Oracle Leads to Incorrect Collateral Valuation | fixed | Medium | |
F-2024-5008 | Lack of Timestamp Validation may Result in Incorrect Pricing of Tokens | fixed | Low | |
F-2024-4911 | Missing Zero Address Check in PToken Transfer may Lead to Loss of Funds and Inconsistencies | fixed | Low | |
F-2024-4903 | MINIMUM_LIQUIDITY Locking Impacts Initial Minter Adversely | mitigated | Low | |
F-2024-4330 | Double-Entry Point Vulnerability in sweepToken Function | fixed | Low | |
F-2024-5010 | Missing Initialization of AlgebraV1PriceOracle in ArbitrumPriceOracle Deployment | fixed | Observation | |
F-2024-5009 | Unsupported ERC20 Tokens may Revert Calls to NFT Oracles | fixed | Observation | |
F-2024-4897 | Incorrect Interface Definition in AlgebraV1PriceOracle | mitigated | Observation | |
F-2024-4446 | Outdated Version of Solidity and OpenZeppelin library | accepted | 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/paribus/paribus-protocol→ |
Commit | 56e0ba2 |
Whitepaper | https://paribus.io/documents/PARIBUS-Litepaper-V1.0.pdf→ |
Requirements | https://docs.paribus.io/,→ |
Technical Requirements | README.md |
Scope Details
- Commit
- 56e0ba2
- Requirements
- https://docs.paribus.io/,→
- Technical Requirements
- README.md
Contracts in Scope
contracts/ErrorReporter.sol
contracts/Comptroller/ComptrollerStorage.sol
contracts/Comptroller/ComptrollerInterfaces.sol
contracts/PNFTToken/PNFTToken.sol
contracts/PNFTToken/PNFTTokenInterfaces.sol
contracts/PToken/PToken.sol
contracts/PToken/PErc20/PErc20.sol
contracts/PToken/PErc20/PErc20Delegate.sol
contracts/PToken/PErc20/PErc20DelegateV2.sol
contracts/PToken/PTokenInterfaces.sol
contracts/PriceOracle/ArbitrumPriceOracle.sol
contracts/PriceOracle/Impl/AggregatorOracle.sol
contracts/PriceOracle/Impl/AlgebraV1PriceOracle.sol
contracts/PriceOracle/Impl/Api3PriceOracle.sol
contracts/PriceOracle/Impl/ChainlinkPriceOracle.sol