Open c4-bot-1 opened 6 months ago
raymondfam marked the issue as insufficient quality report
raymondfam marked the issue as primary issue
SCW is proxy-deployed whose initialization logic is different than what you have described here.
3docSec changed the severity to QA (Quality Assurance)
Interesting finding. If we exclude user errors, it is safe to assume that wallets created by the factory are initialized with non-zero addresses because the factory creates and initializes wallets in the same call.
The only exception to the above is the implementation contract, that has its storage initialized in the constructor. For this one, the only consequence I can imagine is that the implementation wallet can accept UserOperations
from anybody. This does not seem to be a big deal, apart from self-calls to upgradeToAndCall
which are however secured by the onlyProxy
modifier.
The similar finding (this and this) pointed by #90 as having previously been judged valid are much more impactful because they open a viable path for destructing the implementation - this is not true for this codebase.
Leaving this as QA because having address(1)
as the implementation owner is a sound recommendation that would prevent the implementation contract from accepting UserOperations
with malformed signatures.
3docSec marked the issue as grade-a
Lines of code
https://github.com/code-423n4/2024-03-coinbase/blob/e0573369b865d47fed778de00a7b6df65ab1744e/src/SmartWallet/CoinbaseSmartWallet.sol#L102-L107
Vulnerability details
Impact
Function
_validSignature()
inConibaseSmartWallet.sol
utilizesisValidSignatureNow()
from Solady implementation. If the signature is invalid, function returnsaddress(0)
. For not-yet initialised implementation ofCoinbaseSmartWallet
the owner will be zero, thus every invalid signature generated by the attacker will be evaluated as valid ones (invalid signature returnsaddress(0)
, the owner of uninitializedConibaseSmartWallet
isaddresss(0)
, thus the address returned byisValidSignatureNow()
will match the owner).The very similar issue had been reported during the previous Code4rena contest and evaluated as High. Please review below links for further Impact reference and more detailed explaination:
https://github.com/code-423n4/2023-01-biconomy-findings/issues/14
https://github.com/code-423n4/2023-01-biconomy-findings/issues/496#issuecomment-1384930216
Proof of Concept
File: ConibaseSmartWallet.sol
abi.encode(address(0))
isValidSignatureNow()
from Solady will returnaddress(0)
when signature is not validadddress(0)
) is the same as the returned value fromisValidSignatureNow()
-address(0)
- signature will be evaluated as validCoinbaseSmartWallet
.Tools Used
Manual code review
Recommended Mitigation Steps
The owner of non-yet initialized
CoinbaseSmartWallet
should not beaddress(0)
. Set it toaddress(1)
instead.File: src/SmartWallet/CoinbaseSmartWallet.sol
line 105, should be changed to:
owners[0] = abi.encode(address(1));
Assessed type
Access Control