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.
BETA: This SDK is currently being reviewed by the Compound team. Some changes might be made before final release. For questions, please reach out.
The API Reference docs can be found at https://unpkg.com/@widolabs/collateral-swap-sdk@latest/docs/index.html.
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:
- 1.List existing supported Comet deployments
- 2.List supported collaterals on the Comet deployment
- 3.Fetch the user's collateral on a specific Comet deployment
- 4.Request a quote for swapping user's collateral for another token
- 5.Query the user's current position and the predicted position after the collateral swap
- 6.Execute the collateral swap, and check how the position finally looks
npm install --save @widolabs/collateral-swap-sdk
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.
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,
// },
// ]
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 }
// }
// ]
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
// }
// }
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.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
// }
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
: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.
Last modified 3mo ago