11import { ChainId , RPParams } from "sushi" ;
22import { BigNumber , ethers } from "ethers" ;
3+ import { estimateGasCost , getTxFee } from "./gas" ;
34import { ErrorSeverity , errorSnapshot } from "./error" ;
45import { Native , Token , WNATIVE } from "sushi/currency" ;
56import { ROUTE_PROCESSOR_4_ADDRESS } from "sushi/config" ;
@@ -8,8 +9,15 @@ import { createViemClient, getDataFetcher } from "./config";
89import { mnemonicToAccount , privateKeyToAccount } from "viem/accounts" ;
910import { erc20Abi , multicall3Abi , orderbookAbi , routeProcessor3Abi } from "./abis" ;
1011import { context , Context , SpanStatusCode , trace , Tracer } from "@opentelemetry/api" ;
11- import { BotConfig , CliOptions , ViemClient , TokenDetails , OwnedOrder } from "./types" ;
1212import { parseAbi , hexToNumber , numberToHex , PublicClient , NonceManagerSource } from "viem" ;
13+ import {
14+ BotConfig ,
15+ CliOptions ,
16+ ViemClient ,
17+ OwnedOrder ,
18+ TokenDetails ,
19+ OperationState ,
20+ } from "./types" ;
1321
1422/** Standard base path for eth accounts */
1523export const BasePath = "m/44'/60'/0'/0/" as const ;
@@ -112,9 +120,7 @@ export async function initAccounts(
112120 confirmations : 4 ,
113121 timeout : 100_000 ,
114122 } ) ;
115- const txCost = ethers . BigNumber . from ( receipt . effectiveGasPrice ) . mul (
116- receipt . gasUsed ,
117- ) ;
123+ const txCost = ethers . BigNumber . from ( getTxFee ( receipt , config ) ) ;
118124 if ( receipt . status === "success" ) {
119125 accounts [ i ] . BALANCE = topupAmountBn ;
120126 mainAccount . BALANCE =
@@ -151,6 +157,7 @@ export async function manageAccounts(
151157 avgGasCost : BigNumber ,
152158 lastIndex : number ,
153159 wgc : ViemClient [ ] ,
160+ state : OperationState ,
154161 tracer ?: Tracer ,
155162 ctx ?: Context ,
156163) {
@@ -159,11 +166,11 @@ export async function manageAccounts(
159166 for ( let i = config . accounts . length - 1 ; i >= 0 ; i -- ) {
160167 if ( config . accounts [ i ] . BALANCE . lt ( avgGasCost . mul ( 4 ) ) ) {
161168 try {
162- const gasPrice = await config . viemClient . getGasPrice ( ) ;
163169 await sweepToMainWallet (
164170 config . accounts [ i ] ,
165171 config . mainAccount ,
166- gasPrice ,
172+ state ,
173+ config ,
167174 tracer ,
168175 ctx ,
169176 ) ;
@@ -256,9 +263,7 @@ export async function manageAccounts(
256263 confirmations : 4 ,
257264 timeout : 100_000 ,
258265 } ) ;
259- const txCost = ethers . BigNumber . from ( receipt . effectiveGasPrice ) . mul (
260- receipt . gasUsed ,
261- ) ;
266+ const txCost = ethers . BigNumber . from ( getTxFee ( receipt , config ) ) ;
262267 if ( receipt . status === "success" ) {
263268 accountsToAdd -- ;
264269 acc . BALANCE = topupAmountBN ;
@@ -476,10 +481,12 @@ export async function getBatchTokenBalanceForAccount(
476481export async function sweepToMainWallet (
477482 fromWallet : ViemClient ,
478483 toWallet : ViemClient ,
479- gasPrice : bigint ,
484+ state : OperationState ,
485+ config : BotConfig ,
480486 tracer ?: Tracer ,
481487 ctx ?: Context ,
482488) {
489+ const gasPrice = state . gasPrice ;
483490 const mainSpan = tracer ?. startSpan ( "sweep-wallet-funds" , undefined , ctx ) ;
484491 const mainCtx = mainSpan ? trace . setSpan ( context . active ( ) , mainSpan ) : undefined ;
485492 mainSpan ?. setAttribute ( "details.wallet" , fromWallet . account . address ) ;
@@ -488,7 +495,6 @@ export async function sweepToMainWallet(
488495 fromWallet . BOUNTY . map ( ( v ) => v . symbol ) ,
489496 ) ;
490497
491- gasPrice = ethers . BigNumber . from ( gasPrice ) . mul ( 107 ) . div ( 100 ) . toBigInt ( ) ;
492498 const erc20 = new ethers . utils . Interface ( erc20Abi ) ;
493499 const txs : {
494500 bounty : TokenDetails ;
@@ -499,7 +505,7 @@ export async function sweepToMainWallet(
499505 } ;
500506 } [ ] = [ ] ;
501507 const failedBounties : TokenDetails [ ] = [ ] ;
502- let cumulativeGasLimit = ethers . constants . Zero ;
508+ let cumulativeGas = ethers . constants . Zero ;
503509 for ( let i = 0 ; i < fromWallet . BOUNTY . length ; i ++ ) {
504510 const bounty = fromWallet . BOUNTY [ i ] ;
505511 try {
@@ -517,29 +523,28 @@ export async function sweepToMainWallet(
517523 continue ;
518524 }
519525 const tx = {
526+ gasPrice,
520527 to : bounty . address as `0x${string } `,
521528 data : erc20 . encodeFunctionData ( "transfer" , [
522529 toWallet . account . address ,
523530 balance ,
524531 ] ) as `0x${string } `,
525532 } ;
526- const gas = await fromWallet . estimateGas ( tx ) ;
533+ // const gas = await fromWallet.estimateGas(tx);
534+ const gas = ( await estimateGasCost ( tx , fromWallet , config , state . l1GasPrice ) )
535+ . totalGasCost ;
527536 txs . push ( { tx, bounty, balance : ethers . utils . formatUnits ( balance , bounty . decimals ) } ) ;
528- cumulativeGasLimit = cumulativeGasLimit . add ( gas ) ;
537+ cumulativeGas = cumulativeGas . add ( gas ) ;
529538 } catch {
530539 addWatchedToken ( bounty , failedBounties ) ;
531540 }
532541 }
533542
534- if ( cumulativeGasLimit . mul ( gasPrice ) . mul ( 125 ) . div ( 100 ) . gt ( fromWallet . BALANCE ) ) {
543+ if ( cumulativeGas . mul ( 125 ) . div ( 100 ) . gt ( fromWallet . BALANCE ) ) {
535544 const span = tracer ?. startSpan ( "fund-wallet-to-sweep" , undefined , mainCtx ) ;
536545 span ?. setAttribute ( "details.wallet" , fromWallet . account . address ) ;
537546 try {
538- const transferAmount = cumulativeGasLimit
539- . mul ( gasPrice )
540- . mul ( 125 )
541- . div ( 100 )
542- . sub ( fromWallet . BALANCE ) ;
547+ const transferAmount = cumulativeGas . mul ( 125 ) . div ( 100 ) . sub ( fromWallet . BALANCE ) ;
543548 span ?. setAttribute ( "details.amount" , ethers . utils . formatUnits ( transferAmount ) ) ;
544549 const hash = await toWallet . sendTx ( {
545550 to : fromWallet . account . address ,
@@ -550,7 +555,7 @@ export async function sweepToMainWallet(
550555 confirmations : 4 ,
551556 timeout : 100_000 ,
552557 } ) ;
553- const txCost = ethers . BigNumber . from ( receipt . effectiveGasPrice ) . mul ( receipt . gasUsed ) ;
558+ const txCost = ethers . BigNumber . from ( getTxFee ( receipt , config ) ) ;
554559 if ( receipt . status === "success" ) {
555560 span ?. setStatus ( {
556561 code : SpanStatusCode . OK ,
@@ -592,7 +597,7 @@ export async function sweepToMainWallet(
592597 confirmations : 4 ,
593598 timeout : 100_000 ,
594599 } ) ;
595- const txCost = ethers . BigNumber . from ( receipt . effectiveGasPrice ) . mul ( receipt . gasUsed ) ;
600+ const txCost = ethers . BigNumber . from ( getTxFee ( receipt , config ) ) ;
596601 if ( receipt . status === "success" ) {
597602 if ( ! toWallet . BOUNTY . find ( ( v ) => v . address === txs [ i ] . bounty . address ) ) {
598603 toWallet . BOUNTY . push ( txs [ i ] . bounty ) ;
@@ -626,32 +631,31 @@ export async function sweepToMainWallet(
626631 const span = tracer ?. startSpan ( "sweep-remaining-gas-to-main-wallet" , undefined , mainCtx ) ;
627632 span ?. setAttribute ( "details.wallet" , fromWallet . account . address ) ;
628633 try {
629- const gasLimit = ethers . BigNumber . from (
630- await fromWallet . estimateGas ( {
631- to : toWallet . account . address ,
632- value : 0n ,
633- } ) ,
634+ const estimation = await estimateGasCost (
635+ { to : toWallet . account . address , value : 0n , gasPrice } as any ,
636+ fromWallet ,
637+ config ,
638+ state . l1GasPrice ,
634639 ) ;
640+
635641 const remainingGas = ethers . BigNumber . from (
636642 await fromWallet . getBalance ( { address : fromWallet . account . address } ) ,
637643 ) ;
638- const transferAmount = remainingGas . sub ( gasLimit . mul ( gasPrice ) ) ;
644+ const transferAmount = remainingGas . sub ( estimation . totalGasCost ) ;
639645 if ( transferAmount . gt ( 0 ) ) {
640646 span ?. setAttribute ( "details.amount" , ethers . utils . formatUnits ( transferAmount ) ) ;
641647 const hash = await fromWallet . sendTx ( {
642648 gasPrice,
643649 to : toWallet . account . address ,
644650 value : transferAmount . toBigInt ( ) ,
645- gas : gasLimit . toBigInt ( ) ,
651+ gas : estimation . gas ,
646652 } ) ;
647653 const receipt = await fromWallet . waitForTransactionReceipt ( {
648654 hash,
649655 confirmations : 4 ,
650656 timeout : 100_000 ,
651657 } ) ;
652- const txCost = ethers . BigNumber . from ( receipt . effectiveGasPrice ) . mul (
653- receipt . gasUsed ,
654- ) ;
658+ const txCost = ethers . BigNumber . from ( getTxFee ( receipt , config ) ) ;
655659 if ( receipt . status === "success" ) {
656660 toWallet . BALANCE = toWallet . BALANCE . add ( transferAmount ) ;
657661 fromWallet . BALANCE = fromWallet . BALANCE . sub ( txCost ) . sub ( transferAmount ) ;
@@ -691,16 +695,19 @@ export async function sweepToMainWallet(
691695 * Sweep bot's bounties to eth
692696 * @param config - The config obj
693697 */
694- export async function sweepToEth ( config : BotConfig , tracer ?: Tracer , ctx ?: Context ) {
698+ export async function sweepToEth (
699+ config : BotConfig ,
700+ state : OperationState ,
701+ tracer ?: Tracer ,
702+ ctx ?: Context ,
703+ ) {
695704 const skipped : TokenDetails [ ] = [ ] ;
696705 const rp4Address = ROUTE_PROCESSOR_4_ADDRESS [
697706 config . chain . id as keyof typeof ROUTE_PROCESSOR_4_ADDRESS
698707 ] as `0x${string } `;
699708 const rp = new ethers . utils . Interface ( routeProcessor3Abi ) ;
700709 const erc20 = new ethers . utils . Interface ( erc20Abi ) ;
701- const gasPrice = ethers . BigNumber . from ( await config . mainAccount . getGasPrice ( ) )
702- . mul ( 107 )
703- . div ( 100 ) ;
710+ const gasPrice = ethers . BigNumber . from ( state . gasPrice ) ;
704711 for ( let i = 0 ; i < config . mainAccount . BOUNTY . length ; i ++ ) {
705712 const bounty = config . mainAccount . BOUNTY [ i ] ;
706713 const span = tracer ?. startSpan ( "sweep-to-gas" , undefined , ctx ) ;
@@ -906,30 +913,15 @@ export function addWatchedToken(
906913export async function fundOwnedOrders (
907914 ownedOrders : OwnedOrder [ ] ,
908915 config : BotConfig ,
916+ state : OperationState ,
909917) : Promise < { ownedOrder ?: OwnedOrder ; error : string } [ ] > {
910918 const failedFundings : { ownedOrder ?: OwnedOrder ; error : string } [ ] = [ ] ;
911919 const ob = new ethers . utils . Interface ( orderbookAbi ) ;
912920 const erc20 = new ethers . utils . Interface ( erc20Abi ) ;
913921 const rp = new ethers . utils . Interface ( routeProcessor3Abi ) ;
914922 const rp4Address =
915923 ROUTE_PROCESSOR_4_ADDRESS [ config . chain . id as keyof typeof ROUTE_PROCESSOR_4_ADDRESS ] ;
916- let gasPrice : BigNumber ;
917- for ( let i = 0 ; i < 4 ; i ++ ) {
918- try {
919- gasPrice = ethers . BigNumber . from ( await config . viemClient . getGasPrice ( ) )
920- . mul ( 107 )
921- . div ( 100 ) ;
922- break ;
923- } catch ( e ) {
924- if ( i == 3 )
925- return [
926- {
927- error : errorSnapshot ( "failed to get gas price" , e ) ,
928- } ,
929- ] ;
930- else await sleep ( 10000 * ( i + 1 ) ) ;
931- }
932- }
924+ const gasPrice = ethers . BigNumber . from ( state . gasPrice ) ;
933925 if ( config . selfFundOrders ) {
934926 for ( let i = 0 ; i < ownedOrders . length ; i ++ ) {
935927 const ownedOrder = ownedOrders [ i ] ;
@@ -973,7 +965,7 @@ export async function fundOwnedOrders(
973965 config . mainAccount . account . address ,
974966 rp4Address ,
975967 config . dataFetcher ,
976- gasPrice ! ,
968+ gasPrice ,
977969 ) ;
978970 const initSellAmount = ethers . BigNumber . from ( route . amountOutBI ) ;
979971 let sellAmount : BigNumber ;
@@ -988,7 +980,7 @@ export async function fundOwnedOrders(
988980 config . mainAccount . account . address ,
989981 rp4Address ,
990982 config . dataFetcher ,
991- gasPrice ! ,
983+ gasPrice ,
992984 ) ;
993985 if ( topupAmount . lte ( route . amountOutBI ) ) {
994986 finalRpParams = rpParams ;
@@ -1013,9 +1005,7 @@ export async function fundOwnedOrders(
10131005 confirmations : 4 ,
10141006 timeout : 100_000 ,
10151007 } ) ;
1016- const swapTxCost = ethers . BigNumber . from (
1017- swapReceipt . effectiveGasPrice ,
1018- ) . mul ( swapReceipt . gasUsed ) ;
1008+ const swapTxCost = ethers . BigNumber . from ( getTxFee ( swapReceipt , config ) ) ;
10191009 config . mainAccount . BALANCE = config . mainAccount . BALANCE . sub ( swapTxCost ) ;
10201010 if ( swapReceipt . status === "success" ) {
10211011 config . mainAccount . BALANCE = config . mainAccount . BALANCE . sub (
@@ -1050,8 +1040,8 @@ export async function fundOwnedOrders(
10501040 timeout : 100_000 ,
10511041 } ) ;
10521042 const approveTxCost = ethers . BigNumber . from (
1053- approveReceipt . effectiveGasPrice ,
1054- ) . mul ( approveReceipt . gasUsed ) ;
1043+ getTxFee ( approveReceipt , config ) ,
1044+ ) ;
10551045 config . mainAccount . BALANCE =
10561046 config . mainAccount . BALANCE . sub ( approveTxCost ) ;
10571047 if ( approveReceipt . status === "reverted" ) {
@@ -1073,9 +1063,7 @@ export async function fundOwnedOrders(
10731063 confirmations : 4 ,
10741064 timeout : 100_000 ,
10751065 } ) ;
1076- const txCost = ethers . BigNumber . from ( receipt . effectiveGasPrice ) . mul (
1077- receipt . gasUsed ,
1078- ) ;
1066+ const txCost = ethers . BigNumber . from ( getTxFee ( receipt , config ) ) ;
10791067 config . mainAccount . BALANCE = config . mainAccount . BALANCE . sub ( txCost ) ;
10801068 if ( receipt . status === "success" ) {
10811069 ownedOrder . vaultBalance = ownedOrder . vaultBalance . add ( topupAmount ) ;
0 commit comments