Skip to content

Commit

Permalink
feat(ui): apply diamond architecture to staking page (#804)
Browse files Browse the repository at this point in the history
* fix: match  contract type according to diamond architecture
  • Loading branch information
bojan07 committed Oct 12, 2023
1 parent 000bdb6 commit 1d686bc
Show file tree
Hide file tree
Showing 16 changed files with 221 additions and 185 deletions.
7 changes: 3 additions & 4 deletions packages/dapp/components/lib/contracts-shortcuts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { BigNumber, ethers } from "ethers";
import { ERC1155Ubiquity, ERC20 } from "types";
import { BigNumber, ethers, Contract } from "ethers";

import { performTransaction } from "./utils";

export async function ensureERC20Allowance(
logName: string,
contract: ERC20,
contract: Contract,
amount: BigNumber,
signer: ethers.providers.JsonRpcSigner,
spender: string,
Expand All @@ -25,7 +24,7 @@ export async function ensureERC20Allowance(
return true;
}

export async function ensureERC1155Allowance(logName: string, contract: ERC1155Ubiquity, signer: ethers.providers.JsonRpcSigner, spender: string): Promise<boolean> {
export async function ensureERC1155Allowance(logName: string, contract: Contract, signer: ethers.providers.JsonRpcSigner, spender: string): Promise<boolean> {
const signerAddress = await signer.getAddress();
const isAllowed = await contract.isApprovedForAll(signerAddress, spender);
console.log(`${logName} isAllowed: `, isAllowed);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import useWeb3, { PossibleProviders } from "../use-web-3";

import Deployed_Contracts from "@ubiquity/contracts/deployments.json";
import NAMED_ACCOUNTS from "../../../config/named-accounts.json";
import { getCurveFactoryContract, getDebtCouponManagerContract, getERC20Contract, getIJarContract, getYieldProxyContract } from "@/components/utils/contracts";

const getDebtCouponManagerAddress = () => {
const contractDeployments: Record<string, any> = Deployed_Contracts;
const record = contractDeployments["1"] ?? {};
const contract = record?.contracts ? record?.contracts["DebtCouponManager"] : undefined;
return contract ? contract.address : undefined;
};
export const DEBT_COUPON_MANAGER_ADDRESS = getDebtCouponManagerAddress();
import { getCurveFactoryContract, getERC20Contract, getIJarContract, getYieldProxyContract } from "@/components/utils/contracts";

export type NamedContracts = ReturnType<typeof connectedContracts> | null;
export function connectedContracts(provider: NonNullable<PossibleProviders>) {
Expand All @@ -20,7 +11,6 @@ export function connectedContracts(provider: NonNullable<PossibleProviders>) {
usdc: getERC20Contract(NAMED_ACCOUNTS.USDC, provider),
dai: getERC20Contract(NAMED_ACCOUNTS.DAI, provider),
usdt: getERC20Contract(NAMED_ACCOUNTS.USDT, provider),
debtCouponManager: getDebtCouponManagerContract(DEBT_COUPON_MANAGER_ADDRESS, provider),
jarUsdc: getIJarContract(NAMED_ACCOUNTS.jarUSDCAddr, provider),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Contract, ethers } from "ethers";

import latestDeployment from "@ubiquity/contracts/broadcast/05_StakingShare.s.sol/31337/run-latest.json";
import useWeb3 from "../use-web-3";
import { sushiSwapPoolAddress, dollar3poolMarketAddress } from "@/lib/utils";

// contract build artifacts
// separately deployed contracts
Expand All @@ -27,6 +28,10 @@ import StakingFacetArtifact from "@ubiquity/contracts/out/StakingFacet.sol/Staki
import StakingFormulasFacetArtifact from "@ubiquity/contracts/out/StakingFormulasFacet.sol/StakingFormulasFacet.json";
import TWAPOracleDollar3poolFacetArtifact from "@ubiquity/contracts/out/TWAPOracleDollar3poolFacet.sol/TWAPOracleDollar3poolFacet.json";
import UbiquityPoolFacetArtifact from "@ubiquity/contracts/out/UbiquityPoolFacet.sol/UbiquityPoolFacet.json";
// other related contracts
// import SushiSwapPoolArtifact from "@ubiquity/contracts/out/SushiSwapPool.sol/SushiSwapPool.json";
import IMetaPoolArtifact from "@ubiquity/contracts/out/IMetaPool.sol/IMetaPool.json";
import UniswapV2PairABI from "@/components/config/abis/uniswap-v-2-pair.json";

/**
* Returns all of the available protocol contracts.
Expand All @@ -52,7 +57,8 @@ import UbiquityPoolFacetArtifact from "@ubiquity/contracts/out/UbiquityPoolFacet
* Contracts on hold (i.e. obsolete) until we find a better utility for them:
* - https://github.com/ubiquity/ubiquity-dollar/tree/development/packages/contracts/src/ubiquistick
*/
const useProtocolContracts = () => {
export type ProtocolContracts = ReturnType<typeof useProtocolContracts> | null;
const useProtocolContracts = async () => {
// get current web3 provider
const { provider } = useWeb3();

Expand Down Expand Up @@ -80,6 +86,9 @@ const useProtocolContracts = () => {
stakingFormulasFacet: Contract | null,
twapOracleDollar3poolFacet: Contract | null,
ubiquityPoolFacet: Contract | null,
// related contracts
sushiPoolGovernanceDollarLp: Contract | null,
curveMetaPoolDollarTriPoolLp: Contract | null,
} = {
// separately deployed contracts (i.e. not part of the diamond)
creditNft: null,
Expand All @@ -103,6 +112,9 @@ const useProtocolContracts = () => {
stakingFormulasFacet: null,
twapOracleDollar3poolFacet: null,
ubiquityPoolFacet: null,
// related contracts
sushiPoolGovernanceDollarLp: null,
curveMetaPoolDollarTriPoolLp: null,
};

let diamondAddress = '';
Expand Down Expand Up @@ -148,6 +160,18 @@ const useProtocolContracts = () => {
protocolContracts.twapOracleDollar3poolFacet = new ethers.Contract(diamondAddress, TWAPOracleDollar3poolFacetArtifact.abi, <Provider>provider);
protocolContracts.ubiquityPoolFacet = new ethers.Contract(diamondAddress, UbiquityPoolFacetArtifact.abi, <Provider>provider);

// other related contracts
// const sushiSwapPool = await protocolContracts.managerFacet.sushiSwapPoolAddress();
// const sushiSwapPoolContract = new ethers.Contract(sushiSwapPool, SushiSwapPoolArtifact.abi, <Provider>provider);
// const UniswapV2PairContract = new ethers.Contract(await sushiSwapPoolContract.pair(), UniswapV2PairABI, <Provider>provider);
const UniswapV2PairContract = new ethers.Contract(sushiSwapPoolAddress, UniswapV2PairABI, <Provider>provider);
protocolContracts.sushiPoolGovernanceDollarLp = UniswapV2PairContract;

// const dollar3poolMarket = await protocolContracts.managerFacet.stableSwapMetaPoolAddress();
// const metaPoolContract = new ethers.Contract(dollar3poolMarket, IMetaPoolArtifact.abi, <Provider>provider);
const metaPoolContract = new ethers.Contract(dollar3poolMarketAddress, IMetaPoolArtifact.abi, <Provider>provider);
protocolContracts.curveMetaPoolDollarTriPoolLp = metaPoolContract;

return protocolContracts;
};

Expand Down
40 changes: 26 additions & 14 deletions packages/dapp/components/lib/hooks/use-balances.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { erc1155BalanceOf } from "@/lib/utils";
import { BigNumber, Contract } from "ethers";
import { erc1155BalanceOf, _3crvTokenAddress } from "@/lib/utils";
import { BigNumber } from "ethers";
import { createContext, useContext, useEffect, useState } from "react";
import useManagerManaged from "./contracts/use-manager-managed";
import useNamedContracts from "./contracts/use-named-contracts";
import useWalletAddress from "./use-wallet-address";
import { ChildrenShim } from "./children-shim-d";
import useProtocolContracts from "@/components/lib/hooks/contracts/use-protocol-contracts";
import { getERC20Contract } from "@/components/utils/contracts";
import useWeb3 from "@/components/lib/hooks/use-web-3";

export interface Balances {
uad: BigNumber;
Expand All @@ -26,24 +28,34 @@ export const BalancesContext = createContext<[Balances | null, RefreshBalances]>
export const BalancesContextProvider: React.FC<ChildrenShim> = ({ children }) => {
const [balances, setBalances] = useState<Balances | null>(null);
const [walletAddress] = useWalletAddress();
const managedContracts = useManagerManaged();
const namedContracts = useNamedContracts();
const protocolContracts = useProtocolContracts();
const { provider } = useWeb3();

async function refreshBalances() {
if (walletAddress && managedContracts && namedContracts) {
if (!walletAddress || !namedContracts || !protocolContracts || !provider) {
return;
}

const contracts = await protocolContracts;

if(contracts.creditNft && contracts.stakingShare) {
// const _3crvTokenAddress = await contracts.managerFacet?.curve3PoolTokenAddress();
const _3crvTokenContract = getERC20Contract(_3crvTokenAddress, provider);

const [uad, _3crv, uad3crv, ucr, ubq, ucrNft, stakingShares, usdc, dai, usdt] = await Promise.all([
managedContracts.dollarToken.balanceOf(walletAddress),
managedContracts._3crvToken.balanceOf(walletAddress),
managedContracts.dollarMetapool.balanceOf(walletAddress),
managedContracts.creditToken.balanceOf(walletAddress),
managedContracts.governanceToken.balanceOf(walletAddress),
erc1155BalanceOf(walletAddress, managedContracts.creditNft),
erc1155BalanceOf(walletAddress, managedContracts.stakingToken),
contracts.dollarToken?.balanceOf(walletAddress),
_3crvTokenContract.balanceOf(walletAddress),
contracts.curveMetaPoolDollarTriPoolLp?.balanceOf(walletAddress),
contracts.creditToken?.balanceOf(walletAddress),
contracts.governanceToken?.balanceOf(walletAddress),
erc1155BalanceOf(walletAddress, contracts.creditNft),
erc1155BalanceOf(walletAddress, contracts.stakingShare),
namedContracts.usdc.balanceOf(walletAddress),
namedContracts.dai.balanceOf(walletAddress),
namedContracts.usdt.balanceOf(walletAddress),
]);

setBalances({
uad,
_3crv,
Expand All @@ -61,7 +73,7 @@ export const BalancesContextProvider: React.FC<ChildrenShim> = ({ children }) =>

useEffect(() => {
refreshBalances();
}, [walletAddress, managedContracts]);
}, [walletAddress, protocolContracts]);

return <BalancesContext.Provider value={[balances, refreshBalances]}>{children}</BalancesContext.Provider>;
};
Expand Down
4 changes: 4 additions & 0 deletions packages/dapp/components/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ export const uCR_USDT_ADDRESS = "0x9d498aB38Aa889AE0f4A865d30da2116ee9716bC";
// Uniswap Router address
export const V3_ROUTER_ADDRESS = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45";

export const sushiSwapPoolAddress = "0x41e087485f47538752A1195D984109cB8Dc0E429";
export const dollar3poolMarketAddress = "0x20955CB69Ae1515962177D164dfC9522feef567E";
export const _3crvTokenAddress = "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490";

export const safeParseEther = (val: string) => {
try {
return ethers.utils.parseEther(val);
Expand Down
15 changes: 5 additions & 10 deletions packages/dapp/components/lib/with-loaded-context.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { ethers } from "ethers";
import useDeployedContracts, { DeployedContracts } from "./hooks/contracts/use-deployed-contracts";
import { ManagedContracts } from "./hooks/contracts/use-manager-managed";
import useProtocolContracts, { ProtocolContracts } from "./hooks/contracts/use-protocol-contracts";
import useNamedContracts, { NamedContracts } from "./hooks/contracts/use-named-contracts";
import useWeb3, { PossibleProviders } from "./hooks/use-web-3";

import useManagerManaged from "@/components/lib/hooks/contracts/use-manager-managed";
export type LoadedContext = {
managedContracts: NonNullable<ManagedContracts>;
deployedContracts: NonNullable<DeployedContracts>;
protocolContracts: NonNullable<ProtocolContracts>;
namedContracts: NonNullable<NamedContracts>;
web3Provider: NonNullable<PossibleProviders>;
walletAddress: string;
Expand All @@ -17,19 +14,17 @@ export type LoadedContext = {
export default function withLoadedContext<T>(El: (params: LoadedContext & T) => JSX.Element, ElNull?: () => JSX.Element) {
return (otherParams: T) => {
const { walletAddress, signer, provider } = useWeb3();
const managedContracts = useManagerManaged();
const deployedContracts = useDeployedContracts();
const namedContracts = useNamedContracts();
const protocolContracts = useProtocolContracts();

if (provider && walletAddress && signer && managedContracts && deployedContracts && namedContracts) {
if (provider && walletAddress && signer && protocolContracts && namedContracts) {
return (
<El
web3Provider={provider}
walletAddress={walletAddress}
signer={signer}
namedContracts={namedContracts}
managedContracts={managedContracts}
deployedContracts={deployedContracts}
protocolContracts={protocolContracts}
{...otherParams}
/>
);
Expand Down
25 changes: 13 additions & 12 deletions packages/dapp/components/redeem/debt-coupon-deposit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { useState } from "react";
import { ensureERC20Allowance } from "@/lib/contracts-shortcuts";
import { formatEther } from "@/lib/format";
import { safeParseEther } from "@/lib/utils";
import useDeployedContracts from "../lib/hooks/contracts/use-deployed-contracts";
import useManagerManaged from "../lib/hooks/contracts/use-manager-managed";
import useProtocolContracts from "@/components/lib/hooks/contracts/use-protocol-contracts";
import useBalances from "../lib/hooks/use-balances";
import useSigner from "../lib/hooks/use-signer";
import useTransactionLogger from "../lib/hooks/use-transaction-logger";
Expand All @@ -18,8 +17,7 @@ const UcrNftGenerator = () => {
const signer = useSigner();
const [balances, refreshBalances] = useBalances();
const [, doTransaction, doingTransaction] = useTransactionLogger();
const deployedContracts = useDeployedContracts();
const managedContracts = useManagerManaged();
const protocolContracts = useProtocolContracts();

const [inputVal, setInputVal] = useState("");
const [expectedDebtCoupon, setExpectedDebtCoupon] = useState<BigNumber | null>(null);
Expand All @@ -28,16 +26,18 @@ const UcrNftGenerator = () => {
return <span>Connect wallet</span>;
}

if (!balances || !managedContracts || !deployedContracts) {
if (!balances || !protocolContracts) {
return <span>· · ·</span>;
}

const depositDollarForDebtCoupons = async (amount: BigNumber) => {
const { debtCouponManager } = deployedContracts;
// cspell: disable-next-line
await ensureERC20Allowance("uAD -> DebtCouponManager", managedContracts.dollarToken, amount, signer, debtCouponManager.address);
await (await debtCouponManager.connect(signer).exchangeDollarsForCreditNft(amount)).wait();
refreshBalances();
const contracts = await protocolContracts;
if (contracts.dollarToken && contracts.creditNftManagerFacet) {
// cspell: disable-next-line
await ensureERC20Allowance("uCR -> CreditNftManagerFacet", contracts.dollarToken, amount, signer, contracts.creditNftManagerFacet.address);
await (await contracts.creditNftManagerFacet.connect(signer).exchangeDollarsForCreditNft(amount)).wait();
refreshBalances();
}
};

const handleBurn = async () => {
Expand All @@ -52,11 +52,12 @@ const UcrNftGenerator = () => {
};

const handleInput = async (val: string) => {
const contracts = await protocolContracts;
setInputVal(val);
const amount = extractValidAmount(val);
if (amount) {
if (amount && contracts.creditNftRedemptionCalculatorFacet) {
setExpectedDebtCoupon(null);
setExpectedDebtCoupon(await managedContracts.creditNftCalculator.connect(signer).getCreditNftAmount(amount));
setExpectedDebtCoupon(await contracts.creditNftRedemptionCalculatorFacet.connect(signer).getCreditNftAmount(amount));
}
};

Expand Down
2 changes: 1 addition & 1 deletion packages/dapp/components/redeem/debt-coupon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const uDEBT = "uDEBT";
const uAR = "uAR";

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const DebtCouponContainer = ({ managedContracts, deployedContracts, web3Provider, walletAddress, signer }: LoadedContext) => {
export const DebtCouponContainer = ({ protocolContracts, web3Provider, walletAddress, signer }: LoadedContext) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [balances, refreshBalances] = useBalances();
const [, doTransaction] = useTransactionLogger();
Expand Down
15 changes: 7 additions & 8 deletions packages/dapp/components/redeem/lib/use-prices.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getIMetaPoolContract } from "@/components/utils/contracts";
import useProtocolContracts from "@/components/lib/hooks/contracts/use-protocol-contracts";
import useWeb3 from "@/components/lib/hooks/use-web-3";
import { BigNumber, utils } from "ethers";
Expand All @@ -17,12 +16,12 @@ const usePrices = (): [BigNumber | null, BigNumber | null, () => Promise<void>]
return;
}

if(protocolContracts.managerFacet && protocolContracts.twapOracleDollar3poolFacet) {
const dollarTokenAddress = await protocolContracts.managerFacet.dollarTokenAddress();
const newTwapPrice = await protocolContracts.twapOracleDollar3poolFacet.consult(dollarTokenAddress);
const dollar3poolMarket = await protocolContracts.managerFacet.stableSwapMetaPoolAddress();
const dollarMetapool = getIMetaPoolContract(dollar3poolMarket, provider)
const newSpotPrice = await dollarMetapool["get_dy(int128,int128,uint256)"](0, 1, utils.parseEther("1"));
const contracts = await protocolContracts;

if(contracts.curveMetaPoolDollarTriPoolLp) {
const dollarTokenAddress = await contracts.managerFacet?.dollarTokenAddress();
const newTwapPrice = await contracts.twapOracleDollar3poolFacet?.consult(dollarTokenAddress);
const newSpotPrice = await contracts.curveMetaPoolDollarTriPoolLp["get_dy(int128,int128,uint256)"](0, 1, utils.parseEther("1"));
setTwapPrice(newTwapPrice);
setSpotPrice(newSpotPrice);
}
Expand All @@ -34,7 +33,7 @@ const usePrices = (): [BigNumber | null, BigNumber | null, () => Promise<void>]

useEffect(() => {
refreshPrices();
}, [protocolContracts, provider]);
}, [provider]);

return [twapPrice, spotPrice, refreshPrices];
};
Expand Down
Loading

1 comment on commit 1d686bc

@ubiquibot
Copy link

@ubiquibot ubiquibot bot commented on 1d686bc Oct 12, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.