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
Rank: 25/99
Findings: 2
Award: $361.02
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: horsefacts
Also found by: 0x29A, GimelSec, GreyArt, Lambda, Ruhum, antonttc, berndartmueller, byterocket, cccz, codexploder, dipp, oyc_109, unforgiven
InfinityExchange.sol#L300-L328 InfinityExchange.sol#L336-L364
When using InfinityExchange.sol:takeMultipleOneOrders
or InfinityExchange.sol:takeOrders
, if currency == address(0)
and a user has a msg.value > totalPrice
the overspent ETH is left in the contract and not sent back to the user.
Consider changing the msg.value >= totalPrice
on line 326 and line 362 to msg.value == totalPrice
or sending the difference back to the function user.
#0 - KenzoAgada
2022-06-21T12:14:36Z
Duplicate of #244
#1 - nneverlander
2022-06-22T16:43:52Z
Duplicate
#2 - HardlyDifficult
2022-07-10T12:40:54Z
276.9248 USDC - $276.92
InfinityStaker.sol#L116-L131 InfinityStaker.sol#L290-L325
In InfinityStaker.sol
, when calling the unstake
function _updateUserStakedAmounts
is called to readjust the user staked amounts. If a user stakes an amount in a duration and has an already vested amont in a higher duration, the user might lose the not yet vested stake in the lower duration.
This is due to the _updateUserStakedAmounts
function setting the userStakedAmount on all durations to 0 if its vesting amount is 0 without checking if the duration has a non-zero staked amount.
A user has 1000 tokens staked in the TWELVE_MONTH duration which can be vested.
Before unstaking the vested TWELVE_MONTH stake, the user then stakes an additional 2000 tokens into the THREE_MONTH duration.
The user then calls unstake
to unstake the 1000 tokens in the TWELVE_MONTH duration. (Before the THREE_MONTH stake can be vested)
The _updateUserStakedAmounts
will then check if the unstake amount is more than the amount which can be vested for each duration.
if (amount > vestedThreeMonths) { userstakedAmounts[user][Duration.THREE_MONTHS].amount = 0; userstakedAmounts[user][Duration.THREE_MONTHS].timestamp = 0; amount = amount - vestedThreeMonths;
Since vestedThreeMonths
is 0, the THREE_MONTH stake amount is set to 0 and eventually the TWELVE_MONTH stake is decreased by 1000.
The user receives 1000 tokens and loses the 2000 tokens staked in THREE_MONTHS.
The userStakedAmount should only decrease if the vested amount > 0. Consider adding an additional check for each if statement in the _updateUserStakedAmounts
to check if the vested amount for that duration is more than 0 and to only reset the duration's stake if this is true.
#0 - nneverlander
2022-06-22T17:43:41Z
Duplicate
#1 - HardlyDifficult
2022-07-12T06:36:23Z