Skip to content

Commit

Permalink
Update APY calculations for SKY (#4030)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcinciarka authored Sep 23, 2024
1 parent 1ec5453 commit c718669
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 23 deletions.
25 changes: 19 additions & 6 deletions blockchain/better-calls/sky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import BigNumber from 'bignumber.js'
import { mainnetContracts } from 'blockchain/contracts/mainnet'
import { getRpcProvider, NetworkIds } from 'blockchain/networks'
import { amountToWad } from 'blockchain/utils'
import { SECONDS_PER_YEAR } from 'components/constants'
import { ethers } from 'ethers'
import {
SkyDaiUsds__factory,
Expand All @@ -10,6 +11,8 @@ import {
SkySusds__factory,
} from 'types/ethers-contracts'

const mkrSkySwapValue = 24 * 1000 // 1 MKR = 24000 SKY

export const skyDaiUsdsSwap = async ({
token,
amount,
Expand Down Expand Up @@ -133,23 +136,33 @@ export const skyUsdsWalletStakeDetails = async ({ ownerAddress }: { ownerAddress
}
}

export const skyUsdsStakeDetails = async () => {
export const skyUsdsStakeDetails = async ({ mkrPrice }: { mkrPrice?: BigNumber }) => {
if (!mkrPrice) {
return {
apy: new BigNumber(0),
totalUSDSLocked: new BigNumber(0),
}
}
const rpcProvider = getRpcProvider(1)
const skyStakingContract = new ethers.Contract(
mainnetContracts.sky.staking.address,
SkyStaking__factory.abi,
rpcProvider,
)
const skyPrice = mkrPrice.div(mkrSkySwapValue)
const [rewardRate, totalUSDSLocked] = await Promise.all([
skyStakingContract['rewardRate']().then((rewardPercentage: ethers.BigNumber) => {
return new BigNumber(ethers.utils.formatUnits(rewardPercentage, 18))
}),
skyStakingContract['totalSupply']().then((USDSLocked: ethers.BigNumber) => {
return new BigNumber(ethers.utils.formatUnits(USDSLocked, 18))
}),
skyStakingContract['totalSupply']().then(
(USDSLocked: ethers.BigNumber) => new BigNumber(ethers.utils.formatUnits(USDSLocked, 18)),
),
])
return { rewardRate, totalUSDSLocked } as {
rewardRate: BigNumber
const rewardsPerYear = rewardRate.times(SECONDS_PER_YEAR)
const rewardsPerYearPrice = rewardsPerYear.times(skyPrice)
const apy = rewardsPerYearPrice.div(totalUSDSLocked)
return { apy, totalUSDSLocked } as {
apy: BigNumber
totalUSDSLocked: BigNumber
}
}
6 changes: 3 additions & 3 deletions features/sky/components/stake/SkyStakePositionView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { VaultActionInput } from 'components/vault/VaultActionInput'
import type { ethers } from 'ethers'
import { showAllowanceInfo } from 'features/sky/helpers'
import { useSky } from 'features/sky/hooks/useSky'
import { formatCryptoBalance } from 'helpers/formatters/format'
import { formatCryptoBalance, formatDecimalAsPercent } from 'helpers/formatters/format'
import { zero } from 'helpers/zero'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
Expand All @@ -39,7 +39,7 @@ type SkyStakeViewType = {
earned: BigNumber
}
skyStakeData: {
rewardRate: BigNumber
apy: BigNumber
totalUSDSLocked: BigNumber
}
isOwner: boolean
Expand Down Expand Up @@ -303,7 +303,7 @@ export const SkyStakePositionView = ({
/>
<DetailsSectionContentCard
title="SKY Reward Rate"
value={`${formatCryptoBalance(skyStakeData.rewardRate)}`}
value={`${formatDecimalAsPercent(skyStakeData.apy, { noPercentSign: true })}`}
unit="%"
/>
<DetailsSectionContentCard
Expand Down
9 changes: 5 additions & 4 deletions handlers/portfolio/positions/handlers/sky/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import BigNumber from 'bignumber.js'
import { skyUsdsStakeDetails, skyUsdsWalletStakeDetails } from 'blockchain/better-calls/sky'
import { NetworkNames } from 'blockchain/networks'
import { OmniProductType } from 'features/omni-kit/types'
import type { PortfolioPositionsHandler } from 'handlers/portfolio/types'
import { formatCryptoBalance, formatPercent } from 'helpers/formatters/format'
import { formatCryptoBalance, formatDecimalAsPercent } from 'helpers/formatters/format'
import { LendingProtocol } from 'lendingProtocols'

export const skyPositionsHandler: PortfolioPositionsHandler = async ({ address }) => {
export const skyPositionsHandler: PortfolioPositionsHandler = async ({ address, prices }) => {
return Promise.all([
skyUsdsWalletStakeDetails({
ownerAddress: address,
}),
skyUsdsStakeDetails(),
skyUsdsStakeDetails({ mkrPrice: new BigNumber(prices.MKR) }),
]).then(([usdsWalletStakeDetails, usdsStakeDetails]) => {
return {
address,
Expand All @@ -31,7 +32,7 @@ export const skyPositionsHandler: PortfolioPositionsHandler = async ({ address }
},
{
type: 'apy',
value: formatPercent(usdsStakeDetails.rewardRate).toString(),
value: formatDecimalAsPercent(usdsStakeDetails.apy),
},
],
lendingType: 'passive',
Expand Down
16 changes: 11 additions & 5 deletions handlers/product-hub/update-handlers/sky/skyHandler.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { skyUsdsStakeDetails } from 'blockchain/better-calls/sky'
import { getNetworkContracts } from 'blockchain/contracts'
import { NetworkIds, networksById } from 'blockchain/networks'
import type { Tickers } from 'blockchain/prices.types'
import type { ProductHubItem, ProductHubSupportedNetworks } from 'features/productHub/types'
import type {
ProductHubHandlerResponse,
ProductHubHandlerResponseData,
} from 'handlers/product-hub/types'
import { skyProductHubProducts } from 'handlers/product-hub/update-handlers/sky/skyProducts'

async function getSkyData(networkId: NetworkIds.MAINNET): ProductHubHandlerResponse {
return Promise.all([skyUsdsStakeDetails()]).then(([srrData]) => {
async function getSkyData(
networkId: NetworkIds.MAINNET,
tickers: Tickers,
): ProductHubHandlerResponse {
return Promise.all([
skyUsdsStakeDetails({ mkrPrice: tickers['mkr-usd'] || tickers['mkr-maker'] }),
]).then(([srrData]) => {
return {
table: skyProductHubProducts
.map((product) => {
Expand All @@ -25,7 +31,7 @@ async function getSkyData(networkId: NetworkIds.MAINNET): ProductHubHandlerRespo
secondaryTokenAddress,
network: networksById[networkId].name as ProductHubSupportedNetworks,
hasRewards: true,
fee: srrData.rewardRate.toString(),
weeklyNetApy: srrData.apy.toFixed(2),
liquidity: srrData.totalUSDSLocked.toString(),
}
}
Expand All @@ -37,8 +43,8 @@ async function getSkyData(networkId: NetworkIds.MAINNET): ProductHubHandlerRespo
})
}

export default async function (): ProductHubHandlerResponse {
return Promise.all([getSkyData(NetworkIds.MAINNET)]).then((responses) => {
export default async function (tickers: Tickers): ProductHubHandlerResponse {
return Promise.all([getSkyData(NetworkIds.MAINNET, tickers)]).then((responses) => {
return responses.reduce<ProductHubHandlerResponseData>(
(v, response) => {
return {
Expand Down
3 changes: 2 additions & 1 deletion helpers/context/ProductContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,8 @@ export function setupProductContext(
const skyUsdsWalletStakeDetails$ = (ownerAddress?: string) =>
onEveryBlock$.pipe(() => fromPromise(skyUsdsWalletStakeDetails({ ownerAddress })))

const skyUsdsStakeDetails$ = () => onEveryBlock$.pipe(() => fromPromise(skyUsdsStakeDetails()))
const skyUsdsStakeDetails$ = (mkrPrice?: BigNumber) =>
onEveryBlock$.pipe(() => fromPromise(skyUsdsStakeDetails({ mkrPrice })))

return {
aaveLikeAvailableLiquidityInUSDC$: aaveV2Services.aaveLikeAvailableLiquidityInUSDC$,
Expand Down
11 changes: 7 additions & 4 deletions pages/earn/srr/[wallet].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const SkyStakeUsdsView = ({ walletAddress }: { walletAddress?: string }) => {
earned: BigNumber
}>()
const [tempSkyStakeData, setTempSkyStakeData] = useState<{
rewardRate: BigNumber
apy: BigNumber
totalUSDSLocked: BigNumber
}>()
const [tempBalancesData, setTempBalancesData] = useState<BigNumber[]>()
Expand All @@ -40,7 +40,10 @@ const SkyStakeUsdsView = ({ walletAddress }: { walletAddress?: string }) => {
allowanceForAccountEthers$,
skyUsdsWalletStakeDetails$,
skyUsdsStakeDetails$,
tokenPriceUSD$,
} = useProductContext()
const _tokenPriceUSD$ = useMemo(() => tokenPriceUSD$(['MKR']), [tokenPriceUSD$])
const [tokenPrices] = useObservable(_tokenPriceUSD$)
const [skyStakeWalletData, skyStakeWalletError] = useObservable(
useMemo(
() => (reloadingTokenInfo ? of(undefined) : skyUsdsWalletStakeDetails$(walletAddress)),
Expand All @@ -49,8 +52,8 @@ const SkyStakeUsdsView = ({ walletAddress }: { walletAddress?: string }) => {
)
const [skyStakeData, skyStakeError] = useObservable(
useMemo(
() => (reloadingTokenInfo ? of(undefined) : skyUsdsStakeDetails$()),
[skyUsdsStakeDetails$, reloadingTokenInfo],
() => (reloadingTokenInfo ? of(undefined) : skyUsdsStakeDetails$(tokenPrices?.MKR)),
[reloadingTokenInfo, skyUsdsStakeDetails$, tokenPrices?.MKR],
),
)
useEffect(() => {
Expand All @@ -62,7 +65,7 @@ const SkyStakeUsdsView = ({ walletAddress }: { walletAddress?: string }) => {
}
}, [skyStakeWalletData, tempSkyStakeWalletData])
useEffect(() => {
if (skyStakeData && !tempSkyStakeData?.rewardRate.isEqualTo(skyStakeData.rewardRate)) {
if (skyStakeData && !tempSkyStakeData?.apy.isEqualTo(skyStakeData.apy)) {
setTempSkyStakeData(skyStakeData)
}
}, [skyStakeData, tempSkyStakeData])
Expand Down

0 comments on commit c718669

Please sign in to comment.