Commit ab891d1b authored by Hayden Adams's avatar Hayden Adams

first demo release

parent 65b3660b
{
"name": "hello-world",
"name": "uniswap",
"homepage": "https://haydenadams.github.io/uniswap/",
"version": "0.1.0",
"private": true,
"dependencies": {
......@@ -7,12 +8,17 @@
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-scripts": "1.0.14",
"react-web3": "^0.4.3",
"web3": "^1.0.0-beta.23"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"deploy": "npm run build&&gh-pages -d build"
},
"devDependencies": {
"gh-pages": "^1.0.0"
}
}
pragma solidity 0.4.18;
/// @title SafeMath
/// @dev Math operations with safety checks that throw on error
library SafeMath {
/// @dev Multiplies a times b
function mul(uint256 a, uint256 b)
internal
constant
returns (uint256)
{
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
/// @dev Divides a by b
function div(uint256 a, uint256 b)
internal
constant
returns (uint256)
{
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/// @dev Subtracts a from b
function sub(uint256 a, uint256 b)
internal
constant
returns (uint256)
{
assert(b <= a);
return a - b;
}
/// @dev Adds a to b
function add(uint256 a, uint256 b)
internal
constant
returns (uint256)
{
uint256 c = a + b;
assert(c >= a);
return c;
}
}
......@@ -7,30 +7,78 @@
font-family: Optima, sans-serif;
}
.App-header {
height: 1px;
color: rgb(209, 151, 245);
text-shadow: 2.5px 2px 6px #ff78e5;
font-family: Optima, sans-serif;
}
.App-title {
.title {
position: fixed;
font-size: 8vh;
font-size: 9vh;
margin-top: 1vh;
margin-left: 2vh;
float: left;
padding-left: 2vh;
text-shadow: 3px 3px 10px #f29ae1;
color: rgb(220, 173, 247);
font-weight: bold;
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: rgb(180, 81, 179);
}.title:hover{
color: rgb(122, 251, 255);
text-shadow: 3px 3px 10px #2daae0;
font-weight: bold;
-webkit-text-stroke-width: 2px;
-webkit-text-stroke-color: rgb(22, 177, 210);
}
/* entire container, keeps perspective */
.titled-container {
perspective: 1000px;
}
/* flip the pane when hovered */
.titled-container:hover .title, .titled-container.hover .title {
transform: rotateX(180deg);
}
.titled-container, .front, .back {
width: 1vh;
height: 0.1vh;
}
/* flip speed goes here */
.title {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
/* hide back of pane during swap */
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
/* front pane, placed above back */
.front {
z-index: 2;
/* for firefox 31 */
transform: rotateX(0deg);
}
/* back, initially hidden pane */
.back {
transform: rotateX(180deg);
}
.ethLogo {
position: fixed;
right: 25vh;
z-index: 0;
right: 22vh;
position: fixed;
height: 12vh;
height: 10vh;
z-index: 1;
padding-top: 11px;
padding-right: 12px;
opacity: 0.8;
margin-top: 1vh;
margin-right: 5vh;
opacity: 0.6;
-webkit-filter: invert(.8);
filter: invert(.8);
-moz-user-select: -moz-none;
......@@ -48,7 +96,7 @@
clear: both;
z-index: 1;
height:25vh;
opacity: 0.85;
opacity: 0.75;
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
......@@ -58,81 +106,199 @@
opacity: 1;
}
.Warning {
position: fixed;
z-index: 3;
font-size: 16px;
text-align: center;
left: 35vw;
/*color: rgb(122, 251, 255);
text-shadow: 2px 2px 10px #2daae0;*/
color: rgb(238, 0, 0);
text-shadow: 2px 2px 10px #2daae0;
}
.Account-info {
position: relative;
position: fixed;
z-index: 2;
font-size: 15px;
text-align: left;
font-size: 14px;
top: 60px;
left: 40vw;
color: rgb(122, 251, 255);
text-shadow: 2px 2px 6px #2daae0;
padding-top: 37px;
padding-left: 27em;
text-shadow: 2px 2px 10px #2daae0;
width: 35vw;
}.Account-info:hover{
color: rgb(209, 151, 245);
text-shadow: 2px 2px 10px #ff69f0;
}
.Approval{
font-size: 15px;
.pinkText {
position: fixed;
z-index: 3;
color: rgb(216, 169, 236);
text-shadow: 1px 1px 5px #ff69f0;
text-align: left;
}.pinkText:hover{
color: rgb(122, 251, 255);
text-shadow: 2px 2px 6px #2daae0;
padding-left: 27em;
text-shadow: 2px 2px 10px #2daae0;
}
.Buy{
font-size: 15px;
.greenText {
z-index: 2;
color: rgb(122, 251, 255);
text-shadow: 2px 2px 10px #1c5f7c;
text-align: left;
}.greenText:hover{
color: rgb(220, 160, 245);
text-shadow: 1px 1px 5px #ff69f0;
}
.Approval{
position:fixed;
z-index: 3;
font-size: 15px;
color: rgb(122, 251, 255);
right: 10vw;
top: 30vh;
margin-left: 40vw;
text-shadow: 2px 2px 6px #2daae0;
padding-left: 27em;
}
.approveZero {
background-color: rgba(209, 151, 245, 0.25);
font-size: 14px;
/*text-shadow: 1px 1px 6px #2daae0;*/
font-family: Optima, sans-serif;
font-weight: bolder;
border-radius: 2px;
padding: 2px 4px;
color: rgb(122, 251, 255);
border: 2px solid rgb(122, 251, 255);
-webkit-transition-duration: 0.5s;
transition-duration: 0.5s;
}.approveZero:hover {
background-color: rgba(122, 251, 255, 0.15);
color: rgb(209, 151, 245);
border: 2px solid rgb(209, 151, 245);
/*text-shadow: 0px, 0px, 0px #fff;*/
/*text-shadow: 1px 1px 6px #ff78e5;*/
.approveButton {
position: fixed;
background-color: rgba(209, 151, 245, 0.25);
font-size: 18px;
/*text-shadow: 1px 1px 6px #2daae0;*/
font-family: Optima, sans-serif;
font-weight: bolder;
border-radius: 8px;
padding: 4px 8px;
color: rgb(122, 251, 255);
border: 2px solid rgb(122, 251, 255);
-webkit-transition-duration: 0.5s;
transition-duration: 0.5s;
}.approveButton:hover {
background-color: rgba(122, 251, 255, 0.15);
color: rgb(209, 151, 245);
border: 2px solid rgb(209, 151, 245);
cursor: pointer;
}
.buyButton {
padding: 10px;
.exchange {
position: fixed;
font-family: Optima, sans-serif;
font-size: 18px;
color: rgb(122, 251, 255);
text-shadow: 2px 2px 10px #2daae0;
}
.buyInput {
font-family: Optima, sans-serif;
font-size: 14px;
width: 100px;
height: 20px;
.exchange-buyTokensButton {
position: fixed;
float: left;
bottom: 74vh;
margin-left: 35vw;
}
.exchange-buyEthButton {
position: fixed;
float: left;
bottom: 74vh;
margin-left: 60vw;
}
.exchange-buyTokensInput {
width: 110px;
height: 30px;
text-align: center;
color: rgb(209, 151, 245);
vertical-align: middle;
border: 2px solid rgba(209, 151, 245, .15);
border: 1px solid rgba(180, 81, 179, 0.55);
background-color: rgba(122, 251, 255, 0.15);
border-radius: 8px 0 0 8px;
font-size: 18px;
font-family: Optima, sans-serif;
}
input[type="button"] {
font-family: Optima, sans-serif;
font-size: 14px;
width: 50px;
margin-top: 10px;
height: 26px;
background-color: rgba(209, 151, 245, 0.15);
.exchange-buyEthInput {
width: 110px;
height: 30px;
text-align: center;
color: rgb(209, 151, 245);
vertical-align: middle;
margin-top: -1px;
border: 2px solid rgb(209, 151, 245);
}.input[type="button"]:hover{
color: rgb(209, 151, 245);
border: 1px solid rgba(180, 81, 179, 0.55);
border-radius: 8px 0 0 8px;
background-color: rgba(122, 251, 255, 0.15);
font-size: 18px;
font-family: Optima, sans-serif;
}
.exchange-buyEthInputButton, .exchange-buyTokensInputButton{
position: fixed;
font-size: 20px;
width: 90px;
text-shadow: 3px 3px 10px #1c5f7c;
margin-top: 10px;
height: 30px;
text-align: center;
color: rgb(220, 160, 245);
text-shadow: 1px 1px 5px #ff69f0;
background-color: rgba(126, 228, 255, 0.26);
vertical-align: middle;
margin-top: 1px;
border: 1px solid rgb(180, 81, 179);
border-radius: 0 8px 8px 0;
font-family: Optima, sans-serif;
}.exchange-buyEthInputButton:hover, .exchange-buyTokensInputButton:hover{
cursor: pointer;
color: rgb(220, 173, 247);
background-color: rgba(209, 151, 245, 0.6);
}
.instructions {
position: fixed;
background-color: rgba(0,0,0,0.4);
bottom: 1vh;
border-radius: 15px;
border: 1px solid rgb(180, 81, 179);
color: rgb(122, 251, 255);
text-shadow: 2px 2px 10px #2daae0;
margin-left: 35vw;
margin-right: 1vw;
} .instructions:hover{
color: rgb(216, 169, 236);
text-shadow: 1px 1px 5px #ff69f0;
}
.instructions-title {
text-align: left;
padding-left: 40px;
padding-top: 10px;
font-size: 22px;
}
.instructions-text {
font-size: 15px;
padding-top: 10px;
text-align: left;
padding-left: 25px;
padding-right: 15px;
}
a:visited {
color: rgb(122, 251, 255);
}
a:link {
color: rgb(122, 251, 255);
}
a:hover {
color: rgb(216, 169, 236);
text-shadow: 1px 1px 5px #ff69f0;
}
.instructions-link {
padding-top: 14px;
text-align: left;
}
......@@ -3,12 +3,14 @@ import unicorn from './images/unicornNoBackground.png';
import ethLogo from './images/ethLogo.png';
import './App.css';
var uniswapABI = [{"constant":false,"inputs":[{"name":"tokenAmount","type":"uint256"}],"name":"ownerTokenWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"ethAmount","type":"uint256"}],"name":"ownerEthWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sellQuantity","type":"uint256"},{"name":"minimumEth","type":"uint256"},{"name":"timeout","type":"uint256"}],"name":"tokenToEth","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalTokenQuantity","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"minimumTokens","type":"uint256"},{"name":"timeout","type":"uint256"}],"name":"ethToTokens","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"initialTokenQuantity","type":"uint256"}],"name":"initiateUniswap","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalEthQuantity","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"invariant","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_tokenAddress","type":"address"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"buyer","type":"address"},{"indexed":false,"name":"tokensPurchased","type":"uint256"},{"indexed":false,"name":"ethSpent","type":"uint256"}],"name":"TokenPurchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"buyer","type":"address"},{"indexed":false,"name":"ethPurchased","type":"uint256"},{"indexed":false,"name":"tokensSpent","type":"uint256"}],"name":"EthPurchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]
var uniswapAddress = '0xe52dd7e4c3652600bc6daf601e5a0eea2b072597';
var uniswapAddress = '0x827642f7f022bd74294fd62c1f02a07f3d4ff2bd';
var uniswapContract = window.web3.eth.contract(uniswapABI).at(uniswapAddress);
var tokenABI = [{"constant":true,"inputs":[],"name":"mintingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"finishMinting","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[],"name":"MintFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]
var tokenAddress = '0x8e2183e0Ac73e6FBd1F9E0fAb24368728f978092';
var tokenAddress = '0xca9901076d02f89794262869aad1340bd45d8489';
var tokenContract = window.web3.eth.contract(tokenABI).at(tokenAddress);
/*
......@@ -31,37 +33,74 @@ tokenContract.allEvents((error, event) => {
class App extends Component {
constructor(props){
super(props)
this.state = {ethBalance: null,
tokenBalance: null,
this.state = {ethBalance: 0,
tokenBalance: 0,
tokenAllowance: null,
currentMaskAddress: window.web3.eth.accounts[0],
minimumTokensPurchased: null,
minimumEthPurchased: null,
invariant: null,
marketEth: null,
marketTokens: null
marketTokens: null,
tokenBuyRate: 0,
ethBuyRate: 0,
tokenCost: 0, //eth price of tokens
ethCost: 0, //token price of eth
tokenFee: 0,
ethFee: 0,
tokenBuyError: '',
ethBuyError: '',
networkMessage: ''
}
this.buyTokens = this.buyTokens.bind(this);
this.onInputChange = this.onInputChange.bind(this);
this.onBuyEthInputChange = this.onBuyEthInputChange.bind(this);
this.onBuyTokensInputChange = this.onBuyTokensInputChange.bind(this);
this.tokenBuyRate = this.tokenBuyRate.bind(this);
this.ethBuyRate = this.ethBuyRate.bind(this);
}
componentWillMount(){
}
componentDidMount(){
this.checkNetwork();
this.getMaskAddress();
this.getInvarient();
this.getMarketEth();
this.getMarketTokens();
this.getEthBalance();
this.getTokenBalance();
this.getAllowance();
}
componentDidMount(){
this.tokenBuyRate(1);
this.ethBuyRate(0.5);
}
checkNetwork() {
var self = this;
window.web3.version.getNetwork((err, netId) => {
switch (netId) {
case "1":
console.log('This is mainnet')
self.setState({networkMessage: 'Connected to Ethereum Mainet, please switch to Rinkeby and refresh'});
break
case "2":
console.log('This is the deprecated Morden test network.')
self.setState({networkMessage: 'Connected to Morden testnet, please switch to Rinkeby and refresh'});
break
case "3":
self.setState({networkMessage: 'Connected to Ropstein testnet, please switch to Rinkeby and refresh'})
break
default:
console.log('This is an unknown network.')
}
})
}
approveAllowance(value) {
console.log('oh shit waddup');
tokenContract.approve(uniswapAddress, value, function(error, balance) {
console.log(balance);
});
......@@ -105,7 +144,7 @@ class App extends Component {
uniswapContract.invariant.call(function(err, value){
var number = value.toNumber();
console.log("invariant: " + number/(10**24));
//console.log("invariant: " + number/(10**24));
self.setState({invariant: number});
});
}
......@@ -115,7 +154,7 @@ class App extends Component {
uniswapContract.totalEthQuantity.call(function(err, value){
var number = value.toNumber();
console.log("marketEthQuantity: " + number/(10**18));
//console.log("marketEthQuantity: " + number/(10**18));
self.setState({marketEth: number});
});
}
......@@ -125,33 +164,104 @@ class App extends Component {
uniswapContract.totalTokenQuantity.call(function(err, value){
var number = value.toNumber();
console.log("marketTokenQuantity: " + number/(10**6));
//console.log("marketTokenQuantity: " + number/(10**6));
self.setState({marketTokens: number});
});
}
buyTokens() {
var self = this;
var minTokens = this.state.minimumTokensPurchased
window.web3.eth.getBlock('latest', function(error, blockInfo) {
var time = blockInfo.timestamp;
var maxTime = time + 300; //current block time + 5mins
uniswapContract.ethToTokens.sendTransaction(minTokens, maxTime, {
from: window.web3.eth.coinbase,
value:window.web3.toWei('1','ether') }, function(err, txHash) {});
uniswapContract.ethToTokens.sendTransaction(minTokens, maxTime,
{from: window.web3.eth.coinbase, value:window.web3.toWei(self.state.tokenCost,'ether') },
function(err, txHash) {}
);
});
}
sellTokens() {
//purchase will go through if the amount of ETH is received is within 10%
//this is will be changed by full release, and will be a selectable range
var minEth = this.state.minimumEthPurchased*0.9;
var tokensSold = this.state.ethCost;
window.web3.eth.getBlock('latest', function(error, blockInfo) {
var time = blockInfo.timestamp;
var maxTime = time + 300; //current block time + 5mins
uniswapContract.tokenToEth.sendTransaction(tokensSold, minEth, maxTime, {
from: window.web3.eth.coinbase}, function(err, txHash) {}
);
});
}
onBuyTokensInputChange(event) {
var buyTokensInput = event.target.value;
if(buyTokensInput && buyTokensInput !== 0){
this.setState({ minimumTokensPurchased: buyTokensInput });
this.tokenBuyRate(buyTokensInput);
}
}
onBuyEthInputChange(event) {
var buyEthInput = event.target.value;
if(buyEthInput && buyEthInput !== 0){
this.setState({ minimumEthPurchased: buyEthInput });
this.ethBuyRate(buyEthInput);
}
}
//
//uniswapContract.ethToTokens(minTokens)
tokenBuyRate(buyTokensInput) {
if(buyTokensInput >= this.state.marketTokens/10**6) {
this.setState({tokenBuyRate: 0,
tokenCost: 0,
tokenFee: 0,
tokenBuyError: 'Not enough tokens'
});
}
else{
var tokensPurchased = buyTokensInput;
var invar = this.state.invariant/10**24;
var totalTokens = this.state.marketTokens/10**6;
var totalEth = this.state.marketEth/10**18;
var newTotalEth = invar/(totalTokens-tokensPurchased);
var fee = (newTotalEth - totalEth)/500;
var ethRequired = newTotalEth - totalEth + fee;
var rate = tokensPurchased/ethRequired;
this.setState({tokenBuyRate: rate,
tokenCost: ethRequired,
tokenFee: fee
});
}
}
onInputChange(event) {
this.setState({ minimumTokensPurchased: event.target.value });
ethBuyRate(buyEthInput) {
if(buyEthInput >= this.state.marketEth/10**18) {
this.setState({ethBuyRate: 0,
ethCost: 0,
ethFee: 0,
ethBuyError: 'Not enough tokens'
});
}
else{
var ethPurchased = buyEthInput;
var invar = this.state.invariant/10**24;
var totalEth = this.state.marketEth/10**18;
var totalTokens = this.state.marketTokens/10**6;
var newTotalTokens = invar/(totalEth-ethPurchased);
var fee = (newTotalTokens - totalTokens)/500;
var tokensRequired = newTotalTokens - totalTokens + fee;
var rate = ethPurchased/tokensRequired;
this.setState({ethBuyRate: rate,
ethCost: tokensRequired,
ethFee: fee
});
}
}
......@@ -172,29 +282,70 @@ class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">UNISWAP</h1>
<img src={unicorn} className="unicorn" alt="unicorn"/>
<img src={ethLogo} className="ethLogo" alt = "ethLogo"/>
</header>
<div className="Account-info">
Address: {this.state.currentMaskAddress}<br />
Ether: {this.state.ethBalance} ETH &nbsp;
Tokens: {this.state.tokenBalance} UNT
<div className="titled-container">
<div className="title">
<div className="front">UNISWAP</div>
<div className="back">UNISWAP</div>
</div>
</div>
<img src={unicorn} className="unicorn" alt="unicorn"/>
<img src={ethLogo} className="ethLogo" alt = "ethLogo"/>
<div className="Warning">{this.state.networkMessage}</div>
<div className="Account-info">
Address : {this.state.currentMaskAddress}<br />
Ether : {this.state.ethBalance} ETH &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Tokens: {this.state.tokenBalance.toFixed(2)} UNI<br/>
</div>
<div className="instructions">
<div className="instructions-title">Instructions and Stuff</div>
<div className="instructions-text">
1) Add UNI test token address to MetaMask (first time only)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;Token Address: <i>{tokenAddress}</i><br/><br/>
2) Check that MetaMask is connected to the Rinkeby Testnet<br/><br/>
3) You can now buy UNI test tokens with ETH! Visit the&nbsp;
<span className="instructions-link"><a href= "https://faucet.rinkeby.io/">Rinkeby faucet</a></span> to aquire testnet ETH <br/><br/>
4) To buy ETH with UNI you must approve the Uniswap smart contract to transfer UNI tokens on your behalf. Click the "Approve" button now! (first time only)<br/><br/>
5) Rate is variable based on token availiblity, enter number of tokens to see rate and cost.<br/><br/>
6) This is a proof-of-concept for a decentralized Market Maker exchange. Stay tuned for token-to-token pairs, the ability to become a Market Creator and collect fees,
and a Mainet launch! :) <br/> <br/>
7) This demo was hastily programmed by a single developer <i>(Hi, my name is Hayden!)</i>. Please reach out to me with any questions, comments, complaints, or bug reports.<br/><br/>
&nbsp;&nbsp;Email: hayden@uniswap.io &nbsp;&nbsp; GitHub: https://github.com/haydenadams/uniswap<br/>
&nbsp;&nbsp;ETH Address: 0x4779721CaC18A46DbCF148f2Dd7A8E6cc1F90078<br/><br/>
</div>
<div className="Approval">
Tokens approved: {this.state.tokenAllowance}&nbsp;&nbsp;&nbsp;
<button className="approveZero" onClick={() => {this.approveAllowance(0) }}>Zero Approval</button>
</div>
<div className="Approval">
{/*Tokens approved: {this.state.tokenAllowance}&nbsp;&nbsp;&nbsp;*/}
<button className="approveButton" onClick={() => {this.approveAllowance(5000*10**6) }}>Approve</button>
{/*<button className="approveZero" onClick={() => {this.approveAllowance(0) }}>Zero Approval</button>*/}
</div>
<div className="exchange">
<div className="exchange-buyTokensButton">
<input
className="exchange-buyTokensInput"
//value={this.state.value}
onChange={this.onBuyTokensInputChange}
/>
<input className="exchange-buyTokensInputButton" type="exchange-button" defaultValue="Buy UNI" onClick={() => {this.buyTokens() }}/>
<p className="pinkText">
&nbsp;&nbsp;Rate :&nbsp;&nbsp;&nbsp;{this.state.tokenBuyRate.toFixed(3)} UNI/ETH<br/>
&nbsp;&nbsp;Cost :&nbsp;&nbsp;&nbsp;{this.state.tokenCost.toFixed(5)} ETH<br/>
&nbsp;&nbsp;Fee :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{this.state.tokenFee.toFixed(5)} ETH<br/>
</p>
</div>
<div className="buyButton">
{/*<input type="text" id="buyID" ref={(input) => { this.textInput = input; }}/>*/}
<div className="exchange-buyEthButton">
<input
className="buyInput"
value={this.state.value}
onChange={this.onInputChange}
className="exchange-buyEthInput"
//value={this.state.value}
onChange={this.onBuyEthInputChange}
/>
<input type="button" value="Buy" onClick={() => {this.buyTokens() }}/>
<input className="exchange-buyEthInputButton" type="exchange-button" defaultValue="Buy ETH" onClick={() => {this.sellTokens() }}/>
<p className="pinkText">
&nbsp;&nbsp;Rate :&nbsp;&nbsp;&nbsp;{this.state.ethBuyRate.toFixed(4)} ETH/UNI<br/>
&nbsp;&nbsp;Cost :&nbsp;&nbsp;&nbsp;{this.state.ethCost.toFixed(5)} UNI<br/>
&nbsp;&nbsp;Fee :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{this.state.ethFee.toFixed(5)} UNI
</p>
</div>
</div>
</div>
);
}
......
......@@ -3,6 +3,12 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { Web3Provider } from 'react-web3';
ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(
<Web3Provider>
<App />
</Web3Provider>, document.getElementById('root'));
registerServiceWorker();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment