When an operator submits a deposit_strategy or withdraw_strategy transaction, we call this the rebalance crank.

We define the state variables before the rebalance as:

  • vault.total_amount: t1t_1
  • token_vault.amount: a1a_1
  • strategy.current_liquidity: c1c_1

And the state variables after the rebalance as:

  • vault.total_amount: t2t_2
  • token_vault.amount: a2a_2
  • strategy.current_liquidity: c2c_2

The vault calculates the total accrued interest (profit) after rebalance as:

profit=(c2+a2)(c1+a1)\text{profit} = (c_2 + a_2) - (c_1 + a_1)

Then, the vault updates the total amount:

t2=t1+profitt_2 = t_1 + \text{profit}

Or, equivalently:

t2=t1+(c2+a2)(c1+a1)t_2 = t_1 + (c_2 + a_2) - (c_1 + a_1)

The immediate release of profit generated to the LPs can result in opportunities for a sandwich attack, as seen in the scenario below:

An attacker is able to time their deposit before a rebalance and withdraw immediately after a rebalance in order to get the max profit. In the example above, the attacker is able to earn 10 tokens as a reward by executing the sandwich attack.

Sandwich Attack Prevention

To prevent sandwich attacks, the system does not distribute 100% of the yield generated by lending platforms to LPs immediately after each rebalance. Instead, the yield is “dripped” (released gradually) to LPs over a pre-determined period.

Key State Variables

  • total_amount:
    The total liquidity in the vault (vault balance + all strategy balances).

  • last_updated_locked_profit:
    The total profit that is currently locked, updated at every rebalance.

  • last_report:
    The timestamp of the last rebalance.

  • locked_profit_degradation:
    The rate at which locked profit is released, expressed as a percentage per second (e.g., 0.1% of locked profits released per second).


How Yield Unlocking Works

When a user adds or removes liquidity, the system uses the unlocked amount (not the full vault.total_amount) to calculate how many LP tokens to mint or burn. This is done via the get_unlock_amount function.

Calculation Steps

  1. Calculate Duration Since Last Rebalance:
duration=currentTimelastReport\text{duration} = \text{currentTime} - \text{lastReport}
  1. Calculate Locked Fund Ratio:
lockedFundRatio=1(duration×lockedProfitDegradation)\text{lockedFundRatio} = 1 - (\text{duration} \times \text{lockedProfitDegradation})
  1. Calculate Unlocked Amount:
unlockedAmount=totalAmount(lastUpdatedLockedProfit×lockedFundRatio)\text{unlockedAmount} = \text{totalAmount} - (\text{lastUpdatedLockedProfit} \times \text{lockedFundRatio})

In summary:
Only the unlocked portion of profits is available to LPs at any given time, mitigating the risk of sandwich attacks by preventing instant profit extraction after a rebalance.

Example: Drip duration ~ 5 minutes

As seen in the example above, the rebalancing at t = 2 mins will gain a total of 100 token as yield from the lending platforms. However, as we are using the unlocked amount value to calculate the withdrawal amount, the attacker will not get any of the yield gained if he were to withdraw his tokens immediately after rebalancing. He will also only gain a fraction of the total yield if he withdraws within the next few minutes.