We express our gratitude to the Astral Holding OU team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.
The Sallar ecosystem is a network of community projects that use Sallar as their payment method. With Sallar, you can pay for products and services, such as clothing, and use it as the currency on the Marketplace Community.
Review Scope
10/10
7/10
90%
10/10
The system users should acknowledge all the risks summed up in the risks section of the report
This report may contain confidential information about IT systems and the intellectual property of the Customer, as well as information about potential vulnerabilities and methods of their exploitation.
The report can be disclosed publicly after prior consent by another Party. Any subsequent publication of this report shall be without mandatory consent.
Document
This program manages creation, emission and distribution of a fungible token. Its maximum supply is 12,000,000,000 of which:
2,600,000,000 is distributed to a special “organization” account.
9,400,000,000 is distributed in batches of so-called “blocks”.
There are 470,000 blocks, which are distributed in a game-like fashion one by one in two ways: top-to-bottom (starting from block 1, aka “mining”), and bottom-to-top (starting from block 470,000, aka “staking”). Each block needs to be exhausted (for the next one to become available) by user requests, which the off-chain code posts to the contract on behalf of the users; each such request causes transferring a portion of the block tokens to the user that corresponds to the request. The rules and requests are different for the two directions - the details are in the official documentation →.
Once all the blocks have been consumed, two distribution modes become available: “final mining” and “final staking”. Each mode has a designated account (exclusively managed by the contract) which can be funded by anybody using the previously distributed funds; funds in the special accounts are distributed according to yet new games, whose rules are described in the official documentation →. The two final distribution games are played in cycles, and there can be indefinitely many cycles - as long as there are funds in the special accounts. Like in the normal block distribution modes, the games are played with user requests, which the off-chain code posts to the contract on behalf of the users; each such request causes transferring a portion of the block tokens to the user that corresponds to the request.
Each distribution game has a significant part of its logic outside the contract - which is out of the scope.
The smart contract has the following API:
initialize — Sets up program-related accounts and performs initial mint. Can be called at most once.
initialtokendistribution — Distribute 2,600,000,000 tokens to the “organization” account, provided by the owner. Can be called at most once.
solvetopblock — The owner executes a set of user requests to play the “mining” game.
solvebottomblock — The owner executes a set of user requests to play the “staking” game.
finalmining_ — The owner executes a set of user requests to play the “final mining” game.
finalstaking_ — The owner executes a set of user requests to play the “final staking” game.
changeauthority_ — The owner changes the contract authority to the new one.
The only user of the program is owner - an account registered by the initialize()
function and can be changed using change_authority()
.
The total Documentation quality score is 10 out of 10.
The functional documentation covers everything in satisfactory detail.
Technical description is provided.
The total Code quality score is 7 out of 10.
Redundancies are found (I-2023-0418).
Some confusing points are found (I-2023-0422).
Floating point numbers math is used.
Code coverage of the project is 90% (branch coverage).
final_mining
and final_staking
instructions are tested but their effects are not checked during testing.
The solve_top_block
and solve_bottom_block
instructions that take a lot lines of code (due to redundancies and code duplications) are successfully tested.
Upon auditing, the code was found to contain 1 critical, 2 high, 5 medium, and 1 low severity issues. Out of these, 6 issues have been addressed and resolved, leading to a security score of 10 out of 10.
All identified issues are detailed in the “Findings” section of this report.
The comprehensive audit of the customer's smart contract yields an overall score of 9.1. This score reflects the combined evaluation of documentation, code quality, test coverage, and security aspects of the project.
Unless the smart contract is deployed with the --final
flag, it could be upgraded and its functionality may be changed.
The contract is fully centralized: \-The owner
is the only user and has complete control over it. \-The token distribution claims are made exclusively by the owner
, who is free to arbitrarily forge them in their favor or censor/handicap normal user claims.
A major part of the overall system logic – that is financially relevant – is outside the contract. The contract only processes results of some off-chain computations that are out of the audit scope.
The final_mining
and final_staking
APIs are designed to distribute tokens from the special contract accounts, but it is not guaranteed that the accounts will be properly funded.
Anyone is able to initialize the program by calling initialize
(can be called only once). It is recommended to perform deployment and initialization in one transaction.
The convert_f64_to_u64
and convert_u64_to_f64
will lose precision for numbers over 2^53, however it is unlikely.
The program performs computations in f64
, whereas the token value type is u64
- which requires casting token values to f64
and back. u64
values that take more than 53 bits are likely to be not representable in f64
, and have to be approximated. Moreover, f64
computations have limited precision on their own. Together, this may result in losses of portions of token values. However, the collective losses due to f64
precision are highly unlikely to be significant in USD equivalent.
The deployment code should not be compiled with the bpf-tests
feature.
Code ― | Title | Status | Severity | |
---|---|---|---|---|
F-2023-1594 | Incorrect Value | Fixed | Critical | |
F-2023-159 | Stuck Funds | Mitigated | High | |
F-2023-159 | Unset Or Unsettable Token Metadata | Fixed | High | |
F-2023-160 | Missing Validation & Corrupted Data | Mitigated | Medium | |
F-2023-1600 | Denial Of Service State | Mitigated | Medium | |
F-2023-159 | Missing Validation | Fixed | Medium | |
F-2023-159 | Immutable Ownership | Fixed | Medium | |
F-2023-159 | Invalid Hardcoded Value | Fixed | Medium | |
F-2023-1602 | Inconsistent Data | Fixed | Low | |
I-2023-042 | Unused Code | Fixed | Observation |
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
Severity
Description
Severity
Description
Severity
Description
The scope of the project includes the following smart contracts from the provided repository:
Scope Details
programs/sallar/src/account.rs
programs/sallar/src/context.rs
programs/sallar/src/error.rs
programs/sallar/src/lib.rs
programs/sallar/src/token_math.rs
programs/sallar/src/utils.rs