From 7d0cdcf4fb111c1f4c2aa986cd4e75ce919dc5ba Mon Sep 17 00:00:00 2001 From: tommyrharper Date: Sat, 2 Dec 2023 18:18:08 +0000 Subject: [PATCH 1/5] test: add TokenVesting tests --- test/TokenVesting.test.ts | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/TokenVesting.test.ts diff --git a/test/TokenVesting.test.ts b/test/TokenVesting.test.ts new file mode 100644 index 0000000..af42844 --- /dev/null +++ b/test/TokenVesting.test.ts @@ -0,0 +1,44 @@ +import { ethers, network } from "hardhat" +import { expect } from "chai" +import { duration, increase } from "./utilities" + +const ONE_WEEK = 604800 + +const CLIFF_LENGTH = ONE_WEEK +const DURATION = 2 * ONE_WEEK + +describe.only("TokenVesting", function () { + let blockTimestamp + + before(async function () { + this.signers = await ethers.getSigners() + this.alice = this.signers[0] + + this.JoeToken = await ethers.getContractFactory("JoeToken") + this.TokenVesting = await ethers.getContractFactory("TokenVesting") + }) + + beforeEach(async function () { + blockTimestamp = (await ethers.provider.getBlock("latest")).timestamp + this.joe = await this.JoeToken.deploy() + this.tokenVesting = await this.TokenVesting.deploy(this.alice.address, blockTimestamp, CLIFF_LENGTH, DURATION, true) + this.joe.mint(this.tokenVesting.address, 100) + }) + + it("should only allow release of tokens once cliff is passed", async function () { + await expect(this.tokenVesting.release(this.joe.address)).to.be.revertedWith("TokenVesting: no tokens are due") + await increase(duration.days(6)) + await expect(this.tokenVesting.release(this.joe.address)).to.be.revertedWith("TokenVesting: no tokens are due") + await increase(duration.days(1)) + await this.tokenVesting.release(this.joe.address) + expect(await this.joe.balanceOf(this.alice.address)).to.gt(0) + expect(await this.joe.balanceOf(this.tokenVesting.address)).to.lt(100) + }) + + after(async function () { + await network.provider.request({ + method: "hardhat_reset", + params: [], + }) + }) +}) From 33bd1e9bb5191c90b2869ab484c890dd022cf2d0 Mon Sep 17 00:00:00 2001 From: tommyrharper Date: Sat, 2 Dec 2023 18:18:57 +0000 Subject: [PATCH 2/5] test: full vesting of TokenVesting --- test/TokenVesting.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/TokenVesting.test.ts b/test/TokenVesting.test.ts index af42844..f4861c5 100644 --- a/test/TokenVesting.test.ts +++ b/test/TokenVesting.test.ts @@ -35,6 +35,13 @@ describe.only("TokenVesting", function () { expect(await this.joe.balanceOf(this.tokenVesting.address)).to.lt(100) }) + it("should allow all tokens to be vested once all time has passed", async function() { + await increase(duration.days(14)) + await this.tokenVesting.release(this.joe.address) + expect(await this.joe.balanceOf(this.alice.address)).to.equal(100) + expect(await this.joe.balanceOf(this.tokenVesting.address)).to.equal(0) + }) + after(async function () { await network.provider.request({ method: "hardhat_reset", From 780a9ddd43f1a9ce5f54735ec7a63b8a27f7b9a0 Mon Sep 17 00:00:00 2001 From: tommyrharper Date: Sat, 2 Dec 2023 18:40:56 +0000 Subject: [PATCH 3/5] test: can revoke tokens immediately --- test/TokenVesting.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/TokenVesting.test.ts b/test/TokenVesting.test.ts index f4861c5..330ef27 100644 --- a/test/TokenVesting.test.ts +++ b/test/TokenVesting.test.ts @@ -13,6 +13,7 @@ describe.only("TokenVesting", function () { before(async function () { this.signers = await ethers.getSigners() this.alice = this.signers[0] + this.rando = this.signers[1] this.JoeToken = await ethers.getContractFactory("JoeToken") this.TokenVesting = await ethers.getContractFactory("TokenVesting") @@ -42,6 +43,13 @@ describe.only("TokenVesting", function () { expect(await this.joe.balanceOf(this.tokenVesting.address)).to.equal(0) }) + it("can revoke tokens immediately", async function() { + await this.tokenVesting.revoke(this.joe.address); + await increase(duration.days(14)); + await expect(this.tokenVesting.release(this.joe.address)).to.be.revertedWith("TokenVesting: no tokens are due") + + }); + after(async function () { await network.provider.request({ method: "hardhat_reset", From e828cb8a680c6bd72d8e53e97b434b84ffdd11a7 Mon Sep 17 00:00:00 2001 From: tommyrharper Date: Sat, 2 Dec 2023 18:43:02 +0000 Subject: [PATCH 4/5] test: revoking leaves some tokens vestable --- test/TokenVesting.test.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/test/TokenVesting.test.ts b/test/TokenVesting.test.ts index 330ef27..e0cee25 100644 --- a/test/TokenVesting.test.ts +++ b/test/TokenVesting.test.ts @@ -36,19 +36,30 @@ describe.only("TokenVesting", function () { expect(await this.joe.balanceOf(this.tokenVesting.address)).to.lt(100) }) - it("should allow all tokens to be vested once all time has passed", async function() { + it("should allow all tokens to be vested once all time has passed", async function () { await increase(duration.days(14)) await this.tokenVesting.release(this.joe.address) expect(await this.joe.balanceOf(this.alice.address)).to.equal(100) expect(await this.joe.balanceOf(this.tokenVesting.address)).to.equal(0) }) - it("can revoke tokens immediately", async function() { - await this.tokenVesting.revoke(this.joe.address); - await increase(duration.days(14)); + it("can revoke tokens immediately", async function () { + await this.tokenVesting.revoke(this.joe.address) + await increase(duration.days(14)) await expect(this.tokenVesting.release(this.joe.address)).to.be.revertedWith("TokenVesting: no tokens are due") + }) - }); + it("revoking leaves some tokens vestable", async function () { + await increase(duration.days(10)) + await this.tokenVesting.revoke(this.joe.address) + await this.tokenVesting.release(this.joe.address) + + expect(await this.joe.balanceOf(this.alice.address)).to.gt(0) + expect(await this.joe.balanceOf(this.tokenVesting.address)).to.lt(100) + + await increase(duration.days(7)) + await expect(this.tokenVesting.release(this.joe.address)).to.be.revertedWith("TokenVesting: no tokens are due") + }) after(async function () { await network.provider.request({ From 53f37b04b41d5c987eddb34f0c18d77a51d31acd Mon Sep 17 00:00:00 2001 From: tommyrharper Date: Sat, 2 Dec 2023 18:43:50 +0000 Subject: [PATCH 5/5] test: emergency revoking leaves no tokens vestable --- test/TokenVesting.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/TokenVesting.test.ts b/test/TokenVesting.test.ts index e0cee25..ec92526 100644 --- a/test/TokenVesting.test.ts +++ b/test/TokenVesting.test.ts @@ -61,6 +61,12 @@ describe.only("TokenVesting", function () { await expect(this.tokenVesting.release(this.joe.address)).to.be.revertedWith("TokenVesting: no tokens are due") }) + it("emergency revoking leaves no tokens vestable", async function () { + await increase(duration.days(10)) + await this.tokenVesting.emergencyRevoke(this.joe.address) + await expect(this.tokenVesting.release(this.joe.address)).to.be.revertedWith("TokenVesting: no tokens are due") + }) + after(async function () { await network.provider.request({ method: "hardhat_reset",