dHEDGE V2 SDK
With the rollout of dHEDGE V2, this post aims to demonstrate how managers, traders and developers can easily plug-and-play with the V2 SDK , allowing the ability to leverage the new features and tools that V2 offers. For those who want to dive into an example implementation of the V2 SDK, feel free to check out the dHEDGE V2 SDK Examples repo!
A high level overview of the the dHEDGE V2 SDK:
- Built with ethers.js (version 5)
- Create and manage V2 pools from background app or your own dApp
- Easy-to-use functions to trade assets, provide liquidity or stake assets on Sushiswap
- Useful for creating automated trading bots
- Use in your Javascript or Typescript project with full Typescript support
To start, you will need to initialize the Factory with an ethers wallet and the network.
import { Dhedge, Dapp, Network, ethers } from "@dhedge/v2-sdk";const privateKey = "YOUR_PRIVATE_KEY";
const providerUrl = "https://polygon-mainnet.infura.io/v3/{YOUR_PROJECT_ID}"const provider = new ethers.providers.JsonRpcProvider(providerUrl);
const walletWithProvider = new ethers.Wallet(privateKey, provider);const dhedge = new Dhedge(walletWithProvider, Network.POLYGON);
Once initialized, you can easily create a pool by specifying the Manager Name, Pool Name, Symbol, the enabled assets for trading/depositing, and Manager Fee. Note that we have enabled USDC and DAI as assets that can be traded, but only allow USDC as the asset that can be deposited into this pool.
const usdcTokenAddress = "USDC_TOKEN_ADDRESS"
const daiTokenAddress = "DAI_TOKEN_ADDRESS"const pool = await dhedge.createPool(
"Day Ralio",
"Awesome Fund",
"DRAF",
[
[usdcTokenAddress, true],
[usdtTokenAddress, false],
],
10
)
console.log("created pool with address", pool.address)
To load your pool and fetch the pool composition:
const poolAddress = "YOUR_POOL_ADDRESS"
const pool = await dhedge.loadPool(poolAddress)
const composition = await pool.getComposition()
The ability to change the pool assets that are enabled/disabled is also straight forward. Currently, we have the Pool set to be able to trade USDC and USDT, but only allow USDC for deposits. Let’s change our enabled assets so USDT can be accepted for deposits and WETH enabled as an asset that can be traded (but not deposited).
const enabledAssets = [
{ asset: "USDC_TOKEN_ADDRESS", isDeposit: true },
{ asset: "DAI_TOKEN_ADDRESS", isDeposit: true },
{ asset: "WETH_TOKEN_ADDRESS", isDeposit: false },
]
const tx = await pool.changeAssets(enabledAssets)
A manager of a pool can also designate an address to act as a trader account which will allow the trader to only be able to make trades, swaps and stake. With these trading permissions set by setTrader()
, it ensures they cannot change the Manager Fee of the pool or withdraw a Managers stake.
const tx = await pool.setTrader("TRADER_ACCOUNT_ADDRESS")
Deposit
Before depositing an asset into a pool, one must first approve the asset for deposit. Here we will approve an unlimited amount of USDC for deposit into the pool.
const tx = await pool.approveDeposit("USDC_TOKEN_ADDRESS", ethers.constants.MaxUint256);
We will then deposit 1 USDC into the Pool
const usdcDepositAmount = "100000"
const tx = await pool.deposit("USDC_TOKEN_ADDRESS", usdcDepositAmount);
Withdraw
When wanting to withdraw funds from a pool, you must call withdraw()
with the pool token amount that is currently held. Note that this cannot be called if set as Trader account.
As an example, we withdraw 1.00002975 pool tokens here
const poolTokensWithdrawAmount = "1000029750000000000"
const tx = await pool.withdraw(poolTokensWithdrawAmount);
Trading
Before trading an asset on platforms like Sushiswap, it needs to be approved. Here we will approve an unlimited amount of USDC to trade on Sushiswap.
const tx = await pool.approve(
Dapp.SUSHISWAP,
"USDC_TOKEN_ADDRESS",
ethers.constants.MaxInt256
)
To demonstrate a simple trade on Sushiswap, lets swap 1 USDC into DAI.
const amountIn = "1000000"
const minAmountOut = "997085"
const tx = await pool.trade(
Dapp.SUSHISWAP,
"USDC_TOKEN_ADDRESS",
"DAI_TOKEN_ADDRESS",
amountIn,
minAmountOut
)
Liquidity
Adding liquidity to a Sushiswap pool (for example: USDC/DAI)
const amountUsdc = "1000000"
const amountDai = "997085"
const tx = await pool.addLiquidity(
Dapp.SUSHISWAP,
"USDC_TOKEN_ADDRESS",
"DAI_TOKEN_ADDRESS",
amountUsdc,
amountDai
)
Remove USDC/DAI worth of 1 Sushiswap LP from the liquidity pool
const amountSlpUsdcDai = "1000000000000000000"
const tx = await pool.removeLiquidity(
Dapp.SUSHISWAP,
"USDC_TOKEN_ADDRESS",
"DAI_TOKEN_ADDRESS",
amountSlpUsdcDai
)
Staking/Unstaking SLP & Harvesting Rewards
Enable an unlimited amount of SLP USDC-DAI token for staking on Sushiswap. Make sure to enable the SLP asset for USD/DAI pair before this!
const tx = await pool.approveStaking(
Dapp.SUSHISWAP,
"SLP_USDC_DAI_TOKEN_ADDRESS",
ethers.constants.MaxInt256
)
Stake 1 Sushiswap LP USDC/DAI token
const amountSlpUsdcDai = "1000000000000000000"
const tx = await pool.stake(
Dapp.SUSHISWAP,
"SLP_USDC_DAI_TOKEN_ADDRESS",
amountSlpUsdcDai
)
Unstake 1 Sushiswap LP USDC/DAI token
const amountSlpUsdcDai = "1000000000000000000"
const tx = await pool.unstake(
Dapp.SUSHISWAP,
"SLP_USDC_DAI_TOKEN_ADDRESS",
amountSlpUsdcDai
)
Harvest rewards from staked Sushiswap LP USDC/DAI tokens
const tx = await pool.harvestRewards(
Dapp.SUSHISWAP,
“SLP_USDC_DAI_TOKEN_ADDRESS”
)
Looking Ahead
The flexibility of the V2 framework will allow easy integrations with more protocols down the line, opening the door for a wider variety of strategies that managers and traders can take advantage of.
We hope that this post helps you get started in writing new strategies for your trading bots.
We appreciate your feedback and feel free to ping us on Discord!