From 2336aa4e6ff90ea14c57900ccd24bf70986c85d0 Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Thu, 25 Mar 2021 17:19:05 +1100 Subject: [PATCH] fix: custom token validation for non-token addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When contract addresses that are not ERC-20 or ERC-721 were input, the token would be allowed to be added and would crash the app. In addition, when an ERC-20 contract was deployed without a name and symbol, “Invalid ERC-20 address” would appear. This PR adds error checking from the token detail lookup and reports the error back to the user in the modal. This prevents non-ERC-20/721 contracts from being able to be added to the app and prevents a crash. --- src/app/wallet/views/token_list.nim | 32 +++++++++++-------- .../AppLayouts/Wallet/AddCustomTokenModal.qml | 8 +++-- ui/shared/Input.qml | 3 +- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/app/wallet/views/token_list.nim b/src/app/wallet/views/token_list.nim index 1ecc7c203b..817ac2439b 100644 --- a/src/app/wallet/views/token_list.nim +++ b/src/app/wallet/views/token_list.nim @@ -1,5 +1,5 @@ import # nim libs - tables, json + strformat, tables, json import # vendor libs NimQml @@ -21,18 +21,24 @@ type address: string const getTokenDetailsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = - let - arg = decode[GetTokenDetailsTaskArg](argEncoded) - tkn = newErc20Contract(getCurrentNetwork(), arg.address.parseAddress) - decimals = tkn.tokenDecimals() - - let output = %* { - "address": arg.address, - "name": tkn.tokenName(), - "symbol": tkn.tokenSymbol(), - "decimals": (if decimals == 0: "" else: $decimals) - } - arg.finish(output) + let arg = decode[GetTokenDetailsTaskArg](argEncoded) + try: + let + tkn = newErc20Contract(getCurrentNetwork(), arg.address.parseAddress) + decimals = tkn.tokenDecimals() + output = %* { + "address": arg.address, + "name": tkn.tokenName(), + "symbol": tkn.tokenSymbol(), + "decimals": (if decimals == 0: "" else: $decimals) + } + arg.finish(output) + except Exception as e: + let output = %* { + "address": arg.address, + "error": fmt"{e.msg}. Is this an ERC-20 or ERC-721 contract?", + } + arg.finish(output) proc getTokenDetails[T](self: T, slot: string, address: string) = let arg = GetTokenDetailsTaskArg( diff --git a/ui/app/AppLayouts/Wallet/AddCustomTokenModal.qml b/ui/app/AppLayouts/Wallet/AddCustomTokenModal.qml index 90019d96b0..627f4c024d 100644 --- a/ui/app/AppLayouts/Wallet/AddCustomTokenModal.qml +++ b/ui/app/AppLayouts/Wallet/AddCustomTokenModal.qml @@ -67,13 +67,17 @@ ModalPopup { target: walletModel.customTokenList onTokenDetailsWereResolved: { const jsonObj = JSON.parse(tokenDetails) - if(jsonObj.name === "" || jsonObj.symbol === "" || jsonObj.decimals === ""){ + if (jsonObj.error) { + validationError = jsonObj.error + return + } + if (jsonObj.name === "" && jsonObj.symbol === "" && jsonObj.decimals === "") { //% "Invalid ERC20 address" validationError = qsTrId("invalid-erc20-address") return; } - if(addressInput.text.toLowerCase() === jsonObj.address.toLowerCase()){ + if (addressInput.text.toLowerCase() === jsonObj.address.toLowerCase()) { symbolInput.text = jsonObj.symbol; decimalsInput.text = jsonObj.decimals; nameInput.text = jsonObj.name; diff --git a/ui/shared/Input.qml b/ui/shared/Input.qml index 54424248a6..3557cb8c82 100644 --- a/ui/shared/Input.qml +++ b/ui/shared/Input.qml @@ -179,7 +179,8 @@ Item { font.pixelSize: 12 height: 16 color: Style.current.danger - width: parent.width + width: inputRectangle.width + wrapMode: TextEdit.Wrap } }