What’s under the hood?
In the previous write-up, we explored how Marginly helps users get the maximum out of trading on their favorite DEXs. But it can still be unclear to you what Marginly has under the hood. In this article, we will take a closer look at the tech strengths of the protocol and give a brief overview of the technical aspects that make Marginly stand out.
By way of reminder, Marginly is a margin trading & derivatives layer on top of AMM liquidity that helps DEXs obtain new functionality without extra development efforts. While the protocol unites isolated liquidity pools and a smart order router, Marginly also runs its own mobile-first web interface for a better user experience. Users can go long or short with up to 20X leverage, enjoy advanced options strategies, and earn a passive yield on liquidity provision. Let’s dive deeper into the details of Marginly’s technical implementation.
Protocol architecture
Marginly runs a bundle of EVM-compatible smart contracts that is Gas-optimized and doesn’t rely on off-chain data (trustless). Let’s look closer at the protocol architecture and how the core components of Marginly interact:
As you can see from the diagram in Fig. 1, Marginly consists of three main components:
- Conglomerate of isolated liquidity pools
- Trade router
- Position management & liquidations flow
Isolated pools contain leverage liquidity, users’ margin, and trade proceeds. Every pool includes a base asset and a quote asset (usually a volatile one and a stablecoin), and it’s linked with pools for respective trading pairs on connected AMMs. User margins and trade proceeds are locked in these pools and available for borrowing by the opposite side. As such, shorts pay interest to longs and vice versa.
A smart trade router connects system pools with external AMM DEXs. It includes an off-chain route planner that calculates an optimal route for the specific trade and posts it on-chain, where proposed trading parameters get verified. Also, there is a set of whitelisted proxy contracts that implement connectors to interfaces of external AMMs. Routing identifies places with the most liquidity depth for the particular trade and makes trading on Marginly compatible with long-tail pools.
The third component helps users manage their positions on Marginly: add more margin, withdraw margin, take more leverage, deleverage, or close positions. Also, it executes liquidation mechanisms. We will discuss how liquidations work on Marginly in a separate chapter below. Here is the list of base functions used for position management:
reinit()
Accrue interest rates, and liquidate the riskiest position if neededdeposit base(account_id, qty)
Deposit Base_Asset in the amount of qty and call reinit()deposit quote(account_id, qty)
Deposit Quote_Asset in the amount of qty and call reinit()withdraw base(account_id, qty)
Withdraw Base_Asset in the amount of qty and call reinit()withdraw quote(account_id, qty)
Withdraw Quote_Asset in the amount of qty and call reinit()close position(account_id)
A sequence of (1) swap part of collateral enough to cover the position’s debt, (2) reduce position debts to zero, (3) update system leverage, (4) remove the position from leverage heap, (5) call reinit()receive position(account_id)
Provide liquidity and absorb a liquidated position realizing its net position value and call reinit()transfer position(newOwner)
Transfer position ownership to a previously uninitialized account (that has no position in the system) and call reinit()
Key system parameters
Marginly relies on the global set of system parameters that impact protocol stability and its specific functions. Most of these parameters were defined empirically through extensive stochastic modeling. Still, we will clarify them even more precisely during our testnet launch. Afterward, some of them will become subject to governance voting.
Here is the list of important system parameters for trades and other operations:
max leverage == 20
Maximum allowed leverageinterest rate == Coef * var(Base_Asset)
The proportion of a loan that is charged as interest to the borrower.
var(Base_Asset) — historical long-term average Base_Asset volatility, which we initially set to be 6% or 0.06 per day
Coef — scaling coefficient which governs the steepness of the interest rate curve, the default value is 15swap fee == 0.1%
When users take leverage, they pay swap fee on the notional borrow amountposition min amount == 0.001 ETH
Minimum amount (in base asset) to open a Short or Long positionprice seconds ago == 900 seconds
Number of seconds in the past from which to calculate the time-weighted-average-price from Uniswap TWAP Oracleposition slippage == 2% of the last AMM price
Maximum allowable slippage when managing a positionmargin call slippage == 5% of the last AMM price
Maximum slippage for liquidations
Loan pricing and risk management
We use a risk-based approach to pricing that is opposed to the utilization one that is quite common across DeFi (AAVE, Compound, Gearbox, you name it). The system keeps track of total long and short leverage in each pool to adjust interest rates for either side. The interest rate is proportional to asset volatility and the pool’s leverage. The exact formula looks like this:
Where r — interest rate, L — pool position leverage, σ — implied volatility. Every user action triggers a recalculation and updates the coefficients. This approach allows trades to control the costs of their positions at any time.
You may ask how the σ parameter (volatility) is defined, as it seems to be the key here. It sets an actual foundation for further risk management of the protocol guarding its security and solvency. As such, we need to ensure the precision of selected numbers. We explain our considerations and research to set this parameter below.
After extensive research and deliberation, we decided to set volatility as a governance-tweakable parameter while looking to calculate volatility on-chain in later versions of the protocol. Marginly tracks the close-to-close estimator as the most commonly used volatility measure. The standard definition of volatility is the square root of the variance, and variance is defined as
Where each x_i is a logarithmic return and ẋ is a mean return.
We use intraday frequency to calculate volatility as a means to get a large enough sample size while avoiding irrelevant data.
Now that a framework for volatility calculation has been established, let’s run some simulations. We have a dataset of daily closing prices of WETH/USDC starting from 1 Jan 2020. Based on this data, we calculate log returns and then volatilities over non-overlapping periods of 20, 30, 60, 90, 120, 150, and 180 days.
The cone in Fig. 2 shows the tendency for short-term volatilities to fluctuate more widely than longer-dated volatilities. This is due to the effects of increased sampling errors for short-term estimates and the fact that big moves will be averaged away in the longer term. The chart shows that the long-term average daily volatility is around 5%. Further looking at the historical volatility distribution, we can confirm the above picture:
Fig. 3 shows the actual close-to-close volatility over the sample period. We observe a Gaussian blob centered around 4–5% daily volatility and a fat proper tale with several distinct peaks around 8%, 10%, and 12%. The regime shift (low volatility vs. high volatility) is around 7%. This is the volatility parameter value we selected for Marginly v1 smart contracts.
To sum up, volatility is used as a risk proxy in Marginly, and its consideration facilitates measuring protocol risks. In future versions of the protocol, we will introduce on-chain volatility calculations (as opposed to the current governed parameters) that aim to use the same AMM pools to calculate volatility directly on liquidity that the Marginly pool will be trading against.
Liquidations and deleveraging
Another important aspect of Marginly is its approach to liquidations. In V1 of the protocol, liquidations occur once a trader’s position becomes overleveraged. To ensure we handle liquidations properly and keep protocol solvent even during severe market crashes, we’ve implemented two ‘heaps’ of user positions — for long and short positions, respectively.
All positions within the heaps are sorted by their leverage parameter, so we always have the riskiest ones on top of the list (heap root). Whenever users interact with the contract, they trigger a reinit() function that refreshes the contract state (recalculate all parameters, accrue interests, and check the riskiest long and short position that needs to be liquidated). If the position’s leverage exceeds max leverage set in the protocol, the position is liquidated.
To handle actual liquidations, Marginly introduces deleveraging, which greatly helps during distressed markets. This mechanism allows to close out users’ positions by reducing the total leverage (both collateral and debt). It works even when there is a liquidity shortage in the respective AMM pool.
Let’s consider the following example to understand deleveraging better:
Note that all of the ETH brought in by users 1 and 2 was sold by users 3 and 4. Now let’s say the price of ETH drops to the point where the system needs to liquidate user 1. The protocol will need to sell user 4’s ETH, but it won’t be able to do so as there is no ETH in the pool! This is exactly where deleveraging comes into play.
Instead of selling something that the pool doesn’t have, the protocol will close user positions against the opposing side: short sellers 3 and 4 will have their debts and collaterals reduced by 4 ETH and 3000 USDC proportional to their debt values: let’s take user 3 as an example and calculate his new debt and collateral values after deleveraging:
This is what the pool looks like after deleveraging:
Note the following:
- There is still no ETH liquidity inside the pool after deleveraging.
- Total net position of short sellers increased by the net position of the liquidated user.
- Leverage of short sellers decreased.
- Lender (user 2) didn’t see his net position increase (unlike after regular liquidation).
It’s important to know that in Marginly, NO trading happens when deleveraging is performed. Compare this to the crvUSD behavior, for example. Arbitrageurs still need to perform trades there to level out the AMM price, and they may not be willing to do so when market tanks in one direction or the network is congested, and the gas price is way too high.
We will consider ditching liquidations altogether and resorting only to deleveraging when liquidating user positions in later versions of Marginly.
How we live without oracles
Instead of using centralized oracle systems, we utilize Uniswap v3 TWAP oracle In Marginly v1. It feeds a time-weighted average price of the corresponding Uniswap pool. Thanks to Uniswap’s design, we can choose the time period for which to calculate the average price. This period should be chosen carefully to balance the adaptiveness of the price against the possibility of a flash loan/liquidity attack.
In general, the larger the averaging period, the harder it is to manipulate the price. At the same time, the average price takes longer to respond to sharp price movements, which could lead to large discrepancies between the balance price and the current market price. These discrepancies on their own don’t pose an immediate threat to the Marginly protocol, nor do they present any meaningful arbitrage opportunities.
Our no-oracle approach allows Marginly to rely completely on on-chain data and avoid a single point of failure common among centralized and off-chain oracles. We realize that Uniswap itself may be susceptible to periodic liquidity drains, especially during market turmoil, so we introduce order routing to several liquid venues for the next versions of our protocol. This will allow us to use aggregates or averages from several sources. TWAP oracle itself may be further strengthened by evaluating which fee tier (0,05%, 0.3%, or 1%) Uniswap v3 pool to use the oracle from based on its immediate liquidity.
Quick wrap-up
In this second article of our series exploring Marginly, we have discovered the most interesting technical solutions that are actively used in the protocol. Thanks to our novel vision of designing a leverage protocol, we address the main hurdles of DeFi. The list includes reliance on oracles (we don’t use them), trading long-tail assets (easy: we find the best liquidity for them and even provide 20X leverage), and liquidations (we use deleveraging instead).
We can’t wait to share with you details of those exciting opportunities that we have for partner DEXs. Precisely how they can take advantage of integration with Marginly, get new functionality turn-key, and snatch a piece of our RevShare pie. We will cover this in one of our upcoming articles.
If you need to learn the basics about Marginly, don’t hesitate to refer to our piece describing its essential features.
Meanwhile, don’t miss joining our socials, Twitter and Discord, and don’t miss the announcement of exciting things we are cooking for you to celebrate our upcoming launch!