From 856c6f8fee42ccd334164ad9b20bd92370eacca2 Mon Sep 17 00:00:00 2001 From: Sean Darcy Date: Mon, 19 May 2025 08:05:26 +1000 Subject: [PATCH 1/3] add ability to skip verifying --- scripts/deploy-investor-vesting.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/deploy-investor-vesting.js b/scripts/deploy-investor-vesting.js index ce6b013..fa8e6d3 100755 --- a/scripts/deploy-investor-vesting.js +++ b/scripts/deploy-investor-vesting.js @@ -3,6 +3,7 @@ const fs = require('fs'); const csv = require('csv-parse/sync'); const chalk = require('chalk'); + // This script will deploy many investor contract, it takes as input a CSV "investors.csv" which is required to have // these headers: beneficiary,revoker,start,end,transferableBeneficiary,amount // @@ -16,6 +17,9 @@ const seshAddress = "0x7D7fD4E91834A96cD9Fb2369E7f4EB72383bbdEd"; const rewardsAddress = "0x9d8aB00880CBBdc2Dcd29C179779469A82E7be35"; const multiContributorAddress = "0x36Ee2Da54a7E727cC996A441826BBEdda6336B71"; +// Configuration constants +const SHOULD_VERIFY_CONTRACTS = true; + async function verifyContract(address, constructorArgs) { console.log(chalk.yellow("\nVerifying contract on Etherscan...")); try { @@ -130,10 +134,12 @@ async function main() { console.log(chalk.green("Vesting contract deployed to:"), chalk.yellow(vestingAddress)); - console.log("Waiting for deployment to be confirmed..."); - await vestingContract.deploymentTransaction().wait(5); + if (SHOULD_VERIFY_CONTRACTS) { + console.log("Waiting for deployment to be confirmed..."); + await vestingContract.deploymentTransaction().wait(5); + await verifyContract(vestingAddress, constructorArgs); + } - await verifyContract(vestingAddress, constructorArgs); const seshContract = await hre.ethers.getContractAt("SESH", seshAddress); const amount = hre.ethers.parseUnits(record.amount, 9); // Assuming 9 decimals for SESH From 490ac80080a4f233acba177c8a376afea26c7852 Mon Sep 17 00:00:00 2001 From: Sean Darcy Date: Mon, 19 May 2025 08:09:43 +1000 Subject: [PATCH 2/3] flag for disabling transfer --- scripts/deploy-investor-vesting.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/scripts/deploy-investor-vesting.js b/scripts/deploy-investor-vesting.js index fa8e6d3..f8b723d 100755 --- a/scripts/deploy-investor-vesting.js +++ b/scripts/deploy-investor-vesting.js @@ -19,6 +19,7 @@ const multiContributorAddress = "0x36Ee2Da54a7E727cC996A441826BBEdda6336B71"; // Configuration constants const SHOULD_VERIFY_CONTRACTS = true; +const SHOULD_TRANSFER_FUNDS = false; async function verifyContract(address, constructorArgs) { console.log(chalk.yellow("\nVerifying contract on Etherscan...")); @@ -92,6 +93,8 @@ async function main() { } const deployedContracts = []; + + const seshContract = await hre.ethers.getContractAt("SESH", seshAddress); // Deploy contracts for each investor for (const record of records) { @@ -140,13 +143,13 @@ async function main() { await verifyContract(vestingAddress, constructorArgs); } - - const seshContract = await hre.ethers.getContractAt("SESH", seshAddress); - const amount = hre.ethers.parseUnits(record.amount, 9); // Assuming 9 decimals for SESH - const transferTx = await seshContract.transfer(vestingAddress, amount); - await transferTx.wait(); - - console.log(chalk.green("Tokens transferred:"), chalk.yellow(record.amount), "SESH"); + if (SHOULD_TRANSFER_FUNDS) { + const amount = hre.ethers.parseUnits(record.amount, 9); // Assuming 9 decimals for SESH + const transferTx = await seshContract.transfer(vestingAddress, amount); + await transferTx.wait(); + + console.log(chalk.green("Tokens transferred:"), chalk.yellow(record.amount), "SESH"); + } deployedContracts.push({ beneficiary: record.beneficiary, From 34e8f3a167dd1cab0e7fbd0cd06b64c4265069a9 Mon Sep 17 00:00:00 2001 From: Sean Darcy Date: Mon, 19 May 2025 08:58:51 +1000 Subject: [PATCH 3/3] new script to transfer funds --- scripts/transfer-investor-tokens.js | 98 +++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 scripts/transfer-investor-tokens.js diff --git a/scripts/transfer-investor-tokens.js b/scripts/transfer-investor-tokens.js new file mode 100644 index 0000000..2dc6a1e --- /dev/null +++ b/scripts/transfer-investor-tokens.js @@ -0,0 +1,98 @@ +const hre = require("hardhat"); +const fs = require('fs'); +const chalk = require('chalk'); + +// Constants +const seshAddress = "0x6C9D6d6FB69927e3CED37374d820121c7c5b77e1"; +// Load this jsonFilePath based on what is output when running deploy-investor-vesting.js script. Its default +// output path is: `deployments/vesting-${networkName}-${Date.now()}.json` +const jsonFilePath = "./deployments/vesting-sepolia-1747608242040.json"; + +async function main() { + const [deployer] = await hre.ethers.getSigners(); + console.log("Transferring tokens with account:", chalk.yellow(deployer.address)); + + const networkName = hre.network.name; + console.log("Network:", chalk.cyan(networkName)); + console.log("SESH token address:", chalk.yellow(seshAddress)); + console.log("JSON file:", chalk.yellow(jsonFilePath)); + + if (!fs.existsSync(jsonFilePath)) { + console.error(chalk.red(`Error: JSON file not found at ${jsonFilePath}`)); + process.exit(1); + } + + if (!hre.ethers.isAddress(seshAddress)) { + console.error(chalk.red(`Error: Invalid SESH token address: ${seshAddress}`)); + process.exit(1); + } + + const fileContent = fs.readFileSync(jsonFilePath, 'utf8'); + let deployments; + + try { + deployments = JSON.parse(fileContent); + } catch (error) { + console.error(chalk.red(`Error parsing JSON file: ${error.message}`)); + process.exit(1); + } + + if (!deployments || !Array.isArray(deployments['contracts']) || deployments['contracts'].length === 0) { + console.error(chalk.red("Error: JSON file is empty or invalid")); + process.exit(1); + } + + const seshContract = await hre.ethers.getContractAt("SESH", seshAddress); + + const deployerBalance = await seshContract.balanceOf(deployer.address); + const totalRequired = deployments['contracts'].reduce((sum, deployment) => { + return sum + hre.ethers.parseUnits(deployment.amount, 9); // Assuming 9 decimals for SESH + }, 0n); + + console.log("Your balance:", chalk.yellow(hre.ethers.formatUnits(deployerBalance, 9)), "SESH"); + console.log("Total required:", chalk.yellow(hre.ethers.formatUnits(totalRequired, 9)), "SESH"); + + if (deployerBalance < totalRequired) { + console.error(chalk.red("Error: Insufficient SESH balance for transfers")); + console.error(`You have ${hre.ethers.formatUnits(deployerBalance, 9)} SESH, but need ${hre.ethers.formatUnits(totalRequired, 9)} SESH`); + process.exit(1); + } + + console.log(chalk.yellow("Starting transfers...\n")); + + let successful = 0; + let failed = 0; + + for (const deployment of deployments['contracts']) { + try { + if (!hre.ethers.isAddress(deployment['vestingAddress'])) { + throw new Error(`Invalid vesting contract address: ${deployment['vestingAddress']}`); + } + + const amount = hre.ethers.parseUnits(deployment['amount'], 9); // Assuming 9 decimals for SESH + console.log(chalk.cyan(`Transferring ${deployment['amount']} SESH to ${deployment['vestingAddress']}...`)); + + const transferTx = await seshContract.transfer(deployment['vestingAddress'], amount); + await transferTx.wait(); + + console.log(chalk.green("✓ Transfer successful! Tx hash:"), transferTx.hash); + successful++; + } catch (error) { + console.error(chalk.red(`Error transferring to ${deployment['vestingAddress']}:`), error.message); + failed++; + } + } + + console.log(chalk.cyan("\nTransfer Summary:")); + console.log("Total contracts:", chalk.yellow(deployments['contracts'].length)); + console.log("Successful:", chalk.green(successful)); + console.log("Failed:", failed > 0 ? chalk.red(failed) : chalk.green(failed)); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(chalk.red("Unhandled error:")); + console.error(error); + process.exit(1); + });