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
Rank: 60/105
Findings: 1
Award: $78.26
π Selected for report: 0
π Solo Findings: 0
π Selected for report: immeas
Also found by: 0xDave, 0xbepresent, HE1M, Kutu, betweenETHlines, hansfriese, hihen, peanuts, prc, wait
78.2598 USDC - $78.26
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
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.
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)