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: 58/141
Findings: 2
Award: $125.21
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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
87.195 USDC - $87.19
Function install
fails to perform input validation on arrays to verify the lengths match.
A mismatch could lead to an exception or undefined behavior.
src/Vault.sol:73 function install(bytes4[] memory _selectors, address[] memory _plugins)
https://github.com/code-423n4/2022-07-fractional/blob/main/src/Vault.sol#L73
src/references/SupplyReference.sol:12 address immutable registry;
https://github.com/code-423n4/2022-07-fractional/blob/main/src/references/SupplyReference.sol#L12
src/utils/Metadata.sol:11 address immutable token;
https://github.com/code-423n4/2022-07-fractional/blob/main/src/utils/Metadata.sol#L11
src/interfaces/IMigration.sol:23 // Address for the new vault to migrate to (if buyout is succesful) src/interfaces/IMigration.sol:25 // Boolean status to check if the propoal is active src/interfaces/IMigration.sol:26 bool isCommited; src/interfaces/IMigration.sol:29 // New fraction supply for a given vault that has succesfully migrated src/modules/Migration.sol:322 // Udpates ether balance of caller src/utils/SafeSend.sol:15 /// @param _to Address attemping to send to
🌟 Selected for report: joestakey
Also found by: 0x1f8b, 0x29A, 0xA5DF, 0xKitsune, 0xNazgul, 0xNineDec, 0xalpharush, 0xkatana, 0xsanson, 0xsolstars, 8olidity, Avci, Bnke0x0, BowTiedWardens, Chom, Deivitto, ElKu, Fitraldys, Funen, IllIllI, JC, Kaiziron, Lambda, Limbooo, MEP, NoamYakov, PwnedNoMore, RedOneN, ReyAdmirado, Rohan16, Ruhum, Saintcode_, Sm4rty, TomJ, Tomio, TrungOre, Tutturu, Waze, _Adam, __141345__, ajtra, apostle0x01, asutorufos, benbaessler, brgltd, c3phas, codexploder, cryptphi, delfin454000, dharma09, djxploit, durianSausage, fatherOfBlocks, giovannidisiena, gogo, horsefacts, hrishibhat, hyh, ignacio, jocxyen, jonatascm, karanctf, kebabsec, kyteg, m_Rassska, mektigboy, oyc_109, pedr02b2, rbserver, robee, rokinot, sach1r0, sashik_eth, simon135, slywaters
38.0241 USDC - $38.02
It's possible to avoid storage access and save gas using immutable
keyword for the following variables:
/// @notice Address of VaultRegistry contract address public registry; /// @notice Address of Supply target contract address public supply; /// @notice Address of Transfer target contract address public transfer;
https://github.com/code-423n4/2022-07-fractional/blob/main/src/modules/Buyout.sol#L29-L33
/// @notice Address of Buyout module contract address payable public buyout; /// @notice Address of VaultRegistry contract address public registry;
https://github.com/code-423n4/2022-07-fractional/blob/main/src/modules/Migration.sol#L37-L39
unchecked
block can be used for gas efficiency of the expression that can't overflow/underflowi++
could be unchecked since counter couldn't overflow:
src/Vault.sol:104 for (uint256 i = 0; i < length; i++) {
https://github.com/code-423n4/2022-07-fractional/blob/main/src/Vault.sol#L104
L88 could be unchecked since if totalSupply == 0
previous line (L87) would be reverted:
src/modules/Buyout.sol:86 uint256 buyoutPrice = (msg.value * 100) / src/modules/Buyout.sol:87 (100 - ((depositAmount * 100) / totalSupply)); src/modules/Buyout.sol:88 uint256 fractionPrice = buyoutPrice / totalSupply;
https://github.com/code-423n4/2022-07-fractional/blob/main/src/modules/Buyout.sol#L88
Since reading from memory
is much cheaper than reading from storage
, state variables that are called more than 1 SLOAD inside the function should be cached.
src/modules/Buyout.sol:477 ISupply(supply).burn.selector // supply 2 SLOADs
https://github.com/code-423n4/2022-07-fractional/blob/main/src/modules/Buyout.sol#L477
src/modules/Buyout.sol:501 ITransfer(transfer).ERC1155BatchTransferFrom.selector // transfer 8 SLOADs
https://github.com/code-423n4/2022-07-fractional/blob/main/src/modules/Buyout.sol#L501
Custom errors are available from solidity version 0.8.4. They cost cheaper than require/revert strings.
src/FERC1155.sol:267 "NOT_AUTHORIZED"
https://github.com/code-423n4/2022-07-fractional/blob/main/src/FERC1155.sol#L267
src/FERC1155.sol:285 "UNSAFE_RECIPIENT"
https://github.com/code-423n4/2022-07-fractional/blob/main/src/FERC1155.sol#L285
Prefix increment is cheaper than postfix increment. Consider using ++i in next line:
src/Vault.sol:104 for (uint256 i = 0; i < length; i++) {
https://github.com/code-423n4/2022-07-fractional/blob/main/src/Vault.sol#L104