4
Makefile
4
Makefile
@@ -46,9 +46,11 @@ DEFINES += CHAINID_UPCASE=\"ETHEREUM\" CHAINID_COINNAME=\"ETH\" CHAIN_KIND=CHAIN
|
||||
APP_LOAD_PARAMS += --path "2645'/579218131'"
|
||||
DEFINES += HAVE_STARKWARE
|
||||
DEFINES += STARK_BIP32_PATH_0=0x80000A55 STARK_BIP32_PATH_1=0xA2862AD3
|
||||
ifeq ($(TARGET_NAME), TARGET_NANOX)
|
||||
# Allow to derive ETH 2 public keys
|
||||
APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1
|
||||
DEFINES += HAVE_ETH2
|
||||
endif
|
||||
APPNAME = "Ethereum"
|
||||
DEFINES_LIB=
|
||||
APP_LOAD_FLAGS=--appFlags 0xa40
|
||||
@@ -61,9 +63,11 @@ DEFINES += HAVE_STARKWARE
|
||||
# Keep for Starkware Ropsten tests
|
||||
DEFINES += HAVE_TOKENS_EXTRA_LIST
|
||||
DEFINES += STARK_BIP32_PATH_0=0x80000A55 STARK_BIP32_PATH_1=0xA2862AD3
|
||||
ifeq ($(TARGET_NAME), TARGET_NANOX)
|
||||
# Allow to derive ETH 2 public keys
|
||||
APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1
|
||||
DEFINES += HAVE_ETH2
|
||||
endif
|
||||
APPNAME = "Eth Ropsten"
|
||||
DEFINES_LIB=
|
||||
APP_LOAD_FLAGS=--appFlags 0xa40
|
||||
|
||||
@@ -72,7 +72,7 @@ CONTRACT_STARKWARE_DEPOSIT_TOKEN
|
||||
|
||||
```C
|
||||
if ((context->currentFieldLength == STARKWARE_DEPOSIT_TOKEN_DATA_SIZE) &&
|
||||
(os_memcmp(context->workBuffer, STARKWARE_DEPOSIT_TOKEN_ID, 4) == 0) &&
|
||||
(memcmp(context->workBuffer, STARKWARE_DEPOSIT_TOKEN_ID, 4) == 0) &&
|
||||
quantumSet) {
|
||||
contractProvisioned = CONTRACT_STARKWARE_DEPOSIT_TOKEN;
|
||||
}
|
||||
|
||||
@@ -322,7 +322,7 @@ This command has been supported since firmware version 1.5.0
|
||||
|
||||
This command returns an Ethereum 2 BLS12-381 public key derived following EIP 2333 specification (https://eips.ethereum.org/EIPS/eip-2333)
|
||||
|
||||
This command has been supported since firmware version 1.5.0
|
||||
This command has been supported since firmware version 1.6.0
|
||||
|
||||
#### Coding
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define APP_FLAG_DATA_ALLOWED 0x01
|
||||
#define APP_FLAG_EXTERNAL_TOKEN_NEEDED 0x02
|
||||
#define APP_FLAG_STARKWARE 0x04
|
||||
#define APP_FLAG_STARKWARE_V2 0x08
|
||||
|
||||
#define CLA 0xE0
|
||||
#define INS_GET_PUBLIC_KEY 0x02
|
||||
@@ -29,12 +30,17 @@
|
||||
#define STARKWARE_INS_GET_PUBLIC_KEY 0x02
|
||||
#define STARKWARE_INS_SIGN_MESSAGE 0x04
|
||||
#define STARKWARE_INS_PROVIDE_QUANTUM 0x08
|
||||
#define STARKWARE_INS_UNSAFE_SIGN 0x0A
|
||||
|
||||
#define P1_STARK_ORDER 0x01
|
||||
#define P1_STARK_TRANSFER 0x02
|
||||
#define P1_STARK_ORDER_V2 0x03
|
||||
#define P1_STARK_TRANSFER_V2 0x04
|
||||
#define P1_STARK_CONDITIONAL_TRANSFER 0x05
|
||||
|
||||
#define STARK_ORDER_TYPE 0
|
||||
#define STARK_TRANSFER_TYPE 1
|
||||
#define STARK_CONDITIONAL_TRANSFER_TYPE 2
|
||||
|
||||
#endif
|
||||
|
||||
@@ -64,6 +70,7 @@ void handleSetEth2WinthdrawalIndex(uint8_t p1, uint8_t p2, uint8_t *dataBuffer,
|
||||
void handleStarkwareGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx);
|
||||
void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx);
|
||||
void handleStarkwareProvideQuantum(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx);
|
||||
void handleStarkwareUnsafeSign(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -57,10 +57,13 @@ int eth_plugin_perform_init(uint8_t *contractAddress, ethPluginInitContract_t *i
|
||||
}
|
||||
for (j=0; ((j<INTERNAL_ETH_PLUGINS[i].num_selectors) && (contractAddress != NULL)); j++) {
|
||||
if (memcmp(init->selector, PIC(selectors[j]), SELECTOR_SIZE) == 0) {
|
||||
strcpy(dataContext.tokenContext.pluginName, INTERNAL_ETH_PLUGINS[i].alias);
|
||||
dataContext.tokenContext.pluginAvailable = 1;
|
||||
contractAddress = NULL;
|
||||
break;
|
||||
if ((INTERNAL_ETH_PLUGINS[i].availableCheck == NULL) ||
|
||||
((PluginAvailableCheck)PIC(INTERNAL_ETH_PLUGINS[i].availableCheck))()) {
|
||||
strcpy(dataContext.tokenContext.pluginName, INTERNAL_ETH_PLUGINS[i].alias);
|
||||
dataContext.tokenContext.pluginAvailable = 1;
|
||||
contractAddress = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#include "eth_plugin_internal.h"
|
||||
|
||||
bool erc20_plugin_available_check(void);
|
||||
bool erc721_plugin_available_check(void);
|
||||
|
||||
void erc20_plugin_call(int message, void *parameters);
|
||||
void erc721_plugin_call(int message, void *parameters);
|
||||
void compound_plugin_call(int message, void *parameters);
|
||||
#ifdef HAVE_STARKWARE
|
||||
void starkware_plugin_call(int message, void *parameters);
|
||||
@@ -16,6 +20,13 @@ const uint8_t* const ERC20_SELECTORS[NUM_ERC20_SELECTORS] = {
|
||||
ERC20_TRANSFER_SELECTOR, ERC20_APPROVE_SELECTOR
|
||||
};
|
||||
|
||||
|
||||
static const uint8_t const ERC721_APPROVE_SELECTOR[SELECTOR_SIZE] = { 0x09, 0x5e, 0xa7, 0xb3 };
|
||||
|
||||
const uint8_t* const ERC721_SELECTORS[NUM_ERC721_SELECTORS] = {
|
||||
ERC721_APPROVE_SELECTOR
|
||||
};
|
||||
|
||||
static const uint8_t const COMPOUND_REDEEM_UNDERLYING_SELECTOR[SELECTOR_SIZE] = { 0x85, 0x2a, 0x12, 0xe3 };
|
||||
static const uint8_t const COMPOUND_REDEEM_SELECTOR[SELECTOR_SIZE] = { 0xdb, 0x00, 0x6a, 0x75 };
|
||||
static const uint8_t const COMPOUND_MINT_SELECTOR[SELECTOR_SIZE] = { 0xa0, 0x71, 0x2d, 0x68 };
|
||||
@@ -38,22 +49,32 @@ const uint8_t* const ETH2_SELECTORS[NUM_ETH2_SELECTORS] = {
|
||||
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
static const uint8_t const STARKWARE_REGISTER_ID[SELECTOR_SIZE] = { 0x76, 0x57, 0x18, 0xd7 };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_TOKEN_ID[SELECTOR_SIZE] = { 0x00, 0xae, 0xef, 0x8a };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_ETH_ID[SELECTOR_SIZE] = { 0xe2, 0xbb, 0xb1, 0x58 };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_CANCEL_ID[SELECTOR_SIZE] = { 0xc7, 0xfb, 0x11, 0x7c };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_RECLAIM_ID[SELECTOR_SIZE] = { 0x4e, 0xab, 0x38, 0xf4 };
|
||||
static const uint8_t const STARKWARE_WITHDRAW_ID[SELECTOR_SIZE] = { 0x2e, 0x1a, 0x7d, 0x4d };
|
||||
static const uint8_t const STARKWARE_FULL_WITHDRAWAL_ID[SELECTOR_SIZE] = { 0x27, 0x6d, 0xd1, 0xde };
|
||||
static const uint8_t const STARKWARE_FREEZE_ID[SELECTOR_SIZE] = { 0xb9, 0x10, 0x72, 0x09 };
|
||||
static const uint8_t const STARKWARE_REGISTER_ID[SELECTOR_SIZE] = { 0xdd, 0x24, 0x14, 0xd4 };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_TOKEN_ID[SELECTOR_SIZE] = { 0x25, 0x05, 0xc3, 0xd9 };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_ETH_ID[SELECTOR_SIZE] = { 0x00, 0xae, 0xef, 0x8a };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_CANCEL_ID[SELECTOR_SIZE] = { 0x7d, 0xf7, 0xdc, 0x04 };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_RECLAIM_ID[SELECTOR_SIZE] = { 0xae, 0x87, 0x38, 0x16 };
|
||||
static const uint8_t const STARKWARE_WITHDRAW_ID[SELECTOR_SIZE] = { 0x44, 0x1a, 0x3e, 0x70 };
|
||||
static const uint8_t const STARKWARE_FULL_WITHDRAWAL_ID[SELECTOR_SIZE] = { 0xa9, 0x33, 0x10, 0xc4 };
|
||||
static const uint8_t const STARKWARE_FREEZE_ID[SELECTOR_SIZE] = { 0x93, 0xc1, 0xe4, 0x66 };
|
||||
static const uint8_t const STARKWARE_ESCAPE_ID[SELECTOR_SIZE] = { 0x9e, 0x3a, 0xda, 0xc4 };
|
||||
static const uint8_t const STARKWARE_VERIFY_ESCAPE_ID[SELECTOR_SIZE] = { 0x2d, 0xd5, 0x30, 0x06 };
|
||||
|
||||
static const uint8_t const STARKWARE_WITHDRAW_TO_ID[SELECTOR_SIZE] = { 0x14, 0xcd, 0x70, 0xe4 };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_NFT_ID[SELECTOR_SIZE] = { 0xae, 0x1c, 0xdd, 0xe6 };
|
||||
static const uint8_t const STARKWARE_DEPOSIT_NFT_RECLAIM_ID[SELECTOR_SIZE] = { 0xfc, 0xb0, 0x58, 0x22 };
|
||||
static const uint8_t const STARKWARE_WITHDRAW_AND_MINT_ID[SELECTOR_SIZE] = { 0xd9, 0x14, 0x43, 0xb7 };
|
||||
static const uint8_t const STARKWARE_WITHDRAW_NFT_ID[SELECTOR_SIZE] = { 0x01, 0x9b, 0x41, 0x7a };
|
||||
static const uint8_t const STARKWARE_WITHDRAW_NFT_TO_ID[SELECTOR_SIZE] = { 0xeb, 0xef, 0x0f, 0xd0 };
|
||||
|
||||
|
||||
const uint8_t* const STARKWARE_SELECTORS[NUM_STARKWARE_SELECTORS] = {
|
||||
STARKWARE_REGISTER_ID, STARKWARE_DEPOSIT_TOKEN_ID, STARKWARE_DEPOSIT_ETH_ID,
|
||||
STARKWARE_DEPOSIT_CANCEL_ID, STARKWARE_DEPOSIT_RECLAIM_ID, STARKWARE_WITHDRAW_ID,
|
||||
STARKWARE_FULL_WITHDRAWAL_ID, STARKWARE_FREEZE_ID, STARKWARE_ESCAPE_ID,
|
||||
STARKWARE_VERIFY_ESCAPE_ID
|
||||
STARKWARE_VERIFY_ESCAPE_ID, STARKWARE_WITHDRAW_TO_ID, STARKWARE_DEPOSIT_NFT_ID,
|
||||
STARKWARE_DEPOSIT_NFT_RECLAIM_ID, STARKWARE_WITHDRAW_AND_MINT_ID, STARKWARE_WITHDRAW_NFT_ID,
|
||||
STARKWARE_WITHDRAW_NFT_TO_ID
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -62,6 +83,7 @@ const uint8_t* const STARKWARE_SELECTORS[NUM_STARKWARE_SELECTORS] = {
|
||||
|
||||
const internalEthPlugin_t const INTERNAL_ETH_PLUGINS[] = {
|
||||
{
|
||||
erc20_plugin_available_check,
|
||||
ERC20_SELECTORS,
|
||||
NUM_ERC20_SELECTORS,
|
||||
"-erc20",
|
||||
@@ -69,6 +91,15 @@ const internalEthPlugin_t const INTERNAL_ETH_PLUGINS[] = {
|
||||
},
|
||||
|
||||
{
|
||||
erc721_plugin_available_check,
|
||||
ERC721_SELECTORS,
|
||||
NUM_ERC721_SELECTORS,
|
||||
"-er721",
|
||||
erc721_plugin_call
|
||||
},
|
||||
|
||||
{
|
||||
NULL,
|
||||
COMPOUND_SELECTORS,
|
||||
NUM_COMPOUND_SELECTORS,
|
||||
"-cmpd",
|
||||
@@ -78,6 +109,7 @@ const internalEthPlugin_t const INTERNAL_ETH_PLUGINS[] = {
|
||||
#ifdef HAVE_ETH2
|
||||
|
||||
{
|
||||
NULL,
|
||||
ETH2_SELECTORS,
|
||||
NUM_ETH2_SELECTORS,
|
||||
"-eth2",
|
||||
@@ -89,6 +121,7 @@ const internalEthPlugin_t const INTERNAL_ETH_PLUGINS[] = {
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
{
|
||||
NULL,
|
||||
STARKWARE_SELECTORS,
|
||||
10,
|
||||
"-strk",
|
||||
@@ -98,6 +131,7 @@ const internalEthPlugin_t const INTERNAL_ETH_PLUGINS[] = {
|
||||
#endif
|
||||
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
"",
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
|
||||
#define SELECTOR_SIZE 4
|
||||
|
||||
typedef bool (*PluginAvailableCheck)(void);
|
||||
|
||||
typedef struct internalEthPlugin_t {
|
||||
PluginAvailableCheck availableCheck;
|
||||
const uint8_t **selectors;
|
||||
uint8_t num_selectors;
|
||||
char alias[7];
|
||||
@@ -14,6 +17,9 @@ typedef struct internalEthPlugin_t {
|
||||
#define NUM_ERC20_SELECTORS 2
|
||||
extern const uint8_t* const ERC20_SELECTORS[NUM_ERC20_SELECTORS];
|
||||
|
||||
#define NUM_ERC721_SELECTORS 1
|
||||
extern const uint8_t* const ERC721_SELECTORS[NUM_ERC721_SELECTORS];
|
||||
|
||||
#define NUM_COMPOUND_SELECTORS 4
|
||||
extern const uint8_t* const COMPOUND_SELECTORS[NUM_COMPOUND_SELECTORS];
|
||||
|
||||
@@ -26,7 +32,7 @@ extern const uint8_t* const ETH2_SELECTORS[NUM_ETH2_SELECTORS];
|
||||
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
#define NUM_STARKWARE_SELECTORS 10
|
||||
#define NUM_STARKWARE_SELECTORS 16
|
||||
extern const uint8_t* const STARKWARE_SELECTORS[NUM_STARKWARE_SELECTORS];
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "ethUtils.h"
|
||||
#include "string.h"
|
||||
|
||||
#define ZERO(x) os_memset(x, 0, sizeof(x))
|
||||
#define ZERO(x) memset(x, 0, sizeof(x))
|
||||
|
||||
void handle_check_address(check_address_parameters_t* params, chain_config_t* chain_config) {
|
||||
PRINTF("Params on the address %d\n",(unsigned int)params);
|
||||
@@ -60,10 +60,10 @@ void handle_check_address(check_address_parameters_t* params, chain_config_t* ch
|
||||
}
|
||||
|
||||
if ((strlen(locals_union1.address) != strlen(params->address_to_check + offset_0x)) ||
|
||||
os_memcmp(locals_union1.address, params->address_to_check + offset_0x, strlen(locals_union1.address)) != 0) {
|
||||
memcmp(locals_union1.address, params->address_to_check + offset_0x, strlen(locals_union1.address)) != 0) {
|
||||
PRINTF("Addresses doesn't match\n");
|
||||
return;
|
||||
}
|
||||
PRINTF("Addresses match\n");
|
||||
params->result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
void handle_get_printable_amount( get_printable_amount_parameters_t* params, chain_config_t *config) {
|
||||
uint8_t decimals;
|
||||
char ticker[MAX_TICKER_LEN];
|
||||
os_memset(params->printable_amount, 0, sizeof(params->printable_amount));
|
||||
memset(params->printable_amount, 0, sizeof(params->printable_amount));
|
||||
if (params->amount_length > 32) {
|
||||
PRINTF("Amount is too big, 32 bytes max but buffer has %u bytes", params->amount_length);
|
||||
os_lib_end();
|
||||
@@ -30,4 +30,4 @@ void handle_get_printable_amount( get_printable_amount_parameters_t* params, cha
|
||||
}
|
||||
|
||||
amountToString(params->amount, params->amount_length, decimals, ticker, params->printable_amount, sizeof(params->printable_amount));
|
||||
}
|
||||
}
|
||||
|
||||
25
src/main.c
25
src/main.c
@@ -69,7 +69,7 @@ chain_config_t *chainConfig;
|
||||
void reset_app_context() {
|
||||
//PRINTF("!!RESET_APP_CONTEXT\n");
|
||||
appState = APP_STATE_IDLE;
|
||||
os_memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
called_from_swap = false;
|
||||
#ifdef HAVE_STARKWARE
|
||||
quantumSet = false;
|
||||
@@ -77,8 +77,8 @@ void reset_app_context() {
|
||||
#ifdef HAVE_ETH2
|
||||
eth2WithdrawalIndex = 0;
|
||||
#endif
|
||||
os_memset((uint8_t*)&txContext, 0, sizeof(txContext));
|
||||
os_memset((uint8_t*)&tmpContent, 0, sizeof(tmpContent));
|
||||
memset((uint8_t*)&txContext, 0, sizeof(txContext));
|
||||
memset((uint8_t*)&tmpContent, 0, sizeof(tmpContent));
|
||||
}
|
||||
|
||||
void ui_idle(void) {
|
||||
@@ -118,7 +118,7 @@ void io_seproxyhal_send_status(uint32_t sw) {
|
||||
}
|
||||
|
||||
void format_signature_out(const uint8_t* signature) {
|
||||
os_memset(G_io_apdu_buffer + 1, 0x00, 64);
|
||||
memset(G_io_apdu_buffer + 1, 0x00, 64);
|
||||
uint8_t offset = 1;
|
||||
uint8_t xoffset = 4; //point to r value
|
||||
//copy r
|
||||
@@ -355,14 +355,14 @@ tokenDefinition_t* getKnownToken(uint8_t *contractAddress) {
|
||||
currentToken = (tokenDefinition_t *)PIC(&TOKENS_THUNDERCORE[i]);
|
||||
break
|
||||
}
|
||||
if (os_memcmp(currentToken->address, tmpContent.txContent.destination, 20) == 0) {
|
||||
if (memcmp(currentToken->address, tmpContent.txContent.destination, 20) == 0) {
|
||||
return currentToken;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for(size_t i=0; i<MAX_TOKEN; i++){
|
||||
currentToken = &tmpCtx.transactionContext.tokens[i];
|
||||
if (tmpCtx.transactionContext.tokenSet[i] && (os_memcmp(currentToken->address, contractAddress, 20) == 0)) {
|
||||
if (tmpCtx.transactionContext.tokenSet[i] && (memcmp(currentToken->address, contractAddress, 20) == 0)) {
|
||||
PRINTF("Token found at index %d\n", i);
|
||||
return currentToken;
|
||||
}
|
||||
@@ -390,6 +390,9 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
|
||||
case STARKWARE_INS_PROVIDE_QUANTUM:
|
||||
handleStarkwareProvideQuantum(G_io_apdu_buffer[OFFSET_P1], G_io_apdu_buffer[OFFSET_P2], G_io_apdu_buffer + OFFSET_CDATA, G_io_apdu_buffer[OFFSET_LC], flags, tx);
|
||||
break;
|
||||
case STARKWARE_INS_UNSAFE_SIGN:
|
||||
handleStarkwareUnsafeSign(G_io_apdu_buffer[OFFSET_P1], G_io_apdu_buffer[OFFSET_P2], G_io_apdu_buffer + OFFSET_CDATA, G_io_apdu_buffer[OFFSET_LC], flags, tx);
|
||||
break;
|
||||
default:
|
||||
THROW(0x6D00);
|
||||
break;
|
||||
@@ -406,7 +409,7 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
|
||||
|
||||
switch (G_io_apdu_buffer[OFFSET_INS]) {
|
||||
case INS_GET_PUBLIC_KEY:
|
||||
os_memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
handleGetPublicKey(G_io_apdu_buffer[OFFSET_P1], G_io_apdu_buffer[OFFSET_P2], G_io_apdu_buffer + OFFSET_CDATA, G_io_apdu_buffer[OFFSET_LC], flags, tx);
|
||||
break;
|
||||
|
||||
@@ -423,19 +426,19 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
|
||||
break;
|
||||
|
||||
case INS_SIGN_PERSONAL_MESSAGE:
|
||||
os_memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
handleSignPersonalMessage(G_io_apdu_buffer[OFFSET_P1], G_io_apdu_buffer[OFFSET_P2], G_io_apdu_buffer + OFFSET_CDATA, G_io_apdu_buffer[OFFSET_LC], flags, tx);
|
||||
break;
|
||||
|
||||
case INS_SIGN_EIP_712_MESSAGE:
|
||||
os_memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
handleSignEIP712Message(G_io_apdu_buffer[OFFSET_P1], G_io_apdu_buffer[OFFSET_P2], G_io_apdu_buffer + OFFSET_CDATA, G_io_apdu_buffer[OFFSET_LC], flags, tx);
|
||||
break;
|
||||
|
||||
#ifdef HAVE_ETH2
|
||||
|
||||
case INS_GET_ETH2_PUBLIC_KEY:
|
||||
os_memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
handleGetEth2PublicKey(G_io_apdu_buffer[OFFSET_P1], G_io_apdu_buffer[OFFSET_P2], G_io_apdu_buffer + OFFSET_CDATA, G_io_apdu_buffer[OFFSET_LC], flags, tx);
|
||||
break;
|
||||
|
||||
@@ -675,7 +678,7 @@ void coin_main_with_config(chain_config_t *config) {
|
||||
}
|
||||
|
||||
void init_coin_config(chain_config_t *coin_config) {
|
||||
os_memset(coin_config, 0, sizeof(chain_config_t));
|
||||
memset(coin_config, 0, sizeof(chain_config_t));
|
||||
strcpy(coin_config->coinName, CHAINID_COINNAME " ");
|
||||
coin_config->chainId = CHAIN_ID;
|
||||
coin_config->kind = CHAIN_KIND;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "poorstream.h"
|
||||
|
||||
void poorstream_init(poorstream_t *stream, uint8_t *buffer) {
|
||||
os_memset((void*)stream, 0, sizeof(poorstream_t));
|
||||
memset((void*)stream, 0, sizeof(poorstream_t));
|
||||
stream->pointer = buffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,21 @@ typedef struct internalStorage_t {
|
||||
uint8_t initialized;
|
||||
} internalStorage_t;
|
||||
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
typedef enum starkQuantumType_e {
|
||||
|
||||
STARK_QUANTUM_LEGACY = 0x00,
|
||||
STARK_QUANTUM_ETH,
|
||||
STARK_QUANTUM_ERC20,
|
||||
STARK_QUANTUM_ERC721,
|
||||
STARK_QUANTUM_MINTABLE_ERC20,
|
||||
STARK_QUANTUM_MINTABLE_ERC721
|
||||
|
||||
} starkQuantumType_e;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct tokenContext_t {
|
||||
char pluginName[PLUGIN_ID_LENGTH];
|
||||
uint8_t pluginAvailable;
|
||||
@@ -46,7 +61,9 @@ typedef struct tokenContext_t {
|
||||
|
||||
#ifdef HAVE_STARKWARE
|
||||
uint8_t quantum[32];
|
||||
uint8_t mintingBlob[32];
|
||||
uint8_t quantumIndex;
|
||||
uint8_t quantumType;
|
||||
#endif
|
||||
|
||||
} tokenContext_t;
|
||||
@@ -101,6 +118,11 @@ typedef struct starkContext_t {
|
||||
uint8_t w1[32];
|
||||
uint8_t w2[32];
|
||||
uint8_t w3[32];
|
||||
uint8_t w4[32];
|
||||
uint8_t conditional;
|
||||
uint8_t transferDestination[32];
|
||||
uint8_t fact[32];
|
||||
uint8_t conditionAddress[20];
|
||||
} starkContext_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,21 +9,21 @@ static unsigned char const C_cx_Stark256_n[] = {
|
||||
//n: 0x0800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xb7, 0x81, 0x12, 0x6d, 0xca, 0xe7, 0xb2, 0x32, 0x1e, 0x66, 0xa2, 0x41, 0xad, 0xc6, 0x4d, 0x2f};
|
||||
|
||||
|
||||
// C_cx_secp256k1_n - (C_cx_secp256k1_n % C_cx_Stark256_n)
|
||||
static unsigned char const STARK_DERIVE_BIAS[] = {
|
||||
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
|
||||
0x38, 0xa1, 0x3b, 0x4b, 0x92, 0x0e, 0x94, 0x11, 0xae, 0x6d, 0xa5, 0xf4, 0x0b, 0x03, 0x58, 0xb1
|
||||
};
|
||||
};
|
||||
|
||||
void starkDerivePrivateKey(uint32_t *bip32Path, uint32_t bip32PathLength, uint8_t *privateKeyData) {
|
||||
#if 0
|
||||
// Sanity check
|
||||
void starkDerivePrivateKey(uint32_t *bip32Path, uint32_t bip32PathLength, uint8_t *privateKeyData) {
|
||||
#if 0
|
||||
// Sanity check
|
||||
if (bip32Path[0] != STARK_BIP32_PATH_0) {
|
||||
PRINTF("Invalid Stark derivation path %d\n", bip32Path[0]);
|
||||
THROW(0x6a80);
|
||||
}
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path, bip32PathLength, privateKeyData, NULL);
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path, bip32PathLength, privateKeyData, NULL);
|
||||
PRINTF("Private key before processing %.*H\n", 32, privateKeyData);
|
||||
// TODO - support additional schemes
|
||||
cx_math_modm(privateKeyData, 32, C_cx_Stark256_n, 32);
|
||||
@@ -31,30 +31,32 @@ void starkDerivePrivateKey(uint32_t *bip32Path, uint32_t bip32PathLength, uint8_
|
||||
#else
|
||||
uint8_t tmp[33];
|
||||
uint8_t index = 0;
|
||||
// Sanity check
|
||||
// Sanity check
|
||||
if ((bip32PathLength < 2) || (bip32Path[0] != STARK_BIP32_PATH_0) || (bip32Path[1] != STARK_BIP32_PATH_1)) {
|
||||
PRINTF("Invalid Stark derivation path %d %d\n", bip32Path[0], bip32Path[1]);
|
||||
THROW(0x6a80);
|
||||
}
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path, bip32PathLength, tmp, NULL);
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path, bip32PathLength, tmp, NULL);
|
||||
PRINTF("Private key before processing %.*H\n", 32, tmp);
|
||||
for(;;) {
|
||||
tmp[32] = index;
|
||||
cx_hash_sha256(tmp, 33, privateKeyData, 32);
|
||||
PRINTF("Key hash %.*H\n", 32, privateKeyData);
|
||||
if (cx_math_cmp(privateKeyData, STARK_DERIVE_BIAS, 32) < 0) {
|
||||
cx_math_modm(privateKeyData, 32, C_cx_Stark256_n, 32);
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
PRINTF("Key result %.*H\n", 32, privateKeyData);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void stark_get_amount_string(uint8_t *contractAddress, uint8_t *quantum256, uint8_t *amount64, char *tmp100, char *target100) {
|
||||
uint256_t amountPre, quantum, amount;
|
||||
uint8_t decimals;
|
||||
char *ticker = (char*)PIC(chainConfig->coinName);
|
||||
uint8_t decimals;
|
||||
char *ticker = (char*)PIC(chainConfig->coinName);
|
||||
|
||||
PRINTF("stark_get_amount_string %.*H\n", 20, contractAddress);
|
||||
|
||||
|
||||
@@ -18,8 +18,4 @@ typedef unsigned char ECPoint[EC_POINT_SIZE];
|
||||
void pedersen(FieldElement res, /* out */
|
||||
FieldElement a, FieldElement b);
|
||||
|
||||
int stark_sign(uint8_t *signautre, /* out */
|
||||
uint8_t *privateKeyData, FieldElement token1,
|
||||
FieldElement token2, FieldElement msg);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
#include "stark_crypto.h"
|
||||
#include "shared_context.h"
|
||||
#include "ethUtils.h"
|
||||
|
||||
#include "os_io_seproxyhal.h"
|
||||
@@ -81,7 +82,7 @@ void pedersen(FieldElement res, /* out */
|
||||
ECPoint hash;
|
||||
|
||||
memcpy(hash, PEDERSEN_SHIFT, sizeof(hash));
|
||||
|
||||
|
||||
accum_ec_mul(&hash, a, 1, 1);
|
||||
accum_ec_mul(&hash, a+1, FIELD_ELEMENT_SIZE-1, 0);
|
||||
accum_ec_mul(&hash, b, 1, 3);
|
||||
@@ -94,15 +95,23 @@ int stark_sign(uint8_t *signature, /* out */
|
||||
uint8_t *privateKeyData,
|
||||
FieldElement token1,
|
||||
FieldElement token2,
|
||||
FieldElement msg) {
|
||||
FieldElement msg,
|
||||
FieldElement condition) {
|
||||
unsigned int info = 0;
|
||||
FieldElement hash;
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
PRINTF("Stark sign msg w1 %.*H\n", 32, token1);
|
||||
PRINTF("Stark sign msg w2 %.*H\n", 32, token2);
|
||||
PRINTF("Stark sign w3 %.*H\n", 32, msg);
|
||||
if (condition != NULL) {
|
||||
PRINTF("Stark sign w4 %.*H\n", 32, condition);
|
||||
}
|
||||
pedersen(hash, token1, token2);
|
||||
PRINTF("Pedersen hash 1 %.*H\n", 32, hash);
|
||||
if (condition != NULL) {
|
||||
pedersen(hash, hash, condition);
|
||||
PRINTF("Pedersen hash condition %.*H\n", 32, hash);
|
||||
}
|
||||
pedersen(hash, hash, msg);
|
||||
PRINTF("Pedersen hash 2 %.*H\n", 32, hash);
|
||||
cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
|
||||
@@ -114,27 +123,90 @@ int stark_sign(uint8_t *signature, /* out */
|
||||
}
|
||||
|
||||
// ERC20Token(address)
|
||||
static const uint8_t ERC20_SELECTOR[] = { 0xf4, 0x72, 0x61, 0xb0 };
|
||||
static const uint8_t ERC20_SELECTOR[] = { 0xf4, 0x72, 0x61, 0xb0 };
|
||||
// ETH()
|
||||
static const uint8_t ETH_SELECTOR[] = { 0x83, 0x22, 0xff, 0xf2 };
|
||||
// ERC721Token(address, uint256)
|
||||
static const uint8_t ERC721_SELECTOR[] = { 0x02, 0x57, 0x17, 0x92 };
|
||||
// MintableERC20Token(address)
|
||||
static const uint8_t MINTABLE_ERC20_SELECTOR[] = { 0x68, 0x64, 0x6e, 0x2d };
|
||||
// MintableERC721Token(address,uint256)
|
||||
static const uint8_t MINTABLE_ERC721_SELECTOR[] = { 0xb8, 0xb8, 0x66, 0x72 };
|
||||
static const char NFT_ASSET_ID_PREFIX[] = { 'N', 'F', 'T', ':', 0 };
|
||||
static const char MINTABLE_ASSET_ID_PREFIX[] = { 'M', 'I', 'N', 'T', 'A', 'B', 'L', 'E', ':', 0 };
|
||||
|
||||
void compute_token_id(cx_sha3_t *sha3, uint8_t *contractAddress, uint8_t *quantum, uint8_t *output) {
|
||||
void compute_token_id(cx_sha3_t *sha3, uint8_t *contractAddress, uint8_t quantumType, uint8_t *quantum, uint8_t *mintingBlob, bool assetTypeOnly, uint8_t *output) {
|
||||
uint8_t tmp[36];
|
||||
cx_keccak_init(sha3, 256);
|
||||
if ((contractAddress != NULL) && (!allzeroes(contractAddress, 20))) {
|
||||
const uint8_t *selector = NULL;
|
||||
switch(quantumType) {
|
||||
case STARK_QUANTUM_ERC20:
|
||||
case STARK_QUANTUM_LEGACY:
|
||||
selector = ERC20_SELECTOR;
|
||||
break;
|
||||
case STARK_QUANTUM_ERC721:
|
||||
selector = ERC721_SELECTOR;
|
||||
break;
|
||||
case STARK_QUANTUM_MINTABLE_ERC20:
|
||||
selector = MINTABLE_ERC20_SELECTOR;
|
||||
break;
|
||||
case STARK_QUANTUM_MINTABLE_ERC721:
|
||||
selector = MINTABLE_ERC721_SELECTOR;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unsupported quantum type %d\n", quantumType);
|
||||
return;
|
||||
}
|
||||
PRINTF("compute_token_id for %.*H\n", 20, contractAddress);
|
||||
os_memset(tmp, 0, sizeof(tmp));
|
||||
os_memmove(tmp, ERC20_SELECTOR, 4);
|
||||
os_memmove(tmp + 16, contractAddress, 20);
|
||||
cx_hash((cx_hash_t*)sha3, 0, tmp, sizeof(tmp), NULL, 0);
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
memmove(tmp, selector, 4);
|
||||
memmove(tmp + 16, contractAddress, 20);
|
||||
cx_hash((cx_hash_t*)sha3, 0, tmp, sizeof(tmp), NULL, 0);
|
||||
}
|
||||
else {
|
||||
PRINTF("compute_token_id for ETH\n");
|
||||
cx_hash((cx_hash_t*)sha3, 0, ETH_SELECTOR, sizeof(ETH_SELECTOR), NULL, 0);
|
||||
cx_hash((cx_hash_t*)sha3, 0, ETH_SELECTOR, sizeof(ETH_SELECTOR), NULL, 0);
|
||||
}
|
||||
if ((quantumType == STARK_QUANTUM_ERC721) || (quantumType == STARK_QUANTUM_MINTABLE_ERC721)) {
|
||||
memset(tmp, 0, 32);
|
||||
tmp[31] = 1;
|
||||
PRINTF("compute_token_id quantum %.*H\n", 32, tmp);
|
||||
cx_hash((cx_hash_t*)sha3, CX_LAST, tmp, 32, output, 32);
|
||||
}
|
||||
else {
|
||||
PRINTF("compute_token_id quantum %.*H\n", 32, quantum);
|
||||
cx_hash((cx_hash_t*)sha3, CX_LAST, quantum, 32, output, 32);
|
||||
}
|
||||
if (!assetTypeOnly && ((quantumType != STARK_QUANTUM_LEGACY) &&
|
||||
(quantumType != STARK_QUANTUM_ETH) &&
|
||||
(quantumType != STARK_QUANTUM_ERC20))) {
|
||||
const char *prefix = NULL;
|
||||
output[0] &= 0x03;
|
||||
cx_keccak_init(sha3, 256);
|
||||
switch(quantumType) {
|
||||
case STARK_QUANTUM_ERC721:
|
||||
prefix = NFT_ASSET_ID_PREFIX;
|
||||
break;
|
||||
case STARK_QUANTUM_MINTABLE_ERC20:
|
||||
case STARK_QUANTUM_MINTABLE_ERC721:
|
||||
prefix = MINTABLE_ASSET_ID_PREFIX;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unsupported non default quantum type %d\n", quantumType);
|
||||
return;
|
||||
}
|
||||
cx_hash((cx_hash_t*)sha3, 0, (const uint8_t*)prefix, strlen(prefix), NULL, 0);
|
||||
cx_hash((cx_hash_t*)sha3, 0, output, 32, NULL, 0);
|
||||
cx_hash((cx_hash_t*)sha3, CX_LAST, mintingBlob, 32, output, 32);
|
||||
}
|
||||
if (!assetTypeOnly && ((quantumType == STARK_QUANTUM_MINTABLE_ERC20) || (quantumType == STARK_QUANTUM_MINTABLE_ERC721))) {
|
||||
output[0] = 0x04;
|
||||
output[1] = 0x00;
|
||||
}
|
||||
else {
|
||||
output[0] &= 0x03;
|
||||
}
|
||||
PRINTF("compute_token_id quantum %.*H\n", 32, quantum);
|
||||
cx_hash((cx_hash_t*)sha3, CX_LAST, quantum, 32, output, 32);
|
||||
output[0] &= 0x03;
|
||||
PRINTF("compute_token_id computed token %.*H\n", 32, output);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "cx.h"
|
||||
#include "stark_crypto.h"
|
||||
|
||||
void compute_token_id(cx_sha3_t *sha3, uint8_t *contractAddress, uint8_t *quantum, uint8_t *output);
|
||||
void compute_token_id(cx_sha3_t *sha3, uint8_t *contractAddress, uint8_t quantumType, uint8_t *quantum, uint8_t *mintingBlob, bool assetTypeOnly, uint8_t *output);
|
||||
|
||||
void starkDerivePrivateKey(uint32_t *bip32Path, uint32_t bip32PathLength, uint8_t *privateKeyData);
|
||||
|
||||
@@ -19,7 +19,8 @@ int stark_sign(uint8_t *signature, /* out */
|
||||
uint8_t *privateKeyData,
|
||||
FieldElement token1,
|
||||
FieldElement token2,
|
||||
FieldElement msg);
|
||||
FieldElement msg,
|
||||
FieldElement condition);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
const tokenDefinition_t const TOKENS_EXTRA[NUM_TOKENS_EXTRA] = {
|
||||
|
||||
{{0x4c,0x5f,0x66,0x59,0x61,0x97,0xa8,0x6f,0xb3,0x0a,0x24,0x35,0xe2,0xef,0x4d,0xdc,0xb3,0x93,0x42,0xc9}, "tUSDT ", 6},
|
||||
{{0x1c,0x0f,0x17,0x43,0x67,0x40,0xbf,0xb9,0x2c,0x10,0x70,0xee,0x86,0x32,0x2d,0xe8,0x90,0x83,0x7c,0x6a}, "tUSDT ", 6},
|
||||
{{0xcd,0x07,0x7a,0xbe,0xdd,0x83,0x1a,0x34,0x43,0xff,0xbe,0x24,0xfb,0x76,0x66,0x1b,0xbb,0x17,0xeb,0x69}, "tZRX ", 18},
|
||||
{{0x40,0xd8,0x97,0x85,0x00,0xbf,0x68,0x32,0x4a,0x51,0x53,0x3c,0xd6,0xa2,0x1e,0x3e,0x59,0xbe,0x32,0x4a}, "tBTC ", 18},
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ typedef struct tokenDefinition_t {
|
||||
|
||||
#ifdef HAVE_TOKENS_EXTRA_LIST
|
||||
|
||||
#define NUM_TOKENS_EXTRA 3
|
||||
#define NUM_TOKENS_EXTRA 4
|
||||
|
||||
extern tokenDefinition_t const TOKENS_EXTRA[NUM_TOKENS_EXTRA];
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@ extern const ux_flow_step_t * const ux_stark_transfer_flow [];
|
||||
|
||||
extern const ux_flow_step_t * const ux_stark_self_transfer_flow [];
|
||||
|
||||
extern const ux_flow_step_t * const ux_stark_transfer_conditional_flow [];
|
||||
|
||||
extern const ux_flow_step_t * const ux_stark_self_transfer_conditional_flow [];
|
||||
|
||||
extern const ux_flow_step_t * const ux_approval_starkware_register_flow [];
|
||||
|
||||
extern const ux_flow_step_t * const ux_approval_starkware_deposit_flow [];
|
||||
@@ -46,5 +50,7 @@ extern const ux_flow_step_t * const ux_approval_starkware_escape_flow [];
|
||||
|
||||
extern const ux_flow_step_t * const ux_approval_starkware_verify_escape_flow [];
|
||||
|
||||
extern const ux_flow_step_t * const ux_stark_unsafe_sign_flow [];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ void array_hexstr(char *strbuf, const void *bin, unsigned int len) {
|
||||
|
||||
void convertUint256BE(uint8_t *data, uint32_t length, uint256_t *target) {
|
||||
uint8_t tmp[32];
|
||||
os_memset(tmp, 0, 32);
|
||||
os_memmove(tmp + 32 - length, data, length);
|
||||
memset(tmp, 0, 32);
|
||||
memmove(tmp + 32 - length, data, length);
|
||||
readu256BE(tmp, target);
|
||||
}
|
||||
|
||||
@@ -113,4 +113,4 @@ bool parse_swap_config(uint8_t* config, uint8_t config_len, char* ticker, uint8_
|
||||
}
|
||||
*decimals = config[offset];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
void initTx(txContext_t *context, cx_sha3_t *sha3, txContent_t *content,
|
||||
ustreamProcess_t customProcessor, void *extra) {
|
||||
os_memset(context, 0, sizeof(txContext_t));
|
||||
memset(context, 0, sizeof(txContext_t));
|
||||
context->sha3 = sha3;
|
||||
context->content = content;
|
||||
context->customProcessor = customProcessor;
|
||||
@@ -59,7 +59,7 @@ void copyTxData(txContext_t *context, uint8_t *out, uint32_t length) {
|
||||
THROW(EXCEPTION);
|
||||
}
|
||||
if (out != NULL) {
|
||||
os_memmove(out, context->workBuffer, length);
|
||||
memmove(out, context->workBuffer, length);
|
||||
}
|
||||
if (!(context->processingField && context->fieldSingleByte)) {
|
||||
cx_hash((cx_hash_t*)context->sha3, 0, context->workBuffer, length, NULL, 0);
|
||||
|
||||
@@ -123,7 +123,7 @@ void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out,
|
||||
uint8_t hashAddress[32];
|
||||
cx_keccak_init(sha3Context, 256);
|
||||
cx_hash((cx_hash_t*)sha3Context, CX_LAST, publicKey->W + 1, 64, hashAddress, 32);
|
||||
os_memmove(out, hashAddress + 12, 20);
|
||||
memmove(out, hashAddress + 12, 20);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@ void read_u64_be(uint8_t *in, uint64_t *out) {
|
||||
|
||||
void mul256(uint256_t *number1, uint256_t *number2, uint256_t *target) {
|
||||
uint8_t num1[32], num2[32], result[64];
|
||||
os_memset(&result, 0, sizeof(result));
|
||||
memset(&result, 0, sizeof(result));
|
||||
for(uint8_t i = 0; i<4; i++){
|
||||
write_u64_be(num1+i*sizeof(uint64_t), number1->elements[i/2].elements[i%2]);
|
||||
write_u64_be(num2+i*sizeof(uint64_t), number2->elements[i/2].elements[i%2]);
|
||||
|
||||
@@ -15,6 +15,7 @@ void handleGetAppConfiguration(uint8_t p1, uint8_t p2, uint8_t *workBuffer, uint
|
||||
#endif
|
||||
#ifdef HAVE_STARKWARE
|
||||
G_io_apdu_buffer[0] |= APP_FLAG_STARKWARE;
|
||||
G_io_apdu_buffer[0] |= APP_FLAG_STARKWARE_V2;
|
||||
#endif
|
||||
G_io_apdu_buffer[1] = LEDGER_MAJOR_VERSION;
|
||||
G_io_apdu_buffer[2] = LEDGER_MINOR_VERSION;
|
||||
|
||||
@@ -22,8 +22,8 @@ void getEth2PublicKey(uint32_t *bip32Path, uint8_t bip32PathLength, uint8_t *out
|
||||
memmove(tmp + 16, privateKeyData, 32);
|
||||
cx_ecfp_init_private_key(CX_CURVE_BLS12_381_G1, tmp, 48, &privateKey);
|
||||
cx_ecfp_generate_pair(CX_CURVE_BLS12_381_G1, &publicKey, &privateKey, 1);
|
||||
memset(tmp, 0, 96);
|
||||
memset((void*)&privateKey, 0, sizeof(cx_ecfp_256_extended_private_key_t));
|
||||
explicit_bzero(tmp, 96);
|
||||
explicit_bzero((void*)&privateKey, sizeof(cx_ecfp_256_extended_private_key_t));
|
||||
tmp[47] = 2;
|
||||
cx_math_mult(tmp, publicKey.W + 1 + 48, tmp, 48);
|
||||
if (cx_math_cmp(tmp + 48, BLS12_381_FIELD_MODULUS, 48) > 0) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
uint32_t set_result_get_eth2_publicKey() {
|
||||
uint32_t tx = 0;
|
||||
os_memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.publicKey.W, 48);
|
||||
memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.publicKey.W, 48);
|
||||
tx += 48;
|
||||
return tx;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ void handleGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t da
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_generate_pair(CX_CURVE_256K1, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1);
|
||||
os_memset(&privateKey, 0, sizeof(privateKey));
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
io_seproxyhal_io_heartbeat();
|
||||
getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, tmpCtx.publicKeyContext.address, &global_sha3, chainConfig);
|
||||
#ifndef NO_CONSENT
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
uint32_t set_result_get_publicKey() {
|
||||
uint32_t tx = 0;
|
||||
G_io_apdu_buffer[tx++] = 65;
|
||||
os_memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.publicKey.W, 65);
|
||||
memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.publicKey.W, 65);
|
||||
tx += 65;
|
||||
G_io_apdu_buffer[tx++] = 40;
|
||||
os_memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.address, 40);
|
||||
memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.address, 40);
|
||||
tx += 40;
|
||||
if (tmpCtx.publicKeyContext.getChaincode) {
|
||||
os_memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.chainCode, 32);
|
||||
memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.chainCode, 32);
|
||||
tx += 32;
|
||||
}
|
||||
return tx;
|
||||
|
||||
@@ -47,7 +47,7 @@ void handleProvideErc20TokenInformation(uint8_t p1, uint8_t p2, uint8_t *workBuf
|
||||
THROW(0x6A80);
|
||||
}
|
||||
cx_hash((cx_hash_t*)&sha256, 0, workBuffer + offset, tickerLength, NULL, 0);
|
||||
os_memmove(token->ticker, workBuffer + offset, tickerLength);
|
||||
memmove(token->ticker, workBuffer + offset, tickerLength);
|
||||
token->ticker[tickerLength] = ' ';
|
||||
token->ticker[tickerLength + 1] = '\0';
|
||||
offset += tickerLength;
|
||||
@@ -59,12 +59,12 @@ void handleProvideErc20TokenInformation(uint8_t p1, uint8_t p2, uint8_t *workBuf
|
||||
THROW(0x6A80);
|
||||
}
|
||||
cx_hash((cx_hash_t*)&sha256, CX_LAST, workBuffer + offset, contractNameLength + 20 + 4 + 4, hash, 32);
|
||||
os_memmove(token->contractName, workBuffer + offset, MIN(contractNameLength, sizeof(token->contractName)-1));
|
||||
memmove(token->contractName, workBuffer + offset, MIN(contractNameLength, sizeof(token->contractName)-1));
|
||||
token->contractName[MIN(contractNameLength, sizeof(token->contractName)-1)] = '\0';
|
||||
offset += contractNameLength;
|
||||
dataLength -= contractNameLength;
|
||||
|
||||
os_memmove(token->address, workBuffer + offset, 20);
|
||||
memmove(token->address, workBuffer + offset, 20);
|
||||
offset += 20;
|
||||
dataLength -= 20;
|
||||
token->decimals = U4BE(workBuffer, offset);
|
||||
@@ -116,12 +116,12 @@ void handleProvideErc20TokenInformation(uint8_t p1, uint8_t p2, uint8_t *workBuf
|
||||
THROW(0x6A80);
|
||||
}
|
||||
cx_hash_sha256(workBuffer + offset, tickerLength + 20 + 4 + 4, hash, 32);
|
||||
os_memmove(token->ticker, workBuffer + offset, tickerLength);
|
||||
memmove(token->ticker, workBuffer + offset, tickerLength);
|
||||
token->ticker[tickerLength] = ' ';
|
||||
token->ticker[tickerLength + 1] = '\0';
|
||||
offset += tickerLength;
|
||||
dataLength -= tickerLength;
|
||||
os_memmove(token->address, workBuffer + offset, 20);
|
||||
memmove(token->address, workBuffer + offset, 20);
|
||||
offset += 20;
|
||||
dataLength -= 20;
|
||||
token->decimals = U4BE(workBuffer, offset);
|
||||
@@ -140,7 +140,7 @@ void handleProvideErc20TokenInformation(uint8_t p1, uint8_t p2, uint8_t *workBuf
|
||||
uint32_t index;
|
||||
for (index=0; index < NUM_TOKENS_EXTRA; index++) {
|
||||
currentToken = (tokenDefinition_t *)PIC(&TOKENS_EXTRA[index]);
|
||||
if (os_memcmp(currentToken->address, token->address, 20) == 0) {
|
||||
if (memcmp(currentToken->address, token->address, 20) == 0) {
|
||||
strcpy((char*)token->ticker, (char*)currentToken->ticker);
|
||||
token->decimals = currentToken->decimals;
|
||||
break;
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
|
||||
void handleSetEth2WithdrawalIndex(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx) {
|
||||
UNUSED(dataLength);
|
||||
|
||||
if (dataLength != 4) {
|
||||
THROW(0x6700);
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@ unsigned int io_seproxyhal_touch_signMessage_ok(const bagl_element_t *e) {
|
||||
tmpCtx.messageSigningContext.pathLength, privateKeyData, NULL);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
unsigned int info = 0;
|
||||
io_seproxyhal_io_heartbeat();
|
||||
signatureLength =
|
||||
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
|
||||
tmpCtx.messageSigningContext.hash,
|
||||
sizeof(tmpCtx.messageSigningContext.hash), signature, sizeof(signature), &info);
|
||||
os_memset(&privateKey, 0, sizeof(privateKey));
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
G_io_apdu_buffer[0] = 27;
|
||||
if (info & CX_ECCINFO_PARITY_ODD) {
|
||||
G_io_apdu_buffer[0]++;
|
||||
|
||||
@@ -24,14 +24,14 @@ unsigned int io_seproxyhal_touch_signMessage712_v0_ok(const bagl_element_t *e) {
|
||||
tmpCtx.messageSigningContext712.pathLength, privateKeyData, NULL);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
unsigned int info = 0;
|
||||
io_seproxyhal_io_heartbeat();
|
||||
signatureLength =
|
||||
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
|
||||
hash,
|
||||
sizeof(hash), signature, sizeof(signature), &info);
|
||||
os_memset(&privateKey, 0, sizeof(privateKey));
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
G_io_apdu_buffer[0] = 27;
|
||||
if (info & CX_ECCINFO_PARITY_ODD) {
|
||||
G_io_apdu_buffer[0]++;
|
||||
|
||||
@@ -158,7 +158,7 @@ void compareOrCopy(char* preapproved_string, char* parsed_string, bool silent_mo
|
||||
have some for checksum purpose, so let's get rid of these diffs */
|
||||
to_uppercase(preapproved_string, strlen(preapproved_string));
|
||||
to_uppercase(parsed_string, strlen(parsed_string));
|
||||
if(os_memcmp(preapproved_string, parsed_string, strlen(preapproved_string))){
|
||||
if(memcmp(preapproved_string, parsed_string, strlen(preapproved_string))){
|
||||
THROW(ERR_SILENT_MODE_CHECK_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,14 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
|
||||
privateKeyData, NULL);
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32,
|
||||
&privateKey);
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
unsigned int info = 0;
|
||||
io_seproxyhal_io_heartbeat();
|
||||
signatureLength =
|
||||
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
|
||||
tmpCtx.transactionContext.hash,
|
||||
sizeof(tmpCtx.transactionContext.hash), signature, sizeof(signature), &info);
|
||||
os_memset(&privateKey, 0, sizeof(privateKey));
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
// Parity is present in the sequence tag in the legacy API
|
||||
if (tmpContent.txContent.vLength == 0) {
|
||||
// Legacy API
|
||||
|
||||
@@ -34,8 +34,8 @@ void handleStarkwareGetPublicKey(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, ui
|
||||
cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_generate_pair(CX_CURVE_Stark256, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1);
|
||||
os_memset(&privateKey, 0, sizeof(privateKey));
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
io_seproxyhal_io_heartbeat();
|
||||
#ifndef NO_CONSENT
|
||||
if (p1 == P1_NON_CONFIRM)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
uint32_t set_result_get_stark_publicKey() {
|
||||
uint32_t tx = 0;
|
||||
os_memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.publicKey.W, 65);
|
||||
memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.publicKey.W, 65);
|
||||
tx += 65;
|
||||
return tx;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,35 @@
|
||||
|
||||
void handleStarkwareProvideQuantum(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx) {
|
||||
size_t i = 0;
|
||||
uint8_t expectedDataSize = 20 + 32;
|
||||
uint8_t addressZero = 0;
|
||||
tokenDefinition_t *currentToken = NULL;
|
||||
if (appState != APP_STATE_IDLE) {
|
||||
reset_app_context();
|
||||
}
|
||||
if (dataLength != 20 + 32) {
|
||||
switch(p1) {
|
||||
case STARK_QUANTUM_LEGACY:
|
||||
break;
|
||||
case STARK_QUANTUM_ETH:
|
||||
case STARK_QUANTUM_ERC20:
|
||||
case STARK_QUANTUM_ERC721:
|
||||
case STARK_QUANTUM_MINTABLE_ERC20:
|
||||
case STARK_QUANTUM_MINTABLE_ERC721:
|
||||
expectedDataSize += 32;
|
||||
break;
|
||||
default:
|
||||
THROW(0x6B00);
|
||||
}
|
||||
if (dataLength != expectedDataSize) {
|
||||
THROW(0x6700);
|
||||
}
|
||||
if (!allzeroes(dataBuffer, 20)) {
|
||||
if (p1 == STARK_QUANTUM_LEGACY) {
|
||||
addressZero = allzeroes(dataBuffer, 20);
|
||||
}
|
||||
if ((p1 != STARK_QUANTUM_ETH) && !addressZero) {
|
||||
for(i=0; i<MAX_TOKEN; i++){
|
||||
currentToken = &tmpCtx.transactionContext.tokens[i];
|
||||
if (tmpCtx.transactionContext.tokenSet[i] && (os_memcmp(currentToken->address, dataBuffer, 20) == 0)) {
|
||||
if (tmpCtx.transactionContext.tokenSet[i] && (memcmp(currentToken->address, dataBuffer, 20) == 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -28,8 +46,12 @@ void handleStarkwareProvideQuantum(uint8_t p1, uint8_t p2, uint8_t *dataBuffer,
|
||||
else {
|
||||
i = MAX_TOKEN;
|
||||
}
|
||||
os_memmove(dataContext.tokenContext.quantum, dataBuffer + 20, 32);
|
||||
memmove(dataContext.tokenContext.quantum, dataBuffer + 20, 32);
|
||||
if (p1 != STARK_QUANTUM_LEGACY) {
|
||||
memmove(dataContext.tokenContext.mintingBlob, dataBuffer + 20 + 32, 32);
|
||||
}
|
||||
dataContext.tokenContext.quantumIndex = i;
|
||||
dataContext.tokenContext.quantumType = p1;
|
||||
quantumSet = true;
|
||||
THROW(0x9000);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
poorstream_t bitstream;
|
||||
bool selfTransfer = false;
|
||||
uint8_t order = 1;
|
||||
uint8_t protocol = 2;
|
||||
uint8_t preOffset, postOffset;
|
||||
uint8_t zeroTest;
|
||||
// Initial checks
|
||||
if (appState != APP_STATE_IDLE) {
|
||||
reset_app_context();
|
||||
@@ -29,18 +33,35 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
|
||||
}
|
||||
switch(p1) {
|
||||
case P1_STARK_ORDER:
|
||||
if (dataLength != (20 + 32 + 20 + 32 + 4 + 4 + 8 + 8 + 4 + 4 + 1 + 4 * bip32PathLength)) {
|
||||
THROW(0x6700);
|
||||
}
|
||||
protocol = 1;
|
||||
break;
|
||||
case P1_STARK_TRANSFER:
|
||||
if (dataLength != (20 + 32 + 32 + 4 + 4 + 8 + 4 + 4 + 1 + 4 * bip32PathLength)) {
|
||||
THROW(0x6700);
|
||||
}
|
||||
protocol = 1;
|
||||
order = 0;
|
||||
break;
|
||||
case P1_STARK_ORDER_V2:
|
||||
break;
|
||||
case P1_STARK_TRANSFER_V2:
|
||||
case P1_STARK_CONDITIONAL_TRANSFER:
|
||||
order = 0;
|
||||
break;
|
||||
default:
|
||||
THROW(0x6B00);
|
||||
}
|
||||
postOffset = (protocol == 2 ? 1 + 32 : 0);
|
||||
preOffset = (protocol == 2 ? 1 : 0);
|
||||
if (order) {
|
||||
if (dataLength != (20 + 32 + 20 + 32 + 4 + 4 + 8 + 8 + 4 + 4 + 1 + 4 * bip32PathLength +
|
||||
2 * postOffset)) {
|
||||
THROW(0x6700);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (dataLength != (20 + 32 + 32 + 4 + 4 + 8 + 4 + 4 + 1 + 4 * bip32PathLength +
|
||||
postOffset + (p1 == P1_STARK_CONDITIONAL_TRANSFER ? 32 + 20 : 0))) {
|
||||
THROW(0x6700);
|
||||
}
|
||||
}
|
||||
if (p2 != 0) {
|
||||
THROW(0x6B00);
|
||||
}
|
||||
@@ -51,35 +72,63 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
|
||||
offset += 4;
|
||||
}
|
||||
// Discard the path to use part of dataBuffer as a temporary buffer
|
||||
os_memmove(dataBuffer, dataBuffer + offset, dataLength - offset);
|
||||
// Fail immediately if the contract is unknown
|
||||
if (!allzeroes(dataBuffer, 20) && getKnownToken(dataBuffer) == NULL) {
|
||||
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer);
|
||||
memmove(dataBuffer, dataBuffer + offset, dataLength - offset);
|
||||
dataContext.starkContext.conditional = (p1 == P1_STARK_CONDITIONAL_TRANSFER);
|
||||
if (dataContext.starkContext.conditional) {
|
||||
memmove(dataContext.starkContext.fact, dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4 + 8 + 4 + 4, 32);
|
||||
memmove(dataContext.starkContext.conditionAddress, dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4 + 8 + 4 + 4 + 32, 20);
|
||||
PRINTF("Fact %.*H\n", 32, dataContext.starkContext.fact);
|
||||
PRINTF("Address %.*H\n", 20, dataContext.starkContext.conditionAddress);
|
||||
}
|
||||
|
||||
zeroTest = allzeroes(dataBuffer + preOffset, 20);
|
||||
if (zeroTest && (protocol == 2) && (dataBuffer[0] != STARK_QUANTUM_ETH)) {
|
||||
PRINTF("stark - unexpected quantum descriptor type for null first address %d\n", dataBuffer[0]);
|
||||
THROW(0x6A80);
|
||||
}
|
||||
if (!zeroTest && getKnownToken(dataBuffer + preOffset) == NULL) {
|
||||
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer + preOffset);
|
||||
THROW(0x6A80);
|
||||
}
|
||||
if ((p1 == P1_STARK_ORDER) && (!allzeroes(dataBuffer + 20 + 32, 20) && getKnownToken(dataBuffer + 20 + 32) == NULL)) {
|
||||
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer + 20 + 32);
|
||||
if (order) {
|
||||
zeroTest = allzeroes(dataBuffer + 20 + 32 + postOffset + preOffset, 20);
|
||||
if (zeroTest && (protocol == 2) && (dataBuffer[1 + 20 + 32 + 32] != STARK_QUANTUM_ETH)) {
|
||||
PRINTF("stark - unexpected quantum descriptor type for null second address %d\n", dataBuffer[1 + 20 + 32 + 32]);
|
||||
THROW(0x6A80);
|
||||
}
|
||||
if (!zeroTest && getKnownToken(dataBuffer + 20 + 32 + postOffset + preOffset) == NULL) {
|
||||
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer + 20 + 32 + postOffset + preOffset);
|
||||
THROW(0x6A80);
|
||||
}
|
||||
}
|
||||
// Prepare the Stark parameters
|
||||
io_seproxyhal_io_heartbeat();
|
||||
compute_token_id(&global_sha3, dataBuffer, dataBuffer + 20, dataContext.starkContext.w1);
|
||||
if (p1 == P1_STARK_ORDER) {
|
||||
io_seproxyhal_io_heartbeat();
|
||||
compute_token_id(&global_sha3, dataBuffer + preOffset,
|
||||
(protocol == 2 ? dataBuffer[0] : STARK_QUANTUM_LEGACY),
|
||||
dataBuffer + preOffset + 20,
|
||||
(protocol == 2 ? dataBuffer + 1 + 20 + 32 : NULL), false, dataContext.starkContext.w1);
|
||||
if (order) {
|
||||
io_seproxyhal_io_heartbeat();
|
||||
compute_token_id(&global_sha3, dataBuffer + 20 + 32, dataBuffer + 20 + 32 + 20, dataContext.starkContext.w2);
|
||||
offset = 20 + 32 + 20 + 32;
|
||||
compute_token_id(&global_sha3, dataBuffer + 20 + 32 + postOffset + preOffset,
|
||||
(protocol == 2 ? dataBuffer[1 + 20 + 32 + 32] : STARK_QUANTUM_LEGACY),
|
||||
dataBuffer + 20 + 32 + postOffset + preOffset + 20,
|
||||
(protocol == 2 ? dataBuffer + 1 + 20 + 32 + 32 + 1 + 20 + 32 : NULL), false, dataContext.starkContext.w2);
|
||||
offset = 20 + 32 + postOffset + 20 + 32 + postOffset;
|
||||
}
|
||||
else {
|
||||
os_memmove(dataContext.starkContext.w2, dataBuffer + 20 + 32, 32);
|
||||
offset = 20 + 32 + 32;
|
||||
else {
|
||||
memmove(dataContext.starkContext.w2, dataBuffer + 20 + 32 + postOffset, 32);
|
||||
offset = 20 + 32 + postOffset + 32;
|
||||
}
|
||||
|
||||
poorstream_init(&bitstream, dataContext.starkContext.w3);
|
||||
poorstream_write_bits(&bitstream, 0, 11); // padding
|
||||
poorstream_write_bits(&bitstream, (p1 == P1_STARK_ORDER ? STARK_ORDER_TYPE : STARK_TRANSFER_TYPE), 4);
|
||||
poorstream_write_bits(&bitstream,
|
||||
(p1 == P1_STARK_CONDITIONAL_TRANSFER ? STARK_CONDITIONAL_TRANSFER_TYPE :
|
||||
order ? STARK_ORDER_TYPE : STARK_TRANSFER_TYPE), 4);
|
||||
poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset), 31);
|
||||
poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset + 4), 31);
|
||||
poorstream_write_bits(&bitstream, U8BE(dataBuffer, offset + 4 + 4), 63);
|
||||
if (p1 == P1_STARK_ORDER) {
|
||||
if (order) {
|
||||
poorstream_write_bits(&bitstream, U8BE(dataBuffer, offset + 4 + 4 + 8), 63);
|
||||
offset += 4 + 4 + 8 + 8;
|
||||
}
|
||||
@@ -93,16 +142,31 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
|
||||
PRINTF("stark w1 %.*H\n", 32, dataContext.starkContext.w1);
|
||||
PRINTF("stark w2 %.*H\n", 32, dataContext.starkContext.w2);
|
||||
PRINTF("stark w3 %.*H\n", 32, dataContext.starkContext.w3);
|
||||
|
||||
if (dataContext.starkContext.conditional) {
|
||||
cx_keccak_init(&global_sha3, 256);
|
||||
cx_hash((cx_hash_t*)&global_sha3, 0, dataContext.starkContext.conditionAddress, 20, NULL, 0);
|
||||
cx_hash((cx_hash_t*)&global_sha3, CX_LAST, dataContext.starkContext.fact, 32, dataContext.starkContext.w4, 32);
|
||||
dataContext.starkContext.w4[0] &= 0x03;
|
||||
PRINTF("stark w4 %.*H\n", 32, dataContext.starkContext.w4);
|
||||
}
|
||||
// Prepare the UI
|
||||
if (p1 == P1_STARK_ORDER) {
|
||||
if (order) {
|
||||
io_seproxyhal_io_heartbeat();
|
||||
// amount to sell
|
||||
stark_get_amount_string(dataBuffer, dataBuffer + 20, dataBuffer + 20 + 32 + 20 + 32 + 4 + 4, (char*)(dataBuffer + TMP_OFFSET), strings.common.fullAmount);
|
||||
stark_get_amount_string(dataBuffer + preOffset,
|
||||
dataBuffer + preOffset + 20,
|
||||
dataBuffer + 20 + 32 + postOffset + 20 + 32 + postOffset + 4 + 4,
|
||||
(char*)(dataBuffer + TMP_OFFSET), strings.common.fullAmount);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
// amount to buy
|
||||
stark_get_amount_string(dataBuffer + 20 + 32, dataBuffer + 20 + 32 + 20, dataBuffer + 20 + 32 + 20 + 32 + 4 + 4 + 8, (char*)(dataBuffer + TMP_OFFSET), strings.common.maxFee);
|
||||
stark_get_amount_string(dataBuffer + 20 + 32 + postOffset + preOffset,
|
||||
dataBuffer + 20 + 32 + postOffset + preOffset + 20,
|
||||
dataBuffer + 20 + 32 + postOffset + 20 + 32 + postOffset + 4 + 4 + 8,
|
||||
(char*)(dataBuffer + TMP_OFFSET), strings.common.maxFee);
|
||||
// src vault ID
|
||||
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "%d", U4BE(dataBuffer, 20 + 32 + 20 + 32));
|
||||
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "%d",
|
||||
U4BE(dataBuffer, 20 + 32 + postOffset + 20 + 32 + postOffset));
|
||||
}
|
||||
else {
|
||||
cx_ecfp_public_key_t publicKey;
|
||||
@@ -112,22 +176,37 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
|
||||
cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_generate_pair(CX_CURVE_Stark256, &publicKey, &privateKey, 1);
|
||||
os_memset(&privateKey, 0, sizeof(privateKey));
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
io_seproxyhal_io_heartbeat();
|
||||
selfTransfer = (os_memcmp(publicKey.W + 1, dataBuffer + 20 + 32, 32) == 0);
|
||||
selfTransfer = (memcmp(publicKey.W + 1, dataBuffer + 20 + 32 + postOffset, 32) == 0);
|
||||
PRINTF("self transfer %d\n", selfTransfer);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
// amount to transfer
|
||||
stark_get_amount_string(dataBuffer, dataBuffer + 20, dataBuffer + 20 + 32 + 32 + 4 + 4, (char*)(dataBuffer + TMP_OFFSET), tmpContent.tmp);
|
||||
stark_get_amount_string(dataBuffer + preOffset,
|
||||
dataBuffer + preOffset + 20,
|
||||
dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4, (char*)(dataBuffer + TMP_OFFSET), tmpContent.tmp);
|
||||
// dest vault ID
|
||||
snprintf(strings.tmp.tmp2, sizeof(strings.tmp.tmp2), "%d", U4BE(dataBuffer, 20 + 32 + 32 + 4));
|
||||
snprintf(strings.tmp.tmp2, sizeof(strings.tmp.tmp2), "%d",
|
||||
U4BE(dataBuffer, 20 + 32 + postOffset + 32 + 4));
|
||||
if (!selfTransfer) {
|
||||
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataBuffer + 20 + 32);
|
||||
memmove(dataContext.starkContext.transferDestination, dataBuffer + 20 + 32 + postOffset, 32);
|
||||
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataBuffer + 20 + 32 + postOffset);
|
||||
}
|
||||
}
|
||||
if (order) {
|
||||
ux_flow_init(0, ux_stark_limit_order_flow, NULL);
|
||||
}
|
||||
else {
|
||||
if (selfTransfer) {
|
||||
ux_flow_init(0, (dataContext.starkContext.conditional ? ux_stark_self_transfer_conditional_flow :
|
||||
ux_stark_self_transfer_flow), NULL);
|
||||
}
|
||||
else {
|
||||
ux_flow_init(0, (dataContext.starkContext.conditional ? ux_stark_transfer_conditional_flow :
|
||||
ux_stark_transfer_flow), NULL);
|
||||
}
|
||||
}
|
||||
ux_flow_init(0, p1 == P1_STARK_ORDER ? ux_stark_limit_order_flow : selfTransfer ?
|
||||
ux_stark_self_transfer_flow : ux_stark_transfer_flow, NULL);
|
||||
|
||||
*flags |= IO_ASYNCH_REPLY;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,10 @@ unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e) {
|
||||
io_seproxyhal_io_heartbeat();
|
||||
starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, tmpCtx.transactionContext.pathLength, privateKeyData);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
stark_sign(signature, privateKeyData, dataContext.starkContext.w1, dataContext.starkContext.w2, dataContext.starkContext.w3);
|
||||
G_io_apdu_buffer[0] = 0;
|
||||
stark_sign(signature, privateKeyData, dataContext.starkContext.w1, dataContext.starkContext.w2,
|
||||
dataContext.starkContext.w3,
|
||||
(dataContext.starkContext.conditional ? dataContext.starkContext.w4 : NULL));
|
||||
G_io_apdu_buffer[0] = 0;
|
||||
format_signature_out(signature);
|
||||
tx = 65;
|
||||
G_io_apdu_buffer[tx++] = 0x90;
|
||||
|
||||
@@ -5,6 +5,21 @@
|
||||
|
||||
unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e);
|
||||
|
||||
void stark_sign_display_master_account() {
|
||||
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.transferDestination);
|
||||
}
|
||||
|
||||
void stark_sign_display_condition_address() {
|
||||
strings.tmp.tmp[0] = '0';
|
||||
strings.tmp.tmp[1] = 'x';
|
||||
getEthAddressStringFromBinary(dataContext.starkContext.conditionAddress, (uint8_t*)(strings.tmp.tmp + 2), &global_sha3, chainConfig);
|
||||
strings.tmp.tmp[42] = '\0';
|
||||
}
|
||||
|
||||
void stark_sign_display_condition_fact() {
|
||||
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.fact);
|
||||
}
|
||||
|
||||
UX_STEP_NOCB(ux_stark_limit_order_1_step,
|
||||
pnn,
|
||||
{
|
||||
@@ -44,7 +59,7 @@ UX_STEP_NOCB(ux_stark_limit_order_5_step,
|
||||
UX_STEP_NOCB(ux_stark_limit_order_6_step,
|
||||
bnnn_paging,
|
||||
{
|
||||
.title = "Token Accont",
|
||||
.title = "Token Account",
|
||||
.text = strings.common.fullAddress
|
||||
});
|
||||
|
||||
@@ -100,6 +115,19 @@ UX_STEP_NOCB(ux_stark_self_transfer_2_step,
|
||||
.text = "Transfer"
|
||||
});
|
||||
|
||||
UX_STEP_NOCB(ux_stark_conditional_transfer_2_step,
|
||||
bnnn_paging,
|
||||
{
|
||||
.title = "Conditional",
|
||||
.text = "Transfer"
|
||||
});
|
||||
|
||||
UX_STEP_NOCB(ux_stark_self_conditional_transfer_2_step,
|
||||
bnnn_paging,
|
||||
{
|
||||
.title = "Conditional",
|
||||
.text = "Self Transfer"
|
||||
});
|
||||
|
||||
UX_STEP_NOCB(ux_stark_transfer_3_step,
|
||||
bnnn_paging,
|
||||
@@ -118,7 +146,7 @@ UX_STEP_NOCB(ux_stark_transfer_4_step,
|
||||
UX_STEP_NOCB(ux_stark_transfer_5_step,
|
||||
bnnn_paging,
|
||||
{
|
||||
.title = "Token Accont",
|
||||
.title = "Token Account",
|
||||
.text = strings.tmp.tmp2
|
||||
});
|
||||
|
||||
@@ -140,6 +168,33 @@ UX_STEP_CB(
|
||||
"Reject",
|
||||
});
|
||||
|
||||
UX_STEP_NOCB_INIT(
|
||||
ux_stark_conditional_transfer_4_step,
|
||||
bnnn_paging,
|
||||
stark_sign_display_master_account(),
|
||||
{
|
||||
.title = "Master Account",
|
||||
.text = strings.tmp.tmp
|
||||
});
|
||||
|
||||
UX_STEP_NOCB_INIT(
|
||||
ux_stark_conditional_transfer_8_step,
|
||||
bnnn_paging,
|
||||
stark_sign_display_condition_address(),
|
||||
{
|
||||
.title = "Cond. Address",
|
||||
.text = strings.tmp.tmp
|
||||
});
|
||||
|
||||
UX_STEP_NOCB_INIT(
|
||||
ux_stark_conditional_transfer_9_step,
|
||||
bnnn_paging,
|
||||
stark_sign_display_condition_fact(),
|
||||
{
|
||||
.title = "Cond. Fact",
|
||||
.text = strings.tmp.tmp
|
||||
});
|
||||
|
||||
UX_FLOW(ux_stark_transfer_flow,
|
||||
&ux_stark_transfer_1_step,
|
||||
&ux_stark_transfer_2_step,
|
||||
@@ -159,4 +214,27 @@ UX_FLOW(ux_stark_self_transfer_flow,
|
||||
&ux_stark_transfer_7_step
|
||||
);
|
||||
|
||||
UX_FLOW(ux_stark_transfer_conditional_flow,
|
||||
&ux_stark_transfer_1_step,
|
||||
&ux_stark_conditional_transfer_2_step,
|
||||
&ux_stark_transfer_3_step,
|
||||
&ux_stark_conditional_transfer_4_step,
|
||||
&ux_stark_transfer_5_step,
|
||||
&ux_stark_conditional_transfer_8_step,
|
||||
&ux_stark_conditional_transfer_9_step,
|
||||
&ux_stark_transfer_6_step,
|
||||
&ux_stark_transfer_7_step
|
||||
);
|
||||
|
||||
UX_FLOW(ux_stark_self_transfer_conditional_flow,
|
||||
&ux_stark_transfer_1_step,
|
||||
&ux_stark_self_conditional_transfer_2_step,
|
||||
&ux_stark_transfer_3_step,
|
||||
&ux_stark_transfer_5_step,
|
||||
&ux_stark_conditional_transfer_8_step,
|
||||
&ux_stark_conditional_transfer_9_step,
|
||||
&ux_stark_transfer_6_step,
|
||||
&ux_stark_transfer_7_step
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
54
src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c
Normal file
54
src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
#include "shared_context.h"
|
||||
#include "apdu_constants.h"
|
||||
#include "stark_utils.h"
|
||||
#include "ui_flow.h"
|
||||
#include "ui_callbacks.h"
|
||||
|
||||
void handleStarkwareUnsafeSign(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx) {
|
||||
uint32_t i;
|
||||
uint8_t privateKeyData[32];
|
||||
cx_ecfp_public_key_t publicKey;
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
uint8_t bip32PathLength = *(dataBuffer);
|
||||
uint8_t offset = 1;
|
||||
// Initial checks
|
||||
if (appState != APP_STATE_IDLE) {
|
||||
reset_app_context();
|
||||
}
|
||||
if ((bip32PathLength < 0x01) ||
|
||||
(bip32PathLength > MAX_BIP32_PATH)) {
|
||||
PRINTF("Invalid path\n");
|
||||
THROW(0x6a80);
|
||||
}
|
||||
if ((p1 != 0) || (p2 != 0)) {
|
||||
THROW(0x6B00);
|
||||
}
|
||||
|
||||
if (dataLength != 32 + 4 * bip32PathLength + 1) {
|
||||
THROW(0x6700);
|
||||
}
|
||||
|
||||
tmpCtx.transactionContext.pathLength = bip32PathLength;
|
||||
for (i = 0; i < bip32PathLength; i++) {
|
||||
tmpCtx.transactionContext.bip32Path[i] = U4BE(dataBuffer, offset);
|
||||
PRINTF("Storing path %d %d\n", i, tmpCtx.transactionContext.bip32Path[i]);
|
||||
offset += 4;
|
||||
}
|
||||
memmove(dataContext.starkContext.w2, dataBuffer + offset, 32);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, bip32PathLength, privateKeyData);
|
||||
cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_generate_pair(CX_CURVE_Stark256, &publicKey, &privateKey, 1);
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
io_seproxyhal_io_heartbeat();
|
||||
memmove(dataContext.starkContext.w1, publicKey.W + 1, 32);
|
||||
ux_flow_init(0, ux_stark_unsafe_sign_flow, NULL);
|
||||
|
||||
*flags |= IO_ASYNCH_REPLY;
|
||||
}
|
||||
|
||||
#endif
|
||||
32
src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c
Normal file
32
src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
#include "shared_context.h"
|
||||
#include "stark_utils.h"
|
||||
#include "ui_callbacks.h"
|
||||
|
||||
unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e) {
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
uint8_t privateKeyData[32];
|
||||
uint8_t signature[72];
|
||||
unsigned int info = 0;
|
||||
uint32_t tx = 0;
|
||||
io_seproxyhal_io_heartbeat();
|
||||
starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, tmpCtx.transactionContext.pathLength, privateKeyData);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
|
||||
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
|
||||
dataContext.starkContext.w2, sizeof(dataContext.starkContext.w2), signature, sizeof(signature), &info);
|
||||
G_io_apdu_buffer[0] = 0;
|
||||
format_signature_out(signature);
|
||||
tx = 65;
|
||||
G_io_apdu_buffer[tx++] = 0x90;
|
||||
G_io_apdu_buffer[tx++] = 0x00;
|
||||
reset_app_context();
|
||||
// Send back the response, do not restart the event loop
|
||||
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
|
||||
// Display back the original UX
|
||||
ui_idle();
|
||||
return 0; // do not redraw the widget
|
||||
}
|
||||
|
||||
#endif
|
||||
69
src_features/stark_unsafe_sign/ui_flow_stark_unsafe_sign.c
Normal file
69
src_features/stark_unsafe_sign/ui_flow_stark_unsafe_sign.c
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifdef HAVE_STARKWARE
|
||||
|
||||
#include "shared_context.h"
|
||||
#include "ui_callbacks.h"
|
||||
|
||||
unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e);
|
||||
|
||||
void stark_unsafe_sign_display_account() {
|
||||
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.w1);
|
||||
}
|
||||
|
||||
void stark_unsafe_sign_display_hash() {
|
||||
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.w2);
|
||||
}
|
||||
|
||||
UX_STEP_NOCB(ux_stark_unsafe_sign_1_step,
|
||||
pnn,
|
||||
{
|
||||
&C_icon_warning,
|
||||
"Unsafe",
|
||||
"Stark Sign",
|
||||
});
|
||||
|
||||
UX_STEP_NOCB_INIT(
|
||||
ux_stark_unsafe_sign_2_step,
|
||||
bnnn_paging,
|
||||
stark_unsafe_sign_display_account(),
|
||||
{
|
||||
.title = "From Account",
|
||||
.text = strings.tmp.tmp
|
||||
});
|
||||
|
||||
UX_STEP_NOCB_INIT(
|
||||
ux_stark_unsafe_sign_3_step,
|
||||
bnnn_paging,
|
||||
stark_unsafe_sign_display_hash(),
|
||||
{
|
||||
.title = "Hash",
|
||||
.text = strings.tmp.tmp
|
||||
});
|
||||
|
||||
|
||||
UX_STEP_CB(
|
||||
ux_stark_unsafe_sign_4_step,
|
||||
pbb,
|
||||
io_seproxyhal_touch_stark_unsafe_sign_ok(NULL),
|
||||
{
|
||||
&C_icon_validate_14,
|
||||
"Accept",
|
||||
"and send",
|
||||
});
|
||||
UX_STEP_CB(
|
||||
ux_stark_unsafe_sign_5_step,
|
||||
pb,
|
||||
io_seproxyhal_touch_tx_cancel(NULL),
|
||||
{
|
||||
&C_icon_crossmark,
|
||||
"Reject",
|
||||
});
|
||||
|
||||
UX_FLOW(ux_stark_unsafe_sign_flow,
|
||||
&ux_stark_unsafe_sign_1_step,
|
||||
&ux_stark_unsafe_sign_2_step,
|
||||
&ux_stark_unsafe_sign_3_step,
|
||||
&ux_stark_unsafe_sign_4_step,
|
||||
&ux_stark_unsafe_sign_5_step
|
||||
);
|
||||
|
||||
#endif
|
||||
@@ -55,6 +55,21 @@ bool check_token_binding(char* ticker1, char* ticker2, const ticker_binding_t* b
|
||||
return false;
|
||||
}
|
||||
|
||||
bool erc20_plugin_available_check() {
|
||||
if (quantumSet) {
|
||||
switch(dataContext.tokenContext.quantumType) {
|
||||
case STARK_QUANTUM_LEGACY:
|
||||
case STARK_QUANTUM_ETH:
|
||||
case STARK_QUANTUM_ERC20:
|
||||
case STARK_QUANTUM_MINTABLE_ERC20:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void erc20_plugin_call(int message, void *parameters) {
|
||||
|
||||
switch(message) {
|
||||
|
||||
146
src_plugins/erc721/erc721_plugin.c
Normal file
146
src_plugins/erc721/erc721_plugin.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#include <string.h>
|
||||
#include "eth_plugin_internal.h"
|
||||
#include "eth_plugin_handler.h"
|
||||
#include "shared_context.h"
|
||||
#include "ethUtils.h"
|
||||
#include "utils.h"
|
||||
|
||||
void starkware_print_stark_key(uint8_t *starkKey, char *destination);
|
||||
void starkware_print_eth_address(uint8_t *address, char *destination);
|
||||
|
||||
typedef struct erc721_parameters_t {
|
||||
uint8_t selectorIndex;
|
||||
uint8_t address[20];
|
||||
uint8_t tokenId[32];
|
||||
//tokenDefinition_t *tokenSelf;
|
||||
//tokenDefinition_t *tokenAddress;
|
||||
} erc721_parameters_t;
|
||||
|
||||
bool erc721_plugin_available_check() {
|
||||
if (quantumSet) {
|
||||
switch(dataContext.tokenContext.quantumType) {
|
||||
case STARK_QUANTUM_ERC721:
|
||||
case STARK_QUANTUM_MINTABLE_ERC721:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void erc721_plugin_call(int message, void *parameters) {
|
||||
|
||||
switch(message) {
|
||||
case ETH_PLUGIN_INIT_CONTRACT: {
|
||||
ethPluginInitContract_t *msg = (ethPluginInitContract_t*)parameters;
|
||||
erc721_parameters_t *context = (erc721_parameters_t*)msg->pluginContext;
|
||||
// enforce that ETH amount should be 0
|
||||
if (!allzeroes(msg->pluginSharedRO->txContent->value.value, 32)){
|
||||
PRINTF("Err: Transaction amount is not 0 for erc721 approval\n");
|
||||
msg->result = ETH_PLUGIN_RESULT_ERROR;
|
||||
}
|
||||
else {
|
||||
size_t i;
|
||||
for (i=0; i<NUM_ERC721_SELECTORS; i++) {
|
||||
if (memcmp((uint8_t *)PIC(ERC721_SELECTORS[i]), msg->selector, SELECTOR_SIZE) == 0) {
|
||||
context->selectorIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == NUM_ERC721_SELECTORS) {
|
||||
PRINTF("Unknown erc721 selector %.*H\n", SELECTOR_SIZE, msg->selector);
|
||||
break;
|
||||
}
|
||||
if (msg->dataSize != 4 + 32 + 32) {
|
||||
PRINTF("Invalid erc721 approval data size %d\n", msg->dataSize);
|
||||
break;
|
||||
}
|
||||
PRINTF("erc721 plugin init\n");
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ETH_PLUGIN_PROVIDE_PARAMETER : {
|
||||
ethPluginProvideParameter_t *msg = (ethPluginProvideParameter_t*)parameters;
|
||||
erc721_parameters_t *context = (erc721_parameters_t*)msg->pluginContext;
|
||||
PRINTF("erc721 plugin provide parameter %d %.*H\n", msg->parameterOffset, 32, msg->parameter);
|
||||
switch(msg->parameterOffset) {
|
||||
case 4:
|
||||
memmove(context->address, msg->parameter + 32 - 20, 20);
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
case 4 + 32:
|
||||
memmove(context->tokenId, msg->parameter, 32);
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unhandled parameter offset\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ETH_PLUGIN_FINALIZE: {
|
||||
ethPluginFinalize_t *msg = (ethPluginFinalize_t*)parameters;
|
||||
erc721_parameters_t *context = (erc721_parameters_t*)msg->pluginContext;
|
||||
PRINTF("erc721 plugin finalize\n");
|
||||
msg->tokenLookup1 = msg->pluginSharedRO->txContent->destination;
|
||||
msg->tokenLookup2 = context->address;
|
||||
msg->numScreens = 3;
|
||||
msg->uiType = ETH_UI_TYPE_GENERIC;
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case ETH_PLUGIN_PROVIDE_TOKEN: {
|
||||
ethPluginProvideToken_t *msg = (ethPluginProvideToken_t*)parameters;
|
||||
erc721_parameters_t *context = (erc721_parameters_t*)msg->pluginContext;
|
||||
PRINTF("erc721 plugin provide token dest: %d - address: %d\n", (msg->token1 != NULL), (msg->token2 != NULL));
|
||||
//context->tokenSelf = msg->token1;
|
||||
//context->tokenAddress = msg->token2;
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case ETH_PLUGIN_QUERY_CONTRACT_ID: {
|
||||
ethQueryContractID_t *msg = (ethQueryContractID_t*)parameters;
|
||||
strcpy(msg->name, "Allowance");
|
||||
strcpy(msg->version, "");
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case ETH_PLUGIN_QUERY_CONTRACT_UI: {
|
||||
ethQueryContractUI_t *msg = (ethQueryContractUI_t*)parameters;
|
||||
erc721_parameters_t *context = (erc721_parameters_t*)msg->pluginContext;
|
||||
switch(msg->screenIndex) {
|
||||
case 0:
|
||||
strcpy(msg->title, "Contract Name");
|
||||
starkware_print_eth_address(tmpContent.txContent.destination, msg->msg);
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
strcpy(msg->title, "NFT Contract");
|
||||
starkware_print_eth_address(context->address, msg->msg);
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
strcpy(msg->title, "TokenID");
|
||||
starkware_print_stark_key(context->tokenId, msg->msg);
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF("Unhandled message %d\n", message);
|
||||
}
|
||||
}
|
||||
@@ -16,33 +16,64 @@ typedef enum {
|
||||
STARKWARE_FULL_WITHDRAW,
|
||||
STARKWARE_FREEZE,
|
||||
STARKWARE_ESCAPE,
|
||||
STARKWARE_VERIFY_ESCAPE
|
||||
|
||||
STARKWARE_VERIFY_ESCAPE,
|
||||
STARKWARE_WITHDRAW_TO,
|
||||
STARKWARE_DEPOSIT_NFT,
|
||||
STARKWARE_DEPOSIT_NFT_RECLAIM,
|
||||
STARKWARE_WITHDRAW_AND_MINT,
|
||||
STARKWARE_WITHDRAW_NFT,
|
||||
STARKWARE_WITHDRAW_NFT_TO
|
||||
} starkwareSelector_t;
|
||||
|
||||
// register : starkkey (32), drop param 2
|
||||
#ifndef HAVE_TOKENS_EXTRA_LIST
|
||||
|
||||
static const uint8_t DEVERSIFI_CONTRACT[] = {
|
||||
0x01,
|
||||
0x5d,0x22,0x04,0x5d,0xac,0xea,0xb0,0x3b,0x15,0x80,0x31,0xec,0xb7,0xd9,0xd0,0x6f,0xad,0x24,0x60,0x9b
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static const uint8_t DEVERSIFI_CONTRACT[] = {
|
||||
0x02,
|
||||
0xe7,0x3a,0x39,0x4a,0xde,0x4d,0x94,0xa0,0x73,0x50,0x2d,0xa8,0x70,0x3e,0xa2,0x34,0x90,0xdc,0x7b,0x6a,
|
||||
0x69,0xC6,0x39,0x2E,0xb0,0x2a,0x28,0x82,0x31,0x41,0x34,0xc9,0x8D,0xDC,0xBF,0x73,0xB7,0xAd,0xBa,0xb1
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// register : address (20), stark key (32), drop param 3
|
||||
// Registration
|
||||
// Contract Name
|
||||
// From ETH address
|
||||
// Master account
|
||||
// deposit token : verify tokenId (32), vaultId (4), quantized Amount (32)
|
||||
// deposit token : stark key (32), verify assetType (32), vaultId (4), quantized Amount (32)
|
||||
// Deposit
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// Token Account
|
||||
// Amount
|
||||
// deposit : verify tokenId (32), vaultId (4)
|
||||
// deposit : stark key (32), verify assetType (32), vaultId (4)
|
||||
// Flow similar to deposit
|
||||
// deposit cancel, deposit reclaim : tokenId (32) ignored, vaultId(4)
|
||||
// full withdrawal, freeze : vaultId (4)
|
||||
// deposit cancel, deposit reclaim : stark key (32), assetType (reclaim) / assetId (cancel) (32) ignored, vaultId(4)
|
||||
// full withdrawal, freeze : stark key (32), vaultId (4)
|
||||
// Cancel Deposit | Reclaim Deposit | Full Withdrawal | Freeze
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// Token Account
|
||||
// withdrawal : verify tokenId (32)
|
||||
// withdrawal : stark key (32), verify assetType (32)
|
||||
// Withdrawal
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// To Eth Address
|
||||
// Token Symbol
|
||||
// escape : starkkey (32), vaultId (4), verify tokenId (32), quantized Amount (32)
|
||||
// withdrawal to : stark key (32), verify assetType (32), address (20)
|
||||
// Withdrawal To
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// To Eth Address
|
||||
// Token Symbol
|
||||
// escape : stark key (32), vaultId (4), verify assetType (32), quantized Amount (32)
|
||||
// Escape
|
||||
// Contract Name
|
||||
// Amount
|
||||
@@ -51,31 +82,77 @@ typedef enum {
|
||||
// verify escape : escapeProof (ignore)
|
||||
// Verify Escape
|
||||
// Contract Name
|
||||
// deposit NFT : stark key (32), verify assetType (32), vault id (4), token id (32)
|
||||
// Deposit
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// Token Account
|
||||
// NFT Contract
|
||||
// Token ID
|
||||
// deposit NFT reclaim : stark key (32), verify assetType (32), vault id (4), token id (32)
|
||||
// Reclaim Deposit
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// Token Account
|
||||
// NFT Contract
|
||||
// Token ID
|
||||
// withdraw and mint : stark key (32), verify assetType (32), mintable blob (ignored variable)
|
||||
// Withdrawal
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// Asset Contract
|
||||
// withdraw NFT : stark key (32), verify assetType (32), token id (32)
|
||||
// Withdrawal
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// To Eth Address
|
||||
// NFT Contract
|
||||
// Token ID
|
||||
// withdraw NFT To : stark key (32), verify assetType (32), token id (32), address (20)
|
||||
// Withdrawal To
|
||||
// Contract Name
|
||||
// Master Account
|
||||
// To Eth Address
|
||||
// NFT Contract
|
||||
// Token ID
|
||||
|
||||
|
||||
static const uint8_t STARKWARE_EXPECTED_DATA_SIZE[] = {
|
||||
4 + 32,
|
||||
0,
|
||||
4 + 32 + 32 + 32 + 32,
|
||||
4 + 32 + 32 + 32,
|
||||
4 + 32 + 32 + 32,
|
||||
4 + 32 + 32 + 32,
|
||||
4 + 32 + 32,
|
||||
4 + 32 + 32,
|
||||
4 + 32 + 32,
|
||||
4 + 32,
|
||||
4 + 32,
|
||||
4 + 32,
|
||||
4 + 32 + 32 + 32 + 32,
|
||||
0
|
||||
0,
|
||||
4 + 32 + 32 + 32,
|
||||
4 + 32 + 32 + 32 + 32,
|
||||
4 + 32 + 32 + 32 + 32,
|
||||
0,
|
||||
4 + 32 + 32 + 32,
|
||||
4 + 32 + 32 + 32 + 32
|
||||
};
|
||||
|
||||
static const uint8_t STARKWARE_NUM_SCREENS[] = {
|
||||
4 - 1,
|
||||
4 - 1,
|
||||
4 - 1,
|
||||
3 - 1,
|
||||
3 - 1,
|
||||
4 - 1,
|
||||
3 - 1,
|
||||
3 - 1,
|
||||
5 - 1,
|
||||
2 - 1
|
||||
5 - 1,
|
||||
4 - 1,
|
||||
4 - 1,
|
||||
5 - 1,
|
||||
4 - 1,
|
||||
4 - 1,
|
||||
5 - 1,
|
||||
2 - 1,
|
||||
5 - 1,
|
||||
6 - 1,
|
||||
6 - 1,
|
||||
4 - 1,
|
||||
6 - 1,
|
||||
6 - 1
|
||||
};
|
||||
|
||||
typedef struct starkware_parameters_t {
|
||||
@@ -88,8 +165,22 @@ typedef struct starkware_parameters_t {
|
||||
|
||||
} starkware_parameters_t;
|
||||
|
||||
bool is_deversify_contract(const uint8_t *address) {
|
||||
uint32_t offset = 0;
|
||||
uint8_t size = DEVERSIFI_CONTRACT[0];
|
||||
uint8_t i;
|
||||
|
||||
for (i=0; i<DEVERSIFI_CONTRACT[0]; i++) {
|
||||
if (memcmp(address, DEVERSIFI_CONTRACT + offset + 1, 20) == 0) {
|
||||
return true;
|
||||
}
|
||||
offset += 20;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : rewrite as independant code
|
||||
bool starkware_verify_token_id(uint8_t *tmp32, uint8_t *tokenId) {
|
||||
bool starkware_verify_asset_id(uint8_t *tmp32, uint8_t *tokenId, bool assetTypeOnly) {
|
||||
if (quantumSet) {
|
||||
cx_sha3_t sha3;
|
||||
tokenDefinition_t *currentToken = NULL;
|
||||
@@ -99,7 +190,9 @@ bool starkware_verify_token_id(uint8_t *tmp32, uint8_t *tokenId) {
|
||||
cx_keccak_init(&sha3, 256);
|
||||
compute_token_id(&sha3,
|
||||
(currentToken != NULL ? currentToken->address : NULL),
|
||||
dataContext.tokenContext.quantum, tmp32);
|
||||
dataContext.tokenContext.quantumType,
|
||||
dataContext.tokenContext.quantum,
|
||||
dataContext.tokenContext.mintingBlob, assetTypeOnly, tmp32);
|
||||
if (memcmp(tokenId, tmp32, 32) != 0) {
|
||||
PRINTF("Token ID not matching - computed %.*H\n", 32, tmp32);
|
||||
PRINTF("Current quantum %.*H\n", 32, dataContext.tokenContext.quantum);
|
||||
@@ -114,6 +207,27 @@ bool starkware_verify_token_id(uint8_t *tmp32, uint8_t *tokenId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool starkware_verify_nft_token_id(uint8_t *tokenId) {
|
||||
if (!quantumSet) {
|
||||
PRINTF("Quantum not set\n");
|
||||
return false;
|
||||
}
|
||||
switch(dataContext.tokenContext.quantumType) {
|
||||
case STARK_QUANTUM_ERC721:
|
||||
case STARK_QUANTUM_MINTABLE_ERC721:
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unexpected quantum type for NFT token id check %d\n", dataContext.tokenContext.quantumType);
|
||||
return false;
|
||||
}
|
||||
if (memcmp(dataContext.tokenContext.quantum, tokenId, 32) != 0) {
|
||||
PRINTF("Token ID not matching - expected %.*H\n", 32, dataContext.tokenContext.quantum);
|
||||
PRINTF("Current token ID %.*H\n", 32, tokenId);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void starkware_print_vault_id(uint32_t vaultId, char *destination) {
|
||||
snprintf(destination, 10, "%d", vaultId);
|
||||
}
|
||||
@@ -139,7 +253,7 @@ void starkware_print_amount(uint8_t *amountData, char *destination, bool forEsca
|
||||
if ((amountData == NULL) || (forEscape && (dataContext.tokenContext.quantumIndex == MAX_TOKEN))) {
|
||||
decimals = WEI_TO_ETHER;
|
||||
if (!forEscape) {
|
||||
convertUint256BE(tmpContent.txContent.value.value, tmpContent.txContent.value.length, &amountPre);
|
||||
convertUint256BE(tmpContent.txContent.value.value, tmpContent.txContent.value.length, &amount);
|
||||
}
|
||||
else {
|
||||
readu256BE(amountData, &amountPre);
|
||||
@@ -151,8 +265,10 @@ void starkware_print_amount(uint8_t *amountData, char *destination, bool forEsca
|
||||
ticker = (char*)token->ticker;
|
||||
readu256BE(amountData, &amountPre);
|
||||
}
|
||||
readu256BE(dataContext.tokenContext.quantum, &quantum);
|
||||
mul256(&amountPre, &quantum, &amount);
|
||||
if (amountData != NULL) {
|
||||
readu256BE(dataContext.tokenContext.quantum, &quantum);
|
||||
mul256(&amountPre, &quantum, &amount);
|
||||
}
|
||||
tostring256(&amount, 10, (char*)(G_io_apdu_buffer + 100), 100);
|
||||
strcpy(destination, ticker);
|
||||
adjustDecimals((char*)(G_io_apdu_buffer + 100), strlen((char*)(G_io_apdu_buffer + 100)), destination + strlen(ticker), 50 - strlen(ticker), decimals);
|
||||
@@ -169,6 +285,18 @@ void starkware_print_ticker(char *destination) {
|
||||
strcpy(destination, ticker);
|
||||
}
|
||||
|
||||
// TODO : rewrite as independant code
|
||||
void starkware_print_asset_contract(char *destination) {
|
||||
// token has been validated to be present previously
|
||||
if (dataContext.tokenContext.quantumIndex != MAX_TOKEN) {
|
||||
tokenDefinition_t *token = &tmpCtx.transactionContext.tokens[dataContext.tokenContext.quantumIndex];
|
||||
starkware_print_eth_address(token->address, destination);
|
||||
}
|
||||
else {
|
||||
strcpy(destination, "UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : rewrite as independant code
|
||||
void starkware_get_source_address(char *destination) {
|
||||
uint8_t privateKeyData[32];
|
||||
@@ -180,8 +308,8 @@ void starkware_get_source_address(char *destination) {
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
io_seproxyhal_io_heartbeat();
|
||||
cx_ecfp_generate_pair(CX_CURVE_256K1, &publicKey, &privateKey, 1);
|
||||
os_memset(&privateKey, 0, sizeof(privateKey));
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
explicit_bzero(&privateKey, sizeof(privateKey));
|
||||
explicit_bzero(privateKeyData, sizeof(privateKeyData));
|
||||
io_seproxyhal_io_heartbeat();
|
||||
destination[0] = '0';
|
||||
destination[1] = 'x';
|
||||
@@ -229,75 +357,134 @@ void starkware_plugin_call(int message, void *parameters) {
|
||||
break;
|
||||
}
|
||||
switch(msg->parameterOffset) {
|
||||
|
||||
case 4:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_REGISTER:
|
||||
case STARKWARE_ESCAPE:
|
||||
memmove(context->starkKey, msg->parameter, 32);
|
||||
memmove(context->amount, msg->parameter + 32 - 20, 20);
|
||||
break;
|
||||
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_CANCEL:
|
||||
case STARKWARE_DEPOSIT_RECLAIM:
|
||||
break;
|
||||
case STARKWARE_WITHDRAW:
|
||||
case STARKWARE_FULL_WITHDRAW:
|
||||
case STARKWARE_FREEZE:
|
||||
memmove(context->vaultId, msg->parameter + 32 - 4, 4);
|
||||
break;
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_WITHDRAW:
|
||||
context->validToken = starkware_verify_token_id(context->amount, msg->parameter);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 4 + 32:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_DEPOSIT_CANCEL:
|
||||
case STARKWARE_DEPOSIT_RECLAIM:
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_ESCAPE:
|
||||
memmove(context->vaultId, msg->parameter + 32 - 4, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 4 + 32 + 32:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
memmove(context->amount, msg->parameter, 32);
|
||||
break;
|
||||
case STARKWARE_ESCAPE:
|
||||
context->validToken = starkware_verify_token_id(context->amount, msg->parameter);
|
||||
break;
|
||||
case STARKWARE_WITHDRAW_TO:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
case STARKWARE_WITHDRAW_AND_MINT:
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
memmove(context->starkKey, msg->parameter, 32);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 4 + 32 + 32 + 32:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_ESCAPE:
|
||||
memmove(context->amount, msg->parameter, 32);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
case 4 + 32:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_REGISTER:
|
||||
memmove(context->starkKey, msg->parameter, 32);
|
||||
break;
|
||||
|
||||
case STARKWARE_ESCAPE:
|
||||
memmove(context->vaultId, msg->parameter + 32 - 4, 4);
|
||||
break;
|
||||
|
||||
case STARKWARE_DEPOSIT_CANCEL:
|
||||
case STARKWARE_DEPOSIT_RECLAIM:
|
||||
break;
|
||||
|
||||
case STARKWARE_FULL_WITHDRAW:
|
||||
case STARKWARE_FREEZE:
|
||||
memmove(context->vaultId, msg->parameter + 32 - 4, 4);
|
||||
break;
|
||||
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_WITHDRAW:
|
||||
case STARKWARE_WITHDRAW_TO:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
case STARKWARE_WITHDRAW_AND_MINT:
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
context->validToken = starkware_verify_asset_id(context->amount, msg->parameter, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 4 + 32 + 32:
|
||||
switch(context->selectorIndex) {
|
||||
|
||||
case STARKWARE_ESCAPE:
|
||||
context->validToken = starkware_verify_asset_id(context->amount, msg->parameter, true);
|
||||
break;
|
||||
|
||||
case STARKWARE_DEPOSIT_CANCEL:
|
||||
case STARKWARE_DEPOSIT_RECLAIM:
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
memmove(context->vaultId, msg->parameter + 32 - 4, 4);
|
||||
break;
|
||||
|
||||
case STARKWARE_WITHDRAW_TO:
|
||||
memmove(context->amount, msg->parameter + 32 - 20, 20);
|
||||
break;
|
||||
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
context->validToken = starkware_verify_nft_token_id(msg->parameter);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 4 + 32 + 32 + 32:
|
||||
switch(context->selectorIndex) {
|
||||
|
||||
case STARKWARE_ESCAPE:
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
memmove(context->amount, msg->parameter, 32);
|
||||
break;
|
||||
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
memmove(context->amount, msg->parameter + 32 - 20, 20);
|
||||
break;
|
||||
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
context->validToken = starkware_verify_nft_token_id(msg->parameter);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_REGISTER:
|
||||
case STARKWARE_VERIFY_ESCAPE:
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF("Unhandled parameter offset\n");
|
||||
break;
|
||||
@@ -331,15 +518,19 @@ void starkware_plugin_call(int message, void *parameters) {
|
||||
break;
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
strcpy(msg->name, "Deposit");
|
||||
break;
|
||||
case STARKWARE_DEPOSIT_CANCEL:
|
||||
strcpy(msg->name, "Cancel Deposit");
|
||||
break;
|
||||
case STARKWARE_DEPOSIT_RECLAIM:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
strcpy(msg->name, "Reclaim Deposit");
|
||||
break;
|
||||
case STARKWARE_WITHDRAW:
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
case STARKWARE_WITHDRAW_AND_MINT:
|
||||
strcpy(msg->name, "Withdrawal");
|
||||
break;
|
||||
case STARKWARE_FULL_WITHDRAW:
|
||||
@@ -354,10 +545,15 @@ void starkware_plugin_call(int message, void *parameters) {
|
||||
case STARKWARE_VERIFY_ESCAPE:
|
||||
strcpy(msg->name, "Verify Escape");
|
||||
break;
|
||||
case STARKWARE_WITHDRAW_TO:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
strcpy(msg->name, "Withdrawal To");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
strcpy(msg->version, "Starkware");
|
||||
strcpy(msg->version, is_deversify_contract(tmpContent.txContent.destination) ? "DeversiFi" : "Starkware");
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
}
|
||||
break;
|
||||
@@ -368,47 +564,93 @@ void starkware_plugin_call(int message, void *parameters) {
|
||||
switch(msg->screenIndex) {
|
||||
case 0:
|
||||
strcpy(msg->title, "Contract Name");
|
||||
starkware_print_eth_address(tmpContent.txContent.destination, msg->msg);
|
||||
if (is_deversify_contract(tmpContent.txContent.destination)) {
|
||||
strcpy(msg->msg, "DeversiFi");
|
||||
}
|
||||
else {
|
||||
starkware_print_eth_address(tmpContent.txContent.destination, msg->msg);
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_REGISTER:
|
||||
strcpy(msg->title, "From ETH Address");
|
||||
starkware_get_source_address(msg->msg);
|
||||
break;
|
||||
case STARKWARE_REGISTER:
|
||||
strcpy(msg->title, "From ETH Address");
|
||||
starkware_print_eth_address(context->amount, msg->msg);
|
||||
break;
|
||||
case STARKWARE_ESCAPE:
|
||||
strcpy(msg->title, "Amount");
|
||||
starkware_print_amount(context->amount, msg->msg, true);
|
||||
break;
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_CANCEL:
|
||||
case STARKWARE_DEPOSIT_RECLAIM:
|
||||
case STARKWARE_WITHDRAW:
|
||||
case STARKWARE_FULL_WITHDRAW:
|
||||
case STARKWARE_FREEZE:
|
||||
case STARKWARE_VERIFY_ESCAPE:
|
||||
case STARKWARE_WITHDRAW_TO:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
case STARKWARE_WITHDRAW_AND_MINT:
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
strcpy(msg->title, "Master Account");
|
||||
starkware_print_stark_key(context->starkKey, msg->msg);
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unexpected screen %d for %d\n", msg->screenIndex, context->selectorIndex);
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
case 2:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_REGISTER:
|
||||
case STARKWARE_ESCAPE:
|
||||
strcpy(msg->title, "Master Account");
|
||||
starkware_print_stark_key(context->starkKey, msg->msg);
|
||||
break;
|
||||
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
case STARKWARE_DEPOSIT_CANCEL:
|
||||
case STARKWARE_DEPOSIT_RECLAIM:
|
||||
case STARKWARE_FULL_WITHDRAW:
|
||||
case STARKWARE_FREEZE:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
strcpy(msg->title, "Token Account");
|
||||
starkware_print_vault_id(U4BE(context->vaultId, 0), msg->msg);
|
||||
break;
|
||||
case STARKWARE_WITHDRAW:
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
strcpy(msg->title, "To ETH Address");
|
||||
starkware_get_source_address(msg->msg);
|
||||
break;
|
||||
case STARKWARE_ESCAPE:
|
||||
strcpy(msg->title, "Amount");
|
||||
starkware_print_amount(context->amount, msg->msg, true);
|
||||
case STARKWARE_WITHDRAW_TO:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
strcpy(msg->title, "To ETH Address");
|
||||
starkware_print_eth_address(context->amount, msg->msg);
|
||||
break;
|
||||
case STARKWARE_WITHDRAW_AND_MINT:
|
||||
strcpy(msg->title, "Asset Contract");
|
||||
starkware_print_asset_contract(msg->msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF("Unexpected screen %d for %d\n", msg->screenIndex, context->selectorIndex);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_REGISTER:
|
||||
case 3:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_ESCAPE:
|
||||
strcpy(msg->title, "Master Account");
|
||||
PRINTF("Master account %s\n", msg->msg);
|
||||
starkware_print_stark_key(context->starkKey, msg->msg);
|
||||
strcpy(msg->title, "Token Account");
|
||||
starkware_print_vault_id(U4BE(context->vaultId, 0), msg->msg);
|
||||
break;
|
||||
case STARKWARE_DEPOSIT_TOKEN:
|
||||
case STARKWARE_DEPOSIT_ETH:
|
||||
@@ -418,22 +660,19 @@ void starkware_plugin_call(int message, void *parameters) {
|
||||
msg->msg, false);
|
||||
break;
|
||||
case STARKWARE_WITHDRAW:
|
||||
case STARKWARE_WITHDRAW_TO:
|
||||
strcpy(msg->title, "Token Symbol");
|
||||
starkware_print_ticker(msg->msg);
|
||||
break;
|
||||
default:
|
||||
PRINTF("Unexpected screen %d for %d\n", msg->screenIndex, context->selectorIndex);
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switch(context->selectorIndex) {
|
||||
case STARKWARE_ESCAPE:
|
||||
strcpy(msg->title, "Token Account");
|
||||
starkware_print_vault_id(U4BE(context->vaultId, 0), msg->msg);
|
||||
break;
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
strcpy(msg->title, "NFT Contract");
|
||||
starkware_print_asset_contract(msg->msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF("Unexpected screen %d for %d\n", msg->screenIndex, context->selectorIndex);
|
||||
break;
|
||||
@@ -441,6 +680,24 @@ void starkware_plugin_call(int message, void *parameters) {
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
switch(context->selectorIndex) {
|
||||
|
||||
case STARKWARE_WITHDRAW_NFT:
|
||||
case STARKWARE_WITHDRAW_NFT_TO:
|
||||
case STARKWARE_DEPOSIT_NFT:
|
||||
case STARKWARE_DEPOSIT_NFT_RECLAIM:
|
||||
strcpy(msg->title, "TokenID");
|
||||
starkware_print_stark_key(dataContext.tokenContext.quantum, msg->msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF("Unexpected screen %d for %d\n", msg->screenIndex, context->selectorIndex);
|
||||
break;
|
||||
}
|
||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINTF("Unexpected screen %d for %d\n", msg->screenIndex, context->selectorIndex);
|
||||
break;
|
||||
@@ -453,4 +710,4 @@ void starkware_plugin_call(int message, void *parameters) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user