├── .env.example ├── .eslintrc.js ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── codeql.yml │ ├── coverageBadges.yml │ └── main.yml ├── .gitignore ├── .gitmodules ├── .gitpod.yml ├── .husky └── pre-commit ├── .linguirc ├── .prettierrc ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── index.d.ts ├── index.html ├── orval.config.ts ├── package.json ├── public ├── assets │ └── images │ │ ├── base.svg │ │ ├── berachain.svg │ │ ├── ethereum.png │ │ ├── give │ │ ├── angel-protocol │ │ │ ├── angel-protocol-logo.png │ │ │ └── angel-protocol-logo.svg │ │ ├── gitcoin │ │ │ ├── gitcoin-logo.png │ │ │ └── gitcoin-logo.svg │ │ ├── impact-market │ │ │ ├── impact-market-logo.png │ │ │ └── impact-market-logo.svg │ │ ├── kolektivo │ │ │ ├── kolektivo-logo.png │ │ │ └── kolektivo-logo.svg │ │ └── popcorndao │ │ │ ├── popcorndao-logo.png │ │ │ └── popcorndao-logo.svg │ │ └── grants │ │ ├── black-dao │ │ └── black_dao_logo.svg │ │ ├── composable │ │ └── composable_logo.svg │ │ ├── entropy │ │ ├── entropy_logo.svg │ │ └── ethereum.png │ │ ├── gateway │ │ └── gateway_logo.svg │ │ ├── metamars │ │ └── metamars_logo.svg │ │ ├── mover │ │ └── mover_logo.svg │ │ ├── on-demand │ │ └── metricsdao_logo.svg │ │ └── playgrounds │ │ └── playgrounds_logo.svg ├── favicon.ico ├── favicon.svg ├── logo.svg ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── scripts └── fix-coverage-report.js ├── src ├── .gitignore ├── App.tsx ├── Root.tsx ├── abi │ ├── BLEVaultLido.json │ ├── BLEVaultManagerLido.json │ ├── BalancerV2Pool.json │ ├── BalancerVault.json │ ├── BondAggregator.json │ ├── BondAuctioneer.json │ ├── BondDepository.json │ ├── BondFixedExpirySDA.json │ ├── BondFixedExpiryTeller.json │ ├── BondFixedTermSDA.json │ ├── BondFixedTermTeller.json │ ├── BondTeller.json │ ├── Cooler.json │ ├── CoolerClearingHouse.json │ ├── CoolerClearingHouseV3.json │ ├── CoolerConsolidation.json │ ├── CoolerFactory.json │ ├── CoolerFactoryV2.json │ ├── CoolerV2Composites.json │ ├── CoolerV2Migrator.json │ ├── CoolerV2MonoCooler.json │ ├── CrossChainBridge.json │ ├── CrossChainBridgeTestnet.json │ ├── CrossChainMigrator.json │ ├── CurveFactory.json │ ├── CurveGaugeController.json │ ├── CurveGaugeDeposit.json │ ├── CurvePool.json │ ├── CurveToken.json │ ├── DevFaucet.json │ ├── ERC20BondToken.json │ ├── ERC4626.json │ ├── EmissionManager.json │ ├── FuseProxy.json │ ├── GUniV3Lp.json │ ├── IERC20.json │ ├── OlympusDistributor.json │ ├── OlympusGovernorBravo.json │ ├── OlympusLiquidityRegistry.json │ ├── OlympusProV2.json │ ├── OlympusStaking.json │ ├── OlympusStakingv2.json │ ├── OlympusTokenMigrator.json │ ├── PairContract.json │ ├── Range.json │ ├── RangeOperator.json │ ├── RangePrice.json │ ├── StakingHelper.json │ ├── Timelock.json │ ├── Zap.json │ ├── ZeroDistributor.json │ ├── ZeroEx.json │ ├── gOHM.json │ ├── sOhmv2.json │ └── wsOHM.json ├── assets │ ├── OHM shape.svg │ ├── Olympus Logo.svg │ ├── arbitrum.png │ ├── fonts │ │ ├── NHaasGroteskDSPro-55Rg.woff2 │ │ ├── NHaasGroteskDSPro-65Md.woff2 │ │ └── NHaasGroteskDSPro-75Bd.woff2 │ ├── icons │ │ ├── arrow-down.svg │ │ ├── arrow-up.svg │ │ ├── fullscreen.svg │ │ ├── graph-grt-logo.svg │ │ ├── hamburger.svg │ │ ├── heart.svg │ │ ├── lendAndBorrow.svg │ │ ├── olympus-nav-header.svg │ │ ├── step-1.svg │ │ ├── step-2.svg │ │ ├── step-complete.svg │ │ ├── time-remaining.svg │ │ ├── wallet.svg │ │ └── x.svg │ ├── images │ │ ├── 33-together-spritesheet.png │ │ ├── angel-protocol-logo.svg │ │ ├── gitcoin-logo.svg │ │ ├── impact-market-logo.svg │ │ ├── kolektivo-logo.svg │ │ └── popcorn-logo.svg │ ├── known-issues-commit.png │ ├── metamask.svg │ ├── rainbowkit.css │ ├── tokens │ │ ├── AVAX.svg │ │ ├── avax.png │ │ ├── matic.svg │ │ ├── token_OHM.svg │ │ ├── token_sOHM.svg │ │ ├── usds.svg │ │ └── wETH.svg │ └── walletConnect.svg ├── components │ ├── CallToAction │ │ ├── CallToAction.scss │ │ ├── CallToAction.tsx │ │ └── __tests__ │ │ │ └── CallToAction.unit.test.tsx │ ├── Chart │ │ ├── Chart.tsx │ │ ├── Constants.ts │ │ ├── CustomTooltip.tsx │ │ ├── ExpandedChart.tsx │ │ ├── IntersectionHelper.ts │ │ └── __tests__ │ │ │ ├── Chart.unit.test.tsx │ │ │ └── IntersectionHelper.unit.test.tsx │ ├── ConnectButton │ │ ├── ConnectButton.tsx │ │ └── __tests__ │ │ │ └── ConnectButton.unit.test.tsx │ ├── DevFaucet │ │ └── index.tsx │ ├── Messages │ │ └── Messages.tsx │ ├── Migration │ │ ├── MigrationModal.scss │ │ ├── MigrationModal.tsx │ │ ├── MigrationModalSingle.tsx │ │ └── __tests__ │ │ │ ├── MigrationModal.unit.test.jsx │ │ │ └── MigrationModalSingle.unit.test.tsx │ ├── MigrationCallToAction.tsx │ ├── MigrationNotification.tsx │ ├── PageTitle.test.tsx │ ├── PageTitle.tsx │ ├── SafariFooter.test.tsx │ ├── SafariFooter.tsx │ ├── Sidebar │ │ ├── NavContent.tsx │ │ ├── NavDrawer.tsx │ │ ├── Sidebar.scss │ │ ├── Sidebar.tsx │ │ └── __tests__ │ │ │ └── Sidebar.unit.test.tsx │ ├── StagingNotification.test.tsx │ ├── StagingNotification.tsx │ ├── StakeVersionContainer.tsx │ ├── TokenAllowanceGuard │ │ ├── TokenAllowanceGuard.tsx │ │ └── hooks │ │ │ └── useApproveToken.ts │ ├── TopBar │ │ ├── ThemeSwitch.tsx │ │ ├── TopBar.scss │ │ ├── TopBar.tsx │ │ ├── Wallet │ │ │ └── hooks │ │ │ │ └── useFaucet.ts │ │ └── __tests__ │ │ │ ├── ThemeSwitch.test.unit.tsx │ │ │ └── __snapshots__ │ │ │ └── ThemeSwitch.test.unit.tsx.snap │ ├── WalletBalance │ │ └── WalletBalance.tsx │ ├── WalletConnectedGuard.tsx │ └── library │ │ └── NavItem.tsx ├── constants.ts ├── constants │ ├── addresses.ts │ ├── contracts.ts │ └── tokens.ts ├── generated │ └── coolerLoans.ts ├── helpers │ ├── AllExternalPools.ts │ ├── CountdownTimer.tsx │ ├── DateHelper.ts │ ├── DecimalBigNumber │ │ ├── DecimalBigNumber.ts │ │ └── DecimalBigNumber.unit.test.ts │ ├── Migration.tsx │ ├── Migration.unit.test.js │ ├── NumberHelper.test.ts │ ├── NumberHelper.ts │ ├── SearchParamsHelper.test.ts │ ├── SearchParamsHelper.ts │ ├── ZapHelper.test.ts │ ├── ZapHelper.ts │ ├── analytics │ │ └── trackGAEvent.ts │ ├── bonds │ │ ├── sortByDiscount.test.ts │ │ └── sortByDiscount.ts │ ├── contracts │ │ ├── Contract.ts │ │ ├── Token.ts │ │ ├── getBalancerLPToken.ts │ │ ├── getCurveLPToken.ts │ │ ├── getGelatoLPToken.ts │ │ ├── getLPTokenByAddress.ts │ │ ├── getTokenByAddress.ts │ │ └── getUniOrSushiLPToken.ts │ ├── defiLlamaChainToNetwork.test.ts │ ├── defiLlamaChainToNetwork.ts │ ├── environment │ │ └── Environment │ │ │ ├── Environment.ts │ │ │ └── Environment.unit.test.ts │ ├── index.tsx │ ├── misc │ │ └── isValidAddress.ts │ ├── normalizeSymbol.test.ts │ ├── normalizeSymbol.ts │ ├── pricing │ │ ├── calculateBalancerLPValue.ts │ │ ├── calculateCurveLPValue.ts │ │ ├── calculateGelatoLPValue.ts │ │ ├── calculateUniOrSushiLPValue.ts │ │ ├── getCoingeckoPrice.ts │ │ └── useGetDefillamaPrice.ts │ ├── providers │ │ └── Providers │ │ │ ├── Providers.ts │ │ │ └── Providers.unit.test.ts │ ├── react-query │ │ ├── getQueryData.ts │ │ └── queryAssertion.ts │ ├── subgraph │ │ ├── Constants.ts │ │ ├── ProtocolMetricsHelper.ts │ │ ├── TreasuryQueryHelper.ts │ │ └── __tests__ │ │ │ └── ProtocolMetricsHelper.unit.test.ts │ ├── timeUtil.test.ts │ ├── timeUtil.ts │ ├── truncateAddress.ts │ └── types │ │ ├── assert.test.ts │ │ ├── assert.ts │ │ ├── enumToArray.ts │ │ └── nonNullable.ts ├── hooks │ ├── __tests__ │ │ └── wagmi.test.ts │ ├── index.ts │ ├── useBalance.ts │ ├── useBridging.ts │ ├── useCheckSecondsToNextEpoch.ts │ ├── useContract.ts │ ├── useContractAllowance.ts │ ├── useCurrentIndex.ts │ ├── useFederatedSubgraphQuery.ts │ ├── useFetchZeroExSwapData.ts │ ├── useGetLPStats.ts │ ├── useGetLendBorrowStats.ts │ ├── useGoogleAnalytics.ts │ ├── useHasDust.ts │ ├── useOldAssetsDetected.ts │ ├── useOldAssetsEnoughToMigrate.ts │ ├── usePathForNetwork.ts │ ├── usePrices.ts │ ├── useProtocolMetrics.ts │ ├── useScreenSize.ts │ ├── useStakingRebaseRate.ts │ ├── useTestMode.ts │ ├── useTestableNetworks.ts │ ├── useTheme.ts │ ├── useTokenPrice.ts │ ├── useTokenRecordsMetrics.ts │ ├── useTokenSupplyMetrics.ts │ ├── useTreasuryMetrics.ts │ ├── useTriggerRebase.ts │ ├── useWarmupInfo.ts │ ├── useZeroExSwap.ts │ └── wagmi.ts ├── index.tsx ├── lib │ ├── Bond.ts │ ├── EthersTypes.ts │ └── react-query.tsx ├── networkDetails.ts ├── react-app-env.d.ts ├── setupTests.tsx ├── slices │ ├── AccountSlice.ts │ ├── AppSlice.ts │ ├── MigrateThunk.ts │ ├── PendingTxnsSlice.ts │ ├── StakeThunk.ts │ └── interfaces.ts ├── store.ts ├── style.scss ├── testHandlers.js ├── testHelpers.ts ├── testUtils.tsx ├── testWagmiUtils.ts ├── themes │ ├── dark.js │ ├── darkPalette.js │ ├── fonts.js │ ├── girth.js │ ├── global.js │ ├── light.js │ └── lightPalette.js ├── types │ └── react-step-progress-bar.d.ts └── views │ ├── 404 │ ├── NotFound.scss │ ├── NotFound.tsx │ └── __tests__ │ │ └── NotFound.unit.test.tsx │ ├── Bond │ ├── Bond.tsx │ ├── __mocks__ │ │ └── mockLiveMarkets.tsx │ ├── __tests__ │ │ ├── Bond.unit.test.jsx │ │ └── InverseBond.unit.test.jsx │ ├── components │ │ ├── BondDiscount.tsx │ │ ├── BondDuration.tsx │ │ ├── BondInfoText.tsx │ │ ├── BondList.tsx │ │ ├── BondModal │ │ │ ├── BondModal.tsx │ │ │ ├── BondModalContainerV3.tsx │ │ │ └── components │ │ │ │ ├── BondConfirmModal.tsx │ │ │ │ ├── BondInputArea │ │ │ │ ├── BondInputArea.tsx │ │ │ │ └── hooks │ │ │ │ │ └── usePurchaseBond.ts │ │ │ │ └── BondSettingsModal.tsx │ │ ├── BondPrice.tsx │ │ └── ClaimBonds │ │ │ ├── ClaimBonds.tsx │ │ │ ├── ClaimBondsV3.tsx │ │ │ └── hooks │ │ │ ├── useBondNotes.ts │ │ │ ├── useClaimBonds.ts │ │ │ └── useClaimBondsV3.ts │ ├── hooks │ │ ├── useBond.ts │ │ ├── useBondTokens.ts │ │ ├── useBondV3.ts │ │ └── useLiveBonds.ts │ └── index.tsx │ ├── Bridge │ ├── __tests__ │ │ └── Bridge.unit.test.tsx │ ├── components │ │ ├── BridgeConfirmModal.tsx │ │ ├── BridgeFees.tsx │ │ ├── BridgeInputArea.tsx │ │ ├── BridgeSettingsModal.tsx │ │ └── ChainPickerModal.tsx │ ├── helpers │ │ └── index.ts │ └── index.tsx │ ├── Emission │ ├── hooks │ │ └── useGetEmissionConfig.ts │ └── index.tsx │ ├── Governance │ ├── Components │ │ ├── CallData.tsx │ │ ├── ContractParameters.tsx │ │ ├── CoolerV2GovernanceTableRow.tsx │ │ ├── CurrentVotes.tsx │ │ ├── GovernanceNavigation.tsx │ │ ├── GovernanceTableRow.tsx │ │ ├── ProposalContainer.tsx │ │ ├── Status.tsx │ │ ├── VoteModal.tsx │ │ └── VotingOutcomeBar.tsx │ ├── Delegation │ │ ├── DelegateDetails.tsx │ │ ├── DelegateRow.tsx │ │ ├── DelegateVotingModal.tsx │ │ ├── DelegationMessage.tsx │ │ ├── index.tsx │ │ └── manage.tsx │ ├── Proposals │ │ ├── VoteDetails.tsx │ │ ├── VoteRow.tsx │ │ └── index.tsx │ ├── helpers │ │ ├── fetchFunctionInterface.ts │ │ ├── index.ts │ │ └── normalizeProposal.ts │ ├── hooks │ │ ├── dev │ │ │ ├── GovernanceDevTools.tsx │ │ │ ├── useAddChain.tsx │ │ │ ├── useCancelProposal.tsx │ │ │ ├── useCreateProposal.tsx │ │ │ ├── useMineBlocks.tsx │ │ │ └── useVetoProposal.tsx │ │ ├── useActivateProposal.tsx │ │ ├── useCheckDelegation.tsx │ │ ├── useDelegateVoting.tsx │ │ ├── useExecuteProposal.tsx │ │ ├── useGetCanceledTime.tsx │ │ ├── useGetContractParameters.tsx │ │ ├── useGetCurrentBlockTime.tsx │ │ ├── useGetDelegate.tsx │ │ ├── useGetDelegates.tsx │ │ ├── useGetExecutedTime.tsx │ │ ├── useGetProposalDetails.tsx │ │ ├── useGetProposalFromSubgraph.tsx │ │ ├── useGetProposalsFromSubgraph.tsx │ │ ├── useGetQueuedTime.tsx │ │ ├── useGetReceipt.tsx │ │ ├── useGetVetoedTime.tsx │ │ ├── useGetVotes.tsx │ │ ├── useGetVotingWeight.tsx │ │ ├── useGovernanceDelegationCheck.tsx │ │ ├── useQueueProposal.tsx │ │ └── useVoteForProposal.tsx │ └── index.tsx │ ├── Lending │ ├── Cooler │ │ ├── dashboard │ │ │ ├── Dashboard.tsx │ │ │ ├── IncomeGraph.tsx │ │ │ ├── MaturityGraph.tsx │ │ │ ├── Metrics.tsx │ │ │ └── UtilisationGraph.tsx │ │ ├── hooks │ │ │ ├── customHttpClient.ts │ │ │ ├── useConsolidateCooler.tsx │ │ │ ├── useCreateCooler.tsx │ │ │ ├── useCreateLoan.tsx │ │ │ ├── useExtendLoan.tsx │ │ │ ├── useGetClearingHouse.tsx │ │ │ ├── useGetConsolidationAllowances.tsx │ │ │ ├── useGetCoolerBalance.tsx │ │ │ ├── useGetCoolerForWallet.tsx │ │ │ ├── useGetCoolerLoans.tsx │ │ │ ├── useGetWalletFundsRequired.tsx │ │ │ ├── useRepayLoan.tsx │ │ │ └── useSnapshot.tsx │ │ ├── index.tsx │ │ └── positions │ │ │ ├── ConsolidateLoan.tsx │ │ │ ├── CreateOrRepayLoan.tsx │ │ │ ├── ExtendLoan.tsx │ │ │ └── Positions.tsx │ ├── CoolerV2 │ │ ├── components │ │ │ ├── CollateralInputCard.tsx │ │ │ ├── CoolerV2DelegationModal.tsx │ │ │ ├── CreateOrRepayLoanV2.tsx │ │ │ ├── DebtInputCard.tsx │ │ │ ├── DelegationManagement.tsx │ │ │ ├── DevTools.tsx │ │ │ ├── LoanInformation.tsx │ │ │ ├── LoanToValueSlider.tsx │ │ │ ├── MonoCoolerPositions.tsx │ │ │ └── PositionOverview.tsx │ │ ├── hooks │ │ │ ├── useMonoCoolerCalculations.tsx │ │ │ ├── useMonoCoolerCapacity.tsx │ │ │ ├── useMonoCoolerDebt.tsx │ │ │ ├── useMonoCoolerDelegations.tsx │ │ │ └── useMonoCoolerPosition.tsx │ │ └── utils │ │ │ └── getAuthorizationSignature.ts │ └── LendingMarkets.tsx │ ├── Liquidity │ ├── ClaimModal.tsx │ ├── ConfirmationModal.tsx │ ├── DepositStepsModal.tsx │ ├── ExternalStakePools │ │ ├── ExternalStakePools.tsx │ │ └── __tests__ │ │ │ └── ExternalStakePools.test.tsx │ ├── Vault.tsx │ ├── Vaults.tsx │ ├── WithdrawModal.tsx │ ├── YourAMODeposits.tsx │ ├── ZapSteps.tsx │ └── hooks │ │ ├── useClaimRewards.tsx │ │ ├── useCreateUserVault.tsx │ │ ├── useDepositLiquidity.tsx │ │ ├── useGetExpectedPairTokenAmount.tsx │ │ ├── useGetLastDeposit.tsx │ │ ├── useGetSingleSidedLiquidityVaults.tsx │ │ ├── useGetUserVault.tsx │ │ ├── useGetVault.tsx │ │ └── useWithdrawLiquidity.tsx │ ├── MyBalances │ ├── LearnAboutGohm.tsx │ ├── LearnAboutOhm.tsx │ ├── MyCoolerLoans.tsx │ ├── MyGohmBalances.tsx │ ├── MyOhmBalances.tsx │ └── index.tsx │ ├── Range │ ├── RangeChart.tsx │ ├── RangeConfirmationModal.tsx │ ├── RangeInputForm.tsx │ ├── __mocks__ │ │ └── mockRangeCalls.tsx │ ├── __tests__ │ │ ├── Range.test.tsx │ │ ├── RangeBondsLower.test.tsx │ │ └── RangeBondsUpper.test.tsx │ ├── hooks.tsx │ └── index.tsx │ ├── Stake │ ├── Stake.scss │ ├── Stake.tsx │ ├── __tests__ │ │ ├── Stake.unit.test.tsx │ │ └── __snapshots__ │ │ │ └── StakeMobile.unit.test.jsx.snap │ └── components │ │ ├── ClaimsArea │ │ └── ClaimsArea.tsx │ │ └── StakeArea │ │ ├── StakeArea.tsx │ │ ├── __tests__ │ │ ├── StakeArea.unit.test.jsx │ │ ├── StakeAreaHooks.unit.text.jsx │ │ └── Wrap.unit.test.jsx │ │ └── components │ │ ├── StakeBalances.tsx │ │ └── StakeInputArea │ │ ├── StakeInputArea.tsx │ │ ├── components │ │ ├── StakeConfirmationModal.tsx │ │ └── TokenModal.tsx │ │ └── hooks │ │ ├── useClaimToken.ts │ │ ├── useForfeitToken.ts │ │ ├── useStakeToken.ts │ │ └── useUnstakeToken.ts │ ├── TreasuryDashboard │ ├── TreasuryDashboard.tsx │ ├── __tests__ │ │ ├── TreasuryDashboard.unit.test.tsx │ │ └── TreasuryMobile.unit.test.tsx │ └── components │ │ ├── DataWarning.tsx │ │ ├── Graph │ │ ├── ChartCard.tsx │ │ ├── Constants.ts │ │ ├── LiquidBackingComparisonGraph.tsx │ │ ├── OhmSupply.tsx │ │ ├── OhmSupplyGraph.tsx │ │ ├── OhmSupplyTable.tsx │ │ ├── OwnedLiquidityGraph.tsx │ │ ├── TreasuryAssets.tsx │ │ ├── TreasuryAssetsGraph.tsx │ │ ├── TreasuryAssetsTable.tsx │ │ └── helpers │ │ │ ├── ChartHelper.tsx │ │ │ ├── TokenRecordsQueryHelper.ts │ │ │ └── __tests__ │ │ │ └── TokenRecordsQueryHelper.unit.test.tsx │ │ ├── KnownIssues │ │ └── KnownIssues.tsx │ │ └── Metric │ │ └── Metric.tsx │ ├── Utility │ └── index.tsx │ ├── V1-Stake │ ├── V1-Stake.jsx │ ├── V1-Stake.scss │ └── __tests__ │ │ └── V1-Stake.unit.test.tsx │ ├── Wrap │ └── components │ │ └── WrapInputArea │ │ └── hooks │ │ └── useWrapSohm.tsx │ ├── Zap │ ├── SlippageModal.tsx │ ├── ZapTransactionDetails.tsx │ └── __mocks__ │ │ └── mockZapBalances.tsx │ └── index.ts ├── tests ├── e2e │ ├── testHelpers.ts │ └── tsconfig.json └── unit │ └── launcher.js ├── tsconfig.json ├── vite-env.d.ts ├── vite.config.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | 2 | # Optional 3 | # Google Analytics (https://analytics.google.com/) 4 | VITE_GOOGLE_ANALYTICS_API_KEY="" 5 | # Google Analytics 4 API Key 6 | VITE_GA_4_API_KEY="" 7 | 8 | # Optional 9 | # If you run your own node, you can provide connection url(s) to that node. 10 | # To provide multiple urls for a network, please seperate them with a space. 11 | VITE_ETHEREUM_NODE_URL="" 12 | VITE_ETHEREUM_TESTNET_NODE_URL="" 13 | 14 | VITE_FANTOM_NODE_URL="" 15 | VITE_FANTOM_TESTNET_NODE_URL="" 16 | 17 | VITE_POLYGON_NODE_URL="" 18 | VITE_POLYGON_TESTNET_NODE_URL="" 19 | 20 | 21 | VITE_ARBITRUM_NODE_URL="" 22 | VITE_ARBITRUM_TESTNET_NODE_URL="" 23 | 24 | VITE_AVALANCHE_NODE_URL="" 25 | VITE_AVALANCHE_TESTNET_NODE_URL="" 26 | 27 | # Get a wallet connect project id here: https://cloud.walletconnect.com 28 | VITE_WALLETCONNECT_PROJECT_ID="" 29 | 30 | #Subgraph URL for Protocol Metrics. If not set Protocol Metrics will not be displayed. 31 | VITE_WG_PUBLIC_NODE_URL="" 32 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | jest: true, 5 | browser: true, 6 | }, 7 | parser: "@typescript-eslint/parser", 8 | parserOptions: { 9 | ecmaVersion: 12, 10 | sourceType: "module", 11 | ecmaFeatures: { 12 | jsx: true, 13 | }, 14 | }, 15 | extends: [ 16 | "plugin:prettier/recommended", 17 | "plugin:react-hooks/recommended", 18 | "plugin:@typescript-eslint/recommended", 19 | "plugin:@typescript-eslint/eslint-recommended", 20 | ], 21 | plugins: ["@typescript-eslint", "simple-import-sort", "unused-imports", "no-relative-import-paths"], 22 | rules: { 23 | "prettier/prettier": ["error"], 24 | "import/prefer-default-export": "off", 25 | "prefer-destructuring": "off", 26 | "prefer-template": "off", 27 | "react/prop-types": "off", 28 | "react/destructuring-assignment": "off", 29 | "no-console": "off", 30 | "jsx-a11y/accessible-emoji": ["off"], 31 | "jsx-a11y/click-events-have-key-events": ["off"], 32 | "jsx-a11y/no-static-element-interactions": ["off"], 33 | "no-underscore-dangle": "off", 34 | "no-nested-ternary": "off", 35 | "no-restricted-syntax": "off", 36 | "no-plusplus": "off", 37 | "simple-import-sort/imports": "error", 38 | "unused-imports/no-unused-imports": "error", 39 | "@typescript-eslint/explicit-function-return-type": "off", 40 | "@typescript-eslint/explicit-module-boundary-types": "off", 41 | "@typescript-eslint/ban-ts-comment": "off", 42 | "@typescript-eslint/ban-ts-ignore": "off", 43 | "no-relative-import-paths/no-relative-import-paths": ["warn"], 44 | }, 45 | ignorePatterns: ["build", "node_modules"], 46 | globals: { 47 | React: true, 48 | JSX: true, 49 | }, 50 | overrides: [ 51 | { 52 | files: ["**/*.js", "**/*.jsx"], 53 | rules: { 54 | "no-undef": "error", 55 | }, 56 | }, 57 | ], 58 | }; 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a report to help us improve 4 | title: "[BUG] " 5 | labels: bug, triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the Bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected Behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Workarounds (if any)** 24 | Is there an option to get around this bug to the intended action? 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Desktop (please complete the following information):** 30 | - OS: [e.g. iOS] 31 | - Browser [e.g. chrome, safari] 32 | - Version [e.g. 22] 33 | 34 | **Smartphone (please complete the following information):** 35 | - Device: [e.g. iPhone6] 36 | - OS: [e.g. iOS8.1] 37 | - Browser [e.g. stock browser, safari] 38 | - Version [e.g. 22] 39 | 40 | **Additional Context** 41 | Add any other context about the problem here. 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like. Include clear acceptance criteria.** 14 | A clear and concise description of what you want to happen using the Given, When, Then framework - "Given, I am in the Olympus app, When I want to stake, Then I should have the ability to stake through my wallet provider." You can include multiple examples of acceptance criteria. 15 | 16 | **Is any UX Design input needed?** 17 | If yes, give a description of what is required. 18 | 19 | **Describe alternatives you've considered** 20 | A clear and concise description of any alternative solutions or features you've considered. 21 | 22 | **Tech Notes/Testing Notes** 23 | Include any relevant information related to tech capabilities or testing needed to implement this feature. 24 | 25 | **Out of scope** 26 | Include any necessary out of scope information to make clear what this feature is not delivering. 27 | 28 | **Additional context** 29 | Add any other context or screenshots about the feature request here. 30 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'npm' 4 | directory: '/' 5 | open-pull-requests-limit: 7 6 | reviewers: 7 | - 'OlympusDAO/Frontend' 8 | schedule: 9 | interval: 'daily' 10 | time: '04:00' 11 | target-branch: 'develop' 12 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [master, develop] 6 | 7 | jobs: 8 | analyze: 9 | name: Analyze 10 | runs-on: ubuntu-latest 11 | 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | language: ["javascript"] 16 | 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v2 20 | 21 | - name: Initialize CodeQL 22 | uses: github/codeql-action/init@v2 23 | with: 24 | languages: ${{ matrix.language }} 25 | 26 | - name: Autobuild 27 | uses: github/codeql-action/autobuild@v2 28 | 29 | - name: Perform CodeQL Analysis 30 | uses: github/codeql-action/analyze@v2 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | packages/subgraph/subgraph.yaml 2 | packages/subgraph/generated 3 | packages/subgraph/abis 4 | packages/hardhat/*.txt 5 | **/aws.json 6 | 7 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 8 | **/node_modules 9 | packages/hardhat/artifacts 10 | packages/hardhat/deployments 11 | packages/react-app/src/contracts/* 12 | !packages/react-app/src/contracts/contracts.js 13 | packages/hardhat/cache 14 | 15 | packages/subgraph/config/config.json 16 | tenderly.yaml 17 | 18 | # dependencies 19 | /node_modules 20 | /.pnp 21 | .pnp.js 22 | 23 | # testing 24 | coverage 25 | tests/e2e/videos 26 | base-report.json 27 | branch-report.json 28 | 29 | # production 30 | build 31 | 32 | # misc 33 | .DS_Store 34 | .env 35 | 36 | # debug 37 | npm-debug.log* 38 | yarn-debug.log* 39 | yarn-error.log* 40 | 41 | # Integrated development environnements 42 | .idea 43 | *.sublime-* 44 | 45 | # Hardhat 46 | cache 47 | 48 | .vscode 49 | 50 | src/typechain 51 | 52 | # We use Yarn - prevent this file from being committed to avoid confusion 53 | package-lock.json 54 | 55 | tmp/ 56 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/.gitmodules -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | node_modules/.bin/lint-staged 5 | -------------------------------------------------------------------------------- /.linguirc: -------------------------------------------------------------------------------- 1 | { 2 | "locales": ["en", "fr", "ko", "tr", "pt", "zh", "ar", "de", "es", "vi", "pl", "ru", "el", "it", "se"], 3 | "sourceLocale": "en", 4 | "catalogs": [{ 5 | "path": "src/locales/translations/olympus-frontend/{locale}/messages", 6 | "include": ["src"] 7 | }], 8 | "fallbackLocales": { 9 | "default": "en" 10 | }, 11 | "format": "po" 12 | } 13 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": true, 4 | "printWidth": 120, 5 | "singleQuote": false, 6 | "tabWidth": 2, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Austin Griffith 2021 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.jpg"; 2 | declare module "*.png"; 3 | declare module "*.svg"; 4 | 5 | export default global; 6 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 16 | 18 | 19 | 20 | 21 | OlympusDAO 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /orval.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'orval'; 2 | 3 | export default defineConfig({ 4 | coolerLoans: { 5 | input: "tmp/openapi.yaml", 6 | output: { 7 | target: "src/generated/coolerLoans.ts", 8 | client: "react-query", 9 | clean: true, 10 | override: { 11 | mutator: { 12 | path: "src/views/Lending/Cooler/hooks/customHttpClient.ts", 13 | name: "customHttpClient", 14 | }, 15 | useTypeOverInterfaces: true, 16 | } 17 | }, 18 | hooks: { 19 | afterAllFilesWrite: "yarn lint:fix", 20 | }, 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /public/assets/images/base.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/assets/images/ethereum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/assets/images/ethereum.png -------------------------------------------------------------------------------- /public/assets/images/give/angel-protocol/angel-protocol-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/assets/images/give/angel-protocol/angel-protocol-logo.png -------------------------------------------------------------------------------- /public/assets/images/give/gitcoin/gitcoin-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/assets/images/give/gitcoin/gitcoin-logo.png -------------------------------------------------------------------------------- /public/assets/images/give/impact-market/impact-market-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/assets/images/give/impact-market/impact-market-logo.png -------------------------------------------------------------------------------- /public/assets/images/give/kolektivo/kolektivo-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/assets/images/give/kolektivo/kolektivo-logo.png -------------------------------------------------------------------------------- /public/assets/images/give/popcorndao/popcorndao-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/assets/images/give/popcorndao/popcorndao-logo.png -------------------------------------------------------------------------------- /public/assets/images/grants/entropy/ethereum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/assets/images/grants/entropy/ethereum.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | -------------------------------------------------------------------------------- /public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OlympusDAO", 3 | "description": "A community-owned, decentralized and censorship-resistant reserve currency that is asset-backed, deeply liquid and used widely across Web3", 4 | "iconPath": "logo.svg" 5 | } 6 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /scripts/fix-coverage-report.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const coverageFinalFilename = "coverage-final.json"; 3 | const outputFile = process.argv[2] && process.argv[2] === "--outputFile" ? process.argv[3] : "report.json"; 4 | const cwd = process.cwd(); 5 | const reportJsonFilepath = `${cwd}/${outputFile}`; 6 | const coverageFinalFilepath = `${cwd}/coverage/${coverageFinalFilename}`; 7 | let reportJsonFile; 8 | let coverageFinalJsonFile; 9 | if (fs.existsSync(reportJsonFilepath)) { 10 | reportJsonFile = require(reportJsonFilepath); 11 | } 12 | if (fs.existsSync(coverageFinalFilepath)) { 13 | coverageFinalJsonFile = require(coverageFinalFilepath); 14 | } 15 | console.log("Files exists?", { outputFilename: !!reportJsonFile, coverageFinalFilename: !!coverageFinalJsonFile }); 16 | if (reportJsonFile && coverageFinalJsonFile) { 17 | if (!reportJsonFile.coverageMap) { 18 | console.log(`Adding coverageMap property to ${outputFile} based on ${coverageFinalFilename}`); 19 | reportJsonFile.coverageMap = coverageFinalJsonFile; 20 | fs.writeFileSync(reportJsonFilepath, JSON.stringify(reportJsonFile), err => { 21 | if (err) { 22 | console.error(err); 23 | process.exit(1); 24 | } 25 | }); 26 | } else { 27 | console.log(`coverageMap already exists in ${outputFile}, not doing anything...`); 28 | process.exit(0); 29 | } 30 | } else { 31 | console.log("Not doing anything..."); 32 | process.exit(0); 33 | } 34 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | e2e/videos 2 | e2e/screenshots 3 | -------------------------------------------------------------------------------- /src/Root.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable global-require */ 2 | import { StyledEngineProvider } from "@mui/material/styles"; 3 | import { FC } from "react"; 4 | import { Provider } from "react-redux"; 5 | import { HashRouter } from "react-router-dom"; 6 | import App from "src/App"; 7 | import { wagmiClient } from "src/hooks/wagmi"; 8 | import { ReactQueryProvider } from "src/lib/react-query"; 9 | import store from "src/store"; 10 | import { WagmiConfig } from "wagmi"; 11 | 12 | const Root: FC = () => { 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | export default Root; 29 | -------------------------------------------------------------------------------- /src/abi/StakingHelper.json: -------------------------------------------------------------------------------- 1 | { 2 | "abi": [ 3 | { 4 | "inputs": [ 5 | { "internalType": "address", "name": "_staking", "type": "address" }, 6 | { "internalType": "address", "name": "_OHM", "type": "address" } 7 | ], 8 | "stateMutability": "nonpayable", 9 | "type": "constructor" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "OHM", 14 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 15 | "stateMutability": "view", 16 | "type": "function" 17 | }, 18 | { 19 | "inputs": [{ "internalType": "uint256", "name": "_amount", "type": "uint256" }], 20 | "name": "stake", 21 | "outputs": [], 22 | "stateMutability": "nonpayable", 23 | "type": "function" 24 | }, 25 | { 26 | "inputs": [], 27 | "name": "staking", 28 | "outputs": [{ "internalType": "address", "name": "", "type": "address" }], 29 | "stateMutability": "view", 30 | "type": "function" 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /src/abi/ZeroDistributor.json: -------------------------------------------------------------------------------- 1 | { 2 | "abi": [ 3 | { 4 | "inputs": [{ "internalType": "address", "name": "staking_", "type": "address" }], 5 | "stateMutability": "nonpayable", 6 | "type": "constructor" 7 | }, 8 | { "inputs": [], "name": "Distributor_NoRebaseOccurred", "type": "error" }, 9 | { "inputs": [], "name": "Distributor_NotUnlocked", "type": "error" }, 10 | { "inputs": [], "name": "Distributor_OnlyStaking", "type": "error" }, 11 | { "inputs": [], "name": "distribute", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, 12 | { 13 | "inputs": [], 14 | "name": "retrieveBounty", 15 | "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], 16 | "stateMutability": "pure", 17 | "type": "function" 18 | }, 19 | { 20 | "inputs": [], 21 | "name": "staking", 22 | "outputs": [{ "internalType": "contract IStaking", "name": "", "type": "address" }], 23 | "stateMutability": "view", 24 | "type": "function" 25 | }, 26 | { "inputs": [], "name": "triggerRebase", "outputs": [], "stateMutability": "nonpayable", "type": "function" } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/assets/OHM shape.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/Olympus Logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/arbitrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/src/assets/arbitrum.png -------------------------------------------------------------------------------- /src/assets/fonts/NHaasGroteskDSPro-55Rg.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/src/assets/fonts/NHaasGroteskDSPro-55Rg.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/NHaasGroteskDSPro-65Md.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/src/assets/fonts/NHaasGroteskDSPro-65Md.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/NHaasGroteskDSPro-75Bd.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/src/assets/fonts/NHaasGroteskDSPro-75Bd.woff2 -------------------------------------------------------------------------------- /src/assets/icons/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/assets/icons/arrow-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/graph-grt-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/assets/icons/hamburger.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/icons/olympus-nav-header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/icons/step-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/step-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/step-complete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/time-remaining.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/assets/icons/wallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/images/33-together-spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/src/assets/images/33-together-spritesheet.png -------------------------------------------------------------------------------- /src/assets/known-issues-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/src/assets/known-issues-commit.png -------------------------------------------------------------------------------- /src/assets/tokens/avax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlympusDAO/olympus-frontend/f793fb0b1b92d9f7d9923b321f171b1458ceea5f/src/assets/tokens/avax.png -------------------------------------------------------------------------------- /src/assets/tokens/matic.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/tokens/token_OHM.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/assets/tokens/token_sOHM.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/tokens/usds.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/assets/tokens/wETH.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/components/CallToAction/CallToAction.scss: -------------------------------------------------------------------------------- 1 | .call-to-action { 2 | display: flex; 3 | @media (max-width: 500px) { 4 | flex-direction: column; 5 | & .actionable { 6 | margin-top: 10px; 7 | width: 100%; 8 | } 9 | } 10 | align-items: center; 11 | justify-content: space-between; 12 | width: 97%; 13 | border-radius: 10px; 14 | margin: 0.9rem auto; 15 | padding: 30px; 16 | } 17 | -------------------------------------------------------------------------------- /src/components/CallToAction/CallToAction.tsx: -------------------------------------------------------------------------------- 1 | import "src/components/CallToAction/CallToAction.scss"; 2 | 3 | import { Box, Typography } from "@mui/material"; 4 | import { Paper, PrimaryButton, TertiaryButton } from "@olympusdao/component-library"; 5 | 6 | export const LearnMoreButton = () => ( 7 | 8 | Learn More 9 | 10 | ); 11 | 12 | export interface MigrationButtonProps { 13 | setMigrationModalOpen: (state: boolean) => void; 14 | btnText: string; 15 | } 16 | 17 | export const MigrateButton = ({ setMigrationModalOpen, btnText }: MigrationButtonProps) => ( 18 | { 20 | setMigrationModalOpen(true); 21 | }} 22 | > 23 | {btnText} 24 | 25 | ); 26 | 27 | export interface CallToActionProps { 28 | setMigrationModalOpen: (state: boolean) => void; 29 | } 30 | 31 | const CallToAction = ({ setMigrationModalOpen }: CallToActionProps) => ( 32 | 33 | 34 | 35 | 36 | You have assets ready to migrate to v2 37 | 38 |
39 | 40 | 41 |
42 |
43 |
44 |
45 | ); 46 | 47 | export default CallToAction; 48 | -------------------------------------------------------------------------------- /src/components/CallToAction/__tests__/CallToAction.unit.test.tsx: -------------------------------------------------------------------------------- 1 | import { LearnMoreButton, MigrateButton } from "src/components/CallToAction/CallToAction"; 2 | import CallToAction from "src/components/CallToAction/CallToAction"; 3 | import { fireEvent, render } from "src/testUtils"; 4 | import { describe, expect, it, test, vi } from "vitest"; 5 | 6 | describe("", () => { 7 | test("should render component", () => { 8 | it("should render component", () => { 9 | const container = render( console.log("setMigrationModalOpen")} />); 10 | expect(container).toMatchSnapshot(); 11 | }); 12 | }); 13 | }); 14 | 15 | describe("LearnMoreButton", () => { 16 | it("renders a link to the Olympus DAO migration docs", () => { 17 | const container = render(); 18 | const link = container.getByRole("link", { name: /learn more/i }); 19 | expect(link).toHaveProperty("href", "https://docs.olympusdao.finance/main/basics/migration"); 20 | }); 21 | }); 22 | 23 | describe("MigrateButton", () => { 24 | it("renders button with correct text", () => { 25 | const { getByText } = render(); 26 | expect(getByText("Migrate Now")).not.toBeNull(); 27 | }); 28 | 29 | it("calls setMigrationModalOpen when clicked", () => { 30 | const setMigrationModalOpen = vi.fn(); 31 | const { getByRole } = render(); 32 | const button = getByRole("button"); 33 | fireEvent.click(button); 34 | expect(setMigrationModalOpen).toHaveBeenCalledTimes(1); 35 | expect(setMigrationModalOpen).toHaveBeenCalledWith(true); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /src/components/Chart/Constants.ts: -------------------------------------------------------------------------------- 1 | export enum DataFormat { 2 | Currency, 3 | Percentage, 4 | DateMonth, 5 | Number, 6 | None, 7 | } 8 | 9 | export enum ChartType { 10 | Line, 11 | MultiLine, 12 | Area, 13 | StackedArea, 14 | Bar, 15 | AreaDifference, 16 | Composed, 17 | } 18 | -------------------------------------------------------------------------------- /src/components/Chart/__tests__/Chart.unit.test.tsx: -------------------------------------------------------------------------------- 1 | import { formatCurrencyTick, formatPercentTick } from "src/components/Chart/Chart"; 2 | import { describe, expect, test } from "vitest"; 3 | 4 | describe("curency tick formatter", () => { 5 | test("shortens millions", () => { 6 | expect(formatCurrencyTick(10000000)).toEqual("$10M"); 7 | }); 8 | 9 | test("shortens millions with decimal", () => { 10 | expect(formatCurrencyTick(10000000.01)).toEqual("$10M"); 11 | }); 12 | 13 | test("shortens thousands", () => { 14 | expect(formatCurrencyTick(500000)).toEqual("$500k"); 15 | }); 16 | 17 | test("shortens thousands with decimal", () => { 18 | expect(formatCurrencyTick(500000.01)).toEqual("$500k"); 19 | }); 20 | 21 | test("small number", () => { 22 | expect(formatCurrencyTick(18.01)).toEqual("$18.01"); 23 | }); 24 | 25 | test("empty value", () => { 26 | expect(formatCurrencyTick(0)).toEqual(""); 27 | }); 28 | }); 29 | 30 | describe("percentage tick formatter", () => { 31 | test("normal number", () => { 32 | expect(formatPercentTick(23.02)).toEqual("23.02%"); 33 | }); 34 | 35 | test("normal string", () => { 36 | expect(formatPercentTick("23.02")).toEqual("23.02%"); 37 | }); 38 | 39 | test("empty value", () => { 40 | expect(formatPercentTick(0)).toEqual(""); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /src/components/ConnectButton/__tests__/ConnectButton.unit.test.tsx: -------------------------------------------------------------------------------- 1 | import { ConnectButton, InPageConnectButton } from "src/components/ConnectButton/ConnectButton"; 2 | import { render, screen } from "src/testUtils"; 3 | 4 | describe("", () => { 5 | it("should display Connect Button for TopBar", () => { 6 | render(); 7 | expect(screen.getByText("Connect Wallet")); 8 | }); 9 | 10 | it("should display Connect Wallet for In-Page Connect Buttons", () => { 11 | render(); 12 | expect(screen.getByText("Connect Wallet")); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/components/DevFaucet/index.tsx: -------------------------------------------------------------------------------- 1 | import { Box, FormControl, MenuItem, Select, Typography } from "@mui/material"; 2 | import { SecondaryButton } from "@olympusdao/component-library"; 3 | import { useState } from "react"; 4 | import { useFaucet } from "src/components/TopBar/Wallet/hooks/useFaucet"; 5 | 6 | export const DevFaucet = () => { 7 | const PREFIX = "AssetsIndex"; 8 | const [faucetToken, setFaucetToken] = useState("OHM V2"); 9 | const faucetMutation = useFaucet(); 10 | 11 | const classes = { 12 | selector: `${PREFIX}-selector`, 13 | forecast: `${PREFIX}-forecast`, 14 | faucet: `${PREFIX}-faucet`, 15 | }; 16 | const isFaucetLoading = faucetMutation.isLoading; 17 | 18 | return ( 19 | <> 20 | Dev Faucet 21 | 22 | 23 | 38 | 39 | faucetMutation.mutate(faucetToken)}> 40 | {isFaucetLoading ? "Loading..." : "Get Tokens"} 41 | 42 | 43 | 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /src/components/Messages/Messages.tsx: -------------------------------------------------------------------------------- 1 | import Alert from "@mui/material/Alert"; 2 | import { Icon } from "@olympusdao/component-library"; 3 | import { resolveValue, toast as hotToast } from "react-hot-toast"; 4 | 5 | // A component that displays error messages 6 | const Messages = ({ toast }: { toast: any }) => { 7 | return ( 8 | { 27 | hotToast.dismiss(toast.id); 28 | }} 29 | /> 30 | } 31 | iconMapping={{ 32 | success: , 33 | error: , 34 | warning: , 35 | info: , 36 | }} 37 | elevation={12} 38 | > 39 | {resolveValue(toast.message, toast)} 40 | 41 | ); 42 | }; 43 | 44 | export default Messages; 45 | -------------------------------------------------------------------------------- /src/components/Migration/MigrationModal.scss: -------------------------------------------------------------------------------- 1 | .tooltip { 2 | z-index: 2000; 3 | } 4 | 5 | .docs-link { 6 | text-decoration: inherit; 7 | font: inherit; 8 | color: inherit; 9 | } 10 | 11 | .mig-modal-full { 12 | backdrop-filter: blur(33px); 13 | } 14 | 15 | #migration-modal-description { 16 | &.mobile { 17 | font-size: 0.85rem; 18 | } 19 | line-height: 1.5em; 20 | font-size: 1rem; 21 | padding: 0px 5px; 22 | } 23 | 24 | @media (max-width: 500px) { 25 | .mig-modal-full .MuiBox-root .MuiBox-root, 26 | .mig-modal-full .MuiBox-root .MuiTable-root { 27 | max-width: 100vw; 28 | margin: 0 auto; 29 | // padding: 2% 10%; 30 | } 31 | .modal-inner { 32 | width: 250px; 33 | overflow: scroll; 34 | } 35 | } 36 | 37 | .migration-card { 38 | @supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) { 39 | .MuiBackdrop-root { 40 | background: rgba(100, 100, 100, 0.33) !important; 41 | backdrop-filter: blur(33px) !important; 42 | -webkit-backdrop-filter: blur(33px) !important; 43 | .ohm-card { 44 | opacity: 1 !important; 45 | height: auto; 46 | } 47 | } 48 | } 49 | 50 | /* slightly transparent fallback for Firefox (not supporting backdrop-filter) */ 51 | @supports not ((-webkit-backdrop-filter: none) or (backdrop-filter: none)) { 52 | .MuiBackdrop-root { 53 | background: rgba(100, 100, 100, 0.95); 54 | .ohm-card { 55 | height: auto; 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/components/Migration/__tests__/MigrationModalSingle.unit.test.tsx: -------------------------------------------------------------------------------- 1 | import MigrationModalSingle from "src/components/Migration/MigrationModalSingle"; 2 | import { render } from "src/testUtils"; 3 | import { test } from "vitest"; 4 | 5 | describe("", () => { 6 | test("should render component", () => { 7 | it("should render component", () => { 8 | const { container } = render( 9 | console.log("handleClose")} />, 10 | ); 11 | expect(container).toMatchSnapshot(); 12 | }); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/components/MigrationCallToAction.tsx: -------------------------------------------------------------------------------- 1 | import { Dispatch, SetStateAction } from "react"; 2 | import { useLocation } from "react-router-dom"; 3 | import CallToAction from "src/components/CallToAction/CallToAction"; 4 | import { useOldAssetsDetected } from "src/hooks/useOldAssetsDetected"; 5 | import { useOldAssetsEnoughToMigrate } from "src/hooks/useOldAssetsEnoughToMigrate"; 6 | 7 | export const MigrationCallToAction: React.FC<{ setMigrationModalOpen: Dispatch> }> = props => { 8 | const location = useLocation(); 9 | const trimmedPath = location.pathname + location.hash; 10 | const oldAssetsDetected = useOldAssetsDetected(); 11 | const oldAssetsEnoughToMigrate = useOldAssetsEnoughToMigrate(); 12 | 13 | if (oldAssetsDetected && trimmedPath.indexOf("dashboard") === -1 && oldAssetsEnoughToMigrate) 14 | return ; 15 | 16 | return null; 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/MigrationNotification.tsx: -------------------------------------------------------------------------------- 1 | import MigrationModal from "src/components/Migration/MigrationModal"; 2 | import MigrationModalSingle from "src/components/Migration/MigrationModalSingle"; 3 | import { useHasDust } from "src/hooks/useHasDust"; 4 | import { useOldAssetsDetected } from "src/hooks/useOldAssetsDetected"; 5 | 6 | export const MigrationNotification: React.FC<{ isModalOpen: boolean; onClose: () => void }> = props => { 7 | const hasDust = useHasDust(); 8 | const oldAssetsDetected = useOldAssetsDetected(); 9 | 10 | if (!oldAssetsDetected) return null; 11 | 12 | if (hasDust) return ; 13 | 14 | return ; 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/PageTitle.test.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "@testing-library/react"; 2 | import PageTitle, { OHMPageTitleProps } from "src/components/PageTitle"; 3 | import { describe, expect, it, vi } from "vitest"; 4 | 5 | vi.mock("@mui/material", () => ({ 6 | Box: (props: any) =>
, 7 | Typography: (props: any) =>

, 8 | useMediaQuery: () => false, 9 | useTheme: () => ({ breakpoints: { down: () => "" } }), 10 | })); 11 | 12 | describe("PageTitle", () => { 13 | const props: OHMPageTitleProps = { name: "Splash Page" }; 14 | 15 | it("renders the component with the correct name", () => { 16 | const { getByText } = render(); 17 | expect(getByText("Splash Page")).not.toBeNull(); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/components/PageTitle.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Typography, useMediaQuery, useTheme } from "@mui/material"; 2 | import { FC, ReactElement } from "react"; 3 | 4 | export interface OHMPageTitleProps { 5 | name?: string | ReactElement; 6 | subtitle?: string | ReactElement; 7 | noMargin?: boolean; 8 | } 9 | 10 | /** 11 | * Component for Displaying PageTitle 12 | */ 13 | const PageTitle: FC = ({ name, subtitle, noMargin }) => { 14 | const theme = useTheme(); 15 | const mobile = useMediaQuery(theme.breakpoints.down("sm")); 16 | 17 | return ( 18 | 24 | 25 | {name} 26 | 27 | {subtitle && ( 28 | 29 | {subtitle} 30 | 31 | )} 32 | 33 | ); 34 | }; 35 | 36 | export default PageTitle; 37 | -------------------------------------------------------------------------------- /src/components/SafariFooter.test.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "@testing-library/react"; 2 | import { SafariFooter } from "src/components/SafariFooter"; 3 | import { afterAll, beforeAll, describe, expect, it } from "vitest"; 4 | 5 | describe("SafariFooter", () => { 6 | let userAgent: string; 7 | 8 | beforeAll(() => { 9 | userAgent = navigator.userAgent; 10 | Object.defineProperty(window, "navigator", { 11 | value: { userAgent: "iPhone Safari" }, 12 | writable: true, 13 | }); 14 | }); 15 | 16 | afterAll(() => { 17 | Object.defineProperty(window, "navigator", { 18 | value: { userAgent }, 19 | writable: true, 20 | }); 21 | }); 22 | 23 | it("renders the Safari iPhone footer", () => { 24 | const { container } = render(); 25 | 26 | expect(container.querySelector("#safari-iphone-footer")).not.toBeNull(); 27 | }); 28 | 29 | it("does not render the Safari iPhone footer on other browsers", () => { 30 | Object.defineProperty(window, "navigator", { 31 | value: { userAgent: "Chrome" }, 32 | writable: true, 33 | }); 34 | 35 | const { container } = render(); 36 | 37 | expect(container.querySelector("#safari-iphone-footer")).toBeNull(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /src/components/SafariFooter.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Safari on iPhone prevents the user from scrolling to the bottom of the screen, due 3 | * to the address bar. 4 | * 5 | * On Safari for iPhone, this React component adds an empty div with padding, which ensures that no content 6 | * is hidden. 7 | * 8 | * On all other browsers, this has no effect. 9 | */ 10 | export const SafariFooter: React.FC = () => { 11 | const isSafariOniPhone = navigator.userAgent.match(/(iPhone).*(Safari)/); 12 | 13 | if (!isSafariOniPhone) return <>; 14 | 15 | return