Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Lack of `receive` function renders contract unable of calling payable transactions

Summary

Despite having both validateTransaction and executeTransaction being payable, the contract utilises it's own balance to call the transactions to other contracts. And it doesn't have a mechanism to receive ETH on the contract.

Impact

Without having a receive function and/or a function intended to load up ETH on the wallet, the contract is unable to receive ETH, thus becoming unable of calling any transaction that requires ETH in the value variable of the Transaction call.

Proof of Concept

Proof of Code

Include this tests in MondrianWallet2Test.t.sol

function testValueComesFromWallet() public {
PayableContract payableContract = new PayableContract();
// Arrange
address dest = address(payableContract);
uint256 value = 1 ether;
// Here we assert the Mondrian Wallet holds the balance that'll be transferred
assertEq(address(mondrianWallet).balance, value);
bytes memory functionData =
abi.encodeWithSelector(PayableContract.pay.selector, address(mondrianWallet), AMOUNT);
Transaction memory transaction =
_createUnsignedTransaction(mondrianWallet.owner(), 113, dest, value, functionData);
// Act
vm.prank(mondrianWallet.owner());
mondrianWallet.executeTransaction(EMPTY_BYTES32, EMPTY_BYTES32, transaction);
// Assert
// And here we assert that the Mondrian Wallet balance has been used to execute the transaction
assertEq(address(mondrianWallet).balance, 0);
}
function testCantIncreaseContractBalance() public {
assertEq(address(mondrianWallet).balance, AMOUNT);
vm.deal(ANVIL_DEFAULT_ACCOUNT, AMOUNT);
vm.prank(ANVIL_DEFAULT_ACCOUNT);
payable(address(mondrianWallet)).call{value: AMOUNT}("");
assertNotEq(address(mondrianWallet).balance, AMOUNT * 2);
}

And import this contract to the test file:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract PayableContract {
function pay() external payable {
require(msg.value == 1 ether, "Haven't sent 1 ether");
}
}

Tools Used

Foundry and manual review

Recommendations

Include this into MondrianWallet2.sol

+ receive() external payable {}
Updates

Lead Judging Commences

bube Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Missing receive function

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.