├── Final
├── Backend
│ ├── backend.js
│ ├── database.js
│ ├── ethpricedb.json
│ ├── getprices.js
│ ├── interface.js
│ ├── n2usdabi.json
│ ├── n2usdpricedb.json
│ ├── oracleabi.json
│ ├── package.json
│ └── reservesabi.json
└── Frontend
│ ├── components
│ ├── config.js
│ ├── govabi.json
│ ├── n2dusd-chart.js
│ ├── n2usdabi.json
│ └── rsvabi.json
│ ├── jsconfig.json
│ ├── next.config.js
│ ├── package.json
│ ├── pages
│ ├── _app.js
│ ├── _document.js
│ ├── api
│ │ └── hello.js
│ └── index.js
│ ├── public
│ ├── favicon.ico
│ ├── n2usd-logo.png
│ ├── next.svg
│ └── vercel.svg
│ └── styles
│ ├── Home.module.css
│ ├── globals.css
│ └── reserves.css
├── Part2
├── N2D-USDT-Fake-ERC20-Token-SmartContract.sol
├── N2D-WETH-Fake-ERC20-Token-SmartContract.sol
└── N2USD-Reserves-CollateralVault-SmartContract.sol
├── Part3
└── n2USD-Price-Oracle-Demo-SmartContract.sol
├── Part4
├── N2USD-Algorithmic-Stablecoin-Governance-Contract-Option1.sol
└── N2USD-ERC20-Stablecoin-Smart-Contract.sol
├── Part5
├── N2USD-Algorithmic-Stablecoin-Governance-Contract-Option2.sol
├── USDT.sol
├── n2dr.sol
├── n2usd.sol
└── n2usdreserves.sol
└── README.md
/Final/Backend/backend.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const app = express();
3 | const cors= require("cors");
4 | const corsOptions ={
5 | origin:'*',
6 | optionSuccessStatus:200,
7 | }
8 |
9 | app.use(cors(corsOptions))
10 | app.use(require('body-parser').json());
11 |
12 | const n2dlogo = `
13 | ███╗ ██╗██████╗ ██████╗ ███████╗██╗ ██╗
14 | ████╗ ██║╚════██╗██╔══██╗██╔════╝╚██╗██╔╝
15 | ██╔██╗ ██║ █████╔╝██║ ██║█████╗ ╚███╔╝
16 | ██║╚██╗██║██╔═══╝ ██║ ██║██╔══╝ ██╔██╗
17 | ██║ ╚████║███████╗██████╔╝███████╗██╔╝ ██╗
18 | ╚═╝ ╚═══╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝
19 | `
20 |
21 | const { getDbData, storeEthPrice, storeN2usdPrice } = require('./interface');
22 |
23 | app.post("/getchartinfo", function (req, res) {
24 | const token = req.body.token;
25 | return new Promise((resolve, reject) => {
26 | getDbData(token).then((response) => {
27 | res.statusCode = 200;
28 | res.setHeader("Content-Type", "application/json");
29 | res.setHeader("Cache-Control", "max-age=180000");
30 | res.end(JSON.stringify(response));
31 | resolve();
32 | }).catch((error) => {
33 | res.json(error);
34 | res.status(405).end();
35 | });
36 | });
37 | });
38 |
39 | const refreshEthPrice = async () => {
40 | setInterval(function () {
41 | storeEthPrice();
42 | }, 120000)
43 | }
44 |
45 | const refreshN2usdPrice = async () => {
46 | setInterval(function () {
47 | storeN2usdPrice();
48 | }, 120000)
49 | }
50 |
51 | const server = app.listen(8082, function() {
52 | const port = server.address().port;
53 | console.log('')
54 | console.log(n2dlogo);
55 | console.log('')
56 | refreshEthPrice()
57 | refreshN2usdPrice()
58 | console.log('Backend API Listening on Port: ' + port)
59 | })
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/Final/Backend/database.js:
--------------------------------------------------------------------------------
1 | const ethpricedb = require('./ethpricedb.json');
2 | const n2usdpricedb = require('./n2usdpricedb.json');
3 | const fs = require("fs").promises;
4 |
5 | const readDb = async (token) => {
6 | if (token == 'eth') {
7 | const output = await fs.readFile("ethpricedb.json", function(err, data) {
8 | if (err) throw err;
9 | return Buffer.from(data);
10 | })
11 | const pricedb = JSON.parse(output);
12 | return pricedb;
13 | } else {
14 | const output = await fs.readFile("n2usdpricedb.json", function(err, data) {
15 | if (err) throw err;
16 | return Buffer.from(data);
17 | })
18 | const pricedb = JSON.parse(output);
19 | return pricedb;
20 | }
21 | }
22 |
23 | const writeDb = async (price, time, lastentry, token) => {
24 | let entry = {
25 | updateprice: price,
26 | timedate: time,
27 | entry: lastentry + 1
28 | }
29 | if (token == 'eth') {
30 | ethpricedb.push(entry);
31 | let output = await fs.writeFile("ethpricedb.json", JSON.stringify(ethpricedb), err => {
32 | if (err) throw err;
33 | return 'Done';
34 | })
35 | return output
36 | }
37 | else {
38 | n2usdpricedb.push(entry);
39 | let output = await fs.writeFile("n2usdpricedb.json", JSON.stringify(n2usdpricedb), err => {
40 | if (err) throw err;
41 | return 'Done';
42 | })
43 | return output
44 | }
45 | }
46 |
47 | module.exports = { readDb, writeDb }
48 |
--------------------------------------------------------------------------------
/Final/Backend/ethpricedb.json:
--------------------------------------------------------------------------------
1 | []
2 |
--------------------------------------------------------------------------------
/Final/Backend/getprices.js:
--------------------------------------------------------------------------------
1 | const { ethers } = require("ethers");
2 | const oracleABI = require('./oracleabi.json');
3 | const reserveABI = require('./reservesabi.json');
4 | const n2usdABI = require('./n2usdabi.json');
5 |
6 | const oracleEth = '0x5f4ec3df9cbd43714fe2740f5e3616155c5b8419';
7 | const reservecontract = '0xba1f546071d9d7E2388d420AC1091ce58F661Efc';
8 | const n2usdcontract = '0x480724B920B486af30610b5Ed6456B0113951F43';
9 |
10 | const ethrpc = 'https://rpc.ankr.com/eth';
11 | const mumrpc = 'https://rpc.ankr.com/polygon_mumbai';
12 |
13 | const ethprovider = new ethers.providers.JsonRpcProvider(ethrpc);
14 | const mumprovider = new ethers.providers.JsonRpcProvider(mumrpc);
15 | const key = '89b0896f8b0fea1cec2d7dfd0204ba63e896d4b58581d299aea477dc3f2b2a35';
16 | const walleteth = new ethers.Wallet(key, ethprovider);
17 | const walletmum = new ethers.Wallet(key, mumprovider);
18 |
19 | const ethoracle = new ethers.Contract(oracleEth, oracleABI, walleteth);
20 | const reserves = new ethers.Contract(reservecontract, reserveABI, walletmum);
21 | const n2usd = new ethers.Contract(n2usdcontract, n2usdABI, walletmum);
22 |
23 | async function getEthPrice() {
24 | let ethprice = await ethoracle.latestRoundData().catch((error) => {console.log(error)})
25 | let lastesteth = Number((ethprice.answer).toString()) / 1e8;
26 | return lastesteth;
27 | }
28 |
29 | async function getN2usdPrice() {
30 | let lastesteth = await getEthPrice().catch((error) => {console.log(error)})
31 | let usdtcolraw = await reserves.rsvVault(0).catch((error) => {console.log(error)})
32 | let ethcolraw = await reserves.rsvVault(1).catch((error) => {console.log(error)})
33 | let n2usdSupRaw = await n2usd.totalSupply().catch((error) => {console.log(error)})
34 | let usdtcollateral = Number((usdtcolraw.amount).toString()) / 1e18;
35 | let ethcollateral = Number((ethcolraw.amount).toString()) / 1e18;
36 | let n2usdsupply = Number((n2usdSupRaw.toString())) / 1e18;
37 | let n2usdprice = ((usdtcollateral * 1) + (ethcollateral * lastesteth)) / n2usdsupply;
38 | return n2usdprice
39 |
40 | }
41 |
42 | module.exports = { getEthPrice, getN2usdPrice }
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Final/Backend/interface.js:
--------------------------------------------------------------------------------
1 | const { getEthPrice, getN2usdPrice } = require('./getprices');
2 | const { readDb, writeDb } = require('./database');
3 |
4 | const getDbData = async (token) => {
5 | let fromoutput = await readDb(token).catch((error) => {console.log(error)})
6 | let chartprice = [];
7 | let charttime = [];
8 | let chartentry = [];
9 | if (fromoutput != undefined) {
10 | fromoutput.forEach((value) => {
11 | chartprice.push(value.updateprice)
12 | charttime.push(value.timedate)
13 | chartentry.push(value.entry);
14 | })
15 | }
16 | return { chartprice, charttime, chartentry }
17 | }
18 |
19 |
20 | const storeEthPrice = async () => {
21 | const token = 'eth';
22 | let price = await getEthPrice();
23 | const fetchtime = new Date();
24 | const time =
25 | fetchtime.getHours() +
26 | ":" +
27 | fetchtime.getMinutes() +
28 | ":" +
29 | fetchtime.getSeconds();
30 | const fetchlast = await getDbData(token);
31 | let rawlastentry = fetchlast.chartentry;
32 | if (rawlastentry.length == 0) {
33 | let entry = 0;
34 | await writeDb(price, time, entry, token).catch((error) => {console.log(error)})
35 | }
36 | else if(rawlastentry.length > 0) {
37 | let lastentry = rawlastentry[rawlastentry.length - 1];
38 | await writeDb(price, time, lastentry, token).catch((error) => {console.log(error)})
39 | }
40 | }
41 |
42 | const storeN2usdPrice = async () => {
43 | const token = 'n2usd';
44 | let price = await getN2usdPrice();
45 | const fetchtime = new Date();
46 | const time =
47 | fetchtime.getHours() +
48 | ":" +
49 | fetchtime.getMinutes() +
50 | ":" +
51 | fetchtime.getSeconds();
52 | const fetchlast = await getDbData(token);
53 | let rawlastentry = fetchlast.chartentry;
54 | if (rawlastentry.length == 0) {
55 | let entry = 0;
56 | await writeDb(price, time, entry, token).catch((error) => {console.log(error)})
57 | }
58 | else if(rawlastentry.length > 0) {
59 | let lastentry = rawlastentry[rawlastentry.length - 1];
60 | await writeDb(price, time, lastentry, token).catch((error) => {console.log(error)})
61 | }
62 | }
63 |
64 | module.exports = { getDbData, storeEthPrice, storeN2usdPrice }
--------------------------------------------------------------------------------
/Final/Backend/n2usdabi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "stateMutability": "nonpayable",
5 | "type": "constructor"
6 | },
7 | {
8 | "anonymous": false,
9 | "inputs": [
10 | {
11 | "indexed": true,
12 | "internalType": "address",
13 | "name": "owner",
14 | "type": "address"
15 | },
16 | {
17 | "indexed": true,
18 | "internalType": "address",
19 | "name": "spender",
20 | "type": "address"
21 | },
22 | {
23 | "indexed": false,
24 | "internalType": "uint256",
25 | "name": "value",
26 | "type": "uint256"
27 | }
28 | ],
29 | "name": "Approval",
30 | "type": "event"
31 | },
32 | {
33 | "anonymous": false,
34 | "inputs": [
35 | {
36 | "indexed": true,
37 | "internalType": "address",
38 | "name": "previousOwner",
39 | "type": "address"
40 | },
41 | {
42 | "indexed": true,
43 | "internalType": "address",
44 | "name": "newOwner",
45 | "type": "address"
46 | }
47 | ],
48 | "name": "OwnershipTransferred",
49 | "type": "event"
50 | },
51 | {
52 | "anonymous": false,
53 | "inputs": [
54 | {
55 | "indexed": true,
56 | "internalType": "bytes32",
57 | "name": "role",
58 | "type": "bytes32"
59 | },
60 | {
61 | "indexed": true,
62 | "internalType": "bytes32",
63 | "name": "previousAdminRole",
64 | "type": "bytes32"
65 | },
66 | {
67 | "indexed": true,
68 | "internalType": "bytes32",
69 | "name": "newAdminRole",
70 | "type": "bytes32"
71 | }
72 | ],
73 | "name": "RoleAdminChanged",
74 | "type": "event"
75 | },
76 | {
77 | "anonymous": false,
78 | "inputs": [
79 | {
80 | "indexed": true,
81 | "internalType": "bytes32",
82 | "name": "role",
83 | "type": "bytes32"
84 | },
85 | {
86 | "indexed": true,
87 | "internalType": "address",
88 | "name": "account",
89 | "type": "address"
90 | },
91 | {
92 | "indexed": true,
93 | "internalType": "address",
94 | "name": "sender",
95 | "type": "address"
96 | }
97 | ],
98 | "name": "RoleGranted",
99 | "type": "event"
100 | },
101 | {
102 | "anonymous": false,
103 | "inputs": [
104 | {
105 | "indexed": true,
106 | "internalType": "bytes32",
107 | "name": "role",
108 | "type": "bytes32"
109 | },
110 | {
111 | "indexed": true,
112 | "internalType": "address",
113 | "name": "account",
114 | "type": "address"
115 | },
116 | {
117 | "indexed": true,
118 | "internalType": "address",
119 | "name": "sender",
120 | "type": "address"
121 | }
122 | ],
123 | "name": "RoleRevoked",
124 | "type": "event"
125 | },
126 | {
127 | "anonymous": false,
128 | "inputs": [
129 | {
130 | "indexed": true,
131 | "internalType": "address",
132 | "name": "from",
133 | "type": "address"
134 | },
135 | {
136 | "indexed": true,
137 | "internalType": "address",
138 | "name": "to",
139 | "type": "address"
140 | },
141 | {
142 | "indexed": false,
143 | "internalType": "uint256",
144 | "name": "value",
145 | "type": "uint256"
146 | }
147 | ],
148 | "name": "Transfer",
149 | "type": "event"
150 | },
151 | {
152 | "inputs": [],
153 | "name": "DEFAULT_ADMIN_ROLE",
154 | "outputs": [
155 | {
156 | "internalType": "bytes32",
157 | "name": "",
158 | "type": "bytes32"
159 | }
160 | ],
161 | "stateMutability": "view",
162 | "type": "function"
163 | },
164 | {
165 | "inputs": [],
166 | "name": "MANAGER_ROLE",
167 | "outputs": [
168 | {
169 | "internalType": "bytes32",
170 | "name": "",
171 | "type": "bytes32"
172 | }
173 | ],
174 | "stateMutability": "view",
175 | "type": "function"
176 | },
177 | {
178 | "inputs": [
179 | {
180 | "internalType": "address",
181 | "name": "owner",
182 | "type": "address"
183 | },
184 | {
185 | "internalType": "address",
186 | "name": "spender",
187 | "type": "address"
188 | }
189 | ],
190 | "name": "allowance",
191 | "outputs": [
192 | {
193 | "internalType": "uint256",
194 | "name": "",
195 | "type": "uint256"
196 | }
197 | ],
198 | "stateMutability": "view",
199 | "type": "function"
200 | },
201 | {
202 | "inputs": [
203 | {
204 | "internalType": "address",
205 | "name": "spender",
206 | "type": "address"
207 | },
208 | {
209 | "internalType": "uint256",
210 | "name": "amount",
211 | "type": "uint256"
212 | }
213 | ],
214 | "name": "approve",
215 | "outputs": [
216 | {
217 | "internalType": "bool",
218 | "name": "",
219 | "type": "bool"
220 | }
221 | ],
222 | "stateMutability": "nonpayable",
223 | "type": "function"
224 | },
225 | {
226 | "inputs": [
227 | {
228 | "internalType": "address",
229 | "name": "account",
230 | "type": "address"
231 | }
232 | ],
233 | "name": "balanceOf",
234 | "outputs": [
235 | {
236 | "internalType": "uint256",
237 | "name": "",
238 | "type": "uint256"
239 | }
240 | ],
241 | "stateMutability": "view",
242 | "type": "function"
243 | },
244 | {
245 | "inputs": [
246 | {
247 | "internalType": "uint256",
248 | "name": "amount",
249 | "type": "uint256"
250 | }
251 | ],
252 | "name": "burn",
253 | "outputs": [],
254 | "stateMutability": "nonpayable",
255 | "type": "function"
256 | },
257 | {
258 | "inputs": [
259 | {
260 | "internalType": "address",
261 | "name": "account",
262 | "type": "address"
263 | },
264 | {
265 | "internalType": "uint256",
266 | "name": "amount",
267 | "type": "uint256"
268 | }
269 | ],
270 | "name": "burnFrom",
271 | "outputs": [],
272 | "stateMutability": "nonpayable",
273 | "type": "function"
274 | },
275 | {
276 | "inputs": [],
277 | "name": "decimals",
278 | "outputs": [
279 | {
280 | "internalType": "uint8",
281 | "name": "",
282 | "type": "uint8"
283 | }
284 | ],
285 | "stateMutability": "view",
286 | "type": "function"
287 | },
288 | {
289 | "inputs": [
290 | {
291 | "internalType": "address",
292 | "name": "spender",
293 | "type": "address"
294 | },
295 | {
296 | "internalType": "uint256",
297 | "name": "subtractedValue",
298 | "type": "uint256"
299 | }
300 | ],
301 | "name": "decreaseAllowance",
302 | "outputs": [
303 | {
304 | "internalType": "bool",
305 | "name": "",
306 | "type": "bool"
307 | }
308 | ],
309 | "stateMutability": "nonpayable",
310 | "type": "function"
311 | },
312 | {
313 | "inputs": [
314 | {
315 | "internalType": "bytes32",
316 | "name": "role",
317 | "type": "bytes32"
318 | }
319 | ],
320 | "name": "getRoleAdmin",
321 | "outputs": [
322 | {
323 | "internalType": "bytes32",
324 | "name": "",
325 | "type": "bytes32"
326 | }
327 | ],
328 | "stateMutability": "view",
329 | "type": "function"
330 | },
331 | {
332 | "inputs": [
333 | {
334 | "internalType": "bytes32",
335 | "name": "role",
336 | "type": "bytes32"
337 | },
338 | {
339 | "internalType": "address",
340 | "name": "account",
341 | "type": "address"
342 | }
343 | ],
344 | "name": "grantRole",
345 | "outputs": [],
346 | "stateMutability": "nonpayable",
347 | "type": "function"
348 | },
349 | {
350 | "inputs": [
351 | {
352 | "internalType": "bytes32",
353 | "name": "role",
354 | "type": "bytes32"
355 | },
356 | {
357 | "internalType": "address",
358 | "name": "account",
359 | "type": "address"
360 | }
361 | ],
362 | "name": "hasRole",
363 | "outputs": [
364 | {
365 | "internalType": "bool",
366 | "name": "",
367 | "type": "bool"
368 | }
369 | ],
370 | "stateMutability": "view",
371 | "type": "function"
372 | },
373 | {
374 | "inputs": [
375 | {
376 | "internalType": "address",
377 | "name": "spender",
378 | "type": "address"
379 | },
380 | {
381 | "internalType": "uint256",
382 | "name": "addedValue",
383 | "type": "uint256"
384 | }
385 | ],
386 | "name": "increaseAllowance",
387 | "outputs": [
388 | {
389 | "internalType": "bool",
390 | "name": "",
391 | "type": "bool"
392 | }
393 | ],
394 | "stateMutability": "nonpayable",
395 | "type": "function"
396 | },
397 | {
398 | "inputs": [
399 | {
400 | "internalType": "uint256",
401 | "name": "amount",
402 | "type": "uint256"
403 | }
404 | ],
405 | "name": "mint",
406 | "outputs": [],
407 | "stateMutability": "nonpayable",
408 | "type": "function"
409 | },
410 | {
411 | "inputs": [],
412 | "name": "name",
413 | "outputs": [
414 | {
415 | "internalType": "string",
416 | "name": "",
417 | "type": "string"
418 | }
419 | ],
420 | "stateMutability": "view",
421 | "type": "function"
422 | },
423 | {
424 | "inputs": [],
425 | "name": "owner",
426 | "outputs": [
427 | {
428 | "internalType": "address",
429 | "name": "",
430 | "type": "address"
431 | }
432 | ],
433 | "stateMutability": "view",
434 | "type": "function"
435 | },
436 | {
437 | "inputs": [],
438 | "name": "renounceOwnership",
439 | "outputs": [],
440 | "stateMutability": "nonpayable",
441 | "type": "function"
442 | },
443 | {
444 | "inputs": [
445 | {
446 | "internalType": "bytes32",
447 | "name": "role",
448 | "type": "bytes32"
449 | },
450 | {
451 | "internalType": "address",
452 | "name": "account",
453 | "type": "address"
454 | }
455 | ],
456 | "name": "renounceRole",
457 | "outputs": [],
458 | "stateMutability": "nonpayable",
459 | "type": "function"
460 | },
461 | {
462 | "inputs": [
463 | {
464 | "internalType": "bytes32",
465 | "name": "role",
466 | "type": "bytes32"
467 | },
468 | {
469 | "internalType": "address",
470 | "name": "account",
471 | "type": "address"
472 | }
473 | ],
474 | "name": "revokeRole",
475 | "outputs": [],
476 | "stateMutability": "nonpayable",
477 | "type": "function"
478 | },
479 | {
480 | "inputs": [
481 | {
482 | "internalType": "bytes4",
483 | "name": "interfaceId",
484 | "type": "bytes4"
485 | }
486 | ],
487 | "name": "supportsInterface",
488 | "outputs": [
489 | {
490 | "internalType": "bool",
491 | "name": "",
492 | "type": "bool"
493 | }
494 | ],
495 | "stateMutability": "view",
496 | "type": "function"
497 | },
498 | {
499 | "inputs": [],
500 | "name": "symbol",
501 | "outputs": [
502 | {
503 | "internalType": "string",
504 | "name": "",
505 | "type": "string"
506 | }
507 | ],
508 | "stateMutability": "view",
509 | "type": "function"
510 | },
511 | {
512 | "inputs": [],
513 | "name": "totalSupply",
514 | "outputs": [
515 | {
516 | "internalType": "uint256",
517 | "name": "",
518 | "type": "uint256"
519 | }
520 | ],
521 | "stateMutability": "view",
522 | "type": "function"
523 | },
524 | {
525 | "inputs": [
526 | {
527 | "internalType": "address",
528 | "name": "to",
529 | "type": "address"
530 | },
531 | {
532 | "internalType": "uint256",
533 | "name": "amount",
534 | "type": "uint256"
535 | }
536 | ],
537 | "name": "transfer",
538 | "outputs": [
539 | {
540 | "internalType": "bool",
541 | "name": "",
542 | "type": "bool"
543 | }
544 | ],
545 | "stateMutability": "nonpayable",
546 | "type": "function"
547 | },
548 | {
549 | "inputs": [
550 | {
551 | "internalType": "address",
552 | "name": "from",
553 | "type": "address"
554 | },
555 | {
556 | "internalType": "address",
557 | "name": "to",
558 | "type": "address"
559 | },
560 | {
561 | "internalType": "uint256",
562 | "name": "amount",
563 | "type": "uint256"
564 | }
565 | ],
566 | "name": "transferFrom",
567 | "outputs": [
568 | {
569 | "internalType": "bool",
570 | "name": "",
571 | "type": "bool"
572 | }
573 | ],
574 | "stateMutability": "nonpayable",
575 | "type": "function"
576 | },
577 | {
578 | "inputs": [
579 | {
580 | "internalType": "address",
581 | "name": "newOwner",
582 | "type": "address"
583 | }
584 | ],
585 | "name": "transferOwnership",
586 | "outputs": [],
587 | "stateMutability": "nonpayable",
588 | "type": "function"
589 | }
590 | ]
--------------------------------------------------------------------------------
/Final/Backend/n2usdpricedb.json:
--------------------------------------------------------------------------------
1 | []
2 |
--------------------------------------------------------------------------------
/Final/Backend/oracleabi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "name": "decimals",
5 | "outputs": [
6 | {
7 | "internalType": "uint8",
8 | "name": "",
9 | "type": "uint8"
10 | }
11 | ],
12 | "stateMutability": "view",
13 | "type": "function"
14 | },
15 | {
16 | "inputs": [],
17 | "name": "description",
18 | "outputs": [
19 | {
20 | "internalType": "string",
21 | "name": "",
22 | "type": "string"
23 | }
24 | ],
25 | "stateMutability": "view",
26 | "type": "function"
27 | },
28 | {
29 | "inputs": [
30 | {
31 | "internalType": "uint80",
32 | "name": "_roundId",
33 | "type": "uint80"
34 | }
35 | ],
36 | "name": "getRoundData",
37 | "outputs": [
38 | {
39 | "internalType": "uint80",
40 | "name": "roundId",
41 | "type": "uint80"
42 | },
43 | {
44 | "internalType": "uint256",
45 | "name": "answer",
46 | "type": "uint256"
47 | },
48 | {
49 | "internalType": "uint256",
50 | "name": "startedAt",
51 | "type": "uint256"
52 | },
53 | {
54 | "internalType": "uint256",
55 | "name": "updatedAt",
56 | "type": "uint256"
57 | },
58 | {
59 | "internalType": "uint80",
60 | "name": "answeredInRound",
61 | "type": "uint80"
62 | }
63 | ],
64 | "stateMutability": "view",
65 | "type": "function"
66 | },
67 | {
68 | "inputs": [],
69 | "name": "latestRoundData",
70 | "outputs": [
71 | {
72 | "internalType": "uint80",
73 | "name": "roundId",
74 | "type": "uint80"
75 | },
76 | {
77 | "internalType": "uint256",
78 | "name": "answer",
79 | "type": "uint256"
80 | },
81 | {
82 | "internalType": "uint256",
83 | "name": "startedAt",
84 | "type": "uint256"
85 | },
86 | {
87 | "internalType": "uint256",
88 | "name": "updatedAt",
89 | "type": "uint256"
90 | },
91 | {
92 | "internalType": "uint80",
93 | "name": "answeredInRound",
94 | "type": "uint80"
95 | }
96 | ],
97 | "stateMutability": "view",
98 | "type": "function"
99 | },
100 | {
101 | "inputs": [],
102 | "name": "version",
103 | "outputs": [
104 | {
105 | "internalType": "uint256",
106 | "name": "",
107 | "type": "uint256"
108 | }
109 | ],
110 | "stateMutability": "view",
111 | "type": "function"
112 | }
113 | ]
--------------------------------------------------------------------------------
/Final/Backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "axios": "^1.1.3",
4 | "body-parser": "^1.20.1",
5 | "cookie-parser": "^1.4.6",
6 | "cors": "^2.8.5",
7 | "ethers": "^5.7.2",
8 | "express": "^4.18.2",
9 | "fs": "^0.0.1-security",
10 | "multer": "^1.4.5-lts.1",
11 | "node-fetch": "^2.6.1",
12 | "qs": "^6.11.2"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Final/Backend/reservesabi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "inputs": [],
4 | "stateMutability": "nonpayable",
5 | "type": "constructor"
6 | },
7 | {
8 | "anonymous": false,
9 | "inputs": [
10 | {
11 | "indexed": true,
12 | "internalType": "uint256",
13 | "name": "pid",
14 | "type": "uint256"
15 | },
16 | {
17 | "indexed": false,
18 | "internalType": "uint256",
19 | "name": "amount",
20 | "type": "uint256"
21 | }
22 | ],
23 | "name": "Deposit",
24 | "type": "event"
25 | },
26 | {
27 | "anonymous": false,
28 | "inputs": [
29 | {
30 | "indexed": true,
31 | "internalType": "address",
32 | "name": "previousOwner",
33 | "type": "address"
34 | },
35 | {
36 | "indexed": true,
37 | "internalType": "address",
38 | "name": "newOwner",
39 | "type": "address"
40 | }
41 | ],
42 | "name": "OwnershipTransferred",
43 | "type": "event"
44 | },
45 | {
46 | "anonymous": false,
47 | "inputs": [
48 | {
49 | "indexed": true,
50 | "internalType": "bytes32",
51 | "name": "role",
52 | "type": "bytes32"
53 | },
54 | {
55 | "indexed": true,
56 | "internalType": "bytes32",
57 | "name": "previousAdminRole",
58 | "type": "bytes32"
59 | },
60 | {
61 | "indexed": true,
62 | "internalType": "bytes32",
63 | "name": "newAdminRole",
64 | "type": "bytes32"
65 | }
66 | ],
67 | "name": "RoleAdminChanged",
68 | "type": "event"
69 | },
70 | {
71 | "anonymous": false,
72 | "inputs": [
73 | {
74 | "indexed": true,
75 | "internalType": "bytes32",
76 | "name": "role",
77 | "type": "bytes32"
78 | },
79 | {
80 | "indexed": true,
81 | "internalType": "address",
82 | "name": "account",
83 | "type": "address"
84 | },
85 | {
86 | "indexed": true,
87 | "internalType": "address",
88 | "name": "sender",
89 | "type": "address"
90 | }
91 | ],
92 | "name": "RoleGranted",
93 | "type": "event"
94 | },
95 | {
96 | "anonymous": false,
97 | "inputs": [
98 | {
99 | "indexed": true,
100 | "internalType": "bytes32",
101 | "name": "role",
102 | "type": "bytes32"
103 | },
104 | {
105 | "indexed": true,
106 | "internalType": "address",
107 | "name": "account",
108 | "type": "address"
109 | },
110 | {
111 | "indexed": true,
112 | "internalType": "address",
113 | "name": "sender",
114 | "type": "address"
115 | }
116 | ],
117 | "name": "RoleRevoked",
118 | "type": "event"
119 | },
120 | {
121 | "anonymous": false,
122 | "inputs": [
123 | {
124 | "indexed": true,
125 | "internalType": "uint256",
126 | "name": "pid",
127 | "type": "uint256"
128 | },
129 | {
130 | "indexed": false,
131 | "internalType": "uint256",
132 | "name": "amount",
133 | "type": "uint256"
134 | }
135 | ],
136 | "name": "Withdraw",
137 | "type": "event"
138 | },
139 | {
140 | "inputs": [],
141 | "name": "DEFAULT_ADMIN_ROLE",
142 | "outputs": [
143 | {
144 | "internalType": "bytes32",
145 | "name": "",
146 | "type": "bytes32"
147 | }
148 | ],
149 | "stateMutability": "view",
150 | "type": "function"
151 | },
152 | {
153 | "inputs": [],
154 | "name": "MANAGER_ROLE",
155 | "outputs": [
156 | {
157 | "internalType": "bytes32",
158 | "name": "",
159 | "type": "bytes32"
160 | }
161 | ],
162 | "stateMutability": "view",
163 | "type": "function"
164 | },
165 | {
166 | "inputs": [
167 | {
168 | "internalType": "contract IERC20",
169 | "name": "_colToken",
170 | "type": "address"
171 | }
172 | ],
173 | "name": "addReserve",
174 | "outputs": [],
175 | "stateMutability": "nonpayable",
176 | "type": "function"
177 | },
178 | {
179 | "inputs": [],
180 | "name": "currentReserveCount",
181 | "outputs": [
182 | {
183 | "internalType": "uint256",
184 | "name": "",
185 | "type": "uint256"
186 | }
187 | ],
188 | "stateMutability": "view",
189 | "type": "function"
190 | },
191 | {
192 | "inputs": [
193 | {
194 | "internalType": "uint256",
195 | "name": "_pid",
196 | "type": "uint256"
197 | },
198 | {
199 | "internalType": "uint256",
200 | "name": "_amount",
201 | "type": "uint256"
202 | }
203 | ],
204 | "name": "deposit",
205 | "outputs": [],
206 | "stateMutability": "nonpayable",
207 | "type": "function"
208 | },
209 | {
210 | "inputs": [
211 | {
212 | "internalType": "bytes32",
213 | "name": "role",
214 | "type": "bytes32"
215 | }
216 | ],
217 | "name": "getRoleAdmin",
218 | "outputs": [
219 | {
220 | "internalType": "bytes32",
221 | "name": "",
222 | "type": "bytes32"
223 | }
224 | ],
225 | "stateMutability": "view",
226 | "type": "function"
227 | },
228 | {
229 | "inputs": [
230 | {
231 | "internalType": "bytes32",
232 | "name": "role",
233 | "type": "bytes32"
234 | },
235 | {
236 | "internalType": "address",
237 | "name": "account",
238 | "type": "address"
239 | }
240 | ],
241 | "name": "grantRole",
242 | "outputs": [],
243 | "stateMutability": "nonpayable",
244 | "type": "function"
245 | },
246 | {
247 | "inputs": [
248 | {
249 | "internalType": "bytes32",
250 | "name": "role",
251 | "type": "bytes32"
252 | },
253 | {
254 | "internalType": "address",
255 | "name": "account",
256 | "type": "address"
257 | }
258 | ],
259 | "name": "hasRole",
260 | "outputs": [
261 | {
262 | "internalType": "bool",
263 | "name": "",
264 | "type": "bool"
265 | }
266 | ],
267 | "stateMutability": "view",
268 | "type": "function"
269 | },
270 | {
271 | "inputs": [],
272 | "name": "owner",
273 | "outputs": [
274 | {
275 | "internalType": "address",
276 | "name": "",
277 | "type": "address"
278 | }
279 | ],
280 | "stateMutability": "view",
281 | "type": "function"
282 | },
283 | {
284 | "inputs": [],
285 | "name": "renounceOwnership",
286 | "outputs": [],
287 | "stateMutability": "nonpayable",
288 | "type": "function"
289 | },
290 | {
291 | "inputs": [
292 | {
293 | "internalType": "bytes32",
294 | "name": "role",
295 | "type": "bytes32"
296 | },
297 | {
298 | "internalType": "address",
299 | "name": "account",
300 | "type": "address"
301 | }
302 | ],
303 | "name": "renounceRole",
304 | "outputs": [],
305 | "stateMutability": "nonpayable",
306 | "type": "function"
307 | },
308 | {
309 | "inputs": [
310 | {
311 | "internalType": "bytes32",
312 | "name": "role",
313 | "type": "bytes32"
314 | },
315 | {
316 | "internalType": "address",
317 | "name": "account",
318 | "type": "address"
319 | }
320 | ],
321 | "name": "revokeRole",
322 | "outputs": [],
323 | "stateMutability": "nonpayable",
324 | "type": "function"
325 | },
326 | {
327 | "inputs": [
328 | {
329 | "internalType": "uint256",
330 | "name": "",
331 | "type": "uint256"
332 | }
333 | ],
334 | "name": "rsvVault",
335 | "outputs": [
336 | {
337 | "internalType": "contract IERC20",
338 | "name": "collateral",
339 | "type": "address"
340 | },
341 | {
342 | "internalType": "uint256",
343 | "name": "amount",
344 | "type": "uint256"
345 | }
346 | ],
347 | "stateMutability": "view",
348 | "type": "function"
349 | },
350 | {
351 | "inputs": [
352 | {
353 | "internalType": "bytes4",
354 | "name": "interfaceId",
355 | "type": "bytes4"
356 | }
357 | ],
358 | "name": "supportsInterface",
359 | "outputs": [
360 | {
361 | "internalType": "bool",
362 | "name": "",
363 | "type": "bool"
364 | }
365 | ],
366 | "stateMutability": "view",
367 | "type": "function"
368 | },
369 | {
370 | "inputs": [
371 | {
372 | "internalType": "address",
373 | "name": "newOwner",
374 | "type": "address"
375 | }
376 | ],
377 | "name": "transferOwnership",
378 | "outputs": [],
379 | "stateMutability": "nonpayable",
380 | "type": "function"
381 | },
382 | {
383 | "inputs": [
384 | {
385 | "internalType": "uint256",
386 | "name": "_pid",
387 | "type": "uint256"
388 | },
389 | {
390 | "internalType": "uint256",
391 | "name": "_amount",
392 | "type": "uint256"
393 | }
394 | ],
395 | "name": "withdraw",
396 | "outputs": [],
397 | "stateMutability": "nonpayable",
398 | "type": "function"
399 | }
400 | ]
--------------------------------------------------------------------------------
/Final/Frontend/components/config.js:
--------------------------------------------------------------------------------
1 | import { ethers } from "ethers";
2 | import rsvABI from './rsvabi.json';
3 | import n2usdABI from './n2usdabi.json';
4 |
5 | const rsvcontract = '0xba1f546071d9d7E2388d420AC1091ce58F661Efc';
6 | const n2usdcontract = '0x480724B920B486af30610b5Ed6456B0113951F43';
7 | const rpc = 'https://rpc.ankr.com/polygon_mumbai';
8 | const provider = new ethers.providers.JsonRpcProvider(rpc);
9 | const key = '89b0896f8b0fea1cec2d7dfd0204ba63e896d4b58581d299aea477dc3f2b2a35';
10 | const wallet = new ethers.Wallet(key, provider);
11 | const reserves = new ethers.Contract(rsvcontract, rsvABI, wallet);
12 | const n2usd = new ethers.Contract(n2usdcontract, n2usdABI, wallet);
13 |
14 |
15 |
16 | export async function getReserves() {
17 | const rsvcount = Number((await reserves.reserveLength()).toString());
18 | const n2dusdformat = (await n2usd.totalSupply()).toString();
19 | const n2dusdsupply = ethers.utils.formatEther(n2dusdformat)
20 | let i = 0;
21 | let rsvamounts = [];
22 | for (i; i < rsvcount; i++){
23 | const balance = await reserves.rsvVault(i);
24 | const getbalance = balance.amount.toString();
25 | let formatbalance = ethers.utils.formatEther(getbalance)
26 | rsvamounts.push(formatbalance);
27 | }
28 | return { rsvamounts, n2dusdsupply };
29 | }
--------------------------------------------------------------------------------
/Final/Frontend/components/govabi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "previousOwner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "newOwner",
15 | "type": "address"
16 | }
17 | ],
18 | "name": "OwnershipTransferred",
19 | "type": "event"
20 | },
21 | {
22 | "anonymous": false,
23 | "inputs": [
24 | {
25 | "indexed": false,
26 | "internalType": "uint256",
27 | "name": "time",
28 | "type": "uint256"
29 | },
30 | {
31 | "indexed": false,
32 | "internalType": "uint256",
33 | "name": "amount",
34 | "type": "uint256"
35 | }
36 | ],
37 | "name": "RepegAction",
38 | "type": "event"
39 | },
40 | {
41 | "anonymous": false,
42 | "inputs": [
43 | {
44 | "indexed": true,
45 | "internalType": "bytes32",
46 | "name": "role",
47 | "type": "bytes32"
48 | },
49 | {
50 | "indexed": true,
51 | "internalType": "bytes32",
52 | "name": "previousAdminRole",
53 | "type": "bytes32"
54 | },
55 | {
56 | "indexed": true,
57 | "internalType": "bytes32",
58 | "name": "newAdminRole",
59 | "type": "bytes32"
60 | }
61 | ],
62 | "name": "RoleAdminChanged",
63 | "type": "event"
64 | },
65 | {
66 | "anonymous": false,
67 | "inputs": [
68 | {
69 | "indexed": true,
70 | "internalType": "bytes32",
71 | "name": "role",
72 | "type": "bytes32"
73 | },
74 | {
75 | "indexed": true,
76 | "internalType": "address",
77 | "name": "account",
78 | "type": "address"
79 | },
80 | {
81 | "indexed": true,
82 | "internalType": "address",
83 | "name": "sender",
84 | "type": "address"
85 | }
86 | ],
87 | "name": "RoleGranted",
88 | "type": "event"
89 | },
90 | {
91 | "anonymous": false,
92 | "inputs": [
93 | {
94 | "indexed": true,
95 | "internalType": "bytes32",
96 | "name": "role",
97 | "type": "bytes32"
98 | },
99 | {
100 | "indexed": true,
101 | "internalType": "address",
102 | "name": "account",
103 | "type": "address"
104 | },
105 | {
106 | "indexed": true,
107 | "internalType": "address",
108 | "name": "sender",
109 | "type": "address"
110 | }
111 | ],
112 | "name": "RoleRevoked",
113 | "type": "event"
114 | },
115 | {
116 | "anonymous": false,
117 | "inputs": [
118 | {
119 | "indexed": false,
120 | "internalType": "uint256",
121 | "name": "time",
122 | "type": "uint256"
123 | },
124 | {
125 | "indexed": false,
126 | "internalType": "uint256",
127 | "name": "amount",
128 | "type": "uint256"
129 | }
130 | ],
131 | "name": "Withdraw",
132 | "type": "event"
133 | },
134 | {
135 | "inputs": [
136 | {
137 | "internalType": "contract IERC20",
138 | "name": "colcontract",
139 | "type": "address"
140 | }
141 | ],
142 | "name": "addReserve",
143 | "outputs": [],
144 | "stateMutability": "nonpayable",
145 | "type": "function"
146 | },
147 | {
148 | "inputs": [
149 | {
150 | "internalType": "uint256",
151 | "name": "price",
152 | "type": "uint256"
153 | }
154 | ],
155 | "name": "fetchColPrice",
156 | "outputs": [],
157 | "stateMutability": "nonpayable",
158 | "type": "function"
159 | },
160 | {
161 | "inputs": [
162 | {
163 | "internalType": "bytes32",
164 | "name": "role",
165 | "type": "bytes32"
166 | },
167 | {
168 | "internalType": "address",
169 | "name": "account",
170 | "type": "address"
171 | }
172 | ],
173 | "name": "grantRole",
174 | "outputs": [],
175 | "stateMutability": "nonpayable",
176 | "type": "function"
177 | },
178 | {
179 | "inputs": [],
180 | "name": "renounceOwnership",
181 | "outputs": [],
182 | "stateMutability": "nonpayable",
183 | "type": "function"
184 | },
185 | {
186 | "inputs": [
187 | {
188 | "internalType": "bytes32",
189 | "name": "role",
190 | "type": "bytes32"
191 | },
192 | {
193 | "internalType": "address",
194 | "name": "account",
195 | "type": "address"
196 | }
197 | ],
198 | "name": "renounceRole",
199 | "outputs": [],
200 | "stateMutability": "nonpayable",
201 | "type": "function"
202 | },
203 | {
204 | "inputs": [
205 | {
206 | "internalType": "bytes32",
207 | "name": "role",
208 | "type": "bytes32"
209 | },
210 | {
211 | "internalType": "address",
212 | "name": "account",
213 | "type": "address"
214 | }
215 | ],
216 | "name": "revokeRole",
217 | "outputs": [],
218 | "stateMutability": "nonpayable",
219 | "type": "function"
220 | },
221 | {
222 | "inputs": [
223 | {
224 | "internalType": "address",
225 | "name": "reserve",
226 | "type": "address"
227 | }
228 | ],
229 | "name": "setReserveContract",
230 | "outputs": [],
231 | "stateMutability": "nonpayable",
232 | "type": "function"
233 | },
234 | {
235 | "inputs": [
236 | {
237 | "internalType": "address",
238 | "name": "newOwner",
239 | "type": "address"
240 | }
241 | ],
242 | "name": "transferOwnership",
243 | "outputs": [],
244 | "stateMutability": "nonpayable",
245 | "type": "function"
246 | },
247 | {
248 | "inputs": [],
249 | "name": "validatePeg",
250 | "outputs": [],
251 | "stateMutability": "nonpayable",
252 | "type": "function"
253 | },
254 | {
255 | "inputs": [
256 | {
257 | "internalType": "uint256",
258 | "name": "_amount",
259 | "type": "uint256"
260 | }
261 | ],
262 | "name": "withdraw",
263 | "outputs": [],
264 | "stateMutability": "nonpayable",
265 | "type": "function"
266 | },
267 | {
268 | "inputs": [
269 | {
270 | "internalType": "contract N2DUSD",
271 | "name": "_n2dusd",
272 | "type": "address"
273 | }
274 | ],
275 | "stateMutability": "nonpayable",
276 | "type": "constructor"
277 | },
278 | {
279 | "inputs": [
280 | {
281 | "internalType": "uint256",
282 | "name": "",
283 | "type": "uint256"
284 | }
285 | ],
286 | "name": "_supplyChanges",
287 | "outputs": [
288 | {
289 | "internalType": "string",
290 | "name": "method",
291 | "type": "string"
292 | },
293 | {
294 | "internalType": "uint256",
295 | "name": "amount",
296 | "type": "uint256"
297 | },
298 | {
299 | "internalType": "uint256",
300 | "name": "timestamp",
301 | "type": "uint256"
302 | },
303 | {
304 | "internalType": "uint256",
305 | "name": "blocknum",
306 | "type": "uint256"
307 | }
308 | ],
309 | "stateMutability": "view",
310 | "type": "function"
311 | },
312 | {
313 | "inputs": [],
314 | "name": "DEFAULT_ADMIN_ROLE",
315 | "outputs": [
316 | {
317 | "internalType": "bytes32",
318 | "name": "",
319 | "type": "bytes32"
320 | }
321 | ],
322 | "stateMutability": "view",
323 | "type": "function"
324 | },
325 | {
326 | "inputs": [
327 | {
328 | "internalType": "bytes32",
329 | "name": "role",
330 | "type": "bytes32"
331 | }
332 | ],
333 | "name": "getRoleAdmin",
334 | "outputs": [
335 | {
336 | "internalType": "bytes32",
337 | "name": "",
338 | "type": "bytes32"
339 | }
340 | ],
341 | "stateMutability": "view",
342 | "type": "function"
343 | },
344 | {
345 | "inputs": [],
346 | "name": "GOVERN_ROLE",
347 | "outputs": [
348 | {
349 | "internalType": "bytes32",
350 | "name": "",
351 | "type": "bytes32"
352 | }
353 | ],
354 | "stateMutability": "view",
355 | "type": "function"
356 | },
357 | {
358 | "inputs": [
359 | {
360 | "internalType": "bytes32",
361 | "name": "role",
362 | "type": "bytes32"
363 | },
364 | {
365 | "internalType": "address",
366 | "name": "account",
367 | "type": "address"
368 | }
369 | ],
370 | "name": "hasRole",
371 | "outputs": [
372 | {
373 | "internalType": "bool",
374 | "name": "",
375 | "type": "bool"
376 | }
377 | ],
378 | "stateMutability": "view",
379 | "type": "function"
380 | },
381 | {
382 | "inputs": [],
383 | "name": "n2dusdsupply",
384 | "outputs": [
385 | {
386 | "internalType": "uint256",
387 | "name": "",
388 | "type": "uint256"
389 | }
390 | ],
391 | "stateMutability": "view",
392 | "type": "function"
393 | },
394 | {
395 | "inputs": [],
396 | "name": "owner",
397 | "outputs": [
398 | {
399 | "internalType": "address",
400 | "name": "",
401 | "type": "address"
402 | }
403 | ],
404 | "stateMutability": "view",
405 | "type": "function"
406 | },
407 | {
408 | "inputs": [],
409 | "name": "reserveContract",
410 | "outputs": [
411 | {
412 | "internalType": "address",
413 | "name": "",
414 | "type": "address"
415 | }
416 | ],
417 | "stateMutability": "view",
418 | "type": "function"
419 | },
420 | {
421 | "inputs": [],
422 | "name": "reserveCount",
423 | "outputs": [
424 | {
425 | "internalType": "uint256",
426 | "name": "",
427 | "type": "uint256"
428 | }
429 | ],
430 | "stateMutability": "view",
431 | "type": "function"
432 | },
433 | {
434 | "inputs": [
435 | {
436 | "internalType": "uint256",
437 | "name": "",
438 | "type": "uint256"
439 | }
440 | ],
441 | "name": "rsvList",
442 | "outputs": [
443 | {
444 | "internalType": "contract IERC20",
445 | "name": "colToken",
446 | "type": "address"
447 | }
448 | ],
449 | "stateMutability": "view",
450 | "type": "function"
451 | },
452 | {
453 | "inputs": [],
454 | "name": "stableColatAmount",
455 | "outputs": [
456 | {
457 | "internalType": "uint256",
458 | "name": "",
459 | "type": "uint256"
460 | }
461 | ],
462 | "stateMutability": "view",
463 | "type": "function"
464 | },
465 | {
466 | "inputs": [],
467 | "name": "stableColatPercent",
468 | "outputs": [
469 | {
470 | "internalType": "uint256",
471 | "name": "",
472 | "type": "uint256"
473 | }
474 | ],
475 | "stateMutability": "view",
476 | "type": "function"
477 | },
478 | {
479 | "inputs": [],
480 | "name": "stableColatPrice",
481 | "outputs": [
482 | {
483 | "internalType": "uint256",
484 | "name": "",
485 | "type": "uint256"
486 | }
487 | ],
488 | "stateMutability": "view",
489 | "type": "function"
490 | },
491 | {
492 | "inputs": [],
493 | "name": "supplyChangeCount",
494 | "outputs": [
495 | {
496 | "internalType": "uint256",
497 | "name": "",
498 | "type": "uint256"
499 | }
500 | ],
501 | "stateMutability": "view",
502 | "type": "function"
503 | },
504 | {
505 | "inputs": [
506 | {
507 | "internalType": "bytes4",
508 | "name": "interfaceId",
509 | "type": "bytes4"
510 | }
511 | ],
512 | "name": "supportsInterface",
513 | "outputs": [
514 | {
515 | "internalType": "bool",
516 | "name": "",
517 | "type": "bool"
518 | }
519 | ],
520 | "stateMutability": "view",
521 | "type": "function"
522 | },
523 | {
524 | "inputs": [],
525 | "name": "unstableColatAmount",
526 | "outputs": [
527 | {
528 | "internalType": "uint256",
529 | "name": "",
530 | "type": "uint256"
531 | }
532 | ],
533 | "stateMutability": "view",
534 | "type": "function"
535 | },
536 | {
537 | "inputs": [],
538 | "name": "unstableColPrice",
539 | "outputs": [
540 | {
541 | "internalType": "uint256",
542 | "name": "",
543 | "type": "uint256"
544 | }
545 | ],
546 | "stateMutability": "view",
547 | "type": "function"
548 | }
549 | ]
--------------------------------------------------------------------------------
/Final/Frontend/components/n2dusd-chart.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { Line } from "react-chartjs-2";
3 | import {
4 | Chart as ChartJS,
5 | CategoryScale,
6 | PointElement,
7 | LineElement,
8 | LinearScale,
9 | Title,
10 | Tooltip,
11 | Legend,
12 | Filler,
13 | } from 'chart.js';
14 |
15 |
16 | const backend = "http://localhost:8082";
17 |
18 |
19 | ChartJS.register(
20 | CategoryScale,
21 | Filler,
22 | LinearScale,
23 | PointElement,
24 | LineElement,
25 | Title,
26 | Tooltip,
27 | Legend
28 | );
29 |
30 |
31 | export function N2dusdChart() {
32 | const [priceaction, getPrice] = useState([]);
33 | const [timeaction, getTime] = useState([]);
34 | const [status, colorStatus] = useState('');
35 | const [liveprice, getLivePrice] = useState('');
36 |
37 | useEffect(() => {
38 | const updateChart = setInterval(() => {
39 | getChart();
40 | }, 2000);
41 | return () => clearInterval(updateChart);
42 | }, [liveprice]);
43 |
44 |
45 | async function getChart() {
46 | let token = 'n2usd'
47 | const url = backend + "/getchartinfo";
48 | const config = {
49 | method: "POST",
50 | body: JSON.stringify({ token }),
51 | headers: {
52 | "content-type": "application/json",
53 | },
54 | };
55 | const response = await fetch(url, config);
56 | const output = await response.json();
57 | const pricearray = output.chartprice;
58 | const timearray = output.charttime;
59 | let price = []
60 | let time = []
61 | let i = 0
62 | for (i; i < pricearray.length; i++){
63 | let pricenum = (pricearray[i]).toFixed(4)
64 | price.push(pricenum)
65 | time.push(timearray[i])
66 | }
67 | price.reverse()
68 | time.reverse()
69 | getLivePrice(price[0])
70 | let previous = Number(price[1])
71 | let newvalue = Number(price[0])
72 | if (previous < newvalue) {
73 | colorStatus('#39ff1450')
74 | }
75 | else if (previous > newvalue){
76 | colorStatus('#dd00a980')
77 | }
78 | else
79 | colorStatus('#00c0f935')
80 | getPrice(price);
81 | getTime(time);
82 | }
83 |
84 | const data = {
85 | labels: [ timeaction[10],timeaction[9],timeaction[8], timeaction[7], timeaction[6], timeaction[5], timeaction[4], timeaction[3], timeaction[2], timeaction[1], timeaction[timeaction.length]],
86 | datasets: [
87 | {
88 | lineTension: 0.4,
89 | label: 'n2USD',
90 | borderColor: "#ffffff",
91 | borderWidth: 2,
92 | backgroundColor: status,
93 | borderDashOffset: 0.7,
94 | borderJoinStyle: 'round',
95 | pointBackgroundColor: "white",
96 | pointBorderWidth: 2,
97 | pointColor: 'black',
98 | pointHoverBackgroundColor: "rgba(75,192,192,1)",
99 | pointHoverBorderColor: "white",
100 | pointHoverBorderWidth: 1,
101 | pointRadius: 3,
102 | data: [priceaction[10],priceaction[9],priceaction[8], priceaction[7], priceaction[6], priceaction[5], priceaction[4], priceaction[3], priceaction[2], priceaction[1], priceaction[0]],
103 | fill: 'origin',
104 | }
105 | ],
106 | };
107 |
108 | const options = {
109 | plugins: {
110 | legend: {
111 | display: false,
112 | },
113 | },
114 | scales: {
115 | x: {
116 | grid: {
117 | display: false,
118 | drawBorder: false,
119 | },
120 | ticks:{
121 | display:true,
122 | beginAtZero: true,
123 | align: 'start',
124 | color: '#ffffff',
125 | font: {
126 | size: 14,
127 | family:'SF Pro Display'
128 | }
129 | }
130 | },
131 | y: {
132 | type: 'linear',
133 | position:'right',
134 | min: 0.8,
135 | max: 1.12,
136 | grid: {
137 | drawBorder:false,
138 | display: false,
139 | },
140 | ticks:{
141 | display: true,
142 | color: '#fff',
143 | font: {
144 | size: 16,
145 | family:'SF Pro Display'
146 | }
147 | }
148 | },
149 | },
150 | }
151 |
152 | return (
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
{liveprice}
161 |
162 |
163 |
164 |
165 |
166 | );
167 | }
168 |
--------------------------------------------------------------------------------
/Final/Frontend/components/n2usdabi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "address",
8 | "name": "owner",
9 | "type": "address"
10 | },
11 | {
12 | "indexed": true,
13 | "internalType": "address",
14 | "name": "spender",
15 | "type": "address"
16 | },
17 | {
18 | "indexed": false,
19 | "internalType": "uint256",
20 | "name": "value",
21 | "type": "uint256"
22 | }
23 | ],
24 | "name": "Approval",
25 | "type": "event"
26 | },
27 | {
28 | "anonymous": false,
29 | "inputs": [
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "previousOwner",
34 | "type": "address"
35 | },
36 | {
37 | "indexed": true,
38 | "internalType": "address",
39 | "name": "newOwner",
40 | "type": "address"
41 | }
42 | ],
43 | "name": "OwnershipTransferred",
44 | "type": "event"
45 | },
46 | {
47 | "anonymous": false,
48 | "inputs": [
49 | {
50 | "indexed": true,
51 | "internalType": "bytes32",
52 | "name": "role",
53 | "type": "bytes32"
54 | },
55 | {
56 | "indexed": true,
57 | "internalType": "bytes32",
58 | "name": "previousAdminRole",
59 | "type": "bytes32"
60 | },
61 | {
62 | "indexed": true,
63 | "internalType": "bytes32",
64 | "name": "newAdminRole",
65 | "type": "bytes32"
66 | }
67 | ],
68 | "name": "RoleAdminChanged",
69 | "type": "event"
70 | },
71 | {
72 | "anonymous": false,
73 | "inputs": [
74 | {
75 | "indexed": true,
76 | "internalType": "bytes32",
77 | "name": "role",
78 | "type": "bytes32"
79 | },
80 | {
81 | "indexed": true,
82 | "internalType": "address",
83 | "name": "account",
84 | "type": "address"
85 | },
86 | {
87 | "indexed": true,
88 | "internalType": "address",
89 | "name": "sender",
90 | "type": "address"
91 | }
92 | ],
93 | "name": "RoleGranted",
94 | "type": "event"
95 | },
96 | {
97 | "anonymous": false,
98 | "inputs": [
99 | {
100 | "indexed": true,
101 | "internalType": "bytes32",
102 | "name": "role",
103 | "type": "bytes32"
104 | },
105 | {
106 | "indexed": true,
107 | "internalType": "address",
108 | "name": "account",
109 | "type": "address"
110 | },
111 | {
112 | "indexed": true,
113 | "internalType": "address",
114 | "name": "sender",
115 | "type": "address"
116 | }
117 | ],
118 | "name": "RoleRevoked",
119 | "type": "event"
120 | },
121 | {
122 | "anonymous": false,
123 | "inputs": [
124 | {
125 | "indexed": true,
126 | "internalType": "address",
127 | "name": "from",
128 | "type": "address"
129 | },
130 | {
131 | "indexed": true,
132 | "internalType": "address",
133 | "name": "to",
134 | "type": "address"
135 | },
136 | {
137 | "indexed": false,
138 | "internalType": "uint256",
139 | "name": "value",
140 | "type": "uint256"
141 | }
142 | ],
143 | "name": "Transfer",
144 | "type": "event"
145 | },
146 | {
147 | "inputs": [
148 | {
149 | "internalType": "address",
150 | "name": "spender",
151 | "type": "address"
152 | },
153 | {
154 | "internalType": "uint256",
155 | "name": "amount",
156 | "type": "uint256"
157 | }
158 | ],
159 | "name": "approve",
160 | "outputs": [
161 | {
162 | "internalType": "bool",
163 | "name": "",
164 | "type": "bool"
165 | }
166 | ],
167 | "stateMutability": "nonpayable",
168 | "type": "function"
169 | },
170 | {
171 | "inputs": [
172 | {
173 | "internalType": "uint256",
174 | "name": "amount",
175 | "type": "uint256"
176 | }
177 | ],
178 | "name": "burn",
179 | "outputs": [],
180 | "stateMutability": "nonpayable",
181 | "type": "function"
182 | },
183 | {
184 | "inputs": [
185 | {
186 | "internalType": "address",
187 | "name": "account",
188 | "type": "address"
189 | },
190 | {
191 | "internalType": "uint256",
192 | "name": "amount",
193 | "type": "uint256"
194 | }
195 | ],
196 | "name": "burnFrom",
197 | "outputs": [],
198 | "stateMutability": "nonpayable",
199 | "type": "function"
200 | },
201 | {
202 | "inputs": [
203 | {
204 | "internalType": "address",
205 | "name": "spender",
206 | "type": "address"
207 | },
208 | {
209 | "internalType": "uint256",
210 | "name": "subtractedValue",
211 | "type": "uint256"
212 | }
213 | ],
214 | "name": "decreaseAllowance",
215 | "outputs": [
216 | {
217 | "internalType": "bool",
218 | "name": "",
219 | "type": "bool"
220 | }
221 | ],
222 | "stateMutability": "nonpayable",
223 | "type": "function"
224 | },
225 | {
226 | "inputs": [
227 | {
228 | "internalType": "bytes32",
229 | "name": "role",
230 | "type": "bytes32"
231 | },
232 | {
233 | "internalType": "address",
234 | "name": "account",
235 | "type": "address"
236 | }
237 | ],
238 | "name": "grantRole",
239 | "outputs": [],
240 | "stateMutability": "nonpayable",
241 | "type": "function"
242 | },
243 | {
244 | "inputs": [
245 | {
246 | "internalType": "address",
247 | "name": "spender",
248 | "type": "address"
249 | },
250 | {
251 | "internalType": "uint256",
252 | "name": "addedValue",
253 | "type": "uint256"
254 | }
255 | ],
256 | "name": "increaseAllowance",
257 | "outputs": [
258 | {
259 | "internalType": "bool",
260 | "name": "",
261 | "type": "bool"
262 | }
263 | ],
264 | "stateMutability": "nonpayable",
265 | "type": "function"
266 | },
267 | {
268 | "inputs": [
269 | {
270 | "internalType": "uint256",
271 | "name": "amount",
272 | "type": "uint256"
273 | }
274 | ],
275 | "name": "mint",
276 | "outputs": [],
277 | "stateMutability": "nonpayable",
278 | "type": "function"
279 | },
280 | {
281 | "inputs": [],
282 | "name": "renounceOwnership",
283 | "outputs": [],
284 | "stateMutability": "nonpayable",
285 | "type": "function"
286 | },
287 | {
288 | "inputs": [
289 | {
290 | "internalType": "bytes32",
291 | "name": "role",
292 | "type": "bytes32"
293 | },
294 | {
295 | "internalType": "address",
296 | "name": "account",
297 | "type": "address"
298 | }
299 | ],
300 | "name": "renounceRole",
301 | "outputs": [],
302 | "stateMutability": "nonpayable",
303 | "type": "function"
304 | },
305 | {
306 | "inputs": [
307 | {
308 | "internalType": "bytes32",
309 | "name": "role",
310 | "type": "bytes32"
311 | },
312 | {
313 | "internalType": "address",
314 | "name": "account",
315 | "type": "address"
316 | }
317 | ],
318 | "name": "revokeRole",
319 | "outputs": [],
320 | "stateMutability": "nonpayable",
321 | "type": "function"
322 | },
323 | {
324 | "inputs": [
325 | {
326 | "internalType": "address",
327 | "name": "to",
328 | "type": "address"
329 | },
330 | {
331 | "internalType": "uint256",
332 | "name": "amount",
333 | "type": "uint256"
334 | }
335 | ],
336 | "name": "transfer",
337 | "outputs": [
338 | {
339 | "internalType": "bool",
340 | "name": "",
341 | "type": "bool"
342 | }
343 | ],
344 | "stateMutability": "nonpayable",
345 | "type": "function"
346 | },
347 | {
348 | "inputs": [
349 | {
350 | "internalType": "address",
351 | "name": "from",
352 | "type": "address"
353 | },
354 | {
355 | "internalType": "address",
356 | "name": "to",
357 | "type": "address"
358 | },
359 | {
360 | "internalType": "uint256",
361 | "name": "amount",
362 | "type": "uint256"
363 | }
364 | ],
365 | "name": "transferFrom",
366 | "outputs": [
367 | {
368 | "internalType": "bool",
369 | "name": "",
370 | "type": "bool"
371 | }
372 | ],
373 | "stateMutability": "nonpayable",
374 | "type": "function"
375 | },
376 | {
377 | "inputs": [
378 | {
379 | "internalType": "address",
380 | "name": "newOwner",
381 | "type": "address"
382 | }
383 | ],
384 | "name": "transferOwnership",
385 | "outputs": [],
386 | "stateMutability": "nonpayable",
387 | "type": "function"
388 | },
389 | {
390 | "inputs": [],
391 | "stateMutability": "nonpayable",
392 | "type": "constructor"
393 | },
394 | {
395 | "inputs": [
396 | {
397 | "internalType": "address",
398 | "name": "owner",
399 | "type": "address"
400 | },
401 | {
402 | "internalType": "address",
403 | "name": "spender",
404 | "type": "address"
405 | }
406 | ],
407 | "name": "allowance",
408 | "outputs": [
409 | {
410 | "internalType": "uint256",
411 | "name": "",
412 | "type": "uint256"
413 | }
414 | ],
415 | "stateMutability": "view",
416 | "type": "function"
417 | },
418 | {
419 | "inputs": [
420 | {
421 | "internalType": "address",
422 | "name": "account",
423 | "type": "address"
424 | }
425 | ],
426 | "name": "balanceOf",
427 | "outputs": [
428 | {
429 | "internalType": "uint256",
430 | "name": "",
431 | "type": "uint256"
432 | }
433 | ],
434 | "stateMutability": "view",
435 | "type": "function"
436 | },
437 | {
438 | "inputs": [],
439 | "name": "decimals",
440 | "outputs": [
441 | {
442 | "internalType": "uint8",
443 | "name": "",
444 | "type": "uint8"
445 | }
446 | ],
447 | "stateMutability": "view",
448 | "type": "function"
449 | },
450 | {
451 | "inputs": [],
452 | "name": "DEFAULT_ADMIN_ROLE",
453 | "outputs": [
454 | {
455 | "internalType": "bytes32",
456 | "name": "",
457 | "type": "bytes32"
458 | }
459 | ],
460 | "stateMutability": "view",
461 | "type": "function"
462 | },
463 | {
464 | "inputs": [
465 | {
466 | "internalType": "bytes32",
467 | "name": "role",
468 | "type": "bytes32"
469 | }
470 | ],
471 | "name": "getRoleAdmin",
472 | "outputs": [
473 | {
474 | "internalType": "bytes32",
475 | "name": "",
476 | "type": "bytes32"
477 | }
478 | ],
479 | "stateMutability": "view",
480 | "type": "function"
481 | },
482 | {
483 | "inputs": [
484 | {
485 | "internalType": "bytes32",
486 | "name": "role",
487 | "type": "bytes32"
488 | },
489 | {
490 | "internalType": "address",
491 | "name": "account",
492 | "type": "address"
493 | }
494 | ],
495 | "name": "hasRole",
496 | "outputs": [
497 | {
498 | "internalType": "bool",
499 | "name": "",
500 | "type": "bool"
501 | }
502 | ],
503 | "stateMutability": "view",
504 | "type": "function"
505 | },
506 | {
507 | "inputs": [],
508 | "name": "MANAGER_ROLE",
509 | "outputs": [
510 | {
511 | "internalType": "bytes32",
512 | "name": "",
513 | "type": "bytes32"
514 | }
515 | ],
516 | "stateMutability": "view",
517 | "type": "function"
518 | },
519 | {
520 | "inputs": [],
521 | "name": "name",
522 | "outputs": [
523 | {
524 | "internalType": "string",
525 | "name": "",
526 | "type": "string"
527 | }
528 | ],
529 | "stateMutability": "view",
530 | "type": "function"
531 | },
532 | {
533 | "inputs": [],
534 | "name": "owner",
535 | "outputs": [
536 | {
537 | "internalType": "address",
538 | "name": "",
539 | "type": "address"
540 | }
541 | ],
542 | "stateMutability": "view",
543 | "type": "function"
544 | },
545 | {
546 | "inputs": [
547 | {
548 | "internalType": "bytes4",
549 | "name": "interfaceId",
550 | "type": "bytes4"
551 | }
552 | ],
553 | "name": "supportsInterface",
554 | "outputs": [
555 | {
556 | "internalType": "bool",
557 | "name": "",
558 | "type": "bool"
559 | }
560 | ],
561 | "stateMutability": "view",
562 | "type": "function"
563 | },
564 | {
565 | "inputs": [],
566 | "name": "symbol",
567 | "outputs": [
568 | {
569 | "internalType": "string",
570 | "name": "",
571 | "type": "string"
572 | }
573 | ],
574 | "stateMutability": "view",
575 | "type": "function"
576 | },
577 | {
578 | "inputs": [],
579 | "name": "totalSupply",
580 | "outputs": [
581 | {
582 | "internalType": "uint256",
583 | "name": "",
584 | "type": "uint256"
585 | }
586 | ],
587 | "stateMutability": "view",
588 | "type": "function"
589 | }
590 | ]
--------------------------------------------------------------------------------
/Final/Frontend/components/rsvabi.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "anonymous": false,
4 | "inputs": [
5 | {
6 | "indexed": true,
7 | "internalType": "uint256",
8 | "name": "pid",
9 | "type": "uint256"
10 | },
11 | {
12 | "indexed": false,
13 | "internalType": "uint256",
14 | "name": "amount",
15 | "type": "uint256"
16 | }
17 | ],
18 | "name": "Deposit",
19 | "type": "event"
20 | },
21 | {
22 | "anonymous": false,
23 | "inputs": [
24 | {
25 | "indexed": true,
26 | "internalType": "address",
27 | "name": "previousOwner",
28 | "type": "address"
29 | },
30 | {
31 | "indexed": true,
32 | "internalType": "address",
33 | "name": "newOwner",
34 | "type": "address"
35 | }
36 | ],
37 | "name": "OwnershipTransferred",
38 | "type": "event"
39 | },
40 | {
41 | "anonymous": false,
42 | "inputs": [
43 | {
44 | "indexed": true,
45 | "internalType": "bytes32",
46 | "name": "role",
47 | "type": "bytes32"
48 | },
49 | {
50 | "indexed": true,
51 | "internalType": "bytes32",
52 | "name": "previousAdminRole",
53 | "type": "bytes32"
54 | },
55 | {
56 | "indexed": true,
57 | "internalType": "bytes32",
58 | "name": "newAdminRole",
59 | "type": "bytes32"
60 | }
61 | ],
62 | "name": "RoleAdminChanged",
63 | "type": "event"
64 | },
65 | {
66 | "anonymous": false,
67 | "inputs": [
68 | {
69 | "indexed": true,
70 | "internalType": "bytes32",
71 | "name": "role",
72 | "type": "bytes32"
73 | },
74 | {
75 | "indexed": true,
76 | "internalType": "address",
77 | "name": "account",
78 | "type": "address"
79 | },
80 | {
81 | "indexed": true,
82 | "internalType": "address",
83 | "name": "sender",
84 | "type": "address"
85 | }
86 | ],
87 | "name": "RoleGranted",
88 | "type": "event"
89 | },
90 | {
91 | "anonymous": false,
92 | "inputs": [
93 | {
94 | "indexed": true,
95 | "internalType": "bytes32",
96 | "name": "role",
97 | "type": "bytes32"
98 | },
99 | {
100 | "indexed": true,
101 | "internalType": "address",
102 | "name": "account",
103 | "type": "address"
104 | },
105 | {
106 | "indexed": true,
107 | "internalType": "address",
108 | "name": "sender",
109 | "type": "address"
110 | }
111 | ],
112 | "name": "RoleRevoked",
113 | "type": "event"
114 | },
115 | {
116 | "anonymous": false,
117 | "inputs": [
118 | {
119 | "indexed": true,
120 | "internalType": "uint256",
121 | "name": "pid",
122 | "type": "uint256"
123 | },
124 | {
125 | "indexed": false,
126 | "internalType": "uint256",
127 | "name": "amount",
128 | "type": "uint256"
129 | }
130 | ],
131 | "name": "Withdraw",
132 | "type": "event"
133 | },
134 | {
135 | "inputs": [
136 | {
137 | "internalType": "contract IERC20",
138 | "name": "_colToken",
139 | "type": "address"
140 | }
141 | ],
142 | "name": "addReserve",
143 | "outputs": [],
144 | "stateMutability": "nonpayable",
145 | "type": "function"
146 | },
147 | {
148 | "inputs": [
149 | {
150 | "internalType": "uint256",
151 | "name": "_pid",
152 | "type": "uint256"
153 | },
154 | {
155 | "internalType": "uint256",
156 | "name": "_amount",
157 | "type": "uint256"
158 | }
159 | ],
160 | "name": "deposit",
161 | "outputs": [],
162 | "stateMutability": "nonpayable",
163 | "type": "function"
164 | },
165 | {
166 | "inputs": [
167 | {
168 | "internalType": "bytes32",
169 | "name": "role",
170 | "type": "bytes32"
171 | },
172 | {
173 | "internalType": "address",
174 | "name": "account",
175 | "type": "address"
176 | }
177 | ],
178 | "name": "grantRole",
179 | "outputs": [],
180 | "stateMutability": "nonpayable",
181 | "type": "function"
182 | },
183 | {
184 | "inputs": [],
185 | "name": "renounceOwnership",
186 | "outputs": [],
187 | "stateMutability": "nonpayable",
188 | "type": "function"
189 | },
190 | {
191 | "inputs": [
192 | {
193 | "internalType": "bytes32",
194 | "name": "role",
195 | "type": "bytes32"
196 | },
197 | {
198 | "internalType": "address",
199 | "name": "account",
200 | "type": "address"
201 | }
202 | ],
203 | "name": "renounceRole",
204 | "outputs": [],
205 | "stateMutability": "nonpayable",
206 | "type": "function"
207 | },
208 | {
209 | "inputs": [
210 | {
211 | "internalType": "bytes32",
212 | "name": "role",
213 | "type": "bytes32"
214 | },
215 | {
216 | "internalType": "address",
217 | "name": "account",
218 | "type": "address"
219 | }
220 | ],
221 | "name": "revokeRole",
222 | "outputs": [],
223 | "stateMutability": "nonpayable",
224 | "type": "function"
225 | },
226 | {
227 | "inputs": [
228 | {
229 | "internalType": "address",
230 | "name": "newOwner",
231 | "type": "address"
232 | }
233 | ],
234 | "name": "transferOwnership",
235 | "outputs": [],
236 | "stateMutability": "nonpayable",
237 | "type": "function"
238 | },
239 | {
240 | "inputs": [
241 | {
242 | "internalType": "uint256",
243 | "name": "_pid",
244 | "type": "uint256"
245 | },
246 | {
247 | "internalType": "uint256",
248 | "name": "_amount",
249 | "type": "uint256"
250 | }
251 | ],
252 | "name": "withdraw",
253 | "outputs": [],
254 | "stateMutability": "nonpayable",
255 | "type": "function"
256 | },
257 | {
258 | "inputs": [],
259 | "stateMutability": "nonpayable",
260 | "type": "constructor"
261 | },
262 | {
263 | "inputs": [
264 | {
265 | "internalType": "contract IERC20",
266 | "name": "_colToken",
267 | "type": "address"
268 | }
269 | ],
270 | "name": "checkReserveDuplicate",
271 | "outputs": [],
272 | "stateMutability": "view",
273 | "type": "function"
274 | },
275 | {
276 | "inputs": [],
277 | "name": "DEFAULT_ADMIN_ROLE",
278 | "outputs": [
279 | {
280 | "internalType": "bytes32",
281 | "name": "",
282 | "type": "bytes32"
283 | }
284 | ],
285 | "stateMutability": "view",
286 | "type": "function"
287 | },
288 | {
289 | "inputs": [
290 | {
291 | "internalType": "bytes32",
292 | "name": "role",
293 | "type": "bytes32"
294 | }
295 | ],
296 | "name": "getRoleAdmin",
297 | "outputs": [
298 | {
299 | "internalType": "bytes32",
300 | "name": "",
301 | "type": "bytes32"
302 | }
303 | ],
304 | "stateMutability": "view",
305 | "type": "function"
306 | },
307 | {
308 | "inputs": [
309 | {
310 | "internalType": "bytes32",
311 | "name": "role",
312 | "type": "bytes32"
313 | },
314 | {
315 | "internalType": "address",
316 | "name": "account",
317 | "type": "address"
318 | }
319 | ],
320 | "name": "hasRole",
321 | "outputs": [
322 | {
323 | "internalType": "bool",
324 | "name": "",
325 | "type": "bool"
326 | }
327 | ],
328 | "stateMutability": "view",
329 | "type": "function"
330 | },
331 | {
332 | "inputs": [],
333 | "name": "MANAGER_ROLE",
334 | "outputs": [
335 | {
336 | "internalType": "bytes32",
337 | "name": "",
338 | "type": "bytes32"
339 | }
340 | ],
341 | "stateMutability": "view",
342 | "type": "function"
343 | },
344 | {
345 | "inputs": [],
346 | "name": "owner",
347 | "outputs": [
348 | {
349 | "internalType": "address",
350 | "name": "",
351 | "type": "address"
352 | }
353 | ],
354 | "stateMutability": "view",
355 | "type": "function"
356 | },
357 | {
358 | "inputs": [],
359 | "name": "reserveLength",
360 | "outputs": [
361 | {
362 | "internalType": "uint256",
363 | "name": "",
364 | "type": "uint256"
365 | }
366 | ],
367 | "stateMutability": "view",
368 | "type": "function"
369 | },
370 | {
371 | "inputs": [
372 | {
373 | "internalType": "uint256",
374 | "name": "",
375 | "type": "uint256"
376 | }
377 | ],
378 | "name": "rsvVault",
379 | "outputs": [
380 | {
381 | "internalType": "contract IERC20",
382 | "name": "colToken",
383 | "type": "address"
384 | },
385 | {
386 | "internalType": "uint256",
387 | "name": "amount",
388 | "type": "uint256"
389 | }
390 | ],
391 | "stateMutability": "view",
392 | "type": "function"
393 | },
394 | {
395 | "inputs": [
396 | {
397 | "internalType": "bytes4",
398 | "name": "interfaceId",
399 | "type": "bytes4"
400 | }
401 | ],
402 | "name": "supportsInterface",
403 | "outputs": [
404 | {
405 | "internalType": "bool",
406 | "name": "",
407 | "type": "bool"
408 | }
409 | ],
410 | "stateMutability": "view",
411 | "type": "function"
412 | }
413 | ]
--------------------------------------------------------------------------------
/Final/Frontend/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Final/Frontend/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | module.exports = nextConfig
7 |
--------------------------------------------------------------------------------
/Final/Frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "algochart",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "eslint": "8.45.0",
13 | "eslint-config-next": "13.4.12",
14 | "axios": "^1.3.2",
15 | "bootstrap": "^5.3.0-alpha3",
16 | "chart.js": "^4.3.0",
17 | "chartjs-plugin-datalabels": "^2.2.0",
18 | "react-chartjs-2": "^5.2.0",
19 | "next": "13.4.12",
20 | "react": "18.2.0",
21 | "ethers": "^5.7.2",
22 | "react-dom": "18.2.0",
23 | "sass": "^1.62.1",
24 | "sf-font": "^1.0.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Final/Frontend/pages/_app.js:
--------------------------------------------------------------------------------
1 | import 'bootstrap/dist/css/bootstrap.min.css';
2 | import '@/styles/globals.css'
3 | import '@/styles/reserves.css'
4 | import 'sf-font';
5 | import { useEffect } from "react";
6 |
7 |
8 | function MyApp({ Component, pageProps }) {
9 |
10 | useEffect(() => {
11 | require("bootstrap/dist/js/bootstrap.bundle.min.js");
12 | }, []);
13 |
14 | return (
15 |
30 | )
31 | }
32 |
33 | export default MyApp
--------------------------------------------------------------------------------
/Final/Frontend/pages/_document.js:
--------------------------------------------------------------------------------
1 | import { Html, Head, Main, NextScript } from 'next/document'
2 |
3 | export default function Document() {
4 | return (
5 |
6 |
8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/Final/Frontend/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default function handler(req, res) {
4 | res.status(200).json({ name: 'John Doe' })
5 | }
6 |
--------------------------------------------------------------------------------
/Final/Frontend/pages/index.js:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import React from 'react'
3 | import { useState, useEffect } from 'react';
4 | import { getReserves } from '../components/config';
5 | import { N2dusdChart } from '../components/n2dusd-chart';
6 |
7 | export default function Reserves() {
8 | const [reservesInfo, storeReserves] = useState([])
9 |
10 | useEffect(() => {
11 | const updateStats = setInterval(() => {
12 | getCollaterals();
13 | }, 1000);
14 | return () => clearInterval(updateStats);
15 | }, [reservesInfo]);
16 |
17 | useEffect(() => {
18 | counterNum()
19 | }, [reservesInfo]);
20 |
21 | async function getCollaterals(){
22 | const output = await getReserves();
23 | let colla = output.rsvamounts[0]
24 | let collb = output.rsvamounts[1]
25 | let n2dusdsup = output.n2dusdsupply
26 | const reservesInfo = [
27 | {
28 | coinLogo: "n2usd-logo.png",
29 | colA: "USDT",
30 | colAsupply: colla,
31 | colB: "WETH",
32 | colBsupply: collb,
33 | total: n2dusdsup,
34 | },
35 | ];
36 | storeReserves(reservesInfo)
37 | }
38 |
39 | async function counterNum() {
40 | const counters = document.querySelectorAll(".value");
41 | const speed = 400;
42 |
43 | counters.forEach( counter => {
44 | const animate = () => {
45 | const value = +counter.getAttribute('count');
46 | const data = +counter.innerText;
47 |
48 | const time = value / speed;
49 | if(data < value) {
50 | counter.innerText = (Math.ceil(data + time))
51 | setTimeout(animate, 1);
52 | }else{
53 | counter.innerText = value.toLocaleString();
54 | }
55 |
56 | }
57 |
58 | animate();
59 | });
60 | }
61 |
62 | return (
63 |
64 |
65 |
N2DeX
66 |
67 |
68 |
69 |
70 |
71 |
72 | Stablecoins Are Meant To Be Agnostic.
73 |
74 |
75 |
83 |
84 |
85 | Live Reserves Stats
86 |
87 |
88 | {reservesInfo.map((col, i) => (
89 |
90 |
107 |
111 |
{col.colA}
112 |
113 |
117 | 0
118 |
119 |
120 |
121 |
125 |
{col.colB}
126 |
127 |
131 | 0
132 |
133 |
134 |
135 |
139 |
Total Supply
140 |
141 |
145 | 0
146 |
147 |
148 |
149 |
150 | ))}
151 |
152 |
153 |
154 | );
155 | }
156 |
--------------------------------------------------------------------------------
/Final/Frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/net2devcrypto/Algorithmic-Stablecoin-ERC20/cd21427fc93a34ee3d45b09f7ac10ceb538e5f75/Final/Frontend/public/favicon.ico
--------------------------------------------------------------------------------
/Final/Frontend/public/n2usd-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/net2devcrypto/Algorithmic-Stablecoin-ERC20/cd21427fc93a34ee3d45b09f7ac10ceb538e5f75/Final/Frontend/public/n2usd-logo.png
--------------------------------------------------------------------------------
/Final/Frontend/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Final/Frontend/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Final/Frontend/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .main {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: space-between;
5 | align-items: center;
6 | padding: 6rem;
7 | min-height: 100vh;
8 | }
9 |
10 | .description {
11 | display: inherit;
12 | justify-content: inherit;
13 | align-items: inherit;
14 | font-size: 0.85rem;
15 | max-width: var(--max-width);
16 | width: 100%;
17 | z-index: 2;
18 | font-family: var(--font-mono);
19 | }
20 |
21 | .description a {
22 | display: flex;
23 | justify-content: center;
24 | align-items: center;
25 | gap: 0.5rem;
26 | }
27 |
28 | .description p {
29 | position: relative;
30 | margin: 0;
31 | padding: 1rem;
32 | background-color: rgba(var(--callout-rgb), 0.5);
33 | border: 1px solid rgba(var(--callout-border-rgb), 0.3);
34 | border-radius: var(--border-radius);
35 | }
36 |
37 | .code {
38 | font-weight: 700;
39 | font-family: var(--font-mono);
40 | }
41 |
42 | .grid {
43 | display: grid;
44 | grid-template-columns: repeat(4, minmax(25%, auto));
45 | width: var(--max-width);
46 | max-width: 100%;
47 | }
48 |
49 | .card {
50 | padding: 1rem 1.2rem;
51 | border-radius: var(--border-radius);
52 | background: rgba(var(--card-rgb), 0);
53 | border: 1px solid rgba(var(--card-border-rgb), 0);
54 | transition: background 200ms, border 200ms;
55 | }
56 |
57 | .card span {
58 | display: inline-block;
59 | transition: transform 200ms;
60 | }
61 |
62 | .card h2 {
63 | font-weight: 600;
64 | margin-bottom: 0.7rem;
65 | }
66 |
67 | .card p {
68 | margin: 0;
69 | opacity: 0.6;
70 | font-size: 0.9rem;
71 | line-height: 1.5;
72 | max-width: 30ch;
73 | }
74 |
75 | .center {
76 | display: flex;
77 | justify-content: center;
78 | align-items: center;
79 | position: relative;
80 | padding: 4rem 0;
81 | }
82 |
83 | .center::before {
84 | background: var(--secondary-glow);
85 | border-radius: 50%;
86 | width: 480px;
87 | height: 360px;
88 | margin-left: -400px;
89 | }
90 |
91 | .center::after {
92 | background: var(--primary-glow);
93 | width: 240px;
94 | height: 180px;
95 | z-index: -1;
96 | }
97 |
98 | .center::before,
99 | .center::after {
100 | content: '';
101 | left: 50%;
102 | position: absolute;
103 | filter: blur(45px);
104 | transform: translateZ(0);
105 | }
106 |
107 | .logo {
108 | position: relative;
109 | }
110 | /* Enable hover only on non-touch devices */
111 | @media (hover: hover) and (pointer: fine) {
112 | .card:hover {
113 | background: rgba(var(--card-rgb), 0.1);
114 | border: 1px solid rgba(var(--card-border-rgb), 0.15);
115 | }
116 |
117 | .card:hover span {
118 | transform: translateX(4px);
119 | }
120 | }
121 |
122 | @media (prefers-reduced-motion) {
123 | .card:hover span {
124 | transform: none;
125 | }
126 | }
127 |
128 | /* Mobile */
129 | @media (max-width: 700px) {
130 | .content {
131 | padding: 4rem;
132 | }
133 |
134 | .grid {
135 | grid-template-columns: 1fr;
136 | margin-bottom: 120px;
137 | max-width: 320px;
138 | text-align: center;
139 | }
140 |
141 | .card {
142 | padding: 1rem 2.5rem;
143 | }
144 |
145 | .card h2 {
146 | margin-bottom: 0.5rem;
147 | }
148 |
149 | .center {
150 | padding: 8rem 0 6rem;
151 | }
152 |
153 | .center::before {
154 | transform: none;
155 | height: 300px;
156 | }
157 |
158 | .description {
159 | font-size: 0.8rem;
160 | }
161 |
162 | .description a {
163 | padding: 1rem;
164 | }
165 |
166 | .description p,
167 | .description div {
168 | display: flex;
169 | justify-content: center;
170 | position: fixed;
171 | width: 100%;
172 | }
173 |
174 | .description p {
175 | align-items: center;
176 | inset: 0 0 auto;
177 | padding: 2rem 1rem 1.4rem;
178 | border-radius: 0;
179 | border: none;
180 | border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25);
181 | background: linear-gradient(
182 | to bottom,
183 | rgba(var(--background-start-rgb), 1),
184 | rgba(var(--callout-rgb), 0.5)
185 | );
186 | background-clip: padding-box;
187 | backdrop-filter: blur(24px);
188 | }
189 |
190 | .description div {
191 | align-items: flex-end;
192 | pointer-events: none;
193 | inset: auto 0 0;
194 | padding: 2rem;
195 | height: 200px;
196 | background: linear-gradient(
197 | to bottom,
198 | transparent 0%,
199 | rgb(var(--background-end-rgb)) 40%
200 | );
201 | z-index: 1;
202 | }
203 | }
204 |
205 | /* Tablet and Smaller Desktop */
206 | @media (min-width: 701px) and (max-width: 1120px) {
207 | .grid {
208 | grid-template-columns: repeat(2, 50%);
209 | }
210 | }
211 |
212 | @media (prefers-color-scheme: dark) {
213 | .vercelLogo {
214 | filter: invert(1);
215 | }
216 |
217 | .logo {
218 | filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70);
219 | }
220 | }
221 |
222 | @keyframes rotate {
223 | from {
224 | transform: rotate(360deg);
225 | }
226 | to {
227 | transform: rotate(0deg);
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/Final/Frontend/styles/globals.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --max-width: 1100px;
3 | --border-radius: 12px;
4 | --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono',
5 | 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro',
6 | 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace;
7 |
8 | --foreground-rgb: 0, 0, 0;
9 | --background-start-rgb: 214, 219, 220;
10 | --background-end-rgb: 255, 255, 255;
11 |
12 | --primary-glow: conic-gradient(
13 | from 180deg at 50% 50%,
14 | #16abff33 0deg,
15 | #0885ff33 55deg,
16 | #54d6ff33 120deg,
17 | #0071ff33 160deg,
18 | transparent 360deg
19 | );
20 | --secondary-glow: radial-gradient(
21 | rgba(255, 255, 255, 1),
22 | rgba(255, 255, 255, 0)
23 | );
24 |
25 | --tile-start-rgb: 239, 245, 249;
26 | --tile-end-rgb: 228, 232, 233;
27 | --tile-border: conic-gradient(
28 | #00000080,
29 | #00000040,
30 | #00000030,
31 | #00000020,
32 | #00000010,
33 | #00000010,
34 | #00000080
35 | );
36 |
37 | --callout-rgb: 238, 240, 241;
38 | --callout-border-rgb: 172, 175, 176;
39 | --card-rgb: 180, 185, 188;
40 | --card-border-rgb: 131, 134, 135;
41 | }
42 |
43 | @media (prefers-color-scheme: dark) {
44 | :root {
45 | --foreground-rgb: 255, 255, 255;
46 | --background-start-rgb: 0, 0, 0;
47 | --background-end-rgb: 0, 0, 0;
48 |
49 | --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
50 | --secondary-glow: linear-gradient(
51 | to bottom right,
52 | rgba(1, 65, 255, 0),
53 | rgba(1, 65, 255, 0),
54 | rgba(1, 65, 255, 0.3)
55 | );
56 |
57 | --tile-start-rgb: 2, 13, 46;
58 | --tile-end-rgb: 2, 5, 19;
59 | --tile-border: conic-gradient(
60 | #ffffff80,
61 | #ffffff40,
62 | #ffffff30,
63 | #ffffff20,
64 | #ffffff10,
65 | #ffffff10,
66 | #ffffff80
67 | );
68 |
69 | --callout-rgb: 20, 20, 20;
70 | --callout-border-rgb: 108, 108, 108;
71 | --card-rgb: 100, 100, 100;
72 | --card-border-rgb: 200, 200, 200;
73 | }
74 | }
75 |
76 | * {
77 | box-sizing: border-box;
78 | padding: 0;
79 | margin: 0;
80 | }
81 |
82 | html,
83 | body {
84 | max-width: 100vw;
85 | overflow-x: hidden;
86 | }
87 |
88 | body {
89 | color: rgb(var(--foreground-rgb));
90 | background: linear-gradient(
91 | to bottom,
92 | transparent,
93 | rgb(var(--background-end-rgb))
94 | )
95 | rgb(var(--background-start-rgb));
96 | }
97 |
98 | a {
99 | color: inherit;
100 | text-decoration: none;
101 | }
102 |
103 | @media (prefers-color-scheme: dark) {
104 | html {
105 | color-scheme: dark;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/Final/Frontend/styles/reserves.css:
--------------------------------------------------------------------------------
1 | .reservesbackground {
2 | background-color: #0a090b;
3 | }
4 |
5 | .reserveshero {
6 | background-color: #0a090b;
7 | font-family: 'SF Pro Display';
8 | --bs-gutter-x: 2.5rem;
9 | --bs-gutter-y: 0;
10 | padding-right: calc(var(--bs-gutter-x) * .5);
11 | padding-left: calc(var(--bs-gutter-x) * .5);
12 | margin-right: auto;
13 | margin-left: auto;
14 | max-width: 1300px;
15 | }
16 |
17 | .reservesstats {
18 | background-color: #15151550;
19 | font-family: 'SF Pro Display';
20 | }
21 |
22 | .reservesvalues {
23 | font-family: 'SF Pro Display';
24 | text-shadow: 0px 0.5px 1px #fff;
25 | font-size: xx-large;
26 | margin-top: 0%;
27 | animation: fadeIn 5s;
28 | }
29 |
30 | @keyframes fadeIn {
31 | 0% { opacity: 0; }
32 | 100% { opacity: 1; }
33 | }
34 |
35 | .navstyle {
36 | background-color: rgb(27, 32, 48);
37 | border-style: 'bottom';
38 | }
39 |
40 | .navheader {
41 | background-color: rgb(27, 32, 48);
42 | border-top-style: solid;
43 | border-width:thin;
44 | border-color: #4f4c4c
45 | }
46 |
47 |
48 | .chart{
49 | display: flex;
50 | flex-direction: row;
51 | }
--------------------------------------------------------------------------------
/Part2/N2D-USDT-Fake-ERC20-Token-SmartContract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | /*
4 | Follow/Subscribe Youtube, Github, IM, Tiktok
5 | for more amazing content!!
6 | @Net2Dev
7 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
8 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
9 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
10 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
11 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
12 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
13 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
14 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
15 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
16 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
17 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
18 | TERMS SPECIFIED ABOVE.
19 | */
20 |
21 | import "@openzeppelin/contracts/access/Ownable.sol";
22 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
23 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
24 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
25 |
26 | pragma solidity ^0.8.17.0;
27 |
28 | contract USDT is ERC20, ERC20Burnable, Ownable {
29 |
30 | using SafeERC20 for ERC20;
31 |
32 | constructor() ERC20("Tether USD", "USDT") {}
33 |
34 | function mint(uint256 amount) external onlyOwner {
35 | _mint(msg.sender, amount);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/Part2/N2D-WETH-Fake-ERC20-Token-SmartContract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | /*
4 | Follow/Subscribe Youtube, Github, IM, Tiktok
5 | for more amazing content!!
6 | @Net2Dev
7 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
8 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
9 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
10 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
11 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
12 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
13 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
14 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
15 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
16 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
17 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
18 | TERMS SPECIFIED ABOVE.
19 | */
20 |
21 |
22 | import "@openzeppelin/contracts/access/Ownable.sol";
23 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
24 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
25 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
26 |
27 | pragma solidity ^0.8.17.0;
28 |
29 | contract WETH is ERC20, ERC20Burnable, Ownable {
30 |
31 | using SafeERC20 for ERC20;
32 |
33 | constructor() ERC20("Wrapped ETH", "WETH") {}
34 |
35 | function mint(uint256 amount) external onlyOwner {
36 | _mint(msg.sender, amount);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/Part2/N2USD-Reserves-CollateralVault-SmartContract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | /*
4 | Follow/Subscribe Youtube, Github, IM, Tiktok
5 | for more amazing content!!
6 | @Net2Dev
7 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
8 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
9 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
10 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
11 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
12 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
13 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
14 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
15 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
16 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
17 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
18 | TERMS SPECIFIED ABOVE.
19 | */
20 |
21 |
22 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
23 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
24 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
25 | import "@openzeppelin/contracts/access/Ownable.sol";
26 | import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
27 | import "@openzeppelin/contracts/access/AccessControl.sol";
28 |
29 |
30 | pragma solidity ^0.8.17.0;
31 |
32 | contract N2USDReserves is Ownable, ReentrancyGuard, AccessControl {
33 | using SafeMath for uint256;
34 | using SafeERC20 for IERC20;
35 |
36 | uint256 public currentReserveId;
37 |
38 | struct ReserveVault {
39 | IERC20 collateral;
40 | uint256 amount;
41 | }
42 |
43 | mapping(uint256 => ReserveVault) public _rsvVault;
44 |
45 | event Withdraw (uint256 indexed vid, uint256 amount);
46 | event Deposit (uint256 indexed vid, uint256 amount);
47 |
48 | bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
49 |
50 | constructor() {
51 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
52 | _setupRole(MANAGER_ROLE, _msgSender());
53 | }
54 |
55 | function checkReserveContract(IERC20 _collateral) internal view {
56 | for(uint256 i; i < currentReserveId; i++){
57 | require(_rsvVault[i].collateral != _collateral, "Collateral Address Already Added");
58 | }
59 | }
60 |
61 | function addReserveVault(IERC20 _collateral) external {
62 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
63 | checkReserveContract(_collateral);
64 | _rsvVault[currentReserveId].collateral = _collateral;
65 | currentReserveId++;
66 | }
67 |
68 | function depositCollateral(uint256 vid, uint256 amount) external {
69 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
70 | IERC20 reserves = _rsvVault[vid].collateral;
71 | reserves.safeTransferFrom(address(msg.sender), address(this), amount);
72 | uint256 currentVaultBalance = _rsvVault[vid].amount;
73 | _rsvVault[vid].amount = currentVaultBalance.add(amount);
74 | emit Deposit(vid, amount);
75 | }
76 |
77 | function withdrawCollateral(uint256 vid, uint256 amount) external {
78 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
79 | IERC20 reserves = _rsvVault[vid].collateral;
80 | uint256 currentVaultBalance = _rsvVault[vid].amount;
81 | if (currentVaultBalance >= amount) {
82 | reserves.safeTransfer(address(msg.sender), amount);
83 | _rsvVault[vid].amount = currentVaultBalance.sub(amount);
84 | emit Withdraw(vid, amount);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/Part3/n2USD-Price-Oracle-Demo-SmartContract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | /*
4 | Follow/Subscribe Youtube, Github, IM, Tiktok
5 | for more amazing content!!
6 | @Net2Dev
7 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
8 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
9 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
10 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
11 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
12 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
13 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
14 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
15 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
16 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
17 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
18 | TERMS SPECIFIED ABOVE.
19 | */
20 |
21 | pragma solidity ^0.8.18.0;
22 |
23 | import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
24 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
25 |
26 | contract PriceOracle {
27 | using SafeMath for uint256;
28 |
29 | AggregatorV3Interface private priceOracle;
30 | uint256 public unstableColPrice;
31 | address public datafeed;
32 |
33 | function setDataFeedAddress(address contractaddress) external {
34 | datafeed = contractaddress;
35 | priceOracle = AggregatorV3Interface(datafeed);
36 | }
37 |
38 | function colPriceToWei() external {
39 | ( ,uint256 price, , , ) = priceOracle.latestRoundData();
40 | unstableColPrice = price.mul(1e10);
41 | }
42 |
43 | function rawColPrice() external view returns (uint256) {
44 | ( ,uint256 price, , , ) = priceOracle.latestRoundData();
45 | return price;
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/Part4/N2USD-Algorithmic-Stablecoin-Governance-Contract-Option1.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | /*
4 |
5 | Follow/Subscribe Youtube, Github, IM, Tiktok
6 | for more amazing content!!
7 | @Net2Dev
8 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
9 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
10 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
11 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
12 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
13 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
14 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
15 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
16 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
17 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
18 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
19 | TERMS SPECIFIED ABOVE.
20 | */
21 |
22 | pragma solidity ^0.8.18.0;
23 |
24 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
25 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
26 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
27 | import "@openzeppelin/contracts/access/Ownable.sol";
28 | import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
29 | import "@openzeppelin/contracts/access/AccessControl.sol";
30 | import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
31 | import "./n2usd.sol";
32 |
33 | contract N2DUSDGovern is Ownable, ReentrancyGuard, AccessControl {
34 | using SafeMath for uint256;
35 | using SafeERC20 for IERC20;
36 |
37 | struct SupChange {
38 | string method;
39 | uint256 amount;
40 | uint256 timestamp;
41 | uint256 blocknum;
42 | }
43 |
44 | struct ReserveList {
45 | IERC20 colToken;
46 | }
47 |
48 | mapping (uint256 => ReserveList) public rsvList;
49 |
50 | N2USD private n2usd;
51 | AggregatorV3Interface private priceOracle;
52 | address private reserveContract;
53 | uint256 public n2dusdsupply;
54 | address public datafeed;
55 | uint256 public supplyChangeCount;
56 | uint256 public stableColatPrice = 1e18;
57 | uint256 public stableColatAmount;
58 | uint256 private constant COL_PRICE_TO_WEI = 1e10;
59 | uint256 private constant WEI_VALUE = 1e18;
60 | uint256 public unstableColatAmount;
61 | uint256 public unstableColPrice;
62 | uint256 public reserveCount;
63 |
64 | mapping (uint256 => SupChange) public _supplyChanges;
65 |
66 | bytes32 public constant GOVERN_ROLE = keccak256("GOVERN_ROLE");
67 |
68 | event RepegAction(uint256 time, uint256 amount);
69 | event Withdraw(uint256 time, uint256 amount);
70 |
71 | constructor(N2USD _n2usd) {
72 | n2usd = _n2usd;
73 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
74 | _setupRole(GOVERN_ROLE, _msgSender());
75 | }
76 |
77 | function setDataFeedAddress(address contractaddress) external {
78 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
79 | datafeed = contractaddress;
80 | priceOracle = AggregatorV3Interface(datafeed);
81 | }
82 |
83 | function addColateralToken(IERC20 colcontract) external nonReentrant {
84 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
85 | rsvList[reserveCount].colToken = colcontract;
86 | reserveCount++;
87 | }
88 |
89 | function fetchColPrice() external nonReentrant {
90 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
91 | ( , uint256 price, , , ) = priceOracle.latestRoundData();
92 | uint256 value = (price).mul(COL_PRICE_TO_WEI);
93 | unstableColPrice = value;
94 | }
95 |
96 | function setReserveContract(address reserve) external nonReentrant {
97 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
98 | reserveContract = reserve;
99 | }
100 |
101 | function colateralReBalancing() internal returns (bool) {
102 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
103 | uint256 stableBalance = rsvList[0].colToken.balanceOf(reserveContract);
104 | uint256 unstableBalance = rsvList[1].colToken.balanceOf(reserveContract);
105 | if (stableBalance != stableColatAmount) {
106 | stableColatAmount = stableBalance;
107 | }
108 | if (unstableBalance != stableColatAmount) {
109 | unstableColatAmount = unstableBalance;
110 | }
111 | return true;
112 | }
113 |
114 | function setN2USDSupply(uint256 totalSupply) external {
115 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
116 | n2dusdsupply = totalSupply;
117 | }
118 |
119 | function validatePeg() external nonReentrant {
120 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
121 | bool result = colateralReBalancing();
122 | if (result = true) {
123 | uint256 rawcolvalue = (stableColatAmount.mul(WEI_VALUE)).add(unstableColatAmount.mul(unstableColPrice));
124 | uint256 colvalue = rawcolvalue.div(WEI_VALUE);
125 | if (colvalue < n2dusdsupply) {
126 | uint256 supplyChange = n2dusdsupply.sub(colvalue);
127 | n2usd.burn(supplyChange);
128 | _supplyChanges[supplyChangeCount].method = "Burn";
129 | _supplyChanges[supplyChangeCount].amount = supplyChange;
130 | }
131 | if (colvalue > n2dusdsupply) {
132 | uint256 supplyChange = colvalue.sub(n2dusdsupply);
133 | n2usd.mint(supplyChange);
134 | _supplyChanges[supplyChangeCount].method = "Mint";
135 | _supplyChanges[supplyChangeCount].amount = supplyChange;
136 | }
137 | n2dusdsupply = colvalue;
138 | _supplyChanges[supplyChangeCount].blocknum = block.number;
139 | _supplyChanges[supplyChangeCount].timestamp = block.timestamp;
140 | supplyChangeCount++;
141 | emit RepegAction(block.timestamp, colvalue);
142 | }
143 | }
144 |
145 | function withdraw(uint256 _amount) external nonReentrant {
146 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
147 | n2usd.transfer(address(msg.sender), _amount);
148 | emit Withdraw(block.timestamp, _amount);
149 | }
150 |
151 |
152 | }
153 |
154 |
--------------------------------------------------------------------------------
/Part4/N2USD-ERC20-Stablecoin-Smart-Contract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 |
4 | /*
5 |
6 | Follow/Subscribe Youtube, Github, IM, Tiktok
7 | for more amazing content!!
8 | @Net2Dev
9 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
10 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
11 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
12 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
13 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
14 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
15 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
16 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
17 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
18 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
19 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
20 | TERMS SPECIFIED ABOVE.
21 | */
22 |
23 | pragma solidity ^0.8.18.0;
24 |
25 | import "@openzeppelin/contracts/access/Ownable.sol";
26 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
27 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
28 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
29 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
30 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
31 | import "@openzeppelin/contracts/access/AccessControl.sol";
32 |
33 |
34 | contract N2USD is ERC20, ERC20Burnable, Ownable, AccessControl {
35 |
36 | using SafeMath for uint256;
37 | using SafeERC20 for ERC20;
38 |
39 | mapping (address => uint256) private _balances;
40 |
41 | uint256 private _totalSupply;
42 |
43 | bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
44 |
45 | constructor () ERC20("N2USD Stable", "N2USD") {
46 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
47 | _setupRole(MANAGER_ROLE, _msgSender());
48 | }
49 |
50 | function mint(uint256 amount) external {
51 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
52 | _totalSupply = _totalSupply.add(amount);
53 | _balances[msg.sender] = _balances[msg.sender].add(amount);
54 | _mint(msg.sender, amount);
55 | }
56 | }
--------------------------------------------------------------------------------
/Part5/N2USD-Algorithmic-Stablecoin-Governance-Contract-Option2.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | /*
4 |
5 | Follow/Subscribe Youtube, Github, IM, Tiktok
6 | for more amazing content!!
7 | @Net2Dev
8 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
9 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
10 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
11 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
12 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
13 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
14 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
15 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
16 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
17 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
18 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
19 | TERMS SPECIFIED ABOVE.
20 | */
21 |
22 | pragma solidity ^0.8.18.0;
23 |
24 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
25 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
26 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
27 | import "@openzeppelin/contracts/access/Ownable.sol";
28 | import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
29 | import "@openzeppelin/contracts/access/AccessControl.sol";
30 | import "./n2usd.sol";
31 | import "./n2dr.sol";
32 |
33 | contract N2DUSDGovern is Ownable, ReentrancyGuard, AccessControl {
34 | using SafeMath for uint256;
35 | using SafeERC20 for IERC20;
36 |
37 | struct SupChange {
38 | string method;
39 | uint256 amount;
40 | uint256 timestamp;
41 | uint256 blocknum;
42 | }
43 |
44 | struct ReserveList {
45 | IERC20 colToken;
46 | }
47 |
48 | mapping (uint256 => ReserveList) public rsvList;
49 |
50 | N2USD private n2usd;
51 | N2DR private n2dr;
52 | address private reserveContract;
53 | uint256 public n2dusdsupply;
54 | uint256 public n2drsupply;
55 | address public datafeed;
56 | uint256 public supplyChangeCount;
57 | uint256 public stableColatPrice = 1e18;
58 | uint256 public stableColatAmount;
59 | uint256 private constant COL_PRICE_TO_WEI = 1e10;
60 | uint256 private constant WEI_VALUE = 1e18;
61 | uint256 public unstableColatAmount;
62 | uint256 public unstableColPrice;
63 | uint256 public reserveCount;
64 |
65 | mapping (uint256 => SupChange) public _supplyChanges;
66 |
67 | bytes32 public constant GOVERN_ROLE = keccak256("GOVERN_ROLE");
68 |
69 | event RepegAction(uint256 time, uint256 amount);
70 | event Withdraw(uint256 time, uint256 amount);
71 |
72 | constructor(N2USD _n2usd, N2DR _n2dr) {
73 | n2usd = _n2usd;
74 | n2dr = _n2dr;
75 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
76 | _setupRole(GOVERN_ROLE, _msgSender());
77 | }
78 |
79 | function addColateralToken(IERC20 colcontract) external nonReentrant {
80 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
81 | rsvList[reserveCount].colToken = colcontract;
82 | reserveCount++;
83 | }
84 |
85 | function setReserveContract(address reserve) external nonReentrant {
86 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
87 | reserveContract = reserve;
88 | }
89 |
90 | function setN2drTokenPrice(uint256 marketcap) external nonReentrant {
91 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
92 | n2drsupply = n2dr.totalSupply();
93 | unstableColPrice = ((marketcap).mul(n2drsupply)).div(WEI_VALUE);
94 | }
95 |
96 |
97 | function colateralReBalancing() internal returns (bool) {
98 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
99 | uint256 stableBalance = rsvList[0].colToken.balanceOf(reserveContract);
100 | uint256 unstableBalance = rsvList[1].colToken.balanceOf(reserveContract);
101 | if (stableBalance != stableColatAmount) {
102 | stableColatAmount = stableBalance;
103 | }
104 | if (unstableBalance != stableColatAmount) {
105 | unstableColatAmount = unstableBalance;
106 | }
107 | return true;
108 | }
109 |
110 | function setN2USDSupply(uint256 totalSupply) external {
111 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
112 | n2dusdsupply = totalSupply;
113 | }
114 |
115 | function validatePeg() external nonReentrant {
116 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
117 | bool result = colateralReBalancing();
118 | if (result = true) {
119 | uint256 rawcolvalue = (stableColatAmount.mul(WEI_VALUE)).add(unstableColatAmount.mul(unstableColPrice));
120 | uint256 colvalue = rawcolvalue.div(WEI_VALUE);
121 | if (colvalue < n2dusdsupply) {
122 | uint256 supplyChange = n2dusdsupply.sub(colvalue);
123 | uint256 burnAmount = (supplyChange.div(unstableColPrice)).mul(WEI_VALUE);
124 | n2dr.burn(burnAmount);
125 | _supplyChanges[supplyChangeCount].method = "Burn";
126 | _supplyChanges[supplyChangeCount].amount = supplyChange;
127 | }
128 | if (colvalue > n2dusdsupply) {
129 | uint256 supplyChange = colvalue.sub(n2dusdsupply);
130 | n2usd.mint(supplyChange);
131 | _supplyChanges[supplyChangeCount].method = "Mint";
132 | _supplyChanges[supplyChangeCount].amount = supplyChange;
133 | }
134 | _supplyChanges[supplyChangeCount].blocknum = block.number;
135 | _supplyChanges[supplyChangeCount].timestamp = block.timestamp;
136 | supplyChangeCount++;
137 | emit RepegAction(block.timestamp, colvalue);
138 | }
139 | }
140 |
141 | function withdraw(uint256 _amount) external nonReentrant {
142 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
143 | n2usd.transfer(address(msg.sender), _amount);
144 | emit Withdraw(block.timestamp, _amount);
145 | }
146 |
147 | function withdrawN2dr(uint256 _amount) external nonReentrant {
148 | require(hasRole(GOVERN_ROLE, _msgSender()), "Not allowed");
149 | n2dr.transfer(address(msg.sender), _amount);
150 | emit Withdraw(block.timestamp, _amount);
151 | }
152 |
153 |
154 | }
155 |
156 |
--------------------------------------------------------------------------------
/Part5/USDT.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | import "@openzeppelin/contracts/access/Ownable.sol";
4 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
5 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
6 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
7 |
8 | pragma solidity ^0.8.17.0;
9 |
10 | contract USDT is ERC20, ERC20Burnable, Ownable {
11 |
12 | using SafeERC20 for ERC20;
13 |
14 | constructor() ERC20("Tether USD", "USDT") {}
15 |
16 | function mint(uint256 amount) external onlyOwner {
17 | _mint(msg.sender, amount);
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Part5/n2dr.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | pragma solidity ^0.8.18.0;
4 |
5 | import "@openzeppelin/contracts/access/Ownable.sol";
6 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
7 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
8 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
9 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
10 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
11 | import "@openzeppelin/contracts/access/AccessControl.sol";
12 |
13 |
14 | contract N2DR is ERC20, ERC20Burnable, Ownable, AccessControl {
15 |
16 | using SafeMath for uint256;
17 | using SafeERC20 for ERC20;
18 |
19 | mapping (address => uint256) private _balances;
20 |
21 | uint256 private _totalSupply;
22 |
23 | bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
24 |
25 | constructor () ERC20("N2D Rewards", "N2DR") {
26 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
27 | _setupRole(MANAGER_ROLE, _msgSender());
28 | }
29 |
30 | function mint(uint256 amount) external {
31 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
32 | _totalSupply = _totalSupply.add(amount);
33 | _balances[msg.sender] = _balances[msg.sender].add(amount);
34 | _mint(msg.sender, amount);
35 | }
36 | }
--------------------------------------------------------------------------------
/Part5/n2usd.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | pragma solidity ^0.8.18.0;
4 |
5 | import "@openzeppelin/contracts/access/Ownable.sol";
6 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
7 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
8 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
9 | import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
10 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
11 | import "@openzeppelin/contracts/access/AccessControl.sol";
12 |
13 |
14 | contract N2USD is ERC20, ERC20Burnable, Ownable, AccessControl {
15 |
16 | using SafeMath for uint256;
17 | using SafeERC20 for ERC20;
18 |
19 | mapping (address => uint256) private _balances;
20 |
21 | uint256 private _totalSupply;
22 |
23 | bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
24 |
25 | constructor () ERC20("N2USD Stable", "N2USD") {
26 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
27 | _setupRole(MANAGER_ROLE, _msgSender());
28 | }
29 |
30 | function mint(uint256 amount) external {
31 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
32 | _totalSupply = _totalSupply.add(amount);
33 | _balances[msg.sender] = _balances[msg.sender].add(amount);
34 | _mint(msg.sender, amount);
35 | }
36 | }
--------------------------------------------------------------------------------
/Part5/n2usdreserves.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT LICENSE
2 |
3 | /*
4 |
5 | Follow/Subscribe Youtube, Github, IM, Tiktok
6 | for more amazing content!!
7 | @Net2Dev
8 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗
9 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║
10 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝
11 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░
12 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░
13 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░
14 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL
15 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE
16 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY
17 | OTHER USE. THIS IS TRAINING/EDUCATIONAL
18 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE
19 | TERMS SPECIFIED ABOVE.
20 | */
21 |
22 | pragma solidity ^0.8.17.0;
23 |
24 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
25 | import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
26 | import "@openzeppelin/contracts/utils/math/SafeMath.sol";
27 | import "@openzeppelin/contracts/access/Ownable.sol";
28 | import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
29 | import "@openzeppelin/contracts/access/AccessControl.sol";
30 |
31 | contract N2dUSDReserves is Ownable, ReentrancyGuard, AccessControl {
32 | using SafeMath for uint256;
33 | using SafeERC20 for IERC20;
34 |
35 | uint256 public currentReserveCount;
36 |
37 | struct ReserveVault {
38 | IERC20 collateral;
39 | uint256 amount;
40 | }
41 |
42 | mapping (uint256 => ReserveVault) public rsvVault;
43 |
44 | event Deposit(uint256 indexed pid, uint256 amount);
45 | event Withdraw(uint256 indexed pid, uint256 amount);
46 |
47 | bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
48 |
49 | constructor() {
50 | _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
51 | _setupRole(MANAGER_ROLE, _msgSender());
52 | }
53 |
54 | function checkReserveDuplicate(IERC20 _colToken) internal view {
55 | for (uint256 _pid = 0; _pid < currentReserveCount; _pid++) {
56 | require(rsvVault[_pid].collateral != _colToken, "Collateral Contract Already Added");
57 | }
58 | }
59 |
60 | function addReserve(IERC20 _colToken) external {
61 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
62 | checkReserveDuplicate(_colToken);
63 | rsvVault[currentReserveCount].collateral = _colToken;
64 | currentReserveCount++;
65 | }
66 |
67 | function deposit(uint256 _pid, uint256 _amount) external {
68 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
69 | IERC20 reserve = rsvVault[_pid].collateral;
70 | reserve.safeTransferFrom(address(msg.sender), address(this), _amount);
71 | uint256 currentAmount = rsvVault[_pid].amount;
72 | rsvVault[_pid].amount = currentAmount.add(_amount);
73 | emit Deposit(_pid, _amount);
74 | }
75 |
76 | function withdraw(uint256 _pid, uint256 _amount) external {
77 | require(hasRole(MANAGER_ROLE, _msgSender()), "Not allowed");
78 | IERC20 reserve = rsvVault[_pid].collateral;
79 | uint256 currentAmount = rsvVault[_pid].amount;
80 | if (currentAmount >= _amount){
81 | reserve.safeTransfer(address(msg.sender), _amount);
82 | }
83 | rsvVault[_pid].amount = currentAmount.sub(_amount);
84 | emit Withdraw(_pid, _amount);
85 | }
86 |
87 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Algorithmic-Stablecoin-ERC20
2 | 🤑The Official ERC20 Algoritmic Stablecoin Project Tutorial Repo - Complete repo on how to deploy your own algorithmic stablecoin and back it with a hybrid collateral reserve between other stablecoins or cryptocurrencies.
3 |
4 |
5 |
6 |
7 |
8 | ** THE FILES ATTACHED TO THIS REPO ARE FOR EDUCATIONAL PURPOSES ONLY **
9 |
10 | ** NOT FINANCIAL ADVISE **
11 |
12 | ** USE IT AT YOUR OWN RISK** **I'M NOT RESPONSIBLE FOR ANY USE, ISSUES ETC.. **
13 |
14 | ENTIRE PLAYLIST:
15 |
16 |
17 |
18 | Part 2 Repo
19 |
20 | Click for video:
21 |
22 |
23 |
24 | Part2 Folder Contents:
25 |
26 | ```shell
27 | N2D-USDT-Fake-ERC20-Token-SmartContract.sol
28 | N2D-WETH-Fake-ERC20-Token-SmartContract.sol
29 | N2USD-Reserves-CollateralVault-SmartContract.sol
30 | ```
31 |
32 | Part 3 Repo
33 |
34 | Click for video:
35 |
36 |
37 |
38 | Part3 Folder Contents:
39 |
40 | Make sure you update the AggregatorV3Interface Contract to return uint256 instead of int256. Please refer to tutorial video section : 16:00
41 |
42 | ```shell
43 | n2USD-Price-Oracle-Demo-SmartContract.sol
44 | ```
45 |
46 | Part 4 Repo
47 |
48 | Click for video:
49 |
50 |
51 |
52 | Part4 Folder Contents:
53 |
54 | ```shell
55 | N2USD-Algorithmic-Stablecoin-Governance-Contract-Option1.sol
56 | N2USD-ERC20-Stablecoin-Smart-Contract.sol
57 | ```
58 |
59 | Part 5 Repo
60 |
61 | Click for video:
62 |
63 |
64 |
65 | Part5 Folder Contents:
66 |
67 | ```shell
68 | N2USD-Algorithmic-Stablecoin-Governance-Contract-Option2.sol
69 | ```
70 |
71 | Part 6 FINAL Repo
72 |
73 | Click for video:
74 |
75 |
76 |
77 | Final Folder Contents:
78 |
79 | ```shell
80 | Backend
81 | Frontend
82 | ```
83 |
84 | Step 1
85 |
86 | Download the "Final" Folder, then navigate with your shell/terminal to each project folder and install:
87 |
88 | ```shell
89 | cd final
90 | cd backend
91 | npm i
92 |
93 | cd..
94 | cd frontend
95 | npm i
96 | ```
97 |
98 |
99 | Step 2
100 |
101 | In the "config.js" on frontend and "getprices.js" on the backend, you can either use the already configured test smart contract addresses or add your own contract addresses. Make sure you update the RPC address as well (if needed).
102 |
103 | ```shell
104 | const rsvcontract = '0xba1f546071d9d7E2388d420AC1091ce58F661Efc';
105 | const n2usdcontract = '0x480724B920B486af30610b5Ed6456B0113951F43';
106 | const rpc = 'https://rpc.ankr.com/polygon_mumbai';
107 | ```
108 |
109 | CTRL + S to save!
110 |
111 | Step 3
112 |
113 | Run the backend and await the database to store more than 12 entries before running the frontend. Verify both ethpricedb.json and n2usdpricedb.json files to confirm.
114 |
115 | ```shell
116 | cd final
117 | cd backend
118 | node backend.js
119 | ```
120 |
121 |
122 | Step 4
123 |
124 | Run the Frontend to live visualize the token price!
125 |
126 | ```shell
127 | cd final
128 | cd frontend
129 | npm run dev
130 | ```
131 |
132 |
133 |
--------------------------------------------------------------------------------