141 lines
7.7 KiB
TypeScript
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");
|
|
});
|
|
})
|
|
})
|