Platform: Code4rena
Start Date: 07/07/2022
Pot Size: $75,000 USDC
Total HM: 32
Participants: 141
Period: 7 days
Judge: HardlyDifficult
Total Solo HM: 4
Id: 144
League: ETH
Rank: 38/141
Findings: 2
Award: $329.66
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xA5DF
Also found by: 0x, 0xsanson, 242, Critical, sorrynotsorry, unforgiven, zzzitron
https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/Vault.sol#L24-L29 https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/VaultFactory.sol#L62-L70
The Vault.sol contract is provided on the attack vector surfaces where an actor can everytime frontrun it by monitoring the mempool. The init()
function that sets the owner of the vault contract can be called by anyone who monitors the mempool.
A malicious attacker could monitor the blockchain for bytecode that matches the Vault contract or the init function signature and frontrun the transaction to gain ownership of the contract. This can be repeated as a Denial Of Service (DOS) type of attack, effectively preventing contract deployment and contract ownership, leading to failure of the project design and unrecoverable gas expenses.
Same applies to VaultFactory.sol's deployFor()
function since it imports the Vault.sol contract. Once the Vault address is determined as in the code below, the transaction can be frontrun and the deployed vault's owner would be different than the intended address in parameter.
function init() external { if (nonce != 0) revert Initialized(owner, msg.sender, nonce); nonce = 1; owner = msg.sender; emit TransferOwnership(address(0), msg.sender); }
In VaultFactor.sol;
function deployFor(address _owner) public returns (address payable vault) { bytes32 seed = nextSeeds[tx.origin]; // Prevent front-running the salt by hashing the concatenation of tx.origin and the user-provided seed. bytes32 salt = keccak256(abi.encode(tx.origin, seed)); bytes memory data = abi.encodePacked(); vault = implementation.clone(salt, data); Vault(vault).init();
Manual review
It should be ensured the init() function is callable only by the deployer/owner of the Vault.sol contract.
#0 - ecmendenhall
2022-07-15T03:14:05Z
#1 - HardlyDifficult
2022-07-26T14:20:01Z
This report does not fully explore the impact like #200 had, but accepting it as a dupe since the root cause of an uninitialized template is the same.
🌟 Selected for report: xiaoming90
Also found by: 0x1f8b, 0x29A, 0x52, 0xA5DF, 0xDjango, 0xNazgul, 0xNineDec, 0xf15ers, 0xsanson, 0xsolstars, 242, 8olidity, Amithuddar, Aymen0909, Bnke0x0, BowTiedWardens, David_, Deivitto, ElKu, Funen, Hawkeye, IllIllI, JC, Kaiziron, Keen_Sheen, Kthere, Kulk0, Kumpa, Lambda, MEP, ReyAdmirado, Rohan16, Ruhum, Sm4rty, TomJ, Tomio, Treasure-Seeker, TrungOre, Tutturu, Viksaa39, Waze, _Adam, __141345__, ak1, apostle0x01, asutorufos, async, ayeslick, aysha, bbrho, benbaessler, berndartmueller, c3phas, cccz, chatch, cloudjunky, codexploder, cryptphi, delfin454000, dipp, durianSausage, dy, exd0tpy, fatherOfBlocks, hake, hansfriese, horsefacts, hubble, joestakey, jonatascm, kebabsec, kenzo, kyteg, mektigboy, neumo, oyc_109, pashov, pedr02b2, peritoflores, rajatbeladiya, rbserver, robee, rokinot, s3cunda, sach1r0, sahar, sashik_eth, scaraven, shenwilly, simon135, sorrynotsorry, sseefried, svskaushik, unforgiven, z3s, zzzitron
61.9486 USDC - $61.95
https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/Vault.sol#L32 https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/Vault.sol#L38-L41
Vault contract implements receive()
and fallback()
functions to receive funds. However, there is no method associated with a user to withdraw his funds which might be sent accidentally to a vault contract. This absence of the method results in losing/locking the assets forever in the vault contract. The best example of this kind of occurrence is the WETH and the GOLEM token contracts which have unrecoverable tokens inside.
https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/Vault.sol#L32 https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/Vault.sol#L38-L41
Manual review
The team might consider implementing a withdraw()
function.
#0 - 0x0aa0
2022-07-19T16:33:09Z
Duplicate #546
#1 - HardlyDifficult
2022-08-04T17:59:57Z
This suggestion is potentially a way to help recover from a user error. Lowering risk and converting into a QA report for the warden.