Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Tokens #44

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const EthSwap = artifacts.require("EthSwap");
const Token = artifacts.require("Token");

module.exports = async function(deployer) {

await deployer.deploy(Token);
const token=await Token.deployed();

await deployer.deploy(EthSwap,token.address);
const ethSwap=await EthSwap.deployed();

await token.transfer(ethSwap.address,'1000000000000000000000000')
};
36,607 changes: 31,928 additions & 4,679 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "eth-marketplace",
"name": "eth-swap",
"version": "0.1.0",
"description": "An Ethereum Marketplace",
"author": "[email protected]",
Expand All @@ -14,6 +14,7 @@
"chai": "4.2.0",
"chai-as-promised": "7.1.1",
"chai-bignumber": "3.0.0",
"identicon.js": "^2.3.3",
"react": "16.8.4",
"react-bootstrap": "1.0.0-beta.5",
"react-dom": "16.8.4",
Expand Down
4,117 changes: 4,117 additions & 0 deletions src/abis/EthSwap.json

Large diffs are not rendered by default.

1,397 changes: 1,397 additions & 0 deletions src/abis/Migrations.json

Large diffs are not rendered by default.

4,978 changes: 4,978 additions & 0 deletions src/abis/Token.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/components/App.css
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/* Styles go here */
.logo{
cursor: pointer;
}
67 changes: 44 additions & 23 deletions src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,53 @@
import React, { Component } from 'react';
import logo from '../logo.png';
import './App.css';

import Web3 from 'web3';
import Navbar from './Navbar';
class App extends Component {

async componentWillMount(){
await this.loadWeb3()
await this.loadBlockchainData()
}
async loadBlockchainData(){
const web3=window.web3;

const accounts=await web3.eth.getAccounts()

this.setState({account:accounts[0]})
const ethBalance=await web3.eth.getBalance(this.state.account)
this.setState({ethBalance})
console.log(this.state.ethBalance)

}

async loadWeb3(){
if (window.ethereum) {
window.web3 = new Web3(window.ethereum)
await window.ethereum.enable()
}
else if (window.web3) {
window.web3 = new Web3(window.web3.currentProvider)
}
else {
window.alert('Non-Ethereum browser detected. You should consider trying MetaMask!')
}
}
constructor(props) {
super(props)
this.state = {
account: '',
token: {},
ethSwap: {},
ethBalance: '0',
tokenBalance: '0',
loading: true
}
}
render() {
return (
<div>
<nav className="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
<a
className="navbar-brand col-sm-3 col-md-2 mr-0"
href="http://www.dappuniversity.com/bootcamp"
target="_blank"
rel="noopener noreferrer"
>
Dapp University
</a>
</nav>
<Navbar account={this.state.account}/>
<div className="container-fluid mt-5">
<div className="row">
<main role="main" className="col-lg-12 d-flex text-center">
Expand All @@ -27,18 +59,7 @@ class App extends Component {
>
<img src={logo} className="App-logo" alt="logo" />
</a>
<h1>Dapp University Starter Kit</h1>
<p>
Edit <code>src/components/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="http://www.dappuniversity.com/bootcamp"
target="_blank"
rel="noopener noreferrer"
>
LEARN BLOCKCHAIN <u><b>NOW! </b></u>
</a>
<h1>Hello</h1>
</div>
</main>
</div>
Expand Down
41 changes: 41 additions & 0 deletions src/components/Navbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { Component } from 'react'
import Identicon from 'identicon.js';

class Navbar extends Component {

render() {
return (
<nav className="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
<a
className="navbar-brand col-sm-3 col-md-2 mr-0"
href="http://www.dappuniversity.com/bootcamp"
target="_blank"
rel="noopener noreferrer"
>
EthSwap
</a>
<ul className="navbar-nav px-3">
<li className="nav-item text-nowrap d-none d-sm-none d-sm-block">
<small className="text-secondary">
<small id="account">{this.props.account}</small>
</small>

{ this.props.account
? <img
className="ml-2 logo"
width='30'
height='30'
src={`data:image/png;base64,${new Identicon(this.props.account, 30).toString()}`}
alt=""
/>
: <span></span>
}

</li>
</ul>
</nav>
);
}
}

export default Navbar
48 changes: 48 additions & 0 deletions src/contracts/EthSwap.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
pragma solidity ^0.5.0;

import "./Token.sol";

contract EthSwap{
string public name="EthSwap Instant Exchange";
Token public token;
uint public rate=100;

event TokenPurchased(
address account,
address token,
uint amount,
uint rate
);
event TokensSold(
address account,
address token,
uint amount,
uint rate
);

constructor (Token _token) public {
token = _token;

}

function buyTokens() public payable{
uint tokenAmount = msg.value * rate;

require(token.balanceOf(address(this)) >= tokenAmount);
token.transfer(msg.sender,tokenAmount);

emit TokenPurchased(msg.sender,address(token), tokenAmount, rate);
}
function sellTokens(uint _amount) public {
require(token.balanceOf(msg.sender) >= _amount);

uint etherAmount=_amount/rate;

require(address(this).balance >=etherAmount);

token.transferFrom(msg.sender, address(this), _amount);
msg.sender.transfer(etherAmount);

emit TokensSold(msg.sender,address(token), _amount, rate);
}
}
53 changes: 53 additions & 0 deletions src/contracts/Token.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
pragma solidity ^0.5.0;

contract Token {
string public name = "DApp Token";
string public symbol = "DAPP";
uint256 public totalSupply = 1000000000000000000000000; // 1 million tokens
uint8 public decimals = 18;

//Wei Smallest Eth tokens

event Transfer(
address indexed _from,
address indexed _to,
uint256 _value
);

event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);

mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;

constructor() public {
balanceOf[msg.sender] = totalSupply;
}

function transfer(address _to, uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value);
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}

function approve(address _spender, uint256 _value) public returns (bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= balanceOf[_from]);
require(_value <= allowance[_from][msg.sender]);
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
}
92 changes: 92 additions & 0 deletions test/EthSwap.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const { assert } = require('chai');



const EthSwap = artifacts.require("EthSwap");
const Token = artifacts.require("Token");

require('chai')
.use(require('chai-as-promised'))
.should();

function tokens(n) {
return web3.utils.toWei(n, 'ether');
}

contract('EthSwap',([deployer,investor])=>{
let token,ethSwap
before(async ()=>{
token = await Token.new()
ethSwap = await EthSwap.new(token.address)
await token.transfer(ethSwap.address,tokens('1000000'))
})

describe('Token deployment',async()=>{
it('contract has a name',async()=>{
const name=await token.name()
assert.equal(name,'DApp Token')
})
})
describe('EthSwap deployment',async()=>{
it('contract has a name',async()=>{
const name=await ethSwap.name()
assert.equal(name,'EthSwap Instant Exchange')
})

it('contract has tokens',async()=>{
let balance=await token.balanceOf(ethSwap.address)
assert.equal(balance.toString(),tokens('1000000'))
})
})

describe('buy tokens',async()=>{
let result

before(async () => {
// Purchase tokens before each example
result = await ethSwap.buyTokens({ from: investor, value: web3.utils.toWei('1', 'ether')})
})
it('Allows user to buy tokens for a fixed eth price',async()=>{
let investorBalance=await token.balanceOf(investor)
assert.equal(investorBalance.toString(),tokens('100'))

let ethSwapBalance=await token.balanceOf(ethSwap.address)
assert.equal(ethSwapBalance.toString(),tokens('999900'))
ethSwapBalance=await web3.eth.getBalance(ethSwap.address)
assert.equal(ethSwapBalance.toString(),web3.utils.toWei('1','Ether'))

const event = result.logs[0].args
assert.equal(event.account, investor)
assert.equal(event.token, token.address)
assert.equal(event.amount.toString(), tokens('100').toString())
assert.equal(event.rate.toString(), '100')

})
})

describe('sellTokens()',async()=>{
let result
before(async()=>{
await token.approve(ethSwap.address,tokens('100'),{from:investor})
result = await ethSwap.sellTokens(tokens('100'),{from:investor})
})
it('allows user to sell tokens',async ()=>{
let investorBalance=await token.balanceOf(investor)
assert.equal(investorBalance.toString(),tokens('0'))

let ethSwapBalance
ethSwapBalance = await token.balanceOf(ethSwap.address)
assert.equal(ethSwapBalance.toString(), tokens('1000000'))
ethSwapBalance = await web3.eth.getBalance(ethSwap.address)
assert.equal(ethSwapBalance.toString(), web3.utils.toWei('0', 'Ether'))

const event = result.logs[0].args
assert.equal(event.account, investor)
assert.equal(event.token, token.address)
assert.equal(event.amount.toString(), tokens('100').toString())
assert.equal(event.rate.toString(), '100')

await ethSwap.sellTokens(tokens('500'), { from: investor }).should.be.rejected;
})
})
})