ZetaChain Node - Bug Report
Repo: https://github.com/zeta-chain/node
Version: v37.0.0
Commit: 78e1a91
Date: 2026-01-11
Bug 1: VoteBlame crashes when VoteOnBallot fails
Severity: HIGH
File: x/observer/keeper/msg_server_vote_blame.go
Lines: 32-44
The Problem
Found a nil pointer bug in the blame voting handler. When VoteOnBallot returns an error, the code still tries to read ballot.BallotIdentifier for the error message. But ballot is nil at that point, so it panics.
Basically the error handling code itself causes a crash. Not great.
Why This Matters
- Node goes down if this gets triggered during blame voting
- Multiple validators hitting this = bad time for the network
- Any observer can trigger it by voting when conditions make
VoteOnBallot fail
The Code
// x/observer/keeper/msg_server_vote_blame.go:32-44
ballot, isFinalized, isNew, err := k.VoteOnBallot(
ctx,
observationChain,
msg.Digest(),
types.ObservationType_TSSKeySign,
msg.Creator,
types.VoteType_SuccessObservation,
)
if err != nil {
return nil, sdkerrors.Wrapf(
err,
"%s, BallotIdentifier %v", voteBlameID, ballot.BallotIdentifier) // boom - ballot is nil
}
What Happens
panic: runtime error: invalid memory address or nil pointer dereference
Fix
Just check if ballot exists before using it:
if err != nil {
if ballot != nil {
return nil, sdkerrors.Wrapf(err, "%s, BallotIdentifier %v", voteBlameID, ballot.BallotIdentifier)
}
return nil, sdkerrors.Wrapf(err, "%s, failed to vote on ballot", voteBlameID)
}
Link
https://github.com/zeta-chain/node/blob/78e1a91/x/observer/keeper/msg_server_vote_blame.go#L32-L44
Bug 2: Wrong order of nil check in ZRC20 functions
Severity: MEDIUM
File: x/fungible/keeper/zrc20_cosmos_coins_mapping.go
Lines: 96, 127
The Problem
Two functions check amount.Sign() before checking if amount is nil. Go evaluates left to right, so if you pass nil it crashes before the nil check even runs.
if amount.Sign() <= 0 || amount == nil { // wrong - crashes on nil
Should be:
if amount == nil || amount.Sign() <= 0 { // right - nil check first
Why This Matters
These are exported functions (CheckZRC20Allowance, CheckZRC20Balance). Right now nothing external calls them with nil, but if someone adds a precompile or new feature that does, the node crashes.
It's a bug waiting to happen.
The Code
// line 96
func (k Keeper) CheckZRC20Allowance(..., amount *big.Int) error {
if amount.Sign() <= 0 || amount == nil { // panic on nil
return fungibletypes.ErrInvalidAmount
}
}
// line 127
func (k Keeper) CheckZRC20Balance(..., amount *big.Int) error {
if amount.Sign() <= 0 || amount == nil { // same issue
return fungibletypes.ErrInvalidAmount
}
}
Fix
Flip the order:
if amount == nil || amount.Sign() <= 0 {
return fungibletypes.ErrInvalidAmount
}
Links
Bug 3: Feature flag function crashes on bad context
Severity: LOW
File: zetaclient/context/feature_flags.go
Lines: 10-14
The Problem
When FromContext fails, app is nil. But then the code tries to log with app.logger. Crash.
func EnableMultipleCallsFeatureFlag(ctx context.Context) bool {
app, err := FromContext(ctx)
if err != nil {
app.logger.Warn().Err(err)... // app is nil here
return false
}
}
Why This Matters
Not consensus-critical since it's zetaclient code, but it can crash the client if context is messed up.
Fix
Don't try to use app when it's nil:
if err != nil {
return false // just return, can't log without app
}
Link
https://github.com/zeta-chain/node/blob/78e1a91/zetaclient/context/feature_flags.go#L10-L14
ZetaChain Node - Bug Report
Repo: https://github.com/zeta-chain/node
Version: v37.0.0
Commit:
78e1a91Date: 2026-01-11
Bug 1: VoteBlame crashes when VoteOnBallot fails
Severity: HIGH
File:
x/observer/keeper/msg_server_vote_blame.goLines: 32-44
The Problem
Found a nil pointer bug in the blame voting handler. When
VoteOnBallotreturns an error, the code still tries to readballot.BallotIdentifierfor the error message. Butballotis nil at that point, so it panics.Basically the error handling code itself causes a crash. Not great.
Why This Matters
VoteOnBallotfailThe Code
What Happens
Fix
Just check if ballot exists before using it:
Link
https://github.com/zeta-chain/node/blob/78e1a91/x/observer/keeper/msg_server_vote_blame.go#L32-L44
Bug 2: Wrong order of nil check in ZRC20 functions
Severity: MEDIUM
File:
x/fungible/keeper/zrc20_cosmos_coins_mapping.goLines: 96, 127
The Problem
Two functions check
amount.Sign()before checking ifamountis nil. Go evaluates left to right, so if you pass nil it crashes before the nil check even runs.Should be:
Why This Matters
These are exported functions (
CheckZRC20Allowance,CheckZRC20Balance). Right now nothing external calls them with nil, but if someone adds a precompile or new feature that does, the node crashes.It's a bug waiting to happen.
The Code
Fix
Flip the order:
Links
Bug 3: Feature flag function crashes on bad context
Severity: LOW
File:
zetaclient/context/feature_flags.goLines: 10-14
The Problem
When
FromContextfails,appis nil. But then the code tries to log withapp.logger. Crash.Why This Matters
Not consensus-critical since it's zetaclient code, but it can crash the client if context is messed up.
Fix
Don't try to use
appwhen it's nil:Link
https://github.com/zeta-chain/node/blob/78e1a91/zetaclient/context/feature_flags.go#L10-L14