Introduction
We express our gratitude to the Aspis team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
ASPIS is a decentralized asset management protocol. It operates as a smart contract factory, deploying on-chain asset management vaults tailored to various strategies, such as mutual funds and liquidity pool (LP) management.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for Aspis |
| Audited By | Olesia Bilenka; Seher Saylık |
| Approved By | Ataberk Yavuzer |
| Website | https://aspis.finance/→ |
| Changelog | 08/07/2025 - Preliminary Report |
| 25/07/2025 - Final Report | |
| Platform | Arbitrum, Ethereum, BSC, Base, Polygon |
| Language | Solidity |
| Tags | Signatures; Centralization; Upgradable; Vault; Liquidity Pool; Factory; ERC-1271 |
| Methodology | https://hackenio.cc/sc_methodology→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for Aspis
- Audited By
- Olesia Bilenka; Seher Saylık
- Approved By
- Ataberk Yavuzer
- Website
- https://aspis.finance/→
- Changelog
- 08/07/2025 - Preliminary Report
- 25/07/2025 - Final Report
- Platform
- Arbitrum, Ethereum, BSC, Base, Polygon
- Language
- Solidity
- Tags
- Signatures; Centralization; Upgradable; Vault; Liquidity Pool; Factory; ERC-1271
- Methodology
- https://hackenio.cc/sc_methodology→
Review Scope | |
|---|---|
| Repository | https://github.com/aspis-finance/DAO→ |
| Commit | 8c338f9 |
| Remediation Commit | 1ed6405 |
Review Scope
- Repository
- https://github.com/aspis-finance/DAO→
- Commit
- 8c338f9
- Remediation Commit
- 1ed6405
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
{FindingsVulnSeverityStatusTable}
Documentation quality
Functional requirements are covered.
A technical description is provided.
Code quality
Well-structured architecture with clearly separated modules.
Smart contract interactions are cleanly designed and logically organized.
Follows Solidity best practices, including:
Proper event emissions
Access control mechanisms
Reentrancy guards
Custom error handling.
Mathematical computations are accurate and aligned with protocol requirements.
Effective integration and utilization of multiple oracle sources.
Access control logic is encapsulated in a separate contract, providing a clear and modular authorization layer.
Pool creation follows the Factory pattern, improving extensibility and consistency.
System configuration is well-isolated and delegated to dedicated modules.
Gas-efficient implementation with minimal redundancy, however, some gas inefficiencies and redundant logic duplications were found.
The development environment is configured.
Test coverage
Code coverage of the project couldn't be measured due to the “stack too deep” error.
Simple user interactions are tested.
Some of the contracts are not tested at all. For instance, RedstonePullAdapter, ChainlinkAdapter, OneInchV6Decoder, OdosV2Decoder, etc.
Negative test cases or multi-user interactions are partly covered.
System Overview
Aspis Finance is a decentralized fund management protocol that allows users to create and participate in investment DAOs with automated governance and trading capabilities. The system consists of the following core contracts:
AspisPool — main pool contract that serves as the core of each investment DAO
This is the primary contract that handles all fund operations including deposits, withdrawals, trading execution, and governance integration.
Deposit/Withdrawal System: Users can deposit supported tokens (including ETH) during fundraising periods and receive LP tokens representing their share
Trading Integration: Executes trades through whitelisted DEX protocols (Uniswap, 1inch, Odos) with slippage protection
Fee Collection: Automatically collects entrance fees, fund management fees, performance fees, and rage quit fees
Emergency Controls: Guardian can activate emergency stop to halt all operations
EIP-1271 Signature Validation: Supports smart contract wallet signatures for governance
Supported operations:
Fundraising with configurable time windows and deposit limits
Asset management through trusted protocol integrations
Liquidity provision and yield farming strategies
Governance proposal execution
AspisConfiguration — Configuration contract storing pool-specific parameters including fees, limits, supported tokens, and operational settings.
OneInchV6Decoder — Validates and decodes transaction data for 1inch V6 router calls to ensure only approved operations.
AspisLiquidityCalculatorV3 — Price calculator that aggregates multiple oracle sources to determine USD values of tokens and portfolio holdings.
AspisPoolFactory — Factory contract that deploys complete DAO ecosystems including pool, governance token, voting contract, and configuration.
ACL — Access control list system managing role-based permissions across the protocol with support for oracles and conditional permissions.
UniswapUniversalDecoder — Validates Uniswap Universal Router transaction data to ensure compliance with pool trading restrictions.
AspisLibrary — Utility library containing mathematical functions for fee calculations, deposit validation, and slippage tolerance checks.
UniswapAdapter — Price adapter that fetches token prices from Uniswap V3 pools for portfolio valuation.
AspisRegistry — Central registry managing protocol-wide settings, supported protocols/tokens, and DAO registration with fee configuration.
V4decoder — Specialized decoder for Uniswap V4 operations ensuring transaction compliance with pool parameters.
OdosV2Decoder — Validates transaction data for Odos V2 router calls to prevent unauthorized trading operations.
RedstonePullAdapter — Pull-based price adapter that fetches real-time token prices from Redstone oracles on-demand.
ChainlinkAdapter — Price adapter integrating with Chainlink price feeds for reliable token valuation data.
BytesLib — Low-level utility library providing functions for bytes manipulation and data extraction operations.
Permit2Lib — Integration library for Uniswap's Permit2 system enabling gasless token approvals and transfers.
1inchProtocolLib — Protocol-specific library containing validation logic and utilities for 1inch V6 integration.
AspisGuardian — Multi-role guardian contract with emergency powers and protocol-wide administrative capabilities.
BaseAdapter — Abstract base contract defining the interface and common functionality for all price adapters.
TimeHelpers — Utility contract providing time-related functions with mockable block number and timestamp getters for testing.
PullAdapter — Base contract for pull-based price adapters that fetch data on-demand from external sources.
PushAdapter — Base contract for push-based price adapters that receive regularly updated price data.
ECDSAExternal — External library for ECDSA signature operations and EIP-1271 smart contract signature validation.
Uint256Helpers — Utility library providing safe type conversion functions, particularly for uint256 to smaller integer types.
IACLOracle — Interface defining oracle contracts that can provide additional conditional logic for access control decisions.
AspisProposal — Contract component handling proposal validation and execution logic for DAO governance operations.
Proxy — Utility contract for creating and managing proxy deployments with initialization data encoding.
Privileged roles
Aspis Guardian Role
The Guardian has protocol-wide administrative powers and can:
Set protocol trading commission (up to 0.5%) and manager commission (up to 5%)
Add/remove supported trading protocols and tokens across all DAOs
Register exchange decoders for trade validation
Execute emergency functions on any pool through the guardian contract
Update the pool factory address in the registry
Pool Manager Role
Each pool has a designated manager who can:
Execute trades through supported protocols within spending limits
Update their address (if permitted by pool configuration)
Collect accumulated management fees
Perform direct transfers (if enabled in configuration)
Pool Access Control Roles
The ACL system defines several key roles:
UPGRADE_ROLE: Can upgrade pool contract implementations
DAO_CONFIG_ROLE: Can update pool configuration parameters
EXEC_ROLE: Can execute validated proposals and transactions
Potential Risks
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.
Dependency on External Logic for Implemented Logic: The implemented AspisPool logic 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. However, the protocol implements multiple layers of protection. The AspisLiquidityCalculatorV3 contract provides a clean abstraction over external price feeds, allowing for easy replacement if vulnerabilities are discovered. All external calls are followed by balance verification to ensure expected behavior.
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. However, only pre-approved protocols can be used through the trustedProtocolsSet. The emergencyStop() function can immediately halt all operations if external protocols are compromised.
Dynamic Array Iteration Gas Limit Risks: The project iterates over large dynamic arrays, which leads to excessive gas costs, risking denial of service due to out-of-gas errors. However, the loops were optimized during the remediation, The codebase implemented several gas optimization strategies: unchecked loops, bounded arrays, efficient data structures (EnumerableSet).
Absence of Time-lock Mechanisms for Critical Operations: Without time-locks on critical operations, there is no buffer to review or revert potentially harmful actions, increasing the risk of rapid exploitation and irreversible changes.
Privileged roles' 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 like minting phases. However, the protocol implements comprehensive access controls and critical operations require guardian approval.
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. However, the system uses distributed control across manager, guardian, and DAO roles.
Flexibility and Risk in Contract Upgrades: The project's AspisPoolFactory contract is 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.
Guardian can instantly replace Oracle adapters without time lock protection, enabling immediate price manipulation and fund drainage.
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2025-1152 | ERC1271 Signature Validation in AspisPool Lacks Transfer Receiver Verification, Allowing Front-Running Attacks | mitigated | High | |
| F-2025-1148 | Assignment Operator Bug in ETH-WETH Normalization Logic | fixed | High | |
| F-2025-1117 | Incorrect Fund Management And Performace Fees Calculation Due to Subtraction in Denominator | fixed | High | |
| F-2025-1101 | Incorrect Cardinality Check Using observationCardinalityNext in UniswapAdapter | fixed | High | |
| F-2025-1100 | decodeV4SwapInput Accepts Multiple Swap Actions but Only Handles One Correctly | fixed | High | |
| F-2025-1158 | Inefficient Loops and Potential DoS Vulnerabilities | fixed | Medium | |
| F-2025-1108 | Global Role Permissions in willPerform() May Violate Principle of Least Privilege | accepted | Medium | |
| F-2025-1104 | Hardcoded Redstone Decimals May Break Compatibility | accepted | Medium | |
| F-2025-1104 | LP Token Price May Evaluate to Zero | fixed | Medium | |
| F-2025-1104 | Missing updatedAt Check and Time-Based Validity Constraint in ChainlinkAdapter.getPrice() | fixed | Medium |
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/aspis-finance/DAO→ |
| Commit | 8c338f99c3d667df2576be2d32a4313a36cccaa7 |
| Remediation Commit | 1ed64052227b2e8c90beb89e68e53df9d193de3d |
| Functional Requirements | https://miniature-christmas-824.notion.site/Aspis-Smart-Contracts-Documentation-1c9062e2427c80e0b3caf5e58315e5f6?source=copy_link→ |
| Requirements | https://miniature-christmas-824.notion.site/Aspis-Smart-Contracts-Documentation-1c9062e2427c80e0b3caf5e58315e5f6?source=copy_link→ |
Scope Details
- Repository
- https://github.com/aspis-finance/DAO→
- Commit
- 8c338f99c3d667df2576be2d32a4313a36cccaa7
- Remediation Commit
- 1ed64052227b2e8c90beb89e68e53df9d193de3d
Deployed Contracts
BSC Mainnet
Contract | Address |
|---|---|
| AspisPoolFactory | 0x4b3b3efdfebc923fc0586f53324974caab460c9f→ |
| UniswapUniversalDecoder | 0xb12a2de7f999ae1639ea481c5d8cb40dc1a331d5→ |
| OdosV2Decoder | 0x910b6dee99766c7ec09242bc427989e7e6be7fa2→ |
| OneInchV6Decoder | 0x00192441f8c5d1335f14634959c8e1195a23be51→ |
| RedstonePullAdapter | 0x8034626acaaa5197ee51933194d91f9ebd89b607→ |
| AspisLiquidityCalculatorV3 | 0xe67ead515a6661008a100d034a016a38dcde58c2→ |
Contract
- AspisPoolFactory
Contract
- UniswapUniversalDecoder
Contract
- OdosV2Decoder
Contract
- OneInchV6Decoder
Contract
- RedstonePullAdapter
Contract
- AspisLiquidityCalculatorV3
Polygon
Contract | Address |
|---|---|
| AspisPoolFactory | 0x3449ab64300a2f1e55f5595866c7e021c46dd3f5→ |
| UniswapUniversalDecoder | 0xb89d4cb7ba84ac4db56209a60d0f9fe19b4b109a→ |
| OdosV2Decoder | 0x8a9d9bc9dd64cf984bba7a65651bd0f3b825c571→ |
| OneInchV6Decoder | 0xf55dc22bf413286093d0719da8519863dd81be82→ |
| RedstonePullAdapter | 0x15ba3343fdb1759c259f3fa9c8dfb47b58de020b→ |
| AspisLiquidityCalculatorV3 | 0x481255fd37986e5155e0af4bfa71f2fabc0293e1→ |
Contract
- AspisPoolFactory
Contract
- UniswapUniversalDecoder
Contract
- OdosV2Decoder
Contract
- OneInchV6Decoder
Contract
- RedstonePullAdapter
Contract
- AspisLiquidityCalculatorV3
Base
Contract | Address |
|---|---|
| AspisPoolFactory | 0xf862f466dfe9d07fbf3965488764f71b5eaa6e05→ |
| UniswapUniversalDecoder | 0x42dcb2b6956b6af9552baaf73d32f2c9f18e8c25→ |
| OdosV2Decoder | 0x9bd9af89b5ffd122e0e71bfaac169c0f92e8c1a9→ |
| OneInchV6Decoder | 0x3191c855408defba1ac720840cb7e3e5f3b4f7c8→ |
| RedstonePullAdapter | 0xdaf10eafc1478d1975b34d9c43b8426a4026baaa→ |
| AspisLiquidityCalculatorV3 | 0xda63e54f8a7c383983d557683f72da69f4c287a7→ |
Contract
- AspisPoolFactory
Contract
- UniswapUniversalDecoder
Contract
- OdosV2Decoder
Contract
- OneInchV6Decoder
Contract
- RedstonePullAdapter
Contract
- AspisLiquidityCalculatorV3
Arbitrum
Contract | Address |
|---|---|
| AspisPoolFactory | 0xdd409a48ea15e8db3f4f0c6282c94a983e906d99→ |
| UniswapUniversalDecoder | 0xbee00584a17f973cdf2b4cd90d0f89546128da51→ |
| OdosV2Decoder | 0x9280ad5ee105d33b0c0fd5e034dce833f6b1d282→ |
| OneInchV6Decoder | 0x9c5adece4be4c0089d90b692a2f25ca61464d998→ |
| RedstonePullAdapter | 0x11b453977df423db75f8a4924ffc8df9eddd85ea→ |
| AspisLiquidityCalculatorV3 | 0xca48f3553d2f8ca8a612285834eb7369f138ac9e→ |
Contract
- AspisPoolFactory
Contract
- UniswapUniversalDecoder
Contract
- OdosV2Decoder
Contract
- OneInchV6Decoder
Contract
- RedstonePullAdapter
Contract
- AspisLiquidityCalculatorV3
Assets in Scope
Appendix 3. Additional Valuables
Verification of System Invariants
During the audit of ASPIS, Hacken followed its methodology by performing invariant-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, 80 invariants were tested over 10,000 runs. This thorough testing ensured that the system works correctly even with unexpected or unusual inputs.
Invariant | Test Result | Run Count |
|---|---|---|
| AspisConfiguration: Each user appears exactly once in the whitelist. | Passed | 10K+ |
| AspisConfiguration: Whitelist never contains zero addresses. | Failed | 0 |
| AspisConfiguration: Whitelist state remains consistent after adding/removing users. | Passed | 10K+ |
| AspisConfiguration: Public Fund status remains consistent. | Failed | 10K+ |
| AspisConfiguration: userWhitelisted function returns consistent results with actual whitelist. | Passed | 10K+ |
| AspisConfiguration: Minimum deposit never exceeds maximum deposit. | Passed | 10K+ |
| AspisConfiguration: Financial parameters (maxCap, deposits, price) are always consistent. | Passed | 10K+ |
| AspisConfiguration: Finish time is always after start time when both are set. | Passed | 10K+ |
| AspisConfiguration: All fees never exceed maximum fee percentage (100%). | Passed | 10K+ |
| AspisConfiguration: Trading/Deposit tokens array contains only valid non-zero addresses. | Passed | 10K+ |
| AspisConfiguration: Trusted protocols array contains only valid non-zero addresses. | Passed | 10K+ |
| AspisConfiguration: Trading/Deposit tokens array contains no duplicate addresses. | Passed | 10K+ |
| AspisConfiguration: Every deposit token is also a trading token. | Failed | 0 |
| AspisRegistry: Supported protocols array contains no duplicate addresses. | Passed | 10K+ |
| AspisRegistry: Supported protocols array contains no zero addresses. | Failed | 10K+ |
| AspisRegistry: Supported tokens array contains no duplicate addresses. | Passed | 10K+ |
| AspisRegistry: Supported tokens array contains no zero addresses. | Failed | 0 |
| AspisRegistry: Token addition operations maintain array consistency. | Passed | 10K+ |
| AspisRegistry: DAO names remain unique across all registrations. | Passed | 10K+ |
| AspisRegistry: Registered DAO names maintain consistent status. | Passed | 10K+ |
| AspisRegistry: Decoder mappings remain consistent for valid exchanges. | Passed | 10K+ |
| AspisRegistry: Zero address exchanges cannot have valid decoders. | Passed | 10K+ |
| .AspisRegistry: Commissions never exceed maximum limits. | Passed | 10K+ |
| AspisRegistry: Only guardian can modify supported protocols / tokens. | Passed | 10K+ |
| AspisPool: When emergency mode is activated, the rage quit fee is automatically set to 0. | Passed | 10K+ |
| AspisPool: Manager balance never exceeds the sum of total token supply and protocol manager commission. | Passed | 10K+ |
| AspisPool: Manager address is always valid (non-zero) and can only be changed through authorized means. | Passed | 10K+ |
| AspisPool: Finish time is always greater than start time, and both times are positive values. | Passed | 10K+ |
| AspisPool: All fees (entrance, fund management, performance, rage quit) never exceed 100%. | Passed | 10K+ |
| AspisPool: Minimum deposit is always less than or equal to maximum deposit, and both are positive values. | Passed | 10K+ |
| AspisPool: Total deposits and withdrawals are consistent, withdrawals never exceed deposits, and depositors never exceed total user count. | Passed | 10K+ |
| AspisPool: Total accounted assets (token supply + manager balance + protocol commission) are consistent. | Passed | 10K+ |
| AspisPool: Protocol trading revenue is correct when manager commission exists, ensuring activity consistency. | Passed | 10K+ |
| AspisPool: When depositors exist and fees are configured, manager balance should reflect fee accumulation. | Passed | 10K+ |
| AspisPool: Fundraising phases maintain logical consistency with deposit availability. | Passed | 10K+ |
| AspisPool: Withdrawal windows are logically positioned after fundraising with proper freeze periods and fee structures. | Passed | 10K+ |
| AspisPool: Total effective supply (tokens + fees) stays within reasonable bounds relative to max cap to prevent token inflation attacks. | Passed | 10K+ |
| AspisPool: Deposit limits are enforced consistently when deposits occur. | Passed | 10K+ |
| AspisPool: Private fund whitelist logic functions correctly when depositors exist. | Passed | 10K+ |
| AspisPool: Performance fees remain reasonable relative to total supply and don't exceed the token supply. | Passed | 10K+ |
| AspisPool: Rage quit fee logic correctly applies based on timing (fundraising/freeze/withdrawal window phases) and emergency mode. | Passed | 10K+ |
| AspisPool: Protocol revenue accumulation is consistent with commission rates and both rates are within protocol bounds. | Passed | 10K+ |
| AspisPool: Emergency mode has proper cascade effects while preserving core functionality. | Passed | 10K+ |
| AspisPool: Value conservation principle ensures deposits result in LP token creation and withdrawals respect availability. | Passed | 10K+ |
| AspisPool: Withdrawal window complexity ensures different phases have appropriate fee structures and timing logic. | Passed | 10K+ |
| AspisPool: Emergency mode protects user funds by preserving all core balances and maintaining system mathematical integrity. | Passed | 10K+ |
| AspisPool: Emergency mode blocks new deposits while allowing legitimate withdrawals and maintaining economic consistency. | Passed | 10K+ |
| AspisPoolFactory: Created components count consistency maintained across all types. | Passed | 10K+ |
| AspisPoolFactory: All pools have associated token, voting, and configuration components. | Passed | 10K+ |
| ChainlinkAdapter: Data feed integrity maintained with valid decimals configuration. | Passed | 10K+ |
| ChainlinkAdapter: Multiple conversion operations maintain individual result accuracy. | Passed | 10K+ |
| ChainlinkAdapter: Total conversions always greater than or equal to successful conversions. | Passed | 10K+ |
| UniswapAdapter: ETH and WETH handling maintains correct address differentiation. | Passed | 10K+ |
| UniswapAdapter: Decimal handling ensures accurate conversions across different token standards. | Passed | 10K+ |
| UniswapAdapter: Time-weighted calculations remain within period bounds. | Passed | 10K+ |
| RedstonePullAdapter: Conversions preserve mathematical correctness and positive values. | Passed | 10K+ |
| RedstonePullAdapter: Payload processing remains deterministic and consistent. | Passed | 10K+ |
| RedstonePullAdapter: Decimal handling preserves accuracy for all supported tokens. | Passed | 10K+ |
| ACL: Frozen roles cannot be modified once frozen. | Passed | 10K+ |
| ACL: Permission hashes are unique and deterministic. | Passed | 10K+ |
| ACL: Freeze operations are permanent and irreversible. | Passed | 10K+ |
| ACL: Oracle usage tracking maintains accuracy across all operations. | Passed | 10K+ |
| ACL: Bulk operations are atomic and consistent. | Passed | 10K+ |
| OdosV2Decoder: decodes all the swaps correctly for swapCompact() selector | Passed | 10K+ |
| OdosV2Decoder: decodes all the swaps correctly for swap() selector | Passed | 10K+ |
| OdosV2Decoder: decodes swap correctly for swapPermit2() selector | Passed | 10K+ |
| OdosV2Decoder: decodes zero address as ETH correctly | Passed | 10K+ |
| OdosV2Decoder: reverts on unknown selector | Passed | 10K+ |
| OneInchV6Decoder: it does not overwrite for any offset | Failed | 10K+ |
| OneInchV6Decoder: validates memory write pattern and offsets in curve coin selection | Passed | 10K+ |
| OneInchV6Decoder: testMemoryState reverts on out-of-bounds | Passed | 10K+ |
| OneInchV6Decoder: extract correctly the boolean wrapped flags | Passed | 10K+ |
| UniswapUniversalDecoder: decodes any basic two-token V3 swap path correctly | Passed | 10K+ |
| UniswapUniversalDecoder: decodes any same-token V3 swap path correctly | Passed | 10K+ |
| UniswapUniversalDecoder: decodes any V3 swap path with interleaved fee bytes correctly | Passed | 10K+ |
| UniswapUniversalDecoder: decodes multi-hop V3 swap path (A→B→C) correctly | Passed | 10K+ |
| UniswapUniversalDecoder: decodes single-address (20-byte) V3 swap path correctly | Passed | 10K+ |
| UniswapUniversalDecoder: reverts on V3 swap path shorter than 20 bytes | Passed | 10K+ |
| UniswapUniversalDecoder: decodes any basic two-token V2 swap path correctly | Passed | 10K+ |
| UniswapUniversalDecoder: decodes any basic two-token V4 swap path correctly | Passed | 10K+ |
Invariant
- AspisConfiguration: Each user appears exactly once in the whitelist.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Whitelist never contains zero addresses.
Test Result
- Failed
Run Count
- 0
Invariant
- AspisConfiguration: Whitelist state remains consistent after adding/removing users.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Public Fund status remains consistent.
Test Result
- Failed
Run Count
- 10K+
Invariant
- AspisConfiguration: userWhitelisted function returns consistent results with actual whitelist.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Minimum deposit never exceeds maximum deposit.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Financial parameters (maxCap, deposits, price) are always consistent.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Finish time is always after start time when both are set.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: All fees never exceed maximum fee percentage (100%).
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Trading/Deposit tokens array contains only valid non-zero addresses.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Trusted protocols array contains only valid non-zero addresses.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Trading/Deposit tokens array contains no duplicate addresses.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisConfiguration: Every deposit token is also a trading token.
Test Result
- Failed
Run Count
- 0
Invariant
- AspisRegistry: Supported protocols array contains no duplicate addresses.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisRegistry: Supported protocols array contains no zero addresses.
Test Result
- Failed
Run Count
- 10K+
Invariant
- AspisRegistry: Supported tokens array contains no duplicate addresses.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisRegistry: Supported tokens array contains no zero addresses.
Test Result
- Failed
Run Count
- 0
Invariant
- AspisRegistry: Token addition operations maintain array consistency.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisRegistry: DAO names remain unique across all registrations.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisRegistry: Registered DAO names maintain consistent status.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisRegistry: Decoder mappings remain consistent for valid exchanges.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisRegistry: Zero address exchanges cannot have valid decoders.
Test Result
- Passed
Run Count
- 10K+
Invariant
- .AspisRegistry: Commissions never exceed maximum limits.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisRegistry: Only guardian can modify supported protocols / tokens.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: When emergency mode is activated, the rage quit fee is automatically set to 0.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Manager balance never exceeds the sum of total token supply and protocol manager commission.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Manager address is always valid (non-zero) and can only be changed through authorized means.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Finish time is always greater than start time, and both times are positive values.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: All fees (entrance, fund management, performance, rage quit) never exceed 100%.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Minimum deposit is always less than or equal to maximum deposit, and both are positive values.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Total deposits and withdrawals are consistent, withdrawals never exceed deposits, and depositors never exceed total user count.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Total accounted assets (token supply + manager balance + protocol commission) are consistent.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Protocol trading revenue is correct when manager commission exists, ensuring activity consistency.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: When depositors exist and fees are configured, manager balance should reflect fee accumulation.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Fundraising phases maintain logical consistency with deposit availability.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Withdrawal windows are logically positioned after fundraising with proper freeze periods and fee structures.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Total effective supply (tokens + fees) stays within reasonable bounds relative to max cap to prevent token inflation attacks.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Deposit limits are enforced consistently when deposits occur.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Private fund whitelist logic functions correctly when depositors exist.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Performance fees remain reasonable relative to total supply and don't exceed the token supply.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Rage quit fee logic correctly applies based on timing (fundraising/freeze/withdrawal window phases) and emergency mode.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Protocol revenue accumulation is consistent with commission rates and both rates are within protocol bounds.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Emergency mode has proper cascade effects while preserving core functionality.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Value conservation principle ensures deposits result in LP token creation and withdrawals respect availability.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Withdrawal window complexity ensures different phases have appropriate fee structures and timing logic.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Emergency mode protects user funds by preserving all core balances and maintaining system mathematical integrity.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPool: Emergency mode blocks new deposits while allowing legitimate withdrawals and maintaining economic consistency.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPoolFactory: Created components count consistency maintained across all types.
Test Result
- Passed
Run Count
- 10K+
Invariant
- AspisPoolFactory: All pools have associated token, voting, and configuration components.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ChainlinkAdapter: Data feed integrity maintained with valid decimals configuration.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ChainlinkAdapter: Multiple conversion operations maintain individual result accuracy.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ChainlinkAdapter: Total conversions always greater than or equal to successful conversions.
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapAdapter: ETH and WETH handling maintains correct address differentiation.
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapAdapter: Decimal handling ensures accurate conversions across different token standards.
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapAdapter: Time-weighted calculations remain within period bounds.
Test Result
- Passed
Run Count
- 10K+
Invariant
- RedstonePullAdapter: Conversions preserve mathematical correctness and positive values.
Test Result
- Passed
Run Count
- 10K+
Invariant
- RedstonePullAdapter: Payload processing remains deterministic and consistent.
Test Result
- Passed
Run Count
- 10K+
Invariant
- RedstonePullAdapter: Decimal handling preserves accuracy for all supported tokens.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ACL: Frozen roles cannot be modified once frozen.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ACL: Permission hashes are unique and deterministic.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ACL: Freeze operations are permanent and irreversible.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ACL: Oracle usage tracking maintains accuracy across all operations.
Test Result
- Passed
Run Count
- 10K+
Invariant
- ACL: Bulk operations are atomic and consistent.
Test Result
- Passed
Run Count
- 10K+
Invariant
- OdosV2Decoder: decodes all the swaps correctly for swapCompact() selector
Test Result
- Passed
Run Count
- 10K+
Invariant
- OdosV2Decoder: decodes all the swaps correctly for swap() selector
Test Result
- Passed
Run Count
- 10K+
Invariant
- OdosV2Decoder: decodes swap correctly for swapPermit2() selector
Test Result
- Passed
Run Count
- 10K+
Invariant
- OdosV2Decoder: decodes zero address as ETH correctly
Test Result
- Passed
Run Count
- 10K+
Invariant
- OdosV2Decoder: reverts on unknown selector
Test Result
- Passed
Run Count
- 10K+
Invariant
- OneInchV6Decoder: it does not overwrite for any offset
Test Result
- Failed
Run Count
- 10K+
Invariant
- OneInchV6Decoder: validates memory write pattern and offsets in curve coin selection
Test Result
- Passed
Run Count
- 10K+
Invariant
- OneInchV6Decoder: testMemoryState reverts on out-of-bounds
Test Result
- Passed
Run Count
- 10K+
Invariant
- OneInchV6Decoder: extract correctly the boolean wrapped flags
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: decodes any basic two-token V3 swap path correctly
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: decodes any same-token V3 swap path correctly
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: decodes any V3 swap path with interleaved fee bytes correctly
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: decodes multi-hop V3 swap path (A→B→C) correctly
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: decodes single-address (20-byte) V3 swap path correctly
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: reverts on V3 swap path shorter than 20 bytes
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: decodes any basic two-token V2 swap path correctly
Test Result
- Passed
Run Count
- 10K+
Invariant
- UniswapUniversalDecoder: decodes any basic two-token V4 swap path correctly
Test Result
- Passed
Run Count
- 10K+
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.