Audit · firm’s term: audit report
QuillAudits reviewed Hivello on 1 Oct 2024: 9 findings, 0 critical; 8 marked fixed, 1 open.
Report hosted on quillaudits.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 | 0 | 1 |
| Medium | 0 | 0 | 1 |
| Low | 1 | 0 | 6 |
In the close_vault function, the admin has the ability to close the vault, which could prematurely halt all staking operations. This creates a significant risk, as the vault is central to managing the staking tiers, total staked tokens, and staker profiles. If the vault is closed while there are still active stakers or unclaimed rewards, it could result in unintended consequences, such as the loss of user funds, halted staking processes, and the inability to unstake or claim rewards. pub fn close_vault(_ctx: Context<CloseVault>) -> Result<()> { let payer = _ctx.accounts.identity.key(); require!(payer != ADMIN_PUBKEY, state::ErrorCode::AdminAccountOnly); Ok(()) }
In the stake function of the locking contract, the handling of token decimals is currently hardcoded to assume that the tokens being staked have 8 decimal places (token_decimals = 8). This approach introduces a significant flaw, as not all tokens on the Solana blockchain adhere to the same decimal structure. Different tokens can have varying numbers of decimal places, which represent the precision of the smallest divisible unit of the token. For instance, some tokens might have 6 decimals, while others could have 9 or 0. By hardcoding the decimal value, the contract assumes a fixed precision for all tokens, which can lead to miscalculations in staking amounts, rewards, and other related operations
In the current implementation of the contract, the administrator's public key (ADMIN_PUBKEY) is hardcoded directly into the contract. This creates a significant limitation in the event that the admin key is lost, compromised, or needs to be rotated for any reason. Because the admin key is statically embedded in the contract, there is no mechanism to update or change it without redeploying the entire contract. This can result in severe operational risks, as losing access to the admin key would leave the contract without a way to perform critical management actions such as updating tiers, modifying parameters, or closing the vault.
In the transfer_token function, the current implementation does not perform adequate validation to ensure that the correct token type is being transferred. The function is designed to facilitate token transfers between accounts, but without validating that the token involved in the transfer matches the expected token type, there is a risk of unintended consequences. Specifically, any token account could be passed into the transfer function, and tokens other than the intended one could be transferred. The function logs a message indicating the token transfer, but since the token type is not validated, the log message could be misleading, showing that a transfer has occurred without specifying the correct token type. This lack of validation can introduce confusion and undermine the integrity of the contract.
In the create_token function, there are several instances where numeric values, such as space = 82, rent_fee = 1461600, and decimals = 8, are hardcoded directly into the function. These values, often referred to as "magic numbers," are arbitrary constants that provide no context or explanation for their purpose. Hardcoding such values can significantly reduce the readability, flexibility, and maintainability of the code. Future developers or auditors may not easily understand the significance or calculation behind these numbers, making it harder to update or debug the system. For instance, if the rent or space requirements change in the underlying Solana protocol, these hardcoded values would need to be manually adjusted in every occurrence. Additionally, the fixed decimal value might not work for tokens with different decimal precision, creating inconsistency when minting or transferring tokens.
In the current implementation of the contract, there are no event emissions for critical management actions such as initialize (vault initialization) and update_tiers (updating the staking tiers). These actions represent important state changes in the contract, particularly for system administrators and auditors who need to track how the protocol evolves over time. The absence of events for these key management functions makes it difficult to monitor changes or create a historical log of important contract activities.
The current implementation of the contract lacks comprehensive unit tests and integration tests for several critical functions, particularly those related to core staking mechanisms, management actions, and edge cases.
In the current implementation of the staking system, when a user unstakes all their tokens, the tier information in the staker profile is not cleared. This results in a situation where the user’s staker profile still reflects their highest tier, even though they no longer have any tokens staked. This inconsistency can lead to several problems: it may falsely indicate that the user still qualifies for the highest tier benefits, potentially granting them access to features or rewards they are no longer eligible for. Moreover, since the tier information is not updated or cleared after the tokens are fully unstaked, the system does not accurately reflect the user’s staking status. This creates confusion in the user interface, reporting tools, and any systems that rely on the staker profile data.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (3)
350 projects reviewed · 459 reports · latest Apr 2025
See QuillAudits’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