Leveraging in Curvance allows users to amplify their position by borrowing assets against their collateral and reinvesting them. This creates a more capital-efficient position with greater exposure to underlying assets.
Curvance's leveraging system is built on its powerful Position Management framework, which simplifies complex DeFi operations into single, atomic transactions. This eliminates the manual loop of borrowing, swapping, and depositing that would otherwise be required to build leveraged positions.
For those that want to dive deep into the inner workings of our leverage system, check out our Position Management page here:
Core Structures for Leveraging
To understand leveraging in Curvance, you need to be familiar with two key data structures that control the leverage and deleverage operations:
LeverageStruct
struct LeverageStruct {
IEToken borrowToken; // The eToken you want to borrow from
uint256 borrowAmount; // Amount of underlying tokens to borrow
IPToken positionToken; // The pToken to deposit borrowed funds into
SwapperLib.Swap swapData; // Instructions for swapping borrowed tokens
bytes auxData; // Optional protocol-specific data
}
DeleverageStruct
struct DeleverageStruct {
IPToken positionToken; // The pToken you're unwinding
uint256 collateralAmount; // Amount of pTokens to redeem
IEToken borrowToken; // The eToken debt to repay
SwapperLib.Swap[] swapData; // Array of swaps to execute
uint256 repayAmount; // Amount of debt to repay
bytes auxData; // Optional protocol-specific data
}
SwapperLib.Swap
Both structures use the SwapperLib.Swap structure to handle token swaps:
struct Swap {
address target; // Swap router address
address inputToken; // Token being swapped from
address outputToken; // Token being swapped to
uint256 inputAmount; // Amount to swap
bytes call; // Encoded swap call data
}
Important Note: LeverageStruct takes a single Swap while DeleverageStruct takes an array of Swap operations, allowing for multi-hop swaps when deleveraging.
Pre, Post, and Auxiliary Swap Operations
Pre-Swap when Leveraging
When leveraging, a swap is executed to obtain the collateral asset using the borrowed asset. You must provide the appropriate calldata hex string in the Swap.call struct member. Additionally, ensure the swap's receiver is set to the corresponding PositionManager contract.
Post-Swap when Deleveraging
During deleveraging, a swap is performed to exchange the collateral asset for the borrowed asset. You need to supply the correct calldata hex string in the Swap.call struct member. Also, make sure the swap's receiver is configured as the relevant PositionManager contract.
Auxiliary Swap for Complex Assets
When leveraging or deleveraging exotic assets, you may need to include auxiliary data to initiate the position. For instance, to enter a Pendle PT position, you must provide swap data to exchange the borrowed asset for Pendle PT via Pendle’s internal exchange.
Below is a code snippet demonstrating how to prepare this data:
Maintaining a healthy leverage ratio is crucial to avoid liquidation. Regularly check your position's health by using liquidationStatusOf() in the MarketManager contract. The function returns the lFactor and current prices for the specified tokens.
Function arguments:
Type
Name
Description
address
account
The account to check liquidation status for.
address
earnToken
The eToken (debt token) to be repaid during potential liquidation.
address
positionToken
The pToken (collateral token) to be seized during potential liquidation.
Which returns a tuple:
Type
Description
uint256
lFactor - Account's current liquidation factor. A value of 0 indicates a healthy position. A value between 0 and 1e18 (WAD) indicates a soft liquidation state. A value of 1e18 (WAD) indicates a hard liquidation state.
uint256
earnTokenPrice - Current price for the earnToken (debt token).
uint256
positionTokenPrice - Current price for the positionToken (collateral token).
// Get position status
const [lFactor, earnTokenPrice, pTokenPrice] = await marketManager.liquidationStatusOf(wallet.address, eToken_Address, pToken_Address);
// Check if position is at risk
if (status.gt(ethers.utils.parseUnits('0', 18))) {
console.log('⚠️ WARNING: Position at risk of liquidation!');
}