Skip to content
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.

PUSH0 - Users can revive an expired position with an arbitrary lockDuration while still retaining their initial lock duration #420

Closed
sherlock-admin4 opened this issue Jul 15, 2024 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. Reward A payout will be made for this issue

Comments

@sherlock-admin4
Copy link

sherlock-admin4 commented Jul 15, 2024

PUSH0

Medium

Users can revive an expired position with an arbitrary lockDuration while still retaining their initial lock duration

Summary

The contract MLumStaking allows a user to stake their MLUM for voting power. The contract exposes two functions for extending their locking duration:

  • renewLockPosition(), re-locks a position for exactly _stakingPositions[tokenId].lockDuration, defined by the position itself when it was still active.
  • extendLockPosition(), extends a lock position by a user's choice of duration. The new duration must at least be as long as the position's initial lock duration.

Both of these functionalities retain the position's initialLockDuration, but has restrictions as to what the new lock duration should be.

By combining partial withdrawing and reviving/extending the duration with addToPosition, we show a method to revive a position with an arbitrary lockDuration while retaining the initialLockDuration.

Vulnerability Detail

First of all, the function addToPosition() can be used to lock additional MLUM into a position. This also has an effect of extending their lock duration by a weighted average of the old amount and the added amount by the formula:

New Lock Time = (Remaining Lock Time * Staked MLUM Amount + MLUM Amount to add * Initial Lock Duration) / (MLUM Staked Amount + MLUM Amount to add)

It is worth noting that an expired position can still be added to, in which case they will be revived.

Secondly, the function withdrawFromPosition allows a user to withdraw MLUM from a position, on the condition that the position is expired. The user is able to partially withdraw from a position.

Combining these two facts, we have a method that allows reviving a position with an arbitrary lockDuration:

  • Suppose a position of 90 MLUM has been lock for, initially 90 days. This position is expired.
  • Suppose the owner of this position wishes to re-lock it just for 14 days, to pass the voting eligibility.
  • A user can partial withdraw 14 MLUM, and then lock that exact 14 MLUM again using addToPosition(). The new lock duration is (0 days * 76 MLUM + 90 days * 14 MLUM)/(90 MLUM) = 14 days.
  • The user is now eligible to vote, despite having re-locked a unlocked position for 14 days only.

Impact

User is able to re-lock a position with an arbitrary lockDuration, bypassing all functions intended for lock extension, and allows for voting without locking for the full 3 months. Voting has the effect of directing LUM reward emissions, so this equates to a fund loss

Code Snippet

https://github.com/sherlock-audit/2024-06-magicsea/blob/main/magicsea-staking/src/MlumStaking.sol#L496

https://github.com/sherlock-audit/2024-06-magicsea/blob/main/magicsea-staking/src/MlumStaking.sol#L397

Tool used

Manual Review

Recommendation

Disallow adding to expired positions or disallow partial withdrawing.

Duplicate of #138

@github-actions github-actions bot added duplicate Medium A Medium severity issue. labels Jul 21, 2024
@sherlock-admin2 sherlock-admin2 added the Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label label Jul 22, 2024
@sherlock-admin4 sherlock-admin4 changed the title Icy Basil Seal - Users can revive an expired position with an arbitrary lockDuration while still retaining their initial lock duration PUSH0 - Users can revive an expired position with an arbitrary lockDuration while still retaining their initial lock duration Jul 29, 2024
@sherlock-admin4 sherlock-admin4 added the Reward A payout will be made for this issue label Jul 29, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A Medium severity issue. Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

2 participants