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();
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();
assertEq(address(mondrianWallet).balance, 1e18);
assertEq(user.balance, 0);
}