diff --git a/logging/loggers/eris_format_logger.go b/logging/loggers/burrow_format_logger.go
similarity index 96%
rename from logging/loggers/eris_format_logger.go
rename to logging/loggers/burrow_format_logger.go
index 041ab6111e5f983097244bf0916bded4edba8697..653e1963d1598a156386094f2a8c6f9639872df3 100644
--- a/logging/loggers/eris_format_logger.go
+++ b/logging/loggers/burrow_format_logger.go
@@ -55,6 +55,6 @@ func burrowFormatKeyValueMapper(key, value interface{}) (interface{}, interface{
 	return key, value
 }
 
-func MonaxFormatLogger(logger kitlog.Logger) *burrowFormatLogger {
+func BurrowFormatLogger(logger kitlog.Logger) *burrowFormatLogger {
 	return &burrowFormatLogger{logger: logger}
 }
diff --git a/logging/loggers/info_trace_logger.go b/logging/loggers/info_trace_logger.go
index 574ef51c7c62f4a0e0ea629718c19420a25448f3..1f87e151f18c76ba669ba14ecf2b5abe5809e4fe 100644
--- a/logging/loggers/info_trace_logger.go
+++ b/logging/loggers/info_trace_logger.go
@@ -105,6 +105,6 @@ func (l *infoTraceLogger) Log(keyvals ...interface{}) error {
 // Wrap the output loggers with a a set of standard transforms, a non-blocking
 // ChannelLogger and an outer context
 func wrapOutputLogger(outputLogger kitlog.Logger) *kitlog.Context {
-	return kitlog.NewContext(NonBlockingLogger(ErisFormatLogger(
+	return kitlog.NewContext(NonBlockingLogger(BurrowFormatLogger(
 		VectorValuedLogger(outputLogger))))
 }
diff --git a/manager/burrow-mint/burrow-mint.go b/manager/burrow-mint/burrow-mint.go
index 2af425af915d5718244d19719fa503a0632dedfc..790bad39ca164c9e864f3228e255c3e4329217ac 100644
--- a/manager/burrow-mint/burrow-mint.go
+++ b/manager/burrow-mint/burrow-mint.go
@@ -27,7 +27,7 @@ import (
 	"github.com/monax/burrow/logging"
 	logging_types "github.com/monax/burrow/logging/types"
 
-	sm "github.com/monax/burrow/manager/eris-mint/state"
+	sm "github.com/monax/burrow/manager/burrow-mint/state"
 	manager_types "github.com/monax/burrow/manager/types"
 	"github.com/monax/burrow/txs"
 )
@@ -108,7 +108,7 @@ func (app *BurrowMint) DeliverTx(txBytes []byte) abci.Result {
 		return abci.NewError(abci.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err))
 	}
 
-	err = sm.ExecTx(app.cache, *tx, true, app.evc)
+	err = sm.ExecTx(app.cache, *tx, true, app.evc, app.logger)
 	if err != nil {
 		return abci.NewError(abci.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
 	}
@@ -130,7 +130,7 @@ func (app *BurrowMint) CheckTx(txBytes []byte) abci.Result {
 	}
 
 	// TODO: map ExecTx errors to sensible abci error codes
-	err = sm.ExecTx(app.checkCache, *tx, false, nil)
+	err = sm.ExecTx(app.checkCache, *tx, false, nil, app.logger)
 	if err != nil {
 		return abci.NewError(abci.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err))
 	}
diff --git a/manager/burrow-mint/state/execution.go b/manager/burrow-mint/state/execution.go
index f2ee4ac9147a1d8bcf8c5cf0d444921211328d37..62fb49730cb197aea578bb5b4711287806131461 100644
--- a/manager/burrow-mint/state/execution.go
+++ b/manager/burrow-mint/state/execution.go
@@ -28,6 +28,7 @@ import (
 	"github.com/monax/burrow/txs"
 	. "github.com/monax/burrow/word256"
 
+	"github.com/monax/burrow/logging"
 	"github.com/tendermint/go-events"
 )
 
@@ -184,7 +185,8 @@ func getInputs(state AccountGetter, ins []*txs.TxInput) (map[string]*acm.Account
 	return accounts, nil
 }
 
-func getOrMakeOutputs(state AccountGetter, accounts map[string]*acm.Account, outs []*txs.TxOutput) (map[string]*acm.Account, error) {
+func getOrMakeOutputs(state AccountGetter, accounts map[string]*acm.Account,
+	outs []*txs.TxOutput, logger logging_types.InfoTraceLogger) (map[string]*acm.Account, error) {
 	if accounts == nil {
 		accounts = make(map[string]*acm.Account)
 	}
@@ -200,7 +202,7 @@ func getOrMakeOutputs(state AccountGetter, accounts map[string]*acm.Account, out
 		// output account may be nil (new)
 		if acc == nil {
 			if !checkedCreatePerms {
-				if !hasCreateAccountPermission(state, accounts) {
+				if !hasCreateAccountPermission(state, accounts, logger) {
 					return nil, fmt.Errorf("At least one input does not have permission to create accounts")
 				}
 				checkedCreatePerms = true
@@ -320,6 +322,7 @@ func adjustByOutputs(accounts map[string]*acm.Account, outs []*txs.TxOutput) {
 func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable,
 	logger logging_types.InfoTraceLogger) (err error) {
 
+	logger = logging.WithScope(logger, "ExecTx")
 	// TODO: do something with fees
 	fees := int64(0)
 	_s := blockCache.State() // hack to access validators and block height
@@ -333,13 +336,13 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		}
 
 		// ensure all inputs have send permissions
-		if !hasSendPermission(blockCache, accounts) {
+		if !hasSendPermission(blockCache, accounts, logger) {
 			return fmt.Errorf("At least one input lacks permission for SendTx")
 		}
 
 		// add outputs to accounts map
 		// if any outputs don't exist, all inputs must have CreateAccount perm
-		accounts, err = getOrMakeOutputs(blockCache, accounts, tx.Outputs)
+		accounts, err = getOrMakeOutputs(blockCache, accounts, tx.Outputs, logger)
 		if err != nil {
 			return err
 		}
@@ -384,41 +387,46 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		// Validate input
 		inAcc = blockCache.GetAccount(tx.Input.Address)
 		if inAcc == nil {
-			log.Info(fmt.Sprintf("Can't find in account %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Cannot find input account",
+				"tx_input", tx.Input)
 			return txs.ErrTxInvalidAddress
 		}
 
 		createContract := len(tx.Address) == 0
 		if createContract {
-			if !hasCreateContractPermission(blockCache, inAcc) {
+			if !hasCreateContractPermission(blockCache, inAcc, logger) {
 				return fmt.Errorf("Account %X does not have CreateContract permission", tx.Input.Address)
 			}
 		} else {
-			if !hasCallPermission(blockCache, inAcc) {
+			if !hasCallPermission(blockCache, inAcc, logger) {
 				return fmt.Errorf("Account %X does not have Call permission", tx.Input.Address)
 			}
 		}
 
 		// pubKey should be present in either "inAcc" or "tx.Input"
 		if err := checkInputPubKey(inAcc, tx.Input); err != nil {
-			log.Info(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Cannot find public key for input account",
+				"tx_input", tx.Input)
 			return err
 		}
 		signBytes := acm.SignBytes(_s.ChainID, tx)
 		err := validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
-			log.Info(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err))
+			logging.InfoMsg(logger, "validateInput failed",
+				"tx_input", tx.Input, "error", err)
 			return err
 		}
 		if tx.Input.Amount < tx.Fee {
-			log.Info(fmt.Sprintf("Sender did not send enough to cover the fee %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Sender did not send enough to cover the fee",
+				"tx_input", tx.Input)
 			return txs.ErrTxInsufficientFunds
 		}
 
 		if !createContract {
 			// Validate output
 			if len(tx.Address) != 20 {
-				log.Info(fmt.Sprintf("Destination address is not 20 bytes %X", tx.Address))
+				logging.InfoMsg(logger, "Destination address is not 20 bytes",
+					"address", tx.Address)
 				return txs.ErrTxInvalidAddress
 			}
 			// check if its a native contract
@@ -432,7 +440,7 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			outAcc = blockCache.GetAccount(tx.Address)
 		}
 
-		log.Info(fmt.Sprintf("Out account: %v", outAcc))
+		logger.Trace("output_account", outAcc)
 
 		// Good!
 		value := tx.Input.Amount - tx.Fee
@@ -470,11 +478,13 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 				// you have to wait a block to avoid a re-ordering attack
 				// that will take your fees
 				if outAcc == nil {
-					log.Info(fmt.Sprintf("%X tries to call %X but it does not exist.",
-						inAcc.Address, tx.Address))
+					logging.InfoMsg(logger, "Call to address that does not exist",
+						"caller_address", inAcc.Address,
+						"callee_address", tx.Address)
 				} else {
-					log.Info(fmt.Sprintf("%X tries to call %X but code is blank.",
-						inAcc.Address, tx.Address))
+					logging.InfoMsg(logger, "Call to address that holds no code",
+						"caller_address", inAcc.Address,
+						"callee_address", tx.Address)
 				}
 				err = txs.ErrTxInvalidAddress
 				goto CALL_COMPLETE
@@ -484,14 +494,18 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			if createContract {
 				// We already checked for permission
 				callee = txCache.CreateAccount(caller)
-				log.Info(fmt.Sprintf("Created new contract %X", callee.Address))
+				logging.TraceMsg(logger, "Created new contract",
+					"contract_address", callee.Address,
+					"contract_code", callee.Code)
 				code = tx.Data
 			} else {
 				callee = toVMAccount(outAcc)
-				log.Info(fmt.Sprintf("Calling contract %X with code %X", callee.Address, callee.Code))
+				logging.TraceMsg(logger, "Calling existing contract",
+					"contract_address", callee.Address,
+					"contract_code", callee.Code)
 				code = callee.Code
 			}
-			log.Info(fmt.Sprintf("Code for this contract: %X", code))
+			logger.Trace("callee_")
 
 			// Run VM call and sync txCache to blockCache.
 			{ // Capture scope for goto.
@@ -504,11 +518,12 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 				ret, err = vmach.Call(caller, callee, code, tx.Data, value, &gas)
 				if err != nil {
 					// Failure. Charge the gas fee. The 'value' was otherwise not transferred.
-					log.Info(fmt.Sprintf("Error on execution: %v", err))
+					logging.InfoMsg(logger, "Error on execution",
+						"error", err)
 					goto CALL_COMPLETE
 				}
 
-				log.Info("Successful execution")
+				logging.TraceMsg(logger, "Successful execution")
 				if createContract {
 					callee.Code = ret
 				}
@@ -517,8 +532,12 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 
 		CALL_COMPLETE: // err may or may not be nil.
 
-			// Create a receipt from the ret and whether errored.
-			log.Notice("VM call complete", "caller", caller, "callee", callee, "return", ret, "err", err)
+			// Create a receipt from the ret and whether it erred.
+			logging.TraceMsg(logger, "VM call complete",
+				"caller", caller,
+				"callee", callee,
+				"return", ret,
+				"error", err)
 
 			// Fire Events for sender and receiver
 			// a separate event will be fired from vm for each additional call
@@ -550,27 +569,30 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		// Validate input
 		inAcc = blockCache.GetAccount(tx.Input.Address)
 		if inAcc == nil {
-			log.Info(fmt.Sprintf("Can't find in account %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Cannot find input account",
+				"tx_input", tx.Input)
 			return txs.ErrTxInvalidAddress
 		}
 		// check permission
-		if !hasNamePermission(blockCache, inAcc) {
+		if !hasNamePermission(blockCache, inAcc, logger) {
 			return fmt.Errorf("Account %X does not have Name permission", tx.Input.Address)
 		}
 		// pubKey should be present in either "inAcc" or "tx.Input"
 		if err := checkInputPubKey(inAcc, tx.Input); err != nil {
-			log.Info(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Cannot find public key for input account",
+				"tx_input", tx.Input)
 			return err
 		}
 		signBytes := acm.SignBytes(_s.ChainID, tx)
 		err := validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
-			log.Info(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err))
+			logging.InfoMsg(logger, "validateInput failed",
+				"tx_input", tx.Input, "error", err)
 			return err
 		}
-		// fee is in addition to the amount which is used to determine the TTL
 		if tx.Input.Amount < tx.Fee {
-			log.Info(fmt.Sprintf("Sender did not send enough to cover the fee %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Sender did not send enough to cover the fee",
+				"tx_input", tx.Input)
 			return txs.ErrTxInsufficientFunds
 		}
 
@@ -586,7 +608,11 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		expiresIn := int(value / costPerBlock)
 		lastBlockHeight := _s.LastBlockHeight
 
-		log.Info("New NameTx", "value", value, "costPerBlock", costPerBlock, "expiresIn", expiresIn, "lastBlock", lastBlockHeight)
+		logging.TraceMsg(logger, "New NameTx",
+			"value", value,
+			"cost_per_block", costPerBlock,
+			"expires_in", expiresIn,
+			"last_block_height", lastBlockHeight)
 
 		// check if the name exists
 		entry := blockCache.GetNameRegEntry(tx.Name)
@@ -598,7 +624,9 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			if entry.Expires > lastBlockHeight {
 				// ensure we are owner
 				if bytes.Compare(entry.Owner, tx.Input.Address) != 0 {
-					log.Info(fmt.Sprintf("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name))
+					logging.InfoMsg(logger, "Sender is trying to update a name for which they are not an owner",
+						"sender_address", tx.Input.Address,
+						"name", tx.Name)
 					return txs.ErrTxPermissionDenied
 				}
 			} else {
@@ -609,7 +637,8 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 			if value == 0 && len(tx.Data) == 0 {
 				// maybe we reward you for telling us we can delete this crap
 				// (owners if not expired, anyone if expired)
-				log.Info("Removing namereg entry", "name", entry.Name)
+				logging.TraceMsg(logger, "Removing NameReg entry (no value and empty data in tx requests this)",
+					"name", entry.Name)
 				blockCache.RemoveNameRegEntry(entry.Name)
 			} else {
 				// update the entry by bumping the expiry
@@ -620,7 +649,10 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 					}
 					entry.Expires = lastBlockHeight + expiresIn
 					entry.Owner = tx.Input.Address
-					log.Info("An old namereg entry has expired and been reclaimed", "name", entry.Name, "expiresIn", expiresIn, "owner", entry.Owner)
+					logging.TraceMsg(logger, "An old NameReg entry has expired and been reclaimed",
+						"name", entry.Name,
+						"expires_in", expiresIn,
+						"owner", entry.Owner)
 				} else {
 					// since the size of the data may have changed
 					// we use the total amount of "credit"
@@ -631,7 +663,12 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 						return errors.New(fmt.Sprintf("Names must be registered for at least %d blocks", txs.MinNameRegistrationPeriod))
 					}
 					entry.Expires = lastBlockHeight + expiresIn
-					log.Info("Updated namereg entry", "name", entry.Name, "expiresIn", expiresIn, "oldCredit", oldCredit, "value", value, "credit", credit)
+					logging.TraceMsg(logger, "Updated NameReg entry",
+						"name", entry.Name,
+						"expires_in", expiresIn,
+						"old_credit", oldCredit,
+						"value", value,
+						"credit", credit)
 				}
 				entry.Data = tx.Data
 				blockCache.UpdateNameRegEntry(entry)
@@ -647,7 +684,9 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 				Data:    tx.Data,
 				Expires: lastBlockHeight + expiresIn,
 			}
-			log.Info("Creating namereg entry", "name", entry.Name, "expiresIn", expiresIn)
+			logging.TraceMsg(logger, "Creating NameReg entry",
+				"name", entry.Name,
+				"expires_in", expiresIn)
 			blockCache.UpdateNameRegEntry(entry)
 		}
 
@@ -850,31 +889,37 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 		// Validate input
 		inAcc = blockCache.GetAccount(tx.Input.Address)
 		if inAcc == nil {
-			log.Debug(fmt.Sprintf("Can't find in account %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Cannot find input account",
+				"tx_input", tx.Input)
 			return txs.ErrTxInvalidAddress
 		}
 
 		permFlag := tx.PermArgs.PermFlag()
 		// check permission
-		if !HasPermission(blockCache, inAcc, permFlag) {
+		if !HasPermission(blockCache, inAcc, permFlag, logger) {
 			return fmt.Errorf("Account %X does not have moderator permission %s (%b)", tx.Input.Address, ptypes.PermFlagToString(permFlag), permFlag)
 		}
 
 		// pubKey should be present in either "inAcc" or "tx.Input"
 		if err := checkInputPubKey(inAcc, tx.Input); err != nil {
-			log.Debug(fmt.Sprintf("Can't find pubkey for %X", tx.Input.Address))
+			logging.InfoMsg(logger, "Cannot find public key for input account",
+				"tx_input", tx.Input)
 			return err
 		}
 		signBytes := acm.SignBytes(_s.ChainID, tx)
 		err := validateInput(inAcc, signBytes, tx.Input)
 		if err != nil {
-			log.Debug(fmt.Sprintf("validateInput failed on %X: %v", tx.Input.Address, err))
+			logging.InfoMsg(logger, "validateInput failed",
+				"tx_input", tx.Input,
+				"error", err)
 			return err
 		}
 
 		value := tx.Input.Amount
 
-		log.Debug("New PermissionsTx", "function", ptypes.PermFlagToString(permFlag), "args", tx.PermArgs)
+		logging.TraceMsg(logger, "New PermissionsTx",
+			"perm_flag", ptypes.PermFlagToString(permFlag),
+			"perm_args", tx.PermArgs)
 
 		var permAcc *acm.Account
 		switch args := tx.PermArgs.(type) {
@@ -946,7 +991,8 @@ func ExecTx(blockCache *BlockCache, tx txs.Tx, runCall bool, evc events.Fireable
 //---------------------------------------------------------------
 
 // Get permission on an account or fall back to global value
-func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag) bool {
+func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag,
+	logger logging_types.InfoTraceLogger) bool {
 	if perm > ptypes.AllPermFlags {
 		sanity.PanicSanity("Checking an unknown permission in state should never happen")
 	}
@@ -963,55 +1009,67 @@ func HasPermission(state AccountGetter, acc *acm.Account, perm ptypes.PermFlag)
 		if state == nil {
 			sanity.PanicSanity("All known global permissions should be set!")
 		}
-		log.Info("Permission for account is not set. Querying GlobalPermissionsAddress", "perm", permString)
-		return HasPermission(nil, state.GetAccount(ptypes.GlobalPermissionsAddress), perm)
+		logging.TraceMsg(logger, "Permission for account is not set. Querying GlobalPermissionsAddres.",
+			"perm_flag", permString)
+		return HasPermission(nil, state.GetAccount(ptypes.GlobalPermissionsAddress), perm, logger)
 	} else if v {
-		log.Info("Account has permission", "address", fmt.Sprintf("%X", acc.Address), "perm", permString)
+		logging.TraceMsg(logger, "Account has permission",
+			"account_address", acc.Address,
+			"perm_flag", permString)
 	} else {
-		log.Info("Account does not have permission", "address", fmt.Sprintf("%X", acc.Address), "perm", permString)
+		logging.TraceMsg(logger, "Account does not have permission",
+			"account_address", acc.Address,
+			"perm_flag", permString)
 	}
 	return v
 }
 
 // TODO: for debug log the failed accounts
-func hasSendPermission(state AccountGetter, accs map[string]*acm.Account) bool {
+func hasSendPermission(state AccountGetter, accs map[string]*acm.Account,
+	logger logging_types.InfoTraceLogger) bool {
 	for _, acc := range accs {
-		if !HasPermission(state, acc, ptypes.Send) {
+		if !HasPermission(state, acc, ptypes.Send, logger) {
 			return false
 		}
 	}
 	return true
 }
 
-func hasNamePermission(state AccountGetter, acc *acm.Account) bool {
-	return HasPermission(state, acc, ptypes.Name)
+func hasNamePermission(state AccountGetter, acc *acm.Account,
+	logger logging_types.InfoTraceLogger) bool {
+	return HasPermission(state, acc, ptypes.Name, logger)
 }
 
-func hasCallPermission(state AccountGetter, acc *acm.Account) bool {
-	return HasPermission(state, acc, ptypes.Call)
+func hasCallPermission(state AccountGetter, acc *acm.Account,
+	logger logging_types.InfoTraceLogger) bool {
+	return HasPermission(state, acc, ptypes.Call, logger)
 }
 
-func hasCreateContractPermission(state AccountGetter, acc *acm.Account) bool {
-	return HasPermission(state, acc, ptypes.CreateContract)
+func hasCreateContractPermission(state AccountGetter, acc *acm.Account,
+	logger logging_types.InfoTraceLogger) bool {
+	return HasPermission(state, acc, ptypes.CreateContract, logger)
 }
 
-func hasCreateAccountPermission(state AccountGetter, accs map[string]*acm.Account) bool {
+func hasCreateAccountPermission(state AccountGetter, accs map[string]*acm.Account,
+	logger logging_types.InfoTraceLogger) bool {
 	for _, acc := range accs {
-		if !HasPermission(state, acc, ptypes.CreateAccount) {
+		if !HasPermission(state, acc, ptypes.CreateAccount, logger) {
 			return false
 		}
 	}
 	return true
 }
 
-func hasBondPermission(state AccountGetter, acc *acm.Account) bool {
-	return HasPermission(state, acc, ptypes.Bond)
+func hasBondPermission(state AccountGetter, acc *acm.Account,
+	logger logging_types.InfoTraceLogger) bool {
+	return HasPermission(state, acc, ptypes.Bond, logger)
 }
 
-func hasBondOrSendPermission(state AccountGetter, accs map[string]*acm.Account) bool {
+func hasBondOrSendPermission(state AccountGetter, accs map[string]*acm.Account,
+	logger logging_types.InfoTraceLogger) bool {
 	for _, acc := range accs {
-		if !HasPermission(state, acc, ptypes.Bond) {
-			if !HasPermission(state, acc, ptypes.Send) {
+		if !HasPermission(state, acc, ptypes.Bond, logger) {
+			if !HasPermission(state, acc, ptypes.Send, logger) {
 				return false
 			}
 		}
diff --git a/manager/burrow-mint/state/permissions_test.go b/manager/burrow-mint/state/permissions_test.go
index 92dff5fa10c0cd779e89880c4a3cb56f86405482..4ac30975234d7091283f9f5d3667e2ec744199ef 100644
--- a/manager/burrow-mint/state/permissions_test.go
+++ b/manager/burrow-mint/state/permissions_test.go
@@ -29,6 +29,7 @@ import (
 	"github.com/monax/burrow/txs"
 	. "github.com/monax/burrow/word256"
 
+	"github.com/monax/burrow/logging/lifecycle"
 	"github.com/tendermint/go-crypto"
 	dbm "github.com/tendermint/go-db"
 	"github.com/tendermint/go-events"
@@ -109,6 +110,7 @@ x 		- roles: has, add, rm
 // keys
 var user = makeUsers(10)
 var chainID = "testchain"
+var logger = lifecycle.NewStdErrLogger()
 
 func makeUsers(n int) []*acm.PrivAccount {
 	accounts := []*acm.PrivAccount{}
@@ -175,7 +177,7 @@ func TestSendFails(t *testing.T) {
 	}
 	tx.AddOutput(user[1].Address, 5)
 	tx.SignInput(chainID, 0, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -188,7 +190,7 @@ func TestSendFails(t *testing.T) {
 	}
 	tx.AddOutput(user[4].Address, 5)
 	tx.SignInput(chainID, 0, user[2])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -201,7 +203,7 @@ func TestSendFails(t *testing.T) {
 	}
 	tx.AddOutput(user[4].Address, 5)
 	tx.SignInput(chainID, 0, user[3])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -217,7 +219,7 @@ func TestSendFails(t *testing.T) {
 	}
 	tx.AddOutput(user[6].Address, 5)
 	tx.SignInput(chainID, 0, user[3])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -241,7 +243,7 @@ func TestName(t *testing.T) {
 		t.Fatal(err)
 	}
 	tx.Sign(chainID, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -253,7 +255,7 @@ func TestName(t *testing.T) {
 		t.Fatal(err)
 	}
 	tx.Sign(chainID, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -273,7 +275,7 @@ func TestCallFails(t *testing.T) {
 	// simple call tx should fail
 	tx, _ := txs.NewCallTx(blockCache, user[0].PubKey, user[4].Address, nil, 100, 100, 100)
 	tx.Sign(chainID, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -282,7 +284,7 @@ func TestCallFails(t *testing.T) {
 	// simple call tx with send permission should fail
 	tx, _ = txs.NewCallTx(blockCache, user[1].PubKey, user[4].Address, nil, 100, 100, 100)
 	tx.Sign(chainID, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -291,7 +293,7 @@ func TestCallFails(t *testing.T) {
 	// simple call tx with create permission should fail
 	tx, _ = txs.NewCallTx(blockCache, user[3].PubKey, user[4].Address, nil, 100, 100, 100)
 	tx.Sign(chainID, user[3])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -303,7 +305,7 @@ func TestCallFails(t *testing.T) {
 	// simple call create tx should fail
 	tx, _ = txs.NewCallTx(blockCache, user[0].PubKey, nil, nil, 100, 100, 100)
 	tx.Sign(chainID, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -312,7 +314,7 @@ func TestCallFails(t *testing.T) {
 	// simple call create tx with send perm should fail
 	tx, _ = txs.NewCallTx(blockCache, user[1].PubKey, nil, nil, 100, 100, 100)
 	tx.Sign(chainID, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -321,7 +323,7 @@ func TestCallFails(t *testing.T) {
 	// simple call create tx with call perm should fail
 	tx, _ = txs.NewCallTx(blockCache, user[2].PubKey, nil, nil, 100, 100, 100)
 	tx.Sign(chainID, user[2])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -342,7 +344,7 @@ func TestSendPermission(t *testing.T) {
 	}
 	tx.AddOutput(user[1].Address, 5)
 	tx.SignInput(chainID, 0, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal("Transaction failed", err)
 	}
 
@@ -357,7 +359,7 @@ func TestSendPermission(t *testing.T) {
 	tx.AddOutput(user[2].Address, 10)
 	tx.SignInput(chainID, 0, user[0])
 	tx.SignInput(chainID, 1, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -390,7 +392,7 @@ func TestCallPermission(t *testing.T) {
 	// A single input, having the permission, should succeed
 	tx, _ := txs.NewCallTx(blockCache, user[0].PubKey, simpleContractAddr, nil, 100, 100, 100)
 	tx.Sign(chainID, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal("Transaction failed", err)
 	}
 
@@ -504,7 +506,7 @@ func TestCreatePermission(t *testing.T) {
 	// A single input, having the permission, should succeed
 	tx, _ := txs.NewCallTx(blockCache, user[0].PubKey, nil, createCode, 100, 100, 100)
 	tx.Sign(chainID, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal("Transaction failed", err)
 	}
 	// ensure the contract is there
@@ -529,7 +531,7 @@ func TestCreatePermission(t *testing.T) {
 	// A single input, having the permission, should succeed
 	tx, _ = txs.NewCallTx(blockCache, user[0].PubKey, nil, createFactoryCode, 100, 100, 100)
 	tx.Sign(chainID, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal("Transaction failed", err)
 	}
 	// ensure the contract is there
@@ -747,7 +749,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	}
 	tx.AddOutput(user[6].Address, 5)
 	tx.SignInput(chainID, 0, user[0])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal("Transaction failed", err)
 	}
 
@@ -762,7 +764,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	tx.AddOutput(user[7].Address, 10)
 	tx.SignInput(chainID, 0, user[0])
 	tx.SignInput(chainID, 1, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -780,7 +782,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	tx.AddOutput(user[4].Address, 6)
 	tx.SignInput(chainID, 0, user[0])
 	tx.SignInput(chainID, 1, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err == nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err == nil {
 		t.Fatal("Expected error")
 	} else {
 		fmt.Println(err)
@@ -800,7 +802,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	tx.AddOutput(user[7].Address, 10)
 	tx.SignInput(chainID, 0, user[0])
 	tx.SignInput(chainID, 1, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal("Unexpected error", err)
 	}
 
@@ -816,7 +818,7 @@ func TestCreateAccountPermission(t *testing.T) {
 	tx.AddOutput(user[4].Address, 3)
 	tx.SignInput(chainID, 0, user[0])
 	tx.SignInput(chainID, 1, user[1])
-	if err := ExecTx(blockCache, tx, true, nil); err != nil {
+	if err := ExecTx(blockCache, tx, true, nil, logger); err != nil {
 		t.Fatal("Unexpected error", err)
 	}
 
@@ -1091,7 +1093,7 @@ func execTxWaitEvent(t *testing.T, blockCache *BlockCache, tx txs.Tx, eventid st
 	})
 	evc := events.NewEventCache(evsw)
 	go func() {
-		if err := ExecTx(blockCache, tx, true, evc); err != nil {
+		if err := ExecTx(blockCache, tx, true, evc, logger); err != nil {
 			ch <- err.Error()
 		}
 		evc.Flush()
@@ -1174,7 +1176,7 @@ func testSNativeTx(t *testing.T, expectPass bool, blockCache *BlockCache, perm p
 	}
 	tx, _ := txs.NewPermissionsTx(blockCache, user[0].PubKey, snativeArgs)
 	tx.Sign(chainID, user[0])
-	err := ExecTx(blockCache, tx, true, nil)
+	err := ExecTx(blockCache, tx, true, nil, logger)
 	if expectPass {
 		if err != nil {
 			t.Fatal("Unexpected exception", err)
diff --git a/manager/burrow-mint/state/state_test.go b/manager/burrow-mint/state/state_test.go
index 72b23255af0384aacb0c377557d8df5520c76b2e..b81b617098377045f116402c1de157df995b6928 100644
--- a/manager/burrow-mint/state/state_test.go
+++ b/manager/burrow-mint/state/state_test.go
@@ -34,7 +34,7 @@ func init() {
 
 func execTxWithState(state *State, tx txs.Tx, runCall bool) error {
 	cache := NewBlockCache(state)
-	if err := ExecTx(cache, tx, runCall, nil); err != nil {
+	if err := ExecTx(cache, tx, runCall, nil, logger); err != nil {
 		return err
 	} else {
 		cache.Sync()
@@ -769,7 +769,7 @@ func TestSuicide(t *testing.T) {
 
 	// we use cache instead of execTxWithState so we can run the tx twice
 	cache := NewBlockCache(state)
-	if err := ExecTx(cache, tx, true, nil); err != nil {
+	if err := ExecTx(cache, tx, true, nil, logger); err != nil {
 		t.Errorf("Got error in executing call transaction, %v", err)
 	}
 
@@ -777,7 +777,7 @@ func TestSuicide(t *testing.T) {
 	// shouldn't happen twice and the caller should lose fee
 	tx.Input.Sequence += 1
 	tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx)
-	if err := ExecTx(cache, tx, true, nil); err != nil {
+	if err := ExecTx(cache, tx, true, nil, logger); err != nil {
 		t.Errorf("Got error in executing call transaction, %v", err)
 	}
 
diff --git a/manager/manager.go b/manager/manager.go
index c8baf8909f4cef2a9016876af43a0c2729b9678e..c05e3c40a4adabaad4e152734937231dc42fada8 100644
--- a/manager/manager.go
+++ b/manager/manager.go
@@ -24,6 +24,7 @@ import (
 	burrowmint "github.com/monax/burrow/manager/burrow-mint"
 
 	"github.com/monax/burrow/logging"
+	logging_types "github.com/monax/burrow/logging/types"
 )
 
 // NewApplicationPipe returns an initialised Pipe interface
diff --git a/rpc/v0/codec.go b/rpc/v0/codec.go
index b6b20f628a761616040705600e053bbd915dbcf1..59133df73f07c03e44cf40cf5886b37ce6fadf06 100644
--- a/rpc/v0/codec.go
+++ b/rpc/v0/codec.go
@@ -18,8 +18,6 @@ import (
 	"io"
 	"io/ioutil"
 
-	rpc "github.com/monax/burrow/rpc"
-
 	"github.com/monax/burrow/rpc"
 	wire "github.com/tendermint/go-wire"
 )
diff --git a/rpc/v0/rest_server_test.go b/rpc/v0/rest_server_test.go
index 2b4328e68d368a2f3a754cd4e12a16102737fd2b..cb4fd4d69566ba6a337f64a1f61e9109e7d542c4 100644
--- a/rpc/v0/rest_server_test.go
+++ b/rpc/v0/rest_server_test.go
@@ -33,10 +33,14 @@ import (
 	"github.com/monax/burrow/txs"
 
 	"github.com/gin-gonic/gin"
+	"github.com/monax/burrow/logging/lifecycle"
+	logging_types "github.com/monax/burrow/logging/types"
 	"github.com/stretchr/testify/suite"
 	"github.com/tendermint/log15"
 )
 
+var logger logging_types.InfoTraceLogger = lifecycle.NewStdErrLogger()
+
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())
 	log15.Root().SetHandler(log15.LvlFilterHandler(
@@ -67,7 +71,7 @@ func (mockSuite *MockSuite) SetupSuite() {
 	sConf := server.DefaultServerConfig()
 	sConf.Bind.Port = 31402
 	// Create a server process.
-	proc, _ := server.NewServeProcess(sConf, restServer)
+	proc, _ := server.NewServeProcess(sConf, logger, restServer)
 	err := proc.Start()
 	if err != nil {
 		panic(err)
diff --git a/test/server/scumbag.go b/test/server/scumbag_test.go
similarity index 85%
rename from test/server/scumbag.go
rename to test/server/scumbag_test.go
index c403a0d1ad3756d02451293b55cdd5c59f20cf31..6031aa94721c09a1d36c79841a060f2648a3c2e9 100644
--- a/test/server/scumbag.go
+++ b/test/server/scumbag_test.go
@@ -23,9 +23,13 @@ import (
 	"github.com/monax/burrow/server"
 
 	"github.com/gin-gonic/gin"
+	"github.com/monax/burrow/logging/lifecycle"
+	logging_types "github.com/monax/burrow/logging/types"
 	"github.com/tendermint/log15"
 )
 
+var logger logging_types.InfoTraceLogger = lifecycle.NewStdErrLogger()
+
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())
 	log15.Root().SetHandler(log15.LvlFilterHandler(
@@ -68,13 +72,13 @@ func (this *ScumSocketService) Process(data []byte, session *server.WSSession) {
 
 func NewScumsocketServer(maxConnections uint16) *server.WebSocketServer {
 	sss := &ScumSocketService{}
-	return server.NewWebSocketServer(maxConnections, sss)
+	return server.NewWebSocketServer(maxConnections, sss, logger)
 }
 
 func NewServeScumbag() (*server.ServeProcess, error) {
 	cfg := server.DefaultServerConfig()
 	cfg.Bind.Port = uint16(31400)
-	return server.NewServeProcess(cfg, NewScumbagServer())
+	return server.NewServeProcess(cfg, logger, NewScumbagServer())
 }
 
 func NewServeScumSocket(wsServer *server.WebSocketServer) (*server.ServeProcess,
@@ -82,5 +86,5 @@ func NewServeScumSocket(wsServer *server.WebSocketServer) (*server.ServeProcess,
 	cfg := server.DefaultServerConfig()
 	cfg.WebSocket.WebSocketEndpoint = "/scumsocket"
 	cfg.Bind.Port = uint16(31401)
-	return server.NewServeProcess(cfg, wsServer)
+	return server.NewServeProcess(cfg, logger, wsServer)
 }