diff --git a/client/.eslintrc.json b/client/.eslintrc.json new file mode 100755 index 0000000..5e603ec --- /dev/null +++ b/client/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "react-app" +} diff --git a/client/.gitignore b/client/.gitignore new file mode 100755 index 0000000..7254ea7 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,26 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# lol macs +.DS_Store/ + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/client/.node-version b/client/.node-version new file mode 100755 index 0000000..db24ab9 --- /dev/null +++ b/client/.node-version @@ -0,0 +1 @@ +10.13.0 diff --git a/client/README.md b/client/README.md new file mode 100755 index 0000000..ab163a4 --- /dev/null +++ b/client/README.md @@ -0,0 +1 @@ +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). diff --git a/client/config-overrides.js b/client/config-overrides.js new file mode 100755 index 0000000..94f0c0a --- /dev/null +++ b/client/config-overrides.js @@ -0,0 +1,18 @@ +/* config-overrides.js */ +const { zeppelinSolidityHotLoader } = require('./config/webpack'); + +module.exports = function override(config, env) { + //do stuff with the webpack config... + + // allow importing from outside of app/src folder, ModuleScopePlugin prevents this. + const scope = config.resolve.plugins.findIndex(o => o.constructor.name === 'ModuleScopePlugin'); + if (scope > -1) { + config.resolve.plugins.splice(scope, 1); + } + + // add Zeppelin Solidity hot reloading support + // have to insert before last loader, because CRA user 'file-loader' as default one + config.module.rules.splice(config.module.rules - 2, 0, zeppelinSolidityHotLoader); + + return config; +} diff --git a/client/config/webpack.js b/client/config/webpack.js new file mode 100755 index 0000000..db2a1bc --- /dev/null +++ b/client/config/webpack.js @@ -0,0 +1,21 @@ +const zeppelinSolidityHotLoaderOptions = { + network: 'development', + // you can stop loader from automatic compile/push/updgrade + // action by setting disabled flag to true, but it will still + // serve .json files from file system + disabled: true, +} + +module.exports = { + zeppelinSolidityHotLoader: { + test: /\.sol$/, + use: [ + { loader: 'json-loader' }, + { + loader: 'zeppelin-solidity-hot-loader', + options: zeppelinSolidityHotLoaderOptions, + }, + ], + }, + zeppelinSolidityHotLoaderOptions, +}; diff --git a/client/netlify.toml b/client/netlify.toml new file mode 100755 index 0000000..40a8fa2 --- /dev/null +++ b/client/netlify.toml @@ -0,0 +1,6 @@ +# The following redirect is intended for use with most SPAs that handle +# routing internally. +[[redirects]] + from = "/*" + to = "/index.html" + status = 200 diff --git a/client/package.json b/client/package.json new file mode 100755 index 0000000..4aeb8dc --- /dev/null +++ b/client/package.json @@ -0,0 +1,38 @@ +{ + "name": "client", + "version": "0.1.0", + "private": true, + "dependencies": { + "@material-ui/core": "^4.0.0", + "@material-ui/icons": "^4.0.0", + "dotenv": "^8.2.0", + "eslint": "^6.0.1", + "json-loader": "^0.5.7", + "node-sass": "^4.11.0", + "react": "^16.8.6", + "react-app-rewired": "^2.1.0", + "react-dom": "^16.8.6", + "react-router-dom": "^5.0.0", + "react-scripts": "^2.1.3", + "rimble-ui": "^0.11.1", + "styled-components": "^4.1.3", + "web3": "1.0.0-beta.37", + "zeppelin-solidity-hot-loader": "^1.2.3" + }, + "scripts": { + "start": "react-app-rewired start", + "build": "react-app-rewired build", + "test": "react-app-rewired test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": "react-app" + }, + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ], + "devDependencies": {} +} diff --git a/client/public/favicon-32x32.png b/client/public/favicon-32x32.png new file mode 100755 index 0000000..3fe479b Binary files /dev/null and b/client/public/favicon-32x32.png differ diff --git a/client/public/index.html b/client/public/index.html new file mode 100755 index 0000000..de7cf43 --- /dev/null +++ b/client/public/index.html @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Matic Plasma Backed Asset Swap + + + +
+ + + diff --git a/client/public/manifest.json b/client/public/manifest.json new file mode 100755 index 0000000..1f2f141 --- /dev/null +++ b/client/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/client/public/pic_bg.png b/client/public/pic_bg.png new file mode 100755 index 0000000..1bcc6e3 Binary files /dev/null and b/client/public/pic_bg.png differ diff --git a/client/src/App.css b/client/src/App.css new file mode 100755 index 0000000..53ba871 --- /dev/null +++ b/client/src/App.css @@ -0,0 +1,41 @@ +/* Styles go here */ +.token { + height: 150px; + width: 150px; + border-radius: 50%; + display: inline-block; +} + + +.App { + text-align: center; +} + +.App-logo { + animation: App-logo-spin infinite 20s linear; + height: 40vmin; +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/client/src/App.js b/client/src/App.js new file mode 100755 index 0000000..97921ec --- /dev/null +++ b/client/src/App.js @@ -0,0 +1,202 @@ +import React, { Component } from "react"; +import getWeb3, { getGanacheWeb3, Web3 } from "./utils/getWeb3"; +import Header from "./components/Header/index.js"; +import Footer from "./components/Footer/index.js"; +import Hero from "./components/Hero/index.js"; +import Web3Info from "./components/Web3Info/index.js"; + +// SwapFactory +import SwapFactory from "./components/NewBancorPool/index.js"; + +import { Typography, Grid, TextField } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/styles'; +import { theme } from './utils/theme'; +import { Loader, Button, Card, Input, Heading, Table, Form, Flex, Box, Image, EthAddress } from 'rimble-ui'; +import { zeppelinSolidityHotLoaderOptions } from '../config/webpack'; + +import styles from './App.module.scss'; +//import './App.css'; + + + +class App extends Component { + constructor(props) { + super(props); + + this.state = { + /////// Default state + storageValue: 0, + web3: null, + accounts: null, + route: window.location.pathname.replace("/", "") + }; + } + + + + ///////--------------------- Functions of testFunc --------------------------- + + + + + + + + //////////////////////////////////// + ///// Ganache + //////////////////////////////////// + getGanacheAddresses = async () => { + if (!this.ganacheProvider) { + this.ganacheProvider = getGanacheWeb3(); + } + if (this.ganacheProvider) { + return await this.ganacheProvider.eth.getAccounts(); + } + return []; + } + + componentDidMount = async () => { + const hotLoaderDisabled = zeppelinSolidityHotLoaderOptions.disabled; + + let NewBancorPool = {}; + try { + NewBancorPool = require("../../build/contracts/NewBancorPool.json"); // Load ABI of contract of NewBancorPool + } catch (e) { + console.log(e); + } + + try { + const isProd = process.env.NODE_ENV === 'production'; + if (!isProd) { + // Get network provider and web3 instance. + const web3 = await getWeb3(); + let ganacheAccounts = []; + + try { + ganacheAccounts = await this.getGanacheAddresses(); + } catch (e) { + console.log('Ganache is not running'); + } + + // Use web3 to get the user's accounts. + const accounts = await web3.eth.getAccounts(); + // Get the contract instance. + const networkId = await web3.eth.net.getId(); + const networkType = await web3.eth.net.getNetworkType(); + const isMetaMask = web3.currentProvider.isMetaMask; + let balance = accounts.length > 0 ? await web3.eth.getBalance(accounts[0]): web3.utils.toWei('0'); + balance = web3.utils.fromWei(balance, 'ether'); + + let instanceNewBancorPool = null; + let deployedNetwork = null; + + // Create instance of contracts + if (NewBancorPool.networks) { + deployedNetwork = NewBancorPool.networks[networkId.toString()]; + if (deployedNetwork) { + instanceNewBancorPool = new web3.eth.Contract( + NewBancorPool.abi, + deployedNetwork && deployedNetwork.address, + ); + console.log('=== instanceNewBancorPool ===', instanceNewBancorPool); + } + } + + if (NewBancorPool) { + this.setState({ + web3, + ganacheAccounts, + accounts, + balance, + networkId, + networkType, + hotLoaderDisabled, + isMetaMask, + new_bancor_pool: instanceNewBancorPool + }, () => { + this.refreshValues( + instanceNewBancorPool + ); + setInterval(() => { + this.refreshValues(instanceNewBancorPool); + }, 5000); + }); + } + else { + this.setState({ web3, ganacheAccounts, accounts, balance, networkId, networkType, hotLoaderDisabled, isMetaMask }); + } + } + } catch (error) { + // Catch any errors for any of the above operations. + alert( + `Failed to load web3, accounts, or contract. Check console for details.`, + ); + console.error(error); + } + }; + + componentWillUnmount() { + if (this.interval) { + clearInterval(this.interval); + } + } + + refreshValues = (instanceNewBancorPool) => { + if (instanceNewBancorPool) { + console.log('refreshValues of instanceStreamingMoney'); + } + } + + renderLoader() { + return ( +
+ +

Loading Web3, accounts, and contract...

+

Unlock your metamask

+
+ ); + } + + renderDeployCheck(instructionsKey) { + return ( +
+
+ Your contracts are not deployed in this network. Two potential reasons:
+

+ Maybe you are in the wrong network? Point Metamask to localhost.
+ You contract is not deployed. Follow the instructions below. +

+
+
+ ); + } + + renderInstructions() { + return ( +
+ +
+ ); + } + + renderNewBancorPool() { + return ( +
+ +
+ ); + } + + render() { + return ( +
+
+ {this.state.route === '' && this.renderInstructions()} + {this.state.route === 'swap_factory' && this.renderNewBancorPool()} +
+ ); + } +} + +export default App; diff --git a/client/src/App.module.scss b/client/src/App.module.scss new file mode 100755 index 0000000..12ff8d2 --- /dev/null +++ b/client/src/App.module.scss @@ -0,0 +1,81 @@ +@import './layout/variables.scss'; + +.App { + text-align: center; + display: flex; + flex-flow: column nowrap; + justify-content: flex-start; + align-items: center; +} + +code { + background: #fefefe; + box-shadow: 0 0px 2px 0px #ccc; + padding: 8px 16px; + font-size: 14px; + width: 100%; + font-family: source-code-pro,Menlo,Monaco,Consolas,Courier New, monospace; +} + +.wrapper { + min-height: 80vh; + width: 100%; + display: flex; + flex-flow: column nowrap; + align-items: center; +} + +.setup, .contracts { + width: 100%; + padding: 40px 0; + display: flex; + flex-flow: column nowrap; + align-items: center; + + .notice { + margin: 15px 0; + + p { + padding: 10px; + background: #ededed; + box-shadow: 0 1px 1px 2px #ccc; + border: 1px solid #ddd; + color: #444; + } + } + + .widgets { + display: flex; + max-width: 1200px; + width: 100%; + flex-flow: row wrap; + justify-content: space-between; + align-items: flex-start; + margin: 20px 0; + } +} + +.loader { + width: 100%; + display: flex; + flex-flow: column nowrap; + align-items: center; + justify-content: center; + min-height: 80vh; + padding: 40px 0; + h3 { + margin-top: 30px; + } +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + + +/* MapBox */ diff --git a/client/src/App.test.js b/client/src/App.test.js new file mode 100755 index 0000000..a754b20 --- /dev/null +++ b/client/src/App.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/client/src/components/Footer/footer.module.scss b/client/src/components/Footer/footer.module.scss new file mode 100755 index 0000000..59819be --- /dev/null +++ b/client/src/components/Footer/footer.module.scss @@ -0,0 +1,78 @@ +@import '../../layout/variables.scss'; +.footer { + width: 100%; + display: flex; + flex-flow: row wrap; + justify-content: space-between; + align-items: flex-start; + background: $white; + border-top: 1px solid #D8D8D8; + padding: 25px 100px; + + .brand { + display: flex; + flex-flow: column nowrap; + color: $primary; + .created { + width: 100%; + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + align-items: center; + width: 400px; + color: $primary; + + img { + width: 33px; + margin-right: 14px; + } + + a { + color: $white; + margin-top: 4px; + } + + span { + color: $white; + margin-left: 60px; + line-height: 30px; + + a { + color: $purple-aux; + } + } + } + + .copyright { + font-size: 14px; + margin-top: 10px; + text-align: left; + color: rgba(0,0,0, 0.6); + } + } + + .links { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: flex-start; + a { + margin: 0 10px; + } + img { + width: 21px; + } + } +} + +@media only screen and (max-width: $screen-sm-max) { + + .footer { + padding: 80px 40px; + + .links { + margin-top: 20px; + width: 100%; + } + } +} diff --git a/client/src/components/Footer/index.js b/client/src/components/Footer/index.js new file mode 100755 index 0000000..dfc56df --- /dev/null +++ b/client/src/components/Footer/index.js @@ -0,0 +1,18 @@ +import React from 'react'; +import styles from './footer.module.scss'; + + +const Footer = () => ( + +) + +export default Footer; diff --git a/client/src/components/Header/header.module.scss b/client/src/components/Header/header.module.scss new file mode 100755 index 0000000..6036cb8 --- /dev/null +++ b/client/src/components/Header/header.module.scss @@ -0,0 +1,92 @@ +@import '../../layout/variables.scss'; + +.header { + width: 100%; + background: #3C4653; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + height: auto; + display: flex; + justify-content: center; + + nav { + width: 100%; + max-width: 1180px; + padding: 0 30px; + display: flex; + justify-content: space-between; + align-items: center; + + .brand { + display: flex; + flex-flow: row nowrap; + justify-content: flex-start; + align-items: center; + width: 300px; + + img { + width: 120px; + margin-right: 14px; + } + } + + ul { + margin: 0; + padding: 0; + display: flex; + flex-flow: row nowrap; + height: 60px; + list-style: none; + + li { + padding: 15px; + margin: 0; + margin-right: 60px; + text-decoration: none; + a { + color: $white; + text-transform: uppercase; + font-size: 14px; + letter-spacing: 2px; + text-decoration: none; + font-family: 'Roboto Mono', monospace; + letter-spacing: 0.8px; + opacity: 0.8; + + &:hover { + opacity: 1; + text-decoration: none; + border-bottom: 2px solid $white; + } + } + } + } + } +} + +@media only screen and (max-width: $screen-sm-max) { + + .header nav ul .brand { + width: 100%; + margin-right: 0px; + justify-content: flex-start; + } +} +@media only screen and (max-width: $screen-sm-min) { + .header { + + nav { + flex-flow: row wrap; + margin-top: 10px; + } + + nav ul { + flex-flow: row wrap; + height: auto; + li { + width: 100%; + text-align: left; + padding: 3px 0; + } + } + } +} diff --git a/client/src/components/Header/index.js b/client/src/components/Header/index.js new file mode 100755 index 0000000..00a0c6c --- /dev/null +++ b/client/src/components/Header/index.js @@ -0,0 +1,16 @@ +import React from 'react'; +import styles from './header.module.scss'; + +const Header = () => ( +
+ +
+) + +export default Header; diff --git a/client/src/components/Hero/Hero.module.scss b/client/src/components/Hero/Hero.module.scss new file mode 100755 index 0000000..354f3c4 --- /dev/null +++ b/client/src/components/Hero/Hero.module.scss @@ -0,0 +1,101 @@ +@import '../../layout/variables.scss'; + +.Hero { + padding: 60px 20px; + width: 100%; + color: white; + display: flex; + flex-flow: row wrap; + align-items: flex-start; + justify-content: space-around; + background: linear-gradient(to bottom, #3C4653 , #212830); + + .hwrapper { + display: flex; + flex-flow: row wrap; + max-width: 1180px; + justify-content: space-between; + align-items: center; + width: 100%; + } + + .left, .right { + display: flex; + flex-flow: column nowrap; + width: calc(50% - 80px); + min-width: 400px; + justify-content: flex-end; + align-items: flex-start; + text-align: left; + margin-top: 20px; + margin-bottom: 20px; + padding: 0 20px; + + h1 { + font-size: 46px; + line-height: 50px; + margin-top: 0px; + font-weight: 300; + } + + h2 { + font-size: 1em; + line-height: 1.6; + font-weight: 500; + max-width: 400px; + color: #39e6e0; + } + + img { + width: 92%; + } + } + + .sellingpoints { + display: flex; + width: 100%; + justify-content: flex-end; + flex-flow: column nowrap; + + .feature { + margin: 6px 0; + font-size: 1em; + font-weight: 400; + opacity: 0.9; + + a { + color: $white; + font-weight: 600; + text-decoration: none; + + &:hover { + text-decoration: none; + border-bottom: 2px solid #fff; + } + } + } + } + + .ctas { + display: flex; + flex-flow: row wrap; + margin: 40px 0 0; + justify-content: flex-start; + + .mainLink { + text-decoration: none; + color: $blue; + font-weight: bold; + + &:hover { + text-decoration: underline; + } + } + } +} + +@media only screen and (max-width: 480px) { + .Hero .left, .Hero .right { + min-width: 92%; + } +} diff --git a/client/src/components/Hero/index.js b/client/src/components/Hero/index.js new file mode 100755 index 0000000..96406a5 --- /dev/null +++ b/client/src/components/Hero/index.js @@ -0,0 +1,14 @@ +import React, { Component } from "react"; +import styles from './Hero.module.scss'; + + +export default class Hero extends Component { + render() { + return ( +
+
+

Top Page

+
+ ); + } +} diff --git a/client/src/components/NewBancorPool/config.js b/client/src/components/NewBancorPool/config.js new file mode 100644 index 0000000..d846e0c --- /dev/null +++ b/client/src/components/NewBancorPool/config.js @@ -0,0 +1,27 @@ +/*** + * @dev - Reference from https://docs.matic.network/matic-js-tutorial/#configuring-matic-test-tokens-on-metamask + */ +require('dotenv').config(); + + +module.exports = { + MATIC_PROVIDER: 'https://testnet2.matic.network', // This is the MATIC testnet RPC + PARENT_PROVIDER: 'https://ropsten.infura.io/v3/70645f042c3a409599c60f96f6dd9fbc', // This is the Ropsten testnet RPC + ROOTCHAIN_ADDRESS: '0x60e2b19b9a87a3f37827f2c8c8306be718a5f9b4', // The address for the main Plasma contract in Ropsten testnet + WITHDRAWMANAGER_ADDRESS: '0x4ef2b60cdd4611fa0bc815792acc14de4c158d22', // An address for the WithdrawManager contract on Ropsten testnet + DEPOSITMANAGER_ADDRESS: '0x4072fab2a132bf98207cbfcd2c341adb904a67e9', // An address for a DepositManager contract in Ropsten testnet + SYNCER_URL: 'https://matic-syncer2.api.matic.network/api/v1', // Backend service which syncs the Matic sidechain state to a MySQL database which we use for faster querying. This comes in handy especially for constructing withdrawal proofs while exiting assets from Plasma. + WATCHER_URL: 'https://ropsten-watcher2.api.matic.network/api/v1', // Backend service which syncs the Matic Plasma contract events on Ethereum mainchain to a MySQL database which we use for faster querying. This comes in handy especially for listening to asset deposits on the Plasma contract. + ROOTWETH_ADDRESS: '0x421dc9053cb4b51a7ec07b60c2bbb3ec3cfe050b', // This is a wrapped ETH ERC20 contract address so that we can support ETH deposits to the sidechain + MATICWETH_ADDRESS: '0x31074c34a757a4b9FC45169C58068F43B717b2D0', // The corresponding wrapped ETH ERC20 contract address on the Matic chain + + PRIVATE_KEY: process.env.PRIVATE_KEY, // A sample private key prefix with `0x` + //PRIVATE_KEY: '', // A sample private key prefix with `0x` + FROM_ADDRESS: process.env.FROM_ADDRESS, // Your address + //FROM_ADDRESS: '', // Your address + + ROPSTEN_TEST_TOKEN: '0x70459e550254b9d3520a56ee95b78ee4f2dbd846', // Contract for ERC20 in Ropsten + MATIC_TEST_TOKEN: '0xc82c13004c06E4c627cF2518612A55CE7a3Db699', // Contract for ERC20 in Matic testnet + ROPSTEN_ERC721_TOKEN: '0x07d799252cf13c01f602779b4dce24f4e5b08bbd', // Contract for ERC721 in Ropsten testnet + MATIC_ERC721_TOKEN: '0x9f289a264b6db56d69ad53f363d06326b984e637', // Contract for ERC721 in matic testnet +} diff --git a/client/src/components/NewBancorPool/index.js b/client/src/components/NewBancorPool/index.js new file mode 100644 index 0000000..5c277b8 --- /dev/null +++ b/client/src/components/NewBancorPool/index.js @@ -0,0 +1,189 @@ +import React, { Component } from "react"; +import getWeb3, { getGanacheWeb3, Web3 } from "../../utils/getWeb3"; + +import App from "../../App.js"; + +import { Typography, Grid, TextField } from '@material-ui/core'; +import { ThemeProvider } from '@material-ui/styles'; +import { theme } from '../../utils/theme'; +import { Loader, Button, Card, Input, Heading, Table, Form, Flex, Box, Image, EthAddress } from 'rimble-ui'; +import { zeppelinSolidityHotLoaderOptions } from '../../../config/webpack'; + +import styles from '../../App.module.scss'; +//import './App.css'; + + + + +export default class NewBancorPool extends Component { + constructor(props) { + super(props); + + this.state = { + /////// Default state + storageValue: 0, + web3: null, + accounts: null, + route: window.location.pathname.replace("/", "") + }; + + this.getTestData = this.getTestData.bind(this); + } + + + getTestData = async () => { + const { accounts, new_bancor_pool, web3 } = this.state; + + const response_1 = await new_bancor_pool.methods.testFunc().send({ from: accounts[0] }) + console.log('=== response of testFunc() function ===', response_1); + } + + + //////////////////////////////////// + ///// Refresh Values + //////////////////////////////////// + refreshValues = (instanceNewBancorPool) => { + if (instanceNewBancorPool) { + console.log('refreshValues of instanceNewBancorPool'); + } + } + + + //////////////////////////////////// + ///// Ganache + //////////////////////////////////// + getGanacheAddresses = async () => { + if (!this.ganacheProvider) { + this.ganacheProvider = getGanacheWeb3(); + } + if (this.ganacheProvider) { + return await this.ganacheProvider.eth.getAccounts(); + } + return []; + } + + componentDidMount = async () => { + const hotLoaderDisabled = zeppelinSolidityHotLoaderOptions.disabled; + + let NewBancorPool = {}; + try { + NewBancorPool = require("../../../../build/contracts/NewBancorPool.json"); // Load ABI of contract of NewBancorPool + } catch (e) { + console.log(e); + } + + try { + const isProd = process.env.NODE_ENV === 'production'; + if (!isProd) { + // Get network provider and web3 instance. + const web3 = await getWeb3(); + let ganacheAccounts = []; + + try { + ganacheAccounts = await this.getGanacheAddresses(); + } catch (e) { + console.log('Ganache is not running'); + } + + // Use web3 to get the user's accounts. + const accounts = await web3.eth.getAccounts(); + // Get the contract instance. + const networkId = await web3.eth.net.getId(); + const networkType = await web3.eth.net.getNetworkType(); + const isMetaMask = web3.currentProvider.isMetaMask; + let balance = accounts.length > 0 ? await web3.eth.getBalance(accounts[0]): web3.utils.toWei('0'); + balance = web3.utils.fromWei(balance, 'ether'); + + let instanceNewBancorPool = null; + let deployedNetwork = null; + + // Create instance of contracts + if (NewBancorPool.networks) { + deployedNetwork = NewBancorPool.networks[networkId.toString()]; + if (deployedNetwork) { + instanceNewBancorPool = new web3.eth.Contract( + NewBancorPool.abi, + deployedNetwork && deployedNetwork.address, + ); + console.log('=== instanceNewBancorPool ===', instanceNewBancorPool); + } + } + + if (NewBancorPool) { + // Set web3, accounts, and contract to the state, and then proceed with an + // example of interacting with the contract's methods. + this.setState({ + web3, + ganacheAccounts, + accounts, + balance, + networkId, + networkType, + hotLoaderDisabled, + isMetaMask, + new_bancor_pool: instanceNewBancorPool + }, () => { + this.refreshValues( + instanceNewBancorPool + ); + setInterval(() => { + this.refreshValues(instanceNewBancorPool); + }, 5000); + }); + } + else { + this.setState({ web3, ganacheAccounts, accounts, balance, networkId, networkType, hotLoaderDisabled, isMetaMask }); + } + } + } catch (error) { + // Catch any errors for any of the above operations. + alert( + `Failed to load web3, accounts, or contract. Check console for details.`, + ); + console.error(error); + } + } + + + + render() { + return ( + +
+ + + + + +

Swap Factory

+ + random unsplash image + +
+ +
+
+ + + + + + +
+
+ ); + } + +} diff --git a/client/src/components/Web3Info/Web3Info.module.scss b/client/src/components/Web3Info/Web3Info.module.scss new file mode 100755 index 0000000..ab81cee --- /dev/null +++ b/client/src/components/Web3Info/Web3Info.module.scss @@ -0,0 +1,35 @@ +@import '../../layout/variables.scss'; + +.web3 { + padding: 40px 0; + display: flex; + flex-flow: column wrap; + justify-content: flex-start; + align-items: flex-start; + width: 380px; + height: auto; + padding: 40px 20px; + border: 1px solid #ccc; + box-shadow: 0px 2px 2px #ccc; + + h3 { + border-bottom: 1px dotted #FFBE44; + padding-bottom: 5px; + } + + .dataPoint { + display: flex; + flex-flow: column nowrap; + align-items: flex-start; + margin: 5px 0; + width: 100%; + + .value { + font-weight: bold; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: baseline; + } + } +} diff --git a/client/src/components/Web3Info/index.js b/client/src/components/Web3Info/index.js new file mode 100755 index 0000000..047b852 --- /dev/null +++ b/client/src/components/Web3Info/index.js @@ -0,0 +1,64 @@ +import React, { Component } from "react"; +import { EthAddress, Blockie } from 'rimble-ui'; +import styles from './Web3Info.module.scss'; + +export default class Web3Info extends Component { + + renderNetworkName(networkId) { + switch (networkId) { + case 3: + return 'Ropsten'; + case 4: + return 'Rinkeby'; + case 1: + return 'Main'; + case 42: + return 'Kovan'; + default: + return 'Private'; + } + } + + render() { + const { networkId, accounts, balance, isMetaMask } = this.props; + return ( +
+

Your Web3 Info

+
+
+ Network: +
+
+ {networkId} - {this.renderNetworkName(networkId)} +
+
+
+
+ Your address: +
+
+ + +
+
+
+
+ Your ETH balance: +
+
+ {balance} +
+
+
+
+ Using Metamask: +
+
+ {isMetaMask ? 'YES' : 'NO'} +
+
+
+ ); + } +} diff --git a/client/src/index.js b/client/src/index.js new file mode 100755 index 0000000..edf6f79 --- /dev/null +++ b/client/src/index.js @@ -0,0 +1,12 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import './layout/index.scss'; +import App from './App'; +import * as serviceWorker from './serviceWorker'; + +ReactDOM.render(, document.getElementById('root')); + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: http://bit.ly/CRA-PWA +serviceWorker.unregister(); diff --git a/client/src/layout/index.scss b/client/src/layout/index.scss new file mode 100755 index 0000000..8b8334b --- /dev/null +++ b/client/src/layout/index.scss @@ -0,0 +1,207 @@ +@import './variables.scss'; + +html { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} + + +html, body { + overflow-x: hidden; +} + +body { + margin: 0; + padding: 0; + font: 112.5%/1.45em 'Roboto',sans-serif; + box-sizing: border-box; + overflow-y: scroll; + background: $white; + color: $primary; +} + +a { + color: $blue; + text-decoration: none; + cursor: pointer; + + &:hover { + text-decoration: underline; + } +} + +* { + box-sizing: inherit; +} +*:before { + box-sizing: inherit; +} +*:after { + box-sizing: inherit; +} + +body { + color: hsla(0, 0%, 0%, 0.8); + font-weight: normal; + word-wrap: break-word; + font-kerning: normal; + -moz-font-feature-settings: "kern", "liga", "clig", "calt"; + -ms-font-feature-settings: "kern", "liga", "clig", "calt"; + -webkit-font-feature-settings: "kern", "liga", "clig", "calt"; + font-feature-settings: "kern", "liga", "clig", "calt"; +} + +img { + max-width: 100%; + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 0; +} +h1 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-weight: bold; + text-rendering: optimizeLegibility; + line-height: 1.1; + font-size: 2em; + font-weight: 300; +} +h2 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 1.62671rem; + line-height: 1.1; +} +h3 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 1.38316rem; + line-height: 1.1; +} +h4 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 1rem; + line-height: 1.1; +} +h5 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 0.85028rem; + line-height: 1.1; +} +h6 { + margin-left: 0; + margin-right: 0; + margin-top: 0; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + padding-top: 0; + margin-bottom: 1.45rem; + color: inherit; + font-weight: bold; + text-rendering: optimizeLegibility; + font-size: 0.78405rem; + line-height: 1.1; +} + +button { + box-shadow: none; + outline: none; + color: $white; + padding: 10px 15px; + border: 1px solid $white; + font-size: 16px; + font-weight: 400; + cursor: pointer; + + &.purple { + background: $primary; + &:hover { + background: $white; + color: $primary; + border-color: $primary; + } + } + + &.yellow { + background: $yellow; + &:hover { + background: $white; + color: $yellow; + border-color: $yellow; + } + } + + &.pink { + background: $pink; + &:hover { + background: $white; + color: $pink; + border-color: $pink; + } + } +} + +input { + width: 100%; + border: 1px solid #ccc; + padding: 5px; + color: $primary; + margin: 5px 0; +} + +@media only screen and (max-width: 480px) { + html { + font-size: 100%; + } +} diff --git a/client/src/layout/variables.scss b/client/src/layout/variables.scss new file mode 100755 index 0000000..98b427c --- /dev/null +++ b/client/src/layout/variables.scss @@ -0,0 +1,21 @@ +// Colors +$primary: #3C4653; +$blue: #39e6e0; +$purple: #4420D8; +$purple-aux: #917DFF; +$yellow: #FFBE44; +$pink: #FF2972; +$white: #FFF; +$black: #000; + +// Fonts (use typography.js) +$font-size-base: 16px; +$font-size-h1: 3.375em; +// $font-family-sans-serif: 'Open Sans', sans-serif; +$line-height-base: 1.42; + +// Responsive +$screen-xs: 576px; +$screen-sm-min: 768px; +$screen-sm-max: 992px; +$screen-md-max: 1280px; diff --git a/client/src/routes.js b/client/src/routes.js new file mode 100755 index 0000000..53eee5d --- /dev/null +++ b/client/src/routes.js @@ -0,0 +1,87 @@ +/*! + +========================================================= +* Light Bootstrap Dashboard React - v1.3.0 +========================================================= + +* Product Page: https://www.creative-tim.com/product/light-bootstrap-dashboard-react +* Copyright 2019 Creative Tim (https://www.creative-tim.com) +* Licensed under MIT (https://github.com/creativetimofficial/light-bootstrap-dashboard-react/blob/master/LICENSE.md) + +* Coded by Creative Tim + +========================================================= + +* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +*/ +import Dashboard from "./views/Dashboard.jsx"; +import UserProfile from "./views/UserProfile.jsx"; +import TableList from "./views/TableList.jsx"; +import Typography from "./views/Typography.jsx"; +import Icons from "./views/Icons.jsx"; +import Maps from "./views/Maps.jsx"; +import Notifications from "./views/Notifications.jsx"; +import Upgrade from "./views/Upgrade.jsx"; + +const dashboardRoutes = [ + { + path: "/dashboard", + name: "Dashboard", + icon: "pe-7s-graph", + component: Dashboard, + layout: "/admin" + }, + { + path: "/user", + name: "User Profile", + icon: "pe-7s-user", + component: UserProfile, + layout: "/admin" + }, + { + path: "/table", + name: "Table List", + icon: "pe-7s-note2", + component: TableList, + layout: "/admin" + }, + { + path: "/typography", + name: "Typography", + icon: "pe-7s-news-paper", + component: Typography, + layout: "/admin" + }, + { + path: "/icons", + name: "Icons", + icon: "pe-7s-science", + component: Icons, + layout: "/admin" + }, + { + path: "/maps", + name: "Maps", + icon: "pe-7s-map-marker", + component: Maps, + layout: "/admin" + }, + { + path: "/notifications", + name: "Notifications", + icon: "pe-7s-bell", + component: Notifications, + layout: "/admin" + }, + { + upgrade: true, + path: "/upgrade", + name: "Upgrade to PRO", + icon: "pe-7s-rocket", + component: Upgrade, + layout: "/admin" + } +]; + +export default dashboardRoutes; diff --git a/client/src/serviceWorker.js b/client/src/serviceWorker.js new file mode 100755 index 0000000..2283ff9 --- /dev/null +++ b/client/src/serviceWorker.js @@ -0,0 +1,135 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read http://bit.ly/CRA-PWA + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.1/8 is considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +export function register(config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit http://bit.ly/CRA-PWA' + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl, config) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl, config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type'); + if ( + response.status === 404 || + (contentType != null && contentType.indexOf('javascript') === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister(); + }); + } +} diff --git a/client/src/utils/getWeb3.js b/client/src/utils/getWeb3.js new file mode 100755 index 0000000..e76055d --- /dev/null +++ b/client/src/utils/getWeb3.js @@ -0,0 +1,61 @@ +import Web3 from "web3"; +// require('dotenv').config(); +// const INFURA_API_KEY = process.env.INFURA_API_KEY; + +//const FALLBACK_WEB3_PROVIDER = process.env.REACT_APP_NETWORK || 'https://rinkeby.infura.io/v3/' + INFURA_API_KEY; // Rinkeby +const FALLBACK_WEB3_PROVIDER = process.env.REACT_APP_NETWORK || 'http://0.0.0.0:7545'; // Ganache-GUI +//const FALLBACK_WEB3_PROVIDER = process.env.REACT_APP_NETWORK || 'http://0.0.0.0:8545'; + + +const getWeb3 = () => + new Promise((resolve, reject) => { + // Wait for loading completion to avoid race conditions with web3 injection timing. + window.addEventListener("load", async () => { + // Modern dapp browsers... + if (window.ethereum) { + const web3 = new Web3(window.ethereum); + try { + // Request account access if needed + await window.ethereum.enable(); + // Acccounts now exposed + resolve(web3); + } catch (error) { + reject(error); + } + } + // Legacy dapp browsers... + else if (window.web3) { + // Use Mist/MetaMask's provider. + const web3 = window.web3; + console.log("Injected web3 detected."); + resolve(web3); + } + // Fallback to localhost; use dev console port by default... + else { + const provider = new Web3.providers.HttpProvider( + FALLBACK_WEB3_PROVIDER + ); + const web3 = new Web3(provider); + console.log("No web3 instance injected, using Infura/Local web3."); + resolve(web3); + } + }); + }); + +const getGanacheWeb3 = () => { + const isProd = process.env.NODE_ENV === 'production'; + if (isProd) { + return null; + } + const provider = new Web3.providers.HttpProvider( + //'https://rinkeby.infura.io/v3/' + INFURA_API_KEY // Rinkeby + 'http://0.0.0.0:7545' // Ganache-GUI + //'http://0.0.0.0:8545' // Ganache-CLI + ); + const web3 = new Web3(provider); + console.log("No local ganache found."); + return web3; +} + +export default getWeb3; +export { getGanacheWeb3, Web3 }; diff --git a/client/src/utils/theme.js b/client/src/utils/theme.js new file mode 100755 index 0000000..d57d9dc --- /dev/null +++ b/client/src/utils/theme.js @@ -0,0 +1,18 @@ +import green from '@material-ui/core/colors/green'; +import blueGrey from '@material-ui/core/colors/blueGrey'; +import { createMuiTheme } from '@material-ui/core/styles'; + +export const theme = createMuiTheme({ + palette: { + primary: { + dark: blueGrey[900], + light: blueGrey[600], + main: blueGrey[800], + }, + secondary: { + dark: green[900], + light: green[500], + main: green[800], + }, + }, +}); diff --git a/scripts/compile.sh b/scripts/bancor-protocol/compile.sh similarity index 100% rename from scripts/compile.sh rename to scripts/bancor-protocol/compile.sh diff --git a/scripts/deploy-one.js b/scripts/bancor-protocol/deploy-one.js similarity index 100% rename from scripts/deploy-one.js rename to scripts/bancor-protocol/deploy-one.js diff --git a/scripts/fix-modules.js b/scripts/bancor-protocol/fix-modules.js similarity index 100% rename from scripts/fix-modules.js rename to scripts/bancor-protocol/fix-modules.js diff --git a/scripts/flatten.js b/scripts/bancor-protocol/flatten.js similarity index 100% rename from scripts/flatten.js rename to scripts/bancor-protocol/flatten.js diff --git a/scripts/rebuild-all.js b/scripts/bancor-protocol/rebuild-all.js similarity index 100% rename from scripts/rebuild-all.js rename to scripts/bancor-protocol/rebuild-all.js diff --git a/scripts/run-tests.js b/scripts/bancor-protocol/run-tests.js similarity index 100% rename from scripts/run-tests.js rename to scripts/bancor-protocol/run-tests.js diff --git a/scripts/verify-all.js b/scripts/bancor-protocol/verify-all.js similarity index 100% rename from scripts/verify-all.js rename to scripts/bancor-protocol/verify-all.js diff --git a/test/BancorConverter.js b/test/bancor-protocol/BancorConverter.js similarity index 100% rename from test/BancorConverter.js rename to test/bancor-protocol/BancorConverter.js diff --git a/test/BancorConverterRegistry.js b/test/bancor-protocol/BancorConverterRegistry.js similarity index 100% rename from test/BancorConverterRegistry.js rename to test/bancor-protocol/BancorConverterRegistry.js diff --git a/test/BancorConverterRegistryData.js b/test/bancor-protocol/BancorConverterRegistryData.js similarity index 100% rename from test/BancorConverterRegistryData.js rename to test/bancor-protocol/BancorConverterRegistryData.js diff --git a/test/BancorConverterUpgrader.js b/test/bancor-protocol/BancorConverterUpgrader.js similarity index 100% rename from test/BancorConverterUpgrader.js rename to test/bancor-protocol/BancorConverterUpgrader.js diff --git a/test/BancorFormula.js b/test/bancor-protocol/BancorFormula.js similarity index 100% rename from test/BancorFormula.js rename to test/bancor-protocol/BancorFormula.js diff --git a/test/BancorNetwork.js b/test/bancor-protocol/BancorNetwork.js similarity index 100% rename from test/BancorNetwork.js rename to test/bancor-protocol/BancorNetwork.js diff --git a/test/BancorNetworkPathFinder.js b/test/bancor-protocol/BancorNetworkPathFinder.js similarity index 100% rename from test/BancorNetworkPathFinder.js rename to test/bancor-protocol/BancorNetworkPathFinder.js diff --git a/test/BancorNetworkWithOldConverter.js b/test/bancor-protocol/BancorNetworkWithOldConverter.js similarity index 100% rename from test/BancorNetworkWithOldConverter.js rename to test/bancor-protocol/BancorNetworkWithOldConverter.js diff --git a/test/BancorX.js b/test/bancor-protocol/BancorX.js similarity index 100% rename from test/BancorX.js rename to test/bancor-protocol/BancorX.js diff --git a/test/ContractFeatures.js b/test/bancor-protocol/ContractFeatures.js similarity index 100% rename from test/ContractFeatures.js rename to test/bancor-protocol/ContractFeatures.js diff --git a/test/ContractRegistry.js b/test/bancor-protocol/ContractRegistry.js similarity index 100% rename from test/ContractRegistry.js rename to test/bancor-protocol/ContractRegistry.js diff --git a/test/CrowdsaleController.js b/test/bancor-protocol/CrowdsaleController.js similarity index 100% rename from test/CrowdsaleController.js rename to test/bancor-protocol/CrowdsaleController.js diff --git a/test/ERC20Token.js b/test/bancor-protocol/ERC20Token.js similarity index 100% rename from test/ERC20Token.js rename to test/bancor-protocol/ERC20Token.js diff --git a/test/EtherToken.js b/test/bancor-protocol/EtherToken.js similarity index 100% rename from test/EtherToken.js rename to test/bancor-protocol/EtherToken.js diff --git a/test/Managed.js b/test/bancor-protocol/Managed.js similarity index 100% rename from test/Managed.js rename to test/bancor-protocol/Managed.js diff --git a/test/Owned.js b/test/bancor-protocol/Owned.js similarity index 100% rename from test/Owned.js rename to test/bancor-protocol/Owned.js diff --git a/test/SafeMath.js b/test/bancor-protocol/SafeMath.js similarity index 100% rename from test/SafeMath.js rename to test/bancor-protocol/SafeMath.js diff --git a/test/SmartToken.js b/test/bancor-protocol/SmartToken.js similarity index 100% rename from test/SmartToken.js rename to test/bancor-protocol/SmartToken.js diff --git a/test/SmartTokenController.js b/test/bancor-protocol/SmartTokenController.js similarity index 100% rename from test/SmartTokenController.js rename to test/bancor-protocol/SmartTokenController.js diff --git a/test/TokenHolder.js b/test/bancor-protocol/TokenHolder.js similarity index 100% rename from test/TokenHolder.js rename to test/bancor-protocol/TokenHolder.js diff --git a/test/Whitelist.js b/test/bancor-protocol/Whitelist.js similarity index 100% rename from test/Whitelist.js rename to test/bancor-protocol/Whitelist.js diff --git a/test/XConversions.js b/test/bancor-protocol/XConversions.js similarity index 100% rename from test/XConversions.js rename to test/bancor-protocol/XConversions.js diff --git a/test/XTransferRerouter.js b/test/bancor-protocol/XTransferRerouter.js similarity index 100% rename from test/XTransferRerouter.js rename to test/bancor-protocol/XTransferRerouter.js diff --git a/test/bin/bancor_converter_v10.abi b/test/bancor-protocol/bin/bancor_converter_v10.abi similarity index 100% rename from test/bin/bancor_converter_v10.abi rename to test/bancor-protocol/bin/bancor_converter_v10.abi diff --git a/test/bin/bancor_converter_v10.bin b/test/bancor-protocol/bin/bancor_converter_v10.bin similarity index 100% rename from test/bin/bancor_converter_v10.bin rename to test/bancor-protocol/bin/bancor_converter_v10.bin diff --git a/test/bin/bancor_converter_v11.abi b/test/bancor-protocol/bin/bancor_converter_v11.abi similarity index 100% rename from test/bin/bancor_converter_v11.abi rename to test/bancor-protocol/bin/bancor_converter_v11.abi diff --git a/test/bin/bancor_converter_v11.bin b/test/bancor-protocol/bin/bancor_converter_v11.bin similarity index 100% rename from test/bin/bancor_converter_v11.bin rename to test/bancor-protocol/bin/bancor_converter_v11.bin diff --git a/test/bin/bancor_converter_v4.abi b/test/bancor-protocol/bin/bancor_converter_v4.abi similarity index 100% rename from test/bin/bancor_converter_v4.abi rename to test/bancor-protocol/bin/bancor_converter_v4.abi diff --git a/test/bin/bancor_converter_v4.bin b/test/bancor-protocol/bin/bancor_converter_v4.bin similarity index 100% rename from test/bin/bancor_converter_v4.bin rename to test/bancor-protocol/bin/bancor_converter_v4.bin diff --git a/test/bin/bancor_converter_v9.abi b/test/bancor-protocol/bin/bancor_converter_v9.abi similarity index 100% rename from test/bin/bancor_converter_v9.abi rename to test/bancor-protocol/bin/bancor_converter_v9.abi diff --git a/test/bin/bancor_converter_v9.bin b/test/bancor-protocol/bin/bancor_converter_v9.bin similarity index 100% rename from test/bin/bancor_converter_v9.bin rename to test/bancor-protocol/bin/bancor_converter_v9.bin diff --git a/test/helpers/BancorConverter.js b/test/bancor-protocol/helpers/BancorConverter.js similarity index 100% rename from test/helpers/BancorConverter.js rename to test/bancor-protocol/helpers/BancorConverter.js diff --git a/test/helpers/ContractRegistryClient.js b/test/bancor-protocol/helpers/ContractRegistryClient.js similarity index 100% rename from test/helpers/ContractRegistryClient.js rename to test/bancor-protocol/helpers/ContractRegistryClient.js diff --git a/test/helpers/FormulaConstants.js b/test/bancor-protocol/helpers/FormulaConstants.js similarity index 100% rename from test/helpers/FormulaConstants.js rename to test/bancor-protocol/helpers/FormulaConstants.js diff --git a/test/helpers/Utils.js b/test/bancor-protocol/helpers/Utils.js similarity index 100% rename from test/helpers/Utils.js rename to test/bancor-protocol/helpers/Utils.js diff --git a/utils/README.md b/utils/bancor-protocol/README.md similarity index 100% rename from utils/README.md rename to utils/bancor-protocol/README.md diff --git a/utils/deploy_network_emulation.js b/utils/bancor-protocol/deploy_network_emulation.js similarity index 100% rename from utils/deploy_network_emulation.js rename to utils/bancor-protocol/deploy_network_emulation.js diff --git a/utils/migrate_converter_registry_1.js b/utils/bancor-protocol/migrate_converter_registry_1.js similarity index 100% rename from utils/migrate_converter_registry_1.js rename to utils/bancor-protocol/migrate_converter_registry_1.js diff --git a/utils/migrate_converter_registry_2.js b/utils/bancor-protocol/migrate_converter_registry_2.js similarity index 100% rename from utils/migrate_converter_registry_2.js rename to utils/bancor-protocol/migrate_converter_registry_2.js diff --git a/utils/retrieve_contract_version.js b/utils/bancor-protocol/retrieve_contract_version.js similarity index 100% rename from utils/retrieve_contract_version.js rename to utils/bancor-protocol/retrieve_contract_version.js diff --git a/utils/verify_network_path_finder.js b/utils/bancor-protocol/verify_network_path_finder.js similarity index 100% rename from utils/verify_network_path_finder.js rename to utils/bancor-protocol/verify_network_path_finder.js