Introduction
We express our gratitude to the ACN LABS team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Portals Contracts is a project with smart contracts that manage customizable vesting strategies and staking pools, allowing administrators to define flexible rules for token distribution and staking.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for ACN LABS |
| Audited By | Olesia Bilenka |
| Approved By | Przemyslaw Swiatowiec, Ataberk Yavuzer |
| Website | https://tenextoken.io/→ |
| Changelog | 21/01/2025 - Preliminary Report |
| 30/01/2025 - Final Report | |
| Platform | BSC; Base |
| Language | Solidity |
| Tags | Vesting; Staking; Claims |
| Methodology | https://hackenio.cc/sc_methodology→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for ACN LABS
- Audited By
- Olesia Bilenka
- Approved By
- Przemyslaw Swiatowiec, Ataberk Yavuzer
- Website
- https://tenextoken.io/→
- Changelog
- 21/01/2025 - Preliminary Report
- 30/01/2025 - Final Report
- Platform
- BSC; Base
- Language
- Solidity
- Tags
- Vesting; Staking; Claims
- Methodology
- https://hackenio.cc/sc_methodology→
Review Scope | |
|---|---|
| Repository | https://github.com/blank-development/portals-contracts→ |
| Commit | 0100c46 |
Review Scope
- Commit
- 0100c46
Audit Summary
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.
There are some duplications were found in the contracts.
The development environment is configured.
Test coverage
Code coverage of the project is 93% (Hardhat branch coverage) and 35% (Foundry branch coverage),
Deployment and basic user interactions are covered with tests.
Some InterestHelper cases coverage is missed.
Most of the functionality is tested.
System Overview
Portals Contracts is a project with smart contracts that manage customizable vesting strategies and staking pools, allowing administrators to define flexible rules for token distribution and staking:
PortalsMasterChef - is a contract that facilitates staking and reward distribution for multiple pools with customizable parameters. It supports token staking, reward claiming, and early unstaking with optional fees and penalties. The contract uses an upgradable architecture and integrates with ERC-20 tokens for staking and rewards, as well as ERC-721 tokens for providing additional NFT-based multipliers.
Key features include batch staking with token burns, dynamic APY and lock periods, and the ability to adjust pool parameters such as hard caps, fees, and multipliers. Users can stake tokens, claim rewards individually or across all pools, and unstake with potential penalties during lock periods. The contract includes safeguards such as pool existence validation, percentage cap limits, and role-based access control for administrative actions. Additionally, it supports treasury and depositor roles for batch operations and integrates fee burning mechanisms for added flexibility.
PortalsVesting - is a smart contract designed to manage token vesting strategies, enabling the controlled release of tokens over time based on predefined schedules. It supports various vesting types, including linear, interval-based, monthly, and exponential monthly vesting, providing flexibility to accommodate different use cases. Each vesting strategy can define parameters such as cliff duration, start time, total duration, initial unlock percentage, and interval-based unlocking rates.
The contract allows for whitelisting participants, specifying the amount of tokens allocated to each, and tracking their distributed and remaining tokens. Admins can manage strategies by adding, updating, and revoking participants' vesting rights. The contract also includes features to handle revocable vesting, enabling admins to reclaim tokens if needed.
DateTime - is a smart contract designed to handle date and time operations within Ethereum smart contracts. It provides various functions to work with UNIX timestamps, allowing developers to convert timestamps into human-readable components such as years, months, days, hours, minutes, and seconds. Additionally, it enables the conversion of structured date and time data into a UNIX timestamp.
InterestHelper - contract extends the DSMath library to facilitate precise calculations for compounding interest in a Solidity environment. The contract is designed to manage fixed-point arithmetic operations for financial calculations, such as accruing interest over time and converting yearly rates into formats suitable for compounding.
Privileged roles
In the PortalsMasterChef contract, the privileged roles and their respective permissions are as follows:
Owner:
Adding new staking pools and updating existing pool parameters, such as APY, lock periods, and hard caps.
Configuring batch staking parameters, including the treasury address, depositor address, and the percentage of tokens to burn during batch staking.
Adjusting claim fees and the recipient address for those fees.
Revoking tokens or NFTs by transferring them directly to their address.
Depositor:
Perform batch stake-and-burn operations for multiple users within a specified pool.
In the PortalsVesting contract, the privileged roles and their respective permissions are as follows:
Owner:
Add new vesting strategies with parameters like name, cliff duration, start time, duration, initial unlock percentage, revocability, intervals, unlock percentages, growth rates, and type.
Update existing vesting strategies, except for those with monthly or exponential monthly schedules.
Add wallets to a vesting strategy’s whitelist with specific token amounts.
Update the token amount for a wallet in the whitelist.
Revoke a wallet from the whitelist, making it ineligible for further distributions.
Enable or disable vesting status for specific wallets.
Perform batch additions to the whitelist.
Withdraw any amount of tokens from the contract balance.
Potential Risks
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 like minting phases.
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.
Flexibility and Risk in Contract Upgrades: The PortalsMasterChef contract is upgradeable, 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
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2025-8197 | Potential Incompatibility with Fee-On-Transfer Tokens in PortalsMasterChef Contract | accepted | Medium | |
| F-2025-8553 | Potential Claim Transaction Failure Due to Gas Limit in _hasSufficientRewardsForPayout | accepted | Low | |
| F-2025-8207 | CEI Pattern Violations in PortalsMasterChef and PortalVesting Contracts | fixed | Low | |
| F-2025-8203 | Centralization Risks in PortalsMasterChef Contract | accepted | Low | |
| F-2025-8202 | Incorrect Reward Balance Validation in PortalsMasterChef Contract for Pools Sharing the Same Token | fixed | Low | |
| F-2025-8199 | Potential Unstake Lock Due to Lack of Reward Token Funding Mechanism | fixed | Low | |
| F-2025-8294 | Code Duplication in PortalsVesting and PortalsMasterChef Contracts | fixed | Observation | |
| F-2025-8291 | Missing Validation for duration in addVestingStrategy and setVestingStrategy Functions | fixed | Observation | |
| F-2025-8206 | Unclear Function Naming in PortalsMasterChef and PortalsVesting Contracts | fixed | Observation | |
| F-2025-8205 | Missing Zero Address Validations in PortalsMasterChef Contract | fixed | Observation |
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/blank-development/portals-contracts→ |
| Commit | 0100c46469cd202a9cc9b08e89db61037c834c2b |
| Whitepaper | https://github.com/blank-development/portals-contracts/blob/master/README.md→ |
Scope Details
- Commit
- 0100c46469cd202a9cc9b08e89db61037c834c2b
Assets in Scope
Appendix 3. Additional Valuables
Verification of System Invariants
During the audit of Portals Contracts, Hacken followed its methodology by performing fuzz-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, 14 invariants were tested over 50,000 runs. This thorough testing ensured that the system works correctly even with unexpected or unusual inputs.
Invariant | Test Result | Run Count |
|---|---|---|
The totalDeposit of a pool must always increase or remain the same after a stake operation. | Passed | 50K+ |
The totalDeposit of a pool must always decrease or remain the same after an unstake operation. | Passed | 50K+ |
User balance should update correctly after stake. | Passed | 50K+ |
User balance should update correctly after unstake. | Passed | 50K+ |
The totalDeposit in a pool must always remain below or equal to the hardCap. | Passed | 50K+ |
No stake operations can occur after the endDate minus the lock period. | Passed | 50K+ |
| If an early unstake fee is applied, the fee is correctly deducted, burned, and transferred to the fee recipient. | Passed | 50K+ |
| Rewards must be consistent with the APY, time elapsed, and any applicable NFT multiplier. | Passed | 50K+ |
The initial unlock amount for any wallet must always match the specified initialUnlockPercent of its allocated tokens. | Passed | 50K+ |
The amount unlocked per interval must be consistent with the unlockPerInterval parameter. | Passed | 50K+ |
| After the final interval, all tokens must be vested. | Passed | 50K+ |
| The vesting schedule must align with the timestamps calculated during strategy creation. | Passed | 50K+ |
| Total vested tokens must equal the allocation by the end of the schedule. | Failed | 50K+ |
If a wallet’s whitelist entry is revoked, its revokeDate must be recorded, and no further tokens can be claimed. | Passed | 50K+ |
Invariant
- The
totalDepositof a pool must always increase or remain the same after astakeoperation. Test Result
- Passed
Run Count
- 50K+
Invariant
- The
totalDepositof a pool must always decrease or remain the same after anunstakeoperation. Test Result
- Passed
Run Count
- 50K+
Invariant
- User balance should update correctly after
stake. Test Result
- Passed
Run Count
- 50K+
Invariant
- User balance should update correctly after
unstake. Test Result
- Passed
Run Count
- 50K+
Invariant
- The
totalDepositin a pool must always remain below or equal to thehardCap. Test Result
- Passed
Run Count
- 50K+
Invariant
- No
stakeoperations can occur after theendDateminus the lock period. Test Result
- Passed
Run Count
- 50K+
Invariant
- If an early unstake fee is applied, the fee is correctly deducted, burned, and transferred to the fee recipient.
Test Result
- Passed
Run Count
- 50K+
Invariant
- Rewards must be consistent with the APY, time elapsed, and any applicable NFT multiplier.
Test Result
- Passed
Run Count
- 50K+
Invariant
- The initial unlock amount for any wallet must always match the specified
initialUnlockPercentof its allocated tokens. Test Result
- Passed
Run Count
- 50K+
Invariant
- The amount unlocked per interval must be consistent with the
unlockPerIntervalparameter. Test Result
- Passed
Run Count
- 50K+
Invariant
- After the final interval, all tokens must be vested.
Test Result
- Passed
Run Count
- 50K+
Invariant
- The vesting schedule must align with the timestamps calculated during strategy creation.
Test Result
- Passed
Run Count
- 50K+
Invariant
- Total vested tokens must equal the allocation by the end of the schedule.
Test Result
- Failed
Run Count
- 50K+
Invariant
- If a wallet’s whitelist entry is revoked, its
revokeDatemust be recorded, and no further tokens can be claimed. Test Result
- Passed
Run Count
- 50K+
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.