Bug: `getBalance` uses default denom instead of `gasPrice` denom for multi-token chains
Description:
On chains with multiple gas tokens (e.g., AtomOne), the current implementation of getBalance uses this.network.denom to query the bot's balance. However, if the script is configured to use a different gas token (e.g., uphoton) via the gasPrice setting, the balance check may incorrectly fail, assuming there are insufficient funds - even if the bot holds sufficient balance in the correct denom (uphoton).
This issue prevents the autostake script from running, as it falsely assumes the bot does not have enough tokens to cover gas fees.
Steps to Reproduce:
- Configure the bot with a gas price like
0.225uphotonon a chain that supports multiple gas tokens (e.g. AtomOne). - Ensure the bot has a sufficient
uphotonbalance but a low or zero balance in the default denom (uatone). - Attempt to run the autostake script.
Expected Behavior:
The bot should query its balance in the denom defined by gasPrice (i.e., uphoton) and proceed if it has enough balance.
Actual Behavior:
The bot queries the balance in uatone (default denom), fails the check, and halts the script with "Bot balance is too low" error.
Proposed Solution:
I am not submitting a PR yet, because I am not familiar with the codebase and don't want to break things for others, but here is what worked on my case:
- Add support for
gasPricedenom extraction inNetwork.mjs:
https://github.com/eco-stake/restake/blob/0ad04908fa9a77feaa3aa8537451d350d27239c1/src/utils/Network.mjs#L93-L100
if(this.gasPrice){
this.gasPriceAmount = GasPrice.fromString(this.gasPrice).amount.toString()
this.gasPriceStep = this.data.gasPriceStep || {
"low": multiply(this.gasPriceAmount, 0.5),
"average": multiply(this.gasPriceAmount, 1),
"high": multiply(this.gasPriceAmount, 2)
}
+ this.gasPriceDenom = GasPrice.fromString(this.gasPrice).denom
}
- Update
getBalanceinNetworkRunner.mjsto use it:
https://github.com/eco-stake/restake/blob/0ad04908fa9a77feaa3aa8537451d350d27239c1/src/autostake/NetworkRunner.mjs#L83-L95
getBalance() {
let timeout = this.opts.delegationsTimeout
+ return this.queryClient.getBalance(this.operator.botAddress, this.network.gasPriceDenom || this.network.denom, { timeout })
.then(
(balance) => {
this.logger.info('Fetched bot balance', balance)
return balance.amount
},
(error) => {
throw new Error(`Failed to get balance: ${error.message || error}`)
}
)
}