62
62
63
63
#include <ed25519-donna.h>
64
64
65
+ #include "int-util.h"
65
66
#include "reconstruct_wallet_flow.h"
66
67
#include "solana_api.h"
67
68
#include "solana_contracts.h"
@@ -346,7 +347,8 @@ STATIC bool solana_fetch_valid_transaction(solana_query_t *query) {
346
347
if (SOL_OK != solana_byte_array_to_unsigned_txn (
347
348
solana_txn_context -> transaction ,
348
349
total_size ,
349
- & solana_txn_context -> transaction_info ) ||
350
+ & solana_txn_context -> transaction_info ,
351
+ & solana_txn_context -> extra_data ) ||
350
352
SOL_OK !=
351
353
solana_validate_unsigned_txn (& solana_txn_context -> transaction_info )) {
352
354
return false;
@@ -355,12 +357,62 @@ STATIC bool solana_fetch_valid_transaction(solana_query_t *query) {
355
357
return true;
356
358
}
357
359
360
+ static bool verify_priority_fee () {
361
+ if (solana_txn_context -> extra_data .compute_unit_price_micro_lamports > 0 ) {
362
+ // verify priority fee
363
+ uint64_t priority_fee , carry ;
364
+
365
+ // Capacity to multiply 2 numbers upto 8-byte value and store the result in
366
+ // 2 separate 8-byte variables
367
+ priority_fee =
368
+ mul128 (solana_txn_context -> extra_data .compute_unit_price_micro_lamports ,
369
+ solana_txn_context -> extra_data .compute_unit_limit ,
370
+ & carry );
371
+
372
+ // prepare the whole 128-bit little-endian representation of priority fee
373
+ uint8_t be_micro_lamports [16 ] = {0 };
374
+ memcpy (be_micro_lamports , & priority_fee , sizeof (priority_fee ));
375
+ memcpy (be_micro_lamports + sizeof (priority_fee ), & carry , sizeof (carry ));
376
+
377
+ // outputs 128-bit (16-byte) big-endian representation of priority fee
378
+ cy_reverse_byte_array (be_micro_lamports , sizeof (be_micro_lamports ));
379
+
380
+ char priority_fee_string [33 ] = {'\0' },
381
+ priority_fee_decimal_string [34 ] = {'\0' };
382
+
383
+ byte_array_to_hex_string (be_micro_lamports ,
384
+ sizeof (be_micro_lamports ),
385
+ priority_fee_string ,
386
+ sizeof (priority_fee_string ));
387
+ if (!convert_byte_array_to_decimal_string (
388
+ sizeof (priority_fee_string ) - 1 ,
389
+ solana_get_decimal () + 6 , // +6 for micro
390
+ priority_fee_string ,
391
+ priority_fee_decimal_string ,
392
+ sizeof (priority_fee_decimal_string ))) {
393
+ solana_send_error (ERROR_COMMON_ERROR_UNKNOWN_ERROR_TAG , 1 );
394
+ return false;
395
+ }
396
+
397
+ char display [100 ] = "" ;
398
+ snprintf (display ,
399
+ sizeof (display ),
400
+ UI_TEXT_VERIFY_PRIORITY_FEE ,
401
+ priority_fee_decimal_string ,
402
+ SOLANA_LUNIT );
403
+ if (!core_confirmation (display , solana_send_error )) {
404
+ return false;
405
+ }
406
+ }
407
+ return true;
408
+ }
409
+
358
410
static bool verify_solana_transfer_sol_transaction () {
359
411
char address [45 ] = {0 };
360
412
size_t address_size = sizeof (address );
361
413
362
414
const uint8_t transfer_instruction_index =
363
- solana_txn_context -> transaction_info .transfer_instruction_index ;
415
+ solana_txn_context -> extra_data .transfer_instruction_index ;
364
416
// verify recipient address;
365
417
if (!b58enc (address ,
366
418
& address_size ,
@@ -408,6 +460,9 @@ static bool verify_solana_transfer_sol_transaction() {
408
460
return false;
409
461
}
410
462
463
+ if (!verify_priority_fee ())
464
+ return false;
465
+
411
466
set_app_flow_status (SOLANA_SIGN_TXN_STATUS_VERIFY );
412
467
return true;
413
468
}
@@ -535,13 +590,14 @@ static bool is_token_whitelisted(const uint8_t *address,
535
590
536
591
static bool verify_solana_transfer_token_transaction () {
537
592
const uint8_t transfer_instruction_index =
538
- solana_txn_context -> transaction_info .transfer_instruction_index ;
593
+ solana_txn_context -> extra_data .transfer_instruction_index ;
539
594
540
595
const uint8_t * token_mint = solana_txn_context -> transaction_info
541
596
.instruction [transfer_instruction_index ]
542
597
.program .transfer_checked .token_mint ;
543
- const solana_token_program_t * contract = NULL ;
544
- if (!is_token_whitelisted (token_mint , & contract )) {
598
+ solana_token_program_t contract = {0 };
599
+ const solana_token_program_t * contract_pointer = & contract ;
600
+ if (!is_token_whitelisted (token_mint , & contract_pointer )) {
545
601
// Contract Unverifed, Display warning
546
602
delay_scr_init (ui_text_unverified_token , DELAY_TIME );
547
603
@@ -570,13 +626,16 @@ static bool verify_solana_transfer_token_transaction() {
570
626
.decimal = token_decimals ,
571
627
};
572
628
573
- contract = & empty_contract ;
629
+ memcpy (& contract , & empty_contract , sizeof (empty_contract ));
630
+
574
631
} else {
632
+ memcpy (& contract , contract_pointer , sizeof (contract ));
633
+
575
634
char msg [100 ] = "" ;
576
635
snprintf (msg ,
577
636
sizeof (msg ),
578
637
UI_TEXT_SEND_TOKEN_PROMPT ,
579
- contract -> symbol ,
638
+ contract . symbol ,
580
639
SOLANA_NAME );
581
640
if (!core_confirmation (msg , solana_send_error )) {
582
641
return false;
@@ -632,7 +691,7 @@ static bool verify_solana_transfer_token_transaction() {
632
691
633
692
byte_array_to_hex_string (be_units , 8 , amount_string , sizeof (amount_string ));
634
693
if (!convert_byte_array_to_decimal_string (16 ,
635
- contract -> decimal ,
694
+ contract . decimal ,
636
695
amount_string ,
637
696
amount_decimal_string ,
638
697
sizeof (amount_decimal_string ))) {
@@ -644,11 +703,14 @@ static bool verify_solana_transfer_token_transaction() {
644
703
sizeof (display ),
645
704
UI_TEXT_VERIFY_AMOUNT ,
646
705
amount_decimal_string ,
647
- contract -> symbol );
706
+ contract . symbol );
648
707
if (!core_confirmation (display , solana_send_error )) {
649
708
return false;
650
709
}
651
710
711
+ if (!verify_priority_fee ())
712
+ return false;
713
+
652
714
set_app_flow_status (SOLANA_SIGN_TXN_STATUS_VERIFY );
653
715
return true;
654
716
}
0 commit comments