DCIPs/assets/eip-5725/test/VestingNFT.test.ts

176 lines
5.7 KiB
TypeScript

import { ethers } from 'hardhat'
import { Signer } from 'ethers'
import { expect } from 'chai'
import { increaseTime } from './helpers/time'
// typechain
import { ERC20Mock, VestingNFT } from '../typechain-types'
const testValues = {
payout: '1000000000',
lockTime: 60,
}
describe('VestingNFT', function () {
let accounts: Signer[]
let vestingNFT: VestingNFT
let mockToken: ERC20Mock
let receiverAccount: string
let unlockTime: number
beforeEach(async function () {
const VestingNFT = await ethers.getContractFactory('VestingNFT')
vestingNFT = await VestingNFT.deploy('VestingNFT', 'TLV')
await vestingNFT.deployed()
const ERC20Mock = await ethers.getContractFactory('ERC20Mock')
mockToken = await ERC20Mock.deploy(
'1000000000000000000000',
18,
'LockedToken',
'LOCK'
)
await mockToken.deployed()
await mockToken.approve(vestingNFT.address, '1000000000000000000000')
accounts = await ethers.getSigners()
receiverAccount = await accounts[1].getAddress()
unlockTime = await createVestingNft(vestingNFT, receiverAccount, mockToken)
})
it('Supports ERC721 and IERC5725 interfaces', async function () {
expect(await vestingNFT.supportsInterface('0x80ac58cd')).to.equal(true)
/**
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified
* // Solidity export interface id:
* bytes4 public constant IID_ITEST = type(IERC5725).interfaceId;
* // Pull out the interfaceId in tests
* const interfaceId = await vestingNFT.IID_ITEST();
*/
// Vesting NFT Interface ID
expect(await vestingNFT.supportsInterface('0xf8600f8b')).to.equal(true)
})
it('Returns a valid vested payout', async function () {
const totalPayout = await vestingNFT.vestedPayoutAtTime(0, unlockTime)
expect(await vestingNFT.vestedPayout(0)).to.equal(0)
await increaseTime(testValues.lockTime)
expect(await vestingNFT.vestedPayout(0)).to.equal(totalPayout)
})
it('Reverts with invalid ID', async function () {
await expect(vestingNFT.vestedPayout(1)).to.revertedWith(
'VestingNFT: invalid token ID'
)
await expect(vestingNFT.vestedPayoutAtTime(1, unlockTime)).to.revertedWith(
'VestingNFT: invalid token ID'
)
await expect(vestingNFT.vestingPayout(1)).to.revertedWith(
'VestingNFT: invalid token ID'
)
await expect(vestingNFT.claimablePayout(1)).to.revertedWith(
'VestingNFT: invalid token ID'
)
await expect(vestingNFT.vestingPeriod(1)).to.revertedWith(
'VestingNFT: invalid token ID'
)
await expect(vestingNFT.payoutToken(1)).to.revertedWith(
'VestingNFT: invalid token ID'
)
await expect(vestingNFT.claim(1)).to.revertedWith(
'VestingNFT: invalid token ID'
)
// NOTE: Removed claimTo from spec
// await expect(vestingNFT.claimTo(1, receiverAccount)).to.revertedWith(
// "VestingNFT: invalid token ID"
// );
})
it('Returns a valid pending payout', async function () {
expect(await vestingNFT.vestingPayout(0)).to.equal(testValues.payout)
})
it('Returns a valid releasable payout', async function () {
const totalPayout = await vestingNFT.vestedPayoutAtTime(0, unlockTime)
expect(await vestingNFT.claimablePayout(0)).to.equal(0)
await increaseTime(testValues.lockTime)
expect(await vestingNFT.claimablePayout(0)).to.equal(totalPayout)
})
it('Returns a valid vesting period', async function () {
const vestingPeriod = await vestingNFT.vestingPeriod(0)
expect(vestingPeriod.vestingEnd).to.equal(unlockTime)
})
it('Returns a valid payout token', async function () {
expect(await vestingNFT.payoutToken(0)).to.equal(mockToken.address)
})
it('Is able to claim', async function () {
const connectedVestingNft = vestingNFT.connect(accounts[1])
await increaseTime(testValues.lockTime)
const txReceipt = await connectedVestingNft.claim(0)
await txReceipt.wait()
expect(await mockToken.balanceOf(receiverAccount)).to.equal(
testValues.payout
)
})
it('Reverts claim when payout is 0', async function () {
const connectedVestingNft = vestingNFT.connect(accounts[1])
await expect(connectedVestingNft.claim(0)).to.revertedWith(
'VestingNFT: No pending payout'
)
})
it('Reverts claim when payout is not from owner', async function () {
const connectedVestingNft = vestingNFT.connect(accounts[2])
await expect(connectedVestingNft.claim(0)).to.revertedWith(
'Not owner of NFT'
)
})
// NOTE: Removed claimTo from spec
// it("Is able to claim to other account", async function () {
// const connectedVestingNft = vestingNFT.connect(accounts[1]);
// const otherReceiverAddress = await accounts[2].getAddress();
// await increaseTime(testValues.lockTime);
// const txReceipt = await connectedVestingNft.claimTo(
// 0,
// otherReceiverAddress
// );
// await txReceipt.wait();
// expect(await mockToken.balanceOf(otherReceiverAddress)).to.equal(
// testValues.payout
// );
// });
it('Reverts when creating to account 0', async function () {
await expect(
vestingNFT.create(
'0x0000000000000000000000000000000000000000',
testValues.payout,
unlockTime,
mockToken.address
)
).to.revertedWith('to cannot be address 0')
})
})
async function createVestingNft(
vestingNFT: VestingNFT,
receiverAccount: string,
mockToken: ERC20Mock
) {
const latestBlock = await ethers.provider.getBlock('latest')
const unlockTime = latestBlock.timestamp + testValues.lockTime
const txReceipt = await vestingNFT.create(
receiverAccount,
testValues.payout,
unlockTime,
mockToken.address
)
await txReceipt.wait()
return unlockTime
}