Skip to content

fix(safe): route Cap Money Multisig alerts to the CAP channel - #352

Merged
spalen0 merged 1 commit into
mainfrom
fix/safe-cap-money-telegram-routing
Sep 9, 2026
Merged

fix(safe): route Cap Money Multisig alerts to the CAP channel#352
spalen0 merged 1 commit into
mainfrom
fix/safe-cap-money-telegram-routing

Conversation

@spalen0

@spalen0 spalen0 commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Problem

The Cap Money Multisig (0xb8FC4940…8793) is registered in ALL_SAFE_ADDRESSES under the protocol label "CAP MONEY".

That field doubles as the Telegram channel key. send_telegram_message resolves credentials as:

topic_id = os.getenv(f"TELEGRAM_TOPIC_ID_{protocol.upper()}")
...
chat_id  = os.getenv(f"TELEGRAM_CHAT_ID_{protocol.upper()}")

For this entry that is TELEGRAM_TOPIC_ID_CAP MONEY — not a legal env-var name, so it can never be set. Every alert for this Safe therefore fell into the missing-credentials branch (utils/telegram.py:243) and was discarded:

if not bot_token or not chat_id:
    ...
    logger.warning("Missing Telegram credentials for %s", protocol)
    return

The failure is silent — a log warning, no alert, no error. This Safe has produced no notifications since it was added in 36fb771.

Fix

Relabel to "CAP". That is the intended destination:

  • monitoring.yaml already declares a Safe Multisig monitor — "Cap Money Multisig queue" — under the cap protocol.
  • TELEGRAM_TOPIC_ID_CAP exists, and is where the CAP timelock monitor already reports.

"CAP MONEY" was the only entry in ALL_SAFE_ADDRESSES containing a space, so no other Safe is affected.

Regression test

Added TestSafeProtocolLabels::test_protocol_labels_are_valid_env_var_suffixes, asserting every protocol label matches [A-Za-z0-9_]+. Verified it fails against the old value:

- ['CAP MONEY']
+ [] : Safe protocol labels must be usable as env-var suffixes, got: ['CAP MONEY']

Also documented the constraint in a comment above ALL_SAFE_ADDRESSES.

Why this matters now

Surfaced while reviewing a CAP timelock operation that moves UUPS upgrade rights from this multisig to the Timelock (see yearn/risk-score#460). The multisig retains 92 Access Control roles after that operation, including 11 selectors on cUSD it can call with no timelock delay (pauseProtocol, rescueERC20, setWhitelist, removeAsset, …). Its queue is exactly what we want eyes on, and we had none.

Testing

uv run ruff format .   # 176 files left unchanged
uv run ruff check .    # All checks passed!
uv run pytest tests/test_safe_main.py tests/test_monitoring_config.py tests/test_known_addresses.py -q
# 34 passed

🤖 Generated with Claude Code

The Cap Money Multisig was registered under the protocol label "CAP MONEY".
That field doubles as the Telegram channel key — send_telegram_message looks
up TELEGRAM_TOPIC_ID_{protocol.upper()} / TELEGRAM_CHAT_ID_{protocol.upper()},
which for this entry is "TELEGRAM_TOPIC_ID_CAP MONEY". That is not a legal
env-var name and can never be set, so every alert for this Safe hit the
"Missing Telegram credentials" branch in utils/telegram.py and was dropped
with only a log warning.

The Safe has been silent since it was added in 36fb771. monitoring.yaml
already lists a "Safe Multisig" monitor ("Cap Money Multisig queue") under
the cap protocol, and TELEGRAM_TOPIC_ID_CAP exists, so "CAP" is the intended
destination and matches where the CAP timelock monitor already reports.

It was the only entry in ALL_SAFE_ADDRESSES containing a space. Add a
regression test asserting every protocol label is a usable env-var suffix,
plus a comment recording the constraint.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@spalen0
spalen0 merged commit 64d6fe3 into main Sep 9, 2026
3 checks passed
@spalen0
spalen0 deleted the fix/safe-cap-money-telegram-routing branch September 9, 2026 21:48
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.

1 participant