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.
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.
You can do this whole process without the Superfluid SDK but it simplifies the calls significantly. We recommend you use it but if you for some reason cannot use it for your project purposes, join our discord for guidance.
This tutorial assumes you know the difference between StIbAlluo and StIbAlluoUSD. Ricochet is only natively compatible with StIbAlluo so we are working with that token throughout. The user must have StIbAlluoUSD tokens rather than IbAlluoUSD to do this tutorial.
There are a couple work-arounds to this, including using a contract on chain, combining approvals and wrapping from IbAlluoUSD--> StIbAlluoUSD in the batchCall etc.
However here - for simplicity - we will only work with StIbAlluo (which is a simple wrapper for IbAlluo!)
npm install @superfluid-finance/sdk-core
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();
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.
Start the DCA!
1
const operations = [
2
sf.idaV1.approveSubscription({
3
superToken: StIbAlluoETH,
4
indexId: outputIndex.toString(),
5
publisher: twoWayMarketibAlluoUSDETHAddress,
6
userData
7
}),
8
sf.idaV1.approveSubscription({
9
superToken: subsidy,
10
indexId: subsidyIndex.toString(),
11
publisher: twoWayMarketibAlluoUSDETHAddress,
12
userData
13
}),
14
sf.cfaV1.createFlow({
15
superToken: StIbAlluoUSD,
16
sender: wallet.address,
17
receiver: twoWayMarketibAlluoUSDETHAddress,
18
flowRate: "120000000000000",
19
userData
20
}),
21
];
22
await sf.batchCall(operations).exec(signer);
BatchCall allows us to 'batch' together multiple superfluid calls so that the user only needs to approve one transaction. Great for UX!
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.
Full code snippet
1
import { Signer, Wallet } from "ethers";
2
import { ethers} from "hardhat"
3
import { Framework } from "@superfluid-finance/sdk-core";
4
5
async function main() {
6
7
// Key addresses
8
const StIbAlluoUSD = "0xE9E759B969B991F2bFae84308385405B9Ab01541"
9
const StIbAlluoETH = "0x2D4Dc956FBd0044a4EBA945e8bbaf98a14025C2d";
10
11
// Ric address and key ricochet parameters
12
const subsidy = "0x263026E7e53DBFDce5ae55Ade22493f828922965";
13
const subsidyIndex = 3;
14
const inputIndex =0 ;
15
const outputIndex =1;
16
const twoWayMarketibAlluoUSDETHAddress = '0xD0a8aeD52e80F99F7daDa1E22369B707437b6B34';
17
const userData = '0x';
18
19
// Setup
20
const provider = ethers.provider;
21
const sf = await Framework.create({
22
chainId: 137,
23
provider: provider,
24
});
25
let signer: Signer;
26
if (typeof mneumonic !== "string") {
27
return
28
}
29
signer = provider.getSigner();
30
31
const operations = [
32
sf.idaV1.approveSubscription({
33
superToken: StIbAlluoETH,
34
indexId: outputIndex.toString(),
35
publisher: twoWayMarketibAlluoUSDETHAddress,
36
userData
37
}),
38
sf.idaV1.approveSubscription({
39
superToken: subsidy,
40
indexId: subsidyIndex.toString(),
41
publisher: twoWayMarketibAlluoUSDETHAddress,
42
userData
43
}),
44
sf.cfaV1.createFlow({
45
superToken: StIbAlluoUSD,
46
sender: wallet.address,
47
receiver: twoWayMarketibAlluoUSDETHAddress,
48
flowRate: "120000000000000",
49
userData
50
}),
51
];
52
await sf.batchCall(operations).exec(signer);
53
}
54
55
main()
56
.then(() => process.exit(0))
57
.catch((error) => {
58
console.error(error);
59
process.exit(1);
60
});
61
Last modified 11mo ago