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

feat(ui): apply diamond architecture to staking page #804

Merged
merged 22 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b1b2bc2
feat: apply diamond to home page
bojan07 Oct 2, 2023
dd22fa0
fix: added debug option to refreshPrices function
bojan07 Oct 3, 2023
b2bbdca
fix: make code clean in use-prices
bojan07 Oct 3, 2023
510e7a2
Merge branch 'ubiquity:development' into development
bojan07 Oct 3, 2023
8da767d
feat: used protocol-contracts in use-balances and use-named-contracts
bojan07 Oct 3, 2023
b3a3856
feat: applied protocol-contracts to child components of staking page
bojan07 Oct 3, 2023
5e1a071
fix: fixed build error and made code clean in use-balances
bojan07 Oct 3, 2023
f5ac79b
fix: used non-null assertion operator for object null checking
bojan07 Oct 4, 2023
18ee556
fix: added metapool and governancemarket contract to protocol-contrac…
bojan07 Oct 4, 2023
9ad50ee
chore: cleamake use-protocol-contracts clean
bojan07 Oct 4, 2023
1ce1d35
fix: applied new name convention
bojan07 Oct 5, 2023
57bc6e1
fix: object null checking
bojan07 Oct 5, 2023
6972f9c
fix: cleaned refresh balance function
bojan07 Oct 5, 2023
61ee7f7
fix: hardcoded some addresses and fixed prefetch-constants function
bojan07 Oct 6, 2023
eb6e495
fix: checking big number zero value
bojan07 Oct 6, 2023
88c1b46
fix: non-null assertion operator and infinite hook loop
bojan07 Oct 10, 2023
8edb930
Merge branch 'ubiquity:development' into development
bojan07 Oct 10, 2023
9e07817
fix: contract type in allowance functions
bojan07 Oct 10, 2023
de99518
Merge branch 'ubiquity:development' into development
bojan07 Oct 12, 2023
e7dc29f
fix: passed hardcoded addresses as variable
bojan07 Oct 12, 2023
c086a17
fix: updated variable names according to new name convention
bojan07 Oct 12, 2023
cd4ce71
fix: match contract type according to diamond architecture
bojan07 Oct 12, 2023
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
6 changes: 3 additions & 3 deletions packages/dapp/components/lib/contracts-shortcuts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { BigNumber, ethers } from "ethers";
import { BigNumber, ethers, Contract } from "ethers";
import { ERC1155Ubiquity, ERC20 } from "types";

import { performTransaction } from "./utils";

export async function ensureERC20Allowance(
logName: string,
contract: ERC20,
contract: ERC20 | Contract,
amount: BigNumber,
bojan07 marked this conversation as resolved.
Show resolved Hide resolved
signer: ethers.providers.JsonRpcSigner,
spender: string,
Expand All @@ -25,7 +25,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: ERC1155Ubiquity | 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 @@ -27,6 +27,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 +56,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 +85,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 +111,9 @@ const useProtocolContracts = () => {
stakingFormulasFacet: null,
twapOracleDollar3poolFacet: null,
ubiquityPoolFacet: null,
// related contracts
sushiPoolGovernanceDollarLp: null,
curveMetaPoolDollarTriPoolLp: null,
};

let diamondAddress = '';
Expand Down Expand Up @@ -148,6 +159,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("0x41e087485f47538752A1195D984109cB8Dc0E429", UniswapV2PairABI, <Provider>provider);
bojan07 marked this conversation as resolved.
Show resolved Hide resolved
protocolContracts.sushiPoolGovernanceDollarLp = UniswapV2PairContract;

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

return protocolContracts;
};

Expand Down
39 changes: 26 additions & 13 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 { 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,35 @@ 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 _3crvToken = await contracts.managerFacet?.curve3PoolTokenAddress();
const _3crvToken = "0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490";
const _3crvTokenContract = getERC20Contract(_3crvToken, provider);

const [uad, _3crv, uad3crv, ucr, ubq, ucrNft, stakingShares, usdc, dai, usdt] = await Promise.all([
bojan07 marked this conversation as resolved.
Show resolved Hide resolved
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 +74,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
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
32 changes: 17 additions & 15 deletions packages/dapp/components/redeem/ucr-nft-redeem.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { BigNumber, ethers, Contract } from "ethers";
import { useEffect, useState } from "react";
import { useState } from "react";

import { ensureERC1155Allowance } 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";
import useWalletAddress from "../lib/hooks/use-wallet-address";
import Button from "../ui/button";
import PositiveNumberInput from "../ui/positive-number-input";
import useEffectAsync from "../lib/hooks/use-effect-async";

const UcrNftRedeem = () => {
const [walletAddress] = useWalletAddress();
const signer = useSigner();
const [, refreshBalances] = useBalances();
const [, doTransaction, doingTransaction] = useTransactionLogger();
const deployedContracts = useDeployedContracts();
const managedContracts = useManagerManaged();
const protocolContracts = useProtocolContracts();

const [inputVal, setInputVal] = useState("");
const [debtIds, setDebtIds] = useState<BigNumber[] | null>(null);
Expand All @@ -32,14 +31,15 @@ const UcrNftRedeem = () => {
}
};

useEffect(() => {
if (managedContracts && walletAddress) {
fetchDebts(walletAddress, managedContracts.creditNft);
useEffectAsync(async () => {
const contracts = await protocolContracts;
if (contracts.creditNft && walletAddress) {
fetchDebts(walletAddress, contracts.creditNft);
}
}, [managedContracts, walletAddress]);
}, [walletAddress]);

if (!walletAddress || !signer) return <span>Connect wallet</span>;
if (!deployedContracts || !managedContracts || !debtIds) return <span>· · ·</span>;
if (!protocolContracts || !debtIds) return <span>· · ·</span>;
if (debtIds.length === 0) return <span>No uCR-NFT coupons</span>;

async function fetchDebts(address: string, contract: Contract) {
Expand Down Expand Up @@ -67,12 +67,14 @@ const UcrNftRedeem = () => {
};

const redeemUcrNftForUad = async (amount: BigNumber) => {
const { debtCouponManager } = deployedContracts;
const contracts = await protocolContracts;
const debtId = debtIds[selectedDebtId];
if (debtId && (await ensureERC1155Allowance("uCR-NFT -> DebtCouponManager", managedContracts.creditNft, signer, debtCouponManager.address))) {
await (await debtCouponManager.connect(signer).redeemCreditNft(debtId, amount)).wait();
refreshBalances();
fetchDebts(walletAddress, managedContracts.creditNft);
if (contracts.creditNft && contracts.creditNftManagerFacet) {
bojan07 marked this conversation as resolved.
Show resolved Hide resolved
if (debtId && (await ensureERC1155Allowance("uCR-NFT -> CreditNftManagerFacet", contracts.creditNft, signer, contracts.creditNftManagerFacet.address))) {
await (await contracts.creditNftManagerFacet.connect(signer).redeemCreditNft(debtId, amount)).wait();
bojan07 marked this conversation as resolved.
Show resolved Hide resolved
refreshBalances();
fetchDebts(walletAddress, contracts.creditNft);
}
}
};

Expand Down
Loading
Loading