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.
Protocol-Specific Leveraging
Curvance supports specialized implementations for different asset types. Each implementation has its own way of handling the auxData field in the leverage and deleverage structs.
Velodrome/Aerodrome LP Tokens
When leveraging Velodrome or Aerodrome LP positions:
// No special auxData needed for Velodrome/Aerodrome
const leverageData = {
borrowToken: E_TOKEN,
borrowAmount: ethers.utils.parseUnits('500', 18),
positionToken: P_TOKEN, // A Velodrome LP pToken
swapData: swapData,
auxData: '0x'
};
Pendle LP Tokens
For Pendle LP tokens, the auxData field contains important parameters:
// Encode Pendle-specific data for LP tokens
const pendleData = {
market: '0x...', // Pendle market address
tokenIn: borrowUnderlying,
tokenOut: '0x...', // SY token address
netTokenIn: ethers.utils.parseUnits('500', 18),
tokenOutMinAmount: ethers.utils.parseUnits('495', 18), // Min amount with slippage
swapData: [] // Additional Pendle swap data if needed
};
// Encode the auxData
const auxData = ethers.utils.defaultAbiCoder.encode(
['uint256', 'tuple(address,address,address,uint256,uint256,tuple[])'],
[ethers.utils.parseUnits('495', 18), pendleData]
);
const leverageData = {
borrowToken: E_TOKEN,
borrowAmount: ethers.utils.parseUnits('500', 18),
positionToken: P_TOKEN, // A Pendle LP pToken
swapData: swapData,
auxData: auxData
};
Pendle PT Tokens
For Pendle Principal Tokens, the auxData format differs slightly:
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!');
}