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.

Pivot alert: Wido has become Walnut. This docs as well as the Wido Zap API will be discontinued. Read full announcement.

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:

  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

Preparation: Install Wido Collateral Swap SDK using NPM

npm install --save @widolabs/collateral-swap-sdk

Step 1: Check which collaterals are supported on the Comet deployment

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

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

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

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

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

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:

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.

Last updated