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

Using BigNumber for distribution #225

Closed
Closed
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
74 changes: 35 additions & 39 deletions web/components/Strategy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import Image from "next/image";
import { pluralize } from "@/utils/pluralize";
import { findMostRepeatedString } from "@/utils/findMostRepeatedString";
import { useTweetShare } from "@/hooks/useTweetShare";
import { BigNumber } from "ethers";
import { parseUnits } from "ethers/lib/utils";
import clsx from "clsx";

export default function Strategy(props: {
Expand Down Expand Up @@ -67,6 +69,11 @@ export default function Strategy(props: {

const [selectedNetwork, setSelectedNetwork] =
useState<NetworkName>(networkName);
const {
tokens,
updateToken: updateToken,
selectedToken,
} = useToken(selectedNetwork);
const {
execute: executeDonation,
getBalance,
Expand All @@ -77,6 +84,7 @@ export default function Strategy(props: {
props.fetchedStrategies,
amount,
selectedNetwork,
selectedToken,
overwrites
);
const [
Expand All @@ -86,14 +94,8 @@ export default function Strategy(props: {
const [{ wallet }, connectWallet] = useConnectWallet();
const { data: session } = useSession();
const router = useRouter();
const {
tokens,
updateToken: updateToken,
selectedToken,
} = useToken(selectedNetwork);

const { strategies, handleAmountUpdate, handleNetworkUpdate } =
strategiesHandler;

const { strategies, handleAmountUpdate, handleNetworkUpdate, handleTokenUpdate } = strategiesHandler;
const selectedStrategiesLength = strategies.filter((x) => x.selected).length;
const tweetUrl = useTweetShare(
props.runId,
Expand All @@ -104,6 +106,7 @@ export default function Strategy(props: {
const [isFundingPending, setIsFundingPending] = useState(false);

useEffect(() => {
handleTokenUpdate()
setBalance((currentBalance) => {
if (currentBalance) return null;
});
Expand All @@ -117,7 +120,7 @@ export default function Strategy(props: {
setIsFundingPending(true);

try {
if (selectedStrategiesLength === 0 || amount === "0") return;
if (selectedStrategiesLength === 0 || !amount || amount === "0") return;

const currentNetworkId = SUPPORTED_NETWORKS[selectedNetwork];
if (connectedChain && currentNetworkId !== +connectedChain.id) {
Expand All @@ -131,10 +134,11 @@ export default function Strategy(props: {
return;
}

const balance = await getBalance(wallet, selectedToken);

if (+amount >= +balance) {
setBalance(balance);
const fetchedBalance = await getBalance(wallet, selectedToken);
const amountInDecimals = parseUnits(amount, selectedToken.decimals)
const selectedStrategies = strategies.filter((x) => x.selected);
if (fetchedBalance.lt(amountInDecimals)) {
setBalance(fetchedBalance.toString());
setIsFundingPending(false);
return;
}
Expand All @@ -145,33 +149,27 @@ export default function Strategy(props: {
selectedNetwork
);

const donations = strategies
.filter((x) => x.selected)
.map((strategy) => {
const networkIndex = strategy.networks.indexOf(selectedNetwork);
return {
amount: strategy.amount as string,
description: strategy.project.description as string,
title: strategy.project.title as string,
recipient: strategy.recipients[networkIndex],
};
});

const amounts = donations
.map((x) => Number(x.amount))
.filter((x) => x > 0);
const amounts = selectedStrategies
.filter((x) => !!x.amount)
.map((x) => x.amount as string)

const totalAmount = amounts.reduce((a, b) => a + b, 0);
const recipientAddresses = selectedStrategies
.map((strategy) => strategy.recipients[strategy.networks.indexOf(selectedNetwork)]);

if (+allowance < totalAmount) {
await approve(wallet, selectedToken, totalAmount, selectedNetwork);
const totalAmount = amounts.reduce((a, b) => a.add(b), BigNumber.from(0))
if (allowance.lt(totalAmount)) {
await approve(
wallet,
selectedToken,
totalAmount,
selectedNetwork
);
}

await executeDonation(
selectedNetwork,
selectedToken,
donations.map((x) => x.recipient),
amounts
recipientAddresses,
amounts.map(a => Number(a))
);

setShowSuccessModal(true);
Expand Down Expand Up @@ -250,7 +248,7 @@ export default function Strategy(props: {
</div>
</div>
</div>
<StrategyTable {...strategiesHandler} network={selectedNetwork} />
<StrategyTable {...strategiesHandler} network={selectedNetwork} token={selectedToken} />
<div
className={clsx(
"flex flex-col md:flex-row justify-between md:items-center w-full gap-2 py-4 border-t-2 border-indigo-100",
Expand All @@ -263,7 +261,7 @@ export default function Strategy(props: {
className='h-12'
placeholder='Enter the amount you want to fund'
error={
balance && +balance < +amount
!!balance
? `Insufficient ${selectedToken.name} balance`
: ""
}
Expand All @@ -273,9 +271,7 @@ export default function Strategy(props: {
.filter((x) => x.name !== selectedToken.name)
.map((x) => ({ value: x.name }))}
field={{ value: selectedToken.name }}
onChange={async (newToken) =>
await updateToken(newToken)
}
onChange={updateToken}
/>
}
value={amount !== "0" ? amount : undefined}
Expand Down
7 changes: 4 additions & 3 deletions web/components/StrategyTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import {
StrategyInformation,
StrategiesHandler,
} from "@/hooks/useStrategiesHandler";
import { NetworkName } from "@/utils/ethereum";
import { NetworkName, TokenInformation } from "@/utils/ethereum";
import { SparkleIcon } from "./Icons";
import { CaretRight } from "@phosphor-icons/react";
import { Tooltip } from "./Tooltip";
import { formatUnits, parseUnits } from "ethers/lib/utils";

interface WeightInputProps {
selected: boolean;
Expand Down Expand Up @@ -88,7 +89,7 @@ function WeightInput({
);
}

export function StrategyTable(props: StrategiesHandler & { network: NetworkName }) {
export function StrategyTable(props: StrategiesHandler & { network: NetworkName, token: TokenInformation }) {
const [{ wallet }] = useConnectWallet();
const {
strategies,
Expand Down Expand Up @@ -261,7 +262,7 @@ export function StrategyTable(props: StrategiesHandler & { network: NetworkName
</div>
{!!wallet && (
<div className='col-span-2'>{`$${
entry.amount || "0.00"
entry.amount ? Number(entry.amount) / 10 ** props.token.decimals : "0"
}`}</div>
)}
<div
Expand Down
34 changes: 11 additions & 23 deletions web/hooks/useDonation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ import {
ERC20_ABI,
NetworkName,
TokenInformation,
getTokensForNetwork,
splitTransferFunds,
} from "@/utils/ethereum";
import { ethers } from "ethers";
import { BigNumber, ethers } from "ethers";

export function useDonation() {
const [{ wallet }] = useConnectWallet();

const execute = async (
selectedNetwork: NetworkName,
selectedToken: TokenInformation,
network: NetworkName,
token: TokenInformation,
recipientAddresses: string[],
amounts: number[]
) => {
Expand All @@ -27,22 +26,14 @@ export function useDonation() {

const signer = ethersProvider.getSigner();

const token = getTokensForNetwork(selectedNetwork).find(
(t) => t.name == selectedToken.name
);

if (!token) {
throw new Error(`Token with name: ${selectedToken} is not valid`);
}
console.log(recipientAddresses, amounts, signer, token, selectedNetwork);
console.log(recipientAddresses, amounts.map(x => x.toString()), signer, token, network);

await splitTransferFunds(
recipientAddresses,
amounts,
signer,
selectedNetwork,
token.address,
token.decimals
network,
token.address
);
};

Expand All @@ -55,11 +46,10 @@ export function useDonation() {
const signer = ethersProvider.getSigner();
const tokenContract = new ethers.Contract(token.address, ERC20_ABI, signer);
const currentAddress = await signer.getAddress();
const balance = await tokenContract.balanceOf(currentAddress);
return ethers.utils.formatUnits(balance.toString(), token.decimals);
return await tokenContract.balanceOf(currentAddress);
};

const getAllowance = async (wallet: WalletState, token: TokenInformation, network: NetworkName) => {
const getAllowance = async (wallet: WalletState, token: TokenInformation, network: NetworkName): Promise<BigNumber> => {
const ethersProvider = new ethers.providers.Web3Provider(
wallet.provider,
"any"
Expand All @@ -70,14 +60,13 @@ export function useDonation() {
const currentAddress = await signer.getAddress();
const contractAddress = DISPERSE_CONTRACT_ADDRESSES[network];

const balance = await tokenContract.allowance(currentAddress, contractAddress);
return ethers.utils.formatUnits(balance.toString(), token.decimals);
return await tokenContract.allowance(currentAddress, contractAddress);
};

const approve = async (
wallet: WalletState,
token: TokenInformation,
amount: number,
amount: BigNumber,
network: NetworkName
) => {
const ethersProvider = new ethers.providers.Web3Provider(
Expand All @@ -88,8 +77,7 @@ export function useDonation() {
const tokenContract = new ethers.Contract(token.address, ERC20_ABI, signer);

const contractAddress = DISPERSE_CONTRACT_ADDRESSES[network];
const amountInDecimals = ethers.utils.parseUnits(amount.toString(), token.decimals);
const approveTx = await tokenContract.approve(contractAddress, amountInDecimals);
const approveTx = await tokenContract.approve(contractAddress, amount);
await approveTx.wait(1);
};

Expand Down
Loading
Loading