diff --git a/src/components/views/donate/Recurring/ModifySuperToken/DepositSuperToken.tsx b/src/components/views/donate/Recurring/ModifySuperToken/DepositSuperToken.tsx
index 7396e7cb30..fb79d0c5e0 100644
--- a/src/components/views/donate/Recurring/ModifySuperToken/DepositSuperToken.tsx
+++ b/src/components/views/donate/Recurring/ModifySuperToken/DepositSuperToken.tsx
@@ -2,6 +2,7 @@ import { useState, type FC, useEffect } from 'react';
import { Button, Flex } from '@giveth/ui-design-system';
import { useAccount, useBalance } from 'wagmi';
import { useIntl } from 'react-intl';
+import { ethers } from 'ethers';
import { Framework } from '@superfluid-finance/sdk-core';
import { ISuperToken, IToken } from '@/types/superFluid';
import { AddressZero } from '@/lib/constants/constants';
@@ -125,6 +126,7 @@ export const DepositSuperToken: FC = ({
// EThx is not a Wrapper Super Token and should load separately
let superTokenAsset;
+ let newAmount = amount;
if (superToken.symbol === 'ETHx') {
superTokenAsset = await sf.loadNativeAssetSuperToken(
superToken.id,
@@ -132,10 +134,18 @@ export const DepositSuperToken: FC = ({
} else {
superTokenAsset = await sf.loadWrapperSuperToken(superToken.id);
}
+ if (token && token.decimals === 6) {
+ const divisor = BigInt(10 ** token.decimals);
+ const currentAmount = Number(amount) / Number(divisor);
+ newAmount = ethers.utils
+ .parseUnits(currentAmount.toString(), 18)
+ .toBigInt();
+ }
+ console.log('token', token);
+ console.log('supertoken', superToken);
const upgradeOperation = await superTokenAsset.upgrade({
- amount: amount.toString(),
+ amount: newAmount.toString(),
});
-
const tx = await upgradeOperation.exec(signer);
const res = await tx.wait();
if (!res.status) {
@@ -165,7 +175,6 @@ export const DepositSuperToken: FC = ({
closeModal();
}
};
-
return (
{step === EModifySuperTokenSteps.MODIFY ? (
diff --git a/src/components/views/donate/Recurring/ModifySuperToken/ModifySuperTokenModal.tsx b/src/components/views/donate/Recurring/ModifySuperToken/ModifySuperTokenModal.tsx
index a5a02b3812..39bc665f41 100644
--- a/src/components/views/donate/Recurring/ModifySuperToken/ModifySuperTokenModal.tsx
+++ b/src/components/views/donate/Recurring/ModifySuperToken/ModifySuperTokenModal.tsx
@@ -13,7 +13,7 @@ import { EModifySuperTokenSteps } from './common';
import config from '@/configuration';
interface IModifySuperTokenModalProps extends IModal {
- selectedToken: IToken;
+ selectedToken: ISuperToken | IToken;
tokenStreams: ISuperfluidStream[];
refreshBalance: () => void;
}
diff --git a/src/components/views/donate/Recurring/ModifySuperToken/WithDrawSuperToken.tsx b/src/components/views/donate/Recurring/ModifySuperToken/WithDrawSuperToken.tsx
index 4c9e2dbe3d..f0f1e5cd9e 100644
--- a/src/components/views/donate/Recurring/ModifySuperToken/WithDrawSuperToken.tsx
+++ b/src/components/views/donate/Recurring/ModifySuperToken/WithDrawSuperToken.tsx
@@ -187,7 +187,7 @@ export const WithDrawSuperToken: FC = ({
title='Withdraw from this stream balance'
amount={amount}
price={tokenPrice}
- token={token!}
+ token={superToken!}
/>
{
if (selectedRecurringToken.token.isSuperToken) {
setAmount(balance.value || 0n);
}
+ if (selectedRecurringToken.token.decimals === 6) {
+ setAmount(0n);
+ setPerMonthAmount(0n);
+ }
}, [selectedRecurringToken, balance]);
const underlyingToken = selectedRecurringToken?.token.underlyingToken;
+ // Introduce a scaling factor to handle tokens with different decimals
+ const scaleFactor =
+ selectedRecurringToken?.token.decimals === 6 ? 10000n : 1n;
+
// total means project + giveth
- const totalPerSec = perMonthAmount / ONE_MONTH_SECONDS;
+ const totalPerSec = perMonthAmount / (ONE_MONTH_SECONDS / scaleFactor);
const projectPerMonth =
(perMonthAmount * BigInt(100 - donationToGiveth)) / 100n;
const givethPerMonth = perMonthAmount - projectPerMonth;
const tokenBalance = balance?.value;
- const tokenStream = tokenStreams[selectedRecurringToken?.token.id || ''];
+ const tokenStream =
+ tokenStreams[selectedRecurringToken?.token.id.toLowerCase() || ''];
const anchorContractAddress = useMemo(
() => findAnchorContractAddress(project.anchorContracts),
@@ -168,7 +177,8 @@ export const RecurringDonationCard = () => {
0n,
) || 0n;
const totalStreamPerSec = totalPerSec + otherStreamsPerSec;
- const totalStreamPerMonth = totalStreamPerSec * ONE_MONTH_SECONDS;
+ const totalStreamPerMonth =
+ totalStreamPerSec * (ONE_MONTH_SECONDS / scaleFactor);
const streamRunOutInMonth =
totalStreamPerSec > 0 ? amount / totalStreamPerMonth : 0n;
const isTotalStreamExceed =
@@ -767,7 +777,9 @@ export const RecurringDonationCard = () => {
{showTopUpModal && selectedRecurringToken && (
= ({
{limitFraction(
- formatUnits(
- amount,
- token.underlyingToken?.decimals || 18,
- ),
+ formatUnits(amount, token.decimals || 18),
)}
- {token.symbol}
+ {token.underlyingToken?.symbol || token.symbol}
{subtext}
@@ -47,7 +44,7 @@ export const Item: FC = ({
.multipliedBy(amount.toString())
.toFixed(0),
),
- token.underlyingToken?.decimals || 18,
+ token.decimals || 18,
),
2,
)}
diff --git a/src/components/views/donate/Recurring/RecurringDonationModal/RecurringDonationModal.tsx b/src/components/views/donate/Recurring/RecurringDonationModal/RecurringDonationModal.tsx
index 76021e47e1..89863d004f 100644
--- a/src/components/views/donate/Recurring/RecurringDonationModal/RecurringDonationModal.tsx
+++ b/src/components/views/donate/Recurring/RecurringDonationModal/RecurringDonationModal.tsx
@@ -10,6 +10,7 @@ import { Framework, type Operation } from '@superfluid-finance/sdk-core';
import { useAccount } from 'wagmi';
import { useIntl } from 'react-intl';
import { formatUnits } from 'viem';
+import { ethers } from 'ethers';
import { Modal } from '@/components/modals/Modal';
import { useModalAnimation } from '@/hooks/useModalAnimation';
import { IModal } from '@/types/common';
@@ -227,10 +228,32 @@ const RecurringDonationInnerModal: FC = ({
const operations: Operation[] = [];
+ let newAmount = amount;
+ let newPerMonthAmount = perMonthAmount;
+
+ // This is a special case with tokens that have 6 decimals
+ // We need to convert the amount to 18 decimals for the upgrade operation
+ // And also for the flow rate calculation
+ if (selectedRecurringToken.token.decimals === 6) {
+ const divisor = BigInt(
+ 10 ** selectedRecurringToken.token.decimals,
+ );
+ const currentAmount = Number(amount) / Number(divisor);
+ newAmount = ethers.utils
+ .parseUnits(currentAmount.toString(), 18)
+ .toBigInt();
+
+ const currentPerMonth =
+ Number(perMonthAmount) / Number(divisor);
+ newPerMonthAmount = ethers.utils
+ .parseUnits(currentPerMonth.toString(), 18)
+ .toBigInt();
+ }
+
// Upgrade the token to super token
if (!isUpdating && !selectedRecurringToken.token.isSuperToken) {
const upgradeOperation = await superToken.upgrade({
- amount: amount.toString(),
+ amount: newAmount.toString(),
});
//Upgrading ETHx is a special case and can't be batched
@@ -245,8 +268,8 @@ const RecurringDonationInnerModal: FC = ({
throw new Error('Project wallet address not found');
}
- const _flowRate =
- (perMonthAmount * BigInt(100 - donationToGiveth)) /
+ let _flowRate =
+ (newPerMonthAmount * BigInt(100 - donationToGiveth)) /
100n /
ONE_MONTH_SECONDS;
@@ -279,7 +302,7 @@ const RecurringDonationInnerModal: FC = ({
}
const _newFlowRate =
- (perMonthAmount * BigInt(donationToGiveth)) /
+ (newPerMonthAmount * BigInt(donationToGiveth)) /
100n /
ONE_MONTH_SECONDS;
diff --git a/src/components/views/donate/Recurring/SelectTokenModal/SelectTokenModal.tsx b/src/components/views/donate/Recurring/SelectTokenModal/SelectTokenModal.tsx
index b6aa89e915..a841587642 100644
--- a/src/components/views/donate/Recurring/SelectTokenModal/SelectTokenModal.tsx
+++ b/src/components/views/donate/Recurring/SelectTokenModal/SelectTokenModal.tsx
@@ -51,6 +51,7 @@ const SelectTokenInnerModal: FC = ({
setShowModal,
}) => {
const [tokens, setTokens] = useState([]);
+ const [underlyingTokens, setUnderlyingTokens] = useState([]);
const [balances, setBalances] = useState({});
const { formatMessage } = useIntl();
@@ -84,11 +85,12 @@ const SelectTokenInnerModal: FC = ({
return acc;
}, {} as IBalances);
- const filteredTokens = superTokens.filter(
- token => !(newBalances[token.symbol] > 0n),
- );
+ const filteredTokens = superTokens.filter(token => {
+ return !(newBalances[token.underlyingToken.symbol] > 0n);
+ });
setTokens(filteredTokens);
+ setUnderlyingTokens(superTokens);
// Update the state with the new balances
setBalances(newBalances);
@@ -127,12 +129,14 @@ const SelectTokenInnerModal: FC = ({
{Object.keys(tokenStreams).map(tokenId => {
const token = superTokens.find(
- token => token.id === tokenId,
+ token =>
+ token.id.toLowerCase() ===
+ tokenId.toLowerCase(),
) as IToken;
return token ? (
= ({
) : null;
})}
{superTokens.map(token =>
- tokenStreams[token.id] ||
+ tokenStreams[token.id.toLowerCase()] ||
balances[token.symbol] === 0n ? null : (
= ({
id: 'label.superfluid_eligible_tokens_description',
})}
- {tokens.length > 0 ? (
- tokens.map(token => (
- {
- setSelectedRecurringToken({
- token: token.underlyingToken,
- balance:
- balances[
- token.underlyingToken.symbol
- ],
- });
- setShowModal(false);
- }}
- />
+ {underlyingTokens.length > 0 ? (
+ underlyingTokens.map(token => (
+ <>
+ {
+ setSelectedRecurringToken({
+ token: token.underlyingToken,
+ balance:
+ balances[
+ token.underlyingToken
+ .symbol
+ ],
+ });
+ setShowModal(false);
+ }}
+ />
+ >
))
) : (
diff --git a/src/components/views/userProfile/donationsTab/recurringTab/StreamRow.tsx b/src/components/views/userProfile/donationsTab/recurringTab/StreamRow.tsx
index 353678be1c..7df4fbd631 100644
--- a/src/components/views/userProfile/donationsTab/recurringTab/StreamRow.tsx
+++ b/src/components/views/userProfile/donationsTab/recurringTab/StreamRow.tsx
@@ -1,4 +1,4 @@
-import { useState, type FC } from 'react';
+import { useState, useMemo, type FC } from 'react';
import styled from 'styled-components';
import { P, brandColors, semanticColors } from '@giveth/ui-design-system';
import { formatUnits } from 'viem';
@@ -8,7 +8,7 @@ import { TokenIcon } from '@/components/views/donate/TokenIcon/TokenIcon';
import { TableCell } from './ActiveStreamsSection';
import { ISuperfluidStream } from '@/types/superFluid';
import { ONE_MONTH_SECONDS } from '@/lib/constants/constants';
-import { limitFraction } from '@/helpers/number';
+import { limitFraction, formatDonation } from '@/helpers/number';
import config from '@/configuration';
import { countActiveStreams } from '@/helpers/donate';
import { findTokenByAddress } from '@/helpers/superfluid';
@@ -19,6 +19,13 @@ interface IStreamRowProps {
}
export const StreamRow: FC = ({ tokenStream }) => {
+ const superToken = useMemo(
+ () =>
+ config.OPTIMISM_CONFIG.SUPER_FLUID_TOKENS.find(
+ s => s.id === tokenStream[0].token.id,
+ ),
+ [tokenStream],
+ );
const [showModifyModal, setShowModifyModal] = useState(false);
const { address, chain } = useAccount();
const { switchChain } = useSwitchChain();
@@ -39,7 +46,7 @@ export const StreamRow: FC = ({ tokenStream }) => {
0n,
);
const monthlyFlowRate = totalFlowRate * ONE_MONTH_SECONDS;
- const { symbol, decimals } = tokenStream[0].token;
+ // const { symbol } = tokenStream[0].token;
const runOutMonth =
monthlyFlowRate > 0 && balance?.value
? balance?.value / monthlyFlowRate
@@ -57,12 +64,12 @@ export const StreamRow: FC = ({ tokenStream }) => {
)
: '0'}
- {symbol}
+ {superToken?.symbol}
- {limitFraction(
- formatUnits(monthlyFlowRate || 0n, decimals),
+ {formatDonation(
+ limitFraction(formatUnits(BigInt(monthlyFlowRate), 18)),
)}
{underlyingSymbol}
@@ -109,11 +116,11 @@ export const StreamRow: FC = ({ tokenStream }) => {
Deposit/Withdraw
- {showModifyModal && (
+ {showModifyModal && superToken && (
)}
diff --git a/src/config/production.tsx b/src/config/production.tsx
index d394f547a6..3396524042 100644
--- a/src/config/production.tsx
+++ b/src/config/production.tsx
@@ -522,31 +522,46 @@ const config: EnvConfig = {
isSuperToken: true,
coingeckoId: 'dai',
},
- // {
- // underlyingToken: {
- // decimals: 6,
- // id: '0x7f5c764cbc14f9669b88837ca1490cca17c31607',
- // name: 'USD Coin',
- // symbol: 'USDC',
- // coingeckoId: 'usd-coin',
- // },
- // decimals: 18,
- // id: '0x8430f084b939208e2eded1584889c9a66b90562f',
- // name: 'Super USD Coin',
- // symbol: 'USDCx',
- // isSuperToken: true,
- // coingeckoId: 'usd-coin',
- // },
+ {
+ underlyingToken: {
+ decimals: 6,
+ id: '0x7f5c764cbc14f9669b88837ca1490cca17c31607',
+ name: 'Bridged USD Coin',
+ symbol: 'USDC.e',
+ coingeckoId: 'usd-coin',
+ },
+ decimals: 18,
+ id: '0x8430f084b939208e2eded1584889c9a66b90562f',
+ name: 'Super Bridged USD Coin',
+ symbol: 'USDC.ex',
+ isSuperToken: true,
+ coingeckoId: 'usd-coin',
+ },
+ {
+ underlyingToken: {
+ decimals: 6,
+ id: '0x0b2c639c533813f4aa9d7837caf62653d097ff85',
+ name: 'USD Coin',
+ symbol: 'USDC',
+ coingeckoId: 'usd-coin',
+ },
+ decimals: 18,
+ id: '0x35adeb0638eb192755b6e52544650603fe65a006',
+ name: 'Super USD Coin',
+ symbol: 'USDCx',
+ isSuperToken: true,
+ coingeckoId: 'usd-coin',
+ },
{
underlyingToken: {
decimals: 18,
- id: '0x4F604735c1cF31399C6E711D5962b2B3E0225AD3',
+ id: '0x4f604735c1cf31399c6e711d5962b2b3e0225ad3',
name: 'Glo Dollar',
symbol: 'USDGLO',
coingeckoId: 'glo-dollar',
},
decimals: 18,
- id: '0x9F41d0AA24E599fd8D0c180Ee3C0F609dc41c622',
+ id: '0x9f41d0aa24e599fd8d0c180ee3c0f609dc41c622',
name: 'Super Glo Dollar',
symbol: 'USDGLOx',
isSuperToken: true,