diff --git a/.gitignore b/.gitignore index b9fa1d938..7d401ff17 100644 --- a/.gitignore +++ b/.gitignore @@ -45,4 +45,5 @@ Thumbs.db # env .env.local -.nx/cache \ No newline at end of file +.nx/cache +.nx/workspace-data \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 265178b3f..d537a2801 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,5 @@ /dist /coverage generated -/.nx/cache \ No newline at end of file +/.nx/cache +/.nx/workspace-data \ No newline at end of file diff --git a/apps/defi/.env b/apps/defi/.env index 8eb265efb..9ea258cf4 100644 --- a/apps/defi/.env +++ b/apps/defi/.env @@ -6,7 +6,6 @@ VITE_WALLET_CONNECT_PROJECT_ID= # Alchemy account id VITE_ALCHEMY_ID= -VITE_ALCHEMY_ARBITRUM_ID= # Google Tag Manager container id for usage analytics, disabled if left blank VITE_GTM_CONTAINER_ID= diff --git a/apps/defi/index.html b/apps/defi/index.html index 2ab5b0de4..1349edccc 100644 --- a/apps/defi/index.html +++ b/apps/defi/index.html @@ -42,6 +42,9 @@ + + + @@ -55,7 +58,7 @@ - +
diff --git a/apps/defi/public/manifest.json b/apps/defi/public/manifest.json new file mode 100644 index 000000000..a259960e7 --- /dev/null +++ b/apps/defi/public/manifest.json @@ -0,0 +1,6 @@ +{ + "name": "Origin Unified Defi", + "description": "The official dapp for our groundbreaking multichain yield ecosystem", + "iconPath": "https://raw.githubusercontent.com/OriginProtocol/origin-defi/main/libs/shared/icons/src/origin/origin-logo.svg", + "providedBy": { "name": "Origin", "url": "https://www.originprotocol.com/" } +} diff --git a/apps/defi/src/components/Topnav/components/AlertPopover.tsx b/apps/defi/src/components/Topnav/components/AlertPopover.tsx new file mode 100644 index 000000000..c285004ba --- /dev/null +++ b/apps/defi/src/components/Topnav/components/AlertPopover.tsx @@ -0,0 +1,93 @@ +import { Divider, Stack, Typography } from '@mui/material'; +import { useTxButton } from '@origin/defi/shared'; +import { ClickAwayPopover, TokenIcon } from '@origin/shared/components'; +import { tokens } from '@origin/shared/contracts'; +import { PoweredBySafe } from '@origin/shared/icons'; +import { TxButton } from '@origin/shared/providers'; +import { useIntl } from 'react-intl'; + +import type { StackProps } from '@mui/material'; +import type { ClickAwayPopoverProps } from '@origin/shared/components'; +import type { Contract, Token } from '@origin/shared/contracts'; + +export const AlertPopover = ( + props: Omit, +) => { + const intl = useIntl(); + + return ( + + + + + {intl.formatMessage({ + defaultMessage: + 'It looks like you are minting from a contract and have not opted into yield. Contracts must opt-in to receive yield.', + })} + + + + }> + + + + + ); +}; + +type RebaseRowProps = { token: Token } & StackProps; + +const RebaseRow = ({ token, ...rest }: RebaseRowProps) => { + const intl = useIntl(); + const { params, callbacks } = useTxButton({ + params: { + contract: token as Contract, + functionName: 'rebaseOptIn', + value: 0n, + }, + activity: { + type: 'rebasing', + status: 'idle', + tokenIdIn: token.id, + }, + }); + + return ( + + + + {intl.formatMessage( + { defaultMessage: 'Enable rebasing for {symbol}' }, + { symbol: token.symbol }, + )} + + + + ); +}; diff --git a/apps/defi/src/components/Topnav/components/Topnav.tsx b/apps/defi/src/components/Topnav/components/Topnav.tsx index 7999266e8..06ee8a0ae 100644 --- a/apps/defi/src/components/Topnav/components/Topnav.tsx +++ b/apps/defi/src/components/Topnav/components/Topnav.tsx @@ -13,16 +13,24 @@ import { } from '@mui/material'; import Grid2 from '@mui/material/Unstable_Grid2/Grid2'; import { trackEvent, useActivitiesStatus } from '@origin/defi/shared'; -import { FaBarsRegular, OriginLabel } from '@origin/shared/icons'; +import { tokens } from '@origin/shared/contracts'; +import { + FaBarsRegular, + FaCircleExclamationRegular, + OriginLabel, +} from '@origin/shared/icons'; import { ChainMenuButton, OpenAccountModalButton, + useIsRebaseBannerVisible, } from '@origin/shared/providers'; +import { not } from 'ramda'; import { useIntl } from 'react-intl'; import { Link as RouterLink } from 'react-router-dom'; import { useAccount } from 'wagmi'; import { AccountPopover } from './AccountPopover'; +import { AlertPopover } from './AlertPopover'; import { DrawerMenu } from './DrawerMenu'; import { HoverMenu } from './HoverMenu'; @@ -34,10 +42,15 @@ export const Topnav = () => { const isSm = useMediaQuery(theme.breakpoints.down('md')); const accountMenuAnchorEl = useRef(null); const [accountMenuOpen, setAccountMenuOpen] = useState(false); + const alertMenuAnchorEl = useRef(null); + const [alertMenuOpen, setAlertMenuOpen] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false); const { status, pendingCount } = useActivitiesStatus(); + const isNonRebasingOETH = useIsRebaseBannerVisible(tokens.mainnet.OETH); + const isNonRebasingOUSD = useIsRebaseBannerVisible(tokens.mainnet.OUSD); const isLoading = status === 'pending' && pendingCount > 0; + const showRebaseMenu = isNonRebasingOETH || isNonRebasingOUSD; return ( <> @@ -106,6 +119,29 @@ export const Topnav = () => { gap: 1.25, }} > + {showRebaseMenu && ( + <> + + { + setAlertMenuOpen(false); + }} + /> + + )} { sx: { '&&&': { minWidth: 80, borderRadius: 2 } }, }} hideAddress={isMd} + hideWrongNetwork > {isLoading ? ( diff --git a/apps/defi/src/env.d.ts b/apps/defi/src/env.d.ts index 4e62a11be..2f6f1336e 100644 --- a/apps/defi/src/env.d.ts +++ b/apps/defi/src/env.d.ts @@ -4,7 +4,6 @@ interface ImportMetaEnv { readonly VITE_WALLET_CONNECT_PROJECT_ID: string; readonly VITE_ALCHEMY_ID: string; - readonly VITE_ALCHEMY_ARBITRUM_ID: string; readonly VITE_SUBSQUID_URL: string; readonly VITE_ALCHEMY_RPC: string; readonly VITE_CUSTOM_RPC?: string; diff --git a/apps/defi/src/lang/en.json b/apps/defi/src/lang/en.json index 7eeda8ddc..349448857 100644 --- a/apps/defi/src/lang/en.json +++ b/apps/defi/src/lang/en.json @@ -271,6 +271,12 @@ "value": "OETH analytics" } ], + "2zUGfB": [ + { + "type": 0, + "value": "Enable rebasing" + } + ], "3Lr8o5": [ { "type": 0, @@ -651,6 +657,12 @@ "value": "The amount of OGV in your wallet" } ], + "9/afiv": [ + { + "type": 0, + "value": "Signing" + } + ], "94TAJq": [ { "type": 0, @@ -1031,6 +1043,12 @@ "value": "0 months" } ], + "Fbsq1t": [ + { + "type": 0, + "value": "Rebasing enabled" + } + ], "FfOtze": [ { "type": 1, @@ -1177,6 +1195,12 @@ "value": "Claim Rewards" } ], + "IP0AHa": [ + { + "type": 0, + "value": "Error while enabling rebasing" + } + ], "IfZsEo": [ { "type": 0, @@ -2505,6 +2529,12 @@ "value": "Quorum" } ], + "icM8PS": [ + { + "type": 0, + "value": "It looks like you are minting from a contract and have not opted into yield. Contracts must opt-in to receive yield." + } + ], "j8y+qc": [ { "type": 1, @@ -2625,6 +2655,16 @@ "value": "Approving" } ], + "m2eUvr": [ + { + "type": 0, + "value": "Enable rebasing for " + }, + { + "type": 1, + "value": "symbol" + } + ], "m9XypM": [ { "type": 0, @@ -3003,6 +3043,12 @@ "value": "Casting vote" } ], + "v0B1E9": [ + { + "type": 0, + "value": "Enabling rebasing" + } + ], "vLIiaK": [ { "type": 0, @@ -3127,6 +3173,16 @@ "value": "Earnings and transaction history" } ], + "xpU+qf": [ + { + "type": 1, + "value": "symbolIn" + }, + { + "type": 0, + "value": " on contract" + } + ], "xwfunk": [ { "type": 0, diff --git a/apps/defi/src/lang/extracts/en.json b/apps/defi/src/lang/extracts/en.json index 49f1a6dda..72ce19be7 100644 --- a/apps/defi/src/lang/extracts/en.json +++ b/apps/defi/src/lang/extracts/en.json @@ -119,6 +119,9 @@ "2ahSeJ": { "defaultMessage": "OETH analytics" }, + "2zUGfB": { + "defaultMessage": "Enable rebasing" + }, "3Lr8o5": { "defaultMessage": "Larger redemptions coming soon" }, @@ -260,6 +263,9 @@ "8w4BfJ": { "defaultMessage": "The amount of OGV in your wallet" }, + "9/afiv": { + "defaultMessage": "Signing" + }, "94TAJq": { "defaultMessage": "TVL: {tvl}" }, @@ -410,6 +416,9 @@ "F6lS59": { "defaultMessage": "0 months" }, + "Fbsq1t": { + "defaultMessage": "Rebasing enabled" + }, "FfOtze": { "defaultMessage": "{value}" }, @@ -467,6 +476,9 @@ "IEM00S": { "defaultMessage": "Claim Rewards" }, + "IP0AHa": { + "defaultMessage": "Error while enabling rebasing" + }, "IfZsEo": { "defaultMessage": "Vote against" }, @@ -983,6 +995,9 @@ "ibDi9l": { "defaultMessage": "Quorum" }, + "icM8PS": { + "defaultMessage": "It looks like you are minting from a contract and have not opted into yield. Contracts must opt-in to receive yield." + }, "j8y+qc": { "defaultMessage": "{label}" }, @@ -1043,6 +1058,9 @@ "m/L3sK": { "defaultMessage": "Approving" }, + "m2eUvr": { + "defaultMessage": "Enable rebasing for {symbol}" + }, "m9XypM": { "defaultMessage": "Sending {amount} {symbolIn} to {chainOut}." }, @@ -1208,6 +1226,9 @@ "utrdPr": { "defaultMessage": "Casting vote" }, + "v0B1E9": { + "defaultMessage": "Enabling rebasing" + }, "vLIiaK": { "defaultMessage": "Bridge {symbol}" }, @@ -1259,6 +1280,9 @@ "xnfnI5": { "defaultMessage": "Earnings and transaction history" }, + "xpU+qf": { + "defaultMessage": "{symbolIn} on contract" + }, "xwfunk": { "defaultMessage": "Restricted Access" }, diff --git a/apps/defi/vite.config.mts b/apps/defi/vite.config.mts index fde1fda22..71be46649 100644 --- a/apps/defi/vite.config.mts +++ b/apps/defi/vite.config.mts @@ -10,6 +10,7 @@ export default defineConfig({ root: __dirname, build: { outDir: '../../dist/apps/defi', + emptyOutDir: true, reportCompressedSize: true, commonjsOptions: { transformMixedEsModules: true, diff --git a/apps/governance/vite.config.mts b/apps/governance/vite.config.mts index 951c9f213..e735413e0 100644 --- a/apps/governance/vite.config.mts +++ b/apps/governance/vite.config.mts @@ -10,6 +10,7 @@ export default defineConfig({ root: __dirname, build: { outDir: '../../dist/apps/governance', + emptyOutDir: true, reportCompressedSize: true, commonjsOptions: { transformMixedEsModules: true, diff --git a/apps/oeth/vite.config.mts b/apps/oeth/vite.config.mts index 71d8b6f58..936c579a5 100644 --- a/apps/oeth/vite.config.mts +++ b/apps/oeth/vite.config.mts @@ -10,6 +10,7 @@ export default defineConfig({ root: __dirname, build: { outDir: '../../dist/apps/oeth', + emptyOutDir: true, reportCompressedSize: true, commonjsOptions: { transformMixedEsModules: true, diff --git a/apps/ousd/vite.config.mts b/apps/ousd/vite.config.mts index a258ebe11..f11583297 100644 --- a/apps/ousd/vite.config.mts +++ b/apps/ousd/vite.config.mts @@ -10,6 +10,7 @@ export default defineConfig({ root: __dirname, build: { outDir: '../../dist/apps/ousd', + emptyOutDir: true, reportCompressedSize: true, commonjsOptions: { transformMixedEsModules: true, diff --git a/apps/prime/vite.config.mts b/apps/prime/vite.config.mts index 14fe9ef48..d17f9ccb1 100644 --- a/apps/prime/vite.config.mts +++ b/apps/prime/vite.config.mts @@ -10,6 +10,7 @@ export default defineConfig({ root: __dirname, build: { outDir: '../../dist/apps/prime', + emptyOutDir: true, reportCompressedSize: true, commonjsOptions: { transformMixedEsModules: true, diff --git a/libs/defi/ogv/src/migration/components/ConvertModal.tsx b/libs/defi/ogv/src/migration/components/ConvertModal.tsx index eada23e4d..b9be40b34 100644 --- a/libs/defi/ogv/src/migration/components/ConvertModal.tsx +++ b/libs/defi/ogv/src/migration/components/ConvertModal.tsx @@ -102,45 +102,29 @@ export const ConvertModal = ({ } = useApprovalButton({ token: tokens.mainnet.OGV, amount: total, - spender: isNilOrEmpty(veOgvlockups) - ? contracts.mainnet.zapperMigrator.address - : contracts.mainnet.OGVMigrator.address, + spender: contracts.mainnet.OGVMigrator.address, enableAllowance: true, enableGas: true, }); - const params = isNilOrEmpty(veOgvlockups) - ? { - contract: contracts.mainnet.zapperMigrator, - functionName: 'migrate', - args: [ - ogvBalance, - ...(stakingRatio > 0 - ? [stakedConverted[0], getMonthDurationToSeconds(duration)] - : []), - ], - } - : { - contract: contracts.mainnet.OGVMigrator, - functionName: 'migrate', - args: [ - veOgvlockups?.map((l) => BigInt(l.lockupId)) ?? [], - ogvBalance, - 0n, - ogvRewards > 0n, - stakedConverted[0], - stakingRatio > 0 ? getMonthDurationToSeconds(duration) : 0n, - ], - }; - const { params: writeParams, callbacks: writeCallbacks, gasPrice: writeGas, isWriteGasLoading, } = useTxButton({ - // eslint-disable-next-line @typescript-eslint/no-explicit-any - params: params as any, + params: { + contract: contracts.mainnet.OGVMigrator, + functionName: 'migrate', + args: [ + veOgvlockups?.map((l) => BigInt(l.lockupId)) ?? [], + ogvBalance, + 0n, + ogvRewards > 0n, + stakedConverted[0], + stakingRatio > 0 ? getMonthDurationToSeconds(duration) : 0n, + ], + }, callbacks: { onWriteSuccess: () => { queryClient.invalidateQueries(); diff --git a/libs/defi/shared/src/clients/wagmi.ts b/libs/defi/shared/src/clients/wagmi.ts index 9a85c7bea..7426746b5 100644 --- a/libs/defi/shared/src/clients/wagmi.ts +++ b/libs/defi/shared/src/clients/wagmi.ts @@ -53,7 +53,7 @@ export const wagmiConfig = createConfig({ ? fallback([ http( `${import.meta.env.VITE_ALCHEMY_ARBITRUM_RPC}${ - import.meta.env.VITE_ALCHEMY_ARBITRUM_ID + import.meta.env.VITE_ALCHEMY_ID }`, ), http(), diff --git a/libs/defi/shared/src/components/Activities/components/ActivityTile.tsx b/libs/defi/shared/src/components/Activities/components/ActivityTile.tsx index e142c439d..00aa8bce9 100644 --- a/libs/defi/shared/src/components/Activities/components/ActivityTile.tsx +++ b/libs/defi/shared/src/components/Activities/components/ActivityTile.tsx @@ -1,5 +1,9 @@ import { Box, Stack, Typography } from '@mui/material'; -import { ErrorTooltipLabel, ExternalLink } from '@origin/shared/components'; +import { + ErrorTooltipLabel, + ExternalLink, + TooltipLabel, +} from '@origin/shared/components'; import { isNilOrEmpty } from '@origin/shared/utils'; import { useIntl } from 'react-intl'; @@ -19,7 +23,6 @@ export const ActivityTile = ({ activity, ...rest }: ActivityTileProps) => { const title = option.title(activity, intl); const subtitle = option.subtitle(activity, intl); const icon = option.icon(activity); - const endIcon = option?.endIcon?.(activity) ?? option.icon(activity); const href = isNilOrEmpty(activity?.txHash) ? undefined : `https://etherscan.io/tx/${activity?.txHash}`; @@ -29,7 +32,7 @@ export const ActivityTile = ({ activity, ...rest }: ActivityTileProps) => { {icon} - + {!isNilOrEmpty(href) ? ( @@ -38,17 +41,19 @@ export const ActivityTile = ({ activity, ...rest }: ActivityTileProps) => { {title} )} - - {isNilOrEmpty(activity?.error) ? ( - {subtitle} - ) : ( - {activity.error} - )} - - - - {endIcon} + {isNilOrEmpty(activity?.error) ? ( + + {subtitle} + + ) : ( + {activity.error} + )} + {!isNilOrEmpty(option?.endIcon?.(activity)) && ( + + {option?.endIcon?.(activity)} + + )} ); }; diff --git a/libs/defi/shared/src/components/Activities/constants.tsx b/libs/defi/shared/src/components/Activities/constants.tsx index fb22cddcc..8e1495842 100644 --- a/libs/defi/shared/src/components/Activities/constants.tsx +++ b/libs/defi/shared/src/components/Activities/constants.tsx @@ -27,6 +27,7 @@ import type { DelegateVoteActivity, ExtendStakeActivity, MigrateActivity, + RebasingActivity, RedeemActivity, StakeActivity, SwapActivity, @@ -361,6 +362,35 @@ export const activityOptions: Record = { return ; }, }, + rebasing: { + title: (activity, intl) => + ({ + pending: intl.formatMessage({ defaultMessage: 'Enabling rebasing' }), + signed: intl.formatMessage({ defaultMessage: 'Enabling rebasing' }), + success: intl.formatMessage({ defaultMessage: 'Rebasing enabled' }), + error: intl.formatMessage({ + defaultMessage: 'Error while enabling rebasing', + }), + idle: intl.formatMessage({ defaultMessage: 'Enable rebasing' }), + })[activity.status], + subtitle: (activity, intl) => { + const { tokenIdIn } = activity as RebasingActivity; + const tokenIn = getTokenById(tokenIdIn); + + return intl.formatMessage( + { + defaultMessage: '{symbolIn} on contract', + }, + { symbolIn: tokenIn.symbol }, + ); + }, + icon: (activity) => { + const { tokenIdIn } = activity as RebasingActivity; + const tokenIn = getTokenById(tokenIdIn); + + return ; + }, + }, redeem: { title: (activity, intl) => ({ diff --git a/libs/defi/shared/src/components/Activities/types.ts b/libs/defi/shared/src/components/Activities/types.ts index 67c82baef..5d4a58fc6 100644 --- a/libs/defi/shared/src/components/Activities/types.ts +++ b/libs/defi/shared/src/components/Activities/types.ts @@ -96,6 +96,11 @@ export interface VoteActivity extends ActivityBase { proposalId: string; } +export interface RebasingActivity extends ActivityBase { + type: 'rebasing'; + tokenIdIn: TokenId; +} + export type Activity = | ApprovalActivity | BridgeActivity @@ -103,6 +108,7 @@ export type Activity = | DelegateVoteActivity | ExtendStakeActivity | MigrateActivity + | RebasingActivity | RedeemActivity | StakeActivity | SwapActivity diff --git a/libs/defi/shared/src/components/Banners/RebasingBanner.tsx b/libs/defi/shared/src/components/Banners/RebasingBanner.tsx new file mode 100644 index 000000000..1313a9153 --- /dev/null +++ b/libs/defi/shared/src/components/Banners/RebasingBanner.tsx @@ -0,0 +1,67 @@ +import { + Collapse, + Stack, + Typography, + useMediaQuery, + useTheme, +} from '@mui/material'; +import { TokenIcon } from '@origin/shared/components'; +import { TxButton, useIsRebaseBannerVisible } from '@origin/shared/providers'; +import { useIntl } from 'react-intl'; + +import { useTxButton } from '../TxButton'; + +import type { StackProps } from '@mui/material'; +import type { Contract, Token } from '@origin/shared/contracts'; + +export type RebasingBannerProps = { token: Token } & StackProps; + +export const RebasingBanner = ({ token, ...rest }: RebasingBannerProps) => { + const intl = useIntl(); + const theme = useTheme(); + const isSmall = useMediaQuery(theme.breakpoints.down('md')); + const isBannerVisible = useIsRebaseBannerVisible(token); + const { params, callbacks } = useTxButton({ + params: { + contract: token as Contract, + functionName: 'rebaseOptIn', + value: 0n, + }, + activity: { + type: 'rebasing', + status: 'idle', + tokenIdIn: token.id, + }, + }); + + return ( + + + + + {intl.formatMessage({ + defaultMessage: + 'It looks like you are minting from a contract and have not opted into yield. You must opt-in to receive yield.', + })} + + + + + ); +}; diff --git a/libs/defi/shared/src/components/Banners/index.ts b/libs/defi/shared/src/components/Banners/index.ts index cdd4a39e6..f575317ef 100644 --- a/libs/defi/shared/src/components/Banners/index.ts +++ b/libs/defi/shared/src/components/Banners/index.ts @@ -1 +1,2 @@ export * from './MergerBanner'; +export * from './RebasingBanner'; diff --git a/libs/defi/theme/src/components.tsx b/libs/defi/theme/src/components.tsx index c1073d5d6..e1a7bd3b7 100644 --- a/libs/defi/theme/src/components.tsx +++ b/libs/defi/theme/src/components.tsx @@ -286,30 +286,25 @@ export const components = (base: Theme): ThemeOptions => ({ defaultProps: { enableColorScheme: true, }, - styleOverrides: (theme) => ` - html { - overflow-x: hidden; - padding-left: calc(100vw - 100%); - } - - body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - text-rendering: optimizeLegibility; - font-size: ${theme.typography.body3.fontSize}px; - line-height: ${theme.typography.body3.lineHeight}; - font-weight: ${theme.typography.body3.fontWeight}; - } - - input[type=number] { - -moz-appearance: textfield; - } - - input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; - } - `, + styleOverrides: (theme) => ({ + body: { + height: '100%', + '-webkit-font-smoothing': 'antialiased', + '-moz-osx-font-smoothing': 'grayscale', + textRendering: 'optimizeLegibility', + fontSize: theme.typography.body3.fontSize, + lineHeight: theme.typography.body3.lineHeight, + fontWeight: theme.typography.body3.fontWeight, + }, + 'input[type=number]': { + '-moz-appearance': 'textfield', + }, + 'input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button': + { + '-webkit-appearance': 'none', + margin: 0, + }, + }), }, MuiDialog: { defaultProps: { diff --git a/libs/shared/contracts/src/abis/ZapperMigrator.ts b/libs/shared/contracts/src/abis/ZapperMigrator.ts deleted file mode 100644 index 85fa096e2..000000000 --- a/libs/shared/contracts/src/abis/ZapperMigrator.ts +++ /dev/null @@ -1,164 +0,0 @@ -export const ZapperMigratorABI = [ - { - type: 'constructor', - inputs: [ - { - name: '_ogv', - type: 'address', - internalType: 'address', - }, - { - name: '_ogn', - type: 'address', - internalType: 'address', - }, - { - name: '_migrator', - type: 'address', - internalType: 'address', - }, - { - name: '_ognStaking', - type: 'address', - internalType: 'address', - }, - { - name: '_governor', - type: 'address', - internalType: 'address', - }, - ], - stateMutability: 'nonpayable', - }, - { - type: 'function', - name: 'governor', - inputs: [], - outputs: [ - { - name: '', - type: 'address', - internalType: 'address', - }, - ], - stateMutability: 'view', - }, - { - type: 'function', - name: 'initialize', - inputs: [], - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - name: 'migrate', - inputs: [ - { - name: 'ogvAmount', - type: 'uint256', - internalType: 'uint256', - }, - ], - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - name: 'migrate', - inputs: [ - { - name: 'ogvAmount', - type: 'uint256', - internalType: 'uint256', - }, - { - name: 'newStakeAmount', - type: 'uint256', - internalType: 'uint256', - }, - { - name: 'newStakeDuration', - type: 'uint256', - internalType: 'uint256', - }, - ], - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - name: 'migrator', - inputs: [], - outputs: [ - { - name: '', - type: 'address', - internalType: 'contract IMigrator', - }, - ], - stateMutability: 'view', - }, - { - type: 'function', - name: 'ogn', - inputs: [], - outputs: [ - { - name: '', - type: 'address', - internalType: 'contract IMintableERC20', - }, - ], - stateMutability: 'view', - }, - { - type: 'function', - name: 'ognStaking', - inputs: [], - outputs: [ - { - name: '', - type: 'address', - internalType: 'contract IStaking', - }, - ], - stateMutability: 'view', - }, - { - type: 'function', - name: 'ogv', - inputs: [], - outputs: [ - { - name: '', - type: 'address', - internalType: 'contract IMintableERC20', - }, - ], - stateMutability: 'view', - }, - { - type: 'function', - name: 'transferTokens', - inputs: [ - { - name: 'token', - type: 'address', - internalType: 'address', - }, - { - name: 'amount', - type: 'uint256', - internalType: 'uint256', - }, - ], - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'error', - name: 'NotGovernor', - inputs: [], - }, -] as const; diff --git a/libs/shared/contracts/src/contracts.ts b/libs/shared/contracts/src/contracts.ts index c8aa05d6f..87da7885d 100644 --- a/libs/shared/contracts/src/contracts.ts +++ b/libs/shared/contracts/src/contracts.ts @@ -29,7 +29,6 @@ import { UniswapV3RouterABI } from './abis/UniswapV3Router'; import { UniswapV3WETHPrimeETHPoolABI } from './abis/UniswapV3WETHPrimeETHPool'; import { WOETHCCIPZapperABI } from './abis/WOETHCCIPZapper'; import { xOGNGovernanceABI } from './abis/xOGNGovernance'; -import { ZapperMigratorABI } from './abis/ZapperMigrator'; export const contracts = { mainnet: { @@ -238,12 +237,6 @@ export const contracts = { abi: xOGNGovernanceABI, name: 'xOGNGovernance', }, - zapperMigrator: { - address: '0xC202CDa20A8C34C7a282890eAE2Bb9CC0B115877', - chainId: mainnet.id, - abi: ZapperMigratorABI, - name: 'zapperMigrator', - }, }, arbitrum: { // Chainlink CCIP diff --git a/libs/shared/providers/src/prices/types.ts b/libs/shared/providers/src/prices/types.ts index bbd268fd5..971d13acc 100644 --- a/libs/shared/providers/src/prices/types.ts +++ b/libs/shared/providers/src/prices/types.ts @@ -1,9 +1,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import type { HexAddress } from '@origin/shared/utils'; import type { ReadContractParameters } from 'viem'; export type WagmiOption = { id: SupportedTokenPrice; config: ReadContractParameters & { + address: HexAddress; chainId: number; }; mapResult?: (args: any) => number; diff --git a/libs/shared/providers/src/rebaseBanner/components/RebaseBanner.tsx b/libs/shared/providers/src/rebaseBanner/components/RebaseBanner.tsx index 994ab075f..165c93f26 100644 --- a/libs/shared/providers/src/rebaseBanner/components/RebaseBanner.tsx +++ b/libs/shared/providers/src/rebaseBanner/components/RebaseBanner.tsx @@ -12,7 +12,7 @@ export const RebaseBanner = (props: StackProps) => { const intl = useIntl(); const theme = useTheme(); const isSmall = useMediaQuery(theme.breakpoints.down('md')); - const visible = useIsRebaseBannerVisible(); + const visible = useIsRebaseBannerVisible(tokens.mainnet.OETH); if (!visible) { return null; diff --git a/libs/shared/providers/src/rebaseBanner/hooks.ts b/libs/shared/providers/src/rebaseBanner/hooks.ts index eff60f6db..3dd201357 100644 --- a/libs/shared/providers/src/rebaseBanner/hooks.ts +++ b/libs/shared/providers/src/rebaseBanner/hooks.ts @@ -1,17 +1,28 @@ -import { tokens } from '@origin/shared/contracts'; import { ZERO_ADDRESS } from '@origin/shared/utils'; import { useAccount, useReadContract } from 'wagmi'; -export const useIsRebaseBannerVisible = () => { - const { address, isConnected, connector } = useAccount(); +import { useIsContract } from '../wagmi'; + +import type { Token } from '@origin/shared/contracts'; + +export const useIsRebaseBannerVisible = (token: Token) => { + const { address, isConnected } = useAccount(); + const { data: isContract, isLoading: isIscontractLoading } = useIsContract(); const { data, isLoading } = useReadContract({ - address: tokens.mainnet.OETH.address, - abi: tokens.mainnet.OETH.abi, + address: token.address, + abi: token.abi, functionName: 'rebaseState', - chainId: tokens.mainnet.OETH.chainId, + chainId: token.chainId, args: [address ?? ZERO_ADDRESS], - query: { enabled: !!address }, + query: { enabled: isConnected && !isIscontractLoading && isContract }, }); - return isConnected && !isLoading && data === 0 && connector?.id === 'safe'; + return ( + isConnected && + !isIscontractLoading && + !isLoading && + data !== undefined && + isContract && + [0, 1].includes(Number(data)) + ); }; diff --git a/libs/shared/providers/src/wagmi/components/OpenAccountModalButton.tsx b/libs/shared/providers/src/wagmi/components/OpenAccountModalButton.tsx index f827f1b0b..f41379fb5 100644 --- a/libs/shared/providers/src/wagmi/components/OpenAccountModalButton.tsx +++ b/libs/shared/providers/src/wagmi/components/OpenAccountModalButton.tsx @@ -15,6 +15,7 @@ interface OpenAccountModalButtonProps extends ButtonProps { connectedProps?: ButtonProps; disconnectedProps?: ButtonProps; hideAddress?: boolean; + hideWrongNetwork?: boolean; } export const OpenAccountModalButton = forwardRef< @@ -27,6 +28,7 @@ export const OpenAccountModalButton = forwardRef< connectedProps, disconnectedProps, hideAddress, + hideWrongNetwork, children, ...rest }, @@ -58,7 +60,7 @@ export const OpenAccountModalButton = forwardRef< ); } - if (chain.unsupported) { + if (!hideWrongNetwork && chain.unsupported) { return (