Audit name:

[SCA] Paraswap / Portikus-Contracts / Sep2024

Date:

Nov 1, 2024

Table of Content

Introduction

Audit Summary

System Overview

Potential Risks

Findings

Appendix 1. Definitions

Appendix 2. Scope

Disclaimer

Introduction

We express our gratitude to the ParaSwap team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.

Portikus is an intent-based protocol designed to facilitate gasless swaps through the execution of signed user intents by authorized agents. The protocol's architecture is centered around a registry of agents and modules and a factory for adapter creation.

The repository has been moved. The latest version of the previous repository can be found in the new repository at https://github.com/0xLaita/portikus-public .

  • Document

    Name
    Smart Contract Code Review and Security Analysis Report for ParaSwap
    Audited By
    Turgay Arda Usman, Kornel Światłowski
    Approved By
    Ataberk Yavuzer
    Changelog
    30/09/2024 - Preliminary Report
    04/10/2024 - Second Report
    01/11/2024 - Final Report
    Platform
    Ethereum
    Language
    Solidity
    Tags
    Layer 2, ERC-20, DEX, Signatures, Upgradable

Audit Summary

11Total Findings
2Resolved
8Accepted
1Mitigated

The system users should acknowledge all the risks summed up in the risks section of the report

Documentation quality

  • Functional requirements are provided.

  • Technical description is provided.

Code quality

  • The code mostly follows best practices and style guides.

    • See obersavitions and low severity findings for more details.

  • Several template code patterns were found.

  • The development environment is configured.

Test coverage

Code coverage of the project is 100% (branch coverage).

  • Deployment and basic user interactions are covered with tests.

System Overview

Portikus is an intent-based protocol designed to facilitate gasless swaps through the execution of signed user intents by authorized agents. It has the following contracts:

  • The PortikusV2 - is the second version of the Portikus protocol, designed to facilitate the creation of modular adapter contracts and manage a registry of verified agents. The contract combines a factory pattern, enabling the deployment of customizable adapters, with a registry system that tracks trusted agents authorized to execute orders on behalf of users. Additionally, the registry stores modules that can be installed to extend the functionality of the adapter contracts. This architecture enhances flexibility and security by allowing the modular expansion of features while ensuring that only trusted entities interact with user assets.

  • The Registry - is a core component of the Portikus protocol, serving as a registry for both verified agents and modules. Verified agents are authorized to execute transactions on behalf of users, while registered modules expand the functionality of Portikus adapter contracts. The contract allows the owner to add or remove agents and modules, ensuring that only trusted entities can interact with user assets or modify system behavior.

  • The Factory - facilitates the creation of modular executor contracts, known as Adapters, using the create2 opcode for deterministic deployment. This approach allows the same contract address to be generated based on a provided salt, ensuring predictable deployments.

  • The Adapter - is a core component of the PortikusV2 protocol, designed to manage modules and execute their functions. It allows the owner to install and uninstall registered modules, which extend the contract's functionality by adding specific function selectors. The contract integrates a fallback function to delegate calls to the appropriate module based on the function signature. Ownership can be transferred, and the contract ensures only registered modules from the PortikusV2 registry can be installed. It is structured to manage modular, upgradable functionality dynamically.

  • The BaseModule - is an abstract base for all modules in the Portikus V2 protocol, providing foundational structure and metadata for each module. The contract allows inheriting modules to define their own function selectors and metadata while ensuring they are compliant with the Portikus V2.

  • The FeeClaimerModule -is a smart contract in the Portikus V2 protocol that enables partners and the protocol to manage fee withdrawals. It allows partners to claim their collected fees in a secure and modular way. The contract includes functions for withdrawing specific amounts, withdrawing all fees at once, and batch processing multiple fee claims across different tokens. It also manages protocol-level fee claims, enabling authorized entities to withdraw protocol fees.

  • The NonceManagementModule - is a smart contract designed to manage transaction nonces within the Portikus V2 protocol. It allows users to invalidate specific nonces or multiple nonces in bulk, helping to prevent the reuse of nonces for unauthorized or replay attacks. The contract also provides functionality to query the status of nonces, enabling users or external systems to check whether particular nonces have been used.

  • The ERC20UtilsLib - is a utility library designed to streamline and secure ERC20 token interactions within the Portikus V2 protocol. It handles common tasks such as token transfers, balance queries, and token approval through the permit function.

  • The FeeManagerLib - is a library designed to manage fees within adapter modules of the PortikusV2 protocol. It provides functionality for fee processing, collection, and distribution between protocol participants, such as partners and the protocol itself. The library processes fees based on a partner’s fee structure, calculates protocol and partner fees, and allows partners to withdraw collected fees in ERC20 tokens or ETH. Additionally, the contract includes mechanisms to ensure only authorized accounts can claim protocol fees.

  • The FillableOrderHashLib - is a library that handles the hashing of FillableOrder structures within a protocol. It computes a unique hash for each order using the keccak256.

  • The FillableStorageLib - is a library designed to manage fillable orders within the PortikusV2 protocol. It provides a mechanism for storing and updating the filled amounts of orders using their unique hashes.

  • The ModuleManagerLib - is a library designed to facilitate the management of modules within an adapter contrac. It allows for the installation and uninstallation of modules while dynamically handling their associated function selectors. The library ensures that each function selector is unique and not already assigned to another module, preventing potential conflicts. Overall, this library plays a critical role in enabling modularity within the PortikusV2 protocol.

  • The NonceManagerLib - is a library designed to efficiently manage nonces within adapter modules of the PortikusV2 protocol. By utilizing a mapping structure, the library provides functionalities for marking nonces as used, checking if a nonce has been consumed, and invalidating specific nonces for the sender.

  • The OrderHashLib - is a library designed for efficiently hashing Order structs.

  • The SignatureLib - is a specialized library for validating signatures within smart contracts, supporting both EIP-2098 and ERC-1271 signature formats. It provides essential functions to verify the authenticity of signed data, ensuring that only legitimate signers can execute specific actions.

  • The BaseSettlementModule - serves as an abstract foundation for settlement facets within the Portikus V2 protocol, incorporating essential functionalities such as EIP712 signing, reentrancy protection, and authorization checks.

  • The DirectSettlementModule - facilitates the direct settlement of orders using agents' funds. This contract processes individual and batch orders by verifying their authenticity, transferring input assets from the order owner to the agent, and ensuring the correct output assets are delivered to the designated beneficiary. It employs rigorous validation mechanisms, including nonce management and signature verification, to prevent unauthorized transactions and ensure order integrity. The module also manages fees and permits, allowing for seamless asset transfers and efficient fee processing.

  • The FillableDirectSettlementModule  - is a smart contract designed to facilitate the direct settlement of fillable orders within the Portikus V2 protocol. It allows agents to partially or fully settle orders using specified percentages, providing flexibility in managing asset transfers. This module verifies the authenticity of orders, processes input asset transfers from order owners, and ensures that output assets are delivered to the designated beneficiaries.

  • The FillableSwapSettlementModule - is a smart contract designed to facilitate the settlement of fillable orders within a decentralized exchange ecosystem. It manages the entire lifecycle of a swap, including pre-execution checks, execution of the swap via an external executor, and post-execution steps to ensure proper asset transfer to beneficiaries. The contract verifies order authenticity and integrity through signature validation and nonce management.

  • The SwapSettlementModule -is a smart contract designed to facilitate the settlement of swap orders. It handles the entire settlement process, including pre-execution verification, execution of the order through an external executor contract, and post-execution asset transfers. The module ensures that the specified conditions of the orders are met, including the validity of signatures and deadlines, while transferring the necessary assets between parties.

Privileged roles

  • The owner of can create new adapters.

  • The owner can register or unregister modules.

  • The owner can register or unregister agents.

  • The owner can set the protocol fee claimer.

  • An authorized agent can execute intents on behalf of users.

  • An authorized agent can settle orders.

  • The fee claimer can withdraw all their collected fees for a specific token.

Potential Risks

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.

The implemented logic uses a external contract (SafeTransferLib.sol from solady) 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 project's contracts are upgradable, allowing the administrator to update the contract logic at any time. While this provides flexibility in addressing issues and evolving the project, it also introduces risks if upgrade processes are not properly managed or secured, potentially allowing for unauthorized changes that could compromise the project's integrity and security.

The project iterates over large dynamic arrays, which leads to excessive gas costs, risking denial of service due to out-of-gas errors, directly impacting contract usability and reliability.

The  project does not support non-standard ERC20 tokens. Adding such tokens in the future can cause additional risks.

The SafeTransferFrom function in the project assumes that ERC20 tokens return a value of 1 or no data upon successful transfers. However, non-standard ERC20 tokens that return other values (e.g., 0 or 2) or no value at all may cause the contract to misinterpret the transfer status, leading to transaction reverts. This can disrupt the functionality and user experience, as users may encounter unexpected transaction failures when interacting with non-standard tokens, impacting the overall usability and reliability of the system.

The ShortStrings implementation supports strings up to 31 bytes in length. If a longer string is passed, the system may either truncate the string, leading to data loss if not properly handled, or throw an error, potentially disrupting contract execution.

Making external calls within loops increases the risk of gas exhaustion, potentially leading to failed transactions and reduced contract reliability, especially when processing large datasets.

Findings

Code
Title
Status
Severity
F-2024-6340
Rounding and Precision Loss in Fill Calculation
Accepted

Low
F-2024-6311
Incrementing selectorPosition Inside the Loop
Fixed

Low
F-2024-6294
Lack of msg.value Validation in directSettle Functions Permits Incorrect Native Token Transfers
Accepted

Low
F-2024-6218
Lack of Approval Reset Logic for Non-zero Allowances
Mitigated

Low
F-2024-6198
Lack Of Access Control In Module Management
Fixed

Low
F-2024-6271
EIP-2098 Signature Verification Incompatibility with Traditional ECDSA Signatures
Accepted

Observation
F-2024-6315
Missing Validation for ERC20 Static Call Return Size
Accepted

Observation
F-2024-6249
Decreased Interoperability from Removing the IERC5267 Interface
Accepted

Observation
F-2024-6248
Reduced Flexibility due to Hardcoded Name and Version Values
Accepted

Observation
F-2024-6224
Inconsistent Fee Handling for Stablecoins
Accepted

Observation
1-10 of 11 findings

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

    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.

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:

Contracts in Scope

PortikusV2.sol - PortikusV2.sol
adapter
Adapter.sol - adapter/Adapter.sol
interfaces
IAdapter.sol - adapter/interfaces/IAdapter.sol
IERC173.sol - adapter/interfaces/IERC173.sol
IErrors.sol - adapter/interfaces/IErrors.sol
executors
example
AugustusExecutor.sol - executors/example/AugustusExecutor.sol
ThreeStepExecutor.sol - executors/example/ThreeStepExecutor.sol
libraries
ExecutorLib.sol - executors/libraries/ExecutorLib.sol
interfaces
IExecutor.sol - executors/interfaces/IExecutor.sol
factory
Factory.sol - factory/Factory.sol
modules
base
BaseModule.sol - modules/base/BaseModule.sol
FeeClaimerModule.sol - modules/base/FeeClaimerModule.sol
NonceManagementModule.sol - modules/base/NonceManagementModule.sol

Disclaimer