@@ -81,46 +81,33 @@ func runFunding(ctx context.Context) error {
8181 }()
8282 }
8383
84- // If ERC20 mode is enabled, fund with tokens instead of ETH
85- if params .TokenAddress != "" {
86- log .Info ().Str ("tokenAddress" , params .TokenAddress ).Msg ("Starting ERC20 token funding (ETH funding disabled)" )
87- if err = fundWalletsWithERC20 (ctx , c , tops , privateKey , addresses , privateKeys ); err != nil {
88- return err
89- }
90- log .Info ().Msg ("Wallet(s) funded with ERC20 tokens! 🪙" )
91- } else {
92- // Fund wallets.
93- log .Debug ().Msg ("checking if multicall3 is supported" )
94- var multicall3Addr * common.Address
95- if len (params .Multicall3Address ) > 0 {
96- addr := common .HexToAddress (params .Multicall3Address )
97- if addr == (common.Address {}) {
98- log .Warn ().
99- Str ("address" , params .Multicall3Address ).
100- Msg ("invalid multicall3 address provided, will try to detect or deploy multicall3" )
101- multicall3Addr = & addr
102- }
84+ // Fund wallets.
85+ log .Debug ().Msg ("checking if multicall3 is supported" )
86+ var multicall3Addr * common.Address
87+ if len (params .Multicall3Address ) > 0 {
88+ addr := common .HexToAddress (params .Multicall3Address )
89+ if addr == (common.Address {}) {
90+ log .Warn ().
91+ Str ("address" , params .Multicall3Address ).
92+ Msg ("invalid multicall3 address provided, will try to detect or deploy multicall3" )
93+ multicall3Addr = & addr
10394 }
95+ }
10496
105- multicall3Addr , _ = util .IsMulticall3Supported (ctx , c , true , tops , multicall3Addr )
106- if multicall3Addr != nil {
107- log .Info ().
108- Stringer ("address" , multicall3Addr ).
109- Msg ("multicall3 is supported and will be used to fund wallets" )
110- return fundWalletsWithMulticall3 (ctx , c , tops , addresses , multicall3Addr )
111- } else {
112- log .Info ().Msg ("multicall3 is not supported, will use funder contract to fund wallets" )
113- // Deploy or instantiate the Funder contract.
114- var contract * funder.Funder
115- contract , err = deployOrInstantiateFunderContract (ctx , c , tops , privateKey , len (addresses ))
116- if err != nil {
117- return err
118- }
119- if err = fundWallets (ctx , c , tops , contract , addresses ); err != nil {
120- return err
121- }
122- }
97+ multicall3Addr , _ = util .IsMulticall3Supported (ctx , c , true , tops , multicall3Addr )
98+ if multicall3Addr != nil {
99+ log .Info ().
100+ Stringer ("address" , multicall3Addr ).
101+ Msg ("multicall3 is supported and will be used to fund wallets" )
102+ err = fundWalletsWithMulticall3 (ctx , c , tops , addresses , multicall3Addr )
103+ } else {
104+ log .Info ().Msg ("multicall3 is not supported, will use funder contract to fund wallets" )
105+ err = fundWalletsWithFunder (ctx , c , tops , privateKey , addresses , privateKeys )
123106 }
107+ if err != nil {
108+ return err
109+ }
110+
124111 log .Info ().Msg ("Wallet(s) funded! 💸" )
125112
126113 log .Info ().Msgf ("Total execution time: %s" , time .Since (startTime ))
@@ -355,6 +342,29 @@ func fundWallets(ctx context.Context, c *ethclient.Client, tops *bind.TransactOp
355342 return nil
356343}
357344
345+ func fundWalletsWithFunder (ctx context.Context , c * ethclient.Client , tops * bind.TransactOpts , privateKey * ecdsa.PrivateKey , addresses []common.Address , privateKeys []* ecdsa.PrivateKey ) error {
346+ var err error
347+ // If ERC20 mode is enabled, fund with tokens instead of ETH
348+ if params .TokenAddress != "" {
349+ log .Info ().Str ("tokenAddress" , params .TokenAddress ).Msg ("Starting ERC20 token funding (ETH funding disabled)" )
350+ if err = fundWalletsWithERC20 (ctx , c , tops , privateKey , addresses , privateKeys ); err != nil {
351+ return err
352+ }
353+ log .Info ().Msg ("Wallet(s) funded with ERC20 tokens! 🪙" )
354+ } else {
355+ // Deploy or instantiate the Funder contract.
356+ var contract * funder.Funder
357+ contract , err = deployOrInstantiateFunderContract (ctx , c , tops , privateKey , len (addresses ))
358+ if err != nil {
359+ return err
360+ }
361+ if err = fundWallets (ctx , c , tops , contract , addresses ); err != nil {
362+ return err
363+ }
364+ }
365+ return nil
366+ }
367+
358368func fundWalletsWithMulticall3 (ctx context.Context , c * ethclient.Client , tops * bind.TransactOpts , wallets []common.Address , multicall3Addr * common.Address ) error {
359369 log .Debug ().
360370 Msg ("funding wallets with multicall3" )
@@ -370,7 +380,14 @@ func fundWalletsWithMulticall3(ctx context.Context, c *ethclient.Client, tops *b
370380 log .Debug ().Uint64 ("accsToFundPerTx" , accsToFundPerTx ).Msg ("multicall3 max accounts to fund per tx" )
371381 chSize := (uint64 (len (wallets )) / accsToFundPerTx ) + 1
372382
373- txsCh := make (chan * types.Transaction , chSize )
383+ var txsCh chan * types.Transaction
384+ if params .TokenAddress == "" {
385+ txsCh = make (chan * types.Transaction , chSize )
386+ } else {
387+ txsCh = make (chan * types.Transaction , chSize * 2 )
388+ }
389+
390+ errCh := make (chan error , chSize )
374391
375392 accs := []common.Address {}
376393 wg := sync.WaitGroup {}
@@ -390,16 +407,33 @@ func fundWalletsWithMulticall3(ctx context.Context, c *ethclient.Client, tops *b
390407 wg .Add (1 )
391408 go func (tops * bind.TransactOpts , accs []common.Address ) {
392409 defer wg .Done ()
410+ var iErr error
393411 if rl != nil {
394- err : = rl .Wait (ctx )
395- if err != nil {
396- log .Error ().Err (err ).Msg ("rate limiter wait failed before funding accounts with multicall3" )
412+ iErr = rl .Wait (ctx )
413+ if iErr != nil {
414+ log .Error ().Err (iErr ).Msg ("rate limiter wait failed before funding accounts with multicall3" )
397415 return
398416 }
399417 }
400- tx , err := util .Multicall3FundAccountsWithNativeToken (c , tops , accs , params .FundingAmountInWei , multicall3Addr )
401- if err != nil {
402- log .Error ().Err (err ).Msg ("failed to fund accounts with multicall3" )
418+ var tx * types.Transaction
419+ if params .TokenAddress != "" {
420+ tokenAddress := common .HexToAddress (params .TokenAddress )
421+ var txApprove * types.Transaction
422+ txApprove , tx , iErr = util .Multicall3FundAccountsWithERC20Token (ctx , c , tops , accs , tokenAddress , params .TokenAmount , multicall3Addr )
423+ if txApprove != nil {
424+ log .Info ().
425+ Stringer ("txHash" , txApprove .Hash ()).
426+ Int ("done" , i + 1 ).
427+ Uint64 ("of" , uint64 (len (wallets ))).
428+ Msg ("transaction to approve ERC20 token spending by multicall3 sent" )
429+ txsCh <- txApprove
430+ }
431+ } else {
432+ tx , iErr = util .Multicall3FundAccountsWithNativeToken (c , tops , accs , params .FundingAmountInWei , multicall3Addr )
433+ }
434+ if iErr != nil {
435+ errCh <- iErr
436+ log .Error ().Err (iErr ).Msg ("failed to fund accounts with multicall3" )
403437 return
404438 }
405439 log .Info ().
@@ -414,6 +448,21 @@ func fundWalletsWithMulticall3(ctx context.Context, c *ethclient.Client, tops *b
414448 }
415449 wg .Wait ()
416450 close (txsCh )
451+ close (errCh )
452+
453+ var combinedErrors error
454+ for len (errCh ) > 0 {
455+ err = <- errCh
456+ if combinedErrors == nil {
457+ combinedErrors = err
458+ } else {
459+ combinedErrors = errors .Join (combinedErrors , err )
460+ }
461+ }
462+ // return if there were errors sending the funding transactions
463+ if combinedErrors != nil {
464+ return combinedErrors
465+ }
417466
418467 log .Info ().Msg ("all funding transactions sent, waiting for confirmation..." )
419468
@@ -438,7 +487,7 @@ func fundWalletsWithMulticall3(ctx context.Context, c *ethclient.Client, tops *b
438487 }
439488 log .Info ().
440489 Stringer ("txHash" , tx .Hash ()).
441- Msg ("transaction to fund accounts confirmed" )
490+ Msg ("transaction confirmed" )
442491 }
443492
444493 return nil
0 commit comments