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

Error and amount fixes #224

Merged
merged 2 commits into from
Feb 22, 2024
Merged
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
102 changes: 62 additions & 40 deletions web/components/Strategy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export default function Strategy(props: {
const [selectedNetwork, setSelectedNetwork] = useState<NetworkName>(networkName);
const {
execute: executeDonation,
isTransactionPending,
getBalance,
getAllowance,
approve,
Expand All @@ -82,6 +81,7 @@ export default function Strategy(props: {
const { strategies, handleAmountUpdate, handleNetworkUpdate } = strategiesHandler;
const selectedStrategiesLength = strategies.filter((x) => x.selected).length;
const tweetUrl = useTweetShare(props.runId, strategies, selectedNetwork, props.prompt)
const [isFundingPending, setIsFundingPending] = useState(false);

useEffect(() => {
setBalance((currentBalance) => {
Expand All @@ -94,51 +94,73 @@ export default function Strategy(props: {
}

const executeTransaction = async () => {
if (selectedStrategiesLength === 0 || amount === "0") return;
setIsFundingPending(true);

const currentNetworkId = SUPPORTED_NETWORKS[selectedNetwork];
if (connectedChain && currentNetworkId !== +connectedChain.id) {
await setChain({ chainId: `0x${currentNetworkId.toString(16)}` });
return;
}
try {
if (selectedStrategiesLength === 0 || amount === "0") return;

if (!selectedToken || !wallet) return;
const currentNetworkId = SUPPORTED_NETWORKS[selectedNetwork];
if (connectedChain && currentNetworkId !== +connectedChain.id) {
await setChain({ chainId: `0x${currentNetworkId.toString(16)}` });
setIsFundingPending(false);
return;
}

const balance = await getBalance(wallet, selectedToken);
if (!selectedToken || !wallet) {
setIsFundingPending(false);
return;
};

if (+amount >= +balance) {
setBalance(balance);
return;
}

const allowance = await getAllowance(
wallet,
selectedToken,
selectedNetwork
);
const balance = await getBalance(wallet, selectedToken);

if (+allowance < +amount) {
await approve(wallet, selectedToken, amount, selectedNetwork);
}
if (+amount >= +balance) {
setBalance(balance);
setIsFundingPending(false);
return;
}

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 allowance = await getAllowance(
wallet,
selectedToken,
selectedNetwork
);

await executeDonation({
donations,
network: selectedNetwork,
token: selectedToken,
});
setShowSuccessModal(true);
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 totalAmount = amounts.reduce((a, b) => a + b, 0);

if (+allowance < totalAmount) {
await approve(wallet, selectedToken, totalAmount, selectedNetwork);
}

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

setShowSuccessModal(true);
} catch (e: any) {
throw e;
} finally {
setIsFundingPending(false);
}
};

async function regenerateStrat(prompt: string) {
Expand Down Expand Up @@ -253,10 +275,10 @@ export default function Strategy(props: {
</div>
<Button
disabled={
selectedStrategiesLength === 0 || amount === "0" || amount === "" || isTransactionPending
selectedStrategiesLength === 0 || amount === "0" || amount === "" || isFundingPending
}
onClick={executeTransaction}>
{isTransactionPending ? (
{isFundingPending ? (
<>
<div>Pending</div>
<LoadingCircle hideText color='white' />
Expand Down
84 changes: 29 additions & 55 deletions web/hooks/useDonation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,42 @@ import {
getTokensForNetwork,
splitTransferFunds,
} from "@/utils/ethereum";
import { useState } from "react";
import { ethers } from "ethers";

export interface FundingEntry {
network: NetworkName;
token: TokenInformation;
donations: {
description: string;
title: string;
amount: string;
recipient: string;
}[];
}

export function useDonation() {
const [{ wallet }] = useConnectWallet();
const [isTransactionPending, setIsTransactionPending] = useState(false);

const execute = async (plan: FundingEntry) => {
if (!wallet || isTransactionPending) return;
const execute = async (
selectedNetwork: NetworkName,
selectedToken: TokenInformation,
recipientAddresses: string[],
amounts: number[]
) => {
if (!wallet) return;
const ethersProvider = new ethers.providers.Web3Provider(
wallet.provider,
"any"
);

const signer = ethersProvider.getSigner();

setIsTransactionPending(true);

const { network: selectedNetwork, token: selectedToken, donations } = plan;
const filteredDonations = donations.filter((d) => Number(d.amount) > 0);

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

if (!token) {
throw new Error(`Token with name: ${selectedToken} is not valid`);
}
const amounts = filteredDonations.map((d) => Number(d.amount));
console.log(plan, amounts, signer, token);
try {
await splitTransferFunds(
filteredDonations.map((d) => d.recipient),
amounts,
signer,
selectedNetwork,
token.address,
token.decimals
);
} catch (e) {
throw e;
} finally {
setIsTransactionPending(false);
}
console.log(recipientAddresses, amounts, signer, token, selectedNetwork);

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

const getBalance = async (wallet: WalletState, token: TokenInformation) => {
Expand Down Expand Up @@ -96,31 +77,24 @@ export function useDonation() {
const approve = async (
wallet: WalletState,
token: TokenInformation,
amount: string,
amount: number,
network: NetworkName
) => {
setIsTransactionPending(true);

try {
const ethersProvider = new ethers.providers.Web3Provider(
wallet.provider,
"any"
);
const signer = ethersProvider.getSigner();
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);
await approveTx.wait(1);
} finally {
setIsTransactionPending(false);
}
const ethersProvider = new ethers.providers.Web3Provider(
wallet.provider,
"any"
);
const signer = ethersProvider.getSigner();
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);
await approveTx.wait(1);
};

return {
execute,
isTransactionPending,
getBalance,
approve,
getAllowance
Expand Down
Loading