diff options
Merge pull request #296 from MetaMask/i252
idStore - add DELEGATE_CALL detection
Diffstat (limited to 'app')
-rw-r--r-- | app/scripts/background.js | 22 | ||||
-rw-r--r-- | app/scripts/lib/idStore.js | 44 |
2 files changed, 47 insertions, 19 deletions
diff --git a/app/scripts/background.js b/app/scripts/background.js index 1098efe87..3ad95d3e9 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -248,15 +248,15 @@ function updateBadge(state){ // Add unconfirmed Tx + Msg // -function newUnsignedTransaction(txParams, cb){ +function newUnsignedTransaction(txParams, onTxDoneCb){ var state = idStore.getState() if (!state.isUnlocked) { createUnlockRequestNotification({ title: 'Account Unlock Request', }) - var txId = idStore.addUnconfirmedTransaction(txParams, cb) + idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, noop) } else { - addUnconfirmedTx(txParams, cb) + addUnconfirmedTx(txParams, onTxDoneCb) } } @@ -272,13 +272,15 @@ function newUnsignedMessage(msgParams, cb){ } } -function addUnconfirmedTx(txParams, cb){ - var txId = idStore.addUnconfirmedTransaction(txParams, cb) - createTxNotification({ - title: 'New Unsigned Transaction', - txParams: txParams, - confirm: idStore.approveTransaction.bind(idStore, txId, noop), - cancel: idStore.cancelTransaction.bind(idStore, txId), +function addUnconfirmedTx(txParams, onTxDoneCb){ + idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, function(err, txData){ + if (err) return onTxDoneCb(err) + createTxNotification({ + title: 'New Unsigned Transaction', + txParams: txParams, + confirm: idStore.approveTransaction.bind(idStore, txData.id, noop), + cancel: idStore.cancelTransaction.bind(idStore, txData.id), + }) }) } diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js index a0bfa9d3a..d569174dc 100644 --- a/app/scripts/lib/idStore.js +++ b/app/scripts/lib/idStore.js @@ -1,12 +1,14 @@ const EventEmitter = require('events').EventEmitter const inherits = require('util').inherits const Transaction = require('ethereumjs-tx') +const ethUtil = require('ethereumjs-util') const LightwalletKeyStore = require('eth-lightwallet').keystore const LightwalletSigner = require('eth-lightwallet').signing const async = require('async') const clone = require('clone') const extend = require('xtend') const createId = require('web3-provider-engine/util/random-id') +const ethBinToOps = require('eth-bin-to-ops') const autoFaucet = require('./auto-faucet') const configManager = require('./config-manager-singleton') const messageManager = require('./message-manager') @@ -182,13 +184,13 @@ IdentityStore.prototype.exportAccount = function(address, cb) { // // comes from dapp via zero-client hooked-wallet provider -IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, cb){ - +IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, onTxDoneCb, cb){ + var self = this // create txData obj with parameters and meta data var time = (new Date()).getTime() var txId = createId() txParams.metamaskId = txId - txParams.metamaskNetworkId = this._currentState.network + txParams.metamaskNetworkId = self._currentState.network var txData = { id: txId, txParams: txParams, @@ -198,14 +200,38 @@ IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, cb){ configManager.addTx(txData) console.log('addUnconfirmedTransaction:', txData) - // keep the cb around for after approval (requires user interaction) - // This cb fires completion to the Dapp's write operation. - this._unconfTxCbs[txId] = cb + // keep the onTxDoneCb around for after approval/denial (requires user interaction) + // This onTxDoneCb fires completion to the Dapp's write operation. + self._unconfTxCbs[txId] = onTxDoneCb + + // perform static analyis on the target contract code + var provider = self._ethStore._query.currentProvider + if (txParams.to) { + provider.sendAsync({ id: 1, method: 'eth_getCode', params: [txParams.to, 'latest'] }, function(err, res){ + if (err) return didComplete(err) + if (res.error) return didComplete(res.error) + var code = ethUtil.toBuffer(res.result) + if (code !== '0x') { + var ops = ethBinToOps(code) + var containsDelegateCall = ops.some((op)=>op.name === 'DELEGATECALL') + txData.containsDelegateCall = containsDelegateCall + didComplete() + } else { + didComplete() + } + }) + } else { + didComplete() + } - // signal update - this._didUpdate() + function didComplete(err){ + if (err) return cb(err) + // signal update + self._didUpdate() + // signal completion of add tx + cb(null, txData) + } - return txId } // comes from metamask ui |