import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers" ; import { expect } from "chai" ; import { Contract } from "ethers" ; import { ethers } from "hardhat" ; import MerkleTree from "merkletreejs" ; import { generateMerkleTree , getProof } from "../lib/proof" ; const contractName = "DevCoin" ; describe ( `${ contractName } Airdrop` , ( ) => { let dc ; let tree ; let goodAddresses ; let goodSigners ; let badSigners ; let treasury ; let owner ; let airdropSupply ; let airdropSize ; let CAP ; beforeEach ( async ( ) => { const signers = await ethers . getSigners ( ) ; owner = signers . shift ( ) ! ; treasury = signers . shift ( ) ! ; goodSigners = signers . slice ( 0 , 5 ) ; goodAddresses = goodSigners . map ( ( s ) => s . address ) ; badSigners = signers . slice ( 5 ) ; const DevCoin = await ethers . getContractFactory ( contractName ) ; dc = await DevCoin . deploy ( await treasury . getAddress ( ) ) ; await dc . deployed ( ) ; CAP = BigInt ( await dc . cap ( ) ) ; treasury = await dc . getTreasuryAddress ( ) ; airdropSupply = BigInt ( await dc . getAirdropSupply ( ) ) ; airdropSize = BigInt ( await dc . getAirdropSize ( ) ) ; tree = generateMerkleTree ( goodAddresses ) ; const merkleRoot = tree . getHexRoot ( ) ; const setRootTx = await dc . setMerkleRoot ( merkleRoot ) ; await setRootTx . wait ( ) ; expect ( await dc . merkleRoot ( ) ) . to . equal ( merkleRoot ) ; } ) ; it ( "Contains remaining tokens in the treasury" , async function ( ) { expect ( await dc . balanceOf ( treasury ) ) . to . equal ( CAP - airdropSupply ) ; } ) ; it ( "Has total supply equal to cap" , async function ( ) { expect ( await dc . totalSupply ( ) ) . to . equal ( CAP ) ; } ) ; it ( "Allows claiming with valid proofs" , async function ( ) { const goodSigner = goodSigners [ 1 ] ; const goodAddress = goodSigner . address ; const goodProof = getProof ( tree , goodAddress ) ; const claimTx = await dc . connect ( goodSigner ) . claim ( goodProof ) ; await claimTx . wait ( ) ; const goodBalance = await dc . connect ( goodSigner ) . myBalance ( ) ; expect ( goodBalance ) . to . equal ( airdropSize ) ; expect ( await dc . balanceOf ( dc . address ) ) . to . equal ( airdropSupply - airdropSize ) ; expect ( dc . connect ( goodSigner ) . claim ( goodProof ) ) . to . be . revertedWith ( "DEV: Already claimed airdrop" ) ; const badSigner = badSigners [ 0 ] ; expect ( dc . connect ( badSigner ) . claim ( goodProof ) ) . to . be . revertedWith ( "DEV: Not holder of prestigious NFT" ) ; expect ( await dc . totalSupply ( ) ) . to . equal ( CAP ) ; } ) ; it ( "sweeps unclaimed amount" , async function ( ) { const goodSigner = goodSigners [ 2 ] ; const goodAddress = goodSigner . address ; const goodProof = getProof ( tree , goodAddress ) ; const claimTx = await dc . connect ( goodSigner ) . claim ( goodProof ) ; await claimTx . wait ( ) ; await dc . sweep ( ) ; expect ( await dc . balanceOf ( treasury ) ) . to . equal ( CAP - airdropSize ) ; expect ( await dc . balanceOf ( dc . address ) ) . to . equal ( 0 ) ; } ) ; } ) ;