contracts-imtbl/test/testGameItemMall.ts
2024-07-24 16:10:39 +08:00

149 lines
7.1 KiB
TypeScript

import { expect } from 'chai'
import hre from "hardhat";
import {
getBytes,
solidityPackedKeccak256,
} from 'ethers'
import {
loadFixture,
} from "@nomicfoundation/hardhat-toolbox/network-helpers";
describe('GameItemMall', 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);
await ft.mint(otherAccount.address, '1000');
const GameItemMall = await hre.ethers.getContractFactory("GameItemMall");
const mall = await GameItemMall.deploy( ft.target, verifier, verifier, 3600);
const chainId = hre.network.config.chainId
await operatorAllowlist.grantRegistrarRole(owner.address)
await operatorAllowlist.addAddressToAllowlist([mall.target])
return { mall, owner, otherAccount, verifier, ft, chainId };
}
describe("Deployment", function () {
it('should deploy GameIteMall with the correct verifier', async function() {
const { mall, verifier } = await loadFixture(deployOneContract);
expect(await mall.verifier()).to.equal(verifier);
});
it('should deploy GameItemMall with the correct FT address', async function() {
const { mall, ft } = await loadFixture(deployOneContract);
expect(await mall.erc20Supported(ft.target)).to.equal(true);
});
})
describe("buy", function () {
it('should buy item success', async function() {
const { mall, ft, otherAccount, owner, chainId } = await loadFixture(deployOneContract);
const amount = 100;
// @ts-ignore
await ft.connect(otherAccount).approve(mall.target, amount);
const nonce = (Math.random() * 1000) | 0;
const now = Date.now() / 1000 | 0;
const orderId = '100000001'
/**
function getMessageHash(
address _buyer,
address _passport,
uint256 _orderId,
address _currency,
uint256 _amount,
address _contract,
uint256 _chainId,
uint256 _signTime,
uint256 _saltNonce
)
*/
let localMsgHash = solidityPackedKeccak256(["address","address", "uint256", "address", "uint256", "address", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, orderId, ft.target, amount, mall.target, chainId, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
/**
* function buy(
address passport,
uint256 orderId,
address currency,
uint256 amount,
uint256 signTime,
uint256 saltNonce,
bytes calldata signature
)
*/
//@ts-ignore
await expect(mall.connect(otherAccount).buy(otherAccount.address, orderId, ft.target, amount, now, nonce, signature))
.to.emit(mall, "ItemSoldOut")
.withArgs(otherAccount.address, otherAccount.address, orderId, ft.target, amount);
expect(await ft.balanceOf(otherAccount.address)).to.equal(900);
});
it('should revert buy item for signature error', async function() {
const { mall, ft, otherAccount, owner, chainId } = await loadFixture(deployOneContract);
const amount = 100;
// @ts-ignore
await ft.connect(otherAccount).approve(mall.target, amount);
const nonce = (Math.random() * 1000) | 0;
const now = Date.now() / 1000 | 0;
const orderId = '100000001'
let localMsgHash = solidityPackedKeccak256(["address","address", "uint256", "address", "uint256", "address", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, orderId, ft.target, amount, mall.target, chainId, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
//@ts-ignore
await expect(mall.connect(otherAccount).buy(otherAccount.address, orderId, ft.target, amount + 1, now, nonce, signature)).to.be.revertedWith("invalid signature");
});
it('should revert buy item for not approval', async function() {
const { mall, ft, otherAccount, owner, chainId } = await loadFixture(deployOneContract);
const amount = 100;
const nonce = (Math.random() * 1000) | 0;
const now = Date.now() / 1000 | 0;
const orderId = '100000001'
let localMsgHash = solidityPackedKeccak256(["address","address", "uint256", "address", "uint256", "address", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, orderId, ft.target, amount, mall.target, chainId, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
//@ts-ignore
await expect(mall.connect(otherAccount).buy(otherAccount.address, orderId, ft.target, amount, now, nonce, signature)).to.be.revertedWith("ERC20: insufficient allowance");
});
it('should revert buy item for signature used', async function() {
const { mall, ft, otherAccount, owner, chainId } = await loadFixture(deployOneContract);
const amount = 100;
// @ts-ignore
await ft.connect(otherAccount).approve(mall.target, amount);
const nonce = (Math.random() * 1000) | 0;
const now = Date.now() / 1000 | 0;
const orderId = '100000001'
let localMsgHash = solidityPackedKeccak256(["address","address", "uint256", "address", "uint256", "address", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, orderId, ft.target, amount, mall.target, chainId, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
//@ts-ignore
await mall.connect(otherAccount).buy(otherAccount.address, orderId, ft.target, amount, now, nonce, signature)
//@ts-ignore
await expect(mall.connect(otherAccount).buy(otherAccount.address, orderId, ft.target, amount, now, nonce, signature)).to.be.revertedWith("signature used. please send another transaction with new signature");
});
it('should revert buy item for unsupport currency', async function() {
const { mall, ft, otherAccount, owner, chainId } = await loadFixture(deployOneContract);
const amount = 100;
// @ts-ignore
await ft.connect(otherAccount).approve(mall.target, amount);
const nonce = (Math.random() * 1000) | 0;
const now = Date.now() / 1000 | 0;
const orderId = '100000001'
await mall.removeERC20Support(ft.target);
let localMsgHash = solidityPackedKeccak256(["address","address", "uint256", "address", "uint256", "address", "uint256", "uint256", "uint256"],
[otherAccount.address, otherAccount.address, orderId, ft.target, amount, mall.target, chainId, now, nonce]);
const signature = await owner.signMessage(getBytes(localMsgHash));
//@ts-ignore
await expect(mall.connect(otherAccount).buy(otherAccount.address, orderId, ft.target, amount, now, nonce, signature)).to.be.revertedWith("currency is not supported");
});
})
})