Compound SDK This SDK enables swapping collateral on open loan positions without the need to repay the loan, in a single transaction. It currently only supports Compound v3 Comet.
Feedback or help: please do not hesitate to contact us .
Demo
Compound Extensions tab
API Reference
The API Reference docs can be found at https://unpkg.com/@widolabs/collateral-swap-sdk@latest/docs/index.html .
Integration Guide
In this guide, we are going to use this SDK to swap one collateral for another on Compound v3, without repaying the loan taken against the collateral.
The example will assume the user (wallet) has some collateral deposited on the Comet contract, and a loan taken against it.
The steps we will follow are:
List existing supported Comet deployments
List supported collaterals on the Comet deployment
Fetch the user's collateral on a specific Comet deployment
Request a quote for swapping user's collateral for another token
Query the user's current position and the predicted position after the collateral swap
Execute the collateral swap, and check how the position finally looks
Preparation: Install Wido Collateral Swap SDK using NPM
Copy npm install --save @widolabs/collateral-swap-sdk
Step 1: Check which collaterals are supported on the Comet deployment
Copy import { WidoCompoundSdk } from "@widolabs/collateral-swap-sdk" ;
const deployments = WidoCompoundSdk .getDeployments ();
console .log (deployments);
// [
// { chainId: 1, asset: 'usdc', cometKey: 'mainnet_usdc' },
// { chainId: 1, asset: 'weth', cometKey: 'mainnet_weth' },
// { chainId: 137, asset: 'usdc', cometKey: 'polygon_usdc' },
// { chainId: 5, asset: 'usdc', cometKey: 'goerli_usdc' },
// { chainId: 5, asset: 'weth', cometKey: 'goerli_weth' },
// { chainId: 80001, asset: 'usdc', cometKey: 'mumbai_usdc' },
// { chainId: 420, asset: 'usdc', cometKey: 'goerli_optimism_usdc' },
// { chainId: 43113, asset: 'usdc', cometKey: 'fuji_usdc' }
// ]
All supported deployments will be returned, both from mainnets and testnets.
Step 2: Check which collaterals are supported on the Comet deployment
Copy import { WidoCompoundSdk } from "@widolabs/collateral-swap-sdk" ;
const provider = new Web3Provider ( window .ethereum);
const signer = provider .getSigner ();
const widoSdk = new WidoCompoundSdk (signer , "mainnet_usdc" )
const supportedAssets = await widoSdk .getSupportedCollaterals ();
console .log (supportedAssets);
// [
// {
// name: "COMP",
// address: '0xc00e94Cb662C3520282E6f5717214004A7f26888'
// decimals: 18,
// },
// {
// name: "WBTC",
// address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599'
// decimals: 8,
// },
// {
// name: "WETH",
// address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
// decimals: 18,
// },
// {
// name: "UNI",
// address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
// decimals: 18,
// },
// {
// name: "LINK",
// address: '0x514910771AF9Ca656af840dff83E8264EcF986CA'
// decimals: 18,
// },
// ]
Step 3: Fetch the user's collateral on a specific Comet deployment
Copy import { WidoCompoundSdk } from "@widolabs/collateral-swap-sdk" ;
const provider = new Web3Provider ( window .ethereum);
const signer = provider .getSigner ();
const widoSdk = new WidoCompoundSdk (signer , "mainnet_usdc" )
const userBalances = await widoSdk .getUserCollaterals ();
console .log (userBalances);
// [
// {
// name: 'COMP',
// address: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
// decimals: 18,
// balance: BigNumber { _hex: '0x00', _isBigNumber: true }
// },
// {
// name: 'WBTC',
// address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599',
// decimals: 8,
// balance: BigNumber { _hex: '0x00', _isBigNumber: true }
// },
// {
// name: 'WETH',
// address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
// decimals: 18,
// balance: BigNumber { _hex: '0x0de0b6b3a7640000', _isBigNumber: true }
// },
// {
// name: 'UNI',
// address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
// decimals: 18,
// balance: BigNumber { _hex: '0x00', _isBigNumber: true }
// },
// {
// name: 'LINK',
// address: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
// decimals: 18,
// balance: BigNumber { _hex: '0x00', _isBigNumber: true }
// }
// ]
Step 4: Request a quote to know how much final collateral we would end up with
Copy import { WidoCompoundSdk } from "@widolabs/collateral-swap-sdk" ;
import ethers from 'ethers' ;
const provider = new Web3Provider ( window .ethereum);
const signer = provider .getSigner ();
const widoSdk = new WidoCompoundSdk (signer , "mainnet_usdc" )
const amount = ethers . utils .parseEther ( "0.5" ); // amount value between 0 and value returned by `getUserCollaterals()`
const swapQuote = await widoSdk .getCollateralSwapRoute ( "WETH" , "COMP" , amount);
console .log (swapQuote);
// {
// isSupported: true,
// provider: 1,
// to: '0x7Fb69e8fb1525ceEc03783FFd8a317bafbDfD394',
// data: '0x...',
// tokenManager: '0xF2F02200aEd0028fbB9F183420D3fE6dFd2d3EcD',
// fromCollateral: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
// fromCollateralAmount: '500000000000000000',
// toCollateral: '0xc00e94Cb662C3520282E6f5717214004A7f26888',
// toCollateralAmount: '26238220177505992645',
// toCollateralMinAmount: '25975837975730933760',
// fees: {
// providerFee: 0.0004
// widoFee: 0.00103
// totalUsd: 0.42
// }
// }
Step 5: Check the user's current position and the predicted position after the swap
Copy import { WidoCompoundSdk } from "@widolabs/collateral-swap-sdk" ;
const provider = new Web3Provider ( window .ethereum);
const signer = provider .getSigner ();
const widoSdk = new WidoCompoundSdk (signer , "mainnet_usdc" )
const amount = ethers . utils .parseEther ( "0.5" );
const swapQuote = await widoSdk .getCollateralSwapRoute ( "WETH" , "COMP" , amount);
const currentPosition = await widoSdk .getUserCurrentPosition ();
const predictedPosition = await widoSdk .getUserPredictedPosition (swapQuote);
console .log (currentPosition);
// {
// collateralValue: 3570.5722302717495,
// liquidationPoint: 622.7533904370241,
// borrowCapacity: 2722.9021236902245,
// borrowAvailable: 2222.9980186902244
// }
console .log (predictedPosition);
// {
// collateralValue: 3565.1815966519125,
// liquidationPoint: 677.6477724359966,
// borrowCapacity: 2406.4960243373307,
// borrowAvailable: 1906.5919193373306
// }
The collateral value
of the position might change, generally decrease a bit due to protocol fees and slippage.
The borrow capacity
may also be changed because every collateral has different borrow factor.
Step 6: Execute the collateral swap, and check how the position finally looks
Copy import { WidoCompoundSdk } from "@widolabs/collateral-swap-sdk" ;
const provider = new Web3Provider ( window .ethereum);
const signer = provider .getSigner ();
const widoSdk = new WidoCompoundSdk (signer , "mainnet_usdc" )
const amount = ethers . utils .parseEther ( "0.5" );
const swapQuote = await widoSdk .getCollateralSwapRoute ( "WETH" , "COMP" , amount);
const txHash = await wido .swapCollateral (swapQuote)
console .log (txHash);
// 0x58274b1d8f8...
// wait for the tx to confirm
await provider .waitForTransaction (txHash)
const currentPosition = await widoSdk .getUserCurrentPosition ();
console .log (currentPosition);
// {
// collateralValue: 3565.1815966519125,
// liquidationPoint: 677.6477724359966,
// borrowCapacity: 2406.4960243373307,
// borrowAvailable: 1906.5919193373306
// }
Rebuilding the SDK when the user or the market changes
The SDK is built once and used across the whole process of collateral swapping. That is so most of the repeating values don't need to be constantly fed into all the functions.
In case the signer changes, we need to rebuild the SDK object to work properly. The same needs to be done if the selectedMarket
changes.
If you use React, the way you can do this is by using useMemo
or useEffect
, and keep the wallet provider and the account watched.
The following is an example using useMemo
:
Copy const widoSdk = useMemo (() => {
const signer = web3 .getSigner ();
return new WidoCompoundSdk (signer , selectedMarket)
} , [web3 , account , selectedMarket]);
This is how you can ensure the SDK object is always up-to-date.
Feedback or help: Please do not hesitate to contact us .