vAMM
Voltz vAMM Contract
The Virtual Automated Market Maker is a Voltz Protocol smart contract used for price discovery only. It helps with setting the fixed rate of interest rate swaps while the management of the underlying positions and their margin accounts alongside liquidations are handled by the Margin Engine.
The vAMM uses the constant product formula
, where
represents 1% of fixed tokens and
represents variable tokens.
The concept behind fixed tokens is relatively straightforward; if an actor is entitled to 100 of the 1% virtual fixed tokens then, at maturity of the IRS pool, they can claim exactly 1 token of the underlying. Note, this assumes the term of the IRS pool is precisely one year. On the other hand, 1 virtual variable token gives an actor exposure to the variable cash-flows that can be generated with 1 token worth of deposits in the underlying yield-bearing pool (e.g. aDAI), over the term of the IRS pool.
Thus, the vAMM defines the rate at which a trader can exchange fixed-for-variable or variable-for-fixed cash-flows. Given the axes of the vAMM, the relationship between the vAMM price and the annualized fixed rate is of the following form:
Voltz vAMM uses the concept of concentrated liquidity inspired by Uniswap v3. This allows Liquidity Providers to deposit variable tokens and 1% fixed tokens into the vAMM at pre-determined, custom fixed rate ranges. When the fixed rate is out of an LP’s position (fixed rate range), the liquidity is inactive, meaning the liquidity won’t be used to enter IRS contracts and earn fees.
The vAMM the has two key responsibilities:
- It enables traders to enter into Interest Rate Swaps
- It enables liquidity providers to add liquidity to the vAMM in custom fixed rate ranges
The mint function adds liquidity to a given position, uniquely identifiable by its owner address, upper and lower ticks.
The mint will not succeed if the position margin balance in underlying tokens is below the initial margin requirement of the position following a mint.
Additionally, the mint will revert if the address of the position owner does not match that of the
msg.sender
and the msg.sender
is not approved by the position owner.function mint(address recipient, int24 tickLower, int24 tickUpper, uint128 amount) external nonpayable returns (int256 positionMarginRequirement)
Parameters
Name | Type | Description |
---|---|---|
recipient | address | The address for which the liquidity will be created |
tickLower | int24 | The lower tick of the position for which to add liquidity |
tickUpper | int24 | The upper tick of the position for which to add liquidity |
amount | uint128 | The amount of liquidity to mint |
Returns
Name | Type | Description |
---|---|---|
positionMarginRequirement | int256 | The Initial Margin Requirement of the position following the mint |
The burn function removes liquidity from a given position, uniquely identifiable by its owner address, upper and lower ticks.
function burn(address recipient, int24 tickLower, int24 tickUpper, uint128 amount) external nonpayable returns (int256 positionMarginRequirement)
Parameters
Name | Type | Description |
---|---|---|
recipient | address | The address for which the liquidity will be removed |
tickLower | int24 | The lower tick of the position for which to remove liquidity |
tickUpper | int24 | The upper tick of the position in which to remove liquidity |
amount | uint128 | The amount of liquidity to remove |
Returns
Name | Type | Description |
---|---|---|
positionMarginRequirement | int256 | The Initial Margin Requirement of the position following the removal of liquidity |
The swap function engages a given position into an interest rate swap where the counterparty is the pool of Liquidity Providers active in the tick range crossed by the swap. The swap will not succeed if the position margin balance in underlying tokens is below the initial margin requirement of the position following a swap.
Each Interest Rate Swap initiated on Voltz Protocol will convey a fee which the position owner needs to pay to the liquidity providers (in the active tick range) in underlying tokens. Refer to Section 3 of the litepaper for more information on how fees are calculated.
function swap(SwapParams params) external nonpayable returns (int256 _fixedTokenDelta, int256 _variableTokenDelta, uint256 _cumulativeFeeIncurred, int256 _fixedTokenDeltaUnbalanced, int256 _marginRequirement)
Parameters
Name | Type | Description |
---|---|---|
params | SwapParams | Parameters necessary to initiate an Interest Rate Swap |
SwapParams
Name | Type | Description |
---|---|---|
recipient | address | The address of the position owner |
amountSpecified | int256 | Notional (in terms of underlying tokens) of the Interest Rate Swap. If the value is positive, the recipient is a Fixed Taker (short variable rate). If the value is negative, the recipient is a Variable Taker (long variable rate) |
sqrtPriceLimitX96 | uint160 | The Q64.96 sqrt price limit. If dealing with a variable taker swap, the sqrt price of the vAMM cannot be less than this value. If dealing with a fixed taker swap, the sqrt price cannot be more than this value. |
tickLower | int24 | Lower tick of the position |
tickUpper | int24 | Upper tick of the position |
Returns
Name | Type | Description |
---|---|---|
_fixedTokenDelta | int256 | The delta (either positive or negative) that will be applied to the fixed token balance of the position after the swap. |
_variableTokenDelta | int256 | The delta (either positive or negative) that will be applied to the variable token balance of the position after the swap. |
_cumulativeFeeIncurred | uint256 | Fees paid by the recipient to the liquidity providers in the tick range crossed by the swap. |
_fixedTokenDeltaUnbalanced | int256 | The fixed token delta before rebalancing is applied to retrieve the _fixedTokenDelta. Rebalancing is necessary to account for accrued cashflows since the inception of the IRS pool. |
_marginRequirement | int256 | The initial margin requirement in underlying tokens of the recipient's position following the swap. |
The function updatePosition allows a user who entered an Interest Rate Swap position to update the position by providing more margin, effectively increasing their collaterlisation, or withdrawing their as much margin as possible without undercollateralising their position. It returns the position margin requirement.
function updatePosition(ModifyPositionParams memory params) private returns(int256 positionMarginRequirement)
Name | Type | Description |
---|---|---|
params | | |
Name | Type | Description |
---|---|---|
positionMarginRequirement | int256 | |
The function computeGrowthInside calculates the change in the fixed and variable yield tokens as well as the increase in the fees being collected.
function computeGrowthInside(
int24 tickLower,
int24 tickUpper
)
external
view
override
returns (int256 fixedTokenGrowthInsideX128, int256 variableTokenGrowthInsideX128, uint256 feeGrowthInsideX128)
Name | Type | Description |
---|---|---|
tickLower | int24 | Lower bound of the tick range to be used for concentrated liquidity provision. |
tickUpper | int24 | Upper bound of the tick range to be used for concentrated liquidity provision. |
Last modified 1yr ago