Coinbase Smart Wallet - 7ashraf's results

Smart Wallet from Coinbase Wallet

General Information

Platform: Code4rena

Start Date: 14/03/2024

Pot Size: $49,000 USDC

Total HM: 3

Participants: 51

Period: 7 days

Judge: 3docSec

Id: 350

League: ETH

Coinbase

Findings Distribution

Researcher Performance

Rank: 23/51

Findings: 1

Award: $36.34

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

36.3397 USDC - $36.34

Labels

bug
grade-a
QA (Quality Assurance)
sufficient quality report
Q-15

External Links

Quality Assurance Report

Summary

Issue NumberIssue TitleNumber of Instances
L-01Check if msg.value is the same as the passed amount2
L-02Avoid hardcoded strings and addresses3
L-04More safety is advised when removing owners1
N-01Remove un-necessary checks1
N-02Consider emitting an event for the following functions2
N-03Add comments to explain assembly code3
N-04Inaccurate variable emission1

[L-01] Check if msg.value is the same as the passed amount

Instances

    function entryPointDeposit(uint256 amount) external payable onlyOwner {
        SafeTransferLib.safeTransferETH(entryPoint(), amount);
    }
        (bool success, bytes memory result) = target.call{value: value}(data);

[L-02] Avoid hardcoded strings and addresses

Using hardcoded addresses or strings should be avoidable and may overcomplicate things in case of a contract upgrade, rather store contract addresses in a variable and add a setter to change the address in case of an upgrade

Instances

    function entryPoint() public pure returns (address) {
        return 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789;
    }
    function entryPoint() public view virtual returns (address) {
        return 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789;
    }
        return ("Coinbase Smart Wallet", "1");

[L-04] More safety is advised when removing owners

Instances

    function removeOwnerAtIndex(uint256 index) public virtual onlyOwner {
        bytes memory owner = ownerAtIndex(index);
        if (owner.length == 0) revert NoOwnerAtIndex(index);

        delete _getMultiOwnableStorage().isOwner[owner];
        delete _getMultiOwnableStorage().ownerAtIndex[index];

        emit RemoveOwner(index, owner);
    }

Mitigation

  • It is recommended to not allow the user to remove himself
  • It is recommended to check if the system has at least only one owner to avoid the removal of all owners

[N-01] Remove unnecessary checks

Instances

        assert(mode != PostOpMode.postOpReverted);

[N-02] Consider emitting an event for the following functions

Instances

function withdrawGasExcess() external
function ownerWithdraw(address asset, address to, uint256 amount) external onlyOwner

[N-03] Add comments to explain assembly code

Instances

        assembly ("memory-safe") {
            if missingAccountFunds {
                // Ignore failure (it's EntryPoint's job to verify, not the account's).
                pop(call(gas(), caller(), missingAccountFunds, codesize(), 0x00, codesize(), 0x00))
            }
        }
            assembly ("memory-safe") {
                revert(add(result, 32), mload(result))
            }
           assembly ("memory-safe") {
                owner := mload(add(ownerBytes, 32))
            }

[N-04] Inaccurate variable emission

Instances

        revert InvalidOwnerBytesLength(ownerBytes);

Mitigation

Change to ownerBytes.length

#0 - raymondfam

2024-03-23T01:07:11Z

L4 to #22

L1: It's pre-checked and post-checked respectively by the source/destination function. N4: It's going to cause type mismatch from bytes to unit256

2L and 3 NC.

#1 - c4-pre-sort

2024-03-23T01:07:17Z

raymondfam marked the issue as sufficient quality report

#2 - c4-judge

2024-03-27T13:10:18Z

3docSec marked the issue as grade-a

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter