diff --git a/.solhint.json b/.solhint.json index 55b4979..cf6ab80 100644 --- a/.solhint.json +++ b/.solhint.json @@ -14,6 +14,7 @@ "no-empty-blocks": "off", "contract-name-camelcase": "off", "const-name-snakecase": "off", - "no-inline-assembly": "off" + "no-inline-assembly": "off", + "var-name-mixedcase": "off" } } diff --git a/.solhintignore b/.solhintignore new file mode 100644 index 0000000..e69de29 diff --git a/.vscode/settings.json b/.vscode/settings.json index 0648cde..1c70d2c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,8 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "npm.exclude": "**/lib/**", - "solidity.formatter": "forge", + "solidity.formatter": "prettier", + // "solidity.formatter": "forge", "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true } diff --git a/foundry/test/CTF/Damn-Vulnerable-DeFi/01.Unstoppable.t.sol b/foundry/test/CTF/Damn-Vulnerable-DeFi/01.Unstoppable.t.sol index 47bcda0..9be6d0c 100644 --- a/foundry/test/CTF/Damn-Vulnerable-DeFi/01.Unstoppable.t.sol +++ b/foundry/test/CTF/Damn-Vulnerable-DeFi/01.Unstoppable.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import { Test } from "forge-std/Test.sol"; -import "forge-std/Vm.sol"; +import { Vm } from "forge-std/Vm.sol"; import { console2 } from "forge-std/console2.sol"; import { console } from "forge-std/console.sol"; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -11,8 +11,6 @@ import { ReceiverUnstoppable } from "@contracts/CTF/Damn-Vulnerable-DeFi/01.Unst import { UnstoppableVault } from "@contracts/CTF/Damn-Vulnerable-DeFi/01.Unstoppable/UnstoppableVault.sol"; /* - https://www.damnvulnerabledefi.xyz/challenges/unstoppable/ - forge test --match-path foundry/test/CTF/Damn-Vulnerable-DeFi/01.Unstoppable.t.sol -vvvvv */ @@ -25,8 +23,8 @@ contract Unstoppable_01_Test is Test { UnstoppableVault private vault; ReceiverUnstoppable private receiver; - uint256 TOKENS_IN_VAULT = 1_000_000 ether; - uint256 INITIAL_PLAYER_TOKEN_BALANCE = 10 ether; + uint256 private TOKENS_IN_VAULT = 1_000_000 ether; + uint256 private INITIAL_PLAYER_TOKEN_BALANCE = 10 ether; function setUp() public { vm.startPrank(deployer); diff --git a/hardhat.config.ts b/hardhat.config.ts new file mode 100644 index 0000000..58f12d0 --- /dev/null +++ b/hardhat.config.ts @@ -0,0 +1,136 @@ +import "@nomicfoundation/hardhat-toolbox"; +import { config as dotenvConfig } from "dotenv"; +import "hardhat-deploy"; +import type { HardhatUserConfig } from "hardhat/config"; +import type { NetworkUserConfig } from "hardhat/types"; +import { resolve } from "path"; + +import "./tasks/accounts"; +import "./tasks/greet"; +import "./tasks/taskDeploy"; + +const dotenvConfigPath: string = process.env.DOTENV_CONFIG_PATH || "./.env"; +dotenvConfig({ path: resolve(__dirname, dotenvConfigPath) }); + +// Ensure that we have all the environment variables we need. +const mnemonic: string | undefined = process.env.MNEMONIC; +if (!mnemonic) { + throw new Error("Please set your MNEMONIC in a .env file"); +} + +const infuraApiKey: string | undefined = process.env.INFURA_API_KEY; +if (!infuraApiKey) { + throw new Error("Please set your INFURA_API_KEY in a .env file"); +} + +const chainIds = { + "arbitrum-mainnet": 42161, + avalanche: 43114, + bsc: 56, + ganache: 1337, + hardhat: 31337, + mainnet: 1, + "optimism-mainnet": 10, + "polygon-mainnet": 137, + "polygon-mumbai": 80001, + sepolia: 11155111, +}; + +function getChainConfig(chain: keyof typeof chainIds): NetworkUserConfig { + let jsonRpcUrl: string; + switch (chain) { + case "avalanche": + jsonRpcUrl = "https://api.avax.network/ext/bc/C/rpc"; + break; + case "bsc": + jsonRpcUrl = "https://bsc-dataseed1.binance.org"; + break; + default: + jsonRpcUrl = "https://" + chain + ".infura.io/v3/" + infuraApiKey; + } + return { + accounts: { + count: 10, + mnemonic, + path: "m/44'/60'/0'/0", + }, + chainId: chainIds[chain], + url: jsonRpcUrl, + }; +} + +const config: HardhatUserConfig = { + defaultNetwork: "hardhat", + namedAccounts: { + deployer: 0, + }, + etherscan: { + apiKey: { + arbitrumOne: process.env.ARBISCAN_API_KEY || "", + avalanche: process.env.SNOWTRACE_API_KEY || "", + bsc: process.env.BSCSCAN_API_KEY || "", + mainnet: process.env.ETHERSCAN_API_KEY || "", + optimisticEthereum: process.env.OPTIMISM_API_KEY || "", + polygon: process.env.POLYGONSCAN_API_KEY || "", + polygonMumbai: process.env.POLYGONSCAN_API_KEY || "", + sepolia: process.env.ETHERSCAN_API_KEY || "", + }, + }, + gasReporter: { + currency: "USD", + enabled: process.env.REPORT_GAS ? true : false, + excludeContracts: [], + src: "./contracts", + }, + networks: { + hardhat: { + accounts: { + mnemonic, + }, + chainId: chainIds.hardhat, + }, + ganache: { + accounts: { + mnemonic, + }, + chainId: chainIds.ganache, + url: "http://localhost:8545", + }, + arbitrum: getChainConfig("arbitrum-mainnet"), + avalanche: getChainConfig("avalanche"), + bsc: getChainConfig("bsc"), + mainnet: getChainConfig("mainnet"), + optimism: getChainConfig("optimism-mainnet"), + "polygon-mainnet": getChainConfig("polygon-mainnet"), + "polygon-mumbai": getChainConfig("polygon-mumbai"), + sepolia: getChainConfig("sepolia"), + }, + paths: { + artifacts: "./artifacts", + cache: "./cache", + sources: "./contracts", + tests: "./test", + }, + solidity: { + version: "0.8.19", + settings: { + metadata: { + // Not including the metadata hash + // https://github.com/paulrberg/hardhat-template/issues/31 + bytecodeHash: "none", + }, + // Disable the optimizer when debugging + // https://hardhat.org/hardhat-network/#solidity-optimizer-support + optimizer: { + enabled: true, + runs: 800, + }, + }, + }, + typechain: { + outDir: "types", + target: "ethers-v6", + }, +}; + +export default config; diff --git a/hardhat/deploy/.gitkeep b/hardhat/deploy/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/hardhat/tasks/.gitkeep b/hardhat/tasks/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/hardhat/test/.gitkeep b/hardhat/test/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index 80d0c9d..0dc48a9 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,6 @@ "name": "Boris Liu", "url": "https://github.com/6boris" }, - "devDependencies": { - "prettier": "^3.0.3", - "solhint": "^3.6.2" - }, "keywords": [ "blockchain", "ethereum", @@ -29,5 +25,43 @@ "test": "forge test", "test:coverage": "forge coverage", "test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir foundry/coverage" + }, + "devDependencies": { + "prettier": "^3.0.3", + "solhint": "^3.6.2", + "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", + "@nomicfoundation/hardhat-network-helpers": "^1.0.6", + "@nomicfoundation/hardhat-toolbox": "^3.0.0", + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-verify": "^1.0.0", + "@trivago/prettier-plugin-sort-imports": "^4.0.0", + "@typechain/ethers-v6": "^0.4.0", + "@typechain/hardhat": "^8.0.0", + "@types/chai": "^4.3.4", + "@types/fs-extra": "^9.0.13", + "@types/mocha": "^10.0.0", + "@types/node": "^18.11.9", + "@typescript-eslint/eslint-plugin": "^5.44.0", + "@typescript-eslint/parser": "^5.44.0", + "chai": "^4.3.7", + "cross-env": "^7.0.3", + "dotenv": "^16.0.3", + "eslint": "^8.28.0", + "eslint-config-prettier": "^8.5.0", + "ethers": "^6.4.0", + "fs-extra": "^10.1.0", + "hardhat": "^2.12.2", + "hardhat-deploy": "^0.11.29", + "hardhat-gas-reporter": "^1.0.9", + "lodash": "^4.17.21", + "mocha": "^10.1.0", + "prettier-plugin-solidity": "^1.1.2", + "rimraf": "^4.1.2", + "solhint-plugin-prettier": "^0.0.5", + "solidity-coverage": "^0.8.2", + "ts-generator": "^0.1.1", + "ts-node": "^10.9.1", + "typechain": "^8.2.0", + "typescript": "^4.9.3" } }