All audits

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-core

Components reviewed

1 module
  1. See the published report for the file list

Findings

1Critical
1High
6Medium
2Low
0Informational

9 of 10 findings resolved before the final report.

IDTitleSeverityStatus
6.2.1Incorrect 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…

Criticalacknowledged
6.2.2Critical 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).

Highfixed
6.2.3Unauthorized 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).

Mediumfixed
6.2.4Interest Rate Model at Zero Utilization May Not Reflect baseRate

The InterestRateStrategyOne.getInterestRates() function determines the current lending and borrowing rates for a reserve.

Mediumfixed
6.2.5Linear 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.

Mediumfixed
6.2.6Inflated 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.

Mediumfixed
6.2.7AxelarPool 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.

Mediumfixed
6.2.8Lack 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();.

Mediumfixed
6.2.9Immutable Cross-Chain Configuration Limits Adaptability

The AxelarPool.sol contract initializes the acceptedSourceChain string parameter within its constructor.

Lowfixed
6.2.10Front-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.

Lowfixed

Methodology

Review process

  1. 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.

  2. Automated analysis

    Static analysers sweep the full codebase to surface known weakness patterns, unreachable states and deviations from established conventions.

  3. Manual code review

    Independent engineers read the code line by line, concentrating on business logic, access control, arithmetic and the handling of external calls.

  4. Adversarial testing

    Property-based fuzzing and invariant tests attack the assumptions the protocol relies on, targeting states that ordinary unit tests never reach.

  5. 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.

  6. 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.