From 16bd1020c3799742233048cac656157eb6acce3c Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 30 Jan 2020 17:10:44 +0100 Subject: [PATCH 1/6] added more tests and fixed bug when only receive declared --- src/app/ui/universal-dapp-ui.js | 18 ++++-- test-browser/tests/specialFunctions.js | 76 +++++++++++++++++++++----- 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/app/ui/universal-dapp-ui.js b/src/app/ui/universal-dapp-ui.js index bfb303206f..03a34c06db 100644 --- a/src/app/ui/universal-dapp-ui.js +++ b/src/app/ui/universal-dapp-ui.js @@ -133,7 +133,7 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address - + @@ -161,7 +161,7 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address const fallback = self.udapp.getFallbackInterface(contractABI) const receive = self.udapp.getReceiveInterface(contractABI) const args = { - funABI: fallback, + funABI: fallback || receive, address: address, contractName: contractName, contractABI: contractABI @@ -177,16 +177,22 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address } } if (calldata) { - if (calldata.length > 3 && calldata.substr(0, 2) === '0x') { + if (calldata.length < 2) setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') + if (calldata.length < 4 && calldata.substr(0, 2) === '0x') { + setLLIError('The calldata should be a valid hexadecimal value with size of at least one byte.') + } else if (calldata.substr(0, 2) === '0x') { if (!helper.isHexadecimal(calldata.substr(2, calldata.length))) { - setLLIError('the calldata should be a valid hexadecimal value.') + setLLIError('The calldata should be a valid hexadecimal value.') } + } else if (!helper.isHexadecimal(calldata)) { + setLLIError('The calldata should be a valid hexadecimal value.') } if (!fallback) { - setLLIError("'fallback' function is not defined") + setLLIError("'Fallback' function is not defined") } } - if ((calldata || amount !== '0') && !error) self.runTransaction(false, args, null, calldata, null) + if (!receive && !fallback) setLLIError("Both 'receive' and 'fallback' functions are not defined") + if (!error) self.runTransaction(false, args, null, calldata, null) } contractActionsWrapper.appendChild(lowLevelInteracions) diff --git a/test-browser/tests/specialFunctions.js b/test-browser/tests/specialFunctions.js index b1b7b2ce9e..0ef58c1bab 100644 --- a/test-browser/tests/specialFunctions.js +++ b/test-browser/tests/specialFunctions.js @@ -2,15 +2,6 @@ var init = require('../helpers/init') var sauce = require('./sauce') -/** - * both are declared, sending data - * both are declared - receive called, sending wei - * both are declared - fallback should fail cause not payable, sending data and wei - * receive is declared, failing, fallback is not declared, sending data - * receive is not declared, fallback is payable, sending wei - * receive is not declared, fallback is payable, sending data and wei - * both are not declared, sending data and wei, should fail - */ module.exports = { before: function (browser, done) { init(browser, done) @@ -36,6 +27,18 @@ module.exports = { }) }) }, + 'Use special functions receive/follback - both are declared - receive called, failing sending data < 1 byte': function (browser) { + // don't need to redeploy it, same contract + browser.perform((done) => { + browser.getAddressAtPosition(0, (address) => { + browser.sendLowLevelTx(address, '0', '0xa') + .pause(1000) + .waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`) + .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `size of at least one byte`) + .perform(done) + }) + }) + }, 'Use special functions receive/follback - both are declared - receive called, sending wei': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { @@ -61,7 +64,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - receive is declared, failing, fallback is not declared, sending data': function (browser) { + 'Use special functions receive/follback - only receive is declared, sending wei': function (browser) { browser.waitForElementVisible('#icon-panel', 10000) .testContracts('receiveOnly.sol', sources[1]['browser/receiveOnly.sol'], ['CheckSpecials']) .clickLaunchIcon('udapp') @@ -69,16 +72,29 @@ module.exports = { .createContract('') .clickInstance(1) .perform((done) => { + browser.getAddressAtPosition(1, (address) => { + browser.sendLowLevelTx(address, '1', '') + .pause(1000) + .journalLastChildIncludes('to:CheckSpecials.(receive)') + .journalLastChildIncludes('value:1 wei') + .journalLastChildIncludes('data:0x') + .perform(done) + }) + }) + }, + 'Use special functions receive/follback - only receive is declared, failing, fallback is not declared, sending data': function (browser) { + // don't need to redeploy it, same contract + browser.perform((done) => { browser.getAddressAtPosition(1, (address) => { browser.sendLowLevelTx(address, '0', '0xaa') .pause(1000) .waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`) - .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `'fallback' function is not defined`) + .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `'Fallback' function is not defined`) .perform(done) }) }) }, - 'Use special functions receive/fallback - receive is not declared, fallback is payable, sending wei': function (browser) { + 'Use special functions receive/fallback - only fallback is payable, sending wei': function (browser) { browser.waitForElementVisible('#icon-panel', 10000) .testContracts('fallbackOnlyPayable.sol', sources[2]['browser/fallbackOnlyPayable.sol'], ['CheckSpecials']) .clickLaunchIcon('udapp') @@ -96,7 +112,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - receive is not declared, fallback is payable, sending data and wei': function (browser) { + 'Use special functions receive/follback - only fallback is diclared and is payable, sending data and wei': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { browser.getAddressAtPosition(2, (address) => { @@ -109,7 +125,7 @@ module.exports = { }) }) }, - 'Use special functions receive/fallback - receive is not declared, fallback should fail cause not payable, sending wei': function (browser) { + 'Use special functions receive/fallback - only fallback is declared, fallback should fail cause not payable, sending wei': function (browser) { browser.waitForElementVisible('#icon-panel', 10000) .testContracts('fallbackOnlyNotPayable.sol', sources[3]['browser/fallbackOnlyNotPayable.sol'], ['CheckSpecials']) .clickLaunchIcon('udapp') @@ -136,7 +152,7 @@ module.exports = { .setValue('#value', 0) .createContract('') .clickInstance(4) - .pause(10000) + .pause(1000) .perform((done) => { browser.getAddressAtPosition(4, (address) => { browser.sendLowLevelTx(address, '1', '0xaa') @@ -147,6 +163,27 @@ module.exports = { .perform(done) }) }) + }, + 'Use special functions receive/fallback - receive and fallback are not declared, sending nothing': function (browser) { + browser.waitForElementVisible('#icon-panel', 10000) + .testContracts('notSpecial.sol', sources[5]['browser/notSpecial.sol'], ['CheckSpecials']) + .clickLaunchIcon('udapp') + .selectContract('CheckSpecials') + .waitForElementVisible('#value') + .clearValue('#value') + .setValue('#value', 0) + .createContract('') + .clickInstance(5) + .pause(1000) + .perform((done) => { + browser.getAddressAtPosition(5, (address) => { + browser.sendLowLevelTx(address, '0', '') + .pause(1000) + .waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`) + .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `Both 'receive' and 'fallback' functions are not defined`) + .perform(done) + }) + }) .end() }, tearDown: sauce @@ -199,5 +236,14 @@ var sources = [ } ` } + }, + { + 'browser/notSpecial.sol': { + content: ` + contract CheckSpecials { + function otherFallback() payable external {} + } + ` + } } ] From 5d8258ee182974eb367eedb102da0dcdbfdc3a92 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 30 Jan 2020 18:06:57 +0100 Subject: [PATCH 2/6] get funABI just before making the tx --- src/app/ui/universal-dapp-ui.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/app/ui/universal-dapp-ui.js b/src/app/ui/universal-dapp-ui.js index 03a34c06db..1e3a70c6a4 100644 --- a/src/app/ui/universal-dapp-ui.js +++ b/src/app/ui/universal-dapp-ui.js @@ -191,7 +191,17 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address setLLIError("'Fallback' function is not defined") } } - if (!receive && !fallback) setLLIError("Both 'receive' and 'fallback' functions are not defined") + + if (!receive && !fallback) setLLIError(`Both 'receive' and 'fallback' functions are not defined`) + + // we have to put the right function ABI: + // if receive is defined and that there is no calldata => receive function is called + // if fallback is defined => fallback function is called + if (receive && !calldata) args.funABI = receive + else if (fallback) args.funABI = fallback + + if (!args.funABI) setLLIError(`Please define at least a 'Fallback' with/without sending calldata or a 'Receive' without sending calldata`) + if (!error) self.runTransaction(false, args, null, calldata, null) } From 792ffc3e155c21117222e7f29cb5516bd30ebb72 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 30 Jan 2020 18:29:05 +0100 Subject: [PATCH 3/6] checking for even and new test --- src/app/ui/universal-dapp-ui.js | 22 +++++++++++----------- src/lib/helper.js | 5 ++++- test-browser/tests/specialFunctions.js | 16 ++++++++++++++-- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/app/ui/universal-dapp-ui.js b/src/app/ui/universal-dapp-ui.js index 1e3a70c6a4..e795225bb1 100644 --- a/src/app/ui/universal-dapp-ui.js +++ b/src/app/ui/universal-dapp-ui.js @@ -166,7 +166,6 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address contractName: contractName, contractABI: contractABI } - let calldata = calldataInput.value const amount = document.querySelector('#value').value if (amount !== '0') { // check for numeric and receive/fallback @@ -176,16 +175,17 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address setLLIError("In order to receive Ether transfer the contract should have either 'receive' or payable 'fallback' function") } } + let calldata = calldataInput.value if (calldata) { - if (calldata.length < 2) setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') - if (calldata.length < 4 && calldata.substr(0, 2) === '0x') { - setLLIError('The calldata should be a valid hexadecimal value with size of at least one byte.') - } else if (calldata.substr(0, 2) === '0x') { - if (!helper.isHexadecimal(calldata.substr(2, calldata.length))) { - setLLIError('The calldata should be a valid hexadecimal value.') + if (calldata.length < 2 || calldata.length < 4 && helper.is0XPrefixed(calldata)) { + setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') + } else { + if (helper.is0XPrefixed(calldata)) { + calldata = calldata.substr(2, calldata.length) + } + if (!helper.isHexadecimal(calldata)) { + setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') } - } else if (!helper.isHexadecimal(calldata)) { - setLLIError('The calldata should be a valid hexadecimal value.') } if (!fallback) { setLLIError("'Fallback' function is not defined") @@ -200,9 +200,9 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address if (receive && !calldata) args.funABI = receive else if (fallback) args.funABI = fallback - if (!args.funABI) setLLIError(`Please define at least a 'Fallback' with/without sending calldata or a 'Receive' without sending calldata`) + if (!args.funABI) setLLIError(`Please define a 'Fallback' function to send calldata and a either 'Receive' or payable 'Fallback' to send ethers`) - if (!error) self.runTransaction(false, args, null, calldata, null) + if (!error) self.runTransaction(false, args, null, calldataInput.value, null) } contractActionsWrapper.appendChild(lowLevelInteracions) diff --git a/src/lib/helper.js b/src/lib/helper.js index 93f688e4f9..cda3bfe519 100644 --- a/src/lib/helper.js +++ b/src/lib/helper.js @@ -45,7 +45,10 @@ module.exports = { return name.match(/[:*?"<>\\'|]/) != null }, isHexadecimal (value) { - return /^[0-9a-fA-F]+$/.test(value) + return /^[0-9a-fA-F]+$/.test(value) && (value.length % 2 === 0) + }, + is0XPrefixed (value) { + return value.substr(0, 2) === '0x' }, isNumeric (value) { return /^\+?(0|[1-9]\d*)$/.test(value) diff --git a/test-browser/tests/specialFunctions.js b/test-browser/tests/specialFunctions.js index 0ef58c1bab..fa773dcd85 100644 --- a/test-browser/tests/specialFunctions.js +++ b/test-browser/tests/specialFunctions.js @@ -34,7 +34,7 @@ module.exports = { browser.sendLowLevelTx(address, '0', '0xa') .pause(1000) .waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`) - .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `size of at least one byte`) + .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `the calldata should be a valid hexadecimal value with size of at least one byte.`) .perform(done) }) }) @@ -164,6 +164,18 @@ module.exports = { }) }) }, + 'Use special functions receive/fallback - receive and fallback are declared and payable, sending wei': function (browser) { + browser.perform((done) => { + browser.getAddressAtPosition(4, (address) => { + browser.sendLowLevelTx(address, '1', '') + .pause(1000) + .journalLastChildIncludes('to:CheckSpecials.(receive)') + .journalLastChildIncludes('value:1 wei') + .journalLastChildIncludes('data:0x') + .perform(done) + }) + }) + }, 'Use special functions receive/fallback - receive and fallback are not declared, sending nothing': function (browser) { browser.waitForElementVisible('#icon-panel', 10000) .testContracts('notSpecial.sol', sources[5]['browser/notSpecial.sol'], ['CheckSpecials']) @@ -180,7 +192,7 @@ module.exports = { browser.sendLowLevelTx(address, '0', '') .pause(1000) .waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`) - .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `Both 'receive' and 'fallback' functions are not defined`) + .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `Please define a 'Fallback' function to send calldata and a either 'Receive' or payable 'Fallback' to send ethers`) .perform(done) }) }) From 6bbd28e9a63856d27cbafee8a8822498ea00048c Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 30 Jan 2020 22:35:12 +0100 Subject: [PATCH 4/6] returning on error --- src/app/ui/universal-dapp-ui.js | 19 ++++++++----------- test-browser/tests/specialFunctions.js | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/app/ui/universal-dapp-ui.js b/src/app/ui/universal-dapp-ui.js index e795225bb1..97dae39f25 100644 --- a/src/app/ui/universal-dapp-ui.js +++ b/src/app/ui/universal-dapp-ui.js @@ -151,10 +151,8 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address ` function sendData () { - let error = false function setLLIError (text) { llIError.innerText = text - if (text !== '') error = true } setLLIError('') @@ -170,29 +168,29 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address if (amount !== '0') { // check for numeric and receive/fallback if (!helper.isNumeric(amount)) { - setLLIError('Value to send should be a number') + return setLLIError('Value to send should be a number') } else if (!receive && !(fallback && fallback.stateMutability === 'payable')) { - setLLIError("In order to receive Ether transfer the contract should have either 'receive' or payable 'fallback' function") + return setLLIError("In order to receive Ether transfer the contract should have either 'receive' or payable 'fallback' function") } } let calldata = calldataInput.value if (calldata) { if (calldata.length < 2 || calldata.length < 4 && helper.is0XPrefixed(calldata)) { - setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') + return setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') } else { if (helper.is0XPrefixed(calldata)) { calldata = calldata.substr(2, calldata.length) } if (!helper.isHexadecimal(calldata)) { - setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') + return setLLIError('the calldata should be a valid hexadecimal value with size of at least one byte.') } } if (!fallback) { - setLLIError("'Fallback' function is not defined") + return setLLIError("'Fallback' function is not defined") } } - if (!receive && !fallback) setLLIError(`Both 'receive' and 'fallback' functions are not defined`) + if (!receive && !fallback) return setLLIError(`Both 'receive' and 'fallback' functions are not defined`) // we have to put the right function ABI: // if receive is defined and that there is no calldata => receive function is called @@ -200,9 +198,8 @@ UniversalDAppUI.prototype.renderInstanceFromABI = function (contractABI, address if (receive && !calldata) args.funABI = receive else if (fallback) args.funABI = fallback - if (!args.funABI) setLLIError(`Please define a 'Fallback' function to send calldata and a either 'Receive' or payable 'Fallback' to send ethers`) - - if (!error) self.runTransaction(false, args, null, calldataInput.value, null) + if (!args.funABI) return setLLIError(`Please define a 'Fallback' function to send calldata and a either 'Receive' or payable 'Fallback' to send ethers`) + self.runTransaction(false, args, null, calldataInput.value, null) } contractActionsWrapper.appendChild(lowLevelInteracions) diff --git a/test-browser/tests/specialFunctions.js b/test-browser/tests/specialFunctions.js index fa773dcd85..2e1481b6f3 100644 --- a/test-browser/tests/specialFunctions.js +++ b/test-browser/tests/specialFunctions.js @@ -192,7 +192,7 @@ module.exports = { browser.sendLowLevelTx(address, '0', '') .pause(1000) .waitForElementVisible(`#instance${address} label[id="deployAndRunLLTxError"]`) - .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `Please define a 'Fallback' function to send calldata and a either 'Receive' or payable 'Fallback' to send ethers`) + .assert.containsText(`#instance${address} label[id="deployAndRunLLTxError"]`, `Both 'receive' and 'fallback' functions are not defined`) .perform(done) }) }) From 32071f6390aa49702d3fc1779758cae018316123 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 30 Jan 2020 22:40:26 +0100 Subject: [PATCH 5/6] typo --- test-browser/tests/specialFunctions.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test-browser/tests/specialFunctions.js b/test-browser/tests/specialFunctions.js index 2e1481b6f3..2ef57d0e2c 100644 --- a/test-browser/tests/specialFunctions.js +++ b/test-browser/tests/specialFunctions.js @@ -27,7 +27,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - both are declared - receive called, failing sending data < 1 byte': function (browser) { + 'Use special functions receive/fallback - both are declared - receive called, failing sending data < 1 byte': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { browser.getAddressAtPosition(0, (address) => { @@ -39,7 +39,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - both are declared - receive called, sending wei': function (browser) { + 'Use special functions receive/fallback - both are declared - receive called, sending wei': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { browser.getAddressAtPosition(0, (address) => { @@ -52,7 +52,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - both are declared - fallback should fail cause not payable, sending data and wei': function (browser) { + 'Use special functions receive/fallback - both are declared - fallback should fail cause not payable, sending data and wei': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { browser.getAddressAtPosition(0, (address) => { @@ -64,7 +64,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - only receive is declared, sending wei': function (browser) { + 'Use special functions receive/fallback - only receive is declared, sending wei': function (browser) { browser.waitForElementVisible('#icon-panel', 10000) .testContracts('receiveOnly.sol', sources[1]['browser/receiveOnly.sol'], ['CheckSpecials']) .clickLaunchIcon('udapp') @@ -82,7 +82,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - only receive is declared, failing, fallback is not declared, sending data': function (browser) { + 'Use special functions receive/fallback - only receive is declared, failing, fallback is not declared, sending data': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { browser.getAddressAtPosition(1, (address) => { @@ -112,7 +112,7 @@ module.exports = { }) }) }, - 'Use special functions receive/follback - only fallback is diclared and is payable, sending data and wei': function (browser) { + 'Use special functions receive/fallback - only fallback is diclared and is payable, sending data and wei': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { browser.getAddressAtPosition(2, (address) => { From 4f4d0baa0e13c272fdb1beab54e3c4815f47da5e Mon Sep 17 00:00:00 2001 From: LianaHus Date: Thu, 30 Jan 2020 22:43:42 +0100 Subject: [PATCH 6/6] test titles corrected --- test-browser/tests/specialFunctions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-browser/tests/specialFunctions.js b/test-browser/tests/specialFunctions.js index 2ef57d0e2c..acd150a69e 100644 --- a/test-browser/tests/specialFunctions.js +++ b/test-browser/tests/specialFunctions.js @@ -27,7 +27,7 @@ module.exports = { }) }) }, - 'Use special functions receive/fallback - both are declared - receive called, failing sending data < 1 byte': function (browser) { + 'Use special functions receive/fallback - both are declared, failing sending data < 1 byte': function (browser) { // don't need to redeploy it, same contract browser.perform((done) => { browser.getAddressAtPosition(0, (address) => { @@ -94,7 +94,7 @@ module.exports = { }) }) }, - 'Use special functions receive/fallback - only fallback is payable, sending wei': function (browser) { + 'Use special functions receive/fallback - only fallback declared and is payable, sending wei': function (browser) { browser.waitForElementVisible('#icon-panel', 10000) .testContracts('fallbackOnlyPayable.sol', sources[2]['browser/fallbackOnlyPayable.sol'], ['CheckSpecials']) .clickLaunchIcon('udapp')