Research / Chain files / Arbitrum
13 contracts on Arbitrum One are tracked and scored by an oracle on Arbitrum Sepolia: GMX, Aave, Compound, Pendle, Fluid, Uniswap and the Arbitrum Security Council. Arbitrum is where an address with no code can be a governor, and where one of our own published scores was wrong and had to be corrected.
Three calls on the Arbitrum (Sepolia) oracle, read at the latest block. They need a public RPC and cast (Foundry) and nothing from us. The public RPC of this chain keeps no history for that block, so the values below are the ones the Watch read at block 319507783: they change when the oracle is re-pushed.
RPC=https://sepolia-rollup.arbitrum.io/rpc ORACLE=0x50840a7667baEa9D05ad4ae3dCeb384724b58720 TARGET=0x3c3d99fd298f679dbc2cecd132b4ec4d0f5e6e72 # GMX V2 (Synthetics) RoleStore # 1. how many contracts this oracle tracks cast call $ORACLE "trackedTargetsCount()(uint256)" --rpc-url $RPC # 2. its score, five sub-scores then the composite, then lastUpdated and the method hash cast call $ORACLE "getScore(address)((uint8,uint8,uint8,uint8,uint8,uint8,uint64,bytes32))" $TARGET --rpc-url $RPC # 3. is that score older than maxStaleness cast call $ORACLE "isStale(address)(bool)" $TARGET --rpc-url $RPC
Expected
1 -> 13 2 -> (10, 0, 50, 52, 80, 19, 1791852875, 0x51163f3cce4612011bca19a651e2c0b650d9c670559f9036a37acfadf0532f54) admin, multisig, timelock, price feed, shared signers, composite 3 -> false
The score originally published for the GMX V2 role store, 71, followed a rule that checked one timelock controller. Re-derived from zero against Arbitrum One, that controller holds no role on the store. The live timelock admins are a 5-of-8 Safe, a 4-of-6 Safe and one plain key that GMX's own configuration file labels as a timelock admin. That key can signal a grant of the role-admin role, executable after the controller's 24-hour delay; the 5-of-8 Safe can cancel. The corrected score is far lower, and the contract page shows the current value.
# the timelock admins of the GMX V2 role store, and what each one is ARB=https://arb1.arbitrum.io/rpc STORE=0x3c3d99FD298f679DBC2CEcd132b4eC4d0F5e6e72 KEY=$(cast keccak $(cast abi-encode "f(string)" "TIMELOCK_ADMIN")) for m in $(cast call $STORE "getRoleMembers(bytes32,uint256,uint256)(address[])" $KEY 0 10 --rpc-url $ARB | tr -d '[] ' | tr ',' ' '); do echo "$(cast code $m --rpc-url $ARB | cut -c1-12) nonce $(cast nonce $m --rpc-url $ARB)"; done # -> three members: two Safes (0x6080604052, nonce 1) and one with code 0x (a plain key, nonce above 70)
The Arbitrum Security Council emergency Safe needs 9 of 12 signatures and holds the executor role on the L2 UpgradeExecutor. The ordinary core timelock of the chain has an 8-day delay; the emergency Safe can act without waiting for it. This is a documented part of Arbitrum's security model, not a flaw found here. Because this Safe is the emergency root of every protocol on the chain, its score is capped rather than raised, and it is tracked as a systemic target.
# the Safe: threshold and owners ARB=https://arb1.arbitrum.io/rpc SC=0x423552c0f05baccac5bfa91c6dcf1dc53a0a1641 cast call $SC "getThreshold()(uint256)" --rpc-url $ARB cast call $SC "getOwners()(address[])" --rpc-url $ARB | tr ',' '\n' | wc -l # -> 9, then 12 # it holds the executor role, and the core timelock's delay cast call 0xCF57572261c7c2BCF21ffD220ea7d1a27D40A827 "hasRole(bytes32,address)(bool)" $(cast keccak EXECUTOR_ROLE) $SC --rpc-url $ARB cast call 0x34d45e99f7D8c45ed05B5cA72D54bbD1fb3F98f0 "getMinDelay()(uint256)" --rpc-url $ARB # -> true, then 691200 (8 days)
Notes: scored_targets_2026-09-17.md
The owner chain of the Uniswap V3 factory on Arbitrum ends at an address that has no code. An earlier version of this repository described it as a vanity-ground bare key built to look like Uniswap's governance address. That was wrong, and the correction is published: the address is the Arbitrum L1-to-L2 alias of Uniswap's Ethereum Governance Timelock, computed as the L1 address plus 0x1111000000000000000000000000000000001111 modulo 2^160. An alias has no code by design, which a scorer that reads empty code as a plain key gets wrong.
# the alias, computed from the Uniswap Timelock on Ethereum (the owner of the V4 PoolManager there)
TL=$(cast call 0x000000000004444c5dc75cb358380d2e3de08a90 "owner()(address)" --rpc-url https://ethereum-rpc.publicnode.com)
python3 -c "print(hex((int('$TL',16) + 0x1111000000000000000000000000000000001111) % (1<<160)))"
# -> the alias address, 0x2bad...46cd
# the V3 factory on Arbitrum: its owner is an adapter, the adapter's owner is the alias, and the alias has no code
ARB=https://arb1.arbitrum.io/rpc
ADAPTER=$(cast call 0x1F98431c8aD98523631AE4a59f267346ea31F984 "owner()(address)" --rpc-url $ARB)
ALIAS=$(cast call $ADAPTER "owner()(address)" --rpc-url $ARB)
echo $ALIAS
cast code $ALIAS --rpc-url $ARB
# -> the alias address (0x2bad...46cd, as computed above), then 0x (no code)Notes: correction_2026-09-16-uniswap-bridge-alias.md · finding_2026-09-20-uniswap-one-timelock-eleven-targets.md
13 targets are tracked on Arbitrum, read from mainnet and scored by the oracle on Arbitrum (Sepolia). Bands of the composite score:
| critical | 3 |
|---|---|
| weak | 1 |
| moderate | 5 |
| decent | 3 |
| strong | 1 |
Up to 12 targets, ordered by value where known, then by lowest score. Each name opens the contract page.
| Target | Composite | Band |
|---|---|---|
| Arbitrum Security Council Emergency Safe | 64 | decent |
| Aave V3 Pool (Arbitrum) | 71 | decent |
| GMX V2 (Synthetics) RoleStore | 19 | critical |
| Fluid Liquidity (Arbitrum) | 59 | moderate |
| Uniswap V3 Factory (Arbitrum One) | 85 | strong |
| Compound V3 | 78 | decent |
| Pendle V2 | 43 | moderate |
| Camelot AMMv3 (Algebra) Factory | 31 | weak |
| GMX V1 Perps | 57 | moderate |
| Radiant Capital LendingPool (V2 Core) | 55 | moderate |
| GNSMultiCollatDiamond (verified source) | 4 | critical |
| OAdapter (verified source) | 8 | critical |
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.