Skip to content

Commit

Permalink
Feat: Add pUSDInStabilityPool dynamic, price fetch dynamic for wBTC
Browse files Browse the repository at this point in the history
  • Loading branch information
JAYDARANIYA committed Feb 5, 2024
1 parent f9846b8 commit 8afeea9
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 29 deletions.
20 changes: 18 additions & 2 deletions src/components/Params.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import BigNumber from "bignumber.js";
import { Params as ParamsType } from "../utils/types";

type ParamsProps = {
Expand All @@ -6,9 +7,17 @@ type ParamsProps = {
totalColl: string;
totalDebt: string;
vaultCount: string;
pUSDInStabilityPool: string;
};

const Params = ({ mcr, baseRate, totalColl, totalDebt, vaultCount }: ParamsProps) => {
const Params = ({
mcr,
baseRate,
totalColl,
totalDebt,
vaultCount,
pUSDInStabilityPool
}: ParamsProps) => {
return (
<div className="bg-white shadow-lg rounded-lg p-6 bg-gradient-to-r from-blue-200 to-blue-400 w-full md:w-[45%]">
<h3 className="text-xl mb-2 font-semibold border-b pb-2">Neper statistics</h3>
Expand Down Expand Up @@ -43,7 +52,14 @@ const Params = ({ mcr, baseRate, totalColl, totalDebt, vaultCount }: ParamsProps
</li>
<li className="flex justify-between py-1">
<span>pUSD in Stability Pool</span>
<span className="font-medium">83.3M (57.1%)</span>
<span className="font-medium">
{pUSDInStabilityPool} pUSD (
{BigNumber(pUSDInStabilityPool)
.dividedBy(BigNumber(totalDebt))
.multipliedBy(100)
.toFixed(2)}
%)
</span>
</li>
</ul>
</div>
Expand Down
102 changes: 79 additions & 23 deletions src/context/AppContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { JsonRpcProvider, JsonRpcSigner, ethers, parseEther } from "ethers";
import React, { createContext, useContext, useEffect, useState } from "react";
import { useAccount, useChainId } from "wagmi";
import { CHAINS, Q64_MUL_100 } from "../utils/constants";
import { CHAINS, Q64, Q64_MUL_100 } from "../utils/constants";
import NeperCore from "../abi/NeperCore";
import BigNumber from "bignumber.js";
import ERC20 from "../abi/ERC20";
Expand Down Expand Up @@ -34,7 +34,8 @@ const AppContext = createContext<AppContextType>({
vaultCount: "",
baseRate: "",
debtRebaseIndex: "",
collRebaseIndex: ""
collRebaseIndex: "",
pUSDInStabilityPool: ""
},
increaseCollateral: async (collAmount: string) => {},
decreaseCollateral: async (collAmount: string) => {},
Expand All @@ -60,7 +61,6 @@ const AppContext = createContext<AppContextType>({
export const AppProvider = ({ children }: any) => {
// State that you want to provide to other components
const [stats, setStats] = useState<Params>({} as Params);
const priceFeed = 40000;
const chainId = useChainId();
const { address, isConnected } = useAccount();
const defaultOptions: DefaultOptions = {
Expand All @@ -80,14 +80,42 @@ export const AppProvider = ({ children }: any) => {
const stats = await fetchStats();
const stabilityPoolState = await fetchStabilityPoolStats();
if (!isConnected || !address) return;
await fetchVault(address, stats);
let price = await fetchPrice();
await fetchVault(address, stats, price);
await fetchStabilityPool(address, stabilityPoolState);
};

useEffect(() => {
fetchAllData();
}, [address, isConnected]);

async function fetchPrice(): Promise<any> {
try {
const client = new ApolloClient({
uri: CHAINS["0x" + chainId.toString(16)].subgraphEndpoint,
cache: new InMemoryCache(),
defaultOptions
});

const query = gql`
query {
priceFeed(id: "003") {
id
price
lastUpdate
}
}
`;

const price = await client.query({ query });

return price.data.priceFeed.price;
} catch (err: any) {
console.error(err);
throw err;
}
}

const fetchVaultsFromSubgraph = async (account: string) => {
try {
const client = new ApolloClient({
Expand Down Expand Up @@ -182,6 +210,7 @@ export const AppProvider = ({ children }: any) => {
id
currentScale
currentEpoch
neperUSDDeposit
P
}
}
Expand All @@ -195,15 +224,15 @@ export const AppProvider = ({ children }: any) => {
const fetchStats = async () => {
try {
const statsHere = (await fetchStatsFromSubgraph()).data.states;
console.log(statsHere);
setStats({
baseRate: parseFloat(statsHere.baseRate).toFixed(2),
mcr: parseFloat(statsHere.mcr).toFixed(2),
totalColl: parseFloat(statsHere.totalColl).toFixed(4),
totalDebt: new BigNumber(statsHere.pUSDSupply).dividedBy(1e18).toFixed(2),
vaultCount: statsHere.vaultCount,
debtRebaseIndex: statsHere.debtRebaseIndex,
collRebaseIndex: statsHere.collRebaseIndex
collRebaseIndex: statsHere.collRebaseIndex,
pUSDInStabilityPool: "0.0"
});

return statsHere;
Expand All @@ -225,18 +254,27 @@ export const AppProvider = ({ children }: any) => {
};
}

let pUSDSupply = new BigNumber(statsHere.neperUSDDeposit).dividedBy(1e18);

setStats(prev => {
return {
...prev,
pUSDInStabilityPool: pUSDSupply.toFixed(2)
};
});

return {
currentScale: BigNumber(statsHere[0].currentScale),
currentEpoch: BigNumber(statsHere[0].currentEpoch),
P: BigNumber(statsHere[0].P)
currentScale: BigNumber(statsHere.currentScale),
currentEpoch: BigNumber(statsHere.currentEpoch),
P: BigNumber(statsHere.P)
};
} catch (err: any) {
console.error(err);
throw err;
}
};

const fetchVault = async (owner: string, stats: Params) => {
const fetchVault = async (owner: string, stats: Params, price: number) => {
try {
const vaultsRes = (await fetchVaultsFromSubgraph(owner)).data.vaults;

Expand Down Expand Up @@ -265,7 +303,7 @@ export const AppProvider = ({ children }: any) => {
debt: debt.toFixed(2),
coll: coll.toFixed(4),
collRatio: debt.isGreaterThan(0)
? new BigNumber(coll).multipliedBy(priceFeed).multipliedBy(100).dividedBy(debt).toFixed(2)
? new BigNumber(coll).multipliedBy(price).multipliedBy(100).dividedBy(debt).toFixed(2)
: "MAX",
liquidationAt: new BigNumber(stats.mcr)
.multipliedBy(debt)
Expand All @@ -291,15 +329,9 @@ export const AppProvider = ({ children }: any) => {
return;
}

console.log("Stability Pool Res");
console.log(stabilityPoolRes);

// TODO: compute reward amount per stake unit
const reward_amount = "0.0";

const stake_amount = calculateCompoundedStakeFromSnapshots(stabilityPoolRes, stats);
// calculateCompoundedStakeFromSnapshots(new BigNumber(stabilityPoolRes.currentDeposit).multipliedBy(1e18), stats)
// new BigNumber(stabilityPoolRes.currentDeposit).toFixed(2);

const reward_amount = calculateCollGainFromSnapShot(stabilityPoolRes, stats);

setStabilityPool({
reward_amount,
Expand All @@ -311,6 +343,33 @@ export const AppProvider = ({ children }: any) => {
}
};

function calculateCollGainFromSnapShot(userSnapshot: any, snapshot: any): string {
const initialStake = BigNumber(userSnapshot.currentDeposit).multipliedBy(1e18);

const SP_SCALING_FACTOR = Math.pow(2, 32);
const user_P: BigNumber = BigNumber(userSnapshot.P);
const user_scale: BigNumber = BigNumber(userSnapshot.scale);
const user_epoch: BigNumber = BigNumber(userSnapshot.epoch);
const user_S = BigNumber(userSnapshot.S);

// const S = BigNumber(snapshot.S);
// const cachedScale = BigNumber(snapshot.currentScaleCached);
// const cachedEpoch = BigNumber(snapshot.currentEpochCached);

// if (user_P.isEqualTo(0)) return "0.0";

// let firstPortion: BigNumber = S.minus(user_S);
// let secondPortion: BigNumber = S.dividedBy(SP_SCALING_FACTOR);

// let collGain = initialStake
// .multipliedBy(firstPortion.multipliedBy(secondPortion))
// .dividedBy(user_P)
// .dividedBy(Q64);

// return collGain.dividedBy(1e8).toFixed(2);
return "0.0";
}

/// userSnapshot: the user's snapshot {currentDeposit, S, P, scale, epoch}
/// snapshot: the current snapshot {currentScale, currentEpoch, P}
function calculateCompoundedStakeFromSnapshots(userSnapshot: any, snapshot: any): string {
Expand All @@ -332,7 +391,7 @@ export const AppProvider = ({ children }: any) => {
let compoundedStake: BigNumber;
const scaleDiff: number = currentScale.minus(scaleSnapshot).toNumber();

if (snapshot_P.isEqualTo(0) && P.isEqualTo(0)) {
if (snapshot_P.isEqualTo(0) && (P.isNaN() || P.isEqualTo(0))) {
return userSnapshot.currentDeposit;
}

Expand All @@ -343,9 +402,6 @@ export const AppProvider = ({ children }: any) => {
* at least 2^32 (i.e., FixedPoint.Q32) -- so return 0.
*/
if (scaleDiff === 0) {
console.log("Scale Diff 0");
console.log("Initial Stake");
console.log(initialStake.toString());
compoundedStake = initialStake.multipliedBy(P).dividedBy(snapshot_P);
} else if (scaleDiff === 1) {
compoundedStake = initialStake
Expand Down
3 changes: 2 additions & 1 deletion src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import StabilityPool from "../components/StabilityPool";
function HomePage() {
const { isLoading } = useTypedSelector(state => state.contract);

const { vault, stats } = useAppContext();
const { vault, stats, } = useAppContext();

return (
<>
Expand Down Expand Up @@ -47,6 +47,7 @@ function HomePage() {
totalDebt={stats.totalDebt}
vaultCount={stats.vaultCount}
baseRate={stats.baseRate}
pUSDInStabilityPool={stats.pUSDInStabilityPool}
/>

<Toaster />
Expand Down
6 changes: 3 additions & 3 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export const CHAINS: Chains = {
currency: { name: "ETH", symbol: "ETH", decimals: 18 },
subgraphEndpoint: "https://api.studio.thegraph.com/query/64179/nepercore/version/latest",
contracts: {
neperCore: "0xE39e0bdfFb6bA12F1869c85a7cB908816553f0E3",
neperUSD: "0x32Eef049F5AC6aF211A0D94a4DE844CC6804D2F3",
neperCore: "0x6E41052542A9f0da414b351DAC213dB833aC616C",
neperUSD: "0x5F8C60f2877F83F3254634400d2F315675CD57E7",
wbtc: "0xD085812E6B7FC569809423Fb7c564f56547a85Ed",
stabilityPool: "0x0f9519F40dAfCeC618e3d35e501E8823F0C26fBD"
stabilityPool: "0x3dE9ba89c85852F1d253efDC2B96919Db4e7F539"
}
},
"0x5a2": {
Expand Down
1 change: 1 addition & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ export interface Params {
vaultCount: string;
debtRebaseIndex: string;
collRebaseIndex: string;
pUSDInStabilityPool : string;
}

0 comments on commit 8afeea9

Please sign in to comment.