AMM Swap
One can think of the AMM as a standard UniV3 range order, where sqrtPriceLowX96
and sqrtPriceHighX96
represent the upper and lower bounds of the range. These ranges are determined and actively managed by the liquidityProvider
, to provide the best risk-adjusted returns to its users.
The parameters for an incoming AMM swap can look like the following Solidity example:
Note: It is important to leave the swapContext
field empty because the HOT differentiates between an HOT swap and an AMM swap by checking if the length of the swapContext.externalContext
and the swapContext.swapFeeModuleContext
is 0 or not.
Effective Liquidity
AMM swaps can only trade against the liquidity stored in the _effectiveAMMLiquidity
variable. The remaining part of the reserves are considered passive ( more about this later ). So there might be cases where the reserves available to the the AMM are low, even though the total reserves deposited in the pool are high. This is intentional since _effectiveAMMLiquidity
requires careful security checks before it can be updated, as described below.
Effective AMM Liquidity
HOT assumes that at any point of time reserves can be in any arbitrary composition. This is because incoming HOT swaps can trade at any price and amounts (restricted by some configurable bounds), hence creating a misalignment of reserve amounts that would otherwise be implied by a standard UniV3 range order. Consequently, the fundamental invariants of CPMMs do not hold for the reserves.
To make sure that the AMM works correctly no matter what the reserve composition looks like, we decouple the reserves into 2 categories:
Active Reserves - These are balanced reserves that adhere to the xy=k invariant, and can be utilized by both the AMM and HOT swaps.
Passive Reserves - Any unbalanced reserves that are not part of the active reserves are considered passive. Only HOT swaps can access the passive reserves.
Design Goals:
Minimize the amount of passive reserves in the system, by rebalancing into active reserves at any opportunity we get.
Make sure that the liquidity remains constant (
_effectiveAMMLiquidity
) before and after any AMM swap.Utilize the maximum possible amount of active reserves.
We achieve these design goals by calling the _updateAMMLiquidity
internal function after any interaction that could potentially change the reserve composition, and if said interaction contains the appropriate number of invariant checks to mitigate the damage from AMM spot price manipulation.
More about the risks, and protections around _updateAMMLiquidity
in a separate document.
Last updated