Conversation
Kefancao
approved these changes
Sep 8, 2026
tqin7
approved these changes
Sep 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Stork is moving its signing logic into a TEE and rotating the aggregator signer key on September 15, 2026 at 10am ET.
Consumers that verify signatures themselves must accept
0x0bb53E0d5E89778DCD13C2720667D292368dD053as the signer from that point.The Stork provider currently compares the recovered signer against exactly one address, taken from
STORK_PUB_KEYor the hardcoded default.Once the key rotates, every Stork price fails verification and the feed goes stale until each operator updates the variable.
A single-address check also cannot cover a rollout where different environments see different signers at the same time.
How
STORK_PUB_KEYnow accepts a comma-separated list of Ethereum addresses, and a signature is valid when the recovered address matches any entry.A single address remains a valid one-element list, so existing configuration keeps working unchanged.
NewAPIHandlerand stored on the handler, rather than read from the environment on every price.DefaultSignerAddressesis used and contains both the current address0x0a803F9b1CCe32e2773e0d2e98b37E0775cA5d44and the new one0x0bb53E0d5E89778DCD13C2720667D292368dD053.VerifyStorkSignaturetakes the signer list as an explicit argument and returns an error when the list is empty.Trade-offs:
STORK_PUB_KEYrequires a restart. That was already the case in practice since the process environment does not change at runtime.What
providers/apis/stork/utils.go:DefaultSignerAddresses,SignerAddressesFromEnv,ParseSignerAddresses;VerifyStorkSignaturenow takes[]common.Addressand checks membership.providers/apis/stork/api_handler.go:APIHandlerholdssigners, populated inNewAPIHandler; construction fails on an invalidSTORK_PUB_KEY.providers/apis/stork/api_handler_test.go: tests for list parsing (whitespace, prefixes, repeated separators), environment fallback and copy-on-fallback, fail-fast construction, and multi-signer verification against the real XAU-USD production signature in first, middle, and last position.TestCreateURLexpects the&provider=storkquery parameter, and the unset-variable case asserts the defaults are used.providers/apis/pyth/api_handler_test.go: the unset-variable case asserts the defaultPYTH_PUB_KEYis used for verification; a new case covers an invalid value.providers/base/provider_test.go: the unchanged-result timestamp test derives its timestamps fromtime.Now()instead of fixed calendar dates, so the "after now" assertion holds regardless of when the test runs.Verified locally with Go 1.25.4:
make lint,go mod tidy,go build ./..., andgo test -raceover all non-integration packages.