|
| 1 | +import { deployments, ethers, getNamedAccounts, network } from "hardhat"; |
| 2 | +import { toBigInt, BigNumberish, Addressable } from "ethers"; |
| 3 | +import { PNK, KlerosCore, SortitionModule, IncrementalNG, DisputeKitGated } from "../../typechain-types"; |
| 4 | +import { expect } from "chai"; |
| 5 | +import { Courts } from "../../deploy/utils"; |
| 6 | +import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers"; |
| 7 | + |
| 8 | +/* eslint-disable no-unused-vars */ |
| 9 | +/* eslint-disable no-unused-expressions */ // https://github.com/standard/standard/issues/690#issuecomment-278533482 |
| 10 | + |
| 11 | +describe("DisputeKitGated", async () => { |
| 12 | + const ONE_THOUSAND_PNK = 10n ** 21n; |
| 13 | + const thousandPNK = (amount: BigNumberish) => toBigInt(amount) * ONE_THOUSAND_PNK; |
| 14 | + |
| 15 | + let deployer: string; |
| 16 | + let juror1: HardhatEthersSigner; |
| 17 | + let juror2: HardhatEthersSigner; |
| 18 | + let disputeKitGated: DisputeKitGated; |
| 19 | + let pnk: PNK; |
| 20 | + let core: KlerosCore; |
| 21 | + let sortitionModule: SortitionModule; |
| 22 | + let rng: IncrementalNG; |
| 23 | + const RANDOM = 424242n; |
| 24 | + |
| 25 | + beforeEach("Setup", async () => { |
| 26 | + ({ deployer } = await getNamedAccounts()); |
| 27 | + [, juror1, juror2] = await ethers.getSigners(); |
| 28 | + |
| 29 | + await deployments.fixture(["Arbitration", "VeaMock"], { |
| 30 | + fallbackToGlobal: true, |
| 31 | + keepExistingDeployments: false, |
| 32 | + }); |
| 33 | + disputeKitGated = (await ethers.getContract("DisputeKitGated")) as DisputeKitGated; |
| 34 | + pnk = (await ethers.getContract("PNK")) as PNK; |
| 35 | + core = (await ethers.getContract("KlerosCore")) as KlerosCore; |
| 36 | + sortitionModule = (await ethers.getContract("SortitionModule")) as SortitionModule; |
| 37 | + |
| 38 | + // Make the tests more deterministic with this dummy RNG |
| 39 | + await deployments.deploy("IncrementalNG", { |
| 40 | + from: deployer, |
| 41 | + args: [RANDOM], |
| 42 | + log: true, |
| 43 | + }); |
| 44 | + rng = (await ethers.getContract("IncrementalNG")) as IncrementalNG; |
| 45 | + |
| 46 | + await sortitionModule.changeRandomNumberGenerator(rng.target, 20).then((tx) => tx.wait()); |
| 47 | + }); |
| 48 | + |
| 49 | + const encodeExtraData = ( |
| 50 | + courtId: number, |
| 51 | + minJurors: number, |
| 52 | + disputeKitId: number, |
| 53 | + tokenGate: string | Addressable, |
| 54 | + isERC1155: boolean, |
| 55 | + tokenId: BigNumberish |
| 56 | + ) => { |
| 57 | + // Packing of tokenGate and isERC1155 |
| 58 | + // uint88 (padding 11 bytes) + bool (1 byte) + address (20 bytes) = 32 bytes |
| 59 | + const packed = ethers.solidityPacked(["uint88", "bool", "address"], [0, isERC1155, tokenGate]); |
| 60 | + return ethers.AbiCoder.defaultAbiCoder().encode( |
| 61 | + ["uint256", "uint256", "uint256", "bytes32", "uint256"], |
| 62 | + [courtId, minJurors, disputeKitId, packed, tokenId] |
| 63 | + ); |
| 64 | + }; |
| 65 | + |
| 66 | + const stakeAndDraw = async ( |
| 67 | + courtId: number, |
| 68 | + minJurors: number, |
| 69 | + disputeKitId: number, |
| 70 | + tokenGate: string | Addressable, |
| 71 | + isERC1155: boolean, |
| 72 | + tokenId: BigNumberish |
| 73 | + ) => { |
| 74 | + // Stake jurors |
| 75 | + for (const juror of [juror1, juror2]) { |
| 76 | + await pnk.transfer(juror.address, thousandPNK(10)).then((tx) => tx.wait()); |
| 77 | + expect(await pnk.balanceOf(juror.address)).to.equal(thousandPNK(10)); |
| 78 | + |
| 79 | + await pnk |
| 80 | + .connect(juror) |
| 81 | + .approve(core.target, thousandPNK(10), { gasLimit: 300000 }) |
| 82 | + .then((tx) => tx.wait()); |
| 83 | + |
| 84 | + await core |
| 85 | + .connect(juror) |
| 86 | + .setStake(Courts.GENERAL, thousandPNK(10), { gasLimit: 300000 }) |
| 87 | + .then((tx) => tx.wait()); |
| 88 | + |
| 89 | + expect(await sortitionModule.getJurorBalance(juror.address, 1)).to.deep.equal([ |
| 90 | + thousandPNK(10), // totalStaked |
| 91 | + 0, // totalLocked |
| 92 | + thousandPNK(10), // stakedInCourt |
| 93 | + 1, // nbOfCourts |
| 94 | + ]); |
| 95 | + } |
| 96 | + |
| 97 | + const extraData = encodeExtraData(courtId, minJurors, disputeKitId, tokenGate, isERC1155, tokenId); |
| 98 | + console.log("extraData", extraData); |
| 99 | + |
| 100 | + const tokenInfo = await disputeKitGated.extraDataToTokenInfo(extraData); |
| 101 | + expect(tokenInfo[0]).to.equal(pnk.target); |
| 102 | + expect(tokenInfo[1]).to.equal(false); |
| 103 | + expect(tokenInfo[2]).to.equal(0); |
| 104 | + |
| 105 | + const arbitrationCost = await core["arbitrationCost(bytes)"](extraData); |
| 106 | + |
| 107 | + // Warning: this dispute cannot be executed, in reality it should be created by an arbitrable contract, not an EOA. |
| 108 | + const tx = await core["createDispute(uint256,bytes)"](2, extraData, { value: arbitrationCost }).then((tx) => |
| 109 | + tx.wait() |
| 110 | + ); |
| 111 | + const disputeId = 0; |
| 112 | + // console.log(tx?.logs); |
| 113 | + |
| 114 | + await network.provider.send("evm_increaseTime", [2000]); // Wait for minStakingTime |
| 115 | + await network.provider.send("evm_mine"); |
| 116 | + await sortitionModule.passPhase().then((tx) => tx.wait()); // Staking -> Generating |
| 117 | + |
| 118 | + const lookahead = await sortitionModule.rngLookahead(); |
| 119 | + for (let index = 0; index < lookahead; index++) { |
| 120 | + await network.provider.send("evm_mine"); |
| 121 | + } |
| 122 | + |
| 123 | + await sortitionModule.passPhase().then((tx) => tx.wait()); // Generating -> Drawing |
| 124 | + return core.draw(disputeId, 20, { gasLimit: 1000000 }); |
| 125 | + }; |
| 126 | + |
| 127 | + describe("When gating with PNK token", async () => { |
| 128 | + it("Should draw all the jurors successfully", async () => { |
| 129 | + await stakeAndDraw(Courts.GENERAL, 3, 3, pnk.target, false, 0); |
| 130 | + // TODO: expect.... |
| 131 | + }); |
| 132 | + }); |
| 133 | +}); |
0 commit comments