diff --git a/foundry.toml b/foundry.toml index 2bc811e7..b8878bcf 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,9 +2,15 @@ fuzz-runs = 10_000 [profile.default] -# via-ir = true # Enable the IR-based optimizer (yul) +via-ir = true # Enable the IR-based optimizer (yul) +optimizer = true +bytecode_hash = "none" # prevents compiler from attaching bytecode hash to contract metadata + +[profile.fastDev] +via-ir = false # Enable the IR-based optimizer (yul) optimizer = true optimizer_runs = 10_000 + gas_reports = ["AllowList", "ContinuousFundraising", "FeeSettings", "PersonalInvite", "PersonalInviteFactory", "Token"] [rpc_endpoints] diff --git a/hardhat.config.ts b/hardhat.config.ts index 903096b0..92bdad19 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,11 +1,11 @@ -import { HardhatUserConfig, task } from "hardhat/config"; +import { HardhatUserConfig, task } from 'hardhat/config'; -import "dotenv/config"; -import "hardhat-gas-reporter"; -import "@nomiclabs/hardhat-etherscan"; -import "@typechain/hardhat"; -import "@nomiclabs/hardhat-ethers"; -import "@nomiclabs/hardhat-waffle"; +import 'dotenv/config'; +import 'hardhat-gas-reporter'; +import '@nomiclabs/hardhat-etherscan'; +import '@typechain/hardhat'; +import '@nomiclabs/hardhat-ethers'; +import '@nomiclabs/hardhat-waffle'; // require("@nomiclabs/hardhat-waffle"); // require("hardhat-gas-reporter"); @@ -14,7 +14,7 @@ import "@nomiclabs/hardhat-waffle"; // This is a sample Hardhat task. To learn how to create your own go to // https://hardhat.org/guides/create-task.html -task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { +task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => { const accounts = await hre.ethers.getSigners(); for (const account of accounts) { @@ -30,48 +30,59 @@ task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { */ const config: HardhatUserConfig = { solidity: { - version: "0.8.17", + version: '0.8.17', settings: { + // optimizer: { + // enabled: true, + // runs: 10000, + // }, + metadata: { + bytecodeHash: 'none', + }, + viaIR: true, optimizer: { enabled: true, - runs: 10000, + details: { + yulDetails: { + //optimizerSteps: 'u', // recommended by hh, but yields longer bytecode + }, + }, }, - // viaIR: true, // outputSelection: { "*": { "*": ["storageLayout"] } }, }, }, networks: { localhost: { - url: "http://localhost:8545", + url: 'http://localhost:8545', }, ropsten: { - url: process.env.ROPSTEN_URL || "", + url: process.env.ROPSTEN_URL || '', accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], }, goerli: { - url: process.env.GOERLI_RPC_URL || "", + url: process.env.GOERLI_RPC_URL || '', accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], }, mainnet: { - url: process.env.MAINNET_RPC_URL || "", + url: process.env.MAINNET_RPC_URL || '', accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], }, }, gasReporter: { enabled: process.env.REPORT_GAS !== undefined, - currency: "USD", + currency: 'USD', }, etherscan: { apiKey: process.env.ETHERSCAN_API_KEY, }, typechain: { - outDir: "types", - target: "ethers-v5", + outDir: 'types', + target: 'ethers-v5', alwaysGenerateOverloads: false, // should overloads with full signatures like deposit(uint256) be generated always, even if there are no overloads? - externalArtifacts: ["externalArtifacts/*.json"], // optional array of glob patterns with external artifacts to process (for example external libs from node_modules) + externalArtifacts: ['externalArtifacts/*.json'], // optional array of glob patterns with external artifacts to process (for example external libs from node_modules) dontOverrideCompile: false, // defaults to false }, }; diff --git a/lib/forge-std b/lib/forge-std index 066ff16c..e8a047e3 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 066ff16c5c03e6f931cd041fd366bc4be1fae82a +Subproject commit e8a047e3f40f13fa37af6fe14e6e06283d9a060e diff --git a/test/ContinuousFundraising.t.sol b/test/ContinuousFundraising.t.sol index c51dcad9..e8463e8b 100644 --- a/test/ContinuousFundraising.t.sol +++ b/test/ContinuousFundraising.t.sol @@ -732,19 +732,32 @@ contract ContinuousFundraisingTest is Test { /* try to unpause too soon after setMaxAmountOfTokenToBeSold */ - function testFailUnpauseTooSoonAfterSetMaxAmountOfTokenToBeSold() public { - uint256 time = block.timestamp; - vm.warp(time); + function testUnpauseTooSoonAfterSetMaxAmountOfTokenToBeSold( + uint128 startTime, + uint32 changeDelay, + uint32 attemptUnpauseDelay + ) public { + uint256 unpauseDelay = raise.delay(); + vm.assume(startTime < type(uint128).max / 2); + vm.assume(startTime > 0); + vm.assume(changeDelay > 0); + vm.assume(attemptUnpauseDelay > 0); + vm.assume(attemptUnpauseDelay < unpauseDelay + changeDelay); + + vm.warp(startTime); vm.prank(owner); raise.pause(); - assertTrue(raise.paused()); - assertTrue(raise.coolDownStart() == time); - vm.warp(time + 2 hours); + assertTrue(raise.paused(), "raise should be paused"); + assertTrue(raise.coolDownStart() == startTime, "coolDownStart should be startTime"); + vm.warp(startTime + changeDelay); vm.prank(owner); raise.setMaxAmountOfTokenToBeSold(700); - assertTrue(raise.coolDownStart() == time + 2 hours); - vm.warp(time + raise.delay() + 1 seconds); + assertTrue(raise.coolDownStart() == startTime + changeDelay, "coolDownStart should be startTime + changeDelay"); + vm.warp(startTime + attemptUnpauseDelay); vm.prank(owner); + console.log("current time: ", block.timestamp); + console.log("unpause at: ", startTime + changeDelay + unpauseDelay); + vm.expectRevert("There needs to be at minimum one day to change parameters"); raise.unpause(); // must fail because of the parameter update } @@ -770,19 +783,34 @@ contract ContinuousFundraisingTest is Test { /* try to unpause too soon after setCurrencyReceiver */ - function testFailUnpauseTooSoonAfterSetCurrencyReceiver() public { - uint256 time = block.timestamp; - vm.warp(time); + function testUnpauseTooSoonAfterSetCurrencyReceiver( + uint128 startTime, + uint32 changeDelay, + uint32 attemptUnpauseDelay, + address newCurrencyReceiver + ) public { + uint256 unpauseDelay = raise.delay(); + vm.assume(startTime < type(uint128).max / 2); + vm.assume(startTime > 0); + vm.assume(changeDelay > 0); + vm.assume(attemptUnpauseDelay > 0); + vm.assume(attemptUnpauseDelay < unpauseDelay + changeDelay); + vm.assume(newCurrencyReceiver != address(0)); + + vm.warp(startTime); vm.prank(owner); raise.pause(); - assertTrue(raise.paused()); - assertTrue(raise.coolDownStart() == time); - vm.warp(time + 2 hours); + assertTrue(raise.paused(), "raise should be paused"); + assertTrue(raise.coolDownStart() == startTime, "coolDownStart should be startTime"); + vm.warp(startTime + changeDelay); vm.prank(owner); - raise.setCurrencyReceiver(payable(address(buyer))); - assertTrue(raise.coolDownStart() == time + 2 hours); - vm.warp(time + raise.delay() + 1 hours); + raise.setCurrencyReceiver(newCurrencyReceiver); + assertTrue(raise.coolDownStart() == startTime + changeDelay, "coolDownStart should be startTime + changeDelay"); + vm.warp(startTime + attemptUnpauseDelay); vm.prank(owner); + console.log("current time: ", block.timestamp); + console.log("unpause at: ", startTime + changeDelay + unpauseDelay); + vm.expectRevert("There needs to be at minimum one day to change parameters"); raise.unpause(); // must fail because of the parameter update } @@ -808,19 +836,35 @@ contract ContinuousFundraisingTest is Test { /* try to unpause too soon after setMinAmountPerBuyer */ - function testFailUnpauseTooSoonAfterSetMinAmountPerBuyer() public { - uint256 time = block.timestamp; - vm.warp(time); + function testUnpauseTooSoonAfterSetMinAmountPerBuyer( + uint128 startTime, + uint32 changeDelay, + uint32 attemptUnpauseDelay, + uint256 newMinAmountPerBuyer + ) public { + uint256 unpauseDelay = raise.delay(); + vm.assume(startTime < type(uint128).max / 2); + vm.assume(startTime > 0); + vm.assume(changeDelay > 0); + vm.assume(attemptUnpauseDelay > 0); + vm.assume(attemptUnpauseDelay < unpauseDelay + changeDelay); + vm.assume(newMinAmountPerBuyer > 0); + vm.assume(newMinAmountPerBuyer <= raise.maxAmountPerBuyer()); + + vm.warp(startTime); vm.prank(owner); raise.pause(); - assertTrue(raise.paused()); - assertTrue(raise.coolDownStart() == time); - vm.warp(time + 2 hours); + assertTrue(raise.paused(), "raise should be paused"); + assertTrue(raise.coolDownStart() == startTime, "coolDownStart should be startTime"); + vm.warp(startTime + changeDelay); vm.prank(owner); - raise.setMinAmountPerBuyer(700); - assertTrue(raise.coolDownStart() == time + 2 hours); - vm.warp(time + raise.delay() + 1 hours); + raise.setMinAmountPerBuyer(newMinAmountPerBuyer); + assertTrue(raise.coolDownStart() == startTime + changeDelay, "coolDownStart should be startTime + changeDelay"); + vm.warp(startTime + attemptUnpauseDelay); vm.prank(owner); + console.log("current time: ", block.timestamp); + console.log("unpause at: ", startTime + changeDelay + unpauseDelay); + vm.expectRevert("There needs to be at minimum one day to change parameters"); raise.unpause(); // must fail because of the parameter update } @@ -846,19 +890,34 @@ contract ContinuousFundraisingTest is Test { /* try to unpause too soon after setMaxAmountPerBuyer */ - function testFailUnpauseTooSoonAfterSetMaxAmountPerBuyer() public { - uint256 time = block.timestamp; - vm.warp(time); + function testUnpauseTooSoonAfterSetMaxAmountPerBuyer( + uint128 startTime, + uint32 changeDelay, + uint32 attemptUnpauseDelay, + uint256 newMaxAmountPerBuyer + ) public { + uint256 unpauseDelay = raise.delay(); + vm.assume(startTime < type(uint128).max / 2); + vm.assume(startTime > 0); + vm.assume(changeDelay > 0); + vm.assume(attemptUnpauseDelay > 0); + vm.assume(attemptUnpauseDelay < unpauseDelay + changeDelay); + vm.assume(newMaxAmountPerBuyer >= raise.minAmountPerBuyer()); + + vm.warp(startTime); vm.prank(owner); raise.pause(); - assertTrue(raise.paused()); - assertTrue(raise.coolDownStart() == time); - vm.warp(time + 2 hours); + assertTrue(raise.paused(), "raise should be paused"); + assertTrue(raise.coolDownStart() == startTime, "coolDownStart should be startTime"); + vm.warp(startTime + changeDelay); vm.prank(owner); - raise.setMaxAmountPerBuyer(700); - assertTrue(raise.coolDownStart() == time + 2 hours); - vm.warp(time + raise.delay() + 1 hours); + raise.setMaxAmountPerBuyer(newMaxAmountPerBuyer); + assertTrue(raise.coolDownStart() == startTime + changeDelay, "coolDownStart should be startTime + changeDelay"); + vm.warp(startTime + attemptUnpauseDelay); vm.prank(owner); + console.log("current time: ", block.timestamp); + console.log("unpause at: ", startTime + changeDelay + unpauseDelay); + vm.expectRevert("There needs to be at minimum one day to change parameters"); raise.unpause(); // must fail because of the parameter update } @@ -881,22 +940,56 @@ contract ContinuousFundraisingTest is Test { raise.unpause(); } + // /* + // try to unpause too soon after setCurrencyAndTokenPrice + // */ + // function testUnpauseTooSoonAfterSetCurrencyAndTokenPrice() public { + // uint256 time = block.timestamp; + // vm.warp(time); + // vm.prank(owner); + // raise.pause(); + // assertTrue(raise.paused()); + // assertTrue(raise.coolDownStart() == time); + // vm.warp(time + 2 hours); + // vm.prank(owner); + // raise.setCurrencyAndTokenPrice(paymentToken, 700); + // assertTrue(raise.coolDownStart() == time + 2 hours); + // vm.warp(time + raise.delay() + 1 hours); + // vm.prank(owner); + // vm.expectRevert("There needs to be at minimum one day to change parameters"); + // raise.unpause(); // must fail because of the parameter update + // } + /* try to unpause too soon after setCurrencyAndTokenPrice */ - function testUnpauseTooSoonAfterSetCurrencyAndTokenPrice() public { - uint256 time = block.timestamp; - vm.warp(time); + function testUnpauseTooSoonAfterSetCurrencyAndTokenPrice( + uint128 startTime, + uint32 changeDelay, + uint32 attemptUnpauseDelay, + uint256 newTokenPrice + ) public { + uint256 unpauseDelay = raise.delay(); + vm.assume(startTime < type(uint128).max / 2); + vm.assume(startTime > 0); + vm.assume(changeDelay > 0); + vm.assume(attemptUnpauseDelay > 0); + vm.assume(attemptUnpauseDelay < unpauseDelay + changeDelay); + vm.assume(newTokenPrice > 0); + + vm.warp(startTime); vm.prank(owner); raise.pause(); - assertTrue(raise.paused()); - assertTrue(raise.coolDownStart() == time); - vm.warp(time + 2 hours); + assertTrue(raise.paused(), "raise should be paused"); + assertTrue(raise.coolDownStart() == startTime, "coolDownStart should be startTime"); + vm.warp(startTime + changeDelay); vm.prank(owner); - raise.setCurrencyAndTokenPrice(paymentToken, 700); - assertTrue(raise.coolDownStart() == time + 2 hours); - vm.warp(time + raise.delay() + 1 hours); + raise.setCurrencyAndTokenPrice(paymentToken, newTokenPrice); + assertTrue(raise.coolDownStart() == startTime + changeDelay, "coolDownStart should be startTime + changeDelay"); + vm.warp(startTime + attemptUnpauseDelay); vm.prank(owner); + console.log("current time: ", block.timestamp); + console.log("unpause at: ", startTime + changeDelay + unpauseDelay); vm.expectRevert("There needs to be at minimum one day to change parameters"); raise.unpause(); // must fail because of the parameter update }