├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .prettierrc.json
├── README.md
├── generate-farm-info.sh
├── generate-static.sh
├── package.json
├── public
├── favicon.ico
├── favicon.svg
├── fonts
│ ├── NeueHaasGroteskDisp Pro Md.eot
│ ├── NeueHaasGroteskDisp Pro Md.ttf
│ ├── NeueHaasGroteskDisp Pro Md.woff
│ └── NeueHaasGroteskDisp Pro Md.woff2
├── index.html
├── manifest.json
└── robots.txt
├── scripts
└── remove-iframe-deny.js
├── src
├── App.js
├── App.test.js
├── assets
│ ├── aav-ewhite-logo-risk.svg
│ ├── aav-ewhite-logo.svg
│ ├── b-icon.svg
│ ├── b-protocol-icon-risk.svg
│ ├── b-protocol-small-logo.svg
│ ├── bp-icon-gold.svg
│ ├── bprotocol.svg
│ ├── circle-x-icon.svg
│ ├── close.svg
│ ├── coin-icons
│ │ ├── AAVE.svg
│ │ ├── BAT.png
│ │ ├── COMP.png
│ │ ├── DAI.png
│ │ ├── ETH.png
│ │ ├── LINK.png
│ │ ├── MKR.svg
│ │ ├── SUSHI.svg
│ │ ├── TUSD.png
│ │ ├── UNI.png
│ │ ├── USDC.png
│ │ ├── USDT.png
│ │ ├── WBTC legacy.png
│ │ ├── WBTC.png
│ │ ├── YFI.svg
│ │ └── ZRX.png
│ ├── com-icon-bl.svg
│ ├── compound-full-logo.svg
│ ├── compound-logo-a-1-risk.svg
│ ├── compound-logo-black.svg
│ ├── compound-logo.svg
│ ├── connect-your-wallet.svg
│ ├── dai.svg
│ ├── discord.svg
│ ├── dollar-icon.svg
│ ├── etherium.svg
│ ├── export-icon.svg
│ ├── github.svg
│ ├── hundred-logo.svg
│ ├── i-icon-green.svg
│ ├── i-icon.svg
│ ├── images
│ │ ├── borrow-repay.png
│ │ ├── compound-import-popup.png
│ │ ├── deposit-withdraw.png
│ │ ├── maker-dau.png
│ │ ├── maker-migration.png
│ │ ├── mobile-support.png
│ │ ├── modal-header.svg
│ │ └── vote.svg
│ ├── linkedin.svg
│ ├── liquity-logo.svg
│ ├── logo-maker-black.svg
│ ├── logo-maker-green.svg
│ ├── logo-maker-white-risk.svg
│ ├── logo-maker-white.svg
│ ├── maker-dao-background.svg
│ ├── medium-icon.svg
│ ├── red-x-icon.svg
│ ├── t-compound-logo-a-1.svg
│ ├── t-logo-maker-white.svg
│ ├── triangle.svg
│ ├── tvl-bg.svg
│ ├── tvl-graph.svg
│ ├── twitter-icon.svg
│ ├── v-icon-white-thick.svg
│ ├── v-icon-white.svg
│ ├── v-icon.svg
│ ├── view-icon-opeq-bg.svg
│ ├── view-icon.svg
│ └── x-icon.svg
├── common
│ └── constants.js
├── components
│ ├── AppAlert.js
│ ├── AppError.js
│ ├── BorrowLimit.js
│ ├── ConnectButton.js
│ ├── CurrencyBox.js
│ ├── CurrencyBoxHeader.js
│ ├── DaiBox.js
│ ├── EtheriumBox.js
│ ├── FAQContent.js
│ ├── FragLoader.js
│ ├── GlobalStats.js
│ ├── GlobalStatsEmpty.js
│ ├── Header.js
│ ├── Header2.js
│ ├── InstaInfo.js
│ ├── LeaveUs.js
│ ├── LiquidationPrice.js
│ ├── LoadingRing.js
│ ├── ModalContainer.js
│ ├── Pulser.js
│ ├── RiskContent.js
│ ├── Sidebar.js
│ ├── TermsOfUseContent.js
│ ├── Ticker.js
│ ├── Tooltip.js
│ ├── Tvl.js
│ ├── TvlTooltip.js
│ ├── action-panels
│ │ ├── Borrow.js
│ │ ├── Deposit.js
│ │ ├── Loading.js
│ │ ├── MigrationButton.js
│ │ ├── Repay.js
│ │ └── Withdraw.js
│ ├── compound-components
│ │ ├── ActionBox.js
│ │ ├── ActionBoxFooter.js
│ │ ├── BalanceBox.js
│ │ ├── BalanceListBox.js
│ │ ├── BorrowLimit.js
│ │ ├── ClaimComp.js
│ │ ├── CoinList.js
│ │ ├── CoinListBox.js
│ │ ├── CoinListHeader.js
│ │ ├── CoinListItem.js
│ │ ├── HeaderBorrowLimit.js
│ │ ├── ImportAllowanceToggle.js
│ │ ├── MigrateFromCompound.js
│ │ ├── MigrateFromCompoundModal.js
│ │ ├── MigrationAssetList.js
│ │ ├── ProgressBar.js
│ │ ├── TxInProgress.js
│ │ └── Unlock.js
│ ├── modals
│ │ ├── BproClaimModal.js
│ │ ├── ClaimCompModal.js
│ │ ├── GemModal.js
│ │ ├── MigrationModal.js
│ │ ├── TermsAndConditionContent.js
│ │ ├── TermsAndConditionsModal.js
│ │ └── WalletSelectionModal.js
│ └── style-components
│ │ ├── AnimateNumberChange.js
│ │ ├── AnimateNumericalString.js
│ │ ├── BpLoader.js
│ │ ├── Buttons.js
│ │ ├── GreyLine.js
│ │ ├── HeaderProgressBar.js
│ │ ├── ModalClaimHeader.js
│ │ ├── NotificationsContainer.js
│ │ ├── ProgressBar.js
│ │ ├── ResponsiveContainer.js
│ │ ├── Tabs.js
│ │ └── Toggle.js
├── containers
│ ├── Compound.js
│ ├── Dashboard.js
│ ├── FAQ.js
│ ├── FarmInfo.js
│ ├── Liquity.js
│ ├── LiquityLegacy.js
│ ├── Risk.js
│ └── Terms.js
├── index.css
├── index.js
├── lib
│ ├── Actions.js
│ ├── ApiHelper.js
│ ├── EventBus.js
│ ├── ScoreInterface.js
│ ├── Utils.js
│ ├── bInterface.js
│ ├── compound.interface.js
│ ├── compound.util.js
│ ├── compoundConfig
│ │ ├── abi.js
│ │ ├── compUserInfoAbi.js
│ │ ├── compoundImportAbi.js
│ │ ├── flashImportAbi.js
│ │ ├── initialState.js
│ │ ├── kovanAddress.js
│ │ ├── mainnetAddress.js
│ │ ├── readme.md
│ │ └── registryAbi.js
│ ├── insta.interface.js
│ ├── instaConfig
│ │ ├── abi.js
│ │ └── mainnetAddress.js
│ ├── liquity.interface.js
│ └── liquityConfig
│ │ ├── abi.js
│ │ └── mainnetAddress.js
├── screenSizes.js
├── scss
│ ├── _animations.scss
│ ├── _app.scss
│ ├── _buttons.scss
│ ├── _colors.scss
│ ├── _currency.scss
│ ├── _fonts.scss
│ ├── _hamburger.scss
│ ├── _layout.scss
│ ├── _migrate.scss
│ ├── _modal.scss
│ ├── _reset.scss
│ ├── _sidebar.scss
│ ├── _tooltip.scss
│ └── _utils.scss
├── serviceWorker.js
├── setupTests.js
├── stores
│ ├── apy.store.js
│ ├── bpro.store.js
│ ├── compound.store.js
│ ├── compoundMigration.store.js
│ ├── insta.store.js
│ ├── main.comp.store.js
│ ├── main.hundred.store.js
│ ├── main.liquity.store.js
│ ├── main.store.js
│ ├── maker.store.js
│ ├── router.store.js
│ └── user.store.js
├── style.scss
└── wallets
│ └── Wallets.js
├── test
├── package-lock.json
├── package.json
├── test-kovan.sh
├── test
│ ├── compound.test.js
│ ├── test.js
│ └── testWbtc.js
└── truffle-config.js
├── tests
└── e2e
│ ├── .eslintrc.js
│ ├── specs
│ ├── compound-import-spec.js
│ ├── compound-spec.js
│ ├── maker-gem-spec.js
│ ├── maker-import-spec.js
│ ├── maker-spec.js
│ └── website-spec.js
│ ├── test-utils.js
│ └── tsconfig.json
├── workers-site
├── .cargo-ok
├── .gitignore
├── index.js
├── package-lock.json
└── package.json
└── yarn.lock
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true
4 | },
5 | "extends": [
6 | "eslint:recommended",
7 | "plugin:react/recommended"
8 | ],
9 | "parserOptions": {
10 | "ecmaFeatures": {
11 | "jsx": true
12 | },
13 | "ecmaVersion": 12,
14 | "sourceType": "module"
15 | },
16 | "plugins": [
17 | "react"
18 | ],
19 | "rules": {
20 | "indent": [
21 | "error",
22 | "tab"
23 | ],
24 | "linebreak-style": [
25 | "error",
26 | "unix"
27 | ],
28 | "quotes": [
29 | "error",
30 | "double"
31 | ],
32 | "semi": [
33 | "error",
34 | "never"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 | /dist
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 | pacakge-lock.json
26 | API.json
27 |
28 | # test
29 | /test/node_modules
30 | /test/pacakge-lock.json
31 | /test/run-tests.bash
32 | test/ganache-kovan.sh
33 | .vscode/launch.json
34 |
35 | # CF worker site
36 | #===========================
37 | wrangler.toml
38 |
39 | # E2E tests
40 | #===========================
41 | .env
42 | tests/e2e/videos
43 | tests/e2e/screenshots
44 | tests/snapshot-id.txt
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | *.json
2 | *.md
3 | *html
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "printWidth": 100,
4 | "semi": false,
5 | "singleQuote": false,
6 | "jsxSingleQuote": false,
7 | "bracketSpacing": true,
8 | "jsxBracketSameLine": true,
9 | "requirePragma": true
10 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `yarn start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `yarn test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `yarn build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `yarn eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
46 | ### Code Splitting
47 |
48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
49 |
50 | ### Analyzing the Bundle Size
51 |
52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
53 |
54 | ### Making a Progressive Web App
55 |
56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
57 |
58 | ### Advanced Configuration
59 |
60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
61 |
62 | ### Deployment
63 |
64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
65 |
66 | ### `yarn build` fails to minify
67 |
68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
69 |
--------------------------------------------------------------------------------
/generate-farm-info.sh:
--------------------------------------------------------------------------------
1 | rsync -avr --exclude='farm-info' build/ build/farm-info
--------------------------------------------------------------------------------
/generate-static.sh:
--------------------------------------------------------------------------------
1 | cd build
2 | mkdir app && cp index.html app
3 | mkdir maker && cp index.html maker
4 | mkdir compound && cp index.html compound
5 | mkdir liquity && cp index.html liquity
6 | mkdir faq && cp index.html faq
7 | mkdir risk && cp index.html risk
8 | mkdir terms && cp index.html terms
9 | mkdir farm-info && cp index.html farm-info
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bprotocol-react-client",
3 | "version": "1.0.27",
4 | "private": true,
5 | "dependencies": {
6 | "@cloudflare/kv-asset-handler": "^0.1.0",
7 | "@metamask/detect-provider": "^1.2.0",
8 | "@testing-library/jest-dom": "^4.2.4",
9 | "@testing-library/react": "^9.3.2",
10 | "@testing-library/user-event": "^7.1.2",
11 | "@walletconnect/web3-provider": "1.6.6",
12 | "axios": "^0.21.0",
13 | "detect-browser": "^5.1.1",
14 | "esm": "^3.2.25",
15 | "mobx": "^6.0.4",
16 | "mobx-react": "^7.0.5",
17 | "moment": "^2.29.1",
18 | "qs": "^6.9.4",
19 | "react": "^16.13.1",
20 | "react-device-detect": "^1.17.0",
21 | "react-dom": "^16.13.1",
22 | "react-router-dom": "^5.2.0",
23 | "react-scripts": "3.4.3",
24 | "react-spring": "^8.0.27",
25 | "react-tooltip": "^4.2.11",
26 | "styled-components": "^5.2.1",
27 | "styled-flex-component": "^3.0.5",
28 | "web3": "^1.4.0"
29 | },
30 | "scripts": {
31 | "dev": "react-scripts start",
32 | "start": "react-scripts start",
33 | "build": "npm version patch && react-scripts build && ./generate-static.sh && node ./scripts/remove-iframe-deny.js",
34 | "build:farm-info": "npm version patch && PUBLIC_URL=/farm-info react-scripts build && ./generate-farm-info.sh && node ./scripts/remove-iframe-deny.js",
35 | "test": "react-scripts test",
36 | "test:e2e": "SECRET_WORDS=$(grep SECRET_WORDS .env | cut -d '=' -f2) NETWORK_NAME=localhost synpress run",
37 | "hardhat:proxy": "http-server --proxy $(grep RPC_URL .env | cut -d '=' -f2) --port 8545",
38 | "test:integration": "(touch tests/snapshot-id.txt & npm run hardhat:proxy & npm start & npm run test:e2e)",
39 | "eject": "react-scripts eject",
40 | "lint": "eslint ./src",
41 | "check": "prettier --check ./src",
42 | "format": "prettier --write ./src ./test"
43 | },
44 | "eslintConfig": {
45 | "extends": "react-app"
46 | },
47 | "browserslist": {
48 | "production": [
49 | ">0.2%",
50 | "not dead",
51 | "not op_mini all"
52 | ],
53 | "development": [
54 | "last 1 chrome version",
55 | "last 1 firefox version",
56 | "last 1 safari version"
57 | ]
58 | },
59 | "devDependencies": {
60 | "@synthetixio/synpress": "https://github.com/backstop-protocol/synpress.git#4d45c96e1e8ef67a2d8c5016ec4b2d4a80557b74",
61 | "eslint": "^6.6.0",
62 | "eslint-plugin-react": "^7.22.0",
63 | "http-server": "^13.0.0",
64 | "node-sass": "^4.14.1",
65 | "prettier": "^2.2.1",
66 | "sass-loader": "^10.0.1"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
1 | F40D6CE7-4B76-44BF-B583-679B75EAE8C5 Created with sketchtool.
--------------------------------------------------------------------------------
/public/favicon.svg:
--------------------------------------------------------------------------------
1 | F40D6CE7-4B76-44BF-B583-679B75EAE8C5 Created with sketchtool.
--------------------------------------------------------------------------------
/public/fonts/NeueHaasGroteskDisp Pro Md.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.eot
--------------------------------------------------------------------------------
/public/fonts/NeueHaasGroteskDisp Pro Md.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.ttf
--------------------------------------------------------------------------------
/public/fonts/NeueHaasGroteskDisp Pro Md.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.woff
--------------------------------------------------------------------------------
/public/fonts/NeueHaasGroteskDisp Pro Md.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/public/fonts/NeueHaasGroteskDisp Pro Md.woff2
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
24 |
25 |
29 |
30 |
39 | B.Protocol
40 |
41 |
42 | You need to enable JavaScript to run this app.
43 |
44 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "b-icon.svg",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/scripts/remove-iframe-deny.js:
--------------------------------------------------------------------------------
1 | const { execSync } = require("child_process");
2 | const { existsSync, readFileSync, writeFileSync } = require("fs");
3 |
4 | const workerFile = "workers-site/index.js"
5 |
6 | const workerScript = readFileSync(workerFile, { encoding: "ascii" })
7 | .replace(`response.headers.set("X-Frame-Options", "DENY");`, "");
8 |
9 | writeFileSync(workerFile, workerScript);
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, {Suspense} from "react";
2 | import "./style.scss";
3 | import { BrowserRouter as Router, Route, Redirect } from "react-router-dom";
4 | import AppError from "./components/AppError";
5 | import NotificationsContainer from "./components/style-components/NotificationsContainer";
6 | import AppAlert from "./components/AppAlert";
7 | import ModalContainer from "./components/ModalContainer"
8 | import Sidebar from "./components/Sidebar"
9 | import {observer} from "mobx-react"
10 | import routerStore from "./stores/router.store"
11 | import { createBrowserHistory } from "history";
12 | import styled from "styled-components"
13 | import * as qs from "qs";
14 |
15 | const browserHistory = createBrowserHistory();
16 | routerStore.setRouteProps(browserHistory)
17 |
18 |
19 | const Dashboard = React.lazy(() => import("./containers/Dashboard"));
20 | const Compound = React.lazy(() => import("./containers/Compound"));
21 | const Liquity = React.lazy(() => import("./containers/Liquity"));
22 | const LiquityLegacy = React.lazy(() => import("./containers/LiquityLegacy"));
23 | const Risk = React.lazy(() => import("./containers/Risk"));
24 | const TermsOfUse = React.lazy(() => import("./containers/Terms"));
25 | const FAQ = React.lazy(() => import("./containers/FAQ"));
26 | const FarmInfo = React.lazy(() => import("./containers/FarmInfo"));
27 |
28 | function renderPage (props, PageComponent) {
29 | return (
30 | }>
31 |
32 |
33 | )
34 | }
35 |
36 | const App = observer(() => {
37 | const { history } = routerStore.routeProps;
38 | const {search, pathname} = history.location
39 | const params = qs.parse(search, { ignoreQueryPrefix: true })
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | {/* Default route */}
50 |
51 |
52 |
53 | (renderPage(props, Dashboard))} />
54 | (renderPage(props, Dashboard))} />
55 | (renderPage(props, Compound))} />
56 | (renderPage(props, Liquity))} />
57 | (renderPage(props, LiquityLegacy))} />
58 | (renderPage(props, FAQ))} />
59 | (renderPage(props, TermsOfUse))} />
60 | (renderPage(props, Risk))} />
61 | (renderPage(props, FarmInfo))} />
62 |
63 |
64 | );
65 | })
66 |
67 | export default App;
68 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('Has "B.Protocol" in the page text', () => {
6 | const { getByText } = render( );
7 | const linkElement = getByText(/B.Protocol/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/src/assets/aav-ewhite-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/assets/b-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/assets/bp-icon-gold.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/assets/circle-x-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/assets/close.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/assets/coin-icons/AAVE.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/assets/coin-icons/BAT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/BAT.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/COMP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/COMP.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/DAI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/DAI.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/ETH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/ETH.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/LINK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/LINK.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/MKR.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/assets/coin-icons/SUSHI.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/assets/coin-icons/TUSD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/TUSD.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/UNI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/UNI.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/USDC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/USDC.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/USDT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/USDT.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/WBTC legacy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/WBTC legacy.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/WBTC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/WBTC.png
--------------------------------------------------------------------------------
/src/assets/coin-icons/YFI.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/assets/coin-icons/ZRX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/coin-icons/ZRX.png
--------------------------------------------------------------------------------
/src/assets/com-icon-bl.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/assets/compound-full-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/compound-logo-a-1-risk.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/assets/compound-logo-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/assets/compound-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/assets/connect-your-wallet.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/assets/dai.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/assets/discord.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/assets/dollar-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/assets/etherium.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/assets/export-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/assets/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/assets/i-icon-green.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/i-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/images/borrow-repay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/borrow-repay.png
--------------------------------------------------------------------------------
/src/assets/images/compound-import-popup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/compound-import-popup.png
--------------------------------------------------------------------------------
/src/assets/images/deposit-withdraw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/deposit-withdraw.png
--------------------------------------------------------------------------------
/src/assets/images/maker-dau.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/maker-dau.png
--------------------------------------------------------------------------------
/src/assets/images/maker-migration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/maker-migration.png
--------------------------------------------------------------------------------
/src/assets/images/mobile-support.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/src/assets/images/mobile-support.png
--------------------------------------------------------------------------------
/src/assets/images/vote.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/assets/linkedin.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/liquity-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/assets/logo-maker-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/logo-maker-green.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/assets/logo-maker-white-risk.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/logo-maker-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/maker-dao-background.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/assets/medium-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/red-x-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/assets/t-compound-logo-a-1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/assets/t-logo-maker-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/assets/triangle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/assets/tvl-bg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/assets/tvl-graph.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/assets/twitter-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/assets/v-icon-white-thick.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/assets/v-icon-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/assets/v-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/assets/view-icon-opeq-bg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/assets/view-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/assets/x-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/common/constants.js:
--------------------------------------------------------------------------------
1 | export const BP_API = "https://eth-node.b-protocol.workers.dev"
2 | export const KOVAN_BP_API = "https://kovan-node.b-protocol.workers.dev"
--------------------------------------------------------------------------------
/src/components/AppAlert.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {numm} from "../lib/Utils";
3 | import EventBus from "../lib/EventBus";
4 | import styled from "styled-components"
5 | import { setTimeout } from "timers";
6 | import LoadingRing from "./LoadingRing";
7 |
8 | const Alert = styled.div`
9 | display: flex;
10 | color: #bf8517;
11 | background-color: white;
12 | background-image: linear-gradient(rgba(251, 201, 89, 0.3), rgba(251, 201, 89, 0.3));
13 | font-size: 12px;
14 | justify-content: center;
15 | align-items: center;
16 | height: 27px;
17 | `
18 |
19 | const AlertActionBtn = styled.div`
20 | min-width: 80px;
21 | margin-left: 15px;
22 | padding: 0 6px;
23 | color: #bf8517;
24 | text-align: center;
25 | background-color: rgba(0, 0, 0, 0);
26 | border: 1px solid rgb(251, 201, 89);
27 | border-radius: 6px;
28 | :hover {
29 | cursor: pointer;
30 | opacity: 0.8;
31 | }
32 | `
33 |
34 | const Overides = styled.div`
35 | min-width: 80px;
36 | margin-left: 15px;
37 | padding: 0 30px;
38 | transform: scale(0.7);
39 | .lds-ring div {
40 | border-color: #bf8517 transparent transparent transparent;
41 | }
42 | `
43 |
44 | export default class AppAlert extends Component {
45 |
46 | constructor(props) {
47 | super(props);
48 |
49 | this.state = {
50 | alert: false,
51 | alertMessage: "",
52 | actionBtn: null,
53 | actionFn: null,
54 | waiting: null
55 | }
56 | }
57 |
58 | componentDidMount() {
59 | EventBus.$on('app-alert',(msg, actionBtn, actionFn) => {
60 | this.setState({alert: !!msg, alertMessage: msg, actionBtn, actionFn});
61 | });
62 | }
63 |
64 | async callActionFn(fn){
65 |
66 | try{
67 | this.setState({waiting: true})
68 | await Promise.all([fn(), new Promise((resolve, reject)=> {setTimeout(resolve, 3000)})])
69 | } catch (err){
70 | console.error(err)
71 | } finally {
72 | this.setState({waiting: false})
73 | }
74 | }
75 |
76 | render() {
77 |
78 | const {alert, alertMessage, actionBtn, actionFn, waiting} = this.state;
79 |
80 | return (
81 |
82 | {alert &&
83 |
84 | {alertMessage}
85 | {actionBtn &&
86 |
87 | {!waiting &&
this.callActionFn(actionFn)}> {actionBtn} }
88 | {waiting &&
}
89 |
90 | }
91 |
92 | }
93 |
94 | )
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/components/AppError.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {numm} from "../lib/Utils";
3 | import EventBus from "../lib/EventBus";
4 |
5 | export default class AppError extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | error: false,
12 | errorMessage : ""
13 | }
14 | }
15 |
16 | componentDidMount() {
17 | EventBus.$on('app-error',(err) => {
18 | this.setState({error: true, errorMessage: err || "An error has occured"});
19 | console.error(err)
20 | setTimeout(() => {
21 | this.setState({error: false});
22 | }, 3000)
23 | });
24 |
25 | }
26 |
27 | render() {
28 |
29 | const {error} = this.state;
30 |
31 | return (
32 |
33 | {error &&
{this.state.errorMessage}
}
34 |
35 | )
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/components/BorrowLimit.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {numm} from "../lib/Utils";
3 | import Flex, {FlexItem} from "styled-flex-component";
4 | import LiquidationPrice from './LiquidationPrice'
5 | import styled from "styled-components"
6 | import {device} from "../screenSizes";
7 |
8 | const Container = styled.div`
9 | width: 567px;
10 | display: flex;
11 | @media ${device.largeLaptop} {
12 | width: 414px;
13 | }
14 | `
15 |
16 | export default class BorrowLimit extends Component {
17 |
18 | render() {
19 |
20 | const {userInfo} = this.props;
21 | const collateralToBorrowRatio = (userInfo && userInfo.bCdpInfo.maxDaiDebt?numm(userInfo.bCdpInfo.daiDebt / userInfo.bCdpInfo.maxDaiDebt * 100):0)
22 | const ratioPositionStyle = collateralToBorrowRatio > 50 ? {right: '0%'} : {left: '100%'}
23 | return (
24 |
25 |
26 |
27 |
Borrow Limit
28 |
29 |
30 | {collateralToBorrowRatio}%
31 |
32 |
33 |
34 | {userInfo?numm(userInfo.bCdpInfo.daiDebt):0} DAI
35 | {userInfo?numm(userInfo.bCdpInfo.maxDaiDebt):0} DAI
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | )
44 | }
45 | }
--------------------------------------------------------------------------------
/src/components/ConnectButton.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 | import React, { Component } from "react";
5 | import EventBus from '../lib/EventBus';
6 | import {Link} from "react-router-dom";
7 | import {observer} from "mobx-react"
8 | import userStore from "../stores/user.store"
9 |
10 | function increaseABit(number) {
11 | return parseInt(1.1 * Number(number));
12 | }
13 |
14 | class ConnectButton extends Component {
15 | constructor(props) {
16 | super(props);
17 | }
18 |
19 | render() {
20 | const { loggedIn, user, connecting } = userStore
21 | if(connecting) {
22 | return null
23 | }
24 | return (
25 |
26 | { loggedIn ? (
27 |
28 |
29 | {user}
30 |
31 |
32 | ) : (
33 |
34 |
35 |
36 | By using bprotocol, you agree to the{" "}
37 |
46 | Terms and Conditions
47 |
48 |
49 |
50 |
51 |
55 | Connect
56 |
57 |
58 | )}
59 |
60 | );
61 | }
62 | }
63 |
64 | export default observer(ConnectButton)
65 |
--------------------------------------------------------------------------------
/src/components/CurrencyBoxHeader.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {observer} from "mobx-react"
3 | import styled from "styled-components"
4 | import Flex, {FlexItem} from "styled-flex-component";
5 | import {device} from "../screenSizes";
6 |
7 | const Container = styled.div`
8 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif;
9 | height: 40px;
10 | width: 100%;
11 | opacity: 0.28;
12 | font-size: 12px;
13 | letter-spacing: 0.6px;
14 | color: #0b0412;
15 | line-height: 1.5;
16 | padding: 0 20px;
17 | border-bottom: 1px solid rgba(151, 151, 151, 0.25);
18 | width: 100%;
19 | .asset{
20 | width: calc(46px + 20px + 85px + 20px);
21 | }
22 | .fee{
23 | width: 70px;
24 | margin-right: 20px;
25 | }
26 |
27 | @media ${device.largeLaptop} {
28 | font-size: 11px;
29 | .asset{
30 | width: calc(46px + 20px + 77px + 20px);
31 | }
32 | }
33 | @media ${device.laptop} {
34 | font-size: 11px;
35 | .asset{
36 | width: calc(40px + 7.5px + 73px + 7.5px);
37 | }
38 | .fee{
39 | margin-right: 7.5px;
40 | }
41 | }
42 | @media ${device.mobile} {
43 | .asset{
44 | width: calc(40px + 7.5px + 30px + 7.5px);
45 | }
46 | }
47 | `
48 |
49 | class CurrencyBoxHeader extends Component {
50 |
51 | render () {
52 | const {showStabilityFee} = this.props
53 | return (
54 |
55 |
56 |
57 | Asset
58 |
59 |
60 | {showStabilityFee && Stability fee }
61 |
62 |
63 | Balance
64 |
65 |
66 |
67 | )
68 | }
69 | }
70 |
71 | export default observer(CurrencyBoxHeader)
--------------------------------------------------------------------------------
/src/components/DaiBox.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {numm} from "../lib/Utils";
3 | import Dai from "../assets/dai.svg";
4 | import CurrencyBox from "./CurrencyBox";
5 | import Repay from "./action-panels/Repay";
6 | import Borrow from "./action-panels/Borrow";
7 | import {observer} from "mobx-react"
8 | import userStore from "../stores/user.store"
9 |
10 | class DaiBox extends Component {
11 |
12 | formatValue(userInfo) { return userInfo?numm(userInfo.bCdpInfo.daiDebt, 2):0; }
13 | calculateUSD(userInfo) { return userInfo?numm(userInfo.bCdpInfo.daiDebt, 2):0; }
14 | borrowLimit(userInfo, value, value2) { return userInfo?numm((userInfo.bCdpInfo.daiDebt+value2) / userInfo.bCdpInfo.maxDaiDebt*100, 2, 100) : 0 }
15 |
16 | render() {
17 | const {userInfo, onPanelAction, stabilityFee} = this.props;
18 | const {showConnect} = userStore
19 |
20 | return (
21 |
24 | )
25 | }
26 | }
27 |
28 | export default observer(DaiBox)
29 |
--------------------------------------------------------------------------------
/src/components/EtheriumBox.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {numm, symbolToDisplayDecimalPointMap as symbol2decimal} from "../lib/Utils";
3 | import CurrencyBox from "./CurrencyBox";
4 | import Etherium from "../assets/etherium.svg";
5 | import Deposit from "./action-panels/Deposit";
6 | import Withdraw from "./action-panels/Withdraw";
7 | import {observer} from "mobx-react"
8 | import userStore from "../stores/user.store"
9 | import Web3 from "web3"
10 | const {fromWei, toWei} = Web3.utils
11 |
12 | class EtheriumBox extends Component {
13 |
14 | formatValue = (userInfo) => {
15 | if(!userInfo){
16 | return 0
17 | }
18 | return numm(userInfo.collaeralDeposited, symbol2decimal[this.props.symbol]);
19 | }
20 |
21 | calculateUSD = (userInfo) => {
22 | if(!userInfo){
23 | return 0
24 | }
25 | return numm(userInfo.collaeralDeposited * userInfo.miscInfo.spotPrice, symbol2decimal['USD'])
26 | }
27 |
28 | borrowLimit (userInfo, value) {
29 | return userInfo?numm(userInfo.bCdpInfo.daiDebt / value * 100, 2, 100) : 0
30 | }
31 |
32 | render() {
33 |
34 | const {userInfo, onPanelAction, onOpenPanel, symbol} = this.props;
35 | const {showConnect} = userStore
36 |
37 | return (
38 |
41 | )
42 | }
43 | }
44 |
45 | export default observer(EtheriumBox)
--------------------------------------------------------------------------------
/src/components/FragLoader.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function FragLoader() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/GlobalStatsEmpty.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import DollarIcon from "../assets/bp-icon-gold.svg";
3 | import Pulser from "./Pulser";
4 | import {Observer} from "mobx-react"
5 |
6 |
7 | export default class GlobalStats extends Component {
8 |
9 | constructor(props) {
10 | super(props);
11 | }
12 |
13 | render() {
14 | return (
15 |
16 | {() =>
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | }
28 |
29 | )
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {numm} from "../lib/Utils";
3 | import ConnectButton from "./ConnectButton";
4 | import GlobalStatsEmpty from "./GlobalStatsEmpty";
5 | import BorrowLimit from "./BorrowLimit";
6 | import Tvl from "./Tvl";
7 | import ConnectWallet from "../assets/connect-your-wallet.svg";
8 | import userStore from "../stores/user.store"
9 | import {observer} from "mobx-react"
10 | import mainStore from "../stores/main.store"
11 | import mainCompStore from "../stores/main.comp.store"
12 | import Tabs from "./style-components/Tabs"
13 | import makerStoreManager, {makerStoreNames} from "../stores/maker.store"
14 | import {ResponsiveWidthHeader, HeaderItemContainer} from "./style-components/ResponsiveContainer"
15 |
16 | class Header extends Component {
17 | render() {
18 | const {info, onConnect, logo} = this.props;
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
26 | {(userStore.displayConnect || false)&&
27 |
28 |
Connect your wallet
29 |
30 |
}
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | {info &&
39 |
40 | }
41 | {!info &&
42 |
43 | }
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | )
52 | }
53 | }
54 |
55 | export default observer(Header)
56 |
--------------------------------------------------------------------------------
/src/components/Header2.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {numm} from "../lib/Utils";
3 | import ConnectButton from "./ConnectButton";
4 | import GlobalStatsEmpty from "./GlobalStatsEmpty";
5 | import BorrowLimit from "./BorrowLimit";
6 | import Tvl from "./Tvl";
7 | import ConnectWallet from "../assets/connect-your-wallet.svg";
8 | import userStore from "../stores/user.store"
9 | import {observer} from "mobx-react"
10 | import HeaderBorrowLimit from "../components/compound-components/HeaderBorrowLimit"
11 | import {ResponsiveWidthHeader, HeaderItemContainer} from "./style-components/ResponsiveContainer"
12 | import mainStore from "../stores/main.store"
13 | import mainCompStore from "../stores/main.comp.store"
14 | import {Transition} from 'react-spring/renderprops'
15 |
16 | class Header2 extends Component {
17 | render() {
18 |
19 | const {info, onConnect, logo, fullPage, textLogo} = this.props;
20 | const {loggedIn} = userStore
21 | return (
22 |
23 |
24 |
25 | {logo &&
}
26 | {textLogo &&
{textLogo} }
27 |
28 |
29 | {(userStore.displayConnect || false)&&
30 |
31 |
Connect your wallet
32 |
33 |
}
34 |
35 |
36 |
37 |
38 |
39 |
40 | {!fullPage &&
41 |
47 | {toggle =>
48 | toggle
49 | ? props =>
50 | : props =>
51 | }
52 |
53 | }
54 |
55 |
56 |
57 | )
58 | }
59 | }
60 |
61 | export default observer(Header2)
62 |
--------------------------------------------------------------------------------
/src/components/InstaInfo.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import styled from "styled-components"
3 | import { TableContainer, ContentBox, Cell, ANS, Button, Title} from "../containers/FarmInfo"
4 | import Flex, {FlexItem} from "styled-flex-component"
5 |
6 | export default class InstaInfo extends Component {
7 |
8 | render() {
9 | const {bproStore, account} = this.props
10 | return (
11 |
12 |
13 | Instadapp account
14 |
15 |
16 | {account}
17 |
18 |
19 |
20 | |
21 | uBPRO-BIP4 |
22 | BPRO {"(If TVL < $150m)"} |
23 | BPRO {"(If TVL > $150m)"} |
24 |
25 | {/*
26 | User Reward |
27 | /month |
28 | /month |
29 | /month |
30 | */}
31 |
32 | Accumulated |
33 | |
34 | |
35 | |
36 |
37 |
38 |
39 | Claimable
40 | |
41 | |
42 | |
43 | |
44 |
45 |
46 | Wallet Balance |
47 | |
48 | |
49 | |
50 |
51 |
52 | this.props.openClaimModal(bproStore)}>
53 |
54 | CLAIM uBPRO-BIP4
55 |
56 |
57 |
58 |
59 |
60 | )
61 | }
62 | }
--------------------------------------------------------------------------------
/src/components/LoadingRing.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function LoadingRing() {
4 | return (
5 |
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/src/components/ModalContainer.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import XIcon from "../assets/x-icon.svg";
3 | import EventBus from "../lib/EventBus";
4 |
5 | export default class ModalContainer extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | component : null,
12 | noWrapper : null,
13 | show: false
14 | }
15 | }
16 |
17 | componentDidMount() {
18 | EventBus.$on('show-modal', this.showModalBox.bind(this));
19 | EventBus.$on('close-modal', this.closeModalBox.bind(this));
20 | }
21 |
22 | showModalBox(component, noWrapper) {
23 | document.body.style.overflow = "hidden"; // ADD THIS LINE
24 | this.setState({component, noWrapper, show: true});
25 | }
26 |
27 | closeModalBox = () => {
28 | this.setState({component:
, show: false});
29 | document.body.style.overflow = "auto"; // ADD THIS LINE
30 | };
31 |
32 | render() {
33 | const {component, noWrapper, show} = this.state;
34 | const cls = show ? 'modal-container active' : 'modal-container';
35 |
36 | return (
37 | noWrapper ? EventBus.$emit('close-modal') : ""}>
38 | {this.state.component && !noWrapper &&
39 |
40 |
EventBus.$emit('close-modal')}>
41 |
42 |
43 | {component}
44 |
45 | }
46 | {this.state.component && noWrapper &&
47 |
e.stopPropagation()}>
48 | {component}
49 |
50 | }
51 |
52 | )
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/Ticker.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {observer} from "mobx-react"
3 |
4 | class Ticker extends Component {
5 |
6 | constructor(props) {
7 | super(props);
8 |
9 | this.state = {
10 | value : props.value,
11 | changes : [],
12 | }
13 | }
14 |
15 | componentDidUpdate(prevProps, prevState) {
16 | if (this.props.value && !this.state.value || this.state.value !== this.props.value) {
17 | let changes = [];
18 | if (prevState.value) {
19 | const old = prevState.value.toString(), notold = this.props.value.toString();
20 | for (let c = 0; c < old.length; c++) {
21 | if (notold[c] !== old[c]) changes.push(c);
22 | }
23 | }
24 | if (this.props.value !== '0' && this.props.value !== '')
25 | this.setState({value : this.props.value, changes});
26 | setTimeout(() => this.setState({changes: []}), 300);
27 | }
28 |
29 | }
30 |
31 | render() {
32 | let {value, changes} = this.state;
33 | let {primary, small} = this.props;
34 | primary = primary ? primary : 6666;
35 |
36 | value = value ? value.toString().split('') : ['0'];
37 |
38 | return (
39 |
40 | {value.map((n, index) => (
41 | 7 ? "s-one" : " one") : "") +
48 | (value.length > 7
49 | ? index < primary
50 | ? " s-primary"
51 | : n === "1"
52 | ? "s-one small fade-small-one"
53 | : "small"
54 | : index < primary
55 | ? " primary"
56 | : "") +
57 | (changes.indexOf(index) > -1 ? " in" : "")
58 | }
59 | >
60 | {n}
61 |
62 | ))}
63 |
64 | );
65 | }
66 | }
67 |
68 | export default observer(Ticker)
--------------------------------------------------------------------------------
/src/components/Tooltip.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function Tooltip(props) {
4 |
5 |
6 | let tooltipCls = 'tooltip';
7 | if (props.bottom) tooltipCls += ' bottom';
8 | if (props.className) tooltipCls += ' '+props.className;
9 |
10 | return (
11 |
12 |
13 | {props.children}
14 |
15 | )
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/action-panels/Borrow.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {validateBorrow} from "../../lib/Actions";
3 | import Tooltip from "../Tooltip";
4 |
5 | export default class Borrow extends Component {
6 |
7 | name = "Borrow";
8 | action = "borrow";
9 | actioning = "Borrowing";
10 |
11 | constructor(props) {
12 | super(props);
13 |
14 | this.state = {
15 | val : '',
16 | invalid : false,
17 | error: '',
18 | }
19 | }
20 |
21 | validate = async (val) => {
22 | const ok = await validateBorrow(val);
23 |
24 | let error = '';
25 | if (!ok[0]) error = ok[1];
26 |
27 | this.setState({invalid: !ok[0], error});
28 | return ok;
29 | };
30 |
31 | doAction = () => {
32 | const {val} = this.state;
33 | if (!val*1) return false;
34 |
35 | this.props.onPanelAction(this.action, val, this.actioning)
36 | };
37 |
38 | onChange = (e) => {
39 | const val = e.target.value;
40 | const res = this.props.onPanelInput(val);
41 | if (res !== false) {
42 | this.setState({val: res});
43 | this.validate(res);
44 | }
45 | };
46 |
47 | render() {
48 |
49 | const {invalid, error, val} = this.state;
50 |
51 | return (
52 |
53 |
Borrow
54 |
How much DAI would you like to Borrow?
55 |
56 |
57 |
58 | {error && {error} }
59 |
60 |
{this.name}
61 |
62 |
63 |
Unlock DAI to continue
64 |
65 |
66 | )
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/components/action-panels/Deposit.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {validateDeposit, validateRepay} from "../../lib/Actions";
3 | import Tooltip from "../Tooltip";
4 |
5 | export default class Deposit extends Component {
6 |
7 | name = "Deposit";
8 | action = "deposit";
9 | actioning = "Depositing";
10 |
11 | constructor(props) {
12 | super(props);
13 |
14 | this.state = {
15 | invalid : false,
16 | val : '',
17 | error : '',
18 | }
19 | }
20 |
21 | componentDidMount() {
22 | }
23 |
24 | validate = async (val) => {
25 | const ok = await validateDeposit(val);
26 |
27 | let error = '';
28 | if (!ok[0]) error = ok[1];
29 |
30 | this.setState({invalid: !ok[0], error});
31 | return ok;
32 | };
33 |
34 | doAction = () => {
35 | const {invalid, val} = this.state;
36 | if (invalid || !val*1) return false;
37 |
38 | this.props.onPanelAction(this.action, this.input.value, this.actioning)
39 | };
40 |
41 | onChange = (e) => {
42 | const val = e.target.value;
43 | const res = this.props.onPanelInput(val);
44 | if (res !== false) {
45 | this.setState({val: res});
46 | this.validate(res);
47 | }
48 | };
49 |
50 | render() {
51 |
52 | const {invalid, val, error} = this.state;
53 | const {currency} = this.props
54 | return (
55 |
56 |
Deposit
57 |
How much {currency} would you like to deposit?
58 |
59 |
60 | this.input = e} />
61 | {error && {error} }
62 |
63 |
{this.name}
64 |
65 |
66 |
Unlock DAI to continue
67 |
68 |
69 | )
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/components/action-panels/Loading.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import WhiteBgViewIcon from "../../assets/view-icon.svg";
3 | import BlacBgViewIcon from "../../assets/view-icon-opeq-bg.svg";
4 | import BIcon from "../../assets/b-icon.svg";
5 | import VIcon from "../../assets/v-icon.svg";
6 | import XIcon from "../../assets/red-x-icon.svg";
7 | import FragLoader from "../FragLoader";
8 | import {isKovan} from "../../lib/Utils"
9 |
10 | const blackBgStyle = {
11 | color: '#647686',
12 | fill: '#647686',
13 | 'flex-direction': 'column',
14 | 'justify-content': 'space-between',
15 | height: '91px',
16 | padding: 0,
17 | }
18 |
19 | export default class Loading extends Component {
20 |
21 | render() {
22 | const kovan = isKovan()
23 | const { actioning, value, currency, completed, failed, hash, blackBg } = this.props;
24 |
25 | const icon = completed ? VIcon : (failed ? XIcon : BIcon);
26 | const resultText = completed ? 'Completed' : (failed ? 'Failed' : '');
27 | const ViewIcon = blackBg ? BlacBgViewIcon : WhiteBgViewIcon
28 | const extraStyle = blackBg ? blackBgStyle : {}
29 |
30 | return (
31 |
32 |
33 | {completed || failed && }
34 | {(!completed && !failed) && }
35 |
36 | {actioning} {value} {currency} {resultText}
37 | {(!failed && hash) &&
}
43 |
44 | )
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/action-panels/Withdraw.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {validateDeposit, validateWithdraw} from "../../lib/Actions";
3 | import Tooltip from "../Tooltip";
4 |
5 | export default class Withdraw extends Component {
6 |
7 | name = "Withdraw";
8 | action = "withdraw";
9 | actioning = "Withdrawing";
10 |
11 | constructor(props) {
12 | super(props);
13 |
14 | this.state = {
15 | val : '',
16 | invalid : false,
17 | error: '',
18 | }
19 | }
20 |
21 | validate = async (val) => {
22 | const ok = await validateWithdraw(val);
23 |
24 | let error = '';
25 | if (!ok[0]) error = ok[1];
26 |
27 | this.setState({invalid: !ok[0], error});
28 | return ok;
29 | };
30 |
31 |
32 | doAction = () => {
33 | const {invalid, val} = this.state;
34 | if (invalid || !val*1) return false;
35 |
36 | this.props.onPanelAction(this.action, this.input.value, this.actioning)
37 | };
38 |
39 | onChange = (e) => {
40 | const val = e.target.value;
41 | const res = this.props.onPanelInput(val);
42 | if (res !== false) {
43 | this.setState({val: res});
44 | this.validate(res);
45 | }
46 | };
47 |
48 | setMax = () => {
49 | const {userInfo, currency} = this.props
50 | const val = (Math.floor(userInfo.collaeralDeposited * 1000000)/1000000).toString();
51 | const res = this.props.onPanelInput(val);
52 | if (res !== false) {
53 | this.setState({val: res});
54 | this.validate(res);
55 | }
56 | };
57 |
58 | render() {
59 |
60 | const {invalid, val, error} = this.state;
61 | const noDaiDebt = this.props.userInfo.bCdpInfo.daiDebt === 0
62 | const {currency} = this.props
63 | return (
64 |
65 |
Withdraw
66 |
How much {currency} would you like to withdraw?
67 |
68 |
69 | {noDaiDebt &&
Set Max
}
70 |
this.input = e} />
71 | {error &&
{error} }
72 |
73 |
{this.name}
74 |
75 |
76 | )
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/components/compound-components/BalanceListBox.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {observer} from "mobx-react"
3 | import styled from "styled-components"
4 | import CoinListHeader from "./CoinListHeader"
5 | import CoinList from "./CoinList"
6 | import compoundStore from "../../stores/compound.store"
7 | import ResponsiveWidthCol from "../style-components/ResponsiveContainer"
8 | import {device} from "../../screenSizes";
9 |
10 | const Container = styled.div`
11 | padding-top: 50px;
12 | @media ${device.largeLaptop} {
13 | padding-top: 42.5px;
14 | }
15 | @media ${device.laptop} {
16 | padding-top: 35px;
17 | }
18 | `
19 |
20 | class BalanceListBox extends Component {
21 |
22 | render () {
23 | const {list, type} = this.props
24 | return (
25 |
26 |
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | export default observer(BalanceListBox)
--------------------------------------------------------------------------------
/src/components/compound-components/CoinList.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {observer} from "mobx-react"
3 | import styled from "styled-components"
4 | import CoinListItem from "./CoinListItem"
5 | import Flex, {FlexItem} from "styled-flex-component";
6 | import {Transition, animated} from 'react-spring/renderprops'
7 | import compoundStore from "../../stores/compound.store";
8 | import userStore from "../../stores/user.store"
9 |
10 | class CoinList extends Component {
11 |
12 | render () {
13 | const {list: items, isInBalanceBox, type, coinStatusToShow} = this.props
14 |
15 | return (
16 | item.symbol}
22 | from={{ opacity: 0, height: 0, zIndex: 0}}
23 | enter={{ opacity: 1 , height: "auto", zIndex: 1}}
24 | leave={{ opacity: 0, height: 0, zIndex: -1}}>
25 | {(item, state, i) => (props =>
26 |
27 |
32 | )
33 | }
34 |
35 | )
36 | }
37 | }
38 |
39 | export default observer(CoinList)
--------------------------------------------------------------------------------
/src/components/compound-components/CoinListBox.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {observer} from "mobx-react"
3 | import styled from "styled-components"
4 | import CoinListHeader from "./CoinListHeader"
5 | import CoinList from "./CoinList"
6 | import compoundStore from "../../stores/compound.store"
7 | import ResponsiveWidthCol from "../style-components/ResponsiveContainer"
8 | import { Transition } from "react-spring/renderprops";
9 |
10 | const Container = styled(ResponsiveWidthCol)`
11 | border-radius: 12px;
12 | box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.22);
13 | border-style: solid;
14 | border-width: 0.5px;
15 | border-image-source: linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.4) 5%, rgba(255, 255, 255, 0) 20%, rgba(255, 255, 255, 0));
16 | `
17 |
18 | class CoinListBox extends Component {
19 |
20 | render () {
21 | const {list, type} = this.props
22 | const show = list.length > 0
23 | return (
24 |
30 | {show => show && (props =>
31 |
32 |
33 |
34 |
35 | )}
36 |
37 | )
38 | }
39 | }
40 |
41 | export default observer(CoinListBox)
--------------------------------------------------------------------------------
/src/components/compound-components/CoinListHeader.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {observer} from "mobx-react"
3 | import styled from "styled-components"
4 | import Flex, {FlexItem} from "styled-flex-component";
5 | import {device} from "../../screenSizes";
6 |
7 | export const ClHeader = styled.div`
8 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif;
9 | padding-left: 40px;
10 | height: 45px;
11 | width: 100%;
12 | opacity: 0.28;
13 | font-size: 12px;
14 | letter-spacing: 0.6px;
15 | color: #0b0412;
16 | line-height: 1.5;
17 | @media ${device.largeLaptop} {
18 | font-size: 11px;
19 | }
20 | @media ${device.laptop} {
21 | font-size: 11px;
22 | }
23 | `
24 |
25 | class CoinListHeader extends Component {
26 |
27 | render () {
28 | return (
29 |
30 |
31 |
32 | Asset
33 |
34 |
35 | APY
36 |
37 |
38 | Balance
39 |
40 |
41 |
42 | )
43 | }
44 | }
45 |
46 | export default observer(CoinListHeader)
--------------------------------------------------------------------------------
/src/components/compound-components/ProgressBar.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import styled from "styled-components"
3 |
4 | const Bar = styled.div`
5 | border-radius: 4px;
6 | width: 100%;
7 | height: 4px;
8 | background-color: rgba(11, 4, 18, 0.15);
9 | `
10 |
11 | const Marker = styled.div`
12 | transition: all 0.3s ease-in-out;
13 | border-radius: 4px 0 0 4px;
14 | width: ${({precent})=> precent}%;
15 | height 100%;
16 | background: black;
17 | `
18 |
19 | export default (props)=> {
20 | return (
21 |
22 |
23 |
24 | )
25 | }
--------------------------------------------------------------------------------
/src/components/compound-components/TxInProgress.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 | import React, {Component} from "react";
5 | import {observer} from "mobx-react"
6 | import styled from "styled-components"
7 | import Flex, {FlexItem} from "styled-flex-component";
8 |
9 | class TxInProgress extends Component {
10 | render () {
11 | return (
12 | TxInProgress
13 | )
14 | }
15 | }
16 |
17 | export default observer(TxInProgress)
--------------------------------------------------------------------------------
/src/components/compound-components/Unlock.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 | import React, {Component} from "react";
5 | import {observer} from "mobx-react"
6 | import styled from "styled-components"
7 | import Flex, {FlexItem} from "styled-flex-component";
8 | import ActionBoxFooter from "./ActionBoxFooter"
9 | import LoadingRing from "../LoadingRing";
10 | import { depositEth } from "../../lib/compound.interface";
11 | import {device} from "../../screenSizes";
12 | import {ActionEnum} from "../../lib/compound.util"
13 |
14 | const Text = styled.div`
15 | font-family: "Poppins", sans-serif;
16 | font-size: 14px;
17 | font-weight: normal;
18 | font-stretch: normal;
19 | font-style: normal;
20 | line-height: normal;
21 | letter-spacing: normal;
22 | color: #0b0412;
23 | @media ${device.largeLaptop} {
24 | font-size: 13px;
25 | }
26 | @media ${device.laptop} {
27 | font-size: 13px;
28 | }
29 | `
30 | const Container = styled.div`
31 | visibility: ${({hide})=> hide ? "hidden" : "visible"};
32 | .tickbox{
33 | margin: 3px 2px 0 0;
34 | }
35 | pointer-events: ${({disable})=> disable ? "none" : "auto"};
36 | `
37 |
38 | class Unlock extends Component{
39 |
40 | constructor(props) {
41 | super(props);
42 |
43 | this.state = {
44 | unlocked: false,
45 | unlocking: false,
46 | }
47 | }
48 |
49 | onUnlock = async () => {
50 | try{
51 | if(this.state.unlocked){
52 | return
53 | }
54 | const {coin} = this.props
55 | this.setState({unlocking: true});
56 | await coin.unlock()
57 | this.setState({
58 | unlocked: true,
59 | unlocking: false,
60 | })
61 | } catch (err){
62 | this.setState({
63 | unlocked: false,
64 | unlocking: false,
65 | })
66 | }
67 | }
68 |
69 | render () {
70 |
71 | let {unlocking} = this.state
72 | const {coin, action} = this.props
73 | const unlocked = coin.isUnlocked() || this.state.unlocked // this is used to acount for UI delay
74 | const text = !unlocked ? `Unlock ${coin.symbol} to continue` : `${coin.symbol} is unlocked`
75 | return (
76 |
77 |
78 |
79 | {text}
80 |
81 |
82 | {unlocking && }
83 |
84 |
85 |
86 | )
87 | }
88 | }
89 |
90 | export default observer(Unlock)
--------------------------------------------------------------------------------
/src/components/modals/MigrationModal.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import MigrationDrawing from "../../assets/images/maker-migration.png";
3 | import EventBus from "../../lib/EventBus";
4 | import { migrateMakerDao } from "../../lib/Actions";
5 | import makerStoreManager, {makerStores} from "../../stores/maker.store"
6 |
7 | export default class MigrationModal extends Component {
8 | onMigrate = async () => {
9 | const makerCollType = makerStoreManager.currentStore
10 | EventBus.$emit(`migration-started-${makerCollType}`);
11 | EventBus.$emit("close-modal");
12 | try {
13 | await migrateMakerDao();
14 | EventBus.$emit(`migration-completed-${makerCollType}`);
15 | setTimeout(() => {
16 | makerStores[makerCollType].getUserInfo()
17 | }, 3000)
18 | }
19 | catch (e) {
20 | EventBus.$emit(`migration-failed-${makerCollType}`);
21 | }
22 | };
23 |
24 | render() {
25 |
26 | return (
27 |
28 |
Import your Vault
29 |
By importing your MakerDAO Vault you give priority to B.Protocol in the liquidation process
30 |
The Vault remains under your full control, and will start accumulate a user score
31 |
Read the risks of using B.Protocol
32 |
B.Protocol does not protect you from liquidations
33 |
34 |
35 |
36 |
37 | Import
38 |
39 |
40 | )
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/components/style-components/AnimateNumberChange.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {Spring, animated, interpolate} from 'react-spring/renderprops'
3 | import {toCommmSepratedString} from "../../lib/Utils"
4 |
5 | export default class AnimateNumberChange extends Component{
6 |
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | from : props.val,
12 | to : props.val,
13 | }
14 | }
15 |
16 | componentDidUpdate(prevProps) {
17 | if (this.props.val !== prevProps.val) {
18 | this.setState({from: prevProps.val, to: this.props.val})
19 | }
20 | }
21 |
22 | render () {
23 | const decimals = this.props.decimals || 2
24 | const duration = this.props.duration || 300
25 | const commas = this.props.commas || true
26 |
27 | return (
28 |
33 | {({number}) => {number.interpolate(x=> toCommmSepratedString(parseFloat(x).toFixed(decimals)))} }
34 |
35 | )
36 | }
37 | }
--------------------------------------------------------------------------------
/src/components/style-components/AnimateNumericalString.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {Spring, animated, interpolate} from 'react-spring/renderprops'
3 | import {toCommmSepratedString} from "../../lib/Utils"
4 |
5 | export default class AnimateNumericalString extends Component{
6 |
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | from : props.val,
12 | to : props.val,
13 | }
14 | }
15 |
16 | componentDidUpdate(prevProps) {
17 | if (this.props.val !== prevProps.val) {
18 | this.setState({from: prevProps.val, to: this.props.val})
19 | }
20 | }
21 |
22 | render () {
23 | const decimals = this.props.decimals || 2
24 | const duration = this.props.duration || 300
25 |
26 | return (
27 |
32 | {({number}) => {number.interpolate(x=> parseFloat(x).toFixed(decimals))} }
33 |
34 | )
35 | }
36 | }
--------------------------------------------------------------------------------
/src/components/style-components/BpLoader.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export default function BpLoader(props) {
4 | const styles = {
5 | border: "none",
6 | padding: 0,
7 | flex: 0,
8 | }
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | )
19 | }
20 |
--------------------------------------------------------------------------------
/src/components/style-components/Buttons.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import styled from "styled-components"
3 | import {device} from "../../screenSizes";
4 |
5 | const SmallButtonContainer = styled.div`
6 | cursor: pointer;
7 | padding: 0 15px;
8 | height: 18px;
9 | border-radius: 5px;
10 | display: flex;
11 | align-items: center;
12 | justify-content: center;
13 | background-color: rgba(214, 242, 227, 0.4);
14 | height: 26px;
15 | span{
16 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif;
17 | font-size: 14px;
18 | font-weight: normal;
19 | font-stretch: normal;
20 | font-style: normal;
21 | line-height: normal;
22 | letter-spacing: 0.6px;
23 | color: white;
24 | }
25 | @media ${device.largeLaptop} {
26 | height: 20px;
27 | span{
28 | font-size: 13px;
29 | }
30 | }
31 | @media ${device.laptop} {
32 | height: 18px;
33 | span{
34 | font-size: 12px;
35 | }
36 | }
37 | `
38 |
39 | export const SmallButton = (props) => {
40 | return(
41 |
42 |
43 | {props.children}
44 |
45 |
46 | )
47 | }
48 |
49 | export const ModalButton = styled.div`
50 | transition: all 0.3s ease-in-out;
51 | min-width: 218px;
52 | padding: 0 10px;
53 | height: 48px;
54 | border-radius: 4px;
55 | background-color: #12c164;
56 | display: flex;
57 | justify-content:center;
58 | align-items: center;
59 | cursor: pointer;
60 | span {
61 | transition: all 0.3s ease-in-out;
62 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif;
63 | font-size: 14px;
64 | font-weight: normal;
65 | font-stretch: normal;
66 | font-style: normal;
67 | line-height: normal;
68 | letter-spacing: 0.7px;
69 | color: white;
70 | padding: 10px;
71 | text-transform: uppercase;
72 | }
73 | &.disabled{
74 | background-color: #cccccc;
75 | pointer-events: none;
76 | }
77 | &.done{
78 | background-color: white;
79 | border: 2px solid #12c164;
80 | pointer-events: none;
81 | span{
82 | color: #12c164!important;
83 | }
84 | }
85 | `
--------------------------------------------------------------------------------
/src/components/style-components/GreyLine.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components"
2 |
3 | const GreyLine = styled.div`
4 | width: 100%;
5 | height: 1px;
6 | opacity: 0.25;
7 | background: rgb(151, 151, 151);
8 | `
9 |
10 | export default GreyLine
--------------------------------------------------------------------------------
/src/components/style-components/HeaderProgressBar.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import styled from "styled-components"
3 |
4 | const Bar = styled.div`
5 | border-radius: 4px;
6 | width: 100%;
7 | height: 8px;
8 | background-color: rgba(66, 110, 85, 0.12);
9 | `
10 |
11 | const Marker = styled.div`
12 | transition: all 0.3s ease-in-out;
13 | border-radius: 4px;
14 | width: ${({precent})=> precent}%;
15 | height 100%;
16 | background: linear-gradient(to right, rgba(37, 30, 43, 0.38) -4%, #100d13);
17 | `
18 |
19 | export default (props)=> {
20 | return (
21 |
22 |
23 |
24 | )
25 | }
--------------------------------------------------------------------------------
/src/components/style-components/NotificationsContainer.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components"
2 |
3 | const NotificationsContainer = styled.div`
4 | position: fixed;
5 | top: 0;
6 | left: 0;
7 | z-index: 1800;
8 | width: 100%;
9 | `
10 |
11 | export default NotificationsContainer
--------------------------------------------------------------------------------
/src/components/style-components/ProgressBar.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import styled from "styled-components"
3 |
4 | const Bar = styled.div`
5 | border-radius: 4px;
6 | width: 100%;
7 | height: 4px;
8 | background-color: rgba(11, 4, 18, 0.15);
9 | `
10 |
11 | const Marker = styled.div`
12 | transition: all 0.3s ease-in-out;
13 | border-radius: 4px 0 0 4px;
14 | width: ${({precent})=> precent}%;
15 | height 100%;
16 | background: black;
17 | `
18 |
19 | export default (props)=> {
20 | return (
21 |
22 |
23 |
24 | )
25 | }
--------------------------------------------------------------------------------
/src/components/style-components/ResponsiveContainer.js:
--------------------------------------------------------------------------------
1 | import styled from "styled-components"
2 | import {device} from "../../screenSizes";
3 |
4 | const ResponsiveWidthCol = styled.div`
5 | width: 610px;
6 | margin: 20px;
7 | @media ${device.largeLaptop} {
8 | width: 550px;
9 | margin: 10px;
10 | }
11 | @media ${device.laptop} {
12 | width: 450px;
13 | }
14 | @media ${device.tablet} {
15 | max-width: 610px;
16 | width: calc(100vw - 20px)
17 | }
18 | `
19 |
20 | export const ResponsiveWidthHeader = styled.div`
21 | max-width: ${610 * 2 + 40}px;
22 | @media ${device.largeLaptop} {
23 | max-width: ${560 * 2 + 40}px;
24 | }
25 | @media ${device.laptop} {
26 | max-width: ${498 * 2 + 40}px;
27 | padding: 0 5px;
28 | }
29 | @media ${device.tablet} {
30 | padding: 0 15px;
31 | }
32 | `
33 |
34 | export const HeaderItemContainer = styled.div`
35 | width: 50%;
36 | padding: 0 20px;
37 | display: flex;
38 | justify-content: center;
39 | align-items: center;
40 | min-width: 570px;
41 | min-height: 322px;
42 | @media ${device.largeLaptop} {
43 | padding: 0 10px;
44 | min-width: 430px;
45 | min-height: 257px;
46 | }
47 | @media ${device.laptop} {
48 | padding: 0 10px;
49 | min-width: 400px;
50 | min-height: 200px;
51 | }
52 | @media ${device.tablet} {
53 | padding: 0 10px;
54 | min-width: 390px;
55 | min-height: 200px;
56 | }
57 | @media ${device.mobile} {
58 | padding: 0 10px;
59 | min-width: 360px;
60 | min-height: 200px;
61 | }
62 |
63 | `
64 |
65 | export default ResponsiveWidthCol
--------------------------------------------------------------------------------
/src/components/style-components/Tabs.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import styled from "styled-components"
3 | import Flex, {FlexItem} from "styled-flex-component";
4 | import {device} from "../../screenSizes"
5 | const Container = styled.div`
6 | position: relative;
7 | bottom: -6px;
8 |
9 | .shadow-cut{
10 | position: relative;
11 | z-index:10;
12 | width: 100%;
13 | height: 6px;
14 | background-color: #fff;
15 | }
16 | `
17 |
18 | const Tab = styled.div`
19 | padding: 15px 30px;
20 | font-family: "NeueHaasGroteskDisp Pro Md", sans-serif;
21 | font-size: 18px;
22 | white-space: nowrap;
23 | @media ${device.largeLaptop} {
24 | font-size: 16px;
25 | }
26 | @media ${device.mobile} {
27 | font-size: 14px;
28 | padding: 15px 20px;
29 | }
30 |
31 | font-weight: normal;
32 | font-stretch: normal;
33 | font-style: normal;
34 | line-height: normal;
35 | letter-spacing: normal;
36 | color: #0b0412;
37 | cursor: pointer;
38 | &.selected{
39 | background-color: white;
40 | border-radius: 5px;
41 | box-shadow: 0 0 6px 0 rgb(0 0 0 / 22%);
42 | border-bottom-right-radius: 0;
43 | border-bottom-left-radius: 0;
44 | }
45 |
46 | `
47 |
48 | export default (props)=> {
49 | const tabs = props.tabNames || []
50 | const selected = props.selected
51 | return (
52 |
53 |
54 | {tabs.map(tab => props.onClick(tab)} key={tab} className={selected == tab ? "selected" : ""}>{tab} )}
55 |
56 |
57 |
58 | )
59 | }
--------------------------------------------------------------------------------
/src/containers/Compound.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | import React, { Component } from "react";
4 | import logo from "../assets/compound-full-logo.svg";
5 | import Etherium from "../assets/etherium.svg";
6 | import Header2 from "../components/Header2";
7 | import { doApiAction } from "../lib/Actions";
8 | import compoundStore from "../stores/compound.store"
9 | import {observer} from "mobx-react"
10 | import styled from "styled-components"
11 | import Flex, {FlexItem} from "styled-flex-component";
12 | import BalanceBox from "../components/compound-components/BalanceBox"
13 | import CoinListBox from "../components/compound-components/CoinListBox"
14 | import {CoinStatusEnum} from "../lib/compound.util"
15 | import {device} from "../screenSizes";
16 | import routerStore from "../stores/router.store"
17 |
18 | const Overides = styled.div`
19 | margin-bottom: 100px;
20 | `
21 |
22 | class Compound extends Component {
23 |
24 | constructor(props) {
25 | super(props);
26 | }
27 |
28 | componentDidMount() {
29 | routerStore.setRouteProps(this.props.history)
30 | compoundStore.getUserInfo()
31 | }
32 |
33 | getList(coinStatusToShow){
34 | const items = compoundStore.coinList.filter(coinAddress=> {
35 | const coin = compoundStore.coinsInTx[coinAddress] || compoundStore.coinMap[coinAddress] // preserve state until tx is finished and UI is ready to dispaly new coin state
36 | if(!coin.symbol){
37 | return false
38 | }
39 | return coin.isCoinStatus(coinStatusToShow)
40 | })
41 | .map(coinAddress => {
42 | const coin = compoundStore.coinsInTx[coinAddress] || compoundStore.coinMap[coinAddress]
43 | return coin
44 | })
45 | return items
46 | }
47 |
48 | render() {
49 | const { userInfo, userInfoUpdate, coinList } = compoundStore
50 | console.log("comp userInfoUpdate ", userInfoUpdate)
51 | return (
52 |
53 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | );
70 | }
71 | }
72 |
73 | export default observer(Compound)
--------------------------------------------------------------------------------
/src/containers/Dashboard.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import Etherium from "../assets/etherium.svg";
3 | import Header from "../components/Header";
4 | import EtheriumBox from "../components/EtheriumBox";
5 | import DaiBox from "../components/DaiBox";
6 | import { doApiAction } from "../lib/Actions";
7 | import EventBus from "../lib/EventBus";
8 | import logo from "../assets/logo-maker-black.svg";
9 | import makerStoreManager, {makerStoreNames, makerStores} from "../stores/maker.store"
10 | import {observer} from "mobx-react"
11 | import routerStore from "../stores/router.store"
12 | import mainStore from "../stores/main.store"
13 |
14 | class Dashboard extends Component {
15 |
16 | constructor(props) {
17 | super(props);
18 | }
19 |
20 | componentDidMount() {
21 | routerStore.setRouteProps(this.props.history)
22 | }
23 |
24 | onAction = async (action, value, onHash) => {
25 | try {
26 | const res = await doApiAction(action, value, null, onHash);
27 | makerStoreManager.getMakerStore().getUserInfo()
28 | return res;
29 | } catch (error) {
30 | if(error.message === "GEM_MODAL_CLOSED"){
31 | EventBus.$emit("close-action")
32 | return
33 | }
34 | EventBus.$emit("action-failed", null, action);
35 | let errorMsg = null;
36 | if(action.toString() === "repay")
37 | errorMsg = "Repay is expected to fail, likely because your DAI balance is too low (by 0.000001 DAI or less)";
38 | EventBus.$emit("app-error", errorMsg, action);
39 | console.log(error);
40 | return false;
41 | }
42 | };
43 |
44 | render() {
45 | const {getMakerStore, storeChanges, currentStore} = makerStoreManager
46 | const { userInfo, userInfoUpdate, symbol } = getMakerStore()
47 | console.log("userInfoUpdate ", userInfoUpdate)
48 |
49 | return (
50 |
51 |
56 | {makerStoreNames.map(name => {
57 | return (
58 |
59 |
64 |
71 |
72 | )
73 | })}
74 |
75 | );
76 | }
77 | }
78 |
79 | export default observer(Dashboard)
--------------------------------------------------------------------------------
/src/containers/FAQ.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import FAQContent from "../components/FAQContent";
3 | import routerStore from "../stores/router.store"
4 |
5 | export default class FAQ extends Component {
6 |
7 | constructor (props) {
8 | super(props)
9 | this.state = {height:0}
10 | }
11 |
12 | componentDidMount() {
13 | routerStore.setRouteProps(this.props.history)
14 | const height = document.querySelector('.menu-item-header').clientHeight;
15 | this.setState({ height });
16 | }
17 |
18 | render() {
19 | const { handleItemChange, history } = this.props;
20 | return (
21 |
22 |
23 |
FAQ
24 |
25 | The following are the most common questions the B.Protocol team has been asked by new users of the protocol.
26 | It will be updated as we go forward. Get yourself educated…
27 |
28 |
29 | {/*
*/}
30 |
34 |
35 |
36 |
37 | );
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/containers/Liquity.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import {observer} from "mobx-react"
3 | import routerStore from "../stores/router.store"
4 |
5 | class Liquity extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 | }
10 |
11 | componentDidMount() {
12 | routerStore.setRouteProps(this.props.history)
13 | }
14 |
15 | render() {
16 | return (
17 |
23 | );
24 | }
25 | }
26 |
27 | export default observer(Liquity)
28 |
--------------------------------------------------------------------------------
/src/containers/LiquityLegacy.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import {observer} from "mobx-react"
3 | import routerStore from "../stores/router.store"
4 |
5 | class LiquityLegacy extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 | }
10 |
11 | componentDidMount() {
12 | routerStore.setRouteProps(this.props.history)
13 | }
14 |
15 | render() {
16 | return (
17 |
23 | );
24 | }
25 | }
26 |
27 | export default observer(LiquityLegacy)
28 |
--------------------------------------------------------------------------------
/src/containers/Risk.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import routerStore from "../stores/router.store"
3 | import Sidebar from "../components/Sidebar";
4 | import RiskContent from "../components/RiskContent";
5 |
6 | export default class Risk extends Component {
7 |
8 | constructor (props) {
9 | super(props)
10 | this.state = {height:0}
11 | }
12 |
13 | componentDidMount() {
14 | routerStore.setRouteProps(this.props.history)
15 | const height = document.querySelector('.menu-item-header').clientHeight;
16 | this.setState({ height });
17 | }
18 |
19 | render() {
20 | const { handleItemChange, history } = this.props;
21 | return (
22 |
23 |
24 |
Risks
25 |
26 | Interacting with lending platforms does not come without risks,
27 | and while B.Protocol design does not add additional risk, the user
28 | should make his/her own research and understand the risks in the
29 | underlying lending platforms (MakerDAO, Compound, Aave), and the
30 | security guarantees B.Protocol provides.
31 |
32 |
33 | Whitepapers:
34 |
60 |
61 |
62 |
66 |
67 |
68 |
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/containers/Terms.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import routerStore from "../stores/router.store"
3 | import Sidebar from "../components/Sidebar";
4 | import TermsOfUseContent from "../components/TermsOfUseContent";
5 |
6 | export default class Terms extends Component {
7 |
8 | constructor (props) {
9 | super(props)
10 | this.state = {height:0}
11 | }
12 |
13 | componentDidMount() {
14 | routerStore.setRouteProps(this.props.history)
15 | const height = document.querySelector('.menu-item-header').clientHeight;
16 | this.setState({ height });
17 | }
18 |
19 | render() {
20 | const { handleItemChange, history } = this.props;
21 | return (
22 |
23 |
24 |
Terms of Use
25 |
26 |
30 |
31 |
32 |
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 | import { configure as mobxConfiguration} from "mobx"
7 |
8 | mobxConfiguration({
9 | enforceActions: "never", // silence mobx action warnings
10 | })
11 |
12 | // last resort global exception catchers
13 | window.onError = function(message, source, lineno, colno, error) {
14 | console.warn(`Error: ${error.msg} @: ${error.stack}`)
15 | return true
16 | }
17 |
18 | window.addEventListener('unhandledrejection', function (event) {
19 | console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
20 | event.preventDefault();
21 | });
22 |
23 | ReactDOM.render(
24 |
25 |
26 | ,
27 | document.getElementById('root')
28 | );
29 |
30 | // If you want your app to work offline and load faster, you can change
31 | // unregister() to register() below. Note this comes with some pitfalls.
32 | // Learn more about service workers: https://bit.ly/CRA-PWA
33 | serviceWorker.unregister();
34 | // version logger
35 | const {version} = require("../package.json")
36 | console.log("--version: ", version)
37 |
--------------------------------------------------------------------------------
/src/lib/EventBus.js:
--------------------------------------------------------------------------------
1 | class _EventBus {
2 |
3 | constructor() {
4 | this.bus = {};
5 | }
6 |
7 | $on(id, callback) {
8 | if (!this.bus[id]) this.bus[id] = [];
9 | this.bus[id].push(callback);
10 | }
11 |
12 | $off(id, callback) {
13 | if (!this.bus[id]) return;
14 | for (let i = this.bus[id].length-1; i >= 0; i--) {
15 | if (this.bus[id][i] === callback) {
16 | this.bus.splice(i, 1);
17 | return;
18 | }
19 | }
20 | }
21 |
22 | $emit(id, ...vars) {
23 | if (this.bus[id]) {
24 | for (let callback of this.bus[id]) callback(...vars);
25 | }
26 | }
27 | }
28 |
29 | const EventBus = new _EventBus();
30 |
31 | export default EventBus;
32 |
--------------------------------------------------------------------------------
/src/lib/Utils.js:
--------------------------------------------------------------------------------
1 | import Web3 from "web3"
2 | const {toBN, toWei, fromWei} = Web3.utils
3 |
4 | /**
5 | *
6 | * @param {*} v
7 | * @param {*} decPoint
8 | * @param {*} max
9 | */
10 | export const numm = (v,decPoint = 2, max = Infinity) => {const r = parseFloat(Math.min(max, v)).toFixed(decPoint); return (isNaN(r*1))?0:r}
11 |
12 | /**
13 | *
14 | * @param {*} number
15 | * @param {*} decimalPoint
16 | */
17 | export const chop = (number, decimalPoint) => Math.floor(parseFloat(number) * Math.pow(10, decimalPoint)) / Math.pow(10, decimalPoint)
18 |
19 |
20 | export const symbolToDisplayDecimalPointMap = {
21 | USD: 2,
22 | DAI: 2,
23 | ETH: 4,
24 | WBTC: 5,
25 | }
26 |
27 | export const maxAllowance = toBN("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)
28 | const reallyLargeAllowance = toBN("8888888888888888888888888888888888888888888888888888888888888888", 16)
29 | export const hasAllowance = (allowance) => toBN(allowance).gt(reallyLargeAllowance)
30 |
31 | export const isKovan = () => {
32 | try{
33 | return parseInt(window.ethereum.chainId) === parseInt("0x2A")
34 | } catch (err){
35 | return false
36 | }
37 | }
38 |
39 | export const toCommmSepratedString = (n) => n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
40 |
41 | export const percentage = (partialValue, totalValue) => (100 * partialValue) / totalValue;
42 |
43 | export const stringToFixed = (string, numbersAfterTheDeciamlPoint) => {
44 | const decimalPointIndex = string.indexOf(".")
45 | if(decimalPointIndex === -1){
46 | return string
47 | }
48 | return string.slice(0, decimalPointIndex + numbersAfterTheDeciamlPoint)
49 | }
50 |
51 | const delay = (msec, value) => {
52 | return new Promise(done => window.setTimeout((() => done(value)), msec));
53 | }
54 |
55 | export const isFinished = (promise) => {
56 | return Promise.race([delay(0, false), promise.then(() => true, () => true)]);
57 | }
58 |
59 | export const toUiDecimalPointFormat = (bn, decimalPoint) => {
60 | const factor = toBN(10).pow(toBN(18 - decimalPoint))
61 | const x = toBN(bn).mul(factor)
62 | return fromWei(x)
63 | }
64 |
65 | export const fromUiDeciamlPointFormat = (num, decimalPoint) => {
66 | const factor = toBN(10).pow(toBN(18 - decimalPoint))
67 | const x = toBN(toWei(num))
68 | return x.div(factor)
69 | }
70 |
71 | export const gasToEth = async (gas, web3) => {
72 | const gasPrice = await web3.eth.getGasPrice()
73 | const cost = toBN(gas).mul(toBN(gasPrice))
74 | const result = web3.utils.fromWei(cost.toString())
75 | return result
76 | }
--------------------------------------------------------------------------------
/src/lib/compoundConfig/compoundImportAbi.js:
--------------------------------------------------------------------------------
1 | export const compoundImportAbi = [{"inputs":[{"internalType":"contract Registry","name":"_registery","type":"address"},{"internalType":"contract BComptroller","name":"_bComptroller","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"bComptroller","outputs":[{"internalType":"contract BComptroller","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xeaeec94b"},{"constant":true,"inputs":[],"name":"bETH","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x61983163"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"internalType":"contract Registry","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x7b103999"},{"constant":false,"inputs":[{"internalType":"address[]","name":"cTokenCollateral","type":"address[]"}],"name":"importCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x4cef1adc"},{"constant":false,"inputs":[{"internalType":"address[]","name":"cTokenCollateral","type":"address[]"},{"internalType":"address[]","name":"collateralUnderlying","type":"address[]"},{"internalType":"address[]","name":"cTokenDebt","type":"address[]"},{"internalType":"address[]","name":"debtUnderlying","type":"address[]"},{"internalType":"uint256","name":"ethFlashLoan","type":"uint256"}],"name":"importAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xdc861faa"}]
--------------------------------------------------------------------------------
/src/lib/compoundConfig/flashImportAbi.js:
--------------------------------------------------------------------------------
1 | export const flashImportAbi = [{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address[]","name":"cTokenCollateral","type":"address[]"},{"internalType":"address[]","name":"collateralUnderlying","type":"address[]"},{"internalType":"address[]","name":"cTokenDebt","type":"address[]"},{"internalType":"address[]","name":"debtUnderlying","type":"address[]"},{"internalType":"address payable","name":"importer","type":"address"},{"internalType":"uint256","name":"ethAmountToFlashBorrow","type":"uint256"},{"internalType":"address payable","name":"flash","type":"address"}],"name":"flashImport","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xdf623698"}]
--------------------------------------------------------------------------------
/src/lib/compoundConfig/kovanAddress.js:
--------------------------------------------------------------------------------
1 | export const addresses = {
2 | "cZRX": "0xAf45ae737514C8427D373D50Cd979a242eC59e5a",
3 | "cWBTC legacy": "0xa1fAA15655B0e7b6B6470ED3d096390e6aD93Abb",
4 | "cWBTC": "0xbf3f6592c1f523eee8e6a78a50264531480bbf7e",
5 | "cUSDT": "0x3f0A0EA2f86baE6362CF9799B523BA06647Da018",
6 | "cUSDC": "0x4a92E71227D294F041BD82dd8f78591B75140d63",
7 | "cETH": "0x41B5844f4680a8C38fBb695b7F9CFd1F64474a72",
8 | "cBAT": "0x4a77fAeE9650b09849Ff459eA1476eaB01606C7a",
9 | "cDAI": "0xF0d0EB522cfa50B716B3b1604C4F0fA6f04376AD",
10 | "Comptroller": "0x5eAe89DC1C671724A672ff0630122ee834098657",
11 | "COMP": "0x61460874a7196d6a22d1ee4922473664b3e95270",
12 |
13 | "compUserInfoAddress": "0x2df603eef6ff4a02c527164cbcdae77fa393dc3c",
14 | "bComptrollerAddress": "0x777f6369cc1cf921905c8899e127391d6ee5f009",
15 | "registryAddress": "0x0056186fbfcb8cd679343ae88764efef55ea12b2",
16 | "sugerDady": "0xA1A343B4245e4364e6b9c4574F9F7A3C1D849Ad6",
17 | "compoundImportAddress": "0x40fa13c14e3f10a4d6915849e9a057148bda4fd6",
18 | "flashImportAddress": "0xF9fa648c46bb1e1f249ABA973397077CDc20fC78",
19 | "jarConnector": "0x061133BE90f97B6Eb7f73eD9Dc50eFB1DD96ED72",
20 | "jar": "0x18DB5F7711d57974d825f9ca45D21627353bEb72",
21 | "compClaimData": "0x8A4D0ad9005154fa4b7A9A9896d97fb88Ee7f9aa"
22 | }
23 |
--------------------------------------------------------------------------------
/src/lib/compoundConfig/mainnetAddress.js:
--------------------------------------------------------------------------------
1 | export const addresses = {
2 | "cCOMP": "0x70e36f6bf80a52b3b46b3af8e106cc0ed743e8e4",
3 | "cUSDC": "0x39AA39c021dfbaE8faC545936693aC917d5E7563",
4 | "cDAI": "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643",
5 | "Comptroller": "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B",
6 | "cUSDT": "0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9",
7 | "cBAT": "0x6C8c6b02E7b2BE14d4fA6022Dfd6d75921D90E4E",
8 | "cETH": "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5",
9 | "cUNI": "0x35a18000230da775cac24873d00ff85bccded550",
10 | "cZRX": "0xB3319f5D18Bc0D84dD1b4825Dcde5d5f7266d407",
11 | "cWBTC legacy": "0xC11b1268C1A384e55C48c2391d8d480264A3A7F4",
12 | "cWBTC": "0xccF4429DB6322D5C611ee964527D42E5d685DD6a",
13 | "cTUSD": "0x12392f67bdf24fae0af363c24ac620a2f67dad86",
14 | "cLINK": "0xface851a4921ce59e912d19329929ce6da6eb0c7",
15 | "cMKR": "0x95b4ef2869ebd94beb4eee400a99824bf5dc325b",
16 | "cSUSHI": "0x4b0181102a0112a2ef11abee5563bb4a3176c9d7",
17 | "cYFI": "0x80a2ae356fc9ef4305676f7a3e2ed04e12c33946",
18 | "cAAVE": "0xe65cdb6479bac1e22340e4e755fae7e509ecd06c",
19 | "COMP": "0xc00e94cb662c3520282e6f5717214004a7f26888",
20 | /* B.Compound specific addresses
21 | ===================================================================== */
22 | "compUserInfoAddress": "0xe8986fb27cb7ee2575ed14133da4820be4a38228",
23 | "bComptrollerAddress": "0x9db10b9429989cc13408d7368644d4a1cb704ea3",
24 | "registryAddress": "0xbf698df5591caf546a7e087f5806e216afed666a",
25 | "sugerDady": "0x4F868C1aa37fCf307ab38D215382e88FCA6275E2",
26 | "compoundImportAddress": "0x035cccb015a826b754529b4d04587182b8210344",
27 | "flashImportAddress": "0xa5c48ef0301437bb2f5afdda8aedbe817f5e11d6",
28 | "jarConnector": "0xd24e557762589124d7cfef90d870df17c25bff8a",
29 | "jar": "0xb493d1b6048b801747d72f755b6efbfa1b4c6103",
30 | "compClaimData": "0x3a9cfE56604c5f4892950Ab3a3D9355901395B51"
31 | }
--------------------------------------------------------------------------------
/src/lib/compoundConfig/readme.md:
--------------------------------------------------------------------------------
1 | ### for the full updated resources
2 |
3 | please visit this link
4 | https://github.com/compound-finance/compound-config
--------------------------------------------------------------------------------
/src/lib/insta.interface.js:
--------------------------------------------------------------------------------
1 | import { ABI } from "./instaConfig/abi"
2 | import { addresses as mainnetAddresses } from "./instaConfig/mainnetAddress"
3 | import Web3 from "web3"
4 | const {toBN, fromWei, toWei} = Web3.utils
5 |
6 | export const getAccounts = async (web3, networkId, user) => {
7 | if(networkId != 1){
8 | return []
9 | }
10 | const { Contract } = web3.eth
11 | const dsaResolver = new Contract(ABI.dsaResolver, mainnetAddresses.dsaResolver)
12 | return dsaResolver.methods.getAuthorityAccounts(user).call({gasLimit:10e6})
13 | }
--------------------------------------------------------------------------------
/src/lib/instaConfig/mainnetAddress.js:
--------------------------------------------------------------------------------
1 | export const addresses = {
2 | "dsaResolver": "0x621AD080ad3B839e7b19e040C77F05213AB71524",
3 | }
--------------------------------------------------------------------------------
/src/lib/liquity.interface.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 | import { ABI } from "./liquityConfig/abi"
5 | import { addresses as mainnetAddresses } from "./liquityConfig/mainnetAddress"
6 | import Web3 from "web3"
7 | const {toBN, fromWei, toWei} = Web3.utils
8 |
9 | // todo balancOf(userAddress).div(totalSuply)
10 |
11 | export const getBamms = async (web3, networkId) => {
12 | const { Contract } = web3.eth
13 | const bammKeeper = new Contract(ABI.bammKeeper, mainnetAddresses.bammKeeper)
14 | let res = []
15 | let exception
16 | let i = 0
17 | while (!exception){
18 | try{
19 | const address = await bammKeeper.methods.bamms(i).call({gasLimit:10e6})
20 | res.push(address)
21 | i++
22 | } catch (e){
23 | exception = e
24 | }
25 | }
26 | return res
27 | }
28 |
29 | export const getBammLusd = (web3, networkId, bammAddress) => {
30 | const { Contract } = web3.eth
31 | const sp = new Contract(ABI.stabilityPool, mainnetAddresses.stabilityPool)
32 | return sp.methods.getCompoundedLUSDDeposit(bammAddress).call({gasLimit:10e6})
33 | }
34 |
35 | export const getUserLiquityTvl = async (web3, networkId, userAddress) => {
36 | const { Contract } = web3.eth
37 | const bamms = await getBamms(web3, networkId)
38 | let userLiquityTvl = toBN('0')
39 | for (const bammAddress of bamms){
40 | const bamm = new Contract(ABI.bamm, bammAddress)
41 | const userBalance = await bamm.methods.balanceOf(userAddress).call({gasLimit:10e6})
42 | const totalSupply = await bamm.methods.totalSupply().call({gasLimit:10e6})
43 | const totalLusd = await getBammLusd(web3, networkId, bammAddress)
44 | const userAddaitionalLusd = toBN(totalLusd).mul(toBN(userBalance)).div(toBN(totalSupply))
45 | userLiquityTvl = userLiquityTvl.add(userAddaitionalLusd)
46 | }
47 | return userLiquityTvl
48 | }
--------------------------------------------------------------------------------
/src/lib/liquityConfig/mainnetAddress.js:
--------------------------------------------------------------------------------
1 | export const addresses = {
2 | "stabilityPool": "0x66017D22b0f8556afDd19FC67041899Eb65a21bb",
3 | "bammKeeper": "0xeaE019ef845A4Ffdb8829210De5D30aC6FbB5371"
4 | }
--------------------------------------------------------------------------------
/src/screenSizes.js:
--------------------------------------------------------------------------------
1 | // defaults to desktop
2 | // mobile is not supprted for now
3 |
4 | const size = {
5 | largeLaptop: 1600,
6 | laptop: 1366,
7 | tablet: 1023,
8 | mobile: 600,
9 | }
10 |
11 | export const device = {
12 | largeLaptop: `screen and (max-width: ${size.largeLaptop}px)`,
13 | laptop: `screen and (max-width: ${size.laptop}px)`,
14 | tablet: `screen and (max-width: ${size.tablet}px)`,
15 | mobile: `screen and (max-width: ${size.mobile}px)`,
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/scss/_animations.scss:
--------------------------------------------------------------------------------
1 | @keyframes rotate {
2 | 0% {
3 | transform: rotate(0);
4 | }
5 |
6 | 50% {
7 | transform: rotate(180deg);
8 | }
9 |
10 | 100% {
11 | transform: rotate(360deg);
12 | }
13 | }
14 |
15 | @keyframes fadein {
16 | 0% {
17 | opacity: 0;
18 | }
19 | 100% {
20 | opacity: 1;
21 | }
22 | }
23 |
24 | @keyframes dropin {
25 | 0% {
26 | opacity: 0;
27 | transform: translateY(-30px);
28 | }
29 | 100% {
30 | opacity: 1;
31 | transform: translateY(0);
32 | }
33 | }
34 |
35 | @keyframes dropout {
36 | 0% {
37 | opacity: 0;
38 | transform: translateY(0);
39 | }
40 | 100% {
41 | opacity: 1;
42 | transform: translateY(-30px);
43 | }
44 | }
45 |
46 | @keyframes pulse {
47 | 0% {
48 | transform: scale(1);
49 | opacity: 1;
50 | }
51 |
52 | 20% {
53 | transform: scale(1.1);
54 | opacity: 0;
55 | }
56 |
57 | 31% {
58 | transform: scale(0.7);
59 | opacity: 0;
60 | }
61 | 32% {
62 | opacity: 0;
63 | }
64 |
65 | 50% {
66 | transform: scale(1);
67 | opacity: 1;
68 | }
69 |
70 | 100% {
71 | transform: scale(1);
72 | opacity: 1;
73 | }
74 |
75 | }
76 |
77 | @keyframes frag {
78 | 0% {
79 | transform: scale(1);
80 | opacity: 1;
81 | }
82 |
83 | 20% {
84 | transform: translate(7px, -7px);
85 | opacity: 0;
86 | }
87 |
88 | 25% {
89 | opacity: 0;
90 | }
91 |
92 | 31% {
93 | transform: translate(-10px, 10px);
94 | }
95 | 32% {
96 | opacity: 0;
97 | }
98 |
99 | 50% {
100 | transform: translate(0,0);
101 | opacity: 1;
102 | }
103 |
104 | 100% {
105 | transform: scale(1);
106 | opacity: 1;
107 | }
108 |
109 | }
110 |
111 | .fade-in{
112 | animation: fadein 0.5s forwards;
113 | animation-timing-function: ease-in-out;
114 | }
--------------------------------------------------------------------------------
/src/scss/_colors.scss:
--------------------------------------------------------------------------------
1 | $pageBg: #ffffff;
2 |
3 | $jumboBg: #f2fbf6;
4 | $jumboBgStart: rgba(37, 192, 104, 0);
5 | $jumboBgEnd: rgba(12, 233, 108, 0.45);
6 |
7 | $btnColor: #17ab57;
8 | $btnBg: #d6f2e3;
9 | $sidebarBg: #0b0412;
10 | $sidebarColor: #647686;
11 | $sidebarSeparatorColor: transparentize(#647686, 0.7);
12 |
13 | $sidebarBtnBg: #fbb936;
14 | $sidebarBtnColor: #734a00;
15 | $sidebarBtnHoverBg: #ffffff;
16 | $sidebarBtnHoverColor: #333333;
17 |
18 | $sidebarSocialBtnBg: #121b23;
19 |
20 | $panelBg: #ffffff;
21 | $panelColor: #0b0412;
22 | $panelSecondaryColor: transparentize(#0b0412, 0.5);
23 | $panelSeparatorColor: transparentize(#979797, 0.8);
24 |
25 | $statsColor: #ffffff;
26 | $statsTitleColor: #ffffff;
27 |
28 | $inputBorder: #979797;
29 |
--------------------------------------------------------------------------------
/src/scss/_fonts.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "NeueHaasGroteskDisp Pro Md";
3 | src: url("/fonts/NeueHaasGroteskDisp Pro Md.eot");
4 | src: url("/fonts/NeueHaasGroteskDisp Pro Md.eot?#iefix")
5 | format("embedded-opentype"),
6 | url("/app/fonts/NeueHaasGroteskDisp Pro Md.woff2")
7 | format("woff2"), url("/fonts/NeueHaasGroteskDisp Pro Md.woff")
8 | format("woff"), url("/fonts/NeueHaasGroteskDisp Pro Md.ttf")
9 | format("truetype"), url("//db.onlinewebfonts.com/t/c891e94039740e4a24a9f53324fd91be.svg#NeueHaasGroteskDisp Pro Md")
10 | format("svg"); }
11 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;800&display=swap');
12 |
13 | $titleFont: "NeueHaasGroteskDisp Pro Md";
14 | $bodyFont : "Poppins";
15 |
--------------------------------------------------------------------------------
/src/scss/_layout.scss:
--------------------------------------------------------------------------------
1 | .even {
2 | display: flex;
3 | & > * {
4 | flex: 1;
5 | padding-right: 5px;
6 | &:last-child{
7 | padding-right: 0;
8 | }
9 | }
10 | @media screen and (max-width: 600px) {
11 | flex-wrap: wrap;
12 | }
13 | }
14 |
15 |
16 | .split {
17 | display: flex;
18 | justify-content: space-between;
19 | align-items: center;
20 |
21 | & > * {
22 | }
23 | }
24 |
25 |
26 | #root {
27 | display: flex;
28 | min-height: 100%;
29 | }
30 |
31 | .container {
32 | width: 95%;
33 | margin: 0 auto;
34 | max-width: 1260px;
35 | transition: all 0.3s;
36 |
37 | @media screen and (max-width: 1600px) {
38 | max-width: 1160px;
39 | }
40 |
41 | @media screen and (max-width: 1366px) {
42 | max-width: 1036px;
43 | }
44 |
45 | }
46 |
47 | .title-bar {
48 | height: 117px;
49 |
50 | @media screen and (max-width: 1600px) {
51 | height: 86px;
52 | }
53 |
54 | h1 {
55 | font-size: 28px;
56 | font-weight: normal;
57 | letter-spacing: 1.4px;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/scss/_migrate.scss:
--------------------------------------------------------------------------------
1 | @import "fonts";
2 | @import "colors";
3 |
4 | .migrate {
5 |
6 | display: flex;
7 | flex-direction: column;
8 | align-items: center;
9 |
10 | .migration-drawing {
11 | margin: 30px 0;
12 | img {
13 | max-width: 438px;
14 | }
15 | }
16 |
17 | h2 {
18 | font-family: $titleFont, sans-serif;
19 | font-size: 32px;
20 | font-weight: normal;
21 | letter-spacing: 1.6px;
22 | }
23 | @media (max-width: 1023px){
24 | width: 90%;
25 | min-height: 90%!important;
26 | padding: 0 5%;
27 | text-align: center;
28 | h2{
29 | font-size:26px;
30 | }
31 | }
32 | @media (max-width: 600px){
33 | h2{
34 | font-size: 20px;
35 | }
36 | .migration-drawing {
37 | margin: 20px 0;
38 | img {
39 | max-width: 100%;
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/scss/_modal.scss:
--------------------------------------------------------------------------------
1 | @import "colors";
2 | @import "fonts";
3 |
4 | .modal {
5 |
6 | &-container {
7 | opacity: 0;
8 | position: fixed;
9 | top: -200vh;
10 | z-index: 100000;
11 | background-color: rgba(255,255,255,0.9);
12 | left: 0;
13 | width: 100%;
14 | height: 100%;
15 | transition: opacity 0.3s;
16 | align-items: center;
17 | justify-content: center;
18 |
19 | &.active {
20 | top: 0;
21 | display: flex;
22 | opacity: 1;
23 | }
24 | }
25 |
26 | &-dialog {
27 | width: 815px;
28 | height: 600px;
29 | background-color: #ffffff;
30 | border-radius: 6px;
31 | box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.2), 0 0 10px 0 rgba(0, 0, 0, 0.1);
32 | @media screen and (max-width: 1023px){
33 | width:80%;
34 | min-height: 80%;
35 | }
36 | @media screen and (max-width: 600px){
37 | width: 98%;
38 | min-height: 90%;
39 | }
40 | }
41 |
42 | &-close-btn {
43 | display: flex;
44 | justify-content: flex-end;
45 | margin: 30px;
46 | opacity: 0.7;
47 | transition: all 0.2s;
48 |
49 | &:hover {
50 | opacity: 1;
51 | }
52 |
53 | img {
54 | width: 24px;
55 | cursor: pointer;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/scss/_reset.scss:
--------------------------------------------------------------------------------
1 | @import "fonts";
2 |
3 | p,h1,h2,h3,h4,h5,h6,ul,li,button {
4 | margin: 0; padding: 0;
5 | }
6 |
7 | div {
8 | box-sizing: border-box;
9 | }
10 |
11 | body, html {
12 | height: 100%;
13 | }
14 | body {
15 | font-family: $bodyFont, sans-serif;
16 | font-weight: normal;
17 | font-stretch: normal;
18 | font-style: normal;
19 | line-height: normal;
20 | }
21 |
--------------------------------------------------------------------------------
/src/scss/_tooltip.scss:
--------------------------------------------------------------------------------
1 | .tooltip {
2 |
3 | &-container {
4 | position: relative;
5 | flex: 1;
6 | }
7 |
8 | color: #000000;
9 |
10 | opacity: 0;
11 | animation: fadein 0.3s forwards;
12 |
13 | min-width: 30px;
14 | top: 60px;
15 | left: 50%;
16 | transform: translate(-50%, 0);
17 | padding: 0 10px;
18 | background-color: #ffffff;
19 | font-size: 14px;
20 | border-radius: 4px;
21 | position: absolute;
22 | z-index: 666;
23 | box-sizing: border-box;
24 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
25 | display: flex;
26 | flex-direction: column;
27 | align-items: center;
28 | justify-content: center;
29 | height: 40px;
30 | white-space: nowrap;
31 |
32 | @media screen and (max-width: 1399px) {
33 | font-size: 12px;
34 | height: 30px;
35 | }
36 |
37 | @media screen and (max-width: 767px) {
38 | height: 20px;
39 | font-size: 10px;
40 | padding: 0 3px;
41 | }
42 | }
43 |
44 | .react-tooltip-custom{
45 | font-size: 14px;
46 | border-radius: 4px;
47 | z-index: 666;
48 | box-sizing: border-box;
49 | color: #000000;
50 | opacity: 1!important;
51 | background-color: white;
52 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
53 | padding: 0 10px;
54 |
55 | @media screen and (max-width: 1399px) {
56 | font-size: 12px;
57 | }
58 |
59 | @media screen and (max-width: 767px) {
60 | font-size: 10px;
61 | padding: 0 3px;
62 | }
63 | }
64 |
65 | .tooltip i {
66 | position:absolute;
67 | top:100%;
68 | left:50%;
69 | margin-left:-8px;
70 | width:16px;
71 | height:8px;
72 | overflow:hidden;
73 | }
74 |
75 | .tooltip i::after {
76 | content:'';
77 | position:absolute;
78 | width:8px;
79 | height:8px;
80 | left:50%;
81 | top: -100%;
82 | transform:translate(-50%,50%) rotate(45deg);
83 | background-color:#ffffff;
84 | box-shadow:0 1px 4px rgba(0,0,0,0.25);
85 | }
86 |
87 | // bottom mode
88 |
89 | .tooltip.bottom {
90 | i {
91 | top: auto;
92 | bottom: 100%;
93 |
94 | &::after {
95 | top: 0;
96 | }
97 | }
98 | }
99 |
100 | .tooltip.left {
101 | margin-left: 14%;
102 | @media screen and (max-width: 767px) {
103 | margin-left: 19%;
104 | }
105 |
106 | i {
107 | left: 15%;
108 | }
109 | }
110 |
111 | .tooltip.right {
112 | margin-right: 25%;
113 |
114 | i {
115 | right: 15%;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/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/extend-expect';
6 |
--------------------------------------------------------------------------------
/src/stores/insta.store.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 | import { makeAutoObservable, runInAction } from "mobx"
5 | import {getAccounts} from "../lib/insta.interface"
6 | import userStore from "./user.store"
7 | import { BproStore } from './bpro.store'
8 | import { ApyStore } from './apy.store'
9 |
10 | export const bproInstaStores = {}
11 |
12 | class InstaStore {
13 | accounts = []
14 |
15 | constructor (){
16 | makeAutoObservable(this)
17 | }
18 |
19 | onUserConnect = async () => {
20 | try{
21 | this.getAccounts()
22 | } catch (err){
23 | console.error(err)
24 | }
25 | }
26 |
27 | async getAccounts() {
28 | const { web3, networkType, user } = userStore
29 | const accounts = await getAccounts(web3, networkType, user)
30 | accounts.forEach(account => {
31 | bproInstaStores[account] = new BproStore('uBPRO-BIP4', account)
32 | bproInstaStores[account].onUserConnect()
33 | })
34 | runInAction(()=> {
35 | this.accounts = accounts
36 | })
37 | }
38 |
39 | }
40 |
41 | export default new InstaStore()
--------------------------------------------------------------------------------
/src/stores/main.hundred.store.js:
--------------------------------------------------------------------------------
1 | import { makeAutoObservable, runInAction } from "mobx"
2 | import axios from "axios"
3 |
4 | /**
5 | * Main Store is desigend for general purpose app data
6 | */
7 | class MainHundredStore {
8 |
9 | hundredTvlFantom = 0
10 | hundredTvlArbitrum = 0
11 |
12 | get TVL(){
13 | return this.hundredTvlFantom + this.hundredTvlArbitrum
14 | }
15 |
16 | constructor (){
17 | makeAutoObservable(this)
18 | this.dataPromise = this.fetchGeneralDappData()
19 | }
20 |
21 | async fetchGeneralDappData () {
22 | try{
23 | await this.fetchBammUsd()
24 | } catch (err) {
25 | console.error(err)
26 | }
27 | }
28 |
29 | async fetchBammUsd () {
30 | try{
31 | const {data} = await axios.get('https://api.llama.fi/protocol/b.protocol')
32 | const {currentChainTvls} = data
33 | debugger
34 | this.hundredTvlArbitrum = currentChainTvls.Arbitrum
35 | this.hundredTvlFantom = currentChainTvls.Fantom
36 | } catch (err) {
37 | console.error(err)
38 | }
39 | }
40 | }
41 |
42 | export default new MainHundredStore()
43 |
--------------------------------------------------------------------------------
/src/stores/main.liquity.store.js:
--------------------------------------------------------------------------------
1 | import { makeAutoObservable, runInAction } from "mobx"
2 | import { getBammLusd, getBamms } from "../lib/liquity.interface"
3 | import Web3 from "web3"
4 | import {BP_API} from "../common/constants"
5 |
6 | const { fromWei} = Web3.utils
7 |
8 | /**
9 | * Main Store is desigend for general purpose app data
10 | */
11 | class MainLiquityStore {
12 |
13 | liquityTvlNumeric = 0
14 |
15 | constructor (){
16 | makeAutoObservable(this)
17 | this.dataPromise = this.fetchGeneralDappData()
18 | }
19 |
20 | async fetchGeneralDappData () {
21 | try{
22 | await this.fetchBammUsd()
23 | } catch (err) {
24 | console.error(err)
25 | }
26 | }
27 |
28 | async fetchBammUsd () {
29 | const web3 = new Web3(BP_API)
30 | const bamms = await getBamms(web3, "1")
31 | const bammsTvls = await Promise.all(bamms.map(async (bammAddress)=> {
32 | const lusd = await getBammLusd(web3, "1", bammAddress)
33 | return parseFloat(fromWei(lusd))
34 | }))
35 | runInAction(()=>{
36 | this.liquityTvlNumeric = bammsTvls.reduce((x, y)=> x + y)
37 | })
38 | }
39 | }
40 |
41 | export default new MainLiquityStore()
42 |
--------------------------------------------------------------------------------
/src/stores/router.store.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 | import { makeAutoObservable, runInAction } from "mobx"
5 |
6 | class RouterStore {
7 | routeProps = {}
8 |
9 | constructor (){
10 | makeAutoObservable(this)
11 | }
12 |
13 | setRouteProps = history => {
14 | this.routeProps.history = history
15 | }
16 |
17 | getRoute () {
18 | const path = this.routeProps.history.location.pathname
19 | if(path.indexOf("maker") > -1) {
20 | return "maker"
21 | }
22 | if(path.indexOf("compound")> -1) {
23 | return "compound"
24 | }
25 | }
26 | }
27 |
28 | export default new RouterStore()
--------------------------------------------------------------------------------
/src/style.scss:
--------------------------------------------------------------------------------
1 | @import "scss/animations";
2 | @import "scss/fonts";
3 | @import "scss/reset";
4 | @import "scss/layout";
5 | @import "scss/modal";
6 | @import "scss/tooltip";
7 | @import "scss/utils";
8 | @import "scss/buttons";
9 | @import "scss/currency";
10 | @import "scss/sidebar";
11 | @import "scss/app";
12 | @import "scss/migrate";
13 | @import "scss/hamburger";
14 |
15 |
--------------------------------------------------------------------------------
/src/wallets/Wallets.js:
--------------------------------------------------------------------------------
1 | import WalletConnectProvider from "@walletconnect/web3-provider";
2 | import Web3 from "web3"
3 | import EventBus from "../lib/EventBus"
4 | import {BP_API, KOVAN_BP_API} from "../common/constants"
5 | import { isAndroid, isIOS } from "react-device-detect";
6 | import detectEthereumProvider from '@metamask/detect-provider'
7 |
8 | /**
9 | * getWallet functions return a Consistent API
10 | *
11 | * web3
12 | * provider
13 | * connectFn: a function that connects and retruns the user account public key
14 | *
15 | */
16 |
17 | export const getMetaMask = async () => {
18 | const provider = window.ethereum || await detectEthereumProvider()
19 | if (!provider) {
20 | if(isAndroid || isIOS) {
21 | const currentPath = window.location.pathname
22 | window.location.replace("https://metamask.app.link/dapp/app.bprotocol.org" + currentPath)
23 | return
24 | }
25 | EventBus.$emit("app-error", "metamask is not connected");
26 | return;
27 | }
28 |
29 | const web3 = new Web3(Web3.givenProvider || "ws://localhost:8545")
30 |
31 | const connectFn = async () => {
32 | try{
33 | const accounts = await provider.request({ method: "eth_requestAccounts" })
34 | return accounts[0]
35 | }
36 | catch(err) {
37 | if (err.code === 4001) {
38 | // EIP-1193 userRejectedRequest error
39 | // If this happens, the user rejected the connection request.
40 | EventBus.$emit("app-error", "Please connect to Meta Mask");
41 | } else {
42 | EventBus.$emit("app-error", err.message);
43 | }
44 | }
45 | }
46 |
47 | return {
48 | web3,
49 | provider,
50 | connectFn
51 | }
52 | }
53 |
54 | export const getWalletConnect = (newConnection) => {
55 | // wallet connect caches last connection
56 | if(newConnection){
57 | // removing the stored connection to force a new one
58 | window.localStorage.removeItem("walletconnect")
59 | }
60 | // Create WalletConnect Provider
61 | const provider = new WalletConnectProvider({
62 | // indexd by chain ID
63 | rpc: {
64 | 1: BP_API,
65 | 42: KOVAN_BP_API
66 | // ...
67 | }
68 | })
69 | const web3 = new Web3(provider)
70 | const connectFn = async () => {
71 | // Enable session (triggers QR Code modal)
72 | await provider.enable()
73 | return provider.accounts[0]
74 | }
75 |
76 | return {
77 | web3,
78 | provider,
79 | connectFn
80 | }
81 | }
82 |
83 | export const walletTypes = {
84 | "WALLET_CONNECT": "WALLET_CONNECT",
85 | "META_MASK": "META_MASK",
86 | }
--------------------------------------------------------------------------------
/test/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cdp-js-helper",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "bInterface.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/backstop-protocol/cdp-js-helper.git"
15 | },
16 | "author": "",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/backstop-protocol/cdp-js-helper/issues"
20 | },
21 | "homepage": "https://github.com/backstop-protocol/cdp-js-helper#readme",
22 | "dependencies": {
23 | "babel-node-modules": "0.0.1",
24 | "babel-polyfill": "^6.26.0",
25 | "babel-register": "^6.26.0",
26 | "esm": "^3.2.25",
27 | "ganache-cli": "6.10.1",
28 | "truffle": "5.1.49",
29 | "web3": "^1.3.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/test/test-kovan.sh:
--------------------------------------------------------------------------------
1 | trap "exit" INT TERM ERR
2 | trap "kill 0" EXIT
3 |
4 | ./ganache-kovan.sh &
5 | ./someProcessB &
6 |
7 | wait
--------------------------------------------------------------------------------
/tests/e2e/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const absoluteSynpressNodeModulesPath = path.join(
3 | process.cwd(),
4 | '/node_modules/@synthetixio/synpress'
5 | );
6 |
7 | module.exports = {
8 | extends: `${absoluteSynpressNodeModulesPath}/.eslintrc.js`,
9 | rules: {
10 | 'ui-testing/no-css-page-layout-selector': ['warn', 'cypress'],
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/tests/e2e/specs/website-spec.js:
--------------------------------------------------------------------------------
1 |
2 | describe('checks website is up & pages exist', () => {
3 |
4 | before('',() => {
5 | cy.visit("/")
6 | })
7 |
8 | it('/', () => {
9 | cy.visit("/")
10 | cy.contains("Total value locked")
11 | })
12 | it('/maker', () => {
13 | cy.visit("/maker")
14 | cy.contains("Total value locked")
15 | })
16 | it('/app', () => {
17 | cy.visit("/app")
18 | cy.contains("Total value locked")
19 | })
20 | it('/compound', () => {
21 | cy.visit("/compound")
22 | cy.contains("Total value locked")
23 | })
24 | it('/faq', () => {
25 | cy.visit("/faq")
26 | cy.contains("FAQ")
27 | })
28 | it('/risk', () => {
29 | cy.visit("/risk")
30 | cy.contains("Risk")
31 | })
32 | it("/terms", () => {
33 | cy.visit("/terms")
34 | cy.contains("terms of use")
35 | })
36 |
37 | })
--------------------------------------------------------------------------------
/tests/e2e/test-utils.js:
--------------------------------------------------------------------------------
1 | export const wait = {
2 | short: 1000,
3 | }
4 |
--------------------------------------------------------------------------------
/tests/e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "baseUrl": "../../node_modules",
5 | "types": ["cypress", "@types/puppeteer-core", "@synthetixio/synpress/support", "cypress-wait-until", "@testing-library/cypress"],
6 | "outDir": "./output"
7 | },
8 | "include": ["**/*.*"]
9 | }
10 |
--------------------------------------------------------------------------------
/workers-site/.cargo-ok:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/backstop-protocol/react-client/2be166fdc7ca9ddd46369be0c67b49dd6e0973f1/workers-site/.cargo-ok
--------------------------------------------------------------------------------
/workers-site/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | worker
3 |
--------------------------------------------------------------------------------
/workers-site/index.js:
--------------------------------------------------------------------------------
1 | import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'
2 |
3 | /**
4 | * The DEBUG flag will do two things that help during development:
5 | * 1. we will skip caching on the edge, which makes it easier to
6 | * debug.
7 | * 2. we will return an error message on exception in your Response rather
8 | * than the default 404.html page.
9 | */
10 | const DEBUG = false
11 |
12 | addEventListener('fetch', event => {
13 | try {
14 | event.respondWith(handleEvent(event))
15 | } catch (e) {
16 | if (DEBUG) {
17 | return event.respondWith(
18 | new Response(e.message || e.toString(), {
19 | status: 500,
20 | }),
21 | )
22 | }
23 | event.respondWith(new Response('Internal Error', { status: 500 }))
24 | }
25 | })
26 |
27 | async function handleEvent(event) {
28 | const url = new URL(event.request.url)
29 | let options = {}
30 |
31 | /**
32 | * You can add custom logic to how we fetch your assets
33 | * by configuring the function `mapRequestToAsset`
34 | */
35 | // options.mapRequestToAsset = handlePrefix(/^\/docs/)
36 |
37 | try {
38 | if (DEBUG) {
39 | // customize caching
40 | options.cacheControl = {
41 | bypassCache: true,
42 | };
43 | }
44 | const page = await getAssetFromKV(event, options);
45 |
46 | // allow headers to be altered
47 | const response = new Response(page.body, page);
48 |
49 | response.headers.set("X-XSS-Protection", "1; mode=block");
50 | response.headers.set("X-Content-Type-Options", "nosniff");
51 | response.headers.set("Referrer-Policy", "unsafe-url");
52 | response.headers.set("Feature-Policy", "none");
53 |
54 | return response;
55 |
56 | } catch (e) {
57 | // if an error is thrown try to serve the asset at 404.html
58 | if (!DEBUG) {
59 | try {
60 | let notFoundResponse = await getAssetFromKV(event, {
61 | mapRequestToAsset: req => new Request(`${new URL(req.url).origin}/404.html`, req),
62 | })
63 |
64 | return new Response(notFoundResponse.body, { ...notFoundResponse, status: 404 })
65 | } catch (e) {}
66 | }
67 |
68 | return new Response(e.message || e.toString(), { status: 500 })
69 | }
70 | }
71 |
72 | /**
73 | * Here's one example of how to modify a request to
74 | * remove a specific prefix, in this case `/docs` from
75 | * the url. This can be useful if you are deploying to a
76 | * route on a zone, or if you only want your static content
77 | * to exist at a specific path.
78 | */
79 | function handlePrefix(prefix) {
80 | return request => {
81 | // compute the default (e.g. / -> index.html)
82 | let defaultAssetKey = mapRequestToAsset(request)
83 | let url = new URL(defaultAssetKey.url)
84 |
85 | // strip the prefix from the path for lookup
86 | url.pathname = url.pathname.replace(prefix, '/')
87 |
88 | // inherit all other props from the default request
89 | return new Request(url.toString(), defaultAssetKey)
90 | }
91 | }
--------------------------------------------------------------------------------
/workers-site/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worker",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@cloudflare/kv-asset-handler": {
8 | "version": "0.1.2",
9 | "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.1.2.tgz",
10 | "integrity": "sha512-otES1gV5mEhNh82p/sJERPMMrC7UOLV2JyfKf4e3EX1TmMkZ3N8IDGAqRNsoRU8UYTO7wc83I7pH1p4ozAdgMQ==",
11 | "requires": {
12 | "mime": "^2.5.2"
13 | }
14 | },
15 | "mime": {
16 | "version": "2.5.2",
17 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
18 | "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg=="
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/workers-site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "worker",
4 | "version": "1.0.0",
5 | "description": "A template for kick starting a Cloudflare Workers project",
6 | "main": "index.js",
7 | "author": "Ashley Lewis ",
8 | "license": "MIT",
9 | "dependencies": {
10 | "@cloudflare/kv-asset-handler": "~0.1.2"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------