CertiK reviewed NATIX Network (NATIX Network - audit) on 19 Sep 2024: 15 findings, 0 critical; 9 marked fixed, 1 acknowledged, 5 open.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 1 | 0 |
| Medium | 0 | 0 | 3 |
| Low | 5 | 0 | 6 |
The project failed to compile, and some of the dependencies may have problems. The details are as following dependency: ```toml spl-associated-token-account = { version = "2.3.1", features = [ "no-entrypoint" ]} ``` The issue should related to the version update on solana-program which caused the version of `spl-associated-token-account` to be yanked, more details can be found: https://github.com/solana-labs/solana-program-library/issues/6897
In the current implementation, the `program_account` refers to the pool account that holds staking information, while the `stake_account` refers to the token account that holds the staked tokens and rewards. However, the program allows multiple `program_account` and `stake_account` instances, which can cause confusion between different pools and token accounts. For example, UserA could stake using `program_account1` and `stake_account1`, but then withdraw using `program_account1` and `stake_account2`. To prevent this, each `program_account` should be explicitly linked to a specific `stake_account` to avoid any potential confusion.
The function `control_user_solana_address` in `src/control_user_solana_address.rs` performs a weak validation on the ownership of the user's associated token account. The current validation only checks if the user_account.key matches the expected address, but it doesn't ensure that the user_account is actually owned by the user. ```rust=25 if user_account.key != &address { return Err(ProgramError::InvalidAccountOwner); } ``` In Solana, associated token accounts can be transferred to other users, which means that the owner of the token account may not be the original user who created it. This weak validation can potentially allow unauthorized access or transfers of the associated token account. Reference: https://github.com/solana-labs/solana-program-library/issues/2640
The `cancel` function in cancel.rs allows users to cancel all their unstake requests. However, the function includes a call to `control_stake_amount` with None as the amount parameter after giving back the unstakes to the user's stake pool. The `control_stake_amount` function validates if the total stake amount for the user's address is within the configured limit. ```rust=38 if sum_stakes > staking_pool.config.max_stake_amount { return Err(ProgramError::Custom(102)); } ``` If canceling the unstake requests causes the total stake to exceed the limit, the control_stake_amount function would return an error, blocking the cancellation process. This means that users may be unable to cancel their unstake requests if doing so would cause their total stake to exceed the allowed limit. --- At the same time, the limitation on unique stakes (`config.maximum_stakers`) can be broken due to cancellation when a new user joins between the `unstack` and `cancel` periods. ```rust=32 for staker in staking_pool.stakers.iter().filter(|staker| staker.unstake_time == 0 && staker.stake_time > 0) { set.insert(staker.address); } set.len() ```
The address check is intended to verify that the input token program account is the legitimate token program (i.e., `spl_token::id()`) on Solana. However, the provided `token_program_account` does not perform this check, raising concerns about the validity of the account input by the user.
The `user_account` and `stake_account` are treated as token accounts associated with the `natix_token_mint`. But before decoding them as a `TokenAccount`, there is no validation to confirm that its owner is the **Token Program**, which allows the user to input a malicious token account.
The mint validation for `stake_token_account` is missing which may allow user input an non-NATIX token account.
In the `withdraw.rs` file, line 72 calculates the total amount of tokens to be forfeited during a withdrawal in the staking contract: ```rust=72 forfeit_amount = forfeit_amount.checked_add((penalty.checked_sub(reward)).unwrap_or(0)).expect("Overflow during forfeit summation"); ``` However, there is a concern with this implementation: The penalty amount is subtracted from the reward amount using `penalty.checked_sub(reward)`. This means that an amount of tokens equal to the reward will remain in the stake account, mixing with the user's deposit and project rewards since it is not specifically tracked.
The current implementation of the staking program lacks validation or constraints while setting the staking rate. Consequently, it's possible to set a value greater than 100, allowing for an interest rate exceeding 100%.
The report names a repository or files. Open the report to see its scope.
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us