Fractional v2 contest - Bnke0x0'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: 73/141

Findings: 2

Award: $100.96

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

[L-01] Insufficient input validation (Checking for length greater than one is useless because the caller can just pass a weighting of zero for the second asset in order to exclude it):-

1. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 62): `(_data.length > 1`

[L-02] Move ETH constant to child contract (All of the functions in the SafeSend require 0x0 when referring to Ether, not the constant here. Having it here will lead to mistakes down the line.):-

1. File: 2022-07-fractional/src/utils/SafeSend.sol (line 11-12): `address payable public constant WETH_ADDRESS = payable(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);`

[L-03] Unused receive() function will lock Ether in contract (If the intention is for the Ether to be used, the function should call another function, otherwise it should revert):-

1. File: 2022-07-fractional/src/Vault.sol (line 32): `receive() external payable {}` 2. File: 2022-07-fractional/src/modules/Buyout.sol (line 53): `receive() external payable {}` 3. File: 2022-07-fractional/src/modules/Migration.sol (line 63): `receive() external payable {}`

[L-04] Missing checks for address(0x0) when assigning values to address state variables:-

1. File: 2022-07-fractional/src/FERC1155.sol (line 234): `_controller = _newController;` 2. File: 2022-07-fractional/src/Vault.sol (line 95): `owner = _newOwner;`

[L-05] Open TODOS:-

1. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 24): `// TODO: This can be aesthetically simplified with a switch. Not sure it will` 2. File: 2022-07-fractional/src/Vault.sol (line 95): `owner = _newOwner;` 3. File: 2022-07-fractional/src/modules/Migration.sol (line 63): `receive() external payable {}` 4. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 51): `for (uint256 i = 0; i < _proof.length; ++i) {` 5. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 110): `for (uint256 i; i < result.length; ++i) {`

[L-06] address.call{value:x}() should be used instead of payable.transfer() (The use of payable.transfer() is heavily frowned upon because it can lead to the locking of funds. The transfer() call requires that the recipient has a payable callback, only provides 2300 gas for its operation.):-

1. File: 2022-07-fractional/src/modules/Migration.sol (line 172): `payable(msg.sender).transfer(ethAmount);` 2. File: 2022-07-fractional/src/modules/Migration.sol (line 325): `payable(msg.sender).transfer(userEth);`

[L-07] Cross-chain replay attacks (Storing the block.chainid is not safe.):-

1. File: 2022-07-fractional/src/FERC1155.sol (line 375-378): `DOMAIN_TYPEHASH, keccak256(bytes(NAME)), keccak256(bytes(VERSION)), block.chainid,`

[N-01] Use a more recent version of solidity (Use a solidity version of at least 0.8.15 to get string.concat() to be used instead of abi.encodePacked(<str>,<str>) ):-

1. File: 2022-07-fractional/src/FERC1155.sol (line 2): `pragma solidity 0.8.13;` 2. File: 2022-07-fractional/src/VaultFactory.sol (line 2): `pragma solidity 0.8.13;` 3. File: 2022-07-fractional/src/VaultRegistry.sol (line 2): `pragma solidity 0.8.13;`

[N-02] Event is missing indexed fields (Each event should use three indexed fields if there are three or more fields):-

1. File: 2022-07-fractional/src/interfaces/IBuyout.sol (line 55-61): `event Start( address indexed _vault, address indexed _proposer, uint256 _startTime, uint256 _buyoutPrice, uint256 _fractionPrice );` 2. File: 2022-07-fractional/src/interfaces/IBuyout.sol (line 74): `event End(address _vault, State _state, address indexed _proposer);` 3. File: 2022-07-fractional/src/interfaces/IBuyout.sol (line 79): `event Cash(address _vault, address indexed _casher, uint256 _amount);` 4. File: 2022-07-fractional/src/interfaces/IERC1155.sol (line 5-24): `interface IERC1155 { event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); event TransferBatch( address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts ); event TransferSingle( address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount );` 5. File: 2022-07-fractional/src/interfaces/IERC20.sol (line 6-11): `event Approval( address indexed _owner, address indexed _spender, uint256 _amount ); event Transfer(address indexed _from, address indexed _to, uint256 amount);` 6. File: 2022-07-fractional/src/interfaces/IERC721.sol (line 11-15): `event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved );` 7. File: 2022-07-fractional/src/interfaces/IFERC1155.sol (line 26-41): ` event SetRoyalty( address indexed _receiver, uint256 _id, uint256 _percentage ); /// @dev Event log for approving a spender of a token type /// @param _owner Address of the owner of the token type /// @param _operator Address of the spender of the token type /// @param _id ID of the token type /// @param _approved Approval status for the token type event SingleApproval( address indexed _owner, address indexed _operator, uint256 _id, bool _approved );` 8. File: 2022-07-fractional/src/interfaces/IMigration.sol (line 61-81): `event FractionsMigrated( address indexed _oldVault, address indexed _newVault, uint256 _proposalId, uint256 _amount ); /// @dev Event log for settling a vault /// @param _oldVault Address of the old vault /// @param _newVault Address of the vault /// @param _proposalId id of the proposal for the Migration /// @param _modules Addresses of module contracts /// @param _plugins Addresses of plugin contracts /// @param _selectors List of plugin function selectors event VaultMigrated( address indexed _oldVault, address indexed _newVault, uint256 _proposalId, address[] _modules, address[] _plugins, bytes4[] _selectors );` 9. File: 2022-07-fractional/src/interfaces/IVault.sol (line 25-29): `event Execute(address indexed _target, bytes _data, bytes _response); /// @dev Event log for installing plugins /// @param _selectors List of function selectors /// @param _plugins List of plugin contracts event InstallPlugin(bytes4[] _selectors, address[] _plugins); uint256 _amount );` 10. File: 2022-07-fractional/src/interfaces/IVaultRegistry.sol (line 33-37): `event VaultDeployed( address indexed _vault, address indexed _token, uint256 _id );`

[N-03] Multiple address mappings can be combined into a single mapping of an address to a struct, where appropriate :-

1. File: 2022-07-fractional/src/FERC1155.sol (line 26-34): ` mapping(uint256 => address) public metadata; /// @notice Mapping to track account nonces for metadata txs owner => nonces mapping(address => uint256) public nonces; /// @notice Mapping to track total supply for token ID types => totalSupply mapping(uint256 => uint256) public totalSupply; /// @notice Mapping to track royalty receivers for token ID types => royaltyAddress mapping(uint256 => address) private royaltyAddress; /// @notice Mapping to track the royalty percent for token ID types => royaltyPercent mapping(uint256 => uint256) private royaltyPercent;` 2. File: 2022-07-fractional/src/modules/Migration.sol (line 45-50): ` mapping(address => mapping(uint256 => Proposal)) public migrationInfo; /// @notice Mapping of a proposal ID to a user's ether contribution mapping(uint256 => mapping(address => uint256)) private userProposalEth; /// @notice Mapping of a proposal ID to a user's fractions contribution mapping(uint256 => mapping(address => uint256)) private userProposalFractions;`

[N-04] File is missing NatSpec :-

1. File: 2022-07-fractional/src/FERC1155.sol (line 1): `// SPDX-License-Identifier: MIT` 2. File: 2022-07-fractional/src/Vault.sol (line 1): `// SPDX-License-Identifier: MIT` 3. File: 2022-07-fractional/src/VaultFactory.sol (line 1): `// SPDX-License-Identifier: MIT` 4. File: 2022-07-fractional/src/VaultRegistry.sol (line 1): `// SPDX-License-Identifier: MIT` 5. File: 2022-07-fractional/src/constants/Memory.sol (line 1): `// SPDX-License-Identifier: MIT` 6. File: 2022-07-fractional/src/constants/Permit.sol (line 1): `// SPDX-License-Identifier: MIT` 7. File: 2022-07-fractional/src/constants/Supply.sol(line 1): `// SPDX-License-Identifier: MIT` 8. File: 2022-07-fractional/src/constants/Transfer.sol (line 1): `// SPDX-License-Identifier: MIT` 9. File: 2022-07-fractional/src/interfaces/IBaseVault.sol (line 1): `// SPDX-License-Identifier: MIT` 10. File: 2022-07-fractional/src/interfaces/IBuyout.sol (line 1): `// SPDX-License-Identifier: MIT` 11. File: 2022-07-fractional/src/interfaces/IERC1155.sol (line 1): `// SPDX-License-Identifier: MIT` 12. File: 2022-07-fractional/src/interfaces/IERC20.sol(line 1): `// SPDX-License-Identifier: MIT` 13. File: 2022-07-fractional/src/interfaces/IERC721.sol (line 1): `// SPDX-License-Identifier: MIT` 14. File: 2022-07-fractional/src/interfaces/IFERC1155.sol (line 1): `// SPDX-License-Identifier: MIT` 15. File: 2022-07-fractional/src/interfaces/IMigration.sol (line 1): `// SPDX-License-Identifier: MIT` 16. File: 2022-07-fractional/src/interfaces/IMinter.sol (line 1): `// SPDX-License-Identifier: MIT` 17. File: 2022-07-fractional/src/interfaces/IModule.sol (line 1): `// SPDX-License-Identifier: MIT` 18. File: 2022-07-fractional/src/interfaces/INFTReceiver.sol (line 1): `// SPDX-License-Identifier: MIT` 19. File: 2022-07-fractional/src/interfaces/IProtoform.sol (line 1): `// SPDX-License-Identifier: MIT` 20. File: 2022-07-fractional/src/interfaces/ISupply.sol (line 1): `// SPDX-License-Identifier: MIT` 21. File: 2022-07-fractional/src/interfaces/ITransfer.sol (line 1): `// SPDX-License-Identifier: MIT` 22. File: 2022-07-fractional/src/interfaces/IVault.sol (line 1): `// SPDX-License-Identifier: MIT` 23. File: 2022-07-fractional/src/interfaces/IVaultFactory.sol (line 1): `// SPDX-License-Identifier: MIT` 24. File: 2022-07-fractional/src/interfaces/IVaultRegistry.sol (line 1): `// SPDX-License-Identifier: MIT` 25. File: 2022-07-fractional/src/modules/Buyout.sol (line 1): `// SPDX-License-Identifier: MIT` 26. File: 2022-07-fractional/src/modules/Migration.sol (line 1): `// SPDX-License-Identifier: MIT` 27. File: 2022-07-fractional/src/modules/Minter.sol (line 1): `// SPDX-License-Identifier: MIT` 28. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 1): `// SPDX-License-Identifier: MIT` 29. File: 2022-07-fractional/src/references/SupplyReference.sol (line 1): `// SPDX-License-Identifier: MIT` 30. File: 2022-07-fractional/src/references/TransferReference.sol (line 1): `// SPDX-License-Identifier: MIT` 31. File: 2022-07-fractional/src/targets/Supply.sol (line 1): `// SPDX-License-Identifier: MIT` 32. File: 2022-07-fractional/src/targets/Transfer.sol (line 1): `// SPDX-License-Identifier: MIT` 33. 2022-07-fractional/src/utils/MerkleBase.sol (line 1): `// SPDX-License-Identifier: MIT` 34. File: 2022-07-fractional/src/utils/Metadata.sol (line 1): `// SPDX-License-Identifier: MIT` 35. File: 2022-07-fractional/src/utils/Multicall.sol (line 1): `// SPDX-License-Identifier: MIT` 36. File: 2022-07-fractional/src/utils/SafeSend.sol (line 1): `// SPDX-License-Identifier: MIT` 36. File: 2022-07-fractional/src/utils/SelfPermit.sol (line 1): `// SPDX-License-Identifier: MIT`

[G-01] State variables only set in the constructor should be declared immutable:-

1. File: j2022-07-fractional/src/Vault.sol (line 12-17): ` /// @notice Address of vault owner address public owner; /// @notice Merkle root hash of vault permissions bytes32 public merkleRoot; /// @notice Initializer value uint256 public nonce;` 2. File: 2022-07-fractional/src/VaultFactory.sol (line 15): `address public implementation;` 3. File: 2022-07-fractional/src/modules/Buyout.sol (line 29-33): ` address public registry; /// @notice Address of Supply target contract address public supply; /// @notice Address of Transfer target contract address public transfer;` 4. File: 2022-07-fractional/src/modules/Migration.sol (line 36-41): ` /// @notice Address of Buyout module contract address payable public buyout; /// @notice Address of VaultRegistry contract address public registry; /// @notice Counter used to assign IDs to new proposals uint256 public nextId;` 5. File: 2022-07-fractional/src/modules/Minter.sol (line 14): `address public supply;` 6. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 19): `address public registry;` 7. File: 2022-07-fractional/src/VaultFactory.sol (line 15): `address public implementation;`

[G-02] x = x + y is cheaper than x += y:-

1. File: 2022-07-fractional/src/FERC1155.sol (line 62): `totalSupply[_id] -= _amount;` 2. File: 2022-07-fractional/src/FERC1155.sol (line 270): `balanceOf[_from][_id] -= _amount;` 3. File: 2022-07-fractional/src/modules/Buyout.sol (line 139): `buyoutInfo[_vault].ethBalance -= ethAmount;` 4. File: 2022-07-fractional/src/modules/Migration.sol (line 156): `proposal.totalFractions -= amount;` 5. File: 2022-07-fractional/src/modules/Migration.sol (line 160): `proposal.totalEth -= ethAmount;` 6. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 190): `ceil -= pOf2;` 7. File: 2022-07-fractional/src/FERC1155.sol (line 86): `totalSupply[_id] += _amount;` 8. File: 2022-07-fractional/src/FERC1155.sol (line 271): `balanceOf[_to][_id] += _amount;` 9. File: 2022-07-fractional/src/modules/Buyout.sol (line 176): `buyoutInfo[_vault].ethBalance += msg.value;` 10. File: 2022-07-fractional/src/modules/Migration.sol (line 123-124): `proposal.totalEth += msg.value; userProposalEth[_proposalId][msg.sender] += msg.value;` 11. File: 2022-07-fractional/src/modules/Migration.sol (line 134-135): `proposal.totalFractions += _amount; userProposalFractions[_proposalId][msg.sender] += _amount;` 12. File: 2022-07-fractional/src/modules/Migration.sol (line 497): `treeLength += IModule(_modules[i]).getLeafNodes().length;` 13. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 147): `for (uint256 i; i < length - 1; i += 2) {`

[G-03] <array>.length should not be looked up in every loop of a for-loop:-

1. File: 2022-07-fractional/src/modules/Buyout.sol (line 454): `for (uint256 i; i < permissions.length; ) {` 2. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 64): `for (uint256 i = 0; i < _tokens.length; ) {` 3. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 83): `for (uint256 i = 0; i < _tokens.length; ) {` 4. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 107): `for (uint256 i = 0; i < _tokens.length; ++i) {` 5. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 130): `for (uint256 i; i < _modules.length; ++i) {` 6. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 132): `for (uint256 j; j < leaves.length; ++j) {` 7. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 51): `for (uint256 i = 0; i < _proof.length; ++i) {` 8. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 110): `for (uint256 i; i < result.length; ++i) {`

[G-04] i++ costs less gas than ++i, especially when it’s used in for-loops (i--/--i too):-

1. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 107): `for (uint256 i = 0; i < _tokens.length; ++i) {` 2. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 130): `for (uint256 i; i < _modules.length; ++i) {` 3. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 132): `for (uint256 j; j < leaves.length; ++j) {` 4. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 51): `for (uint256 i = 0; i < _proof.length; ++i) {` 5. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 110): `for (uint256 i; i < result.length; ++i) {`

[G-05] Using private rather than public for constants, saves gas (If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table):-

1. File: 2022-07-fractional/src/FERC1155.sol (line 15-17): ` string public constant NAME = "FERC1155"; /// @notice Version number of the token contract string public constant VERSION = "1";` 2. File: 2022-07-fractional/src/modules/Buyout.sol (line 35-37): ` uint256 public constant PROPOSAL_PERIOD = 2 days; /// @notice Time length of the rejection period uint256 public constant REJECTION_PERIOD = 4 days;` 3. File: 2022-07-fractional/src/modules/Migration.sol (line 43): `uint256 public constant PROPOSAL_PERIOD = 7 days;` 4. File: 2022-07-fractional/src/utils/SafeSend.sol (line 11-12): `address payable public constant WETH_ADDRESS = payable(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);`

[G-06] require()/revert() strings longer than 32 bytes cost extra gas:-

1. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 78): `require(_data.length > 1, "wont generate proof for single leaf");`

[G-07] It costs more gas to initialize variables to zero than to let the default of zero be applied:-

1. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 64): `for (uint256 i = 0; i < _tokens.length; ) {` 2. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 83): `for (uint256 i = 0; i < _tokens.length; ) {` 3. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 107): `for (uint256 i = 0; i < _tokens.length; ++i) {` 4. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 51): `for (uint256 i = 0; i < _proof.length; ++i) {`

[G-08] require() or revert() statements that check input arguments should be at the top of the function:-

1. File: 2022-07-fractional/src/FERC1155.sol (line 297): `require(metadata[_id] != address(0), "NO METADATA");` 2. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 62): `require(_data.length > 1, "wont generate root for single leaf");` 3. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 78): `require(_data.length > 1, "wont generate proof for single leaf");` 4. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 51): `for (uint256 i = 0; i < _proof.length; ++i) {` 5. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 110): `for (uint256 i; i < result.length; ++i) {`

[G-09] Use a more recent version of solidity:-

1. File: 2022-07-fractional/src/FERC1155.sol (line 2): `pragma solidity 0.8.13;` 2. File: 2022-07-fractional/src/Vault.sol (line 2): `pragma solidity 0.8.13;` 3. File: 2022-07-fractional/src/VaultFactory.sol (line 2): `pragma solidity 0.8.13;` 4. File: 2022-07-fractional/src/VaultRegistry.sol (line 2): `pragma solidity 0.8.13;` 5. File: 2022-07-fractional/src/constants/Memory.sol (line 2): `pragma solidity 0.8.13;` 6. File: 2022-07-fractional/src/constants/Permit.sol (line 2): `pragma solidity 0.8.13;` 7. File: 2022-07-fractional/src/constants/Supply.sol(line 2): `pragma solidity 0.8.13;` 8. File: 2022-07-fractional/src/constants/Transfer.sol (line 2): `pragma solidity 0.8.13;` 9. File: 2022-07-fractional/src/interfaces/IBaseVault.sol (line 2): `pragma solidity 0.8.13;` 10. File: 2022-07-fractional/src/interfaces/IBuyout.sol (line 2): `pragma solidity 0.8.13;` 11. File: 2022-07-fractional/src/interfaces/IERC1155.sol (line 2): `pragma solidity 0.8.13;` 12. File: 2022-07-fractional/src/interfaces/IERC20.sol(line 2): `pragma solidity 0.8.13;` 13. File: 2022-07-fractional/src/interfaces/IERC721.sol (line 2): `pragma solidity 0.8.13;` 14. File: 2022-07-fractional/src/interfaces/IFERC1155.sol (line 2): `pragma solidity 0.8.13;` 15. File: 2022-07-fractional/src/interfaces/IMigration.sol (line 2): `pragma solidity 0.8.13;` 16. File: 2022-07-fractional/src/interfaces/IMinter.sol (line 2): `pragma solidity 0.8.13;` 17. File: 2022-07-fractional/src/interfaces/IModule.sol (line 2): `pragma solidity 0.8.13;` 18. File: 2022-07-fractional/src/interfaces/INFTReceiver.sol (line 2): `pragma solidity 0.8.13;` 19. File: 2022-07-fractional/src/interfaces/IProtoform.sol (line 2): `pragma solidity 0.8.13;` 20. File: 2022-07-fractional/src/interfaces/ISupply.sol (line 2): `pragma solidity 0.8.13;` 21. File: 2022-07-fractional/src/interfaces/ITransfer.sol (line 2): `pragma solidity 0.8.13;` 22. File: 2022-07-fractional/src/interfaces/IVault.sol (line 2): `pragma solidity 0.8.13;` 23. File: 2022-07-fractional/src/interfaces/IVaultFactory.sol (line 2): `pragma solidity 0.8.13;` 24. File: 2022-07-fractional/src/interfaces/IVaultRegistry.sol (line 2): `pragma solidity 0.8.13;` 25. File: 2022-07-fractional/src/modules/Buyout.sol (line 2): `pragma solidity 0.8.13;` 26. File: 2022-07-fractional/src/modules/Migration.sol (line 2): `pragma solidity 0.8.13;` 27. File: 2022-07-fractional/src/modules/Minter.sol (line 2): `pragma solidity 0.8.13;` 28. File: 2022-07-fractional/src/modules/protoforms/BaseVault.sol (line 2): `pragma solidity 0.8.13;` 29. File: 2022-07-fractional/src/references/SupplyReference.sol (line 2): `pragma solidity 0.8.13;` 30. File: 2022-07-fractional/src/references/TransferReference.sol (line 2): `pragma solidity 0.8.13;` 31. File: 2022-07-fractional/src/targets/Supply.sol (line 2): `pragma solidity 0.8.13;` 32. File: 2022-07-fractional/src/targets/Transfer.sol (line 2): `pragma solidity 0.8.13;` 33. 2022-07-fractional/src/utils/MerkleBase.sol (line 2): `pragma solidity 0.8.13;` 34. File: 2022-07-fractional/src/utils/Metadata.sol (line 2): `pragma solidity 0.8.13;` 35. File: 2022-07-fractional/src/utils/Multicall.sol (line 2): `pragma solidity 0.8.13;` 36. File: 2022-07-fractional/src/utils/SafeSend.sol (line 2): `pragma solidity 0.8.13;` 36. File: 2022-07-fractional/src/utils/SelfPermit.sol (line 2): `pragma solidity 0.8.13;`

[G-10] Multiple address mappings can be combined into a single mapping of an address to a struct, where appropriate {Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot} :-

1. File: 2022-07-fractional/src/FERC1155.sol (line 25-34): ` /// @notice Mapping of metadata contracts for token ID types => metadata address mapping(uint256 => address) public metadata; /// @notice Mapping to track account nonces for metadata txs owner => nonces mapping(address => uint256) public nonces; /// @notice Mapping to track total supply for token ID types => totalSupply mapping(uint256 => uint256) public totalSupply; /// @notice Mapping to track royalty receivers for token ID types => royaltyAddress mapping(uint256 => address) private royaltyAddress; /// @notice Mapping to track the royalty percent for token ID types => royaltyPercent mapping(uint256 => uint256) private royaltyPercent;`

[G-11] Empty blocks should be removed or emit something:-

1. File: 2022-07-fractional/src/Vault.sol (line 32): `preceive() external payable {}` 2. File: 2022-07-fractional/src/modules/Buyout.sol (line 53): `receive() external payable {}` 3. File: 2022-07-fractional/src/modules/Migration.sol (line 63): `receive() external payable {}` 4. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 8): `constructor() {}`

[G-12] Use custom errors rather than revert()/require() strings to save deployment gas:-

1. File: 2022-07-fractional/src/FERC1155.sol (line 263): `require( msg.sender == _from || isApprovedForAll[_from][msg.sender] || isApproved[_from][msg.sender][_id], "NOT_AUTHORIZED" );` 2. File: 2022-07-fractional/src/FERC1155.sol (line 275): `require( _to.code.length == 0 ? _to != address(0) : INFTReceiver(_to).onERC1155Received( msg.sender, _from, _id, _amount, _data ) == INFTReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" );` 3. File: 2022-07-fractional/src/FERC1155.sol (line 297): `require(metadata[_id] != address(0), "NO METADATA");` 4. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 62): `require(_data.length > 1, "wont generate root for single leaf");` 5. File: 2022-07-fractional/src/utils/MerkleBase.sol (line 78): `require(_data.length > 1, "wont generate proof for single leaf");`

[G-13] Functions guaranteed to revert when called by normal users can be marked payable (If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided.):-

1. File: 2022-07-fractional/src/FERC1155.sol (line 37-50): ` modifier onlyController() { address controller_ = controller(); if (msg.sender != controller_) revert InvalidSender(controller_, msg.sender); _; } /// @notice Modifier for restricting function calls to the VaultRegistry modifier onlyRegistry() { address vaultRegistry = VAULT_REGISTRY(); if (msg.sender != vaultRegistry) revert InvalidSender(vaultRegistry, msg.sender); _; }` 2. File: 2022-07-fractional/src/FERC1155.sol (line 56-63): `function burn( address _from, uint256 _id, uint256 _amount ) external onlyRegistry { _burn(_from, _id, _amount); totalSupply[_id] -= _amount; }` 3. File: 2022-07-fractional/src/FERC1155.sol (line 79-87): `function mint( address _to, uint256 _id, uint256 _amount, bytes memory _data ) external onlyRegistry { _mint(_to, _id, _amount, _data); totalSupply[_id] += _amount; }` 4. File: 2022-07-fractional/src/FERC1155.sol (line 198-232): `function setContractURI(string calldata _uri) external onlyController { contractURI = _uri; } /// @notice Sets the token metadata contract /// @param _metadata Address for metadata contract /// @param _id Token ID to set the metadata for function setMetadata(address _metadata, uint256 _id) external onlyController { metadata[_id] = _metadata; emit SetMetadata(_metadata, _id); } /// @notice Sets the token royalties /// @param _id Token ID royalties are being updated for /// @param _receiver Address to receive royalties /// @param _percentage Percentage of royalties on secondary sales function setRoyalties( uint256 _id, address _receiver, uint256 _percentage ) external onlyController { royaltyAddress[_id] = _receiver; royaltyPercent[_id] = _percentage; emit SetRoyalty(_receiver, _id, _percentage); } /// @notice Updates the controller address for the FERC1155 token contract /// @param _newController Address of new controlling entity function transferController(address _newController) external onlyController {`
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