const [ signer ] = await hre . ethers . getSigners ();
" 0x4f2040FEaAD8b19E254006153E7BBB0674F4DaE3 " , // token0
" 0x7464f84F2c6686b6365a373E8FB7c15741e07275 " ,
" 0x677b7FfE9435735F2b1CEE325527e9268CD011F2 " ,
" 0xa0aC0f7A8726351beF090B6966aA77E07cF0Fb15 " ,
const multicallABI = [{ " type " : " function " , " stateMutability " : " payable " , " outputs " :[{ " type " : " uint256 " , " name " : " blockNumber " , " internalType " : " uint256 " },{ " type " : " bytes[] " , " name " : " returnData " , " internalType " : " bytes[] " }], " name " : " aggregate " , " inputs " :[{ " type " : " tuple[] " , " name " : " calls " , " internalType " : " struct Multicall3.Call[] " , " components " :[{ " type " : " address " , " name " : " target " , " internalType " : " address " },{ " type " : " bytes " , " name " : " callData " , " internalType " : " bytes " }]}]},{ " type " : " function " , " stateMutability " : " payable " , " outputs " :[{ " type " : " tuple[] " , " name " : " returnData " , " internalType " : " struct Multicall3.Result[] " , " components " :[{ " type " : " bool " , " name " : " success " , " internalType " : " bool " },{ " type " : " bytes " , " name " : " returnData " , " internalType " : " bytes " }]}], " name " : " aggregate3 " , " inputs " :[{ " type " : " tuple[] " , " name " : " calls " , " internalType " : " struct Multicall3.Call3[] " , " components " :[{ " type " : " address " , " name " : " target " , " internalType " : " address " },{ " type " : " bool " , " name " : " allowFailure " , " internalType " : " bool " },{ " type " : " bytes " , " name " : " callData " , " internalType " : " bytes " }]}]},{ " type " : " function " , " stateMutability " : " payable " , " outputs " :[{ " type " : " tuple[] " , " name " : " returnData " , " internalType " : " struct Multicall3.Result[] " , " components " :[{ " type " : " bool " , " name " : " success " , " internalType " : " bool " },{ " type " : " bytes " , " name " : " returnData " , " internalType " : " bytes " }]}], " name " : " aggregate3Value " , " inputs " :[{ " type " : " tuple[] " , " name " : " calls " , " internalType " : " struct Multicall3.Call3Value[] " , " components " :[{ " type " : " address " , " name " : " target " , " internalType " : " address " },{ " type " : " bool " , " name " : " allowFailure " , " internalType " : " bool " },{ " type " : " uint256 " , " name " : " value " , " internalType " : " uint256 " },{ " type " : " bytes " , " name " : " callData " , " internalType " : " bytes " }]}]},{ " type " : " function " , " stateMutability " : " payable " , " outputs " :[{ " type " : " uint256 " , " name " : " blockNumber " , " internalType " : " uint256 " },{ " type " : " bytes32 " , " name " : " blockHash " , " internalType " : " bytes32 " },{ " type " : " tuple[] " , " name " : " returnData " , " internalType " : " struct Multicall3.Result[] " , " components " :[{ " type " : " bool " , " name " : " success " , " internalType " : " bool " },{ " type " : " bytes " , " name " : " returnData " , " internalType " : " bytes " }]}], " name " : " blockAndAggregate " , " inputs " :[{ " type " : " tuple[] " , " name " : " calls " , " internalType " : " struct Multicall3.Call[] " , " components " :[{ " type " : " address " , " name " : " target " , " internalType " : " address " },{ " type " : " bytes " , " name " : " callData " , " internalType " : " bytes " }]}]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " uint256 " , " name " : " basefee " , " internalType " : " uint256 " }], " name " : " getBasefee " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " bytes32 " , " name " : " blockHash " , " internalType " : " bytes32 " }], " name " : " getBlockHash " , " inputs " :[{ " type " : " uint256 " , " name " : " blockNumber " , " internalType " : " uint256 " }]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " uint256 " , " name " : " blockNumber " , " internalType " : " uint256 " }], " name " : " getBlockNumber " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " uint256 " , " name " : " chainid " , " internalType " : " uint256 " }], " name " : " getChainId " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " address " , " name " : " coinbase " , " internalType " : " address " }], " name " : " getCurrentBlockCoinbase " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " uint256 " , " name " : " difficulty " , " internalType " : " uint256 " }], " name " : " getCurrentBlockDifficulty " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " uint256 " , " name " : " gaslimit " , " internalType " : " uint256 " }], " name " : " getCurrentBlockGasLimit " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " uint256 " , " name " : " timestamp " , " internalType " : " uint256 " }], " name " : " getCurrentBlockTimestamp " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " uint256 " , " name " : " balance " , " internalType " : " uint256 " }], " name " : " getEthBalance " , " inputs " :[{ " type " : " address " , " name " : " addr " , " internalType " : " address " }]},{ " type " : " function " , " stateMutability " : " view " , " outputs " :[{ " type " : " bytes32 " , " name " : " blockHash " , " internalType " : " bytes32 " }], " name " : " getLastBlockHash " , " inputs " :[]},{ " type " : " function " , " stateMutability " : " payable " , " outputs " :[{ " type " : " tuple[] " , " name " : " returnData " , " internalType " : " struct Multicall3.Result[] " , " components " :[{ " type " : " bool " , " name " : " success " , " internalType " : " bool " },{ " type " : " bytes " , " name " : " returnData " , " internalType " : " bytes " }]}], " name " : " tryAggregate " , " inputs " :[{ " type " : " bool " , " name " : " requireSuccess " , " internalType " : " bool " },{ " type " : " tuple[] " , " name " : " calls " , " internalType " : " struct Multicall3.Call[] " , " components " :[{ " type " : " address " , " name " : " target " , " internalType " : " address " },{ " type " : " bytes " , " name " : " callData " , " internalType " : " bytes " }]}]},{ " type " : " function " , " stateMutability " : " payable " , " outputs " :[{ " type " : " uint256 " , " name " : " blockNumber " , " internalType " : " uint256 " },{ " type " : " bytes32 " , " name " : " blockHash " , " internalType " : " bytes32 " },{ " type " : " tuple[] " , " name " : " returnData " , " internalType " : " struct Multicall3.Result[] " , " components " :[{ " type " : " bool " , " name " : " success " , " internalType " : " bool " },{ " type " : " bytes " , " name " : " returnData " , " internalType " : " bytes " }]}], " name " : " tryBlockAndAggregate " , " inputs " :[{ " type " : " bool " , " name " : " requireSuccess " , " internalType " : " bool " },{ " type " : " tuple[] " , " name " : " calls " , " internalType " : " struct Multicall3.Call[] " , " components " :[{ " type " : " address " , " name " : " target " , " internalType " : " address " },{ " type " : " bytes " , " name " : " callData " , " internalType " : " bytes " }]}]}];
const multicallAddress = " 0xcA11bde05977b3631167028862bE2a173976CA11 " ;
const multicall = new hre . ethers . Contract (multicallAddress , multicallABI , signer);
const contracts = tokens . map ( ( addr : string ) => new hre . ethers . Contract (addr , abi , signer));
const balances = await Promise . all (contracts . map ( ( contract ) => {
return contract . balanceOf (signer . address ) ;
const allowances = await Promise . all (contracts . map ( ( contract ) => {
return contract . allowance (signer . address , multicallAddress) ;
for ( let i = 0 ; i < contracts . length ; i ++ ) {
if (allowances[i] . toString () !== balances[i] . toString ()) {
await contracts[i] . approve (multicallAddress, balances[i]);
/** Creating Random Wallets for Distribution **/
new hre . ethers . Wallet . createRandom (),
new hre . ethers . Wallet . createRandom (),
new hre . ethers . Wallet . createRandom (),
new hre . ethers . Wallet . createRandom (),
new hre . ethers . Wallet . createRandom (),
let distributionCalls = [];
contracts . forEach ( ( contract , index ) => {
wallets . forEach ( ( wallet , index2 ) => {
contract . interface . encodeFunctionData ( " transferFrom " , [signer . address , wallet . address , 1 ])
const results = await multicall . aggregate3 (distributionCalls);