Prepared by:
HALBORN
Last Updated 12/08/2025
Date of Engagement: November 12th, 2025 - November 20th, 2025
100% of all REPORTED Findings have been addressed
All findings
6
Critical
0
High
0
Medium
0
Low
2
Informational
4
THORChain engaged Halborn to conduct a security assessment of the Rujira FIN contracts, beginning on November 10th, 2025 and ending on November 18th, 2025. This security assessment was scoped exclusively to the updates introduced in version 1.1.0 of Rujira FIN, as the core system had already been reviewed in a previous audit. Commit hashes and further details can be found in the Sources section of this report.
Rujira FIN is a decentralized order book protocol built on top of Thorchain, enabling spot trading of native assets without wrapped tokens. It handles order creation, matching, and settlement fully on-chain.
The team at Halborn assigned a full-time security engineer to verify the security of the updated smart contracts. The security engineer is a blockchain and smart-contract security expert with advanced penetration testing, smart-contract hacking, and deep knowledge of multiple blockchain protocols.
The purpose of this assessment was to:
Ensure that the updated smart contract functions operate as intended
Identify potential security issues introduced or affected by the new logic in version 1.1.0
In summary, Halborn identified a few improvements to further harden the system and reduce the likelihood or impact of potential risks, which have been completely addressed by the Rujira development team. The most relevant ones were the following:
Forbid denom changes during migration unless the contract is fully shut down or enforce a pre-migration check ensuring no active orders or pools exist.
Deduplicate or reject repeated MarketMaker addresses during initialization before storing them.
Replace inv().unwrap() with a checked inversion that errors on zero or tiny prices, and validate MM price inputs before use.
Reject zero or negative tick values during configuration and validate ticks explicitly in Tick::new and Tick::validate.
Explicitly reject Fixed <= 0 before tick validation, add guards to prevent underflow in truncation, and ensure validation returns a contract error instead of panicking.
Replace the intermediate multiplication with amount.multiply_ratio(...) to avoid overflow and add tests with values near Uint128::MAX.
Halborn performed a combination of manual and automated security testing to balance efficiency, timeliness, practicality, and accuracy in regard to the scope of this assessment. While manual testing is essential to uncover flaws in logic, process, and implementation, automated techniques enhance coverage and quickly detect deviations from best practices.
The following phases and associated tools were used during the assessment:
Research into architecture, version 1.1.0 updates, and overall protocol purpose.
Manual code read and walkthrough of the updated Rust modules.
Manual assessment of critical arithmetic operations, rate handling, and overflow/underflow protections.
Logical review of order matching, bucket aggregation, and MarketMaker calculation flow.
Validation of safe handling for zero and invalid price conditions.
Review and verification of integration and unit tests covering the updated logic.
| EXPLOITABILITY 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 (C:N) Low (C:L) Medium (C:M) High (C:H) Critical (C: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
2
Informational
4
| Security analysis | Risk level | Remediation Date |
|---|---|---|
| Denoms can be changed during migrate with an active order book | Low | Solved - 11/26/2025 |
| Duplicate Market Makers addresses allow liquidity double-counting | Low | Solved - 11/26/2025 |
| Zero Tick size collapses price grid and blocks non-zero fixed prices | Informational | Solved - 11/26/2025 |
| Swap operation panics on zero or tiny MarketMaker prices | Informational | Solved - 11/26/2025 |
| Accepting `Fixed(0) prices triggers unhandled panic during Tick validation | Informational | Solved - 11/26/2025 |
| Potential Uint128 overflow in EitherOrBoth proportional split | Informational | Solved - 11/26/2025 |
//
//
//
//
//
//
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
RUJI Trade FIN v1.1
* Use Google Chrome for best results
** Check "Background Graphics" in the print settings if needed