From 1dd786223eed3ce3fc64f126c05d41c75d159f1a Mon Sep 17 00:00:00 2001 From: Rodrigo Quelhas Date: Mon, 20 Jan 2025 11:05:04 +0000 Subject: [PATCH] update proxy filter --- runtime/moonbase/src/lib.rs | 43 ++++++------ runtime/moonbeam/src/lib.rs | 42 ++++++------ runtime/moonriver/src/lib.rs | 42 ++++++------ .../test-proxy/test-proxy-identity.ts | 65 +++++++++++++++++++ 4 files changed, 131 insertions(+), 61 deletions(-) diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index 9774af7bca..5cd1c82cc1 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -970,7 +970,6 @@ impl pallet_evm_precompile_proxy::EvmProxyCallFilter for ProxyType { && match PrecompileName::from_address(call.to.0) { Some( PrecompileName::AuthorMappingPrecompile - | PrecompileName::IdentityPrecompile | PrecompileName::ParachainStakingPrecompile, ) => true, Some(ref precompile) if is_governance_precompile(precompile) => true, @@ -1023,26 +1022,28 @@ impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { ProxyType::Any => true, - ProxyType::NonTransfer => { - matches!( - c, - RuntimeCall::System(..) - | RuntimeCall::ParachainSystem(..) - | RuntimeCall::Timestamp(..) - | RuntimeCall::ParachainStaking(..) - | RuntimeCall::Referenda(..) - | RuntimeCall::Preimage(..) - | RuntimeCall::ConvictionVoting(..) - | RuntimeCall::TreasuryCouncilCollective(..) - | RuntimeCall::OpenTechCommitteeCollective(..) - | RuntimeCall::Identity(..) - | RuntimeCall::Utility(..) - | RuntimeCall::Proxy(..) | RuntimeCall::AuthorMapping(..) - | RuntimeCall::CrowdloanRewards( - pallet_crowdloan_rewards::Call::claim { .. } - ) - ) - } + ProxyType::NonTransfer => match c { + RuntimeCall::Identity( + pallet_identity::Call::add_sub { .. } | pallet_identity::Call::set_subs { .. }, + ) => false, + call => { + matches!( + call, + RuntimeCall::System(..) + | RuntimeCall::ParachainSystem(..) + | RuntimeCall::Timestamp(..) | RuntimeCall::ParachainStaking(..) + | RuntimeCall::Referenda(..) | RuntimeCall::Preimage(..) + | RuntimeCall::ConvictionVoting(..) + | RuntimeCall::TreasuryCouncilCollective(..) + | RuntimeCall::OpenTechCommitteeCollective(..) + | RuntimeCall::Utility(..) | RuntimeCall::Proxy(..) + | RuntimeCall::Identity(..) | RuntimeCall::AuthorMapping(..) + | RuntimeCall::CrowdloanRewards( + pallet_crowdloan_rewards::Call::claim { .. } + ) + ) + } + }, ProxyType::Governance => matches!( c, RuntimeCall::Referenda(..) diff --git a/runtime/moonbeam/src/lib.rs b/runtime/moonbeam/src/lib.rs index a4892e32d0..9190d2804a 100644 --- a/runtime/moonbeam/src/lib.rs +++ b/runtime/moonbeam/src/lib.rs @@ -1020,26 +1020,28 @@ impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { ProxyType::Any => true, - ProxyType::NonTransfer => { - matches!( - c, - RuntimeCall::System(..) - | RuntimeCall::ParachainSystem(..) - | RuntimeCall::Timestamp(..) - | RuntimeCall::ParachainStaking(..) - | RuntimeCall::Referenda(..) - | RuntimeCall::Preimage(..) - | RuntimeCall::ConvictionVoting(..) - | RuntimeCall::TreasuryCouncilCollective(..) - | RuntimeCall::OpenTechCommitteeCollective(..) - | RuntimeCall::Identity(..) - | RuntimeCall::Utility(..) - | RuntimeCall::Proxy(..) | RuntimeCall::AuthorMapping(..) - | RuntimeCall::CrowdloanRewards( - pallet_crowdloan_rewards::Call::claim { .. } - ) - ) - } + ProxyType::NonTransfer => match c { + RuntimeCall::Identity( + pallet_identity::Call::add_sub { .. } | pallet_identity::Call::set_subs { .. }, + ) => false, + call => { + matches!( + call, + RuntimeCall::System(..) + | RuntimeCall::ParachainSystem(..) + | RuntimeCall::Timestamp(..) | RuntimeCall::ParachainStaking(..) + | RuntimeCall::Referenda(..) | RuntimeCall::Preimage(..) + | RuntimeCall::ConvictionVoting(..) + | RuntimeCall::TreasuryCouncilCollective(..) + | RuntimeCall::OpenTechCommitteeCollective(..) + | RuntimeCall::Utility(..) | RuntimeCall::Proxy(..) + | RuntimeCall::Identity(..) | RuntimeCall::AuthorMapping(..) + | RuntimeCall::CrowdloanRewards( + pallet_crowdloan_rewards::Call::claim { .. } + ) + ) + } + }, ProxyType::Governance => matches!( c, RuntimeCall::Referenda(..) diff --git a/runtime/moonriver/src/lib.rs b/runtime/moonriver/src/lib.rs index 3c30809b75..e8c82f3377 100644 --- a/runtime/moonriver/src/lib.rs +++ b/runtime/moonriver/src/lib.rs @@ -1028,26 +1028,28 @@ impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { ProxyType::Any => true, - ProxyType::NonTransfer => { - matches!( - c, - RuntimeCall::System(..) - | RuntimeCall::ParachainSystem(..) - | RuntimeCall::Timestamp(..) - | RuntimeCall::ParachainStaking(..) - | RuntimeCall::Referenda(..) - | RuntimeCall::Preimage(..) - | RuntimeCall::ConvictionVoting(..) - | RuntimeCall::TreasuryCouncilCollective(..) - | RuntimeCall::OpenTechCommitteeCollective(..) - | RuntimeCall::Identity(..) - | RuntimeCall::Utility(..) - | RuntimeCall::Proxy(..) | RuntimeCall::AuthorMapping(..) - | RuntimeCall::CrowdloanRewards( - pallet_crowdloan_rewards::Call::claim { .. } - ) - ) - } + ProxyType::NonTransfer => match c { + RuntimeCall::Identity( + pallet_identity::Call::add_sub { .. } | pallet_identity::Call::set_subs { .. }, + ) => false, + call => { + matches!( + call, + RuntimeCall::System(..) + | RuntimeCall::ParachainSystem(..) + | RuntimeCall::Timestamp(..) | RuntimeCall::ParachainStaking(..) + | RuntimeCall::Referenda(..) | RuntimeCall::Preimage(..) + | RuntimeCall::ConvictionVoting(..) + | RuntimeCall::TreasuryCouncilCollective(..) + | RuntimeCall::OpenTechCommitteeCollective(..) + | RuntimeCall::Utility(..) | RuntimeCall::Proxy(..) + | RuntimeCall::Identity(..) | RuntimeCall::AuthorMapping(..) + | RuntimeCall::CrowdloanRewards( + pallet_crowdloan_rewards::Call::claim { .. } + ) + ) + } + }, ProxyType::Governance => matches!( c, RuntimeCall::Referenda(..) diff --git a/test/suites/dev/moonbase/test-proxy/test-proxy-identity.ts b/test/suites/dev/moonbase/test-proxy/test-proxy-identity.ts index 0e687ab97c..86fadd263b 100644 --- a/test/suites/dev/moonbase/test-proxy/test-proxy-identity.ts +++ b/test/suites/dev/moonbase/test-proxy/test-proxy-identity.ts @@ -1,6 +1,22 @@ import "@moonbeam-network/api-augment"; import { beforeEach, describeSuite, expect } from "@moonwall/cli"; import { GLMR, type KeyringPair, alith, generateKeyringPair } from "@moonwall/util"; +import { BN, u8aToU8a } from "@polkadot/util"; +import type { EventRecord } from "@polkadot/types/interfaces"; +import type { ApiPromise } from "@polkadot/api"; +import type { RegistryError } from "@polkadot/types-codec/types"; + +const getProxyErrors = (api: ApiPromise, events: EventRecord[]): RegistryError[] => { + return events + .filter(({ event }) => api.events.proxy.ProxyExecuted.is(event)) + .map(({ event }) => { + const module = event.data["result"].toJSON()["err"]["module"]; + return api.registry.findMetaError({ + index: new BN(module.index), + error: u8aToU8a(module.error), + }); + }); +}; describeSuite({ id: "D013005", @@ -137,6 +153,55 @@ describeSuite({ }); }, }); + + it({ + id: "T03", + title: "Should fail when calling pallet_identity through a `NonTransfer` proxy", + test: async () => { + // Add Alith as NonTransfer Proxy of another account + const blockAdd = await context.createBlock( + context.polkadotJs().tx.proxy.addProxy(alith.address, "NonTransfer", 0).signAsync(signer) + ); + expect(blockAdd.result?.successful).to.be.true; + + let alithNonce = await context + .viem() + .getTransactionCount({ address: alith.address as `0x${string}` }); + const blockExecute = await context.createBlock([ + // Alith adds itself as sub account of another account using a proxy call, + // and reserves a deposit + await context + .polkadotJs() + .tx.proxy.proxy( + signer.address, + "NonTransfer", + context.polkadotJs().tx.identity.addSub(alith.address, { Raw: "test" }) + ) + .signAsync(alith, { nonce: alithNonce++ }), + // Another flavour of the call above, it does exactly the same thing. + await context + .polkadotJs() + .tx.proxy.proxy( + signer.address, + "NonTransfer", + context.polkadotJs().tx.identity.setSubs([[alith.address, { Raw: "test" }]]) + ) + .signAsync(alith, { nonce: alithNonce++ }), + ]); + expect(blockExecute.result!.length).to.equal(2); + expect(blockExecute.result!.every(({ successful }) => successful)).to.be.true; + const errors = blockExecute.result!.flatMap(({ events }) => + getProxyErrors(context.polkadotJs(), events) + ); + expect(errors.length).to.equal(2); + // We expect the calls to fail, `ProxyType` filters these calls + // for `NonTransfer` proxy calls. + for (const error of errors) { + expect(error.docs[0]).to.equal("The origin filter prevent the call to be dispatched."); + expect(error.name).to.equal("CallFiltered"); + } + }, + }); }, });