Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

test: validate ETHBankContract logic #41

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion artifacts/build-info/90e177e7aa8bdf7e3b9e23480f412115.json

This file was deleted.

1 change: 1 addition & 0 deletions artifacts/build-info/ea9a291c34c8521587e09ab66dc4101e.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"_format": "hh-sol-dbg-1",
"buildInfo": "../../build-info/90e177e7aa8bdf7e3b9e23480f412115.json"
"buildInfo": "../../build-info/ea9a291c34c8521587e09ab66dc4101e.json"
}
4 changes: 2 additions & 2 deletions artifacts/contracts/ETHBankContract.sol/ETHBankContract.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion contracts/ETHBankContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ contract ETHBankContract {
require(ethAmount != 0, "you must add ETH");
ethBalances[msg.sender] += ethAmount;
(bool success, ) = address(this).call{value: ethAmount}("");
console.log("txn success here:____", success);
require(success, "failed to deposit ETH");
emit Deposit(msg.sender, ethAmount, balanceBefore, ethBalances[msg.sender]);
}
Expand Down
120 changes: 114 additions & 6 deletions test/ETHBankContract.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers");
const { expect } = require("chai");
const { ethers } = require("hardhat");
const { getGasFee } = require("../utils");

describe("ETHBank Test Suite", function () {
describe.only("ETHBank Test Suite", function () {
// define loadFixture
// fixtures can return anything you consider useful for your tests
const deployTokenFixture = async () => {
Expand All @@ -12,15 +14,121 @@ describe("ETHBank Test Suite", function () {

describe("Post Deployment State Variables", async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This describe block should be Deployment

it("Should return state variables", async () => {
// extract loadFixture variables
// extract loadFixture variables
const { ETHBankContract, owner, addr1, addr2 } = await loadFixture(deployTokenFixture);
expect(await ETHBankContract.owner()).to.eq(owner.address)
expect(await ETHBankContract.ethBalances(owner.address)).to.eq(0)
expect(await ETHBankContract.owner()).to.eq(owner.address);
expect(await ETHBankContract.ethBalances(owner.address)).to.eq(0);
});
});

describe("Transactions", async () => {
describe("Deposit Validations", async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under Transactions, you should have sub-wrappers - Deposit and Withdrawal
To appropriately categorize your test cases, under each of these, ensure you have corresponding Validation, Transactions and Events describe wrappers and each with its it test case

// validate attempt to send 0 ETH to ETHBankContract
it("Should revert attempt to deposit 0 ETH", async () => {
const { ETHBankContract, addr1 } = await loadFixture(deployTokenFixture);
const depositAmount = ethers.utils.parseEther("0.1");
await expect(ETHBankContract.connect(addr1).depositETH({ value: depositAmount })).to.be.revertedWith(
"you must add ETH"
);
});
});

describe("Deposit Transactions", async () => {
it.only("Should deposit ETH", async () => {
const { ETHBankContract, addr1, owner } = await loadFixture(deployTokenFixture);
const { parseEther, formatEther } = ethers.utils;
const { getBalance } = ethers.provider;
const depositAmount = parseEther("1");
//assert the contract balance before deposit
expect(await getBalance(ETHBankContract.address)).to.eq(parseEther("0"));
// Get the balance of addr1 before the deposit
const balanceBefore = await ETHBankContract.ethBalances(addr1.address);
// assert that the sender's balance is 0 before the deposit
expect(balanceBefore).to.eq(0);
const addr1BalanceBefore = await getBalance(addr1.address);
// assert that the sender's balance is greater than or equal to depositAmount
expect(addr1BalanceBefore).to.greaterThanOrEqual(depositAmount);
// Deposit the ETH
// await ETHBankContract.connect(addr1).depositETH();
const transaction = await ETHBankContract.connect(addr1).depositETH({ value: depositAmount });
// Get gas price used by the transaction
const gasUsed = await getGasFee(transaction.hash);
// Get the balance of addr1 after the deposit
const balanceAfter = await ETHBankContract.ethBalances(addr1.address);
//assert that the new balance of addr1 is equal to depositAmount
expect(balanceAfter).to.eq(depositAmount);
// await provider.getBalance(user1.address);
const addr1ETHBalanceAfterDeposit = await getBalance(addr1.address);
// assert that addr1ETHBalanceAfterDeposit is equal to depositAmount - gasUsed

const addr1BalanceBeforePlusGasUsed = addr1BalanceBefore + (addr1ETHBalanceAfterDeposit + formatEther(gasUsed));


console.log("__addr1BalanceBefore__", formatEther(addr1BalanceBefore));
console.log("__addr1ETHBalanceAfterDeposit__", formatEther(addr1ETHBalanceAfterDeposit));
console.log("__addr1BalanceBeforePlusGasUsed__", addr1BalanceBeforePlusGasUsed);
console.log("__gasUsed__", formatEther(gasUsed));


expect(formatEther(addr1BalanceBefore)).to.eq(addr1BalanceBeforePlusGasUsed);

return;
//Get contract balance after deposit
const ethContractBalance = await getBalance(ETHBankContract.address);
// assert that ethContractBalance is equal to depositAmount
expect(ethContractBalance).to.eq(depositAmount);
});
});

describe("Deposit Events", async () => {
// validate attempt to send 0 ETH to ETHBankContract
it("Should revert attempt to deposit 0 ETH", async () => {
const { ETHBankContract, addr1, owner } = await loadFixture(deployTokenFixture);
// Get the balance of addr1 before the deposit
const balanceBefore = await ETHBankContract.ethBalances(addr1.address);
// assert that the sender's balance is 0 before the deposit
expect(balanceBefore).to.eq(0);
const depositAmount = ethers.utils.parseEther("1");
// assert that the deposit amount is not 0
expect(depositAmount).not.to.eq(0);
// Deposit the ETH
// const transaction = await ETHBankContract.connect(addr1).depositETH({ value: depositAmount });
await expect(ETHBankContract.connect(addr1).depositETH({ value: depositAmount }))
.to.emit(ETHBankContract, "Deposit")
.withArgs(addr1.address, depositAmount, balanceBefore, ethers.utils.parseEther("5"));
});
});

it("Should withdraw ETH", async () => {
const { ETHBankContract, addr1 } = await loadFixture(deployTokenFixture);
const depositAmount = ethers.utils.parseEther("1");

// Deposit some ETH to the contract
await ETHBankContract.connect(addr1).depositETH({ value: depositAmount });

// Get the balance of addr1 before the withdrawal
const balanceBefore = await ETHBankContract.ethBalances(addr1.address);

// Assert that addr1 balance is not 0
expect(balanceBefore).not.to.eq(0);

const withdrawalAmount = ethers.utils.parseEther("0.5");

// Assert that withdraw amount is not greater than balance
expect(balanceBefore).to.be.at.least(withdrawalAmount);

// Withdraw ETH from the contract
const transaction = await ETHBankContract.connect(addr1).withdrawETH(withdrawalAmount);
const receipt = await transaction.wait();

// Get the balance of addr1 after the withdrawal
const balanceAfter = await ETHBankContract.ethBalances(addr1.address);

// Assert that the balance of addr1 is correctly updated after the withdrawal
expect(balanceAfter).to.eq(balanceBefore.sub(withdrawalAmount));


// Assert that the Withdraw event was emitted with the correct arguments
expect(receipt.events[0])
.to.emit(ETHBankContract, "Withdraw")
.withArgs(addr1.address, withdrawalAmount, balanceBefore, balanceAfter);
});
});
19 changes: 13 additions & 6 deletions utils/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
// define loadFixture
// fixtures can return anything you consider useful for your tests

const { ethers } = require("hardhat")
const { ethers } = require("hardhat");
async function deployContractFixture(contractName) {
const ContractInstance = await ethers.deployContract(contractName);
const ContractInstance = await ethers.deployContract(contractName);

console.log("cont")
return { ContractInstance };
};
console.log("cont");
return { ContractInstance };
}

async function getGasFee(transactionHash) {
const transactionReceipt = await ethers.provider.getTransactionReceipt(transactionHash);
const gasUsed = transactionReceipt.gasUsed;
const gasPrice = (await ethers.provider.getGasPrice()).toBigInt(); // Convert to BigInt
const gasFee = gasUsed.mul(gasPrice);
return gasFee;
}

module.exports = { deployContractFixture }
module.exports = { deployContractFixture, getGasFee };