Skip to content

feat: move StockOracleSwitch setGlobal to MANAGER + add batchSetStatus#196

Open
ricklista wants to merge 2 commits into
masterfrom
feature/stock-oracle-switch-batch-status
Open

feat: move StockOracleSwitch setGlobal to MANAGER + add batchSetStatus#196
ricklista wants to merge 2 commits into
masterfrom
feature/stock-oracle-switch-batch-status

Conversation

@ricklista

@ricklista ricklista commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Two changes to StockOracleSwitch (the open/closed gate for tokenized-stock markets):

  1. setGlobal moves from BOT to MANAGER — the single global market-hours switch becomes governance-controlled, while routine per-stock open/close stays with the automation BOT.
  2. New batchSetStatus(address[] tokens, bool status) — lets BOT open or close many registered stocks in one call by delegating to open/close (strict — reverts the whole batch on a no-op or unregistered token).

Change type

  • New contract
  • Upgrade (existing proxy)
  • Bug fix
  • Gas optimization
  • Configuration change
  • Migration / deploy script
  • Test

Contracts changed

Contract File Type
StockOracleSwitch src/oracle/StockOracleSwitch.sol modified
StockOracleDeploy script/oracle/deploy_stockOracle.sol modified (comments only)
StockOracleSwitchTest test/oracle/StockOracleSwitch.t.sol modified (tests)
StockOracleTest test/oracle/StockOracle.t.sol modified (tests)

Interface changes

  • setGlobal(bool open)access role changed BOTMANAGER (signature unchanged).
  • open(address) / close(address) — visibility externalpublic (still BOT-gated) so batchSetStatus can call them internally. ABI/selectors unchanged.
  • batchSetStatus(address[] calldata tokens, bool status)new external, BOT role. Opens (status = true) or closes (status = false) every token in tokens by delegating to open/close. Strict — inherits the open/close guards, so a token already in the target state (AlreadySet) or unregistered (NotRegistered) reverts the whole batch. Emits the existing StockEnable(token, status) event per token.
  • No new events, errors, or state variables.

Storage layout

Verified via forge inspect StockOracleSwitch storage-layoutunchanged:

Name Type Slot
registered mapping(address => bool) 0
enabled mapping(address => bool) 1
globalEnabled bool 2

No state variables added/removed/reordered (only a function added, a modifier changed, and open/close visibility widened). Safe to deploy as a UUPS implementation upgrade — no collision risk.

Access control

  • setGlobal now requires MANAGER instead of BOT. Operationally, the global daily/market-hours switch must be toggled by the MANAGER holder (a Gnosis Safe after deploy_stockOracleTransferRole.sol), not the bot.
  • batchSetStatus is BOT-gated and delegates to open/close, which became public but stay BOT-gated; the per-element role check still passes because the internal call preserves msg.sender.
  • Role-admin wiring unchanged (MANAGER still admins BOT; _authorizeUpgrade still DEFAULT_ADMIN_ROLE).

Risk assessment

Area Risk Note
Storage collision 🟢 None Layout verified identical; no new/reordered state vars.
Fund safety 🟢 None Switch holds no funds; only gates StockOracle.peek via isEnabled.
Access control 🟡 Low Intentional setGlobal role move BOTMANAGER; open/close widened to public but stay BOT-gated. Covered by tests (incl. a test asserting BOT is now rejected on setGlobal).
External call safety 🟢 None No external calls added; batchSetStatus only delegates to in-contract open/close.

Deployment

  • Chain: BSC mainnet. Requires deploying a new StockOracleSwitch implementation and calling upgradeToAndCall on the live proxy 0xb4678C3E8B49d2b95Da48458f98805da193A8498 (admin = Timelock 0x07D274a68393E8b8a2CCf19A2ce4Ba3518735253 after role handoff).
  • No new env vars, no storage migration.
  • Post-upgrade ops note: daily global open/close is now a MANAGER (Safe) action; per-stock open/close (incl. bulk batchSetStatus) remains a BOT action.

Test plan

  • forge test --mc StockOracle passes — 64 tests (StockOracleSwitchTest 43 + StockOracleTest 21).
  • New batchSetStatus coverage: bulk close-then-open + event order, already-in-state reverts (AlreadySet), non-BOT rejected, unregistered token reverts the whole batch (state rolled back), empty array no-op.
  • setGlobal tests updated to MANAGER, plus a new test asserting BOT can no longer call it.
  • prettier --check clean.
  • Note: the repo-wide forge test includes BSC fork suites needing BSC_RPC; this PR ran the targeted oracle suites, which exercise all changed code.

🤖 Generated with Claude Code

ricklista and others added 2 commits June 18, 2026 10:31
- setGlobal (global market switch) now requires MANAGER instead of BOT; BOT keeps per-stock open/close. The sensitive daily/global switch moves to governance while routine per-stock toggling stays with the automation bot.
- Add batchSetStatus(address[] tokens, bool status): sets every listed registered stock to status (true=open / false=close) in one call (BOT role). Idempotent — tokens already in the target state are skipped; an unregistered token reverts the whole batch.
- Update tests for both changes + fix stale "BOT calls setGlobal" comments in deploy_stockOracle.sol.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… -> public

- open/close: external -> public so batchSetStatus can call them in-loop (the internal call preserves msg.sender = BOT, so onlyRole still passes). ABI/selectors unchanged.
- batchSetStatus now delegates to open/close per element instead of inlining state writes; it is strict — an already-in-state (AlreadySet) or unregistered (NotRegistered) token reverts the whole batch.
- Update test: idempotent no-op skip -> AlreadySet revert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@qingyang-lista qingyang-lista 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.

LGTM

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.

2 participants