# Boost \_ Folks Finance 33534 - \[Smart Contract - Medium] denial of service vulnerability and possible

Submitted on Mon Jul 22 2024 16:38:28 GMT-0400 (Atlantic Standard Time) by @A2Security for [Boost | Folks Finance](https://immunefi.com/bounty/folksfinance-boost/)

Report ID: #33534

Report type: Smart Contract

Report severity: Medium

Target: <https://testnet.snowtrace.io/address/0x3324B5BF2b5C85999C6DAf2f77b5a29aB74197cc?utm\\_source=immunefi>

Impacts:

* Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)

## Description

## Description

The implementation of the `createAccount()` function in the spoke and hub contract allows a potential Denial of Service (DoS) attack, where an attacker can exploit the account creation process across different chains. When a user attempts to create an account from a spoke chain, an attacker can listen for this transaction on the source chain and preemptively call the `createAccount()` function on the hub chain using the same account ID. This results in the victim's transaction reverting, as the attacker effectively blocks the user's ability to create an account with the intended ID.

## Impact

This vulnerability can have catastrophic consequences, allowing attackers to prevent any or all users from creating cross-chain accounts. Users who send a cross-chain message will not only be unable to create the desired account but also risk losing the funds already paid to cover the cross-chain delivery and execution of the message. This leads to a significant loss of trust in the protocol, as users may find themselves unable to access the services they expected, further impacting user retention and engagement.

### Code Snippet

Here’s how the `createAccount()` function is invoked on the spoke contract:

```solidity
function createAccount(
    Messages.MessageParams memory params,
    bytes32 accountId,
    bytes32 refAccountId
) external payable nonReentrant {
    _doOperation(params, Messages.Action.CreateAccount, accountId, abi.encodePacked(refAccountId));
}
```

In this code snippet, the `createAccount()` function accepts transaction parameters and unique identifiers for the account being created. The critical part is the call to `_doOperation`, which is responsible for creating a message that will be forwarded through the bridging protocol (such as Wormhole or CCIP) to the hub chain. As we can see the accountId is a free parameter that the user can set it to anything want to.

The message will be then recieved in the Hub contract and the `AccountManager` where it will be processed by the `createAccount()` function, and if this `accountId` is already reserved the transaction will revert.

```solidity
    function createAccount(
        bytes32 accountId,
        uint16 chainId,
        bytes32 addr,
        bytes32 refAccountId
    ) external override onlyRole(HUB_ROLE) {
        // check account is not already created (empty is reserved for admin)
        if (isAccountCreated(accountId) || accountId == bytes32(0)) revert AccountAlreadyCreated(accountId);

        // check address is not already registered
        if (isAddressRegistered(chainId, addr)) revert AddressPreviouslyRegistered(chainId, addr);

        // check referrer is well defined
>>        if (!(isAccountCreated(refAccountId) || refAccountId == bytes32(0)))
>>           revert InvalidReferrerAccount(refAccountId);

        // create account
        accounts[accountId] = true;
        accountAddresses[accountId][chainId] = AccountAddress({ addr: addr, invited: false, registered: true });
        registeredAddresses[addr][chainId] = accountId;

        emit CreateAccount(accountId, chainId, addr, refAccountId);
    }
```

## Tools Used

Manual review

## Recommended Mitigation Steps

1Implement a mechanism to hash the user address (`msg.sender` in the source chain) along with the chain ID when generating account IDs. This will ensure that account IDs are unique across users and chains, preventing the possibility of attackers blocking legitimate account creation attempts.

## Proof of concept

## Proof of Concept

The vulnerability can be demonstrated as follows:

1. A user sends a transaction to create an account from a spoke chain (e.g., Spoke A).
2. An attacker observes this transaction on Spoke A and calls the `createAccount()` function on the hub chain (e.g., Hub B) using the same account ID.
3. When the user's transaction is forwarded to the hub chain, it reverts because the account ID has already been registered by the attacker.
