diff --git a/contracts/BlockHeaderToken.sol b/contracts/BlockHeaderToken.sol index c0c2fa9..2721910 100644 --- a/contracts/BlockHeaderToken.sol +++ b/contracts/BlockHeaderToken.sol @@ -33,6 +33,17 @@ contract BlockToken is ERC20{ _burn(_user, _amount); } + function tokenTransfer(address _recepient, uint256 _amount) notAmount0(_amount) external { + _transfer(msg.sender, _recepient, _amount); + } + + function transferTokenFrom(address _sender, address _recepient, uint256 _amount) notAmount0(_amount) external { + _transfer(_sender, _recepient, _amount); + } + + function tokenApprove(address spender, uint256 _amount) notAmount0(_amount) external{ + _approve(msg.sender, spender, _amount); + } } diff --git a/contracts/Counter.sol b/contracts/Counter.sol index fa8560c..3a2a4a4 100644 --- a/contracts/Counter.sol +++ b/contracts/Counter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.28; +pragma solidity ^0.8.0; interface ICounter { function setCount(uint256 _count) external; @@ -25,24 +25,24 @@ contract Counter is ICounter { } -// contract F { -// // Initializing interface IC -// IC public _ic; -// // Initializing the contract address -// address public contractCAddress; +// // 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); -// } +// // 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 setCount(uint256 _count) public { +// // _ic.setCount(_count); +// // } -// function getCount() public view returns(uint256) { -// return _ic.getCount(); -// } -// } \ No newline at end of file +// // function getCount() public view returns(uint256) { +// // return _ic.getCount(); +// // } +// // } \ No newline at end of file diff --git a/contracts/CounterV2.sol b/contracts/CounterV2.sol new file mode 100644 index 0000000..43a6428 --- /dev/null +++ b/contracts/CounterV2.sol @@ -0,0 +1,63 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface MeCounterV2 { + function resetCount() external; + function setCount(uint256 _count) external; + function decreaseCount() external; + function increaseCountByOne() external; + function getCount() external view returns(uint256); + +} + +contract CounterV2 is MeCounterV2 { + uint256 public count; + address owner; + + constructor() { + owner = msg.sender; + } + + function setCount(uint256 _count) public { + require(_count > 0, "Cannot pass in 0 value as argument"); + require(msg.sender == owner, "Unauthorized User: Only owner can alter the count"); + count = _count; + } + + + function increaseCountByOne() public { + require(msg.sender == owner, "Unauthorized User"); + count += 1; + } + + function getCount() public view returns(uint256) { + // require(msg.sender == owner, "Unauthorized User"); + return count; + } + + function resetCount() public { + require(msg.sender == owner, "Unauthorized User"); + if (count > 0) { + count = 0; + } + } + + function decreaseCount() external { + count -= 1; + } +} + +contract CounterV2Caller{ + MeCounterV2 public _MeCounterV2; + address public contractCountV2Add; + + constructor (address _contractCountV2Add) { + contractCountV2Add = _contractCountV2Add; + _MeCounterV2 = MeCounterV2 (_contractCountV2Add); + } + + function decreementCaller() external { + _MeCounterV2.decreaseCount(); + } + +} \ No newline at end of file diff --git a/contracts/Lock.sol b/contracts/Lock.sol index 2f385f7..7c6b906 100644 --- a/contracts/Lock.sol +++ b/contracts/Lock.sol @@ -1,34 +1,34 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.28; +// // SPDX-License-Identifier: UNLICENSED +// pragma solidity ^0.8.28; -// Uncomment this line to use console.log -// import "hardhat/console.sol"; +// // Uncomment this line to use console.log +// // import "hardhat/console.sol"; -contract Lock { - uint public unlockTime; - address payable public owner; +// contract Lock { +// uint public unlockTime; +// address payable public owner; - event Withdrawal(uint amount, uint when); +// event Withdrawal(uint amount, uint when); - constructor(uint _unlockTime) payable { - require( - block.timestamp < _unlockTime, - "Unlock time should be in the future" - ); +// constructor(uint _unlockTime) payable { +// require( +// block.timestamp < _unlockTime, +// "Unlock time should be in the future" +// ); - unlockTime = _unlockTime; - owner = payable(msg.sender); - } +// unlockTime = _unlockTime; +// owner = payable(msg.sender); +// } - function withdraw() public { - // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal - // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp); +// function withdraw() public { +// // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal +// // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp); - require(block.timestamp >= unlockTime, "You can't withdraw yet"); - require(msg.sender == owner, "You aren't the owner"); +// require(block.timestamp >= unlockTime, "You can't withdraw yet"); +// require(msg.sender == owner, "You aren't the owner"); - emit Withdrawal(address(this).balance, block.timestamp); +// emit Withdrawal(address(this).balance, block.timestamp); - owner.transfer(address(this).balance); - } -} +// owner.transfer(address(this).balance); +// } +// } diff --git a/package-lock.json b/package-lock.json index cc2bf83..d2e9473 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ }, "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@types/minimatch": "^5.1.2", "hardhat": "^2.26.1" } }, @@ -1687,15 +1688,11 @@ } }, "node_modules/@types/minimatch": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-6.0.0.tgz", - "integrity": "sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==", - "deprecated": "This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed.", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true, - "peer": true, - "dependencies": { - "minimatch": "*" - } + "license": "MIT" }, "node_modules/@types/mocha": { "version": "10.0.10", diff --git a/package.json b/package.json index a7c3ef4..3af3ab2 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "hardhat-project", "devDependencies": { "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@types/minimatch": "^5.1.2", "hardhat": "^2.26.1" }, "scripts": { diff --git a/test/BlockToken.js b/test/BlockToken.js index f51869d..96973a4 100644 --- a/test/BlockToken.js +++ b/test/BlockToken.js @@ -79,4 +79,177 @@ describe("BlockToken Test Suite", () => { expect(await BlockToken.balanceOf(owner_)).to.eq(900); }); }); + +>> Cletus-Assignment2 + + describe("burning From", () =>{ + it("Should not burn if user doesn't have tokens", async () => { + const {BlockToken, owner_, addr1} = await loadFixture(deployBlockToken); + await expect(BlockToken.connect(owner_).burnFrom(addr1, 1000) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + }); + + it("Shound burn from an address successfully", async () => { + const {BlockToken, owner_, addr1} = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(2000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(2000); + + await BlockToken.connect(owner_).burnFrom(addr1,1000); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + }); + + it("Should revert when burning zero tokens", async () => { + const { BlockToken, owner_, addr1 } = await loadFixture(deployBlockToken); + await expect( + BlockToken.connect(owner_).burnFrom(addr1, 0) + ).to.be.revertedWith("BlockToken:: Zero amount not supported"); + }); + + it("Should revert when burning more than balance", async () => { + const { BlockToken, owner_ ,addr1} = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(500, addr1); + await expect( + BlockToken.connect(owner_).burnFrom(addr1, 1000) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + }); + + it("Should revert if burnining called by different address", async () =>{ + const { BlockToken,addr2, addr1 } = await loadFixture(deployBlockToken); + // test that another user cant call successfully + let malicioustxn = BlockToken.connect(addr1).burnFrom(addr2, 1000); + await expect(malicioustxn).to.be.revertedWith( + "BlockToken:: Unauthorized User" + ); + }); +}); + +describe("Approve token transfer", () =>{ + it("Should revert when approving zero tokens", async () => { + const { BlockToken, owner_,addr1,addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(1000, addr1); + + await expect( + BlockToken.connect(addr1).tokenApprove(addr2, 0) + ).to.be.revertedWith("BlockToken:: Zero amount not supported"); + }); + + it("Should revert if approving to address zero", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + let ZeroAddress = "0x0000000000000000000000000000000000000000"; + + await BlockToken.connect(owner_).mint(500, addr1) + await expect( + BlockToken.connect(addr1).tokenApprove(ZeroAddress, 50) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InvalidSpender"); + }); + + it("Should Approve Tokens Successfully", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + + await BlockToken.connect(addr1).tokenApprove(addr2, 300); + expect(await BlockToken.allowance(addr1,addr2)).to.eq(300); + + }); + }); + describe("Token Transfer ", () => { + describe("TOken transfer Transaction", () => { + it("Should revert if from address doesn't have tokens", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + // await BlockToken.connect(owner_).mint(1000, addr1); + await expect( + BlockToken.connect(addr1).tokenTransfer(addr2, 1000) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + }); + + it("Should revert when transfering zero tokens", async () => { + const { BlockToken, owner_,addr1,addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(1000, addr1); + + await expect( + BlockToken.connect(addr1).tokenTransfer(addr2, 0) + ).to.be.revertedWith("BlockToken:: Zero amount not supported"); + }); + + it("Should revert when transfering more than balance", async () => { + const { BlockToken, owner_, addr1,addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(500, addr1); + await expect( + BlockToken.connect(addr1).tokenTransfer(addr2, 1000) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + }); + + it("Should revert if transfering to address zero", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + let ZeroAddress = "0x0000000000000000000000000000000000000000"; + + await BlockToken.connect(owner_).mint(500, addr1) + await expect( + BlockToken.connect(addr1).tokenTransfer(ZeroAddress, 50) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InvalidReceiver"); + }); + + it("Should Burn Tokens Successfully", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(1000, addr1); + expect(await BlockToken.balanceOf(addr1)).to.eq(1000); + + await BlockToken.connect(addr1).tokenTransfer(addr2, 300); + expect(await BlockToken.balanceOf(addr1)).to.eq(700); + expect(await BlockToken.balanceOf(addr2)).to.eq(300); + + }); + }); +}); + +describe("TransferFrom Token", () => { + it("Should revert if owner address doesn't have tokens", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(addr1).tokenApprove(addr2,100); + await expect( + BlockToken.connect(addr2).transferTokenFrom(addr1,owner_,50) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + }); + + it("Should revert when transfering zero tokens", async () => { + const { BlockToken, owner_,addr1,addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(1000, addr1); + await BlockToken.connect(addr1).tokenApprove(addr2,500) + await expect( + BlockToken.connect(addr2).transferTokenFrom(addr1,owner_, 0) + ).to.be.revertedWith("BlockToken:: Zero amount not supported"); + }); + + it("Should revert when transfering more than balance", async () => { + const { BlockToken, owner_, addr1,addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(1000, addr1); + await BlockToken.connect(addr1).tokenApprove(addr2,5000) + await expect( + BlockToken.connect(addr2).transferTokenFrom(addr1,owner_, 2000) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InsufficientBalance"); + }); + + it("Should revert if transfering to address zero", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + let ZeroAddress = "0x0000000000000000000000000000000000000000"; + await BlockToken.connect(owner_).mint(1000, addr1); + await BlockToken.connect(addr1).tokenApprove(addr2,5000) + await expect( + BlockToken.connect(addr2).transferTokenFrom(addr1, ZeroAddress, 500) + ).to.be.revertedWithCustomError(BlockToken, "ERC20InvalidReceiver"); + }); + + it("Should Transfer Tokens Successfully Using TranasferFrom", async () => { + const { BlockToken, owner_, addr1, addr2 } = await loadFixture(deployBlockToken); + await BlockToken.connect(owner_).mint(1000, addr1); + await BlockToken.connect(addr1).tokenApprove(addr2,5000) + + await BlockToken.connect(addr2).transferTokenFrom(addr1,addr2, 400); + + expect(await BlockToken.balanceOf(addr1)).to.eq(600); + expect(await BlockToken.balanceOf(addr2)).to.eq(400); + + }); + }); + }) }); +>>> Erc20-testing diff --git a/test/Counter.js b/test/Counter.js index 507bd94..e9c3e09 100644 --- a/test/Counter.js +++ b/test/Counter.js @@ -1,3 +1,103 @@ +<< Cletus-Assignment2 +// const {loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); +// // const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); +// 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 +// } + +// // 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 +// }) +// }) + +// describe("Transactions", () => { +// describe("SetCount", () => { + +// it("Should set appropriate count values", async () => { +// const counter = await loadFixture(deployCounter); // A demo disployment of an instance, 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 () => { +// 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); +// await counter.setCount(20) + +// let count3 = await counter.getCount(); // check initial count value before txn +// expect(count3).to.eq(20); +// await counter.setCount(30) + +// let count4 = await counter.getCount(); // check initial count value before txn +// expect(count4).to.eq(30); +// await counter.setCount(40) + +// }) +// }) + +// describe("IncreaseCountByOne", () => { +// // it("Should set appropriate increaseCountByOne value", 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.increaseCountByOne(); // assert that count = 0 upon deployment +// // let count2 = await counter.getCount(); // check initial count value before txn +// // expect(count1).to.eq(0); + + +// // }) + +// it("Should set appropriate values for multiple increaseCountByOne txns", 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(50) + +// // await counter.increaseCountByOne(s); +// let count2 = 50 +// // expect(count2).to.eq(50); + +// while (count2 < 50) { +// console.log(count2); +// count2++; +// } +// // for (let index = 0; index < 51; index++) { +// await counter.increaseCountByOne(); + +// // }, + +// // let count3 = await counter.getCount(); // check initial count value before txn +// // expect(count3).to.eq(101); + + + + +// }) +// }) +// }) +// }) +======= // const { // loadFixture, // } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); @@ -88,3 +188,4 @@ // }); // }); // }); +>> Erc20-testing diff --git a/test/CounterV2.js b/test/CounterV2.js new file mode 100644 index 0000000..e54114e --- /dev/null +++ b/test/CounterV2.js @@ -0,0 +1,101 @@ +// const {loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); +// // const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); +// const { expect } = require("chai"); + + +// // util functon +// const deployCounter = async () => { +// // target the Counter contract within our contract folder +// const CounterContract = await ethers.getContractFactory("CounterV2"); // target Counter.sol +// const counterV2 = await CounterContract.deploy(); // deploy the Counter contract + + +// const CounterContract1 = await ethers.getContractFactory("CounterV2Caller"); +// const targetAddress = await counterV2.getAddress(); //const targetAddress = await counterV2.getAddress(); + +// const counterV2caller = await CounterContract1.deploy(targetAddress); + + +// return {counterV2, counterV2caller} ; // return the deployed instance of our counter contract +// } + + +// //Counter Test +// describe("Testing Counter Suite Contract.sol", () => { +// describe("Deployment", async() => { +// it("Should return default values upon deployment", async () => { +// const {counterV2} = await loadFixture(deployCounter); +// expect(await counterV2.count()).to.eq(0); +// }); +// }); + +// describe("Transaction", () => { +// describe("SetCount", () => { +// it("Should set appropriate count values", async () => { +// const {counterV2} = await loadFixture(deployCounter); +// let count1 = await counterV2.getCount(); +// expect(count1).to.eq(0); +// await counterV2.setCount(10); +// }) +// it("Should set appropriate values for multiple setCount txns", async () => { +// const {counterV2} = await loadFixture(deployCounter); +// let count1 = await counterV2.getCount(); +// expect(count1).to.eq(0); +// await counterV2.setCount(1); + +// let count2 = await counterV2.getCount(); +// expect(count2).to.eq(1); +// await counterV2.setCount(2); +// }) +// }) + +// describe("resetCount", () => { +// it("Should reset the value to a default", async () => { +// const {counterV2} = await loadFixture(deployCounter); +// let count1 = await counterV2.getCount(); +// expect(count1).to.eq(0); +// await counterV2.setCount(10); + +// let count2 = await counterV2.getCount(); +// expect(count2).to.eq(10); +// await counterV2.setCount(20); + +// let count3 = await counterV2.getCount(); +// expect(count3).to.eq(20); +// await counterV2.resetCount(); + +// }) +// }) + +// describe("IncreaseCountByOne", () => { +// it("Should set appropriate increaseCountByOne value", async () => { +// const {counterV2} = await loadFixture(deployCounter); // extract deployed counter instace +// let count1 = await counterV2.getCount(); // check initial count value before txn +// expect(count1).to.eq(0); + +// let count2 = await counterV2.getCount(); // check initial count value before txn +// expect(count1).to.eq(0); + +// }) + +// }) + +// describe("DecreaseCount", () => { +// it("Should decrease Count by one value", async () => { +// const {counterV2, counterV2caller} = await loadFixture(deployCounter); // extract deployed counter instace +// let count1 = await counterV2.getCount(); // check initial count value before txn +// expect(count1).to.eq(0); +// await counterV2.setCount(10) + +// let count2 = await counterV2.getCount(); // check initial count value before txn +// expect(count2).to.eq(10); +// await counterV2caller.decreementCaller(); + +// let count3 = await counterV2.getCount(); // check initial count value before txn +// expect(count3).to.eq(9); + +// }) + +// }) +// }) +// }) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 574e785..10d7742 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, - "resolveJsonModule": true + "resolveJsonModule": true, + // "types": ["minimatch"] } }