11import { nextTick } from "node:process" ;
22
3- import { chains , PERCENTAGE_FACTOR } from "@gearbox-protocol/sdk" ;
3+ import { chains , formatBN , PERCENTAGE_FACTOR } from "@gearbox-protocol/sdk" ;
44import type {
55 AnvilClient ,
66 AnvilNodeInfo ,
@@ -14,6 +14,7 @@ import type {
1414 ContractFunctionArgs ,
1515 ContractFunctionName ,
1616 EncodeFunctionDataParameters ,
17+ FeeValuesEIP1559 ,
1718 PrivateKeyAccount ,
1819 PublicClient ,
1920 SimulateContractParameters ,
@@ -68,6 +69,8 @@ export default class Client {
6869
6970 #balance?: { value : bigint ; status : StatusCode } ;
7071
72+ #gasFees: { maxFeePerGas ?: bigint ; maxPriorityFeePerGas ?: bigint } = { } ;
73+
7174 public async launch ( ) : Promise < void > {
7275 const { chainId, network, optimistic, privateKey, pollingInterval } =
7376 this . config ;
@@ -110,23 +113,27 @@ export default class Client {
110113 this . logger . debug ( "running on real rpc" ) ;
111114 }
112115 await this . #checkBalance( ) ;
116+ if ( this . config . optimistic ) {
117+ this . #gasFees = await this . pub . estimateFeesPerGas ( ) ;
118+ this . logger . debug ( this . #gasFees, "optimistic gas fees" ) ;
119+ }
113120 }
114121
115122 public async liquidate (
116123 request : SimulateContractReturnType [ "request" ] ,
117- logger : ILogger ,
118124 ) : Promise < TransactionReceipt > {
119125 if ( this . config . dryRun && ! this . config . optimistic ) {
120126 throw new Error ( "dry run mode" ) ;
121127 }
122- logger . debug ( "sending liquidation tx" ) ;
128+ this . logger . debug ( "sending liquidation tx" ) ;
123129 const { abi, address, args, dataSuffix, functionName, ...rest } = request ;
124130 const data = encodeFunctionData ( {
125131 abi,
126132 args,
127133 functionName,
128134 } as EncodeFunctionDataParameters ) ;
129135 const req = await this . wallet . prepareTransactionRequest ( {
136+ ...( this . #gasFees as any ) ,
130137 ...rest ,
131138 to : request . address ,
132139 data,
@@ -135,25 +142,39 @@ export default class Client {
135142 if ( maxPriorityFeePerGas && maxFeePerGas ) {
136143 req . maxPriorityFeePerGas = 10n * maxPriorityFeePerGas ;
137144 req . maxFeePerGas = 2n * maxFeePerGas + req . maxPriorityFeePerGas ;
138- logger . debug (
139- {
140- maxFeePerGas : req . maxFeePerGas ,
141- maxPriorityFeePerGas : req . maxPriorityFeePerGas ,
142- } ,
143- `increase gas fees` ,
144- ) ;
145145 }
146146 if ( gas ) {
147147 req . gas = ( gas * ( GAS_X + PERCENTAGE_FACTOR ) ) / PERCENTAGE_FACTOR ;
148148 }
149+ const txCost = req . gas * req . maxFeePerGas + ( req . value ?? 0n ) ;
150+ this . logger . debug (
151+ {
152+ maxFeePerGas : req . maxFeePerGas ,
153+ maxPriorityFeePerGas : req . maxPriorityFeePerGas ,
154+ gas : req . gas ,
155+ txCost,
156+ } ,
157+ `increase gas fees` ,
158+ ) ;
159+
160+ if ( this . #balance && txCost > this . #balance. value ) {
161+ this . logger . warn (
162+ {
163+ txCost,
164+ balance : this . #balance. value ,
165+ } ,
166+ `transaction cost ${ formatBN ( txCost , 18 ) } exceeds balance (${ formatBN ( this . #balance. value , 18 ) } ETH)` ,
167+ ) ;
168+ }
169+
149170 const serializedTransaction = await this . wallet . signTransaction ( req ) ;
150171 const hash = await this . wallet . sendRawTransaction ( {
151172 serializedTransaction,
152173 } ) ;
153174 const { data : _data , to, value, account, ...params } = req ;
154- logger . debug ( { hash, ...params } , "sent transaction" ) ;
175+ this . logger . debug ( { hash, ...params } , "sent transaction" ) ;
155176 const receipt = await this . #waitForTransactionReceipt( hash ) ;
156- logger . debug ( { hash, status : receipt . status } , "received receipt" ) ;
177+ this . logger . debug ( { hash, status : receipt . status } , "received receipt" ) ;
157178 if ( ! this . config . optimistic ) {
158179 nextTick ( ( ) => {
159180 this . #checkBalance( ) . catch ( ( ) => { } ) ;
0 commit comments