Managing withdrawal requests in IERC4626

Managing withdrawal queue

To request a withdrawal a user calls withdraw(uint256 assets, address receiver, address owner) specifying the amount of LP tokens they want to withdraw. At this point they are added to the queue.

Every ~7 days Alluo Booster Pool calls loopRewards() , where the following steps are executed:

  1. funds are unlocked from Frax

  2. _processWithdrawalRequests() keeps the amount of LPs requested for withdrawals and burns the shares of users who are in the withdrawal queue

  3. _relockToFrax() relocks the remaing funds into Frax Convex again

  4. current rewards per share are updated

Keeping totalAssets() consistent

Since shares are minted 1:1 ot deposited assets, total supply of shares should always be equal to total amount of assets in the vault. Total assets comprise the following:

  • underlying pool lp token

  • wrapped lp token

  • funds locked in frax convex

When shares are burnt during a harvest, factual amount of assets does not change until users claim their withdrawals. Up until then to balance out burnt shares the contract keeps track of unsatisfied withdrawal requests in totalRequestedWithdrawals which is included into totalAssets() calculation.


  1. Imagine you deposit $100. userWithdrawals.withdrawalRequested=0, userWithdrawals.withdrawalAvailable=0, balanceOf() = 100

  2. you withdraw() $50 userWithdrawals.withdrawalRequested=50, userWithdrawals.withdrawalAvailable=0, balanceOf() = 100

  3. you decide to withdraw $20 more, you call withdraw(20). userWithdrawals.withdrawalRequested=70, userWithdrawals.withdrawalAvailable=0, balanceOf() = 100

  4. Funds are unlocked by resolver. userWithdrawals.withdrawalRequested=0, userWithdrawals.withdrawalAvailable=70, balanceOf() = 30

  5. You put another request to withdraw $10. userWithdrawals.withdrawalRequested=10, userWithdrawals.withdrawalAvailable=70, balanceOf() = 30

  6. Funds are unlocked after the next cycle. userWithdrawals.withdrawalRequested=0, userWithdrawals.withdrawalAvailable=80, balanceOf() = 20

  7. You finally claim() and $80 are transferred to you. userWithdrawals.withdrawalRequested=0, userWithdrawals.withdrawalAvailable=0, balanceOf() = 20

Last updated