diff --git a/pallets/unified-accounts/src/tests.rs b/pallets/unified-accounts/src/tests.rs index 30f3c40eb2..d6e3fd6203 100644 --- a/pallets/unified-accounts/src/tests.rs +++ b/pallets/unified-accounts/src/tests.rs @@ -184,83 +184,120 @@ fn account_claim_should_work() { } #[test] -fn account_claim_should_not_work() { +fn account_default_claim_works() { ExtBuilder::default().build().execute_with(|| { - // invald signature - assert_noop!( - UnifiedAccounts::claim_evm_address( - RuntimeOrigin::signed(ALICE), - UnifiedAccounts::eth_address(&bob_secret()), - get_evm_signature(&BOB, &bob_secret()) - ), - Error::::InvalidSignature + let alice_default_evm = + ::DefaultAccountMapping::into_h160(ALICE.into()); + + // claim default account + assert_ok!(UnifiedAccounts::claim_default_evm_address( + RuntimeOrigin::signed(ALICE) + )); + System::assert_last_event(RuntimeEvent::UnifiedAccounts( + crate::Event::AccountClaimed { + account_id: ALICE.clone(), + evm_address: alice_default_evm.clone(), + }, + )); + + // check UnifiedAddressMapper's mapping works + assert_eq!( + >::to_h160(&ALICE), + Some(alice_default_evm) ); + assert_eq!( + >::to_account_id(&alice_default_evm), + Some(ALICE) + ); + + // should not allow to claim afterwards assert_noop!( UnifiedAccounts::claim_evm_address( RuntimeOrigin::signed(ALICE), - UnifiedAccounts::eth_address(&bob_secret()), + UnifiedAccounts::eth_address(&alice_secret()), get_evm_signature(&ALICE, &alice_secret()) ), - Error::::InvalidSignature + Error::::AlreadyMapped ); + }); +} +#[test] +fn replay_attack_should_not_be_possible() { + ExtBuilder::default().build().execute_with(|| { + let alice_eth = UnifiedAccounts::eth_address(&alice_secret()); + let alice_signature = get_evm_signature(&ALICE, &alice_secret()); + + // alice claim her eth address first assert_ok!(UnifiedAccounts::claim_evm_address( RuntimeOrigin::signed(ALICE), - UnifiedAccounts::eth_address(&alice_secret()), - get_evm_signature(&ALICE, &alice_secret()) + alice_eth, + alice_signature )); - // AccountId already mapped + + // bob intercepted alice signature and tries to perform + // replay attack to claim alice eth address as his own, + // this should fail. assert_noop!( UnifiedAccounts::claim_evm_address( - RuntimeOrigin::signed(ALICE), - UnifiedAccounts::eth_address(&alice_secret()), - get_evm_signature(&ALICE, &alice_secret()) + RuntimeOrigin::signed(BOB), + alice_eth, + alice_signature ), Error::::AlreadyMapped ); - // eth address already mapped + }); +} + +#[test] +fn frontrun_attack_should_not_be_possible() { + ExtBuilder::default().build().execute_with(|| { + let alice_eth = UnifiedAccounts::eth_address(&alice_secret()); + let alice_signature = get_evm_signature(&ALICE, &alice_secret()); + + // bob intercepted alice signature and tries to perform + // frontrun attack to claim alice eth address as his own + // this should fail with InvalidSignature. assert_noop!( UnifiedAccounts::claim_evm_address( RuntimeOrigin::signed(BOB), - UnifiedAccounts::eth_address(&alice_secret()), - get_evm_signature(&ALICE, &alice_secret()) + alice_eth, + alice_signature ), - Error::::AlreadyMapped + Error::::InvalidSignature ); + + // alice can claim her eth address + assert_ok!(UnifiedAccounts::claim_evm_address( + RuntimeOrigin::signed(ALICE), + alice_eth, + alice_signature + )); }); } #[test] -fn account_default_claim_works() { +fn connecting_mapped_accounts_should_not_work() { ExtBuilder::default().build().execute_with(|| { - let alice_default_evm = - ::DefaultAccountMapping::into_h160(ALICE.into()); - - // claim default account - assert_ok!(UnifiedAccounts::claim_default_evm_address( - RuntimeOrigin::signed(ALICE) - )); - System::assert_last_event(RuntimeEvent::UnifiedAccounts( - crate::Event::AccountClaimed { - account_id: ALICE.clone(), - evm_address: alice_default_evm.clone(), - }, - )); + // connect ALICE accounts + connect_accounts(&ALICE, &alice_secret()); - // check UnifiedAddressMapper's mapping works - assert_eq!( - >::to_h160(&ALICE), - Some(alice_default_evm) - ); - assert_eq!( - >::to_account_id(&alice_default_evm), - Some(ALICE) + // AccountId already mapped + // ALICE attempts to connect another evm address + assert_noop!( + UnifiedAccounts::claim_evm_address( + RuntimeOrigin::signed(ALICE), + UnifiedAccounts::eth_address(&bob_secret()), + get_evm_signature(&BOB, &bob_secret()) + ), + Error::::AlreadyMapped ); - // should not allow to claim afterwards + // eth address already mapped + // BOB attempts to connect alice_eth that is already mapped assert_noop!( UnifiedAccounts::claim_evm_address( - RuntimeOrigin::signed(ALICE), + RuntimeOrigin::signed(BOB), UnifiedAccounts::eth_address(&alice_secret()), get_evm_signature(&ALICE, &alice_secret()) ),