Example: Using IbAlluoUSD and Ricochet to do capital efficient DCA into ETH
This tutorial walks through how users can use IbAlluo to most capital efficiently dollar cost average into assets by constantly earning yield on both sides of the transaction.
The most capital efficient way to buy an asset
If you were to do standard DCA from USDC --> ETH, it would actually not be the most capital efficient because your assets on both sides (USDC before it is DCAed and ETH after you have DCAed) are sitting idle instead of earning yield.
Using IbAlluo can boost your returns on both sides if you were to do IbAlluoUSD --> IbAlluoETH. Your USD is earning yield with Alluo before it is converted to IbAlluoETH and your IbAlluoETH will continue to earn yield.
Ricochet Exchange has built on top of the Alluo ecosystem so that users can do exactly this, boosting DCA yields by over 5% simply by making sure that assets on both sides of the DCA stream are being used efficiently in the DeFi ecosystem.
Going from IbAlluoUSD to DCAing into IbAlluoETH
1. Set up the Superfluid SDK
npm install @superfluid-finance/sdk-core
2. Set key constants and parameters
Import key dependencies, set up addresses and set up the signer.
All the Ricochet parameters are unique for each DCA pair. If you need more guidance on this , reach out on discord.
import { Signer, Wallet } from "ethers";
import { ethers} from "hardhat"
import { Framework } from "@superfluid-finance/sdk-core";
async function main() {
// Key addresses
const StIbAlluoUSD = "0xE9E759B969B991F2bFae84308385405B9Ab01541"
const StIbAlluoETH = "0x2D4Dc956FBd0044a4EBA945e8bbaf98a14025C2d";
// Ric address and key ricochet parameters
const subsidy = "0x263026E7e53DBFDce5ae55Ade22493f828922965";
const subsidyIndex = 3;
const inputIndex =0 ;
const outputIndex =1;
const twoWayMarketibAlluoUSDETHAddress = '0xD0a8aeD52e80F99F7daDa1E22369B707437b6B34';
const userData = '0x';
// Setup
const provider = ethers.provider;
const sf = await Framework.create({
chainId: 137, //your chainId here
provider: provider,
});
let signer: Signer;
if (typeof mneumonic !== "string") {
return
}
signer = provider.getSigner();
3. Encode correct function calls
The first two operations are approving Ricochet Exchange to 'airdrop' IbAlluoETH and RIC (Ricochet native incentive tokens) to us. This is how Ricochet distributes DCA'd assets.
The last createFlow operation creates a flow of 0.00012 IbAlluoUSD per second to be DCA'd - equivalently 311.04 IbAlluoUSD per month.
const operations = [
sf.idaV1.approveSubscription({
superToken: StIbAlluoETH,
indexId: outputIndex.toString(),
publisher: twoWayMarketibAlluoUSDETHAddress,
userData
}),
sf.idaV1.approveSubscription({
superToken: subsidy,
indexId: subsidyIndex.toString(),
publisher: twoWayMarketibAlluoUSDETHAddress,
userData
}),
sf.cfaV1.createFlow({
superToken: StIbAlluoUSD,
sender: wallet.address,
receiver: twoWayMarketibAlluoUSDETHAddress,
flowRate: "120000000000000",
userData
}),
];
await sf.batchCall(operations).exec(signer);
Why batchCall?
BatchCall allows us to 'batch' together multiple superfluid calls so that the user only needs to approve one transaction. Great for UX!
When do we need to approveSubscription to Ricochet?
Only the first time you start the DCA. The second time the user wants to createFlow, updateFlow or DeleteFlow, there is no need to do so. However, if the user wants to DCA into a different asset pair (say IbAlluoUSD --> IbAlluoBTC), this needs to be setup again with the appropriate parameters.
If you do not approveSubscription, you will not receive your DCA'd rewards so please ensure that you do so.
import { Signer, Wallet } from "ethers";
import { ethers} from "hardhat"
import { Framework } from "@superfluid-finance/sdk-core";
async function main() {
// Key addresses
const StIbAlluoUSD = "0xE9E759B969B991F2bFae84308385405B9Ab01541"
const StIbAlluoETH = "0x2D4Dc956FBd0044a4EBA945e8bbaf98a14025C2d";
// Ric address and key ricochet parameters
const subsidy = "0x263026E7e53DBFDce5ae55Ade22493f828922965";
const subsidyIndex = 3;
const inputIndex =0 ;
const outputIndex =1;
const twoWayMarketibAlluoUSDETHAddress = '0xD0a8aeD52e80F99F7daDa1E22369B707437b6B34';
const userData = '0x';
// Setup
const provider = ethers.provider;
const sf = await Framework.create({
chainId: 137,
provider: provider,
});
let signer: Signer;
if (typeof mneumonic !== "string") {
return
}
signer = provider.getSigner();
const operations = [
sf.idaV1.approveSubscription({
superToken: StIbAlluoETH,
indexId: outputIndex.toString(),
publisher: twoWayMarketibAlluoUSDETHAddress,
userData
}),
sf.idaV1.approveSubscription({
superToken: subsidy,
indexId: subsidyIndex.toString(),
publisher: twoWayMarketibAlluoUSDETHAddress,
userData
}),
sf.cfaV1.createFlow({
superToken: StIbAlluoUSD,
sender: wallet.address,
receiver: twoWayMarketibAlluoUSDETHAddress,
flowRate: "120000000000000",
userData
}),
];
await sf.batchCall(operations).exec(signer);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Last updated