Ability to enjoy max benefits while only being locked for the minimum duration
Summary
The increaseLock() function of the TimeLockPool is using the wrong deposit to verify whether the deposit has been ended and to calculate the remaining duration.
Vulnerability Detail
The increaseLock() function of the TimeLockPool contract verifies the remaining duration and whether the deposit has been expired on the depositId linked to the msg.sender. While on the other hand, the amount of deposit tokens and share amount is increased on the depositId linked to the receiver.
Impact
An attacker could exploit the vulnerability as follows:
Create a new lock A with a very small amount and maxLockDuration from account A
Create a new lock B (or use an existing one) with an arbitrary amount and MIN_LOCK_DURATION (10 minutes) from account B.
Ensure the depositId of both locks are the same. This could be done by creating/deleting arbitrary locks until the amount of deposit’s of account A and B are the same.
Call the increaseLock function from the account linked to lock A with a large _increaseAmount and address of account B as _receiver
Lock B (with the small lock duration) will be increased with the _increaseAmount and a bonus of shares multiplied by 5 (due to the maxLockDuration of lock A).
The attacker benefits from the 500% multiplier benefits while only having to lock their assets for a minimum of 10 minutes.
Zarf
high
Ability to enjoy max benefits while only being locked for the minimum duration
Summary
The
increaseLock()
function of theTimeLockPool
is using the wrong deposit to verify whether the deposit has been ended and to calculate the remaining duration.Vulnerability Detail
The
increaseLock()
function of theTimeLockPool
contract verifies the remaining duration and whether the deposit has been expired on the depositId linked to the msg.sender. While on the other hand, the amount of deposit tokens and share amount is increased on the depositId linked to the receiver.Impact
An attacker could exploit the vulnerability as follows:
maxLockDuration
from account AMIN_LOCK_DURATION
(10 minutes) from account B.depositId
of both locks are the same. This could be done by creating/deleting arbitrary locks until the amount of deposit’s of account A and B are the same.increaseLock
function from the account linked to lock A with a large_increaseAmount
and address of account B as_receiver
_increaseAmount
and a bonus of shares multiplied by 5 (due to themaxLockDuration
of lock A).Code Snippet
https://github.com/sherlock-audit/2022-10-merit-circle/blob/main/merit-liquidity-mining/contracts/TimeLockPool.sol#L203
Tool used
Manual Review
Recommendation
Assign the
userDeposit
to the_depositId
linked to the_receiver
instead of_msgSender()
as follows:Duplicate of #102