# Introduction&#x20;

High level overview of the Marginly protocol.

*Marginly* is a smart contract-based margin trading & derivatives application that allows users to take up to 20x leveraged long and short positions on crypto-assets across different DEXes and AMMs such as Uniswap, SushiSwap, Curve, Balancer, and others.

*Marginly* provides slick leveraged swap interfaces built with the mobile-first approach and simplified integration with DeFi aggregators, routers, and wallets.&#x20;

### Features

* **B2B-ready:** Integrate leveraged trading and farming into your protocol’s interface.
* Fully on-chain: Marginly works with wide range of on-chain oracles and doesn’t require off-chain information
* **Asset Variety:** Open any pool on Marginly as long as there is corresponding liquid AMM pool.&#x20;
* **Margin trading:** Trade up to 20x leveraged (long & short) with trade execution through liquidity pools of connected DEX-es.
* **Leveraged Farming:** Farm yield by borrowing WETH to leverage long LRTs and LSTs.&#x20;

### Tech features

* **Fully decentralized:** *Marginly* uses no off-chain information and relies on [Uniswap v3 oracles](https://uniswap.org/blog/uniswap-v3-oracles).
* **Risk segregation:** Each *Marginly* liquidity pool is comprised of a single risk asset and a stablecoin. With this approach, the risk is fully isolated to a single volatile asset thus making it more predictable and manageable. *Marginly* risk framework allows utilizing borrowed capital with maximum efficiency while ensuring strict controls over the pool solvency.
* **Liquidity Infinity Loop:** *Marginly* enables a self-reinforcing cycle in which assets can be reused by the opposite party as leverage for their trades. In other words, longs pay shorts, while shorts pay longs.
* **Deleveraging vs. Liquidations:** In case of margin calls, the system automatically reduces the amount of debt in a portfolio by reversing trades within its pools instead of auctioning positions out on linked DEXes.
* **Order routing:** *Marginly* is designed to execute spot trading across multiple DeFi protocols in different blockchains, which helps aggregate liquidity and enables long-tail asset trading.   &#x20;

### Marginly v1

For the initial version of *Marginly,* we want it simple and efficient serving as a proof of concept.  Refer to ["Future Plans"](/future-plans/beyond-marginly-v1) section to get a glimpse into what we have in store for upcoming versions of the protocol. Open discussion on this subject is encouraged: feel free to use a dedicated [Discord channel](https://discord.com/channels/1097798692003655781/1141627085589315614) to voice your opinion and reach out to developers and other active community members.&#x20;

#### Supported blockchain networks

[Arbitrum](https://app.marginly.com/arbitrum)\
[Blast](https://app.marginly.com/blast)

More are to come.

### Official Marginly Links

Be wary of scammers: always make sure that you are interacting with the official websites. Do not connect your wallets to unofficial websites offering free tokens or promoting investment opportunities.&#x20;

* Website: <https://marginly.com/>
* Blog: <https://marginly.medium.com/>
* Github: <https://github.com/eq-lab/marginly/>
* Docs: <https://docs.marginly.com/>
* X: <https://twitter.com/marginlycom>
* Discord: <https://discord.gg/QUTgn64n82>
* Telegram: <https://t.me/marginly>

Please use our [Discord support channel](https://discord.com/channels/1097798692003655781/1124254753468190740) if there is anything else you'd like to know about Marginly. &#x20;


# How to

Find out how to use Marginly app


# Connect a wallet

Learn how to connect a wallet to Marginly

### About

First step using Marginly. The app supports multiple wallets such as Metamask, Brave, Trust Wallet, Ledger Live and many others. &#x20;

### **Step-by-step guide**

1. Click the network icon in the top right corner
2. Scan QR code with mobile or choose from a number of options in the desktop section
3. Make sure you have connected the correct wallet and correct network by doing the following:

   Click on network icon in the top right corner (1) and then click on the network (3)

<figure><img src="/files/HwwemNawvJu08Bgkmr4l" alt=""><figcaption></figcaption></figure>

Check your wallet (1), network (2) and balances (3)

<figure><img src="/files/FkS27UvWFM1PCLG68l7G" alt=""><figcaption></figcaption></figure>


# Swap

Learn how to swap assets in Marginly

### **About**

Swap functionality is vital for trading activity and position management: servicing debts, taking profits and executing a trading strategy.

### **Step-by-step guide**

1. Select desired pool
2. Click "Swap" tab (1), choose asset you want to swap out (2), asset you want to swap for (3), press "Get Asset" button (4)

<figure><img src="/files/omiD6r7w9i3TEC0WuRPZ" alt=""><figcaption></figcaption></figure>

1. Sign transaction in wallet


# Approve Spending

Learn how to approve spending in Marginly

### **About**

Before doing any transaction with a new asset, spending limits must be set and approved.

### **Step-by-step guide**

1. Click “Continue” to approve spending when prompted

<figure><img src="/files/JuvAmSxZAjLuHaawm9G1" alt=""><figcaption></figcaption></figure>

2. The box (3) should be filled automaticlly. If this does not happen, set spending cap by clicking either “Use site suggestion” (1), “Max” (2) or input spending cap manually (3) and click Next (4)

<figure><img src="/files/6Dcqscj7zlhODXjPyhMK" alt=""><figcaption></figcaption></figure>

3. Click on Approve
4. Receive confirmation

<figure><img src="/files/gqJEe0YIvztGMQSbN7lV" alt=""><figcaption></figcaption></figure>


# Open a Long Position

Learn how to open a long position in Marginly

### About

Taking a long position means you are betting on a price increase. In this case a loan is taken out in a stablecoin (or other quote asset) to buy more of the asset with the goal of making a profit when the price moves up.&#x20;

### **Step-by-step guide**

1. Select a pool with the desired asset on the main screen of the app.&#x20;
2. Input margin amount (1), choose leverage (2) and press Long button (3)

<figure><img src="/files/L3E37mdQdfOgchhvs3FJ" alt=""><figcaption></figcaption></figure>

3. Sign transaction in wallet
4. Receive confirmation&#x20;

<figure><img src="/files/Iw5e9ykBMrCXct1ASIXA" alt=""><figcaption></figcaption></figure>


# Open a Short Position

Learn how to open a short position in Marginly

### About

Taking a short position means you are betting on a price decrease. In this case a loan is taken out in the risk asset to immediately sell it with the goal of making a profit when the price moves down.&#x20;

### **Step-by-step guide**

1. Select a pool with the desired asset on the main screen of the app.&#x20;
2. Click “Short” (1), input margin amount (2), choose leverage (3) and press Short button (4)

<figure><img src="/files/QnqXLhaX91pmf95dhKRz" alt=""><figcaption></figcaption></figure>

3. Sign transaction in wallet
4. Receive confirmation&#x20;

<figure><img src="/files/Le0E9eSl6LhMO8NpnvNO" alt=""><figcaption></figcaption></figure>


# Withdraw Funds

Learn how to withdraw funds from an open position in Marginly

### **Step-by-step guide**

1. Select your position on the main screen of the app
2. Click the “-” button

<figure><img src="/files/aUh2ILQRq3tosOK20i4k" alt=""><figcaption></figcaption></figure>

3. Input desired amount (1) and press “withdraw” (2)

<figure><img src="/files/CYvbP6hI00W0PptoSKhc" alt=""><figcaption></figcaption></figure>

4. Sign transaction in wallet
5. Receive confirmation

<figure><img src="/files/jRlz1xx5CCaDhSfWSC6J" alt=""><figcaption></figcaption></figure>


# Add Funds

Learn how to add funds to an open position in Marginly

### About

Adding funds is required when a trader desires to keep a losing position open and maintain a healthy margin to avoid a margin call.&#x20;

### Step-by-step guide

1. Select your position on the main screen of the app
2. Click the “+” button&#x20;

<figure><img src="/files/ajsF2YC9byBAlTLOj3CA" alt=""><figcaption></figcaption></figure>

3. Input desired amount (1) and press “Add” (2)

<figure><img src="/files/ALLYoh0c3XJ1uybUwpYR" alt=""><figcaption></figcaption></figure>

4. Sign transaction in wallet
5. Receive confirmation

<figure><img src="/files/tM2bLiZJDoOAI9gOVFck" alt=""><figcaption></figcaption></figure>


# Close Position

Learn how to close a position in Marginly

### About

Whether it's taking a profit or a loss - closing a position is an integral part of trading.

### Step-by-step guide

1. Select your position on the main screen of the app
2. Press “Close Position”

<figure><img src="/files/PvjxLgztTIz5NxJ2fjqf" alt=""><figcaption></figcaption></figure>

3. Sign transaction in wallet
4. Receive confirmation

<figure><img src="/files/PEYfb1vkIB66Bcr3ixqq" alt=""><figcaption></figcaption></figure>


# Increase Leverage

Learn how to increase position leverage in Marginly

### About

When a trader is not sufficiently leveraged for their personal risk tolerance.&#x20;

### Step-by-step guide

1. Select your position on the main screen of the app
2. Click on “+” symbol in the top right corner

<figure><img src="/files/ZVQpvP1yBBQ6Y790K9eS" alt=""><figcaption></figcaption></figure>

3. Select how much leverage to add (1) and click “Buy” (2)

<figure><img src="/files/kOf9H9pogFOkUwWcMDHe" alt=""><figcaption></figcaption></figure>

\
4\. Sign transaction in wallet

5\. Receive confirmation

<figure><img src="/files/SlzPYiYufQzxiJZZ0lkU" alt=""><figcaption></figcaption></figure>

<br>


# Pay Off Debt

Learn how to pay off debts in Marginly

### About

A vital instrument of portfolio management.&#x20;

### Step-by-step guide

1. Select your position on the main screen of the app
2. Click “Pay Off” button

<figure><img src="/files/u1njoq7b1R0aSnd3ryNZ" alt=""><figcaption></figcaption></figure>

3. Input amount to deposit (1) and click “Repay” (2)

<figure><img src="/files/Wpf8Z6D8gSJZ8w0mJkxw" alt=""><figcaption></figcaption></figure>

4. Sign transaction in wallet
5. Receive confirmation

<figure><img src="/files/PGoTN4J7WGjYvoGKqT2V" alt=""><figcaption></figcaption></figure>


# Deposit Liquidity

Learn how to provide liquidity to a pool in Marginly

### About

Users can provide liquidity to Marginly pools and earn fees from borrowers.&#x20;

### Step-by-step guide

1. Click Earn on the main screen of the app
2. Click “lend” on the asset you wish to deposit

<figure><img src="/files/kJttSUBskUUuV8uEg9qm" alt=""><figcaption></figcaption></figure>

3. Input desired amount (1) and press “Lend” (2)

<figure><img src="/files/Pn2Q0WfNPlEQtslg7Kjy" alt=""><figcaption></figcaption></figure>

4. Sign transaction in wallet
5. Receive confirmation

<figure><img src="/files/YFZy1Hooto4553sdgwtu" alt=""><figcaption></figcaption></figure>


# Withdraw Liquidity

Learn how to take liquidity out of a pool in Marginly

### About

Users can withdraw previously deposited liquidity from Marginly pools&#x20;

### Step-by-step guide

1. Select your lending position on the main screen of the app
2. Click “Withdraw”

<figure><img src="/files/ctRlnA5nfioGD75Lce1i" alt=""><figcaption></figcaption></figure>

3. Input amount (1) and click “Withdraw” (2)

<figure><img src="/files/Cc4KhnIal68C1oNThOz0" alt=""><figcaption></figcaption></figure>

4. Sign transaction in wallet
5. Receive confirmation

<figure><img src="/files/dCZprCJ97UyU6sSAmYPV" alt=""><figcaption></figcaption></figure>


# Add Liquidity

Learn how to increase a position in a liquidity pool

### About

Users can add more liquidity to Marginly pools.

### Step-by-step guide

1. Select your lending position on the main screen of the app
2. Click “Lend more”

<figure><img src="/files/OWB5FdXpQzYHVYLOdfhx" alt=""><figcaption></figcaption></figure>

Input amount (1) and click “Lend” (2)

<figure><img src="/files/9li0YSCgkhz3sjgd5IHs" alt=""><figcaption></figcaption></figure>

3. Sign transaction in wallet
4. Receive confirmation


# Smart contract addresses

Contains addresses for every blockchain Marginly is deployed on


# Arbitrum

<table><thead><tr><th width="205">Contract</th><th>Address</th></tr></thead><tbody><tr><td>Router</td><td><a href="https://arbiscan.io/address/0x8e650512b532c83262fde1eda1c5a2a898b4db00">https://arbiscan.io/address/0x8e650512b532c83262fde1eda1c5a2a898b4db00</a></td></tr><tr><td>PoolImplementation</td><td><a href="https://arbiscan.io/address/0x1d17f7a1e9a53cce6c89495af1e3753c11bf6da2">https://arbiscan.io/address/0x1d17f7a1e9a53cce6c89495af1e3753c11bf6da2</a></td></tr><tr><td>Factory</td><td><a href="https://arbiscan.io/address/0x1e36749E00229759dca262cB25Ad8d9B21bEB3F5">https://arbiscan.io/address/0x1e36749E00229759dca262cB25Ad8d9B21bEB3F5</a></td></tr><tr><td>Pool_weth-usdc-native</td><td><a href="https://arbiscan.io/address/0x87e711bcb9ed1f2f6dec8fcc74cd2e0613d43b86">https://arbiscan.io/address/0x87e711bcb9ed1f2f6dec8fcc74cd2e0613d43b86</a></td></tr><tr><td>Pool_arb-usdc-native</td><td><a href="https://arbiscan.io/address/0x0F750fBb044037254b5843C6b4a715AA12876d94">https://arbiscan.io/address/0x0F750fBb044037254b5843C6b4a715AA12876d94</a></td></tr><tr><td>Pool_weth-usdc</td><td><a href="https://arbiscan.io/address/0x53C08A5e2b7bc973d3d5Aee60373969E30e93B93">https://arbiscan.io/address/0x53C08A5e2b7bc973d3d5Aee60373969E30e93B93</a></td></tr><tr><td>Pool_wbtc-weth</td><td><a href="https://arbiscan.io/address/0x99Cc2A68e121F2434db5C5D63670212F07f89ee8">https://arbiscan.io/address/0x99Cc2A68e121F2434db5C5D63670212F07f89ee8</a></td></tr><tr><td>Pool_arb-usdc</td><td><a href="https://arbiscan.io/address/0x5ceB22fe09C7259b9dceef243615f180664BCE70">https://arbiscan.io/address/0x5ceB22fe09C7259b9dceef243615f180664BCE70</a></td></tr><tr><td>Pool_gmx-weth</td><td><a href="https://arbiscan.io/address/0x0637b18b5c5b7fe72f63a5511d2e90bec7fc828e">https://arbiscan.io/address/0x0637b18b5c5b7fe72f63a5511d2e90bec7fc828e</a></td></tr><tr><td>Pool_link-weth</td><td><a href="https://arbiscan.io/address/0x6e699E6eD6391259e4Cec38c16d80f772dF9F370">https://arbiscan.io/address/0x6e699E6eD6391259e4Cec38c16d80f772dF9F370</a></td></tr><tr><td>Pool_pendle-weth</td><td><a href="https://arbiscan.io/address/0x3adc0f25c7A23a626A67811c47d0A0DbE21773a4">https://arbiscan.io/address/0x3adc0f25c7A23a626A67811c47d0A0DbE21773a4</a></td></tr><tr><td>Pool_rdnt-weth</td><td><a href="https://arbiscan.io/address/0x82bC6A8dA5988E66676014cA99056Bd7A2f44dF2">https://arbiscan.io/address/0x82bC6A8dA5988E66676014cA99056Bd7A2f44dF2</a></td></tr><tr><td>Keeper</td><td><a href="https://arbiscan.io/address/0x193E76C78e1c02BF35c1F789Ce2a1aE39F865629">https://arbiscan.io/address/0x193E76C78e1c02BF35c1F789Ce2a1aE39F865629</a></td></tr><tr><td>KeeperUniswapV3</td><td><a href="https://arbiscan.io/address/0xdddf54e1323d0d07bfdfedadc56fadf2045330df">https://arbiscan.io/address/0xdddf54e1323d0d07bfdfedadc56fadf2045330df</a></td></tr></tbody></table>


# Blast

| Contract         | Address                                                                          |
| ---------------- | -------------------------------------------------------------------------------- |
| Pool\_musd-usdb  | <https://blastscan.io/address/0xb312D61915c878938fcE09D13DD3006c6835b3e5>        |
| Pool\_weth-usdb  | <https://blastscan.io/address/0x1f06e6e226bE4F0a66B7f8b1007997DC9De1eBC7>        |
| KeeperUniswapV3  | <https://blastscan.io/address/0x953bCae95340b4f275c357a9d847E36617401f8e>        |
| Blast Operator   | <https://blastscan.io/address/0xC8F8F0ac6b78afc8559Cc39C71361dAB043f9a14>        |
| Blast Points API | api.marginly.com/api/users/{userAddress}/marginlyPool/{poolAddress}/blast-points |


# FAQ

Some of the most frequently asked questions are answered here

### **Q: What is Marginly?**

A: Marginly is a smart contract-based margin trading & derivatives application that allows users to take up to 20x leveraged long and short positions on crypto-assets across different DEXes in multiple networks.

### **Q: Who developed Marginly?**

A: A dedicated team within [EQlab](https://eqlab.io/) is working on Marginly.

### **Q: How can I get involved with Marginly?**

A: Join our [Discord](https://discord.gg/e69RwaaC) for feedback and discussion, follow us on [Twitter](https://twitter.com/marginlycom) to keep up with the news and check out Marginly’s [Galxe](https://galxe.com/marginly) space to participate in contests and other promotional activities.

### **Q: How do I trade on Marginly?**

A: Marginly app is in public beta so anyone can try it out by visiting beta.marginly.com

### **Q: How do I get testnet tokens?**

A: Testnet tokens can be obtained in [this](https://discord.com/channels/1097798692003655781/1124273397321453669) discord channel. Type /get and paste your address. Please note that tokens can only be received once per address.

### **Q: Can I swap testnet tokens?**

A: Sure! Feel free to use this direct link: <https://beta.marginly.com/swap> for swapping assets

### **Q: What chains/networks does Marginly support?**

A: At the moment Marginly supports Arbitrum, Polygon and zkSync. More networks might be supported in the future.

### **Q: What oracle does Marginly use?**

A: Marginly uses Uniswap V3 TWAP oracle for V1 of the protocol. Refer [here](https://marginly.medium.com/marginly-protocol-design-100-decentralized-and-trustless-739716e61a3f) for additional information.

### **Q: How is the liquidation price calculated? Why is my liquidation price so close to my entry point?**

A: The way leverage trading works is that the liquidation price moves closer to the entry price as leverage increases. This makes high leverage plays both lucrative and risky as even a small move against the trader in the price of the underlying may result in liquidation. Refer [here](https://docs.marginly.com/protocol-mechanics/risk-management/liquidations-and-deleveraging) for a detailed breakdown and examples.

### Q: Has the code been audited?

A: An agreement has been reached with Quantstamp regarding an audit. More info [here](https://marginly.medium.com/marginly-set-to-undergo-an-audit-with-quantstamp-ahead-of-protocol-launch-bf09025d06d).

### Q: Is there a Marginly token?&#x20;

A: There is no native Marginly token yet however a tokenomics release is planned after Marginly launches on mainnet.

### Q: Is there a public sale?&#x20;

A: There is no public sale. The project is self-funded.

### Q: Is there a way to earn Marginly tokens or other rewards in public testnet?

A: There are testnet trading contests that reward winners with future Marginly native token allocations. More information [here](https://marginly.medium.com/marginly-beta-trading-contest-announcement-f41f297c0297).

### Q: I received a private message promising free tokens/NFTs/future airdrop allocation. Is it real?

A: No, it's a scam. We do not message users directly offering free tokens or NFTs of any kind. We also do not offer users any private investment opportunities.

### Q: Who do I contact for partnerships, integrations and other proposals?

A: Feel free to reach out to Discord moderators and you’ll be assisted with your query.


# Providing Liquidity

This page describes how users put liquidity into Marginly pools.

{% hint style="info" %}
From here on, we consider USDC/ETH Marginly pool for simplicity which works in conjunction with the corresponding Uniswap v3 USDC/ETH pool.
{% endhint %}

### Now

Liquidity providers deposit **quote asset** (USDC) or **base asset** (ETH) liquidity into the pool for other users to borrow. Users then earn variable interest rates when traders borrow USDC to go long or borrow ETH to go short. USDC providers earn rewards in USDC, while ETH providers earn rewards in ETH. \
\
ETH holders (USDC borrowers) pay interest fees in USDC to USDC holders (ETH borrowers), who  pay interest fees in ETH in return. The system is symmetric: longs pay shorts, and shorts pay longs. All debt accruals and reward accruals are pairwise. In *Marginly,* we calculate and handle these accruals as coefficients on user collateral and debt recorded in the system.&#x20;

### In Future

In later versions of the *Marginly protocol,* we could also facilitate investment in different currencies: e.g., invest WBTC in an ETH/USDC long position.

* the initial conversion of WBTC to ETH (initial margin) for a long position
* the initial conversion of WBTC to USDC (initial margin) for a short position

We'd need to monitor the input currency (WBTC) exposure to the collateral currency (ETH or USDC) ticker.

Profit is given by the margin value (ETH margin) in WBTC and the trading P\&L on the ETH/USDC exposure.


# Trading

this page describes leveraged trading mechanics inside marginly protocol.

### Margin and Leverage

* Users who want to leverage long ETH deposit ETH margin.&#x20;
* Users who want to sell ETH short deposit USDC margin.&#x20;

{% hint style="info" %}
*Marginly* works with margin, so the margin for longs is always the base asset (e.g., ETH), while the margin for shorts is always the quote asset (e.g., USDC).&#x20;
{% endhint %}

Long buyers have ETH recorded as collateral, and USDC recorded as debt. Short sellers have USDC recorded as collateral, and ETH recorded as debt.&#x20;

Let’s consider a simple example here:

* the market price is 1000 USDC for 1 ETH&#x20;
* **user1** deposits 1 ETH into the pool
* **user2** (the short seller) deposits 100 USDC margin and sells short 1 ETH on Uniswap v3 depositing back the 1000 USDC trade proceeds (all atomically in one transaction thanks to *Marginly* smart contract design)

The pool configuration in this scenario is shown below: (the "+" sign means collateral, while the "-" sign means debt)

<table><thead><tr><th width="91">User</th><th width="97" align="center">ETH+</th><th width="95" align="center">ETH-</th><th width="95" align="center">USDC+</th><th width="90" align="center">USDC-</th><th width="91" align="center">NetPos</th><th width="112" align="center">Leverage</th></tr></thead><tbody><tr><td>1</td><td align="center"><mark style="color:green;"><strong>1</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1000</td><td align="center">1</td></tr><tr><td>2</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>1</strong></mark></td><td align="center"><mark style="color:green;"><strong>1100</strong></mark></td><td align="center">0</td><td align="center">100</td><td align="center">11</td></tr></tbody></table>

Current pool balances are:

ETH balance: 0\
USDC balance: 1100

Now **user 3** comes in and longs ETH: he puts in 0,2 ETH margin and longs 1 ETH borrowing 1000 USDC from the pool. The pool positions configuration now looks the following way:

<table><thead><tr><th width="91">User</th><th width="97" align="center">ETH+</th><th width="95" align="center">ETH-</th><th width="95" align="center">USDC+</th><th width="90" align="center">USDC-</th><th width="91" align="center">NetPos</th><th width="107" align="center">Leverage</th></tr></thead><tbody><tr><td>1</td><td align="center"><mark style="color:green;"><strong>1</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1000</td><td align="center">1</td></tr><tr><td>2</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>1</strong></mark></td><td align="center"><mark style="color:green;"><strong>1100</strong></mark></td><td align="center">0</td><td align="center">100</td><td align="center">11</td></tr><tr><td>3</td><td align="center"><mark style="color:green;"><strong>1.2</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>1000</strong></mark></td><td align="center">200</td><td align="center">6</td></tr></tbody></table>

Current pool balances are:

ETH balance: 1.2\
USDC balance: 100

As you may notice, pool balances change between ETH and USDC, reflecting users’ trades. You also may see that the pool can leverage against itself: in the example above, there is only 100 USDC left in the pool, while the total debt in the system is 1000 USDC: pool balances reflect the net positions, while users may be levered both long and short.&#x20;

*Marginly* does not require traders to fund 100% of their position. There is a maximum leverage of 20x for traders, meaning that for every $1 of margin deposited, traders can can trade with up to $19 additional capital.&#x20;

If a trader's position exceeds the maximum leverage, it will become eligible for liquidation (or deleveraging with no liquidations in future protocol versions).&#x20;

### Liquidations

When a user's position leverage exceeds maximum leverage, the position becomes eligible for liquidation. This section provides a brief overview of how liquidation process works in Marginly. Unlike, let’s say Compound v3, which only allows for position absorption, Marginly has a multiple-step process:

1. Marginly protocol liquidates user positions automatically on any user action as the system keeps on-chain lists of “bad” (in the order of descending leverage) positions both long and short. This proved quite effective on the testnet. Basically, if trades/user actions happen every block, the system checks for liquidations and performs them when needed every block. Currently the protocol liquidates only the top worst position both long and short. This is done for gas optimization reasons, as liquidating multiple positions could harm the user who invoked the liquidation. Effectively the liquidation penalty on every position in the system is 1 / max leverage = 1 / 20 = 5%, so the entire *Marginly* pool earns penalties on liquidations.
2. Additionally, Marginly offers a keeper service which can absorb underwater positions (underwater position is a position whose leverage is greater than the critical). Ultimately the keeper's account will be the position holder with all of its assets and liabilities. This position is subject to all the liquidation checks just like any other. If the keeper doesn’t have sufficient funds to absorb the losses, he won’t be able to do the liquidation. To mitigate this Marginly sets aside a fraction of swap fees as an insurance cushion to be used by the keeper. Marginly provides keeper service as an open source software and encourages users to run multiple instances of the keeper to compete for liquidations and liquidation penalties. However, Ideally we would want liquidations to happen automatically as in point number one above. If keepers earn penalties to themselves, the pool LPs will not earn this reward.
3. Finally, Marginly does have no-liquidation mechanics we call [***deleveraging***](https://docs.marginly.com/protocol-mechanics/risk-management/liquidations-and-deleveraging#deleveraging). Marginly resorts to deleveraging when the protocol needs to liquidate the borrower but there is not enough collateral in the pool to sell.

For future versions (e.g. Marginly v2) we seek to expand the deleveraging idea and employ it as a default option: e.g. instead of liquidating a user on an external market have his position go to the opposing side reducing the overall pool leverage this way. Short sellers will absorb liquidating long positions and vice versa. To achieve this and design a beautiful self-adjusting system we need to perform R\&D and do some careful modeling to account for various pool imbalance scenarios.


# Marginly MAX leverage specifics

In Marginly, we specifically invoke a margin call before every user action: If your position happens to be the riskiest in the system, it will liquidate automatically on ANY action of ANY user.&#x20;

Unfortunately, this means that when you close your position, and it's the riskiest one, instead of closure, you will get liquidated. Why not add leverage checks, you ask? This additional “if” logic increases contract size and requires complete refactoring by splitting the smart contract into many parts.&#x20;

We will eventually have to do that as we envision some changes/improvements for Marginly’s protocol, including this particular one related to the riskiest position management.&#x20;

\
Additionally, I would like to talk about the[ TWAP oracle](https://docs.marginly.com/protocol-mechanics/risk-management#twap-oracle) we use to value user positions. Take a look at the following picture:

<figure><img src="https://lh7-us.googleusercontent.com/40AWwGLhRUd-Pjp524vNlU9xoWS52zWRkv06n2T2xrZg52dQQ7i6ALh5jB0BJEBw_8l0VGNyL3Ivy_lRvfwRpXpItWeUJzihOjgGj4NKhh66ox4TNblUskLojZRlfZFUdMVkQFHWpkeMdcK2OAhkyl0" alt=""><figcaption></figcaption></figure>

It is an ETH/USDC 1-minute chart. The red line is the average over 30 minutes - our 30-minute TWAP price. Now imagine that you went long 20x in the shaded area. Even though the price temporarily goes up, the TWAP price, at which Marginly values your position, continues to decline as the moving average is lagging current data. If you use max leverage, you will get liquidated. This behavior could be somewhat misleading when looking solely at the charts.\
\
The same happens to shorts, by the way, Imagine you shorted at 1880 with 20x, but the system will value your position at \~1882.5 (the TWAP price). This is an instant liquidation.&#x20;

One of the things we’re currently working on within our UX is a warning on position openings, so people understand the implications when they use max leverage.


# Overview

Marginly architecture consists of the following contracts:

* marginly pool implementation
* factory
* pool
* router

Marginly pool implementation (`contracts/contract/MarginlyPool.sol`) is a pool bytecode. This deployed contract is basically an uninitialized version of marginly pool, which is cloned during creation of a new pool. The cloning approach is chosen in order for our factory  contract size to fit with ethereum evm limit of 24 KiB.

Factory (`contracts/contracts/MarginlyFactory.sol`) creates new Marginly pools via 'createPool' method. This method clones marginly pool implementation and calls 'initialize' method, which sets pool variables and parameters that can be found [here](/protocol-architecture/pools/pool-variables) and [here](/protocol-architecture/pools/pool-parameters).&#x20;

\
Factory stores the following info common for all our pools:

* router address
* fee holder address
* tech position owner address

Though 'createPool' method is 'ownerOnly' right now, we are planning to make it permissionless in the future versions.

Router (`router/contracts/MarginlyRouter.sol`) is a contract that makes swaps on different DEXs of user's choice. It has two main methods:

* `swapExactInput` -- makes swap with exact amount of swapped tokens
* `swapExactOutput` -- makes swap with exact amount of tokens, received after swap

The user's choice is defined by a `swapCalldata` argument, which is decoded to an array of DEX indexes and their swap ratio. Default value for this argument is 0. It represents swap on UniswapV3 and is used during liquidation. Such swaps can be performed by any wallet or contract not limited to Marginly pools.

DEXs Swap implementations are located in `router/contract/abstract/dex` directory.


# Pools


# Pool variables

These are the variables and aggregates that the Marginly protocol keeps track of inside its smart-contracts

<table><thead><tr><th width="225.5">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>Base Collateral</td><td>Sum of all ETH collateral in the system.</td></tr><tr><td>Quote Collateral</td><td>Sum of all USDC collateral in the system.</td></tr><tr><td>Base Debt</td><td>Discounted total debt in ETH. </td></tr><tr><td>Quote Debt</td><td>Discounted total debt in USDC. </td></tr><tr><td>Long leverage</td><td>This is leverage of all long positions in the protocol. Longs borrow USDC against ETH to buy more ETH.</td></tr><tr><td>Short leverage</td><td>This is leverage of all short positions in the protocol. Shorts borrow ETH against USDC to sell it for more USDC</td></tr><tr><td>Base Debt Coef</td><td><p>Total accrued interest from the inception. Recalculated every time any user performs any action. Tracks debt accrual in the system: </p><pre><code>ARL(t) = ARL(t-1) * (1 + Long leverage * ir)^dt
ir = Coef * var(ETH)
</code></pre></td></tr><tr><td>Quote Debt Coeff</td><td><p>Total accrued interest from the inception. Recalculated every time any user performs any action. Tracks debt accrual in the system: </p><pre><code>ARS(t) = ARS(t-1) * (1 + Short leverage * ir)^dt
ir = Coef * var(ETH)
</code></pre></td></tr><tr><td>Base Collateral Coef</td><td>This is the collateral coefficient for ETH liquidity.<br><br>It increases every time the interest rate from ETH shorts is accrued. It also increases every time shorts are liquidated with the surplus. It may decrease when liquidated position has negative net difference. </td></tr><tr><td>Quote Collateral Coef</td><td>This is the mToken price for the USDC liquidity.<br><br>It increases every time the interest rate from USDC shorts is accrued. It also increases every time ETH longs are liquidated with the surplus.  It may decrease when liquidated position has negative net difference. </td></tr><tr><td>Base Deleverage Coef</td><td>Coefficient used in base collateral calculations after deleverage</td></tr><tr><td>Quote Deleverage Coef</td><td>Coefficient used in quote collateral calculations after deleverage</td></tr></tbody></table>


# Pool parameters

These are parameters that control protocol risk and earnings and may be changed via Marginly governance.

<table><thead><tr><th width="214.5">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>max leverage</td><td>maximum allowable leverage. by default = 20</td></tr><tr><td>interest rate</td><td>The proportion of a loan that is charged as interest to the borrower. <br><br><code>interest rate = Coef * var(ETH)</code><br><br><strong>var(ETH)</strong> - historical long-term average ETH volatility, which we initially set to be 6% or 0.06 per day. Subject to periodical reassessment by Marginly governance. <br><br><strong>Coef</strong> - scaling coefficient which governs the steepness of the interest rate curve, the default value is 15</td></tr><tr><td>swap fee</td><td>0.1% by default. When users take leverage, they pay 0.1% on the notional borrow amount.</td></tr><tr><td>fee</td><td>2% by default. Extra annual interest rate added to debt with every reinit.</td></tr><tr><td>position min amount</td><td>Minimum amount (in base token) to open a Short or Long position. By default = 0.001 ETH</td></tr><tr><td>price seconds ago</td><td>Parameter for Uniswap TWAP Oracle. Number of seconds in the past from which to calculate the time-weighted-average-price. By default = 900 seconds. </td></tr><tr><td>position slippage</td><td>Maximum allowable slippage when managing a position. By default = 2% of the current (last) AMM price.</td></tr><tr><td>margin call slippage</td><td>Maximum allowable slippage when liquidating a position.<br>By default = 5% of the current (last) AMM price.</td></tr><tr><td>base asset limit</td><td>Maximum allowable balance of the base asset in the pool. </td></tr><tr><td>quote asset limit</td><td>Maximum allowable balance of the quote asset in the pool. </td></tr></tbody></table>


# User positions

User positions inside Marginly have following parameters:

<table><thead><tr><th width="165.5">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>Base amount</td><td><p>User’s ETH collateral: <br>Total user ETH = Base amount * Base Collateral Coef</p><p></p><p>or <br></p><p>User’s discounted ETH debt: <br>Total base debt = Base amount * Accrued rate</p></td></tr><tr><td>Quote amount</td><td><p>User’s USDC collateral:<br>Total user USDC = Quote amount * Quote Collateral Coef</p><p></p><p>or </p><p></p><p>User’s discounted USDC debt: <br>Total quote debt = Quote amount * Accrued rate</p></td></tr><tr><td>Type</td><td><p>Type of position:</p><ul><li>Uninitialized (by default)</li><li>Lend (quote amount and base amount as collateral)</li><li>Short (quote amount - as collateral, base amount - as debt)</li><li>Long (quote amount - as debt, base amount - as collateral)</li></ul></td></tr><tr><td>Heap position</td><td><p>Index of position in leverage heap (short or long).</p><p>By default, 0 (meaning the id doesn’t exist in any leverage heaps). Otherwise, the index of the heap equals heap position minus 1.</p></td></tr></tbody></table>


# User actions

Description of all user-facing and internal auxiliary functions available inside the Marginly protocol

<table><thead><tr><th width="137.66666666666669">Function</th><th width="137">Parameter</th><th>Description</th></tr></thead><tbody><tr><td>deposit base</td><td><p>account_id</p><p>qty<br>longQty</p></td><td><p>deposit ETH: </p><p></p><ul><li>accrue system-wide interest, margincall position if needed</li><li>update user position: reduce debt or increase collateral,</li><li>update contract parameters</li><li>if longQty is not zero, then makes <code>long</code> call</li></ul></td></tr><tr><td>deposit quote</td><td><p>account_id</p><p>qty<br>shortQty</p></td><td><p>deposit USDC: </p><p></p><ul><li>accrue system-wide interest, margincall position if needed</li><li>update user position: reduce debt or increase collateral</li><li>update contract parameters</li><li>if shortQty is not zero, then makes <code>short</code> call</li></ul></td></tr><tr><td>withdraw base</td><td><p>account_id</p><p>qty</p></td><td><p>withdraw ETH: </p><p></p><ul><li>accrue system-wide interest, margincall position if needed</li><li><p>calculate new user L, if L &#x3C;=max leverage:</p><ul><li>update user position: reduce ETH collateral</li><li>update contract parameters</li></ul></li></ul></td></tr><tr><td>withdraw quote</td><td><p>account_id</p><p>qty</p></td><td><p>withdraw USDC: </p><p></p><ul><li>accrue system-wide interest, margincall position if needed</li><li><p>calculate new user L, if L &#x3C;=max leverage:</p><ul><li>update user position: reduce USDC collateral</li><li>update contract parameters</li></ul></li></ul></td></tr><tr><td>Long</td><td><p>account_id</p><p>qty (L)</p></td><td><p>This is an atomic sequence of actions: if one of the steps fails, all of the transaction is reverted:</p><ul><li>reinit user (accrue interest from USDC debt), margincall user if needed.</li><li>check that user account's L &#x3C; max leverage, if false - margincall user, all next steps are skipped</li><li>fetch price P_trade from an external AMM / router to buy qty ETH</li><li>take from the pool P_trade * qty USDC, revert if not enough USDC in the pool</li><li>sell USDC, buy ETH in uniswap</li><li>put qty ETH into the pool</li><li>update user collateral: base_collater += qty</li><li>update user debt: quote_debt += qty * P_trade * (1 + swap fee) / accrued rate</li><li>check that user account's L &#x3C; max_leverage, if false - revert</li><li>update system aggregates</li></ul></td></tr><tr><td>Short</td><td><p>account_id</p><p>qty (L)</p></td><td><p>This is an atomic sequence of actions: if one of the steps fails, all of the transaction is reverted: </p><ul><li>reinit user (accrue interest from ETH debt), margincall user if needed.</li><li>check that user account's L &#x3C; max_leverage, if false - margincall user, all next steps are skipped</li><li>fetch price P_trade from an external AMM / router to sell qty ETH</li><li>take from the pool qty ETH, revert if not enough ETH in the pool</li><li>sell ETH, buy USDC in uniswap</li><li>put qty * P_trade USDC  into the pool</li><li>update user collateral: quote collateral += qty * P_trade * (1 - swap fee) / accrued rate</li><li>update user debt: base_debt += qty</li><li>check that user account's L &#x3C; max leverage, if false - revert</li><li>update system aggregates </li></ul></td></tr><tr><td>close position</td><td>account_id<br></td><td><p>This is an atomic sequence of actions: if one of the steps fails, all of the transaction is reverted: </p><ul><li>reinit user (accrue interest from ETH debt), margincall user if needed.</li><li>swap part of collateral enough to cover position’s debt</li><li>reduce position debts  to zero</li><li>update system leverage</li><li>remove position from leverage heap</li></ul></td></tr><tr><td>reinit</td><td><br></td><td><p>Accrue interest rates, syncs balances and liquidate riskiest position if needed: </p><p></p><p>Marginly tracks leverages of user long and short positions sorted from highest to lowest (using heaps), each time interest rates are accrued, system checks if the leverage of the most risky position (heap root) is above max leverage it gets liquidated automatically. All of the collateral is sold and the liquidated user effectively pays a penalty of &#x3C;=5%. All the penalty is distributed to liquidity providers<br></p><p>This function is free for any user to call as it's in the best interest of the pool participants to call it to collect liquidation fees. <br></p><p>This function is called automatically inside any user facing function. </p></td></tr><tr><td>Receive position</td><td>account_id<br></td><td><p>Provide liquidity and absorb liquidated position, effectively realising its net position value. <br></p><p>This function is useful when there is no collateral to sell in the system, but liquidations still need to happen. </p></td></tr><tr><td>Emergency withdraw</td><td><br></td><td><p>Available when the system parameter mode is EmergencyShort or EmergencyLong. Theses scenarios are only possible in the system when there is not enough ETH collateral to cover USDC debt and vice versa: not enough USDC collateral to cover ETH debt.<br></p><p><strong>Emergency Short mode:</strong><br></p><p>There is no liquidity in the system and the insurance pool to liquidate bad short positions. In that mode all positions of type Lend and Long could withdraw their collateral minus amounts needed to reduce short positions debts.<br></p><p><strong>Emergency Long mode:</strong><br></p><p>There is no liquidity in the system and the insurance pool to liquidate bad long positions. In that mode all positions of type Lend and Short could withdraw their collateral minus amounts needed to reduce short positions debts.</p></td></tr></tbody></table>


# Pool Factory API

This a factory smart-contract for deploying Marginly pools.

### MarginlyFactory

Deploys Marginly and manages ownership and control over pool

#### marginlyPoolImplementation

```solidity
address marginlyPoolImplementation
```

#### uniswapFactory

```solidity
address uniswapFactory
```

Address of uniswap factory

#### swapRouter

```solidity
address swapRouter
```

Address of uniswap swap router

#### feeHolder

```solidity
address feeHolder
```

Swap fee holder

#### WETH9

```solidity
address WETH9
```

Address of wrapped ETH

#### techPositionOwner

```solidity
address techPositionOwner
```

Technical position address

#### getPool

```solidity
mapping(address => mapping(address => mapping(uint24 => address))) getPool
```

Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist

*quoteToken and baseToken may be passed in either token0/token1 or token1/token0 order*

#### constructor

```solidity
constructor(address _marginlyPoolImplementation, address _uniswapFactory, address _swapRouter, address _feeHolder, address _WETH9, address _techPositionOwner) public
```

#### createPool

```solidity
function createPool(address quoteToken, address baseToken, uint24 uniswapFee, struct MarginlyParams params) external returns (address pool)
```

Creates a pool for the two given tokens and fee

*tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments are invalid.*

**Parameters**

| Name       | Type                  | Description                                     |
| ---------- | --------------------- | ----------------------------------------------- |
| quoteToken | address               | One of the two tokens in the desired pool       |
| baseToken  | address               | The other of the two tokens in the desired pool |
| uniswapFee | uint24                | Fee for uniswap pool                            |
| params     | struct MarginlyParams | pool parameters                                 |

**Return Values**

| Name | Type    | Description                           |
| ---- | ------- | ------------------------------------- |
| pool | address | The address of the newly created pool |

#### changeSwapRouter

```solidity
function changeSwapRouter(address newSwapRouter) external
```

Changes swap router address used by Marginly pools

**Parameters**

| Name          | Type    | Description                |
| ------------- | ------- | -------------------------- |
| newSwapRouter | address | address of new swap router |

#### renounceOwnership

```solidity
function renounceOwnership() public
```

Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner.

NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.


# Pool API

Pool API description

### MarginlyPool

#### factory

```solidity
address factory
```

Returns address of Marginly factory

#### quoteToken

```solidity
address quoteToken
```

Returns the address of quote token from pool

#### baseToken

```solidity
address baseToken
```

Returns the address of base token from pool

#### uniswapPool

```solidity
address uniswapPool
```

Returns the address of associated uniswap pool

#### mode

```solidity
enum Mode mode
```

#### params

```solidity
struct MarginlyParams params
```

#### discountedQuoteCollateral

```solidity
uint256 discountedQuoteCollateral
```

*Sum of all quote token in collateral*

#### discountedQuoteDebt

```solidity
uint256 discountedQuoteDebt
```

*Sum of all quote token in debt*

#### discountedBaseCollateral

```solidity
uint256 discountedBaseCollateral
```

*Sum of all base token collateral*

#### discountedBaseDebt

```solidity
uint256 discountedBaseDebt
```

*Sum of all base token in debt*

#### lastReinitTimestampSeconds

```solidity
uint256 lastReinitTimestampSeconds
```

*Timestamp of last reinit execution*

#### baseCollateralCoeff

```solidity
struct FP96.FixedPoint baseCollateralCoeff
```

*Aggregate for base collateral time change calculations*

#### baseDelevCoeff

```solidity
struct FP96.FixedPoint baseDelevCoeff
```

*Aggregate for deleveraged base collateral*

#### baseDebtCoeff

```solidity
struct FP96.FixedPoint baseDebtCoeff
```

*Aggregate for base debt time change calculations*

#### quoteCollateralCoeff

```solidity
struct FP96.FixedPoint quoteCollateralCoeff
```

*Aggregate for quote collateral time change calculations*

#### quoteDelevCoeff

```solidity
struct FP96.FixedPoint quoteDelevCoeff
```

*Aggregate for deleveraged quote collateral*

#### quoteDebtCoeff

```solidity
struct FP96.FixedPoint quoteDebtCoeff
```

*Accrued interest rate and fee for quote debt*

#### initialPrice

```solidity
struct FP96.FixedPoint initialPrice
```

*Initial price. Used to sort key and shutdown calculations. Value gets reset for the latter one*

#### emergencyWithdrawCoeff

```solidity
struct FP96.FixedPoint emergencyWithdrawCoeff
```

*Ratio of best side collaterals before and after margin call of opposite side in shutdown mode*

#### Leverage

```solidity
struct Leverage {
  uint128 shortX96;
  uint128 longX96;
}
```

#### systemLeverage

```solidity
struct MarginlyPool.Leverage systemLeverage
```

#### positions

```solidity
mapping(address => struct Position) positions
```

users positions

#### constructor

```solidity
constructor() public
```

#### initializeMarginlyPool

```solidity
function _initializeMarginlyPool(address _quoteToken, address _baseToken, bool _quoteTokenIsToken0, address _uniswapPool, struct MarginlyParams _params) internal
```

*Initializes Marginly pool*

#### initialize

```solidity
function initialize(address _quoteToken, address _baseToken, bool _quoteTokenIsToken0, address _uniswapPool, struct MarginlyParams _params) external virtual
```

*Initializes the pool*

#### receive

```solidity
receive() external payable
```

#### lock

```solidity
modifier lock()
```

*Protects against reentrancy*

#### onlyFactoryOwner

```solidity
modifier onlyFactoryOwner()
```

#### setParameters

```solidity
function setParameters(struct MarginlyParams _params) external
```

Sets the pool parameters. May only be called by the pool owner

#### getBasePrice

```solidity
function getBasePrice() public view returns (struct FP96.FixedPoint)
```

Get oracle price baseToken / quoteToken

#### getLiquidationPrice

```solidity
function getLiquidationPrice() public view returns (struct FP96.FixedPoint)
```

Get TWAP price used in mc slippage calculations

#### shutDown

```solidity
function shutDown(uint256 swapCalldata) external
```

Switch to emergency mode when collateral of any side not enough to cover debt

**Parameters**

| Name         | Type    | Description                                                                    |
| ------------ | ------- | ------------------------------------------------------------------------------ |
| swapCalldata | uint256 | router calldata for splitting swap to reduce potential sandwich attacks impact |

#### sweepETH

```solidity
function sweepETH() external
```

Sweep ETH balance of contract

#### getHeapPosition

```solidity
function getHeapPosition(uint32 index, bool _short) external view returns (bool success, struct MaxBinaryHeapLib.Node)
```

*Used by keeper service*

#### execute

```solidity
function execute(enum CallType call, uint256 amount1, uint256 amount2, uint256 limitPriceX96, bool flag, address receivePositionAddress, uint256 swapCalldata) external payable
```

**Parameters**

| Name                   | Type          | Description                                                               |
| ---------------------- | ------------- | ------------------------------------------------------------------------- |
| call                   | enum CallType |                                                                           |
| amount1                | uint256       |                                                                           |
| amount2                | uint256       |                                                                           |
| limitPriceX96          | uint256       |                                                                           |
| flag                   | bool          | unwrapETH in case of withdraw calls or syncBalance in case of reinit call |
| receivePositionAddress | address       |                                                                           |
| swapCalldata           | uint256       |                                                                           |

#### getTimestamp

```solidity
function getTimestamp() internal view virtual returns (uint256)
```


# TWAP oracle

Uniswap TWAP is calculated using the time-weighted mean price of an asset over some interval of time. TWAP, like any average, is both a smoothed and lagging indicator of the trade price: a TWAP over a shorter time interval is a less smooth, more up-to-date function, while a TWAP over a longer time interval is a smoother function and less up-to-date.

TWAP perfectly fits Marginly protocol for several reasons. First, TWAP is [resistant to price manipulation attacks](https://blog.uniswap.org/uniswap-v3-oracles). It cannot be manipulated within a transaction or block (for example, with flash loans or flash bots). It is also expensive to manipulate using large market orders because the manipulated price must be maintained for some period of time relative to the TWAP time interval. During this time, other market participants can take advantage of the manipulated price with arbitrage, which will cause it to revert back to the broader market price.

Second, the smooth nature of TWAP helps to remove the impact of price shocks on borrowers. In the event of a large trade, the current price on Uniswap can be moved significantly. Usually, arbitrageurs will quickly converge this to the fair market value, so the magnitude of the TWAP change will only be a fraction of the temporary price movement. This smoothed behaviour prevents some unnecessary liquidations and positions that may quickly become insolvent.


# Loan pricing

This page describes how Marginly prices loans.

A collateralized loan model for the pool we consider has the following specifications:

* The loan has an infinite lifetime (no maturity)
* At time 0, the user borrows amount Q (Q > 0) USD from the pool using 1 unit of an asset (e.g., ETH) as collateral.
* The continuously compounding loan interest rate is r. The client may regain the asset by repaying the Q\*exp(rt) amount to the pool at any time t ≥ 0.
* User may default (not obliged to return the loan)

The task may be regarded as a user buying an American option at the price of (asset price - Q) with the following payoff function:

$$
Y\_t = max (0; P^{ETH}\_t - Qe^{rt}); t \geq0
$$

This time-dependent strike price option is evaluated, for example, in [Xia and Zhou](https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1467-9965.2006.00305.x). Since in our setup, we know the exact position user wants to take (the leverage), and thus the effective option value, we can rearrange final equations to solve for the interest rate r: *Marginly* calculates interest rate as proportional to the asset volatility and the leverage of the pool’s position:

$$
r {\sim L\frac{\sigma^{2}}{2}}
$$

*Marginly* keeps track of the total long leverage and the total short leverage in the pool and scales interest rates proportionally for each side. This way, every time any user performs any action in the system, it recalculates how much interest has accrued since the last time and updates collateral and debt coefficients accordingly.


# Errors

A list containing errors that exist in Marginly. Descriptions provide context, user actions mention what sort of activity might trigger said error while display message contains the information that a user sees when encountering the error.&#x20;

<table data-full-width="true"><thead><tr><th width="256">Error</th><th width="210">Description</th><th width="121">User action</th><th width="293">Display message</th></tr></thead><tbody><tr><td>AccessDenied();</td><td>Pool Factory error if someone invokes owner methods</td><td></td><td></td></tr><tr><td>ExceedsLimit();</td><td>As a result of user action token limits will be exceeded</td><td>Deposit Long Short</td><td>Pool asset limit reached. Try again later. Learn more about limits here (TBD).</td></tr><tr><td>EmergencyMode();</td><td>Only withdrawals are allowed. Action is shut down</td><td>Any action except for emergency withdraw</td><td>The Pool is in shutdown mode. Only emergency withdrawals are allowed. Learn more about the shutdown <a href="https://docs.marginly.com/protocol-mechanics/risk-management#shutdown-mode">here</a></td></tr><tr><td>Forbidden();</td><td>Pool Factory error. Generic error e.g. when setting parameters</td><td></td><td></td></tr><tr><td>LongEmergency();</td><td>Withdraw from short position in emergency mode</td><td>Any action except for emergency withdraw</td><td>The Pool is in shutdown mode. Only emergency withdrawals are allowed. Learn more about the shutdown <a href="https://docs.marginly.com/protocol-mechanics/risk-management#shutdown-mode">here</a></td></tr><tr><td>Locked();</td><td>Protection from reentrancy smart contract attack. Prevents smart contract from invoking itself</td><td></td><td></td></tr><tr><td>LessThanMinimalAmount();</td><td>Amount is less than minimum allowed position size</td><td>Deposit Long Short</td><td>Asset quantity has to be greater than &#x3C;<em>%limit%</em>> <em>&#x3C;%token%></em></td></tr><tr><td>BadLeverage();</td><td>Leverage exceeds maximum allowed</td><td>Long Short Withdraw</td><td>Max leverage of <em>&#x3C;%leverage%></em> exceeded. Please adjust trade parameters and try again.</td></tr><tr><td>NotLiquidatable();</td><td>Keeper fails to receiveposition() with normal leverage</td><td></td><td></td></tr><tr><td>NotOwner();</td><td>pool error: non-owner invokes owner methods</td><td></td><td></td></tr><tr><td>NotWETH9();</td><td>When the asset is not from WETH9 contract. Can appear during wrap/unwrap</td><td></td><td></td></tr><tr><td>PoolAlreadyCreated();</td><td>This pool already exists</td><td></td><td></td></tr><tr><td>PositionInitialized();</td><td>Appears only in the receiveposition()</td><td></td><td></td></tr><tr><td>ShortEmergency();</td><td>Withdraw from long position in emergency mode</td><td>Any action except for emergency withdraw</td><td>The Pool is in shutdown mode. Only emergency withdrawals are allowed. Learn more about the shutdown <a href="https://docs.marginly.com/protocol-mechanics/risk-management#shutdown-mode">here</a></td></tr><tr><td>SlippageLimit();</td><td>exchange exceeded the slippage limit. can trigger other router errors: - InsufficientAmount: swapexactinput with bad price - TooMuchRequested: swapexactoutput with bad price</td><td>Long Short Close Liquidate</td><td>Slippage limit of &#x3C;%slippage%> exceeded. Please adjust the trade parameters and try again.</td></tr><tr><td>NotEmergency();</td><td>emergency withdrawal when not in shutdown.</td><td></td><td></td></tr><tr><td>UninitializedPosition();</td><td>when withdrawing from an empty position</td><td></td><td></td></tr><tr><td>UniswapPoolNotFound();</td><td>pool factory error: there is no corresponding uniswap pool</td><td></td><td></td></tr><tr><td>UnknownCall();</td><td>decoding-related error</td><td></td><td></td></tr><tr><td>WrongIndex();</td><td>heap access error</td><td></td><td></td></tr><tr><td>WrongPositionType();</td><td>long/short/withdraw/close using unsupported collateral</td><td>Long Short Withdraw Close</td><td>Can’t <strong>long</strong> &#x3C;base_token> with &#x3C;quote_token as margin> Can’t <strong>short</strong> &#x3C;base_token> with &#x3C;base_token as margin> Can’t <strong>withdraw</strong> debt.</td></tr><tr><td>WrongValue();</td><td>pool factory: wrong parameter value when creating a pool</td><td></td><td></td></tr><tr><td>ZeroAmount();</td><td><p>when depositing/withdrawing 0 amount</p><p>router: when exchange amount is 0</p></td><td></td><td>Can’t deposit/withdraw/exchange 0 tokens.</td></tr><tr><td>STF</td><td>safe transfer if no approval or insufficient balance. router: not enough money in marginly pool</td><td></td><td>Insufficient pool balance to perform the transaction.</td></tr><tr><td>ST</td><td>pool doesn’t have a balance. router: dex is sending wrong amounts</td><td></td><td>Insufficient pool balance to perform the transaction.</td></tr><tr><td>STE</td><td>same as ST but for ETH.</td><td></td><td>Insufficient pool balance to perform the transaction.</td></tr><tr><td>UnknownDex</td><td>router can’t find dex</td><td></td><td></td></tr><tr><td>Forbidden</td><td>generic error when setting router parameters.</td><td></td><td></td></tr><tr><td>UnknownPool</td><td>router error: no Pool on target DEX with specified tokens</td><td></td><td></td></tr><tr><td>WrongAmountOut</td><td>router error: dex amount doesn't match expected amount</td><td></td><td></td></tr></tbody></table>


# Marginly SDK

Allows to biuld  contract calls and use  math calculations for applications on top of Marginly.

#### MarginlyPoolExecute

Contains an abstract class with methods to generate calls input for Marginly contracts.

```
import { BigNumber, parseUnits } from 'ethers';
import { convertPriceHumanToX96, MarginlyPoolExecute } from '@eq-lab/marginly-sdk';

const wethDecimals = BigNumber.from(18);
const usdcDecimals = BigNumber.from(6);

const depositBaseAmount = parseUnits('1', wethDecimals);
const longAmount = parseUnits('10', wethDecimals);
const limitPriceX96 = convertPriceHumanToX96(
    BigNumber.from(2000), 
    wethDecimals, 
    usdcDecimals
);

const { method, args, value } = MarginlyPoolExecute.depositBaseAndLong(
    depositBaseAmount, 
    longAmount, 
    limitPriceX96
);
```

#### MarginlyPoolPosition

This class is used to construct a Marginly position representation with real values from pools inner discounted ones. Moreover it contains methods for position characteristics calculations such as:

* leverage
* liquidation price
* available withdraw amounts

#### MarginlyPoolMath

Contains low level math, used in contract calculations and other modules of sdk including:

* FP96 math
* discounted-to-real values conversions
* X96 price conversions
* low level position/pool parameters calculations (e.g. leverage, liquidation price)

### Tests

Run tests

```
yarn test
```


# Router architecture

### MarginlyRouter

#### constructor

```solidity
constructor(struct AdapterInput[] _adapters) public
```

#### swapExactInput

```solidity
function swapExactInput(uint256 swapCalldata, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| swapCalldata | uint256 | calldata for multiple swaps            |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |

#### swapExactOutput

```solidity
function swapExactOutput(uint256 swapCalldata, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 amountOut) external returns (uint256 amountIn)
```

swap with exact output

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| swapCalldata | uint256 | calldata for multiple swaps            |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| maxAmountIn  | uint256 | maximal amount of tokenIn to swap      |
| amountOut    | uint256 | exact amount of tokenOut to receive    |

**RouterActions**

#### addDexAdapters

```solidity
function addDexAdapters(struct AdapterInput[] _adapters) external
```

*add dex adapters to router*

**Parameters**

| Name       | Type                   | Description                                   |
| ---------- | ---------------------- | --------------------------------------------- |
| \_adapters | struct AdapterInput\[] | input to MarginlyRouter `addDexAdapters` call |

#### transferMarginlyRouterOwnership

```solidity
function transferMarginlyRouterOwnership(address to) external
```

*Set a new owner of a Marginly router contract. Allowed only for MarginlyPoolAdmin owner*

**Parameters**

| Name | Type    | Description                            |
| ---- | ------- | -------------------------------------- |
| to   | address | Address of a new Marginly router owner |

#### acceptMarginlyRouterOwnership

```solidity
function acceptMarginlyRouterOwnership() external
```

*Accepts Marginly router contract ownership*


# Adapters

### AdapterActions

#### addPools

```solidity
function addPools(struct PoolInput[] pools) external
```

*Add pools to router adapter storage. Allowed only for MarginlyPoolAdmin owner*

**Parameters**

| Name  | Type                | Description         |
| ----- | ------------------- | ------------------- |
| pools | struct PoolInput\[] | New pool parameters |

#### transferRouterAdapterOwnership

```solidity
function transferRouterAdapterOwnership(uint256 dexIdx, address to) external
```

*Set a new owner of a Marginly router adapter contract. Allowed only for MarginlyPoolAdmin owner*

**Parameters**

| Name   | Type    | Description                                    |
| ------ | ------- | ---------------------------------------------- |
| dexIdx | uint256 | Index of a dex                                 |
| to     | address | Address of a new Marginly router adapter owner |

#### acceptRouterAdapterOwnership

```solidity
function acceptRouterAdapterOwnership(uint256 dexIdx) external
```

*Accepts ownership of adapter. Needed for new pools addition*

**Parameters**

| Name   | Type    | Description    |
| ------ | ------- | -------------- |
| dexIdx | uint256 | Index of a dex |


# ApeSwapAdapter

### ApeSwapAdapter

#### constructor

```solidity
constructor(struct PoolInput[] pools) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address recipient, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 amountOut, bytes data) external returns (uint256 amountIn)
```

swap with exact output

**Parameters**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| recipient   | address | recipient of amountOut of tokenOut     |
| tokenIn     | address | address of a token to swap on dex      |
| tokenOut    | address | address of a token to receive from dex |
| maxAmountIn | uint256 | maximal amount of tokenIn to swap      |
| amountOut   | uint256 | exact amount of tokenOut to receive    |
| data        | bytes   | data for AdapterCallback               |


# BalancerAdapter

### BalancerAdapter

#### balancerVault

```solidity
address balancerVault
```

#### constructor

```solidity
constructor(struct PoolInput[] pools, address _balancerVault) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address recipient, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 amountOut, bytes data) external returns (uint256 amountIn)
```

swap with exact output

**Parameters**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| recipient   | address | recipient of amountOut of tokenOut     |
| tokenIn     | address | address of a token to swap on dex      |
| tokenOut    | address | address of a token to receive from dex |
| maxAmountIn | uint256 | maximal amount of tokenIn to swap      |
| amountOut   | uint256 | exact amount of tokenOut to receive    |
| data        | bytes   | data for AdapterCallback               |

### FundManagement

```solidity
struct FundManagement {
  address sender;
  bool fromInternalBalance;
  address payable recipient;
  bool toInternalBalance;
}
```

### SingleSwap

```solidity
struct SingleSwap {
  bytes32 poolId;
  enum SwapKind kind;
  contract IAsset assetIn;
  contract IAsset assetOut;
  uint256 amount;
  bytes userData;
}
```

### SwapKind

```solidity
enum SwapKind {
  GIVEN_IN,
  GIVEN_OUT
}
```

### IVault

#### swap

```solidity
function swap(struct SingleSwap singleSwap, struct FundManagement funds, uint256 limit, uint256 deadline) external payable returns (uint256)
```

### IAsset

### IBasePool

#### getPoolId

```solidity
function getPoolId() external view returns (bytes32)
```


# CamelotAdapter

### CamelotAdapter

#### constructor

```solidity
constructor(struct PoolInput[] pools) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address, address, address, uint256, uint256, bytes) external pure returns (uint256)
```

### ICamelotPair

#### getAmountOut

```solidity
function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256)
```


# KyberSwapClassicAdapter

### KyberSwapClassicAdapter

#### constructor

```solidity
constructor(struct PoolInput[] pools) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address recipient, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 amountOut, bytes data) external returns (uint256 amountIn)
```

swap with exact output

**Parameters**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| recipient   | address | recipient of amountOut of tokenOut     |
| tokenIn     | address | address of a token to swap on dex      |
| tokenOut    | address | address of a token to receive from dex |
| maxAmountIn | uint256 | maximal amount of tokenIn to swap      |
| amountOut   | uint256 | exact amount of tokenOut to receive    |
| data        | bytes   | data for AdapterCallback               |

### IKC

#### getTradeInfo

```solidity
function getTradeInfo() external view returns (uint256, uint256, uint256, uint256, uint256)
```


# KyberSwapElasticAdapter

### KyberSwapElasticAdapter

#### constructor

```solidity
constructor(struct PoolInput[] pools) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address recipient, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 amountOut, bytes data) external returns (uint256 amountIn)
```

swap with exact output

**Parameters**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| recipient   | address | recipient of amountOut of tokenOut     |
| tokenIn     | address | address of a token to swap on dex      |
| tokenOut    | address | address of a token to receive from dex |
| maxAmountIn | uint256 | maximal amount of tokenIn to swap      |
| amountOut   | uint256 | exact amount of tokenOut to receive    |
| data        | bytes   | data for AdapterCallback               |

#### swapCallback

```solidity
function swapCallback(int256 deltaQty0, int256 deltaQty1, bytes data) external
```

### IKyberElasticPool

#### swap

```solidity
function swap(address recipient, int256 swapQty, bool isToken0, uint160 limitSqrtP, bytes data) external returns (int256 amount0Delta, int256 amount1Delta)
```


# UniswapV2Adapter

### UniswapV2Adapter

#### constructor

```solidity
constructor(struct PoolInput[] pools) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address recipient, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 amountOut, bytes data) external returns (uint256 amountIn)
```

swap with exact output

**Parameters**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| recipient   | address | recipient of amountOut of tokenOut     |
| tokenIn     | address | address of a token to swap on dex      |
| tokenOut    | address | address of a token to receive from dex |
| maxAmountIn | uint256 | maximal amount of tokenIn to swap      |
| amountOut   | uint256 | exact amount of tokenOut to receive    |
| data        | bytes   | data for AdapterCallback               |


# UniswapV3Adapter

### UniswapV3Adapter

#### constructor

```solidity
constructor(struct PoolInput[] pools) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address recipient, address tokenIn, address tokenOut, uint256 maxAmountIn, uint256 amountOut, bytes data) external returns (uint256 amountIn)
```

swap with exact output

**Parameters**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| recipient   | address | recipient of amountOut of tokenOut     |
| tokenIn     | address | address of a token to swap on dex      |
| tokenOut    | address | address of a token to receive from dex |
| maxAmountIn | uint256 | maximal amount of tokenIn to swap      |
| amountOut   | uint256 | exact amount of tokenOut to receive    |
| data        | bytes   | data for AdapterCallback               |

#### uniswapV3SwapCallback

```solidity
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes data) external
```


# WooFiAdapter

### WooFiAdapter

#### constructor

```solidity
constructor(struct PoolInput[] pools) public
```

#### swapExactInput

```solidity
function swapExactInput(address recipient, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes data) external returns (uint256 amountOut)
```

swap with exact input

**Parameters**

| Name         | Type    | Description                            |
| ------------ | ------- | -------------------------------------- |
| recipient    | address | recipient of amountOut of tokenOut     |
| tokenIn      | address | address of a token to swap on dex      |
| tokenOut     | address | address of a token to receive from dex |
| amountIn     | uint256 | exact amount of tokenIn to swap        |
| minAmountOut | uint256 | minimal amount of tokenOut to receive  |
| data         | bytes   | data for AdapterCallback               |

#### swapExactOutput

```solidity
function swapExactOutput(address, address, address, uint256, uint256, bytes) external pure returns (uint256)
```

### IWooPoolV2

#### swap

```solidity
function swap(address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address to, address rebateTo) external returns (uint256 realToAmount)
```


# Risk Management Overview

This section describes how Marginly manages risks

### Risk framework

The *Marginly* v1 risk framework achieves the following:

1. Maximizes capital efficiency through leveraged trading activity. &#x20;
2. Optimizes on-chain handling of the framework parameters.&#x20;
3. Minimizes the probability of pool insolvency.

By implementing the loan pricing mechanism in the previous section, *Marginly* incorporates risk framework directly into the smart contract business logic:

* *Marginly* v1 uses the base asset (ETH) volatility as a risk proxy.
* *Marginly* v1 prices long and short positions in aggregate: protocol calculates long and short leverage of the entire pool and uses them to scale long and short interest rates.
* *Marginly* v1 updates users' positions on-action basis where each public method in smart contracts firstly accrues user debts (recalculates compounded interest), recalculates leverage, and performs liquidations if needed.
* *Marginly* v1 implements a decentralized price oracle and uses Uniswap v3's TWAP to calculate and update user positions.
* *Marginly* v1 stores two max-heaps of long and short users' leverages in a smart contract where each public method always tries to margin call the top 1 position if its leverage is > 20 and update the heap.
* *Marginly* v1 implements a public `receive_position()` method, which allows calling for margin in any liquidating position with outside liquidity.&#x20;
* *Marginly* v1 implements additional ***deleveraging*** functionality, which allows long buyers to absorb liquidating short positions and vice-versa.

### Risk management

*Marginly* further enhances risk management by closely considering the following two broad risk categories related to spot-leveraged trading:

<table><thead><tr><th width="150.5">Risk</th><th>Description</th></tr></thead><tbody><tr><td>Volatility Risk</td><td><p>The higher the volatility of the ETH, the less likely pool is to recover the full loan amount in the event of default. <br></p><p>Marginally incorporates volatility into the interest rate calculation, so traders pay more for the risk when the market volatility is high. Governance has a dashboard to monitor volatility and changes the interest rate parameter on-chain. <br></p><p>ETH price may experience sharp jumps, with intraday returns swinging as much as 25% on both sides. Imagine an example where the ETH price jumped lower, and there are a lot of leveraged long positions in the system holding ETH as collateral. Highly leveraged positions will be at risk of getting insolvent: market panic, multiple accounts being liquidated, blockchain network congestion, and liquidity drying out on Uniswap, all in conjunction, will lead to the inability to recover the full loan amount when liquidating. Marginly uses the insurance pool as a  liquidity of last resort to cover possible protocol losses in such scenarios. </p><p></p><p>System participants / Marginly DAO will have a dashboard to monitor system solvency and the pace of asset accumulation in the insurance pool.  </p></td></tr><tr><td>Liquidity Risk</td><td><p>The lower the liquidity depth in the ETH/USDC uniswap pool, the less likely the pool to recover the full loan amount in the event of default. <br></p><p>Expected shortfall (ES) shows what is the average worst 1% return ETH may demonstrate during a single day. It is then used to calculate how much collateral is at risk of liquidation. This collateral’s realizable value depends on the liquidity depth in uniswap. </p><p></p><p>System participants have a dashboard to monitor uniswap liquidity and effective realisable price given current liquidity conditions.</p></td></tr></tbody></table>


# Keeper service and smart contract description

Learn how Keeper service handles liquidations

### Keeper service

Keeper is a node.js service that monitors riskiest long and short positions within Marginly pools for liquidation and triggers the keeper contract to do so.&#x20;

Service configuration takes in Marginly pools addresses, network parameters and account address. This account is used for keeper transactions. The Keeper service then checks riskiest long and short positions. If a position’s leverage exceeds max leverage parameter (20 by default), the Keeper service calls up the smart contract to perform liquidation.&#x20;

The Keeper service attempts to liquidate positions in a loop every 3 seconds if the smart contract throws an error.&#x20;

### Keeper smart contract

Keeper smart contract’s job is to liquidate a position in Marginly. To this end the contract does the following:

* Takes out a loan in AAVE
* Makes the swap on Uniswap
* Return the loan to AAVE and any proceeds to the liquidator

All users can trigger the contract. It utilizes AAVE V3 for flash loan functionality and Uniswap V3 to execute swaps.&#x20;

Transaction takes the following inputs:

* Token
* Amount
* Marginly pool address
* Position address
* Minimum profit amount

Keeper transaction then does the following operations:

* requests an AAVE V3 flashloan&#x20;
* attempts to liquidate the position upon receiving a callback&#x20;
* gives the liquidated position’s collateral to the liquidator
* withdraws collateral and swaps for the token that was loaned out on AAVE

Two checks happen after the swap:

* Is the collateral sufficient to return AAVE flash loan and keep required premium
* Is the remaining amount equal to or greater than the minimum profit amount

Transaction reverts if an exception is thrown at any stage during the liquidation process. Most notable examples include the following:

* position can not be liquidated
* minimum profit amount check fails
* insufficient collateral to cover the flash loan&#x20;

In this case the user pays a fee for calling up the transaction.

<br>


# Keeper contract architecture

### MarginlyKeeper

Contract helper for Marginly position liquidators.

*It makes liquidations utilizing AAVE flashloans*

#### Profit

```solidity
event Profit(address liquidatedPosition, address token, uint256 amount)
```

*Emitted when liquidation occurs*

**Parameters**

| Name               | Type    | Description         |
| ------------------ | ------- | ------------------- |
| liquidatedPosition | address | liquidated position |
| token              | address | profit token        |
| amount             | uint256 | profit amount       |

#### LiquidationParams

```solidity
struct LiquidationParams {
  address marginlyPool;
  address positionToLiquidate;
  address liquidator;
  uint256 minProfit;
}
```

#### ADDRESSES\_PROVIDER

```solidity
contract IPoolAddressesProvider ADDRESSES_PROVIDER
```

#### POOL

```solidity
contract IPool POOL
```

#### constructor

```solidity
constructor(address addressesProvider) public
```

#### flashLoan

```solidity
function flashLoan(address asset, uint256 amount, uint16 referralCode, address marginlyPool, address positionToLiquidate, uint256 minProfit) external
```

Takes a simple flashloan in AAVE v3 protocol to liquidate a position in Marginly

**Parameters**

| Name                | Type    | Description                                       |
| ------------------- | ------- | ------------------------------------------------- |
| asset               | address | borrow asset                                      |
| amount              | uint256 | borrow amount                                     |
| referralCode        | uint16  | referral code to get rewards in AAVE              |
| marginlyPool        | address | address of marginly pool                          |
| positionToLiquidate | address | address of liquidatable position in Marginly pool |
| minProfit           | uint256 | amount of minimum profit worth in borrow asset    |

#### executeOperation

```solidity
function executeOperation(address asset, uint256 amount, uint256 premium, address initiator, bytes data) external returns (bool)
```

Executes an operation after receiving the flash-borrowed asset

*Ensure that the contract can return the debt + premium, e.g., has enough funds to repay and has approved the Pool to pull the total amount*

**Parameters**

| Name      | Type    | Description                             |
| --------- | ------- | --------------------------------------- |
| asset     | address | The address of the flash-borrowed asset |
| amount    | uint256 | The amount of the flash-borrowed asset  |
| premium   | uint256 | The fee of the flash-borrowed asset     |
| initiator | address | The address of the flashloan initiator  |
| data      | bytes   |                                         |

**Return Values**

| Name | Type | Description                                                      |
| ---- | ---- | ---------------------------------------------------------------- |
| \[0] | bool | True if the execution of the operation succeeds, false otherwise |


# Liquidations and Deleveraging

This page describes mechanics behind Marginly's liquidations and deleveraging

As we described in the [Trading](/protocol-mechanics/trading) section the maximum leverage available both for longs and shorts in Marginly is 20x. So what happens when the user's position exceeds this threshold? There are two possible outcomes which we describe below.&#x20;

### Liquidations

Liquidation flow is straightforward: sell liquidating position's collateral on Uniswap, use proceeds to repay liquidating position's debt, put excess (if any) back to the pool. With such an approach the entire pool enjoys an additional stream of revenues in a form of 5% penalty ( 1 / max leverage) on every position liquidation that occurs in the system. To better understand the mechanics, let's consider a simple example we've seen before when we discussed [trading mechanics](https://docs.marginly.com/protocol-mechanics/trading#margin-and-leverage):&#x20;

<table><thead><tr><th width="91">User</th><th width="97" align="center">ETH+</th><th width="95" align="center">ETH-</th><th width="95" align="center">USDC+</th><th width="90" align="center">USDC-</th><th width="91" align="center">NetPos</th><th width="109" align="center">Leverage</th></tr></thead><tbody><tr><td>1</td><td align="center"><mark style="color:green;"><strong>1</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">1000</td><td align="center">1</td></tr><tr><td>2</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>1</strong></mark></td><td align="center"><mark style="color:green;"><strong>1100</strong></mark></td><td align="center">0</td><td align="center">100</td><td align="center">11</td></tr></tbody></table>

User 2 sold short 1 ETH at a price of 1000 USDC. If the price of ETH starts to rise, the user's leverage will grow and at some critical price the user's position will become eligible for liquidation. It's easy to calculate the liquidation price given the maximum allowable leverage, collateral value and quantity of ETH being short:&#x20;

$$
P\_{liq}^{short} = \frac{usdc\_collateral\_value}{Q\_{eth}^{short}}\cdot \frac{L\_{max} - 1}{L\_{max}}
$$

Liquidation price for a long position is calculated symmetrically as follows:&#x20;

$$
P\_{liq}^{long} = \frac{usdc\_debt\_value}{Q\_{eth}^{long}}\cdot \frac{L\_{max} }{L\_{max}-1}
$$

Going back to the example above and using the first formula above, we can calculate that if the price of ETH rises to 1045 USDC, user's position will have leverage of 20x and will get liquidated. Assuming there is no slippage and swap fees are absent, the system will automatically (see [*reinit()*](/protocol-architecture/pools/user-actions) method description for details) sell user's collateral and buy 1100 worth of ETH at current price of 1045 USDC netting \~ 1.0526 ETH in return. The new pool state will now look like this:&#x20;

<table><thead><tr><th width="91">User</th><th width="97" align="center">ETH+</th><th width="95" align="center">ETH-</th><th width="95" align="center">USDC+</th><th width="90" align="center">USDC-</th><th width="91" align="center">NetPos</th><th width="115" align="center">Leverage</th></tr></thead><tbody><tr><td>1</td><td align="center"><mark style="color:green;"><strong>1.0526</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center"><strong>1100</strong></td><td align="center">1</td></tr><tr><td>2</td><td align="center">0</td><td align="center"><strong>0</strong></td><td align="center"><strong>0</strong></td><td align="center">0</td><td align="center"><strong>0</strong></td><td align="center">N/A</td></tr></tbody></table>

Of-course, in real life we can't neglect slippage, swap fees, and balance price vs. swap price discrepancies. So the penalty pool earns will be less than 5% almost surely. To control the slippage on liquidations, Marginly will revert transactions if the swap will result in price movement of more than 5% (*margin call slippage* [parameter](/protocol-architecture/pools/pool-parameters)).&#x20;

### Deleveraging

Liquidity may be absent in the pool when it all gets borrowed. Following situation may occur: the protocol needs to liquidate the borrower but there is not enough collateral in the pool to sell. To address such situations Marginly introduces ***no-liquidation*** approach called ***Deleveraging***. Deleveraging is a process of reduction of the total leverage of the pool (collateral and debt) when there is a liquidity shortage.

A slightly more sophisticated example is required to provide a clear explanation, let's assume the pool composition looks the following way:&#x20;

<table><thead><tr><th width="91">User</th><th width="97" align="center">ETH+</th><th width="95" align="center">ETH-</th><th width="95" align="center">USDC+</th><th width="90" align="center">USDC-</th><th width="91" align="center">NetPos</th><th width="109" align="center">Leverage</th></tr></thead><tbody><tr><td>1</td><td align="center"><mark style="color:green;"><strong>4</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>3000</strong></mark></td><td align="center">1000</td><td align="center">4</td></tr><tr><td>2</td><td align="center"><mark style="color:green;"><strong>2</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">2000</td><td align="center">1</td></tr><tr><td>3</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>5</strong></mark></td><td align="center"><mark style="color:green;"><strong>6000</strong></mark></td><td align="center">0</td><td align="center">1000</td><td align="center">6</td></tr><tr><td>4</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>1</strong></mark></td><td align="center"><mark style="color:green;"><strong>6000</strong></mark></td><td align="center">0</td><td align="center">5000</td><td align="center">1.2</td></tr></tbody></table>

Note, that all of the ETH brought by users 1 and 2 was sold by users 3 and 4. Now let's say the ETH price drops up until the point where the system needs to liquidate user 1. the protocol will need to sell user's 4 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.&#x20;

Instead of selling something that the pool doesn't have, the protocol will close user's position 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:&#x20;

$$
new\_debt = old\_debt - \frac{eth\_liquidated}{total\_eth\_debt}\cdot old\_debt=5-\frac{4}{6}\cdot5 \approx 1.667 \quad \text{ETH}
$$

$$
new\_collateral = old\_collateral - \frac{usdc\_liquidated}{total\_eth\_debt}\cdot old\_debt= 3500 \quad \text{USDC}
$$

The entire pool will look the following way after deleveraging:&#x20;

<table><thead><tr><th width="91">User</th><th width="97" align="center">ETH+</th><th width="95" align="center">ETH-</th><th width="95" align="center">USDC+</th><th width="90" align="center">USDC-</th><th width="100" align="center">NetPos</th><th width="108" align="center">Leverage</th></tr></thead><tbody><tr><td>1</td><td align="center"><strong>0</strong></td><td align="center">0</td><td align="center">0</td><td align="center"><strong>0</strong></td><td align="center">0</td><td align="center">N/A</td></tr><tr><td>2</td><td align="center"><mark style="color:green;"><strong>2</strong></mark></td><td align="center">0</td><td align="center">0</td><td align="center">0</td><td align="center">2000</td><td align="center">1</td></tr><tr><td>3</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>1.667</strong></mark></td><td align="center"><mark style="color:green;"><strong>3500</strong></mark></td><td align="center">0</td><td align="center"><strong>1833.33</strong></td><td align="center">1.0909</td></tr><tr><td>4</td><td align="center">0</td><td align="center"><mark style="color:red;"><strong>0.333</strong></mark></td><td align="center"><mark style="color:green;"><strong>5500</strong></mark></td><td align="center">0</td><td align="center"><strong>5166.67</strong></td><td align="center">1.0645</td></tr></tbody></table>

Note the following:&#x20;

* 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.&#x20;
* Lender (user 2) didn't see his net position increase (unlike after regular liquidation). &#x20;

The implementation of deleveraging mechanics will use *deleverage coefficients* to modify total collateral and total debt inside the pools. This is similar to how collateral and debt aggregates are modified by *collateral coefficients* and *accrued rates* (see [pool variables](/protocol-architecture/pools/pool-variables) section for details).&#x20;

**Bottom line:** \
\
Marginly introduces a novel *deleveraging* mechanics in relation to pool's liquidity management. This mechanics complements traditional liquidations and allows to close out users' positions even when there is liquidity shortage inside the pool. In next versions of Marginly protocol we might consider ditching liquidations altogether and resorting only to deleveraging when liquidating user positions.  &#x20;


# Volatility as risk proxy

This page explains some of the details of measuring volatility and sheds light on the type of analysis Marginly performs for measuring protocol risks.

### On-chain volatility&#x20;

There are several ways to handle volatility on-chain:

<table><thead><tr><th width="264.6666666666667">Approach</th><th width="210">Pros</th><th>Cons</th></tr></thead><tbody><tr><td>Setup a risk framework to periodically set the volatility parameter via governance.</td><td><ul><li>Easy to implement.</li><li>Doesn’t require on-chain computation.</li></ul></td><td><ul><li>Changing volatility parameter takes considerable time.</li></ul></td></tr><tr><td>Calculate volatility on-chain using oracle and / or on-chain AMM prices.</td><td><ul><li>Flexibility. Many ways to do calculations. </li><li>Fully decentralized approach.</li></ul></td><td><ul><li>Costly computations.</li><li>High variance, high bias models.</li></ul></td></tr><tr><td>Fetch volatility from oracle or 3rd party protocols.</td><td><ul><li>Outsource of computation.</li></ul></td><td><ul><li>Limited or no available options at the moment.</li><li>Requires trust in a 3rd party oracle provider.</li></ul></td></tr></tbody></table>

*Marginly* v1 will initially follow the first approach while aiming to use the same AMM pools to calculate volatility directly on liquidity that the Marginly pool will be trading against.&#x20;

### Volatility estimation

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:

$$
s^2 = \frac{1}{N} \sum\_{i=1}^{N} (x\_i-\bar x)^2
$$

where each x\_i are logarithmic return and x dashed is a mean return.&#x20;

When looking at asset time series, it is tough to distinguish mean returns (the drift or trend of the price) from variance, and estimates of the mean return are notoriously noisy, especially for small samples. So we generally set the mean return in the equation of sample variance above to zero. This increases the accuracy of measurement by removing a source of noise. Note that we are not claiming that assets have zero drift. We merely state that simultaneous estimation of mean returns and variance leads to noisy results.&#x20;

The one big problem with a close-to-close estimator is that it converges slowly to actual volatility (population variance) with the growth of the number of samples N. Volatility measurements have significant uncertainty associated with them, and for very small sample sizes, this can overwhelm any information completely. So we have to choose a sample size that achieves a balance between including data from periods that are no longer relevant and using too little data so that sampling error dominates.&#x20;

To mitigate the problem, we can use intraday frequency to calculate volatility. We sample 4-hour closing prices for the past 30 days to calculate an actual volatility measure, resulting in a total of 180 data points which is enough to reduce sampling error significantly.&#x20;

### Volatility in context

Now that we know how to calculate volatility let's put it into context: 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.&#x20;

To gain the most information from a given price series, it would generally be necessary to use overlapping data. This will induce an artificial degree of correlation in the estimates of volatility and will bias our results somewhat. If we use 30-day volatility and roll this forward by one day, we will still have 29 data points in common with the first data set. The two volatilities will be highly correlated because they are almost the same. Variance from overlapping return series needs to be adjusted by a factor given by a fancy formula, which we won’t show here, but definitely take into account when calculating volatilities.&#x20;

<figure><img src="/files/H53uw4KmfVs5iP2rjt7V" alt=""><figcaption></figcaption></figure>

The cone 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 volatility is around 5% a day. \
\
Armed with this knowledge you can gauge the typical asset move you might expect given its current price, volatility level, and time period you're considering:&#x20;

$$
E = S\_0 \sdot \sigma \sdot \sqrt{T}
$$

So for example, given the ETH price of \~2000 USDC, 5% daily volatility, and 5 days period, we can expect it to move it \~ 223 USDC in either direction or in relative terms around 11%.

Looking at intraday data in the same format (here, we use one-hour samples for the past 30 days and the close-to-close estimator), we see the following picture: average volatility has a wider possible range and is skewed to the upside. The median value of 3% tells us that past 30 days, there hasn't been much price action in the ETH-USD price pair. Note that it's common to see values up to 8% (these are the numbers we observed during the 2022 bear market).&#x20;

<figure><img src="/files/jbSV327Jc3lh3P1auiWC" alt=""><figcaption></figcaption></figure>

Further looking at the historical volatility distribution, we can confirm the above picture.

<figure><img src="/files/ryzjvdcXqNL2f9koOYxQ" alt=""><figcaption></figcaption></figure>

The diagram clearly shows what actual close-to-close volatility has been in the past over the sample period we examine. We can see several distinct volatility peaks: a Gaussian blob centered around 4-5% daily volatility (the long-term average volatility we estimated earlier) and a fat proper tale with several distinct peaks around 8%, 10%, and 12%, respectively. The *regime shift* (low volatility vs. high volatility) is around 7%. We will deploy Marginly v1 contracts with this initial volatility parameter value.&#x20;


# Insurance pool

The insurance pool is a separate liquidity pool that earns protocol fees and liquidation penalties in return for system risk management. Currently, the insurance pool is accumulating liquidity at 50% of all trading fees collected by the platform.&#x20;

Governance can change this weight based on the information and considerations outlined in the risk management section.

The insurance pool is a liquidator of last resort: when there is not enough liquidity in the system, the pool steps up to liquidate risky positions. It receives up to a 5% profit margin by doing so. \
\
The amount of liquidity required to be held in the insurance pool can be efficiently measured when we calculate how much liquidity the system lacks under specific market stress scenarios.


# Shutdown mode

There is a special shutdown mode in *Marginly* v1. This mode is enabled by smart contract admin when there is system insolvency, that is:&#x20;

* When there is not enough USDC collateral value to support the entire ETH debt value
* When there is not enough ETH collateral value to support the whole USDC debt value

System insolvency is a critical situation in which the protocol stops functioning correctly and thus requires the winding down of user positions and protocol instantiation. In normal market conditions and the absence of "black swans" events like the sudden USDC depeg or a protocol or AMM hack with depletion of liquidity, we wouldn't expect a shutdown to happen. This is a once-in-a-lifetime event, yet it still requires proper handling.&#x20;

In the shutdown mode, no new positions are allowed to be opened, and the side opposite to the insolvent side is responsible for restoring the system's solvency at its expense. If shorts are insolvent (ETH debt value > USDC collateral value), longs will pay with their ETH collateral to reduce the system's ETH debt until the solvency is restored. If longs are insolvent (USDC debt value > ETH collateral value), shorts will pay with their USDC collateral to reduce the system's USDC debt until the solvency is restored.  &#x20;


# Marginly economics

Description of protocol cashflows and future plans for the tokenomics

*Marginly* v1 does not have an ecosystem token. Sound tokenomics requires a sound design with initial data and statistics backing it. This is why we aim to launch Marginly v1 as-is, gauge user interest, and obtain trading/liquidity statistics before making further architecture decisions.&#x20;

### Revenues and expenses&#x20;

In *Marginly,* we have the following revenue streams and required expenses:

| Revenue streams                                                                     | Expenses                                                                                                                                            |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| <ol><li>Borrower interest</li><li>Liquidation penalties</li><li>Swap fees</li></ol> | <ol><li>Bootstrap insurance pool</li><li>Reward integration partners</li><li>Reward the team</li><li>Reward long-term liquidity providers</li></ol> |

*Marginly* v1 is designed in such a way that both borrower interest and liquidation penalties are interchanged between system longs (borrowers of USDC pay USDC liquidity providers) and system shorts (borrowers of ETH pay ETH liquidity providers).

We have put together the revenues [spreadsheet](https://docs.google.com/spreadsheets/d/1NjmAnI5oByteYMvGZxMITfCMUi6cgQM2lHnP1iuBxrk/edit#gid=828721623) to gauge the APR percentage each revenue stream offers the system. The most probable initial working ranges are highlighted in the document.&#x20;

The bottom table of the revenues [spreadsheet](https://docs.google.com/spreadsheets/d/1NjmAnI5oByteYMvGZxMITfCMUi6cgQM2lHnP1iuBxrk/edit#gid=828721623) shows how the swap fee scales with the greater protocol adoption, which is measured by the annualized trading volume to TVL ratio. The higher this indicator, the more effective APR *Marginly* earns.&#x20;

Initially, *Marginly* will bootstrap the insurance pool with fees applied on revenue streams, as it is crucial for the system's solvency and safety. With later protocol releases, fees will be split among different expenses to allow for protocol expansion.&#x20;


# Beyond Marginly v1

This page describes team's vision on future protocol enhancements

The current version of *Marginly* described in this document is v1. Even though it is sophisticated enough and handles risks responsibly, there is still a lot of room for improvement.&#x20;

The dev team continues its active research on the future of the DeFi and aims to introduce the v2 version of the *Marginly* protocol, which will include the following features:

* **Deleveraging**: auto-deleverage risky positions to avoid liquidations.&#x20;
* **Option strategies**: Introduce option-based strategies using Uniswap position exposure.
* **Multiple liquidity sources**: Connect other sources of Liquidity, such as Curve’s tri-crypto pool for leveraged trading. Introduce smart routing and smart liquidity management.&#x20;

Let's elaborate on each of the points in detail:

### Deleveraging:

{% hint style="info" %}
Deleveraging reduces one's leverage (collateral and debt) when the system has a liquidity shortage.
{% endhint %}

Liquidity may be absent in the system in the following cases:

* The lender (liquidity provider) wants to withdraw, and there is no liquidity as all of it was borrowed.
* The protocol needs to liquidate the borrower, and there is no collateral to sell as all of it was borrowed.

The second case may be reduced to the first case if the `receive_position()` method is called, and the position receiver reduces the entire liquidating position debt are several possible approaches to the problem of liquidity shortage in the system. Some try to avoid it altogether, others introduce ways to correct it when it has already happened, while both could benefit from additional market-driven interest rate mechanics such as utilization-based interest rate curves commonly seen in classical DeFi lending protocols. We envision the following possibilities for improvements in newer versions of *Marginly*:

1. Introduce a reserve ratio to limit the amount of liquidity that may be taken out of the system: with such an approach, there could never be a situation when the entire collateral has been borrowed as debt because there will always be a fraction left governed by the magnitude of the reserve ratio. Potential bank runs still have to be accounted for, though, as the reserve ratio doesn’t solve the problem completely but rather mitigates it.
2. Do honest deleverage when liquidating positions. Modify collateral and debt coefficients of the opposite side in the system, effectively reducing the overall long or short system leverage. This approach appeals to its simplicity. One alternative option is to de-lever consecutively, starting with the riskiest position first and moving down the leverage heap.&#x20;
3. Target a certain long/short ratio in the system, which is the ratio of total USDC debt value (longs) to the total WETH debt value (shorts). So one could imagine a system that penalizes or deleverages the long side when the ratio is above one and deleverages shorts when the ratio is below one.&#x20;

### Multiple liquidity sources

Liquidity risk is one of the main risks with which investors are concerned. What happens to the system in the absence of external liquidity sources? How are risky positions being liquidated in such cases? What are other liquidity options besides Uniswap pools? These are examples of essential questions that we will have to find answers to in future versions of the *Marginly* protocol.&#x20;

When there is more than one pool available to choose from, there arises the need to build a logic that would identify which pool is best to use, given current liquidity conditions and immediate trade parameters. So-called routers best perform these tasks. One example of such a router is the 1inch’s router. We plan to use such routers in future versions of the *Marginly* protocol and might even consider building one of our own.

### Option strategies

One way to think about a Uniswap liquidity position is as a **covered call** or a **short cash-secured put** option strategy, depending on whether the strike tick had been above or below the current spot price when liquidity was deployed.&#x20;

Overall, Uniswap liquidity positions are a combination of long positions in two tokens and short options (either calls or puts) on those tokens. The trading fee revenue earned by liquidity providers can be thought of as the premium received for selling those options. Armed with this knowledge, we can create short straddle or short strangle option positions:

* **Short Straddle:** Deploy 2 x ETH liquidity to the single tick as close to the current market price as possible, then sell 1 x ETH on the market.
* **Short Strangle:** Deploy USDC liquidity in a range below the current market price and deploy ETH liquidity in a range above the current market price, then sell the same amount of ETH elsewhere in a separate transaction.&#x20;

In future versions of the *Marginly* protocol, we are going to exploit the above knowledge to offer users the delta-neutral option strategies described above, which help control directional biases of their portfolios.&#x20;


# Some ideas for Marginly v2

Risks of leveraged trading and how Marginly addresses them

### Risks of leveraged trading and how Marginly addresses them. Some ideas for Marginly v2.

### Introduction

We designed the Marginly protocol with the idea that risk management is crucial to any borrowing activity. The risks associated with spot leveraged trading are as follows:\
\
1\. **Counterparty risk** - Smart contracts are hacked or fundamentally broken so users can no longer access their positions and funds.&#x20;

2\. **Technical risk** - Technical issues with the trading platform, wallet software, and internet connectivity can disrupt the execution of leveraged trades.

3\. **Market risk** - the risk of the market price fluctuations of the traded asset. the risk of sudden price jumps due to the high volatility nature of crypto or because of some unforeseen (black swan) events. &#x20;

4\. **Liquidity risk** - the risk of insufficient asset amounts to perform an exchange in required volumes. May be as external and internal:&#x20;

* **External**: Trade slippage may be high on the AMM in high volatility market.&#x20;
* **Internal**: There might be no liquidity inside the Marginly pool to trade or withdraw.&#x20;

5\. **Margin call risk**: If a trade goes against a user’s position, they may be required to deposit additional funds (margin call) to cover potential losses. Failure to do so could lead to forced position liquidation. This risk is closely tied to both the market and the liquidity risk. We will cover this risk when we talk about Market and Liquidity risks.\
\
Let’s address each of the risks in greater detail and discuss mitigation strategies both current and potential for Marginly v2.&#x20;

### Counterparty risk

This risk is easy to explain yet hard to control. Users may lose their funds due to bugs and/or exploits found inside Marginly smart contracts. This risk reflects the human factor in the development and audit of smart contracts, where occasional errors might seep in through the tests during the development stage and through the audit process during the audit stage.<br>

The best way to mitigate counterparty risk is to follow a strict process in developing and testing the smart contract logic and code.\
\
At Marginly we cover all of the smart contract methods with unit tests that must be passed before any functionality gets updated. We also run [integrational scenarios](https://github.com/eq-lab/marginly/tree/contest-deploy/packages/int-tests) that involve testnet deployment and trading emulation with testnet tokens and Uniswap v3 mock.\
\
Additionally, the audit must be performed by 3rd party professionals on close-to-live scenarios by deploying and playing with the smart contracts to blockchain testnets. The audit report has to be publicly available. [Quantstamp will audit Marginly](https://marginly.medium.com/marginly-set-to-undergo-an-audit-with-quantstamp-ahead-of-protocol-launch-bf09025d06d) v1 contracts.\
\
Finally, when the Marginly protocol is live, there will be a dedicated Marginly token allocation for the bug bounty programs, so white hackers may do their business!

### Technical risk

This risk entails everything that is related to the proper functioning of Marginly interfaces, [Walletconnect](https://walletconnect.com/) provider, and the wallet you use to sign blockchain transactions. In case anything goes wrong with the abovementioned components due to software bugs or poor internet connection, you may temporarily lose access to your Marginly position and thus fail to act timely on your portfolio.&#x20;

We run testnets and contests and allow people to participate and interact with the app so we can catch all the interface and connection errors and minimize their occurrence. Our QA team follows scenarios of common user flows and makes sure interfaces and wallet management run smoothly in different browsers and on different devices.&#x20;

We have created more than 100 manual tests for regression testing with specialized testing software. We run these tests once a month to assess the overall app behavior. We also collect extensive user feedback from our Discord server and categorize it so we can prioritize our future work. &#x20;

We are working on the desktop version of the app at the moment, yet we recommend using the mobile version as we envision the mobile-first app future. We observed stable behavior and smooth running of the Marginly web app on the following operational systems and several cell phone devices:  &#x20;

**iOS**: version 15.4 or higher. Safari or Chrome browser, walletconnect with Metamask wallet.\
**Android**: Android 11 or higher. Chrome or Firefox browser, walletconnect with Metamask wallet.

To mitigate the technical risk we recommend using the Marginly app only with a stable internet connection. Please don’t hesitate to report UX bugs so that the dev team can fix them in a timely manner. You can reach out to us in Marginly’s [discord](https://discord.com/invite/tCTYwTzM8h) and [twitter](https://twitter.com/marginlycom). We will additionally consider bug bounty programs to motivate people to find non-critical technical bugs that impede the normal functioning of the app.&#x20;

### Market risk

This is the one risk we can analyze extensively using several statistical methods at our disposal. Market risk is important in the context of leveraged trading because it is closely related to the maximum leverage a trader should take and to the concept of liquidation prices.&#x20;

The higher the volatility of the underlying tradeable asset, the less likely the pool is to recover the full loan amount in the event of default. Marginly incorporates volatility into the interest rate calculation, so traders pay more for the risk when the market volatility is high. Marginly runs a [risk dashboard](https://dashboard.marginly.com/) to monitor volatility and possible risks on-chain.

Using the [Marginly dashboard](https://dashboard.marginly.com/) users can quickly assess the current market regime and define their drawdown tolerance given the historical volatility distribution and simulated returns histogram.&#x20;

Let’s consider an example: I want to long ETH and would love to know the safe level of leverage I can take. Here’s the approximate algorithm I would use with the Marginly risk dashboard:\
\
1\. Assess current and historical volatility measures:&#x20;

<figure><img src="https://lh3.googleusercontent.com/3UY0R_l3c3HFM6g10EKRR_di83TsZZgbXRZvwK4NuFSCtUHqcsKQsOgU1i4CP5vc3l73RROpnph8vuPZaIDZtEGRfWx8LraAyZevUc_5_6E8N6zpQj5fMY1FRmhDD6slBPfVrQe-KkeYp-4qlMDLMPk" alt=""><figcaption></figcaption></figure>

\
This chart tells me that currently, the volatility is at the low range of the spectrum, which is confirmed further by the volatility cone chart: The median daily volatility is around 4% while right now we sit below 2.5%, so it's reasonable to assume a volatility increase in the near future.\
\ <br>

<figure><img src="https://lh6.googleusercontent.com/-N6DnUmrQn83pbAxzgR9McpreaKMfRlDF0mGotm67PveVUnSx33z_7zYQGiWS2Hm4dVnQVi5IReopf5uZpk53cNOOn5Ee9N48uG0uVxBG4iwE6a-kGgE-0XP5OVAVDvTH0isxV83dZj_4PzDBTOkTa8" alt=""><figcaption></figcaption></figure>

2\. Look at the simulated returns histogram.\
When simulating returns we assume that the underlying asset (ETH in our example) follows a geometric Brownian motion process intervened with Poisson-distributed price jumps.\
\
The threshold for classification of the price return as a jump was set at a magnitude of 10%. This parameter itself has to be reassessed periodically, as looking at the log returns chart for the past year we barely see returns exceeding 10% in magnitude, the 5% threshold (green lines) looks much better in the mid-term market perspective:&#x20;

<figure><img src="https://lh3.googleusercontent.com/Ic290ZdC3Jb1K97n0pm8VJ2CNBCLcHy_nNmNaygRs-912zdaiZE2KCRGmUq6EiLG_8feYfd0OLsrCq6QsWbXHzURldXFp3Q9MJ_9GI8vSVLy9fQ2_Z9EmGszy02RyeaQEM6s_vh1VWSfcQJ1Abaq51o" alt=""><figcaption></figcaption></figure>

\
\
The histogram of simulated returns shows us the distribution of worst 1% daily ETH returns in 1000 simulations of random price walks. On average in 1% worst-case scenarios I can expect to see a price drop of the underlying asset (ETH) around 7% a day.&#x20;

<figure><img src="https://lh6.googleusercontent.com/vv2TnkC3g3MmuXaN0tz6mn1wmbHc9AESgMSlWmXZNatPNaD5nrrn8hxe0wfxG_PjUHP20HOCkFK7CArJj2hswFQt3lRuaxqI-Zffve-Wjm0O73A1uwzLAC4RtYdKm_4_SqTgi5DCuwhgoQMQW0-c-5Y" alt=""><figcaption></figcaption></figure>

3\. Calculate maximum tolerable leverage. Armed with the knowledge about worst 1% drawdowns, I now can gauge the expected asset move given its current price, volatility, and time period I’m considering for a leveraged trade:

<figure><img src="/files/wcnWgXRvE59UdVp4flGK" alt=""><figcaption></figcaption></figure>

So for example, given the ETH price around \~1700 USDC as of writing, the 7% average wost 1% drawdown, and 5 days trade period, I can expect ETH to move: 266 USDC or 15% in either direction. This number can be used to further calculate the maximum allowable leverage:\
\
Even if my ETH collateral in the worst case scenario falls by 15% over the course of 5 days, I still want it to cover my debt sufficiently enough to have room for a critical margin of 5% (max leverage = 20). So in total, I should bear a 20% drawdown at minimum. That means the maximum leverage I should consider is: Lmax=120% = 5

### **Marginly market risk related parameters**

Currently in Marginly, there are two parameters which are used to control the Market risk:&#x20;

* Maximum leverage: the maximum leverage of any single position is allowed to have before it gets liquidated. This is analogous to the Liquidation threshold in Aave, for example. 80% liquidation threshold is the same as max leverage of 5 = 1 / (1 - 80%). \ <br>
* [Interest rate:](https://docs.marginly.com/protocol-mechanics/loan-pricing) this parameter is scaled by leverage, in particular, the interest rate is proportional to the overall long or short leverage and the current volatility level of the underlying: \ <br>

  <figure><img src="/files/c2611sbviDarkbE1bfzb" alt=""><figcaption></figcaption></figure>

The higher the corresponding leverage and the higher is the underlying volatility the higher interest rate will be recorded for the corresponding party (longs or shorts).\
\
There is a nice market-driven touch to this dynamic. Interest rates adjust with the market and with the open interest in Marginly.  If there are only longs in the pool, the interest rate for USDC lenders who provide USDC for borrowers to go long will be very high, potentially attracting more USDC lenders. If, on the other hand,  shorts dominate the pool, the interest rate for ETH will be high and all ETH lenders will enjoy high interest, potentially attracting new ETH liquidity into the pool.&#x20;

### **Current Marginly architecture:**

Users get liquidated unconditionally when their portfolio reaches the maximum leverage level. The borrower effectively loses 5% of his collateral.\
\
This collateral is earned by the pool if liquidation happens automatically due to the riskiest position being liquidated [every time the Marginly smart contract is invoked](https://docs.marginly.com/protocol-mechanics/trading#liquidations).\
\
Additionally, the liquidating position may be absorbed by any other position inside Marginly. We offer keeper service bots for this purpose. These are web3js scrips which when run constantly monitor the Marginly contracts in search of the arbitrage opportunities. Given that receiving position parameters are within the required margins after the absorption happens the entire collateral margin of 5% is earned by a single position.&#x20;

### **Architecture considerations for Marginly v2:**

1. Some protocols, like[ Euler finance](https://www.euler.finance/), for example, don’t liquidate entire positions and instead allow liquidators to return position health factor (leverage in our case) to the target level. \
   Marginly could also target a long-term “sustainable” (see market risk sections to understand how to gauge sustainability) leverage. The pool could slowly deleverage user positions proportional to their debts to bring pool leverage back to the target. &#x20;
2. Another approach we consider is to allow trading/swapping inside the pool. [crvUSD](https://crvusd.0xreviews.xyz/) algorithm introduces an AMM that allows for dynamic arbitrage opportunities since the price of collateral inside the pool changes faster than the oracle price. Such a pool effectively sells low and buys high paying this spread fee as a cost of hedging its collateral.\
   \
   Marginly can incentivize arbitrageurs or liquidators to buy out collateral of positions with dynamic discounts when these positions approach critical leverage levels. This is similar to point one above and could come as a complimentary protocol feature. &#x20;
3. The third interesting option uses the fact that Uniswap v3 allows liquidity providers to concentrate liquidity in any arbitrary range. This feature allows LPs to model/mimic any liquidity distribution, including existing AMMs such as Curve, Balancer, or Uni v2. See this great [Paradigm post](https://www.paradigm.xyz/2021/06/uniswap-v3-the-universal-amm) for details. Ultimately, the Uniswap v3 LP behaves as a short cash-secured put or a covered call depending on whether the deployed liquidity is above or below the current spot price. Curious minds may follow [this excellent explanation](https://lambert-guillaume.medium.com/uniswap-v3-lp-tokens-as-perpetual-put-and-call-options-5b66219db827) for some insights.&#x20;

Consider the example: Marginly ETH/USDC pool sits on an ETH net long position, this means there is a risk of ETH price depreciation: if the ETH price drops to a certain strike price X, the long position will require liquidation. Liquidation means selling ETH on the market to recover borrowed USDC to wind down the long positions. There needs to be a guaranteed buyer to absorb this selling. Buying ETH at a predetermined price in a predetermined quantity is exactly how Uniswap v3 position behaves when USDC is deployed at the strike price that is lower than the current market price. So effectively, we can use Uniswap v3 LP positions as protection for longs! Same works for shorts by the way.&#x20;

The idea sounds simple on paper but starts to get complicated when you start thinking about the actual protocol architecture. Do we implement our own concentrated liquidity AMM and use its liquidity as a hedge? Alternatively, do we allow Uniswap v3 LPs to lock their NFTs? How do we guarantee that locked liquidity will be used explicitly by the Marginly pools?&#x20;

### Liquidity risk

This one is relatively simple to understand. Let’s first understand the external liquidity risk.

\
The less liquidity there is on external trading venues, the smaller the chance that traders can make good execution trades. The lower the liquidity depth in the ETH/USDC uniswap pool, the less likely the Marginly pool is to recover the full loan amount in the event of default.\
\
Consider the following liquidity distribution as an example: this is the ETH-USDC Uniswap v3 pool liquidity distribution on Arbitrum. Different shades of blue show 2% and 5% spreads for reference. Around 10K USDC worth of ETH must be traded to move the price by 2%, and around 20K USDC is needed to move the price by 5%. \
\
&#x20; &#x20;

<figure><img src="https://lh4.googleusercontent.com/180whSphj5CnZBtaIT9STTyEf4C_j6diCq7NZJZsqenupeGgHwwC21q20CT79iTNdYwbH6ETDhrL4p-XBWn4P0h45oo9g2ZGx9R1Nl4yHCgImrzF8lk8c9GxNpSDZh0CRacyr__TKZop9xl7TI-bqyk" alt=""><figcaption></figcaption></figure>

<br>

Now imagine that the protocol needs to liquidate the position which is 50K in size. This would move the pool price significantly more than the 5% (max leverage = 20) liquidation threshold. This is a good illustration of the external liquidity risk. Bear in mind that this risk is exacerbated when the market is in turmoil as LP providers start leaving the Uniswap pool. &#x20;

Now let us consider the *internal* liquidity risk.\
\
We’ve covered one possible scenario in detail in our docs on [Marginly deleveraging mechanics](https://app.gitbook.com/o/-LqAeCvM12bCwSTs3V-o/s/QiFBW4qPpAjrKQaezZ3s/protocol-mechanics/risk-management/liquidations-and-deleveraging#deleveraging). Basically, liquidity may be absent in the pool when the protocol needs to liquidate an underwater position. Consider the following pool state as an example:<br>

<figure><img src="https://lh5.googleusercontent.com/ooc3N2pVEZ26sOLLeUC7nT4m0ZQMj16KbmKluSmseOVxNUakyzdL0DjyDI6YlkgXqLxe4Vgs9fe6FZtWbJWXukX__NqMKHoGuqdV_jzGIzIOdfeMZ1XKHlPQTnoT9U_5xExO-wVtddlvA4ygGSQitA4" alt=""><figcaption></figcaption></figure>

There are 3 users in the ETH/USDC pool.

* **Lender** (0) supplied 20K USDC in liquidity.&#x20;
* **Buyer** (1) borrowed 18K USDC to buy 18 ETH using 1 ETH as collateral.&#x20;
* **Seller** (2) borrowed 12 ETH to sell for 12K USDC using 2K USDC as collateral.\
  liquidated the pool will be in liquidity deadlock: the system needs 19 ETH for liquidation, but the pool has only 7 ETH left after the short seller sold ETH from the pool.\
  \
  The long position gets liquidated when the ETH price is falling, while the short position is net positive. The obvious solution here is to cancel out the fraction of the long position against the entire short position. Limiting the short position’s profit potential while at the same time curbing the long position’s loss.

### **Marginly liquidity risk-related parameters**

1. **Position slippage**: the maximum slippage allowed when opening or closing leveraged positions on the external AMM. The default value is 2%. The transaction will revert if trade results in higher slippage.
2. **Margin call slippage**: the maximum slippage allowed when liquidating a position on the external AMM. The default value is 5%. The transaction will revert if liquidation results in higher than the default slippage.
3. **Base asset limit**: Maximum allowable balance of the base asset in the pool. (ETH for example). This parameter is used to gauge the concentration risk of any given asset. Too much of an asset in the pool may lead to overexposure and an inability to handle cascading liquidations in market turmoil.
4. **Quote asset limit**: Maximum allowable balance of the quote asset in the pool. (USDC for example). This parameter is used to gauge the concentration risk of any given asset. Too much of an asset in the pool may lead to overexposure and an inability to handle cascading liquidations in market turmoil.

### **Current Marginly architecture:**&#x20;

CurrentlyMarginly liquidates risky positions and sells their collateral on the corresponding DEX or AMM. In addition to covering the insolvent position on the open market, Marginly allows any willing party to absorb the liquidating position and realize its net value (we discussed this above).&#x20;

There are also [deleveraging](https://docs.marginly.com/protocol-mechanics/risk-management/liquidations-and-deleveraging#deleveraging) mechanics that come into play when a borrower needs to get liquidated but there isn’t enough liquidity in the pool to sell his collateral. ETH collateral of long buyers pays off the ETH debt of short sellers, while USDC debt from long buyers reduces the USDC collateral of short sellers.&#x20;

### **Architecture considerations for Marginly v2:**&#x20;

We want to address both the internal and external liquidity risks. Intuitively, the best way to address both of them is to amend or modify the deleveraging functionality in such a way that we resort to external AMM trading only in rare cases when there is no deleveraging option left on the table. This way the protocol won’t be doing trades on a thin market when liquidations need to happen, while at the same time solving for the internal liquidity risk, as the absence of liquidity inside the Marginly pool will not lead to deadlocks and will simply require the overall leverage to wind down within the pool.&#x20;

The devil is, as usual, in the details. The concept of deleveraging is closely related to the idea of targeting a “sustainable” pool leverage as we discussed above in the market risk section. There are a lot of questions to be answered, just to give the reader food for thought here are some of them:&#x20;

1. Will users agree to the fact that their winning positions will get deleveraged automatically once liquidations of opposite side positions happen in the Marginly protocol?
2. Should the protocol target some default (e.g. 50%/50%) pool asset value ratio to avoid the liquidity imbalance which may lead to the need for deleveraging? &#x20;
3. Should the protocol have a reserve ratio to disallow borrowing of all of the assets from the pool?&#x20;

### Conclusion

In this article we have covered some of the common risks related to leveraged trading and described how Marginly addresses them. We’ve also presented current issues, challenges, and open questions we face. We have presented some ideas for future versions of the Marginly protocol. We highly anticipate positive user feedback and discussion around these ideas. In the next articles, we will expand on the ideas presented here and will consider each proposed approach, and its pros and cons in greater detail. <br>


# Trading Contest FAQ

### Q: Can I use the faucet more than once?

A: No. The initial portfolio of virtual assets can be requested from the faucet once per address.

### Q: Will inactive members be excluded from the leaderboards?

A: They won’t, as it can affect the accurate qualification schedule. For example, this measure would exclude traders who choose to swap everything for USDC and hold until the end of the contest. Such passive strategies are perfectly viable, and traders who employ them can expect to have their place on the leaderboard.

### Q: Will there be a trade history page?

A: Yes, we are working on it. Follow us on [Twitter](https://twitter.com/marginlycom) for upcoming dev updates to get notified when it's live.

### Q: Wen rewards?

A: All contest winners will get special NFT badges in three weeks after we wrap up the contest on the specific network. These badges make users eligible for a share of the future airdrop conducted by Marginly. The airdrop will happen after Marginly mainnet launch, the exact date is TBA.

### Q: What's the difference between all these NFTs in Galxe? Please briefly explain which is needed for what.

A: There are 3 NFTs and an OAT available on Marginly Galxe.\
**Marginly Paper Plane** is a basic NFT badge to award for following Marginly socials. This badge is a mandatory requirement to be eligible for trading contest prizes.

**Marginly Airplane** is a more senior badge to award for completing the on-chain task in the Marginly app beta. It’s required for getting Marginly Rocket.

**Marginly Rocket** is the rarest Marginly NFT badge. This badge is to award team captains for their active participation in trading contests and to be raffled among especially distinguished users in other Marginly campaigns on Galxe. This badge entitles holders to a share in the future Marginly airdrop.&#x20;

**Marginly Paper Plane OAT** is similar to the Marginly Paper Plane. The only difference is that users don’t have to pay for gas when they get it.&#x20;

### Q: I want to swap assets in my portfolio. Is there a way to do that?

A: Sure! You can swap assets directly on the trade screen. Select desired pool and click "Swap".

<figure><img src="/files/6YRMUaw71Ftq6RMel9IK" alt=""><figcaption></figcaption></figure>

### **Q: Where do I check my liquidation price and funding rate?**

A: Click on the info button in the bottom right corner to see estimated funding rate and liquidation price on the trade screen

<figure><img src="https://lh5.googleusercontent.com/fqffSB2vEFPQpPPoA6cajJEUYXdlBdzMI9V5HWWxfs0E09NuqIewhlV5hYQsNH1XF6CspxOQt18IpQssrkl6WdKot_ZdyBRgV3kMLKlV7CEe4UX5s9IXbz-XLC8udHChWyGqDQJBgQJJF69fput0qlE" alt=""><figcaption></figcaption></figure>


# Audit

By Quantstamp

{% file src="/files/rYnslIDQ6wykpHzd3Jc4" %}

{% file src="/files/QrrUHAeIhmoQNsWCLA4g" %}


