From 0fb1b328f731d69e90ccdeb1db48dad73c4724aa Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Fri, 30 Jul 2021 19:27:53 +0200 Subject: [PATCH] Added validation of TokenGrant.initialize parameters --- contracts/grant/TokenGrant.sol | 12 ++- test/grant/TokenGrant.test.js | 156 +++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 2 deletions(-) diff --git a/contracts/grant/TokenGrant.sol b/contracts/grant/TokenGrant.sol index e49fbb33..27c335c3 100644 --- a/contracts/grant/TokenGrant.sol +++ b/contracts/grant/TokenGrant.sol @@ -14,7 +14,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /// according to the provided staking policy. contract TokenGrant { // TODO Not implemented yet: - // TODO - TokenGrantFactory, master clone factory TokenGrant contract + // TODO - TokenGrantFactory, master clone factory TokenGrant contract // TODO initialization prevention. // TODO - Staking, including checking the policy, allowed staking // TODO contracts, and calling the staking contract. @@ -54,7 +54,15 @@ contract TokenGrant { uint256 _start, uint256 _cliff, IGrantStakingPolicy _stakingPolicy - ) public { + ) external { + require(address(_token) != address(0), "Token must not be 0x0"); + require(_grantee != address(0), "Grantee must not be 0x0"); + require(_amount != 0, "Amount must not be 0"); + require(_duration != 0, "Duration must not be 0"); + require(_start != 0, "Start timestamp must not be 0"); + require(_cliff != 0, "Cliff timestamp must not be 0"); + // TODO: validate staking policy is not 0x0 + token = _token; grantee = _grantee; revocable = _revocable; diff --git a/test/grant/TokenGrant.test.js b/test/grant/TokenGrant.test.js index 5688e8f8..5536cc83 100644 --- a/test/grant/TokenGrant.test.js +++ b/test/grant/TokenGrant.test.js @@ -19,6 +19,162 @@ describe("TokenGrant", () => { await token.deployed() }) + describe("initialize", () => { + const revocable = true + const amount = to1e18(120000) // 120k tokens + const duration = 15552000 // 180 days + let start + let cliff + const stakingPolicy = ZERO_ADDRESS + + let tokenGrant + + beforeEach(async () => { + now = await lastBlockTime() + start = now + cliff = now + + const TokenGrant = await ethers.getContractFactory("TokenGrant") + tokenGrant = await TokenGrant.deploy() + tokenGrant.deployed() + }) + + context("when token is zero address", () => { + it("should revert", async () => { + await expect( + tokenGrant.initialize( + ZERO_ADDRESS, + grantee.address, + revocable, + amount, + duration, + start, + cliff, + stakingPolicy + ) + ).to.be.revertedWith("Token must not be 0x0") + }) + }) + + context("when grantee is zero address", () => { + it("should revert", async () => { + await expect( + tokenGrant.initialize( + token.address, + ZERO_ADDRESS, + revocable, + amount, + duration, + start, + cliff, + stakingPolicy + ) + ).to.be.revertedWith("Grantee must not be 0x0") + }) + }) + + context("when amount is 0", () => { + it("should revert", async () => { + await expect( + tokenGrant.initialize( + token.address, + grantee.address, + revocable, + 0, + duration, + start, + cliff, + stakingPolicy + ) + ).to.be.revertedWith("Amount must not be 0") + }) + }) + + context("when duration is 0", () => { + it("should revert", async () => { + await expect( + tokenGrant.initialize( + token.address, + grantee.address, + revocable, + amount, + 0, + start, + cliff, + stakingPolicy + ) + ).to.be.revertedWith("Duration must not be 0") + }) + }) + + context("when start is 0", () => { + it("should revert", async () => { + await expect( + tokenGrant.initialize( + token.address, + grantee.address, + revocable, + amount, + duration, + 0, + cliff, + stakingPolicy + ) + ).to.be.revertedWith("Start timestamp must not be 0") + }) + }) + + context("when cliff is 0", () => { + it("should revert", async () => { + await expect( + tokenGrant.initialize( + token.address, + grantee.address, + revocable, + amount, + duration, + start, + 0, + stakingPolicy + ) + ).to.be.revertedWith("Cliff timestamp must not be 0") + }) + }) + + context("when all parameters are valid", () => { + const amount = to1e18(41211) + + beforeEach(async () => { + await token.connect(deployer).mint(deployer.address, amount) + await token.connect(deployer).approve(tokenGrant.address, amount) + + await tokenGrant.initialize( + token.address, + grantee.address, + revocable, + amount, + duration, + start, + cliff, + ZERO_ADDRESS + ) + }) + + it("should transfer tokens to the grant", async () => { + expect(await token.balanceOf(tokenGrant.address)).to.equal(amount) + }) + + it("should initialize all fields", async () => { + expect(await tokenGrant.token()).to.equal(token.address) + expect(await tokenGrant.revocable()).to.equal(revocable) + expect(await tokenGrant.amount()).to.equal(amount) + expect(await tokenGrant.duration()).to.equal(duration) + expect(await tokenGrant.start()).to.equal(start) + expect(await tokenGrant.cliff()).to.equal(cliff) + }) + }) + }) + describe("unlockedAmount", () => { const assertionPrecision = to1e18(1) // +- 1 token