Skip to content

Commit f61829a

Browse files
pgherveougithub-actions[bot]atheiggwpez
committed
[revive] eth-decimals (#9101)
On Ethereum, 1 ETH is represented as 10^18 wei (wei being the smallest unit). On Polkadot 1 DOT is defined as 1010 plancks. It means that any value smaller than 10^8 wei can not be expressed with the native balance. Any contract that attempts to use such a value currently reverts with a DecimalPrecisionLoss error. In theory, RPC can define a decimal representation different from Ethereum mainnet (10^18). In practice tools (frontend libraries, wallets, and compilers) ignore it and expect 18 decimals. The current behaviour breaks eth compatibility and needs to be updated. See issue #109 for more details. Fix paritytech/contract-issues#109 [weights compare](https://weights.tasty.limo/compare?unit=weight&ignore_errors=true&threshold=10&method=asymptotic&repo=polkadot-sdk&old=master&new=pg/eth-decimals&path_pattern=substrate/frame/**/src/weights.rs,polkadot/runtime/*/src/weights/**/*.rs,polkadot/bridges/modules/*/src/weights.rs,cumulus/**/weights/*.rs,cumulus/**/weights/xcm/*.rs,cumulus/**/src/weights.rs) --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Alexander Theißen <alex.theissen@me.com> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
1 parent 08c9fe9 commit f61829a

29 files changed

Lines changed: 2122 additions & 991 deletions

cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1200,7 +1200,7 @@ parameter_types! {
12001200
impl pallet_migrations::Config for Runtime {
12011201
type RuntimeEvent = RuntimeEvent;
12021202
#[cfg(not(feature = "runtime-benchmarks"))]
1203-
type Migrations = pallet_migrations::migrations::ResetPallet<Runtime, Revive>;
1203+
type Migrations = pallet_revive::migrations::v1::Migration<Runtime>;
12041204
// Benchmarks need mocked migrations to guarantee that they succeed.
12051205
#[cfg(feature = "runtime-benchmarks")]
12061206
type Migrations = pallet_migrations::mock_helpers::MockedMigrations;

cumulus/parachains/runtimes/assets/common/src/erc20_transactor.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818
1919
use core::marker::PhantomData;
2020
use ethereum_standards::IERC20;
21-
use frame_support::{
22-
pallet_prelude::Zero,
23-
traits::{fungible::Inspect, OriginTrait},
24-
};
21+
use frame_support::traits::{fungible::Inspect, OriginTrait};
2522
use pallet_revive::{
2623
precompiles::alloy::{
2724
primitives::{Address, U256 as EU256},
@@ -127,7 +124,7 @@ where
127124
pallet_revive::Pallet::<T>::bare_call(
128125
T::RuntimeOrigin::signed(who.clone()),
129126
asset_id,
130-
BalanceOf::<T>::zero(),
127+
U256::zero(),
131128
gas_limit,
132129
DepositLimit::Balance(StorageDepositLimit::get()),
133130
data,
@@ -185,7 +182,7 @@ where
185182
pallet_revive::Pallet::<T>::bare_call(
186183
T::RuntimeOrigin::signed(TransfersCheckingAccount::get()),
187184
asset_id,
188-
BalanceOf::<T>::zero(),
185+
U256::zero(),
189186
gas_limit,
190187
DepositLimit::Balance(StorageDepositLimit::get()),
191188
data,

polkadot/xcm/pallet-xcm/src/precompiles.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ mod test {
184184
},
185185
H160,
186186
},
187-
DepositLimit,
187+
DepositLimit, U256,
188188
};
189189
use polkadot_parachain_primitives::primitives::Id as ParaId;
190190
use sp_runtime::traits::AccountIdConversion;
@@ -229,7 +229,7 @@ mod test {
229229
let result = pallet_revive::Pallet::<Test>::bare_call(
230230
RuntimeOrigin::signed(ALICE),
231231
xcm_precompile_addr,
232-
0u128,
232+
U256::zero(),
233233
Weight::MAX,
234234
DepositLimit::UnsafeOnlyForDryRun,
235235
encoded_call,
@@ -277,7 +277,7 @@ mod test {
277277
let result = pallet_revive::Pallet::<Test>::bare_call(
278278
RuntimeOrigin::signed(ALICE),
279279
xcm_precompile_addr,
280-
0u128,
280+
U256::zero(),
281281
Weight::MAX,
282282
DepositLimit::UnsafeOnlyForDryRun,
283283
encoded_call,
@@ -325,7 +325,7 @@ mod test {
325325
let result = pallet_revive::Pallet::<Test>::bare_call(
326326
RuntimeOrigin::signed(ALICE),
327327
xcm_precompile_addr,
328-
0u128,
328+
U256::zero(),
329329
Weight::MAX,
330330
DepositLimit::UnsafeOnlyForDryRun,
331331
encoded_call,
@@ -374,7 +374,7 @@ mod test {
374374
let result = pallet_revive::Pallet::<Test>::bare_call(
375375
RuntimeOrigin::signed(ALICE),
376376
xcm_precompile_addr,
377-
0u128,
377+
U256::zero(),
378378
Weight::MAX,
379379
DepositLimit::UnsafeOnlyForDryRun,
380380
encoded_call,
@@ -400,7 +400,7 @@ mod test {
400400
let result = pallet_revive::Pallet::<Test>::bare_call(
401401
RuntimeOrigin::signed(ALICE),
402402
xcm_precompile_addr,
403-
0u128,
403+
U256::zero(),
404404
Weight::MAX,
405405
DepositLimit::UnsafeOnlyForDryRun,
406406
encoded_call,
@@ -449,7 +449,7 @@ mod test {
449449
let result = pallet_revive::Pallet::<Test>::bare_call(
450450
RuntimeOrigin::signed(ALICE),
451451
xcm_precompile_addr,
452-
0u128,
452+
U256::zero(),
453453
Weight::MAX,
454454
DepositLimit::UnsafeOnlyForDryRun,
455455
encoded_call,
@@ -476,7 +476,7 @@ mod test {
476476
let result = pallet_revive::Pallet::<Test>::bare_call(
477477
RuntimeOrigin::signed(ALICE),
478478
xcm_precompile_addr,
479-
0u128,
479+
U256::zero(),
480480
Weight::MAX,
481481
DepositLimit::UnsafeOnlyForDryRun,
482482
encoded_call,
@@ -518,7 +518,7 @@ mod test {
518518
let xcm_weight_results = pallet_revive::Pallet::<Test>::bare_call(
519519
RuntimeOrigin::signed(ALICE),
520520
xcm_precompile_addr,
521-
0u128,
521+
U256::zero(),
522522
Weight::MAX,
523523
DepositLimit::UnsafeOnlyForDryRun,
524524
encoded_weight_call,
@@ -540,7 +540,7 @@ mod test {
540540
let result = pallet_revive::Pallet::<Test>::bare_call(
541541
RuntimeOrigin::signed(ALICE),
542542
xcm_precompile_addr,
543-
0u128,
543+
U256::zero(),
544544
Weight::MAX,
545545
DepositLimit::UnsafeOnlyForDryRun,
546546
encoded_call,
@@ -578,7 +578,7 @@ mod test {
578578
let xcm_weight_results = pallet_revive::Pallet::<Test>::bare_call(
579579
RuntimeOrigin::signed(ALICE),
580580
xcm_precompile_addr,
581-
0u128,
581+
U256::zero(),
582582
Weight::MAX,
583583
DepositLimit::UnsafeOnlyForDryRun,
584584
encoded_weight_call,
@@ -600,7 +600,7 @@ mod test {
600600
let result = pallet_revive::Pallet::<Test>::bare_call(
601601
RuntimeOrigin::signed(ALICE),
602602
xcm_precompile_addr,
603-
0u128,
603+
U256::zero(),
604604
Weight::MAX,
605605
DepositLimit::UnsafeOnlyForDryRun,
606606
encoded_call,
@@ -646,7 +646,7 @@ mod test {
646646
let xcm_weight_results = pallet_revive::Pallet::<Test>::bare_call(
647647
RuntimeOrigin::signed(ALICE),
648648
xcm_precompile_addr,
649-
0u128,
649+
U256::zero(),
650650
Weight::MAX,
651651
DepositLimit::UnsafeOnlyForDryRun,
652652
encoded_weight_call,
@@ -668,7 +668,7 @@ mod test {
668668
let result = pallet_revive::Pallet::<Test>::bare_call(
669669
RuntimeOrigin::signed(ALICE),
670670
xcm_precompile_addr,
671-
0u128,
671+
U256::zero(),
672672
Weight::MAX,
673673
DepositLimit::UnsafeOnlyForDryRun,
674674
encoded_call,
@@ -713,7 +713,7 @@ mod test {
713713
let xcm_weight_results = pallet_revive::Pallet::<Test>::bare_call(
714714
RuntimeOrigin::signed(ALICE),
715715
xcm_precompile_addr,
716-
0u128,
716+
U256::zero(),
717717
Weight::MAX,
718718
DepositLimit::UnsafeOnlyForDryRun,
719719
encoded_weight_call,
@@ -742,7 +742,7 @@ mod test {
742742
let result = pallet_revive::Pallet::<Test>::bare_call(
743743
RuntimeOrigin::signed(ALICE),
744744
xcm_precompile_addr,
745-
0u128,
745+
U256::zero(),
746746
Weight::MAX,
747747
DepositLimit::UnsafeOnlyForDryRun,
748748
encoded_call,
@@ -768,7 +768,7 @@ mod test {
768768
let result = pallet_revive::Pallet::<Test>::bare_call(
769769
RuntimeOrigin::signed(ALICE),
770770
xcm_precompile_addr,
771-
0u128,
771+
U256::zero(),
772772
Weight::MAX,
773773
DepositLimit::UnsafeOnlyForDryRun,
774774
encoded_call,
@@ -816,7 +816,7 @@ mod test {
816816
let xcm_weight_results = pallet_revive::Pallet::<Test>::bare_call(
817817
RuntimeOrigin::signed(ALICE),
818818
xcm_precompile_addr,
819-
0u128,
819+
U256::zero(),
820820
Weight::MAX,
821821
DepositLimit::UnsafeOnlyForDryRun,
822822
encoded_weight_call,
@@ -840,7 +840,7 @@ mod test {
840840
let xcm_weight_results = pallet_revive::Pallet::<Test>::bare_call(
841841
RuntimeOrigin::signed(ALICE),
842842
xcm_precompile_addr,
843-
0u128,
843+
U256::zero(),
844844
Weight::MAX,
845845
DepositLimit::UnsafeOnlyForDryRun,
846846
encoded_weight_call,

prdoc/pr_9101.prdoc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
title: '[revive] eth-decimals'
2+
doc:
3+
- audience: Runtime Dev
4+
description: |-
5+
On Ethereum, 1 ETH is represented as 10^18 wei (wei being the smallest unit).
6+
On Polkadot 1 DOT is defined as 10^10 plancks. It means that any value smaller than 10^8 wei can not be expressed with the native balance. Any contract that attempts to use such a value currently reverts with a DecimalPrecisionLoss error.
7+
8+
In theory, RPC can define a decimal representation different from Ethereum mainnet (10^18). In practice tools (frontend libraries, wallets, and compilers) ignore it and expect 18 decimals.
9+
10+
The current behaviour breaks eth compatibility and needs to be updated. See issue #109 for more details.
11+
12+
13+
Fix https://github.com/paritytech/contract-issues/issues/109
14+
[weights compare](https://weights.tasty.limo/compare?unit=weight&ignore_errors=true&threshold=10&method=asymptotic&repo=polkadot-sdk&old=master&new=pg/eth-decimals&path_pattern=substrate/frame/**/src/weights.rs,polkadot/runtime/*/src/weights/**/*.rs,polkadot/bridges/modules/*/src/weights.rs,cumulus/**/weights/*.rs,cumulus/**/weights/xcm/*.rs,cumulus/**/src/weights.rs)
15+
crates:
16+
- name: pallet-revive
17+
bump: major
18+
- name: pallet-revive-fixtures
19+
bump: major
20+
- name: assets-common
21+
bump: major
22+
- name: asset-hub-westend-runtime
23+
bump: major
24+
- name: pallet-xcm
25+
bump: major
26+
- name: pallet-assets
27+
bump: major

substrate/frame/assets/src/precompiles.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ mod test {
369369
pallet_revive::Pallet::<Test>::bare_call(
370370
RuntimeOrigin::signed(1),
371371
H160::from(asset_addr),
372-
0u64,
372+
0u32.into(),
373373
Weight::MAX,
374374
DepositLimit::UnsafeOnlyForDryRun,
375375
data,
@@ -405,7 +405,7 @@ mod test {
405405
let data = pallet_revive::Pallet::<Test>::bare_call(
406406
RuntimeOrigin::signed(1),
407407
H160::from(asset_addr),
408-
0u64,
408+
0u32.into(),
409409
Weight::MAX,
410410
DepositLimit::UnsafeOnlyForDryRun,
411411
data,
@@ -436,7 +436,7 @@ mod test {
436436
let data = pallet_revive::Pallet::<Test>::bare_call(
437437
RuntimeOrigin::signed(1),
438438
H160::from(asset_addr),
439-
0u64,
439+
0u32.into(),
440440
Weight::MAX,
441441
DepositLimit::UnsafeOnlyForDryRun,
442442
data,
@@ -482,7 +482,7 @@ mod test {
482482
pallet_revive::Pallet::<Test>::bare_call(
483483
RuntimeOrigin::signed(owner),
484484
H160::from(asset_addr),
485-
0u64,
485+
0u32.into(),
486486
Weight::MAX,
487487
DepositLimit::UnsafeOnlyForDryRun,
488488
data,
@@ -506,7 +506,7 @@ mod test {
506506
let data = pallet_revive::Pallet::<Test>::bare_call(
507507
RuntimeOrigin::signed(owner),
508508
H160::from(asset_addr),
509-
0u64,
509+
0u32.into(),
510510
Weight::MAX,
511511
DepositLimit::UnsafeOnlyForDryRun,
512512
data,
@@ -528,7 +528,7 @@ mod test {
528528
pallet_revive::Pallet::<Test>::bare_call(
529529
RuntimeOrigin::signed(spender),
530530
H160::from(asset_addr),
531-
0u64,
531+
0u32.into(),
532532
Weight::MAX,
533533
DepositLimit::UnsafeOnlyForDryRun,
534534
data,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
//! This calls another contract as passed as its account id.
19+
#![no_std]
20+
#![no_main]
21+
include!("../panic_handler.rs");
22+
23+
use uapi::{input, HostFn, HostFnImpl as api};
24+
25+
#[no_mangle]
26+
#[polkavm_derive::polkavm_export]
27+
pub extern "C" fn deploy() {}
28+
29+
#[no_mangle]
30+
#[polkavm_derive::polkavm_export]
31+
pub extern "C" fn call() {
32+
input!(
33+
value: &[u8; 32],
34+
callee_addr: &[u8; 20],
35+
);
36+
37+
// Call the callee
38+
api::call(
39+
uapi::CallFlags::empty(),
40+
callee_addr,
41+
u64::MAX, // How much ref_time to devote for the execution. u64::MAX = use all.
42+
u64::MAX, // How much proof_size to devote for the execution. u64::MAX = use all.
43+
&[u8::MAX; 32], // No deposit limit.
44+
value, // Value transferred to the contract.
45+
&[0u8; 0], // input
46+
None,
47+
)
48+
.unwrap();
49+
}

substrate/frame/revive/fixtures/contracts/caller_contract.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub extern "C" fn call() {
3535

3636
// The value to transfer on instantiation and calls. Chosen to be greater than existential
3737
// deposit.
38-
let value = u256_bytes(32768u64);
38+
let value = u256_bytes(32_768_000_000u64);
3939
let salt = [0u8; 32];
4040

4141
// Callee will use the first 4 bytes of the input to return an exit status.

substrate/frame/revive/fixtures/contracts/create_storage_and_instantiate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub extern "C" fn call() {
4343
key[0] = 1;
4444
api::set_storage(StorageFlags::empty(), &key, data);
4545

46-
let value = u256_bytes(10_000u64);
46+
let value = u256_bytes(10_000_000_000u64);
4747
let salt = [0u8; 32];
4848
let mut address = [0u8; 20];
4949
let mut deploy_input = [0; 32 + 4];

substrate/frame/revive/fixtures/contracts/delegate_call_lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub extern "C" fn call() {
4040
// Assert that `value_transferred` is equal to the value
4141
// passed to the `caller` contract: 1337.
4242
let value = u64_output!(api::value_transferred,);
43-
assert_eq!(value, 1337);
43+
assert_eq!(value, 1337_000_000);
4444

4545
// Assert that ALICE is the caller of the contract.
4646
let mut caller = [0u8; 20];

substrate/frame/revive/fixtures/contracts/destroy_and_transfer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ include!("../panic_handler.rs");
2222
use uapi::{input, u256_bytes, HostFn, HostFnImpl as api, StorageFlags};
2323

2424
const ADDRESS_KEY: [u8; 32] = [0u8; 32];
25-
const VALUE: [u8; 32] = u256_bytes(65536);
25+
const VALUE: [u8; 32] = u256_bytes(65_536_000_000);
2626

2727
#[no_mangle]
2828
#[polkavm_derive::polkavm_export]

0 commit comments

Comments
 (0)