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: 39/105
Findings: 4
Award: $185.85
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: adriro
Also found by: 0x1f8b, 0x73696d616f, 0xdeadbeef0x, BClabs, HE1M, Haipls, Jayus, Kalzak, Lirios, Qeew, V_B, adriro, ast3ros, aviggiano, betweenETHlines, bin2chen, chaduke, dragotanqueray, ey88, giovannidisiena, hihen, horsefacts, ladboy233, wait, zaskoh
26.2582 USDC - $26.26
https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccountFactory.sol#L38 https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccountFactory.sol#L40
Every userOperation
with valid initCode
(wallet deployment) can be frontran which results in DoS
userOperation
with the intention to deploy a proxy wallet for herselfinitCode
SenderCreator.createSender
with the initcode, or directly SmartAccountFactory.deployCounterFactualWallet
require(address(proxy) != address(0), "Create2 call failed");
*The create2 call will return address(0) if the desired contract is already deployed.
userOperation
with an initCode
can be DoS'dVSCode
Currently, there is no easy way to minimize this issue, because the create2
call doesnt return any difference if the transaction actually failed because something went wrong, or if it just failed because the desired contract is already deployed.
One could consider removing the require(address(proxy) != address(0), "Create2 call failed");
requirement, however, this most likely will lead to other issues in the transaction flow one needs to think careful about.
#0 - c4-judge
2023-01-18T07:16:52Z
gzeon-c4 marked the issue as duplicate of #460
#1 - c4-sponsor
2023-01-26T03:33:02Z
livingrockrises marked the issue as sponsor confirmed
#2 - c4-judge
2023-02-10T12:25:21Z
gzeon-c4 changed the severity to 3 (High Risk)
#3 - c4-judge
2023-02-10T12:25:26Z
gzeon-c4 marked the issue as satisfactory
🌟 Selected for report: immeas
Also found by: 0xDave, 0xbepresent, HE1M, Kutu, betweenETHlines, hansfriese, hihen, peanuts, prc, wait
78.2598 USDC - $78.26
execute
and executeBatch
are never callable by entryPoint
Currently, the execute
and executeBatch
functions are most probably meant to be called by entryPoint
or owner
:
_requireFromEntryPointOrOwner();
However, the onlyOwner
modifier effectively prevents these functions from ever being called by entryPoint
, limiting the contracts functionalities.
VSCode
Consider removing the onlyOwner
modifier from execute
and executeBatch
#0 - c4-judge
2023-01-18T00:39:23Z
gzeon-c4 marked the issue as duplicate of #390
#1 - c4-sponsor
2023-01-26T06:44:59Z
livingrockrises marked the issue as sponsor confirmed
#2 - c4-judge
2023-02-10T12:21:33Z
gzeon-c4 marked the issue as satisfactory
🌟 Selected for report: 0x52
Also found by: 0xSmartContract, Deivitto, Diana, IllIllI, Koolex, Rolezn, SleepingBugs, V_B, adriro, betweenETHlines, cryptostellar5, oyc_109, peanuts
44.8261 USDC - $44.83
https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L22 https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/base/ModuleManager.sol#L18
The SmartAccount
contract is used as a proxy implementation, however, it inherits non-upgradeable dependencies which could break upgradeability.
We are aware of the fact that the proxy -> implementation solution is mostly used for gas-savings, however, this fact is undeniable present and might occur in production.
VSCode
Consider adding a uint256[49] private __gap;
variable at the end of the state variable declarations to free up space for future variables.
#0 - c4-judge
2023-01-18T07:14:01Z
gzeon-c4 marked the issue as duplicate of #352
#1 - c4-sponsor
2023-02-09T11:43:11Z
livingrockrises marked the issue as sponsor confirmed
#2 - c4-judge
2023-02-10T12:36:41Z
gzeon-c4 marked the issue as satisfactory
🌟 Selected for report: 0xSmartContract
Also found by: 0x1f8b, 0xAgro, 0xdeadbeef0x, 0xhacksmithh, 2997ms, Atarpara, Bnke0x0, Diana, HE1M, IllIllI, Josiah, Kalzak, Lirios, MalfurionWhitehat, MyFDsYours, Raiders, RaymondFam, Rolezn, SaharDevep, Sathish9098, Udsen, Viktor_Cortess, adriro, ast3ros, betweenETHlines, btk, chaduke, chrisdior4, cryptostellar5, csanuragjain, giovannidisiena, gz627, hl_, horsefacts, joestakey, juancito, ladboy233, lukris02, nadin, oyc_109, pauliax, peanuts, prady, sorrynotsorry, zaskoh
36.5015 USDC - $36.50
Typographical error: https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L74
Duplicate initialization check: https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L168
The owner == address(0)
check is sufficient.
pullTokens
The function should be named pushTokens
because it doesn't execute a transferFrom
but a (safe)transfer
using SafeERC20 for
IERC20`Consider implementing the using
syntax.
Enum
already importedIt is not necessary to import Enum
, since its already imported within Executor
.
getModulesPaginated
The getModulesPaginated
function works in descending order, however, this is not well documented. Users would expect this function to be working in ascending order.
Consider adding a comment to this function.
setFallbackHandler
lacks a non-zero validationConsider adding a non-zero validation for the function input.
_defaultImpl
can never be changedConsider removing the immutable keyword and add a setter function for the aforementioned variable for the case that the implementation needs to be changed.
deployWallet
Consider adding an event for the aforementioned function.
Executor
contract should have an indexed to
parameterConsider adding the indexed
keyword to the to
parameter.
import "../utils/Exec.sol";
Consider removing the unused import.
The EntryPoint
contract is written in the bad structure e.g. internal before public functions, variable declarations in the middle of the contract etc.
This reduces readability for third-parties.
Consider refactoring the structure for the aforementioned contracts.
handleOps
might run out of gasThe handleOps
function loops twice over the UserOperations
array, if this array ever becomes too large, the function will run out of gas.
Consider limiting the array to a reasonable length.
*The same applies for handleAggregatedOps
setEntryPoint
Consider adding a non-zero validation for this function.
using Address for address
The contract should follow the best-practices and implement using Address for address
to make the code cleaner and more readable.
_disableInitializer
Currently, all implementation contracts lack the aforementioned function. It might make sense to call this function within the constructor to avoid an initialization of the implementation contract.
#0 - c4-judge
2023-01-22T15:52:31Z
gzeon-c4 marked the issue as grade-b
#1 - c4-sponsor
2023-02-09T12:25:49Z
livingrockrises marked the issue as sponsor confirmed