From 8cdec0652e8da2d69cf16e5e7357e96048f09dcd Mon Sep 17 00:00:00 2001 From: Jochen Hoenicke Date: Thu, 8 Mar 2018 12:05:53 +0100 Subject: [PATCH] Ethereum: Fix fee computation. - Gas is always in ether, even when sending tokens. - Fee is computed by multiplying gas limit with gas price. - Parse numbers already in sign_tx. - Made rlp.encode non-recursive (also fixes not passing include_length). --- src/apps/ethereum/layout.py | 9 ++++----- src/apps/ethereum/sign_tx.py | 12 ++++++------ src/trezor/crypto/rlp.py | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/apps/ethereum/layout.py b/src/apps/ethereum/layout.py index 88f40f289..84f46528f 100644 --- a/src/apps/ethereum/layout.py +++ b/src/apps/ethereum/layout.py @@ -24,10 +24,10 @@ async def require_confirm_tx(ctx, to, value, chain_id, token=None): async def require_confirm_fee(ctx, spending, gas_price, gas_limit, chain_id, token=None): content = Text('Confirm transaction', ui.ICON_SEND, ui.BOLD, format_ethereum_amount(spending, token, chain_id), - ui.NORMAL, 'Gas:', - ui.BOLD, format_ethereum_amount(gas_price, token, chain_id), - ui.NORMAL, 'Limit:', - ui.BOLD, format_ethereum_amount(gas_limit, token, chain_id), + ui.NORMAL, 'Gas price:', + ui.BOLD, format_ethereum_amount(gas_price, None, chain_id), + ui.NORMAL, 'Maximum fee:', + ui.BOLD, format_ethereum_amount(gas_price * gas_limit, None, chain_id), icon_color=ui.GREEN) await require_hold_to_confirm(ctx, content, ButtonRequestType.SignTx) @@ -52,7 +52,6 @@ def split_address(address): def format_ethereum_amount(value, token, chain_id): - value = int.from_bytes(value, 'big') if token: suffix = token[2] decimals = token[3] diff --git a/src/apps/ethereum/sign_tx.py b/src/apps/ethereum/sign_tx.py index f1d18e665..a641a4869 100644 --- a/src/apps/ethereum/sign_tx.py +++ b/src/apps/ethereum/sign_tx.py @@ -20,22 +20,22 @@ async def ethereum_sign_tx(ctx, msg): # detect ERC - 20 token token = None + recipient = msg.to + value = int.from_bytes(msg.value, 'big') if len(msg.to) == 20 and \ len(msg.value) == 0 and \ data_total == 68 and \ len(msg.data_initial_chunk) == 68 and \ msg.data_initial_chunk[:16] == b'\xa9\x05\x9c\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': token = tokens.token_by_chain_address(msg.chain_id, msg.to) + recipient = msg.data_initial_chunk[16:36] + value = int.from_bytes(msg.data_initial_chunk[36:68], 'big') - if token is None: - await require_confirm_tx(ctx, msg.to, msg.value, msg.chain_id) - else: - await require_confirm_tx(ctx, msg.data_initial_chunk[16:36], msg.data_initial_chunk[36:68], msg.chain_id, token) - + await require_confirm_tx(ctx, recipient, value, msg.chain_id, token) if token is None and msg.data_length > 0: await require_confirm_data(ctx, msg.data_initial_chunk, data_total) - await require_confirm_fee(ctx, msg.value, msg.gas_price, msg.gas_limit, msg.chain_id, token) + await require_confirm_fee(ctx, value, int.from_bytes(msg.gas_price, 'big'), int.from_bytes(msg.gas_limit, 'big'), msg.chain_id, token) data = bytearray() data += msg.data_initial_chunk diff --git a/src/trezor/crypto/rlp.py b/src/trezor/crypto/rlp.py index 1f13bd7b3..0745bca0a 100644 --- a/src/trezor/crypto/rlp.py +++ b/src/trezor/crypto/rlp.py @@ -22,7 +22,7 @@ def encode_length(l: int, is_list: bool) -> bytes: def encode(data, include_length=True) -> bytes: if isinstance(data, int): - return encode(int_to_bytes(data)) + data = int_to_bytes(data) if isinstance(data, bytearray): data = bytes(data) if isinstance(data, bytes):