After just e2e-deploy, the automated trader exits immediately with a zero-balance error even though the trading account holds collateral. The failure is a balance-view mismatch on Nibiru’s multi-VM token model, not an unfunded account.
What happens
Running go run ./cmd/trader auto --config auto-trader.localnet.json (via just run-auto-localnet) loads the auto-trader config, performs a health check, then stops:
Balance is zero, stopping automated trading
Error: auto trading: balance is zero for collateral denom tf/nibi1zaavvzxez0elundtn32qnk9lkm8kmcsz44g7xl/stnibi, fund this address nibi1cr6tg4cjvux00pj6zjqkh6d0jzg7mksaywxyl3
The health-check log shows balance_tf/.../stnibi=0 for account nibi1cr6tg4cjvux00pj6zjqkh6d0jzg7mksaywxyl3.
Why this is misleading
On Nibiru, a FunToken-mapped collateral like stNIBI exists in two representations: a Cosmos bank coin (tf/.../stnibi) and an EVM ERC-20 at a mapped contract address. Sai EVM trading spends collateral through the EVM path; holding only the ERC-20 form is valid.
The E2E deploy funds the validator-derived EVM account (0xC0f4b45712670cf7865A14816bE9Af9091EDdA1d, bech32 nibi1cr6tg4cjvux00pj6zjqkh6d0jzg7mksaywxyl3) with ERC-20 stNIBI, not bank coins. nibid q evm balance confirms the split:
{
"addr_evm": "0xC0f4b45712670cf7865A14816bE9Af9091EDdA1d",
"addr_bech32": "nibi1cr6tg4cjvux00pj6zjqkh6d0jzg7mksaywxyl3",
"erc20_addr": "0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6",
"erc20_symbol": "stNIBI",
"erc20_balance_human": "1000",
"erc20_balance_base": "1000000000",
"bank_coin_denom": "tf/nibi1zaavvzxez0elundtn32qnk9lkm8kmcsz44g7xl/stnibi",
"bank_balance_human": "0",
"bank_balance_base": "0"
}
The account has 1000 stNIBI on the ERC-20 side and zero on the bank side.
Where the views diverge
In lib/sai-trading/services/evmtrader/, the manual open path (EVMTrader.OpenTradeFromConfig) queries ERC-20 balance via queryERC20Balance before sizing a trade. The auto-trader path (EVMTrader.RunAutoTrading in auto_trader.go) gates on collateral availability using queryCosmosBalance, which reads the x/bank module only. The periodic health check (runHealthCheck) reports the same bank-only figure under balance_<denom>.
So the tool can truthfully report zero bank balance while the account holds spendable ERC-20 collateral—the exact state E2E deploy produces. The error message’s “fund this address with <bank denom>” guidance points operators at the wrong leg of the balance.
Impact
Localnet E2E and auto-trading workflows fail out of the box after a successful deploy. Operators who inspect funding with bank queries or the health-check log conclude the account is empty. The failure mode is especially confusing because Sai itself accepts ERC-20 collateral and the deploy script intentionally lands funds there.
After
just e2e-deploy, the automated trader exits immediately with a zero-balance error even though the trading account holds collateral. The failure is a balance-view mismatch on Nibiru’s multi-VM token model, not an unfunded account.What happens
Running
go run ./cmd/trader auto --config auto-trader.localnet.json(viajust run-auto-localnet) loads the auto-trader config, performs a health check, then stops:The health-check log shows
balance_tf/.../stnibi=0for accountnibi1cr6tg4cjvux00pj6zjqkh6d0jzg7mksaywxyl3.Why this is misleading
On Nibiru, a FunToken-mapped collateral like stNIBI exists in two representations: a Cosmos bank coin (
tf/.../stnibi) and an EVM ERC-20 at a mapped contract address. Sai EVM trading spends collateral through the EVM path; holding only the ERC-20 form is valid.The E2E deploy funds the validator-derived EVM account (
0xC0f4b45712670cf7865A14816bE9Af9091EDdA1d, bech32nibi1cr6tg4cjvux00pj6zjqkh6d0jzg7mksaywxyl3) with ERC-20 stNIBI, not bank coins.nibid q evm balanceconfirms the split:{ "addr_evm": "0xC0f4b45712670cf7865A14816bE9Af9091EDdA1d", "addr_bech32": "nibi1cr6tg4cjvux00pj6zjqkh6d0jzg7mksaywxyl3", "erc20_addr": "0x7D4B7B8CA7E1a24928Bb96D59249c7a5bd1DfBe6", "erc20_symbol": "stNIBI", "erc20_balance_human": "1000", "erc20_balance_base": "1000000000", "bank_coin_denom": "tf/nibi1zaavvzxez0elundtn32qnk9lkm8kmcsz44g7xl/stnibi", "bank_balance_human": "0", "bank_balance_base": "0" }The account has 1000 stNIBI on the ERC-20 side and zero on the bank side.
Where the views diverge
In
lib/sai-trading/services/evmtrader/, the manual open path (EVMTrader.OpenTradeFromConfig) queries ERC-20 balance viaqueryERC20Balancebefore sizing a trade. The auto-trader path (EVMTrader.RunAutoTradinginauto_trader.go) gates on collateral availability usingqueryCosmosBalance, which reads the x/bank module only. The periodic health check (runHealthCheck) reports the same bank-only figure underbalance_<denom>.So the tool can truthfully report zero bank balance while the account holds spendable ERC-20 collateral—the exact state E2E deploy produces. The error message’s “fund this address with
<bank denom>” guidance points operators at the wrong leg of the balance.Impact
Localnet E2E and auto-trading workflows fail out of the box after a successful deploy. Operators who inspect funding with bank queries or the health-check log conclude the account is empty. The failure mode is especially confusing because Sai itself accepts ERC-20 collateral and the deploy script intentionally lands funds there.