UNPKG

@gooddollar/goodprotocol

Version:
99 lines (90 loc) 3.59 kB
import { countBy, chunk, difference, flatten, sortBy } from "lodash"; import fs from "fs"; import { network, ethers, upgrades } from "hardhat"; import { Contract, Provider, setMulticallAddress } from "ethers-multicall"; import Identity from "../../artifacts/contracts/Interfaces.sol/IIdentity.json"; setMulticallAddress(122, "0x3CE6158b7278Bf6792e014FA7B4f3c6c46fe9410"); const CLAIM_START_BLOCK = 17896430; const fuseProvider = new ethers.providers.JsonRpcBatchProvider( "https://explorer-node.fuse.io/" // "https://rpc.fuse.io" ); const ethcallProvider = new Provider(fuseProvider, 122); const GD_FUSE = "0x495d133b938596c9984d462f007b676bdc57ecec"; const IDENTITY_FUSE = "0xFa8d865A962ca8456dF331D78806152d3aC5B84F"; let gd = new ethers.Contract( GD_FUSE, [ "event Transfer(address indexed from, address indexed to, uint amount)", "function balanceOf(address) view returns(uint256)" ], fuseProvider ); const gdMulti = new Contract(GD_FUSE, [ "event Transfer(address indexed from, address indexed to, uint amount)", "function balanceOf(address) view returns(uint256)" ]); const hasBalanceToRefund = async wallets => { const chunks = chunk(wallets, 1000); let balances = {}; for (let batch of chunks) { const calls = batch.map(a => gdMulti.balanceOf(a)); const result = await ethcallProvider.all(calls); console.log("batch:", batch.length, calls.length, result.length); batch.forEach((d, i) => (balances[d] = result[i])); } console.log("got balances for:", Object.entries(balances).length); const hasBalance = countBy(balances, v => v >= 9622260); const noBalance = Object.entries(balances).filter(([k, v]) => v < 9622260); console.log({ hasBalance }); return noBalance.map(_ => _[0]); }; const hasRefunded = async wallets => { const curBlock = (await gd.provider.getBlockNumber()) - 1; console.log({ curBlock }); let toBlock = CLAIM_START_BLOCK + 50000; let refunded = []; let startBlock = CLAIM_START_BLOCK; while (startBlock <= curBlock) { const events = await gd.queryFilter( gd.filters.Transfer(undefined, "0xd253A5203817225e9768C05E5996d642fb96bA86"), startBlock, toBlock ); const accounts = events.filter(e => e.args.amount >= 9622260).map(_ => _.args.from.toLowerCase()); refunded.push(...accounts); console.log("has refunded:", { startBlock, toBlock, accounts: accounts.length }); toBlock = Math.min(curBlock, toBlock + 50000); startBlock += 50000; } return refunded; }; const whereIsTheMoney = async noBalance => { let targets = []; for (let batch of chunk(noBalance, 100)) { const tos = await Promise.all( batch.map(async a => { const e = await gd.queryFilter(gd.filters.Transfer(a), CLAIM_START_BLOCK); const tos = e.filter(_ => _.args.amount > 1000000).map(_ => _.args.to); return tos; }) ); targets.push(...flatten(tos)); } const targetCounter = countBy(targets, _ => _); console.log("transfer targets:", sortBy(Object.entries(targetCounter), "1").reverse()); }; const main = async () => { const wallets = JSON.parse(fs.readFileSync("torefund.json").toString()).map(_ => _.toLowerCase()); console.log("Total Claimed:", wallets.length); const refunded = await hasRefunded(wallets); const notRefunded = difference(wallets, refunded); console.log("refunded:", refunded.length, "not refunded:", notRefunded.length); const noBalanceToRefund = await hasBalanceToRefund(notRefunded); await whereIsTheMoney(noBalanceToRefund); }; main().catch(e => console.log(e));