1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-23 02:29:10 +00:00
This commit is contained in:
Roman Zeyde 2025-04-19 09:37:57 +10:00 committed by GitHub
commit 9fa80ce0b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 110 additions and 3 deletions

View File

@ -0,0 +1 @@
Clear sign ETH staking transactions on Everstake pool.

View File

@ -567,8 +567,101 @@ static void ethereum_signing_handle_erc20(struct signing_params *params,
}
}
enum staking_operation_t {
ETH_STAKING_STAKE,
ETH_STAKING_UNSTAKE,
ETH_STAKING_CLAIM,
};
static void layoutEthereumConfirmStakingTx(enum staking_operation_t op) {
const char *_line1 = NULL;
const char *_line2 = NULL;
switch (op) {
case ETH_STAKING_STAKE:
_line1 = _("Stake ETH");
_line2 = _("on Everstake?");
break;
case ETH_STAKING_UNSTAKE:
_line1 = _("Unstake ETH");
_line2 = _("from Everstake?");
break;
case ETH_STAKING_CLAIM:
_line1 = _("Claim ETH");
_line2 = _("from Everstake?");
break;
}
layoutDialogSwipe(&bmp_icon_question, _("Cancel"), _("Confirm"), NULL, _line1,
_line2, NULL, NULL, NULL, NULL);
}
// smart contract 'data' field lengths in bytes
#define SC_FUNC_SIG_BYTES (4)
#define SC_ARGUMENT_BYTES (32)
// staking operations function signatures
static const uint8_t SC_FUNC_SIG_STAKE[] = {0x3a, 0x29, 0xdb, 0xae};
static const uint8_t SC_FUNC_SIG_UNSTAKE[] = {0x76, 0xec, 0x87, 0x1c};
static const uint8_t SC_FUNC_SIG_CLAIM[] = {0x33, 0x98, 0x6f, 0xfa};
// addresses for pool (stake/unstake) and accounting (claim) operations
static const uint8_t ADDRESS_POOL_HOLESKY_TESTNET[] = {
0xaf, 0xa8, 0x48, 0x35, 0x71, 0x54, 0xa6, 0xa6, 0x24, 0x68,
0x6b, 0x34, 0x83, 0x3, 0xef, 0x9a, 0x13, 0xf6, 0x32, 0x64};
static const uint8_t ADDRESS_POOL_MAINNET[] = {
0xd5, 0x23, 0x79, 0x4c, 0x87, 0x9d, 0x9e, 0xc0, 0x28, 0x96,
0xa, 0x23, 0x1f, 0x86, 0x67, 0x58, 0xe4, 0x5, 0xbe, 0x34};
static const uint8_t ADDRESS_ACCOUNTING_HOLESKY_TESTNET[] = {
0x62, 0x40, 0x87, 0xdd, 0x19, 0x4, 0xab, 0x12, 0x2a, 0x32,
0x87, 0x8c, 0xe9, 0xe9, 0x33, 0xc7, 0x7, 0x1f, 0x53, 0xb9};
static const uint8_t ADDRESS_ACCOUNTING_MAINNET[] = {
0x7a, 0x7f, 0xb, 0x3c, 0x23, 0xc2, 0x3a, 0x31, 0xcf, 0xcb,
0xc, 0x44, 0x70, 0x9b, 0xe7, 0xd, 0x4d, 0x54, 0x5c, 0x6e};
// Returns `true` if it is a staking-related transaction and updates `op` with
// its specific operation.
static bool isEthereumStakingTx(const struct signing_params *params,
enum staking_operation_t *op) {
if (params->data_initial_chunk_size < SC_FUNC_SIG_BYTES) {
return false;
}
bool is_address_pool =
((memcmp(params->pubkeyhash, ADDRESS_POOL_HOLESKY_TESTNET, 20) == 0) ||
(memcmp(params->pubkeyhash, ADDRESS_POOL_MAINNET, 20) == 0));
if (is_address_pool) {
if (memcmp(params->data_initial_chunk_bytes, SC_FUNC_SIG_STAKE,
SC_FUNC_SIG_BYTES) == 0) {
*op = ETH_STAKING_STAKE;
return true;
}
if (memcmp(params->data_initial_chunk_bytes, SC_FUNC_SIG_UNSTAKE,
SC_FUNC_SIG_BYTES) == 0) {
*op = ETH_STAKING_UNSTAKE;
return true;
}
}
bool is_address_acconting =
((memcmp(params->pubkeyhash, ADDRESS_ACCOUNTING_HOLESKY_TESTNET, 20) ==
0) ||
(memcmp(params->pubkeyhash, ADDRESS_ACCOUNTING_MAINNET, 20) == 0));
if (is_address_acconting) {
if (memcmp(params->data_initial_chunk_bytes, SC_FUNC_SIG_CLAIM,
SC_FUNC_SIG_BYTES) == 0) {
*op = ETH_STAKING_CLAIM;
return true;
}
}
return false;
}
static bool ethereum_signing_confirm_common(
const struct signing_params *params) {
enum staking_operation_t staking_op;
if (isEthereumStakingTx(params, &staking_op)) {
layoutEthereumConfirmStakingTx(staking_op);
return protectButton(ButtonRequestType_ButtonRequest_SignTx, false);
}
if (params->token != NULL) {
layoutEthereumConfirmTx(params->data_initial_chunk_bytes + 16, 20,
params->data_initial_chunk_bytes + 36, 32,

View File

@ -16,7 +16,7 @@
import pytest
from trezorlib import ethereum, exceptions, messages
from trezorlib import ethereum, exceptions, messages, models
from trezorlib.debuglink import TrezorClientDebugLink as Client
from trezorlib.debuglink import message_filters
from trezorlib.exceptions import TrezorFailure
@ -461,11 +461,12 @@ def test_signtx_data_pagination(client: Client, flow):
_sign_tx_call()
@pytest.mark.models("core")
@parametrize_using_common_fixtures("ethereum/sign_tx_staking.json")
@pytest.mark.parametrize("chunkify", (True, False))
def test_signtx_staking(client: Client, chunkify: bool, parameters: dict, result: dict):
input_flow = InputFlowEthereumSignTxStaking(client).get()
input_flow = None
if client.model is not models.T1B1:
input_flow = InputFlowEthereumSignTxStaking(client).get()
_do_test_signtx(
client, parameters, result, input_flow=input_flow, chunkify=chunkify
)

View File

@ -517,6 +517,18 @@
"T1B1_en_ethereum-test_signtx.py::test_signtx_eip1559[True-nodata]": "5b008a081b4ef9e7b47c9d0c1fc4bb24d729d77841193694232bd2da4a386515",
"T1B1_en_ethereum-test_signtx.py::test_signtx_eip1559_access_list": "f6c5f398d4e80fc8f93cf70e9b10de24b9a968db04dc6ea21b28d1a273f04ca1",
"T1B1_en_ethereum-test_signtx.py::test_signtx_eip1559_access_list_larger": "f6c5f398d4e80fc8f93cf70e9b10de24b9a968db04dc6ea21b28d1a273f04ca1",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[False-claim_holesky]": "b6436c9cff4887a41b5faea0d95d402ae79361d3053f5844781f290bd08d7760",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[False-claim_mainnet]": "b6436c9cff4887a41b5faea0d95d402ae79361d3053f5844781f290bd08d7760",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[False-stake_holesky]": "b1d77955f3d496d32811b24866ef5a87eef560754dd046bdf9644320b0b0c701",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[False-stake_main]": "b1d77955f3d496d32811b24866ef5a87eef560754dd046bdf9644320b0b0c701",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[False-unstake_holesky]": "25bf7fce024ab64eda5094704d121bac62e04318afe05e2995f3282cdaad53ea",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[False-unstake_main]": "25bf7fce024ab64eda5094704d121bac62e04318afe05e2995f3282cdaad53ea",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[True-claim_holesky]": "b6436c9cff4887a41b5faea0d95d402ae79361d3053f5844781f290bd08d7760",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[True-claim_mainnet]": "b6436c9cff4887a41b5faea0d95d402ae79361d3053f5844781f290bd08d7760",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[True-stake_holesky]": "b1d77955f3d496d32811b24866ef5a87eef560754dd046bdf9644320b0b0c701",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[True-stake_main]": "b1d77955f3d496d32811b24866ef5a87eef560754dd046bdf9644320b0b0c701",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[True-unstake_holesky]": "25bf7fce024ab64eda5094704d121bac62e04318afe05e2995f3282cdaad53ea",
"T1B1_en_ethereum-test_signtx.py::test_signtx_staking[True-unstake_main]": "25bf7fce024ab64eda5094704d121bac62e04318afe05e2995f3282cdaad53ea",
"T1B1_en_misc-test_msg_cipherkeyvalue.py::test_decrypt": "a849d9e11e222d1348ce3135680a2a61ed265692adeba4bd48af2fdc65207e61",
"T1B1_en_misc-test_msg_cipherkeyvalue.py::test_decrypt_badlen": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"T1B1_en_misc-test_msg_cipherkeyvalue.py::test_encrypt": "e36d5b5db4b3733c9f484b149c0f966b3dd66e8b54e1b5bccf9da5cca7abed91",