Meditate.

There’s a vulnerable function i want you to try to find it before you proceed on knowing the answer. It’s rather a very beautiful exploit.

function _deposit(
 address account,
 uint256 amount,
 uint256 duration
 ) private {
 if (_deposits[account] > 0 && amount > 0 && duration > 0) revert
ChangeAmountAndUnlockTimeForExistingAccount();
 if (amount > 0) {
 oneInch.transferFrom(msg.sender, address(this), amount);
 _deposits[account] += amount;
 totalDeposits += amount;
 }
 uint256 lockedTill = Math.max(_unlockTime[account], block.timestamp) +
duration;
 uint256 lockedPeriod = lockedTill - block.timestamp;
 if (lockedPeriod < MIN_LOCK_PERIOD) revert LockTimeLessMinLock();
 if (lockedPeriod > MAX_LOCK_PERIOD) revert LockTimeMoreMaxLock();
 _unlockTime[account] = lockedTill;
 _mint(account, _balanceAt(_deposits[account], lockedTill) /
_VOTING_POWER_DIVIDER - balanceOf(account));
 }


The external function calling this

function depositFor(address _account, uint256 _amount, uint256 _duration) external {
     _deposit(_account, _amount, _duration);
}        

Attacker can front run or block a user by withdraw amount . The depositfor allows to set 0 amount in to contract . Because of it attacker can provide the address of an user account and _duration can be set to any lock duration.

Because of this a user cannot withdraw until the arbitary duration completes, This allows an attacker to front run user deposits . It’s all about how you assume things, This was really easy to find. The more you assume things the more you get .

Thank you ~