contracts-imtbl/test/testTokenClaim.ts
2024-08-22 15:18:47 +08:00

141 lines
7.7 KiB
TypeScript

import { expect } from 'chai'
import hre from "hardhat";
import {
getBytes,
solidityPackedKeccak256,
} from 'ethers'
import {
loadFixture,
} from "@nomicfoundation/hardhat-toolbox/network-helpers";
describe('TokenClaim', function() {
async function deployOneContract() {
const [owner, otherAccount] = await hre.ethers.getSigners();
const verifier = owner.address;
const OperatorAllowlist = await hre.ethers.getContractFactory("OperatorAllowlist");
const operatorAllowlist = await OperatorAllowlist.deploy(owner.address);
const CFFT = await hre.ethers.getContractFactory("ImmutableERC20MinterBurnerPermit");
const ft = await CFFT.deploy(owner.address, owner.address, owner.address, "test usdc", "usdc", '100000000000000000000000000');
await ft.grantMinterRole(owner.address);
const amount = '10000000000000000000000';
await ft.mint(owner.address, amount);
const TokenClaim = await hre.ethers.getContractFactory("TokenClaim");
const claimer = await TokenClaim.deploy( verifier, ft.target, verifier, 3600);
// @ts-ignore
await ft.connect(owner).approve(claimer.target, amount);
const chainId = hre.network.config.chainId
await operatorAllowlist.grantRegistrarRole(owner.address)
await operatorAllowlist.addAddressToAllowlist([claimer.target])
return { claimer, owner, otherAccount, verifier, ft, chainId };
}
describe("Deployment", function () {
it('should deploy TokenClaim with the correct verifier', async function() {
const { claimer, verifier } = await loadFixture(deployOneContract);
expect(await claimer.verifier()).to.equal(verifier);
});
it('should deploy TokenClaim with the correct FT address', async function() {
const { claimer, ft, owner } = await loadFixture(deployOneContract);
expect(await claimer.erc20Wallets(ft.target)).to.equal(owner.address);
});
})
describe("Claim", function () {
it('should claim token success', async function() {
const { claimer, ft, owner, chainId, otherAccount } = await loadFixture(deployOneContract);
const amount = 100;
const nonce = (Math.random() * 1000) | 0;
const now = (Date.now() / 1000) | 0;
const bit = 1;
let localMsgHash = solidityPackedKeccak256(["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, ft.target, claimer.target, chainId, amount, bit, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
const vals = [amount, bit, now, nonce];
// @ts-ignore
await expect(claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature))
.to.emit(claimer, "EventTokenClaimed")
.withArgs(otherAccount.address, ft.target, otherAccount.address, amount, bit);
expect(await ft.balanceOf(otherAccount.address)).to.equal(amount);
});
it('should revert claim token for signature used', async function() {
const { claimer, ft, owner, chainId, otherAccount } = await loadFixture(deployOneContract);
const amount = 100;
const nonce = (Math.random() * 1000) | 0;
const now = (Date.now() / 1000) | 0;
const bit = 1;
let localMsgHash = solidityPackedKeccak256(["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, ft.target, claimer.target, chainId, amount, bit, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
const vals = [amount, bit, now, nonce];
//@ts-ignore
await claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature)
// @ts-ignore
await expect(claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature)).to.be.revertedWith("signature used. please send another transaction with new signature");
});
it('should revert claim token for timeout', async function() {
const { claimer, ft, owner, chainId, otherAccount } = await loadFixture(deployOneContract);
const amount = 100;
// @ts-ignore
// await ft.connect(owner).approve(claimer.target, '10000000000000000000000');
const nonce = (Math.random() * 1000) | 0;
const now = (Date.now() / 1000 - 3601) | 0;
const bit = 1;
let localMsgHash = solidityPackedKeccak256(["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, ft.target, claimer.target, chainId, amount, bit, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
const vals = [amount, bit, now, nonce];
// @ts-ignore
await expect(claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature)).to.be.revertedWith("expired, please send another transaction with new signature");
});
it('should revert claim token for token not support', async function() {
const { claimer, ft, owner, chainId, otherAccount } = await loadFixture(deployOneContract);
await claimer.updateERC20Wallet(ft.target, '0x0000000000000000000000000000000000000000');
const amount = 100;
const nonce = (Math.random() * 1000) | 0;
const now = (Date.now() / 1000) | 0;
const bit = 1;
let localMsgHash = solidityPackedKeccak256(["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, ft.target, claimer.target, chainId, amount, bit, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
const vals = [amount, bit, now, nonce];
// @ts-ignore
await expect(claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature)).to.be.revertedWith("TokenClaim: token is not supported");
});
it('should revert claim token for condition check failed', async function() {
const { claimer, ft, owner, chainId, otherAccount } = await loadFixture(deployOneContract);
const amount = 100;
const nonce = (Math.random() * 1000) | 0;
const now = (Date.now() / 1000) | 0;
let bit = 1;
let localMsgHash = solidityPackedKeccak256(["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, ft.target, claimer.target, chainId, amount, bit, now, nonce]);
let signature = await owner.signMessage(getBytes(localMsgHash));
let vals = [amount, bit, now, nonce];
// @ts-ignore
await claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature)
bit = 1 << 2 ;
localMsgHash = solidityPackedKeccak256(["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, ft.target, claimer.target, chainId, amount, bit, now, nonce]);
signature = await owner.signMessage(getBytes(localMsgHash));
vals = [amount, bit, now, nonce];
// @ts-ignore
await claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature)
bit = 1 | 1 << 2 ;
localMsgHash = solidityPackedKeccak256(["address","address", "address", "address", "uint256","uint256", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, ft.target, claimer.target, chainId, amount, bit, now, nonce]);
signature = await owner.signMessage(getBytes(localMsgHash));
vals = [amount, bit, now, nonce];
// @ts-ignore
await expect(claimer.connect(otherAccount).claim(otherAccount.address, ft.target, vals, signature)).to.be.revertedWith("TokenClaim: condition check failed");
});
})
})