Skip to content

Commit

Permalink
feat(core): improve ethereum tokens ui (fixes #800)
Browse files Browse the repository at this point in the history
  • Loading branch information
matejcik committed Nov 12, 2020
1 parent be9fcf7 commit 3756a05
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 17 deletions.
1 change: 1 addition & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- CoinJoin preauthorization and signing flow. [#1053]
- Value of the `safety-checks` setting to the `Features` message. [#1193]
- ERC20 tokens show contract address for confirmation. Unknown ERC20 tokens show wei amount. [#800]

### Changed
- The `safety-checks` setting gained new possible value `PromptTemporarily` which overrides safety checks until device reboot. [#1133]
Expand Down
30 changes: 24 additions & 6 deletions core/src/apps/ethereum/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
from trezor import ui
from trezor.messages import ButtonRequestType
from trezor.strings import format_amount
from trezor.ui.scroll import Paginated
from trezor.ui.text import Text
from trezor.utils import chunks

from apps.common.confirm import require_confirm, require_hold_to_confirm
from apps.common.layout import split_address

from . import networks, tokens
from . import networks
from .address import address_from_bytes


async def require_confirm_tx(ctx, to_bytes, value, chain_id, token=None, tx_type=None):
def _address_amount_screen(to_bytes, value, chain_id, token, tx_type):
if to_bytes:
to_str = address_from_bytes(to_bytes, networks.by_chain_id(chain_id))
else:
Expand All @@ -24,10 +25,30 @@ async def require_confirm_tx(ctx, to_bytes, value, chain_id, token=None, tx_type
for to_line in split_address(to_str):
text.br()
text.mono(to_line)

return text


async def require_confirm_tx(ctx, to_bytes, value, chain_id, tx_type=None):
text = _address_amount_screen(to_bytes, value, chain_id, None, tx_type)
# we use SignTx, not ConfirmOutput, for compatibility with T1
await require_confirm(ctx, text, ButtonRequestType.SignTx)


async def require_confirm_tx_erc20(ctx, to_bytes, value, chain_id, token, tx_type=None):
address_amount = _address_amount_screen(to_bytes, value, chain_id, token, tx_type)

contract = Text("Confirm transaction", ui.ICON_SEND, ui.GREEN, new_lines=False)
contract.normal(ui.GREY, "Contract:", ui.FG)
_, contract_address, _, _ = token
contract_address_hex = "0x" + hexlify(contract_address).decode()
contract.mono(*split_data(contract_address_hex))

await require_confirm(
ctx, Paginated([address_amount, contract]), ButtonRequestType.SignTx
)


async def require_confirm_fee(
ctx, spending, gas_price, gas_limit, chain_id, token=None, tx_type=None
):
Expand Down Expand Up @@ -57,10 +78,7 @@ async def require_confirm_data(ctx, data, data_total):

def format_ethereum_amount(value: int, token, chain_id: int, tx_type=None):
if token:
if token is tokens.UNKNOWN_TOKEN:
return "Unknown token value"
suffix = token[2]
decimals = token[3]
_, _, suffix, decimals = token
else:
suffix = networks.shortcut_by_chain_id(chain_id, tx_type)
decimals = 18
Expand Down
13 changes: 11 additions & 2 deletions core/src/apps/ethereum/sign_tx.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@

from . import address, tokens
from .keychain import with_keychain_from_chain_id
from .layout import require_confirm_data, require_confirm_fee, require_confirm_tx
from .layout import (
require_confirm_data,
require_confirm_fee,
require_confirm_tx,
require_confirm_tx_erc20,
)

# maximum supported chain id
MAX_CHAIN_ID = 2147483629
Expand Down Expand Up @@ -40,8 +45,12 @@ async def sign_tx(ctx, msg, keychain):
token = tokens.token_by_chain_address(msg.chain_id, address_bytes)
recipient = msg.data_initial_chunk[16:36]
value = int.from_bytes(msg.data_initial_chunk[36:68], "big")
await require_confirm_tx_erc20(
ctx, recipient, value, msg.chain_id, token, msg.tx_type
)

await require_confirm_tx(ctx, recipient, value, msg.chain_id, token, msg.tx_type)
else:
await require_confirm_tx(ctx, recipient, value, msg.chain_id, msg.tx_type)
if token is None and msg.data_length > 0:
await require_confirm_data(ctx, msg.data_initial_chunk, data_total)

Expand Down
4 changes: 1 addition & 3 deletions core/src/apps/ethereum/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# flake8: noqa
# fmt: off

UNKNOWN_TOKEN = (None, None, None, None)


def token_by_chain_address(chain_id, address):
if False:
Expand Down Expand Up @@ -3489,4 +3487,4 @@ def token_by_chain_address(chain_id, address):
return (chain_id, address, "DGT", 0) # esn / DGT
elif address == b"\x01\x46\xb9\xdc\xd9\xfb\x2a\xbc\x1b\x5b\x13\x6c\x28\xd2\x0d\x00\x37\x52\x69\x61":
return (chain_id, address, "TOPM", 18) # esn / TOPM
return UNKNOWN_TOKEN
return (chain_id, address, "Wei UNKN", 0)
4 changes: 1 addition & 3 deletions core/src/apps/ethereum/tokens.py.mako
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ def group_tokens(tokens):
return r
%>\

UNKNOWN_TOKEN = (None, None, None, None)


def token_by_chain_address(chain_id, address):
if False:
Expand All @@ -27,4 +25,4 @@ def token_by_chain_address(chain_id, address):
return (chain_id, address, ${black_repr(t.symbol)}, ${t.decimals}) # ${t.chain} / ${t.name.strip()}
% endfor
% endfor
return UNKNOWN_TOKEN
return (chain_id, address, "Wei UNKN", 0)
12 changes: 11 additions & 1 deletion tests/device_tests/test_msg_ethereum_signtx.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@
TO_ADDR = "0x1d1c328764a41bda0492b66baa30c4a339ff85ef"


def input_flow_token(debug):
yield # confirm amount + destination
debug.swipe_up()
debug.press_yes()
yield # confirm transaction
debug.press_yes()


@pytest.mark.altcoin
@pytest.mark.ethereum
class TestMsgEthereumSigntx:
Expand All @@ -38,6 +46,7 @@ def test_ethereum_signtx_known_erc20_token(self, client):
messages.EthereumTxRequest(data_length=None),
]
)
client.set_input_flow(input_flow_token(client.debug))

data = bytearray()
# method id signalizing `transfer(address _to, uint256 _value)` function
Expand Down Expand Up @@ -124,6 +133,7 @@ def test_ethereum_signtx_unknown_erc20_token(self, client):
messages.EthereumTxRequest(data_length=None),
]
)
client.set_input_flow(input_flow_token(client.debug))

data = bytearray()
# method id signalizing `transfer(address _to, uint256 _value)` function
Expand All @@ -140,7 +150,7 @@ def test_ethereum_signtx_unknown_erc20_token(self, client):
"0000000000000000000000000000000000000000000000000000000000000123"
)
)
# since this token is unknown trezor should display "unknown token value"
# since this token is unknown trezor should display the amount in wei

sig_v, sig_r, sig_s = ethereum.sign_tx(
client,
Expand Down
4 changes: 2 additions & 2 deletions tests/ui_tests/fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,11 @@
"test_msg_ethereum_signmessage.py::test_sign[VeryLongMessage!VeryLongMessage!VeryLongMessage!VeryLong": "df073fddce8691ef78717584fde2d66f8335a59dc4aec158e72197c1faafa31d",
"test_msg_ethereum_signtx.py-test_ethereum_sanity_checks": "5a80508a71a9ef64f94762b07636f90e464832f0f4a3102af8fa1a8c69e94586",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_data": "5d5df0ea6a141aa6b79717d944bce36dbc0966299e7283629c7354cef4bf6b50",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_known_erc20_token": "2cda05063110c8eda4b7c77f4ad632cfeb76649eba0d1733be125890c9aab937",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_known_erc20_token": "d8fdb580fa22afdb64750d05b9ddbcf889662933b683668e7a4f0ff77707174c",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_message": "f15bfcd910b3a315515a07babc1f1bbfb30a78a9304b0fa4646cfc91911a638c",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_newcontract": "b8672006a9590fa69b4a882830810734ddbf120327780d59e51dd894afa383cc",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_nodata": "9d69b61aee19c42c22651cd9912d8a29b2ac6987b552966a6659e3505d4869e7",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_unknown_erc20_token": "74ccd107e69bfd5d08355636f4d5814a9e4f2d2153f63a4a10bfab39c4ff60a1",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_unknown_erc20_token": "bec70cf4c6086749f7d32964ea51f83458327a6698dc3ee5fe3c2a0e8f059022",
"test_msg_ethereum_signtx.py-test_ethereum_signtx_wanchain": "4abb87c2b2836601971af8483fb95ff0f5913bdf912ff3e17a20c8c34872470a",
"test_msg_ethereum_signtx_eip155.py::test_chain_ids[1-60-sig0]": "4fb0b0b8fb5f803132a422d8b26d51e46ee6976c04ad0de29230adfc63d0e44c",
"test_msg_ethereum_signtx_eip155.py::test_chain_ids[2018-2018-sig4]": "1eaf3c481d105f3c5da45e3455f6af13ac7c77a3796a9b69fdd38adae89a0401",
Expand Down

0 comments on commit 3756a05

Please sign in to comment.