Prepared by:
HALBORN
Last Updated 10/09/2024
Date of Engagement by: August 28th, 2024 - September 2nd, 2024
100% of all REPORTED Findings have been addressed
All findings
1
Critical
0
High
0
Medium
0
Low
0
Informational
1
IBX
team engaged Halborn to conduct a security assessment on their Artic L.Overflow
program beginning on August 28th, 2024 and ending on September 2nd, 2024. The security assessment was scoped to the smart contracts provided in the GitHub repository artic-overflow-sc. Commit hashes, and further details, can be found in the Scope section of this report.
IBX
is releasing Artic L.Overflow
, a program thought to allow the users to safely invest SOL in IBX
public sales, while respecting the project policy.
Halborn
was provided 4 days for the engagement and assigned one full-time security engineer to review the security of the Solana Program in scope. The engineer is a blockchain and smart contract security expert with advanced smart contract hacking skills, and deep knowledge of multiple blockchain protocols.
The purpose of the assessment is to:
Identify potential security issues within the codebase.
Check that the codebase does not have any known vulnerability that might affect the participants funds
Validate that users can safely invest in the IBX team
public sales without any security concern
In summary, Halborn did not identify any significant security risks. However, one improvement was highlighted that has been acknowledged by the IBX team
:
Duplication of validations in multiple functions
Halborn
performed a combination of a manual review of the source code and automated security testing to balance efficiency, timeliness, practicality, and accuracy in regard to the scope of the program assessment. While manual testing is recommended to uncover flaws in business logic, processes, and implementation; automated testing techniques help enhance coverage of programs and can quickly identify items that do not follow security best practices.
The following phases and associated tools were used throughout the term of the assessment:
Research into the architecture, purpose, and use of the token airdrop program.
Manual program source code review to identify business logic issues.
Mapping out possible attack vectors
Thorough assessment of safety and usage of critical Rust variables and functions in scope that could lead to arithmetic vulnerabilities.
Scanning dependencies for known vulnerabilities (cargo audit
).
EXPLOITABILIY METRIC () | METRIC VALUE | NUMERICAL VALUE |
---|---|---|
Attack Origin (AO) | Arbitrary (AO:A) Specific (AO:S) | 1 0.2 |
Attack Cost (AC) | Low (AC:L) Medium (AC:M) High (AC:H) | 1 0.67 0.33 |
Attack Complexity (AX) | Low (AX:L) Medium (AX:M) High (AX:H) | 1 0.67 0.33 |
IMPACT METRIC () | METRIC VALUE | NUMERICAL VALUE |
---|---|---|
Confidentiality (C) | None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) | 0 0.25 0.5 0.75 1 |
Integrity (I) | None (I:N) Low (I:L) Medium (I:M) High (I:H) Critical (I:C) | 0 0.25 0.5 0.75 1 |
Availability (A) | None (A:N) Low (A:L) Medium (A:M) High (A:H) Critical (A:C) | 0 0.25 0.5 0.75 1 |
Deposit (D) | None (D:N) Low (D:L) Medium (D:M) High (D:H) Critical (D:C) | 0 0.25 0.5 0.75 1 |
Yield (Y) | None (Y:N) Low (Y:L) Medium (Y:M) High (Y:H) Critical (Y:C) | 0 0.25 0.5 0.75 1 |
SEVERITY COEFFICIENT () | COEFFICIENT VALUE | NUMERICAL VALUE |
---|---|---|
Reversibility () | None (R:N) Partial (R:P) Full (R:F) | 1 0.5 0.25 |
Scope () | Changed (S:C) Unchanged (S:U) | 1.25 1 |
Severity | Score Value Range |
---|---|
Critical | 9 - 10 |
High | 7 - 8.9 |
Medium | 4.5 - 6.9 |
Low | 2 - 4.4 |
Informational | 0 - 1.9 |
Critical
0
High
0
Medium
0
Low
0
Informational
1
Security analysis | Risk level | Remediation Date |
---|---|---|
Duplication of validations in multiple functions | Informational | Acknowledged |
// Informational
The participate_in_overflow
is the entry point called by users to participate in the IBX team
public sale.
Participants should provide an amount greater than 0.1 SOL, and the total amount invested should not pass the 50 SOL.
After participating in the public sale, a Participant account is created to track the user investment.
The current version of the code validates the max amount of SOL in the participate_in_overflow
code, as shown in the snippet below:
participate_in_overflow.rs
// Checking that the user is allowed to buy this tickets
if participant_details.total_invested_sol + sol_amount > USER_OVERFLOW_MAX_SOL as u64 {
msg!("User cap reached");
return Err(OverflowError::UserOverflowCapReached.into());
}
if sol_amount < USER_OVERFLOW_MIN_SOL as u64 {
msg!("Min amount not reached");
return Err(OverflowError::ForbiddenAction.into());
}
// Transfering the funds to the multisig account
invoke(
&system_instruction::transfer(&user_account.key, &multisig_account.key, sol_amount),
&[
user_account.clone(),
multisig_account.clone(),
system_program_account.clone(),
],
)?;
// Registering the SOL investment into the overflow state
overflow_info.participate(sol_amount)?;
// Storing the participation
participant_details.participate(sol_amount)?;
The snippet above shows the mentioned validation and also highlights in line 156 that the participate
method is called. This method can is shown in the snippet below:
fn participate(&mut self, sol_amount: u64) -> Result<(), ProgramError> {
if self.total_invested_sol + sol_amount > USER_OVERFLOW_MAX_SOL {
msg!("User overflow cap reached");
return Err(OverflowError::UserOverflowCapReached.into());
}
self.total_invested_sol += sol_amount;
Ok(())
}
The snippet above highlights the lines with max investment validation duplicated.
The same situation happens in the end_overflow.rs
and overflow.rs
files, which are used to end the Overflow public sale.
Both snippets can be seen below:
end_overflow.rs
if overflow_info.ended {
msg!("Overflow is already ended");
return Err(OverflowError::AlreadyEnded.into());
}
//#endregion
//#region End overflow process
// Getting current timestamp from block
let clock = Clock::get()?;
let current_timestamp = clock.unix_timestamp as u64;
let current_block_number = clock.slot;
// Ending the overflow
overflow_info.end(current_timestamp)?;
fn end(&mut self, ended_at: u64) -> Result<(), ProgramError> {
if self.ended {
return Err(OverflowError::AlreadyEnded.into());
}
self.ended = true;
self.ended_at = ended_at;
Ok(())
}
While duplicating these validations poses no apparent risk, reducing the codebase is generally considered good practice to enhance readability as much as possible.
Consider following the next two recommendations:
removing one of the validations that is duplicated, either in participate_in_overflow.rs
or participant.rs
.
removing one of the validations that is duplicated, either in end_overflow.rs
or overflow.rs
.
ACKNOWLEDGED: The IBX team acknowledged this finding.
Halborn used automated security scanners to assist with detection of well-known security issues and vulnerabilities. Among the tools used was cargo audit
, a security scanner for vulnerabilities reported to the RustSec Advisory Database. All vulnerabilities published in https://crates.io
are stored in a repository named The RustSec Advisory Database. cargo audit
is a human-readable version of the advisory database which performs a scanning on Cargo.lock. Security Detections are only in scope. All vulnerabilities shown here were already disclosed in the above report. However, to better assist the developers maintaining this code, the auditors are including the output with the dependencies tree, and this is included in the cargo audit output to better know the dependencies affected by unmaintained and vulnerable crates.
Cargo Audit Results
ID | package | Short Description |
---|---|---|
RUSTSEC-2024-0344 | curve25519-dalek | Timing variability in |
Halborn strongly recommends conducting a follow-up assessment of the project either within six months or immediately following any material changes to the codebase, whichever comes first. This approach is crucial for maintaining the project’s integrity and addressing potential vulnerabilities introduced by code modifications.
// Download the full report
* Use Google Chrome for best results
** Check "Background Graphics" in the print settings if needed