add divest, minor improvements

This commit is contained in:
Hayden Adams 2018-04-03 10:08:27 +09:00
parent 1a73cdfa58
commit 955d5bab2e
13 changed files with 113 additions and 35 deletions

@ -433,7 +433,6 @@ class App extends Component {
scrollToComponent(this.Links, { offset: 0, align: 'top', duration: 500})
}
render() {
return (
<div className={this.props.web3Store.connected && !this.props.web3Store.metamaskLocked && this.props.web3Store.interaction !== 'disconnected' ? "App" : "App dim"}>
@ -476,7 +475,8 @@ class App extends Component {
symbolToTokenAddress={this.symbolToTokenAddress}
/>
<About toggleAbout={this.toggleAbout} location={this}/>
<Transactions transactions={this.state.transactions} interaction={this.props.web3Store.interaction} />
{//<Transactions transactions={this.state.transactions} interaction={this.props.web3Store.interaction} />
}
</div>
)
}

@ -24,7 +24,8 @@ import {
SET_INVEST_ETH_BALANCE,
SET_INVEST_SHARES_INPUT,
SET_INVEST_ETH_REQUIRED,
SET_INVEST_TOKENS_REQUIRED
SET_INVEST_TOKENS_REQUIRED,
SET_INVEST_CHECKED
} from '../constants';
export const setInputBalance = (inputBalance) => ({
@ -156,3 +157,8 @@ export const setInvestTokensRequired = (investTokensRequired) => ({
type: SET_INVEST_TOKENS_REQUIRED,
investTokensRequired
});
export const setInvestChecked = (investChecked) => ({
type: SET_INVEST_CHECKED,
investChecked
});

@ -1,14 +1,14 @@
import React from 'react'
import React from 'react'
function AboutMessage ({ toggled }) {
if (toggled === true) {
return (
<section className="expand grey-bg border pa2">
<p>Uniswap is a trustless, decentralized exchange for Ether and ERC20 tokens. It uses a market maker mechanism, where liquidity providers invest a reserve of ETH and a single ERC20 token within an Ethereum smart contract. An exchange rate is set between the tokens and ETH based on the relative availibility of each token. A small transaction fee is payed to the liquidity providers proportional to their investment.</p>
<p>There is a separate contract for each ETH-ERC20 pair. These contracts can "tunnel" between each other for direct ERC20-ERC20 trades. Only one exchange can exist per token, and anyone can contribute liquidity to any exchange. A factory/registry contract provides a public interface for creating new Uniswap exchanges, and looking up the exchange associated a given token address.</p>
<p>A full writeup will be available soon. Until then, here is some more info on Market Makers:</p>
<p>Uniswap is an automated market maker exchange capable of both ETH-to-ERC20 and ERC20-to-ERC20 trades. Anyone can become a liquidity provider, and invest in the liquidity pool of an ERC20 token. This allows other users to trade that token for any other token with liquidity, at an exchange rate based on their relative availibility. When a token trade is executed, a small fee is payed to the liquidity providers for both tokens, proportional to their investment.</p>
<p>A full writeup can be found here: <a href="https://hackmd.io/Tlf08KuPTbqsHLKk5hzAvA">Uniswap Project Overview</a></p>
<p>Please reach out if you would like to get involved or support the project.</p>
<p>Email: <a href="mailto:hayden@uniswap.io">hayden@uniswap.io</a></p>
<p><span role="img" aria-label="GitHub"></span> <a href="https://github.com/uniswap">github.com/uniswap</a></p>
<p><span role="img" aria-label="Email">📧 </span><a href="mailto:hayden@uniswap.io">hayden@uniswap.io</a></p>
</section>
)
} else {
@ -16,4 +16,4 @@ function AboutMessage ({ toggled }) {
}
}
export default AboutMessage;
export default AboutMessage;

@ -159,7 +159,7 @@ class Exchange extends Component {
<p></p>
</div>
<div className="value border pa2">
<input type="number" readOnly={true} value={(this.props.exchange.outputValue/10**18).toFixed(6)} placeholder="0"/>
<input type="number" readOnly={true} value={(this.props.exchange.outputValue/10**18).toFixed(4)} placeholder="0"/>
<SelectToken token={this.props.exchange.outputToken} onSelectToken={this.onSelectToken} type="output"/>
<p className="dropdown">{'<'}</p>
</div>

@ -3,7 +3,18 @@ import SelectToken from './SelectToken';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { setInvestToken, setInvestInvariant, setInvestEthPool, setInvestTokenPool, setInvestShares, setInvestTokenBalance, setInvestEthBalance, setInvestSharesInput, setUserShares, setInvestEthRequired, setInvestTokensRequired} from '../actions/exchange-actions';
import { setInvestToken,
setInvestInvariant,
setInvestEthPool,
setInvestTokenPool,
setInvestShares,
setInvestTokenBalance,
setInvestEthBalance,
setInvestSharesInput,
setUserShares,
setInvestEthRequired,
setInvestTokensRequired,
setInvestChecked} from '../actions/exchange-actions';
class Invest extends Component {
@ -29,6 +40,10 @@ class Invest extends Component {
this.getInvestOutput();
}
toggleCheck = () => {
this.props.setInvestChecked(!this.props.exchange.investChecked);
}
getInvestExchangeState = () => {
var exchange = this.props.symbolToExchangeContract(this.props.exchange.investToken.value);
@ -50,7 +65,6 @@ class Invest extends Component {
}
getInvestBalance = () => {
console.log('yo');
var token = this.props.symbolToTokenContract(this.props.exchange.investToken.value);
var exchange = this.props.symbolToExchangeContract(this.props.exchange.investToken.value);
@ -75,7 +89,7 @@ class Invest extends Component {
var tokensRequired = ((this.props.exchange.investTokenPool)/this.props.exchange.investShares)*inputValue;
this.props.setInvestEthRequired(ethRequired);
this.props.setInvestTokensRequired(tokensRequired);
console.log("requires ", ethRequired, " ETH ", tokensRequired, this.props.exchange.investToken.value);
// console.log("requires ", ethRequired, " ETH ", tokensRequired, this.props.exchange.investToken.value);
} else {
this.props.setInvestEthRequired(0);
this.props.setInvestTokensRequired(0);
@ -86,6 +100,10 @@ class Invest extends Component {
if (this.props.web3Store.investToggle === true) {
return (
<section className="grey-bg border pa2">
<div onChange={this.toggleCheck.bind(this)}>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Invest <input type="radio" checked={this.props.exchange.investChecked} onChange={()=>{}} /> &nbsp;&nbsp;&nbsp;&nbsp;
Divest <input type="radio" checked={!this.props.exchange.investChecked} onChange={()=>{}} />
</div>
<div className="invest investValue border pa2">
<p> Select token and input number of shares: &nbsp;&nbsp;&nbsp;</p>
<div className="investSelectToken">
@ -101,18 +119,18 @@ class Invest extends Component {
</div>
<div className="investValue border pa2">
<p> Total Liquidity </p>
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{(this.props.exchange.investEthPool/10**18).toFixed(2)} ETH </p>
<p> {(this.props.exchange.investTokenPool/10**18).toFixed(2)} {this.props.exchange.investToken.value} </p>
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{(this.props.exchange.investEthPool/10**18).toFixed(4)} ETH </p>
<p> {(this.props.exchange.investTokenPool/10**18).toFixed(4)} {this.props.exchange.investToken.value} </p>
</div>
<div className="investValue border pa2">
<p> &nbsp;Each share is worth: </p>
<p> {((this.props.exchange.investEthPool/10**18)/this.props.exchange.investShares).toFixed(5)} ETH &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p> {((this.props.exchange.investTokenPool/10**18)/this.props.exchange.investShares).toFixed(5)} {this.props.exchange.investToken.value} </p>
<p> {((this.props.exchange.investEthPool/10**18)/this.props.exchange.investShares).toFixed(4)} ETH &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p> {((this.props.exchange.investTokenPool/10**18)/this.props.exchange.investShares).toFixed(4)} {this.props.exchange.investToken.value} </p>
</div>
<div className="investValue border pa2">
<p> Account Balance: </p>
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{(this.props.exchange.investEthBalance/10**18).toFixed(5)} ETH </p>
<p> {(this.props.exchange.investTokenBalance/10**18).toFixed(5)} {this.props.exchange.investToken.value} </p>
<p> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{(this.props.exchange.investEthBalance/10**18).toFixed(4)} ETH </p>
<p> {(this.props.exchange.investTokenBalance/10**18).toFixed(4)} {this.props.exchange.investToken.value} </p>
</div>
</section>
)
@ -139,7 +157,8 @@ const mapDispatchToProps = (dispatch) => {
setInvestSharesInput,
setInvestEthRequired,
setInvestTokensRequired,
setUserShares
setUserShares,
setInvestChecked
}, dispatch);
}

@ -10,6 +10,7 @@ class Links extends Component {
<section className="links" ref={(section) => { this.props.location.Links = section; }} >
<a onClick={() => {this.props.toggleInvest()}} className="link border pa2 f-a">
<p className="underline">Invest liquidity to collect fees</p>
<p></p>
</a>
</section>
<Invest

@ -108,7 +108,7 @@ class Purchase extends Component {
if (this.props.web3Store.interaction === 'input') {
return (
<a className="swap border pa2" role="button" onClick={() => {this.purchaseTokens()}}>
<b>{"I want to swap " + this.props.exchange.inputValue + " " + this.props.exchange.inputToken.value + " for " + (this.props.exchange.outputValue/10**18).toFixed(6) + " " + this.props.exchange.outputToken.value}</b>
<b>{"I want to swap " + this.props.exchange.inputValue + " " + this.props.exchange.inputToken.value + " for " + (this.props.exchange.outputValue/10**18).toFixed(4) + " " + this.props.exchange.outputToken.value}</b>
</a>
)
} else {

@ -5,11 +5,11 @@ function RateAndFee ({ exchangeRate, outputTokenValue, inputTokenValue, exchange
<section className="rate border pa2">
<span className="rate-info">
<p>Rate</p>
<p>{(exchangeRate).toFixed(6)} {outputTokenValue + "/" + inputTokenValue}</p>
<p>{(exchangeRate).toFixed(4)} {outputTokenValue + "/" + inputTokenValue}</p>
</span>
<span className="rate-info">
<p>Fee</p>
<p>{(exchangeFee/10**18).toFixed(6)} {inputTokenValue}</p>
<p>{(exchangeFee/10**18).toFixed(4)} {inputTokenValue}</p>
</span>
</section>
)

@ -5,13 +5,17 @@ import { setBlockTimestamp, setInteractionState } from '../actions/web3-actions'
import { setExchangeInputValue, setExchangeOutputValue } from '../actions/exchange-actions';
class Purchase extends Component {
purchaseShares = async () => {
buyOrSellShares = async () => {
await this.props.setBlockTimestamp(this.props.web3Store.web3);
this.sharesPurchase();
if(this.props.exchange.investChecked) {
this.buyShares();
} else {
this.sellShares();
}
}
sharesPurchase = () => {
buyShares = () => {
console.log(this.props.exchange.inputToken.value, 'ahh')
var exchange = this.props.symbolToExchangeContract(this.props.exchange.investToken.value);
var minShares = 1;
@ -35,16 +39,58 @@ class Purchase extends Component {
.on('error', console.error);
}
sellShares = () => {
var exchange = this.props.symbolToExchangeContract(this.props.exchange.investToken.value);
var minEth = 1;
var minTokens = 1;
var sharesInt = parseInt(this.props.exchange.investSharesInput, 10).toString();
// var timeout = this.props.web3Store.blockTimestamp + 300; //current block time + 5mins
exchange.methods.divestLiquidity(sharesInt, minEth, minTokens).send({from: this.props.web3Store.currentMaskAddress})
.on('transactionHash', (result) => {
// console.log('Transaction Hash created')
// let transactions = this.state.transactions
// transactions.push(result)
// this.setState({ transactions: transactions });
// this.props.setExchangeInputValue(0);
// this.props.setExchangeOutputValue(0);
// this.props.setInteractionState('submitted');
console.log(result);
// cookie.save('transactions', transactions, { path: '/' })
})
.on('receipt', (receipt) => {console.log(receipt)}) //Transaction Submitted to blockchain
.on('confirmation', (confirmationNumber, receipt) => {console.log("Block Confirmations: " + confirmationNumber)}) //Transaction Mined
.on('error', console.error);
}
buyOrSell = (input) => {
if(input) {
return 'buy'
} else {
return 'sell'
}
}
render() {
if (this.props.exchange.investEthRequired > 0) {
// fix later
if (!this.props.exchange.investChecked && 1 === 0) {
return (
<a className="swap border pa2" role="button" onClick={() => {this.purchaseShares()}}>
<b>{"I want to buy " + this.props.exchange.investSharesInput + " shares for " + (this.props.exchange.investEthRequired/10**18).toFixed(4) + " ETH and " + (this.props.exchange.investTokensRequired/10**18).toFixed(4) + " " + this.props.exchange.investToken.value}</b>
</a>
<p className="swap border pa2">
<b>Not enough shares!</b>
</p>
)
} else {
return (<a className="swap grey-bg hidden border pa2"></a>)
return (
<a className="swap border pa2" role="button" onClick={() => {this.buyOrSellShares()}}>
<b>I want to {this.buyOrSell(this.props.exchange.investChecked)} {this.props.exchange.investSharesInput} shares for {(this.props.exchange.investEthRequired/10**18).toFixed(4)} ETH and {(this.props.exchange.investTokensRequired/10**18).toFixed(4)} {this.props.exchange.investToken.value}</b>
</a>
)
}
} else {
return (<a className="swap grey-bg hidden border pa2"></a>)
}
}
}

@ -29,7 +29,7 @@ class Visualization extends Component {
console.log(query, 'query')
axios.get('http://ec2-18-233-168-186.compute-1.amazonaws.com:3000/graphql', { params: {query: query } })
axios.get('http://ec2-34-193-175-237.compute-1.amazonaws.com:3000/graphql', { params: {query: query } })
.then(data => this.setState({data: data.data.data.Event }))
.then(() => this.createLineGraph())
.catch(err => console.error(err));
@ -49,7 +49,7 @@ class Visualization extends Component {
}
}`;
axios.get('http://ec2-18-233-168-186.compute-1.amazonaws.com:3000/graphql', { params: { query: query }})
axios.get('http://ec2-34-193-175-237.compute-1.amazonaws.com:3000/graphql', { params: { query: query }})
.then(data => this.setState({data: data.data.data.Event}))
.then(() => {
this.createNewLineGraph()

@ -60,6 +60,7 @@ export const SET_INVEST_ETH_BALANCE = 'SET_INVEST_ETH_BALANCE';
export const SET_INVEST_SHARES_INPUT = 'SET_INVEST_SHARES_INPUT';
export const SET_INVEST_ETH_REQUIRED = 'SET_INVEST_ETH_REQUIRED';
export const SET_INVEST_TOKENS_REQUIRED = 'SET_INVEST_TOKENS_REQUIRED';
export const SET_INVEST_CHECKED = 'SET_INVEST_CHECKED';
// test setInteractionState
export const INITIALIZE_GLOBAL_WEB3 = 'INITIALIZE_GLOBAL_WEB3';

@ -24,7 +24,8 @@ import {
SET_INVEST_TOKEN_BALANCE,
SET_INVEST_SHARES_INPUT,
SET_INVEST_ETH_REQUIRED,
SET_INVEST_TOKENS_REQUIRED
SET_INVEST_TOKENS_REQUIRED,
SET_INVEST_CHECKED
} from '../constants';
export default (state = {}, action) => {
@ -54,7 +55,8 @@ export default (state = {}, action) => {
investTokenBalance,
investSharesInput,
investEthRequired,
investTokensRequired
investTokensRequired,
investChecked
} = action;
switch(action.type) {
@ -110,6 +112,8 @@ export default (state = {}, action) => {
return Object.assign({}, state, { investEthRequired: investEthRequired });
case SET_INVEST_TOKENS_REQUIRED:
return Object.assign({}, state, { investTokensRequired: investTokensRequired });
case SET_INVEST_CHECKED:
return Object.assign({}, state, { investChecked: investChecked });
default: return state;
}
}

@ -59,6 +59,7 @@ export default {
investEthBalance: 0,
investSharesInput: 0,
investEthRequired: 0,
investTokensRequired: 0
investTokensRequired: 0,
investChecked: true
}
}