diff --git a/packages/eslint-graph-config/README.md b/packages/eslint-graph-config/README.md index 8dca2ba6e..3e0a41cff 100644 --- a/packages/eslint-graph-config/README.md +++ b/packages/eslint-graph-config/README.md @@ -40,6 +40,12 @@ module.exports = [ '@typescript-eslint/no-unsafe-argument': 'off', }, }, + { + ignores: [ + 'library/*', // ignore its contents + '!node_modules/mylibrary/' // unignore `node_modules/mylibrary` directory + ] + } ] ``` diff --git a/packages/eslint-graph-config/index.ts b/packages/eslint-graph-config/index.ts index ccffd6b14..2ab60d95b 100644 --- a/packages/eslint-graph-config/index.ts +++ b/packages/eslint-graph-config/index.ts @@ -31,7 +31,6 @@ export default [ 'no-only-tests': noOnlyTests, 'no-secrets': noSecrets, }, - ignores: ['dist/*', 'node_modules/*', 'build/*'], rules: { 'prefer-const': 'warn', '@typescript-eslint/no-inferrable-types': 'warn', @@ -47,4 +46,7 @@ export default [ '@stylistic/brace-style': ['error', '1tbs'], }, }, + { + ignores: ['**/dist/*', '**/node_modules/*', '**/build/*', '**/cache/*', '**/.graphclient/*'], + }, ] diff --git a/packages/token-distribution/deploy/1_test.ts b/packages/token-distribution/deploy/1_test.ts index 779cf5b36..92b626012 100644 --- a/packages/token-distribution/deploy/1_test.ts +++ b/packages/token-distribution/deploy/1_test.ts @@ -2,14 +2,14 @@ import { utils } from 'ethers' import consola from 'consola' import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' +import { DeployFunction, DeployOptions } from 'hardhat-deploy/types' const { parseEther } = utils const logger = consola.create({}) const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deploy } = hre.deployments + const deploy = (name: string, options: DeployOptions) => hre.deployments.deploy(name, options) const { deployer } = await hre.getNamedAccounts() // -- Fake Graph Token -- diff --git a/packages/token-distribution/deploy/2_l1_manager_wallet.ts b/packages/token-distribution/deploy/2_l1_manager_wallet.ts index 66cbc3af9..a2bd7ecac 100644 --- a/packages/token-distribution/deploy/2_l1_manager_wallet.ts +++ b/packages/token-distribution/deploy/2_l1_manager_wallet.ts @@ -3,7 +3,7 @@ import { utils } from 'ethers' import '@nomiclabs/hardhat-ethers' import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' +import { DeployFunction, DeployOptions } from 'hardhat-deploy/types' import { GraphTokenMock } from '../build/typechain/contracts/GraphTokenMock' import { GraphTokenLockManager } from '../build/typechain/contracts/GraphTokenLockManager' @@ -14,7 +14,7 @@ const { parseEther, formatEther } = utils const logger = consola.create({}) const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deploy } = hre.deployments + const deploy = (name: string, options: DeployOptions) => hre.deployments.deploy(name, options) const { deployer } = await hre.getNamedAccounts() // -- Graph Token -- diff --git a/packages/token-distribution/deploy/3_l2_wallet.ts b/packages/token-distribution/deploy/3_l2_wallet.ts index 53a9f7f5c..36679613c 100644 --- a/packages/token-distribution/deploy/3_l2_wallet.ts +++ b/packages/token-distribution/deploy/3_l2_wallet.ts @@ -1,15 +1,14 @@ import consola from 'consola' import '@nomiclabs/hardhat-ethers' import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' +import { DeployFunction, DeployOptions } from 'hardhat-deploy/types' import { getDeploymentName } from './lib/utils' - const logger = consola.create({}) const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deploy } = hre.deployments + const deploy = (name: string, options: DeployOptions) => hre.deployments.deploy(name, options) const { deployer } = await hre.getNamedAccounts() // Deploy the master copy of GraphTokenLockWallet diff --git a/packages/token-distribution/deploy/4_l1_transfer_tool.ts b/packages/token-distribution/deploy/4_l1_transfer_tool.ts index b8fb04473..125483f56 100644 --- a/packages/token-distribution/deploy/4_l1_transfer_tool.ts +++ b/packages/token-distribution/deploy/4_l1_transfer_tool.ts @@ -1,5 +1,4 @@ import consola from 'consola' -import { utils } from 'ethers' import '@nomiclabs/hardhat-ethers' import { HardhatRuntimeEnvironment } from 'hardhat/types' @@ -50,12 +49,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { owner = deployer logger.warn(`No owner address provided, will use the deployer address as owner: ${owner}`) } - + // Deploy the L1GraphTokenLockTransferTool with a proxy. // hardhat-deploy doesn't get along with constructor arguments in the implementation // combined with an OpenZeppelin transparent proxy, so we need to do this using // the OpenZeppelin hardhat-upgrades tooling, and save the deployment manually. - + // TODO modify this to use upgradeProxy if a deployment already exists? logger.info('Deploying L1GraphTokenLockTransferTool proxy...') const transferToolFactory = await ethers.getContractFactory('L1GraphTokenLockTransferTool') diff --git a/packages/token-distribution/deploy/5_l2_manager.ts b/packages/token-distribution/deploy/5_l2_manager.ts index 5572345da..93016663f 100644 --- a/packages/token-distribution/deploy/5_l2_manager.ts +++ b/packages/token-distribution/deploy/5_l2_manager.ts @@ -3,7 +3,7 @@ import { utils } from 'ethers' import '@nomiclabs/hardhat-ethers' import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' +import { DeployFunction, DeployOptions } from 'hardhat-deploy/types' import { GraphTokenMock } from '../build/typechain/contracts/GraphTokenMock' import { askConfirm, getDeploymentName, promptContractAddress } from './lib/utils' @@ -14,7 +14,7 @@ const { parseEther, formatEther } = utils const logger = consola.create({}) const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deploy } = hre.deployments + const deploy = (name: string, options: DeployOptions) => hre.deployments.deploy(name, options) const { deployer } = await hre.getNamedAccounts() // -- Graph Token -- diff --git a/packages/token-distribution/deploy/6_l2_transfer_tool.ts b/packages/token-distribution/deploy/6_l2_transfer_tool.ts index 659a104a4..f449ebe84 100644 --- a/packages/token-distribution/deploy/6_l2_transfer_tool.ts +++ b/packages/token-distribution/deploy/6_l2_transfer_tool.ts @@ -1,5 +1,4 @@ import consola from 'consola' -import { utils } from 'ethers' import '@nomiclabs/hardhat-ethers' import { HardhatRuntimeEnvironment } from 'hardhat/types' @@ -18,8 +17,6 @@ const artifacts = new Artifacts(ARTIFACTS_PATH) const l2TransferToolAbi = artifacts.readArtifactSync('L2GraphTokenLockTransferTool').abi const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer } = await hre.getNamedAccounts() - // -- Graph Token -- // Get the addresses we will use @@ -40,12 +37,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { logger.warn('No L1 GRT address provided') process.exit(1) } - + // Deploy the L2GraphTokenLockTransferTool with a proxy. // hardhat-deploy doesn't get along with constructor arguments in the implementation // combined with an OpenZeppelin transparent proxy, so we need to do this using // the OpenZeppelin hardhat-upgrades tooling, and save the deployment manually. - + // TODO modify this to use upgradeProxy if a deployment already exists? logger.info('Deploying L2GraphTokenLockTransferTool proxy...') const transferToolFactory = await ethers.getContractFactory('L2GraphTokenLockTransferTool') diff --git a/packages/token-distribution/deploy/lib/utils.ts b/packages/token-distribution/deploy/lib/utils.ts index 7330f4e55..afc38555b 100644 --- a/packages/token-distribution/deploy/lib/utils.ts +++ b/packages/token-distribution/deploy/lib/utils.ts @@ -12,10 +12,10 @@ export const askConfirm = async (message: string) => { type: 'confirm', message, }) - return res.confirm + return res.confirm ? res.confirm as boolean : false } -export const promptContractAddress = async (name: string, logger: Consola): Promise => { +export const promptContractAddress = async (name: string, logger: Consola): Promise => { const res1 = await inquirer.prompt({ name: 'contract', type: 'input', @@ -37,5 +37,5 @@ export const getDeploymentName = async (defaultName: string): Promise => default: defaultName, message: 'Save deployment as?', }) - return res['deployment-name'] + return res['deployment-name'] as string } diff --git a/packages/token-distribution/hardhat.config.ts b/packages/token-distribution/hardhat.config.ts index 4fa7a9cb8..eaa994346 100644 --- a/packages/token-distribution/hardhat.config.ts +++ b/packages/token-distribution/hardhat.config.ts @@ -80,6 +80,7 @@ function setupNetworkConfig(config) { // Env +// eslint-disable-next-line @typescript-eslint/no-misused-promises extendEnvironment(async (hre) => { const accounts = await hre.ethers.getSigners() try { @@ -152,7 +153,6 @@ const config = { }, }, etherscan: { - //url: process.env.ETHERSCAN_API_URL, apiKey: process.env.ETHERSCAN_API_KEY, customChains: [ { @@ -163,7 +163,7 @@ const config = { browserURL: 'https://sepolia.arbiscan.io', }, }, - ] + ], }, typechain: { outDir: 'build/typechain/contracts', diff --git a/packages/token-distribution/ops/create.ts b/packages/token-distribution/ops/create.ts index 778865ec0..0dce2d253 100644 --- a/packages/token-distribution/ops/create.ts +++ b/packages/token-distribution/ops/create.ts @@ -2,7 +2,7 @@ import PQueue from 'p-queue' import fs from 'fs' import consola from 'consola' import inquirer from 'inquirer' -import { utils, BigNumber, Event, ContractTransaction, ContractReceipt, Contract, ContractFactory } from 'ethers' +import { BigNumber, Contract, ContractFactory, ContractReceipt, ContractTransaction, Event, utils } from 'ethers' import { NonceManager } from '@ethersproject/experimental' import { task } from 'hardhat/config' @@ -47,7 +47,7 @@ export const askConfirm = async () => { type: 'confirm', message: `Are you sure you want to proceed?`, }) - return res.confirm + return res.confirm ? res.confirm as boolean : false } const isValidAddress = (address: string) => { @@ -68,10 +68,10 @@ export const isValidAddressOrFail = (address: string) => { const loadDeployData = (filepath: string): TokenLockConfigEntry[] => { const data = fs.readFileSync(filepath, 'utf8') - const entries = data.split('\n').map((e) => e.trim()) + const entries = data.split('\n').map(e => e.trim()) entries.shift() // remove the title from the csv return entries - .filter((entryData) => !!entryData) + .filter(entryData => !!entryData) .map((entryData) => { const entry = entryData.split(',') return { @@ -89,9 +89,9 @@ const loadDeployData = (filepath: string): TokenLockConfigEntry[] => { const loadResultData = (filepath: string): TokenLockConfigEntry[] => { const data = fs.readFileSync(filepath, 'utf8') - const entries = data.split('\n').map((e) => e.trim()) + const entries = data.split('\n').map(e => e.trim()) return entries - .filter((entryData) => !!entryData) + .filter(entryData => !!entryData) .map((entryData) => { const entry = entryData.split(',') return { @@ -246,7 +246,7 @@ const populateEntries = async ( tokenAddress: string, ownerAddress: string, ) => { - const results = [] + const results: TokenLockConfigEntry[] = [] for (const entry of entries) { entry.owner = ownerAddress entry.salt = await calculateSalt(hre, entry, managerAddress, tokenAddress) @@ -323,7 +323,7 @@ task('create-token-locks', 'Create token lock contracts from file') entries = await populateEntries(hre, entries, manager.address, tokenAddress, taskArgs.ownerAddress) // Filter out already deployed ones - entries = entries.filter((entry) => !deployedEntries.find((deployedEntry) => deployedEntry.salt === entry.salt)) + entries = entries.filter(entry => !deployedEntries.find(deployedEntry => deployedEntry.salt === entry.salt)) logger.success(`Total of ${entries.length} entries after removing already deployed. All good!`) if (entries.length === 0) { logger.warn('Nothing new to deploy') @@ -378,7 +378,7 @@ task('create-token-locks', 'Create token lock contracts from file') const queue = new PQueue({ concurrency: 6 }) for (const entry of entries) { - queue.add(async () => { + await queue.add(async () => { logger.log('') logger.info(`Creating contract...`) logger.log(prettyConfigEntry(entry)) diff --git a/packages/token-distribution/ops/delete.ts b/packages/token-distribution/ops/delete.ts index d4ca09b25..1cb84c755 100644 --- a/packages/token-distribution/ops/delete.ts +++ b/packages/token-distribution/ops/delete.ts @@ -1,6 +1,6 @@ import { task } from 'hardhat/config' import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { prettyEnv, askConfirm, waitTransaction } from './create' +import { askConfirm, prettyEnv, waitTransaction } from './create' import consola from 'consola' import { TxBuilder } from './tx-builder' diff --git a/packages/token-distribution/ops/info.ts b/packages/token-distribution/ops/info.ts index a0a024a37..4906293df 100644 --- a/packages/token-distribution/ops/info.ts +++ b/packages/token-distribution/ops/info.ts @@ -1,21 +1,21 @@ import PQueue from 'p-queue' import { task } from 'hardhat/config' import '@nomiclabs/hardhat-ethers' -import { BigNumber, Contract, utils, providers } from 'ethers' +import { BigNumber, Contract, utils } from 'ethers' import { HardhatRuntimeEnvironment } from 'hardhat/types' import CoinGecko from 'coingecko-api' import { Block } from '@ethersproject/abstract-provider' import * as GraphClient from '../.graphclient' import { + CuratorWalletsDocument, + CuratorWalletsQuery, execute, + GraphAccountDocument, + GraphAccountQuery, GraphNetworkDocument, GraphNetworkQuery, TokenLockWalletsDocument, TokenLockWalletsQuery, - CuratorWalletsDocument, - CuratorWalletsQuery, - GraphAccountQuery, - GraphAccountDocument, } from '../.graphclient' import { ExecutionResult } from 'graphql' @@ -58,7 +58,7 @@ type GraphAccount = Pick & { // Helpers -const toInt = (s) => parseInt(s) / 1e18 +const toInt = s => parseInt(s) / 1e18 const toBN = (s: string): BigNumber => BigNumber.from(s) const formatGRT = (n: BigNumber): string => utils.formatEther(n) const formatRoundGRT = (n: BigNumber): string => formatGRT(n).split('.')[0] @@ -251,8 +251,8 @@ async function getExtendedWalletInfo( const walletInfoEntries: { [key: string]: WalletInfo } = {} const queue = new PQueue({ concurrency: RPC_CONCURRENCY }) - contracts.map(async (contract) => { - queue.add(async () => { + void contracts.map(async (contract) => { + await queue.add(async () => { // Get subgraph data const graphAccount = await getGraphAccount(contract.address, blockNumber) @@ -333,12 +333,12 @@ class TokenSummary { public show(detail = false) { console.log(`= Managed: ${formatRoundGRT(this.totalManaged)} [n:${this.totalCount}]`) console.log( - `- Available (${this.totalAvailable.mul(100).div(this.totalManaged)}%):`, + `- Available (${this.totalAvailable.mul(100).div(this.totalManaged).toString()}%):`, formatRoundGRT(this.totalAvailable), ) - console.log(`- Free (${this.totalFree.mul(100).div(this.totalManaged)}%):`, formatRoundGRT(this.totalFree)) + console.log(`- Free (${this.totalFree.mul(100).div(this.totalManaged).toString()}%):`, formatRoundGRT(this.totalFree)) console.log( - `-- Released (${this.totalFree.gt(0) ? this.totalReleased.mul(100).div(this.totalFree) : 0}%): ${formatRoundGRT( + `-- Released (${this.totalFree.gt(0) ? this.totalReleased.mul(100).div(this.totalFree).toString() : 0}%): ${formatRoundGRT( this.totalReleased, )} [n:${this.contractsReleased.length}]`, ) @@ -414,8 +414,8 @@ task('contracts:list', 'List all token lock contracts') const tokensUsedStaked = BigNumber.from(graphAccount.indexer?.stakedTokens || 0) const tokensUsedDelegated = graphAccount.delegator ? BigNumber.from(graphAccount.delegator.totalStakedTokens).sub( - BigNumber.from(graphAccount.delegator.totalUnstakedTokens), - ) + BigNumber.from(graphAccount.delegator.totalUnstakedTokens), + ) : BigNumber.from(0) // print wallet entries @@ -471,7 +471,7 @@ task('contracts:summary', 'Show summary of balances') const block = await hre.ethers.provider.getBlock(blockNumber) console.log('Block:', block.number, '/', new Date(block.timestamp * 1000).toDateString(), '\n') const allWallets = await getWallets(block.number) - const revocableWallets = allWallets.filter((wallet) => wallet.revocable === 'Enabled') + const revocableWallets = allWallets.filter(wallet => wallet.revocable === 'Enabled') // Calculate summaries (for all vestings) const summary: TokenSummary = new TokenSummary(block) @@ -482,8 +482,8 @@ task('contracts:summary', 'Show summary of balances') // Calculate summaries (for revocable vestings) const queue = new PQueue({ concurrency: RPC_CONCURRENCY }) const revocableSummary: TokenSummary = new TokenSummary(block) - revocableWallets.map(async (wallet) => { - queue.add(async () => { + void revocableWallets.map(async (wallet) => { + await queue.add(async () => { const contract = await hre.ethers.getContractAt('GraphTokenLockWallet', wallet.id) await revocableSummary.addWallet(wallet, contract) }) @@ -514,10 +514,10 @@ task('contracts:summary', 'Show summary of balances') // Exchange locked let managedAmountExchanges = vestingListExchanges - .map((vesting) => toBN(vesting.managedAmount)) + .map(vesting => toBN(vesting.managedAmount)) .reduce((a, b) => a.add(b), toBN('0')) let freeAmountExchanges = vestingListExchanges - .map((vesting) => getFreeAmount(vesting, block.timestamp)) + .map(vesting => getFreeAmount(vesting, block.timestamp)) .reduce((a, b) => a.add(b), toBN('0')) managedAmountExchanges = managedAmountExchanges.add(toWei('283333334')) freeAmountExchanges = freeAmountExchanges.add(toWei('150000000')) @@ -574,7 +574,7 @@ task('contracts:show', 'Show info about an specific contract') await contract.amountPerPeriod(), await contract.surplusAmount(), await contract.vestedAmount(), - ]).then((results) => results.map((e) => formatRoundGRT(e))) + ]).then(results => results.map(e => formatRoundGRT(e))) const [startTime, endTime, periods, currentPeriod, periodDuration, revocable, owner, manager] = await Promise.all([ contract.startTime(), @@ -693,8 +693,8 @@ task('contracts:list-pending-lock', 'List all token lock contracts that have not console.log(`Checking lock status...`) const queue = new PQueue({ concurrency: RPC_CONCURRENCY }) const pendingLocks: TokenLockWallet[] = [] - allWallets.map(async (wallet) => { - queue.add(async () => { + void allWallets.map(async (wallet) => { + await queue.add(async () => { // Original contract didn't support accepting/cancelling lock, we can safely ignore those // so we wrap isAccepted() call in try/catch and keep going if it fails try { diff --git a/packages/token-distribution/ops/tx-builder.ts b/packages/token-distribution/ops/tx-builder.ts index 159bd9a21..6a6f200d7 100644 --- a/packages/token-distribution/ops/tx-builder.ts +++ b/packages/token-distribution/ops/tx-builder.ts @@ -1,8 +1,22 @@ import fs from 'fs' import path from 'path' +export interface BuilderTx { + to: string + data: string + value: number | string + contractMethod?: null + contractInputsValues?: null +} + +interface TxBuilderContents { + createdAt: number + chainId: string + transactions: BuilderTx[] +} + export class TxBuilder { - contents: any + contents: TxBuilderContents outputFile: string constructor(chainId: string, _template?: string) { @@ -20,7 +34,7 @@ export class TxBuilder { this.contents.chainId = chainId } - addTx(tx: any) { + addTx(tx: BuilderTx) { this.contents.transactions.push({ ...tx, contractMethod: null, contractInputsValues: null }) } diff --git a/packages/token-distribution/package.json b/packages/token-distribution/package.json index 331fa3bd7..37069fc41 100644 --- a/packages/token-distribution/package.json +++ b/packages/token-distribution/package.json @@ -13,7 +13,7 @@ "test:gas": "RUN_EVM=true REPORT_GAS=true scripts/test", "test:coverage": "scripts/coverage", "lint": "yarn run lint:ts && yarn run lint:sol", - "lint:ts": "eslint 'test/**/*.{js,ts}' --fix", + "lint:ts": "eslint '**/*.{js,ts}' --fix", "lint:sol": "prettier --write contracts/**/*.sol && solhint --fix contracts/**/*.sol --config node_modules/solhint-graph-config/index.js", "security": "scripts/security", "flatten": "scripts/flatten", diff --git a/packages/token-distribution/tsconfig.json b/packages/token-distribution/tsconfig.json index 8027b0d63..ba8d0153c 100644 --- a/packages/token-distribution/tsconfig.json +++ b/packages/token-distribution/tsconfig.json @@ -10,6 +10,7 @@ }, "exclude": ["dist", "node_modules"], "include": [ + ".solcover.js", "eslint.config.js", "prettier.config.js", "./hardhat.config.ts",