-
Total Prize Pool: $49,000 in USDC
- HM awards: $24,750 in USDC
- QA awards: $750 in USDC
- Bot Race awards: $2,250 in USDC
- Analysis awards: $1,500 in USDC
- Gas awards: $750 in USDC
- Judge awards: $5,600 in USDC
- Lookout awards: $2,400 in USDC
- Scout awards: $500 in USDC
- Mitigation Review: $10,500 in USDC (Opportunity goes to top 3 certified wardens based on placement in this audit.)
-
Join C4 Discord to register
-
Submit findings using the C4 form
-
Starts March 14, 2024 20:00 UTC
-
Ends March 21, 2024 20:00 UTC
The 4naly3er report can be found here.
Automated findings output for the audit can be found here within 24 hours of audit opening.
Note for C4 wardens: Anything included in this Automated Findings / Publicly Known Issues
section is considered a publicly known issue and is ineligible for awards.
- SmartWallet
- Crosschain replay via executeWithoutChainIdValidation relies on gas values from one chain being valid and accepted by a bundler on other chains. This may not be the case.
- WebAuthnSol
- Read comments on
WebAuthn.sol
for details on validation steps we are knowingly skipping
- Read comments on
- FreshCryptoLib
- Exploits should only be considered in the context of a call path starting with
ecdsa_verify
. Other functions are not intended to be called directly.
- Exploits should only be considered in the context of a call path starting with
- MagicSpend
- When acting as a paymaster, EntryPoint will debit MagicSpend slightly more than actualGasCost, meaning what is withheld on a gas-paying withdraw will not cover 100% of MagicSpend's balance decrease in the EntryPoint.
validatePaymasterUserOp
checks address.balance, which currently violates ERC-7562 rules, however there is PR to change this.
This audit covers four separate but related groups of code
- SmartWallet is a smart contract wallet. In addition to Ethereum address owners, it supports passkey owners and validates their signatures via WebAuthnSol. It supports multiple owners and allows for signing account-changing user operations such that they can be replayed across any EVM chain where the account has the same address. It is ERC-4337 compliant and can be used with paymasters such as MagicSpend.
- WebAuthnSol is a library for verifying WebAuthn Authentication Assertions onchain.
- FreshCryptoLib is an excerpt from FreshCryptoLib, including the function
ecdsa_verify
and all code this function depends on.ecdsa_verify
is used by WebAuthnSol onchains without the RIP-7212 verifier, andFCL.n
is used to check for signature malleability. - MagicSpend is a contract that allows for signature-based withdraws. MagicSpend is a EntryPoint v0.6 compliant paymaster and also allows using withdraws to pay transaction gas, in this way.
- Previous audits:
- Documentation: Each folder has a detailed README. Please read those.
- Demo!: You can try using all of these contracts together on our demo site.
- Explainer Video: Here's a video talking through the demo and what is going on behind the scenes.
The complete scope of this audit is the files included in src/
-
Which blockchains will this code be deployed to, and are considered in scope for this audit?
- We have near-term plans to deploy this code to the mainnets of the following chains: Ethereum, Base, Optimism, Arbitrum, Polygon, BNB, Avalanche, Gnosis.
-
Roles/Permissions
- SmartWallet
- Only owner or self
- MultiOwnable.addOwnerAddress
- MultiOwnable.addOwnerPublicKey
- MultiOwnable.AddOwnerAddressAtIndex
- MultiOwnable.addOwnerPublicKeyAtIndex
- MultiOwnable.removeOwnerAtIndex
- UUPSUpgradable.upgradeToAndCall
- Only EntryPoint, owner, or self
- CoinbaseSmartWallet.execute
- CoinbaseSmartWallet.executeBatch
- Only EntryPoint
- CoinbaseSmartWallet.executeWithoutChainIdValidation
- validateUserOp
- Only owner or self
- MagicSpend
- Only owner
- ownerWithdraw
- entryPointDeposit
- entryPointWithdraw
- entryPointAddStake
- entryPointUnlockStake
- entryPointWithdrawStake
- Only owner
- SmartWallet
-
ERC/EIP Compliance
ERC1271
: Should comply withERC1271
CoinbaseSmartWalletFactory
: Should comply with factory behavior defined inERC4337
CoinbaseSmartWallet
: Should comply with account behavior defined inERC4337
MagicSpend
: Should comply with paymaster behavior defined inERC4337
- SmartWallet
- Can an attacker move funds from the account?
- Can an attacker brick (make unusable) the account?
- Can functions not in
canSkipChainIdValidation
be used viaexecuteWithoutChainIdValidation
?
- MagicSpend
- Can an attacker withdraw using an invalid WithdrawRequest?
- Can an attacker be credited more than WithdrawRequest.amount?
- Are there any griefing attacks that could cause this paymaster to be banned by bundlers?
- WebAuthn
- False positive or false negative in validation
- Are there valid webauthn authentication assertions that do not pass our validation?
- False positive or false negative in validation
- FreshCryptoLib
- False positive or false negative in validation
- SmartWallet
- Only current owners or EntryPoint can make calls that
- Decrease account balance.
- Add or remove owner.
- Upgrade account.
- Any current owner can add or remove any other owner.
- Only current owners or EntryPoint can make calls that
- MagicSpend
- Only owner can
- Move funds from contract without a valid
WithdrawRequest
. - Stake and unstake in EntryPoint.
- Add and withdraw from EntryPoint balance.
- Move funds from contract without a valid
- Every
WithdrawRequest
can only be used once. - A
WithdrawRequest
cannot be used pastWithdrawRequest.expiry
. - Withdrawers can never receive more than
WithdrawRequest.amount
. - Withdrawers using paymaster functionality should receive exactly
WithdrawRequest.amount - postOp_actualGasCost
. - At the end of a transaction,
_withdrawableETH
contains no non-zero balances.
- Only owner can
- WebAuthn
- Validation passes if and only if
'"challenge":""<challenge>"
occurs inclientDataJSON
starting atchallengeIndex
.'"type":"webauth.get"
is occurs inclientDataJSON
starting attypeIndex
.- User presence bit is set.
- User verified bit is set, if required.
r
ands
are valid signature values forx
,y
on the message hash that results fromclientDataJSON
andauthenticatorData
.
- Validation passes if and only if
- FreshCryptoLib
- All calls with valid sets of message, r, s, Qx, and Qy for the secp256r1 curve should return true.
- All calls with invalid sets of message, r, s, Qx, and Qy for the secp256r1 curve should revert or return false.
- If you have a public code repo, please share it here: https://github.com/coinbase/smart-wallet, https://github.com/coinbase/magic-spend, https://github.com/base-org/webauthn-sol, https://github.com/base-org/fresh-crypto-lib-audit
- How many contracts are in scope?: 7
- Total SLoC for these contracts?: 786
- How many external imports are there?: 11
- How many separate interfaces and struct definitions are there for the contracts within scope?: 0
- Does most of your code generally use composition or inheritance?: Composition
- How many external calls?: 5
- What is the overall line coverage percentage provided by your tests?: 95
- Is this an upgrade of an existing system?: False
- Check all that apply (e.g. timelock, NFT, AMM, ERC20, rollups, etc.):
- Is there a need to understand a separate part of the codebase / get context in order to audit this part of the protocol?: False
- Please describe required context:
- Does it use an oracle?: No
- Describe any novel or unique curve logic or mathematical models your code uses:
- Is this either a fork of or an alternate implementation of another project?: True
- Does it use a side-chain?:
- Describe any specific areas you would like addressed:
This repository is managed using Foundry.
Install Foundry
Run the following command and then follow the instructions.
curl -L https://foundry.paradigm.xyz | bash
Install Modules
forge install
Run Tests
forge test
Solidity 0.8.23
is used to compile and test the smart contracts.
Employees of Coinbase and employees' family members are ineligible to participate in this audit.