diff --git a/prdoc/pr_9705.prdoc b/prdoc/pr_9705.prdoc new file mode 100644 index 0000000000000..c7fad40ea194d --- /dev/null +++ b/prdoc/pr_9705.prdoc @@ -0,0 +1,9 @@ +title: '[pallet-revive] Properly convert `Ext::minimum_balance` value to `U256`' +doc: +- audience: Runtime Dev + description: | + The value returned by `minimum_balance` was just cast into `U256`, + without applying the actual conversion factor (`NativeToEthRatio`). +crates: +- name: pallet-revive + bump: patch diff --git a/substrate/frame/revive/src/exec.rs b/substrate/frame/revive/src/exec.rs index e0f190b60051d..84467b23d5b67 100644 --- a/substrate/frame/revive/src/exec.rs +++ b/substrate/frame/revive/src/exec.rs @@ -2059,7 +2059,8 @@ where } fn minimum_balance(&self) -> U256 { - T::Currency::minimum_balance().into() + let min = T::Currency::minimum_balance(); + crate::Pallet::::convert_native_to_evm(min) } fn deposit_event(&mut self, topics: Vec, data: Vec) { diff --git a/substrate/frame/revive/src/exec/tests.rs b/substrate/frame/revive/src/exec/tests.rs index 163aa1cbf3258..407ad5e7fda9b 100644 --- a/substrate/frame/revive/src/exec/tests.rs +++ b/substrate/frame/revive/src/exec/tests.rs @@ -1578,6 +1578,42 @@ fn call_deny_reentry() { }); } +#[test] +fn minimum_balance_must_return_converted_balance() { + let min_balance: BalanceOf = ::Currency::minimum_balance(); + let min_balance_evm_value: U256 = Pallet::::convert_native_to_evm(min_balance); + + let succ_fail_code = MockLoader::insert(Constructor, move |ctx, _| { + // The value returned by `Ext::minimum_balance` is `U256`, it must + // have been converted from the native balance type to `U256`. + assert_eq!(ctx.ext.minimum_balance(), min_balance_evm_value); + exec_success() + }); + + ExtBuilder::default() + .with_code_hashes(MockLoader::code_hashes()) + .build() + .execute_with(|| { + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + let succ_fail_executable = + MockExecutable::from_storage(succ_fail_code, &mut gas_meter).unwrap(); + let mut storage_meter = storage::meter::Meter::new(deposit_limit::()); + set_balance(&ALICE, min_balance * 10_000); + + assert_ok!(MockStack::run_instantiate( + ALICE, + succ_fail_executable, + &mut gas_meter, + &mut storage_meter, + min_balance_evm_value, + vec![], + Some(&[0; 32]), + false, + BumpNonce::Yes, + )); + }); +} + #[test] fn nonce() { let fail_code = MockLoader::insert(Constructor, |_, _| exec_trapped()); @@ -1605,7 +1641,7 @@ fn nonce() { Weight::MAX, U256::MAX, Code::Existing(success_code), - ctx.ext.minimum_balance() * 100, + ctx.ext.minimum_balance(), vec![], Some(&[0; 32]), ) @@ -1635,6 +1671,8 @@ fn nonce() { .build() .execute_with(|| { let min_balance = ::Currency::minimum_balance(); + let min_balance_evm_value: U256 = Pallet::::convert_native_to_evm(min_balance); + let mut gas_meter = GasMeter::::new(GAS_LIMIT); let fail_executable = MockExecutable::from_storage(fail_code, &mut gas_meter).unwrap(); let success_executable = @@ -1653,7 +1691,7 @@ fn nonce() { fail_executable, &mut gas_meter, &mut storage_meter, - (min_balance * 100).into(), + min_balance_evm_value * 100, vec![], Some(&[0; 32]), false, @@ -1667,7 +1705,7 @@ fn nonce() { success_executable, &mut gas_meter, &mut storage_meter, - (min_balance * 100).into(), + min_balance_evm_value * 100, vec![], Some(&[0; 32]), false, @@ -1680,7 +1718,7 @@ fn nonce() { succ_fail_executable, &mut gas_meter, &mut storage_meter, - (min_balance * 200).into(), + min_balance_evm_value * 200, vec![], Some(&[0; 32]), false, @@ -1693,7 +1731,7 @@ fn nonce() { succ_succ_executable, &mut gas_meter, &mut storage_meter, - (min_balance * 200).into(), + min_balance_evm_value * 200, vec![], Some(&[0; 32]), false,