Skip to content

Commit def9ecf

Browse files
authored
Added kETH APR Adapter for lst-optimizer (#1070)
* Updated stakehouse adaptor to show APY for each LSD network * Fixed TVL issue * Accounted for unstaked validators * Added averge APY for all LSDs * Added kETH adapter
1 parent f2f4cfc commit def9ecf

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[
2+
{
3+
"inputs": [],
4+
"name": "totalAssets",
5+
"outputs": [
6+
{
7+
"internalType": "uint256",
8+
"name": "total",
9+
"type": "uint256"
10+
}
11+
],
12+
"stateMutability": "view",
13+
"type": "function"
14+
},
15+
{
16+
"inputs": [],
17+
"name": "assetsRatio",
18+
"outputs": [
19+
{
20+
"components": [
21+
{
22+
"internalType": "address",
23+
"name": "token",
24+
"type": "address"
25+
},
26+
{
27+
"internalType": "uint256",
28+
"name": "valueInETH",
29+
"type": "uint256"
30+
}
31+
],
32+
"internalType": "struct KETHStrategy.AssetRatio[]",
33+
"name": "info",
34+
"type": "tuple[]"
35+
}
36+
],
37+
"stateMutability": "view",
38+
"type": "function"
39+
}
40+
]

src/adaptors/lst-optimizer/index.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
const utils = require('../utils');
2+
const sdk = require('@defillama/sdk');
3+
const axios = require('axios');
4+
const { ethers } = require('ethers');
5+
6+
const kETHStrategyAbi = require('./abis/kETHStrategy.json');
7+
8+
const bigToNum = (bn) => {
9+
if (typeof(bn) == 'string')
10+
ethers.BigNumber.from(bn);
11+
12+
bn = ethers.utils.formatEther(bn);
13+
return Number(bn);
14+
}
15+
16+
const queryStakingAprs = async () => {
17+
const rETHResult = (await axios.get('https://dt4w6sqvtl.execute-api.eu-central-1.amazonaws.com/mainnet/')).data;
18+
const beaconChainApr = Number(rETHResult.beaconChainAPR) * 100;
19+
const rETH = Number(rETHResult.rethAPR) * 0.9;
20+
const dETH = (beaconChainApr * 32) / 24;
21+
22+
const stETHResult = (await axios.get('https://eth-api.lido.fi/v1/protocol/steth/apr/last')).data;
23+
const stETH = Number(stETHResult.data.apr) * 0.9;
24+
25+
return {stETH, rETH, dETH};
26+
}
27+
28+
const topLvl = async (chainString, underlying) => {
29+
30+
const kETHStrategyAddress = "0xa060a5F83Db8bf08b45Cf56Db370c9383b7B895C";
31+
const dETHVaultAddress = "0x4c7aF9BdDac5bD3bee9cd2Aa2FeEeeE7610f5a6B";
32+
const bsnFarmingAddress = "0x5CeCfAf8f8c2983A3336adbe836aF39192a72895";
33+
34+
const wstETHTokenAddress = "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0";
35+
const rETHTokenAddress = "0xae78736Cd615f374D3085123A210448E74Fc6393";
36+
const dETHTokenAddress = "0x3d1E5Cf16077F349e999d6b21A4f646e83Cd90c5";
37+
const savETHTokenAddress = "0x00ee7ea7ca2b5cc47908f0cad1f296efbde1402e";
38+
const gETHTokenAddress = "0xe550adfbcadaa86dfe05d0c67c2e6f27accf5cf1";
39+
40+
let kETHTvl = bigToNum((await sdk.api.abi.call({
41+
abi: kETHStrategyAbi.find(abi => abi.name == "totalAssets"),
42+
target: kETHStrategyAddress
43+
})).output);
44+
45+
let kETHAssets = (await sdk.api.abi.call({
46+
abi: kETHStrategyAbi.find(abi => abi.name == "assetsRatio"),
47+
target: kETHStrategyAddress,
48+
})).output;
49+
50+
const stETHValue = bigToNum(
51+
kETHAssets.find((item) =>
52+
item.token.toLowerCase() == wstETHTokenAddress.toLowerCase()
53+
).valueInETH )
54+
55+
56+
const rETHValue = bigToNum(
57+
kETHAssets.find((item) =>
58+
item.token.toLowerCase() == rETHTokenAddress.toLowerCase()
59+
).valueInETH)
60+
61+
62+
const dETHValue =
63+
bigToNum(
64+
kETHAssets.find((item) =>
65+
item.token.toLowerCase() == dETHTokenAddress.toLowerCase()
66+
).valueInETH
67+
) +
68+
bigToNum(
69+
kETHAssets.find((item) =>
70+
item.token.toLowerCase() == savETHTokenAddress.toLowerCase()
71+
).valueInETH
72+
) +
73+
bigToNum(
74+
kETHAssets.find((item) =>
75+
item.token.toLowerCase() == gETHTokenAddress.toLowerCase()
76+
).valueInETH
77+
)
78+
79+
const ethValue = kETHTvl - stETHValue - rETHValue - dETHValue
80+
81+
const stakingAprs = await queryStakingAprs();
82+
83+
const kETHApr =
84+
(stETHValue * stakingAprs.stETH +
85+
rETHValue * stakingAprs.rETH +
86+
dETHValue * stakingAprs.dETH +
87+
ethValue) /
88+
kETHTvl
89+
90+
const ethUSDPrice = (
91+
await axios.get(`https://coins.llama.fi/prices/current/ethereum:0x0000000000000000000000000000000000000000`)
92+
).data;
93+
94+
ethUsd = ethUSDPrice.coins['ethereum:0x0000000000000000000000000000000000000000'].price;
95+
96+
return [{
97+
pool: `${kETHStrategyAddress}-${chainString}`.toLowerCase(),
98+
chain: utils.formatChain(chainString),
99+
project: 'lst-optimizer',
100+
symbol: "kETH",
101+
tvlUsd: kETHTvl * ethUsd,
102+
apyBase: kETHApr,
103+
underlyingTokens: [wstETHTokenAddress, rETHTokenAddress, dETHTokenAddress],
104+
}];
105+
};
106+
107+
const main = async () => {
108+
const data = await topLvl (
109+
'ethereum',
110+
'0x0000000000000000000000000000000000000000'
111+
)
112+
113+
return data.flat();
114+
};
115+
116+
module.exports = {
117+
timetravel: false,
118+
apy: main,
119+
url: 'https://dapp.getketh.com/home/',
120+
};

0 commit comments

Comments
 (0)