Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strkfarm #11213

Merged
merged 2 commits into from
Aug 6, 2024
Merged

Strkfarm #11213

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions projects/strkfarm/erc4626.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const ERC4626Abi = [
{
"name": "asset",
"type": "function",
"inputs": [],
"outputs": [
{
"type": "core::starknet::contract_address::ContractAddress"
}
],
"state_mutability": "view"
},
{
"name": "balanceOf",
"type": "function",
"inputs": [
{
"name": "account",
"type": "core::starknet::contract_address::ContractAddress"
}
],
"outputs": [
{
"type": "core::integer::u256"
}
],
"state_mutability": "view",
"customInput": 'address',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akiraonstarknet so, this is needed for some reason, dont ask me why (I did some hack long time ago), your code was failing because of this line

},
{
"name": "total_assets",
"type": "function",
"inputs": [],
"outputs": [
{
"type": "core::integer::u256"
}
],
"state_mutability": "view"
}
]

const ERC4626AbiMap = {}
ERC4626Abi.forEach(i => ERC4626AbiMap[i.name] = i)

module.exports = {
ERC4626AbiMap
}
80 changes: 80 additions & 0 deletions projects/strkfarm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* STRKFarm is a yield aggregator and strategy builder on Starknet
* - We use various DeFi protocols on starknet to design yield strategies
*/

const { multiCall } = require("../helper/chain/starknet");
const ADDRESSES = require('../helper/coreAssets.json');
const { ERC4626AbiMap } = require('./erc4626');
const { ERC721StratAbiMap } = require('./sensei');

const STRATEGIES = {
"AutoCompounding": [{ // auto-compounds user tokens (e.g. STRK) by investing in zkLend
address: "0x00541681b9ad63dff1b35f79c78d8477f64857de29a27902f7298f7b620838ea", // STRK Auto-compounding
token: ADDRESSES.starknet.STRK
}, {
address: "0x016912b22d5696e95ffde888ede4bd69fbbc60c5f873082857a47c543172694f", // USDC Auto-compounding
token: ADDRESSES.starknet.USDC
}],
"Sensei": [{ // strategy using delta neutral looping across zklend and nostra protocols
address: "0x020d5fc4c9df4f943ebb36078e703369c04176ed00accf290e8295b659d2cea6", // STRK Sensei
token: ADDRESSES.starknet.STRK,
zToken: '0x06d8fa671ef84f791b7f601fa79fea8f6ceb70b5fa84189e3159d532162efc21'
}, {
address: "0x04937b58e05a3a2477402d1f74e66686f58a61a5070fcc6f694fb9a0b3bae422",
token: ADDRESSES.starknet.USDC, // USDC Sensei
zToken: '0x047ad51726d891f972e74e4ad858a261b43869f7126ce7436ee0b2529a98f486'
}]
}

// returns tvl and token of the AutoCompounding strategies
async function computeAutoCompoundingTVL(api) {
const contracts = STRATEGIES.AutoCompounding;
// though these will be zToken (i.e. zkLend token, e.g. zUSDC),
// according to zkLend, 1zToken = 1 underlying token
// so, 1 zSTRK == 1 STRK, 1 zUSDC == 1 USDC
const totalAssets = await multiCall({
calls: contracts.map(c => c.address),
abi: ERC4626AbiMap.total_assets
});

api.addTokens(contracts.map(c => c.token), totalAssets);
}

// returns tvl and token of the Sensei strategies
async function computeSenseiTVL(api) {
// Sensei strategies contain multiple LP tokens in each contract bcz of looping and borrow,
// but we only consider the zToken bal divided by a factor (to offset looping) as TVL
// - This is bcz any deposit by user first gets deposited into zkLend for zToken
const contracts = STRATEGIES.Sensei;
const settings = await multiCall({
calls: contracts.map(c => c.address),
abi: ERC721StratAbiMap.get_settings
});

const DENOMINATOR_FACTOR = 1000000n;
const offsetFactors = settings.map(s => s.coefs_sum2); // The factor is in 10**6 terms
const balances = await multiCall({
calls: contracts.map(c => ({
target: c.zToken,
params: c.address,
})),
abi: ERC4626AbiMap.balanceOf
});

const adjustedBalances = balances.map((b, i) => (b * DENOMINATOR_FACTOR) / (DENOMINATOR_FACTOR + BigInt(offsetFactors[i])));
api.addTokens(contracts.map(c => c.token), adjustedBalances);
}

async function tvl(api) {
await computeAutoCompoundingTVL(api);
await computeSenseiTVL(api);
}

module.exports = {
doublecounted: true,
methodology: "The TVL is calculated as a sum of total assets deposited into strategies",
starknet: {
tvl,
},
};
41 changes: 41 additions & 0 deletions projects/strkfarm/sensei.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const ERC721StratAbi = [
{
"name": "get_settings",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "fee_percent",
"type": "core::integer::u128"
},
{
"name": "fee_receiver",
"type": "core::starknet::contract_address::ContractAddress"
},
{
"name": "min_health_factor",
"type": "core::integer::u32"
},
{
"name": "target_health_factor",
"type": "core::integer::u32"
},
{
"name": "coefs_sum1",
"type": "core::integer::u128"
},
{
"name": "coefs_sum2",
"type": "core::integer::u128"
}
],
"state_mutability": "view"
}
]

const ERC721StratAbiMap = {}
ERC721StratAbi.forEach(i => ERC721StratAbiMap[i.name] = i)

module.exports = {
ERC721StratAbiMap
}
Loading