diff --git a/src/handle_finalize.c b/src/handle_finalize.c index 039c4a59..7ab05eb3 100644 --- a/src/handle_finalize.c +++ b/src/handle_finalize.c @@ -10,6 +10,9 @@ void handle_finalize(ethPluginFinalize_t *msg) { case DELEGATE: msg->numScreens = 1; break; + case MINT: + msg->numScreens = 4; + break; default: PRINTF("Selector index: %d not supported\n", context->selectorIndex); msg->result = ETH_PLUGIN_RESULT_ERROR; diff --git a/src/handle_init_contract.c b/src/handle_init_contract.c index cc1523ea..d7107d5d 100644 --- a/src/handle_init_contract.c +++ b/src/handle_init_contract.c @@ -45,6 +45,9 @@ void handle_init_contract(ethPluginInitContract_t *msg) { case DELEGATE: context->next_param = BENEFICIARY; break; + case MINT: + context->next_param = ADDRESS; + break; // Keep this default: PRINTF("Missing selectorIndex: %d\n", context->selectorIndex); diff --git a/src/handle_provide_parameter.c b/src/handle_provide_parameter.c index 54c6989f..bde85b35 100644 --- a/src/handle_provide_parameter.c +++ b/src/handle_provide_parameter.c @@ -15,6 +15,37 @@ static void handle_beneficiary(ethPluginProvideParameter_t *msg, context_t *cont } } +static void handle_mint(ethPluginProvideParameter_t *msg, context_t *context) { + switch (context->next_param) { + case ADDRESS: + copy_address(context->address, msg->parameter, sizeof(context->address)); + context->next_param = MIN_AMOUNT_RECEIVED; + break; + case MIN_AMOUNT_RECEIVED: + copy_parameter(context->amount_received, + msg->parameter, + sizeof(context->amount_received)); + context->next_param = BENEFICIARY; + break; + case BENEFICIARY: + copy_address(context->beneficiary, msg->parameter, sizeof(context->beneficiary)); + context->next_param = BOOLEAN; + break; + case BOOLEAN: + if (!U2BE_from_parameter(msg->parameter, &context->boolean)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } + context->next_param = NONE; + break; + case NONE: + break; + default: + PRINTF("Param not supported: %d\n", context->next_param); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } +} + void handle_provide_parameter(ethPluginProvideParameter_t *msg) { context_t *context = (context_t *) msg->pluginContext; // We use `%.*H`: it's a utility function to print bytes. You first give @@ -32,6 +63,9 @@ void handle_provide_parameter(ethPluginProvideParameter_t *msg) { case DELEGATE: handle_beneficiary(msg, context); break; + case MINT: + handle_mint(msg, context); + break; default: PRINTF("Selector Index not supported: %d\n", context->selectorIndex); msg->result = ETH_PLUGIN_RESULT_ERROR; diff --git a/src/handle_query_contract_id.c b/src/handle_query_contract_id.c index f5608c9b..b6e47bd3 100644 --- a/src/handle_query_contract_id.c +++ b/src/handle_query_contract_id.c @@ -19,6 +19,10 @@ void handle_query_contract_id(ethQueryContractID_t *msg) { strlcpy(msg->version, "Delegate", msg->versionLength); msg->result = ETH_PLUGIN_RESULT_OK; break; + case MINT: + strlcpy(msg->version, "Mint", msg->versionLength); + msg->result = ETH_PLUGIN_RESULT_OK; + break; default: PRINTF("Selector index: %d not supported\n", context->selectorIndex); msg->result = ETH_PLUGIN_RESULT_ERROR; diff --git a/src/handle_query_contract_ui.c b/src/handle_query_contract_ui.c index 2617ded4..e6c0ec7e 100644 --- a/src/handle_query_contract_ui.c +++ b/src/handle_query_contract_ui.c @@ -23,8 +23,8 @@ // Set UI for "Receive" screen. // EDIT THIS: Adapt / remove this function to your needs. -/* static bool set_receive_ui(ethQueryContractUI_t *msg, const context_t *context) { - strlcpy(msg->title, "Receive Min.", msg->titleLength); +static bool set_receive_ui(ethQueryContractUI_t *msg, const context_t *context) { + strlcpy(msg->title, "Amount", msg->titleLength); uint8_t decimals = context->decimals; const char *ticker = context->ticker; @@ -41,7 +41,7 @@ ticker, msg->msg, msg->msgLength); -} */ +} // Set UI for "Beneficiary" screen. static bool set_beneficiary_ui(ethQueryContractUI_t *msg, context_t *context) { @@ -50,6 +50,7 @@ static bool set_beneficiary_ui(ethQueryContractUI_t *msg, context_t *context) { strlcpy(msg->title, "Address", msg->titleLength); break; case DELEGATE: + case MINT: strlcpy(msg->title, "Beneficiary", msg->titleLength); break; default: @@ -73,6 +74,50 @@ static bool set_beneficiary_ui(ethQueryContractUI_t *msg, context_t *context) { chainid); } +static bool set_address_ui(ethQueryContractUI_t *msg, context_t *context) { + switch (context->selectorIndex) { + case MINT: + strlcpy(msg->title, "Address", msg->titleLength); + break; + default: + PRINTF("Received an invalid selectorIndex\n"); + break; + } + + // Prefix the address with `0x`. + msg->msg[0] = '0'; + msg->msg[1] = 'x'; + + // We need a random chainID for legacy reasons with `getEthAddressStringFromBinary`. + // Setting it to `0` will make it work with every chainID :) + uint64_t chainid = 0; + + return getEthAddressStringFromBinary( + context->address, + msg->msg + 2, // +2 here because we've already prefixed with '0x'. + chainid); +} + +static bool set_boolean_ui(ethQueryContractUI_t *msg, context_t *context) { + switch (context->selectorIndex) { + case MINT: + strlcpy(msg->title, "Basket Mode", msg->titleLength); + break; + default: + PRINTF("Received an invalid selectorIndex\n"); + break; + } + + if (context->boolean == 0) { + snprintf(msg->msg, msg->msgLength, "%s", "False"); + return true; + } else { + snprintf(msg->msg, msg->msgLength, "%s", "True"); + return true; + } + return false; +} + void handle_query_contract_ui(ethQueryContractUI_t *msg) { context_t *context = (context_t *) msg->pluginContext; bool ret = false; @@ -97,6 +142,25 @@ void handle_query_contract_ui(ethQueryContractUI_t *msg) { break; } break; + case MINT: + switch (msg->screenIndex) { + case 0: + ret = set_address_ui(msg, context); + break; + case 1: + ret = set_receive_ui(msg, context); + break; + case 2: + ret = set_beneficiary_ui(msg, context); + break; + case 3: + ret = set_boolean_ui(msg, context); + break; + default: + PRINTF("Received an invalid screenIndex\n"); + break; + } + break; default: PRINTF("Received an invalid selectorIndex\n"); break; diff --git a/src/plugin.h b/src/plugin.h index c9e80238..981ad280 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -27,7 +27,8 @@ // - a map named SELECTORS associating each NAME with it's value #define SELECTORS_LIST(X) \ X(CREATE_REWARD_VAULT, 0x577ee5c7) \ - X(DELEGATE, 0x5c19a95c) + X(DELEGATE, 0x5c19a95c) \ + X(MINT, 0x328ebaf7) // Xmacro helpers to define the enum and map // Do not modify ! @@ -51,6 +52,8 @@ typedef enum { MIN_AMOUNT_RECEIVED = 0, TOKEN_RECEIVED, BENEFICIARY, + ADDRESS, + BOOLEAN, PATH_OFFSET, PATH_LENGTH, UNEXPECTED_PARAMETER, @@ -64,17 +67,17 @@ typedef struct context_s { // For display. uint8_t amount_received[INT256_LENGTH]; uint8_t beneficiary[ADDRESS_LENGTH]; + uint8_t address[ADDRESS_LENGTH]; uint8_t token_received[ADDRESS_LENGTH]; char ticker[MAX_TICKER_LEN]; uint8_t decimals; uint8_t token_found; - + uint16_t boolean; // For parsing data. uint8_t next_param; // Set to be the next param we expect to parse. uint16_t offset; // Offset at which the array or struct starts. bool go_to_offset; // If set, will force the parsing to iterate through parameters until // `offset` is reached. - // For both parsing and display. selector_t selectorIndex; } context_t; diff --git a/tests/abis/0xb05b8099d9de1e5cf07cd135d059d5a5ed484388.abi.json b/tests/abis/0xb05b8099d9de1e5cf07cd135d059d5a5ed484388.abi.json new file mode 100644 index 00000000..cd79aa9f --- /dev/null +++ b/tests/abis/0xb05b8099d9de1e5cf07cd135d059d5a5ed484388.abi.json @@ -0,0 +1,1973 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessControlBadConfirmation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "neededRole", + "type": "bytes32" + } + ], + "name": "AccessControlUnauthorizedAccount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [], + "name": "AmountOutOfRange", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AssetIsBadCollateral", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AssetIsNotBadCollateral", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "AssetNotRegistered", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "EnforcedPause", + "type": "error" + }, + { + "inputs": [], + "name": "ExceedGlobalCap", + "type": "error" + }, + { + "inputs": [], + "name": "ExceedRelativeCap", + "type": "error" + }, + { + "inputs": [], + "name": "ExpectedPause", + "type": "error" + }, + { + "inputs": [], + "name": "FailedCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shares", + "type": "uint256" + } + ], + "name": "InsufficientAssets", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "InsufficientRecapitalizeAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitialization", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidationDisabled", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidationWithReferenceCollateral", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "expectedOwner", + "type": "address" + } + ], + "name": "MismatchedOwner", + "type": "error" + }, + { + "inputs": [], + "name": "NotFactory", + "type": "error" + }, + { + "inputs": [], + "name": "NotInitializing", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "NotPegged", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "OverOneHundredPercentRate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "RecapitalizeNotNeeded", + "type": "error" + }, + { + "inputs": [], + "name": "UUPSUnauthorizedCallContext", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "slot", + "type": "bytes32" + } + ], + "name": "UUPSUnsupportedProxiableUUID", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "internalType": "address", + "name": "expectedCaller", + "type": "address" + } + ], + "name": "UnauthorizedCaller", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "UnderNinetyEightPercentRate", + "type": "error" + }, + { + "inputs": [], + "name": "UnexpectedBasketModeStatus", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "VaultAlreadyRegistered", + "type": "error" + }, + { + "inputs": [], + "name": "VaultPaused", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAmount", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "ZeroWeight", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "forced", + "type": "bool" + } + ], + "name": "BasketModeForced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isBadCollateral", + "type": "bool" + } + ], + "name": "CollateralAssetStatusSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "name": "CollectedFeeWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lower", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "upper", + "type": "uint256" + } + ], + "name": "DepegOffsetsSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "feeReceiver", + "type": "address" + } + ], + "name": "FeeReceiverSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "globalCap", + "type": "uint256" + } + ], + "name": "GlobalCapSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "HoneyMinted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "HoneyRedeemed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "badAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "goodAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "Liquidated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "LiquidationRateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "LiquidationStatusSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "maxFeedDelay", + "type": "uint256" + } + ], + "name": "MaxFeedDelaySet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "minShareAmount", + "type": "uint256" + } + ], + "name": "MinSharesToRecapitalizeSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "MintRateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "POLFeeCollectorFeeRateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "polFeeCollector", + "type": "address" + } + ], + "name": "POLFeeCollectorSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "PriceFeedChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "target", + "type": "uint256" + } + ], + "name": "RecapitalizeBalanceThresholdSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "Recapitalized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "name": "RedeemRateSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "old", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "ReferenceCollateralSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "relativeCap", + "type": "uint256" + } + ], + "name": "RelativeCapSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "VaultCreated", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MANAGER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PAUSER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "UPGRADE_INTERFACE_VERSION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "beacon", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "collectedFees", + "outputs": [ + { + "internalType": "uint256", + "name": "collectedFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "createVault", + "outputs": [ + { + "internalType": "contract ERC4626", + "name": "vault", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeReceiver", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "forcedBasketMode", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWeights", + "outputs": [ + { + "internalType": "uint256[]", + "name": "w", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "honey", + "outputs": [ + { + "internalType": "contract Honey", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_governance", + "type": "address" + }, + { + "internalType": "address", + "name": "_honey", + "type": "address" + }, + { + "internalType": "address", + "name": "_polFeeCollector", + "type": "address" + }, + { + "internalType": "address", + "name": "_feeReceiver", + "type": "address" + }, + { + "internalType": "address", + "name": "_priceOracle", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "isBadCollateralAsset", + "outputs": [ + { + "internalType": "bool", + "name": "badCollateral", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "isMint", + "type": "bool" + } + ], + "name": "isBasketModeEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "basketMode", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "isPegged", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "badCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "goodCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "goodAmount", + "type": "uint256" + } + ], + "name": "liquidate", + "outputs": [ + { + "internalType": "uint256", + "name": "badAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minSharesToRecapitalize", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "bool", + "name": "expectBasketMode", + "type": "bool" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "honeyToMint", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "mintRates", + "outputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "numRegisteredAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "pauseVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "polFeeCollector", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "polFeeCollectorFeeRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceFeedMaxDelay", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "priceOracle", + "outputs": [ + { + "internalType": "contract IPriceOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "proxiableUUID", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "recapitalize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "recapitalizeBalanceThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "targetBalance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "honeyAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "bool", + "name": "expectBasketMode", + "type": "bool" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256[]", + "name": "redeemed", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "redeemRates", + "outputs": [ + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "referenceCollateral", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "registeredAssets", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "relativeCap", + "outputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "callerConfirmation", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "_isBadCollateral", + "type": "bool" + } + ], + "name": "setCollateralAssetStatus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "lowerOffset", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "upperOffset", + "type": "uint256" + } + ], + "name": "setDepegOffsets", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeReceiver", + "type": "address" + } + ], + "name": "setFeeReceiver", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "forced", + "type": "bool" + } + ], + "name": "setForcedBasketMode", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setGlobalCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "name": "setLiquidationEnabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "extraRate", + "type": "uint256" + } + ], + "name": "setLiquidationRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "maxTolerance", + "type": "uint256" + } + ], + "name": "setMaxFeedDelay", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "minSharesAmount", + "type": "uint256" + } + ], + "name": "setMinSharesToRecapitalize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintRate", + "type": "uint256" + } + ], + "name": "setMintRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_polFeeCollector", + "type": "address" + } + ], + "name": "setPOLFeeCollector", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_polFeeCollectorFeeRate", + "type": "uint256" + } + ], + "name": "setPOLFeeCollectorFeeRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "target", + "type": "uint256" + } + ], + "name": "setRecapitalizeBalanceThreshold", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemRate", + "type": "uint256" + } + ], + "name": "setRedeemRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "setReferenceCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setRelativeCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "unpauseVault", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "vaults", + "outputs": [ + { + "internalType": "contract CollateralVault", + "name": "vault", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "withdrawAllFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "withdrawFee", + "outputs": [ + { + "internalType": "uint256", + "name": "assets", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ] \ No newline at end of file diff --git a/tests/snapshots/flex/test_mint/00000.png b/tests/snapshots/flex/test_mint/00000.png new file mode 100644 index 00000000..0211c7b1 Binary files /dev/null and b/tests/snapshots/flex/test_mint/00000.png differ diff --git a/tests/snapshots/flex/test_mint/00001.png b/tests/snapshots/flex/test_mint/00001.png new file mode 100644 index 00000000..acafac2d Binary files /dev/null and b/tests/snapshots/flex/test_mint/00001.png differ diff --git a/tests/snapshots/flex/test_mint/00002.png b/tests/snapshots/flex/test_mint/00002.png new file mode 100644 index 00000000..ce960c31 Binary files /dev/null and b/tests/snapshots/flex/test_mint/00002.png differ diff --git a/tests/snapshots/flex/test_mint/00003.png b/tests/snapshots/flex/test_mint/00003.png new file mode 100644 index 00000000..358c869b Binary files /dev/null and b/tests/snapshots/flex/test_mint/00003.png differ diff --git a/tests/snapshots/flex/test_mint/00004.png b/tests/snapshots/flex/test_mint/00004.png new file mode 100644 index 00000000..be51a9d5 Binary files /dev/null and b/tests/snapshots/flex/test_mint/00004.png differ diff --git a/tests/snapshots/flex/test_mint/00005.png b/tests/snapshots/flex/test_mint/00005.png new file mode 100644 index 00000000..dabe7afe Binary files /dev/null and b/tests/snapshots/flex/test_mint/00005.png differ diff --git a/tests/snapshots/nanosp/test_mint/00000.png b/tests/snapshots/nanosp/test_mint/00000.png new file mode 100644 index 00000000..487ea10f Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00000.png differ diff --git a/tests/snapshots/nanosp/test_mint/00001.png b/tests/snapshots/nanosp/test_mint/00001.png new file mode 100644 index 00000000..3a06d95b Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00001.png differ diff --git a/tests/snapshots/nanosp/test_mint/00002.png b/tests/snapshots/nanosp/test_mint/00002.png new file mode 100644 index 00000000..a910d45a Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00002.png differ diff --git a/tests/snapshots/nanosp/test_mint/00003.png b/tests/snapshots/nanosp/test_mint/00003.png new file mode 100644 index 00000000..31cc63ed Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00003.png differ diff --git a/tests/snapshots/nanosp/test_mint/00004.png b/tests/snapshots/nanosp/test_mint/00004.png new file mode 100644 index 00000000..e6348719 Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00004.png differ diff --git a/tests/snapshots/nanosp/test_mint/00005.png b/tests/snapshots/nanosp/test_mint/00005.png new file mode 100644 index 00000000..8aa19e2a Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00005.png differ diff --git a/tests/snapshots/nanosp/test_mint/00006.png b/tests/snapshots/nanosp/test_mint/00006.png new file mode 100644 index 00000000..d3508954 Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00006.png differ diff --git a/tests/snapshots/nanosp/test_mint/00007.png b/tests/snapshots/nanosp/test_mint/00007.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00007.png differ diff --git a/tests/snapshots/nanosp/test_mint/00008.png b/tests/snapshots/nanosp/test_mint/00008.png new file mode 100644 index 00000000..a58590b9 Binary files /dev/null and b/tests/snapshots/nanosp/test_mint/00008.png differ diff --git a/tests/snapshots/nanox/test_mint/00000.png b/tests/snapshots/nanox/test_mint/00000.png new file mode 100644 index 00000000..487ea10f Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00000.png differ diff --git a/tests/snapshots/nanox/test_mint/00001.png b/tests/snapshots/nanox/test_mint/00001.png new file mode 100644 index 00000000..3a06d95b Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00001.png differ diff --git a/tests/snapshots/nanox/test_mint/00002.png b/tests/snapshots/nanox/test_mint/00002.png new file mode 100644 index 00000000..a910d45a Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00002.png differ diff --git a/tests/snapshots/nanox/test_mint/00003.png b/tests/snapshots/nanox/test_mint/00003.png new file mode 100644 index 00000000..31cc63ed Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00003.png differ diff --git a/tests/snapshots/nanox/test_mint/00004.png b/tests/snapshots/nanox/test_mint/00004.png new file mode 100644 index 00000000..e6348719 Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00004.png differ diff --git a/tests/snapshots/nanox/test_mint/00005.png b/tests/snapshots/nanox/test_mint/00005.png new file mode 100644 index 00000000..8aa19e2a Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00005.png differ diff --git a/tests/snapshots/nanox/test_mint/00006.png b/tests/snapshots/nanox/test_mint/00006.png new file mode 100644 index 00000000..d3508954 Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00006.png differ diff --git a/tests/snapshots/nanox/test_mint/00007.png b/tests/snapshots/nanox/test_mint/00007.png new file mode 100644 index 00000000..570ce28d Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00007.png differ diff --git a/tests/snapshots/nanox/test_mint/00008.png b/tests/snapshots/nanox/test_mint/00008.png new file mode 100644 index 00000000..a58590b9 Binary files /dev/null and b/tests/snapshots/nanox/test_mint/00008.png differ diff --git a/tests/snapshots/stax/test_mint/00000.png b/tests/snapshots/stax/test_mint/00000.png new file mode 100644 index 00000000..72a1fc47 Binary files /dev/null and b/tests/snapshots/stax/test_mint/00000.png differ diff --git a/tests/snapshots/stax/test_mint/00001.png b/tests/snapshots/stax/test_mint/00001.png new file mode 100644 index 00000000..7d5019d5 Binary files /dev/null and b/tests/snapshots/stax/test_mint/00001.png differ diff --git a/tests/snapshots/stax/test_mint/00002.png b/tests/snapshots/stax/test_mint/00002.png new file mode 100644 index 00000000..03f35020 Binary files /dev/null and b/tests/snapshots/stax/test_mint/00002.png differ diff --git a/tests/snapshots/stax/test_mint/00003.png b/tests/snapshots/stax/test_mint/00003.png new file mode 100644 index 00000000..c51cec5c Binary files /dev/null and b/tests/snapshots/stax/test_mint/00003.png differ diff --git a/tests/snapshots/stax/test_mint/00004.png b/tests/snapshots/stax/test_mint/00004.png new file mode 100644 index 00000000..392165d4 Binary files /dev/null and b/tests/snapshots/stax/test_mint/00004.png differ diff --git a/tests/snapshots/stax/test_mint/00005.png b/tests/snapshots/stax/test_mint/00005.png new file mode 100644 index 00000000..339db1b4 Binary files /dev/null and b/tests/snapshots/stax/test_mint/00005.png differ diff --git a/tests/test_mint.py b/tests/test_mint.py new file mode 100644 index 00000000..26b708db --- /dev/null +++ b/tests/test_mint.py @@ -0,0 +1,76 @@ +from pathlib import Path +import json +import os + +from web3 import Web3 +from eth_typing import ChainId + +from ledger_app_clients.ethereum.client import EthAppClient +import ledger_app_clients.ethereum.response_parser as ResponseParser +from ledger_app_clients.ethereum.utils import get_selector_from_data, recover_transaction +from ragger.navigator import NavInsID + +from .utils import get_appname_from_makefile, DERIVATION_PATH + + +ROOT_SCREENSHOT_PATH = Path(__file__).parent +ABIS_FOLDER = "%s/abis" % (os.path.dirname(__file__)) + +PLUGIN_NAME = get_appname_from_makefile() + + +with open("%s/0xb05b8099d9de1e5cf07cd135d059d5a5ed484388.abi.json" % (ABIS_FOLDER)) as file: + contract = Web3().eth.contract( + abi=json.load(file), + # Get address from filename + address=bytes.fromhex(os.path.basename(file.name).split(".")[0].split("x")[-1]) + ) + + +# EDIT THIS: build your own test +def test_mint(backend, firmware, navigator, test_name, wallet_addr): + client = EthAppClient(backend) + + data = contract.encode_abi("mint", [ + bytes.fromhex("015fd589F4f1A33ce4487E12714e1B15129c9329"), + Web3.to_wei(1.13, "ether"), + bytes.fromhex("4C368fFE3650379d6318C8d4630bc51f8Ad12bB6"), + False, + ]) + + # first setup the external plugin + client.set_external_plugin(PLUGIN_NAME, + contract.address, + # Extract function selector from the encoded data + get_selector_from_data(data)) + + tx_params = { + "nonce": 20, + "maxFeePerGas": Web3.to_wei(145, "gwei"), + "maxPriorityFeePerGas": Web3.to_wei(1.5, "gwei"), + "gas": 173290, + "to": contract.address, + "value": 0, + "chainId": ChainId.ETH, + "data": data + } + # send the transaction + with client.sign(DERIVATION_PATH, tx_params): + # Validate the on-screen request by performing the navigation appropriate for this device + if firmware.is_nano: + navigator.navigate_until_text_and_compare(NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Accept", + ROOT_SCREENSHOT_PATH, + test_name) + else: + navigator.navigate_until_text_and_compare(NavInsID.SWIPE_CENTER_TO_LEFT, + [NavInsID.USE_CASE_REVIEW_CONFIRM, + NavInsID.USE_CASE_STATUS_DISMISS], + "Hold to sign", + ROOT_SCREENSHOT_PATH, + test_name) + # verify signature + vrs = ResponseParser.signature(client.response().data) + addr = recover_transaction(tx_params, vrs) + assert addr == wallet_addr.get()