“It is not possible for the average user to stay ahead of yield changes and perform risk management all the time, automation is needed. However, building this automation is non-trivial; it involves integration with multiple yield generating platforms and executing allocation strategies that protect liquidity while trying to earn the best-case yield. There are also other factors to consider, such as fund accessibility and mitigation of risks of connected protocols.
In this paper, we present Meteora Dynamic Vaults - The Yield Layer for Solana. This comprises an end-to-end risk management framework of optimising yield, mitigating lending protocols risks, and maintaining full principal liquidity.”
4.3 Hermes Meteora Dynamic Vaults Keeper Program In this section, we describe Hermes our off-chain yield optimizer keeper program, diving into its algorithmic design for finding optimal yield allocations and the risk factors it helps to mitigate. Hermes contains the necessary program logic (monitoring and tracking of the lending pools) of the operator. 4.3.1 Algorithm to find optimal yield allocations Annual Percentage Rate (APR) of lendings depends on a few factors: amount borrowed, amount deposited, interest rate model. The higher the amount borrowed, the higher the APR. When funds are deposited into a lending pool, borrowing interest will be shared amongst depositors, resulting in the decrease of deposit APR.
id: 1c2029121313982ddb1edbab40f4eb6f - page: 8
The algorithm to search for optimal yield allocations begins by breaking liquidity to small portions (lines1-2). For each portion, we simulate deposits in all lending platforms and compare the APR after the simulated deposit (lines 4-8). We will then pick the platform with the highest APR for this portion and update the deposit amount on the platform in the simulation (lines 10-12). We repeat this until 100% of total liquidity is deposited in the simulation to find the optimum allocation (lines 5-12). By doing so, we are able to find the most optimized yield allocations amongst the changing APR values with each deposit and withdrawal. If the latest allocation differs from the last allocation by more than 0.1%, a rebalance crank is sent to withdraw or deposit into the lending protocols according to the latest allocation (lines 14-16).
id: a0ea44caa1c8e20f5a52a04d61e0df85 - page: 8
# Off chain simulation 1: portion x # x is minimally 100, set by admin 2: deposit_amount vault.total_amount / portion 3: last_allocation[] current allocation of vault.total_amount in each lending platform 4: allocation[] track allocation after simulation to each lending platform 5: FOR each portion 6: 7: 8: 9: 10: 11: 12: 13: ENDFOR FOR each platform Simulate deposit_amount to platform APR[platform] APR of platform after simulated deposit ENDFOR highest_APR_platform Select platform with the highest APR in APR[platform] allocation[highest_APR_platform] deposit_amount + allocation[highest_APR_platform] Update deposit_amount to platform # On Chain Rebalance crank 14: IF diff( allocation[] , last_allocation[] ) > 0.1% THEN 15: 16: ENDIF Send rebalance crank to allocate funds according to allocation[] Figure 2: The optimal yield allocation algorithm 8
id: c75b7f9a2cba0df13dded93c24f8aa0b - page: 8
4.3.2 Rebalancing Crank Mechanism This section describes the rebalance crank mechanism and calculations of how the vault total amount is updated after each rebalancing. Hermes will claim yield from the various lending protocols after each rebalancing run. Rebalancing is run once every few minutes and the yield collected is included in the vault total amount as illustrated below. We call state variables before the rebalance: vault.total_amount : 1 token_vault.amount : 1 strategy.current_liquidity : 1 And the state variables after the rebalance: vault.total_amount : 2 token_vault.amount : 2 strategy.current_liquidity : 2 Then the vault would know that the total accrued interest after rebalance is: = ( 2 ) ( + 1 2 ) + 1 The vault will then update the total amount: = 1 2 + Or: 2 = 1 + ( 2 ) ( + 1 2 ) + 1 Rebalancing calculation illustration: Event 1 1 2 2 1
id: 86be53fb0962bf081d43469269359f94 - page: 9