/Bank

Primary LanguageJavaScript

REQUIREMENT:

Write a README.md file which describes the project, describes the directory structure, and where the frontend project can be accessed (see #8). Please also include your public Ethereum account if you would like to receive your certification as an NFT (this is optional). 

In your README.md, be sure to have clear instructions on: 
Installing dependencies for your project 
Accessing or—if your project needs a server (not required)—running your project
Running your smart contract unit tests and which port a local testnet should be running on.
Note: This section used to require three bash scripts but has been revised.

Decrypt - Your Smart CryptoCurrency Bank

About

This DApp provides ETH and ERC20 tokens deposit and withdrawal services to users. User's deposit will earn an interest from other established protocols such as Compound. Users should be aware that ERC20 tokens which are deposited will be converted into ETH and earn interest. Users can choose to withdraw the balances as ETH or any other ERC20 tokens.

The DApp interacts with established protocols such as Compound and Uniswap for token swaps and earning interest. It also uses Openzeppelin contracts and libraries such as ERC20, ReentrancyGuard and Address.

The contract is deployed and verified on the Rinkeby testnet at 0x0eaee27d1cdbaF249dAb7B1CcBdDeAFCB5Ae86eB

Dependencies

To run the DApp in a local environment, the following dependencies are required:

  • Node v14.15.0
  • Truffle v5.4.17
    • Truffle: npm i -g truffle
    • HDWallet provider: npm i @truffle/hdwallet-provider
    • Contract verification: npm i truffle-plugin-verify
    • Ganache-cli: npm i ganache-cli
  • Openzeppelin contracts and libraries: npm i @openzeppelin/contracts
  • Front end
    • React: npm i -g react
    • React-bootstrap: npm i react-bootstrap
    • Bootstrap: npm i bootstrap
    • React Error Boundary: npm i react-error-boundary
  • Web3
    • web3js: npm i -g web3
    • ethers: npm i -g ethers
    • Metamask: npm i @metamask/detect-provider
    • Install metamask wallet in your browser
  • Utils
    • .env file: npm i dotenv

How to Interact with the DApp

There are 3 ways to interact with this DApp.

Interact through publicly deployed web interface

  • Go to: https://smartbank.vercel.app/
  • If you do not have a Metamask browser extension, install Metamask in your browser. Connect your Metamask wallet and start interacting with the app.

Interact through local network

  • Download this folder
  • Run cd blockchain-developer-bootcamp-final-project-master which is the root directory
  • Run npm install to install all the dependencies in the package.json file
  • Launch the user interface via port: 3000 by running the following command in the root directory npm run start
  • Access the user interface via http://localhost:3000
  • If you do not have Metamask browser extension, install Metamask in your browser. Connect your Metamask wallet and start interacting with the app.

Interact via Etherscan

Directory Structure

Key files and folders structures are as below:

blockchain-developer-bootcamp-final-project-master (root directory)
+-- migrations
|   +-- 1_initial_migration.js
|   +-- 2_deploy_contracts.js 
|
+-- public
|
+-- src
|   +-- abis
|   +-- Component
|   |   +-- Header.js
|   |   +-- MetamaskConnectButton.js
|   |   +-- Fallback.js
|   |
|   +-- contracts
|   |   +-- Migrations.sol
|   |   +-- SmartBank.sol    
|   |
|   +-- App.js
|   +-- App.css
|   +-- index.css
|   +-- index.js
|
+-- test
|   +-- SmartBank.test.js    
|
+-- truffle-config.js
+-- package.json
+-- .env.example
+-- avoiding_common_attacks.md
+-- design_pattern_decisions.md
+-- deployed_address.txt

Contracts

  • SmartBank contract is compiled using Solidity compiler 0.8.0 and consists of the following key functions:
    • addBalance
      • Purpose: for users to deposit ETH to the contract which will earn interest from Compound
      • Input: deposit amount (specified as msg.value)
      • Output: return true on successful execution, emit depositETH event
    • addBalanceERC20
      • Purpose: for users to deposit ERC20 token which will then be converted to ETH and earn interest from Compound
      • Input: ERC20 token address, deposit amount
      • Output: return true on successful execution, emit depositERC20Token event
    • getBalanceInWei
      • Purpose: read-only function to view a user's balance in ETH terms
      • Input: user address
      • Output: total balance including interest in ETH terms
    • withdraw
      • Purpose: for users to withdraw balance from the contract in ETH; "nonReentrant" is applied to prevent reentrancy
      • Input: withdraw amount
      • Output: return true on successful execution, emit withdrawETH event
    • withdrawInERC20
      • Purpose: for users to withdraw balance from the contract in an ERC20 token; "non-Reentrant" is applied to prevent reentrancy
      • Input: withdraw amount in ETH terms, ERC20 token address
      • Output: return true on successful execution, emit withdrawERC20Token event
  • You can deploy the SmartBank contract to the Rinkeby network by running the following command. Make sure you have sufficient ETH balance to pay for the gas fee.
truffle migration --reset --network rinkeby
  • The deployment of the contract will require the following dependencies and modifications of default settings:
    • Constructor inputs are specified in migrations/2_deploy_contracts.js. More details in Migration section below.
    • Network configuration is specified in truffle-config.js. More details in Truffle Configuration below.
    • HDWallet provider - install via npm i -g @truffle/hdwallet-provider
    • Network provider - create an account with Infura/Alchemy and get the provider URL
    • Fill in the .env.example file with the necessary account and network provider details
    • Due to the contracts and abi folder residing in src folder, you have to modify the default Truffle directory in truffle-config.js, as below:
    contracts_directory: './src/contract/',
    contracts_build_directory: './src/abis',
    migrations_directory: './migrations'
    

Migration

  • Within the Migrations folder, 2_deploy_contracts.js retrieves the contract artifacts (abi) and deploys the contract together with the addresses of the following, as required inputs in the constructor:
    • Uniswap
    • CEther
    • WETH
  • The address inputs vary depending on the network of which the contract will be deployed (mainnet, rinkeby or development)

Smart Contract Unit Tests

  • You need to install ganache-cli(see "Dependencies" section above) to run the unit test
  • In the SmartBank.test.js file, on line 21, you need to supply your own MAINNET_RPC_URL pointing to the mainnet to initialise web3 as the test requires forking mainnet. [Note: Infura ID has been provided in the test file to facilitate testing, it will be deleted after the project completion.]
  • To run the unit tests, you need to fork the mainnet and initialize the 2 sample accounts below (for the purpose of using their ETH and DAI balances). Note that Infura ID has been provided below to facilitate testing, it will be deleted after the project completion. Also make sure you have added mainnet_fork network to your truffle-config.js (refer to truffle-config.js file for details)
ganache-cli --fork https://mainnet.infura.io/v3/85a90f73f7794d79a0689382745635af --unlock '0x1e3D6eAb4BCF24bcD04721caA11C478a2e59852D' '0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8' --networkId 999

  • Once you have done the above, open a new terminal and run the tests in SmartBank.test.js on mainnet fork in a separate terminal via the command below:
truffle test --network mainnet_fork

  • SmartBank.test.js conducts 8 unit tests, as below:
    • to verify that the contract exists, ie. should have a valid address
    • to verify that the contract should accept deposit and the amount is correct
    • to verify that the deposit can earn interest from Compound
    • to verify that an event is emitted when a deposit is made
    • to verify that the withdraw function reverts when one attempts to withdraw more than available balance
    • to verify that there is correct amount remaining after a withdrawal is made
    • to verify that the contract should accept an ERC20 token deposit
    • to verify that the contract should allow withdrawal in ERC20 token based on dex exchange rate
  • exceptionsHelpers.js file provides the required functions for handling exceptions produced during the tests
  • Before running truffle test, please ensure that you modify the default Truffle directory for contracts and abi as stated in the "Contracts" and "Truffle Configuration" sections.
  • Dependencies: npm i @openzeppelin/test-helpers

Front End

  • The front-end is built using React library with the necessary Hooks and deployed to web interface via Vercel.
  • The front-end includes the following:
    • Metamask wallet connect button
    • Display the wallet account balance
    • Allows user to submit deposit or withdraw tokens or ETH
  • Input validation to provide better user experience and avoid error fallback
  • Metamask connector can detect a change of network in your Metamask wallet and the web interface will issue a warning to the user that the app is only deployed on Rinkeby network

Truffle Configuration

  • truffle-config.js contains the network configuration for the following networks:
    • development
    • Rinkeby testnet
    • Mainnet
    • Mainnet_fork
  • HDwallet provider is required to connect to the Rinkeby testnet or Mainnet
    • install via npm i -g @truffle/hdwallet-provider
  • Seed phrase and network provider (Infura or Alchemy) details are stored locally in a .env file. An example of such file is available - .env.example
  • Due to the contracts and abi folder residing in src folder, you have to modify the default Truffle directory in truffle-config.js, as below:
    contracts_directory: './src/contract/',
    contracts_build_directory: './src/abis',
    migrations_directory: './migrations'
    

Deployed Address and Verification

The contract is deployed and verified on Rinkeby testnet at 0x0eaee27d1cdbaF249dAb7B1CcBdDeAFCB5Ae86eB

Screencast

https://www.youtube.com/watch?v=06ZhjX3d1No&t=1037s

Ethereum account (for NFT certification)

0xb2cddF705eA6f12D7B5Da081F679305A3209Af99