In ArrakisMetaVaultFactory.sol, there is a function name deployPrivateVault for user to create their private vault, however attacker make users can't track their private vault
Vulnerability Detail
Function is deployPrivateVault using create3 with parameter vault = Create3.create3(salt, creationCode). The vault address will be determined by the salt value and the creationCode. Salt value will be calculated by: bytes32 salt = keccak256(abi.encode(msg.sender, salt_)). Both msg.sender and salt_ can be observed by an attacker when TX is mined. The creationCode is calculated like this:
Attacker can have all initialize parameter's value here (public variable and from TX), can get Initialization Code of private vault by calling getCreationCode in arrakis-modular\src\CreationCodePrivateVault.sol. With all that information, an attacker can frontrun the creation TX with their own creation request (can use create2 opcode directly), with the same parameters. When the victim's transaction would be executed, the address is non-empty so the EVM would reject its creation. This would result in a bad UX for a user, cause they saw that the creation was not success. The result vault would still be usable, but would be hard to track as it was created in another TX.
Impact
As mention above, bad UX for user, and it hard for user to track their private vault. Furthermore, the NFT can't be mined for user, the result vault would not be added to _privateVaults array. Can consider it like a DOS attack.
Likelihood: not easy but possible
Impact: medium
So I think this will be a medium issue
RadCet
medium
Users lost their private vault
Summary
In ArrakisMetaVaultFactory.sol, there is a function name
deployPrivateVault
for user to create their private vault, however attacker make users can't track their private vaultVulnerability Detail
Function is
deployPrivateVault
using create3 with parametervault = Create3.create3(salt, creationCode)
. The vault address will be determined by the salt value and the creationCode. Salt value will be calculated by:bytes32 salt = keccak256(abi.encode(msg.sender, salt_))
. Both msg.sender and salt_ can be observed by an attacker when TX is mined. The creationCode is calculated like this:Attacker can have all initialize parameter's value here (public variable and from TX), can get
Initialization Code
of private vault by callinggetCreationCode
inarrakis-modular\src\CreationCodePrivateVault.sol
. With all that information, an attacker can frontrun the creation TX with their own creation request (can usecreate2
opcode directly), with the same parameters. When the victim's transaction would be executed, the address is non-empty so the EVM would reject its creation. This would result in a bad UX for a user, cause they saw that the creation was not success. The result vault would still be usable, but would be hard to track as it was created in another TX.Impact
As mention above, bad UX for user, and it hard for user to track their private vault. Furthermore, the NFT can't be mined for user, the result vault would not be added to
_privateVaults
array. Can consider it like a DOS attack. Likelihood: not easy but possible Impact: medium So I think this will be a medium issueCode Snippet
ArrakisMetaVaultFactory.sol
Tool used
Manual Review
Recommendation
Use an private ever-increasing nonce counter to guarantee unique contract addresses.