diff --git a/contracts/tasks/index.ts b/contracts/tasks/index.ts index 37d8529c8..6f4bfc5e2 100644 --- a/contracts/tasks/index.ts +++ b/contracts/tasks/index.ts @@ -12,3 +12,4 @@ import './fetchRound' import './mergeAllocations' import './setDurations' import './deploySponsor' +import './loadUsers' diff --git a/contracts/tasks/loadUsers.ts b/contracts/tasks/loadUsers.ts new file mode 100644 index 000000000..6fb185d2f --- /dev/null +++ b/contracts/tasks/loadUsers.ts @@ -0,0 +1,86 @@ +import { task } from 'hardhat/config' +import { Contract, utils, ContractReceipt } from 'ethers' +import fs from 'fs' + +/* + * Script to bulkload users into the simple user registry. + * File path can be relative or absolute path. + * The script can only be run by the owner of the simple user registry + * + * Sample usage: + * + * yarn hardhat load-users --file-path addresses.txt --user-registry
--network goerli + */ + +/** + * Add a user to the Simple user registry + * + * @param registry Simple user registry contract + * @param address User wallet address + * @returns transaction receipt + */ +async function addUser( + registry: Contract, + address: string +): Promise { + const tx = await registry.addUser(address) + const receipt = await tx.wait() + return receipt +} + +/** + * Load users in the file into the simple user registry + * + * @param registry Simple user registry contract + * @param filePath The path of the file containing the addresses + */ +async function loadFile(registry: Contract, filePath: string) { + let content: string | null = null + try { + content = fs.readFileSync(filePath, 'utf8') + } catch (err) { + console.error('Failed to read file', filePath, err) + return + } + + const addresses: string[] = [] + content.split(/\r?\n/).forEach(async (address) => { + addresses.push(address) + }) + + for (let i = 0; i < addresses.length; i++) { + const address = addresses[i] + const isValidAddress = Boolean(address) && utils.isAddress(address) + if (isValidAddress) { + console.log('Adding address', address) + try { + const result = await addUser(registry, address) + if (result.status !== 1) { + throw new Error( + `Transaction ${result.transactionHash} failed with status ${result.status}` + ) + } + } catch (err) { + console.error('Failed to add address', address, err) + break + } + } else { + console.warn('Skipping invalid address', address) + } + } +} + +task('load-users', 'Bulkload recipients into the simple user registry') + .addParam('userRegistry', 'The simple user registry contract address') + .addParam( + 'filePath', + 'The path of the file containing addresses separated by newline' + ) + .setAction(async ({ userRegistry, filePath }, { ethers }) => { + const registry = await ethers.getContractAt( + 'SimpleUserRegistry', + userRegistry + ) + + await loadFile(registry, filePath) + })