Technical Overview
Last updated
Last updated
Avitus employs a two‐step flow to facilitate secure and efficient liquidity provisioning:
createDeposit
Gathers deposit parameters from the user
Validates those parameters
Prepares a deposit record
Returns a unique deposit key
executeDeposit
Uses the deposit key to fetch the prepared deposit
Validates current market conditions and user parameters
Executes token swaps, calculates fees/price impact
Mints “market tokens” to the user based on the final deposit value
In the sections below, each step and function are explained in detail.
createDeposit
FlowThe user initiates the deposit by calling createDeposit
with:
Deposit details — information such as token addresses, desired deposit amounts, market where they want to invest and any additional parameters (like minimum acceptable tokens to receive).
User account address — the address that will eventually receive the minted “market tokens.”
Box: validate Account and Market
Purpose: Verifies that:
The caller’s address is valid (e.g., not the zero address).
The market into which the user is depositing is recognized and active in Avitus.
Outcome: If either validation fails, the transaction reverts immediately, preventing invalid deposits.
Box: get Intial Long and short token
Purpose: Determines how many of each token (long token, short token) were sent by the user into the Avitus deposit vault.
Special Case:
If the deposited token is the wrapped native token (e.g., WETH), the protocol notes that execution fees may be deducted in that token.
Box: Deduct execution fees from the user’s deposit
Purpose:
Confirms the user has provided enough tokens to cover the deposit and the execution fee.
If insufficient, the deposit is reverted.
Box: validateReceiver
Purpose: Ensures the user‐specified receiver address (the address that will receive the minted market tokens) is valid (non‐zero, properly formatted).
Box: Construct Deposit Object
Purpose:
Packages all the user’s deposit parameters (validated amounts, addresses, fees) into a cohesive data structure.
This object will be stored on‐chain and referenced in the second step.
Box: Generate a Unique Key
Purpose:
Produces a unique identifier (often a bytes32
hash) for the deposit.
This key references the specific deposit record and is essential for the subsequent executeDeposit
call.
Box: Validate Execution Fee
Purpose:
Compares the user’s provided fee amount with the estimated cost of executing the deposit.
If it falls short, the deposit creation is rejected.
Box: Estimate Gas
Purpose:
Predicts how much gas the eventual executeDeposit
call might consume, based on factors like how many tokens are being processed, and what swaps might be needed.
Box: Validate Callback Gas Limit
Purpose:
Ensures any “callback” function (if Avitus is set up to do a callback to a user’s contract) has a safe, allowable gas limit.
Box: Store Deposit Details
Purpose:
Persists the constructed deposit data and the unique deposit key to Avitus’s internal data store (e.g., a mapping in a smart contract).
Box: Emit Event
Purpose:
Fires a blockchain event indicating that a deposit record was created.
Off‐chain services (like UIs or indexers) can track deposits by listening to this event.
Box: Return the Key
Purpose:
Returns the unique key to the caller, typically as a function return value.
The user (or front‐end) must keep this key to proceed with the executeDeposit
step.
executeDeposit
FlowOnce the deposit has been created, someone must call executeDeposit
(usually the same user, but it could be a keeper or another authorized entity). They will provide the deposit key generated earlier.
Box: Gas Calculation
Purpose:
Adjusts the starting gas in compliance with Ethereum’s “63/64 rule” or other chain‐specific nuances to ensure that subsequent internal calls have enough gas.
Box: Remove Deposit Entry
Purpose:
Retrieves the deposit data (by the key) from Avitus’s store.
Removes that record to avoid potential replay or duplication.
If the deposit key is invalid or doesn’t exist, the transaction reverts.
Box: Fetch Market Data
Purpose:
Retrieves important info about the target market where the user is depositing.
Data may include the current liquidity, existing market token supply, price feeds, and any special rules or limits.
Box: Validate Initial Deposit
Purpose:
If this is the first deposit into a brand‐new market, enforces any extra constraints for “initial deposits” (e.g., minimum liquidity thresholds).
Box: Get Market Prices
Purpose:
Retrieves the latest token prices from oracles or internal price feeds.
Used for calculating how many market tokens to mint in return for the user’s deposit.
Box: Distribute Position Impact Pool
Purpose:
Adjusts the deposit’s effect on the overall liquidity pool by distributing any existing “price impact” from prior trades or deposits.
Helps maintain fair pricing as liquidity changes.
Box: Validate Max PnL Factor
Purpose:
Ensures the protocol’s risk parameters are respected (e.g., you can’t deposit if you’d exceed a certain profit‐and‐loss exposure).
Box: Perform Swaps
Purpose:
Executes any necessary token swaps to obtain the correct balance of “long” vs. “short” tokens for this deposit.
For instance, if a user deposits ETH but the market requires both ETH and a stablecoin for the position, it will swap as needed.
Box: Calculate USD Values
Purpose:
Converts the user’s final token amounts (post‐swap) into an equivalent USD value, based on the mid‐market price.
Box: Calculate Price Impact USD
Purpose:
Determines how much the user’s deposit changes the market price (e.g., if a large deposit pushes the token price up or down).
This is reflected as positive or negative price impact.
Box: Process Long and Short Token Deposits
Purpose:
If the deposit includes both “long” and “short” positions, handles them in separate branches.
Ensures each side is credited correctly according to the deposit amounts.
Box: Calculate Swap Fees
Purpose:
Determines the total fees owed to the protocol for performing these swaps, typically a percentage of the swapped amounts.
Box: Increment Claimable Fees
Purpose:
Adds the newly calculated swap fees to the protocol’s claimable‐fee pool, which may be collected by governance or stakers.
Box: Retrieve Pool Value Info
Purpose:
Fetches the total liquidity in the market.
This is crucial for deciding how many new “market tokens” the depositor should receive, based on the deposit’s share of the pool.
Box: Retrieve Market Token Supply
Purpose:
Checks the total supply of existing market tokens.
Used to calculate the depositor’s ownership stake in the pool.
Box: Handle Positive Price Impact
Purpose:
If the deposit contributes beneficially to the pool (e.g., balancing liquidity or covering an under‐collateralized side), the depositor might receive extra market tokens (an incentive to add liquidity).
Box: Mint Market Tokens
Purpose:
Mints new tokens in proportion to the user’s deposit value relative to the total pool value and existing token supply.
Box: Validate Minimum Tokens
Purpose:
Ensures the user receives at least the minimum number of tokens they specified in their deposit parameters.
If the actual amount is too low (due to price movement or slippage), the deposit may revert to protect the user.
Box: Handle Negative Price Impact
Purpose:
If the deposit causes a negative price impact, fewer tokens get minted.
Some of the tokens may remain in the “impact pool” instead of going to the user.
Box: Final Validations
Purpose:
Double‐checks that internal balances, minted amounts, and fees all align with Avitus’s rules.
Confirms no deposit constraints are violated at the last minute (e.g., user deposit didn’t exceed some cap).
Box: Pay Execution Fees
Purpose:
Distributes the execution fee (collected earlier) to the entity that executed the deposit, such as a keeper or the protocol itself.
Box: Final Minting
Purpose:
Officially transfers the newly minted market tokens into the user’s (receiver’s) address.
Concludes the deposit process, marking it as complete.
In Avitus, opening a trade (e.g., going long or short on an asset, or swapping tokens) is separated into two steps:
createOrder
The user supplies initial parameters for the order (collateral, fees, target market, etc.).
The protocol validates these parameters, estimates fees, and stores the order in Avitus’s data store.
A unique key is generated to track this specific order.
executeOrder
The protocol checks real‐time conditions (e.g., price feeds, trigger prices).
If everything is valid, Avitus processes the order (swaps, opens a position, etc.).
Finally, it deducts fees, executes callbacks if needed, and completes the order.
Each section below covers these two functions and their internal steps in detail.
createOrder
FlowcreateOrder
The user triggers the createOrder
function, passing:
orderVault
— the contract or module that manages collateral and token transfers.
params
— order‐specific parameters such as:
Order type (e.g. increase position, decrease position, swap).
Collateral (which token the user is depositing).
Fees (execution fee, possible referral discounts, etc.).
Market details (which market(s) the user wants to trade).
Other data like leverage and position size
Box: Validate Trader’s Account
Purpose: Ensures the trader’s account (caller) meets protocol requirements.
For example: verifying the trader’s address isn’t banned, restricted or does not meet the margin requirements.
Outcome: If the account fails these checks, the function reverts.
Box: Set Trader Referral Code (Referral Storage)
Purpose:
If the user (trader) provided a referral code, associate that code with the user’s account in the referral tracking system.
Helps the protocol track which referrals led to new orders and potentially distribute referral rewards.
Box: Process Order Based on Type
Purpose:
Determines the initial handling of collateral and execution fees, depending on whether the user is:
Decreasing a position
Uses the params
amount to reduce the trader’s open position.
Collateral adjustments might be performed directly.
Swapping tokens or Increasing a position
If the collateral token is the wrapped native token (e.g., WNT), ensure the user deposited enough for the entire collateral plus the execution fee.
Deduct the execution fee from the collateral if needed.
Box: Record Execution Fee
Purpose:
If using the wrapped native token (e.g., WNT) for fees, Avitus transfers the required amount of tokens into an internal fee pool (or dedicated fee address).
Ensures that the protocol has the necessary gas to later execute the order.
Box: Validate Order Conditions
Purpose:
For Position Orders (long/short trades): verifies the user’s target market is valid and open for trading.
For Swap Orders: checks the entire swap path (e.g., token A → token B → token C) to ensure each “hop” is recognized and the pair/market is valid.
Outcome: If the market or path is invalid, the order is rejected.
Box: Validate Receiver and Callback
Purpose:
Ensures the order’s “receiver” address (where any output tokens or position credit goes) is valid.
If the user specified a “callback,” Avitus checks the gas limit or other conditions to ensure that callback execution is allowed.
Box: Estimate and Validate Gas Fees
Purpose:
Estimates the on‐chain gas needed to execute this order in the future.
Validates that the execution fee the user provided is sufficient to cover this estimated cost (otherwise reverts).
Box: Generate Unique Key and Save Order
Purpose:
Creates a unique identifier (Key) for the new order.
Validates that the order object is not empty.
Saves the order’s data in Avitus’s Data Store under that key, enabling later retrieval during executeOrder
.
executeOrder
FlowWhen market conditions are right—such as the order’s trigger price being met or the user initiating the final step—someone (the user, a keeper, or another designated executor) calls executeOrder
with the order key.
Box: Validate the Order
Purpose:
Ensures the order object is present in the data store, not expired, not malformed, etc.
Confirms that the order is indeed eligible for execution.
Box: Validate Order’s Trigger Price
Purpose:
For limit orders or stop orders, checks if the trigger price set by the user has been reached in the marketplace.
If the trigger price condition isn’t met, the order can’t be executed.
Box: Remove the Order from Storage
Purpose:
Once confirmed valid, Avitus removes the order record from its data store so it cannot be executed again (prevents double‐execution or replay).
Box: Adjust Gas Accounting
Purpose:
Accounts for Ethereum’s “63/64 rule” on internal calls or any other which is specific to chain.
Ensures that subsequent internal operations have enough gas.
If the gas is insufficient, it reverts here rather than mid‐execution.
Box: Process the Order
Purpose:
Executes the core logic of the trade (opening or closing a position, swapping tokens, etc.).
For a position increase: uses the user’s collateral to open a bigger position.
For a position decrease: closes or partially closes the user’s position, returning any freed collateral.
For a swap: executes the swap route from token A → token B → ... → token X.
Box: Validate Internal State Changes
Purpose:
After the core logic runs, Avitus checks that internal balances (collateral, user position sizes, etc.) are consistent.
Ensures the user’s new position size, collateral usage, or token holdings are reflected correctly.
Box: Execute Callback Logic
Purpose:
If the user specified a “callback” in the order, Avitus calls the user’s contract here.
For example, a user might want to do something automatically after the trade is filled.
This step is only performed if the callback was validated earlier.
Box: Pay Execution Fee
Purpose:
Avitus uses the fees collected in the “Record Execution Fee” step (from createOrder
) to compensate the executor or the protocol.
This covers the gas cost and any additional execution overhead.
New Final Step
Purpose:
Deposit Collateral: Once the order is validated and all conditions are met, Avitus deposits the user’s collateral into the clearinghouse.
Leveraged Exposure: From there, the user gets leveraged exposure via the self‐hedging automated market‐making pool. In practice, the user is borrowing exposure from the pool which houses the assets provided by liquidity providers (LPs) without owning the underlying asset directly.
Active Management:
The clearinghouse actively manages the position, tracking mark‐to‐market valuations in near‐real‐time.
Next Section: Further technical details on how the clearinghouse handles collateral, margin requirements can be found in the upcoming “Clearinghouse” section.