Web3 · Smart contract audit
Strobe Finance
softstack completed a smart contract audit of Strobe Finance's Protocol in July 2025, reporting 10 findings (1 critical, 1 high, 6 medium and 2 low), of which 9 were resolved or mitigated before the final report. The full report is published in the softstack public audit archive.
Key facts
- Client
- Strobe Finance
- Completed
- Type
- Smart contract audit
- Chains
- XRP Ledger, Ethereum
- Commit
5f7f3e0e64f1
About the project
Strobe Finance is a decentralised yield and money market protocol serving XRP holders across the XRP Ledger ecosystem. It runs on the XRPL EVM sidechain and relies on Axelar cross-chain messaging to reach other networks. The protocol offers DeFi primitives such as lending, borrowing and liquidity provisioning for assets that originate on the XRP Ledger.
Scope
Source repositorygithub.com/strobe-protocol/strobe-v1-coreComponents reviewed
1 module- See the published report for the file list
Findings
9 of 10 findings resolved before the final report.
| ID | Title | Severity | Status |
|---|---|---|---|
6.2.1 | Incorrect State Handling in Cross-Chain Operations The AxelarPool._executeWithInterchainToken function processes cross-chain commands. For operations involving the outbound transfer of tokens from the protocol to a user on another chain (i.e., WITHDRAW, WITHDRAW_ALL, BORROW), the current… | Critical | acknowledged |
6.2.2 | Critical Reliance on Unvalidated Oracle Price Feeds The Pool.sol contract determines the value of user collateral and debt by making direct calls to _oracle.getPrice(token). | High | fixed |
6.2.3 | Unauthorized Initiation of Trapped Token Clearing The AxelarPool.clearTrappedToken() function is an external function designed to release tokens that were previously "trapped" due to failures in cross-chain operations (e.g., a failed deposit after tokens were received by AxelarPool). | Medium | fixed |
6.2.4 | Interest Rate Model at Zero Utilization May Not Reflect baseRate The InterestRateStrategyOne.getInterestRates() function determines the current lending and borrowing rates for a reserve. | Medium | fixed |
6.2.5 | Linear Gas Scaling in Health Checks Leading to Potential DoS The core internal function Pool.calculateUserCollateralData() is responsible for determining a user's total collateral value and total collateral required to maintain their loan positions. | Medium | fixed |
6.2.6 | Inflated Reserve Balance in Post-Liquidation Rate Calculation Due to Double-Counting During a liquidation event within Pool.sol, the amount repaid by the liquidator appears to be effectively double-counted when determining the reserveBalance parameter used for the subsequent interest rate calculation. | Medium | fixed |
6.2.7 | AxelarPool Susceptible to Reentrancy Leading to Pool.sol State Manipulation The AxelarPool.sol contract serves as an intermediary for cross-chain operations, invoking core logic in Pool.sol. | Medium | fixed |
6.2.8 | Lack of ERC20 Decimals Validation in _addReserve Leads to Potential DoS for Reserve Operations The PoolConfig._addReserve() function, responsible for initializing new token reserves, fetches the decimals of the provided token contract via an external call: uint8 decimals = ERC20(token).decimals();. | Medium | fixed |
6.2.9 | Immutable Cross-Chain Configuration Limits Adaptability The AxelarPool.sol contract initializes the acceptedSourceChain string parameter within its constructor. | Low | fixed |
6.2.10 | Front-Running Attack on AssertionPoster Configuration The subtraction rawUserDebtBefore - rawAmount can underflow if rawAmount > rawUserDebtBefore. This would corrupt debt accounting, allowing users to bypass repayment obligations and potentially drain funds. | Low | fixed |
Methodology
Review process
Scoping and threat modelling
The commit hash is frozen and the attack surface is mapped: asset flows, trust assumptions, privileged roles and the external systems the code depends on.
Automated analysis
Static analysers sweep the full codebase to surface known weakness patterns, unreachable states and deviations from established conventions.
Manual code review
Independent engineers read the code line by line, concentrating on business logic, access control, arithmetic and the handling of external calls.
Adversarial testing
Property-based fuzzing and invariant tests attack the assumptions the protocol relies on, targeting states that ordinary unit tests never reach.
Reporting
Every finding is documented with a severity rating, its impact, the steps to reproduce it and a concrete remediation the team can act on.
Remediation verification
Submitted fixes are re-reviewed against the original finding, and the final report records the resolved state of each one.
FAQ
The review reported 10 findings: 1 critical, 1 high, 6 medium and 2 low. 9 of 10 were resolved or mitigated before the final report.
The review covered the code in github.com/strobe-protocol/strobe-v1-core at commit 5f7f3e0. The published report lists every file covered.
This report covers the code as reviewed in July 2025 at commit 5f7f3e0. Any code changed after that point is outside the reviewed scope.