Infinity NFT Marketplace contest - auditor0517's results

The world's most advanced NFT marketplace.

General Information

Platform: Code4rena

Start Date: 14/06/2022

Pot Size: $50,000 USDC

Total HM: 19

Participants: 99

Period: 5 days

Judge: HardlyDifficult

Total Solo HM: 4

Id: 136

League: ETH

Infinity NFT Marketplace

Findings Distribution

Researcher Performance

Rank: 29/99

Findings: 1

Award: $276.92

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Ruhum

Also found by: 0xDjango, GimelSec, GreyArt, auditor0517, dipp, p4st13r4, wagmi

Labels

bug
duplicate
3 (High Risk)
sponsor confirmed

Awards

276.9248 USDC - $276.92

External Links

Lines of code

https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L116-L131 https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L290-L325

Vulnerability details

Impact

Users could lose an unvested amount permanently after InfinityStaker.unstake().

Proof of Concept

It's because the timestamp of lower duration would be larger than the one of higher duration. So vested amount of higher duration would be positive when vested amount of lower duration is 0.

  1. Stake amount 1 for SIX_MONTHS duration.
  2. 6 months later, stake another amount 1 for THREE_MONTHS duration.
  3. 1 day later, try to unstake amount 1.
  4. unstake will work without reverts because the vested amount of SIX_MONTHS is 1. But it will clear the staked amount of THREE_MONTHS also from L302-L304.

Tools Used

Manual Review

The vested amount is 0 or staked amount whether it meets timestamp requirement or not. So you can check if the vested amount is greater than 0 before clear staked amount.

if (amount > noVesting) { userstakedAmounts[user][Duration.NONE].amount = 0; userstakedAmounts[user][Duration.NONE].timestamp = 0; amount = amount - noVesting; if (amount > vestedThreeMonths) { if(vestedThreeMonths != 0) { //new condition userstakedAmounts[user][Duration.THREE_MONTHS].amount = 0; userstakedAmounts[user][Duration.THREE_MONTHS].timestamp = 0; amount = amount - vestedThreeMonths; } if (amount > vestedSixMonths) { if(vestedSixMonths != 0) { //new condition userstakedAmounts[user][Duration.SIX_MONTHS].amount = 0; userstakedAmounts[user][Duration.SIX_MONTHS].timestamp = 0; amount = amount - vestedSixMonths; } if (amount > vestedTwelveMonths) { if(vestedTwelveMonths != 0) //new condition { userstakedAmounts[user][Duration.TWELVE_MONTHS].amount = 0; userstakedAmounts[user][Duration.TWELVE_MONTHS].timestamp = 0; } } else { userstakedAmounts[user][Duration.TWELVE_MONTHS].amount -= amount; } } else { userstakedAmounts[user][Duration.SIX_MONTHS].amount -= amount; } } else { userstakedAmounts[user][Duration.THREE_MONTHS].amount -= amount; } } else { userstakedAmounts[user][Duration.NONE].amount -= amount; }

#7 - HardlyDifficult

2022-07-10T14:57:10Z

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