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

The contract is supposed to be a wallet but a `receive()` function is not defined which prevents the transfer of funds to the contract

Summary

The receive() function is not defined in the MondrianWallet2 contract. This will prevent the contract to receive any funds. But the contract is supposed to be used as a wallet. So, this is an unwanted limitation.

Vulnerability Details

The MondrianWallet2 contract does not provide a receive() function. This means that the contract is not payable and cannot receive any funds. So, it cannot be used as a wallet which breaks the desired functionality.

Impact

The MondrianWallet2 is unable to receive funds. This breaks the desired logic. It can be demonstrated with the following test.

Proof of Code

Look at the following test.

function testReceive() public {
MondrianWallet2 implementation = new MondrianWallet2();
ERC1967Proxy proxy = new ERC1967Proxy(address(implementation), "");
MondrianWallet2 mondrianWallet = MondrianWallet2(
payable(address(proxy))
);
mondrianWallet.initialize();
mondrianWallet.transferOwnership(
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
);
address user = makeAddr("user");
vm.startPrank(user);
vm.deal(user, 1e18);
address(mondrianWallet).call{value: 1e18}("");
vm.stopPrank();
// No funds were transferred to the Mondrian Wallet
assertEq(user.balance, 1e18);
}

The tests proves that no funds can be transferred to the contract.

Tools Used

Manual Review

Recommendations

Add the receive() function to the MondrianWallet2 contract. Look at the following code.

contract MondrianWallet2 is IAccount, Initializable, OwnableUpgradeable, UUPSUpgradeable {
...
+ receive() external payable {}
...
}

After the method is added it can be confirmed that the contract can receive funds with the following test.

function testReceiveFixed() public {
MondrianWallet2 implementation = new MondrianWallet2();
ERC1967Proxy proxy = new ERC1967Proxy(address(implementation), "");
MondrianWallet2 mondrianWallet = MondrianWallet2(
payable(address(proxy))
);
mondrianWallet.initialize();
mondrianWallet.transferOwnership(
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
);
address user = makeAddr("user");
vm.startPrank(user);
vm.deal(user, 1e18);
address(mondrianWallet).call{value: 1e18}("");
vm.stopPrank();
// Funds were transferred to the Mondrian Wallet
assertEq(address(mondrianWallet).balance, 1e18);
assertEq(user.balance, 0);
}
Updates

Lead Judging Commences

bube Lead Judge about 1 year 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.