When a user tries to create a Nexus account that has already been deployed, the initial ETH deposit will get stuck in the respective factory contract. Attackers can leverage this to perform griefing attacks on users.
A user can create a new Nexus account using the createAccount()
function in NexusAccountFactory.sol
, RegistryFactory.sol
and K1ValidatorFactory.sol
.
For example, let's look at the NexusAccountFactory.sol
contract's createAccount()
function :
Here, the salt used for the create2
opcode in LibClone.createDeterministicERC1967()
is constructed by user-controlled call data.
This means that for the same calldata, the generated address will be the same. Consequently, anyone can call createAccount()
with particular calldata and deploy a Nexus account with a deterministic address.
This is acceptable as account creation is supposed to be permissionless. As long as the calldata is not malicious, the user is safe, even if someone else deploys that address before them.
The real vulnerability lies in the fact that when the alreadyDeployed
flag is activated in the createAccount()
function call, the ETH that the user sent as an initial deposit for their Nexus account gets stuck in the factory contract itself and is not refunded to the user or sent to the Nexus account.
This opens up a griefing attack vector, wherein an attacker can front-run a user's createAccount()
transaction, deploy the Nexus account with a 0
initial deposit, and when the user's transaction gets executed, the function will exit with the alreadyDeployed
flag set to true, causing the msg.value
amount of ETH to get stuck in the factory contract.
The attack vector is as follows :
User calls createAccount()
with msg.value = X
Attacker observes user's transaction in the mempool and copies the calldata
Attacker front-runs the user's transaction and creates the Nexus account with msg.value = 0
When the user's transaction gets executed, X
ETH gets stuck in the factory contract instead of being added to the Nexus account.
Similarly, this vulnerability is present in RegistryFactory.sol
and K1ValidatorFactory.sol
as well.
RegistryFactory.sol
:
K1ValidatorFactory.sol
:
Permanent loss of funds
Manual Review
Transfer msg.value
back to the user or to the Nexus account
address if alreadyDeployed
flag is active.
Valid high, given it can be executed on any chain that has a public mempool. - These two issues has similar root cause as issue #171 and duplicates, but is the only issue that highlights a valid exploit scenario that can cause a loss of funds - Issue #82 can forcefully cause funds to be stuck within the factory contract, given `createDeterministicERC1967` will not revert when a new Nexus Proxy instance is already deployed. - Issue #91 can forcefully transfer funds out of Nexus Account by front-running a creation, setting a allowance and then self destructing. Duplicating due to the following reasons: - Both issues are contigent on front-running an account creation, which is only possible since the salt use to deploy a new Nexus Proxy instance are user deployed. So the same fix of including `msg.sender` and/or a unique identifier would prevent these attacks. i.e. same root cause --> different attack paths - Both issues have similarities with issue #112 , but I would say is a unique issue given even if #112 is fixed, this issues will not be fixed
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.