diff --git a/dapps/faucet/dapp.go b/dapps/faucet/dapp.go
index 0bc74cb23579dabf7fbe58bafad8788d6692f069..977c18282320c210a775323b453de02e6a343535 100644
--- a/dapps/faucet/dapp.go
+++ b/dapps/faucet/dapp.go
@@ -124,11 +124,11 @@ func run(*node.Plugin) {
 }
 
 func configureEvents() {
-	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		defer cachedMessage.Release()
-		defer cachedMessageMetadata.Release()
+	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessageEvent *tangle.CachedMessageEvent) {
+		defer cachedMessageEvent.Message.Release()
+		defer cachedMessageEvent.MessageMetadata.Release()
 
-		msg := cachedMessage.Unwrap()
+		msg := cachedMessageEvent.Message.Unwrap()
 		if msg == nil || !faucetpayload.IsFaucetReq(msg) {
 			return
 		}
diff --git a/dapps/networkdelay/dapp.go b/dapps/networkdelay/dapp.go
index 426f5da498b7242eeff3fc01257f3ce13f450ab6..65098f91a0dbe33fb3a5a0c7f066d62376315976 100644
--- a/dapps/networkdelay/dapp.go
+++ b/dapps/networkdelay/dapp.go
@@ -4,7 +4,6 @@ import (
 	"sync"
 	"time"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	messageTangle "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
 	"github.com/iotaledger/goshimmer/plugins/config"
@@ -77,11 +76,11 @@ func configure(_ *node.Plugin) {
 	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(onReceiveMessageFromMessageLayer))
 }
 
-func onReceiveMessageFromMessageLayer(cachedMessage *message.CachedMessage, cachedMessageMetadata *messageTangle.CachedMessageMetadata) {
-	defer cachedMessage.Release()
-	defer cachedMessageMetadata.Release()
+func onReceiveMessageFromMessageLayer(cachedMessageEvent *messageTangle.CachedMessageEvent) {
+	defer cachedMessageEvent.Message.Release()
+	defer cachedMessageEvent.MessageMetadata.Release()
 
-	solidMessage := cachedMessage.Unwrap()
+	solidMessage := cachedMessageEvent.Message.Unwrap()
 	if solidMessage == nil {
 		log.Debug("failed to unpack solid message from message layer")
 
diff --git a/dapps/valuetransfers/dapp.go b/dapps/valuetransfers/dapp.go
index d1f0ce69228f9e32589a904c523c27228934668c..0b28fd31cd98943a949098fc553ec1c75e688d43 100644
--- a/dapps/valuetransfers/dapp.go
+++ b/dapps/valuetransfers/dapp.go
@@ -7,12 +7,10 @@ import (
 	"time"
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/consensus"
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
 	valuepayload "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tipmanager"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	messageTangle "github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
 	"github.com/iotaledger/goshimmer/packages/vote"
@@ -136,13 +134,13 @@ func configure(_ *node.Plugin) {
 	tipManager = TipManager()
 	valueObjectFactory = ValueObjectFactory()
 
-	_tangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedMetadata *tangle.CachedPayloadMetadata) {
-		cachedMetadata.Release()
-		cachedPayload.Consume(tipManager.AddTip)
+	_tangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayloadEvent *tangle.CachedPayloadEvent) {
+		cachedPayloadEvent.PayloadMetadata.Release()
+		cachedPayloadEvent.Payload.Consume(tipManager.AddTip)
 	}))
-	_tangle.Events.PayloadDisliked.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedMetadata *tangle.CachedPayloadMetadata) {
-		cachedMetadata.Release()
-		cachedPayload.Consume(tipManager.RemoveTip)
+	_tangle.Events.PayloadDisliked.Attach(events.NewClosure(func(cachedPayloadEvent *tangle.CachedPayloadEvent) {
+		cachedPayloadEvent.PayloadMetadata.Release()
+		cachedPayloadEvent.Payload.Consume(tipManager.RemoveTip)
 	}))
 
 	// configure FCOB consensus rules
@@ -188,11 +186,11 @@ func run(*node.Plugin) {
 	runFPC()
 }
 
-func onReceiveMessageFromMessageLayer(cachedMessage *message.CachedMessage, cachedMessageMetadata *messageTangle.CachedMessageMetadata) {
-	defer cachedMessage.Release()
-	defer cachedMessageMetadata.Release()
+func onReceiveMessageFromMessageLayer(cachedMessageEvent *messageTangle.CachedMessageEvent) {
+	defer cachedMessageEvent.Message.Release()
+	defer cachedMessageEvent.MessageMetadata.Release()
 
-	solidMessage := cachedMessage.Unwrap()
+	solidMessage := cachedMessageEvent.Message.Unwrap()
 	if solidMessage == nil {
 		log.Debug("failed to unpack solid message from message layer")
 
@@ -237,10 +235,10 @@ func AwaitTransactionToBeBooked(txID transaction.ID, maxAwait time.Duration) err
 	// reason the same transaction gets booked multiple times
 	exit := make(chan struct{})
 	defer close(exit)
-	closure := events.NewClosure(func(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *tangle.CachedTransactionMetadata, decisionPending bool) {
-		defer cachedTransaction.Release()
-		defer cachedTransactionMetadata.Release()
-		if cachedTransaction.Unwrap().ID() != txID {
+	closure := events.NewClosure(func(cachedTransactionBookEvent *tangle.CachedTransactionBookEvent) {
+		defer cachedTransactionBookEvent.Transaction.Release()
+		defer cachedTransactionBookEvent.TransactionMetadata.Release()
+		if cachedTransactionBookEvent.Transaction.Unwrap().ID() != txID {
 			return
 		}
 		select {
diff --git a/dapps/valuetransfers/packages/branchmanager/branchmanager.go b/dapps/valuetransfers/packages/branchmanager/branchmanager.go
index cb9b4a3f94471e50bdb0f1e6af34842157d33366..3e58994b5abebb8d20cdafe5505dd348e1d8a30f 100644
--- a/dapps/valuetransfers/packages/branchmanager/branchmanager.go
+++ b/dapps/valuetransfers/packages/branchmanager/branchmanager.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"sort"
 
-	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/kvstore"
 	"github.com/iotaledger/hive.go/marshalutil"
 	"github.com/iotaledger/hive.go/objectstorage"
@@ -48,15 +47,7 @@ func New(store kvstore.KVStore) (branchManager *BranchManager) {
 		childBranchStorage:    osFactory.New(osChildBranch, osChildBranchFactory, osChildBranchOptions...),
 		conflictStorage:       osFactory.New(osConflict, osConflictFactory, osConflictOptions...),
 		conflictMemberStorage: osFactory.New(osConflictMember, osConflictMemberFactory, osConflictMemberOptions...),
-		Events: &Events{
-			BranchPreferred:   events.NewEvent(branchCaller),
-			BranchUnpreferred: events.NewEvent(branchCaller),
-			BranchLiked:       events.NewEvent(branchCaller),
-			BranchDisliked:    events.NewEvent(branchCaller),
-			BranchFinalized:   events.NewEvent(branchCaller),
-			BranchConfirmed:   events.NewEvent(branchCaller),
-			BranchRejected:    events.NewEvent(branchCaller),
-		},
+		Events:                newEvents(),
 	}
 	branchManager.init()
 
diff --git a/dapps/valuetransfers/packages/branchmanager/events.go b/dapps/valuetransfers/packages/branchmanager/events.go
index f9615e209aaeb205624ed1eeb1f533c4019e601a..eadab147d18297d896f0d3d81612bd75e4b7f164 100644
--- a/dapps/valuetransfers/packages/branchmanager/events.go
+++ b/dapps/valuetransfers/packages/branchmanager/events.go
@@ -29,6 +29,18 @@ type Events struct {
 	BranchRejected *events.Event
 }
 
+func newEvents() *Events {
+	return &Events{
+		BranchPreferred:   events.NewEvent(branchCaller),
+		BranchUnpreferred: events.NewEvent(branchCaller),
+		BranchLiked:       events.NewEvent(branchCaller),
+		BranchDisliked:    events.NewEvent(branchCaller),
+		BranchFinalized:   events.NewEvent(branchCaller),
+		BranchConfirmed:   events.NewEvent(branchCaller),
+		BranchRejected:    events.NewEvent(branchCaller),
+	}
+}
+
 func branchCaller(handler interface{}, params ...interface{}) {
 	handler.(func(branch *CachedBranch))(params[0].(*CachedBranch).Retain())
 }
diff --git a/dapps/valuetransfers/packages/consensus/fcob.go b/dapps/valuetransfers/packages/consensus/fcob.go
index b8a2925bdb4130375e22c408b3a674095e1c5ac8..91306d8b4c71e77ff69b8e634a7156dcafc7f328 100644
--- a/dapps/valuetransfers/packages/consensus/fcob.go
+++ b/dapps/valuetransfers/packages/consensus/fcob.go
@@ -3,7 +3,6 @@ package consensus
 import (
 	"time"
 
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager"
 	"github.com/iotaledger/hive.go/events"
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
@@ -61,13 +60,13 @@ func (fcob *FCOB) ProcessVoteResult(ev *vote.OpinionEvent) {
 
 // onTransactionBooked analyzes the transaction that was booked by the Tangle and initiates the FCOB rules if it is not
 // conflicting. If it is conflicting and a decision is still pending we trigger a voting process.
-func (fcob *FCOB) onTransactionBooked(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *tangle.CachedTransactionMetadata, decisionPending bool) {
-	defer cachedTransaction.Release()
+func (fcob *FCOB) onTransactionBooked(cachedTransactionBookEvent *tangle.CachedTransactionBookEvent) {
+	defer cachedTransactionBookEvent.Transaction.Release()
 
-	cachedTransactionMetadata.Consume(func(transactionMetadata *tangle.TransactionMetadata) {
+	cachedTransactionBookEvent.TransactionMetadata.Consume(func(transactionMetadata *tangle.TransactionMetadata) {
 		if transactionMetadata.Conflicting() {
 			// abort if the previous consumers where finalized already
-			if !decisionPending {
+			if !cachedTransactionBookEvent.Pending {
 				return
 			}
 
@@ -76,7 +75,7 @@ func (fcob *FCOB) onTransactionBooked(cachedTransaction *transaction.CachedTrans
 			return
 		}
 
-		fcob.scheduleSetPreferred(cachedTransactionMetadata.Retain())
+		fcob.scheduleSetPreferred(cachedTransactionBookEvent.TransactionMetadata.Retain())
 	})
 }
 
@@ -139,12 +138,12 @@ func (fcob *FCOB) setFinalized(cachedTransactionMetadata *tangle.CachedTransacti
 
 // onFork triggers a voting process whenever a Transaction gets forked into a new Branch. The initial opinion is derived
 // from the preferred flag that was set using the FCOB rule.
-func (fcob *FCOB) onFork(cachedTransaction *transaction.CachedTransaction, cachedTransactionMetadata *tangle.CachedTransactionMetadata, cachedTargetBranch *branchmanager.CachedBranch, conflictingInputs []transaction.OutputID) {
-	defer cachedTransaction.Release()
-	defer cachedTransactionMetadata.Release()
-	defer cachedTargetBranch.Release()
+func (fcob *FCOB) onFork(forkEvent *tangle.ForkEvent) {
+	defer forkEvent.Transaction.Release()
+	defer forkEvent.TransactionMetadata.Release()
+	defer forkEvent.Branch.Release()
 
-	transactionMetadata := cachedTransactionMetadata.Unwrap()
+	transactionMetadata := forkEvent.TransactionMetadata.Unwrap()
 	if transactionMetadata == nil {
 		return
 	}
diff --git a/dapps/valuetransfers/packages/tangle/events.go b/dapps/valuetransfers/packages/tangle/events.go
index 17207555c01f1fd714c7fdef352e46fbab7cd994..49bd4ad1bac9d4f3c8716dba142fdf9c2446a743 100644
--- a/dapps/valuetransfers/packages/tangle/events.go
+++ b/dapps/valuetransfers/packages/tangle/events.go
@@ -69,6 +69,40 @@ func (eventSource EventSource) String() string {
 	return [...]string{"EventSourceTangle", "EventSourceBranchManager"}[eventSource]
 }
 
+// CachedPayloadEvent represents the parameters of cachedPayloadEvent
+type CachedPayloadEvent struct {
+	Payload         *payload.CachedPayload
+	PayloadMetadata *CachedPayloadMetadata
+}
+
+// CachedTransactionEvent represents the parameters of cachedTransactionEvent
+type CachedTransactionEvent struct {
+	Transaction         *transaction.CachedTransaction
+	TransactionMetadata *CachedTransactionMetadata
+}
+
+// CachedTransactionBookEvent represents the parameters of transactionBookedEvent
+type CachedTransactionBookEvent struct {
+	Transaction         *transaction.CachedTransaction
+	TransactionMetadata *CachedTransactionMetadata
+	Pending             bool
+}
+
+// ForkEvent represents the parameters of forkEvent
+type ForkEvent struct {
+	Transaction         *transaction.CachedTransaction
+	TransactionMetadata *CachedTransactionMetadata
+	Branch              *branchmanager.CachedBranch
+	InputIDs            []transaction.OutputID
+}
+
+// CachedAttachmentsEvent represents the parameters of cachedTransactionAttachmentEvent
+type CachedAttachmentsEvent struct {
+	Transaction         *transaction.CachedTransaction
+	TransactionMetadata *CachedTransactionMetadata
+	Attachments         *CachedAttachment
+}
+
 func newEvents() *Events {
 	return &Events{
 		PayloadAttached:        events.NewEvent(cachedPayloadEvent),
@@ -101,56 +135,74 @@ func payloadIDEvent(handler interface{}, params ...interface{}) {
 }
 
 func cachedPayloadEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*payload.CachedPayload, *CachedPayloadMetadata))(
-		params[0].(*payload.CachedPayload).Retain(),
-		params[1].(*CachedPayloadMetadata).Retain(),
-	)
+	handler.(func(*CachedPayloadEvent))(cachedPayloadRetain(params[0].(*CachedPayloadEvent)))
 }
 
 func cachedPayloadErrorEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*payload.CachedPayload, *CachedPayloadMetadata, error))(
-		params[0].(*payload.CachedPayload).Retain(),
-		params[1].(*CachedPayloadMetadata).Retain(),
-		params[2].(error),
+	handler.(func(*CachedPayloadEvent, error))(
+		cachedPayloadRetain(params[0].(*CachedPayloadEvent)),
+		params[1].(error),
 	)
 }
 
 func transactionBookedEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, bool))(
-		params[0].(*transaction.CachedTransaction).Retain(),
-		params[1].(*CachedTransactionMetadata).Retain(),
-		params[2].(bool),
-	)
+	handler.(func(*CachedTransactionBookEvent))(cachedTransactionBookRetain(params[0].(*CachedTransactionBookEvent)))
 }
 
 func forkEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, *branchmanager.CachedBranch, []transaction.OutputID))(
-		params[0].(*transaction.CachedTransaction).Retain(),
-		params[1].(*CachedTransactionMetadata).Retain(),
-		params[2].(*branchmanager.CachedBranch).Retain(),
-		params[3].([]transaction.OutputID),
-	)
+	handler.(func(*ForkEvent))(forkRetain(params[0].(*ForkEvent)))
 }
 
 func cachedTransactionEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata))(
-		params[0].(*transaction.CachedTransaction).Retain(),
-		params[1].(*CachedTransactionMetadata).Retain(),
-	)
+	handler.(func(*CachedTransactionEvent))(cachedTransactionRetain(params[0].(*CachedTransactionEvent)))
 }
 
 func cachedTransactionErrorEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, error))(
-		params[0].(*transaction.CachedTransaction).Retain(),
-		params[1].(*CachedTransactionMetadata).Retain(),
-		params[2].(error),
+	handler.(func(*CachedTransactionEvent, error))(
+		cachedTransactionRetain(params[0].(*CachedTransactionEvent)),
+		params[1].(error),
 	)
 }
 
 func cachedTransactionAttachmentEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, *CachedAttachment))(
-		params[0].(*transaction.CachedTransaction).Retain(),
-		params[1].(*CachedTransactionMetadata).Retain(),
-		params[2].(*CachedAttachment).Retain(),
-	)
+	handler.(func(*CachedAttachmentsEvent))(cachedAttachmentsRetain(params[0].(*CachedAttachmentsEvent)))
+}
+
+func cachedPayloadRetain(cachedPayload *CachedPayloadEvent) *CachedPayloadEvent {
+	return &CachedPayloadEvent{
+		Payload:         cachedPayload.Payload.Retain(),
+		PayloadMetadata: cachedPayload.PayloadMetadata.Retain(),
+	}
+}
+
+func cachedTransactionRetain(cachedTransaction *CachedTransactionEvent) *CachedTransactionEvent {
+	return &CachedTransactionEvent{
+		Transaction:         cachedTransaction.Transaction.Retain(),
+		TransactionMetadata: cachedTransaction.TransactionMetadata.Retain(),
+	}
+}
+
+func cachedTransactionBookRetain(cachedTransaction *CachedTransactionBookEvent) *CachedTransactionBookEvent {
+	return &CachedTransactionBookEvent{
+		Transaction:         cachedTransaction.Transaction.Retain(),
+		TransactionMetadata: cachedTransaction.TransactionMetadata.Retain(),
+		Pending:             cachedTransaction.Pending,
+	}
+}
+
+func forkRetain(forkEvent *ForkEvent) *ForkEvent {
+	return &ForkEvent{
+		Transaction:         forkEvent.Transaction.Retain(),
+		TransactionMetadata: forkEvent.TransactionMetadata.Retain(),
+		Branch:              forkEvent.Branch.Retain(),
+		InputIDs:            forkEvent.InputIDs,
+	}
+}
+
+func cachedAttachmentsRetain(cachedTransaction *CachedAttachmentsEvent) *CachedAttachmentsEvent {
+	return &CachedAttachmentsEvent{
+		Transaction:         cachedTransaction.Transaction.Retain(),
+		TransactionMetadata: cachedTransaction.TransactionMetadata.Retain(),
+		Attachments:         cachedTransaction.Attachments.Retain(),
+	}
 }
diff --git a/dapps/valuetransfers/packages/tangle/signature_filter_test.go b/dapps/valuetransfers/packages/tangle/signature_filter_test.go
index cf47cbc11045abdbeec4f14ada2efaae6ddd62c2..e664d062b3893bcb3f9d3d101a3f087e31564111 100644
--- a/dapps/valuetransfers/packages/tangle/signature_filter_test.go
+++ b/dapps/valuetransfers/packages/tangle/signature_filter_test.go
@@ -121,31 +121,31 @@ func newSyncMessageParser(messageFilters ...messageparser.MessageFilter) (tester
 	}
 
 	// setup async behavior (store result + mark WaitGroup done)
-	messageParser.Events.BytesRejected.Attach(events.NewClosure(func(bytes []byte, err error, peer *peer.Peer) {
+	messageParser.Events.BytesRejected.Attach(events.NewClosure(func(bytesRejectedEvent *messageparser.BytesRejectedEvent, err error) {
 		tester.result = &messageParserResult{
 			accepted: false,
 			message:  nil,
-			peer:     peer,
+			peer:     bytesRejectedEvent.Peer,
 			err:      err,
 		}
 
 		tester.wg.Done()
 	}))
-	messageParser.Events.MessageRejected.Attach(events.NewClosure(func(message *message.Message, err error, peer *peer.Peer) {
+	messageParser.Events.MessageRejected.Attach(events.NewClosure(func(msgRejectedEvent *messageparser.MessageRejectedEvent, err error) {
 		tester.result = &messageParserResult{
 			accepted: false,
-			message:  message,
-			peer:     peer,
+			message:  msgRejectedEvent.Message,
+			peer:     msgRejectedEvent.Peer,
 			err:      err,
 		}
 
 		tester.wg.Done()
 	}))
-	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(message *message.Message, peer *peer.Peer) {
+	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *messageparser.MessageParsedEvent) {
 		tester.result = &messageParserResult{
 			accepted: true,
-			message:  message,
-			peer:     peer,
+			message:  msgParsedEvent.Message,
+			peer:     msgParsedEvent.Peer,
 			err:      nil,
 		}
 
diff --git a/dapps/valuetransfers/packages/tangle/tangle.go b/dapps/valuetransfers/packages/tangle/tangle.go
index dcc2f23febb551987faa71f4e1aba4195660711c..52007a6be3c999ba580975a34c28a58c95bd2be9 100644
--- a/dapps/valuetransfers/packages/tangle/tangle.go
+++ b/dapps/valuetransfers/packages/tangle/tangle.go
@@ -100,11 +100,18 @@ func (tangle *Tangle) AttachPayloadSync(payloadToStore *payload.Payload) {
 
 	// trigger events
 	if tangle.missingPayloadStorage.DeleteIfPresent(payloadToStore.ID().Bytes()) {
-		tangle.Events.MissingPayloadReceived.Trigger(cachedPayload, cachedPayloadMetadata)
+		tangle.Events.MissingPayloadReceived.Trigger(&CachedPayloadEvent{
+			Payload:         cachedPayload,
+			PayloadMetadata: cachedPayloadMetadata})
 	}
-	tangle.Events.PayloadAttached.Trigger(cachedPayload, cachedPayloadMetadata)
+	tangle.Events.PayloadAttached.Trigger(&CachedPayloadEvent{
+		Payload:         cachedPayload,
+		PayloadMetadata: cachedPayloadMetadata})
 	if transactionIsNew {
-		tangle.Events.TransactionReceived.Trigger(cachedTransaction, cachedTransactionMetadata, cachedAttachment)
+		tangle.Events.TransactionReceived.Trigger(&CachedAttachmentsEvent{
+			Transaction:         cachedTransaction,
+			TransactionMetadata: cachedTransactionMetadata,
+			Attachments:         cachedAttachment})
 	}
 
 	// check solidity
@@ -238,7 +245,11 @@ func (tangle *Tangle) Fork(transactionID transaction.ID, conflictingInputs []tra
 	}
 
 	// trigger events + set result
-	tangle.Events.Fork.Trigger(cachedTransaction, cachedTransactionMetadata, cachedTargetBranch, conflictingInputs)
+	tangle.Events.Fork.Trigger(&ForkEvent{
+		Transaction:         cachedTransaction,
+		TransactionMetadata: cachedTransactionMetadata,
+		Branch:              cachedTargetBranch,
+		InputIDs:            conflictingInputs})
 	forked = true
 
 	return
@@ -570,7 +581,9 @@ func (tangle *Tangle) setTransactionFinalized(transactionID transaction.ID, even
 			}
 
 			// trigger the corresponding event
-			tangle.Events.TransactionFinalized.Trigger(cachedTransaction, cachedTransactionMetadata)
+			tangle.Events.TransactionFinalized.Trigger(&CachedTransactionEvent{
+				Transaction:         cachedTransaction,
+				TransactionMetadata: cachedTransactionMetadata})
 
 			// propagate the rejected flag
 			if !metadata.Preferred() && !metadata.Rejected() {
@@ -641,7 +654,9 @@ func (tangle *Tangle) propagateRejectedToTransactions(transactionID transaction.
 						})
 					})
 
-					tangle.Events.TransactionUnpreferred.Trigger(cachedTransaction, cachedTransactionMetadata)
+					tangle.Events.TransactionUnpreferred.Trigger(&CachedTransactionEvent{
+						Transaction:         cachedTransaction,
+						TransactionMetadata: cachedTransactionMetadata})
 				}
 
 				// if the transaction is not finalized, yet then we set it to finalized
@@ -676,7 +691,9 @@ func (tangle *Tangle) propagateRejectedToTransactions(transactionID transaction.
 				})
 
 				// trigger event
-				tangle.Events.TransactionRejected.Trigger(cachedTransaction, cachedTransactionMetadata)
+				tangle.Events.TransactionRejected.Trigger(&CachedTransactionEvent{
+					Transaction:         cachedTransaction,
+					TransactionMetadata: cachedTransactionMetadata})
 			})
 		})
 	}
@@ -726,7 +743,9 @@ func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdateStackEntry(pro
 		}
 
 		// trigger payload event
-		tangle.Events.PayloadConfirmed.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata)
+		tangle.Events.PayloadConfirmed.Trigger(&CachedPayloadEvent{
+			Payload:         propagationStackEntry.CachedPayload,
+			PayloadMetadata: propagationStackEntry.CachedPayloadMetadata})
 
 		// propagate confirmed status to transaction and its outputs
 		if currentTransactionMetadata.setConfirmed(true) {
@@ -738,7 +757,9 @@ func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdateStackEntry(pro
 				return true
 			})
 
-			tangle.Events.TransactionConfirmed.Trigger(propagationStackEntry.CachedTransaction, propagationStackEntry.CachedTransactionMetadata)
+			tangle.Events.TransactionConfirmed.Trigger(&CachedTransactionEvent{
+				Transaction:         propagationStackEntry.CachedTransaction,
+				TransactionMetadata: propagationStackEntry.CachedTransactionMetadata})
 		}
 	case false:
 		// abort if transaction is not finalized and neither of parents is rejected
@@ -751,7 +772,9 @@ func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdateStackEntry(pro
 			return
 		}
 
-		tangle.Events.PayloadRejected.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata)
+		tangle.Events.PayloadRejected.Trigger(&CachedPayloadEvent{
+			Payload:         propagationStackEntry.CachedPayload,
+			PayloadMetadata: propagationStackEntry.CachedPayloadMetadata})
 	}
 
 	// schedule checks of approvers and consumers
@@ -789,9 +812,13 @@ func (tangle *Tangle) setTransactionPreferred(transactionID transaction.ID, pref
 
 			// trigger the correct event
 			if preferred {
-				tangle.Events.TransactionPreferred.Trigger(cachedTransaction, cachedTransactionMetadata)
+				tangle.Events.TransactionPreferred.Trigger(&CachedTransactionEvent{
+					Transaction:         cachedTransaction,
+					TransactionMetadata: cachedTransactionMetadata})
 			} else {
-				tangle.Events.TransactionUnpreferred.Trigger(cachedTransaction, cachedTransactionMetadata)
+				tangle.Events.TransactionUnpreferred.Trigger(&CachedTransactionEvent{
+					Transaction:         cachedTransaction,
+					TransactionMetadata: cachedTransactionMetadata})
 			}
 
 			// propagate changes to value tangle and branch DAG if we were called from the tangle
@@ -864,7 +891,9 @@ func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack
 		}
 
 		// trigger payload event
-		tangle.Events.PayloadLiked.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata)
+		tangle.Events.PayloadLiked.Trigger(&CachedPayloadEvent{
+			Payload:         propagationStackEntry.CachedPayload,
+			PayloadMetadata: propagationStackEntry.CachedPayloadMetadata})
 
 		// propagate liked to transaction and its outputs
 		if currentTransactionMetadata.setLiked(true) {
@@ -877,7 +906,9 @@ func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack
 			})
 
 			// trigger event
-			tangle.Events.TransactionLiked.Trigger(propagationStackEntry.CachedTransaction, propagationStackEntry.CachedTransactionMetadata)
+			tangle.Events.TransactionLiked.Trigger(&CachedTransactionEvent{
+				Transaction:         propagationStackEntry.CachedTransaction,
+				TransactionMetadata: propagationStackEntry.CachedTransactionMetadata})
 		}
 	case false:
 		// abort if the payload has been marked as disliked before
@@ -885,7 +916,9 @@ func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack
 			return
 		}
 
-		tangle.Events.PayloadDisliked.Trigger(propagationStackEntry.CachedPayload, propagationStackEntry.CachedPayloadMetadata)
+		tangle.Events.PayloadDisliked.Trigger(&CachedPayloadEvent{
+			Payload:         propagationStackEntry.CachedPayload,
+			PayloadMetadata: propagationStackEntry.CachedPayloadMetadata})
 
 		// look if we still have any liked attachments of this transaction
 		likedAttachmentFound := false
@@ -908,7 +941,9 @@ func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack
 				})
 
 				// trigger event
-				tangle.Events.TransactionDisliked.Trigger(propagationStackEntry.CachedTransaction, propagationStackEntry.CachedTransactionMetadata)
+				tangle.Events.TransactionDisliked.Trigger(&CachedTransactionEvent{
+					Transaction:         propagationStackEntry.CachedTransaction,
+					TransactionMetadata: propagationStackEntry.CachedTransactionMetadata})
 			}
 		}
 	}
@@ -1078,7 +1113,9 @@ func (tangle *Tangle) deleteTransaction(transactionID transaction.ID, cause erro
 	cachedTransaction.Consume(func(tx *transaction.Transaction) {
 		// if the removal was triggered by an invalid Transaction
 		if errors.Is(cause, ErrTransactionInvalid) {
-			tangle.Events.TransactionInvalid.Trigger(cachedTransaction, cachedTransactionMetadata, cause)
+			tangle.Events.TransactionInvalid.Trigger(&CachedTransactionEvent{
+				Transaction:         cachedTransaction,
+				TransactionMetadata: cachedTransactionMetadata}, cause)
 		}
 
 		// mark transaction as deleted
@@ -1151,7 +1188,9 @@ func (tangle *Tangle) deletePayloadFutureCone(payloadID payload.ID, cause error)
 		cachedPayload.Consume(func(currentPayload *payload.Payload) {
 			// trigger payload invalid if it was called with an "invalid cause"
 			if errors.Is(cause, ErrPayloadInvalid) || errors.Is(cause, ErrTransactionInvalid) {
-				tangle.Events.PayloadInvalid.Trigger(cachedPayload, cachedPayloadMetadata, cause)
+				tangle.Events.PayloadInvalid.Trigger(&CachedPayloadEvent{
+					Payload:         cachedPayload,
+					PayloadMetadata: cachedPayloadMetadata}, cause)
 			}
 
 			// delete payload
@@ -1231,7 +1270,10 @@ func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list.
 
 	// trigger events and schedule check of approvers / consumers
 	if transactionBooked {
-		tangle.Events.TransactionBooked.Trigger(solidificationStackEntry.CachedTransaction, solidificationStackEntry.CachedTransactionMetadata, decisionPending)
+		tangle.Events.TransactionBooked.Trigger(&CachedTransactionBookEvent{
+			Transaction:         solidificationStackEntry.CachedTransaction,
+			TransactionMetadata: solidificationStackEntry.CachedTransactionMetadata,
+			Pending:             decisionPending})
 
 		tangle.ForEachConsumers(currentTransaction, tangle.createValuePayloadFutureConeIterator(solidificationStack, processedPayloads))
 	}
@@ -1280,7 +1322,9 @@ func (tangle *Tangle) bookTransaction(cachedTransaction *transaction.CachedTrans
 	}
 
 	// trigger event if transaction became solid
-	tangle.Events.TransactionSolid.Trigger(cachedTransaction, cachedTransactionMetadata)
+	tangle.Events.TransactionSolid.Trigger(&CachedTransactionEvent{
+		Transaction:         cachedTransaction,
+		TransactionMetadata: cachedTransactionMetadata})
 
 	consumedBranches := make(branchmanager.BranchIds)
 	conflictingInputs := make([]transaction.OutputID, 0)
@@ -1437,7 +1481,9 @@ func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPa
 	}
 
 	// trigger event if payload became solid
-	tangle.Events.PayloadSolid.Trigger(cachedPayload, cachedPayloadMetadata)
+	tangle.Events.PayloadSolid.Trigger(&CachedPayloadEvent{
+		Payload:         cachedPayload,
+		PayloadMetadata: cachedPayloadMetadata})
 
 	cachedAggregatedBranch, err := tangle.BranchManager().AggregateBranches([]branchmanager.BranchID{parent2BranchID, parent1BranchID, transactionBranchID}...)
 	if err != nil {
diff --git a/dapps/valuetransfers/packages/tangle/tangle_event_test.go b/dapps/valuetransfers/packages/tangle/tangle_event_test.go
index bdd3f1dfc42386262c342e644c8d298852563958..2ac6a950d3f42a208def763922d1d7002f518798 100644
--- a/dapps/valuetransfers/packages/tangle/tangle_event_test.go
+++ b/dapps/valuetransfers/packages/tangle/tangle_event_test.go
@@ -4,9 +4,7 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
@@ -79,130 +77,174 @@ func (e *eventTangle) Expect(eventName string, arguments ...interface{}) {
 	e.On(eventName, arguments...).Once()
 }
 
-func (e *eventTangle) PayloadAttached(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap())
+func (e *eventTangle) PayloadAttached(cachedPayloadEvent *CachedPayloadEvent) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata})
 }
 
-func (e *eventTangle) PayloadSolid(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap())
+func (e *eventTangle) PayloadSolid(cachedPayloadEvent *CachedPayloadEvent) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata})
 }
 
-func (e *eventTangle) PayloadLiked(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap())
+func (e *eventTangle) PayloadLiked(cachedPayloadEvent *CachedPayloadEvent) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata})
 }
 
-func (e *eventTangle) PayloadConfirmed(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap())
+func (e *eventTangle) PayloadConfirmed(cachedPayloadEvent *CachedPayloadEvent) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata})
 }
 
-func (e *eventTangle) PayloadRejected(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap())
+func (e *eventTangle) PayloadRejected(cachedPayloadEvent *CachedPayloadEvent) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata})
 }
 
-func (e *eventTangle) PayloadDisliked(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap())
+func (e *eventTangle) PayloadDisliked(cachedPayloadEvent *CachedPayloadEvent) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata})
 }
 
-func (e *eventTangle) MissingPayloadReceived(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap())
+func (e *eventTangle) MissingPayloadReceived(cachedPayloadEvent *CachedPayloadEvent) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata})
 }
 
 func (e *eventTangle) PayloadMissing(id payload.ID) {
 	e.Called(id)
 }
 
-func (e *eventTangle) PayloadInvalid(payload *payload.CachedPayload, payloadMetadata *CachedPayloadMetadata, err error) {
-	defer payload.Release()
-	defer payloadMetadata.Release()
-	e.Called(payload.Unwrap(), payloadMetadata.Unwrap(), err)
-}
-
-func (e *eventTangle) TransactionReceived(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, attachment *CachedAttachment) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	defer attachment.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), attachment.Unwrap())
-}
-
-func (e *eventTangle) TransactionInvalid(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, err error) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), err)
-}
-
-func (e *eventTangle) TransactionSolid(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) TransactionBooked(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, decisionPending bool) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), decisionPending)
-}
-
-func (e *eventTangle) TransactionPreferred(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) TransactionUnpreferred(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) TransactionLiked(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) TransactionDisliked(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) TransactionFinalized(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) TransactionConfirmed(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) TransactionRejected(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap())
-}
-
-func (e *eventTangle) Fork(transaction *transaction.CachedTransaction, transactionMetadata *CachedTransactionMetadata, branch *branchmanager.CachedBranch, outputIDs []transaction.OutputID) {
-	defer transaction.Release()
-	defer transactionMetadata.Release()
-	defer branch.Release()
-	e.Called(transaction.Unwrap(), transactionMetadata.Unwrap(), branch.Unwrap(), outputIDs)
+func (e *eventTangle) PayloadInvalid(cachedPayloadEvent *CachedPayloadEvent, err error) {
+	defer cachedPayloadEvent.Payload.Release()
+	defer cachedPayloadEvent.PayloadMetadata.Release()
+	e.Called(&CachedPayloadEvent{
+		Payload:         cachedPayloadEvent.Payload,
+		PayloadMetadata: cachedPayloadEvent.PayloadMetadata}, err)
+}
+
+func (e *eventTangle) TransactionReceived(cachedAttachmentsEvent *CachedAttachmentsEvent) {
+	defer cachedAttachmentsEvent.Transaction.Release()
+	defer cachedAttachmentsEvent.TransactionMetadata.Release()
+	defer cachedAttachmentsEvent.Attachments.Release()
+	e.Called(&CachedAttachmentsEvent{
+		Transaction:         cachedAttachmentsEvent.Transaction,
+		TransactionMetadata: cachedAttachmentsEvent.TransactionMetadata,
+		Attachments:         cachedAttachmentsEvent.Attachments})
+}
+
+func (e *eventTangle) TransactionInvalid(cachedTransactionEvent *CachedTransactionEvent, err error) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata}, err)
+}
+
+func (e *eventTangle) TransactionSolid(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) TransactionBooked(cachedTransactionBookEvent *CachedTransactionBookEvent) {
+	defer cachedTransactionBookEvent.Transaction.Release()
+	defer cachedTransactionBookEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionBookEvent{
+		Transaction:         cachedTransactionBookEvent.Transaction,
+		TransactionMetadata: cachedTransactionBookEvent.TransactionMetadata,
+		Pending:             cachedTransactionBookEvent.Pending})
+}
+
+func (e *eventTangle) TransactionPreferred(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) TransactionUnpreferred(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) TransactionLiked(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) TransactionDisliked(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) TransactionFinalized(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) TransactionConfirmed(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) TransactionRejected(cachedTransactionEvent *CachedTransactionEvent) {
+	defer cachedTransactionEvent.Transaction.Release()
+	defer cachedTransactionEvent.TransactionMetadata.Release()
+	e.Called(&CachedTransactionEvent{
+		Transaction:         cachedTransactionEvent.Transaction,
+		TransactionMetadata: cachedTransactionEvent.TransactionMetadata})
+}
+
+func (e *eventTangle) Fork(forkEvent *ForkEvent) {
+	defer forkEvent.Transaction.Release()
+	defer forkEvent.TransactionMetadata.Release()
+	defer forkEvent.Branch.Release()
+	e.Called(&ForkEvent{
+		Transaction:         forkEvent.Transaction,
+		TransactionMetadata: forkEvent.TransactionMetadata,
+		Branch:              forkEvent.Branch,
+		InputIDs:            forkEvent.InputIDs})
 }
 
 // TODO: Error is never tested
diff --git a/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
index 542690dd8994a847f383ec96a9be6259165093e7..0fa4b6170fc77ee8df27015b6103c3df68edbebb 100644
--- a/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
+++ b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
@@ -80,11 +80,22 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-GENESIS, A+, B+, C+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything, true)
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.True(t, cachedTransactionBookEvent.Pending)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-GENESIS, A+, B+, C+]"])
@@ -154,11 +165,22 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-A, D+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-A, D+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-A, D+]"], mock.Anything, true)
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.True(t, cachedTransactionBookEvent.Pending)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-A, D+]"])
@@ -214,11 +236,22 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-B, -C, E+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-B, -C, E+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-B, -C, E+]"], mock.Anything, true)
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.True(t, cachedTransactionBookEvent.Pending)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-B, -C, E+]"])
@@ -265,8 +298,12 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 		// create payload
 		valueObjects["[-B, -C, E+] (Reattachment)"] = payload.New(valueObjects["[-B, -C, E+]"].ID(), valueObjects["[-GENESIS, A+, B+, C+]"].ID(), transactions["[-B, -C, E+]"])
 
-		tangle.Expect("PayloadAttached", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-B, -C, E+] (Reattachment)"])
@@ -329,12 +366,26 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-A, F+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-A, F+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-A, F+]"], mock.Anything, true)
-		tangle.Expect("Fork", transactions["[-A, D+]"], mock.Anything, mock.Anything, []transaction.OutputID{outputA})
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.True(t, cachedTransactionBookEvent.Pending)
+		}))
+		tangle.Expect("Fork", mock.MatchedBy(func(forkEvent *ForkEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], forkEvent.Transaction.Unwrap()) &&
+				assert.ElementsMatch(t, []transaction.OutputID{outputA}, forkEvent.InputIDs)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-A, F+]"])
@@ -413,11 +464,22 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-E, -F, G+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-E, -F, G+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-E, -F, G+]"], mock.Anything, true)
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.True(t, cachedTransactionBookEvent.Pending)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-E, -F, G+]"])
@@ -481,10 +543,18 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-F, -D, Y+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-F, -D, Y+]"], mock.Anything)
-		tangle.Expect("PayloadInvalid", valueObjects["[-F, -D, Y+]"], mock.Anything, mock.MatchedBy(func(err error) bool { return assert.Error(t, err) }))
-		tangle.Expect("TransactionReceived", transactions["[-F, -D, Y+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionInvalid", transactions["[-F, -D, Y+]"], mock.Anything, mock.MatchedBy(func(err error) bool { return assert.Error(t, err) }))
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-F, -D, Y+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadInvalid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-F, -D, Y+]"], cachedPayloadEvent.Payload.Unwrap())
+		}), mock.MatchedBy(func(err error) bool { return assert.Error(t, err) }))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-F, -D, Y+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionInvalid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-F, -D, Y+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}), mock.MatchedBy(func(err error) bool { return assert.Error(t, err) }))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-F, -D, Y+]"])
@@ -509,8 +579,12 @@ func preparePropagationScenario1(t *testing.T) (*eventTangle, map[string]*transa
 	{
 		valueObjects["[-B, -C, E+] (2nd Reattachment)"] = payload.New(valueObjects["[-A, F+]"].ID(), valueObjects["[-A, D+]"].ID(), transactions["[-B, -C, E+]"])
 
-		tangle.Expect("PayloadAttached", valueObjects["[-B, -C, E+] (2nd Reattachment)"], mock.Anything)
-		tangle.Expect("PayloadInvalid", valueObjects["[-B, -C, E+] (2nd Reattachment)"], mock.Anything, mock.MatchedBy(func(err error) bool { return assert.Error(t, err) }))
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (2nd Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadInvalid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (2nd Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}), mock.MatchedBy(func(err error) bool { return assert.Error(t, err) }))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-B, -C, E+] (2nd Reattachment)"])
@@ -565,12 +639,26 @@ func preparePropagationScenario2(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-C, H+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-C, H+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-C, H+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-C, H+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-C, H+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-C, H+]"], mock.Anything, true)
-		tangle.Expect("Fork", transactions["[-B, -C, E+]"], mock.Anything, mock.Anything, []transaction.OutputID{outputC})
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-C, H+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-C, H+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-C, H+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-C, H+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-C, H+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.Equal(t, true, cachedTransactionBookEvent.Pending)
+		}))
+		tangle.Expect("Fork", mock.MatchedBy(func(forkEvent *ForkEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], forkEvent.Transaction.Unwrap()) &&
+				assert.ElementsMatch(t, []transaction.OutputID{outputC}, forkEvent.InputIDs)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-C, H+]"])
@@ -671,11 +759,22 @@ func preparePropagationScenario2(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-H, -D, I+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-H, -D, I+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-H, -D, I+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-H, -D, I+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-H, -D, I+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-H, -D, I+]"], mock.Anything, true)
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-H, -D, I+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-H, -D, I+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-H, -D, I+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-H, -D, I+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-H, -D, I+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.True(t, cachedTransactionBookEvent.Pending)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-H, -D, I+]"])
@@ -740,11 +839,22 @@ func preparePropagationScenario2(t *testing.T) (*eventTangle, map[string]*transa
 		// check if signatures are valid
 		assert.True(t, transactions["[-B, J+]"].SignaturesValid())
 
-		tangle.Expect("PayloadAttached", valueObjects["[-B, J+]"], mock.Anything)
-		tangle.Expect("PayloadSolid", valueObjects["[-B, J+]"], mock.Anything)
-		tangle.Expect("TransactionReceived", transactions["[-B, J+]"], mock.Anything, mock.Anything)
-		tangle.Expect("TransactionSolid", transactions["[-B, J+]"], mock.Anything)
-		tangle.Expect("TransactionBooked", transactions["[-B, J+]"], mock.Anything, true)
+		tangle.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, J+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, J+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, J+]"], cachedAttachmentsEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, J+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, J+]"], cachedTransactionBookEvent.Transaction.Unwrap()) &&
+				assert.True(t, cachedTransactionBookEvent.Pending)
+		}))
 
 		// attach payload
 		tangle.AttachPayloadSync(valueObjects["[-B, J+]"])
@@ -811,31 +921,59 @@ func TestPropagationScenario1(t *testing.T) {
 		}
 
 		// preferring [-GENESIS, A+, B+, C+] will get it liked
-		tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
 
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true)
 		verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, false, true, false, false)
 
 		// finalizing [-B, -C, E+] will not get it confirmed, as [-GENESIS, A+, B+, C+] is not yet confirmed
-		tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
 
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true)
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, -C, E+]"])
 		verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, false, false)
 
 		// finalize [-GENESIS, A+, B+, C+] to also get [-B, -C, E+] as well as [-B, -C, E+] (Reattachment) confirmed
-		tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
 
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"])
 		verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false)
@@ -851,22 +989,54 @@ func TestPropagationScenario1(t *testing.T) {
 		defer tangle.DetachAll()
 
 		// finalizing [-GENESIS, A+, B+, C+] will get the entire future cone finalized and rejected
-		tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything)
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
 
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"])
 		verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], false, true, false, false, true)
@@ -893,26 +1063,53 @@ func TestPropagationScenario1(t *testing.T) {
 			debugger.RegisterAlias(tx.ID(), "TransactionID"+name)
 		}
 
-		tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
 
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true)
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"])
 		verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false)
 
-		tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything)
-
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 		// finalize & reject
 		//debugger.Enable()
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, -C, E+]"])
@@ -942,12 +1139,24 @@ func TestPropagationScenario1(t *testing.T) {
 		tangle, transactions, valueObjects, branches, _ := preparePropagationScenario1(t)
 		defer tangle.DetachAll()
 
-		tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true)
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"])
@@ -960,14 +1169,30 @@ func TestPropagationScenario1(t *testing.T) {
 		verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], false, false, false, false, false)
 		verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, false, false, false, false)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-B, -C, E+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// confirm [-B, -C, E+]
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true)
@@ -975,27 +1200,57 @@ func TestPropagationScenario1(t *testing.T) {
 		verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, true, false)
 		verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], true, true, true, true, false)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-A, D+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// prefer [-A, D+]
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-A, D+]"], true)
 		verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], true, false, true, false, false)
 		verifyBranchState(t, tangle, branches["A"], false, true, false, false)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("PayloadDisliked", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionUnpreferred", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionDisliked", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-A, D+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadDisliked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionUnpreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionDisliked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// simulate vote result to like [-A, F+] -> [-A, F+] becomes confirmed and [-A, D+] rejected
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-A, F+]"], true)
@@ -1006,12 +1261,24 @@ func TestPropagationScenario1(t *testing.T) {
 		verifyInclusionState(t, tangle, valueObjects["[-A, D+]"], false, true, false, false, true)
 		verifyBranchState(t, tangle, branches["A"], true, false, false, true)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-E, -F, G+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, false, false, false, false)
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-E, -F, G+]"], true)
@@ -1026,68 +1293,144 @@ func TestPropagationScenario1(t *testing.T) {
 		tangle, transactions, valueObjects, branches, _ := preparePropagationScenario1(t)
 		defer tangle.DetachAll()
 
-		tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// confirm [-GENESIS, A+, B+, C+]
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true)
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"])
 		verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-B, -C, E+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// confirm [-B, -C, E+]
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true)
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, -C, E+]"])
 		verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, true, false)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-A, F+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// prefer [-A, F+] and thus Branch B
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-A, F+]"], true)
 		verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], true, false, true, false, false)
 		verifyBranchState(t, tangle, branches["B"], false, true, false, false)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-E, -F, G+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// prefer [-E, -F, G+]
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-E, -F, G+]"], true)
 		verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], true, false, true, false, false)
 
-		tangle.Expect("PayloadLiked", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("PayloadConfirmed", valueObjects["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionPreferred", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionLiked", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything)
-		tangle.Expect("TransactionConfirmed", transactions["[-A, D+]"], mock.Anything)
-
-		tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("PayloadDisliked", valueObjects["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionUnpreferred", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionDisliked", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-A, F+]"], mock.Anything)
-		tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("PayloadDisliked", valueObjects["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionUnpreferred", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionDisliked", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything)
-		tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything)
+		tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadDisliked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionUnpreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionDisliked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("PayloadDisliked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+		}))
+		tangle.Expect("TransactionUnpreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionDisliked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
+		tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// simulate vote result to like [-A, D+] -> [-A, D+] becomes confirmed and [-A, F+], [-E, -F, G+] rejected
 		setTransactionPreferredWithCheck(t, tangle, transactions["[-A, D+]"], true)
@@ -1118,22 +1461,42 @@ func TestPropagationScenario2(t *testing.T) {
 		debugger.RegisterAlias(tx.ID(), "TransactionID"+name)
 	}
 
-	tangle.Expect("PayloadLiked", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-	tangle.Expect("PayloadConfirmed", valueObjects["[-GENESIS, A+, B+, C+]"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
-	tangle.Expect("TransactionConfirmed", transactions["[-GENESIS, A+, B+, C+]"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-GENESIS, A+, B+, C+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-GENESIS, A+, B+, C+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// confirm [-GENESIS, A+, B+, C+]
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"], true)
 	setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"])
 	verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false)
 
-	tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("PayloadLiked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-B, -C, E+]"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// prefer [-B, -C, E+] and thus Branch D
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-B, -C, E+]"], true)
@@ -1141,18 +1504,30 @@ func TestPropagationScenario2(t *testing.T) {
 	verifyBranchState(t, tangle, branches["D"], false, true, false, false)
 	verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], true, false, true, false, false)
 
-	tangle.Expect("PayloadLiked", valueObjects["[-A, F+]"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-A, F+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-A, F+]"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// prefer [-A, F+] and thus Branch B
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-A, F+]"], true)
 	verifyInclusionState(t, tangle, valueObjects["[-A, F+]"], true, false, true, false, false)
 	verifyBranchState(t, tangle, branches["B"], false, true, false, false)
 
-	tangle.Expect("PayloadLiked", valueObjects["[-E, -F, G+]"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-E, -F, G+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-E, -F, G+]"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// prefer [-E, -F, G+]
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-E, -F, G+]"], true)
@@ -1175,33 +1550,76 @@ func TestPropagationScenario2(t *testing.T) {
 	verifyBranchState(t, tangle, branches["E"], false, false, false, false)
 	verifyBranchState(t, tangle, branches["ACE"], false, false, false, false)
 
-	tangle.Expect("PayloadLiked", valueObjects["[-H, -D, I+]"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-H, -D, I+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-H, -D, I+]"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-H, -D, I+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-H, -D, I+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-H, -D, I+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// prefer [-H, -D, I+] - should be liked after votes on [-A, D+] and [-C, H+]
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-H, -D, I+]"], true)
 	verifyInclusionState(t, tangle, valueObjects["[-H, -D, I+]"], true, false, false, false, false)
 
-	tangle.Expect("PayloadLiked", valueObjects["[-A, D+]"], mock.Anything)
-	tangle.Expect("PayloadConfirmed", valueObjects["[-A, D+]"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-A, D+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-A, D+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-A, D+]"], mock.Anything)
-	tangle.Expect("TransactionConfirmed", transactions["[-A, D+]"], mock.Anything)
-
-	tangle.Expect("PayloadRejected", valueObjects["[-A, F+]"], mock.Anything)
-	tangle.Expect("PayloadDisliked", valueObjects["[-A, F+]"], mock.Anything)
-	tangle.Expect("TransactionUnpreferred", transactions["[-A, F+]"], mock.Anything)
-	tangle.Expect("TransactionDisliked", transactions["[-A, F+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-A, F+]"], mock.Anything)
-	tangle.Expect("TransactionRejected", transactions["[-A, F+]"], mock.Anything)
-	tangle.Expect("PayloadRejected", valueObjects["[-E, -F, G+]"], mock.Anything)
-	tangle.Expect("PayloadDisliked", valueObjects["[-E, -F, G+]"], mock.Anything)
-	tangle.Expect("TransactionUnpreferred", transactions["[-E, -F, G+]"], mock.Anything)
-	tangle.Expect("TransactionDisliked", transactions["[-E, -F, G+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-E, -F, G+]"], mock.Anything)
-	tangle.Expect("TransactionRejected", transactions["[-E, -F, G+]"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-A, D+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, D+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+
+	tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadDisliked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-A, F+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionUnpreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionDisliked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-A, F+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+
+	tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadDisliked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-E, -F, G+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionUnpreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionDisliked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-E, -F, G+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// simulate vote result to like [-A, D+] -> [-A, D+] becomes confirmed and [-A, F+], [-E, -F, G+] rejected
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-A, D+]"], true)
@@ -1213,21 +1631,49 @@ func TestPropagationScenario2(t *testing.T) {
 	verifyBranchState(t, tangle, branches["B"], true, false, false, true)
 	verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, true, false, false, true)
 
-	tangle.Expect("PayloadLiked", valueObjects["[-C, H+]"], mock.Anything)
-	tangle.Expect("PayloadConfirmed", valueObjects["[-C, H+]"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-C, H+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-C, H+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-C, H+]"], mock.Anything)
-	tangle.Expect("TransactionConfirmed", transactions["[-C, H+]"], mock.Anything)
-
-	tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("PayloadDisliked", valueObjects["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("TransactionUnpreferred", transactions["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("TransactionDisliked", transactions["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("TransactionRejected", transactions["[-B, -C, E+]"], mock.Anything)
-	tangle.Expect("PayloadRejected", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
-	tangle.Expect("PayloadDisliked", valueObjects["[-B, -C, E+] (Reattachment)"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-C, H+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-C, H+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-C, H+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-C, H+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-C, H+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-C, H+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+
+	tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadDisliked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionUnpreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionDisliked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionRejected", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, -C, E+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("PayloadRejected", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadDisliked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, -C, E+] (Reattachment)"], cachedPayloadEvent.Payload.Unwrap())
+	}))
 
 	// simulate vote result to like [-C, H+] -> [-C, H+] becomes confirmed and [-B, -C, E+], [-B, -C, E+] (Reattachment) rejected
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-C, H+]"], true)
@@ -1244,9 +1690,15 @@ func TestPropagationScenario2(t *testing.T) {
 	// TODO: BD is not finalized
 
 	// [-H, -D, I+] is already preferred
-	tangle.Expect("PayloadConfirmed", valueObjects["[-H, -D, I+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-H, -D, I+]"], mock.Anything)
-	tangle.Expect("TransactionConfirmed", transactions["[-H, -D, I+]"], mock.Anything)
+	tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-H, -D, I+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-H, -D, I+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-H, -D, I+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// [-H, -D, I+] should now be liked
 	verifyInclusionState(t, tangle, valueObjects["[-H, -D, I+]"], true, false, true, false, false)
@@ -1255,12 +1707,24 @@ func TestPropagationScenario2(t *testing.T) {
 	// [-B, J+] should be unchanged
 	verifyInclusionState(t, tangle, valueObjects["[-B, J+]"], false, false, false, false, false)
 
-	tangle.Expect("PayloadLiked", valueObjects["[-B, J+]"], mock.Anything)
-	tangle.Expect("PayloadConfirmed", valueObjects["[-B, J+]"], mock.Anything)
-	tangle.Expect("TransactionPreferred", transactions["[-B, J+]"], mock.Anything)
-	tangle.Expect("TransactionLiked", transactions["[-B, J+]"], mock.Anything)
-	tangle.Expect("TransactionFinalized", transactions["[-B, J+]"], mock.Anything)
-	tangle.Expect("TransactionConfirmed", transactions["[-B, J+]"], mock.Anything)
+	tangle.Expect("PayloadLiked", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, J+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("PayloadConfirmed", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(valueObjects["[-B, J+]"], cachedPayloadEvent.Payload.Unwrap())
+	}))
+	tangle.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, J+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionLiked", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, J+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionFinalized", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, J+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	tangle.Expect("TransactionConfirmed", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(transactions["[-B, J+]"], cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	// [-B, J+] should become confirmed after preferring and finalizing
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-B, J+]"], true)
diff --git a/dapps/valuetransfers/packages/tangle/tangle_test.go b/dapps/valuetransfers/packages/tangle/tangle_test.go
index b0d1273e98b444a5c9084b2281c420216458d248..fa5208cd2d9348621d6564bcfdc2555e80abb5b2 100644
--- a/dapps/valuetransfers/packages/tangle/tangle_test.go
+++ b/dapps/valuetransfers/packages/tangle/tangle_test.go
@@ -26,7 +26,9 @@ func TestSetTransactionPreferred(t *testing.T) {
 	valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx)
 	tangle.storeTransactionModels(valueObject)
 
-	event.Expect("TransactionPreferred", tx, mock.Anything)
+	event.Expect("TransactionPreferred", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(tx, cachedTransactionEvent.Transaction.Unwrap())
+	}))
 
 	modified, err := tangle.SetTransactionPreferred(tx.ID(), true)
 	require.NoError(t, err)
@@ -54,7 +56,9 @@ func TestBookTransaction(t *testing.T) {
 		cachedTransaction, cachedTransactionMetadata, _, transactionIsNew := tangle.storeTransactionModels(valueObject)
 		assert.True(t, transactionIsNew)
 
-		event.Expect("TransactionSolid", tx, mock.Anything)
+		event.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(tx, cachedTransactionEvent.Transaction.Unwrap())
+		}))
 
 		// manually trigger a booking: tx will be marked solid, but it cannot be book as its inputs are unavailable
 		transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata)
@@ -124,7 +128,9 @@ func TestBookTransaction(t *testing.T) {
 		// assert that branchID is undefined before being booked
 		assert.Equal(t, branchmanager.UndefinedBranchID, txMetadata.BranchID())
 
-		event.Expect("TransactionSolid", tx1, mock.Anything)
+		event.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+			return assert.ObjectsAreEqual(tx1, cachedTransactionEvent.Transaction.Unwrap())
+		}))
 		// TransactionBooked is triggered outside of bookTransaction
 
 		transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata)
@@ -157,8 +163,13 @@ func TestBookTransaction(t *testing.T) {
 			assert.Equal(t, branchmanager.UndefinedBranchID, txMetadata.BranchID())
 
 			// manually book the double spending tx2, this will mark it as solid and trigger a fork
-			event.Expect("TransactionSolid", tx2, mock.Anything)
-			event.Expect("Fork", tx1, mock.Anything, mock.Anything, inputIDs)
+			event.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+				return assert.ObjectsAreEqual(tx2, cachedTransactionEvent.Transaction.Unwrap())
+			}))
+			event.Expect("Fork", mock.MatchedBy(func(forkEvent *ForkEvent) bool {
+				return assert.ObjectsAreEqual(tx1, forkEvent.Transaction.Unwrap()) &&
+					assert.ElementsMatch(t, inputIDs, forkEvent.InputIDs)
+			}))
 
 			transactionBooked, decisionPending, err := tangle.bookTransaction(cachedTransaction, cachedTransactionMetadata)
 			require.NoError(t, err)
@@ -332,7 +343,10 @@ func TestFork(t *testing.T) {
 		valueObject := payload.New(payload.GenesisID, payload.GenesisID, tx)
 		tangle.storeTransactionModels(valueObject)
 
-		event.Expect("Fork", tx, mock.Anything, mock.Anything, []transaction.OutputID{})
+		event.Expect("Fork", mock.MatchedBy(func(forkEvent *ForkEvent) bool {
+			return assert.ObjectsAreEqual(tx, forkEvent.Transaction.Unwrap()) &&
+				assert.ElementsMatch(t, []transaction.OutputID{}, forkEvent.InputIDs)
+		}))
 
 		forked, finalized, err := tangle.Fork(tx.ID(), []transaction.OutputID{})
 		require.NoError(t, err)
@@ -390,7 +404,9 @@ func TestBookPayload(t *testing.T) {
 		txMetadata := cachedTransactionMetadata.Unwrap()
 		txMetadata.setBranchID(branchmanager.BranchID{1})
 
-		event.Expect("PayloadSolid", valueObject, mock.Anything)
+		event.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObject, cachedPayloadEvent.Payload.Unwrap())
+		}))
 		payloadBooked, err := tangle.bookPayload(cachedPayload.Retain(), cachedMetadata.Retain(), cachedTransactionMetadata.Retain())
 		defer func() {
 			cachedPayload.Release()
@@ -420,7 +436,9 @@ func TestBookPayload(t *testing.T) {
 		txMetadata := cachedTransactionMetadata.Unwrap()
 		txMetadata.setBranchID(branchmanager.BranchID{1})
 
-		event.Expect("PayloadSolid", valueObject, mock.Anything)
+		event.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+			return assert.ObjectsAreEqual(valueObject, cachedPayloadEvent.Payload.Unwrap())
+		}))
 		payloadBooked, err := tangle.bookPayload(cachedPayload.Retain(), cachedMetadata.Retain(), cachedTransactionMetadata.Retain())
 		defer func() {
 			cachedPayload.Release()
@@ -1261,7 +1279,9 @@ func TestPayloadBranchID(t *testing.T) {
 	{
 		valueObject := payload.New(payload.GenesisID, payload.GenesisID, createDummyTransaction())
 
-		event.Expect("PayloadMissing", valueObject.ID())
+		event.Expect("PayloadMissing", mock.MatchedBy(func(ID payload.ID) bool {
+			return assert.ObjectsAreEqual(valueObject.ID(), ID)
+		}))
 		branchID := tangle.payloadBranchID(valueObject.ID())
 		assert.Equal(t, branchmanager.UndefinedBranchID, branchID)
 	}
@@ -1573,19 +1593,38 @@ func TestMissingPayloadReceived(t *testing.T) {
 	parent := payload.New(payload.GenesisID, payload.GenesisID, tx)
 	child := payload.New(parent.ID(), parent.ID(), tx)
 
-	event.Expect("PayloadAttached", child, mock.Anything)
-	event.Expect("PayloadMissing", parent.ID(), mock.Anything)
-	event.Expect("TransactionReceived", tx, mock.Anything, mock.Anything)
+	event.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(child, cachedPayloadEvent.Payload.Unwrap())
+	}))
+	event.Expect("PayloadMissing", mock.MatchedBy(func(ID payload.ID) bool {
+		return assert.ObjectsAreEqual(parent.ID(), ID)
+	}))
+	event.Expect("TransactionReceived", mock.MatchedBy(func(cachedAttachmentsEvent *CachedAttachmentsEvent) bool {
+		return assert.ObjectsAreEqual(tx, cachedAttachmentsEvent.Transaction.Unwrap())
+	}))
 
 	// submit the child first; it cannot be solidified
 	tangle.AttachPayloadSync(child)
 
-	event.Expect("PayloadAttached", parent, mock.Anything)
-	event.Expect("PayloadSolid", parent, mock.Anything)
-	event.Expect("MissingPayloadReceived", parent, mock.Anything)
-	event.Expect("PayloadSolid", child, mock.Anything)
-	event.Expect("TransactionSolid", tx, mock.Anything, mock.Anything)
-	event.Expect("TransactionBooked", tx, mock.Anything, true)
+	event.Expect("PayloadAttached", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(parent, cachedPayloadEvent.Payload.Unwrap())
+	}))
+	event.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(parent, cachedPayloadEvent.Payload.Unwrap())
+	}))
+	event.Expect("MissingPayloadReceived", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(parent, cachedPayloadEvent.Payload.Unwrap())
+	}))
+	event.Expect("PayloadSolid", mock.MatchedBy(func(cachedPayloadEvent *CachedPayloadEvent) bool {
+		return assert.ObjectsAreEqual(child, cachedPayloadEvent.Payload.Unwrap())
+	}))
+	event.Expect("TransactionSolid", mock.MatchedBy(func(cachedTransactionEvent *CachedTransactionEvent) bool {
+		return assert.ObjectsAreEqual(tx, cachedTransactionEvent.Transaction.Unwrap())
+	}))
+	event.Expect("TransactionBooked", mock.MatchedBy(func(cachedTransactionBookEvent *CachedTransactionBookEvent) bool {
+		return assert.ObjectsAreEqual(tx, cachedTransactionBookEvent.Transaction.Unwrap()) &&
+			assert.True(t, cachedTransactionBookEvent.Pending)
+	}))
 
 	// submitting the parent makes everything solid
 	tangle.AttachPayloadSync(parent)
diff --git a/dapps/valuetransfers/packages/test/tangle_test.go b/dapps/valuetransfers/packages/test/tangle_test.go
index 82be2f4c6ef761c993b6f395e0dd741174333b7c..cccd920d2345680c532637740e3a99549b9605b7 100644
--- a/dapps/valuetransfers/packages/test/tangle_test.go
+++ b/dapps/valuetransfers/packages/test/tangle_test.go
@@ -105,10 +105,10 @@ func TestTangle_ValueTransfer(t *testing.T) {
 func recordLikedPayloads(valueTangle *tangle.Tangle) (recordedLikedPayloads map[payload.ID]types.Empty, resetFunc func()) {
 	recordedLikedPayloads = make(map[payload.ID]types.Empty)
 
-	valueTangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *tangle.CachedPayloadMetadata) {
-		defer cachedPayloadMetadata.Release()
+	valueTangle.Events.PayloadLiked.Attach(events.NewClosure(func(cachedPayloadEvent *tangle.CachedPayloadEvent) {
+		defer cachedPayloadEvent.PayloadMetadata.Release()
 
-		cachedPayload.Consume(func(payload *payload.Payload) {
+		cachedPayloadEvent.Payload.Consume(func(payload *payload.Payload) {
 			recordedLikedPayloads[payload.ID()] = types.Void
 		})
 	}))
diff --git a/packages/binary/drng/drng.go b/packages/binary/drng/drng.go
index 357457b93ffa898f5de114f911871c75fdef8ecc..af1a1a4272d79d374f314081be5324fbcd2cb2cb 100644
--- a/packages/binary/drng/drng.go
+++ b/packages/binary/drng/drng.go
@@ -2,8 +2,6 @@ package drng
 
 import (
 	"github.com/iotaledger/goshimmer/packages/binary/drng/state"
-	cbEvents "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectivebeacon/events"
-	"github.com/iotaledger/hive.go/events"
 )
 
 // DRNG holds the state and events of a drng instance.
@@ -15,10 +13,7 @@ type DRNG struct {
 // New creates a new DRNG instance.
 func New(setters ...state.Option) *DRNG {
 	return &DRNG{
-		State: state.New(setters...),
-		Events: &Event{
-			CollectiveBeacon: events.NewEvent(cbEvents.CollectiveBeaconReceived),
-			Randomness:       events.NewEvent(randomnessReceived),
-		},
+		State:  state.New(setters...),
+		Events: newEvent(),
 	}
 }
diff --git a/packages/binary/drng/events.go b/packages/binary/drng/events.go
index a3420fcaca949bb995910044b0a3d74b42092151..f45c95d8d578b4327431c449f8d7da694f661db4 100644
--- a/packages/binary/drng/events.go
+++ b/packages/binary/drng/events.go
@@ -2,6 +2,7 @@ package drng
 
 import (
 	"github.com/iotaledger/goshimmer/packages/binary/drng/state"
+	cbEvents "github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectivebeacon/events"
 	"github.com/iotaledger/hive.go/events"
 )
 
@@ -13,6 +14,13 @@ type Event struct {
 	Randomness *events.Event
 }
 
+func newEvent() *Event {
+	return &Event{
+		CollectiveBeacon: events.NewEvent(cbEvents.CollectiveBeaconReceived),
+		Randomness:       events.NewEvent(randomnessReceived),
+	}
+}
+
 func randomnessReceived(handler interface{}, params ...interface{}) {
 	handler.(func(state.Randomness))(params[0].(state.Randomness))
 }
diff --git a/packages/binary/messagelayer/messageparser/events.go b/packages/binary/messagelayer/messageparser/events.go
index d02a52d85a376ac09e2986e4bba3fcb57847e57b..b10316d01075f2c4e744354714bd00f90ff7bc3b 100644
--- a/packages/binary/messagelayer/messageparser/events.go
+++ b/packages/binary/messagelayer/messageparser/events.go
@@ -1,6 +1,10 @@
 package messageparser
 
-import "github.com/iotaledger/hive.go/events"
+import (
+	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/hive.go/autopeering/peer"
+	"github.com/iotaledger/hive.go/events"
+)
 
 // Events represents events happening on a message parser.
 type Events struct {
@@ -11,3 +15,41 @@ type Events struct {
 	// Fired when a message got rejected by a filter.
 	MessageRejected *events.Event
 }
+
+// MessageParsedEvent represents the parameters of messageParsedEvent
+type MessageParsedEvent struct {
+	Message *message.Message
+	Peer    *peer.Peer
+}
+
+// BytesRejectedEvent represents the parameters of bytesRejectedEvent
+type BytesRejectedEvent struct {
+	Bytes []byte
+	Peer  *peer.Peer
+}
+
+// MessageRejectedEvent represents the parameters of messageRejectedEvent
+type MessageRejectedEvent struct {
+	Message *message.Message
+	Peer    *peer.Peer
+}
+
+func newEvents() *Events {
+	return &Events{
+		MessageParsed:   events.NewEvent(messageParsedEvent),
+		BytesRejected:   events.NewEvent(bytesRejectedEvent),
+		MessageRejected: events.NewEvent(messageRejectedEvent),
+	}
+}
+
+func messageParsedEvent(handler interface{}, params ...interface{}) {
+	handler.(func(*MessageParsedEvent))(params[0].(*MessageParsedEvent))
+}
+
+func bytesRejectedEvent(handler interface{}, params ...interface{}) {
+	handler.(func(*BytesRejectedEvent, error))(params[0].(*BytesRejectedEvent), params[1].(error))
+}
+
+func messageRejectedEvent(handler interface{}, params ...interface{}) {
+	handler.(func(*MessageRejectedEvent, error))(params[0].(*MessageRejectedEvent), params[1].(error))
+}
diff --git a/packages/binary/messagelayer/messageparser/message_parser.go b/packages/binary/messagelayer/messageparser/message_parser.go
index 8125095c65dab023ffd8877135ac41dd7d803d5b..05c4f5c089ad25111e2b213c85f10f57dd603231 100644
--- a/packages/binary/messagelayer/messageparser/message_parser.go
+++ b/packages/binary/messagelayer/messageparser/message_parser.go
@@ -7,7 +7,6 @@ import (
 	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messageparser/builtinfilters"
 
 	"github.com/iotaledger/hive.go/autopeering/peer"
-	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/typeutils"
 )
 
@@ -15,7 +14,7 @@ import (
 type MessageParser struct {
 	bytesFilters   []BytesFilter
 	messageFilters []MessageFilter
-	Events         Events
+	Events         *Events
 
 	byteFiltersModified    typeutils.AtomicBool
 	messageFiltersModified typeutils.AtomicBool
@@ -28,17 +27,7 @@ func New() (result *MessageParser) {
 	result = &MessageParser{
 		bytesFilters:   make([]BytesFilter, 0),
 		messageFilters: make([]MessageFilter, 0),
-		Events: Events{
-			MessageParsed: events.NewEvent(func(handler interface{}, params ...interface{}) {
-				handler.(func(*message.Message, *peer.Peer))(params[0].(*message.Message), params[1].(*peer.Peer))
-			}),
-			BytesRejected: events.NewEvent(func(handler interface{}, params ...interface{}) {
-				handler.(func([]byte, error, *peer.Peer))(params[0].([]byte), params[1].(error), params[2].(*peer.Peer))
-			}),
-			MessageRejected: events.NewEvent(func(handler interface{}, params ...interface{}) {
-				handler.(func(*message.Message, error, *peer.Peer))(params[0].(*message.Message), params[1].(error), params[2].(*peer.Peer))
-			}),
-		},
+		Events:         newEvents(),
 	}
 
 	// add builtin filters
@@ -88,7 +77,9 @@ func (messageParser *MessageParser) setupBytesFilterDataFlow() {
 				messageParser.bytesFilters[i].OnAccept(messageParser.bytesFilters[i+1].Filter)
 			}
 			messageParser.bytesFilters[i].OnReject(func(bytes []byte, err error, peer *peer.Peer) {
-				messageParser.Events.BytesRejected.Trigger(bytes, err, peer)
+				messageParser.Events.BytesRejected.Trigger(&BytesRejectedEvent{
+					Bytes: bytes,
+					Peer:  peer}, err)
 			})
 		}
 	}
@@ -109,13 +100,17 @@ func (messageParser *MessageParser) setupMessageFilterDataFlow() {
 		for i := 0; i < numberOfMessageFilters; i++ {
 			if i == numberOfMessageFilters-1 {
 				messageParser.messageFilters[i].OnAccept(func(msg *message.Message, peer *peer.Peer) {
-					messageParser.Events.MessageParsed.Trigger(msg, peer)
+					messageParser.Events.MessageParsed.Trigger(&MessageParsedEvent{
+						Message: msg,
+						Peer:    peer})
 				})
 			} else {
 				messageParser.messageFilters[i].OnAccept(messageParser.messageFilters[i+1].Filter)
 			}
 			messageParser.messageFilters[i].OnReject(func(msg *message.Message, err error, peer *peer.Peer) {
-				messageParser.Events.MessageRejected.Trigger(msg, err, peer)
+				messageParser.Events.MessageRejected.Trigger(&MessageRejectedEvent{
+					Message: msg,
+					Peer:    peer}, err)
 			})
 		}
 	}
@@ -125,7 +120,9 @@ func (messageParser *MessageParser) setupMessageFilterDataFlow() {
 // parses the given message and emits
 func (messageParser *MessageParser) parseMessage(bytes []byte, peer *peer.Peer) {
 	if parsedMessage, _, err := message.FromBytes(bytes); err != nil {
-		messageParser.Events.BytesRejected.Trigger(bytes, err, peer)
+		messageParser.Events.BytesRejected.Trigger(&BytesRejectedEvent{
+			Bytes: bytes,
+			Peer:  peer}, err)
 	} else {
 		messageParser.messageFilters[0].Filter(parsedMessage, peer)
 	}
diff --git a/packages/binary/messagelayer/messageparser/message_parser_test.go b/packages/binary/messagelayer/messageparser/message_parser_test.go
index 4f96612c0cf8c89c84d6702521dda9869320d0ec..fe0ab7fbe0e67b574fda2aa778702d2b69f15449 100644
--- a/packages/binary/messagelayer/messageparser/message_parser_test.go
+++ b/packages/binary/messagelayer/messageparser/message_parser_test.go
@@ -45,7 +45,7 @@ func TestMessageParser_ParseMessage(t *testing.T) {
 	msgParser := New()
 	msgParser.Parse(msg.Bytes(), nil)
 
-	msgParser.Events.MessageParsed.Attach(events.NewClosure(func(msg *message.Message) {
+	msgParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *MessageParsedEvent) {
 		log.Infof("parsed message")
 	}))
 }
diff --git a/packages/binary/messagelayer/messagerequester/events.go b/packages/binary/messagelayer/messagerequester/events.go
index d5c780558eef04c622631176e8bfaaf9192ebc94..74465a1b5a47d5cbde34cbeb70f30fe4cb609116 100644
--- a/packages/binary/messagelayer/messagerequester/events.go
+++ b/packages/binary/messagelayer/messagerequester/events.go
@@ -1,6 +1,7 @@
 package messagerequester
 
 import (
+	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	"github.com/iotaledger/hive.go/events"
 )
 
@@ -11,3 +12,28 @@ type Events struct {
 	// MissingMessageAppeared is triggered when a message is actually present in the node's db although it was still being requested.
 	MissingMessageAppeared *events.Event
 }
+
+// SendRequestEvent represents the parameters of sendRequestEvent
+type SendRequestEvent struct {
+	ID message.ID
+}
+
+// MissingMessageAppearedEvent represents the parameters of missingMessageAppearedEvent
+type MissingMessageAppearedEvent struct {
+	ID message.ID
+}
+
+func newEvents() *Events {
+	return &Events{
+		SendRequest:            events.NewEvent(sendRequestEvent),
+		MissingMessageAppeared: events.NewEvent(missingMessageAppearedEvent),
+	}
+}
+
+func sendRequestEvent(handler interface{}, params ...interface{}) {
+	handler.(func(*SendRequestEvent))(params[0].(*SendRequestEvent))
+}
+
+func missingMessageAppearedEvent(handler interface{}, params ...interface{}) {
+	handler.(func(*MissingMessageAppearedEvent))(params[0].(*MissingMessageAppearedEvent))
+}
diff --git a/packages/binary/messagelayer/messagerequester/messagerequester.go b/packages/binary/messagelayer/messagerequester/messagerequester.go
index e22943a2e7c6fce9dbb532160dda8e0571d0f1ab..a6ba73120e237e6452f466003b56e394a4c64366 100644
--- a/packages/binary/messagelayer/messagerequester/messagerequester.go
+++ b/packages/binary/messagelayer/messagerequester/messagerequester.go
@@ -5,7 +5,6 @@ import (
 	"time"
 
 	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
-	"github.com/iotaledger/hive.go/events"
 )
 
 // the maximum amount of requests before we abort
@@ -15,7 +14,7 @@ const maxRequestThreshold = 500
 type MessageRequester struct {
 	scheduledRequests map[message.ID]*time.Timer
 	options           *Options
-	Events            Events
+	Events            *Events
 
 	scheduledRequestsMutex sync.RWMutex
 }
@@ -28,14 +27,7 @@ func New(missingMessages []message.ID, optionalOptions ...Option) *MessageReques
 	requester := &MessageRequester{
 		scheduledRequests: make(map[message.ID]*time.Timer),
 		options:           newOptions(optionalOptions),
-		Events: Events{
-			SendRequest: events.NewEvent(func(handler interface{}, params ...interface{}) {
-				handler.(func(message.ID))(params[0].(message.ID))
-			}),
-			MissingMessageAppeared: events.NewEvent(func(handler interface{}, params ...interface{}) {
-				handler.(func(message.ID))(params[0].(message.ID))
-			}),
-		},
+		Events:            newEvents(),
 	}
 
 	// add requests for all missing messages
@@ -62,7 +54,7 @@ func (requester *MessageRequester) StartRequest(id message.ID) {
 	// schedule the next request and trigger the event
 	requester.scheduledRequests[id] = time.AfterFunc(requester.options.retryInterval, requester.createReRequest(id, 0))
 	requester.scheduledRequestsMutex.Unlock()
-	requester.Events.SendRequest.Trigger(id)
+	requester.Events.SendRequest.Trigger(&SendRequestEvent{ID: id})
 }
 
 // StopRequest stops requests for the given message to further happen.
@@ -77,7 +69,7 @@ func (requester *MessageRequester) StopRequest(id message.ID) {
 }
 
 func (requester *MessageRequester) reRequest(id message.ID, count int) {
-	requester.Events.SendRequest.Trigger(id)
+	requester.Events.SendRequest.Trigger(&SendRequestEvent{ID: id})
 
 	// as we schedule a request at most once per id we do not need to make the trigger and the re-schedule atomic
 	requester.scheduledRequestsMutex.Lock()
diff --git a/packages/binary/messagelayer/tangle/events.go b/packages/binary/messagelayer/tangle/events.go
index 6e8f0519a0225d72f8e58359abc7b27526aba6b0..4799082bb03be15a4d3a04db5bfa6a871e26147a 100644
--- a/packages/binary/messagelayer/tangle/events.go
+++ b/packages/binary/messagelayer/tangle/events.go
@@ -24,6 +24,12 @@ type Events struct {
 	MessageRemoved *events.Event
 }
 
+// CachedMessageEvent represents the parameters of cachedMessageEvent
+type CachedMessageEvent struct {
+	Message         *message.CachedMessage
+	MessageMetadata *CachedMessageMetadata
+}
+
 func newEvents() *Events {
 	return &Events{
 		MessageAttached:        events.NewEvent(cachedMessageEvent),
@@ -40,8 +46,12 @@ func messageIDEvent(handler interface{}, params ...interface{}) {
 }
 
 func cachedMessageEvent(handler interface{}, params ...interface{}) {
-	handler.(func(*message.CachedMessage, *CachedMessageMetadata))(
-		params[0].(*message.CachedMessage).Retain(),
-		params[1].(*CachedMessageMetadata).Retain(),
-	)
+	handler.(func(*CachedMessageEvent))(cachedMessageRetain(params[0].(*CachedMessageEvent)))
+}
+
+func cachedMessageRetain(object *CachedMessageEvent) *CachedMessageEvent {
+	return &CachedMessageEvent{
+		Message:         object.Message.Retain(),
+		MessageMetadata: object.MessageMetadata.Retain(),
+	}
 }
diff --git a/packages/binary/messagelayer/tangle/tangle.go b/packages/binary/messagelayer/tangle/tangle.go
index 69d37ff98e4c07910360d95b46482f0e9bfd12b6..497eaaa3bc7bfb0c5d476e7940520524a8600eeb 100644
--- a/packages/binary/messagelayer/tangle/tangle.go
+++ b/packages/binary/messagelayer/tangle/tangle.go
@@ -23,7 +23,7 @@ type Tangle struct {
 	approverStorage        *objectstorage.ObjectStorage
 	missingMessageStorage  *objectstorage.ObjectStorage
 
-	Events Events
+	Events *Events
 
 	storeMessageWorkerPool async.WorkerPool
 	solidifierWorkerPool   async.WorkerPool
@@ -53,7 +53,7 @@ func New(store kvstore.KVStore) (result *Tangle) {
 		approverStorage:        osFactory.New(PrefixApprovers, approverFactory, objectstorage.CacheTime(cacheTime), objectstorage.PartitionKey(message.IDLength, message.IDLength), objectstorage.LeakDetectionEnabled(false)),
 		missingMessageStorage:  osFactory.New(PrefixMissingMessage, missingMessageFactory, objectstorage.CacheTime(cacheTime), objectstorage.LeakDetectionEnabled(false)),
 
-		Events: *newEvents(),
+		Events: newEvents(),
 	}
 
 	result.solidifierWorkerPool.Tune(1024)
@@ -206,10 +206,14 @@ func (tangle *Tangle) storeMessageWorker(msg *message.Message) {
 
 	// trigger events
 	if tangle.missingMessageStorage.DeleteIfPresent(messageID[:]) {
-		tangle.Events.MissingMessageReceived.Trigger(cachedMessage, cachedMsgMetadata)
+		tangle.Events.MissingMessageReceived.Trigger(&CachedMessageEvent{
+			Message:         cachedMessage,
+			MessageMetadata: cachedMsgMetadata})
 	}
 
-	tangle.Events.MessageAttached.Trigger(cachedMessage, cachedMsgMetadata)
+	tangle.Events.MessageAttached.Trigger(&CachedMessageEvent{
+		Message:         cachedMessage,
+		MessageMetadata: cachedMsgMetadata})
 
 	// check message solidity
 	tangle.solidifierWorkerPool.Submit(func() {
@@ -299,7 +303,9 @@ func (tangle *Tangle) checkMessageSolidityAndPropagate(cachedMessage *message.Ca
 
 		// mark the message as solid if it has become solid
 		if tangle.isMessageSolid(currentMessage, currentMsgMetadata) && currentMsgMetadata.SetSolid(true) {
-			tangle.Events.MessageSolid.Trigger(currentCachedMessage, currentCachedMsgMetadata)
+			tangle.Events.MessageSolid.Trigger(&CachedMessageEvent{
+				Message:         currentCachedMessage,
+				MessageMetadata: currentCachedMsgMetadata})
 
 			// auto. push approvers of the newly solid message to propagate solidification
 			tangle.Approvers(currentMessage.ID()).Consume(func(approver *Approver) {
diff --git a/packages/binary/messagelayer/tangle/tangle_test.go b/packages/binary/messagelayer/tangle/tangle_test.go
index 3052e8735f51d5987f59a7dcdf11e947cf60dce1..5cff80696c84d4cc26f8dd6911ed5db0f5d32ade 100644
--- a/packages/binary/messagelayer/tangle/tangle_test.go
+++ b/packages/binary/messagelayer/tangle/tangle_test.go
@@ -52,18 +52,18 @@ func TestTangle_AttachMessage(t *testing.T) {
 		return
 	}
 
-	messageTangle.Events.MessageAttached.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *CachedMessageMetadata) {
-		cachedMessageMetadata.Release()
+	messageTangle.Events.MessageAttached.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
 
-		cachedMessage.Consume(func(msg *message.Message) {
+		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
 			fmt.Println("ATTACHED:", msg.ID())
 		})
 	}))
 
-	messageTangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *CachedMessageMetadata) {
-		cachedMessageMetadata.Release()
+	messageTangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
 
-		cachedMessage.Consume(func(msg *message.Message) {
+		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
 			fmt.Println("SOLID:", msg.ID())
 		})
 	}))
@@ -162,9 +162,9 @@ func TestTangle_MissingMessages(t *testing.T) {
 	fmt.Println("PRE-GENERATING MESSAGES: DONE")
 
 	var receivedTransactionsCounter int32
-	tangle.Events.MessageAttached.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *CachedMessageMetadata) {
-		defer cachedMessage.Release()
-		defer cachedMessageMetadata.Release()
+	tangle.Events.MessageAttached.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
+		defer cachedMsgEvent.Message.Release()
+		defer cachedMsgEvent.MessageMetadata.Release()
 
 		newReceivedTransactionsCounterValue := atomic.AddInt32(&receivedTransactionsCounter, 1)
 		if newReceivedTransactionsCounterValue%1000 == 0 {
@@ -188,9 +188,9 @@ func TestTangle_MissingMessages(t *testing.T) {
 	}))
 
 	// decrease the counter when a missing message was received
-	tangle.Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *CachedMessageMetadata) {
-		cachedMessageMetadata.Release()
-		cachedMessage.Consume(func(msg *message.Message) {
+	tangle.Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
+		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
 			missingMessagesMapMutex.Lock()
 			delete(missingMessagesMap, msg.ID())
 			missingMessagesMapMutex.Unlock()
@@ -199,9 +199,9 @@ func TestTangle_MissingMessages(t *testing.T) {
 
 	// mark the WaitGroup as done if all messages are solid
 	solidMessageCounter := int32(0)
-	tangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *CachedMessageMetadata) {
-		defer cachedMessageMetadata.Release()
-		defer cachedMessage.Release()
+	tangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *CachedMessageEvent) {
+		defer cachedMsgEvent.MessageMetadata.Release()
+		defer cachedMsgEvent.Message.Release()
 
 		// print progress status message
 		newSolidCounterValue := atomic.AddInt32(&solidMessageCounter, 1)
diff --git a/packages/binary/messagelayer/test/retrievealltips_test.go b/packages/binary/messagelayer/test/retrievealltips_test.go
index 089f222968b62ff78c9db067678c4542c7315359..dc6b4f1c8d8d3c588d7c6dba3aae7d0a01d0d252 100644
--- a/packages/binary/messagelayer/test/retrievealltips_test.go
+++ b/packages/binary/messagelayer/test/retrievealltips_test.go
@@ -23,9 +23,9 @@ func TestRetrieveAllTips(t *testing.T) {
 
 	var wg sync.WaitGroup
 
-	messageTangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		cachedMessage.Release()
-		cachedMessageMetadata.Release()
+	messageTangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.Message.Release()
+		cachedMsgEvent.MessageMetadata.Release()
 		wg.Done()
 	}))
 
diff --git a/packages/binary/messagelayer/tipselector/events.go b/packages/binary/messagelayer/tipselector/events.go
index 348985408f3b29b03fba5f06f926b4d779ca06d8..6107ed5c957d187dce6ba3660d003fc518904130 100644
--- a/packages/binary/messagelayer/tipselector/events.go
+++ b/packages/binary/messagelayer/tipselector/events.go
@@ -14,6 +14,13 @@ type Events struct {
 	TipRemoved *events.Event
 }
 
+func newEvents() *Events {
+	return &Events{
+		TipAdded:   events.NewEvent(messageIDEvent),
+		TipRemoved: events.NewEvent(messageIDEvent),
+	}
+}
+
 func messageIDEvent(handler interface{}, params ...interface{}) {
 	handler.(func(message.ID))(params[0].(message.ID))
 }
diff --git a/packages/binary/messagelayer/tipselector/tipselector.go b/packages/binary/messagelayer/tipselector/tipselector.go
index 96fe65f0c4d7cadb49f55e9b5407f97d610005f4..3bd9bda0879ac2c1aa3d3a035779bb15ab03bd4f 100644
--- a/packages/binary/messagelayer/tipselector/tipselector.go
+++ b/packages/binary/messagelayer/tipselector/tipselector.go
@@ -1,8 +1,6 @@
 package tipselector
 
 import (
-	"github.com/iotaledger/hive.go/events"
-
 	"github.com/iotaledger/goshimmer/packages/binary/datastructure"
 	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 )
@@ -10,17 +8,14 @@ import (
 // TipSelector manages a map of tips and emits events for their removal and addition.
 type TipSelector struct {
 	tips   *datastructure.RandomMap
-	Events Events
+	Events *Events
 }
 
 // New creates a new tip-selector.
 func New(tips ...message.ID) *TipSelector {
 	tipSelector := &TipSelector{
-		tips: datastructure.NewRandomMap(),
-		Events: Events{
-			TipAdded:   events.NewEvent(messageIDEvent),
-			TipRemoved: events.NewEvent(messageIDEvent),
-		},
+		tips:   datastructure.NewRandomMap(),
+		Events: newEvents(),
 	}
 
 	if tips != nil {
diff --git a/plugins/dashboard/livefeed.go b/plugins/dashboard/livefeed.go
index 0d3721dad9c347c27e3efda918cfe80515106048..95bf6c5452a336357d9357da193e16616c2a29aa 100644
--- a/plugins/dashboard/livefeed.go
+++ b/plugins/dashboard/livefeed.go
@@ -28,17 +28,17 @@ func configureLiveFeed() {
 
 func runLiveFeed() {
 	newMsgRateLimiter := time.NewTicker(time.Second / 10)
-	notifyNewMsg := events.NewClosure(func(message *message.CachedMessage, metadata *tangle.CachedMessageMetadata) {
-		metadata.Release()
+	notifyNewMsg := events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
 
 		select {
 		case <-newMsgRateLimiter.C:
-			_, ok := liveFeedWorkerPool.TrySubmit(message)
+			_, ok := liveFeedWorkerPool.TrySubmit(cachedMsgEvent.Message)
 			if !ok {
-				message.Release()
+				cachedMsgEvent.Message.Release()
 			}
 		default:
-			message.Release()
+			cachedMsgEvent.Message.Release()
 		}
 	})
 
diff --git a/plugins/dashboard/visualizer.go b/plugins/dashboard/visualizer.go
index d64c768fa0c87625302baa93b9b9dab0706a2adc..271e8020522fd82aa2b197fe22babeb4edc93930 100644
--- a/plugins/dashboard/visualizer.go
+++ b/plugins/dashboard/visualizer.go
@@ -68,13 +68,13 @@ func sendTipInfo(messageID message.ID, isTip bool) {
 }
 
 func runVisualizer() {
-	notifyNewMsg := events.NewClosure(func(message *message.CachedMessage, metadata *tangle.CachedMessageMetadata) {
-		defer message.Release()
-		defer metadata.Release()
-		_, ok := visualizerWorkerPool.TrySubmit(message.Retain(), metadata.Retain())
+	notifyNewMsg := events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		defer cachedMsgEvent.Message.Release()
+		defer cachedMsgEvent.MessageMetadata.Release()
+		_, ok := visualizerWorkerPool.TrySubmit(cachedMsgEvent.Message.Retain(), cachedMsgEvent.MessageMetadata.Retain())
 		if !ok {
-			message.Release()
-			metadata.Release()
+			cachedMsgEvent.Message.Release()
+			cachedMsgEvent.MessageMetadata.Release()
 		}
 	})
 
diff --git a/plugins/drng/plugin.go b/plugins/drng/plugin.go
index c0714e8a20a878e03dc890f33a7b2ac878ac3f1e..add3f3583824db43146bea1335ae10edaf02fc85 100644
--- a/plugins/drng/plugin.go
+++ b/plugins/drng/plugin.go
@@ -43,10 +43,10 @@ func run(*node.Plugin) {}
 
 func configureEvents() {
 	instance := Instance()
-	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		cachedMessageMetadata.Release()
+	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
 
-		cachedMessage.Consume(func(msg *message.Message) {
+		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
 			if msg.Payload().Type() != payload.Type {
 				return
 			}
diff --git a/plugins/gossip/plugin.go b/plugins/gossip/plugin.go
index 38ff2ce33b7d0dfc44a9d2ad18354ad7a0908dae..dff277855685d020aaa16fbc584f8cc5a7e1eed6 100644
--- a/plugins/gossip/plugin.go
+++ b/plugins/gossip/plugin.go
@@ -4,7 +4,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
+	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/messagerequester"
 	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
 	"github.com/iotaledger/goshimmer/packages/gossip"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
@@ -128,22 +128,22 @@ func configureMessageLayer() {
 	}))
 
 	// configure flow of outgoing messages (gossip on solidification)
-	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		defer cachedMessage.Release()
-		defer cachedMessageMetadata.Release()
+	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		defer cachedMsgEvent.Message.Release()
+		defer cachedMsgEvent.MessageMetadata.Release()
 
 		// only broadcast new message shortly after they have been received
-		metadata := cachedMessageMetadata.Unwrap()
+		metadata := cachedMsgEvent.MessageMetadata.Unwrap()
 		if time.Since(metadata.ReceivedTime()) > ageThreshold {
 			return
 		}
 
-		msg := cachedMessage.Unwrap()
+		msg := cachedMsgEvent.Message.Unwrap()
 		mgr.SendMessage(msg.Bytes())
 	}))
 
 	// request missing messages
-	messagelayer.MessageRequester().Events.SendRequest.Attach(events.NewClosure(func(msgID message.ID) {
-		mgr.RequestMessage(msgID[:])
+	messagelayer.MessageRequester().Events.SendRequest.Attach(events.NewClosure(func(sendRequest *messagerequester.SendRequestEvent) {
+		mgr.RequestMessage(sendRequest.ID[:])
 	}))
 }
diff --git a/plugins/messagelayer/plugin.go b/plugins/messagelayer/plugin.go
index 45ced32efc95d799e380e7081e3bfb4a6b483ab0..571836bced7ec49ea45f6768309a3afa0691d13e 100644
--- a/plugins/messagelayer/plugin.go
+++ b/plugins/messagelayer/plugin.go
@@ -12,7 +12,6 @@ import (
 	"github.com/iotaledger/goshimmer/packages/shutdown"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/local"
 	"github.com/iotaledger/goshimmer/plugins/database"
-	"github.com/iotaledger/hive.go/autopeering/peer"
 	"github.com/iotaledger/hive.go/daemon"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/logger"
@@ -110,28 +109,28 @@ func configure(*node.Plugin) {
 	}))
 
 	// setup messageParser
-	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msg *message.Message, peer *peer.Peer) {
+	messageParser.Events.MessageParsed.Attach(events.NewClosure(func(msgParsedEvent *messageparser.MessageParsedEvent) {
 		// TODO: ADD PEER
-		_tangle.AttachMessage(msg)
+		_tangle.AttachMessage(msgParsedEvent.Message)
 	}))
 
 	// setup messageRequester
 	_tangle.Events.MessageMissing.Attach(events.NewClosure(messageRequester.StartRequest))
-	_tangle.Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		cachedMessageMetadata.Release()
-		cachedMessage.Consume(func(msg *message.Message) {
+	_tangle.Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
+		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
 			messageRequester.StopRequest(msg.ID())
 		})
 	}))
 
 	// setup tipSelector
-	_tangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		cachedMessageMetadata.Release()
-		cachedMessage.Consume(tipSelector.AddTip)
+	_tangle.Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
+		cachedMsgEvent.Message.Consume(tipSelector.AddTip)
 	}))
 
-	MessageRequester().Events.MissingMessageAppeared.Attach(events.NewClosure(func(id message.ID) {
-		_tangle.DeleteMissingMessage(id)
+	MessageRequester().Events.MissingMessageAppeared.Attach(events.NewClosure(func(missingMessageAppeared *messagerequester.MissingMessageAppearedEvent) {
+		_tangle.DeleteMissingMessage(missingMessageAppeared.ID)
 	}))
 }
 
diff --git a/plugins/metrics/plugin.go b/plugins/metrics/plugin.go
index 8787745eac6a9e255fe1bd405b8df6d1dfe106c7..f9ad4e2df4ffe46c7f0d04e54caa8a941990b7e5 100644
--- a/plugins/metrics/plugin.go
+++ b/plugins/metrics/plugin.go
@@ -5,7 +5,6 @@ import (
 	"time"
 
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers"
-	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
 	valuetangle "github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tangle"
 	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/message"
 	"github.com/iotaledger/goshimmer/packages/binary/messagelayer/tangle"
@@ -92,10 +91,10 @@ func registerLocalMetrics() {
 	//// Events declared in other packages which we want to listen to here ////
 
 	// increase received MPS counter whenever we attached a message
-	messagelayer.Tangle().Events.MessageAttached.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		_payloadType := cachedMessage.Unwrap().Payload().Type()
-		cachedMessage.Release()
-		cachedMessageMetadata.Release()
+	messagelayer.Tangle().Events.MessageAttached.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		_payloadType := cachedMsgEvent.Message.Unwrap().Payload().Type()
+		cachedMsgEvent.Message.Release()
+		cachedMsgEvent.MessageMetadata.Release()
 		increaseReceivedMPSCounter()
 		increasePerPayloadCounter(_payloadType)
 		// MessageAttached is triggered in storeMessageWorker that saves the msg to database
@@ -109,12 +108,12 @@ func registerLocalMetrics() {
 	}))
 
 	// messages can only become solid once, then they stay like that, hence no .Dec() part
-	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		cachedMessage.Release()
+	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.Message.Release()
 		solidTimeMutex.Lock()
 		defer solidTimeMutex.Unlock()
 		// Consume should release cachedMessageMetadata
-		cachedMessageMetadata.Consume(func(object objectstorage.StorableObject) {
+		cachedMsgEvent.MessageMetadata.Consume(func(object objectstorage.StorableObject) {
 			msgMetaData := object.(*tangle.MessageMetadata)
 			if msgMetaData.IsSolid() {
 				messageSolidCountDBInc.Inc()
@@ -129,16 +128,16 @@ func registerLocalMetrics() {
 	}))
 
 	// fired when a missing message was received and removed from missing message storage
-	messagelayer.Tangle().Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		cachedMessage.Release()
-		cachedMessageMetadata.Release()
+	messagelayer.Tangle().Events.MissingMessageReceived.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.Message.Release()
+		cachedMsgEvent.MessageMetadata.Release()
 		missingMessageCountDB.Dec()
 	}))
 
 	// Value payload attached
-	valuetransfers.Tangle().Events.PayloadAttached.Attach(events.NewClosure(func(cachedPayload *payload.CachedPayload, cachedPayloadMetadata *valuetangle.CachedPayloadMetadata) {
-		cachedPayload.Release()
-		cachedPayloadMetadata.Release()
+	valuetransfers.Tangle().Events.PayloadAttached.Attach(events.NewClosure(func(cachedPayloadEvent *valuetangle.CachedPayloadEvent) {
+		cachedPayloadEvent.Payload.Release()
+		cachedPayloadEvent.PayloadMetadata.Release()
 		valueTransactionCounter.Inc()
 	}))
 
diff --git a/plugins/syncbeaconfollower/plugin.go b/plugins/syncbeaconfollower/plugin.go
index 69e88877ba0933fce7e129a5680979555ec47b80..bbe4a996119ef2e60109d643206388917bd4910e 100644
--- a/plugins/syncbeaconfollower/plugin.go
+++ b/plugins/syncbeaconfollower/plugin.go
@@ -166,9 +166,9 @@ func configure(_ *node.Plugin) {
 		log.Panicf("Follow node list cannot be empty: %w", ErrMissingFollowNodes)
 	}
 
-	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMessage *message.CachedMessage, cachedMessageMetadata *tangle.CachedMessageMetadata) {
-		cachedMessageMetadata.Release()
-		cachedMessage.Consume(func(msg *message.Message) {
+	messagelayer.Tangle().Events.MessageSolid.Attach(events.NewClosure(func(cachedMsgEvent *tangle.CachedMessageEvent) {
+		cachedMsgEvent.MessageMetadata.Release()
+		cachedMsgEvent.Message.Consume(func(msg *message.Message) {
 			messagePayload := msg.Payload()
 			if messagePayload.Type() != syncbeacon_payload.Type {
 				return