Research / Chain files / Solana

Solana: who can change what the oracle reads

26 programs on Solana mainnet are tracked and scored by a native Anchor program on Devnet, one score account per target. Solana has no contract VM to call: the authority of a program is its upgrade authority and what sits behind it, a Squads multisig, a Realms governance, or a cross-chain executor, and each of those is a different shape.

What a track judge can check in two minutes

Three reads on the Solana (Devnet) program: the number of score accounts, one score account decoded, and its age. They need curl and python3 and nothing from us; the values below are the ones the Watch read, and they change when the oracle is re-pushed.

RPC=https://api.devnet.solana.com
PROGRAM=5VhiTAGLEViGgajhxPbzdWz7WLUAiRy42DY6qi6tYh4W
TARGET=dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH   # Drift Protocol
PDA=5Jp7B2h5pW6brxY2Fkeco1UrnNywatAjV3LJEgSwvMd6      # program-derived address, seeds ["score", TARGET]

# 1. how many score accounts the program owns (87 bytes each)
curl -s $RPC -X POST -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"getProgramAccounts","params":["'$PROGRAM'",{"encoding":"base64","dataSlice":{"offset":0,"length":0},"filters":[{"dataSize":87}]}]}' | python3 -c "import json,sys; print(len(json.load(sys.stdin)['result']))"

# 2. the score account of the target: admin, multisig, timelock, price feed, shared signers, composite, then lastUpdated
curl -s $RPC -X POST -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["'$PDA'",{"encoding":"base64"}]}' | python3 -c "import json,sys,base64,struct; d=base64.b64decode(json.load(sys.stdin)['result']['value']['data'][0]); print(list(d[40:46]), struct.unpack_from('<q',d,46)[0])"

# 3. its age in seconds against the staleness limit (777600 seconds)
curl -s $RPC -X POST -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["'$PDA'",{"encoding":"base64"}]}' | python3 -c "import json,sys,base64,struct,time; d=base64.b64decode(json.load(sys.stdin)['result']['value']['data'][0]); print(int(time.time()) - struct.unpack_from('<q',d,46)[0])"

Expected

1 -> 26
2 -> ([65, 70, 2, 2, 100, 48], 1791859628)   admin, multisig, timelock, price feed, shared signers, composite
3 -> an age below the limit: not stale

3 findings, each with its replay

1. The shared SPL Governance program is upgradeable by a Realms-governed council of 7 members, an effective 5-of-7, run by the company behind Realms

The upgrade authority of the shared SPL Governance program is a program-derived account that also upgrades 14 programs in all. Tracing a real transaction and decoding the Realms accounts shows that it is governed by a council realm: a council mint with a supply of 7 and no decimals, seven distinct holders of one token each (decoded one by one in the note), a 60 percent council vote threshold, no hold-up time and no community vote. That is an effective 5-of-7 council. It is neither a plain key nor a Squads multisig, and it is operated as the platform's own security governance, not as a consumer DAO. The mint authority is the same account, so the council governs its own membership.

Replay it (public data, no key)
# the governance account is the upgrade authority of 14 loader-v3 programs
rpc(){ curl -s https://api.mainnet-beta.solana.com -X POST -H 'content-type: application/json' -d "$1"; }
rpc '{"jsonrpc":"2.0","id":1,"method":"getProgramAccounts","params":["BPFLoaderUpgradeab1e11111111111111111111111",{"encoding":"base64","dataSlice":{"offset":0,"length":0},"filters":[{"memcmp":{"offset":13,"bytes":"HF7gCq7BMB6cFfhharTGGm31sqDdpmvLTgF4WEoW8y9n"}}]}]}' | python3 -c "import json,sys; print(len(json.load(sys.stdin)['result']))"
# -> 14
# the council mint: supply 7, no decimals, and its mint authority is the same account
rpc '{"jsonrpc":"2.0","id":1,"method":"getTokenSupply","params":["ACVqan3WMg6CuE99sn5bNsqpcywg88EhNBAjRftvy7hd"]}' | python3 -c "import json,sys; print(json.load(sys.stdin)['result']['value'])"
rpc '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["ACVqan3WMg6CuE99sn5bNsqpcywg88EhNBAjRftvy7hd",{"encoding":"jsonParsed"}]}' | python3 -c "import json,sys; print(json.load(sys.stdin)['result']['value']['data']['parsed']['info']['mintAuthority'])"
# -> amount 7, decimals 0, then HF7gCq7BMB6cFfhharTGGm31sqDdpmvLTgF4WEoW8y9n

Notes: finding_2026-09-17-spl-governance-shared-instance-controller.md

2. Wormhole's core bridge on Solana is guarded by 19 guardians with a 13-of-19 quorum, an authority that does not fit a k-of-n multisig, so it is documented and not scored

The active guardian set of the Wormhole core bridge on Solana held 19 secp256k1 keys at set index 7 when it was read on 25 September 2026, and the quorum follows the program's own formula, two thirds plus one: 13 of 19. The note records that this authority is a different archetype from the multisigs of the rest of the oracle, so no score was created for it and the next pass does not have to re-scout it. The numbers below are read live and show the set that is active today.

Replay it (public data, no key)
# the bridge configuration and the active guardian set, and the quorum
rpc(){ curl -s https://api.mainnet-beta.solana.com -X POST -H 'content-type: application/json' -d "$1"; }
rpc '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn",{"encoding":"base64"}]}' | python3 -c "import json,sys,base64,struct; d=base64.b64decode(json.load(sys.stdin)['result']['value']['data'][0]); print('active set index', struct.unpack_from('<I',d,0)[0])"
rpc '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["6YLGQQEweF82hbPSWCSeJqifWyT8Pm4QXa3mWSLwjYSh",{"encoding":"base64"}]}' | python3 -c "import json,sys,base64,struct; d=base64.b64decode(json.load(sys.stdin)['result']['value']['data'][0]); i,n=struct.unpack_from('<II',d,0); print('set',i,'keys',n,'quorum',n*2//3+1)"
# -> active set index 7, then set 7 keys 19 quorum 13 (if the guardians rotate the set, the index and the account change: the quorum rule stays)

Notes: finding_2026-09-25-wormhole-core-bridge.md

3. Every Pyth program on Solana shares one upgrade authority, and it is a cross-chain executor with no Solana-side committee

The note found that all 11 Solana programs listed for Pyth share the same upgrade authority, an address with no data that does not match a Squads multisig account under any derivation tried. Its recent transactions run through an executor program that posts a message to Wormhole. Reading Pyth's own source, the note concludes that the executor checks no threshold, quorum or guardian set on the Solana side: the authority comes from the cross-chain message. It states what is not resolved, the exact emitter account that signs, and it gave no score instead of guessing a threshold. Three of the programs are replayed below.

Replay it (public data, no key)
# the upgrade authority of three Pyth programs (receiver, push oracle, legacy oracle)
rpc(){ curl -s https://api.mainnet-beta.solana.com -X POST -H 'content-type: application/json' -d "$1"; }
for p in rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH; do
  PD=$(rpc "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getAccountInfo\",\"params\":[\"$p\",{\"encoding\":\"jsonParsed\"}]}" | python3 -c "import json,sys; print(json.load(sys.stdin)['result']['value']['data']['parsed']['info']['programData'])")
  rpc "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getAccountInfo\",\"params\":[\"$PD\",{\"encoding\":\"jsonParsed\"}]}" | python3 -c "import json,sys; print(json.load(sys.stdin)['result']['value']['data']['parsed']['info']['authority'])"
done
# -> the same address three times (6oXTdojyfDS8m5VtTaYB9xRCxpKGSvKJFndLUPV3V3wT)

Notes: finding_2026-09-30-pyth-governance-lead-not-resolved.md

Targets

26 targets are tracked on Solana, read from mainnet and scored by the oracle on Solana (Devnet). Bands of the composite score:

critical5
weak4
moderate15
decent2

Up to 26 targets, ordered by value where known, then by lowest score. Each name opens the contract page.

TargetCompositeBand
Solend DAO governance realm2critical
Meteora DAMM v22critical
Orca Whirlpool2critical
Save (ex Solend) lending program2critical
Raydium (AMM v4, CLMM, CPMM)14critical
marginfi main lending group33weak
Solstice (USX, YieldVault, Aux)35weak
Lulo (FlexLend)38weak
Flash Trade (Perpetuals)39weak
Solayer (sSOL staking, Endo)40moderate
PumpSwap and pump.fun bonding curve43moderate
Marinade Liquid Staking45moderate
Jupiter Perpetual Exchange46moderate
Sanctum Infinity (S Controller)46moderate
Jupiter Aggregator v647moderate
Drift Protocol48moderate
GMSOL (GMTrade, six programs)51moderate
Exponent (Core)51moderate
Kamino Liquidity (yvaults)54moderate
SPL Stake Pool program (shared infrastructure)54moderate
JitoSOL (Jito Liquid Staking)54moderate
Sanctum validator LSTs (SanctumSpl, SanctumSplMulti)54moderate
Kamino Lend, main market (SOL/BTC)56moderate
Jupiter Lend56moderate
Huma Finance (Permissionless, Institutional)66decent
Loopscale (Loopscale, Beam)70decent

What is not read

Read from the public repository and the Watch at build, 2026-10-15 21:09 UTC. A finding is a dated reading with its replay, not an audit and not investment advice. All chain files ยท Dashboard.