Biconomy - Smart Contract Wallet contest - 0xDave's results

One-Stop solution to enable an effortless experience in your dApp to onboard new users and abstract away transaction complexities.

General Information

Platform: Code4rena

Start Date: 04/01/2023

Pot Size: $60,500 USDC

Total HM: 15

Participants: 105

Period: 5 days

Judge: gzeon

Total Solo HM: 1

Id: 200

League: ETH

Biconomy

Findings Distribution

Researcher Performance

Rank: 60/105

Findings: 1

Award: $78.26

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: immeas

Also found by: 0xDave, 0xbepresent, HE1M, Kutu, betweenETHlines, hansfriese, hihen, peanuts, prc, wait

Labels

bug
2 (Med Risk)
disagree with severity
downgraded by judge
satisfactory
sponsor confirmed
duplicate-390

Awards

78.2598 USDC - $78.26

External Links

Lines of code

https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L489-L492 https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L460

Vulnerability details

function execute(address dest, uint value, bytes calldata func) external onlyOwner{ _requireFromEntryPointOrOwner(); _call(dest, value, func); } function execFromEntryPoint(address dest, uint value, bytes calldata func, Enum.Operation operation, uint256 gasLimit) external onlyEntryPoint returns (bool success) { success = execute(dest, value, func, operation, gasLimit); require(success, "Userop Failed"); }

execFromEntryPoint is a function that can only be accessed by entrypoint. When entrypoint call the function, execute is called. execute, however, can only be called by the owner. As the function has _requireFromEntryPointOrOwner(), it seems that entrypoint can also be called, but execute is using the onlyOwner modifier, so it cannot be accessed unless it is an owner.

Tools Used

Manual audit

execute should be modified to use the mixedAuth modifier as follows. Even if we delete _requireFromEntryPointOrOwner(); the owner can be accessed via mixedAuth.

function execute(address dest, uint value, bytes calldata func) external mixedAuth{ _call(dest, value, func); }

#0 - c4-judge

2023-01-17T08:04:29Z

gzeon-c4 marked the issue as unsatisfactory: Invalid

#1 - gzeoneth

2023-01-17T08:05:00Z

That's a different execute function from the inherited contract https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/base/Executor.sol#L13-L20

    function execute(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation,
        uint256 txGas
    ) internal returns (bool success) {
        if (operation == Enum.Operation.DelegateCall) {

#2 - c4-judge

2023-01-18T00:39:44Z

gzeon-c4 marked the issue as duplicate of #390

#3 - c4-judge

2023-01-18T00:39:55Z

gzeon-c4 marked the issue as partial-50

#4 - livingrockrises

2023-01-26T06:42:02Z

function execute(address dest, uint value, bytes calldata func) external onlyOwner{ _requireFromEntryPointOrOwner(); _call(dest, value, func); }

this needs fixing as it's logically incorrect!

But, two execute functions are confused here in the suggestions hence I tend to dispute / disagree severity for this report.

#5 - c4-sponsor

2023-01-26T06:42:10Z

livingrockrises marked the issue as disagree with severity

#6 - livingrockrises

2023-01-26T06:43:56Z

execFromEntryPoint method could be removed in the final version.

#7 - c4-sponsor

2023-01-26T07:06:34Z

livingrockrises marked the issue as sponsor confirmed

#8 - c4-judge

2023-02-10T12:21:31Z

gzeon-c4 marked the issue as satisfactory

#9 - c4-judge

2023-02-10T12:21:50Z

gzeon-c4 changed the severity to 2 (Med Risk)

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