Skip to content

NAN 005: Zero Gas in Browser Wallets, a Self-Governing Treasury, and the Return of 0x0801 ​

Posted by Unique on 2026-06-30. Releases: v2.14.0, v2.15.0. Prior mainnet upgrade: v2.12.0.

NAN 004 < Nibiru Advancement Notes (NANs) > NAN 006

NAN 005 cover

Summary ​

  • Gasless calls work from ordinary browser wallets. Wallets used to block them by filling in fees the account couldn't pay. Gasless calls can now send NIBI along, too.
  • The Foundation Treasury manages its own signers. Adding or removing a voter is now a Treasury proposal. We retired the legacy SDK multisig and the old Hot Wallet.
  • Fewer ways to touch module-held funds. Governance deposits and tokenfactory got stricter around module accounts.
  • The old oracle address 0x0801 is back, read-only and backed by Sai's oracle, so MIM OFT bridge fee quotes work again.
  • We published our first Wasm runtime fork, which fixes an ARM64 crash that blocked large Sai contracts.
  • nibid localnet --script starts a local chain from the installed binary.

May had no mainnet release. We used it to rehearse two v2.14 changes on testnet, the zero-fee hints and the Treasury migration, with throwaway v2.13.0-test.N tags. That habit stuck. Most releases since have had the same testnet rehearsal.

1) Zero gas has to survive the wallet ​

NAN 003 introduced always_zero_gas_contracts, a governance allowlist of contracts anyone can call without paying NIBI for gas. That should have solved onboarding. Browser wallets got in the way.

A wallet doesn't know about Nibiru's allowlist. Before it sends anything, it asks the RPC for gas prices and fee history, fills in the fee fields, and checks that the account can pay. A brand-new account with no NIBI fails that check, and the wallet refuses to send a transaction the chain would have accepted.

v2.14 fixes this from two sides:

  • The chain checks eligibility first. It recognizes an eligible zero-gas call before fee validation, so nonzero fee fields from a wallet don't disqualify it (PR #2596).
  • The RPC tells wallets what they need to hear. For zero-gas flows, JSON-RPC reports zero across gas price, EIP-1559 fields, fee history, WebSocket heads, transactions, and receipts (PR #2601).

How a zero-gas call gets through a browser wallet

The second part is a real tradeoff. To get wallets to behave, the fee data the RPC reports now depends on the call being made, not only on network conditions. The parts that matter stay honest. Consensus fee rules and EVM execution don't change for any transaction outside the allowlist.

Why not wait for wallets to support zero gas? Because every wallet talks to the RPC its own way. Some run their own simulations. Some force a minimum gas price, probably to give users sensible defaults. The result was that many wallets charged for a call that cost nothing, the opposite of the onboarding we wanted. A chain-level fix is wallet-agnostic. It behaves the same in every wallet and every tool, including ones we've never tested.

The same release, through PR #2610, dropped the rule that zero-gas calls must carry no value. A payable call to an allowlisted contract can now send NIBI with it. The sender still needs enough balance to cover the amount sent. They just don't pay gas on top of it.

2) A Treasury that governs itself ​

The Nibiru Foundation Treasury is a CW3 multisig contract. Its voters live in a separate CW4 group contract. Until v2.14, the admin of that group was an older keyring multisig, nibimultisig. Its signers were chosen when Nibiru launched, and more than half of them no longer work on the project. Getting enough of them to sign anything was close to impossible.

The v2.14 upgrade handler cut that dependency (PR #2602):

  • It updated the voter set once, removing signers who had left.
  • It made the Treasury CW3 contract the admin of its own CW4 voter group. Voter changes are now ordinary Treasury proposals.
  • It moved Wasm admin rights for both contracts to Treasury.
  • On mainnet, it retired the dormant Hot Wallet, swept its balance into Treasury, and left its contracts on chain unused.

Treasury governs itself

The threshold stays at 3-of-N. The point was to stop depending on people who had moved on, without lowering the bar for anyone else.

We did this in an upgrade handler rather than one last nibimultisig transaction, because that transaction would have needed the very signers who were gone. A chain upgrade runs on validator consensus, not on any one key. That makes it the right tool for getting around a key nobody can use. The Treasury is now run by the people actively building Nibiru and Sai.

3) Safer deposits and module accounts ​

Module accounts are addresses that chain modules use to hold funds, such as governance deposits in escrow. v2.14 tightens two modules around them (PR #2603):

  • Governance deposits only accept the denominations set in MinDeposit.
  • Tokenfactory, the module that lets accounts create their own coins, can no longer mint to or burn from module accounts. Creating a tokenfactory denom now takes governance or a sudoer.

These changes close paths that could have touched escrowed funds or module balances in ways nobody intended.

4) Bringing back 0x0801, narrowly ​

NAN 004 described turning off the native oracle and removing its EVM precompile. One deployed contract still needed it. MIM's OFT fee handler calls chainLinkLatestRoundData("unibi:uusd") on 0x0801 to quote bridge fees, and every quote reverted after v2.12.

We didn't bring back the oracle module. Sai's oracle already prices those assets, and it updates faster than the native oracle did. v2.15 answers the old calls from Sai's oracle instead (PR #2621):

  • 0x0801 exists again and answers the two read methods legacy callers use, in the old 18-decimal format.
  • Prices come from an x-oracle Wasm adapter backed by Sai's oracle. A new EVM param, wasm_plugins, says which contract that is.
  • Native oracle voting, feeders, slashing, and messages stay off.
  • It serves the legacy pairs Sai's oracle can keep up: BTC, ETH, ATOM, NIBI, and USDC against USD. Other pairs fail clearly. Nothing falls back to stale module state.

Bringing back 0x0801 as a shim

We kept the list to pairs worth maintaining. Every feed is something to run and monitor, and on the old oracle every feed was also a way for validators to get slashed. The shim exists for contracts already deployed. New contracts should read Sai's oracle directly.

5) Our first Wasm runtime fork ​

ARM64 nodes crashed when they stored or instantiated large Sai contracts. The fault was a relocation bug in Wasmer's Singlepass compiler. We published our own go-wasmvm v1.10.0 with the fix, including the macOS build (PR #2618).

It looked like a one-off at the time. In hindsight, it was the first step toward owning the Wasm runtime, which NAN 006 and NAN 008 pick up.

6) On Sai ​

  • Sai moved to sai.fun, and every market got its own page.
  • TP/SL on the chart. Drag your take profit and stop loss lines to edit them.
  • Your trades on the chart. Buy and sell markers from your trade history.
  • Fee details on every row of your trade history.
  • The Sai Grand Cup, our continent-vs-continent competition (announcement).

References ​

Pull requests behind each section. The Sai repositories are private, so the text above describes each change on its own.

1) Zero gas has to survive the wallet

2) A Treasury that governs itself

3) Safer deposits and module accounts

  • nibiru#2603: Deposit denominations and tokenfactory limits.

4) Bringing back 0x0801, narrowly

5) Our first Wasm runtime fork

  • nibiru#2618: Nibiru's go-wasmvm v1.10.0 with the ARM64 fix.

6) On Sai