import Web3 from "web3"; import BigNumber from "bignumber.js" import { AbiItem } from 'web3-utils'; import { EthAddress, IStaker } from "./@types/staker"; import * as dotenv from "dotenv"; import { governanceAddress, governanceRewardsProposalBlock, hackBlock, oldStakingAddress } from "./config"; import GovernanceAbi from "../abi/GovernanceAbi.json"; import StakingAbi from "../abi/StakingABI.json"; dotenv.config(); const web3 = new Web3(process.env.MAINNET_RPC_URL as string); function getGovernanceFunctionSelector(functionName: string): string { const lockFunctionAbi = GovernanceAbi.find(item => item.name == functionName); if (!lockFunctionAbi) throw new Error(`Cannot find function ${functionName} in Governance contract ABI`); const selector = web3.eth.abi.encodeFunctionSignature(lockFunctionAbi as AbiItem); return selector; } async function getAddressesStakersWithProssibleRewards(): Promise> { const governanceContract = new web3.eth.Contract(GovernanceAbi as AbiItem[], governanceAddress); /* Don't need to fetch all "lock" or "lockAndApproval" transactions from Governance contract, * because user rewards start updating only when RewardUpdateSuccessful events is emitted. */ const rewardsUpdateEvents = await governanceContract.getPastEvents("RewardUpdateSuccessful", { fromBlock: governanceRewardsProposalBlock }); const governanceStakers = rewardsUpdateEvents.map(event => event.returnValues.account as string); return [...new Set(governanceStakers)]; } export async function getStakersWithRewardsBeforeHack(): Promise> { const stakingContract = new web3.eth.Contract(StakingAbi as AbiItem[], oldStakingAddress); const stakersAddresses = await getAddressesStakersWithProssibleRewards(); let stakersWithRewardsBeforeHack: Array = []; for (const address of stakersAddresses) { // Check stakers rewards on previous block before hack const rewardsBeforeHack = await stakingContract.methods.checkReward(address).call({}, hackBlock - 1); // Discard stakers with rewards less than 1 TORN, because accruing each reward requires paying gas if (BigNumber(rewardsBeforeHack).div(1e18).isGreaterThan(1)) stakersWithRewardsBeforeHack.push({ address, rewardBalance: BigNumber(rewardsBeforeHack) }); } return stakersWithRewardsBeforeHack; }