Skip to content

fix: return 0 when contract doesn't implement decimals()#28

Merged
wa0x6e merged 2 commits into
mainfrom
fix/fallback-token-decimals
Mar 18, 2026
Merged

fix: return 0 when contract doesn't implement decimals()#28
wa0x6e merged 2 commits into
mainfrom
fix/fallback-token-decimals

Conversation

@wa0x6e

@wa0x6e wa0x6e commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Partially fix https://snapshot-labs.sentry.io/issues/7328652620/?project=4505606761152512&query=is%3Aunresolved&referrer=issue-stream

When a token contract doesn't implement decimals(), the erc20-balance-of strategy throws an unhandled error that bubbles up as a 500. The sequencer marks the proposal as ERROR_SYNC and retries indefinitely — generating ~36K Sentry errors (SNAPSHOT-SEQUENCER-48) since March 12.

The fix catches CALL_EXCEPTION errors (ethers.js error code for contract reverts) and returns 0 USD value — same as when CoinGecko has no price data. Temporary errors (timeout, network) are re-thrown so the sequencer can retry.

Changes

  • 🐛 Catch CALL_EXCEPTION in erc20-balance-of strategy and return 0
  • 🔄 Re-throw other errors (timeout, network) to allow retries

Test plan

  • Verify overlord no longer returns 500 for contracts missing decimals() (e.g. SENSO 0xC19B6A4Ac7C7Cc24459F08984Bbd09664af17bD1 on mainnet)
  • Verify temporary RPC errors still return 500 so sequencer retries
  • Verify normal tokens with decimals() are unaffected

🤖 Generated with Claude Code

@wa0x6e wa0x6e changed the title fix: fallback token decimals when not in ERC-20 contract fix: fallback to params.decimals when on-chain decimals() call fails Mar 16, 2026
@wa0x6e
wa0x6e force-pushed the fix/fallback-token-decimals branch from 25f6ad5 to bd96686 Compare March 16, 2026 13:28
When getTokenDecimals() fails with CALL_EXCEPTION (contract doesn't
implement decimals()), return 0 USD value instead of letting the error
bubble up as an unhandled 500. Temporary errors (timeout, network) are
re-thrown so the sequencer can retry.

Fixes SNAPSHOT-SEQUENCER-48

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wa0x6e
wa0x6e force-pushed the fix/fallback-token-decimals branch from bd96686 to ef20eee Compare March 16, 2026 13:38
@wa0x6e wa0x6e changed the title fix: fallback to params.decimals when on-chain decimals() call fails fix: return 0 when contract doesn't implement decimals() Mar 16, 2026
@wa0x6e
wa0x6e requested a review from Copilot March 16, 2026 13:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the erc20-balance-of strategy to handle failures when reading ERC20 decimals() more explicitly, avoiding hard failures for a specific class of contract-call errors.

Changes:

  • Wraps getTokenDecimals(...) in a try/catch and returns 0 when the error code is CALL_EXCEPTION.
  • Re-throws non-CALL_EXCEPTION errors to allow upstream retry/handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

try {
tokenDecimals = await getTokenDecimals(Number(tokenNetwork), tokenAddress);
} catch (e: any) {
// CALL_EXCEPTION means the contract doesn't implement decimals()
Comment on lines +96 to +106
let tokenDecimals: number;
try {
tokenDecimals = await getTokenDecimals(Number(tokenNetwork), tokenAddress);
} catch (e: any) {
// CALL_EXCEPTION means the contract doesn't implement decimals()
// Other errors (timeout, network) are temporary and should be retried
if (e.code === 'CALL_EXCEPTION') {
return 0;
}
throw e;
}
@wa0x6e
wa0x6e requested review from ChaituVR and bonustrack March 16, 2026 13:45
} catch (e: any) {
// CALL_EXCEPTION means the contract doesn't implement decimals()
// Other errors (timeout, network) are temporary and should be retried
if (e.code === 'CALL_EXCEPTION') {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think CALL_EXCEPTION can be triggered for many issues, not just "method not implemented"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this particular case, where we try to read data from a read-only function, we're assuming that this error will happen only when the function does not exist, or have a different ABI

@ChaituVR ChaituVR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utAck

@wa0x6e
wa0x6e merged commit 675ef26 into main Mar 18, 2026
3 checks passed
@wa0x6e
wa0x6e deleted the fix/fallback-token-decimals branch March 18, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants