Skip to content

Commit 86992e5

Browse files
committed
fixed approval
1 parent ae551f6 commit 86992e5

16 files changed

+4115
-3806
lines changed

client/src/App.css

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@
4343
border-width: 1mm;
4444

4545
}
46-
body {
4746

48-
background: url(images/wallpaper.jpg);
49-
/* -webkit-background-size: cover; */
50-
/* -moz-background-size: cover; */
51-
/* -o-background-size: cover; */
52-
/* background-size: cover; */
47+
body {
48+
background: url(images/wallpaper.jpg) no-repeat center center fixed;
49+
-webkit-background-size: cover;
50+
-moz-background-size: cover;
51+
-o-background-size: cover;
52+
background-size: cover;
5353
}
5454

5555
.navbar-custom {

client/src/App.js

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class App extends Component {
3838
console.log("TLoading web3 and connected accounts");
3939
// Get network provider and web3 instance.
4040
const web3 = await getWeb3();
41+
console.log("web3 = ", web3);
4142
this.setState({web3});
4243

4344
// Use web3 to get the user's accounts.
@@ -53,7 +54,7 @@ class App extends Component {
5354
if(networkId === 4){
5455
console.log("CORRECT NETWORK");
5556
this.setState({oncorrectNetwork:true});
56-
await this.connectWallet();
57+
// await this.connectWallet();
5758
}else{
5859
this.setState({oncorrectNetwork:false})
5960
}
@@ -139,25 +140,23 @@ class App extends Component {
139140
render() {
140141
let content;
141142
if (!this.state.web3) {
142-
return <div>Loading Web3, accounts, and contracts...</div>;
143-
}
144-
145-
if((this.state.oncorrectNetwork === false) && (this.state.web3)){
146-
return (
147-
148-
<div className="App">
149-
<p >Hi There! </p>
150-
<p>Please Connect To Rinkeby Testnet Then Connect Your Wallet To Start Buying/Selling Tokens</p>
151-
<button type="button" class="btn btn-outline-primary btn-lg"
152-
onClick={async() => {await this.connectWallet();}}>
153-
Connect Your Wallet</button>
143+
content = (<div>Loading Web3, accounts, and contracts...</div>);
144+
}else if (this.state.web3 && (!this.state.tokenA_contract)){
145+
content = (
154146

155-
</div>
147+
<div className="App">
148+
<p >Hi There! </p>
149+
<p>Please Connect To Rinkeby Testnet Then Connect Your Wallet To Start Buying/Selling Tokens</p>
150+
<button type="button" className="btn btn-outline-primary btn-lg"
151+
onClick={async() => {await this.connectWallet();}}>
152+
Connect Your Wallet</button>
153+
154+
</div>
156155

157156

158-
);
159-
}else{
160-
content = (<div>
157+
);
158+
}else{
159+
content = (<div>
161160
<Navbar connectedAccount={this.state.connectedAccount}/>
162161
<Form
163162
web3={this.state.web3}
@@ -171,6 +170,7 @@ class App extends Component {
171170
</div>
172171
);
173172

173+
174174
}
175175

176176
return (

client/src/Form.js

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -72,46 +72,71 @@ class Form extends Component {
7272

7373
async handleSubmit(event) {
7474
event.preventDefault();
75-
// alert("Hi!");
76-
// alert(event.target.value);
77-
// alert(event.submit.name);
78-
// alert(this.state.clicked_button);
75+
7976
if(this.state.clicked_button === "buy"){
80-
let call_value = this.props.web3.utils.toWei((this.state.eth_amount).toString());
77+
let call_value = await (this.props.web3.utils.toWei((this.state.eth_amount).toString()));
78+
console.log("this.state.eth_amount = ", this.state.eth_amount);
79+
console.log("this.state.eth_balance = ", this.state.eth_balance);
8180
console.log("call_value = ", call_value);
82-
if(this.state.selected_token === "A"){
83-
// console.log("eth_amount = ", eth_amount);
81+
82+
if((this.state.eth_balance < call_value)){
83+
alert("You don't have enough ETH to buy Tokens.");
84+
}else{
85+
if(this.state.selected_token === "A"){
86+
await this.props.swapTokens_contract.methods.buyTokensA().send({value:call_value, from:this.props.connectedAccount});
87+
88+
let tokenA_balance = await this.props.tokenA_contract.methods.balanceOf(this.props.connectedAccount).call();
89+
console.log("Token A Balance after buying tokens= ", this.props.web3.utils.fromWei(tokenA_balance));
90+
this.setState({tokenA_balance});
91+
92+
}else if(this.state.selected_token === "B"){
93+
94+
95+
await this.props.swapTokens_contract.methods.buyTokensB().send({value:call_value, from:this.props.connectedAccount});
96+
let tokenB_balance = await this.props.tokenB_contract.methods.balanceOf(this.props.connectedAccount).call();
97+
console.log("Token B Balance after buying tokens= ", this.props.web3.utils.fromWei(tokenB_balance));
98+
this.setState({tokenB_balance});
99+
100+
}else{
101+
alert("ERROR in selected_token");
102+
}
84103

85-
await this.props.swapTokens_contract.methods.buyTokensA().send({value:call_value, from:this.props.connectedAccount});
86-
87-
let tokenA_balance = await this.props.tokenA_contract.methods.balanceOf(this.props.connectedAccount).call();
88-
console.log("Token A Balance after buying tokens= ", this.props.web3.utils.fromWei(tokenA_balance));
89-
this.setState({tokenA_balance});
90104

91-
}else if(this.state.selected_token === "B"){
92-
await this.props.swapTokens_contract.methods.buyTokensB().send({value:call_value, from:this.props.connectedAccount});
93-
let tokenB_balance = await this.props.tokenB_contract.methods.balanceOf(this.props.connectedAccount).call();
94-
console.log("Token B Balance after buying tokens= ", this.props.web3.utils.fromWei(tokenB_balance));
95-
this.setState({tokenB_balance});
96-
97-
}else{
98-
alert("ERROR in selected_token");
99105
}
100106

101107

102108
}else if(this.state.clicked_button === "sell"){
103109
let call_amount = this.props.web3.utils.toWei((this.state.token_amount).toString());
110+
console.log("call amount = ", call_amount);
111+
console.log("this.state.token_amount = ", this.state.token_amount);
112+
console.log("this.state.tokenA_balance = ", this.state.tokenA_balance);
113+
console.log("this.state.tokenB_balance = ", this.state.tokenB_balance);
114+
104115
if(this.state.selected_token === "A"){
105-
await this.props.swapTokens_contract.methods.sellTokensA(call_amount).send({from:this.props.connectedAccount});
106-
let tokenA_balance = await this.props.tokenA_contract.methods.balanceOf(this.props.connectedAccount).call();
107-
console.log("Token A Balance after selling tokens= ", this.props.web3.utils.fromWei(tokenA_balance));
108-
this.setState({tokenA_balance});
116+
if(call_amount > this.state.tokenA_balance){
117+
alert("You don't have enough Tokens to be sold.")
118+
}else{
119+
await this.props.tokenA_contract.methods.approve(this.props.swapContract_address, call_amount).send({from:this.props.connectedAccount});
120+
await this.props.swapTokens_contract.methods.sellTokensA(call_amount).send({from:this.props.connectedAccount});
121+
let tokenA_balance = await this.props.tokenA_contract.methods.balanceOf(this.props.connectedAccount).call();
122+
console.log("Token A Balance after selling tokens= ", this.props.web3.utils.fromWei(tokenA_balance));
123+
this.setState({tokenA_balance});
124+
109125

126+
}
127+
110128
}else if(this.state.selected_token === "B"){
111-
await this.props.swapTokens_contract.methods.sellTokensB(call_amount).send({from:this.props.connectedAccount});
112-
let tokenB_balance = await this.props.tokenA_contract.methods.balanceOf(this.props.connectedAccount).call();
113-
console.log("Token A Balance after selling tokens= ", this.props.web3.utils.fromWei(tokenB_balance));
114-
this.setState({tokenB_balance});
129+
if(call_amount > this.state.tokenB_balance){
130+
alert("You don't have enough Tokens to be sold.")
131+
}else{
132+
await this.props.tokenB_contract.methods.approve(this.props.swapContract_address, call_amount).send({from:this.props.connectedAccount});
133+
await this.props.swapTokens_contract.methods.sellTokensB(call_amount).send({from:this.props.connectedAccount});
134+
let tokenB_balance = await this.props.tokenB_contract.methods.balanceOf(this.props.connectedAccount).call();
135+
console.log("Token A Balance after selling tokens= ", this.props.web3.utils.fromWei(tokenB_balance));
136+
this.setState({tokenB_balance});
137+
138+
}
139+
115140

116141
}else{
117142
alert("ERROR in selected_token");
@@ -173,7 +198,7 @@ class Form extends Component {
173198

174199
const eth_usd_rinkeby_proxy_address = "0x8A753747A1Fa494EC906cE90E9f37563A8AF630e";
175200
const priceFeed = new this.props.web3.eth.Contract(aggregatorV3InterfaceABI, eth_usd_rinkeby_proxy_address);
176-
console.log(priceFeed);
201+
console.log("price feed = ",priceFeed);
177202

178203
let decimals = 0;
179204
decimals = await priceFeed.methods.decimals().call();

client/src/contracts/Migrations.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,18 +1736,18 @@
17361736
"4": {
17371737
"events": {},
17381738
"links": {},
1739-
"address": "0x233937ADdE8e3B644fc41AEFEd9ccc1609f9E7A3",
1740-
"transactionHash": "0xf0fceaeb06bfba569ec210f9322e9f77a4d1132baff35363308a0a9ce2912937"
1739+
"address": "0xeb79Cc12E1DBE1272452E117a9825cF92EAFA98b",
1740+
"transactionHash": "0xd5ed0c11b893a8b07f2af6e4e6610fb834a3c5731dedf8b71b451c719531ee4c"
17411741
},
17421742
"5777": {
17431743
"events": {},
17441744
"links": {},
1745-
"address": "0x4f56C379B4aa4628ab687F2a6a728ab34Ef8D784",
1746-
"transactionHash": "0x0705665bc173131aa7719f73cff13d43b09ade031aebd4bf54982377563e68a0"
1745+
"address": "0x0f4f1a8030652c84Baf744eaca62b3AA65a5a2D5",
1746+
"transactionHash": "0x6f17a97ad01640196759cb020b60c5b00e027348edb31c627a665fe7efb871c3"
17471747
}
17481748
},
17491749
"schemaVersion": "3.4.3",
1750-
"updatedAt": "2021-11-24T19:10:40.825Z",
1750+
"updatedAt": "2021-11-25T21:13:18.087Z",
17511751
"networkType": "ethereum",
17521752
"devdoc": {
17531753
"kind": "dev",

client/src/contracts/SwapTokens.json

Lines changed: 3944 additions & 3700 deletions
Large diffs are not rendered by default.

client/src/contracts/TokenA.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10452,8 +10452,8 @@
1045210452
}
1045310453
},
1045410454
"links": {},
10455-
"address": "0xb6409B711d511A7db64cCBDa2Eca452AAad58ee2",
10456-
"transactionHash": "0x4e5e2d1f696f6bba826ba18d18a5733d57e8c20a492b9d5630ce91b73f79e64b"
10455+
"address": "0xd6054a80ba19E9d34FF09186178903E8D0789189",
10456+
"transactionHash": "0x50fcd578ed256411dae1117c02e6aed041ff06f3529bc02cf5edec119e64e0c9"
1045710457
},
1045810458
"5777": {
1045910459
"events": {
@@ -10509,12 +10509,12 @@
1050910509
}
1051010510
},
1051110511
"links": {},
10512-
"address": "0x8374AB864d5329977B3c82c6D7d51D5EF2E8b875",
10513-
"transactionHash": "0x5a83813ea51943d2331f67ca8eaca6c0e5ca9785bc8b8205141fbe1a1ce1cc0c"
10512+
"address": "0x01f63c9123bE3C588848E01734a1780ffA94D32a",
10513+
"transactionHash": "0xa3da8f8eff175fd8744978816d614a7ffb903183b8a5d43e7c5dd6f545fe0757"
1051410514
}
1051510515
},
1051610516
"schemaVersion": "3.4.3",
10517-
"updatedAt": "2021-11-24T19:10:40.796Z",
10517+
"updatedAt": "2021-11-25T21:13:18.064Z",
1051810518
"networkType": "ethereum",
1051910519
"devdoc": {
1052010520
"kind": "dev",

client/src/contracts/TokenB.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10452,8 +10452,8 @@
1045210452
}
1045310453
},
1045410454
"links": {},
10455-
"address": "0x817E0B7b325Dd3b4EC40bF5895d4f51b01800Da1",
10456-
"transactionHash": "0x436936dab1de7fa9eb02bff866b7e44e7f019d87819d3b00c98ebdf4b96d44fc"
10455+
"address": "0xf71847456f40809cacf991c222A98f1b3F628240",
10456+
"transactionHash": "0xee812b3097ec80bb3162de21e9ff90ea67573af983bd0f01888cf92439520422"
1045710457
},
1045810458
"5777": {
1045910459
"events": {
@@ -10509,12 +10509,12 @@
1050910509
}
1051010510
},
1051110511
"links": {},
10512-
"address": "0x1df09c98652F0A30A65dD5E1cd7229c0B8B03405",
10513-
"transactionHash": "0x6be34c333fffc15b6c330d64b4f84e370853c52d8d4292ab7b6a2de2139d924d"
10512+
"address": "0x438342Af6561D769C094f46A6aE5506c1EE4D6a7",
10513+
"transactionHash": "0xb935589a26346e275a980015b2cf3017222c5c792ff598d78f58be01a8ad1901"
1051410514
}
1051510515
},
1051610516
"schemaVersion": "3.4.3",
10517-
"updatedAt": "2021-11-24T19:10:40.806Z",
10517+
"updatedAt": "2021-11-25T21:13:18.072Z",
1051810518
"networkType": "ethereum",
1051910519
"devdoc": {
1052010520
"kind": "dev",

contracts/SwapTokens.sol

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import "./TokenB.sol";
1212
contract SwapTokens{
1313

1414
string public name = "SwapTokens Instant Exchange";
15-
TokenA public token1;
16-
TokenB public token2;
15+
TokenA token1;
16+
TokenB token2;
1717
uint public rate1 = 100; // 1 TKNA = 0.01 ETH
1818
uint public rate2 = 200; // 1 TKNB = 0.005 ETH
1919
address public owner;
@@ -56,9 +56,9 @@ contract SwapTokens{
5656
event Log(uint gas);
5757

5858

59-
constructor(TokenA _token1, TokenB _token2) {
60-
token1 = _token1;
61-
token2 = _token2;
59+
constructor(address _token1_address, address _token2_address) {
60+
token1 = TokenA(_token1_address);
61+
token2 = TokenB(_token2_address);
6262
owner = msg.sender; // owner is the deployer
6363

6464
}
@@ -88,7 +88,8 @@ contract SwapTokens{
8888
require(token1.balanceOf(address(this)) >= tokenAmount);
8989

9090
// Transfer tokens to the user
91-
token1.transfer(msg.sender, tokenAmount);
91+
token1.transfer(msg.sender, tokenAmount); // swapTokens transfers tokenA to the msg.sender, becaue it has the allowance to do so.
92+
9293

9394
// Emit an event
9495
emit TokensPurchased(msg.sender, address(token1), tokenAmount, rate1);
@@ -130,8 +131,10 @@ contract SwapTokens{
130131

131132
// Require that SwapTokens has enough Eth
132133
require(address(this).balance >= etherAmount);
134+
require(token1.allowance(msg.sender, address(this)) >= _amount);
133135

134136
// Sell tokens
137+
135138
token1.transferFrom(msg.sender, address(this), _amount);
136139
payable(msg.sender).transfer(etherAmount);
137140

@@ -154,7 +157,7 @@ contract SwapTokens{
154157

155158
// Require that SwapTokens has enough Ether
156159
require(address(this).balance >= etherAmount);
157-
160+
require(token2.allowance(msg.sender, address(this)) >= _amount);
158161
// Perform sale
159162
token2.transferFrom(msg.sender, address(this), _amount);
160163
payable(msg.sender).transfer(etherAmount);

deployed_address.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Testnet: Rinkeby
2-
SwapTokens Contract Address: 0x2522B1aAeA8a12cFe82E65CF7B07cc61eFD893DC
3-
TokenA Contract Address: 0xb6409B711d511A7db64cCBDa2Eca452AAad58ee2
4-
TokenB Contract Address: 0x817E0B7b325Dd3b4EC40bF5895d4f51b01800Da1
5-
Migrations Contract Address: 0x233937ADdE8e3B644fc41AEFEd9ccc1609f9E7A3
2+
SwapTokens Contract Address: 0xc485d33d8Da714701ac25De2aAdcCC00A0f70d7B
3+
TokenA Contract Address: 0xd6054a80ba19E9d34FF09186178903E8D0789189
4+
TokenB Contract Address: 0xf71847456f40809cacf991c222A98f1b3F628240
5+
Migrations Contract Address: 0xeb79Cc12E1DBE1272452E117a9825cF92EAFA98b
66
Deployer Public Address: 0x4bb52fF3e053d127265A8A8dDf9Dc291fcF04aF0
7-
Final cost: 0.00967614254761444 ETH
7+
Final cost: 0.009489310034161516 ETH
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
https://github.com/mennat1/blockchain-developer-bootcamp-final-project
2+
3+
Please answer the following questions. Does your project:
4+
5+
1. Follow this naming format: https://github.com/YOUR_GITHUB_USERNAME_HERE/blockchain-developer-bootcamp-final-project? YES
6+
7+
2. Contain a README.md file which describes the project, describes the directory structure, and where the frontend project can be accessed? And has your public Ethereum address if you'd like your certification as an NFT (optional)? YES
8+
9+
3. Contain smart contract(s) which:
10+
--Are commented to the specs described by NatSpec Solidity documentation
11+
--Use at least two design patterns from the "Smart Contracts" section
12+
--Protect against two attack vectors from the "Smart Contracts" section with its the SWC number
13+
--Inherits from at least one library or interface
14+
--Can be easily compiled, migrated and tested? YES
15+
16+
4. Contain a Markdown file named design_pattern_decisions.md and avoiding_common_attacks.md? YES
17+
18+
5. Have at least five smart contract unit tests that pass? YES
19+
20+
6. Contain a `deployed_address.txt` file which contains the testnet address and network where your contract(s) have been deployed? YES
21+
22+
7. Have a frontend interface built with a framework like React or HTML/CSS/JS that:
23+
--Detects the presence of MetaMask
24+
--Connects to the current account
25+
--Displays information from your smart contract
26+
--Allows a user to submit a transaction to update smart contract state
27+
--Updates the frontend if the transaction is successful or not? YES
28+
29+
8. Hosted on Github Pages, Heroku, Netlify, Fleek, or some other free frontend service that gives users a public interface to your decentralized application? (That address should be in your README.md document) YES
30+
31+
9. Have clear instructions for:
32+
1) Installing dependencies for your project
33+
2) Accessing or—if your project needs a server (not required)—running your project
34+
3) Running your smart contract unit tests and which port a local testnet should be running on. YES
35+
36+
10. A screencast of you walking through your project? YES
37+
38+
39+
Congratulations on finishing your final project!

0 commit comments

Comments
 (0)