Fractional v2 contest - 0xf15ers's results

A collective ownership platform for NFTs on Ethereum.

General Information

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

Fractional

Findings Distribution

Researcher Performance

Rank: 99/141

Findings: 1

Award: $62.31

🌟 Selected for report: 0

🚀 Solo Findings: 0

1. Unused interface imports

  • The interfaces (IERC1155, IERC20, IERC1155) imported in Transfer.sol is not used anywhere inside the contract.

2. Address(0) checks

3. Unhandeled return value

  • It is recommended to add require() to the boolean return values.
  • execute() returns boolean values.

4. Unused receive() function will lock ether in contract

5. Less external call be made by calling the token contract's methods directly

  • In start() function of Buyout.sol, while calulating totalSupply of vault IVaultRegistry(registry).totalSupply(_vault). This could be calculated directly by calling FERC1155(token).totalSupply(id) directly which will make one less external call.
// before
(address token, uint256 id) = IVaultRegistry(registry).vaultToToken(_vault);
....
uint256 totalSupply = IVaultRegistry(registry).totalSupply(_vault);
....


// After 
....
(address token, uint256 id) = IVaultRegistry(registry).vaultToToken(_vault);
.........
uint256 totalSupply = IERC1155(token).totalSupply(id);

6. Defined error is not used

7. Use a single modifier instead of using the same guard checks multiple times

8. Use two-step process for transfering ownership

  • Unrecoverable critical process like transferOwnership() could use two step process to prevent unintended mistakes.
  • same for transferController()
  • First, nominate the address, and second accept the nomination from that address ensuring that the access is indeed secured.

9. Use modifier to check the vault status

  • There are several instances where a function needs to revert unless the vault is at a certain state. This code is repeated throught several functions.
  • This can be refactored into a single modifier to make the code look nice and more readable.

for eg.


    modifier vaultState(address _vault, State required) {
        // Reverts if address is not a registered vault
        (address token, uint256 id) = IVaultRegistry(registry).vaultToToken(
            _vault
        );
        if (id == 0) revert NotVault(_vault);
        // Reverts if auction state is not successful
        (, , State current, , , ) = this.buyoutInfo(_vault);
        if (current != required) revert InvalidState(required, current);
    }

Now this modifier can be used in any function that needs to check the vault is in a certain state before performing certain actions.

for eg, lets use function porpose of Migration.sol

    function propose(
        address _vault,
        address[] calldata _modules,
        address[] calldata _plugins,
        bytes4[] calldata _selectors,
        uint256 _newFractionSupply,
        uint256 _targetPrice
    ) external vaultState(_vault, State.INACTIVE) {
    ...
    ...
    }

#0 - HardlyDifficult

2022-08-15T01:11:38Z

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter