Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Invalid

Missing checks on delegate calls allow for all public functions in `MondrianWallet2` to be called via a delegate call. This is not possible in traditional EoAs.

Missing checks on delegate calls allow for all public functions in MondrianWallet2 to be called via a delegate call. This is not possible in traditional EoAs. It breaks the intended functionality of MondrianWallet2 as described in its README.md.

Description: MondrianWallet2:README.md states that:

The wallet should be able to do anything a normal EoA can do, ...

Because it is not a smart contract, a normal EoA cannot have functions that are called via a delegate call. However, all public functions in MondrianWallet2 lack checks that disallow them to be called via a delegate call.

See the missing checks in the following functions:

function validateTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable requireFromBootLoader
function executeTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable requireFromBootLoaderOrOwner
function executeTransactionFromOutside(Transaction memory _transaction) external payable
function payForTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable
function prepareForPaymaster( bytes32, /*_txHash*/ bytes32, /*_possibleSignedHash*/ Transaction memory /*_transaction*/ ) external payable

Impact: The lack of checks disallowing functions to be called via a delegate call, breaking the intended functionality of MondrianWallet2.

Recommended Mitigation: Create a modifier to check for delegate calls and apply this modifier to all public functions.

The mitigation below follows the example from DefaulAccount.sol, written by Matter Labs (creator of ZKSync).

+ modifier ignoreInDelegateCall() {
+ address codeAddress = SystemContractHelper.getCodeAddress();
+ if (codeAddress != address(this)) {
+ assembly {
+ return(0, 0)
+ }
+ }
+
+ _;
+ }
.
.
.
+ function validateTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable requireFromBootLoader ignoreInDelegateCall
- function validateTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable requireFromBootLoader
.
.
.
+ function executeTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable requireFromBootLoaderOrOwner ignoreInDelegateCall
- function executeTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable requireFromBootLoaderOrOwner
.
.
.
+ function executeTransactionFromOutside(Transaction memory _transaction) external payable ignoreInDelegateCall
- function executeTransactionFromOutside(Transaction memory _transaction) external payable
.
.
.
+ function payForTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable ignoreInDelegateCall
- function payForTransaction(bytes32, /*_txHash*/ bytes32, /*_suggestedSignedHash*/ Transaction memory _transaction) external payable
.
.
.
+ function prepareForPaymaster( bytes32, /*_txHash*/ bytes32, /*_possibleSignedHash*/ Transaction memory /*_transaction*/ ) external payable ignoreInDelegateCall
- function prepareForPaymaster( bytes32, /*_txHash*/ bytes32, /*_possibleSignedHash*/ Transaction memory /*_transaction*/ ) external payable
Updates

Lead Judging Commences

bube Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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