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

fix, Uwu-lend #1313

Merged
merged 1 commit into from
Feb 28, 2024
Merged
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
8 changes: 4 additions & 4 deletions src/adapters/uwu-lend/ethereum/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getUWULendingPoolBalances, getUWULendingPoolContracts } from '@adapters/uwu-lend/ethereum/lending'
import { getLendingPoolHealthFactor } from '@lib/aave/v2/lending'
import type { AdapterConfig, BaseContext, Contract, GetBalancesHandler } from '@lib/adapter'
import { resolveBalances } from '@lib/balance'
import { getLendingPoolBalances, getLendingPoolContracts } from '@lib/geist/lending'
import { getMultiFeeDistributionContracts } from '@lib/geist/stake'
import type { Token } from '@lib/token'

Expand All @@ -25,7 +25,7 @@ const chefIncentivesControllerContract: Contract = {
name: 'ChefIncentivesController',
displayName: 'UwU incentives controller',
chain: 'ethereum',
address: '0x21953192664867e19F85E96E1D1Dd79dc31cCcdB',
address: '0xDB5C23ae97f76dacC907f5F13bDa54131C8e9e5a',
}

const UwU: Token = {
Expand All @@ -46,7 +46,7 @@ const UWU_WETH: Contract = {

export const getContracts = async (ctx: BaseContext) => {
const [pools, fmtMultiFeeDistributionContracts] = await Promise.all([
getLendingPoolContracts(ctx, lendingPoolContract, chefIncentivesControllerContract, UwU),
getUWULendingPoolContracts(ctx, lendingPoolContract, chefIncentivesControllerContract, UwU),
getMultiFeeDistributionContracts(ctx, multiFeeDistributionContract, UWU_WETH),
])

Expand All @@ -59,7 +59,7 @@ export const getContracts = async (ctx: BaseContext) => {
export const getBalances: GetBalancesHandler<typeof getContracts> = async (ctx, contracts) => {
const [balances, healthFactor] = await Promise.all([
resolveBalances<typeof getContracts>(ctx, contracts, {
pools: (...args) => getLendingPoolBalances(...args, chefIncentivesControllerContract),
pools: (...args) => getUWULendingPoolBalances(...args, chefIncentivesControllerContract),
fmtMultiFeeDistributionContracts: (...args) =>
getUWUMultiFeeDistributionBalances(...args, {
multiFeeDistribution: multiFeeDistributionContract,
Expand Down
138 changes: 138 additions & 0 deletions src/adapters/uwu-lend/ethereum/lending.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import {
getLendingPoolBalances as getAaveLendingPoolBalances,
getLendingPoolContracts as getAaveLendingPoolContracts,
} from '@lib/aave/v2/lending'
import type { Balance, BalancesContext, BaseContext, Contract } from '@lib/adapter'
import { keyBy, rangeBI } from '@lib/array'
import { call } from '@lib/call'
import { multicall } from '@lib/multicall'
import type { Token } from '@lib/token'

const abi = {
registeredTokens: {
inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
name: 'registeredTokens',
outputs: [{ internalType: 'address', name: '', type: 'address' }],
stateMutability: 'view',
type: 'function',
},
poolLength: {
inputs: [],
name: 'poolLength',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
claimableReward: {
inputs: [
{ internalType: 'address', name: '_user', type: 'address' },
{ internalType: 'address[]', name: '_tokens', type: 'address[]' },
],
name: 'claimableReward',
outputs: [{ internalType: 'uint256[]', name: '', type: 'uint256[]' }],
stateMutability: 'view',
type: 'function',
},
userBaseClaimable: {
inputs: [{ internalType: 'address', name: '', type: 'address' }],
name: 'userBaseClaimable',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
mintedTokens: {
inputs: [],
name: 'mintedTokens',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
} as const

export interface GetLendingPoolContractsParams {
ctx: BaseContext
lendingPool: Contract
chefIncentivesController: Contract
rewardToken: Token
}

/**
* Get AAVE LendingPool lending and borrowing contracts with rewards from ChefIncentives
*/

export async function getUWULendingPoolContracts(
ctx: BaseContext,
lendingPool: Contract,
chefIncentivesController: Contract,
rewardToken: Token,
) {
const contracts: Contract[] = []
const aaveLendingPoolContracts = await getAaveLendingPoolContracts(ctx, lendingPool)
const aaveLendingPoolContractsByAddress = keyBy(aaveLendingPoolContracts, 'address', { lowercase: false })
const lmRewardsCount = await call({ ctx, target: chefIncentivesController.address, abi: abi.poolLength })

const registeredTokensRes = await multicall({
ctx,
calls: rangeBI(0n, lmRewardsCount).map(
(idx) => ({ target: chefIncentivesController.address, params: [idx] }) as const,
),
abi: abi.registeredTokens,
})

for (const registeredTokenRes of registeredTokensRes) {
if (!registeredTokenRes.success) {
continue
}
const contract = aaveLendingPoolContractsByAddress[registeredTokenRes.output]
if (contract) {
contracts.push({ ...contract, rewards: [rewardToken] })
}
}

return contracts
}

export interface GetLendingPoolBalancesParams {
chefIncentivesController: Contract
}

export async function getUWULendingPoolBalances(
ctx: BalancesContext,
contracts: Contract[],
chefIncentivesController: Contract,
) {
const balances: Balance[] = []
const lendBalances = await getAaveLendingPoolBalances(ctx, contracts)
const balanceByAddress = keyBy(lendBalances, 'address', { lowercase: false })

const claimableRewards = await multicall({
ctx,
// @ts-ignore
calls: contracts.map((contract) => ({
target: chefIncentivesController.address,
params: [ctx.address, [contract.address]],
})),
abi: abi.claimableReward,
})

// Attach ChefIncentives rewards
for (let rewardIdx = 0; rewardIdx < claimableRewards.length; rewardIdx++) {
const claimableReward = claimableRewards[rewardIdx]

if (!claimableReward.success) {
continue
}

const balance = balanceByAddress[contracts[rewardIdx].address]
const reward = balance.rewards?.[0] as Contract

if (balance && reward) {
balances.push({
...(balance as Balance),
rewards: [{ ...(reward as Contract), amount: claimableReward.output[0] }],
})
}
}

return balances
}
10 changes: 8 additions & 2 deletions src/adapters/uwu-lend/ethereum/multifee.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Balance, BalancesContext, Contract, RewardBalance } from '@lib/adapter'
import { keyBy } from '@lib/array'
import { call } from '@lib/call'
import { abi as erc20Abi } from '@lib/erc20'
import { multicall } from '@lib/multicall'
import type { Token } from '@lib/token'
import { getUnderlyingBalances } from '@lib/uniswap/v2/pair'
Expand Down Expand Up @@ -90,6 +89,13 @@ const abi = {
stateMutability: 'view',
type: 'function',
},
totalLockedSupply: {
inputs: [],
name: 'totalLockedSupply',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function',
},
} as const

export interface GetMultiFeeDistributionBalancesParams {
Expand Down Expand Up @@ -137,7 +143,7 @@ export async function getUWUMultiFeeDistributionBalances(
call({ ctx, target: params.multiFeeDistribution.address, params: [ctx.address], abi: abi.claimableRewards }),
call({ ctx, target: params.multiFeeDistribution.address, params: [ctx.address], abi: abi.lockedBalances }),
call({ ctx, target: params.multiFeeDistribution.address, params: [ctx.address], abi: abi.earnedBalances }),
call({ ctx, target: params.multiFeeDistribution.address, abi: erc20Abi.totalSupply }),
call({ ctx, target: params.multiFeeDistribution.address, abi: abi.totalLockedSupply }),
multicall({
ctx,
calls: rewards.map((token) => ({ target: contract.address, params: [token.address] }) as const),
Expand Down
Loading