📄

Report #30013

Report Date
April 12, 2024
Status
Closed
Payout

Vulnerability in MultiFlowPump Contract: Lack of Input Validation on Reserves Parameter

Report Info

Report ID

#30013

Report type

Smart Contract

Has PoC?

Yes

Target

https://etherscan.io/address/0xBA510f10E3095B83a0F33aa9ad2544E22570a87C

Impacts

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

Description

The MultiFlowPump smart contract contains a vulnerability in the update function, which lacks input validation on the reserves parameter. This could allow an attacker to pass in malformed or unexpected data, leading to issues with the update process and potentially corrupting the pump state.

Vulnerability Details

The update function in the MultiFlowPump contract takes a uint256[] calldata reserves parameter, representing the current reserves for each token. However, the function does not perform any input validation on the reserves array. An attacker could potentially pass in an empty reserves array, an array with an unexpected number of elements, or values outside of the expected range (e.g., negative values or extremely large values). This could cause the contract to revert, behave in an unintended way, or corrupt the pump state.

Relevant code snippet:

function update(uint256[] calldata reserves, bytes calldata) external {
    uint256 numberOfReserves = reserves.length;
    // ...
}

Impact Details

If exploited, this vulnerability could lead to the corruption of the pump state and incorrect calculation of the Geometric EMA and Cumulative Geometric SMA, which are crucial for the proper functioning of the MultiFlowPump. This could have severe consequences for the platform and its users, potentially resulting in financial losses or other negative impacts.

Recommendations

To mitigate this vulnerability, consider implementing the following input validation checks on the reserves parameter:

  1. Check that the length of the reserves array matches the expected number of reserves.
  2. Ensure that each element in the reserves array is within the expected range (e.g., non-negative and not exceeding a reasonable maximum value).
  3. Consider using a custom struct or a library to represent the reserves data, with built-in validation logic.

Additionally, consider using a pull-based update mechanism, where the contract retrieves the reserve data from a trusted source instead of relying on the caller to provide the data.

Proof of concept

  1. Deploy the MultiFlowPump contract.
  2. Deploy the malicious contract provided below.
  3. Call one of the malicious functions from the malicious contract to trigger the vulnerability.
  4. Observe the contract's behavior, such as reverting, behaving unintentionally, or corrupting the pump state.

Here's the malicious contract targeted to our vulnerability:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./MultiFlowPump.sol";

contract MaliciousContract {
    address private multiFlowPumpAddress;

    constructor(address _multiFlowPumpAddress) {
        multiFlowPumpAddress = _multiFlowPumpAddress;
    }

    function callUpdateWithEmptyArray() external {
        MultiFlowPump(multiFlowPumpAddress).update([], "");
    }

    function callUpdateWithInvalidLengthArray() external {
        uint256[] memory invalidReserves = new uint256[](1);
        invalidReserves[0] = 1 ether;
        MultiFlowPump(multiFlowPumpAddress).update(invalidReserves, "");
    }

    function callUpdateWithOutOfRangeValue() external {
        uint256[] memory invalidReserves = new uint256[](2);
        invalidReserves[0] = 1 ether;
        invalidReserves[1] = type(uint256).max;
        MultiFlowPump(multiFlowPumpAddress).update(invalidReserves, "");
    }
}

This malicious contract contains three functions that target the lack of input validation in the MultiFlowPump contract's update function:

  1. callUpdateWithEmptyArray: Calls the update function with an empty reserves array.
  2. callUpdateWithInvalidLengthArray: Calls the update function with a reserves array of incorrect length.
  3. callUpdateWithOutOfRangeValue: Calls the update function with a reserves array containing an out-of-range value.

Immunefi Response

Thank you for your submission to the Beanstalk bug bounty program. Unfortunately, after reviewing your report, Immunefi has decided to close it due to the assessed impact being out of scope.

Immunefi review:

  • The claimed impact by the whitehat is of the bug bounty program but the assessed impact doesn't match with the claimed impact for the following reasons.
    • There is no proof of concept shared which demonstrate impact on the other users.
  • assessed asset by the triage team is not in scope for the bug bounty program
  • PoC has been submitted to the project

Please note that the project will receive a report of the closed submission and may choose to re-open it, but they are not obligated to do so.