├── public ├── favicon.ico ├── logo192.png ├── logo256.png ├── logo512.png ├── preview.png ├── robots.txt ├── fonts │ ├── sequel.ttf │ ├── lato-v17-latin-300.woff │ ├── lato-v17-latin-300.woff2 │ ├── lato-v17-latin-700.woff │ ├── lato-v17-latin-700.woff2 │ ├── lato-v17-latin-italic.woff │ ├── lato-v17-latin-italic.woff2 │ ├── lato-v17-latin-regular.woff │ ├── lato-v17-latin-300italic.woff │ ├── lato-v17-latin-700italic.woff │ ├── lato-v17-latin-regular.woff2 │ ├── lato-v17-latin-300italic.woff2 │ ├── lato-v17-latin-700italic.woff2 │ ├── average-sans-v9-latin-regular.woff │ └── average-sans-v9-latin-regular.woff2 ├── manifest.json └── index.html ├── src ├── themes │ └── vader │ │ ├── tooltip.js │ │ ├── fonts.js │ │ ├── alert.js │ │ ├── spinner.js │ │ ├── badge.js │ │ ├── switch.js │ │ ├── select.js │ │ ├── typography.js │ │ ├── tag.js │ │ ├── link.js │ │ ├── modal.js │ │ ├── popover.js │ │ ├── colors.js │ │ ├── menu.js │ │ ├── numberinput.js │ │ ├── input.js │ │ ├── index.js │ │ └── button.js ├── assets │ ├── png │ │ └── eth-diamond-purple-purple.png │ └── svg │ │ ├── icons │ │ ├── coinbasewallet.svg │ │ ├── walletconnect.svg │ │ ├── otherwallets.svg │ │ └── metamask.svg │ │ ├── Swap.svg │ │ ├── Graph.svg │ │ ├── Hourglass.svg │ │ └── Option.svg ├── setupTests.js ├── tokenListSources.json ├── App.test.js ├── reportWebVitals.js ├── test-utils.js ├── hooks │ ├── useBondPrice.js │ ├── useBondMaxPayout.js │ ├── useMinter.js │ ├── useUsdvMintedBurnt.js │ ├── useAccountPreCommits.js │ ├── useTreasuryClaimed.js │ ├── useXvaderPrice.js │ ├── useStakingRewardsEarned.js │ ├── usePublicFee.js │ ├── useMinterDailyLimits.js │ ├── useStakingRewardsBalanceOf.js │ ├── useMinterLBT.js │ ├── useTreasuryHasClaim.js │ ├── useRewardsTVL.js │ ├── useClaimableVeth.js │ ├── useBondTerms.js │ ├── useBurnLimitRemains.js │ ├── useMintLimitRemains.js │ ├── useXvaderAPR.js │ ├── useERC20Balance.js │ ├── useUniswapTWAP.js │ ├── useTimeToBlock.js │ ├── useUniswapV2Price.js │ ├── useBondPendingPayout.js │ ├── useLocks.js │ ├── useUSDVprice.js │ ├── useBondInfo.js │ ├── useRewardsAPY.js │ ├── useTreasuryBalance.js │ └── usePreCommit.js ├── components │ ├── ColorModeSwitcher.js │ ├── ModalStyleContainer.js │ ├── TokenJazzicon.js │ ├── BurgerMenu.js │ ├── SortableHeader.js │ ├── USDVpriceIndicator.js │ ├── Position.js │ ├── WalletConnectionModal.js │ ├── Header.js │ ├── WalletConnectionToggle.js │ ├── Logotype.js │ ├── BondItem.js │ ├── BalanceIndicator.js │ └── PositionOverview.js ├── index.js ├── artifacts │ ├── abi │ │ ├── unlockValidator │ │ │ └── index.js │ │ ├── precommitZap │ │ │ └── index.js │ │ ├── converter │ │ │ └── index.js │ │ ├── vaderReserve │ │ │ └── index.js │ │ ├── vaderPoolFactory │ │ │ └── index.js │ │ ├── vaderMath │ │ │ └── index.js │ │ ├── zapEth │ │ │ └── index.js │ │ ├── linearVesting │ │ │ └── index.js │ │ ├── vaderRouter │ │ │ └── index.js │ │ ├── xvader │ │ │ └── index.js │ │ ├── uniswapTWAP │ │ │ └── index.js │ │ ├── treasuryMerkleMap │ │ │ └── index.js │ │ ├── preCommit │ │ │ └── index.js │ │ ├── humanStandardToken │ │ │ └── index.js │ │ ├── vether │ │ │ └── index.js │ │ └── stakingRewards │ │ │ └── index.js │ ├── json │ │ ├── treasuryMap │ │ │ └── usdv │ │ │ │ └── index.json │ │ └── vaderTokens │ │ │ └── index.json │ └── js │ │ └── vaderBonds │ │ └── index.js ├── common │ └── graphql.js ├── App.js ├── locations │ └── bonds.js └── serviceWorker.js ├── .prettierrc ├── .env.sample ├── shell.nix ├── LICENSE ├── .vscode └── linenote │ └── src │ └── locations │ └── bond.js#L502-L524.md ├── package.json ├── .eslintrc.json ├── .gitignore └── README.md /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/logo256.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/logo512.png -------------------------------------------------------------------------------- /public/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/preview.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/themes/vader/tooltip.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | borderRadius: '6px', 4 | }, 5 | } -------------------------------------------------------------------------------- /public/fonts/sequel.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/sequel.ttf -------------------------------------------------------------------------------- /src/themes/vader/fonts.js: -------------------------------------------------------------------------------- 1 | export default { 2 | heading: 'Heading', 3 | body: 'Body', 4 | button: 'Button', 5 | } -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-300.woff -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-300.woff2 -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-700.woff -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-700.woff2 -------------------------------------------------------------------------------- /src/themes/vader/alert.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | container: { 4 | borderRadius: '8px', 5 | }, 6 | }, 7 | } -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-italic.woff -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-italic.woff2 -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-regular.woff -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-300italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-300italic.woff -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-700italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-700italic.woff -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-regular.woff2 -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-300italic.woff2 -------------------------------------------------------------------------------- /public/fonts/lato-v17-latin-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/lato-v17-latin-700italic.woff2 -------------------------------------------------------------------------------- /src/assets/png/eth-diamond-purple-purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/src/assets/png/eth-diamond-purple-purple.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "semi": false, 6 | "useTabs": true 7 | } 8 | -------------------------------------------------------------------------------- /public/fonts/average-sans-v9-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/average-sans-v9-latin-regular.woff -------------------------------------------------------------------------------- /public/fonts/average-sans-v9-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vetherasset/vader-dapp/HEAD/public/fonts/average-sans-v9-latin-regular.woff2 -------------------------------------------------------------------------------- /src/themes/vader/spinner.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | color: 'white', 4 | }, 5 | variants: { 6 | inverted: () => ({ 7 | color: 'black', 8 | }), 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /.env.sample: -------------------------------------------------------------------------------- 1 | # Get your own Alchemy API key ( https://www.youtube.com/watch?v=tfggWxfG9o0 ) 2 | REACT_APP_ALCHEMY_KEY=YOUR_API_KEY_HERE 3 | 4 | # Chain network to use: 5 | # 1: Ethereum Mainnet 6 | # 42: Ethereum Kovan Testnet 7 | REACT_APP_CHAIN_ID=42 8 | -------------------------------------------------------------------------------- /src/themes/vader/badge.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | borderRadius: '6px', 4 | padding: '1px 8px', 5 | }, 6 | colorScheme: { 7 | purple: () => ({ 8 | color: '#9043FB', 9 | background: 'rgba(214, 188, 250, 0.16)', 10 | }), 11 | }, 12 | } -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom' 6 | -------------------------------------------------------------------------------- /src/themes/vader/switch.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | thumb: { 4 | bg: '#4F4F4F', 5 | }, 6 | track: { 7 | bg: '#ffffffd6', 8 | _checked: { 9 | bg: 'bluish.300', 10 | }, 11 | _focus: { 12 | boxShadow: '0 0 0 3px #7b7ce0', 13 | }, 14 | }, 15 | }, 16 | } -------------------------------------------------------------------------------- /src/tokenListSources.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"Vader Token List", 4 | "url":"https://raw.githubusercontent.com/vetherasset/vader-tokens/master/index.json", 5 | "logoURI":"https://raw.githubusercontent.com/vetherasset/branding/main/vader/vader-symbol-coingecko.png", 6 | "enabled":true 7 | } 8 | ] -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import { 2 | overlays = [ 3 | (self: super: { 4 | yarn = super.yarn.override { 5 | nodejs = pkgs.nodejs-17_x; 6 | }; 7 | }) 8 | ]; 9 | } }: 10 | pkgs.mkShell { 11 | nativeBuildInputs = [ 12 | pkgs.nodejs-17_x 13 | pkgs.yarn 14 | ]; 15 | } 16 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { screen } from '@testing-library/react' 3 | import { render } from './test-utils' 4 | import App from './App' 5 | 6 | test('renders learn react link', () => { 7 | render() 8 | const linkElement = screen.getByText(/learn chakra/i) 9 | expect(linkElement).toBeInTheDocument() 10 | }) 11 | -------------------------------------------------------------------------------- /src/themes/vader/select.js: -------------------------------------------------------------------------------- 1 | export default { 2 | variants: { 3 | filled: () => ({ 4 | field: { 5 | background: 'white', 6 | borderColor: 'accent.100', 7 | _hover: { 8 | background: 'white', 9 | }, 10 | _focus: { 11 | borderColor: '#ffd000', 12 | background: 'white', 13 | }, 14 | }, 15 | }), 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry) 5 | getFID(onPerfEntry) 6 | getFCP(onPerfEntry) 7 | getLCP(onPerfEntry) 8 | getTTFB(onPerfEntry) 9 | }) 10 | } 11 | } 12 | 13 | export default reportWebVitals 14 | -------------------------------------------------------------------------------- /src/themes/vader/typography.js: -------------------------------------------------------------------------------- 1 | export default { 2 | uppercase: { 3 | textTransform: 'uppercase', 4 | }, 5 | noLigs: { 6 | fontVariantLigatures: 'none', 7 | }, 8 | p: { 9 | marginBottom: '2.3rem', 10 | }, 11 | h1: { 12 | margin: '0 0 1rem', 13 | }, 14 | h2: { 15 | margin: '0 0 1.5rem', 16 | }, 17 | h3: { 18 | margin: '0 0 1rem', 19 | }, 20 | h4: { 21 | margin: '0 0 0.5rem', 22 | }, 23 | } 24 | -------------------------------------------------------------------------------- /src/test-utils.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from '@testing-library/react' 3 | import { ChakraProvider, theme } from '@chakra-ui/react' 4 | 5 | const AllProviders = ({ children }) => ( 6 | {children} 7 | ) 8 | 9 | const customRender = (ui, options) => 10 | render(ui, { wrapper: AllProviders, ...options }) 11 | 12 | export { customRender as render } 13 | -------------------------------------------------------------------------------- /src/themes/vader/tag.js: -------------------------------------------------------------------------------- 1 | export default { 2 | variants: { 3 | outline: () => ({ 4 | container: { 5 | borderRadius: '12px', 6 | color: '#fff', 7 | boxShadow: 'inset 0 0 0px 1px rgba(255, 255, 255, 0.16)', 8 | background: 'rgba(255, 255, 255, 0.08)', 9 | }, 10 | }), 11 | }, 12 | colorScheme: { 13 | vader: () => ({ 14 | color: '#red', 15 | background: 'rgba(214, 188, 250, 0.16)', 16 | }), 17 | }, 18 | } -------------------------------------------------------------------------------- /src/themes/vader/link.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | borderBottom: '1px solid #fff0', 4 | _hover: { 5 | textDecoration: 'none', 6 | color: '#3fa3fa', 7 | }, 8 | _focus: { 9 | boxShadow: '0 0 0 3px #7b7ce0', 10 | }, 11 | }, 12 | variants: { 13 | underline: () => ({ 14 | _hover: { 15 | textDecoration: 'underline', 16 | color: '#000', 17 | borderBottom: 'none', 18 | }, 19 | }), 20 | }, 21 | } -------------------------------------------------------------------------------- /src/themes/vader/modal.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | dialog: { 4 | padding: '8px 0 0', 5 | borderRadius: '0.8rem', 6 | background: 'white.100', 7 | color: '#4F4F4F', 8 | }, 9 | body: { 10 | padding: '0', 11 | }, 12 | header: { 13 | fontSize: '1.2rem', 14 | paddingBottom: '1.2rem', 15 | }, 16 | closeButton: { 17 | top: '1rem', 18 | _focus: { 19 | boxShadow: '0 0 0 3px #7b7ce0', 20 | }, 21 | }, 22 | }, 23 | } -------------------------------------------------------------------------------- /src/themes/vader/popover.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | content: { 4 | background: 'white.100', 5 | color: '#4F4F4F', 6 | borderRadius: '0.8rem', 7 | _focus: { 8 | boxShadow: '0', 9 | }, 10 | }, 11 | header: { 12 | fontWeight: 'bold', 13 | borderColor: '#00000017', 14 | }, 15 | footer: { 16 | borderColor: '#00000017', 17 | }, 18 | closeButton: { 19 | _focus: { 20 | boxShadow: '0 0 0 3px #7b7ce0', 21 | }, 22 | }, 23 | }, 24 | } -------------------------------------------------------------------------------- /src/hooks/useBondPrice.js: -------------------------------------------------------------------------------- 1 | import { useQuery } from 'react-query' 2 | import { bondPrice } from '../common/ethereum' 3 | import defaults from '../common/defaults' 4 | 5 | export const useBondPrice = (bondAddress, staleTime = defaults.api.staleTime) => { 6 | 7 | const price = useQuery(`${bondAddress}_bondPrice`, async () => { 8 | if (bondAddress) { 9 | return await bondPrice( 10 | bondAddress, 11 | ) 12 | } 13 | }, { 14 | staleTime: staleTime, 15 | }, 16 | ) 17 | 18 | return price 19 | } 20 | -------------------------------------------------------------------------------- /src/hooks/useBondMaxPayout.js: -------------------------------------------------------------------------------- 1 | import { useQuery } from 'react-query' 2 | import { bondMaxPayout } from '../common/ethereum' 3 | import defaults from '../common/defaults' 4 | 5 | export const useBondMaxPayout = (bondAddress, staleTime = defaults.api.staleTime) => { 6 | 7 | const maxPayout = useQuery(`${bondAddress}_maxPayout`, async () => { 8 | if (bondAddress) { 9 | return await bondMaxPayout( 10 | bondAddress, 11 | ) 12 | } 13 | }, { 14 | staleTime: staleTime, 15 | }, 16 | ) 17 | 18 | return maxPayout 19 | } 20 | -------------------------------------------------------------------------------- /src/themes/vader/colors.js: -------------------------------------------------------------------------------- 1 | export default { 2 | primary: '#000000', 3 | accent: { 4 | 100: '#f472b6', 5 | 200: '#f44ca2', 6 | 300: '#d95d9c', 7 | }, 8 | bluish: { 9 | 100: '#3fa3fa', 10 | 200: '#3fa3fa', 11 | 300: '#3fa3fa', 12 | }, 13 | white: { 14 | 100: '#FFD8FE', 15 | }, 16 | green: { 17 | 200: '#7b7ce0', 18 | 500: '#f472b6', 19 | }, 20 | gray: { 21 | 300: '#f1f2f3', 22 | 600: '#302c2d', 23 | 700: '#1a160c', 24 | 800: '#665a81', 25 | }, 26 | vether: { 27 | 200: '#ffba00', 28 | 500: '#ffba00', 29 | }, 30 | pink: { 31 | 200: '#FE9DDB', 32 | 300: '#F296D1', 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /src/hooks/useMinter.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getMinter } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const useMinter = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 8 | 9 | if (!rpc) { 10 | // GQL 2 DO 11 | } 12 | else { 13 | 14 | const address = useQuery('minter', async () => { 15 | return await getMinter() 16 | }, { 17 | staleTime: staleTime, 18 | }, 19 | ) 20 | 21 | return address 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/components/ColorModeSwitcher.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useColorMode, useColorModeValue, IconButton } from '@chakra-ui/react' 3 | import { FaMoon, FaSun } from 'react-icons/fa' 4 | 5 | export const ColorModeSwitcher = (props) => { 6 | const { toggleColorMode } = useColorMode() 7 | const text = useColorModeValue('dark', 'light') 8 | const SwitchIcon = useColorModeValue(FaMoon, FaSun) 9 | 10 | return ( 11 | } 20 | {...props} 21 | /> 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Vader Protocol", 3 | "name": "Vader - decentralized liquidity protocol", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo256.png", 17 | "type": "image/png", 18 | "sizes": "256x256" 19 | }, 20 | { 21 | "src": "logo512.png", 22 | "type": "image/png", 23 | "sizes": "512x512" 24 | } 25 | ], 26 | "start_url": ".", 27 | "display": "standalone", 28 | "theme_color": "#000000", 29 | "background_color": "#000000" 30 | } 31 | -------------------------------------------------------------------------------- /src/themes/vader/menu.js: -------------------------------------------------------------------------------- 1 | export default { 2 | baseStyle: { 3 | list: { 4 | background: 'white.100', 5 | color: '#4F4F4F', 6 | borderRadius: '0.8rem', 7 | borderWidth: '0', 8 | _focus: { 9 | boxShadow: '0', 10 | }, 11 | p: '1rem 0', 12 | }, 13 | item: { 14 | color: '#4f4f4f', 15 | fontWeight: 'bold', 16 | paddingInlineStart: '1rem', 17 | paddingInlineEnd: '1rem', 18 | borderRadius: '0', 19 | alignItems: 'normal', 20 | _hover: { 21 | background: '#ffffff91', 22 | }, 23 | _active: { 24 | background: '#ffffff91', 25 | opacity: '0.866', 26 | }, 27 | _focus: { 28 | background: '#ffffff91', 29 | }, 30 | }, 31 | divider: { 32 | borderColor: '#4f4f4f54', 33 | }, 34 | }, 35 | } -------------------------------------------------------------------------------- /src/components/ModalStyleContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Box, Flex } from '@chakra-ui/react' 3 | import defaults from '../common/defaults' 4 | import PropTypes from 'prop-types' 5 | 6 | 7 | const ModalStyleContainer = ({ children, ...props })=>{ 8 | return( 9 | 15 | 22 | {children} 23 | 24 | 25 | ) 26 | } 27 | 28 | ModalStyleContainer.propTypes = { 29 | children: PropTypes.node.isRequired, 30 | } 31 | 32 | export default ModalStyleContainer 33 | -------------------------------------------------------------------------------- /src/hooks/useUsdvMintedBurnt.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import defaults from '../common/defaults' 4 | 5 | export const useUsdvMintedBurnt = (burnt = false, pollInterval = defaults.api.graphql.pollInterval) => { 6 | 7 | const query = gql` 8 | query { 9 | globals( 10 | orderBy: timestamp 11 | orderDirection: desc 12 | first: 1 13 | where: { 14 | id_gt: "${burnt ? 'burn' : 'mint'}_${defaults.usdv.address}_Day", 15 | id_lt: "${burnt ? 'burn' : 'mint'}_${defaults.usdv.address}_Hour" 16 | } 17 | ) { 18 | value 19 | timestamp 20 | } 21 | }` 22 | 23 | const amount = useApolloQuery( 24 | query, 25 | { 26 | pollInterval: pollInterval, 27 | }, 28 | ) 29 | 30 | return amount 31 | 32 | } -------------------------------------------------------------------------------- /src/hooks/useAccountPreCommits.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import defaults from '../common/defaults' 4 | 5 | export const useAccountPreCommits = (address, first = 1000, skip = 0, pollInterval = defaults.api.graphql.pollInterval) => { 6 | 7 | const query = gql` 8 | query { 9 | accounts( 10 | first: ${first} 11 | skip: ${skip} 12 | where: { 13 | address: "${address}" 14 | } 15 | ) { 16 | commit { 17 | id 18 | amount 19 | commitEvent { 20 | id 21 | index 22 | timestamp 23 | } 24 | isRemoved 25 | } 26 | } 27 | }` 28 | 29 | const commits = useApolloQuery( 30 | query, 31 | { 32 | pollInterval: pollInterval, 33 | }, 34 | ) 35 | 36 | return commits 37 | 38 | } -------------------------------------------------------------------------------- /src/themes/vader/numberinput.js: -------------------------------------------------------------------------------- 1 | export default { 2 | variants: { 3 | transparent: () => ({ 4 | field: { 5 | color: '#fff', 6 | _placeholder: { 7 | color: '#fff', 8 | fontWeight: '400', 9 | }, 10 | paddingInlineStart: '0', 11 | paddingInlineEnd: '0', 12 | background: 'transparent', 13 | _disabled: { 14 | opacity: '0.1', 15 | }, 16 | _hover: { 17 | background: 'transparent', 18 | }, 19 | _focus: { 20 | border: 'none', 21 | background: 'transparent', 22 | }, 23 | }, 24 | }), 25 | filled: () => ({ 26 | field: { 27 | background: '#665a81', 28 | _hover: { 29 | background: '#665a81', 30 | }, 31 | _focus: { 32 | borderColor: 'accent.100', 33 | background: '#665a81', 34 | }, 35 | }, 36 | }), 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /src/assets/svg/icons/coinbasewallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/hooks/useTreasuryClaimed.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getTreasuryClaimed } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | import { useWallet } from 'use-wallet' 7 | import { BigNumber } from 'ethers' 8 | 9 | export const useTreasuryClaimed = ( 10 | account = '', 11 | amount = BigNumber.from(0), 12 | staleTime = defaults.api.staleTime) => { 13 | 14 | const wallet = useWallet() 15 | 16 | const claimed = useQuery(`treasuryClaimed_${account ? account : wallet?.account}`, async () => { 17 | return await getTreasuryClaimed(account ? account : wallet.account) 18 | }, { 19 | staleTime: staleTime, 20 | enabled: (!!account || !!wallet.account), 21 | }, 22 | ) 23 | 24 | return claimed 25 | } 26 | -------------------------------------------------------------------------------- /src/hooks/useXvaderPrice.js: -------------------------------------------------------------------------------- 1 | import { useQuery, gql } from '@apollo/client' 2 | import defaults from '../common/defaults' 3 | 4 | export const useXvaderPrice = (first = 0, pollInterval = defaults.api.pollInterval, type = 'Day') => { 5 | 6 | const query = first > 0 ? gql` 7 | query { 8 | globals( 9 | ${first ? `first: ${first}` : ''} 10 | skip: 0, 11 | orderBy: timestamp, 12 | orderDirection: desc, 13 | where:{ 14 | name: "XVADER_PRICE", 15 | type: "${type}" 16 | }) { 17 | id 18 | name 19 | value 20 | type 21 | timestamp 22 | } 23 | } 24 | ` : gql` 25 | query { 26 | global(id: "XVADER_PRICE") { 27 | id 28 | name 29 | value 30 | } 31 | }` 32 | 33 | const { data, error, loading } = useQuery( 34 | query, 35 | { 36 | pollInterval: pollInterval, 37 | }, 38 | ) 39 | 40 | return [data, loading, error] 41 | } -------------------------------------------------------------------------------- /src/hooks/useStakingRewardsEarned.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getStakingRewardsEarned } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const useStakingRewardsEarned = (address, rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 8 | 9 | if (!rpc) { 10 | // GQL 2 DO 11 | } 12 | else { 13 | 14 | const earned = useQuery(`${defaults.address.stakingRewards}_stakingRewardsEarned_${address}`, 15 | async () => { 16 | if (address) { 17 | return await getStakingRewardsEarned( 18 | address, 19 | ) 20 | } 21 | }, { 22 | staleTime: defaults.api.staleTime, 23 | enabled: (!!address), 24 | }, 25 | ) 26 | 27 | return earned 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/hooks/usePublicFee.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getMinter, getPublicFee } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const usePublicFee = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 8 | 9 | if (!rpc) { 10 | // GQL 2 DO 11 | } 12 | else { 13 | 14 | const { data: minter } = useQuery('minter', async () => { 15 | return await getMinter() 16 | }, { 17 | staleTime: staleTime, 18 | }, 19 | ) 20 | 21 | const fee = useQuery('getPublicFee', async () => { 22 | if (minter) { 23 | return await getPublicFee(minter) 24 | } 25 | }, { 26 | staleTime: staleTime, 27 | enabled: !!minter, 28 | }, 29 | ) 30 | 31 | return fee 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/hooks/useMinterDailyLimits.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getMinterDailyLimits, getMinter } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const useMinterDailyLimits = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 8 | 9 | if (!rpc) { 10 | // GQL 2 DO 11 | } 12 | else { 13 | 14 | const { data: minter } = useQuery('minter', async () => { 15 | return await getMinter() 16 | }, { 17 | staleTime: staleTime, 18 | }, 19 | ) 20 | 21 | const limits = useQuery('dailyLimits', async () => { 22 | return await getMinterDailyLimits(minter) 23 | }, { 24 | staleTime: staleTime, 25 | enabled: !!minter, 26 | }, 27 | ) 28 | 29 | return limits 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /src/components/TokenJazzicon.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useRef } from 'react' 2 | import PropTypes from 'prop-types' 3 | import Jazzicon from '@metamask/jazzicon' 4 | import { Flex } from '@chakra-ui/react' 5 | 6 | export const TokenJazzicon = (props) => { 7 | 8 | TokenJazzicon.propTypes = { 9 | address: PropTypes.string, 10 | } 11 | 12 | const ref = useRef() 13 | 14 | useEffect(() => { 15 | if (props.address) { 16 | ref.current.appendChild(Jazzicon(22, parseInt( 17 | props.address.slice(2, 10), 16))) 18 | } 19 | return () => { 20 | if (props.address) { 21 | if (ref.current) ref.current.getElementsByTagName('div')[0].remove() 22 | } 23 | } 24 | }, [props.address]) 25 | 26 | return ( 27 | 36 | ) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/hooks/useStakingRewardsBalanceOf.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getStakingRewardsBalanceOf } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const useStakingRewardsBalanceOf = (address, rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 8 | 9 | if (!rpc) { 10 | // GQL 2 DO 11 | } 12 | else { 13 | 14 | const balance = useQuery(`${defaults.address.stakingRewards}_stakingRewardsBalanceOf_${address}`, 15 | async () => { 16 | if (address) { 17 | return await getStakingRewardsBalanceOf( 18 | address, 19 | ) 20 | } 21 | }, { 22 | staleTime: defaults.api.staleTime, 23 | enabled: (!!address), 24 | }, 25 | ) 26 | 27 | return balance 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/hooks/useMinterLBT.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getMinter, getMinterLbt } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const useMinterLBT = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 8 | 9 | 10 | if (!rpc) { 11 | // GQL 2 DO 12 | } 13 | else { 14 | 15 | const { data: minter } = useQuery('minter', async () => { 16 | if (minter) { 17 | return await getMinter() 18 | } 19 | }, { 20 | staleTime: staleTime, 21 | }, 22 | ) 23 | 24 | const address = useQuery('lbt', async () => { 25 | if (minter) { 26 | return await getMinterLbt(minter) 27 | } 28 | }, { 29 | staleTime: staleTime, 30 | enabled: !!minter, 31 | }, 32 | ) 33 | 34 | return address 35 | } 36 | } -------------------------------------------------------------------------------- /src/components/BurgerMenu.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import { Menu, MenuItem, MenuButton, IconButton, MenuList } from '@chakra-ui/react' 4 | import { Link } from 'react-router-dom' 5 | import { HamburgerIcon } from '@chakra-ui/icons' 6 | import { WalletConnectionToggle } from './WalletConnectionToggle' 7 | 8 | export const BurgerMenu = (props) => { 9 | BurgerMenu.propTypes = { 10 | pages: PropTypes.array.isRequired, 11 | } 12 | return ( 13 | 16 | } 20 | variant='solid' 21 | /> 22 | 23 | {props.pages.map(p => 27 | 28 | {p.text} 29 | 30 | )} 31 | 32 | 33 | 34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /src/assets/svg/Swap.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/hooks/useTreasuryHasClaim.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getTreasuryClaimed } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | import { useWallet } from 'use-wallet' 7 | import { BigNumber } from 'ethers' 8 | import usdv from '../artifacts/json/treasuryMap/usdv' 9 | import vader from '../artifacts/json/treasuryMap/vader' 10 | 11 | export const useTreasuryHasClaim = ( 12 | account = '', 13 | staleTime = defaults.api.staleTime) => { 14 | 15 | const wallet = useWallet() 16 | const hasUsdv = Object.prototype.hasOwnProperty.call(usdv, account ? account : wallet.account) 17 | const hasVader = Object.prototype.hasOwnProperty.call(vader, account ? account : wallet.account) 18 | 19 | if (hasUsdv && hasVader) return 3 20 | if (hasUsdv || hasVader) { 21 | if (hasUsdv) return 1 22 | if (hasVader) return 2 23 | } 24 | return 0 25 | } 26 | -------------------------------------------------------------------------------- /src/hooks/useRewardsTVL.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getVirtualPrice } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | import { useERC20Balance } from './useERC20Balance' 7 | 8 | export const useRewardsTVL = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 9 | 10 | const balance = useERC20Balance(defaults.address.usdv3crvf, defaults.address.stakingRewards) 11 | 12 | if (!rpc) { 13 | // GQL 2 DO 14 | } 15 | else { 16 | 17 | const virtualPrice = useQuery(`viretualPrice_${defaults.address.usdv3crvf}`, 18 | async () => { 19 | return await getVirtualPrice(defaults.address.usdv3crvf) 20 | }, { 21 | staleTime: defaults.api.staleTime, 22 | }, 23 | ) 24 | 25 | if (balance?.data && 26 | virtualPrice?.data) { 27 | 28 | return balance?.data?.div(virtualPrice?.data) 29 | 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /src/hooks/useClaimableVeth.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | import { useWallet } from 'use-wallet' 3 | import { ethers } from 'ethers' 4 | import { getClaim } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const useClaimableVeth = () => { 8 | 9 | const wallet = useWallet() 10 | const [block, setBlock] = useState(0) 11 | const [claimable, setClaimable] = useState(ethers.BigNumber.from('0')) 12 | 13 | useEffect(() => { 14 | if (wallet.account) { 15 | getClaim(wallet.account) 16 | .then((n) => { 17 | setClaimable(n) 18 | }) 19 | .catch(err => console.log(err)) 20 | } 21 | }, [wallet.account, block]) 22 | 23 | useEffect(() => { 24 | const interval = setInterval(() => { 25 | defaults.network.provider.getBlockNumber() 26 | .then(n => { 27 | setBlock(n) 28 | }) 29 | }, defaults.network.pollInterval) 30 | defaults.network.provider.getBlockNumber() 31 | .then(n => setBlock(n)) 32 | return () => clearInterval(interval) 33 | }, []) 34 | 35 | return claimable 36 | 37 | } -------------------------------------------------------------------------------- /src/hooks/useBondTerms.js: -------------------------------------------------------------------------------- 1 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 2 | import { useQuery } from 'react-query' 3 | import { bondTerms } from '../common/ethereum' 4 | import defaults from '../common/defaults' 5 | 6 | export const useBondTerms = (bondAddress, rpc = false, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 7 | 8 | if (!rpc) { 9 | const query = gql` 10 | query { 11 | term ( 12 | id: "${String(bondAddress).toLowerCase()}" 13 | ) { 14 | controlVariable 15 | vestingTerm 16 | minPrice 17 | maxPayout 18 | maxDebt 19 | } 20 | } 21 | ` 22 | 23 | const terms = useApolloQuery( 24 | query, 25 | { 26 | pollInterval: pollInterval, 27 | }, 28 | ) 29 | 30 | return terms 31 | } 32 | else { 33 | 34 | const terms = useQuery(`${bondAddress}_bondTerms`, async () => { 35 | if (bondAddress) { 36 | return await bondTerms( 37 | bondAddress, 38 | ) 39 | } 40 | }, { 41 | staleTime: staleTime, 42 | }, 43 | ) 44 | 45 | return terms 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /src/hooks/useBurnLimitRemains.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { BigNumber } from 'ethers' 3 | import { useQuery } from 'react-query' 4 | import defaults from '../common/defaults' 5 | import { getMinter, getMinterDailyLimits, getCycleBurns } from '../common/ethereum' 6 | 7 | export const useBurnLimitRemains = (staleTime = defaults.api.staleTime) => { 8 | 9 | const { data: minter } = useQuery('minter', async () => { 10 | return await getMinter() 11 | }, { 12 | staleTime: staleTime, 13 | }, 14 | ) 15 | 16 | const limits = useQuery('dailyLimits', () => { 17 | if (minter) { 18 | return getMinterDailyLimits(minter) 19 | } 20 | }, { 21 | staleTime: staleTime, 22 | enabled: !!minter, 23 | }, 24 | ) 25 | 26 | const burned = useQuery('cycleBurns', async () => { 27 | if (minter) { 28 | return await getCycleBurns(minter) 29 | } 30 | }, { 31 | staleTime: staleTime, 32 | enabled: !!minter, 33 | }, 34 | ) 35 | 36 | if (limits?.data?.[2] && burned?.data) { 37 | return [limits?.data?.[2].sub(burned?.data), burned.refetch] 38 | } 39 | 40 | return [undefined, burned.refetch] 41 | } -------------------------------------------------------------------------------- /src/hooks/useMintLimitRemains.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { BigNumber } from 'ethers' 3 | import { useQuery } from 'react-query' 4 | import defaults from '../common/defaults' 5 | import { getMinter, getMinterDailyLimits, getCycleMints } from '../common/ethereum' 6 | 7 | export const useMintLimitRemains = (staleTime = defaults.api.staleTime) => { 8 | 9 | const { data: minter } = useQuery('minter', async () => { 10 | return await getMinter() 11 | }, { 12 | staleTime: staleTime, 13 | }, 14 | ) 15 | 16 | const limits = useQuery('dailyLimits', () => { 17 | if (minter) { 18 | return getMinterDailyLimits(minter) 19 | } 20 | }, { 21 | staleTime: staleTime, 22 | enabled: !!minter, 23 | }, 24 | ) 25 | 26 | const minted = useQuery('cycleMinted', async () => { 27 | if (minter) { 28 | return await getCycleMints(minter) 29 | } 30 | }, { 31 | staleTime: staleTime, 32 | enabled: !!minter, 33 | }, 34 | ) 35 | 36 | if (limits?.data?.[1] && minted?.data) { 37 | return [limits?.data?.[1].sub(minted?.data), minted.refetch] 38 | } 39 | 40 | return [undefined, minted.refetch] 41 | } -------------------------------------------------------------------------------- /src/hooks/useXvaderAPR.js: -------------------------------------------------------------------------------- 1 | import defaults from '../common/defaults' 2 | import { useXvaderPrice } from './useXvaderPrice' 3 | import { utils } from 'ethers' 4 | 5 | export const useXvaderAPR = (type = 'Day', basedOnNumberOfRecords, days = 365, pollInterval = defaults.api.graphql.pollInterval) => { 6 | 7 | const [xvaderPrices] = useXvaderPrice(basedOnNumberOfRecords, pollInterval, type) 8 | 9 | if(xvaderPrices) { 10 | const [currentPrice] = xvaderPrices?.globals 11 | const [oldestPrice] = xvaderPrices?.globals?.slice(-1) 12 | const currentPriceBN = utils.parseUnits(currentPrice?.value, 'wei') 13 | const oldestPriceBN = utils.parseUnits(oldestPrice?.value, 'wei') 14 | const daysDifferent = Math.floor((currentPrice?.timestamp - oldestPrice?.timestamp) / 86400) 15 | if(currentPriceBN?.gt(0) && oldestPriceBN?.gt(0) && daysDifferent) { 16 | const apr = ((((currentPriceBN.sub(oldestPriceBN)) 17 | .mul(utils.parseUnits('1', 18))) 18 | .div(oldestPriceBN)) 19 | .div(daysDifferent) 20 | .mul(days)) 21 | .toString() 22 | return [utils.formatUnits(apr)] 23 | } 24 | } 25 | 26 | return [] 27 | } -------------------------------------------------------------------------------- /src/hooks/useERC20Balance.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getERC20BalanceOf } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | import { useWallet } from 'use-wallet' 7 | 8 | export const useERC20Balance = (tokenAddress, address, rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 9 | 10 | const wallet = useWallet() 11 | 12 | if (!rpc) { 13 | // GQL 2 DO 14 | } 15 | else { 16 | 17 | const balance = useQuery(`${tokenAddress}_erc20Balanceof_${address ? address : wallet?.account}`, 18 | async () => { 19 | if ((address || wallet?.account) && 20 | tokenAddress) { 21 | return await getERC20BalanceOf( 22 | tokenAddress, 23 | address ? address : wallet?.account, 24 | defaults.network.provider, 25 | ) 26 | } 27 | }, { 28 | staleTime: defaults.api.staleTime, 29 | enabled: ((address || !!wallet?.account) && !!tokenAddress), 30 | }, 31 | ) 32 | 33 | return balance 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/hooks/useUniswapTWAP.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import defaults from '../common/defaults' 5 | import { getMinter, getMinterLbt, getStaleVaderPrice } from '../common/ethereum' 6 | 7 | export const useUniswapTWAP = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 8 | 9 | if (!rpc) { 10 | // GQL 2 DO 11 | } 12 | else { 13 | 14 | const { data: minter } = useQuery('minter', async () => { 15 | return await getMinter() 16 | }, { 17 | staleTime: staleTime, 18 | }, 19 | ) 20 | 21 | const { data: lbt } = useQuery('lbt', async () => { 22 | if (minter) { 23 | return await getMinterLbt(minter) 24 | } 25 | }, { 26 | staleTime: staleTime, 27 | enabled: !!minter, 28 | }, 29 | ) 30 | 31 | const twap = useQuery('getStaleVaderPrice', async () => { 32 | if (lbt) { 33 | return await getStaleVaderPrice(lbt) 34 | } 35 | }, { 36 | staleTime: staleTime, 37 | enabled: !!lbt, 38 | }, 39 | ) 40 | 41 | return twap 42 | } 43 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Vader Protocol 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 | -------------------------------------------------------------------------------- /src/hooks/useTimeToBlock.js: -------------------------------------------------------------------------------- 1 | import { utils } from 'ethers' 2 | import { useEffect, useState } from 'react' 3 | import defaults from '../common/defaults' 4 | import { getDateFromSeconds } from '../common/utils' 5 | 6 | export const useTimeToBlock = (blockTarget) => { 7 | 8 | const [block, setBlock] = useState(undefined) 9 | const [eta, setEta] = useState('0') 10 | 11 | useEffect(() => { 12 | const interval = setInterval(() => { 13 | defaults.network.provider.getBlockNumber() 14 | .then(n => { 15 | setBlock(n) 16 | }) 17 | }, defaults.network.pollInterval) 18 | defaults.network.provider.getBlockNumber() 19 | .then(n => setBlock(n)) 20 | return () => clearInterval(interval) 21 | }, []) 22 | 23 | useEffect(() => { 24 | if(block && blockTarget) { 25 | const target = utils.parseUnits(String(blockTarget), 18) 26 | const blocks = target.sub(utils.parseUnits(String(block)), 18) 27 | const seconds = blocks.div(utils.parseUnits(String(defaults.network.blockTime.second), 18)) 28 | const date = getDateFromSeconds(seconds.toNumber()) 29 | setEta(date) 30 | } 31 | }, [block, blockTarget]) 32 | 33 | return [eta, setBlock] 34 | 35 | } -------------------------------------------------------------------------------- /src/hooks/useUniswapV2Price.js: -------------------------------------------------------------------------------- 1 | import { useQuery, gql } from '@apollo/client' 2 | import defaults from '../common/defaults' 3 | 4 | export const useUniswapV2Price = (pairAddress, principalPrice = false, pollInterval = defaults.api.graphql.pollInterval) => { 5 | 6 | const query = gql` 7 | query { 8 | pairs ( 9 | where: { 10 | id: "${String(pairAddress).toLowerCase()}" 11 | } 12 | ) { 13 | token0Price 14 | token1Price 15 | ${principalPrice ? ` 16 | reserve0 17 | reserve1 18 | totalSupply 19 | ` : ''} 20 | } 21 | }` 22 | 23 | const { data, error, loading } = useQuery( 24 | query, 25 | { 26 | client: defaults.api.graphql.client.uniswapV2, 27 | pollInterval: pollInterval, 28 | }, 29 | ) 30 | 31 | if(principalPrice) { 32 | const tvl = Number((data?.pairs?.[0]?.reserve0) * (data?.pairs?.[0]?.token1Price)) + Number(data?.pairs?.[0]?.reserve1) 33 | const price = Number((tvl) / (data?.pairs?.[0]?.totalSupply)) 34 | return [price && tvl ? { 35 | totalValueLocked: tvl, 36 | principalPrice: price, 37 | } : undefined, loading, error] 38 | } 39 | return [data, loading, error] 40 | 41 | } -------------------------------------------------------------------------------- /src/hooks/useBondPendingPayout.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react' 2 | import { useWallet } from 'use-wallet' 3 | import { ethers } from 'ethers' 4 | import { bondPendingPayoutFor } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | 7 | export const useBondPendingPayout = (bondContractAddress) => { 8 | 9 | const wallet = useWallet() 10 | const [block, setBlock] = useState(0) 11 | const [claimable, setClaimable] = useState(ethers.BigNumber.from('0')) 12 | 13 | useEffect(() => { 14 | if (wallet.account && bondContractAddress) { 15 | bondPendingPayoutFor(bondContractAddress, wallet.account) 16 | .then((n) => { 17 | setClaimable(n) 18 | }) 19 | .catch(err => console.log(err)) 20 | } 21 | }, [wallet.account, bondContractAddress, block]) 22 | 23 | useEffect(() => { 24 | const interval = setInterval(() => { 25 | defaults.network.provider.getBlockNumber() 26 | .then(n => { 27 | setBlock(n) 28 | }) 29 | }, defaults.network.pollInterval) 30 | defaults.network.provider.getBlockNumber() 31 | .then(n => setBlock(n)) 32 | return () => clearInterval(interval) 33 | }, []) 34 | 35 | return [claimable, setBlock] 36 | 37 | } -------------------------------------------------------------------------------- /src/components/SortableHeader.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react' 2 | import PropTypes from 'prop-types' 3 | import { Flex, Text } from '@chakra-ui/react' 4 | import { TriangleUpIcon, TriangleDownIcon } from '@chakra-ui/icons' 5 | 6 | const SortableHeader = ({ name, text, display, sortHandler }) =>{ 7 | const ascColor = '#ff9ddb' 8 | const descColor = '#26a4fe' 9 | const [order, setOrder] = useState('asc') 10 | return ( 11 | { 17 | const newOrder = order === 'asc' ? 'desc' : 'asc' 18 | setOrder(newOrder) 19 | sortHandler(newOrder) 20 | } 21 | }> 22 | {text} 23 | { name !== 'refresh' && 24 | 25 | 26 | } 27 | 28 | ) 29 | } 30 | 31 | SortableHeader.propTypes = { 32 | name: PropTypes.string, 33 | text: PropTypes.string, 34 | sortHandler: PropTypes.func, 35 | display: PropTypes.object, 36 | } 37 | 38 | export default SortableHeader -------------------------------------------------------------------------------- /src/assets/svg/Graph.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/hooks/useLocks.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getLocks } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | import { useWallet } from 'use-wallet' 7 | 8 | export const useLocks = (token, rpc = false, lockIndex = 0, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 9 | 10 | const wallet = useWallet() 11 | 12 | if (!rpc) { 13 | const query = gql` 14 | query { 15 | locks ( 16 | orderBy: release 17 | orderDirection: desc 18 | where: { 19 | isRemoved: false 20 | user_contains: "${wallet?.account?.toLowerCase()}" 21 | ${token ? `token : ${token}` : ''} 22 | } 23 | ) { 24 | token 25 | amount 26 | release 27 | } 28 | } 29 | ` 30 | const locks = useApolloQuery( 31 | query, 32 | { 33 | pollInterval: pollInterval, 34 | }, 35 | ) 36 | 37 | return locks 38 | } 39 | else { 40 | 41 | const locks = useQuery(`locks_${wallet?.account}`, async () => { 42 | return await getLocks(lockIndex) 43 | }, { 44 | staleTime: staleTime, 45 | }, 46 | ) 47 | 48 | return locks 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/assets/svg/Hourglass.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/hooks/useUSDVprice.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getVirtualPrice, getDy } from '../common/ethereum' 5 | import { utils } from 'ethers' 6 | import defaults from '../common/defaults' 7 | 8 | export const useUSDVprice = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 9 | 10 | if (!rpc) { 11 | // GQL 2 DO 12 | } 13 | else { 14 | 15 | const usdv3crvfPrice = useQuery(`get_dy_${defaults.address.usdv3crvf}`, 16 | async () => { 17 | return await getDy(0, 1, utils.parseEther('1'), defaults.address.usdv3crvf) 18 | }, { 19 | staleTime: defaults.api.staleTime, 20 | }, 21 | ) 22 | 23 | const crv3poolPrice = useQuery(`virtualPrice_${defaults.address.crv3pool}`, 24 | async () => { 25 | return await getVirtualPrice(defaults.address.crv3pool) 26 | }, { 27 | staleTime: defaults.api.staleTime, 28 | }, 29 | ) 30 | 31 | if ( 32 | usdv3crvfPrice?.data && 33 | crv3poolPrice?.data) { 34 | return utils.formatEther(String(Number(usdv3crvfPrice?.data?.toString() / 1e18) * Number(crv3poolPrice?.data?.toString()))) 35 | } 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /src/hooks/useBondInfo.js: -------------------------------------------------------------------------------- 1 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 2 | import { useQuery } from 'react-query' 3 | import defaults from '../common/defaults' 4 | import { bondInfo } from '../common/ethereum' 5 | 6 | export const useBondInfo = (bondContractAddress, depositorAddress, rpc = false, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 7 | 8 | if (!rpc) { 9 | const query = gql` 10 | query { 11 | bondInfos ( 12 | where: { 13 | id: "${String(bondContractAddress).toLowerCase()}" 14 | depositor: "${String(depositorAddress).toLowerCase()}" 15 | } 16 | ) { 17 | payout 18 | vesting 19 | lastBlock 20 | } 21 | } 22 | ` 23 | const bondInfoQ = useApolloQuery( 24 | query, 25 | { 26 | pollInterval: pollInterval, 27 | }, 28 | ) 29 | 30 | return bondInfoQ 31 | } 32 | else { 33 | const bondInfoQ = useQuery(`${bondContractAddress}_${depositorAddress}_bondInfo`, async () => { 34 | if (bondContractAddress && depositorAddress) { 35 | return await bondInfo( 36 | bondContractAddress, 37 | depositorAddress, 38 | ) 39 | } 40 | }, { 41 | staleTime: staleTime, 42 | }, 43 | ) 44 | return bondInfoQ 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /.vscode/linenote/src/locations/bond.js#L502-L524.md: -------------------------------------------------------------------------------- 1 | Following tries to set max up to max available, except it can not be used 2 | for now because the js calculation gives different output than the contract. 3 | Might be figured out later. 4 | 5 | ```js 6 | const maxAvailable = (ethers.BigNumber.from(treasuryBalance?.balances?.[0]?.balance) 7 | .lte(ethers.BigNumber.from(bond?.[0]?.maxPayout))) ? 8 | ethers.BigNumber.from(treasuryBalance?.balances?.[0]?.balance, 18) : 9 | ethers.BigNumber.from(bond?.[0]?.maxPayout) 10 | 11 | bondPayoutFor( 12 | String(bond?.[0]?.address).toLocaleLowerCase(), 13 | token0balance, 14 | ) 15 | .then(n => { 16 | if (n.lte(maxAvailable)) { 17 | setInputAmount( 18 | ethers.utils.formatUnits(token0balance, token0.decimals), 19 | ) 20 | setValue(token0balance) 21 | } 22 | else { 23 | setInputAmount( 24 | ethers.utils.formatUnits(maxAvailable.mul(bondPrice), token0.decimals), 25 | ) 26 | setValue(token0balance) 27 | } 28 | }) 29 | ``` -------------------------------------------------------------------------------- /src/assets/svg/icons/walletconnect.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { ColorModeScript } from '@chakra-ui/react' 2 | import React, { StrictMode } from 'react' 3 | import ReactDOM from 'react-dom' 4 | import theme from './themes/vader' 5 | import App from './App' 6 | import defaults from './common/defaults' 7 | import { ApolloProvider } from '@apollo/client' 8 | import { QueryClientProvider } from 'react-query' 9 | import reportWebVitals from './reportWebVitals' 10 | import * as serviceWorker from './serviceWorker' 11 | 12 | ReactDOM.render( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | , 21 | document.getElementById('root'), 22 | ) 23 | 24 | // If you want your app to work offline and load faster, you can change 25 | // unregister() to register() below. Note this comes with some pitfalls. 26 | // Learn more about service workers: https://cra.link/PWA 27 | serviceWorker.unregister() 28 | 29 | // If you want to start measuring performance in your app, pass a function 30 | // to log results (for example: reportWebVitals(console.log)) 31 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 32 | reportWebVitals() 33 | -------------------------------------------------------------------------------- /src/artifacts/abi/unlockValidator/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'anonymous':false, 'inputs':[{ 'indexed':true, 'internalType':'address', 'name':'previousOwner', 'type':'address' }, { 'indexed':true, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnershipTransferred', 'type':'event' }, { 'inputs':[{ 'internalType':'address', 'name':'_account', 'type':'address' }], 'name':'invalidate', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'user', 'type':'address' }, { 'internalType':'uint256', 'name':'', 'type':'uint256' }, { 'internalType':'enum IUSDV.LockTypes', 'name':'', 'type':'uint8' }], 'name':'isValid', 'outputs':[{ 'internalType':'bool', 'name':'', 'type':'bool' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'owner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'renounceOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'transferOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'_account', 'type':'address' }], 'name':'validate', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }] -------------------------------------------------------------------------------- /src/components/USDVpriceIndicator.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Box, Image, Tooltip, useBreakpointValue } from '@chakra-ui/react' 3 | import defaults from '../common/defaults' 4 | import { prettifyNumber } from '../common/utils' 5 | import { useUSDVprice } from '../hooks/useUSDVprice' 6 | 7 | export const USDVpriceIndicator = () => { 8 | 9 | const price = useUSDVprice() 10 | 11 | const maxd = useBreakpointValue({ 12 | base: '2', 13 | md: '2', 14 | lg: '5', 15 | }) 16 | 17 | return ( 18 | <> 19 | {price > 0 && 20 | 26 | 34 | 38 | {`${defaults.usdv.name} 45 | 49 | $ 50 | {prettifyNumber(price, 0, maxd, 'us')} 51 | 52 | 53 | 54 | 55 | } 56 | 57 | ) 58 | } 59 | -------------------------------------------------------------------------------- /src/artifacts/abi/precommitZap/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'inputs':[{ 'internalType':'address', 'name':'_weth', 'type':'address' }, { 'internalType':'address', 'name':'_preCommit', 'type':'address' }], 'stateMutability':'nonpayable', 'type':'constructor' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnerChanged', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnerNominated', 'type':'event' }, { 'inputs':[], 'name':'acceptOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'_owner', 'type':'address' }], 'name':'nominateNewOwner', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'nominatedOwner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'owner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'preCommit', 'outputs':[{ 'internalType':'contract IPreCommit', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'_token', 'type':'address' }], 'name':'recover', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'weth', 'outputs':[{ 'internalType':'contract IWETH', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'zap', 'outputs':[], 'stateMutability':'payable', 'type':'function' }] -------------------------------------------------------------------------------- /src/artifacts/json/treasuryMap/usdv/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "0x7838D17d508a0dbC5ac2B5B0ef121FB2BC5A7EFe": "204181946470", 3 | "0x9e20251aD80B9D1c7ed01f72450FFf6ac58D47Ab": "425028322613", 4 | "0x60Ac0b2f9760b24CcD0C6b03d2b9f2E19c283FF9": "4669891", 5 | "0x185196C8C5Dd5729f22315203E09E33c3f7D7680": "53930633", 6 | "0x273BA31C706b9D9FdAe1FD999183Bfa865895bE9": "100192704", 7 | "0x68f15466B9aF1BF3F0b6E9DE24087d6f35D0b9a5": "5480268", 8 | "0x9F7C2f7540F1074a5957364DD9A1f96FFA2247dc": "550135", 9 | "0xc413ACd6162426bD78D13eef8d93f46671A96E63": "42303439", 10 | "0x2066D92D82e8104d0CEd88c51Bb6721c3EC894C5": "4463158", 11 | "0x9D810070Ce5BcF421603cBcD44AD03cF106a1756": "4833284479", 12 | "0xeAcB799e666a538965a39F1C87348aFc170829E2": "6203014", 13 | "0xb1720612D0131839DC489fCf20398Ea925282fCa": "154031", 14 | "0x1D24C2BEEd8abD30626d6D2589F0E8B92Ca8C2D2": "33326948", 15 | "0x7Ea6E87789C40084030b2289C89fdA723Bd91117": "18451358", 16 | "0x7E94008082f2e8D23B870f75F322e07E1ceD0cdb": "488284", 17 | "0x507633A6076DC92B2587acEE01349c21e5F3B985": "29524945", 18 | "0x173492EeB441B96d288757B6fDC42A1A9440c831": "6630884", 19 | "0x9e93e28ab2b49cdf2934FD4f5f669543e2500969": "14762472", 20 | "0xfc6f9C269368bC86E2Bf61108A6e9602f1d6661a": "4184065", 21 | "0xe1BaF6dB6406Ab1E29995Bff5Cf362d8f984995A": "628777", 22 | "0x8eF3640010DcD214E5eBC37c9a668C2020AA0512": "592916835", 23 | "0xF7a93E66b8e98bC0807c832D29fd82df438a8b56": "12110027", 24 | "0x60Cf705731c13aAE647C062D875830AEB636355e": "1898908", 25 | "0x7C199A0f301913212cfAB3756c3ed8F5B8927713": "256692899", 26 | "0x2A2c1102cC6F3eF7e3d469e47c70ad8181C1FaED": "12363300", 27 | "0x06Cb1c5FCb1dDF0c27fd77Fb4101BAc5Daab56c4": "2477306" 28 | } -------------------------------------------------------------------------------- /src/themes/vader/input.js: -------------------------------------------------------------------------------- 1 | export default { 2 | variants: { 3 | transparent: () => ({ 4 | field: { 5 | color: '#fff', 6 | _placeholder: { 7 | color: '#fff', 8 | fontWeight: '400', 9 | }, 10 | paddingInlineStart: '0', 11 | paddingInlineEnd: '0', 12 | background: 'transparent', 13 | _disabled: { 14 | opacity: '0.1', 15 | }, 16 | _hover: { 17 | background: 'transparent', 18 | }, 19 | _focus: { 20 | border: 'none', 21 | background: 'transparent', 22 | }, 23 | InputRightAddon: { 24 | background: 'red', 25 | }, 26 | }, 27 | }), 28 | filled: () => ({ 29 | field: { 30 | borderRadius: '0.8rem', 31 | background: '#13070e', 32 | borderStyle: 'solid', 33 | borderWidth: '2px', 34 | borderColor: 'accent.100', 35 | _placeholder: { 36 | color: '#fff', 37 | }, 38 | _hover: { 39 | background: '#13070e', 40 | }, 41 | _focus: { 42 | borderColor: '#ff8ac0', 43 | background: '#13070e', 44 | }, 45 | }, 46 | }), 47 | blank: () => ({ 48 | field: { 49 | borderRadius: '0.8rem', 50 | background: 'white', 51 | borderStyle: 'solid', 52 | borderWidth: '2px', 53 | borderColor: 'accent.100', 54 | _hover: { 55 | background: 'white', 56 | }, 57 | _focus: { 58 | borderColor: '#ff8ac0', 59 | background: 'white', 60 | }, 61 | }, 62 | }), 63 | outline: () => ({ 64 | field: { 65 | color: '#fff', 66 | borderRadius: '0.8rem', 67 | _placeholder: { 68 | color: '#fff', 69 | }, 70 | _focus: { 71 | borderColor: '#7b7ce0', 72 | boxShadow: '0 0 0 3px #7b7ce0', 73 | }, 74 | }, 75 | }), 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /src/hooks/useRewardsAPY.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 3 | import { useQuery } from 'react-query' 4 | import { getRewardRate, getVirtualPrice } from '../common/ethereum' 5 | import defaults from '../common/defaults' 6 | import { useUniswapTWAP } from './useUniswapTWAP' 7 | import { useERC20Balance } from '../hooks/useERC20Balance' 8 | import { utils } from 'ethers' 9 | 10 | export const useRewardsAPY = (rpc = true, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 11 | 12 | const TWAprice = useUniswapTWAP() 13 | const balance = useERC20Balance(defaults.address.usdv3crvf, defaults.address.stakingRewards) 14 | 15 | 16 | if (!rpc) { 17 | // GQL 2 DO 18 | } 19 | else { 20 | 21 | const virtualPrice = useQuery(`virtualPrice_${defaults.address.usdv3crvf}`, 22 | async () => { 23 | return await getVirtualPrice(defaults.address.usdv3crvf) 24 | }, { 25 | staleTime: defaults.api.staleTime, 26 | }, 27 | ) 28 | 29 | const rewardRate = useQuery(`rewardRate_${defaults.address.stakingRewards}`, 30 | async () => { 31 | return await getRewardRate() 32 | }, { 33 | staleTime: defaults.api.staleTime, 34 | }, 35 | ) 36 | 37 | if (TWAprice?.data && 38 | balance?.data && 39 | virtualPrice?.data && 40 | rewardRate?.data) { 41 | 42 | const year = 31536000 43 | const tvl = balance?.data?.div(virtualPrice?.data) 44 | const price = utils.formatEther(TWAprice?.data) 45 | const rewardRatePerUSDperSecond = utils.formatEther(rewardRate?.data?.div(tvl)) 46 | 47 | const APRperYear = Number(rewardRatePerUSDperSecond) * year * Number(price) 48 | const APYperYear = ((1 + (APRperYear / year)) ** year) - 1 49 | 50 | return APYperYear 51 | 52 | } 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /src/hooks/useTreasuryBalance.js: -------------------------------------------------------------------------------- 1 | import { useQuery as useApolloQuery, gql } from '@apollo/client' 2 | import { useQuery } from 'react-query' 3 | import { bondTreasury, getERC20BalanceOf } from '../common/ethereum' 4 | import defaults from '../common/defaults' 5 | 6 | export const useTreasuryBalance = (bondAddress, rpc = false, pollInterval = defaults.api.graphql.pollInterval, staleTime = defaults.api.staleTime) => { 7 | 8 | if (!rpc) { 9 | const treasuryQuery = gql` 10 | query { 11 | global( 12 | id: "${String(bondAddress).toLowerCase()}_treasury") 13 | { 14 | value 15 | } 16 | } 17 | ` 18 | 19 | const balanceQuery = gql` 20 | query ($address: String!) { 21 | balances( 22 | where: { 23 | account: $address 24 | token: "${String(defaults.address.vader).toLowerCase()}" 25 | } 26 | ) { 27 | balance 28 | } 29 | } 30 | ` 31 | 32 | const { data: treasury } = useApolloQuery( 33 | treasuryQuery, 34 | ) 35 | 36 | const address = treasury?.global?.value 37 | const balance = useApolloQuery(balanceQuery, 38 | { 39 | skip: !address, 40 | variables: { address }, 41 | pollInterval: pollInterval, 42 | }, 43 | ) 44 | 45 | return balance 46 | } 47 | else { 48 | 49 | const { data: treasury } = useQuery(`${bondAddress}_bondTreasury`, async () => { 50 | if (bondAddress) { 51 | return await bondTreasury( 52 | bondAddress, 53 | ) 54 | } 55 | }, 56 | ) 57 | 58 | const address = treasury 59 | const balance = useQuery(`${address}_treasuryBalance`, async () => { 60 | if (address) { 61 | return await getERC20BalanceOf( 62 | defaults.vader.address, 63 | address, 64 | defaults.network.provider, 65 | ) 66 | } 67 | }, { 68 | staleTime: staleTime, 69 | }, 70 | ) 71 | return balance 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vader-dapp", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@apollo/client": "^3.4.16", 7 | "@chakra-ui/icons": "^1.0.13", 8 | "@chakra-ui/react": "^1.0.0", 9 | "@emotion/react": "^11.0.0", 10 | "@emotion/styled": "^11.0.0", 11 | "@metamask/jazzicon": "^2.0.0", 12 | "@testing-library/jest-dom": "^5.9.0", 13 | "@testing-library/react": "^10.2.1", 14 | "@testing-library/user-event": "^12.0.2", 15 | "axios": "^0.21.1", 16 | "ethers": "^5.3.0", 17 | "framer-motion": "^4.0.0", 18 | "get-token-list": "^1.0.0", 19 | "graphql": "^15.6.1", 20 | "install": "^0.13.0", 21 | "keccak256": "^1.0.3", 22 | "merkletreejs": "^0.2.24", 23 | "pretty-ms": "^7.0.1", 24 | "prop-types": "^15.7.2", 25 | "react": "^17.0.2", 26 | "react-dom": "^17.0.2", 27 | "react-icons": "^4.3.1", 28 | "react-query": "^3.34.4", 29 | "react-router-dom": "^5.2.0", 30 | "react-scripts": "4.0.3", 31 | "react-timeago": "^6.2.1", 32 | "react-use": "^17.3.1", 33 | "react-window": "^1.8.6", 34 | "use-wallet": "^0.13.1", 35 | "web-vitals": "^0.2.2" 36 | }, 37 | "resolutions": { 38 | "react-error-overlay": "6.0.9" 39 | }, 40 | "scripts": { 41 | "start": "react-scripts start", 42 | "build": "react-scripts build", 43 | "test": "react-scripts test", 44 | "eject": "react-scripts eject", 45 | "fix": "eslint . --fix" 46 | }, 47 | "eslintConfig": { 48 | "extends": "react-app" 49 | }, 50 | "browserslist": { 51 | "production": [ 52 | ">0.2%", 53 | "not dead", 54 | "not op_mini all" 55 | ], 56 | "development": [ 57 | "last 1 chrome version", 58 | "last 1 firefox version", 59 | "last 1 safari version" 60 | ] 61 | }, 62 | "devDependencies": { 63 | "react-error-overlay": "6.0.9" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/common/graphql.js: -------------------------------------------------------------------------------- 1 | import { ApolloClient, InMemoryCache, gql } from '@apollo/client' 2 | import { utils } from 'ethers' 3 | import defaults from './defaults' 4 | 5 | const getXVaderPrice = async (type = 'Hour', first) => { 6 | const query = first > 0 ? ` 7 | { 8 | globals( 9 | ${first ? `first: ${first}` : ''} 10 | skip: 0, 11 | orderBy: timestamp, 12 | orderDirection: desc, 13 | where:{ 14 | name: "XVADER_PRICE", 15 | type: "${type}" 16 | }) { 17 | id 18 | name 19 | value 20 | type 21 | timestamp 22 | } 23 | } 24 | ` : ` 25 | { 26 | global(id: "XVADER_PRICE") { 27 | id 28 | name 29 | value 30 | } 31 | } 32 | ` 33 | try { 34 | const result = await queryGraphQL(query, defaults.api.graphql.uri.vaderProtocol) 35 | if (result) { 36 | return result 37 | } 38 | } 39 | catch (err) { 40 | console.log(err) 41 | } 42 | } 43 | 44 | const getXVaderApr = async (type, basedOnNumberOfRecords, days = 365) => { 45 | const prices = await getXVaderPrice(type, basedOnNumberOfRecords) 46 | const [currentPrice] = prices?.globals 47 | const [oldestPrice] = prices?.globals?.slice(-1) 48 | if(currentPrice && oldestPrice) { 49 | const currentPriceBN = utils.parseUnits(currentPrice.value, 'wei') 50 | const oldestPriceBN = utils.parseUnits(oldestPrice.value, 'wei') 51 | const daysDifferent = Math.floor((currentPrice.timestamp - oldestPrice.timestamp) / 86400) 52 | const apr = ((((currentPriceBN.sub(oldestPriceBN)) 53 | .mul(utils.parseUnits('1', 18))) 54 | .div(oldestPriceBN)) 55 | .div(daysDifferent) 56 | .mul(days)) 57 | .toString() 58 | return utils.formatUnits(apr) 59 | } 60 | } 61 | 62 | const queryGraphQL = async (query, uri) => { 63 | try { 64 | const client = new ApolloClient({ 65 | uri: uri, 66 | cache: new InMemoryCache(), 67 | }) 68 | const result = await client.query({ query: gql(query) }) 69 | if (result && result.data) { 70 | return result.data 71 | } 72 | } 73 | catch (err) { 74 | console.log(`Failed to get data from GraphQL: ${err}`) 75 | } 76 | } 77 | 78 | export { 79 | getXVaderPrice, getXVaderApr, 80 | } 81 | -------------------------------------------------------------------------------- /src/assets/svg/icons/otherwallets.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 39 | 42 | 43 | 50 | 56 | 62 | 68 | 69 | -------------------------------------------------------------------------------- /src/artifacts/abi/converter/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'inputs':[{ 'internalType':'contract IERC20', 'name':'_vether', 'type':'address' }, { 'internalType':'contract IERC20', 'name':'_vader', 'type':'address' }, { 'internalType':'bytes32', 'name':'_root', 'type':'bytes32' }, { 'internalType':'uint256', 'name':'_salt', 'type':'uint256' }], 'stateMutability':'nonpayable', 'type':'constructor' }, { 'anonymous':false, 'inputs':[{ 'indexed':true, 'internalType':'address', 'name':'user', 'type':'address' }, { 'indexed':false, 'internalType':'uint256', 'name':'vetherAmount', 'type':'uint256' }, { 'indexed':false, 'internalType':'uint256', 'name':'vaderAmount', 'type':'uint256' }], 'name':'Conversion', 'type':'event' }, { 'inputs':[{ 'internalType':'bytes32', 'name':'', 'type':'bytes32' }], 'name':'claimed', 'outputs':[{ 'internalType':'bool', 'name':'', 'type':'bool' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'bytes32[]', 'name':'proof', 'type':'bytes32[]' }, { 'internalType':'uint256', 'name':'amount', 'type':'uint256' }, { 'internalType':'uint256', 'name':'minVader', 'type':'uint256' }], 'name':'convert', 'outputs':[{ 'internalType':'uint256', 'name':'vaderReceived', 'type':'uint256' }], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'root', 'outputs':[{ 'internalType':'bytes32', 'name':'', 'type':'bytes32' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'salt', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'contract ILinearVesting', 'name':'_vesting', 'type':'address' }], 'name':'setVesting', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'vader', 'outputs':[{ 'internalType':'contract IERC20', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'vesting', 'outputs':[{ 'internalType':'contract ILinearVesting', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'vether', 'outputs':[{ 'internalType':'contract IERC20', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }] -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node": true, 5 | "es2021": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:react/recommended" 10 | ], 11 | "parserOptions": { 12 | "ecmaFeatures": { 13 | "jsx": true 14 | }, 15 | "ecmaVersion": 12, 16 | "sourceType": "module" 17 | }, 18 | "plugins": [ 19 | "react" 20 | ], 21 | "rules": { 22 | "brace-style": ["error", "stroustrup", { "allowSingleLine": true }], 23 | "comma-dangle": ["error", "always-multiline"], 24 | "comma-spacing": "error", 25 | "comma-style": "error", 26 | "curly": ["error", "multi-line", "consistent"], 27 | "dot-location": ["error", "property"], 28 | "handle-callback-err": "off", 29 | "indent": ["error", "tab"], 30 | "max-nested-callbacks": ["error", { "max": 4 }], 31 | "max-statements-per-line": ["error", { "max": 2 }], 32 | "no-console": "off", 33 | "no-empty-function": "warn", 34 | "no-floating-decimal": "error", 35 | "no-inline-comments": "error", 36 | "no-lonely-if": "error", 37 | "no-multi-spaces": "error", 38 | "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], 39 | "no-shadow": ["error", { "allow": ["err", "resolve", "reject"] }], 40 | "no-trailing-spaces": ["error"], 41 | "no-var": "error", 42 | "object-curly-spacing": ["error", "always"], 43 | "prefer-const": "error", 44 | "quotes": ["error", "single"], 45 | "semi": ["error", "never"], 46 | "no-mixed-spaces-and-tabs": "off", 47 | "space-before-blocks": "error", 48 | "space-before-function-paren": ["error", { 49 | "anonymous": "never", 50 | "named": "never", 51 | "asyncArrow": "always" 52 | }], 53 | "space-in-parens": "error", 54 | "space-infix-ops": "error", 55 | "space-unary-ops": "error", 56 | "spaced-comment": "error", 57 | "yoda": "error", 58 | "no-unused-vars": "warn" 59 | }, 60 | "settings": { 61 | "react": { 62 | "version": "detect" // React version. "detect" automatically picks the version you have installed. 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/artifacts/abi/vaderReserve/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'inputs':[{ 'internalType':'contract IERC20', 'name':'_vader', 'type':'address' }, { 'internalType':'address', 'name':'_router', 'type':'address' }, { 'internalType':'address', 'name':'_dao', 'type':'address' }], 'stateMutability':'nonpayable', 'type':'constructor' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'recipient', 'type':'address' }, { 'indexed':false, 'internalType':'uint256', 'name':'amount', 'type':'uint256' }], 'name':'GrantDistributed', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'recipient', 'type':'address' }, { 'indexed':false, 'internalType':'uint256', 'name':'amount', 'type':'uint256' }], 'name':'LossCovered', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':true, 'internalType':'address', 'name':'previousOwner', 'type':'address' }, { 'indexed':true, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnershipTransferred', 'type':'event' }, { 'inputs':[{ 'internalType':'address', 'name':'recipient', 'type':'address' }, { 'internalType':'uint256', 'name':'amount', 'type':'uint256' }], 'name':'grant', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'lastGrant', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'owner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'recipient', 'type':'address' }, { 'internalType':'uint256', 'name':'amount', 'type':'uint256' }], 'name':'reimburseImpermanentLoss', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'renounceOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'reserve', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'router', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'transferOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'vader', 'outputs':[{ 'internalType':'contract IERC20', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 106 | 107 | # dependencies 108 | /node_modules 109 | /.pnp 110 | .pnp.js 111 | 112 | # testing 113 | /coverage 114 | 115 | # production 116 | /build 117 | 118 | # misc 119 | .DS_Store 120 | .env.local 121 | .env.development.local 122 | .env.test.local 123 | .env.production.local 124 | 125 | npm-debug.log* 126 | yarn-debug.log* 127 | yarn-error.log* 128 | 129 | .idea -------------------------------------------------------------------------------- /src/components/Position.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import PropTypes from 'prop-types' 3 | import { Link } from 'react-router-dom' 4 | import { ethers } from 'ethers' 5 | import { Flex, Image, Tag } from '@chakra-ui/react' 6 | import { getTokenByAddress, prettifyCurrency } from '../common/utils' 7 | import defaults from '../common/defaults' 8 | 9 | export const Position = (props) => { 10 | 11 | Position.propTypes = { 12 | foreignTokenAddress: PropTypes.string.isRequired, 13 | position: PropTypes.object.isRequired, 14 | } 15 | 16 | const [token, setToken] = useState({}) 17 | 18 | useEffect(() => { 19 | getTokenByAddress(props.foreignTokenAddress) 20 | .then((t) => { 21 | setToken(t) 22 | }) 23 | return () => setToken({}) 24 | }, [props.foreignTokenAddress]) 25 | 26 | return ( 27 | 28 | 42 | 44 | {`${token.name} 54 | {`${defaults.nativeAsset.name} 64 | {token.symbol}/{defaults.nativeAsset.symbol} 65 | 66 | 72 | {props.position.originalForeign && 73 | 74 | {prettifyCurrency(ethers.utils.formatUnits(props.position.originalForeign, token.decimals), 0, 4, token.symbol)} 75 | 76 | } 77 | {props.position.originalNative && 78 | 79 | {prettifyCurrency(ethers.utils.formatUnits(props.position.originalNative, defaults.nativeAsset.decimals), 0, 4, defaults.nativeAsset.symbol)} 80 | 81 | } 82 | 83 | 84 | 85 | ) 86 | } -------------------------------------------------------------------------------- /src/artifacts/abi/vaderPoolFactory/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'anonymous':false, 'inputs':[{ 'indexed':true, 'internalType':'address', 'name':'previousOwner', 'type':'address' }, { 'indexed':true, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnershipTransferred', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'token0', 'type':'address' }, { 'indexed':false, 'internalType':'address', 'name':'token1', 'type':'address' }, { 'indexed':false, 'internalType':'contract IVaderPool', 'name':'pool', 'type':'address' }, { 'indexed':false, 'internalType':'uint256', 'name':'totalPools', 'type':'uint256' }], 'name':'PoolCreated', 'type':'event' }, { 'inputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'name':'allPools', 'outputs':[{ 'internalType':'contract IVaderPool', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'tokenA', 'type':'address' }, { 'internalType':'address', 'name':'tokenB', 'type':'address' }], 'name':'createPool', 'outputs':[{ 'internalType':'contract IVaderPool', 'name':'pool', 'type':'address' }], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'', 'type':'address' }, { 'internalType':'address', 'name':'', 'type':'address' }], 'name':'getPool', 'outputs':[{ 'internalType':'contract IVaderPool', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'_nativeAsset', 'type':'address' }, { 'internalType':'address', 'name':'_dao', 'type':'address' }], 'name':'initialize', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'nativeAsset', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'owner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'queueActive', 'outputs':[{ 'internalType':'bool', 'name':'', 'type':'bool' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'renounceOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'token0', 'type':'address' }, { 'internalType':'address', 'name':'token1', 'type':'address' }], 'name':'toggleQueue', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'transferOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | https://www.vaderprotocol.io 4 | 5 |

6 | VaderProtocol.app 7 |
8 | All-in-One DeFi Protocol 9 |

10 | 11 | ## About 12 | 13 | > VADER is a liquidity protocol that anchors a slip-based fee Automated Market Maker (“AMM”) with our native stablecoin, USDV. 14 | > USDV is issued by burning to and from the VADER token which acts as the stability mechanism. 15 | 16 | ## Overview 17 | 18 | > To simplify, Vader Protocol is a combination of the best core ideas in DeFi 19 | 20 | Find out more on [docs.vaderprotocol.io](https://docs.vaderprotocol.io) 21 | 22 | ![credit:@viccccx1](https://raw.githubusercontent.com/vetherasset/branding/main/materials/vader-liquidity-protocol-infograph.png) 23 | 24 | ### Requirements 25 | 26 | > The project uses 'env' variables - so copy / duplicate `.env.sample` as `.env` before starting 27 | 28 | ## Getting Started 29 | 30 | [![GitHub branches](https://badgen.net/github/branches/vetherasset/vader-dapp)](https://github.com/vetherasset/vader-dapp/) 31 | [![GitHub issues](https://badgen.net/github/issues/vetherasset/vader-dapp/)](https://github.com/vetherasset/vader-dapp/issues/) 32 | [![GitHub issues](https://img.shields.io/github/issues/vetherasset/vader-dapp)](https://github.com/vetherasset/vader-dapp/issues) 33 | [![GitHub issues-closed](https://img.shields.io/github/issues-closed/vetherasset/vader-dapp)](https://github.com/vetherasset/vader-dapp/issues?q=is%3Aissue+is%3Aclosed) 34 | 35 | 1. Fork & clone repo 🍴 36 | 2. `yarn` or `npm i` 37 | 3. Grab yourself an [Alchemy.com](https://www.youtube.com/watch?v=tfggWxfG9o0) API key and replace `YOUR_API_KEY_HERE` in `.env` 38 | 4. `yarn start` or `npm start` 39 | 5. Browse @ [http://localhost:3000](http://localhost:3000) 40 | 6. Get coding! 🚀🍪 41 | 42 | #### Note(s): 43 | - `.env` file is ignored in Git - *DO NOT* commit your keys or remove from `.gitignore` 44 | - Project bootstrapped with [Create React App](https://github.com/facebook/create-react-app). All scripts are available if you need them (eg: `yarn eject`) 45 | 46 | ## Community 47 | 48 | - Home: [www.vaderprotocol.io](https://www.vaderprotocol.io) 49 | - Docs: [docs.vaderprotocol.io](https://docs.vaderprotocol.io) 50 | - Discord: [discord.com/invite/vaderprotocol](https://discord.com/invite/vaderprotocol) 51 | - Twitter: [twitter.com/VaderProtocol](https://twitter.com/VaderProtocol) 52 | - Telegram: [t.me/vaderprotocol](https://t.me/vaderprotocol) 53 | -------------------------------------------------------------------------------- /src/components/WalletConnectionModal.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react' 2 | import PropTypes from 'prop-types' 3 | import defaults from '../common/defaults' 4 | import { useWallet } from 'use-wallet' 5 | import { 6 | Modal, 7 | ModalHeader, 8 | ModalOverlay, 9 | ModalContent, 10 | ModalBody, 11 | ModalCloseButton, 12 | Box, 13 | Button, 14 | Flex, 15 | Grid, 16 | GridItem, 17 | Image, 18 | Text, 19 | useToast, 20 | } from '@chakra-ui/react' 21 | import { walletNotConnected } from '../messages' 22 | 23 | export const WalletConnectionModal = props => { 24 | WalletConnectionModal.propTypes = { 25 | isOpen: PropTypes.bool.isRequired, 26 | onClose: PropTypes.func.isRequired, 27 | setWorking: PropTypes.func.isRequired, 28 | } 29 | const wallet = useWallet() 30 | const toast = useToast() 31 | const wallets = Object.values(defaults.network.connectors).map( 32 | item => item.meta, 33 | ) 34 | 35 | useEffect(() => { 36 | if (wallet.error) { 37 | return toast({ 38 | ...walletNotConnected, 39 | description: wallet.error.message, 40 | }) 41 | } 42 | }, [wallet.error]) 43 | 44 | const connect = key => { 45 | props.onClose() 46 | props.setWorking(true) 47 | wallet 48 | .connect(key) 49 | .catch(err => { 50 | console.log(err) 51 | toast({ 52 | ...walletNotConnected, 53 | description: err.message, 54 | }) 55 | }) 56 | .finally(() => { 57 | props.setWorking(false) 58 | }) 59 | } 60 | 61 | return ( 62 | <> 63 | 71 | 72 | 73 | Connect Wallet 74 | 75 | 76 | 78 | 79 | {wallets.map(w => ( 80 | 82 | 97 | 98 | ))} 99 | 100 | 101 | 102 | 103 | 104 | 105 | ) 106 | } 107 | -------------------------------------------------------------------------------- /src/artifacts/abi/vaderMath/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'inputs':[], 'name':'ONE', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'vaderDeposited', 'type':'uint256' }, { 'internalType':'uint256', 'name':'vaderBalance', 'type':'uint256' }, { 'internalType':'uint256', 'name':'assetDeposited', 'type':'uint256' }, { 'internalType':'uint256', 'name':'assetBalance', 'type':'uint256' }, { 'internalType':'uint256', 'name':'totalPoolUnits', 'type':'uint256' }], 'name':'calculateLiquidityUnits', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'originalVader', 'type':'uint256' }, { 'internalType':'uint256', 'name':'originalAsset', 'type':'uint256' }, { 'internalType':'uint256', 'name':'releasedVader', 'type':'uint256' }, { 'internalType':'uint256', 'name':'releasedAsset', 'type':'uint256' }], 'name':'calculateLoss', 'outputs':[{ 'internalType':'uint256', 'name':'loss', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'vaderDeposited', 'type':'uint256' }, { 'internalType':'uint256', 'name':'vaderBalance', 'type':'uint256' }, { 'internalType':'uint256', 'name':'assetDeposited', 'type':'uint256' }, { 'internalType':'uint256', 'name':'assetBalance', 'type':'uint256' }], 'name':'calculateSlipAdjustment', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'amountIn', 'type':'uint256' }, { 'internalType':'uint256', 'name':'reserveIn', 'type':'uint256' }, { 'internalType':'uint256', 'name':'reserveOut', 'type':'uint256' }], 'name':'calculateSwap', 'outputs':[{ 'internalType':'uint256', 'name':'amountOut', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'amountOut', 'type':'uint256' }, { 'internalType':'uint256', 'name':'reserveIn', 'type':'uint256' }, { 'internalType':'uint256', 'name':'reserveOut', 'type':'uint256' }], 'name':'calculateSwapReverse', 'outputs':[{ 'internalType':'uint256', 'name':'amountIn', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'a', 'type':'uint256' }, { 'internalType':'uint256', 'name':'b', 'type':'uint256' }], 'name':'delta', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'a', 'type':'uint256' }], 'name':'pow', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'a', 'type':'uint256' }], 'name':'root', 'outputs':[{ 'internalType':'uint256', 'name':'c', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }] -------------------------------------------------------------------------------- /src/themes/vader/index.js: -------------------------------------------------------------------------------- 1 | import { mode } from '@chakra-ui/theme-tools' 2 | import fonts from './fonts' 3 | import typography from './typography' 4 | import colors from './colors' 5 | import alert from './alert' 6 | import badge from './badge' 7 | import button from './button' 8 | import tooltip from './tooltip' 9 | import input from './input' 10 | import numberInput from './numberinput' 11 | import select from './select' 12 | import menu from './menu' 13 | import switchComp from './switch' 14 | import link from './link' 15 | import { extendTheme } from '@chakra-ui/react' 16 | import spinner from './spinner' 17 | import modal from './modal' 18 | import tag from './tag' 19 | import popover from './popover' 20 | 21 | const overrides = { 22 | config: { 23 | useSystemColorMode: false, 24 | initialColorMode: 'dark', 25 | }, 26 | styles: { 27 | global: props => ({ 28 | body: { 29 | fontSize: '1em', 30 | fontWeight: 'normal', 31 | color: 'white', 32 | bg: mode('#000000', '#000000')(props), 33 | }, 34 | 'input::placeholder': { 35 | color: '#000', 36 | }, 37 | '.chakra-alert button:focus': { 38 | boxShadow: '0 0 0 3px #7b7ce0', 39 | }, 40 | h1: { 41 | textTransform: 'uppercase', 42 | margin: '0 0 1rem', 43 | }, 44 | h2: { 45 | margin: '0 0 1.5rem', 46 | }, 47 | h3: { 48 | margin: '0 0 1rem', 49 | }, 50 | h4: { 51 | margin: '0 0 0.5rem', 52 | }, 53 | 'img[src=\'\']': { 54 | opacity: '0', 55 | }, 56 | 'img:not([src])': { 57 | opacity: '0', 58 | }, 59 | '*:focus-visible': { 60 | outline: 'none', 61 | }, 62 | }), 63 | }, 64 | fonts: fonts, 65 | textStyles: typography, 66 | colors: colors, 67 | components: { 68 | Alert: alert, 69 | Button: button, 70 | Input: input, 71 | NumberInput: numberInput, 72 | Badge: badge, 73 | Tooltip: tooltip, 74 | Select: select, 75 | Menu: menu, 76 | Link: link, 77 | Spinner: spinner, 78 | Modal: modal, 79 | Switch: switchComp, 80 | Tag: tag, 81 | Popover: popover, 82 | }, 83 | layerStyles: { 84 | opaque: { 85 | background: 'white.100', 86 | color: '#4F4F4F', 87 | fontWeight: 'bold', 88 | borderRadius: '12px', 89 | }, 90 | colorful: { 91 | borderRadius: '24px', 92 | background: 'linear-gradient(90deg,rgb(100, 71, 101) 0%,rgb(33, 74, 112) 100%)', 93 | }, 94 | inputLike: { 95 | background: 'linear-gradient(90deg,#845a81 0%,#515a85 100%)', 96 | borderRadius: '0.8rem', 97 | padding: '0.6rem 1rem', 98 | }, 99 | overview: { 100 | bg: 'black', 101 | border: '1px solid #ffc300ce', 102 | borderRadius: '19px', 103 | marginBottom: '15px', 104 | p: '19px', 105 | minHeight: '95px', 106 | boxShadow: '0px 0px 32px -20px #ffffff9c', 107 | }, 108 | actionPanel: { 109 | display: 'flex', 110 | width: '100%', 111 | justifyContent: 'center', 112 | }, 113 | menuIcon: { 114 | marginTop: '0.67px', 115 | }, 116 | }, 117 | } 118 | 119 | export default extendTheme(overrides) 120 | -------------------------------------------------------------------------------- /src/assets/svg/Option.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/artifacts/abi/zapEth/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'inputs':[{ 'internalType':'address', 'name':'_weth', 'type':'address' }, { 'internalType':'address', 'name':'_router', 'type':'address' }, { 'internalType':'address', 'name':'_pair', 'type':'address' }, { 'internalType':'address', 'name':'_vader', 'type':'address' }, { 'internalType':'address', 'name':'_bond', 'type':'address' }], 'stateMutability':'nonpayable', 'type':'constructor' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnerChanged', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnerNominated', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'bool', 'name':'_paused', 'type':'bool' }], 'name':'Pause', 'type':'event' }, { 'inputs':[], 'name':'WETH', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'acceptOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'bond', 'outputs':[{ 'internalType':'contract IVaderBond', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'reserveIn', 'type':'uint256' }, { 'internalType':'uint256', 'name':'userIn', 'type':'uint256' }], 'name':'calculateSwapInAmount', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'pure', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'_owner', 'type':'address' }], 'name':'nominateNewOwner', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'nominatedOwner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'owner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'pair', 'outputs':[{ 'internalType':'contract IUniswapV2Pair', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'pause', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'paused', 'outputs':[{ 'internalType':'bool', 'name':'', 'type':'bool' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'_token', 'type':'address' }], 'name':'recover', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'router', 'outputs':[{ 'internalType':'contract IUniswapV2Router', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'unpause', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'vader', 'outputs':[{ 'internalType':'contract IERC20', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'uint256', 'name':'minPayout', 'type':'uint256' }], 'name':'zap', 'outputs':[], 'stateMutability':'payable', 'type':'function' }, { 'stateMutability':'payable', 'type':'receive' }] -------------------------------------------------------------------------------- /src/components/Header.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useLocation } from 'react-router-dom' 3 | import { Button, Flex, Image, useBreakpointValue, Link as LinkExt } from '@chakra-ui/react' 4 | import defaults from '../common/defaults' 5 | import { Link } from 'react-router-dom' 6 | import { Logotype } from './Logotype' 7 | import { WalletConnectionToggle } from './WalletConnectionToggle' 8 | import { BalanceIndicator } from '../components/BalanceIndicator' 9 | import { BurgerMenu } from './BurgerMenu' 10 | 11 | export const Header = (props) => { 12 | 13 | const location = useLocation() 14 | const pages = [ 15 | { 16 | name: 'Stake', 17 | text: 'Stake', 18 | link: '/stake', 19 | }, 20 | { 21 | name: 'Earn', 22 | text: 'Earn', 23 | link: '/earn', 24 | }, 25 | { 26 | name: 'Bond', 27 | text: 'Bond', 28 | link: '/bond', 29 | }, 30 | { 31 | name: 'Acquire', 32 | text: 'Acquire', 33 | link: '/acquire', 34 | }, 35 | { 36 | name: 'Redeem', 37 | text: 'Redeem', 38 | link: '/redeem', 39 | }, 40 | ] 41 | 42 | const current = { 43 | background: '#835a81', 44 | borderRadius: '10px', 45 | fontWeight: '1000', 46 | color: '#fff', 47 | } 48 | 49 | return ( 50 | 54 | 55 | 56 | 67 | {pages.map(p => 68 | 80 | {p.text} 81 | ) 82 | } 83 | 84 | 85 | 90 | {useBreakpointValue({ 91 | base: <> 92 | 93 | , 94 | md: <> 95 | 97 | 109 | 110 | 111 | , 112 | })} 113 | {useBreakpointValue({ 114 | base: , 115 | md: , 116 | })} 117 | 118 | 119 | ) 120 | } 121 | -------------------------------------------------------------------------------- /src/artifacts/abi/linearVesting/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [{ 'inputs':[{ 'internalType':'contract IERC20', 'name':'_vader', 'type':'address' }, { 'internalType':'address', 'name':'_converter', 'type':'address' }], 'stateMutability':'nonpayable', 'type':'constructor' }, { 'anonymous':false, 'inputs':[{ 'indexed':true, 'internalType':'address', 'name':'previousOwner', 'type':'address' }, { 'indexed':true, 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'OwnershipTransferred', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':true, 'internalType':'address', 'name':'from', 'type':'address' }, { 'indexed':false, 'internalType':'uint256', 'name':'amount', 'type':'uint256' }], 'name':'Vested', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'address', 'name':'user', 'type':'address' }, { 'indexed':false, 'internalType':'uint256', 'name':'amount', 'type':'uint256' }], 'name':'VestingCreated', 'type':'event' }, { 'anonymous':false, 'inputs':[{ 'indexed':false, 'internalType':'uint256', 'name':'duration', 'type':'uint256' }], 'name':'VestingInitialized', 'type':'event' }, { 'inputs':[{ 'internalType':'address[]', 'name':'vesters', 'type':'address[]' }, { 'internalType':'uint192[]', 'name':'amounts', 'type':'uint192[]' }], 'name':'begin', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'claim', 'outputs':[{ 'internalType':'uint256', 'name':'vestedAmount', 'type':'uint256' }], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'converter', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'end', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'_vester', 'type':'address' }], 'name':'getClaim', 'outputs':[{ 'internalType':'uint256', 'name':'vestedAmount', 'type':'uint256' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'owner', 'outputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[], 'name':'renounceOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'start', 'outputs':[{ 'internalType':'uint256', 'name':'', 'type':'uint256' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'newOwner', 'type':'address' }], 'name':'transferOwnership', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }, { 'inputs':[], 'name':'vader', 'outputs':[{ 'internalType':'contract IERC20', 'name':'', 'type':'address' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'', 'type':'address' }], 'name':'vest', 'outputs':[{ 'internalType':'uint192', 'name':'amount', 'type':'uint192' }, { 'internalType':'uint64', 'name':'lastClaim', 'type':'uint64' }, { 'internalType':'uint128', 'name':'start', 'type':'uint128' }, { 'internalType':'uint128', 'name':'end', 'type':'uint128' }], 'stateMutability':'view', 'type':'function' }, { 'inputs':[{ 'internalType':'address', 'name':'user', 'type':'address' }, { 'internalType':'uint256', 'name':'amount', 'type':'uint256' }], 'name':'vestFor', 'outputs':[], 'stateMutability':'nonpayable', 'type':'function' }] -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, {} from 'react' 2 | import { BrowserRouter as Router, Switch, Route, Redirect, useLocation } from 'react-router-dom' 3 | import { ChakraProvider, Box } from '@chakra-ui/react' 4 | import theme from './themes/vader' 5 | import { UseWalletProvider } from 'use-wallet' 6 | import { Header } from './components/Header' 7 | import Burn from './locations/burn' 8 | import Redeem from './locations/redeem' 9 | import Stake from './locations/stake' 10 | import Earn from './locations/earn' 11 | import Bonds from './locations/bonds' 12 | import Bond from './locations/bond' 13 | import defaults from './common/defaults' 14 | import { Footer } from './components/Footer' 15 | import { Wave } from './assets/svg/effects/Wave' 16 | 17 | const App = () => { 18 | 19 | return ( 20 | 21 | 22 | 27 |
33 | 34 | 35 | 36 | }/> 37 | 38 | 39 | }/> 40 | 41 | 42 | }/> 43 | 44 | 45 | }/> 46 | 47 | 48 | }/> 49 | 50 | 51 | }/> 52 | 53 | 54 | } /> 55 | 56 |