Skip to content

Commit

Permalink
filter non-owner futurepass calls
Browse files Browse the repository at this point in the history
  • Loading branch information
JCSanPedro committed Sep 29, 2024
1 parent 0eb7d37 commit 394d26d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pallet/futurepass/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
) {
return false;
}

return self == &ProxyType::Owner;
}
match self {
_ => true,
Expand Down
74 changes: 74 additions & 0 deletions pallet/futurepass/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,80 @@ fn proxy_extrinsic_to_proxy_pallet_fails() {
});
}

#[test]
fn cannot_bypass_proxy_extrinsic_via_proxy() {
let funder = create_account(1);
let endowed = [(funder, 1_000_000)];

TestExt::<Test>::default()
.with_balances(&endowed)
.with_xrp_balances(&endowed)
.build()
.execute_with(|| {
let owner = create_account(2);
let (signer, delegate) = create_random_pair();

let proxy_type = ProxyType::Any;
let deadline = 200;

// fund owner
transfer_funds(
MOCK_NATIVE_ASSET_ID,
&funder,
&owner,
FP_CREATION_RESERVE + FP_DELEGATE_RESERVE + 1,
);

// create FP for owner
assert_ok!(Futurepass::create(RuntimeOrigin::signed(owner), owner));
let futurepass = Holders::<Test>::get(&owner).unwrap();

let signature = signer
.sign_prehashed(
&Futurepass::generate_add_delegate_eth_signed_message(
&futurepass,
&delegate,
&proxy_type,
&deadline,
)
.unwrap()
.1,
)
.0;

// register delegate
assert_ok!(Futurepass::register_delegate_with_signature(
RuntimeOrigin::signed(owner),
futurepass,
delegate,
proxy_type,
deadline,
signature,
));

// fund futurepass
transfer_funds(MOCK_NATIVE_ASSET_ID, &funder, &futurepass, 1000);

let other = create_account(4);
let inner_call = Box::new(MockCall::Futurepass(Call::transfer_futurepass {
current_owner: owner,
new_owner: Some(other),
}));
assert_ok!(pallet_proxy::Pallet::<Test>::proxy(
RuntimeOrigin::signed(delegate),
futurepass,
None,
inner_call
));

// the delegate tried to transfer the futurepass, but because it was
// was filtered, the futurepass should still be owned by the original
// owner
assert_eq!(futurepass, Holders::<Test>::get(&owner).unwrap());
assert!(Holders::<Test>::get(&other).is_none());
});
}

#[test]
fn proxy_extrinsic_failures_common() {
let funder = create_account(1);
Expand Down
4 changes: 4 additions & 0 deletions runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,10 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
) {
return false;
}

// the whitelisted calls above should only be able to be called by
// the owner of the futurepass
return self == &ProxyType::Owner;
}
match self {
ProxyType::Owner => true,
Expand Down

0 comments on commit 394d26d

Please sign in to comment.