Fractional v2 contest - Tutturu'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: 74/141

Findings: 3

Award: $100.81

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

1.3977 USDC - $1.40

Labels

bug
duplicate
2 (Med Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Migration.sol#L172 https://github.com/code-423n4/2022-07-fractional/blob/e2c5a962a94106f9495eb96769d7f60f7d5b14c9/src/modules/Migration.sol#L325

Vulnerability details

Impact

The depricated .transfer() function has a hardcoded gas limit of 2300 which due to an increase is opcode costs means that the function might revert when called by a multisig wallet, leading to the funds being locked up . Additionally, it might revert due to:

  1. The caller contract not implementing a payable function

  2. The caller contract implementing a payable fallback function that uses more than 2300 gas

Proof of Concept

The affected contract is Migration.sol, in functions leave() - L#172 and withdrawContribution - L#325

Since both functions follow the correct checks-effects-interactions pattern I recommend replacing .transfer() with a low level .call()

#0 - stevennevins

2022-07-19T21:51:04Z

Duplicate of #325

#1 - HardlyDifficult

2022-07-28T15:47:45Z

Duping to #504

1. Unused receive() will lock Ether into contracts

The following contracts define a payable receive function but have no way of withdrawing or utilizing the sent Ether, resulting in Ether being locked in the contracts. If the intention is to use the Ether that functionality should be added to the function, otherwise it should revert.

There are 3 instances of this issue:

  1. Buyout.sol#L53
  2. Migration.sol#L63
  3. Vault.sol#L32

1. Unnecessary assignment of Status.VALUE to "required" variable

Removing this assignment and directly checking Status.LIVE, Status.INACTIVE, and Status.SUCCESS saves about 10 gas per run, which in case of batchWithdrawERC1155 can mean a few hundred gas.

The issue is found in: 1. Buyout.sol 2. Migration.sol

In Buyout.sol there are 10 instances of this issue:

  1. L#67
  2. L#121
  3. L#158
  4. L#199
  5. L#252
  6. L#284
  7. L#323
  8. L#355
  9. L#391
  10. L#428

In Migration.sol there are 6 instances of this issue:

  1. L#85
  2. L#117
  3. L#149
  4. L#190
  5. L#226
  6. L#441

2. Replace i++ in for loops with unchecked {++i}

Since both install() and uninstall() are callable only by owner, and it is unrealistic to go through 2^256 values required for overflow, this should be safe and will result in gas savings.

There are two instances of this issue in Vault.sol:

  1. install() - L#78
  2. uninstall() - L#104
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