Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clear sign PAY PORTION token #20

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ APPNAME = "Uniswap"

# Application version
APPVERSION_M = 1
APPVERSION_N = 3
APPVERSION_N = 4
APPVERSION_P = 0

APP_SOURCE_FILES += $(BOLOS_SDK)/lib_standard_app/crypto_helpers.c
Expand Down
1 change: 0 additions & 1 deletion PLUGIN_SPECIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ https://docs.uniswap.org/contracts/universal-router/technical-reference#command-
| V3_SWAP_EXACT_OUT |
| WRAP_ETH |
| UNWRAP_ETH |
| PERMIT2_TRANSFER_FROM |
| PERMIT2_PERMIT_BATCH |
| PERMIT2_TRANSFER_FROM_BATCH |
| PERMIT2_PERMIT |
Expand Down
47 changes: 29 additions & 18 deletions src/handle_finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,35 +90,38 @@ static bool valid_wrap_unwrap_amounts(const context_t *context) {
return true;
}

// Resolve token if possible, request otherwise
static bool resolve_asset(io_data_t *io_data) {
if (io_data->asset_type == ETH) {
static bool resolve_asset_raw(asset_type_t *asset_type, asset_info_t *asset_info) {
if (*asset_type == ETH) {
PRINTF("Finalizing IO with asset ETH\n");
io_data->u.token_info.decimals = WEI_TO_ETHER;
strlcpy(io_data->u.token_info.ticker, "ETH", sizeof(io_data->u.token_info.ticker));
asset_info->token_info.decimals = WEI_TO_ETHER;
strlcpy(asset_info->token_info.ticker, "ETH", sizeof(asset_info->token_info.ticker));
return true;

} else if (io_data->asset_type == WETH) {
} else if (*asset_type == WETH) {
PRINTF("Finalizing IO with asset WETH\n");
io_data->u.token_info.decimals = WETH_DECIMALS;
strlcpy(io_data->u.token_info.ticker, WETH_TICKER, sizeof(io_data->u.token_info.ticker));
asset_info->token_info.decimals = WETH_DECIMALS;
strlcpy(asset_info->token_info.ticker, WETH_TICKER, sizeof(asset_info->token_info.ticker));
// Handle it like a token from now on
io_data->asset_type = KNOWN_TOKEN;
*asset_type = KNOWN_TOKEN;
return true;

} else {
PRINTF("Requesting CAL data for token %.*H\n", ADDRESS_LENGTH, io_data->u.address);
PRINTF("Requesting CAL data for token %.*H\n", ADDRESS_LENGTH, asset_info->address);
return false;
}
}

// Resolve token if possible, request otherwise
static bool resolve_asset(io_data_t *io_data) {
return resolve_asset_raw(&io_data->asset_type, &io_data->u);
}

void handle_finalize(ethPluginFinalize_t *msg) {
msg->result = ETH_PLUGIN_RESULT_OK;
context_t *context = (context_t *) msg->pluginContext;

msg->uiType = ETH_UI_TYPE_GENERIC;

// EDIT THIS: Set the total number of screen you will need.
msg->numScreens = 2;

if (context->swap_type == NONE) {
Expand Down Expand Up @@ -173,28 +176,36 @@ void handle_finalize(ethPluginFinalize_t *msg) {
return;
}

if (!valid_wrap_unwrap_amounts(context)) {
PRINTF("Error: valid_wrap_unwrap_amounts failed\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
return;
}

if (!is_sender_address(context->recipient, context->own_address)) {
PRINTF("Displaying recipient\n");
++msg->numScreens;
}

if (context->pay_portion_amount != 0) {
if (context->pay_portion_asset_type != UNSET) {
PRINTF("Displaying pay portion\n");
++msg->numScreens;
}

// Resolve IOs if possible, request otherwise
if (!resolve_asset(&context->input)) {
PRINTF("Requesting CAL info for input token\n");
msg->tokenLookup1 = context->input.u.address;
}

if (!resolve_asset(&context->output)) {
PRINTF("Requesting CAL info for output token\n");
msg->tokenLookup2 = context->output.u.address;
}

if (!resolve_asset_raw(&context->pay_portion_asset_type, &context->pay_portion_asset)) {
if (msg->tokenLookup1 == NULL) {
PRINTF("Requesting CAL info for PAY_PORTION token in item 1\n");
msg->tokenLookup1 = context->pay_portion_asset.address;
} else if (msg->tokenLookup2 == NULL) {
PRINTF("Requesting CAL info for PAY_PORTION token in item 2\n");
msg->tokenLookup2 = context->pay_portion_asset.address;
} else {
PRINTF("Warning: Can't request CAL info for PAY_PORTION token\n");
}
}
}
36 changes: 24 additions & 12 deletions src/handle_provide_parameter.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ static uint8_t prepare_reading_next_input(context_t *context) {
PRINTF("Preparing to read V3_SWAP_EXACT_OUT\n");
context->next_param = INPUT_V3_SWAP_EXACT_OUT_LENGTH;
break;
case PERMIT2_TRANSFER_FROM:
case PERMIT2_PERMIT_BATCH:
case PERMIT2_TRANSFER_FROM_BATCH:
case PERMIT2_PERMIT:
Expand Down Expand Up @@ -173,21 +172,27 @@ static int add_wrap_or_unwrap(const uint8_t parameter[PARAMETER_LENGTH],
return 0;
}

// Set the type of input or output token. Handle it the same way thanks to the io_data_t structure.
static int set_token(const uint8_t address[ADDRESS_LENGTH], io_data_t *io_data) {
static int set_token_raw(const uint8_t address[ADDRESS_LENGTH],
asset_type_t *asset_type,
asset_info_t *pay_portion_asset) {
PRINTF("Setting token\n");
if (token_is_weth(address)) {
PRINTF("Token to set is WETH\n");
io_data->asset_type = WETH;
*asset_type = WETH;
} else {
PRINTF("Token to set is unknown %.*H\n", ADDRESS_LENGTH, address);
io_data->asset_type = UNKNOWN_TOKEN;
memmove(io_data->u.address, address, ADDRESS_LENGTH);
*asset_type = UNKNOWN_TOKEN;
memmove(pay_portion_asset->address, address, ADDRESS_LENGTH);
}

return 0;
}

// Set the type of input or output token. Handle it the same way thanks to the io_data_t structure.
static int set_token(const uint8_t address[ADDRESS_LENGTH], io_data_t *io_data) {
return set_token_raw(address, &io_data->asset_type, &io_data->u);
}

static bool address_partially_matches_io(const uint8_t *address,
io_data_t *io,
bool accept_eth,
Expand Down Expand Up @@ -708,29 +713,36 @@ static void handle_execute(ethPluginProvideParameter_t *msg, context_t *context)
case INPUT_PAY_PORTION_LENGTH:
PRINTF("Interpreting as INPUT_PAY_PORTION_LENGTH\n");
context->next_param = INPUT_PAY_PORTION_TOKEN;
if (context->pay_portion_asset_type != UNSET) {
PRINTF("One PAY_PORTION has already been received. Refusing to handle multiple\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
}
break;
case INPUT_PAY_PORTION_TOKEN:
PRINTF("Interpreting as INPUT_PAY_PORTION_TOKEN\n");
context->next_param = INPUT_PAY_PORTION_RECIPIENT;
if (set_token_raw(msg->parameter + PARAMETER_LENGTH - ADDRESS_LENGTH,
&context->pay_portion_asset_type,
&context->pay_portion_asset) != 0) {
PRINTF("set_token_raw failed\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
}
break;
case INPUT_PAY_PORTION_RECIPIENT:
PRINTF("Interpreting as INPUT_PAY_PORTION_RECIPIENT\n");
context->next_param = INPUT_PAY_PORTION_AMOUNT;
break;
case INPUT_PAY_PORTION_AMOUNT: {
PRINTF("Interpreting as INPUT_PAY_PORTION_AMOUNT\n");
uint16_t new;
if (!U2BE_from_parameter(msg->parameter, &new)) {
if (!U2BE_from_parameter(msg->parameter, &context->pay_portion_amount)) {
PRINTF("Error: Not a valid basis point amount\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
} else {
uint32_t pay_portion_sum = context->pay_portion_amount + new;
PRINTF("pay_portion_sum %d\n", pay_portion_sum);
if (pay_portion_sum > 10000) {
PRINTF("context->pay_portion_amount %d\n", context->pay_portion_amount);
if (context->pay_portion_amount > 10000) {
PRINTF("Error: Not a valid basis point amount\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
} else {
context->pay_portion_amount = pay_portion_sum;
++context->current_command;
if (prepare_reading_next_input(context) != 0) {
msg->result = ETH_PLUGIN_RESULT_ERROR;
Expand Down
77 changes: 53 additions & 24 deletions src/handle_provide_token.c
Original file line number Diff line number Diff line change
@@ -1,60 +1,89 @@
#include "plugin.h"

// We will run in this function if we requested CAL data in handle_finalize

static int provide_token_for_io(io_data_t *io_data,
const extraInfo_t *item,
bool *info_is_missing) {
static bool provide_token_for_io_raw(asset_type_t *asset_type,
asset_info_t *asset_info,
const extraInfo_t *item) {
// Check if we need CAL data for this asset
*info_is_missing = false;
if (io_data->asset_type == UNKNOWN_TOKEN) {
if (*asset_type == UNKNOWN_TOKEN) {
PRINTF("CAL data was requested\n");
if (item == NULL) {
*info_is_missing = true;
PRINTF("Warning: no CAL data provided\n");
return false;
} else {
// Ensure the addresses match
if (memcmp(io_data->u.address, item->token.address, ADDRESS_LENGTH) != 0) {
PRINTF("Error: data provided by the CAL does not match\n");
PRINTF("Needed: %.*H\n", ADDRESS_LENGTH, io_data->u.address);
if (memcmp(asset_info->address, item->token.address, ADDRESS_LENGTH) != 0) {
PRINTF("Warning: data provided by the CAL does not match\n");
PRINTF("Needed: %.*H\n", ADDRESS_LENGTH, asset_info->address);
PRINTF("Received: %.*H\n", ADDRESS_LENGTH, item->token.address);
return -1;
return false;
} else {
// Remember that we know this token.
io_data->asset_type = KNOWN_TOKEN;
*asset_type = KNOWN_TOKEN;
// Store its decimals.
io_data->u.token_info.decimals = item->token.decimals;
asset_info->token_info.decimals = item->token.decimals;
// Store its ticker.
strlcpy(io_data->u.token_info.ticker,
strlcpy(asset_info->token_info.ticker,
(char *) item->token.ticker,
sizeof(io_data->u.token_info.ticker));
sizeof(asset_info->token_info.ticker));
return true;
}
}
} else if (item != NULL) {
PRINTF("Warning: CAL data provided but not requested\n");
return true;
}
return 0;
return true;
}


static bool provide_token_for_io(io_data_t *io_data,
const extraInfo_t *item) {
return provide_token_for_io_raw(&io_data->asset_type, &io_data->u, item);
};

void handle_provide_token(ethPluginProvideInfo_t *msg) {
context_t *context = (context_t *) msg->pluginContext;
msg->result = ETH_PLUGIN_RESULT_OK;
msg->additionalScreens = 0;
bool token_in_info_missing;
bool token_out_info_missing;
bool token_pay_portion_info_missing;

token_in_info_missing = !provide_token_for_io(&context->input, msg->item1);

token_out_info_missing = !provide_token_for_io(&context->output, msg->item2);

if (provide_token_for_io(&context->input, msg->item1, &token_in_info_missing) != 0) {
PRINTF("Error in provide_token_for_io for input\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
if (context->pay_portion_asset_type == UNKNOWN_TOKEN) {
PRINTF("Trying to find info for PAY_PORTION token in CAL\n");
token_pay_portion_info_missing = true;
if (provide_token_for_io_raw(&context->pay_portion_asset_type, &context->pay_portion_asset, msg->item1)) {
PRINTF("Found it in item 1\n");
token_pay_portion_info_missing = false;
} else if (provide_token_for_io_raw(&context->pay_portion_asset_type, &context->pay_portion_asset, msg->item2)) {
PRINTF("Found it in item 2\n");
token_pay_portion_info_missing = false;
}
} else {
token_pay_portion_info_missing = false;
}

if (provide_token_for_io(&context->output, msg->item2, &token_out_info_missing) != 0) {
PRINTF("Error in provide_token_for_io for output\n");
msg->result = ETH_PLUGIN_RESULT_ERROR;
if (token_in_info_missing) {
PRINTF("Missing info for token IN\n");
}
if (token_out_info_missing) {
PRINTF("Missing info for token OUT\n");
}
if (token_pay_portion_info_missing) {
PRINTF("Missing info for token PAY PORTION\n");
}

if (token_in_info_missing || token_out_info_missing) {
if (token_in_info_missing || token_out_info_missing || token_pay_portion_info_missing) {
// Additional screen for a warning
msg->additionalScreens += 3;
msg->additionalScreens += 1;
if (token_in_info_missing || token_out_info_missing) {
// Additional screen for independent in / out asset display
msg->additionalScreens += 2;
}
}
}
Loading
Loading