What changed, and why it matters
This commit adds human-readable display definitions for 1inch decentralized-exchange swap transactions on Trezor hardware wallets. It tells the wallet how to decode and label 1inch swap parameters (amounts, beneficiary, last pool) so users can verify what they are signing on the device screen. The change is purely a data/configuration addition plus matching tests; it does not alter cryptographic code, transaction validation, or signing logic. There is no indication in the commit that this fixes a security vulnerability.
No security action required. Review as normal feature/data addition. If auditing, verify that the new 1inch function signatures, address, chain IDs, and field paths match the official 1inch AggregationRouterV6 ABI and the referenced Ledger clear-signing registry.
Security signals we found
Adds clear-signing metadata only; no signing or key-management code changed
Uses existing parser/formatter primitives; no new parsing logic introduced
Function signatures are verified against keccak_32 under __debug__ assertions
Native-currency address allowlist is explicitly limited to two known sentinel values
Commit message is a routine 'chore' with [no changelog] and no security framing
Some test fixtures are hand-assembled/fabricated calldata, but they are test inputs, not runtime definitions
Evidence from the diff
The patch extends core/src/apps/ethereum/clear_signing_definitions.py with DisplayFormat entries for 1inch AggregationRouterV6 functions (swap, unoswap variants, ethUnoswap variants). It binds them to the known 1inch router address across 13 EVM chains and defines parameter/field formatters using existing parsing primitives (parse_address, parse_uint256, parse_bytes32, TokenAmountFormatter, AddressNameFormatter, AmountFormatter). It also adds 13 test fixtures in common/tests/fixtures/ethereum/sign_tx_clear_signing.json with real and hand-assembled calldata. The existing LiFi and Uniswap definitions were refactored from ALL_DISPLAY_FORMATS.extend(list) to individual ALL_DISPLAY_FORMATS.append(…) calls and their function signatures are now verified at runtime with keccak_32 assertions under if debug. No code that performs signing, key handling, or transaction authorization was changed.
Changed components
core/src/apps/ethereum/clear_signing_definitions.pycommon/tests/fixtures/ethereum/sign_tx_clear_signing.jsonInspect captured patch +1309 / −452
diff --git a/common/tests/fixtures/ethereum/sign_tx_clear_signing.json b/common/tests/fixtures/ethereum/sign_tx_clear_signing.json
index a1a501bc..f848cb4f 100644
--- a/common/tests/fixtures/ethereum/sign_tx_clear_signing.json
+++ b/common/tests/fixtures/ethereum/sign_tx_clear_signing.json
@@ -4,6 +4,266 @@
"passphrase": ""
},
"tests": [
+ {
+ "name": "clear_sign_1inch_swap",
+ "parameters": {
+ "comment": "https://etherscan.io/tx/0x2c18175d5bf78e80892b21896b00eb27bf07ff5948b4be1e56038d8ba7266950",
+ "data": "07ed2379000000000000000000000000990636ecb3ff04d33d92e970d3d588bf5cd8d086000000000000000000000000f0db65d17e30a966c2ae6a21f6bba71cea6e97540000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000990636ecb3ff04d33d92e970d3d588bf5cd8d086000000000000000000000000459e213d8b5e79d706ab22b945e3af983d51bc4c000000000000000000000000000000000000000000000071003fa9d87dc2000000000000000000000000000000000000000000000000000000000000002de7410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000009f90000000000000000000000000000000000000009db0009ad00096300004e00a0744c8c09f0db65d17e30a966c2ae6a21f6bba71cea6e975490cbe4bdd538d6e9b379bff5fe72c3d67a521de500000000000000000000000000000000000000000000000005c9205756dc400000a098aed105000000000000000000000000000000007d007d000000000000000000000000000000000000000000000000000008dd00055200a007e5c0d200000000000000000000000000000000000000000000000000052e0002105120111111125421ca6dc452d289314280a0f8842a65f0db65d17e30a966c2ae6a21f6bba71cea6e97540124cc713a04811642c03b93bb3fe7905266a4a3c300713f97460272be5479f22777c211dc84000000000000000000000000bee3211ab312a8d065c4fef0247448e17a8da0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000f0db65d17e30a966c2ae6a21f6bba71cea6e97540000000000000000000000000000000000000000000000000000000042b7e1d80000000000000000000000000000000000000000000000387d3b44c09372e00000000000000000000000000000000b2ddf0069ba7c5fe970d3d588bf5cd8d08600000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414d00e9e0bed4d42074ef1786b2114d6a211ebe817c429c7da3c74105147d9a6b29dc0d7f1173a1fa5cb0460dc44b5b27946af164e156c5ec48d5d622d805a32b1c0000000000000000000000000000000000000000000000000000000000000000a098aed105000000000000000000000000000000001900e1000000000000000000000000000000000000000000000000000002e600028300a007e5c0d200000000000000000000000000000000000000000000000000025f0002105120111111125421ca6dc452d289314280a0f8842a65dac17f958d2ee523a2206206994597c13d831ec70124cc713a04688f385930a2a67070dc9b52a7b7ec4a955a110b038bd16cfe78e8806dfddd41000000000000000000000000bee3211ab312a8d065c4fef0247448e17a8da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000de14077278f7ac8b1000000000000000000000000000000000000000000000000000000003c15454d00000000000000000000000000000b2ddd0069ba7c5fe970d3d588bf5cd8d0860000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041865a01e3afd96eb104a6d0017d9aa335a46fcc7a1f580b9155188c0176826a7a77c2be7695916dff5bf595519ee67a0966ab1769e792231b4482f5aa4dbd28b11b0000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000148da1ee63c1e5018f0cb37cdff37e004e0088f563e5fe39e05ccc5b1f9840a85d5af5bf1d1762f925bdaddc4201f9840ca0dac17f958d2ee523a2206206994597c13d831ec7d343d5dba2fba55eef58189619c05e33cab95ca1c028b46d03d343d5dba2fba55eef58189619c05e33cab95ca100000000000000000000000000000000000000000000000000000000000248ad00a007e5c0d20000000000000000000000000000000000000000000000000003670002105120111111125421ca6dc452d289314280a0f8842a65f0db65d17e30a966c2ae6a21f6bba71cea6e97540124cc713a04cfca011b8564e7bcc6a9792b8226a4d16ef853e2c19b5f691e66ca8a51a1a8d8000000000000000000000000bee3211ab312a8d065c4fef0247448e17a8da0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f0db65d17e30a966c2ae6a21f6bba71cea6e975400000000000000000000000000000000000000000000000006ab4ca90f5ac5130000000000000000000000000000000000000000000000387d3b44c09372e00000000000000000000000000000000b2ddc0069ba7c5fe970d3d588bf5cd8d08600000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000411413c544e6473def8c4117d32d94db118aae69af01206f12c03f5d246770f41f3ab0cd7a076365d405e4cc96314b7d51522995909055ede938bb3e3db82fb82b1b0000000000000000000000000000000000000000000000000000000000000000a0c9e75c4800000000000000000000000000000000004d001700000000000000000000000000000000000000000000000000011f00004f02a000000000000000000000000000000000000000000000000000000000000540abee63c1e500e6ff8b9a37b0fab776134636d9981aa778c4e718c02aaa39b223fe8d0a0e5c4f27ead9083c756cc251207f86bf177dd4f3494b841a37e810a34dd56c829bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20044394747c5000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011953a000000000000000000000000000000000000000000000000000000000000000000a0f2fa6b662260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000000000000000000000000000000000000002e224f00000000000000000000000000001a6380a06c4eca272260fac5e5542a773aa44fbcfedf7c193bc2c599111111125421ca6dc452d289314280a0f8842a6500000000000000d1f115cb",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x0"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "09a0efb1b7d948ec2be62ff43d9d9282df83d445060de95c44db5067cf9e81bd",
+ "sig_s": "248ffd5f122ddb1eddd41331e28e86f171f2032bbe93ea5e75eaef2262c475d5"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_unoswap",
+ "parameters": {
+ "comment": "https://etherscan.io/tx/0x772f2a3302ff43260dd22c69b740597c0de9434821ddcdce10e42c253815edf6",
+ "data": "83800a8e000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000017cff16da2c808f348e280000000000000000000000d3e9895230e8fb1460852f6cda3c4b926fbc29d8fb39cfb5",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x0"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "f39ecdd11c46c8743385f5a20051268b1a37a56e7a981a616b83264375a4bbf8",
+ "sig_s": "35c18ed7ce660021551239b3b1746d1947acff335b89ee1c249835ebf732dc8f"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_unoswapTo",
+ "parameters": {
+ "comment": "https://etherscan.io/tx/0xa3e7acb0c5702b9ae0ba93224ed9d51b4c827f3295c35c93b74e1d9b169dca6b",
+ "data": "e2c95c82000000000000000000000000d862cdcfeb856c32b3c4f7563f4811d8ddfd42e2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000188932d0c201ca000000000000000000000000000000000000000000000000000c7c88c3b9a9b6d08000000000000003b6d03405c6919b79fac1c3555675ae59a9ac2484f3972f51e6abebb",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x0"
+ },
+ "result": {
+ "sig_v": 37,
+ "sig_r": "d827ffec9e1ed6ee3c256b8e8ba1528d317f5f4005df46c7aae142862184f10c",
+ "sig_s": "377c9b3df8b23f30e8e8fad1bd4fb12a0972b35da9ab9a3460873fa02afc7d7f"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_unoswap2",
+ "parameters": {
+ "comment": "https://etherscan.io/tx/0x2d52823de04e02ed21d561935b4e7363a8cb4684410984e772718f5621e228c6",
+ "data": "8770ba910000000000000000000000005f7827fdeb7c20b443265fc2f40845b715385ff20000000000000000000000000000000000000000000002757a49aba4f641520a0000000000000000000000000000000000000000000002e04c3685295104d6fe2880000000000000000000001f195908f2ee7a6fc15d33b30c82298f568e805c20000000000000000000000027848b0c260961826c4135e69e6cdd45cfba8257d1f115cb",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x0"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "928ddf0625455c8319bc1b251eb9418a4719258f97058981746440299899f8a6",
+ "sig_s": "4e143389f83ead9bc7276ec94e4d1e3bea457b2cc8b6f4cbc6167c52c1759bd7"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_unoswapTo3",
+ "parameters": {
+ "comment": "https://etherscan.io/tx/0x897e8cae0b331eb72240af59387927dfa1791350b7ae51cf2d8766293a5bfc1d",
+ "data": "f7a70056000000000000000000000000893ee5a10aec49aae0ae6e5a78ff79e2069f82e8000000000000000000000000320623b8e4ff03373931769a31fc52a4e78b5d70000000000000000000000000000000000000000000007ef4a40090a01ccc00000000000000000000000000000000000000000000000000000000000079e32bd54a1800020008020811000000db6925ea42897ca786a045b252d95aa7370f44b44010010001080008020000002c683fad51da2cd17793219cc86439c1875c353e208000000000000000000000c7bbec68d12a0d1830360f8ec58fa599ba1b0e9b",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x0"
+ },
+ "result": {
+ "sig_v": 37,
+ "sig_r": "dc94848dec0f020a4006112fe6e4ccc70791d74325b217d189768606130d2170",
+ "sig_s": "1fcd7ae7236bfe0b21341dd5aafc0aebd5bff295cf59edf70885fe1353e980d5"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_ethUnoswap",
+ "parameters": {
+ "comment": "https://etherscan.io/tx/0x2d8b8184e2c817839cbbe0de3d764e29283ec17e6ac6a0b841770e55d50da752",
+ "data": "a76dfc3b00000000000000000000000000000000000000000000000000068ea41a18d0d020800000000000000000000004708077eca6bb527a5bbbd6358ffb043a9c1c14d1f115cb",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x71afd498d0000"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "1b7192d0f6fd3e8de14a1b7267a968e0925a3cc8d9d7475ab2a756f11a6c3923",
+ "sig_s": "76df266e99d40d4319e78624ad8b5287187c517be978c0fdffbf877dffa218a0"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_ethUnoswap2",
+ "parameters": {
+ "comment": "https://etherscan.io/tx/0xe90d637d8c5cd2ccd7723b0c53cbae4a0b2e22335e30b834c65b79daf54249df",
+ "data": "89af926a00000000000000000000000000000000000000000000000579736cd9bf730780208000000000000000000000c7bbec68d12a0d1830360f8ec58fa599ba1b0e9b2000000000000000000000007eb59373d63627be64b42406b108b602174b4cccd1f115cb",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x85a72265a39f07"
+ },
+ "result": {
+ "sig_v": 37,
+ "sig_r": "fe99b795d901752be910788cd79e1d6586e8f641d7529ae3e6a0c28e8f3bdd74",
+ "sig_s": "070878c68eac4cc23217972dedcd362349ab6749060fff608ff420d87705dbb1"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_unoswap3",
+ "parameters": {
+ "comment": "Fabricated tx (this variant is too rare to find on the router); calldata hand-assembled from real values of a real unoswap2 tx",
+ "data": "193674720000000000000000000000005f7827fdeb7c20b443265fc2f40845b715385ff20000000000000000000000000000000000000000000002757a49aba4f641520a0000000000000000000000000000000000000000000002e04c3685295104d6fe2880000000000000000000001f195908f2ee7a6fc15d33b30c82298f568e805c20000000000000000000000027848b0c260961826c4135e69e6cdd45cfba825720000000000000000000000027848b0c260961826c4135e69e6cdd45cfba8257",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x0"
+ },
+ "result": {
+ "sig_v": 37,
+ "sig_r": "a3688dc3327cbdae1ceabb286bfd992601c6c32e8d25e97d5264631169c7207c",
+ "sig_s": "15a5fb26cc77baae2a62f201529baad23b67a8b3428c4ad21537e933fb3e8783"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_unoswapTo2",
+ "parameters": {
+ "comment": "Fabricated tx (this variant is too rare to find on the router); calldata hand-assembled from real values of a real unoswapTo3 tx",
+ "data": "ea76dddf000000000000000000000000893ee5a10aec49aae0ae6e5a78ff79e2069f82e8000000000000000000000000320623b8e4ff03373931769a31fc52a4e78b5d70000000000000000000000000000000000000000000007ef4a40090a01ccc00000000000000000000000000000000000000000000000000000000000079e32bd54a1800020008020811000000db6925ea42897ca786a045b252d95aa7370f44b44010010001080008020000002c683fad51da2cd17793219cc86439c1875c353e",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x0"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "68e1deea28b341a834eef7befbc7826ff498c59eca63489a2df8a3194ac13ce6",
+ "sig_s": "7a6ca9f3cb5763555ac4afee0424d44ba984fd718d69062ae3aeb199a76d17e1"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_ethUnoswap3",
+ "parameters": {
+ "comment": "Fabricated tx (this variant is too rare to find on the router); calldata hand-assembled from real values of a real ethUnoswap2 tx",
+ "data": "188ac35d00000000000000000000000000000000000000000000000579736cd9bf730780208000000000000000000000c7bbec68d12a0d1830360f8ec58fa599ba1b0e9b2000000000000000000000007eb59373d63627be64b42406b108b602174b4ccc2000000000000000000000007eb59373d63627be64b42406b108b602174b4ccc",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x85a72265a39f07"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "1690b9e30a51583b96e04a872791551c26699eab28167a3dc133274ccc273c0b",
+ "sig_s": "30cf565361516de67cd3ed90717c487849fdf4af045e9ae2a1cbdfda747665c1"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_ethUnoswapTo",
+ "parameters": {
+ "comment": "Fabricated tx (this variant is too rare to find on the router); calldata hand-assembled from real values of a real ethUnoswap tx + a real recipient",
+ "data": "175accdc000000000000000000000000893ee5a10aec49aae0ae6e5a78ff79e2069f82e800000000000000000000000000000000000000000000000000068ea41a18d0d020800000000000000000000004708077eca6bb527a5bbbd6358ffb043a9c1c14",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x71afd498d0000"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "a73846241c929e420b9d5a96815b0a5b45445c793cb1db708134f92292f13233",
+ "sig_s": "2a91f7805ef68fd5cd1e04d183616195d69a08b1e420972ce20394f618c3442a"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_ethUnoswapTo2",
+ "parameters": {
+ "comment": "Fabricated tx (this variant is too rare to find on the router); calldata hand-assembled from real values of a real ethUnoswap2 tx + a real recipient",
+ "data": "0f449d71000000000000000000000000893ee5a10aec49aae0ae6e5a78ff79e2069f82e800000000000000000000000000000000000000000000000579736cd9bf730780208000000000000000000000c7bbec68d12a0d1830360f8ec58fa599ba1b0e9b2000000000000000000000007eb59373d63627be64b42406b108b602174b4ccc",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x85a72265a39f07"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "c64fc355200bf014341e7f6370259c2fc52def64565a508c7bebd1e050630a51",
+ "sig_s": "75c6e913f12991eabc460438f793b40118247abca525d8238cdec516515535a6"
+ }
+ },
+ {
+ "name": "clear_sign_1inch_ethUnoswapTo3",
+ "parameters": {
+ "comment": "Fabricated tx (this variant is too rare to find on the router); calldata hand-assembled from real values of a real ethUnoswap2 tx + a real recipient",
+ "data": "493189f0000000000000000000000000893ee5a10aec49aae0ae6e5a78ff79e2069f82e800000000000000000000000000000000000000000000000579736cd9bf730780208000000000000000000000c7bbec68d12a0d1830360f8ec58fa599ba1b0e9b2000000000000000000000007eb59373d63627be64b42406b108b602174b4ccc2000000000000000000000007eb59373d63627be64b42406b108b602174b4ccc",
+ "path": "m/44'/60'/0'/0/1",
+ "to_address": "0x111111125421cA6dc452d289314280a0f8842A65",
+ "chain_id": 1,
+ "nonce": "0x0",
+ "gas_price": "0x14",
+ "gas_limit": "0x14",
+ "tx_type": null,
+ "value": "0x85a72265a39f07"
+ },
+ "result": {
+ "sig_v": 38,
+ "sig_r": "379c4e690e52425cf1b7002d56d66c2af3da0edb1a8298f508729d6b12d88b08",
+ "sig_s": "2a4803e22ac943946d6f77cbad26e9ecbe703d1f6d6802ba31e218f7d6f48b31"
+ }
+ },
{
"name": "clear_sign_lifi_swapTokensMultipleV3ERC20ToERC20",
"parameters": {
diff --git a/core/src/apps/ethereum/clear_signing_definitions.py b/core/src/apps/ethereum/clear_signing_definitions.py
index deb50ede..a8d9f9d5 100644
--- a/core/src/apps/ethereum/clear_signing_definitions.py
+++ b/core/src/apps/ethereum/clear_signing_definitions.py
@@ -17,6 +17,7 @@ from .clear_signing import (
parse_address,
parse_bool,
parse_bytes,
+ parse_bytes32,
parse_string,
parse_uint24,
parse_uint160,
@@ -76,6 +77,542 @@ if __debug__:
ALL_DISPLAY_FORMATS = [APPROVE_DISPLAY_FORMAT, TRANSFER_DISPLAY_FORMAT]
+# https://github.com/LedgerHQ/clear-signing-erc7730-registry/blob/master/registry/1inch/calldata-AggregationRouterV6.json#L9
+ONEINCH_ADDRESS = unhexlify("111111125421cA6dc452d289314280a0f8842A65")
+ONEINCH_CHAINS = [
+ 1,
+ 10,
+ 56,
+ 100,
+ 137,
+ 146,
+ 250,
+ 8217,
+ 8453,
+ 42161,
+ 43114,
+ 59144,
+ 1313161554,
+]
+
+# $.metadata.constants.addressAsEth and addressAsNull from common-AggregationRouterV6.json
+ONEINCH_NATIVE_CURRENCY_ADDRESSES = [
+ unhexlify("EeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"),
+ unhexlify("0000000000000000000000000000000000000000"),
+]
+
+ONEINCH_CONTEXT = BindingContext(
+ [(chain, ONEINCH_ADDRESS) for chain in ONEINCH_CHAINS],
+)
+
+# Rationale for the omitted "Minimum to Receive" (minReturn) field in the
+# unoswap / unoswapTo / ethUnoswap* definitions below:
+# Unlike `swap` (whose `desc` struct carries both srcToken and dstToken), these
+# functions encode only the source token; the destination token is implied by
+# the pool routing packed into the `dex` argument(s) and cannot be recovered
+# from the calldata. The ERC-7730 registry therefore gives their minReturn no
+# tokenPath, so we have no decimals/symbol to format it as a token amount and
+# omit the field rather than display a bare, tokenless integer. (`swap` keeps
+# 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)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_address), # executor
+ Tuple(
+ (
+ parse_address, # srcToken
+ parse_address, # dstToken
+ parse_address, # srcReceiver
+ parse_address, # dstReceiver
+ parse_uint256, # amount
+ parse_uint256, # minReturnAmount
+ parse_uint256, # flags
+ ),
+ is_dynamic=False,
+ ), # desc
+ Dynamic(parse_bytes), # data
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (1, 4), # desc.amount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(1, 0), # desc.srcToken
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ (1, 5), # desc.minReturnAmount
+ "Minimum to Receive",
+ TokenAmountFormatter(
+ token_path=(1, 1), # desc.dstToken
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ (1, 3), "Beneficiary", AddressNameFormatter # desc.dstReceiver
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("83800a8e")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(b"unoswap(uint256,uint256,uint256,uint256)")
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # token
+ Atomic(parse_uint256), # amount
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_bytes32), # dex
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (1,), # amount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(0, (-20,)), # token.[-20:]
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ ContainerPath.From, # @.from
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (3, (-20,)), # dex.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("e2c95c82")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"unoswapTo(uint256,uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # to
+ Atomic(parse_bytes32), # token
+ Atomic(parse_uint256), # amount
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_bytes32), # dex
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (2,), # amount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(1, (-20,)), # token.[-20:]
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ (0, (-20,)), # to.[-20:]
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (4, (-20,)), # dex.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("8770ba91")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"unoswap2(uint256,uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # token
+ Atomic(parse_uint256), # amount
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_bytes32), # dex2
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (1,), # amount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(0, (-20,)), # token.[-20:]
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ ContainerPath.From, # @.from
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (4, (-20,)), # dex2.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("19367472")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"unoswap3(uint256,uint256,uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # token
+ Atomic(parse_uint256), # amount
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_uint256), # dex2
+ Atomic(parse_bytes32), # dex3
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (1,), # amount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(0, (-20,)), # token.[-20:]
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ ContainerPath.From, # @.from
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (5, (-20,)), # dex3.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("ea76dddf")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"unoswapTo2(uint256,uint256,uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # to
+ Atomic(parse_bytes32), # token
+ Atomic(parse_uint256), # amount
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_bytes32), # dex2
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (2,), # amount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(1, (-20,)), # token.[-20:]
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ (0, (-20,)), # to.[-20:]
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (5, (-20,)), # dex2.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("f7a70056")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"unoswapTo3(uint256,uint256,uint256,uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # to
+ Atomic(parse_bytes32), # token
+ Atomic(parse_uint256), # amount
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_uint256), # dex2
+ Atomic(parse_bytes32), # dex3
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (2,), # amount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(1, (-20,)), # token.[-20:]
+ native_currency_address=ONEINCH_NATIVE_CURRENCY_ADDRESSES,
+ ),
+ ),
+ FieldDefinition(
+ (0, (-20,)), # to.[-20:]
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (6, (-20,)), # dex3.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("a76dfc3b")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(b"ethUnoswap(uint256,uint256)")
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_bytes32), # dex
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to Send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ ContainerPath.From, # @.from
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (1, (-20,)), # dex.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("89af926a")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(b"ethUnoswap2(uint256,uint256,uint256)")
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_bytes32), # dex2
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to Send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ ContainerPath.From, # @.from
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (2, (-20,)), # dex2.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("188ac35d")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"ethUnoswap3(uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_uint256), # dex2
+ Atomic(parse_bytes32), # dex3
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to Send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ ContainerPath.From, # @.from
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (3, (-20,)), # dex3.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("175accdc")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(b"ethUnoswapTo(uint256,uint256,uint256)")
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # to
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_bytes32), # dex
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to Send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ (0, (-20,)), # to.[-20:]
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (2, (-20,)), # dex.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("0f449d71")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"ethUnoswapTo2(uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # to
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_bytes32), # dex2
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to Send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ (0, (-20,)), # to.[-20:]
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (3, (-20,)), # dex2.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("493189f0")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"ethUnoswapTo3(uint256,uint256,uint256,uint256,uint256)"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=ONEINCH_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes32), # to
+ Atomic(parse_uint256), # minReturn
+ Atomic(parse_uint256), # dex
+ Atomic(parse_uint256), # dex2
+ Atomic(parse_bytes32), # dex3
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to Send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ (0, (-20,)), # to.[-20:]
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (4, (-20,)), # dex3.[-20:]
+ "Last Pool",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
# https://github.com/LedgerHQ/clear-signing-erc7730-registry/blob/master/registry/lifi/calldata-LIFIDiamond.json
LIFI_ADDRESS = unhexlify("1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE")
LIFI_CHAINS = [
@@ -120,163 +657,23 @@ LIFI_NATIVE_CURRENCY_ADDRESSES = [
unhexlify("0000000000000000000000000000000000000000"),
]
-ALL_DISPLAY_FORMATS.extend(
- [
- DisplayFormat(
- binding_context=LIFI_CONTEXT,
- func_sig=unhexlify(
- "5fd9ae2e"
- ), # swapTokensMultipleV3ERC20ToERC20(bytes32 _transactionId,string _integrator,string _referrer,address _receiver,uint256 _minAmountOut,tuple[] _swapData)
- intent="Swap",
- parameter_definitions=[
- Atomic(parse_bytes), # _transactionId
- Dynamic(parse_string), # _integrator
- Dynamic(parse_string), # _referrer
- Atomic(parse_address), # _receiver
- Atomic(parse_uint256), # _minAmountOut
- Array(
- Tuple(
- (
- parse_address, # callTo
- parse_address, # approveTo
- parse_address, # sendingAssetId
- parse_address, # receivingAssetId
- parse_uint256, # fromAmount
- parse_bytes, # callData
- parse_bool, # requiresDeposit
- ),
- is_dynamic=False,
- )
- ), # _swapData
- ],
- field_definitions=[
- FieldDefinition(
- (5, 0, 4), # _swapData.[0].fromAmount
- "Amount to Send",
- TokenAmountFormatter(
- token_path=(5, 0, 2), # _swapData.[0].sendingAssetId
- ),
- ),
- FieldDefinition(
- (4,), # _minAmountOut
- "Minimum to Receive",
- TokenAmountFormatter(
- token_path=(5, -1, 3), # _swapData.[-1].receivingAssetId
- ),
- ),
- FieldDefinition(
- (3,), # _receiver
- "Recipient",
- AddressNameFormatter,
- ),
- ],
- ),
- DisplayFormat(
- binding_context=LIFI_CONTEXT,
- func_sig=unhexlify(
- "2c57e884"
- ), # swapTokensMultipleV3ERC20ToNative(bytes32 _transactionId,string _integrator,string _referrer,address _receiver,uint256 _minAmountOut,tuple[] _swapData)
- intent="Swap",
- parameter_definitions=[
- Atomic(parse_bytes), # _transactionId
- Dynamic(parse_string), # _integrator
- Dynamic(parse_string), # _referrer
- Atomic(parse_address), # _receiver
- Atomic(parse_uint256), # _minAmountOut
- Array(
- Tuple(
- (
- parse_address, # callTo
- parse_address, # approveTo
- parse_address, # sendingAssetId
- parse_address, # receivingAssetId
- parse_uint256, # fromAmount
- parse_bytes, # callData
- parse_bool, # requiresDeposit
- ),
- is_dynamic=False,
- )
- ), # _swapData
- ],
- field_definitions=[
- FieldDefinition(
- (5, 0, 4), # _swapData.[0].fromAmount
- "Amount to Send",
- TokenAmountFormatter(
- token_path=(5, 0, 2), # _swapData.[0].sendingAssetId
- ),
- ),
- FieldDefinition(
- (4,), # _minAmountOut
- "Minimum Amount to receive",
- AmountFormatter,
- ),
- FieldDefinition(
- (3,), # _receiver
- "Recipient",
- AddressNameFormatter,
- ),
- ],
- ),
- DisplayFormat(
- binding_context=LIFI_CONTEXT,
- func_sig=unhexlify(
- "736eac0b"
- ), # swapTokensMultipleV3NativeToERC20(bytes32 _transactionId,string _integrator,string _referrer,address _receiver,uint256 _minAmountOut,tuple[] _swapData)
- intent="Swap",
- parameter_definitions=[
- Atomic(parse_bytes), # _transactionId
- Dynamic(parse_string), # _integrator
- Dynamic(parse_string), # _referrer
- Atomic(parse_address), # _receiver
- Atomic(parse_uint256), # _minAmountOut
- Array(
- Tuple(
- (
- parse_address, # callTo
- parse_address, # approveTo
- parse_address, # sendingAssetId
- parse_address, # receivingAssetId
- parse_uint256, # fromAmount
- parse_bytes, # callData
- parse_bool, # requiresDeposit
- ),
- is_dynamic=False,
- )
- ), # _swapData
- ],
- field_definitions=[
- FieldDefinition(
- ContainerPath.Value, # @.value
- "Amount to Send",
- AmountFormatter,
- ),
- FieldDefinition(
- (4,), # _minAmountOut
- "Minimum to Receive",
- TokenAmountFormatter(
- token_path=(5, -1, 3), # _swapData.[-1].receivingAssetId
- ),
- ),
- FieldDefinition(
- (3,), # _receiver
- "Recipient",
- AddressNameFormatter,
- ),
- ],
- ),
- DisplayFormat(
- binding_context=LIFI_CONTEXT,
- func_sig=unhexlify(
- "4666fc80"
- ), # swapTokensSingleV3ERC20ToERC20(bytes32 _transactionId,string _integrator,string _referrer,address _receiver,uint256 _minAmountOut,tuple _swapData)
- intent="Swap",
- parameter_definitions=[
- Atomic(parse_bytes), # _transactionId
- Dynamic(parse_string), # _integrator
- Dynamic(parse_string), # _referrer
- Atomic(parse_address), # _receiver
- Atomic(parse_uint256), # _minAmountOut
+_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)[])"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=LIFI_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes), # _transactionId
+ Dynamic(parse_string), # _integrator
+ Dynamic(parse_string), # _referrer
+ Atomic(parse_address), # _receiver
+ Atomic(parse_uint256), # _minAmountOut
+ Array(
Tuple(
(
parse_address, # callTo
@@ -287,41 +684,51 @@ ALL_DISPLAY_FORMATS.extend(
parse_bytes, # callData
parse_bool, # requiresDeposit
),
- is_dynamic=True,
- ), # _swapData
- ],
- field_definitions=[
- FieldDefinition(
- (5, 4), # _swapData.fromAmount
- "Amount to Send",
- TokenAmountFormatter(token_path=(5, 2)), # _swapData.sendingAssetId
- ),
- FieldDefinition(
- (4,), # _minAmountOut
- "Minimum to receive",
- TokenAmountFormatter(
- token_path=(5, 3) # _swapData.receivingAssetId
- ),
+ is_dynamic=False,
+ )
+ ), # _swapData
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (5, 0, 4), # _swapData.[0].fromAmount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(5, 0, 2), # _swapData.[0].sendingAssetId
),
- FieldDefinition(
- (3,), # _receiver
- "Recipient",
- AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (4,), # _minAmountOut
+ "Minimum to Receive",
+ TokenAmountFormatter(
+ token_path=(5, -1, 3), # _swapData.[-1].receivingAssetId
),
- ],
- ),
- DisplayFormat(
- binding_context=LIFI_CONTEXT,
- func_sig=unhexlify(
- "733214a3"
- ), # swapTokensSingleV3ERC20ToNative(bytes32 _transactionId,string _integrator,string _referrer,address _receiver,uint256 _minAmountOut,tuple _swapData)
- intent="Swap",
- parameter_definitions=[
- Atomic(parse_bytes), # _transactionId
- Dynamic(parse_string), # _integrator
- Dynamic(parse_string), # _referrer
- Atomic(parse_address), # _receiver
- Atomic(parse_uint256), # _minAmountOut
+ ),
+ FieldDefinition(
+ (3,), # _receiver
+ "Recipient",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_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)[])"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=LIFI_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes), # _transactionId
+ Dynamic(parse_string), # _integrator
+ Dynamic(parse_string), # _referrer
+ Atomic(parse_address), # _receiver
+ Atomic(parse_uint256), # _minAmountOut
+ Array(
Tuple(
(
parse_address, # callTo
@@ -332,41 +739,49 @@ ALL_DISPLAY_FORMATS.extend(
parse_bytes, # callData
parse_bool, # requiresDeposit
),
- is_dynamic=True,
- ), # _swapData
- ],
- field_definitions=[
- FieldDefinition(
- (5, 4), # _swapData.fromAmount
- "Amount to Send",
- TokenAmountFormatter(
- token_path=(5, 2), # _swapData.sendingAssetId
- ),
- ),
- FieldDefinition(
- (4,), # _minAmountOut
- "Minimum Amount to receive",
- AmountFormatter,
- ),
- FieldDefinition(
- (3,), # _receiver
- "Recipient",
- AddressNameFormatter,
+ is_dynamic=False,
+ )
+ ), # _swapData
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (5, 0, 4), # _swapData.[0].fromAmount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(5, 0, 2), # _swapData.[0].sendingAssetId
),
- ],
- ),
- DisplayFormat(
- binding_context=LIFI_CONTEXT,
- func_sig=unhexlify(
- "af7060fd"
- ), # swapTokensSingleV3NativeToERC20(bytes32 _transactionId,string _integrator,string _referrer,address _receiver,uint256 _minAmountOut,tuple _swapData)
- intent="Swap",
- parameter_definitions=[
- Atomic(parse_bytes), # _transactionId
- Dynamic(parse_string), # _integrator
- Dynamic(parse_string), # _referrer
- Atomic(parse_address), # _receiver
- Atomic(parse_uint256), # _minAmountOut
+ ),
+ FieldDefinition(
+ (4,), # _minAmountOut
+ "Minimum Amount to receive",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ (3,), # _receiver
+ "Recipient",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_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)[])"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=LIFI_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes), # _transactionId
+ Dynamic(parse_string), # _integrator
+ Dynamic(parse_string), # _referrer
+ Atomic(parse_address), # _receiver
+ Atomic(parse_uint256), # _minAmountOut
+ Array(
Tuple(
(
parse_address, # callTo
@@ -377,85 +792,242 @@ ALL_DISPLAY_FORMATS.extend(
parse_bytes, # callData
parse_bool, # requiresDeposit
),
- is_dynamic=True,
- ), # _swapData
- ],
- field_definitions=[
- FieldDefinition(
- ContainerPath.Value, # @.value
- "Amount to send",
- AmountFormatter,
- ),
- FieldDefinition(
- (4,), # _minAmountOut
- "Minimum to Receive",
- TokenAmountFormatter(
- token_path=(5, 3), # _swapData.receivingAssetId
- ),
+ is_dynamic=False,
+ )
+ ), # _swapData
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to Send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ (4,), # _minAmountOut
+ "Minimum to Receive",
+ TokenAmountFormatter(
+ token_path=(5, -1, 3), # _swapData.[-1].receivingAssetId
),
- FieldDefinition(
- (3,), # _receiver
- "Recipient",
- AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (3,), # _receiver
+ "Recipient",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_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))"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=LIFI_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes), # _transactionId
+ Dynamic(parse_string), # _integrator
+ Dynamic(parse_string), # _referrer
+ Atomic(parse_address), # _receiver
+ Atomic(parse_uint256), # _minAmountOut
+ Tuple(
+ (
+ parse_address, # callTo
+ parse_address, # approveTo
+ parse_address, # sendingAssetId
+ parse_address, # receivingAssetId
+ parse_uint256, # fromAmount
+ parse_bytes, # callData
+ parse_bool, # requiresDeposit
),
- ],
- ),
- DisplayFormat(
- binding_context=LIFI_CONTEXT,
- func_sig=unhexlify(
- "4630a0d8"
- ), # swapTokensGeneric(bytes32 _transactionId,string _integrator,string _referrer,address _receiver,uint256 _minAmount,tuple[] _swapData)
- intent="Swap",
- parameter_definitions=[
- Atomic(parse_bytes), # _transactionId
- Dynamic(parse_string), # _integrator
- Dynamic(parse_string), # _referrer
- Atomic(parse_address), # _receiver
- Atomic(parse_uint256), # _minAmount
- Array(
- Tuple(
- (
- parse_address, # callTo
- parse_address, # approveTo
- parse_address, # sendingAssetId
- parse_address, # receivingAssetId
- parse_uint256, # fromAmount
- parse_bytes, # callData
- parse_bool, # requiresDeposit
- ),
- is_dynamic=False,
- )
- ), # _swapData
- ],
- field_definitions=[
- FieldDefinition(
- (
- 5,
- 0,
- 4,
- ), # _swapData.[0].fromAmount
- "Amount info",
- TokenAmountFormatter(
- token_path=(5, 0, 2), # _swapData.[0].sendingAssetId
- native_currency_address=LIFI_NATIVE_CURRENCY_ADDRESSES,
- ),
+ is_dynamic=True,
+ ), # _swapData
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (5, 4), # _swapData.fromAmount
+ "Amount to Send",
+ TokenAmountFormatter(token_path=(5, 2)), # _swapData.sendingAssetId
+ ),
+ FieldDefinition(
+ (4,), # _minAmountOut
+ "Minimum to receive",
+ TokenAmountFormatter(token_path=(5, 3)), # _swapData.receivingAssetId
+ ),
+ FieldDefinition(
+ (3,), # _receiver
+ "Recipient",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_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))"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=LIFI_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes), # _transactionId
+ Dynamic(parse_string), # _integrator
+ Dynamic(parse_string), # _referrer
+ Atomic(parse_address), # _receiver
+ Atomic(parse_uint256), # _minAmountOut
+ Tuple(
+ (
+ parse_address, # callTo
+ parse_address, # approveTo
+ parse_address, # sendingAssetId
+ parse_address, # receivingAssetId
+ parse_uint256, # fromAmount
+ parse_bytes, # callData
+ parse_bool, # requiresDeposit
),
- FieldDefinition(
- (4,), # _minAmount,
- "Minimum Amount to receive",
- TokenAmountFormatter(
- token_path=(5, -1, 3), # # _swapData.[-1].receivingAssetId
- native_currency_address=LIFI_NATIVE_CURRENCY_ADDRESSES,
+ is_dynamic=True,
+ ), # _swapData
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (5, 4), # _swapData.fromAmount
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(5, 2), # _swapData.sendingAssetId
+ ),
+ ),
+ FieldDefinition(
+ (4,), # _minAmountOut
+ "Minimum Amount to receive",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ (3,), # _receiver
+ "Recipient",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_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))"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=LIFI_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes), # _transactionId
+ Dynamic(parse_string), # _integrator
+ Dynamic(parse_string), # _referrer
+ Atomic(parse_address), # _receiver
+ Atomic(parse_uint256), # _minAmountOut
+ Tuple(
+ (
+ parse_address, # callTo
+ parse_address, # approveTo
+ parse_address, # sendingAssetId
+ parse_address, # receivingAssetId
+ parse_uint256, # fromAmount
+ parse_bytes, # callData
+ parse_bool, # requiresDeposit
+ ),
+ is_dynamic=True,
+ ), # _swapData
+ ],
+ field_definitions=[
+ FieldDefinition(
+ ContainerPath.Value, # @.value
+ "Amount to send",
+ AmountFormatter,
+ ),
+ FieldDefinition(
+ (4,), # _minAmountOut
+ "Minimum to Receive",
+ TokenAmountFormatter(
+ token_path=(5, 3), # _swapData.receivingAssetId
+ ),
+ ),
+ FieldDefinition(
+ (3,), # _receiver
+ "Recipient",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_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)[])"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=LIFI_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Atomic(parse_bytes), # _transactionId
+ Dynamic(parse_string), # _integrator
+ Dynamic(parse_string), # _referrer
+ Atomic(parse_address), # _receiver
+ Atomic(parse_uint256), # _minAmount
+ Array(
+ Tuple(
+ (
+ parse_address, # callTo
+ parse_address, # approveTo
+ parse_address, # sendingAssetId
+ parse_address, # receivingAssetId
+ parse_uint256, # fromAmount
+ parse_bytes, # callData
+ parse_bool, # requiresDeposit
),
+ is_dynamic=False,
+ )
+ ), # _swapData
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (
+ 5,
+ 0,
+ 4,
+ ), # _swapData.[0].fromAmount
+ "Amount info",
+ TokenAmountFormatter(
+ token_path=(5, 0, 2), # _swapData.[0].sendingAssetId
+ native_currency_address=LIFI_NATIVE_CURRENCY_ADDRESSES,
),
- FieldDefinition(
- (3,), # receiver
- "Recipient",
- AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (4,), # _minAmount,
+ "Minimum Amount to receive",
+ TokenAmountFormatter(
+ token_path=(5, -1, 3), # # _swapData.[-1].receivingAssetId
+ native_currency_address=LIFI_NATIVE_CURRENCY_ADDRESSES,
),
- ],
- ),
- ]
+ ),
+ FieldDefinition(
+ (3,), # receiver
+ "Recipient",
+ AddressNameFormatter,
+ ),
+ ],
+ ),
)
# https://github.com/LedgerHQ/clear-signing-erc7730-registry/blob/master/registry/uniswap/calldata-UniswapV3Router02.json#L6
@@ -468,171 +1040,196 @@ UNISWAP_CONTEXT = BindingContext(
[(chain, UNISWAP_V3_ROUTER_ADDRESS) for chain in UNISWAP_V3_ROUTER_CHAINS],
)
-ALL_DISPLAY_FORMATS.extend(
- [
- DisplayFormat(
- binding_context=UNISWAP_CONTEXT,
- func_sig=unhexlify("b858183f"), # exactInput(tuple params)
- intent="Swap",
- parameter_definitions=[
- Tuple(
- (
- parse_bytes, # path
- parse_address, # recipient
- parse_uint256, # amountIn
- parse_uint256, # amountOutMinimum
- ),
- is_dynamic=True,
- ), # params
- ],
- field_definitions=[
- FieldDefinition(
- (0, 2), # params.amountIn
- "Amount to Send",
- TokenAmountFormatter(
- token_path=(0, 0, (0, 20)), # params.path.[0:20]
- ),
- ),
- FieldDefinition(
- (0, 3), # params.amountOutMinimum
- "Minimum to Receive",
- TokenAmountFormatter(
- token_path=(0, 0, (-20,)), # params.path.[-20:]
- ),
+_FUNC_SIG = unhexlify("b858183f")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(b"exactInput((bytes,address,uint256,uint256))")
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=UNISWAP_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Tuple(
+ (
+ parse_bytes, # path
+ parse_address, # recipient
+ parse_uint256, # amountIn
+ parse_uint256, # amountOutMinimum
),
- FieldDefinition(
- (0, 1), # params.recipient
- "Beneficiary",
- AddressNameFormatter,
+ is_dynamic=True,
+ ), # params
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (0, 2), # params.amountIn
+ "Amount to Send",
+ TokenAmountFormatter(
+ token_path=(0, 0, (0, 20)), # params.path.[0:20]
),
- ],
- ),
- DisplayFormat(
- binding_context=UNISWAP_CONTEXT,
- func_sig=unhexlify("04e45aaf"), # exactInputSingle(tuple params)
- intent="Swap",
- parameter_definitions=[
- Tuple(
- (
- parse_address, # tokenIn
- parse_address, # tokenOut
- parse_uint24, # fee
- parse_address, # recipient
- parse_uint256, # amountIn
- parse_uint256, # amountOutMinimum
- parse_uint160, # sqrtPriceLimitX96
- ),
- is_dynamic=False,
- ), # params
- ],
- field_definitions=[
- FieldDefinition(
- (0, 4), # amountIn
- "Send",
- TokenAmountFormatter(
- token_path=(0, 0), # params.tokenIn
- ),
- ),
- FieldDefinition(
- (0, 5), # amountOutMinimum
- "Minimum to Receive",
- TokenAmountFormatter(
- token_path=(0, 1), # params.tokenOut
- ),
+ ),
+ FieldDefinition(
+ (0, 3), # params.amountOutMinimum
+ "Minimum to Receive",
+ TokenAmountFormatter(
+ token_path=(0, 0, (-20,)), # params.path.[-20:]
),
- FieldDefinition(
- (0, 2), # fee
- "Uniswap fee",
- UnitFormatter(decimals=4, base="%", prefix=False),
+ ),
+ FieldDefinition(
+ (0, 1), # params.recipient
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("04e45aaf")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"exactInputSingle((address,address,uint24,address,uint256,uint256,uint160))"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=UNISWAP_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Tuple(
+ (
+ parse_address, # tokenIn
+ parse_address, # tokenOut
+ parse_uint24, # fee
+ parse_address, # recipient
+ parse_uint256, # amountIn
+ parse_uint256, # amountOutMinimum
+ parse_uint160, # sqrtPriceLimitX96
),
- FieldDefinition(
- (0, 3), # recipient
- "Beneficiary",
- AddressNameFormatter,
+ is_dynamic=False,
+ ), # params
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (0, 4), # amountIn
+ "Send",
+ TokenAmountFormatter(
+ token_path=(0, 0), # params.tokenIn
),
- ],
- ),
- DisplayFormat(
- binding_context=UNISWAP_CONTEXT,
- func_sig=unhexlify("09b81346"), # exactOutput(tuple params)
- intent="Swap",
- parameter_definitions=[
- Tuple(
- (
- parse_bytes, # path
- parse_address, # recipient
- parse_uint256, # amountOut
- parse_uint256, # amountInMaximum
- ),
- is_dynamic=True,
- ), # params
- ],
- field_definitions=[
- FieldDefinition(
- (0, 3), # params.amountInMaximum
- "Maximum Amount In",
- TokenAmountFormatter(
- token_path=(0, 0, (-20,)), # params.path.[-20:]
- ),
+ ),
+ FieldDefinition(
+ (0, 5), # amountOutMinimum
+ "Minimum to Receive",
+ TokenAmountFormatter(
+ token_path=(0, 1), # params.tokenOut
),
- FieldDefinition(
- (0, 2), # params.amountOut
- "Amount to Receive",
- TokenAmountFormatter(
- token_path=(0, 0, (0, 20)), # params.path.[0:20]
- ),
+ ),
+ FieldDefinition(
+ (0, 2), # fee
+ "Uniswap fee",
+ UnitFormatter(decimals=4, base="%", prefix=False),
+ ),
+ FieldDefinition(
+ (0, 3), # recipient
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("09b81346")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"exactOutput((bytes,address,uint256,uint256))"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=UNISWAP_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Tuple(
+ (
+ parse_bytes, # path
+ parse_address, # recipient
+ parse_uint256, # amountOut
+ parse_uint256, # amountInMaximum
),
- FieldDefinition(
- (0, 1), # params.recipient
- "Beneficiary",
- AddressNameFormatter,
+ is_dynamic=True,
+ ), # params
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (0, 3), # params.amountInMaximum
+ "Maximum Amount In",
+ TokenAmountFormatter(
+ token_path=(0, 0, (-20,)), # params.path.[-20:]
),
- ],
- ),
- DisplayFormat(
- binding_context=UNISWAP_CONTEXT,
- func_sig=unhexlify("5023b4df"), # exactOutputSingle(tuple params)
- intent="Swap",
- parameter_definitions=[
- Tuple(
- (
- parse_address, # tokenIn
- parse_address, # tokenOut
- parse_uint24, # fee
- parse_address, # recipient
- parse_uint256, # amountOut
- parse_uint256, # amountInMaximum
- parse_uint160, # sqrtPriceLimitX96
- ),
- is_dynamic=False,
- ), # params
- ],
- field_definitions=[
- FieldDefinition(
- (0, 5), # amountInMaximum
- "Maximum Amount In",
- TokenAmountFormatter(
- token_path=(0, 0), # params.tokenIn
- ),
+ ),
+ FieldDefinition(
+ (0, 2), # params.amountOut
+ "Amount to Receive",
+ TokenAmountFormatter(
+ token_path=(0, 0, (0, 20)), # params.path.[0:20]
),
- FieldDefinition(
- (0, 4), # amountOut
- "Amount to Receive",
- TokenAmountFormatter(
- token_path=(0, 1), # params.tokenOut
- ),
+ ),
+ FieldDefinition(
+ (0, 1), # params.recipient
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ ],
+ )
+)
+
+_FUNC_SIG = unhexlify("5023b4df")
+if __debug__:
+ assert _FUNC_SIG == base58.keccak_32(
+ b"exactOutputSingle((address,address,uint24,address,uint256,uint256,uint160))"
+ )
+ALL_DISPLAY_FORMATS.append(
+ DisplayFormat(
+ binding_context=UNISWAP_CONTEXT,
+ func_sig=_FUNC_SIG,
+ intent="Swap",
+ parameter_definitions=[
+ Tuple(
+ (
+ parse_address, # tokenIn
+ parse_address, # tokenOut
+ parse_uint24, # fee
+ parse_address, # recipient
+ parse_uint256, # amountOut
+ parse_uint256, # amountInMaximum
+ parse_uint160, # sqrtPriceLimitX96
),
- FieldDefinition(
- (0, 2), # fee
- "Uniswap fee",
- UnitFormatter(decimals=4, base="%", prefix=False),
+ is_dynamic=False,
+ ), # params
+ ],
+ field_definitions=[
+ FieldDefinition(
+ (0, 5), # amountInMaximum
+ "Maximum Amount In",
+ TokenAmountFormatter(
+ token_path=(0, 0), # params.tokenIn
),
- FieldDefinition(
- (0, 3), # recipient
- "Beneficiary",
- AddressNameFormatter,
+ ),
+ FieldDefinition(
+ (0, 4), # amountOut
+ "Amount to Receive",
+ TokenAmountFormatter(
+ token_path=(0, 1), # params.tokenOut
),
- ],
- ),
- ]
+ ),
+ FieldDefinition(
+ (0, 2), # fee
+ "Uniswap fee",
+ UnitFormatter(decimals=4, base="%", prefix=False),
+ ),
+ FieldDefinition(
+ (0, 3), # recipient
+ "Beneficiary",
+ AddressNameFormatter,
+ ),
+ ],
+ ),
)
Why this scored 19/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.