diff --git a/projects/dex-ui/src/wells/wellLoader.ts b/projects/dex-ui/src/wells/wellLoader.ts index 547a6d632..6c1a3a517 100644 --- a/projects/dex-ui/src/wells/wellLoader.ts +++ b/projects/dex-ui/src/wells/wellLoader.ts @@ -31,21 +31,27 @@ const WELL_BLACKLIST: Record = { "0x0adf75da6980fee8f848d52a7af1f8d6f34a8169".toLowerCase(), // BEAN:WETH duplicate, "0xc22dd977c50812f754c14319de84493cc18b6cf0".toLowerCase(), // BEAN:WETH duplicate "0x15d7a96c3dbf6b267fae741d15c3a72f331418fe".toLowerCase(), // BEAN:WETH duplicate + "0xd902f7bd849da907202d177fafc1bd39f6bbadc4".toLowerCase(), // BEAN:WETH duplicate "0xb968de36ce9c61371a82a78b715af660c2209d11".toLowerCase(), // BEAN:wstETH duplicate "0x430837acc8cfe4726453b09b8d782730654899e0".toLowerCase(), // BEAN:wstETH duplicate "0x4731431430e7febd8df6a4aa7d28867927e827a6".toLowerCase(), // BEAN:wstETH duplicate + "0xc49b38dff421622628258683444f4977078cb96b".toLowerCase(), // BEAN:wstETH duplicate "0x8d74ff8e729b4e78898488775b619c05d1ecb5e5".toLowerCase(), // BEAN:weETH duplicate "0x65709d322f9c762f9435a326c653e7393807c0bc".toLowerCase(), // BEAN:weETH duplicate "0x8dc6400022ac4304b3236f4d073053056ac24086".toLowerCase(), // BEAN:weETH duplicate + "0x45f6af24e6eb8371571dde1464a458770cbbbb65".toLowerCase(), // BEAN:weETH duplicate "0x370062BE2d6Fc8d02948fEA75fAfe471F74854CF".toLowerCase(), // BEAN:WBTC duplicate "0xee950139d7730706695a4613198ecac26e69e12d".toLowerCase(), // BEAN:WBTC duplicate "0xb147ff6e2fd05ad3db185028beb3cce4dcb12b72".toLowerCase(), // BEAN:WBTC duplicate + "0xd4baa4197aa17c7f27a2465073de33690d77ec7e".toLowerCase(), // BEAN:WBTC duplicate "0x157219b5D112F2D8aaFD3c7F3bA5D4c73343cc96".toLowerCase(), // BEAN:USDC duplicate "0xdc29769db1caa5cab41835ef9a42becde80de028".toLowerCase(), // BEAN:USDC duplicate "0xde1a4b24aa46286739c1879612c5e5445382d93d".toLowerCase(), // BEAN:USDC duplicate + "0xeaddd2848e962817fd565ea269a7fedb0588b3f4".toLowerCase(), // BEAN:USDC duplicate "0xF3e4FC5c53D5500989e68F81d070094525caC240".toLowerCase(), // BEAN:USDT duplicate "0xacfb4644b708043ad6eff1cc323fda374fe6d3ce".toLowerCase(), // BEAN:USDT duplicate - "0x704e68281325242a60515616228c668e4865694c".toLowerCase() // BEAN:USDT duplicate + "0x704e68281325242a60515616228c668e4865694c".toLowerCase(), // BEAN:USDT duplicate + "0xde8317a2a31a1684e2e4becedec17700718630d8".toLowerCase() // BEAN:USDT duplicate ] }; diff --git a/projects/ui/src/components/Common/Form/TokenInputField.tsx b/projects/ui/src/components/Common/Form/TokenInputField.tsx index c21f27a73..ecb4d0dd2 100644 --- a/projects/ui/src/components/Common/Form/TokenInputField.tsx +++ b/projects/ui/src/components/Common/Form/TokenInputField.tsx @@ -217,7 +217,7 @@ const TokenInput: FC = ({ balance: balance?.toString(), }); if (!amount) return undefined; // if no amount, exit - if (min?.gt(amount)) return min; // clamp @ min + if (amount.gt(0) && min?.gt(amount)) return min; // clamp @ min if (!allowNegative && amount?.lt(ZERO_BN)) return ZERO_BN; // clamp negative if (max?.lt(amount)) return max; // clamp @ max return amount; // no max; always return amount @@ -239,7 +239,6 @@ const TokenInput: FC = ({ /// /// FIXME: throws an error if e.target.value === '.' const newValue = e.target.value ? new BigNumber(e.target.value) : null; - /// Always update the display amount right away. setDisplayAmount(newValue?.toString() || ''); diff --git a/projects/ui/src/components/Common/Form/TokenSelectDialog.tsx b/projects/ui/src/components/Common/Form/TokenSelectDialog.tsx index 1697376cc..3d046b6f4 100644 --- a/projects/ui/src/components/Common/Form/TokenSelectDialog.tsx +++ b/projects/ui/src/components/Common/Form/TokenSelectDialog.tsx @@ -18,7 +18,7 @@ import { StyledDialogContent, StyledDialogTitle, } from '~/components/Common/Dialog'; -import { displayBN } from '~/util'; +import { displayBN, getTokenIndex } from '~/util'; import { ZERO_BN } from '~/constants'; import { FarmerBalances } from '~/state/farmer/balances'; import { FarmerSilo } from '~/state/farmer/silo'; @@ -116,17 +116,18 @@ const TokenSelectDialog: TokenSelectDialogC = React.memo( ); const getBalance = useCallback( - (addr: string) => { + (token: TokenInstance) => { if (!_balances) return ZERO_BN; if (balancesType === 'farm') return ( - (_balances as TokenBalanceMode['farm'])?.[addr]?.[ + (_balances as TokenBalanceMode['farm'])?.[getTokenIndex(token)]?.[ balanceFromInternal ] || ZERO_BN ); return ( - (_balances as TokenBalanceMode['silo-deposits'])?.[addr]?.deposited - ?.amount || ZERO_BN + (_balances as TokenBalanceMode['silo-deposits'])?.[ + getTokenIndex(token) + ]?.deposited?.amount || ZERO_BN ); }, [_balances, balancesType, balanceFromInternal] @@ -245,7 +246,7 @@ const TokenSelectDialog: TokenSelectDialogC = React.memo( {filteredTokenList ? filteredTokenList.map((_token) => { - const tokenBalance = getBalance(_token.address); + const tokenBalance = getBalance(_token); return ( - {message || isArbitrum ? "We're migrating!" : "We're on Arbitrum!"} + {message || isArbitrum ? "We're migrating!" : "We're on Arbitrum One!"} Please check diff --git a/projects/ui/src/components/Field/Actions/Sow.tsx b/projects/ui/src/components/Field/Actions/Sow.tsx index 5b991c98a..cd4ade6ec 100644 --- a/projects/ui/src/components/Field/Actions/Sow.tsx +++ b/projects/ui/src/components/Field/Actions/Sow.tsx @@ -68,6 +68,7 @@ import FormTxnProvider from '~/components/Common/Form/FormTxnProvider'; import useFormTxnContext from '~/hooks/sdk/useFormTxnContext'; import { ClaimAndDoX, SowFarmStep } from '~/lib/Txn'; import useTemperature from '~/hooks/beanstalk/useTemperature'; +import { useMinTokensIn } from '~/hooks/beanstalk/useMinTokensIn'; type SowFormValues = FormStateWithSwapQuote & { settings: SlippageSettingsFragment & { @@ -182,6 +183,8 @@ const SowForm: FC< ); const maxAmountUsed = maxAmountIn ? totalBeansAmount.div(maxAmountIn) : null; + const minTokenIn = useMinTokensIn(tokenIn, sdk.tokens.BEAN); + const txnActions = useFarmerFormTxnsActions({ showGraphicOnClaim: Bean.equals(tokenIn), claimBeansState: values.claimableBeans, @@ -298,6 +301,7 @@ const SowForm: FC< maxAmountIn || ZERO_BN, tokenInBalance?.[values.balanceFrom] || ZERO_BN )} + min={minTokenIn} balance={tokenInBalance || undefined} state={values.tokens[0]} showTokenSelect={showTokenSelect} diff --git a/projects/ui/src/components/Field/Chart/MorningTemperature.tsx b/projects/ui/src/components/Field/Chart/MorningTemperature.tsx index d548408fe..7246ab0a0 100644 --- a/projects/ui/src/components/Field/Chart/MorningTemperature.tsx +++ b/projects/ui/src/components/Field/Chart/MorningTemperature.tsx @@ -321,7 +321,7 @@ const MorningTemperature: React.FC<{ titleTooltip={ The interest rate for Sowing Beans. Beanstalk logarithmically - increases the Temperature for the first 25 blocks of each Season up + increases the Temperature for the first 5 minutes of each Season up to the Max Temperature. } diff --git a/projects/ui/src/components/Nav/Buttons/PriceButton.tsx b/projects/ui/src/components/Nav/Buttons/PriceButton.tsx index 35e1aecd0..8b7be7b08 100644 --- a/projects/ui/src/components/Nav/Buttons/PriceButton.tsx +++ b/projects/ui/src/components/Nav/Buttons/PriceButton.tsx @@ -37,7 +37,6 @@ import { useTokens } from '~/hooks/beanstalk/useTokens'; import { Token } from '@beanstalk/sdk'; import BigNumber from 'bignumber.js'; import useChainId from '~/hooks/chain/useChainId'; -import { IS_DEV } from '~/util'; import FolderMenu from '../FolderMenu'; type TokenPriceEntry = { @@ -290,7 +289,7 @@ const PriceButton: FC = ({ ...props }) => { poolState={beanPools[pool.address]} useTWA={showTWA} ButtonProps={{ - href: `${IS_DEV ? 'http://localhost:2424/#/wells' : BASIN_WELL_LINK}/${chainId}/${pool.address}`, + href: `${BASIN_WELL_LINK}${chainId}/${pool.address}`, target: '_blank', rel: 'noreferrer', }} diff --git a/projects/ui/src/components/Nav/routes.ts b/projects/ui/src/components/Nav/routes.ts index 1ddd4e17c..e58b289bb 100644 --- a/projects/ui/src/components/Nav/routes.ts +++ b/projects/ui/src/components/Nav/routes.ts @@ -11,6 +11,7 @@ import disclosuresIcon from '~/img/beanstalk/interface/nav/disclosures.svg'; import analyticsIcon from '~/img/beanstalk/interface/nav/stats.svg'; import basinIcon from '~/img/beanstalk/interface/nav/basin.svg'; import pipelineIcon from '~/img/beanstalk/interface/nav/pipeline.svg'; +import migrationIcon from '~/img/beanstalk/interface/nav/migration.svg'; export type RouteData = { /** Nav item title */ @@ -83,12 +84,12 @@ const ROUTES: { [key in RouteKeys]: RouteData[] } = { icon: governanceIcon, small: true, }, - // { - // path: '/preview', - // title: 'Migration Preview', - // icon: migrationIcon, - // small: true, - // }, + { + path: '/l2claim', + title: 'Claim Balances on L2', + icon: migrationIcon, + small: true, + }, { path: 'docs', href: 'https://docs.bean.money/almanac', diff --git a/projects/ui/src/components/Silo/Token/TokenAbout.tsx b/projects/ui/src/components/Silo/Token/TokenAbout.tsx index 09218b28f..051a334d9 100644 --- a/projects/ui/src/components/Silo/Token/TokenAbout.tsx +++ b/projects/ui/src/components/Silo/Token/TokenAbout.tsx @@ -5,7 +5,7 @@ import BigNumber from 'bignumber.js'; import { Link } from 'react-router-dom'; import Row from '~/components/Common/Row'; import { useAppSelector } from '~/state'; -import { BASIN_WELL_LINK, ZERO_BN } from '~/constants'; +import { BASE_ARBISCAN_ADDR_LINK, BASIN_WELL_LINK, ZERO_BN } from '~/constants'; import { InfoOutlined } from '@mui/icons-material'; import usePools from '~/hooks/beanstalk/usePools'; import useSdk from '~/hooks/sdk'; @@ -42,7 +42,7 @@ const TokenAbout = ({ token }: { token: Token }) => { Token address { const seedReward = new BigNumber(token.rewards?.seeds?.toHuman() || '0'); const stalkReward = new BigNumber(token.rewards?.stalk?.toHuman() || '0'); + const navigate = useNavigate(); return ( @@ -26,6 +28,7 @@ const TokenDepositRewards = ({ token }: { token: Token }) => { color="secondary" size="small" endIcon={} + onClick={() => navigate('/analytics')} > View rewards @@ -90,6 +93,7 @@ const TokenDepositRewards = ({ token }: { token: Token }) => { color="secondary" size="small" endIcon={} + onClick={() => navigate('/analytics')} > View Bean Supply diff --git a/projects/ui/src/components/Silo/Token/TokenDepositsOverview.tsx b/projects/ui/src/components/Silo/Token/TokenDepositsOverview.tsx index 185487ef2..0065bfa49 100644 --- a/projects/ui/src/components/Silo/Token/TokenDepositsOverview.tsx +++ b/projects/ui/src/components/Silo/Token/TokenDepositsOverview.tsx @@ -63,9 +63,10 @@ const TokenDepositsOverview = ({ token }: Props) => { - {' Deposits'} + Deposits {!isBEAN && ( @@ -87,9 +88,10 @@ const TokenDepositsOverview = ({ token }: Props) => { - {' Deposits'} + Deposits )} diff --git a/projects/ui/src/components/Swap/Actions/Swap.tsx b/projects/ui/src/components/Swap/Actions/Swap.tsx index 0054a42a1..d8c205bca 100644 --- a/projects/ui/src/components/Swap/Actions/Swap.tsx +++ b/projects/ui/src/components/Swap/Actions/Swap.tsx @@ -20,6 +20,7 @@ import { NativeToken, BeanSwapNodeQuote, BeanSwapOperation, + BeanstalkSDK, } from '@beanstalk/sdk'; import { FormApprovingState, @@ -35,14 +36,13 @@ import { import { TokenSelectMode } from '~/components/Common/Form/TokenSelectDialog'; import TokenInputField from '~/components/Common/Form/TokenInputField'; import FarmModeField from '~/components/Common/Form/FarmModeField'; -import { Beanstalk } from '~/generated/index'; import { ZERO_BN } from '~/constants'; import { useBeanstalkContract } from '~/hooks/ledger/useContract'; import useFarmerBalances from '~/hooks/farmer/useFarmerBalances'; import { useSigner } from '~/hooks/ledger/useSigner'; import useAccount from '~/hooks/ledger/useAccount'; -import { MinBN, tokenIshEqual } from '~/util'; +import { getTokenIndex, MinBN, tokenIshEqual } from '~/util'; import { IconSize } from '~/components/App/muiTheme'; import TransactionToast from '~/components/Common/TxnToast'; import { useFetchFarmerBalances } from '~/state/farmer/balances/updater'; @@ -62,6 +62,7 @@ import useQuoteWithParams, { QuoteHandlerResultNew, QuoteHandlerWithParams, } from '~/hooks/ledger/useQuoteWithParams'; +import { useMinTokensIn } from '~/hooks/beanstalk/useMinTokensIn'; /// --------------------------------------------------------------- @@ -113,7 +114,7 @@ const Quoting = ( const SwapForm: FC< FormikProps & { balances: ReturnType; - beanstalk: Beanstalk; + beanstalk: BeanstalkSDK['contracts']['beanstalk']; tokenList: (ERC20Token | NativeToken)[]; defaultValues: SwapFormValues; } @@ -161,15 +162,17 @@ const SwapForm: FC< [balances] ); + const minTokenIn = useMinTokensIn(tokenIn, tokenOut); + const [balanceIn, balanceInInput, balanceInMax] = useMemo(() => { - const _balanceIn = balances[tokenIn.address]; + const _balanceIn = balances[getTokenIndex(tokenIn)]; if (tokensMatch) { const _balanceInMax = _balanceIn[modeIn === FarmFromMode.INTERNAL ? 'internal' : 'external']; return [_balanceIn, _balanceInMax, _balanceInMax] as const; } return [_balanceIn, _balanceIn, _balanceIn?.total || ZERO_BN] as const; - }, [balances, modeIn, tokenIn.address, tokensMatch]); + }, [balances, modeIn, tokenIn, tokensMatch]); const [getAmountsBySource] = useGetBalancesUsedBySource({ tokens: values.tokensIn, @@ -197,12 +200,14 @@ const SwapForm: FC< ? FarmFromMode.INTERNAL : FarmFromMode.EXTERNAL ); + } else if (tokenIn.equals(sdk.tokens.ETH)) { + setFromOptions([BalanceFrom.EXTERNAL]); } else { setFromOptions([BalanceFrom.TOTAL]); setBalanceFromIn(BalanceFrom.TOTAL); setFieldValue('modeIn', FarmFromMode.INTERNAL_EXTERNAL); } - }, [tokensMatch, modeIn, modeOut, setFieldValue]); + }, [tokensMatch, modeIn, modeOut, tokenIn, sdk, setFieldValue]); const noBalance = !balanceInMax?.gt(0); const expectedFromMode = balanceIn @@ -237,6 +242,7 @@ const SwapForm: FC< inputToken.fromHuman(_amountIn.toString()), slippage ); + if (!quoteData) { throw new Error('No route found.'); } @@ -399,8 +405,21 @@ const SwapForm: FC< /// Flip destinations. setFieldValue('modeIn', modeOut); setFieldValue('modeOut', modeIn); + } else { + setFieldValue('tokensIn.0', { ...values.tokenOut }); + setFieldValue('tokenOut', { + ...values.tokensIn[0], + amount: undefined, + }); } - }, [modeIn, modeOut, setFieldValue, tokensMatch]); + }, [ + modeIn, + modeOut, + setFieldValue, + tokensMatch, + values.tokenOut, + values.tokensIn, + ]); // if tokenIn && tokenOut are equal and no balances are found, reverse positions. // This prevents setting of internal balance of given token when there is none @@ -420,8 +439,8 @@ const SwapForm: FC< (_tokens: Set) => { if (tokenSelect === 'tokenOut') { const newTokenOut = Array.from(_tokens)[0]; - setFieldValue('tokenOut.token', newTokenOut); if (tokenIn === newTokenOut) handleTokensEqual(); + setFieldValue('tokenOut.token', newTokenOut); } else if (tokenSelect === 'tokensIn') { const newTokenIn = Array.from(_tokens)[0]; setFieldValue('tokensIn.0.token', newTokenIn); @@ -512,6 +531,7 @@ const SwapForm: FC< ] : undefined } + min={minTokenIn} balance={balanceInInput} quote={quotingOut ? Quoting : undefined} onChange={handleChangeAmountIn} @@ -811,13 +831,12 @@ function getBeanSwapOperation( 'Output token does not match quote. Please refresh the quote.' ); } - if (!quote.sellAmount.eq(amountIn.toNumber())) { + if (!amountIn.eq(quote.sellAmount.toHuman())) { throw new Error( "Input amount doesn't match quote. Please refresh the quote." ); } - const formFmountOutTV = tokenOut.fromHuman(amountOut.toString()); - if (!quote.buyAmount.eq(formFmountOutTV)) { + if (!amountOut.eq(quote.buyAmount.toHuman())) { throw new Error( "Output amount doesn't match quote. Please refresh the quote." ); diff --git a/projects/ui/src/constants/chaininfo.ts b/projects/ui/src/constants/chaininfo.ts index 5ee34b09a..0ab86c8d5 100644 --- a/projects/ui/src/constants/chaininfo.ts +++ b/projects/ui/src/constants/chaininfo.ts @@ -63,7 +63,7 @@ export const CHAIN_INFO: ChainInfoMap = { explorer: 'https://arbiscan.io', explorerName: 'Arbiscan', explorerLogoUrl: arbitrumIcon, - label: 'Arbitrum', + label: 'Arbitrum One', logoUrl: ethereumLogoUrl, nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, statusPage: 'https://status.arbitrum.io/', diff --git a/projects/ui/src/constants/links.ts b/projects/ui/src/constants/links.ts index 203af19be..2db927990 100644 --- a/projects/ui/src/constants/links.ts +++ b/projects/ui/src/constants/links.ts @@ -48,6 +48,8 @@ export const HOW_TO_MM_PATH = /* Base Links */ export const BASE_ETHERSCAN_TX_LINK = 'https://etherscan.io/tx/'; export const BASE_ETHERSCAN_ADDR_LINK = 'https://etherscan.io/address/'; +export const BASE_ARBISCAN_TX_LINK = 'https://arbiscan.io/tx/'; +export const BASE_ARBISCAN_ADDR_LINK = 'https://arbiscan.io/address/'; /* Informational Links */ export const MEDIUM_INTEREST_LINK = diff --git a/projects/ui/src/hooks/beanstalk/useMinTokensIn.ts b/projects/ui/src/hooks/beanstalk/useMinTokensIn.ts new file mode 100644 index 000000000..410b62009 --- /dev/null +++ b/projects/ui/src/hooks/beanstalk/useMinTokensIn.ts @@ -0,0 +1,51 @@ +import { Token } from '@beanstalk/sdk'; +import BigNumber from 'bignumber.js'; +import { useAppSelector } from '~/state'; +import { getTokenIndex, tokenIshEqual } from '~/util'; +import { useMemo } from 'react'; +import { ZERO_BN } from '~/constants'; +import usePrice from './usePrice'; +import { useBalanceTokens } from './useTokens'; + +export function useMinTokensIn(tokenIn: Token, tokenOut: Token) { + const priceMap = useAppSelector((s) => s._beanstalk.tokenPrices); + const tokens = useBalanceTokens(); + const beanPrice = usePrice(); + + const min = useMemo(() => { + const getUsdValue = (t: Token) => { + if (tokenIshEqual(tokens.BEAN, t)) { + return beanPrice; + } + return priceMap[getTokenIndex(t)]; + }; + + const usdTokenIn1 = getUsdValue(tokenIn); + const usdTokenOut1 = getUsdValue(tokenOut); + + if (!usdTokenIn1 || !usdTokenOut1) { + return new BigNumber(1e-6); + } + + if (tokenIn.equals(tokens.ETH)) { + if (tokenOut.equals(tokens.WETH)) return ZERO_BN; + } + + if (tokenOut.equals(tokens.WETH)) { + if (tokenIn.equals(tokens.ETH)) return ZERO_BN; + } + + if (tokenIshEqual(tokenIn, tokenOut)) { + return ZERO_BN; + } + + if (tokenIn.decimals >= 8) { + return new BigNumber(10).pow(-8); + } + return new BigNumber(10).pow(-tokenIn.decimals); + }, [tokens, beanPrice, priceMap, tokenIn, tokenOut]); + + console.log('min: ', min.toString()); + + return min; +} diff --git a/projects/ui/src/hooks/chain/useIsSmartContract.ts b/projects/ui/src/hooks/chain/useIsSmartContract.ts index 0bc350fda..b98091f5f 100644 --- a/projects/ui/src/hooks/chain/useIsSmartContract.ts +++ b/projects/ui/src/hooks/chain/useIsSmartContract.ts @@ -19,7 +19,7 @@ export default function useIsSmartContract() { } else { setIsLoading(true); const _isContract = await getBytecode(client, { address: account as `0x${string}` }) - if (_isContract === "0x") { + if (_isContract === "0x" || !_isContract) { setIsContract(false); } else { setIsContract(true); diff --git a/projects/ui/src/pages/l1delegate.tsx b/projects/ui/src/pages/l1delegate.tsx index 2477f0f0a..d22dfe221 100644 --- a/projects/ui/src/pages/l1delegate.tsx +++ b/projects/ui/src/pages/l1delegate.tsx @@ -4,6 +4,7 @@ import { Button, Card, InputAdornment, + Link, TextField, Typography, } from '@mui/material'; @@ -211,6 +212,14 @@ export default function L1Delegate() { }; }, [l1ReadResults]) + useEffect(() => { + if (!isContract && account) { + checkAddress(account) + } else { + checkAddress("") + } + }, [isContract, account]) + useEffect(() => { getMigrationData(); }, [account, sdk]); @@ -331,9 +340,21 @@ export default function L1Delegate() { <> + {isContract && + + Done with this step? Click here to Claim your assets on Arbitrum One → + + } Delegate Balances @@ -356,7 +377,7 @@ export default function L1Delegate() { fontWeight={600} sx={{ alignSelf: 'center' }} > - Arbitrum + Arbitrum One { } @@ -367,12 +388,12 @@ export default function L1Delegate() { {(beanComplete) && - The specified account will automatically be credited with Circulating Beans once Migration data clears the Arbitrum bridge. + The specified account will automatically be credited with Circulating Beans once Migration data clears the Arbitrum One bridge. } {(migrateInternal && internalComplete) && - Smart Contracts must claim their Beanstalk assets on Arbitrum in order to complete the Migration process. Click the button below to continue. + Smart Contracts must claim their Beanstalk assets on Arbitrum One in order to complete the Migration process. Click the button below to continue. } @@ -435,7 +456,7 @@ export default function L1Delegate() { Beans held in your wallet will be - migrated and automatically sent to the specified address on Arbitrum. + migrated and automatically sent to the specified address on Arbitrum One.