diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go
index 900a3ff4dded1fc950dc8a62c05cbf36735e1122..17b40bc5ef9d8532d929aba0c3b2e6cb8f6de933 100644
--- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go
+++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/test/vm_test.go
@@ -8,13 +8,20 @@ import (
 	"testing"
 	"time"
 
+	"errors"
+
 	. "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/common"
 	"github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/events"
 	ptypes "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/permission/types"
 	"github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/types"
 	. "github.com/eris-ltd/eris-db/Godeps/_workspace/src/github.com/tendermint/tendermint/vm"
+	"github.com/stretchr/testify/assert"
 )
 
+func init() {
+	SetDebug(true)
+}
+
 func newAppState() *FakeAppState {
 	fas := &FakeAppState{
 		accounts: make(map[string]*Account),
@@ -154,65 +161,164 @@ func TestSendCall(t *testing.T) {
 
 	//----------------------------------------------
 	// account2 has insufficient balance, should fail
-	fmt.Println("Should fail with insufficient balance")
-
-	exception := runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 1000)
-	if exception == "" {
-		t.Fatal("Expected exception")
-	}
+	_, err := runVMWaitError(ourVm, account1, account2, addr, contractCode, 1000)
+	assert.Error(t, err, "Expected insufficient balance error")
 
 	//----------------------------------------------
 	// give account2 sufficient balance, should pass
-
 	account2.Balance = 100000
-	exception = runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 1000)
-	if exception != "" {
-		t.Fatal("Unexpected exception", exception)
-	}
+	_, err = runVMWaitError(ourVm, account1, account2, addr, contractCode, 1000)
+	assert.NoError(t, err, "Should have sufficient balance")
 
 	//----------------------------------------------
 	// insufficient gas, should fail
-	fmt.Println("Should fail with insufficient gas")
 
 	account2.Balance = 100000
-	exception = runVMWaitEvents(t, ourVm, account1, account2, addr, contractCode, 100)
-	if exception == "" {
-		t.Fatal("Expected exception")
+	_, err = runVMWaitError(ourVm, account1, account2, addr, contractCode, 100)
+	assert.Error(t, err, "Expected insufficient gas error")
+}
+
+// This test was introduced to cover an issues exposed in our handling of the
+// gas limit passed from caller to callee on various forms of CALL
+// this ticket gives some background: https://github.com/eris-ltd/eris-pm/issues/212
+// The idea of this test is to implement a simple DelegateCall in EVM code
+// We first run the DELEGATECALL with _just_ enough gas expecting a simple return,
+// and then run it with 1 gas unit less, expecting a failure
+func TestDelegateCallGas(t *testing.T) {
+	appState := newAppState()
+	ourVm := NewVM(appState, newParams(), Zero256, nil)
+
+	inOff := 0
+	inSize := 0 // no call data
+	retOff := 0
+	retSize := 32
+	calleeReturnValue := int64(20)
+
+	// DELEGATECALL(retSize, refOffset, inSize, inOffset, addr, gasLimit)
+	// 6 pops
+	delegateCallCost := GasStackOp * 6
+	// 1 push
+	gasCost := GasStackOp
+	// 2 pops, 1 push
+	subCost := GasStackOp * 3
+	pushCost := GasStackOp
+
+	costBetweenGasAndDelegateCall := gasCost + subCost + delegateCallCost + pushCost
+
+	// Do a simple operation using 1 gas unit
+	calleeAccount, calleeAddress := makeAccountWithCode(appState, "callee",
+		bytecode(PUSH1, calleeReturnValue, return1()))
+
+	// Here we split up the caller code so we can make a DELEGATE call with
+	// different amounts of gas. The value we sandwich in the middle is the amount
+	// we subtract from the available gas (that the caller has available), so:
+	// code := bytecode(callerCodePrefix, <amount to subtract from GAS> , callerCodeSuffix)
+	// gives us the code to make the call
+	callerCodePrefix := bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize,
+		PUSH1, inOff, PUSH20, calleeAddress, PUSH1)
+	callerCodeSuffix := bytecode(GAS, SUB, DELEGATECALL, returnWord())
+
+	// Perform a delegate call
+	callerAccount, _ := makeAccountWithCode(appState, "caller",
+		bytecode(callerCodePrefix,
+			// Give just enough gas to make the DELEGATECALL
+			costBetweenGasAndDelegateCall,
+			callerCodeSuffix))
+
+	// Should pass
+	output, err := runVMWaitError(ourVm, callerAccount, calleeAccount, calleeAddress,
+		callerAccount.Code, 100)
+	assert.NoError(t, err, "Should have sufficient funds for call")
+	assert.Equal(t, Int64ToWord256(calleeReturnValue).Bytes(), output)
+
+	callerAccount.Code = bytecode(callerCodePrefix,
+		// Shouldn't be enough gas to make call
+		costBetweenGasAndDelegateCall-1,
+		callerCodeSuffix)
+
+	// Should fail
+	_, err = runVMWaitError(ourVm, callerAccount, calleeAccount, calleeAddress,
+		callerAccount.Code, 100)
+	assert.Error(t, err, "Should have insufficient funds for call")
+}
+
+// Store the top element of the stack (which is a 32-byte word) in memory
+// and return it. Useful for a simple return value.
+func return1() []byte {
+	return bytecode(PUSH1, 0, MSTORE, returnWord())
+}
+
+func returnWord() []byte {
+	// PUSH1 => return size, PUSH1 => return offset, RETURN
+	return bytecode(PUSH1, 32, PUSH1, 0, RETURN)
+}
+
+func makeAccountWithCode(appState AppState, name string,
+	code []byte) (*Account, []byte) {
+	account := &Account{
+		Address: LeftPadWord256([]byte(name)),
+		Balance: 9999999,
+		Code:    code,
+		Nonce:   0,
+	}
+	account.Code = code
+	appState.UpdateAccount(account)
+	// Sanity check
+	address := new([20]byte)
+	for i, b := range account.Address.Postfix(20) {
+		address[i] = b
+	}
+	return account, address[:]
+}
+
+// Subscribes to an AccCall, runs the vm, returns the output any direct exception
+// and then waits for any exceptions transmitted by EventData in the AccCall
+// event (in the case of no direct error from call we will block waiting for
+// at least 1 AccCall event)
+func runVMWaitError(ourVm *VM, caller, callee *Account, subscribeAddr,
+	contractCode []byte, gas int64) (output []byte, err error) {
+	eventCh := make(chan types.EventData)
+	output, err = runVM(eventCh, ourVm, caller, callee, subscribeAddr,
+		contractCode, gas)
+	if err != nil {
+		return
+	}
+	msg := <-eventCh
+	var errString string
+	switch ev := msg.(type) {
+	case types.EventDataTx:
+		errString = ev.Exception
+	case types.EventDataCall:
+		errString = ev.Exception
+	}
+
+	if errString != "" {
+		err = errors.New(errString)
 	}
+	return
 }
 
-// subscribes to an AccCall, runs the vm, returns the exception
-func runVMWaitEvents(t *testing.T, ourVm *VM, caller, callee *Account, subscribeAddr, contractCode []byte, gas int64) string {
+// Subscribes to an AccCall, runs the vm, returns the output and any direct
+// exception
+func runVM(eventCh chan types.EventData, ourVm *VM, caller, callee *Account,
+	subscribeAddr, contractCode []byte, gas int64) ([]byte, error) {
+
 	// we need to catch the event from the CALL to check for exceptions
 	evsw := events.NewEventSwitch()
 	evsw.Start()
-	ch := make(chan interface{})
 	fmt.Printf("subscribe to %x\n", subscribeAddr)
-	evsw.AddListenerForEvent("test", types.EventStringAccCall(subscribeAddr), func(msg types.EventData) {
-		ch <- msg
-	})
+	evsw.AddListenerForEvent("test", types.EventStringAccCall(subscribeAddr),
+		func(msg types.EventData) {
+			eventCh <- msg
+		})
 	evc := events.NewEventCache(evsw)
 	ourVm.SetFireable(evc)
-	go func() {
-		start := time.Now()
-		output, err := ourVm.Call(caller, callee, contractCode, []byte{}, 0, &gas)
-		fmt.Printf("Output: %v Error: %v\n", output, err)
-		fmt.Println("Call took:", time.Since(start))
-		if err != nil {
-			ch <- err.Error()
-		}
-		evc.Flush()
-	}()
-	msg := <-ch
-	switch ev := msg.(type) {
-	case types.EventDataTx:
-		return ev.Exception
-	case types.EventDataCall:
-		return ev.Exception
-	case string:
-		return ev
-	}
-	return ""
+	start := time.Now()
+	output, err := ourVm.Call(caller, callee, contractCode, []byte{}, 0, &gas)
+	fmt.Printf("Output: %v Error: %v\n", output, err)
+	fmt.Println("Call took:", time.Since(start))
+	go func() { evc.Flush() }()
+	return output, err
 }
 
 // this is code to call another contract (hardcoded as addr)
@@ -222,10 +328,92 @@ func callContractCode(addr []byte) []byte {
 	inOff, inSize := byte(0x0), byte(0x0) // no call data
 	retOff, retSize := byte(0x0), byte(0x20)
 	// this is the code we want to run (send funds to an account and return)
+	return bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
+		inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize,
+		PUSH1, retOff, RETURN)
+}
+
+func TestBytecode(t *testing.T) {
+	assert.Equal(t,
+		bytecode(1, 2, 3, 4, 5, 6),
+		bytecode(1, 2, 3, bytecode(4, 5, 6)))
+	assert.Equal(t,
+		bytecode(1, 2, 3, 4, 5, 6, 7, 8),
+		bytecode(1, 2, 3, bytecode(4, bytecode(5), 6), 7, 8))
+	assert.Equal(t,
+		bytecode(PUSH1, 2),
+		bytecode(byte(PUSH1), 0x02))
+	assert.Equal(t,
+		[]byte{},
+		bytecode(bytecode(bytecode())))
+
+	contractAccount := &Account{Address: Int64ToWord256(102)}
+	addr := contractAccount.Address.Postfix(20)
+	gas1, gas2 := byte(0x1), byte(0x1)
+	value := byte(0x69)
+	inOff, inSize := byte(0x0), byte(0x0) // no call data
+	retOff, retSize := byte(0x0), byte(0x20)
+	contractCodeBytecode := bytecode(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
+		inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize,
+		PUSH1, retOff, RETURN)
 	contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73}
 	contractCode = append(contractCode, addr...)
 	contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...)
-	return contractCode
+	assert.Equal(t, contractCode, contractCodeBytecode)
+}
+
+func TestConcat(t *testing.T) {
+	assert.Equal(t,
+		[]byte{0x01, 0x02, 0x03, 0x04},
+		concat([]byte{0x01, 0x02}, []byte{0x03, 0x04}))
+}
+
+// Convenience function to allow us to mix bytes, ints, and OpCodes that
+// represent bytes in an EVM assembly code to make assembly more readable.
+// Also allows us to splice together assembly
+// fragments because any []byte arguments are flattened in the result.
+func bytecode(bytelikes ...interface{}) []byte {
+	bytes := make([]byte, len(bytelikes))
+	for i, bytelike := range bytelikes {
+		switch b := bytelike.(type) {
+		case byte:
+			bytes[i] = b
+		case OpCode:
+			bytes[i] = byte(b)
+		case int:
+			bytes[i] = byte(b)
+			if int(bytes[i]) != b {
+				panic(fmt.Sprintf("The int %v does not fit inside a byte", b))
+			}
+		case int64:
+			bytes[i] = byte(b)
+			if int64(bytes[i]) != b {
+				panic(fmt.Sprintf("The int64 %v does not fit inside a byte", b))
+			}
+		case []byte:
+			// splice
+			return concat(bytes[:i], b, bytecode(bytelikes[i+1:]...))
+		default:
+			panic("Only byte-like codes (and []byte sequences) can be used to form bytecode")
+		}
+	}
+	return bytes
+}
+
+func concat(bss ...[]byte) []byte {
+	offset := 0
+	for _, bs := range bss {
+		offset += len(bs)
+	}
+	bytes := make([]byte, offset)
+	offset = 0
+	for _, bs := range bss {
+		for i, b := range bs {
+			bytes[offset+i] = b
+		}
+		offset += len(bs)
+	}
+	return bytes
 }
 
 /*
diff --git a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go
index f79a3d28734bc69ceaa0a8139d52fb2ad1b5d633..e1f9c7e4a6b9f3fa91eea3ce9095ac1314dce716 100644
--- a/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go
+++ b/Godeps/_workspace/src/github.com/tendermint/tendermint/vm/vm.go
@@ -17,7 +17,7 @@ var (
 	ErrUnknownAddress      = errors.New("Unknown address")
 	ErrInsufficientBalance = errors.New("Insufficient balance")
 	ErrInvalidJumpDest     = errors.New("Invalid jump dest")
-	ErrInsufficientGas     = errors.New("Insuffient gas")
+	ErrInsufficientGas     = errors.New("Insufficient gas")
 	ErrMemoryOutOfBounds   = errors.New("Memory out of bounds")
 	ErrCodeOutOfBounds     = errors.New("Code out of bounds")
 	ErrInputOutOfBounds    = errors.New("Input out of bounds")
@@ -194,7 +194,6 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 	)
 
 	for {
-
 		// Use BaseOp gas.
 		if useGasNegative(gas, GasBaseOp, &err) {
 			return nil, err
@@ -816,7 +815,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 					exception = err.Error()
 				}
 				// NOTE: these fire call events and not particular events for eg name reg or permissions
-				vm.fireCallEvent(&exception, &ret, callee, &Account{Address: addr}, args, value, gas)
+				vm.fireCallEvent(&exception, &ret, callee, &Account{Address: addr}, args, value, &gasLimit)
 			} else {
 				// EVM contract
 				if useGasNegative(gas, GasGetAccount, &err) {
@@ -831,12 +830,12 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 					if acc == nil {
 						return nil, firstErr(err, ErrUnknownAddress)
 					}
-					ret, err = vm.Call(callee, callee, acc.Code, args, value, gas)
+					ret, err = vm.Call(callee, callee, acc.Code, args, value, &gasLimit)
 				} else if op == DELEGATECALL {
 					if acc == nil {
 						return nil, firstErr(err, ErrUnknownAddress)
 					}
-					ret, err = vm.DelegateCall(caller, callee, acc.Code, args, value, gas)
+					ret, err = vm.DelegateCall(caller, callee, acc.Code, args, value, &gasLimit)
 				} else {
 					// nil account means we're sending funds to a new account
 					if acc == nil {
@@ -847,7 +846,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 					}
 					// add account to the tx cache
 					vm.appState.UpdateAccount(acc)
-					ret, err = vm.Call(callee, acc, acc.Code, args, value, gas)
+					ret, err = vm.Call(callee, acc, acc.Code, args, value, &gasLimit)
 				}
 			}
 
@@ -906,7 +905,6 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
 		}
 
 		pc++
-
 	}
 }