Fractional v2 contest - Funen'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: 69/141

Findings: 2

Award: $102.15

🌟 Selected for report: 0

🚀 Solo Findings: 0

  1. missing indexed
  1. File : uint256 _amount

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/interfaces/IBuyout.sol#L65

  1. File : uint256 _amount

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/interfaces/IBuyout.sol#L69

  1. File : address _vault

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/interfaces/IBuyout.sol#L74

  1. Actual code was not the same as comment

since fractionDeposit was not declared in the code as well the code was used depositAmount , so it can be changed instead.

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Buyout.sol#L25

/// - buyoutPrice = (ethDeposit * 100) / (100 - ((fractionDeposit * 100) / totalSupply))

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Buyout.sol#L86-L87

uint256 buyoutPrice = (msg.value * 100) / (100 - ((depositAmount * 100) / totalSupply));
  1. Unnecessary Comment

This can be deleted instead since it was unnecessary to the code

1.) Vault.sol Line.37

// prettier-ignore
  1. Instead of using number it can be set as constant

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/FERC1155.sol#L247

royaltyAmount = (_salePrice * royaltyPercent[_id]) / 100;

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Buyout.sol#L86-L87

uint256 buyoutPrice = (msg.value * 100) / (100 - ((depositAmount * 100) / totalSupply));

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Buyout.sol#L209-L211

(tokenBalance * 1000) / IVaultRegistry(registry).totalSupply(_vault) > 500

  1. SLOAD fractionPrice * _amount can saving more gas

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Buyout.sol#L165

// Reverts if payment amount does not equal price of fractional amount if (msg.value != fractionPrice * _amount) revert InvalidPayment(); //3589182 before

can be saving lot gas by doing this :

uint256 ethAmount = fractionPrice * _amount; // Reverts if payment amount does not equal price of fractional amount if (msg.value != fractionPrice * _amount) revert InvalidPayment(); //3587236 after

This can be saving a lot of gas consumtion.

Tool Used

Remix

  1. Caching in calldata than memory for saving more gas
  1. File : Metadata.sol Line.24
function setURI(uint256 _id, string memory _uri) external { // string calldata _uri
  1. MerkleBase.sol Line.45
bytes32[] memory _proof,
  1. changed using ++i than i++ for cost less gas

Using i++ instead ++i for all the loops, the variable i is incremented using i++. It is known that implementation by using ++i costs less gas per iteration than i++.

src/Vault.sol#L78 for (uint256 i = 0; i < length; i++) { src/Vault.sol#L104 for (uint256 i = 0; i < length; i++) {
  1. change uint256 i = 0 into uint i for saving more gas

using this implementation can saving more gas for each loops.

src/Vault.sol#L78 for (uint256 i = 0; i < length; i++) { src/Vault.sol#L104 for (uint256 i = 0; i < length; i++) { src/utils/MerkleBase.sol#L51 for (uint256 i = 0; i < _proof.length; ++i) { src/modules/protoforms/BaseVault.sol#L83 for (uint256 i = 0; i < _tokens.length; ) { src/modules/protoforms/BaseVault.sol#L107 for (uint256 i = 0; i < _tokens.length; ++i) {
  1. set value as immutable for saving more gas
  1. File : Minter.sol Line.14
address public supply;
  1. File : Migration.sol Line.39
address public registry;
  1. File : Buyout.sol Line.28-31
/// @notice Address of VaultRegistry contract address public registry; /// @notice Address of Supply target contract address public supply;
  1. Saving gas by removing = 0

This implementation code can be saving more gas by removing = 0, it because If a variable was not set/initialized, it is assumed to have default value to 0

  1. File : Migration.sol Line.157
userProposalFractions[_proposalId][msg.sender] = 0;
  1. File : Migration.sol Line.161
userProposalEth[_proposalId][msg.sender] = 0;
  1. File : Migration.sol Line.310
userProposalFractions[_proposalId][msg.sender] = 0;
  1. File : Migration.sol Line.323
userProposalEth[_proposalId][msg.sender] = 0;
  1. Packing struct on interface Ibuyout

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/interfaces/IBuyout.sol

packing struct order by doing an practice down below :

State state; address proposer; uint256 startTime; uint256 fractionPrice; uint256 ethBalance; uint256 lastTotalSupply;

this can be gas saving if this contract called mutiple times.

7.) Short reason string can be used for saving more gas

Every reason string takes at least 32 bytes. Use short reason strings that fits in 32 bytes or it will become more expensive.

src/utils/MerkleBase.sol#L62 "wont generate root for single leaf" src/utils/MerkleBase.sol#L78 "wont generate proof for single leaf"
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