Skip to content

Commit

Permalink
Merge pull request #268 from keepkey/pub-711
Browse files Browse the repository at this point in the history
release candidate v7.1.1
  • Loading branch information
markrypto authored Apr 21, 2021
2 parents 930d6ad + ae5d7b9 commit 6407e55
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 67 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.7.2)

project(KeepKeyFirmware

VERSION 7.1.0
VERSION 7.1.1

LANGUAGES C CXX ASM)

Expand Down
2 changes: 1 addition & 1 deletion deps/python-keepkey
37 changes: 37 additions & 0 deletions include/keepkey/firmware/ethereum_contracts/thortx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* This file is part of the KeepKey project.
*
* Copyright (C) 2021 ShapeShift
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef KEEPKEY_FIRMWARE_ETHEREUMCONTRACTS_THORTX_H
#define KEEPKEY_FIRMWARE_ETHEREUMCONTRACTS_THORTX_H

#include <inttypes.h>
#include <stdbool.h>

#define ETH_ADDRESS "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
#define ETH_NATIVE "\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee\xee"

#define THOR_ROUTER "42a5ed456650a09dc10ebc6361a7480fdd61f27b"

typedef struct _EthereumSignTx EthereumSignTx;

bool thor_isThorchainTx(const EthereumSignTx *msg);
bool thor_confirmThorTx(uint32_t data_total, const EthereumSignTx *msg);


#endif
1 change: 1 addition & 0 deletions lib/firmware/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(sources
ethereum_contracts.c
ethereum_contracts/makerdao.c
ethereum_contracts/zxappliquid.c
ethereum_contracts/thortx.c
ethereum_contracts/zxliquidtx.c
ethereum_contracts/zxswap.c
ethereum_tokens.c
Expand Down
39 changes: 0 additions & 39 deletions lib/firmware/ethereum.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,30 +77,6 @@ bool ethereum_isStandardERC20Approve(const EthereumSignTx *msg) {
return false;
}

bool ethereum_isThorchainTx(const EthereumSignTx *msg) {
if (msg->has_to && msg->to.size == 20 &&
memcmp(msg->data_initial_chunk.bytes,
"\x1f\xec\xe7\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
16) == 0) {
return true;
}
return false;
}

uint8_t ethereum_extractThorchainData(const EthereumSignTx *msg,
char *buffer) {
// Swap data begins 164 chars into data buffer:
// offset = deposit function hash + address + address + uint256
uint16_t offset = 4 + (5 * 32);
int16_t len = msg->data_length - offset;
if (msg->has_data_length && len > 0 && len < 256) {
memcpy(buffer, msg->data_initial_chunk.bytes + offset, len);
// String length must be < 255 characters
return (uint8_t)len;
}
return 0;
}

bool ethereum_getStandardERC20Recipient(const EthereumSignTx *msg,
char *address, size_t len) {
if (len < 2 * 20 + 1) return false;
Expand Down Expand Up @@ -674,21 +650,6 @@ void ethereum_signing_init(EthereumSignTx *msg, const HDNode *node,
data_needs_confirm = false;
}

// Detect THORChain transaction data in memo
if (ethereum_isThorchainTx(msg)) {
if (token == NULL && data_total > 0 && data_needs_confirm) {
char swap_data[256] = {'\0'};
uint8_t swap_data_len = ethereum_extractThorchainData(msg, swap_data);
if (!thorchain_parseConfirmMemo(swap_data, swap_data_len)) {
fsm_sendFailure(FailureType_Failure_Other, _("Malformed THORChain swap data"));
ethereum_signing_abort();
return;
}
needs_confirm = false;
data_needs_confirm = false;
}
}

// detect ERC-20 token
if (data_total == 68 && ethereum_isStandardERC20Transfer(msg)) {
token = tokenByChainAddress(chain_id, msg->to.bytes);
Expand Down
6 changes: 6 additions & 0 deletions lib/firmware/ethereum_contracts.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "keepkey/firmware/ethereum_contracts.h"

#include "keepkey/firmware/ethereum_contracts/thortx.h"
#include "keepkey/firmware/ethereum_contracts/zxappliquid.h"
#include "keepkey/firmware/ethereum_contracts/zxliquidtx.h"
#include "keepkey/firmware/ethereum_contracts/zxswap.h"
Expand All @@ -33,6 +34,8 @@ bool ethereum_contractHandled(uint32_t data_total, const EthereumSignTx *msg,
if (zx_isZxLiquidTx(msg)) return true;
if (zx_isZxApproveLiquid(msg)) return true;

if (thor_isThorchainTx(msg)) return true;

if (makerdao_isMakerDAO(data_total, msg)) return true;

return false;
Expand All @@ -50,6 +53,9 @@ bool ethereum_contractConfirmed(uint32_t data_total, const EthereumSignTx *msg,

if (zx_isZxApproveLiquid(msg))
return zx_confirmApproveLiquidity(data_total, msg);

if (thor_isThorchainTx(msg))
return thor_confirmThorTx(data_total, msg);

if (makerdao_isMakerDAO(data_total, msg))
return makerdao_confirmMakerDAO(data_total, msg);
Expand Down
119 changes: 119 additions & 0 deletions lib/firmware/ethereum_contracts/thortx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* This file is part of the KeepKey project.
*
* Copyright (C) 2021 ShapeShift
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

#include "keepkey/firmware/ethereum_contracts/thortx.h"

#include "keepkey/board/confirm_sm.h"
#include "keepkey/board/util.h"
#include "keepkey/firmware/ethereum.h"
#include "keepkey/firmware/ethereum_tokens.h"
#include "keepkey/firmware/fsm.h"
#include "keepkey/firmware/thorchain.h"
#include "trezor/crypto/address.h"

bool thor_isThorchainTx(const EthereumSignTx *msg) {
if (msg->has_to && msg->to.size == 20 &&
memcmp(msg->data_initial_chunk.bytes,
"\x1f\xec\xe7\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
16) == 0) {
return true;
}
return false;
}

bool thor_confirmThorTx(uint32_t data_total, const EthereumSignTx *msg) {
(void)data_total;

char confStr[41], *conf;
const TokenType *assetToken;
uint8_t *thorchainData, *vaultAddress, *assetAddress, *contractAssetAddress;
uint32_t ctr;
bignum256 Amount;

vaultAddress = (uint8_t *)(msg->data_initial_chunk.bytes + 4 + 12);
contractAssetAddress = (uint8_t *)(msg->data_initial_chunk.bytes + 4 + 32 + 12);
bn_from_bytes(msg->data_initial_chunk.bytes + 4 + 2*32, 32, &Amount);
thorchainData = (uint8_t *)(msg->data_initial_chunk.bytes + 4 + 5*32);

// Start confirmations
for (ctr=0; ctr<20; ctr++) {
snprintf(&confStr[ctr*2], 3, "%02x", msg->to.bytes[ctr]);
}
if (strncmp(confStr, THOR_ROUTER, sizeof(THOR_ROUTER)) == 0) {
conf = "Thorchain router";
} else {
conf = confStr;
}
if (!confirm(ButtonRequestType_ButtonRequest_ConfirmOutput,
"Thorchain data", "Routing through %s", conf)) {
return false;
}

// just display token address and amount as string
for (ctr=0; ctr<20; ctr++) {
snprintf(&confStr[ctr*2], 3, "%02x", vaultAddress[ctr]);
}
if (!confirm(ButtonRequestType_ButtonRequest_ConfirmOutput,
"Thorchain data", "Using Asgard vault %s", confStr)) {
return false;
}

if (memcmp(contractAssetAddress, ETH_ADDRESS, sizeof(ETH_ADDRESS)) == 0) {
assetAddress = (uint8_t *)ETH_NATIVE; // get eth native parameters if asset is not a token
} else {
assetAddress = contractAssetAddress;
}

assetToken = tokenByChainAddress(msg->chain_id, assetAddress);

if (strncmp(assetToken->ticker, " UNKN", 5) == 0) {

// just display token address and amount as string
for (ctr=0; ctr<20; ctr++) {
snprintf(&confStr[ctr*2], 3, "%02x", assetAddress[ctr]);
}
if (!confirm(ButtonRequestType_ButtonRequest_ConfirmOutput,
"Thorchain data", "from asset %s", confStr)) {
return false;
}
// We don't know what the exponent should be so just confirm raw unformatted number
bn_format(&Amount, NULL, " unformatted", 0, 0, false, confStr, sizeof(confStr));

if (!confirm(ButtonRequestType_ButtonRequest_ConfirmOutput,
"Thorchain data", "amount %s", confStr)) {
return false;
}

} else {
ethereumFormatAmount(&Amount, assetToken, msg->chain_id, confStr,
sizeof(confStr));

if (!confirm(ButtonRequestType_ButtonRequest_ConfirmOutput,
"Thorchain data", "Confirm sending %s", confStr)) {
return false;
}
}

if (!thorchain_parseConfirmMemo((const char *)thorchainData, 64))
return false;

return true;
}


20 changes: 10 additions & 10 deletions lib/firmware/ethereum_contracts/zxliquidtx.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ bool zx_isZxLiquidTx(const EthereumSignTx *msg) {
bool zx_confirmZxLiquidTx(uint32_t data_total, const EthereumSignTx *msg) {
(void)data_total;
const TokenType *token;
char constr1[40], constr2[40], *arStr = "";
char constr1[40], constr2[40], tokbuf[32], *arStr = "";
uint8_t *tokenAddress, *deadlineBytes;
bignum256 tokenAmount, tokenMinAmount, ethMinAmount;
bignum256 Amount;
uint64_t deadline;

if (isAddLiquidityEthCall(msg)) {
Expand All @@ -139,9 +139,6 @@ bool zx_confirmZxLiquidTx(uint32_t data_total, const EthereumSignTx *msg) {

tokenAddress = (uint8_t *)(msg->data_initial_chunk.bytes + 4 + 32 - 20);
token = tokenByChainAddress(msg->chain_id, tokenAddress);
bn_from_bytes(msg->data_initial_chunk.bytes + 4 + 32, 32, &tokenAmount);
bn_from_bytes(msg->data_initial_chunk.bytes + 4 + 2*32, 32, &tokenMinAmount);
bn_from_bytes(msg->data_initial_chunk.bytes + 4 + 3*32, 32, &ethMinAmount);
deadlineBytes = (uint8_t *)(msg->data_initial_chunk.bytes + 4 + 6*32 - 8);
deadline = ((uint64_t)deadlineBytes[0] << 8*7) |
((uint64_t)deadlineBytes[1] << 8*6) |
Expand All @@ -152,18 +149,21 @@ bool zx_confirmZxLiquidTx(uint32_t data_total, const EthereumSignTx *msg) {
((uint64_t)deadlineBytes[6] << 8*1) |
((uint64_t)deadlineBytes[7]);

char tokbuf[32];
ethereumFormatAmount(&tokenAmount, token, msg->chain_id, tokbuf, sizeof(tokbuf));
bn_from_bytes(msg->data_initial_chunk.bytes + 4 + 32, 32, &Amount); // token amount
ethereumFormatAmount(&Amount, token, msg->chain_id, tokbuf, sizeof(tokbuf));
snprintf(constr1, 32, "%s", tokbuf);
ethereumFormatAmount(&tokenMinAmount, token, msg->chain_id, tokbuf, sizeof(tokbuf));
bn_from_bytes(msg->data_initial_chunk.bytes + 4 + 2*32, 32, &Amount); // token min amount
ethereumFormatAmount(&Amount, token, msg->chain_id, tokbuf, sizeof(tokbuf));
snprintf(constr2, 32, "%s", tokbuf);
confirm(ButtonRequestType_ButtonRequest_ConfirmOutput, arStr,
"%s\nMinimum %s", constr1, constr2);
if (!confirmFromAccountMatch(msg, arStr)) {
return false;
}

ethereumFormatAmount(&ethMinAmount, NULL, msg->chain_id, tokbuf, sizeof(tokbuf));

bn_from_bytes(msg->data_initial_chunk.bytes + 4 + 3*32, 32, &Amount); // eth min amount
ethereumFormatAmount(&Amount, NULL, msg->chain_id, tokbuf, sizeof(tokbuf));

snprintf(constr1, 32, "%s", tokbuf);
confirm(ButtonRequestType_ButtonRequest_ConfirmOutput, arStr,
"Minimum %s", constr1);
Expand Down
2 changes: 1 addition & 1 deletion lib/firmware/ethereum_contracts/zxswap.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,5 @@ bool zx_confirmZxSwap(uint32_t data_total, const EthereumSignTx *msg) {
return confirm(ButtonRequestType_ButtonRequest_ConfirmOutput, exchange,
"Sell %s\nBuy at least %s", constr1, constr2);

return true;
return true;
}
15 changes: 8 additions & 7 deletions lib/firmware/fsm_msg_thorchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void fsm_msgThorchainGetAddress(const ThorchainGetAddress *msg) {
char mainnet[] = "thor";
char testnet[] = "tthor";
char *pfix;

if (!node) {
return;
}
Expand Down Expand Up @@ -191,7 +191,8 @@ void fsm_msgThorchainMsgAck(const ThorchainMsgAck *msg) {
// See if we can parse the memo
if (!thorchain_parseConfirmMemo(sign_tx->memo, sizeof(sign_tx->memo))) {
// Memo not recognizable, ask to confirm it
if (!confirm(ButtonRequestType_ButtonRequest_ConfirmMemo, _("Memo"), "%s", sign_tx->memo)) {
if (!confirm(ButtonRequestType_ButtonRequest_ConfirmMemo, _("Memo"), "%s",
sign_tx->memo)) {
thorchain_signAbort();
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
layoutHome();
Expand All @@ -200,7 +201,6 @@ void fsm_msgThorchainMsgAck(const ThorchainMsgAck *msg) {
}
}


char node_str[NODE_STRING_LENGTH];
if (!bip32_node_to_string(node_str, sizeof(node_str), coin,
sign_tx->address_n, sign_tx->address_n_count,
Expand All @@ -212,9 +212,9 @@ void fsm_msgThorchainMsgAck(const ThorchainMsgAck *msg) {
}

if (!confirm(ButtonRequestType_ButtonRequest_SignTx, node_str,
"Sign this THORChain transaction on %s? "
"It includes a fee of %" PRIu32 " RUNE and %" PRIu32 " gas.",
sign_tx->chain_id, sign_tx->fee_amount, sign_tx->gas)) {
"Sign this RUNE transaction on %s? "
"Additional network fees apply.",
sign_tx->chain_id)) {
thorchain_signAbort();
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
layoutHome();
Expand All @@ -223,7 +223,8 @@ void fsm_msgThorchainMsgAck(const ThorchainMsgAck *msg) {

RESP_INIT(ThorchainSignedTx);

if (!thorchain_signTxFinalize(resp->public_key.bytes, resp->signature.bytes)) {
if (!thorchain_signTxFinalize(resp->public_key.bytes,
resp->signature.bytes)) {
thorchain_signAbort();
fsm_sendFailure(FailureType_Failure_SyntaxError,
"Failed to finalize signature");
Expand Down
Loading

0 comments on commit 6407e55

Please sign in to comment.