# Boost \_ Folks Finance 33568 - \[Smart Contract - Medium] Front-running vulnerability in cross-chain l

Submitted on Tue Jul 23 2024 15:39:34 GMT-0400 (Atlantic Standard Time) by @A2Security for [Boost | Folks Finance](https://immunefi.com/bounty/folksfinance-boost/)

Report ID: #33568

Report type: Smart Contract

Report severity: Medium

Target: <https://testnet.snowtrace.io/address/0x2cAa1315bd676FbecABFC3195000c642f503f1C9>

Impacts:

* Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
* Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)

## Description

## Brief/Intro

The `BridgeRouter` system contains a vulnerability in its loan creation process. This flaw allows malicious actors to front-run legitimate loan creation attempts, causing financial losses to users and disrupting the normal operation of the cross-chain lending platform. The issue stems from the ability to create loans with arbitrary `IDs` combined with the speed disparity between hub-to-hub and spoke-to-hub transactions.

## Vulnerability Details

* The vulnerability lies in the loan creation process, specifically in the interaction between spoke chains and the hub chain. The core issue stems from the ability of users to choose arbitrary `loanId` when creating loans, combined with the speed difference between hub-to-hub and spoke-to-hub transactions.

Here's a detailed breakdown of the vulnerability:

1. Loan Creation Process:

   * Users can initiate loan creation from spoke chains using the `createLoanAndDeposit` function in **SpokeToken.sol**.

   ```js
    function createLoanAndDeposit(
    Messages.MessageParams memory params,
    bytes32 accountId,
    bytes32 loanId,
    uint256 amount,
    uint16 loanTypeId,
    bytes32 loanName
     ) external payable nonReentrant {
    _doOperation(
        params,
        Messages.Action.CreateLoanAndDeposit,
        accountId,
        amount,
        abi.encodePacked(loanId, poolId, amount, loanTypeId, loanName)
    );
   }
   ```

   * This function allows users to specify any `loanId` they want.
   * The `createLoan` function in **SpokeCommon.sol** on the hub chain also allows arbitrary `loanId` selection.

     ```js
        function createLoan(
        Messages.MessageParams memory params,
        bytes32 accountId,
        bytes32 loanId,
        uint16 loanTypeId,
        bytes32 loanName
        ) external payable nonReentrant {
        _doOperation(params, Messages.Action.CreateLoan, accountId, abi.encodePacked(loanId, loanTypeId, loanName));
        }
     ```
2. Transaction Speed Disparity:

   * Hub-to-hub transactions are processed in a single transaction, as seen with `HubAdapter.sol`.

   ```js
       function sendMessage(Messages.MessageToSend calldata message) external payable override onlyBridgeRouter {
       // ... (other code)
       IBridgeRouter bridgeRouter = msg.sender == address(bridgeRouterSpoke) ? bridgeRouterHub : bridgeRouterSpoke;
       bridgeRouter.receiveMessage{ value: msg.value }(messageReceived);
       // ... (other code)
       }
   ```

   * Spoke-to-hub transactions require cross-chain messaging, making them significantly slower.
3. Exploitation Mechanism:
   * A malicious user observes a victim's `createLoanAndDeposit` transaction on a spoke chain.
   * The attacker quickly calls `createLoan` from **SpokeCommon.sol** on the hub chain using the same `loanId`.
   * Due to the speed advantage, the attacker's transaction is processed first.
4. Victim Transaction Failure:

   * When the victim's transaction reaches the **hub**, it calls `createUserLoan` than `deposit` in **LoanManager.sol** .
   * This function includes a check:

   ```js
       function createUserLoan(bytes32 loanId, bytes32 accountId, uint16 loanTypeId, bytes32 loanName)
       external
       override
       onlyRole(HUB_ROLE)
       nonReentrant
       {
       // ... (other checks)
       if (isUserLoanActive(loanId)) revert UserLoanAlreadyCreated(loanId);
       // ... (rest
       }
   ```

   * Since the `loanId` is already active due to the attacker's transaction, the victim's transaction reverts.
5. Financial Implications:
   * The victim loses crosschain fees for the failed transaction.
   * tokens that were transferred as part of `createLoanAndDeposit`, may be lost for ever.
6. Reversal Complications:
   * The victim can attempt to reverse the transaction to not lose his deposited funds, however this also incurs additional costs:
     * Fees for the initial cross-chain message (spoke to hub)
     * Fees for the reversal cross-chain message (hub to spoke)
     * Gas costs for executing both actions
   * If `returnAdapterId` or `returnGasLimit` weren't specified, reversal will fail, and cause permanent loss of deposited funds.

* This vulnerability exploits the system's cross-chain architecture and the lack of `loanId` reservation or verification mechanisms. It allows malicious actors to block legitimate loan creations and cause significant financial losses to users, undermining the security and reliability of the entire loan system.

## Impact Details

* This vulnerability enables attackers to front-run loan creation transactions, causing immediate financial losses to users through failed transactions and reversal costs.
* More critically, if users fail to specify the `returnIdAdapter` or return `gas limit`, their transactions become non-reversible, resulting in permanent loss of deposited funds. This flaw not only disrupts the platform's core loan creation functionality but also introduces a severe risk of irretrievable asset loss.
* The combination of transaction failures, unexpected costs, and the possibility of permanent fund loss poses an existential threat to the platform's operational integrity make this vulnerability high severity.

## Proof of concept

## Proof of Concept

Here's a step-by-step scenario demonstrating the vulnerability:

1. Victim initiates a `createLoanAndDeposit` transaction on a spoke chain.

```js
// On Spoke Chain
spokeToken.createLoanAndDeposit(params, accountId, loanId, amount, loanTypeId, loanName);
```

2. Attacker observes this transaction and quickly submits a `createLoan` transaction directly to the `spokeCommon` contract on the hub chain.

```js
// On Hub Chain
spokeCommon.createLoan(accountId, loanId, loanTypeId, loanName);
```

3. Due to faster hub-to-hub communication, the attacker's transaction is processed first:
   * In `LoanManager.sol`, the `createUserLoan` function successfully creates the loan for the attacker.

```js
 // In LoanManager.sol
 function createUserLoan(bytes32 loanId, bytes32 accountId, uint16 loanTypeId, bytes32 loanName) {
    if (isUserLoanActive(loanId)) revert UserLoanAlreadyCreated(loanId);
    // Loan created successfully for the attacker
 }
```

4. When the victim's transaction reaches the hub, it fails:

   * In `LoanManager.sol`, the `createUserLoan` function reverts because the loanId is already active.

   ```js
      // In LoanManager.sol
   function createUserLoan(bytes32 loanId, bytes32 accountId, uint16 loanTypeId, bytes32 loanName) {
      if (isUserLoanActive(loanId)) revert UserLoanAlreadyCreated(loanId);
      // Reverts here because loanId is already active
   }
   ```
5. The victim's transaction is reverted, but they've already paid for:
   * Gas fees for the initial transaction
   * Cross-chain messaging fees
6. To recover, the victim must initiate a reversal on the Hub Chain.

This reversal incurs additional costs:

* Gas fees for the reversal transaction
* Cross-chain messaging fees for returning funds

This PoC demonstrates how an attacker can cause financial losses to a victim by front-running their loan creation, exploiting the speed difference between hub-to-hub and spoke-to-hub transactions.
