Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions common/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub enum ProxyType {
Registration,
Transfer,
SmallTransfer,
RootWeights, // Deprecated
RootWeights,
ChildKeys,
SudoUncheckedSetCode,
SwapHotkey,
Expand Down Expand Up @@ -99,10 +99,7 @@ impl From<ProxyType> for u8 {

impl ProxyType {
pub fn is_deprecated(&self) -> bool {
matches!(
self,
Self::Triumvirate | Self::Senate | Self::Governance | Self::RootWeights
)
matches!(self, Self::Triumvirate | Self::Senate | Self::Governance)
}
}

Expand Down
10 changes: 9 additions & 1 deletion runtime/src/proxy_filters/call_groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,14 @@ call_filter_group!(
[RuntimeCall::SubtensorModule(SubtensorCall::start_call),]
);

// Root basket curation. Kept separate so `RootWeights` grants only this call.
call_filter_group!(
RootWeightsCalls,
[RuntimeCall::SubtensorModule(
SubtensorCall::set_root_weights
),]
);

// Residual pallet-subtensor calls that no proxy needs to grant on their own:
// weights, serving, delegate-take, alpha lock/burn/preferences, network
// registration, childkey admin, account association, tempo control, voting
Expand All @@ -441,7 +449,6 @@ call_filter_group!(
SubtensorCommonCalls,
[
RuntimeCall::SubtensorModule(SubtensorCall::set_weights),
RuntimeCall::SubtensorModule(SubtensorCall::set_root_weights),
RuntimeCall::SubtensorModule(SubtensorCall::set_mechanism_weights),
RuntimeCall::SubtensorModule(SubtensorCall::batch_set_weights),
RuntimeCall::SubtensorModule(SubtensorCall::commit_weights),
Expand Down Expand Up @@ -693,6 +700,7 @@ type SubtensorSplitCalls = (
RootClaimCalls,
SubnetIdentityCalls,
SubnetActivationCalls,
RootWeightsCalls,
SubtensorCommonCalls,
);

Expand Down
25 changes: 15 additions & 10 deletions runtime/src/proxy_filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::RuntimeCall;
//
// Each proxy type's permission set is an *additive* union of whole call groups
// from `call_groups`. A call a proxy does not list is denied. `Any` allows
// everything; the deprecated proxies allow nothing.
// everything; the deprecated governance proxies allow nothing.
//
// `Contains` for a tuple is logical OR (any member matches), so these aliases
// read as "allow if the call is in any of these groups".
Expand Down Expand Up @@ -65,6 +65,7 @@ type NonTransferAllowed = (
RootClaimCalls,
SubnetIdentityCalls,
SubnetActivationCalls,
RootWeightsCalls,
SubtensorCommonCalls,
);

Expand All @@ -80,6 +81,7 @@ type NonFungibleAllowed = (
RootClaimCalls,
SubnetIdentityCalls,
SubnetActivationCalls,
RootWeightsCalls,
SubtensorCommonCalls,
);

Expand All @@ -99,6 +101,7 @@ type NonCriticalAllowed = (
RootClaimCalls,
SubnetIdentityCalls,
SubnetActivationCalls,
RootWeightsCalls,
SubtensorCommonCalls,
);

Expand All @@ -117,11 +120,9 @@ pub(crate) fn proxy_type_filter(proxy_type: &ProxyType, call: &RuntimeCall) -> b
ProxyType::SwapHotkey => HotkeySwapCalls::contains(call),
ProxyType::SubnetLeaseBeneficiary => SubnetLeaseAllowed::contains(call),
ProxyType::RootClaim => RootClaimCalls::contains(call),
ProxyType::RootWeights => RootWeightsCalls::contains(call),

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.

[HIGH] Reactivation silently empowers dormant proxy delegates

Proxy definitions are stored by this stable enum value, and is_deprecated() never prevented users from retaining or creating type-12 definitions while its filter denied all calls. This change therefore gives every existing RootWeights delegate new authority without the account owner's consent; the delegate executes as the real hotkey and can alter its root-basket allocation. Introduce a new proxy-type index, or first migrate away all existing type-12 definitions before enabling this filter.

ProxyType::SudoUncheckedSetCode => SudoSetCodeCalls::contains(call),
ProxyType::Triumvirate
| ProxyType::Senate
| ProxyType::Governance
| ProxyType::RootWeights => false,
ProxyType::Triumvirate | ProxyType::Senate | ProxyType::Governance => false,
}
}

Expand Down Expand Up @@ -183,11 +184,11 @@ fn proxy_filter_mode(proxy_type: ProxyType) -> FilterMode {
ProxyType::SwapHotkey => FilterMode::Allow(HotkeySwapCalls::call_infos()),
ProxyType::SubnetLeaseBeneficiary => FilterMode::Allow(SubnetLeaseAllowed::call_infos()),
ProxyType::RootClaim => FilterMode::Allow(RootClaimCalls::call_infos()),
ProxyType::RootWeights => FilterMode::Allow(RootWeightsCalls::call_infos()),
ProxyType::SudoUncheckedSetCode => FilterMode::Allow(SudoSetCodeCalls::call_infos()),
ProxyType::Triumvirate
| ProxyType::Senate
| ProxyType::Governance
| ProxyType::RootWeights => FilterMode::Allow(Vec::new()),
ProxyType::Triumvirate | ProxyType::Senate | ProxyType::Governance => {
FilterMode::Allow(Vec::new())
}
}
}

Expand Down Expand Up @@ -287,11 +288,11 @@ mod tests {
#[test]
fn any_allows_everything_and_deprecated_allow_nothing() {
assert_eq!(allowed_calls(ProxyType::Any), all_runtime_calls());
assert!(!ProxyType::RootWeights.is_deprecated());
for deprecated in [
ProxyType::Triumvirate,
ProxyType::Senate,
ProxyType::Governance,
ProxyType::RootWeights,
] {
assert!(allowed_calls(deprecated).is_empty());
}
Expand Down Expand Up @@ -514,6 +515,10 @@ mod tests {
"SubtensorModule::claim_root_with_hotkey",
])
);
assert_eq!(
allowed_calls(ProxyType::RootWeights),
expected(&["SubtensorModule::set_root_weights"])
);
assert_eq!(
allowed_calls(ProxyType::SudoUncheckedSetCode),
expected(&["Sudo::sudo_unchecked_weight"])
Expand Down
Loading