diff --git a/package.json b/package.json
index 7cc642904d..cd8676e25b 100644
--- a/package.json
+++ b/package.json
@@ -79,7 +79,6 @@
"@supabase/auth-helpers-nextjs": "^0.5.4",
"@supabase/auth-helpers-react": "^0.3.1",
"@supabase/supabase-js": "^2.10.0",
- "@sushiswap/sdk": "5.0.0-canary.116",
"@tanstack/react-query": "^5.49.2",
"@uiw/react-markdown-preview": "^4.1.13",
"@uiw/react-md-editor": "^3.23.3",
diff --git a/src/components/AMMPrices/TokenAMMPriceRow.tsx b/src/components/AMMPrices/TokenAMMPriceRow.tsx
deleted file mode 100644
index a260d4ee88..0000000000
--- a/src/components/AMMPrices/TokenAMMPriceRow.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import { LoadingOutlined } from '@ant-design/icons'
-import { t, Trans } from '@lingui/macro'
-import { Tooltip } from 'antd'
-import SushiswapLogo from 'components/icons/Sushiswap'
-import UniswapLogo from 'components/icons/Uniswap'
-import { ONE_TRILLION } from 'constants/numbers'
-import { classNames } from 'utils/classNames'
-import { formatOrTruncate } from 'utils/format/formatNumber'
-import ExternalLink from '../ExternalLink'
-import TooltipIcon from '../TooltipIcon'
-
-type ExchangeName = 'Uniswap' | 'Sushiswap'
-
-const LOGOS = {
- Uniswap: UniswapLogo,
- Sushiswap: SushiswapLogo,
-}
-
-type Props = {
- className?: string
- exchangeName: ExchangeName
- tokenSymbol: string
- exchangeLink?: string
- WETHPrice?: string
- loading?: boolean
-}
-
-const formatPrice = (price: string) => {
- const p = parseInt(price, 10)
- const formatLimit = ONE_TRILLION
-
- // format all values below trillion value, otherwise truncate is as long number.
- return formatOrTruncate(p, formatLimit)
-}
-
-const NotAvailableText = ({ WETHPrice, exchangeName, tokenSymbol }: Props) => {
- const tooltip = !WETHPrice
- ? t`${exchangeName} has no market for ${tokenSymbol}.`
- : ''
-
- return (
-
-
- {!WETHPrice ? Unavailable : null}
-
-
-
- )
-}
-
-export default function TokenAMMPriceRow({
- className,
- exchangeName,
- tokenSymbol,
- exchangeLink,
- WETHPrice,
- loading,
-}: Props) {
- const LogoComponent = LOGOS[exchangeName]
-
- return (
-
-
-
-
-
- {exchangeName}
-
- {loading &&
}
-
- {!loading &&
- (WETHPrice ? (
-
-
- {`${formatPrice(WETHPrice)} ${tokenSymbol} / ETH`}
-
-
- ) : (
-
- ))}
-
- )
-}
diff --git a/src/components/AMMPrices/hooks/useERC20SushiswapPrice.ts b/src/components/AMMPrices/hooks/useERC20SushiswapPrice.ts
deleted file mode 100644
index 52122b4c18..0000000000
--- a/src/components/AMMPrices/hooks/useERC20SushiswapPrice.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { CurrencyAmount, Pair, Route, Token, WETH9 } from '@sushiswap/sdk'
-import { useQuery } from '@tanstack/react-query'
-import IUniswapV2PairABI from '@uniswap/v2-core/build/IUniswapV2Pair.json'
-import { readNetwork } from 'constants/networks'
-import { WAD_DECIMALS } from 'constants/numbers'
-import { readProvider } from 'constants/readProvider'
-import { Contract } from 'ethers'
-
-/**
- * Fetches information about a pair and constructs a pair from the given two tokens.
- * @param tokenA first token
- * @param tokenB second token
- * @param provider the provider to use to fetch the data
- * Source: https://github.com/Uniswap/v2-sdk/blob/a88048e9c4198a5bdaea00883ca00c8c8e582605/src/fetcher.ts
- */
-async function fetchPairData(tokenA: Token, tokenB: Token): Promise {
- const pairAddress = Pair.getAddress(tokenA, tokenB)
-
- const [reserves0, reserves1] = await new Contract(
- pairAddress,
- IUniswapV2PairABI.abi,
- readProvider,
- ).getReserves()
-
- const balances = tokenA.sortsBefore(tokenB)
- ? [reserves0, reserves1]
- : [reserves1, reserves0]
- return new Pair(
- CurrencyAmount.fromRawAmount(tokenA, balances[0]),
- CurrencyAmount.fromRawAmount(tokenB, balances[1]),
- )
-}
-
-type Props = {
- tokenSymbol: string
- tokenAddress: string
-}
-
-const networkId = readNetwork.chainId
-
-export function useSushiswapPriceQuery({ tokenSymbol, tokenAddress }: Props) {
- const PROJECT_TOKEN = new Token(
- networkId,
- tokenAddress,
- WAD_DECIMALS,
- tokenSymbol,
- )
- const WETH = WETH9[networkId]
-
- return useQuery({
- queryKey: [`${tokenSymbol}-sushiswap-price`],
- queryFn: async () => {
- // note that you may want/need to handle this async code differently,
- // for example if top-level await is not an option
- const pair = await fetchPairData(PROJECT_TOKEN, WETH)
-
- const route = new Route([pair], WETH, PROJECT_TOKEN)
- return {
- tokenSymbol,
- midPrice: route.midPrice,
- }
- },
- })
-}
diff --git a/src/components/AMMPrices/index.tsx b/src/components/AMMPrices/index.tsx
deleted file mode 100644
index 78dba545f7..0000000000
--- a/src/components/AMMPrices/index.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Trans } from '@lingui/macro'
-import { generateAMMLink } from 'lib/amm'
-import { useSushiswapPriceQuery } from './hooks/useERC20SushiswapPrice'
-import { useUniswapPriceQuery } from './hooks/useERC20UniswapPrice'
-import TokenAMMPriceRow from './TokenAMMPriceRow'
-
-type Props = {
- mode: 'buy' | 'redeem'
- tokenSymbol: string
- tokenAddress: string
-}
-
-/**
- * Component for rendering a set of AMM Prices.
- */
-export default function AMMPrices({ mode, tokenSymbol, tokenAddress }: Props) {
- const { data: uniswapPriceData, isLoading: uniswapLoading } =
- useUniswapPriceQuery({
- tokenSymbol,
- tokenAddress,
- })
-
- const { data: sushiswapPriceData, isLoading: sushiswapLoading } =
- useSushiswapPriceQuery({
- tokenSymbol,
- tokenAddress,
- })
-
- return (
- <>
-
- Current 3rd Party Exchange Rates
-
-
-
- >
- )
-}
diff --git a/src/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx b/src/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx
index 8b72f915a4..ee3d20a30d 100644
--- a/src/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx
+++ b/src/components/Create/components/pages/ProjectDetails/ProjectDetailsPage.tsx
@@ -1,6 +1,5 @@
import { RightOutlined } from '@ant-design/icons'
import { t, Trans } from '@lingui/macro'
-import { ADDRESS_ZERO } from '@uniswap/v3-sdk'
import { Col, Form, Row } from 'antd'
import { Callout } from 'components/Callout/Callout'
import { useLockPageRulesWrapper } from 'components/Create/hooks/useLockPageRulesWrapper'
@@ -13,6 +12,7 @@ import { JuiceInput } from 'components/inputs/JuiceTextInput'
import PrefixedInput from 'components/inputs/PrefixedInput'
import { RichEditor } from 'components/RichEditor'
import { CREATE_FLOW } from 'constants/fathomEvents'
+import { constants } from 'ethers'
import { useWallet } from 'hooks/Wallet'
import { trackFathomGoal } from 'lib/fathom'
import Link from 'next/link'
@@ -166,7 +166,7 @@ export const ProjectDetailsPage: React.FC<
}),
])}
>
-
+
{projectOwnerDifferentThanWalletAddress && (
diff --git a/src/components/Project/RedeemAMMPrices.tsx b/src/components/Project/RedeemAMMPrices.tsx
deleted file mode 100644
index 215c64489b..0000000000
--- a/src/components/Project/RedeemAMMPrices.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { Trans } from '@lingui/macro'
-import { Tooltip } from 'antd'
-import Loading from 'components/Loading'
-import { Suspense, lazy } from 'react'
-const AMMPrices = lazy(() => import('components/AMMPrices'))
-
-export const RedeemAMMPrices = ({
- className,
- tokenSymbol,
- tokenAddress,
-}: {
- className?: string
- tokenSymbol: string
- tokenAddress: string
-}) => {
- return (
-
-
- or{' '}
- }>
-
-
- }
- placement="bottomLeft"
- >
-
- sell {tokenSymbol} on exchange.
-
-
-
-
- )
-}
diff --git a/src/lib/amm.ts b/src/lib/amm.ts
deleted file mode 100644
index c1b658e818..0000000000
--- a/src/lib/amm.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-export const generateAMMLink = ({
- mode,
- baseLink,
- tokenAddress,
-}: {
- mode: 'buy' | 'redeem'
- baseLink: string
- tokenAddress: string
-}) => {
- switch (mode) {
- case 'buy':
- return `${baseLink}/swap?inputCurrency=ETH&outputCurrency=${tokenAddress}`
- case 'redeem':
- return `${baseLink}/swap?inputCurrency=${tokenAddress}&outputCurrency=ETH`
- default:
- break
- }
-}
diff --git a/src/locales/messages.pot b/src/locales/messages.pot
index f89068ae21..828bdb844f 100644
--- a/src/locales/messages.pot
+++ b/src/locales/messages.pot
@@ -230,9 +230,6 @@ msgstr ""
msgid "Cycles:"
msgstr ""
-msgid "or <0><1>sell {tokenSymbol} on exchange.1>0>"
-msgstr ""
-
msgid "Amount (USD)"
msgstr ""
@@ -338,9 +335,6 @@ msgstr ""
msgid "<0>Owned by0><1/>"
msgstr ""
-msgid "{tokenSymbol}/ETH exchange rate on {exchangeName}."
-msgstr ""
-
msgid "Your payouts do not sum to 100%. Because your project is set to pay out all available ETH, the remainder will go to the project owner."
msgstr ""
@@ -1499,9 +1493,6 @@ msgstr ""
msgid "Still have questions or want to know more about us? Jump into our Discord and come say hello."
msgstr ""
-msgid "Project tokens can be redeemed to reclaim a portion of the ETH not needed for this cycle's payouts. The amount of ETH returned depends on this cycle's redemption rate.<0>Tokens are burned when they are redeemed.0>"
-msgstr ""
-
msgid "Mint {0}"
msgstr ""
@@ -1757,9 +1748,6 @@ msgstr ""
msgid "Untitled project"
msgstr ""
-msgid "or <0><1>buy {tokenText} on an exchange.1>0>"
-msgstr ""
-
msgid "{chainName} Project #{projectId}"
msgstr ""
@@ -1859,6 +1847,9 @@ msgstr ""
msgid "30 days"
msgstr ""
+msgid "Get more for your PEOPLE."
+msgstr ""
+
msgid "allocation"
msgstr ""
@@ -1985,6 +1976,9 @@ msgstr ""
msgid "Paid as <0/>"
msgstr ""
+msgid "Check <0>Uniswap0>, <1>SushiSwap1>, or other third-party exchanges for better rates before redeeming on Juicebox."
+msgstr ""
+
msgid "Send a percentage of reserved tokens to the wallets and Juicebox projects of your choosing. By default, reserved tokens are sent to the project owner."
msgstr ""
@@ -2354,9 +2348,6 @@ msgstr ""
msgid "reserved token recipient"
msgstr ""
-msgid "{nftCount, plural, one {+ # NFT} other {+ # NFTs}}"
-msgstr ""
-
msgid "Controller configuration"
msgstr ""
@@ -3170,6 +3161,9 @@ msgstr ""
msgid "{tokenTextSingular} recipients"
msgstr ""
+msgid "Project tokens can be redeemed to reclaim a portion of the ETH not needed for this cycle's payouts. The amount of ETH returned depends on this cycle's redemption rate. <0>Tokens are burned when they are redeemed.0>"
+msgstr ""
+
msgid "Will be rounded to <0/>{0}"
msgstr ""
@@ -3236,9 +3230,6 @@ msgstr ""
msgid "Notifications"
msgstr ""
-msgid "{exchangeName} has no market for {tokenSymbol}."
-msgstr ""
-
msgid "Logo"
msgstr ""
@@ -3344,9 +3335,6 @@ msgstr ""
msgid "to select"
msgstr ""
-msgid "Unavailable"
-msgstr ""
-
msgid "Burn token"
msgstr ""
@@ -3512,6 +3500,9 @@ msgstr ""
msgid "With an auction estimate of $10-15 million at Sotheby's, ConstitutionDAO wanted to raise as much as possible and decided to set Payouts to Unlimited. In order to build trust with potential supporters, the campaign set up a 9/13 multisig with core team members and well-known figures in web3. Reserved Rate was also set to 0 to guarantee that everyone had equal access to PEOPLE tokens which would govern the document if they won the auction."
msgstr ""
+msgid "Current Redemption Rate:"
+msgstr ""
+
msgid "Connected wallet not authorized"
msgstr ""
@@ -3548,9 +3539,6 @@ msgstr ""
msgid "No payouts are scheduled for this cycle. All ETH is available for redemption (subject to the redemption rate)."
msgstr ""
-msgid "Receive {receiveText}"
-msgstr ""
-
msgid "Need artwork?"
msgstr ""
@@ -4274,9 +4262,6 @@ msgstr ""
msgid "What's Juicebox?"
msgstr ""
-msgid "Current 3rd Party Exchange Rates"
-msgstr ""
-
msgid "Last {TRENDING_WINDOW_DAYS} days"
msgstr ""
diff --git a/src/packages/v1/components/V1Project/PayProjectForm/PayInputSubText.tsx b/src/packages/v1/components/V1Project/PayProjectForm/PayInputSubText.tsx
deleted file mode 100644
index 8f1458caa0..0000000000
--- a/src/packages/v1/components/V1Project/PayProjectForm/PayInputSubText.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-import { plural, Trans } from '@lingui/macro'
-import { Tooltip } from 'antd'
-import AMMPrices from 'components/AMMPrices'
-import { CurrencyContext } from 'contexts/CurrencyContext'
-import { BigNumber, utils } from 'ethers'
-import { useCurrencyConverter } from 'hooks/useCurrencyConverter'
-import useWeiConverter from 'hooks/useWeiConverter'
-import { CurrencyOption } from 'models/currencyOption'
-import { formatIssuanceRate } from 'packages/v2v3/utils/math'
-import { useContext, useMemo } from 'react'
-import { formattedNum } from 'utils/format/formatNumber'
-import { tokenSymbolText } from 'utils/tokenSymbolText'
-import { PayProjectFormContext } from './payProjectFormContext'
-
-/**
- * Help text shown below the Pay input field.
- *
- * If the user has entered an amount, display
- * the amount of project tokens they will receive.
- *
- * Else, display the exchange rate of the user selected currency to project token.
- */
-export default function PayInputSubText({
- payInCurrency,
- amount,
-}: {
- payInCurrency: CurrencyOption
- amount: string | undefined
-}) {
- const {
- currencyMetadata,
- currencies: { ETH },
- } = useContext(CurrencyContext)
- const { reservedRate, weight, tokenSymbol, tokenAddress, weightingFn, form } =
- useContext(PayProjectFormContext)
-
- const converter = useCurrencyConverter()
- const weiPayAmt = useWeiConverter({
- currency: payInCurrency,
- amount: amount,
- })
-
- const tokenText = tokenSymbolText({
- tokenSymbol,
- capitalize: false,
- plural: true,
- })
-
- const receiveText = useMemo(() => {
- const formatReceivedTickets = (wei: BigNumber): string | undefined => {
- const exchangeRate = weightingFn?.(weight, reservedRate, wei, 'payer')
- return exchangeRate
- ? formattedNum(formatIssuanceRate(exchangeRate))
- : undefined
- }
-
- if (weiPayAmt?.gt(0)) {
- const receivedTickets = formatReceivedTickets(weiPayAmt)
- const tokenReceiveText = tokenSymbolText({
- tokenSymbol,
- capitalize: false,
- plural: receivedTickets !== '1',
- })
- const nftCount = form?.payMetadata?.tierIdsToMint.length
- const nftText = nftCount
- ? plural(nftCount, {
- one: '+ # NFT',
- other: '+ # NFTs',
- })
- : ''
-
- return `${receivedTickets} ${tokenReceiveText} ${nftText}`
- }
-
- const receivedTickets = formatReceivedTickets(
- (payInCurrency === ETH
- ? utils.parseEther('1')
- : converter.usdToWei('1')) ?? BigNumber.from(0),
- )
-
- const tokenReceiveText = tokenSymbolText({
- tokenSymbol,
- capitalize: false,
- plural: receivedTickets !== '1',
- })
-
- return `${receivedTickets} ${tokenReceiveText}/1 ${currencyMetadata[payInCurrency]?.name}`
- }, [
- converter,
- payInCurrency,
- weiPayAmt,
- weight,
- currencyMetadata,
- ETH,
- reservedRate,
- tokenSymbol,
- form?.payMetadata?.tierIdsToMint.length,
- weightingFn,
- ])
-
- return (
-
-
- Receive {receiveText}
-
- {tokenSymbol && tokenAddress && (
-
-
- or{' '}
-
- }
- placement="bottomLeft"
- overlayClassName="min-w-xs"
- overlayInnerStyle={{ padding: '1rem' }}
- >
-
- buy {tokenText} on an exchange.
-
-
-
-
- )}
-
- )
-}
diff --git a/src/packages/v1/components/V1Project/PayProjectForm/PayProjectForm.tsx b/src/packages/v1/components/V1Project/PayProjectForm/PayProjectForm.tsx
index e0c1fa47ea..6e4485c9f5 100644
--- a/src/packages/v1/components/V1Project/PayProjectForm/PayProjectForm.tsx
+++ b/src/packages/v1/components/V1Project/PayProjectForm/PayProjectForm.tsx
@@ -6,7 +6,6 @@ import { NftRewardsContext } from 'packages/v2v3/contexts/NftRewards/NftRewardsC
import { useContext } from 'react'
import { fromWad } from 'utils/format/formatNumber'
import { getHighestAffordableNft, getNftRewardOfFloor } from 'utils/nftRewards'
-import PayInputSubText from './PayInputSubText'
import { PayProjectFormContext } from './payProjectFormContext'
export function PayProjectForm({ disabled }: { disabled?: boolean }) {
@@ -98,10 +97,6 @@ export function PayProjectForm({ disabled }: { disabled?: boolean }) {
/>
}
/>
-
-
-
-
- Redemption rate:{' '}
-
- {fcMetadata?.bondingCurveRate !== undefined
- ? fcMetadata.bondingCurveRate / 2
- : '--'}
- %
-
-
-
- {tokenSymbolText({ tokenSymbol, capitalize: true })} balance:{' '}
+
+ {isConstitutionDao ? (
+
+
+ Get more for your PEOPLE.
+ {' '}
+
+
+ Check{' '}
+
+ Uniswap
+
+ ,{' '}
+
+ SushiSwap
+
+ , or other third-party exchanges for better rates before
+ redeeming on Juicebox.
+
+
+
+ ) : null}
+
+
+
+ Your {tokenSymbolText({ tokenSymbol, capitalize: true })} balance:{' '}
{totalBalance ? (
-
+
+
+ Current Redemption Rate:{' '}
+
+ {fcMetadata?.bondingCurveRate !== undefined
+ ? fcMetadata.bondingCurveRate / 2
+ : '--'}
+ %
+
+
+
+
Currently worth:{' '}
@@ -171,13 +210,15 @@ export default function RedeemModal({
+
+
{overflow?.gt(0) ? (
Project tokens can be redeemed to reclaim a portion of the ETH not
needed for this cycle's payouts. The amount of ETH returned
- depends on this cycle's redemption rate.
-
+ depends on this cycle's redemption rate.{' '}
+
Tokens are burned when they are redeemed.
@@ -215,13 +256,6 @@ export default function RedeemModal({
disabled={totalBalance?.eq(0)}
onChange={val => setRedeemAmount(val)}
/>
- {tokenSymbol && tokenAddress ? (
-
- ) : null}
{overflow?.gt(0) ? (
@@ -234,7 +268,7 @@ export default function RedeemModal({
) : null}
-
+
)
}
diff --git a/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx b/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx
index 80f2804007..ba1eb9ca72 100644
--- a/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx
+++ b/src/packages/v2v3/components/V2V3Project/V2V3ManageTokensSection/AccountBalanceDescription/V2V3BurnOrRedeemModal.tsx
@@ -6,7 +6,6 @@ import { Callout } from 'components/Callout/Callout'
import ETHAmount from 'components/currency/ETHAmount'
import FormattedNumberInput from 'components/inputs/FormattedNumberInput'
import TransactionModal from 'components/modals/TransactionModal'
-import { RedeemAMMPrices } from 'components/Project/RedeemAMMPrices'
import { TokenAmount } from 'components/TokenAmount'
import { ProjectMetadataContext } from 'contexts/ProjectMetadataContext'
import { BigNumber } from 'ethers'
@@ -301,13 +300,6 @@ export function V2V3BurnOrRedeemModal({
disabled={totalBalance?.eq(0)}
onChange={val => setRedeemAmount(val)}
/>
- {tokenSymbol && tokenAddress ? (
-
- ) : null}