Nov 28, 2023
Beyond the dYdX V4 Craze, An In-Depth Analysis of DeFi Leverage
This technical research report was authored by Polaris from the ScaleBit Research Group, with special thanks to Norman, also Henry from SnapFingers for their valuable revisions.
TL;DR
This article delves into the diversity and application scenarios of DeFi leverage, providing a detailed analysis of vulnerabilities at the code level. It also highlights key security considerations for leverage protocols.
Introduction to DeFi Leverage
The recent launch of dYdX V4 has sparked significant attention and participation in the world of perpetual contract exchanges. dYdX has successfully applied the cases of leveraged trading, and we should not only anticipate the immense potential of dYdX V4 but also prioritize the security of leverage protocols. The upcoming discussion will involve specific code analyses and examples to familiarize readers with various leverage strategies and security considerations.
What is Leverage
In the financial realm, leverage is a strategy that relies on borrowing funds to increase the potential returns on investments. In essence, investors or traders borrow capital to amplify exposure to a specific type of asset, project, or instrument far beyond what could be achieved solely with their own capital. Typically, by employing leverage, investors can magnify their purchasing power in the market.
Leverage in DeFi Trading
The use of leverage is one of the most crucial and common features in cryptocurrency asset trading. Shortly after the establishment of decentralized exchanges, despite the already high volatility in the crypto market, leveraging in trades has become increasingly popular.
Similar to traditional finance, traders employ leverage either merely to borrow funds and increase their purchasing power or to utilize various financial derivatives, such as futures and options.
Leverage ratios have also increased from 3x, 5x to over 100x. Higher leverage implies higher risk, but as observed in most centralized exchanges, with the growth of leveraged trading volumes, it’s a risk that aggressive traders seeking higher returns are willing to take.
In-Depth Classification of Leverage
In the context of DeFi, leveraged products can be primarily categorized into four types, each with its own distinct mechanism for generating leverage: leverage lending, margin trading leverage, perpetual contract leverage, and leveraged tokens.
Leverage Lending
DeFi lending and borrowing represent one of the earliest and largest applications within the DeFi space. Giants like MakerDao, Compound, AAVE, Venus, among others, operate in this market. The logic behind gaining leverage through lending crypto assets is straightforward.
For instance, if you hold \$10,000 worth of ETH and anticipate a bullish market, you can collateralize your ETH on Compound, borrow \$5,000 worth of USDC, and use this borrowed USDC to trade for an additional \$5,000 worth of ETH. This way, you gain 1.5x leverage on your ETH. In comparison to your initial \$10,000 capital, you now have an exposure of \$15,000 worth of ETH.
Similarly, if you anticipate a bearish market, you can deposit stablecoins and borrow ETH. If the price of ETH falls, you can purchase ETH at a lower price in the market and repay the debt.
It’s important to note that since you are borrowing from a decentralized protocol, there is a risk of liquidation if the value of your collateral drops or if the value of the borrowed assets exceeds a certain threshold.
Margin Trading Leverage
Through DeFi lending, you can use digital assets for various purposes. DeFi margin trading focuses more on increasing position size (amplifying purchasing power) and is considered a true “leverage position.” However, there is a crucial difference - while the margin position is still open, the trader’s assets act as collateral for the borrowed funds.
dYdX is a prominent decentralized margin trading platform that allows leverage of up to 5x. In dYdX’s margin trading, traders use their own funds as collateral, magnifying their original capital several times over, and use these leveraged funds for larger-scale investments.
Traders need to pay interest charges along with transaction-related fees. This position is not virtual; it involves actual borrowing and buying/selling.
If the market moves unfavorably, the trader’s assets may not be sufficient to fully repay the borrowed amount. To prevent this, the protocol will liquidate your position before reaching a certain liquidation ratio.
Regarding Changes in Leverage in Margin Trading -
Let’s say you are bullish on ETH with a 3x leverage in margin trading but prefer not to adjust your exposure frequently.
You hold \$100 USDC and borrow an additional \$200 USDC for trading \$300 worth of ETH to establish the desired ETH long position. The leverage level is \$300 / \$100 = 3x.
If the price of ETH rises by 20%, your profit will be \$300 * (1 + 20%) - \$300 = \$60. Your relative risk of liquidation is lower, and the actual leverage level decreases to \$360 / (\$360 - \$200) = 2.25x. In other words, your leverage automatically decreases when the price of ETH rises.
If the price of ETH falls by 20%, your loss will be \$300 * (1 - 20%) - \$300 = -\$60. In terms of liquidation risk, you are in a more precarious position, and the actual leverage level automatically increases to \$240 / (\$240 - \$200) = 6x. In other words, your leverage rebalances when the price of ETH falls, indicating that you are in a higher-risk position than before.
Therefore, even though you might think that maintaining a constant leverage is possible by engaging in fixed 3x margin trading, the real-time leverage is continually changing. Refer to the chart below to understand how leverage changes based on price movements[1].
Perpetual Contract Leverage
Perpetual contracts are similar to traditional futures contracts but lack an expiration date. Perpetual contracts mimic margin-based spot markets, and trading occurs close to the underlying reference index price.
Several DeFi projects, such as dYdX, MCDEX, Perpetual Protocol, Injective, among others, offer perpetual contracts for traders. Many traders might find it challenging to distinguish between margin trading and perpetual contracts - in reality, both involve user leverage.
However, there are some differences in leverage mechanisms, fees, and leverage levels.
Perpetual contracts are a type of derivative product for trading synthetic assets, featuring characteristics of trading on margin. They track the underlying asset’s price synthetically, without the need to trade the actual underlying asset. On the other hand, margin trading involves actual borrowing and trading of real crypto assets.
With the advent of perpetual contracts, the concept of funding rates emerged to maintain the perpetual contract’s trading price in line with the underlying reference price. If the contract price is higher than the spot price, long positions pay shorts. In other words, traders need to continually pay fees for their borrowings.
Leverage in perpetual contracts is typically higher than leverage in margin trading and can go up to 100x. Liquidation and the actual leverage mechanism are similar to margin trading.
Leveraged Tokens
Leveraged tokens are derivatives that provide holders with leveraged exposure to the cryptocurrency market without the need for active management of leveraged positions. While they offer leveraged exposure, holders are not required to deal with margin, liquidation, collateral, or funding rates.
The key distinction between leveraged tokens and margin trading/perpetual contracts is that leveraged tokens are periodically or rebalanced upon reaching a certain threshold to maintain a specific level of leverage.
This is notably different from margin trading and perpetual contracts, where the actual leverage of these products changes continuously based on price volatility, even if a trader may have initially specified a certain leverage level.
Let’s examine how the rebalancing works in the example of the 3x ETH mentioned above:
Suppose you hold \$100 USDC and purchase a leveraged token, ETHBULL (3x). The protocol automatically borrows \$200 USDC and trades it for \$200 worth of ETH.
Assuming the price of ETH rises by 20%, and the price of the token, ETHBULL (3x), increases to \$300 * (1 + 20%) - \$200 = \$160 before rebalancing. Now, your actual leverage becomes 2.25 (360 / 160), which is below the target leverage.
As part of the rebalancing process, the protocol borrows more USDC from the stablecoin pool and purchases additional ETH tokens to bring the leverage back to 3x. In our example, the protocol borrows an additional \$120 and exchanges it for ETH. Therefore, the total leverage becomes (360 + 120) / 160 = 3x again.
If the price of ETH falls by 20%, and the price of the token, ETHBULL (3x), decreases to \$300 * (1 - 20%) - \$200 = \$40 before rebalancing. Now, your actual leverage becomes 6 (240 / 40), which is above the target leverage.
In this scenario, the protocol sells ETH tokens and repays the outstanding debt to reduce leverage. In this example, the protocol sells \$120 worth of ETH to pay back to the pool. The debt becomes \$80, and the total leverage becomes (240 - 120) / 40 = 3x again.
In other words, leveraged tokens automatically re-leverage in profit and de-leverage in losses to restore their target leverage level. If this mechanism operates effectively, holders of leveraged tokens are less likely to be liquidated even in unfavorable market trends because the de-leveraging mechanism continuously reduces the user’s effective leverage level.
Therefore, the lending pool in the leveraged tokens model is immune to liquidation risks, making it safer than lending pools in margin trading.
Use Cases of Leverage
Now that we have an understanding of some common types of leveraged DeFi protocols, let’s delve into specific DeFi protocols to explain the applications of leverage.
GMX
GMX[2] is a decentralized spot and perpetual exchange, offering traders the ability to trade assets with leverage of up to 50x. The protocol currently operates on Arbitrum and Avalanche. On GMX, traders have full knowledge of their counterparties, which is completely different from trading on centralized exchanges (CEX). Unlike other perpetual contract protocols like dYdX, GMX operates entirely on-chain and utilizes Automated Market Maker (AMM) functionality for leveraged trading.
What sets GMX apart from other services is that it is a decentralized exchange providing leveraged trading services. In this aspect, it combines the experience of other DeFi exchanges like Uniswap with the leveraged trading services provided by platforms like Binance.
GMX features a liquidity pool known as GLP, a multi-asset pool designed to provide liquidity for margin trading. Users can engage in long/short positions and execute trades by minting and burning GLP tokens. The pool earns LP fees from regular trades and leverage transactions, with these fees being distributed to GMX and GLP holders.
To engage in leveraged trading, traders deposit collateral into the protocol. They have the option to choose leverage up to a maximum of 50x, where higher leverage corresponds to a higher liquidation price. As borrowing costs increase, the liquidation price gradually rises.
For example, when going long on ETH, traders are essentially “renting” the upward potential of ETH from the GLP pool. Conversely, when shorting ETH, traders are “renting” the stablecoin’s upward potential relative to ETH from the GLP pool. However, the assets in the GLP pool are not actually being rented out.
Upon closing a position, if the trader made the correct prediction, profits are paid in the form of tokens from the GLP pool for the long position. Otherwise, losses are deducted from the collateral and paid into the pool. GLP profits from the trader’s losses and gains a share from the trader’s profits.
Throughout this process, traders pay trading fees, opening/closing fees, and borrowing fees in exchange for the upward potential of specified tokens (BTC, ETH, AVAX, UNI, and LINK) against the US dollar in long/short positions.
Merkle Trade
Merkle Trade[3] is a decentralized trading platform that offers cryptocurrency, forex, and commodity trading with leverage of up to 1,000x, along with user-centric advanced trading features. Supported by the Aptos blockchain, Merkle Trade boasts top-notch performance and scalability. Compared to Gains Network, Merkle Trade offers lower trading latency and fees while providing the same high leverage.
Unlike most exchanges, Merkle Trade does not have an order book. Instead, Merkle LP acts as the counterparty for each trade, collecting collateral when traders incur losses and paying profits on closed trades with positive returns.
- Trade Cryptocurrencies, Forex, and Commodities with Leverage up to 1,000x
Merkle Trade aims to provide a wide range of trading pairs from the start, including cryptocurrencies, forex, and commodities, offering some of the highest leverage in the market, reaching up to 150x in cryptocurrencies and up to 1,000x in forex.
- Fair Price Order Execution, Millisecond Latency, Minimal Slippage
Leveraging the Aptos with the lowest latency to date to generate blockchains, Merkle Trade delivers the fastest on-chain trading experience. For traders, this means quicker transaction experience and smaller price slippage resulting from execution delays.
- Decentralized, Non-Custodial Trading with No Counterparty Risk
Traders engage with the liquidity pool (Merkle LP), which serves as the counterparty for every trade on the protocol. All trades and settlements are executed by smart contracts, ensuring that user funds are never held at any point.
- Lowest Fees
Merkle Trade claims to have some of the lowest fees in the market to date. At launch, fees for cryptocurrency trading pairs are as low as 0.05%, and for forex trading pairs, fees go down to 0.0075%.
dYdX
dYdX[4] is a decentralized exchange (DEX) that empowers users to efficiently trade perpetual contracts while maintaining full control over their assets. Since its launch in 2021, dYdX V3 has employed a unique non-custodial Layer 2 scaling solution to facilitate its exchange, but its order book and matching engine are still centrally managed.
Now, with dYdX V4, the protocol is evolving to have its own chain, undergoing a comprehensive overhaul to achieve complete decentralization while increasing throughput. dYdX encompasses three main functionalities: lending, leveraged trading, and perpetual contracts. Leveraged trading includes a built-in lending feature, where funds deposited by users automatically form a liquidity pool. In case of insufficient funds during a trade, the system automatically borrows and pays interest.
Security Analysis of Leverage
After introducing common types and applications of leverage in DeFi, it’s crucial to note that there are still many security issues in the design of leverage. We will now combine specific audit cases to analyze the security concerns and audit focal points in DeFi leverage.
Distinguishing Limit Orders from Market Orders
In most leveraged exchange applications, both limit orders and market orders exist. It is crucial to rigorously distinguish and validate between limit orders and market orders. Next, we will conduct a detailed analysis based on the issues identified in Merkle Trade audit[5].
let now = timestamp::now_seconds();
if (now - order.created_timestamp > 30) {
cancel_order_internal<PairType, CollateralType>(
_order_id,
order,
T_CANCEL_ORDER_EXPIRED
);
return
};
The provided code snippet is part of the validation process within the order execution function. In this function, it checks whether the order has exceeded 30 seconds since its creation. If the condition is met, it invokes the cancel_order_internal()
function to cancel the order. However, if the order is a limit order, it implies that the trader has set a specific price at which they are willing to buy or sell the asset. The time when executing limit orders should not be assessed, as it may result in the majority of limit orders not being executed. Therefore, a strict differentiation in the trading logic between limit orders and market orders is of utmost importance.
Calculation Error in Leverage
Calculation errors have consistently been a common issue in DeFi, particularly in the context of leverage. We will delve into the calculation issues related to leverage using the issues identified in the third-party audit of the Unstoppable[6] protocol as an example.
Let’s take a closer look at the code used for leverage calculation in Unstoppable:
def _calculate_leverage(
_position_value: uint256, _debt_value: uint256, _margin_value: uint256
) -> uint256:
if _position_value <= _debt_value:
# bad debt
return max_value(uint256)
return (
PRECISION
* (_debt_value + _margin_value)
/ (_position_value - _debt_value)
/ PRECISION
)
The _calculate_leverage
function incorrectly calculates leverage by using _debt_value + _margin_value as the numerator instead of _position_value. All three input parameters of this function, _position_value, _debt_value, and _margin_value, are determined by price information provided by the Chainlink oracle. Specifically, _debt_value represents the value of converting the debt share of the position into the amount of USD debt. _margin_value represents the current value (in USD) of the initial margin amount of the position. _position_value represents the current value (in USD) of the initial position amount.
The problem with the calculation lies in the fact that _debt_value + _margin_value does not represent the value of the position. Leverage is the ratio between the current position value and the current margin value. _position_value - _debt_value is correct as it represents the current margin value. However, _debt_value + _margin_value does not represent the current value of the position, as there is no guarantee that the debt token and position token have correlated price volatility.
Example: Assuming the debt token is ETH and the position token is BTC.
Alice uses 1 ETH as margin, borrows 14 ETH (each ETH valued at \$2,000), and obtains 1 BTC (each BTC valued at \$30,000) as position token. The leverage is 14.
The next day, while the price of ETH remains at \$2,000 per ETH, the price of BTC drops from \$30,000 per BTC to \$29,000 per BTC. At this point, the correct leverage should be (_position_value == \$29,000) / (_position_value == \$29,000 - _debt_value == \$28,000) = 29, instead of the value calculated in the contract: (_debt_value == \$28,000 + _margin_value == \$2,000) / (_position_value == \$29,000 - _debt_value == \$28,000) = 30.
Therefore, to address this issue, the correct formula mentioned above should be used to calculate leverage in the smart contract. Calculation errors in leverage can lead to unfair liquidation or the existence of overleveraged positions during price volatility.
In smart contracts, ensuring the correct calculation of leverage is crucial for maintaining the robustness of the system and protecting the interests of users. The proper calculation of leverage should be based on the ratio between the current value of the position and the current value of the margin. If an incorrect calculation formula is used, it may result in the system responding inappropriately to price changes, potentially liquidating positions that shouldn’t be liquidated, or allowing excessively leveraged positions to persist, thereby increasing risks for both the system and users.
Logic Error
Logic errors require particular attention in smart contract audits, especially within the complex logic of DeFi leveraged trading.
Let’s discuss the issue identified in a third-party audit of Tigris[7] (Tigris is a decentralized synthetic leveraged trading platform based on Arbitrum and Polygon), highlighting logical concerns in DeFi leveraged trading.
Examining the logic of the limit close function in Tigris:
function limitClose(
uint _id,
bool _tp,
PriceData calldata _priceData,
bytes calldata _signature
)
external
{
_checkDelay(_id, false);
(uint _limitPrice, address _tigAsset) = tradingExtension._limitClose(_id, _tp, _priceData, _signature);
_closePosition(_id, DIVISION_CONSTANT, _limitPrice, address(0), _tigAsset, true);
}
function _limitClose(
uint _id,
bool _tp,
PriceData calldata _priceData,
bytes calldata _signature
) external view returns(uint _limitPrice, address _tigAsset) {
_checkGas();
IPosition.Trade memory _trade = position.trades(_id);
_tigAsset = _trade.tigAsset;
getVerifiedPrice(_trade.asset, _priceData, _signature, 0);
uint256 _price = _priceData.price;
if (_trade.orderType != 0) revert("4"); //IsLimit
if (_tp) {
if (_trade.tpPrice == 0) revert("7"); //LimitNotSet
if (_trade.direction) {
if (_trade.tpPrice > _price) revert("6"); //LimitNotMet
} else {
if (_trade.tpPrice < _price) revert("6"); //LimitNotMet
}
_limitPrice = _trade.tpPrice;
} else {
if (_trade.slPrice == 0) revert("7"); //LimitNotSet
if (_trade.direction) {
if (_trade.slPrice < _price) revert("6"); //LimitNotMet
} else {
if (_trade.slPrice > _price) revert("6"); //LimitNotMet
}
//@audit stop loss is closed at user specified price NOT market price
_limitPrice = _trade.slPrice;
}
}
When using stop-loss close, the user’s close price is set by them rather than the current asset price. In directional markets and high-leverage scenarios, users may exploit this to achieve nearly risk-free trades. A user can open a long position and set a stop-loss price, which is \$0.01 lower than the current price.
If the price immediately falls in the next update, they can close at their entry price, only incurring opening and closing fees. If the price rises, they have the potential to gain substantial profits. This allows users to abuse the stop-loss price setting method, opening trades with high leverage, significant upward potential, and minimal downward risk.
Price Volatility
Price volatility has a significant impact on DeFi leverage, and considering it at all times is crucial to ensuring the safety of leverage protocols. Let’s delve into an example from the third-party audit of the DeFiner[8] protocol to analyze the issue:
The DeFiner protocol conducts two checks before processing a withdrawal.
Firstly, the method checks if the requested withdrawal amount exceeds the balance of the asset:
function withdraw(address _accountAddr, address _token, uint256 _amount) external onlyAuthorized returns(uint256) {
// Check if withdraw amount is less than user's balance
require(_amount <= getDepositBalanceCurrent(_token, _accountAddr), "Insufficient balance.");
uint256 borrowLTV = globalConfig.tokenInfoRegistry().getBorrowLTV(_token);
Secondly, the method checks if the withdrawal would result in the user’s leverage ratio being too high. The withdrawn amount is subtracted from the user’s “borrow power” at the current price. If the user’s total borrowed value exceeds the new borrow power, the method fails because the user no longer has sufficient collateral to support their borrowing position. However, this require will only be checked if the user is not already over-leveraged:
if(getBorrowETH(_accountAddr) <= getBorrowPower(_accountAddr))
require(
getBorrowETH(_accountAddr) <= getBorrowPower(_accountAddr).sub(
_amount.mul(globalConfig.tokenInfoRegistry().priceFromAddress(_token))
.mul(borrowLTV).div(Utils.getDivisor(address(globalConfig), _token)).div(100)
), "Insufficient collateral when withdraw.");
If the borrowed funds exceed the allowable amount of their “borrow power,” the withdrawal is allowed regardless. This situation may arise in various scenarios, with the most common being price volatility. The protocol did not consider the impact of price volatility on the protocol, leading to this issue.
Others
In addition to the issues mentioned above, such as the lack of distinction between limit orders and market orders, also the impact of calculation errors, logic errors, and price volatility, there are many other security considerations related to leverage protocols that require attention. These include but are not limited to flash loan attacks, price manipulation, oracle security, permission controls, insufficient or lacking checks in leverage verification, and more. When designing and implementing leverage protocols, careful consideration of these factors is essential to ensure the robustness of the protocol and the security of user assets. Preventive measures, real-time monitoring, and emergency response plans are also crucial to mitigate potential risks and safeguard user interests.
Conclusion
The introduction of leveraged trading in DeFi protocols has indeed provided the market with greater operability, but it has also brought about more complex trading mechanisms. While leveraged trading offers users more investment opportunities, the potential risks and challenges to protocol security have become more significant.
With the increase in leverage, protocol operations become more flexible but also more fragile, making them more susceptible to various security threats. This includes potential issues such as the lack of strict distinction between limit orders and market orders, calculation errors, logical errors, and price volatility, these factors result in extreme sensitivity. In such circumstances, a heightened focus on protocol security is necessary to ensure effective protection of user assets.
ScaleBit, a leading blockchain security team of Web3, spans across Silicon Valley, Singapore, Hong Kong, Taiwan, and beyond. We’ve successfully delivered blockchain security solutions to over 200 global institutions and projects, auditing more than 180,000 lines of code and safeguarding assets exceeding 8 billion USD. Make Security Accessible for All! Our mission is to provide security solutions for Web3 Mass Adoption. If you have any security audit needs, feel free to reach out anytime. We specialize in tailoring meticulous, comprehensive, and professional solutions to ensure robust security for both you and the entire Web3 ecosystem!
Reference
[2] https://app.gmx.io/#/dashboard
[3] https://docs.merkle.trade/
[5] https://docs.merkle.trade/resources/audit
[6] https://www.unstoppable.ooo/
About ScaleBit
ScaleBit is a blockchain security team that provides security solutions for Mass Adoption of Web3. With expertise in scaling technologies like blockchain interoperability and zero-knowledge proofs, we provide meticulous and cutting-edge security audits for blockchain applications. The team comprises security professionals with extensive experience in both academia and enterprise. Our mission is to provide security solutions for Web3 Mass Adoption and make security accessible for all.
- Website: https://www.scalebit.xyz/
- Twitter: https://twitter.com/scalebit_