Commit def735e7 authored by vicotor's avatar vicotor

add test contract and scripts

parents
Pipeline #865 failed with stages
node_modules
.env
# Hardhat files
/cache
/artifacts
# TypeChain files
/typechain
/typechain-types
# solidity-coverage files
/coverage
/coverage.json
# Hardhat Ignition default folder for deployments against a local node
ignition/deployments/chain-31337
.idea
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
# Sample Hardhat Project
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.
Try running some of the following tasks:
```shell
npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat ignition deploy ./ignition/modules/Lock.js
```
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract InternalTransfer {
function sendViaTransfer(address payable _to, uint256 _amount) public payable {
_to.transfer(_amount);
}
function sendViaSend(address payable _to, uint256 _amount) public payable returns (bool) {
bool sent = _to.send(_amount);
require(sent, "Send failed");
return sent;
}
function sendViaCall(address payable _to, uint256 _amount) public payable returns (bool) {
(bool success, ) = _to.call{value: _amount}("");
require(success, "Call failed");
return success;
}
receive() external payable {}
}
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract RevertContract {
modifier minimumEther(uint256 _amount) {
require(_amount >= 1*10**18, "minimum 1 ether");
_;
}
function sendViaTransfer(address payable _to, uint256 _amount) public payable minimumEther(_amount) {
require(_amount >= 1*10**18, "minimum 1 ether");
_to.transfer(_amount);
}
function sendViaSend(address payable _to, uint256 _amount) public payable minimumEther(_amount) returns (bool) {
bool sent = _to.send(_amount);
require(sent, "Send failed");
return sent;
}
function sendViaCall(address payable _to, uint256 _amount) public payable minimumEther(_amount) returns (bool) {
(bool success, ) = _to.call{value: _amount}("");
require(success, "Call failed");
return success;
}
receive() external payable {}
}
\ No newline at end of file
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract PublicToken is ERC20 {
constructor() ERC20("PUBLIC TOKEN", "PUB") {
_mint(msg.sender, 1 * 10 ** decimals());
}
function mint(address to, uint256 amount) public {
_mint(to, amount);
}
function burn(uint256 amount) public {
_burn(msg.sender, amount);
}
}
\ No newline at end of file
require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-ethers");
require("dotenv").config()
// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners()
for (const account of accounts) {
console.log(account.address)
}
})
// Define mnemonic for accounts.
let mnemonic = process.env.MNEMONIC
if (!mnemonic) {
// NOTE: this fallback is for development only!
// When using other networks, set the secret in .env.
// DO NOT commit or share your mnemonic with others!
mnemonic = "test test test test test test test test test test test test"
}
// contract owner: 0x9f8fb0488dE145E7467FDeD872098e1115d6ea4C
// contract admin: 0x9f8fb0488dE145E7467FDeD872098e1115d6ea4C
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
const privateKey = process.env.DEPLOY_PRIVATE_KEY
const accounts = { mnemonic }
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
compilers: [
{
version: "0.8.20",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
],
},
etherscan: {
apiKey: {
'achain': 'empty',
'bsc':'AVZIFYCHUFHPG9FDKNMHEWJ1VAW1H5U66T'
},
customChains: [
{
network: "achain",
chainId: 100,
urls: {
apiURL: "https://scan.cmp20.bitheart.org/api",
browserURL: "https://scan.cmp20.bitheart.org"
}
}
]
},
networks: {
hardhat: {
accounts: [{ privateKey, balance: "10000000000000000000000" }], // Example balance
gas: 10000000,
gasPrice: 10000000000,
},
achain: {
// url: "https://achain.bitheart.org",
// url: "http://192.168.1.39:28545",
url: "http://15.206.56.79:28545",
accounts: [privateKey],
},
},
};
// This setup uses Hardhat Ignition to manage smart contract deployments.
// Learn more about it at https://hardhat.org/ignition
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
const JAN_1ST_2030 = 1893456000;
const ONE_GWEI = 1_000_000_000n;
module.exports = buildModule("LockModule", (m) => {
const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030);
const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI);
const lock = m.contract("Lock", [unlockTime], {
value: lockedAmount,
});
return { lock };
});
console.log('Happy developing ✨')
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "testcontract",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"private": true,
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"hardhat": "^2.24.0"
},
"dependencies": {
"@openzeppelin/contracts": "^5.3.0",
"dotenv": "^16.5.0"
}
}
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
async function forceRevert() {
// 部署合约
const factory = await hre.ethers.getContractFactory("RevertContract");
const contract = await factory.deploy();
await contract.waitForDeployment();
const contractAddress = await contract.getAddress();
console.log("Contract deployed at:", contractAddress);
const signer = new hre.ethers.Wallet(process.env.DEPLOY_PRIVATE_KEY, hre.ethers.provider);
const transferAmount = hre.ethers.parseEther("0.0005"); // 小于 1 ETH
var nonce = await hre.ethers.provider.getTransactionCount(signer.address)
// 签名交易
const signedTx = await signer.signTransaction({
type: 0,
chainId: 100,
nonce: nonce,
to: contractAddress,
data: '0xd27f8e66000000000000000000000000a686b69111eadc74d45eeb3be4ae487fd61497e60000000000000000000000000000000000000000000000000001c6bf52634000',
value: transferAmount,
gasLimit: 1000000, // 设置 gas 限制
gasPrice: hre.ethers.parseUnits("1", "gwei"), // 设置 gas 价格
});
// 发送交易
const txResponse = await hre.ethers.provider.broadcastTransaction(signedTx);
console.log("Transaction sent:", txResponse.hash);
}
// Define the script
async function main() {
await forceRevert()
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
async function test() {
const signer = new hre.ethers.Wallet(process.env.DEPLOY_PRIVATE_KEY, hre.ethers.provider);
const transferAmount = hre.ethers.parseEther("0.0001");
var nonce = await hre.ethers.provider.getTransactionCount(signer.address)
nonce = nonce + 1
const signedTx = await signer.signTransaction({
type: 0,
chainId: 100,
nonce: nonce,
to: "0x88395111AB1586a4030dAC62a183542762929bbC",
data: '',
value: transferAmount,
gasLimit: 1000000,
gasPrice: hre.ethers.parseUnits("1", "gwei"),
});
// 发送交易
const txResponse = await hre.ethers.provider.broadcastTransaction(signedTx);
console.log("Transaction sent:", txResponse.hash);
}
// Define the script
async function main() {
await test()
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
// Define the script
async function main() {
// Deploy the contract
const factory = await hre.ethers.getContractFactory(
"InternalTransfer"
);
// const contract = await factory.deploy({ value: hre.ethers.parseEther("0.0008") });
const contract = await factory.deploy();
await contract.waitForDeployment();
const depAddr = await contract.getAddress();
console.log("Contract deployed at:", depAddr);
// sendViaTransfer
const recipient = "0xa686b69111eaDc74d45eEB3bE4aE487Fd61497E6"; // Replace with the recipient's address
const transferAmount = ethers.parseEther("0.0005"); // 0.0005 ETH
const viaTransfer = await contract.sendViaTransfer(recipient, transferAmount, {value: transferAmount});
await viaTransfer.wait();
console.log(`Transferred ${ethers.formatEther(transferAmount)} ETH to ${recipient} via transfer`);
// sendViaCall
const viaCall = await contract.sendViaCall(recipient, transferAmount, {value: transferAmount});
await viaCall.wait();
console.log(`Transferred ${ethers.formatEther(transferAmount)} ETH to ${recipient} via call`);
// sendViaSend
const viaSend = await contract.sendViaSend(recipient, transferAmount, {value: transferAmount});
await viaSend.wait();
console.log(`Transferred ${ethers.formatEther(transferAmount)} ETH to ${recipient} via send`);
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
async function test() {
const signer = new hre.ethers.Wallet(process.env.DEPLOY_PRIVATE_KEY, hre.ethers.provider);
const transferAmount = hre.ethers.parseEther("0.0001");
var nonce = await hre.ethers.provider.getTransactionCount(signer.address)
nonce = nonce - 1
const signedTx = await signer.signTransaction({
type: 0,
chainId: 100,
nonce: nonce,
to: "0x88395111AB1586a4030dAC62a183542762929bbC",
data: '',
value: transferAmount,
gasLimit: 1000000,
gasPrice: hre.ethers.parseUnits("1", "gwei"),
});
// 发送交易
const txResponse = await hre.ethers.provider.broadcastTransaction(signedTx);
console.log("Transaction sent:", txResponse.hash);
}
// Define the script
async function main() {
await test()
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
// Define the script
async function main() {
// Deploy the contract
const factory = await hre.ethers.getContractFactory(
"RevertContract"
);
// const contract = await factory.deploy({ value: hre.ethers.parseEther("0.0008") });
const contract = await factory.deploy();
await contract.waitForDeployment();
const depAddr = await contract.getAddress();
console.log("Contract deployed at:", depAddr);
// sendViaTransfer
const recipient = "0xa686b69111eaDc74d45eEB3bE4aE487Fd61497E6"; // Replace with the recipient's address
const transferAmount = ethers.parseEther("0.0005"); // 0.0005 ETH
const viaTransfer = await contract.sendViaTransfer(recipient, transferAmount, {value: transferAmount, gas: 1000000, gasPrice: 1000000000});
await viaTransfer.wait();
console.log(`Transferred ${ethers.formatEther(transferAmount)} ETH to ${recipient} via transfer`);
// sendViaCall
const viaCall = await contract.sendViaCall(recipient, transferAmount, {value: transferAmount});
await viaCall.wait();
console.log(`Transferred ${ethers.formatEther(transferAmount)} ETH to ${recipient} via call`);
// sendViaSend
const viaSend = await contract.sendViaSend(recipient, transferAmount, {value: transferAmount});
await viaSend.wait();
console.log(`Transferred ${ethers.formatEther(transferAmount)} ETH to ${recipient} via send`);
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
async function test() {
const signer = new hre.ethers.Wallet(process.env.DEPLOY_PRIVATE_KEY, hre.ethers.provider);
const transferAmount = hre.ethers.parseEther("0.0001");
var nonce = await hre.ethers.provider.getTransactionCount(signer.address)
const signedTx = await signer.signTransaction({
type: 0,
chainId: 100,
nonce: nonce,
to: "0x88395111AB1586a4030dAC62a183542762929bbC",
data: '',
value: transferAmount,
gasLimit: 1000000,
gasPrice: hre.ethers.parseUnits("1", "gwei"),
});
// 发送交易
const txResponse = await hre.ethers.provider.broadcastTransaction(signedTx);
console.log("Transaction sent:", txResponse.hash);
}
// Define the script
async function main() {
await test()
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
async function test() {
const signer = new hre.ethers.Wallet(process.env.DEPLOY_PRIVATE_KEY, hre.ethers.provider);
const transferAmount = hre.ethers.parseEther("0.0005");
var nonce = await hre.ethers.provider.getTransactionCount(signer.address)
nonce = nonce + 1;
const signedTx = await signer.signTransaction({
type: 0,
chainId: 100,
nonce: nonce,
// to: "0x88395111AB1586a4030dAC62a183542762929bbC", // first
to: "0x6ddb3A03366e218956483A840D8BfB490ADE1beB", // second
data: '',
value: transferAmount,
gasLimit: 1000000,
gasPrice: hre.ethers.parseUnits("1", "gwei"),
});
// 发送交易
const txResponse = await hre.ethers.provider.broadcastTransaction(signedTx);
console.log("Transaction sent:", txResponse.hash);
}
// Define the script
async function main() {
await test()
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const { ContractFactory } = require("ethers");
const hre = require("hardhat");
// Define the script
async function main() {
// Deploy the contract
const factory = await hre.ethers.getContractFactory(
"PublicToken"
);
// const contract = await factory.deploy({ value: hre.ethers.parseEther("0.0008") });
const contract = await factory.deploy();
await contract.waitForDeployment();
const depAddr = await contract.getAddress();
console.log("Contract deployed at:", depAddr);
}
// Run the script
main().catch((error) => {
console.error("Error:", error);
});
\ No newline at end of file
const {
time,
loadFixture,
} = require("@nomicfoundation/hardhat-toolbox/network-helpers");
const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs");
const { expect } = require("chai");
describe("Lock", function () {
// We define a fixture to reuse the same setup in every test.
// We use loadFixture to run this setup once, snapshot that state,
// and reset Hardhat Network to that snapshot in every test.
async function deployOneYearLockFixture() {
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
const ONE_GWEI = 1_000_000_000;
const lockedAmount = ONE_GWEI;
const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;
// Contracts are deployed using the first signer/account by default
const [owner, otherAccount] = await ethers.getSigners();
const Lock = await ethers.getContractFactory("Lock");
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
return { lock, unlockTime, lockedAmount, owner, otherAccount };
}
describe("Deployment", function () {
it("Should set the right unlockTime", async function () {
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
expect(await lock.unlockTime()).to.equal(unlockTime);
});
it("Should set the right owner", async function () {
const { lock, owner } = await loadFixture(deployOneYearLockFixture);
expect(await lock.owner()).to.equal(owner.address);
});
it("Should receive and store the funds to lock", async function () {
const { lock, lockedAmount } = await loadFixture(
deployOneYearLockFixture
);
expect(await ethers.provider.getBalance(lock.target)).to.equal(
lockedAmount
);
});
it("Should fail if the unlockTime is not in the future", async function () {
// We don't use the fixture here because we want a different deployment
const latestTime = await time.latest();
const Lock = await ethers.getContractFactory("Lock");
await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith(
"Unlock time should be in the future"
);
});
});
describe("Withdrawals", function () {
describe("Validations", function () {
it("Should revert with the right error if called too soon", async function () {
const { lock } = await loadFixture(deployOneYearLockFixture);
await expect(lock.withdraw()).to.be.revertedWith(
"You can't withdraw yet"
);
});
it("Should revert with the right error if called from another account", async function () {
const { lock, unlockTime, otherAccount } = await loadFixture(
deployOneYearLockFixture
);
// We can increase the time in Hardhat Network
await time.increaseTo(unlockTime);
// We use lock.connect() to send a transaction from another account
await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith(
"You aren't the owner"
);
});
it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () {
const { lock, unlockTime } = await loadFixture(
deployOneYearLockFixture
);
// Transactions are sent using the first signer by default
await time.increaseTo(unlockTime);
await expect(lock.withdraw()).not.to.be.reverted;
});
});
describe("Events", function () {
it("Should emit an event on withdrawals", async function () {
const { lock, unlockTime, lockedAmount } = await loadFixture(
deployOneYearLockFixture
);
await time.increaseTo(unlockTime);
await expect(lock.withdraw())
.to.emit(lock, "Withdrawal")
.withArgs(lockedAmount, anyValue); // We accept any value as `when` arg
});
});
describe("Transfers", function () {
it("Should transfer the funds to the owner", async function () {
const { lock, unlockTime, lockedAmount, owner } = await loadFixture(
deployOneYearLockFixture
);
await time.increaseTo(unlockTime);
await expect(lock.withdraw()).to.changeEtherBalances(
[owner, lock],
[lockedAmount, -lockedAmount]
);
});
});
});
});
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("RevertContract", function () {
let RevertContract, revertContract, owner, recipient;
beforeEach(async function () {
// Deploy the contract
[owner] = await ethers.getSigners();
recipient = '0xa686b69111eaDc74d45eEB3bE4aE487Fd61497E6'; // Replace with a valid recipient address
const RevertContractFactory = await ethers.getContractFactory("RevertContract");
revertContract = await RevertContractFactory.deploy();
await revertContract.waitForDeployment();
});
it("should revert sendViaTransfer if amount is less than 1 ether", async function () {
const transferAmount = ethers.parseEther("0.5"); // Less than 1 ether
await expect(
revertContract.sendViaTransfer(recipient, transferAmount, { value: transferAmount })
).to.be.revertedWith("minimum 1 ether");
});
it("should successfully send via transfer if amount is 1 ether or more", async function () {
const transferAmount = ethers.parseEther("1"); // Exactly 1 ether
await expect(
revertContract.sendViaTransfer(recipient, transferAmount, { value: transferAmount })
).to.not.be.reverted;
});
it("should revert sendViaSend if amount is less than 1 ether", async function () {
const sendAmount = ethers.parseEther("0.5"); // Less than 1 ether
await expect(
revertContract.sendViaSend(recipient, sendAmount, { value: sendAmount })
).to.be.revertedWith("minimum 1 ether");
});
it("should successfully send via send if amount is 1 ether or more", async function () {
const sendAmount = ethers.parseEther("1"); // Exactly 1 ether
await expect(
revertContract.sendViaSend(recipient, sendAmount, { value: sendAmount })
).to.not.be.reverted;
});
it("should revert sendViaCall if amount is less than 1 ether", async function () {
const callAmount = ethers.parseEther("0.5"); // Less than 1 ether
await expect(
revertContract.sendViaCall(recipient, callAmount, { value: callAmount })
).to.be.revertedWith("minimum 1 ether");
});
it("should successfully send via call if amount is 1 ether or more", async function () {
const callAmount = ethers.parseEther("1"); // Exactly 1 ether
await expect(
revertContract.sendViaCall(recipient, callAmount, { value: callAmount })
).to.not.be.reverted;
});
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment