Introduction
We express our gratitude to the SalaamGCC team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
Salaamgcc-Contracts is a staking protocol responsible for staking and distribution of rewards tokens.
Document | |
|---|---|
| Name | Smart Contract Code Review and Security Analysis Report for SalaamGCC |
| Audited By | Viktor Lavrenenko |
| Approved By | Ivan Bondar |
| Website | http://salaamgcc.com/→ |
| Changelog | 14/02/2025 - Preliminary Report |
| 21/02/2025 - Final Report | |
| Platform | Ethereum |
| Language | Solidity |
| Tags | Staking, ERC20, Proxies, Upgradeable |
| Methodology | https://hackenio.cc/sc_methodology→ |
Document
- Name
- Smart Contract Code Review and Security Analysis Report for SalaamGCC
- Audited By
- Viktor Lavrenenko
- Approved By
- Ivan Bondar
- Website
- http://salaamgcc.com/→
- Changelog
- 14/02/2025 - Preliminary Report
- 21/02/2025 - Final Report
- Platform
- Ethereum
- Language
- Solidity
- Tags
- Staking, ERC20, Proxies, Upgradeable
- Methodology
- https://hackenio.cc/sc_methodology→
Review Scope | |
|---|---|
| Repository | https://github.com/SalaamGCC/salaamgcc-contracts→ |
| Commit | fa63c1c |
| Retest commit | 130b2c1 |
Review Scope
- Commit
- fa63c1c
- Retest commit
- 130b2c1
Audit Summary
The system users should acknowledge all the risks summed up in the risks section of the report
Documentation quality
Functional requirements are complete:
The project's purpose is described.
Business logic is provided in the internal document.
Use cases are described.
Project's features are complete.
Technical description is provided:
Architectural overview is provided.
Roles and authorization are described.
Information on used technologies is provided.
NatSpec comments for the key functions are provided.
A README file with setup instructions is provided.
Code quality
Best practices are followed.
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.
Negative cases coverage is provided.
Interactions by several users are tested thoroughly.
System Overview
Salaamgcc-Contracts is a staking protocol with the following contracts:
SalaamGcc — an upgradeable ERC-20 token, which has a capped supply and includes features for ownership, pauseability and access control. It has the following attributes:
Name: SalaamGCC.
Symbol: SGCC.
Decimals: 18.
Maximum Supply: 6000000_000 * 10**18.
SalaamGccStaking - the contract manages the staking of tokens and distributes rewards in a specified rewards token.
Privileged roles
The owner of the
SalaamGccStakingcontract can:add the number of reward tokens via the function
SalaamGccStaking::fundRewardPool()to the pool balance, so the pool will be able to reward its users.set the staking cap values via the
SalaamGccStaking::setCap()function.recover any token from the Staking contract to the caller address via the
SalaamGccStaking::recoverERC20()function.can transfer ownership to another address via the
SalaamGccStaking::transferOwnership()function.
The owner of the
SalaamGcccontract can:set the minter address via the
SalaamGccStaking::setMinter()function.can upgrade the implementation contract via the
SalaamGccStaking::upgradeToAndCall()function.
The
MINTERrole of theSalaamGcccontract can mint newSGCCtokens.The
ADMIN_ROLErole of theSalaamGcccontract can pause and unpause theSalaamGccsmart contract viaSalaamGcc::pause()andSalaamGcc::unpause()functions.
Potential Risks
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.
Administrative Key Control Risks: The digital contract architecture relies on administrative keys for critical operations. Centralized control over these keys presents a significant security risk, as compromise or misuse can lead to unauthorized actions or loss of funds.
Pausability Mechanism: The project's contracts utilize a pause feature. This functionality can be used to manage the protocol in case any issue arises that require the lockdown of the system, which means that the system can be paused at any moment.
Flexibility and Risk in Contract Upgrades: 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.
Absence of Upgrade Window Constraints: The contract suite allows for immediate upgrades without a mandatory review or waiting period, increasing the risk of rapid deployment of malicious or flawed code, potentially compromising the system's integrity and user assets.
Fronrunning During The Initialization Of The Implementation Contract: If the deployment and the initialization of the implementation contract, which is SalaamGcc, will not be handled within one transaction, it can cause the front-running of the SalaamGcc::initialize() function by the attacker which will lead to unexpected system behavior.
Acceptance of Any ERC20 Tokens: The SalaamGCCStaking.sol contract allows any ERC20 tokens to be used as staking and reward tokens. Even though the team does not have any plans to use non-standard ERC20 tokens such as fee-on-transfer tokens or rebasing tokens, the current system will face significant problems if such tokens will be accepted.
Reliance On Off-Chain Systems: The functionality and security of system contracts may rely on external off-chain systems or processes that are not covered by this audit. This creates a risk that these off-chain dependencies could fail, be manipulated, or behave unexpectedly, potentially leading to unintended behavior of the system.
Lack of Sufficient Number of Rewards: Stakers of the SalaamGCCStaking contract will not be able to withdraw their rewards if the pool does not have any reward tokens.
Limited Number Of Individual Stakes: The current version of the SalaamGCCStaking contract enables users to stake their tokens to earn the reward tokens in the future. However, it is only possible to stake once and users cannot increase their stake if the number of the stake is not correct.
Distribution Numbers of GCC Tokens: According to the documentation, the 6B totalSupply value of GCC tokens is distributed across 6 entities. There is a risk that the numbers provided in the documentation will not be followed.
Findings
Code ― | Title | Status | Severity | |
|---|---|---|---|---|
| F-2025-8766 | Lack of Incentives for Early Stakers | fixed | High | |
| F-2025-8788 | Incorrect Assumptions Can Lead To Unexpected User Rewards | accepted | Medium | |
| F-2025-8748 | Lack of Token Restrictions Allows Privileged Users to Withdraw Staking and Reward Tokens | fixed | Medium | |
| F-2025-8764 | Reward Manipulation via Partial Withdrawals | fixed | Medium | |
| F-2025-8750 | Missing Reward Update Causes getReward() to Transfer Zero Rewards | fixed | Medium | |
| F-2025-8778 | Improper Implementation of the Halt Mechanics Leads To Unfair Rewards and Denial Of Service | fixed | Low | |
| F-2025-8767 | Missing periodFinish Validation Enables Premature Withdrawals and Reward Claims | fixed | Low | |
| F-2025-8763 | Inconsistent Reward Pool Tracking | fixed | Low | |
| F-2025-8790 | Reward Extension Without Additional Tokens Transfer Can Delay Withdrawals | fixed | Observation | |
| F-2025-8784 | Mismatch Between NatSpec Documentation and Implementation | 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/SalaamGCC/salaamgcc-contracts→ |
| Commit | fa63c1caa3c21a0a9aadd13f8100efb7244d1825 |
| Retest commit | 130b2c1e01f91d82539b258aadff2bb1ae3a7ed3 |
| Whitepaper | Whitepaper→ |
| Requirements | NatSpec→ |
| Technical Requirements | NatSpec→ |
Scope Details
- Commit
- fa63c1caa3c21a0a9aadd13f8100efb7244d1825
- Retest commit
- 130b2c1e01f91d82539b258aadff2bb1ae3a7ed3
- Whitepaper
- Whitepaper→
- Requirements
- NatSpec→
- Technical Requirements
- NatSpec→
Assets in Scope
Appendix 3. Additional Valuables
Verification of System Invariants
During the audit of Salaamgcc-Contracts, Hacken followed its methodology by performing fuzz-testing on the project's main functions. Echidna →, 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, 9 invariants were tested over 5,000,000 runs. This thorough testing ensured that the system works correctly even with unexpected or unusual inputs.
Invariant | Test Result | Run Count |
|---|---|---|
SalaamGcc::mint() should always increase the balance of the recipient and totalSupply of the contract | Passed | 5M |
SalaamGcc::setMinter() should never revert if the correct minter address is set | Passed | 5M |
SalaamGccStaking::setCap() should never revert if the new cap is greater then the totalSupply | Passed | 5M |
SalaamGccStaking::getRewardForDuration() should always return value which is equal to the multiplication of rewardRate and rewardsDuration | Passed | 5M |
SalaamGccStaking::stake() should always update the totalSupply, totalStaked and balance of the user | Passed | 5M |
SalaamGccStaking::setIsWithdrawEnable() should always revert if not called by the owner | Passed | 5M |
SalaamGccStaking::setSweeper() should always revert if not called by the owner | Passed | 5M |
SalaamGccStaking::startStaking() should always revert if not called by the owner | Passed | 5M |
SalaamGccStaking::stopStaking() should always revert if not called by the owner | Passed | 5M |
Invariant
SalaamGcc::mint()should always increase the balance of the recipient and totalSupply of the contractTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGcc::setMinter()should never revert if the correct minter address is setTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGccStaking::setCap()should never revert if the new cap is greater then the totalSupplyTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGccStaking::getRewardForDuration()should always return value which is equal to the multiplication ofrewardRateandrewardsDurationTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGccStaking::stake()should always update the totalSupply, totalStaked and balance of the userTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGccStaking::setIsWithdrawEnable()should always revert if not called by the ownerTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGccStaking::setSweeper()should always revert if not called by the ownerTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGccStaking::startStaking()should always revert if not called by the ownerTest Result
- Passed
Run Count
- 5M
Invariant
SalaamGccStaking::stopStaking()should always revert if not called by the ownerTest Result
- Passed
Run Count
- 5M
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.