diff --git a/lib/opFns.js b/lib/opFns.js index 71c5a8d3ac..2d3ba8e217 100644 --- a/lib/opFns.js +++ b/lib/opFns.js @@ -470,6 +470,8 @@ module.exports = { return loaded }, DUP: function (runState) { + // NOTE: this function manipulates the stack directly! + const stackPos = runState.opCode - 0x7f if (stackPos > runState.stack.length) { trap(ERROR.STACK_UNDERFLOW) @@ -478,6 +480,8 @@ module.exports = { return runState.stack[runState.stack.length - stackPos] }, SWAP: function (runState) { + // NOTE: this function manipulates the stack directly! + var stackPos = runState.opCode - 0x8f // check the stack to make sure we have enough items on teh stack @@ -487,9 +491,10 @@ module.exports = { } // preform the swap - var newTop = runState.stack[swapIndex] - runState.stack[swapIndex] = runState.stack.pop() - return newTop + var topIndex = runState.stack.length - 1 + var tmp = runState.stack[topIndex] + runState.stack[topIndex] = runState.stack[swapIndex] + runState.stack[swapIndex] = tmp }, LOG: function (memOffset, memLength) { var args = Array.prototype.slice.call(arguments, 0) @@ -1023,8 +1028,7 @@ function makeCall (runState, callOptions, localOpts, cb) { // check if account has enough ether // Note: in the case of delegatecall, the value is persisted and doesn't need to be deducted again if (runState.depth >= fees.stackLimit.v || (callOptions.delegatecall !== true && new BN(runState.contract.balance).lt(callOptions.value))) { - runState.stack.push(Buffer.from([0])) - cb(null) + cb(null, Buffer.from([0])) } else { // if creating a new contract then increament the nonce if (!callOptions.to) {