多符号 — 实现
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Allow the Operator to dynamically register new price symbols on OracleHub, and expand genesis initialization to include 5 symbols (ETH/USD, BTC/USD, USDC/USD, SOL/USD, BNB/USD).
Architecture: Two-pronged approach. (A) Expand genesis initialize() call to register all 5 symbols at deployment. (B) Relax addSymbol from onlySystemCall to onlySystemCall OR onlyOperator, and add batchAddSymbols for bulk registration. Tests use OracleHubLocal (Foundry-testable mirror that replaces onlySystemCall with onlyAdmin).
Tech Stack: Solidity ^0.8.20/^0.8.26, Foundry (forge test), TOML config
Task 1: Add batchAddSymbols to IOracleHub interface
batchAddSymbols to IOracleHub interfaceFiles:
Modify:
era-contracts-l1/system-contracts/contracts/interfaces/IOracleHub.sol:39-44
Step 1: Add the new function signature to the interface
Open era-contracts-l1/system-contracts/contracts/interfaces/IOracleHub.sol. In the // --- Admin section (line 39), add batchAddSymbols after addSymbol:
// --- Admin (system call or operator) ---
function addSymbol(bytes32 symbolHash) external;
function batchAddSymbols(bytes32[] calldata symbolHashes) external;
// --- Admin (system call only) ---
function removeSymbol(bytes32 symbolHash) external;
function setConfig(uint256 stalenessThreshold, uint256 deviationThreshold, uint8 minSourceCount) external;
function setOperator(address _operator) external;
function operator() external view returns (address);The key change: addSymbol and batchAddSymbols are grouped under "system call or operator", while removeSymbol/setConfig/setOperator stay under "system call only".
Step 2: Verify file compiles
Run: cd /Users/judybaby/CodeBase/github/Layer2/era-contracts-l1/system-contracts && npx hardhat compile 2>&1 | tail -5 Expected: Compilation error (OracleHub.sol doesn't implement batchAddSymbols yet — that's OK, we'll fix in Task 2)
Step 3: Commit
Task 2: Implement _isSystemCallOrOperator + modify addSymbol + add batchAddSymbols in OracleHub.sol
_isSystemCallOrOperator + modify addSymbol + add batchAddSymbols in OracleHub.solFiles:
Modify:
era-contracts-l1/system-contracts/contracts/OracleHub.sol:131-139
This is the main system contract at 0x8016. It uses the real SystemContractHelper for onlySystemCall.
Step 1: Add the _isSystemCallOrOperator internal function
Add this function in the // ==================== Internal ==================== section (before _updatePrice, around line 193):
You need to add the SystemContractHelper import. Check if it's already imported via SystemContractBase. Open era-contracts-l1/system-contracts/contracts/abstract/SystemContractBase.sol — it imports SystemContractHelper from ../libraries/SystemContractHelper.sol. Since OracleHub inherits SystemContractBase, SystemContractHelper is already accessible. But we need to import it directly since we're calling it in our own function:
Add at the top of OracleHub.sol (after line 3):
Step 2: Modify addSymbol to use dual-permission check
Replace the current addSymbol (lines 133-139):
Step 3: Add batchAddSymbols function
Add this right after addSymbol:
Step 4: Update the section comment
Change line 131 from:
to:
And add a new section comment before removeSymbol:
Step 5: Verify compilation
Run: cd /Users/judybaby/CodeBase/github/Layer2/era-contracts-l1/system-contracts && npx hardhat compile 2>&1 | tail -5 Expected: Compiled successfully
If SystemContractHelper import causes issues (already available via inheritance), remove the explicit import and use the inherited one.
Step 6: Commit
Task 3: Sync contracts-preprocessed copies
Files:
Modify:
era-contracts-l1/system-contracts/contracts-preprocessed/OracleHub.solModify:
era-contracts-l1/system-contracts/contracts-preprocessed/interfaces/IOracleHub.sol
The contracts-preprocessed/ directory must mirror contracts/ exactly for system contract compilation.
Step 1: Copy both files
Step 2: Verify the preprocessed copies match
Expected: No output (files identical)
Step 3: Commit
Task 4: Update OracleHubLocal.sol (Foundry-testable mirror)
Files:
Modify:
contracts/src/oracle/OracleHubLocal.sol:134-155
OracleHubLocal replaces onlySystemCall with onlyAdmin for local Foundry testing. We need to mirror the permission change: addSymbol now allows both admin AND operator.
Step 1: Add _isAdminOrOperator internal function
Add before _updatePrice (around line 192):
Step 2: Modify addSymbol to use dual-permission check
Replace lines 136-141:
Step 3: Add batchAddSymbols function
Add right after addSymbol:
Step 4: Keep removeSymbol as onlyAdmin only — no change needed
Step 5: Verify it compiles
Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge build 2>&1 | tail -5 Expected: Compiled successfully
Step 6: Commit
Task 5: Write 6 new Foundry tests
Files:
Modify:
contracts/test/OracleHub.t.sol(append toOracleHubOperatorTestcontract)
All 6 new tests go inside the existing OracleHubOperatorTest contract (which uses OracleHubLocal and already has operatorAddr, adminAddr, stranger addresses set up).
Step 1: Write the 6 tests
Append these tests at the end of OracleHubOperatorTest (before the closing }):
Step 2: Run tests to verify they fail
Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract OracleHubOperatorTest --match-test "test_addSymbol_by_operator|test_addSymbol_by_admin|test_addSymbol_by_random_reverts|test_batchAddSymbols_by_operator|test_batchAddSymbols_empty_reverts|test_removeSymbol_by_operator_reverts" -vv 2>&1 | tail -20
Expected: If Task 4 was completed, tests should PASS. If not yet, they will fail with "function not found" since OracleHubLocal doesn't have the new functions yet.
Step 3: Run ALL tests (regression)
Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test --match-contract OracleHub -vv 2>&1 | tail -30
Expected: All existing tests + 6 new tests pass. No regressions.
Step 4: Commit
Task 6: Update baby-chain.toml — uncomment 4 symbols
Files:
Modify:
config/baby-chain.toml:25-44
Step 1: Uncomment the 4 symbol configurations
Replace lines 25-44 with the uncommented versions:
Also update the NOTE comment (lines 17-19) to reflect new state:
Step 2: Verify TOML is valid
Run: python3 -c "import tomllib; tomllib.load(open('config/baby-chain.toml', 'rb')); print('OK')" Expected: OK
Step 3: Verify oracle-wiring Rust code still compiles (no Rust changes needed, just verify config parsing)
Run: cd /Users/judybaby/CodeBase/github/Layer2/baby-modules/oracle-wiring && cargo check 2>&1 | tail -5 Expected: Finished (no errors)
Step 4: Commit
Task 7: Final regression + dev-log update
Files:
Modify:
docs/dev-log.md(append entry)
Step 1: Run full Foundry test suite
Run: cd /Users/judybaby/CodeBase/github/Layer2/contracts && forge test -vv 2>&1 | tail -30 Expected: All tests pass (existing + 6 new)
Step 2: Run oracle-wiring tests
Run: cd /Users/judybaby/CodeBase/github/Layer2/baby-modules/oracle-wiring && cargo test 2>&1 | tail -15 Expected: All tests pass
Step 3: Update dev-log
Append to docs/dev-log.md:
Step 4: Commit
Last updated