test(core): move debug asserts into unit tests
What changed, and why it matters
This commit is a code cleanup and test reorganization. It moves sanity-check assertions (which verify that hardcoded cryptocurrency addresses and function signatures are correct) out of the main firmware code and into dedicated unit tests. The actual checks still run during development testing, but they no longer get baked into debug firmware builds. There is no security vulnerability being fixed here.
No security action required. Treat as a normal refactoring/test-maintenance commit. Continue running the relocated unit tests in CI to catch future typos in hardcoded constants.
Security signals we found
No vulnerability patched
No change to runtime behavior or trust assumptions
Debug-only assertions relocated to unit tests
Hardcoded address/signature constants remain identical
Evidence from the diff
The change removes if __debug__:-guarded assert blocks from production modules (clear_signing_definitions.py, yielding.py, yielding_vaults.py, tron/consts.py) and re-creates equivalent assertions as unit tests under core/tests/. The assertions verify that hardcoded function selectors match keccak256 of their Solidity signatures and that hardcoded token/vault address bytes match published blockchain addresses. The behavior of the firmware is unchanged; only the location and build-time inclusion of these self-tests changes. A comment typo in the USDT link is also corrected.
Changed components
core/src/apps/ethereum/clear_signing_definitions.pycore/src/apps/ethereum/yielding.pycore/src/apps/ethereum/yielding_vaults.pycore/src/apps/tron/consts.pycore/tests/test_apps.ethereum.clear_signing_definitions.pycore/tests/test_apps.ethereum.yielding.pycore/tests/test_apps.ethereum.yielding_vaults.pycore/tests/test_apps.tron.consts.pyInspect captured patch +260 / −199
diff --git a/core/src/apps/ethereum/clear_signing_definitions.py b/core/src/apps/ethereum/clear_signing_definitions.py
index be946778..dc80bc58 100644
--- a/core/src/apps/ethereum/clear_signing_definitions.py
+++ b/core/src/apps/ethereum/clear_signing_definitions.py
@@ -50,16 +50,6 @@ TRANSFER_DISPLAY_FORMAT = DisplayFormat(
],
)
-if __debug__:
- from trezor.crypto import base58
-
- assert APPROVE_DISPLAY_FORMAT.func_sig == base58.keccak_32(
- b"approve(address,uint256)"
- )
- assert TRANSFER_DISPLAY_FORMAT.func_sig == base58.keccak_32(
- b"transfer(address,uint256)"
- )
-
def all_display_formats() -> Generator[DisplayFormat, None, None]:
@@ -124,10 +114,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
# its minReturnAmount because its dstToken is available.)
_FUNC_SIG = unhexlify("07ed2379")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swap(address,(address,address,address,address,uint256,uint256,uint256),bytes)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -174,10 +160,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("83800a8e")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"unoswap(uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -213,10 +195,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("e2c95c82")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"unoswapTo(uint256,uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -253,10 +231,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("8770ba91")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"unoswap2(uint256,uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -293,10 +267,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("19367472")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"unoswap3(uint256,uint256,uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -334,10 +304,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("ea76dddf")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"unoswapTo2(uint256,uint256,uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -375,10 +341,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("f7a70056")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"unoswapTo3(uint256,uint256,uint256,uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -417,8 +379,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("a76dfc3b")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(b"ethUnoswap(uint256,uint256)")
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -449,8 +409,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("89af926a")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(b"ethUnoswap2(uint256,uint256,uint256)")
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -482,10 +440,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("188ac35d")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"ethUnoswap3(uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -518,8 +472,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("175accdc")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(b"ethUnoswapTo(uint256,uint256,uint256)")
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -551,10 +503,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("0f449d71")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"ethUnoswapTo2(uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -587,10 +535,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("493189f0")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"ethUnoswapTo3(uint256,uint256,uint256,uint256,uint256)"
- )
yield (
DisplayFormat(
binding_context=ONEINCH_CONTEXT,
@@ -672,10 +616,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
]
_FUNC_SIG = unhexlify("5fd9ae2e")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swapTokensMultipleV3ERC20ToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])"
- )
yield (
DisplayFormat(
binding_context=LIFI_CONTEXT,
@@ -727,10 +667,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("2c57e884")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swapTokensMultipleV3ERC20ToNative(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])"
- )
yield (
DisplayFormat(
binding_context=LIFI_CONTEXT,
@@ -780,10 +716,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("736eac0b")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swapTokensMultipleV3NativeToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])"
- )
yield (
DisplayFormat(
binding_context=LIFI_CONTEXT,
@@ -833,10 +765,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("4666fc80")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swapTokensSingleV3ERC20ToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))"
- )
yield (
DisplayFormat(
binding_context=LIFI_CONTEXT,
@@ -884,10 +812,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("733214a3")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swapTokensSingleV3ERC20ToNative(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))"
- )
yield (
DisplayFormat(
binding_context=LIFI_CONTEXT,
@@ -935,10 +859,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("af7060fd")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swapTokensSingleV3NativeToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))"
- )
yield (
DisplayFormat(
binding_context=LIFI_CONTEXT,
@@ -986,10 +906,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("4630a0d8")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"swapTokensGeneric(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])"
- )
yield (
DisplayFormat(
binding_context=LIFI_CONTEXT,
@@ -1057,10 +973,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("b858183f")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"exactInput((bytes,address,uint256,uint256))"
- )
yield (
DisplayFormat(
binding_context=UNISWAP_CONTEXT,
@@ -1102,10 +1014,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("04e45aaf")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"exactInputSingle((address,address,uint24,address,uint256,uint256,uint160))"
- )
yield (
DisplayFormat(
binding_context=UNISWAP_CONTEXT,
@@ -1155,10 +1063,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("09b81346")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"exactOutput((bytes,address,uint256,uint256))"
- )
yield (
DisplayFormat(
binding_context=UNISWAP_CONTEXT,
@@ -1200,10 +1104,6 @@ def all_display_formats() -> Generator[DisplayFormat, None, None]:
)
_FUNC_SIG = unhexlify("5023b4df")
- if __debug__:
- assert _FUNC_SIG == base58.keccak_32(
- b"exactOutputSingle((address,address,uint24,address,uint256,uint256,uint160))"
- )
yield (
DisplayFormat(
binding_context=UNISWAP_CONTEXT,
diff --git a/core/src/apps/ethereum/yielding.py b/core/src/apps/ethereum/yielding.py
index 55441aa0..0d378f3a 100644
--- a/core/src/apps/ethereum/yielding.py
+++ b/core/src/apps/ethereum/yielding.py
@@ -25,34 +25,6 @@ _MERKL_XYZ_CLAIM_DISTRIBUTOR_ADDR = (
b"\x3e\xf3\xd8\xba\x38\xeb\xe1\x8d\xb1\x33\xce\xc1\x08\xf4\xd1\x4c\xe0\x0d\xd9\xae"
)
-if __debug__:
- from ubinascii import unhexlify
-
- from trezor.crypto.hashlib import sha3_256
-
- assert (
- FUNC_SIG_DEPOSIT
- == sha3_256(b"deposit(uint256,address)", keccak=True).digest()[:4]
- )
- assert (
- FUNC_SIG_WITHDRAW
- == sha3_256(b"withdraw(uint256,address,address)", keccak=True).digest()[:4]
- )
- assert (
- FUNC_SIG_REDEEM
- == sha3_256(b"redeem(uint256,address,address)", keccak=True).digest()[:4]
- )
- assert (
- FUNC_SIG_CLAIM
- == sha3_256(
- b"claim(address[],address[],uint256[],bytes32[][])", keccak=True
- ).digest()[:4]
- )
- # https://etherscan.io/address/0x3ef3d8ba38ebe18db133cec108f4d14ce00dd9ae
- assert _MERKL_XYZ_CLAIM_DISTRIBUTOR_ADDR == unhexlify(
- "3ef3d8ba38ebe18db133cec108f4d14ce00dd9ae"
- )
-
# deposit(uint256 assets, address receiver)
DEPOSIT_DISPLAY_FORMAT = DisplayFormat(
binding_context=None,
diff --git a/core/src/apps/ethereum/yielding_vaults.py b/core/src/apps/ethereum/yielding_vaults.py
index 3f797046..d5e48e69 100644
--- a/core/src/apps/ethereum/yielding_vaults.py
+++ b/core/src/apps/ethereum/yielding_vaults.py
@@ -133,32 +133,6 @@ KNOWN_VAULTS = (
),
)
-if __debug__:
- from ubinascii import unhexlify
-
- # https://etherscan.io/address/0xa511d618cD0F9d7cAD791009d7c5E3b19c9568da
- assert _TEST_SH_USDC_VAULT_ADDRESS == unhexlify(
- "a511d618cd0f9d7cad791009d7c5e3b19c9568da"
- )
- # https://etherscan.io/address/0xde6c23E561F3e55846207EC45A91b777e0F7C889
- assert _SH_USDC_VAULT_ADDRESS == unhexlify(
- "de6c23e561f3e55846207ec45a91b777e0f7c889"
- )
- # https://etherscan.io/address/0xE4DB1c5A1B709CE4d2adA6985D9D506e58F73829
- assert _SH_USDT_VAULT_ADDRESS == unhexlify(
- "e4db1c5a1b709ce4d2ada6985d9d506e58f73829"
- )
- # https://etherscan.io/address/0x704cFb08969048a8DFf298B214F959791d8Da509
- assert _SH_ETH_VAULT_ADDRESS == unhexlify(
- "704cfb08969048a8dff298b214f959791d8da509"
- )
- # https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
- assert _USDC_ADDRESS == unhexlify("a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
- # https://etherscan.io/token/0xdAC1F958D2ee523a2206206994597C13D831ec7
- assert _USDT_ADDRESS == unhexlify("dac17f958d2ee523a2206206994597c13d831ec7")
- # https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
- assert _WETH_ADDRESS == unhexlify("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")
-
UNKNOWN_VAULT = EthereumVaultInfo(
address=None,
chain_id=None,
diff --git a/core/src/apps/tron/consts.py b/core/src/apps/tron/consts.py
index e44132dc..ec82d609 100644
--- a/core/src/apps/tron/consts.py
+++ b/core/src/apps/tron/consts.py
@@ -57,51 +57,6 @@ _AINFT_ADDRESS = b"\x41\x3d\xfe\x63\x7b\x2b\x9a\xe4\x19\x0a\x45\x8b\x5f\x3e\xfc\
_STRX_ADDRESS = b"\x41\xc6\x4e\x69\xac\xde\x1c\x7b\x16\xc2\xa3\xef\xcd\xbb\xda\xa9\x6c\x36\x44\xc2\xb3"
_KLEVER_ADDRESS = b"\x41\xd8\xb8\x08\x98\x56\xce\xd3\x03\x86\x01\xcb\xeb\x1e\x3f\x76\x5c\xab\xc1\x2a\x41"
-if __debug__:
- from trezor.crypto import base58
-
- # https://shasta.tronscan.org/#/token20/TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs
- assert (
- base58.encode_check(_SHASTA_USDT_ADDRESS)
- == "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs"
- )
- # https://tronscan.org/#/token20/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
- assert base58.encode_check(_USDT_ADDRESS) == "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
- # https://tronscan.org/#/token20/TXDk8mbtRbXeYuMNS83CfKPaYYT8XWv9Hz
- assert base58.encode_check(_USDD_ADDRESS) == "TXDk8mbtRbXeYuMNS83CfKPaYYT8XWv9Hz"
- # https://tronscan.org/#/token20/TSSMHYeV2uE9qYH95DqyoCuNCzEL1NvU3S
- assert base58.encode_check(_SUN_ADDRESS) == "TSSMHYeV2uE9qYH95DqyoCuNCzEL1NvU3S"
- # https://tronscan.org/#/token20/TCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9
- assert base58.encode_check(_JST_ADDRESS) == "TCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9"
- # https://tronscan.org/#/token20/TAFjULxiVgT4qWk6UZwjqwZXTSaGaqnVp4
- assert base58.encode_check(_BTT_ADDRESS) == "TAFjULxiVgT4qWk6UZwjqwZXTSaGaqnVp4"
- # https://tronscan.org/#/token20/TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7
- assert base58.encode_check(_WIN_ADDRESS) == "TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7"
- # https://tronscan.org/#/token20/TYhWwKpw43ENFWBTGpzLHn3882f2au7SMi
- assert base58.encode_check(_WBTC_ADDRESS) == "TYhWwKpw43ENFWBTGpzLHn3882f2au7SMi"
- # https://tronscan.org/#/token20/THb4CqiFdwNHsWsQCs4JhzwjMWys4aqCbF
- assert (
- base58.encode_check(_ETH_TRON_ADDRESS) == "THb4CqiFdwNHsWsQCs4JhzwjMWys4aqCbF"
- )
- # https://tronscan.org/#/token20/TPFqcBAaaUMCSVRCqPaQ9QnzKhmuoLR6Rc
- assert base58.encode_check(_USD1_ADDRESS) == "TPFqcBAaaUMCSVRCqPaQ9QnzKhmuoLR6Rc"
- # https://tronscan.org/#/token20/TUPM7K8REVzD2UdV4R5fe5M8XbnR2DdoJ6
- assert base58.encode_check(_HTX_ADDRESS) == "TUPM7K8REVzD2UdV4R5fe5M8XbnR2DdoJ6"
- # https://tronscan.org/#/token20/TUpMhErZL2fhh4sVNULAbNKLokS4GjC1F4
- assert base58.encode_check(_TUSD_ADDRESS) == "TUpMhErZL2fhh4sVNULAbNKLokS4GjC1F4"
- # https://tronscan.org/#/token20/TFptbWaARrWTX5Yvy3gNG5Lm8BmhPx82Bt
- assert base58.encode_check(_WBT_ADDRESS) == "TFptbWaARrWTX5Yvy3gNG5Lm8BmhPx82Bt"
- # https://tronscan.org/#/token20/TNUC9Qb1rRpS5CbWLmNMxXBjyFoydXjWFR
- assert base58.encode_check(_WTRX_ADDRESS) == "TNUC9Qb1rRpS5CbWLmNMxXBjyFoydXjWFR"
- # https://tronscan.org/#/token20/TKkeiboTkxXKJpbmVFbv4a8ov5rAfRDMf9
- assert base58.encode_check(_SUNOLD_ADDRESS) == "TKkeiboTkxXKJpbmVFbv4a8ov5rAfRDMf9"
- # https://tronscan.org/#/token20/TFczxzPhnThNSqr5by8tvxsdCFRRz6cPNq
- assert base58.encode_check(_AINFT_ADDRESS) == "TFczxzPhnThNSqr5by8tvxsdCFRRz6cPNq"
- # https://tronscan.org/#/token20/TU3kjFuhtEo42tsCBtfYUAZxoqQ4yuSLQ5
- assert base58.encode_check(_STRX_ADDRESS) == "TU3kjFuhtEo42tsCBtfYUAZxoqQ4yuSLQ5"
- # https://tronscan.org/#/token20/TVj7RNVHy6thbM7BWdSe9G6gXwKhjhdNZS
- assert base58.encode_check(_KLEVER_ADDRESS) == "TVj7RNVHy6thbM7BWdSe9G6gXwKhjhdNZS"
-
def token_iterator() -> Iterator[Tuple[AnyBytes, int, str]]:
yield (_SHASTA_USDT_ADDRESS, 6, "tUSDT")
diff --git a/core/tests/test_apps.ethereum.clear_signing_definitions.py b/core/tests/test_apps.ethereum.clear_signing_definitions.py
new file mode 100644
index 00000000..011dde61
--- /dev/null
+++ b/core/tests/test_apps.ethereum.clear_signing_definitions.py
@@ -0,0 +1,102 @@
+# flake8: noqa: F403,F405
+from common import * # isort:skip
+
+if not utils.BITCOIN_ONLY:
+ from trezor.crypto import base58
+
+ from apps.ethereum.clear_signing_definitions import (
+ APPROVE_DISPLAY_FORMAT,
+ TRANSFER_DISPLAY_FORMAT,
+ )
+
+# (hex selector, Solidity function signature) pairs — each hardcoded selector
+# must match the first 4 bytes of keccak256(signature).
+_KNOWN_FUNC_SIGS = (
+ ("095ea7b3", b"approve(address,uint256)"),
+ ("a9059cbb", b"transfer(address,uint256)"),
+ (
+ "07ed2379",
+ b"swap(address,(address,address,address,address,uint256,uint256,uint256),bytes)",
+ ),
+ ("83800a8e", b"unoswap(uint256,uint256,uint256,uint256)"),
+ ("e2c95c82", b"unoswapTo(uint256,uint256,uint256,uint256,uint256)"),
+ ("8770ba91", b"unoswap2(uint256,uint256,uint256,uint256,uint256)"),
+ ("19367472", b"unoswap3(uint256,uint256,uint256,uint256,uint256,uint256)"),
+ ("ea76dddf", b"unoswapTo2(uint256,uint256,uint256,uint256,uint256,uint256)"),
+ (
+ "f7a70056",
+ b"unoswapTo3(uint256,uint256,uint256,uint256,uint256,uint256,uint256)",
+ ),
+ ("a76dfc3b", b"ethUnoswap(uint256,uint256)"),
+ ("89af926a", b"ethUnoswap2(uint256,uint256,uint256)"),
+ ("188ac35d", b"ethUnoswap3(uint256,uint256,uint256,uint256)"),
+ ("175accdc", b"ethUnoswapTo(uint256,uint256,uint256)"),
+ ("0f449d71", b"ethUnoswapTo2(uint256,uint256,uint256,uint256)"),
+ ("493189f0", b"ethUnoswapTo3(uint256,uint256,uint256,uint256,uint256)"),
+ (
+ "5fd9ae2e",
+ b"swapTokensMultipleV3ERC20ToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])",
+ ),
+ (
+ "2c57e884",
+ b"swapTokensMultipleV3ERC20ToNative(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])",
+ ),
+ (
+ "736eac0b",
+ b"swapTokensMultipleV3NativeToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])",
+ ),
+ (
+ "4666fc80",
+ b"swapTokensSingleV3ERC20ToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))",
+ ),
+ (
+ "733214a3",
+ b"swapTokensSingleV3ERC20ToNative(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))",
+ ),
+ (
+ "af7060fd",
+ b"swapTokensSingleV3NativeToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))",
+ ),
+ (
+ "4630a0d8",
+ b"swapTokensGeneric(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool)[])",
+ ),
+ ("b858183f", b"exactInput((bytes,address,uint256,uint256))"),
+ (
+ "04e45aaf",
+ b"exactInputSingle((address,address,uint24,address,uint256,uint256,uint160))",
+ ),
+ ("09b81346", b"exactOutput((bytes,address,uint256,uint256))"),
+ (
+ "5023b4df",
+ b"exactOutputSingle((address,address,uint24,address,uint256,uint256,uint160))",
+ ),
+)
+
+
+@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
+class TestEthereumClearSigningDefinitions(unittest.TestCase):
+ def test_known_func_sigs(self):
+ # Verify that every hardcoded function selector matches the first 4
+ # bytes of keccak256 of its Solidity signature, so a typo cannot
+ # silently match the wrong contract method.
+ for hex_selector, signature in _KNOWN_FUNC_SIGS:
+ self.assertEqual(
+ unhexlify(hex_selector),
+ base58.keccak_32(signature),
+ msg=f"selector mismatch for {signature.decode()}",
+ )
+
+ def test_approve_transfer_func_sigs(self):
+ self.assertEqual(
+ APPROVE_DISPLAY_FORMAT.func_sig,
+ base58.keccak_32(b"approve(address,uint256)"),
+ )
+ self.assertEqual(
+ TRANSFER_DISPLAY_FORMAT.func_sig,
+ base58.keccak_32(b"transfer(address,uint256)"),
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/core/tests/test_apps.ethereum.yielding.py b/core/tests/test_apps.ethereum.yielding.py
new file mode 100644
index 00000000..aa0ea0cc
--- /dev/null
+++ b/core/tests/test_apps.ethereum.yielding.py
@@ -0,0 +1,42 @@
+# flake8: noqa: F403,F405
+from common import * # isort:skip
+
+if not utils.BITCOIN_ONLY:
+ from trezor.crypto import base58
+
+ from apps.ethereum import yielding
+
+
+@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
+class TestEthereumYielding(unittest.TestCase):
+ def test_known_func_sigs(self):
+ # Verify that the hardcoded ERC-4626 / claim function selectors match
+ # the keccak256 of their signatures, so a typo cannot silently match
+ # the wrong contract method.
+ self.assertEqual(
+ yielding.FUNC_SIG_DEPOSIT,
+ base58.keccak_32(b"deposit(uint256,address)"),
+ )
+ self.assertEqual(
+ yielding.FUNC_SIG_WITHDRAW,
+ base58.keccak_32(b"withdraw(uint256,address,address)"),
+ )
+ self.assertEqual(
+ yielding.FUNC_SIG_REDEEM,
+ base58.keccak_32(b"redeem(uint256,address,address)"),
+ )
+ self.assertEqual(
+ yielding.FUNC_SIG_CLAIM,
+ base58.keccak_32(b"claim(address[],address[],uint256[],bytes32[][])"),
+ )
+
+ def test_known_address(self):
+ # https://etherscan.io/address/0x3ef3d8ba38ebe18db133cec108f4d14ce00dd9ae
+ self.assertEqual(
+ yielding._MERKL_XYZ_CLAIM_DISTRIBUTOR_ADDR,
+ unhexlify("3ef3d8ba38ebe18db133cec108f4d14ce00dd9ae"),
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/core/tests/test_apps.ethereum.yielding_vaults.py b/core/tests/test_apps.ethereum.yielding_vaults.py
new file mode 100644
index 00000000..0abfe28f
--- /dev/null
+++ b/core/tests/test_apps.ethereum.yielding_vaults.py
@@ -0,0 +1,53 @@
+# flake8: noqa: F403,F405
+from common import * # isort:skip
+
+if not utils.BITCOIN_ONLY:
+ from apps.ethereum import yielding_vaults
+
+
+@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
+class TestEthereumYieldingVaults(unittest.TestCase):
+ def test_known_vault_addresses(self):
+ # Verify that the hardcoded address bytes match the published
+ # Etherscan addresses, so a typo in the literals cannot silently
+ # route users to a wrong vault.
+ self.assertEqual(
+ yielding_vaults._TEST_SH_USDC_VAULT_ADDRESS,
+ unhexlify("a511d618cd0f9d7cad791009d7c5e3b19c9568da"),
+ )
+ # https://etherscan.io/address/0xde6c23E561F3e55846207EC45A91b777e0F7C889
+ self.assertEqual(
+ yielding_vaults._SH_USDC_VAULT_ADDRESS,
+ unhexlify("de6c23e561f3e55846207ec45a91b777e0f7c889"),
+ )
+ # https://etherscan.io/address/0xE4DB1c5A1B709CE4d2adA6985D9D506e58F73829
+ self.assertEqual(
+ yielding_vaults._SH_USDT_VAULT_ADDRESS,
+ unhexlify("e4db1c5a1b709ce4d2ada6985d9d506e58f73829"),
+ )
+ # https://etherscan.io/address/0x704cFb08969048a8DFf298B214F959791d8Da509
+ self.assertEqual(
+ yielding_vaults._SH_ETH_VAULT_ADDRESS,
+ unhexlify("704cfb08969048a8dff298b214f959791d8da509"),
+ )
+
+ def test_known_token_addresses(self):
+ # https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
+ self.assertEqual(
+ yielding_vaults._USDC_ADDRESS,
+ unhexlify("a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"),
+ )
+ # https://etherscan.io/token/0xdAC17F958D2ee523a2206206994597C13D831ec7
+ self.assertEqual(
+ yielding_vaults._USDT_ADDRESS,
+ unhexlify("dac17f958d2ee523a2206206994597c13d831ec7"),
+ )
+ # https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
+ self.assertEqual(
+ yielding_vaults._WETH_ADDRESS,
+ unhexlify("c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"),
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/core/tests/test_apps.tron.consts.py b/core/tests/test_apps.tron.consts.py
new file mode 100644
index 00000000..dc54995d
--- /dev/null
+++ b/core/tests/test_apps.tron.consts.py
@@ -0,0 +1,63 @@
+# flake8: noqa: F403,F405
+from common import * # isort:skip
+
+if not utils.BITCOIN_ONLY:
+ from trezor.crypto import base58
+
+ from apps.tron import consts
+
+
+@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
+class TestTronConsts(unittest.TestCase):
+ def test_known_token_addresses(self):
+ # Verify that the hardcoded TRC-20 address bytes match the published
+ # base58check addresses, so a typo in the literals cannot silently
+ # route users to a wrong token.
+ expected = {
+ # https://shasta.tronscan.org/#/token20/TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs
+ consts._SHASTA_USDT_ADDRESS: "TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs",
+ # https://tronscan.org/#/token20/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
+ consts._USDT_ADDRESS: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
+ # https://tronscan.org/#/token20/TXDk8mbtRbXeYuMNS83CfKPaYYT8XWv9Hz
+ consts._USDD_ADDRESS: "TXDk8mbtRbXeYuMNS83CfKPaYYT8XWv9Hz",
+ # https://tronscan.org/#/token20/TSSMHYeV2uE9qYH95DqyoCuNCzEL1NvU3S
+ consts._SUN_ADDRESS: "TSSMHYeV2uE9qYH95DqyoCuNCzEL1NvU3S",
+ # https://tronscan.org/#/token20/TCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9
+ consts._JST_ADDRESS: "TCFLL5dx5ZJdKnWuesXxi1VPwjLVmWZZy9",
+ # https://tronscan.org/#/token20/TAFjULxiVgT4qWk6UZwjqwZXTSaGaqnVp4
+ consts._BTT_ADDRESS: "TAFjULxiVgT4qWk6UZwjqwZXTSaGaqnVp4",
+ # https://tronscan.org/#/token20/TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7
+ consts._WIN_ADDRESS: "TLa2f6VPqDgRE67v1736s7bJ8Ray5wYjU7",
+ # https://tronscan.org/#/token20/TYhWwKpw43ENFWBTGpzLHn3882f2au7SMi
+ consts._WBTC_ADDRESS: "TYhWwKpw43ENFWBTGpzLHn3882f2au7SMi",
+ # https://tronscan.org/#/token20/THb4CqiFdwNHsWsQCs4JhzwjMWys4aqCbF
+ consts._ETH_TRON_ADDRESS: "THb4CqiFdwNHsWsQCs4JhzwjMWys4aqCbF",
+ # https://tronscan.org/#/token20/TPFqcBAaaUMCSVRCqPaQ9QnzKhmuoLR6Rc
+ consts._USD1_ADDRESS: "TPFqcBAaaUMCSVRCqPaQ9QnzKhmuoLR6Rc",
+ # https://tronscan.org/#/token20/TUPM7K8REVzD2UdV4R5fe5M8XbnR2DdoJ6
+ consts._HTX_ADDRESS: "TUPM7K8REVzD2UdV4R5fe5M8XbnR2DdoJ6",
+ # https://tronscan.org/#/token20/TUpMhErZL2fhh4sVNULAbNKLokS4GjC1F4
+ consts._TUSD_ADDRESS: "TUpMhErZL2fhh4sVNULAbNKLokS4GjC1F4",
+ # https://tronscan.org/#/token20/TFptbWaARrWTX5Yvy3gNG5Lm8BmhPx82Bt
+ consts._WBT_ADDRESS: "TFptbWaARrWTX5Yvy3gNG5Lm8BmhPx82Bt",
+ # https://tronscan.org/#/token20/TNUC9Qb1rRpS5CbWLmNMxXBjyFoydXjWFR
+ consts._WTRX_ADDRESS: "TNUC9Qb1rRpS5CbWLmNMxXBjyFoydXjWFR",
+ # https://tronscan.org/#/token20/TKkeiboTkxXKJpbmVFbv4a8ov5rAfRDMf9
+ consts._SUNOLD_ADDRESS: "TKkeiboTkxXKJpbmVFbv4a8ov5rAfRDMf9",
+ # https://tronscan.org/#/token20/TFczxzPhnThNSqr5by8tvxsdCFRRz6cPNq
+ consts._AINFT_ADDRESS: "TFczxzPhnThNSqr5by8tvxsdCFRRz6cPNq",
+ # https://tronscan.org/#/token20/TU3kjFuhtEo42tsCBtfYUAZxoqQ4yuSLQ5
+ consts._STRX_ADDRESS: "TU3kjFuhtEo42tsCBtfYUAZxoqQ4yuSLQ5",
+ # https://tronscan.org/#/token20/TVj7RNVHy6thbM7BWdSe9G6gXwKhjhdNZS
+ consts._KLEVER_ADDRESS: "TVj7RNVHy6thbM7BWdSe9G6gXwKhjhdNZS",
+ }
+ for address_bytes, expected_b58 in expected.items():
+ self.assertEqual(
+ base58.encode_check(address_bytes),
+ expected_b58,
+ msg=f"mismatch for {expected_b58}",
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
Why this scored 14/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.