From f97539cad703e78056952ad229caa942b52d3dbd Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Jul 2025 20:20:15 +0100 Subject: [PATCH 1/3] chore: updated counter.js and counter.sol files --- contracts/Counter.sol | 43 +++++++++------------- test/Counter.js | 84 ++++++++++++++++++++++++------------------- 2 files changed, 63 insertions(+), 64 deletions(-) diff --git a/contracts/Counter.sol b/contracts/Counter.sol index fa8560c..276ec92 100644 --- a/contracts/Counter.sol +++ b/contracts/Counter.sol @@ -4,45 +4,34 @@ pragma solidity 0.8.28; interface ICounter { function setCount(uint256 _count) external; function increaseCountByOne() external; - function getCount() external view returns(uint256); - + function getCount() external view returns (uint256); } contract Counter is ICounter { uint256 public count; + address public owner; + + constructor() { + owner = msg.sender; + } + + modifier onlyOwner() { + require(msg.sender == owner, "Not owner"); + _; + } - function setCount(uint256 _count) external { + function setCount(uint256 _count) external onlyOwner { + require(_count <= 10, "Count must not exceed 10"); count = _count; } - function increaseCountByOne() public { + function increaseCountByOne() external onlyOwner { + require(count + 1 <= 10, "Count must not exceed 10"); count += 1; } - function getCount() public view returns(uint256) { + function getCount() external view returns (uint256) { return count; } } - -// contract F { -// // Initializing interface IC -// IC public _ic; -// // Initializing the contract address -// address public contractCAddress; - -// constructor(address _contractCAddress) { -// // Set the contract address to the state variable contract address -// contractCAddress = _contractCAddress; -// // Passing the contract address into interface using the address instance of another contract -// _ic = IC(_contractCAddress); -// } - -// function setCount(uint256 _count) public { -// _ic.setCount(_count); -// } - -// function getCount() public view returns(uint256) { -// return _ic.getCount(); -// } -// } \ No newline at end of file diff --git a/test/Counter.js b/test/Counter.js index 99b2931..1dece69 100644 --- a/test/Counter.js +++ b/test/Counter.js @@ -1,49 +1,59 @@ -const {loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); -// const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); +const { loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); const { expect } = require("chai"); -// util functon const deployCounter = async () => { - // target the Counter contract within our contract folder - const CounterContract = await ethers.getContractFactory("Counter"); // target Counter.sol - const counter = await CounterContract.deploy(); // deploy the Counter contract - return counter ; // return the deployed instance of our counter contract + const [owner, otherUser] = await ethers.getSigners(); + const CounterContract = await ethers.getContractFactory("Counter"); + const counter = await CounterContract.deploy(); + return { counter, owner, otherUser }; } -// Counter Test Suite describe("Counter Test Suite", () => { + describe("Deployment", () => { - it("Should return default values upon deployment", async () => { - const counter = await loadFixture(deployCounter); - expect(await counter.count()).to.eq(0); // assert that count = 0 upon deployment - }) - }) + it("Should return default values upon deployment", async () => { + const { counter } = await loadFixture(deployCounter); + expect(await counter.count()).to.eq(0); + }); + }); describe("Transactions", () => { describe("SetCount", () => { - it("Should set appropriate count values", async () => { - const counter = await loadFixture(deployCounter); // extract deployed counter instace - let count1 = await counter.getCount(); // check initial count value before txn - expect(count1).to.eq(0); - await counter.setCount(10) // assert that count = 0 upon deployment - - let count2 = await counter.getCount(); // check initial count value before txn - expect(count2).to.eq(10) // check final count = 10 - }) - - it("Should set appropriate values for multiple setCount txns", async () => { - - }) - }) + it("Should allow owner to set count", async () => { + const { counter, owner } = await loadFixture(deployCounter); + await counter.setCount(5); + expect(await counter.getCount()).to.eq(5); + }); + + it("Should reject non-owner trying to set count", async () => { + const { counter, otherUser } = await loadFixture(deployCounter); + await expect(counter.connect(otherUser).setCount(5)).to.be.revertedWith("Not owner"); + }); + + it("Should not allow count > 10", async () => { + const { counter } = await loadFixture(deployCounter); + await expect(counter.setCount(11)).to.be.revertedWith("Count must not exceed 10"); + }); + }); describe("IncreaseCountByOne", () => { - it("Should set appropriate increaseCountByOne value", async () => { - - }) - - it("Should set appropriate values for multiple increaseCountByOne txns", async () => { - - }) - }) - }) -}) \ No newline at end of file + it("Should allow owner to increase count by 1", async () => { + const { counter } = await loadFixture(deployCounter); + await counter.increaseCountByOne(); + expect(await counter.getCount()).to.eq(1); + }); + + it("Should reject non-owner trying to increase count", async () => { + const { counter, otherUser } = await loadFixture(deployCounter); + await expect(counter.connect(otherUser).increaseCountByOne()).to.be.revertedWith("Not owner"); + }); + + it("Should not allow increasing count beyond 10", async () => { + const { counter } = await loadFixture(deployCounter); + await counter.setCount(10); + await expect(counter.increaseCountByOne()).to.be.revertedWith("Count must not exceed 10"); + }); + }); + }); +}); + From be2d037e753750d4741130c936736a67152c7a11 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Jul 2025 21:39:29 +0100 Subject: [PATCH 2/3] chore: created counterV2.js and counterV2.sol files --- contracts/Counter.sol | 37 ----------------- contracts/CounterV2.sol | 54 +++++++++++++++++++++++++ test/Counter.js | 59 --------------------------- test/CounterV2.js | 89 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 96 deletions(-) delete mode 100644 contracts/Counter.sol create mode 100644 contracts/CounterV2.sol delete mode 100644 test/Counter.js create mode 100644 test/CounterV2.js diff --git a/contracts/Counter.sol b/contracts/Counter.sol deleted file mode 100644 index 276ec92..0000000 --- a/contracts/Counter.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.28; - -interface ICounter { - function setCount(uint256 _count) external; - function increaseCountByOne() external; - function getCount() external view returns (uint256); -} - -contract Counter is ICounter { - uint256 public count; - address public owner; - - constructor() { - owner = msg.sender; - } - - modifier onlyOwner() { - require(msg.sender == owner, "Not owner"); - _; - } - - function setCount(uint256 _count) external onlyOwner { - require(_count <= 10, "Count must not exceed 10"); - count = _count; - } - - function increaseCountByOne() external onlyOwner { - require(count + 1 <= 10, "Count must not exceed 10"); - count += 1; - } - - function getCount() external view returns (uint256) { - return count; - } -} - diff --git a/contracts/CounterV2.sol b/contracts/CounterV2.sol new file mode 100644 index 0000000..cc5a64b --- /dev/null +++ b/contracts/CounterV2.sol @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +interface ICounterV2{ + function setCount(uint256 _count) external; + + function getCount() external view returns(uint256); + + function increaseCountByOne() external; + + function resetCount() external; + + function decreaseCountByOne() external; +} + +contract CounterV2 is ICounterV2 { + uint256 public count; + address owner; + + constructor(){ + owner = msg.sender; + } + + function setCount(uint256 _count) public { + require(_count > 0, "Count must be greater than 0"); + require(msg.sender == owner, "You are unauthorised"); + count = _count; + } + + function getCount() public view returns(uint256) { + return count; + } + + function getOwner() public view returns(address) { + return owner; + } + + function increaseCountByOne() public { + require(msg.sender == owner, "You are unauthorised"); + count+=1; + } + + function resetCount() public { + require(count > 0,"Cannot reset value , It's already at default"); + require(msg.sender == owner, "You are Unauthorised"); + count = 0; + } + + function decreaseCountByOne() public { + require(msg.sender == owner, "You are unauthorised"); + count-=1; + } +} diff --git a/test/Counter.js b/test/Counter.js deleted file mode 100644 index 1dece69..0000000 --- a/test/Counter.js +++ /dev/null @@ -1,59 +0,0 @@ -const { loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); -const { expect } = require("chai"); - -const deployCounter = async () => { - const [owner, otherUser] = await ethers.getSigners(); - const CounterContract = await ethers.getContractFactory("Counter"); - const counter = await CounterContract.deploy(); - return { counter, owner, otherUser }; -} - -describe("Counter Test Suite", () => { - - describe("Deployment", () => { - it("Should return default values upon deployment", async () => { - const { counter } = await loadFixture(deployCounter); - expect(await counter.count()).to.eq(0); - }); - }); - - describe("Transactions", () => { - describe("SetCount", () => { - it("Should allow owner to set count", async () => { - const { counter, owner } = await loadFixture(deployCounter); - await counter.setCount(5); - expect(await counter.getCount()).to.eq(5); - }); - - it("Should reject non-owner trying to set count", async () => { - const { counter, otherUser } = await loadFixture(deployCounter); - await expect(counter.connect(otherUser).setCount(5)).to.be.revertedWith("Not owner"); - }); - - it("Should not allow count > 10", async () => { - const { counter } = await loadFixture(deployCounter); - await expect(counter.setCount(11)).to.be.revertedWith("Count must not exceed 10"); - }); - }); - - describe("IncreaseCountByOne", () => { - it("Should allow owner to increase count by 1", async () => { - const { counter } = await loadFixture(deployCounter); - await counter.increaseCountByOne(); - expect(await counter.getCount()).to.eq(1); - }); - - it("Should reject non-owner trying to increase count", async () => { - const { counter, otherUser } = await loadFixture(deployCounter); - await expect(counter.connect(otherUser).increaseCountByOne()).to.be.revertedWith("Not owner"); - }); - - it("Should not allow increasing count beyond 10", async () => { - const { counter } = await loadFixture(deployCounter); - await counter.setCount(10); - await expect(counter.increaseCountByOne()).to.be.revertedWith("Count must not exceed 10"); - }); - }); - }); -}); - diff --git a/test/CounterV2.js b/test/CounterV2.js new file mode 100644 index 0000000..c807be0 --- /dev/null +++ b/test/CounterV2.js @@ -0,0 +1,89 @@ +const { loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); +const { expect } = require("chai"); + +async function deployCounterV2() { + const [owner, otherUser] = await ethers.getSigners(); + const CounterV2 = await ethers.getContractFactory("CounterV2"); + const counter = await CounterV2.deploy(); + return { counter, owner, otherUser }; +} + +describe("CounterV2 Test Suite", function () { + + describe("Deployment", () => { + it("Should set count to 0 and assign the correct owner", async () => { + const { counter, owner } = await loadFixture(deployCounterV2); + expect(await counter.getCount()).to.equal(0); + expect(await counter.getOwner()).to.equal(owner.address); + }); + }); + + describe("setCount", () => { + it("Should allow owner to set count > 0", async () => { + const { counter } = await loadFixture(deployCounterV2); + await counter.setCount(5); + expect(await counter.getCount()).to.equal(5); + }); + + it("Should fail if non-owner tries to set count", async () => { + const { counter, otherUser } = await loadFixture(deployCounterV2); + await expect(counter.connect(otherUser).setCount(5)).to.be.revertedWith("You are unauthorised"); + }); + + it("Should fail if count is set to 0", async () => { + const { counter } = await loadFixture(deployCounterV2); + await expect(counter.setCount(0)).to.be.revertedWith("Count must be greater than 0"); + }); + }); + + describe("increaseCountByOne", () => { + it("Should allow owner to increase count", async () => { + const { counter } = await loadFixture(deployCounterV2); + await counter.setCount(1); + await counter.increaseCountByOne(); + expect(await counter.getCount()).to.equal(2); + }); + + it("Should reject increase if called by non-owner", async () => { + const { counter, otherUser } = await loadFixture(deployCounterV2); + await counter.setCount(2); + await expect(counter.connect(otherUser).increaseCountByOne()).to.be.revertedWith("You are unauthorised"); + }); + }); + + describe("resetCount", () => { + it("Should reset count to 0 if owner and count > 0", async () => { + const { counter } = await loadFixture(deployCounterV2); + await counter.setCount(3); + await counter.resetCount(); + expect(await counter.getCount()).to.equal(0); + }); + + it("Should revert if count is already 0", async () => { + const { counter } = await loadFixture(deployCounterV2); + await expect(counter.resetCount()).to.be.revertedWith("Cannot reset value , It's already at default"); + }); + + it("Should reject reset from non-owner", async () => { + const { counter, otherUser } = await loadFixture(deployCounterV2); + await counter.setCount(2); + await expect(counter.connect(otherUser).resetCount()).to.be.revertedWith("You are Unauthorised"); + }); + }); + + describe("decreaseCountByOne", () => { + it("Should decrease count by one if owner", async () => { + const { counter } = await loadFixture(deployCounterV2); + await counter.setCount(2); + await counter.decreaseCountByOne(); + expect(await counter.getCount()).to.equal(1); + }); + + it("Should fail if non-owner tries to decrease count", async () => { + const { counter, otherUser } = await loadFixture(deployCounterV2); + await counter.setCount(2); + await expect(counter.connect(otherUser).decreaseCountByOne()).to.be.revertedWith("You are unauthorised"); + }); + }); +}); + From a142276f182427da6a48e506158534e5d08d1832 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 30 Jul 2025 01:58:05 +0100 Subject: [PATCH 3/3] chore: updated the BlockToken.js file and added more tests --- contracts/BlockHeaderToken.sol | 37 +++++ contracts/CounterV2.sol | 54 ------ package-lock.json | 9 + package.json | 9 +- test/BlockToken.js | 292 +++++++++++++++++++++++++++++++++ test/CounterV2.js | 89 ---------- 6 files changed, 344 insertions(+), 146 deletions(-) create mode 100644 contracts/BlockHeaderToken.sol delete mode 100644 contracts/CounterV2.sol create mode 100644 test/BlockToken.js delete mode 100644 test/CounterV2.js diff --git a/contracts/BlockHeaderToken.sol b/contracts/BlockHeaderToken.sol new file mode 100644 index 0000000..953a41c --- /dev/null +++ b/contracts/BlockHeaderToken.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract BlockToken is ERC20{ + + address public owner; + + modifier onlyOwner { + require(msg.sender == owner, "BlockToken:: Unauthorized User"); + _; + } + + modifier notAmount0(uint256 _amount){ + require(_amount != 0, "BlockToken:: Zero amount not supported"); + _; + } + constructor(string memory _name, string memory _symbol, address _owner) ERC20(_name, _symbol){ + require(_owner != address(0), "BlockToken:: Zero address not supported"); + owner = _owner; + } + + function mint(uint256 _amount, address _recepient) onlyOwner notAmount0(_amount) external { + _mint(_recepient, _amount); + } + + function burn(uint256 _amount) notAmount0(_amount) external { + _burn(msg.sender, _amount); + } + + function burnFrom(address _user, uint256 _amount)onlyOwner notAmount0(_amount) external { + _burn(_user, _amount); + } + + +} diff --git a/contracts/CounterV2.sol b/contracts/CounterV2.sol deleted file mode 100644 index cc5a64b..0000000 --- a/contracts/CounterV2.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.0; - -interface ICounterV2{ - function setCount(uint256 _count) external; - - function getCount() external view returns(uint256); - - function increaseCountByOne() external; - - function resetCount() external; - - function decreaseCountByOne() external; -} - -contract CounterV2 is ICounterV2 { - uint256 public count; - address owner; - - constructor(){ - owner = msg.sender; - } - - function setCount(uint256 _count) public { - require(_count > 0, "Count must be greater than 0"); - require(msg.sender == owner, "You are unauthorised"); - count = _count; - } - - function getCount() public view returns(uint256) { - return count; - } - - function getOwner() public view returns(address) { - return owner; - } - - function increaseCountByOne() public { - require(msg.sender == owner, "You are unauthorised"); - count+=1; - } - - function resetCount() public { - require(count > 0,"Cannot reset value , It's already at default"); - require(msg.sender == owner, "You are Unauthorised"); - count = 0; - } - - function decreaseCountByOne() public { - require(msg.sender == owner, "You are unauthorised"); - count-=1; - } -} diff --git a/package-lock.json b/package-lock.json index 656a34f..cc2bf83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,9 @@ "packages": { "": { "name": "hardhat-project", + "dependencies": { + "@openzeppelin/contracts": "^5.4.0" + }, "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^5.0.0", "hardhat": "^2.26.1" @@ -1305,6 +1308,12 @@ "node": ">= 12" } }, + "node_modules/@openzeppelin/contracts": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.4.0.tgz", + "integrity": "sha512-eCYgWnLg6WO+X52I16TZt8uEjbtdkgLC0SUX/xnAksjjrQI4Xfn4iBRoI5j55dmlOhDv1Y7BoR3cU7e3WWhC6A==", + "license": "MIT" + }, "node_modules/@scure/base": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", diff --git a/package.json b/package.json index 0586079..a7c3ef4 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,13 @@ "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^5.0.0", "hardhat": "^2.26.1" - }, + }, "scripts": { - "test": "npx hardhat test", - "compile": "npx hardhat compile", + "test": "npx hardhat test", + "compile": "npx hardhat compile", "node": "npx hardhat node" + }, + "dependencies": { + "@openzeppelin/contracts": "^5.4.0" } } diff --git a/test/BlockToken.js b/test/BlockToken.js new file mode 100644 index 0000000..6152a56 --- /dev/null +++ b/test/BlockToken.js @@ -0,0 +1,292 @@ +const { + loadFixture, +} = require("@nomicfoundation/hardhat-toolbox/network-helpers"); +const { expect } = require("chai"); + +const deployContract = async () => { + let _name = "BlockToken"; + let _symbol = "BCT"; + const [_owner, addr1, addr2] = await ethers.getSigners(); + const BlockTokenContract = await ethers.getContractFactory("BlockToken"); + const BlockToken = await BlockTokenContract.deploy( + _name, + _symbol, + _owner.address + ); + + return { BlockToken, _owner, addr1, addr2, _name, _symbol }; +}; + +describe("BlockToken Test Suite", () => { + describe("Deployment", () => { + it("Should return set values upon deployment", async () => { + const { BlockToken, _name, _symbol, _owner } = await loadFixture( + deployContract + ); + // console.log(_owner.address); + expect(await BlockToken.name()).to.eq(_name); + expect(await BlockToken.symbol()).to.eq(_symbol); + expect(await BlockToken.owner()).to.eq(_owner.address); + }); + + it("Should revert if owner is zero address", async () => { + const BlockTokenContract = await ethers.getContractFactory("BlockToken"); + const zeroAddress = "0x0000000000000000000000000000000000000000"; + + await expect( + BlockTokenContract.deploy("Token", "TKN", zeroAddress) + ).to.be.revertedWith("BlockToken:: Zero address not supported"); + }); + }); + + describe("Minting", () => { + it("Should allow only owner to mint", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + await BlockToken.connect(_owner).mint(10, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(10); + + await expect( + BlockToken.connect(addr1).mint(1000, addr2) + ).to.be.revertedWith("BlockToken:: Unauthorized User"); + }); + + it("Should revert if minting amount is zero", async () => { + const { BlockToken, _owner, addr1 } = await loadFixture(deployContract); + await expect( + BlockToken.connect(_owner).mint(0, addr1) + ).to.be.revertedWith("BlockToken:: Zero amount not supported"); + }); + }); + + describe("Burning", () => { + it("Should not burn if user doesn't have tokens", async () => { + const { BlockToken, _owner, addr1 } = await loadFixture(deployContract); + + await expect( + BlockToken.connect(addr1).burn(1000) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + }); + + it("Should burn tokens successfully", async () => { + const { BlockToken, _owner } = await loadFixture(deployContract); + + await BlockToken.connect(_owner).mint(1000, _owner); + + const balance = await BlockToken.balanceOf(_owner); + expect(balance).to.eq(1000); + + await BlockToken.connect(_owner).burn(100); + const balance2 = await BlockToken.balanceOf(_owner); + expect(balance2).to.eq(900); + }); + + it("Should allow only owner to burnFrom", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + // Check if address 1 can burn from his address + await expect( + BlockToken.connect(addr1).burnFrom(addr1, 800) + ).to.be.revertedWith("BlockToken:: Unauthorized User"); + + await BlockToken.connect(_owner).mint(900, addr2); + expect(await BlockToken.balanceOf(addr2)).to.eq(900); + + // Check if address 1 can burn from another address + await expect( + BlockToken.connect(addr1).burnFrom(addr2, 800) + ).to.be.revertedWith("BlockToken:: Unauthorized User"); + + // Check if owner can burn from successfully + await BlockToken.connect(_owner).burnFrom(addr1, 200); + + const balance = await BlockToken.balanceOf(addr1); + expect(balance).to.eq(800); + }); + + it("Should not burn zero amount", async () => { + const { BlockToken, _owner, addr1 } = await loadFixture(deployContract); + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await expect( + BlockToken.connect(_owner).burnFrom(addr1, 0) + ).to.be.revertedWith("BlockToken:: Zero amount not supported"); + }); + }); + + describe("Transactions", () => { + describe("Transfers", () => { + it("Should transfer tokens from one account to another", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + const zeroAddress = "0x0000000000000000000000000000000000000000"; + + // Transfer to zero address + await expect(BlockToken.connect(_owner).transfer(zeroAddress, 800)).to + .be.reverted; + + await BlockToken.connect(_owner).mint(1000, _owner); + expect(await BlockToken.balanceOf(_owner)).to.eq(1000); + + // Transfer from owner to other account + await BlockToken.connect(_owner).transfer(addr1, 800); + expect(await BlockToken.balanceOf(_owner)).to.eq(200); + expect(await BlockToken.balanceOf(addr1)).to.eq(800); + + // Transfer from account to account + await BlockToken.connect(addr1).transfer(addr2, 400); + expect(await BlockToken.balanceOf(addr1)).to.eq(400); + expect(await BlockToken.balanceOf(addr2)).to.eq(400); + }); + + it("Should transfer tokens less than or equal to balance", async () => { + const { BlockToken, _owner, addr1 } = await loadFixture(deployContract); + + await BlockToken.connect(_owner).mint(1000, _owner); + expect(await BlockToken.balanceOf(_owner)).to.eq(1000); + + await BlockToken.connect(_owner).transfer(addr1, 1000); + expect(await BlockToken.balanceOf(_owner)).to.eq(0); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await expect( + BlockToken.connect(_owner).transfer(addr1, 100) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + expect(await BlockToken.balanceOf(_owner)).to.eq(0); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + }); + + it("Should approve for transferFrom function", async () => { + const { BlockToken, _owner, addr1 } = await loadFixture(deployContract); + + await BlockToken.connect(_owner).mint(1000, _owner); + expect(await BlockToken.balanceOf(_owner)).to.eq(1000); + + await BlockToken.connect(_owner).approve(addr1, 500); + expect(await BlockToken.allowance(_owner, addr1)).to.eq(500); + }); + + it("Should transferFrom based on approve and allowance", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await BlockToken.connect(addr1).approve(_owner, 500); + expect(await BlockToken.connect(addr1).allowance(addr1, _owner)).to.eq( + 500 + ); + await BlockToken.connect(_owner).transferFrom(addr1, addr2, 400); + + expect(await BlockToken.connect(addr2).balanceOf(addr2)).to.eq(400); + }); + + it("Should revert if balance of 'from' is insufficient", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await BlockToken.connect(addr1).approve(_owner, 500); + expect(await BlockToken.connect(addr1).allowance(addr1, _owner)).to.eq( + 500 + ); + await expect( + BlockToken.connect(_owner).transferFrom(addr1, addr2, 700) + ).to.be.revertedWithCustomError( + BlockToken, + "ERC20InsufficientAllowance" + ); + }); + + it("Should revert if balance of 'from' is insufficient", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await BlockToken.connect(addr1).approve(_owner, 500); + expect(await BlockToken.connect(addr1).allowance(addr1, _owner)).to.eq( + 500 + ); + await expect( + BlockToken.connect(_owner).transferFrom(addr1, addr2, 700) + ).to.be.revertedWithCustomError( + BlockToken, + "ERC20InsufficientAllowance" + ); + }); + + it("Should revert if allowance is zero for spender", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await BlockToken.connect(addr1).approve(_owner, 0); + expect(await BlockToken.connect(addr1).allowance(addr1, _owner)).to.eq( + 0 + ); + await expect( + BlockToken.connect(_owner).transferFrom(addr1, addr2, 700) + ).to.be.revertedWithCustomError( + BlockToken, + "ERC20InsufficientAllowance" + ); + }); + + it("Should revert if 'to' is address zero", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + const zeroAddress = "0x0000000000000000000000000000000000000000"; + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await BlockToken.connect(addr1).approve(_owner, 500); + expect(await BlockToken.connect(addr1).allowance(addr1, _owner)).to.eq( + 500 + ); + await expect( + BlockToken.connect(_owner).transferFrom(addr1, zeroAddress, 400) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InvalidReceiver"); + }); + + it("Should revert if allowance is incremented and not replaced", async () => { + const { BlockToken, _owner, addr1, addr2 } = await loadFixture( + deployContract + ); + + await BlockToken.connect(_owner).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await BlockToken.connect(addr1).approve(_owner, 500); + + await BlockToken.connect(addr1).approve(_owner, 700); + expect(await BlockToken.connect(addr1).allowance(addr1, _owner)).to.eq( + 700 + ); + }); + }); + }); +}); diff --git a/test/CounterV2.js b/test/CounterV2.js deleted file mode 100644 index c807be0..0000000 --- a/test/CounterV2.js +++ /dev/null @@ -1,89 +0,0 @@ -const { loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); -const { expect } = require("chai"); - -async function deployCounterV2() { - const [owner, otherUser] = await ethers.getSigners(); - const CounterV2 = await ethers.getContractFactory("CounterV2"); - const counter = await CounterV2.deploy(); - return { counter, owner, otherUser }; -} - -describe("CounterV2 Test Suite", function () { - - describe("Deployment", () => { - it("Should set count to 0 and assign the correct owner", async () => { - const { counter, owner } = await loadFixture(deployCounterV2); - expect(await counter.getCount()).to.equal(0); - expect(await counter.getOwner()).to.equal(owner.address); - }); - }); - - describe("setCount", () => { - it("Should allow owner to set count > 0", async () => { - const { counter } = await loadFixture(deployCounterV2); - await counter.setCount(5); - expect(await counter.getCount()).to.equal(5); - }); - - it("Should fail if non-owner tries to set count", async () => { - const { counter, otherUser } = await loadFixture(deployCounterV2); - await expect(counter.connect(otherUser).setCount(5)).to.be.revertedWith("You are unauthorised"); - }); - - it("Should fail if count is set to 0", async () => { - const { counter } = await loadFixture(deployCounterV2); - await expect(counter.setCount(0)).to.be.revertedWith("Count must be greater than 0"); - }); - }); - - describe("increaseCountByOne", () => { - it("Should allow owner to increase count", async () => { - const { counter } = await loadFixture(deployCounterV2); - await counter.setCount(1); - await counter.increaseCountByOne(); - expect(await counter.getCount()).to.equal(2); - }); - - it("Should reject increase if called by non-owner", async () => { - const { counter, otherUser } = await loadFixture(deployCounterV2); - await counter.setCount(2); - await expect(counter.connect(otherUser).increaseCountByOne()).to.be.revertedWith("You are unauthorised"); - }); - }); - - describe("resetCount", () => { - it("Should reset count to 0 if owner and count > 0", async () => { - const { counter } = await loadFixture(deployCounterV2); - await counter.setCount(3); - await counter.resetCount(); - expect(await counter.getCount()).to.equal(0); - }); - - it("Should revert if count is already 0", async () => { - const { counter } = await loadFixture(deployCounterV2); - await expect(counter.resetCount()).to.be.revertedWith("Cannot reset value , It's already at default"); - }); - - it("Should reject reset from non-owner", async () => { - const { counter, otherUser } = await loadFixture(deployCounterV2); - await counter.setCount(2); - await expect(counter.connect(otherUser).resetCount()).to.be.revertedWith("You are Unauthorised"); - }); - }); - - describe("decreaseCountByOne", () => { - it("Should decrease count by one if owner", async () => { - const { counter } = await loadFixture(deployCounterV2); - await counter.setCount(2); - await counter.decreaseCountByOne(); - expect(await counter.getCount()).to.equal(1); - }); - - it("Should fail if non-owner tries to decrease count", async () => { - const { counter, otherUser } = await loadFixture(deployCounterV2); - await counter.setCount(2); - await expect(counter.connect(otherUser).decreaseCountByOne()).to.be.revertedWith("You are unauthorised"); - }); - }); -}); -