diff --git a/dapps/valuetransfers/packages/branchmanager/branchmanager.go b/dapps/valuetransfers/packages/branchmanager/branchmanager.go
index 0fc7717cd01caeec302adb4e3c89578a44c8ad20..cb9b4a3f94471e50bdb0f1e6af34842157d33366 100644
--- a/dapps/valuetransfers/packages/branchmanager/branchmanager.go
+++ b/dapps/valuetransfers/packages/branchmanager/branchmanager.go
@@ -391,6 +391,11 @@ func (branchManager *BranchManager) setBranchFinalized(cachedBranch *CachedBranc
 
 	branchManager.Events.BranchFinalized.Trigger(cachedBranch)
 
+	// propagate finalized to aggregated child branches
+	if err = branchManager.propagateFinalizedToAggregatedChildBranches(cachedBranch.Retain()); err != nil {
+		return
+	}
+
 	if !branch.Preferred() {
 		branchManager.propagateRejectedToChildBranches(cachedBranch.Retain())
 
@@ -416,11 +421,6 @@ func (branchManager *BranchManager) setBranchFinalized(cachedBranch *CachedBranc
 		})
 	}
 
-	// propagate finalized to aggregated child branches
-	if err = branchManager.propagateFinalizedToAggregatedChildBranches(cachedBranch.Retain()); err != nil {
-		return
-	}
-
 	// schedule confirmed checks of children
 	err = branchManager.propagateConfirmedToChildBranches(cachedBranch.Retain())
 
diff --git a/dapps/valuetransfers/packages/tangle/events.go b/dapps/valuetransfers/packages/tangle/events.go
index 73c81755e4ea7a3774af3a4fd9fb89eb6248a3cb..8194f08f1e9d8e2fe71bc17b0627e41cd276cf84 100644
--- a/dapps/valuetransfers/packages/tangle/events.go
+++ b/dapps/valuetransfers/packages/tangle/events.go
@@ -83,7 +83,7 @@ func newEvents() *Events {
 		PayloadInvalid:         events.NewEvent(cachedPayloadErrorEvent),
 		PayloadUnsolidifiable:  events.NewEvent(payloadIDEvent),
 		TransactionReceived:    events.NewEvent(cachedTransactionAttachmentEvent),
-		TransactionInvalid:     events.NewEvent(cachedTransactionEvent),
+		TransactionInvalid:     events.NewEvent(cachedTransactionErrorEvent),
 		TransactionSolid:       events.NewEvent(cachedTransactionEvent),
 		TransactionBooked:      events.NewEvent(transactionBookedEvent),
 		TransactionPreferred:   events.NewEvent(cachedTransactionEvent),
@@ -141,6 +141,14 @@ func cachedTransactionEvent(handler interface{}, params ...interface{}) {
 	)
 }
 
+func cachedTransactionErrorEvent(handler interface{}, params ...interface{}) {
+	handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, error))(
+		params[0].(*transaction.CachedTransaction).Retain(),
+		params[1].(*CachedTransactionMetadata).Retain(),
+		params[2].(error),
+	)
+}
+
 func cachedTransactionAttachmentEvent(handler interface{}, params ...interface{}) {
 	handler.(func(*transaction.CachedTransaction, *CachedTransactionMetadata, *CachedAttachment))(
 		params[0].(*transaction.CachedTransaction).Retain(),
diff --git a/dapps/valuetransfers/packages/tangle/imgs/scenario1.png b/dapps/valuetransfers/packages/tangle/imgs/scenario1.png
new file mode 100644
index 0000000000000000000000000000000000000000..73b9b7cd0be6ce152a07d59bc5433179eb942b3f
Binary files /dev/null and b/dapps/valuetransfers/packages/tangle/imgs/scenario1.png differ
diff --git a/dapps/valuetransfers/packages/tangle/imgs/scenario2.png b/dapps/valuetransfers/packages/tangle/imgs/scenario2.png
new file mode 100644
index 0000000000000000000000000000000000000000..653997ff5e2e5d8ce3fc7ef8df378bac6ce85bd8
Binary files /dev/null and b/dapps/valuetransfers/packages/tangle/imgs/scenario2.png differ
diff --git a/dapps/valuetransfers/packages/tangle/tangle.go b/dapps/valuetransfers/packages/tangle/tangle.go
index 21931cc9098b0821d52acd4c1a680e5e4285bcae..71c3dbb6db8992fbad9fd3370d9f0c9c0a0d46e5 100644
--- a/dapps/valuetransfers/packages/tangle/tangle.go
+++ b/dapps/valuetransfers/packages/tangle/tangle.go
@@ -50,15 +50,15 @@ func New(store kvstore.KVStore) (tangle *Tangle) {
 	tangle = &Tangle{
 		branchManager: branchmanager.New(store),
 
-		payloadStorage:             osFactory.New(osPayload, osPayloadFactory, objectstorage.CacheTime(time.Second)),
-		payloadMetadataStorage:     osFactory.New(osPayloadMetadata, osPayloadMetadataFactory, objectstorage.CacheTime(time.Second)),
-		missingPayloadStorage:      osFactory.New(osMissingPayload, osMissingPayloadFactory, objectstorage.CacheTime(time.Second)),
-		approverStorage:            osFactory.New(osApprover, osPayloadApproverFactory, objectstorage.CacheTime(time.Second), objectstorage.PartitionKey(payload.IDLength, payload.IDLength), objectstorage.KeysOnly(true)),
-		transactionStorage:         osFactory.New(osTransaction, osTransactionFactory, objectstorage.CacheTime(time.Second), osLeakDetectionOption),
-		transactionMetadataStorage: osFactory.New(osTransactionMetadata, osTransactionMetadataFactory, objectstorage.CacheTime(time.Second), osLeakDetectionOption),
-		attachmentStorage:          osFactory.New(osAttachment, osAttachmentFactory, objectstorage.CacheTime(time.Second), objectstorage.PartitionKey(transaction.IDLength, payload.IDLength), osLeakDetectionOption),
-		outputStorage:              osFactory.New(osOutput, osOutputFactory, OutputKeyPartitions, objectstorage.CacheTime(time.Second), osLeakDetectionOption),
-		consumerStorage:            osFactory.New(osConsumer, osConsumerFactory, ConsumerPartitionKeys, objectstorage.CacheTime(time.Second), osLeakDetectionOption),
+		payloadStorage:             osFactory.New(osPayload, osPayloadFactory, objectstorage.CacheTime(1*time.Second)),
+		payloadMetadataStorage:     osFactory.New(osPayloadMetadata, osPayloadMetadataFactory, objectstorage.CacheTime(1*time.Second)),
+		missingPayloadStorage:      osFactory.New(osMissingPayload, osMissingPayloadFactory, objectstorage.CacheTime(1*time.Second)),
+		approverStorage:            osFactory.New(osApprover, osPayloadApproverFactory, objectstorage.CacheTime(1*time.Second), objectstorage.PartitionKey(payload.IDLength, payload.IDLength), objectstorage.KeysOnly(true)),
+		transactionStorage:         osFactory.New(osTransaction, osTransactionFactory, objectstorage.CacheTime(1*time.Second), osLeakDetectionOption),
+		transactionMetadataStorage: osFactory.New(osTransactionMetadata, osTransactionMetadataFactory, objectstorage.CacheTime(1*time.Second), osLeakDetectionOption),
+		attachmentStorage:          osFactory.New(osAttachment, osAttachmentFactory, objectstorage.CacheTime(1*time.Second), objectstorage.PartitionKey(transaction.IDLength, payload.IDLength), osLeakDetectionOption),
+		outputStorage:              osFactory.New(osOutput, osOutputFactory, OutputKeyPartitions, objectstorage.CacheTime(1*time.Second), osLeakDetectionOption),
+		consumerStorage:            osFactory.New(osConsumer, osConsumerFactory, ConsumerPartitionKeys, objectstorage.CacheTime(1*time.Second), osLeakDetectionOption),
 
 		Events: *newEvents(),
 	}
@@ -1140,7 +1140,7 @@ func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list.
 	// abort if the transaction is not solid or invalid
 	transactionSolid, consumedBranches, transactionSolidityErr := tangle.checkTransactionSolidity(currentTransaction, currentTransactionMetadata)
 	if transactionSolidityErr != nil {
-		tangle.Events.TransactionInvalid.Trigger(solidificationStackEntry.CachedTransaction, solidificationStackEntry.CachedTransactionMetadata)
+		tangle.Events.TransactionInvalid.Trigger(solidificationStackEntry.CachedTransaction, solidificationStackEntry.CachedTransactionMetadata, transactionSolidityErr)
 
 		tangle.deleteTransactionFutureCone(currentTransaction.ID())
 
@@ -1151,7 +1151,7 @@ func (tangle *Tangle) processSolidificationStackEntry(solidificationStack *list.
 	}
 
 	// abort if the payload is not solid or invalid
-	payloadSolid, payloadSolidityErr := tangle.checkPayloadSolidity(currentPayload, currentPayloadMetadata, consumedBranches)
+	payloadSolid, payloadSolidityErr := tangle.payloadBecameNewlySolid(currentPayload, currentPayloadMetadata, consumedBranches)
 	if payloadSolidityErr != nil {
 		tangle.Events.PayloadInvalid.Trigger(solidificationStackEntry.CachedPayload, solidificationStackEntry.CachedPayloadMetadata, payloadSolidityErr)
 
@@ -1336,6 +1336,14 @@ func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPa
 		return
 	}
 
+	branchBranchID := tangle.payloadBranchID(valueObject.BranchID())
+	trunkBranchID := tangle.payloadBranchID(valueObject.TrunkID())
+	transactionBranchID := transactionMetadata.BranchID()
+
+	if branchBranchID == branchmanager.UndefinedBranchID || trunkBranchID == branchmanager.UndefinedBranchID || transactionBranchID == branchmanager.UndefinedBranchID {
+		return
+	}
+
 	// abort if the payload has been marked as solid before
 	if !valueObjectMetadata.setSolid(true) {
 		return
@@ -1344,16 +1352,6 @@ func (tangle *Tangle) bookPayload(cachedPayload *payload.CachedPayload, cachedPa
 	// trigger event if payload became solid
 	tangle.Events.PayloadSolid.Trigger(cachedPayload, cachedPayloadMetadata)
 
-	branchBranchID := tangle.payloadBranchID(valueObject.BranchID())
-	trunkBranchID := tangle.payloadBranchID(valueObject.TrunkID())
-	transactionBranchID := transactionMetadata.BranchID()
-
-	if branchBranchID == branchmanager.UndefinedBranchID ||
-		trunkBranchID == branchmanager.UndefinedBranchID ||
-		transactionBranchID == branchmanager.UndefinedBranchID {
-		return
-	}
-
 	cachedAggregatedBranch, err := tangle.BranchManager().AggregateBranches([]branchmanager.BranchID{branchBranchID, trunkBranchID, transactionBranchID}...)
 	if err != nil {
 		return
@@ -1396,35 +1394,28 @@ func (tangle *Tangle) payloadBranchID(payloadID payload.ID) branchmanager.Branch
 	return payloadMetadata.BranchID()
 }
 
-// checkPayloadSolidity returns true if the given payload is solid. A payload is considered to be solid, if it is either
-// already marked as solid or if its referenced payloads are marked as solid.
-func (tangle *Tangle) checkPayloadSolidity(p *payload.Payload, payloadMetadata *PayloadMetadata, transactionBranches []branchmanager.BranchID) (solid bool, err error) {
+// payloadBecameNewlySolid returns true if the given payload is solid but was not marked as solid. yet.
+func (tangle *Tangle) payloadBecameNewlySolid(p *payload.Payload, payloadMetadata *PayloadMetadata, transactionBranches []branchmanager.BranchID) (solid bool, err error) {
+	// abort if the payload was deleted
 	if p == nil || p.IsDeleted() || payloadMetadata == nil || payloadMetadata.IsDeleted() {
 		return
 	}
 
-	if solid = payloadMetadata.IsSolid(); solid {
+	// abort if the payload was marked as solid already
+	if payloadMetadata.IsSolid() {
 		return
 	}
 
 	combinedBranches := transactionBranches
 
 	trunkBranchID := tangle.payloadBranchID(p.TrunkID())
-	tangle.PayloadMetadata(p.TrunkID()).Consume(func(metadata *PayloadMetadata) { solid = metadata.IsSolid() })
-	if p.TrunkID() == payload.GenesisID {
-		solid = true
-	}
-	if trunkBranchID == branchmanager.UndefinedBranchID || !solid {
+	if trunkBranchID == branchmanager.UndefinedBranchID {
 		return false, nil
 	}
 	combinedBranches = append(combinedBranches, trunkBranchID)
 
 	branchBranchID := tangle.payloadBranchID(p.BranchID())
-	tangle.PayloadMetadata(p.BranchID()).Consume(func(metadata *PayloadMetadata) { solid = metadata.IsSolid() })
-	if p.BranchID() == payload.GenesisID {
-		solid = true
-	}
-	if branchBranchID == branchmanager.UndefinedBranchID || !solid {
+	if branchBranchID == branchmanager.UndefinedBranchID {
 		return false, nil
 	}
 	combinedBranches = append(combinedBranches, branchBranchID)
@@ -1451,8 +1442,10 @@ func (tangle *Tangle) checkTransactionSolidity(tx *transaction.Transaction, meta
 	}
 
 	// abort if we have previously determined the solidity status of the transaction already
-	if solid = metadata.Solid(); solid {
-		consumedBranches = []branchmanager.BranchID{metadata.BranchID()}
+	if metadata.Solid() {
+		if solid = metadata.BranchID() != branchmanager.UndefinedBranchID; solid {
+			consumedBranches = []branchmanager.BranchID{metadata.BranchID()}
+		}
 
 		return
 	}
diff --git a/dapps/valuetransfers/packages/tangle/tangle_concurrency_test.go b/dapps/valuetransfers/packages/tangle/tangle_concurrency_test.go
index ff3562497372f5b3ee391b11191e6ad97d23088d..bf97f7bb86f032fe835e6231612efdc3cd1aea7f 100644
--- a/dapps/valuetransfers/packages/tangle/tangle_concurrency_test.go
+++ b/dapps/valuetransfers/packages/tangle/tangle_concurrency_test.go
@@ -4,14 +4,16 @@ import (
 	"sync"
 	"testing"
 
+	"github.com/iotaledger/hive.go/kvstore/mapdb"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/balance"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/branchmanager"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/payload"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/tipmanager"
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/transaction"
-	"github.com/iotaledger/hive.go/kvstore/mapdb"
-	"github.com/stretchr/testify/assert"
 )
 
 func TestConcurrency(t *testing.T) {
@@ -211,119 +213,124 @@ func TestReverseValueObjectSolidification(t *testing.T) {
 }
 
 func TestReverseTransactionSolidification(t *testing.T) {
-	// img/reverse-transaction-solidification.png
-	// Builds a UTXO-DAG with `txChains` spending outputs from the corresponding chain.
-	// All value objects reference the previous value object, effectively creating a chain.
-	// The test attaches the prepared value objects concurrently in reverse order.
-	tangle := New(mapdb.NewMapDB())
-	defer tangle.Shutdown()
-
-	tipManager := tipmanager.New()
+	testIterations := 500
 
-	txChains := 5
-	count := 100
-	threads := 10
-	countTotal := txChains * threads * count
+	// repeat the test a few times
+	for k := 0; k < testIterations; k++ {
+		// img/reverse-transaction-solidification.png
+		// Builds a UTXO-DAG with `txChains` spending outputs from the corresponding chain.
+		// All value objects reference the previous value object, effectively creating a chain.
+		// The test attaches the prepared value objects concurrently in reverse order.
 
-	// initialize tangle with genesis block
-	outputs := make(map[address.Address][]*balance.Balance)
-	for i := 0; i < txChains; i++ {
-		outputs[address.Random()] = []*balance.Balance{
-			balance.New(balance.ColorIOTA, 1),
-		}
-	}
-	inputIDs := loadSnapshotFromOutputs(tangle, outputs)
+		tangle := New(mapdb.NewMapDB())
 
-	transactions := make([]*transaction.Transaction, countTotal)
-	valueObjects := make([]*payload.Payload, countTotal)
+		tipManager := tipmanager.New()
 
-	// create chains of transactions
-	for i := 0; i < count*threads; i++ {
-		for j := 0; j < txChains; j++ {
-			var tx *transaction.Transaction
+		txChains := 2
+		count := 10
+		threads := 5
+		countTotal := txChains * threads * count
 
-			// transferring from genesis
-			if i == 0 {
-				tx = transaction.New(
-					transaction.NewInputs(inputIDs[j]),
-					transaction.NewOutputs(
-						map[address.Address][]*balance.Balance{
-							address.Random(): {
-								balance.New(balance.ColorIOTA, 1),
-							},
-						}),
-				)
-			} else {
-				// create chains in UTXO dag
-				tx = transaction.New(
-					getTxOutputsAsInputs(transactions[i*txChains-txChains+j]),
-					transaction.NewOutputs(
-						map[address.Address][]*balance.Balance{
-							address.Random(): {
-								balance.New(balance.ColorIOTA, 1),
-							},
-						}),
-				)
+		// initialize tangle with genesis block
+		outputs := make(map[address.Address][]*balance.Balance)
+		for i := 0; i < txChains; i++ {
+			outputs[address.Random()] = []*balance.Balance{
+				balance.New(balance.ColorIOTA, 1),
 			}
-
-			transactions[i*txChains+j] = tx
 		}
-	}
-
-	// prepare value objects (simple chain)
-	for i := 0; i < countTotal; i++ {
-		parent1, parent2 := tipManager.Tips()
-		valueObject := payload.New(parent1, parent2, transactions[i])
-
-		tipManager.AddTip(valueObject)
-		valueObjects[i] = valueObject
-	}
-
-	// attach value objects in reverse order
-	var wg sync.WaitGroup
-	for thread := 0; thread < threads; thread++ {
-		wg.Add(1)
-		go func(threadNo int) {
-			defer wg.Done()
+		inputIDs := loadSnapshotFromOutputs(tangle, outputs)
+
+		transactions := make([]*transaction.Transaction, countTotal)
+		valueObjects := make([]*payload.Payload, countTotal)
+
+		// create chains of transactions
+		for i := 0; i < count*threads; i++ {
+			for j := 0; j < txChains; j++ {
+				var tx *transaction.Transaction
+
+				// transferring from genesis
+				if i == 0 {
+					tx = transaction.New(
+						transaction.NewInputs(inputIDs[j]),
+						transaction.NewOutputs(
+							map[address.Address][]*balance.Balance{
+								address.Random(): {
+									balance.New(balance.ColorIOTA, 1),
+								},
+							}),
+					)
+				} else {
+					// create chains in UTXO dag
+					tx = transaction.New(
+						getTxOutputsAsInputs(transactions[i*txChains-txChains+j]),
+						transaction.NewOutputs(
+							map[address.Address][]*balance.Balance{
+								address.Random(): {
+									balance.New(balance.ColorIOTA, 1),
+								},
+							}),
+					)
+				}
 
-			for i := countTotal - 1 - threadNo; i >= 0; i -= threads {
-				valueObject := valueObjects[i]
-				tangle.AttachPayloadSync(valueObject)
+				transactions[i*txChains+j] = tx
 			}
-		}(thread)
-	}
-	wg.Wait()
+		}
 
-	// verify correctness
-	for i := 0; i < countTotal; i++ {
-		// check if transaction metadata is found in database
-		assert.True(t, tangle.TransactionMetadata(transactions[i].ID()).Consume(func(transactionMetadata *TransactionMetadata) {
-			assert.Truef(t, transactionMetadata.Solid(), "the transaction %s is not solid", transactions[i].ID().String())
-			assert.Equalf(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch")
-		}))
+		// prepare value objects (simple chain)
+		for i := 0; i < countTotal; i++ {
+			parent1, parent2 := tipManager.Tips()
+			valueObject := payload.New(parent1, parent2, transactions[i])
 
-		// check if payload metadata is found in database
-		assert.True(t, tangle.PayloadMetadata(valueObjects[i].ID()).Consume(func(payloadMetadata *PayloadMetadata) {
-			assert.Truef(t, payloadMetadata.IsSolid(), "the payload is not solid")
-			assert.Equalf(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch")
-		}))
+			tipManager.AddTip(valueObject)
+			valueObjects[i] = valueObject
+		}
 
-		// check if outputs are found in database
-		transactions[i].Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool {
-			cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(address, transactions[i].ID()))
-			assert.True(t, cachedOutput.Consume(func(output *Output) {
-				// only the last outputs in chain should not be spent
-				if i+txChains >= countTotal {
-					assert.Equalf(t, 0, output.ConsumerCount(), "the output should not be spent")
-				} else {
-					assert.Equalf(t, 1, output.ConsumerCount(), "the output should be spent")
+		// attach value objects in reverse order
+		var wg sync.WaitGroup
+		for thread := 0; thread < threads; thread++ {
+			wg.Add(1)
+			go func(threadNo int) {
+				defer wg.Done()
+
+				for i := countTotal - 1 - threadNo; i >= 0; i -= threads {
+					valueObject := valueObjects[i]
+					tangle.AttachPayloadSync(valueObject)
 				}
-				assert.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances())
-				assert.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch")
-				assert.Truef(t, output.Solid(), "the output is not solid")
-			}))
-			return true
-		})
+			}(thread)
+		}
+		wg.Wait()
+
+		// verify correctness
+		for i := 0; i < countTotal; i++ {
+			// check if transaction metadata is found in database
+			require.Truef(t, tangle.TransactionMetadata(transactions[i].ID()).Consume(func(transactionMetadata *TransactionMetadata) {
+				require.Truef(t, transactionMetadata.Solid(), "the transaction %s is not solid", transactions[i].ID().String())
+				require.Equalf(t, branchmanager.MasterBranchID, transactionMetadata.BranchID(), "the transaction was booked into the wrong branch")
+			}), "transaction metadata %s not found in database", transactions[i].ID())
+
+			// check if value object metadata is found in database
+			require.Truef(t, tangle.PayloadMetadata(valueObjects[i].ID()).Consume(func(payloadMetadata *PayloadMetadata) {
+				require.Truef(t, payloadMetadata.IsSolid(), "the payload %s is not solid", valueObjects[i].ID())
+				require.Equalf(t, branchmanager.MasterBranchID, payloadMetadata.BranchID(), "the payload was booked into the wrong branch")
+			}), "value object metadata %s not found in database", valueObjects[i].ID())
+
+			// check if outputs are found in database
+			transactions[i].Outputs().ForEach(func(address address.Address, balances []*balance.Balance) bool {
+				cachedOutput := tangle.TransactionOutput(transaction.NewOutputID(address, transactions[i].ID()))
+				require.Truef(t, cachedOutput.Consume(func(output *Output) {
+					// only the last outputs in chain should not be spent
+					if i+txChains >= countTotal {
+						require.Equalf(t, 0, output.ConsumerCount(), "the output should not be spent")
+					} else {
+						require.Equalf(t, 1, output.ConsumerCount(), "the output should be spent")
+					}
+					require.Equal(t, []*balance.Balance{balance.New(balance.ColorIOTA, 1)}, output.Balances())
+					require.Equalf(t, branchmanager.MasterBranchID, output.BranchID(), "the output was booked into the wrong branch")
+					require.Truef(t, output.Solid(), "the output is not solid")
+				}), "output not found in database for tx %s", transactions[i])
+				return true
+			})
+		}
 	}
 }
 
diff --git a/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
index 41552d9212bfdb1060842375b440cae1d0ea1a85..63a8889e3eb4bd02e0a2a7de51cf75599643f3a3 100644
--- a/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
+++ b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
@@ -30,8 +30,9 @@ const (
 	Y
 )
 
-// TODO: clean up create scenario
+// TODO: clean up create scenario with some helper functions: DRY!
 
+// preparePropagationScenario1 creates a tangle according to `img/scenario1.png`.
 func preparePropagationScenario1(t *testing.T) (*Tangle, map[string]*transaction.Transaction, map[string]*payload.Payload, map[string]branchmanager.BranchID, *wallet.Seed) {
 	// create tangle
 	tangle := New(mapdb.NewMapDB())
@@ -496,6 +497,7 @@ func preparePropagationScenario1(t *testing.T) (*Tangle, map[string]*transaction
 	return tangle, transactions, valueObjects, branches, seed
 }
 
+// preparePropagationScenario1 creates a tangle according to `img/scenario2.png`.
 func preparePropagationScenario2(t *testing.T) (*Tangle, map[string]*transaction.Transaction, map[string]*payload.Payload, map[string]branchmanager.BranchID, *wallet.Seed) {
 	tangle, transactions, valueObjects, branches, seed := preparePropagationScenario1(t)
 
@@ -729,6 +731,8 @@ func preparePropagationScenario2(t *testing.T) (*Tangle, map[string]*transaction
 }
 
 func TestPropagationScenario1(t *testing.T) {
+	// img/scenario1.png
+
 	// test past cone monotonicity - all value objects MUST be confirmed
 	{
 		tangle, transactions, valueObjects, _, _ := preparePropagationScenario1(t)
@@ -892,6 +896,7 @@ func TestPropagationScenario1(t *testing.T) {
 }
 
 func TestPropagationScenario2(t *testing.T) {
+	// img/scenario2.png
 	tangle, transactions, valueObjects, branches, _ := preparePropagationScenario2(t)
 
 	// initialize debugger for this test
@@ -958,13 +963,15 @@ func TestPropagationScenario2(t *testing.T) {
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-C, H+]"], true)
 	setTransactionFinalizedWithCheck(t, tangle, transactions["[-C, H+]"])
 
-	verifyBranchState(t, tangle, branches["AC"], true, true, true, false)
 	verifyInclusionState(t, tangle, valueObjects["[-C, H+]"], true, true, true, true, false)
 	verifyBranchState(t, tangle, branches["C"], true, true, true, false)
+	verifyBranchState(t, tangle, branches["AC"], true, true, true, false)
 
 	verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], false, true, false, false, true)
 	verifyBranchState(t, tangle, branches["D"], true, false, false, true)
 	verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], false, true, false, false, true)
+	verifyBranchState(t, tangle, branches["BD"], true, false, false, true)
+	// TODO: BD is not finalized
 
 	// [-H, -D, I+] should now be liked
 	verifyInclusionState(t, tangle, valueObjects["[-H, -D, I+]"], true, false, true, false, false)
@@ -978,8 +985,10 @@ func TestPropagationScenario2(t *testing.T) {
 	setTransactionFinalizedWithCheck(t, tangle, transactions["[-B, J+]"])
 	verifyInclusionState(t, tangle, valueObjects["[-B, J+]"], true, true, true, true, false)
 	verifyBranchState(t, tangle, branches["E"], true, true, true, false)
+	verifyBranchState(t, tangle, branches["ACE"], true, true, true, false)
 }
 
+// verifyBranchState verifies the the branch state according to the given parameters.
 func verifyBranchState(t *testing.T, tangle *Tangle, id branchmanager.BranchID, finalized, liked, confirmed, rejected bool) {
 	assert.True(t, tangle.branchManager.Branch(id).Consume(func(branch *branchmanager.Branch) {
 		assert.Equalf(t, finalized, branch.Finalized(), "branch finalized state does not match")
@@ -989,6 +998,8 @@ func verifyBranchState(t *testing.T, tangle *Tangle, id branchmanager.BranchID,
 		assert.Equalf(t, rejected, branch.Rejected(), "branch rejected state does not match")
 	}))
 }
+
+// verifyInclusionState verifies the inclusion state of outputs and transaction according to the given parameters.
 func verifyTransactionInclusionState(t *testing.T, tangle *Tangle, valueObject *payload.Payload, preferred, finalized, liked, confirmed, rejected bool) {
 	tx := valueObject.Transaction()
 
@@ -1013,6 +1024,7 @@ func verifyTransactionInclusionState(t *testing.T, tangle *Tangle, valueObject *
 	}))
 }
 
+// verifyValueObjectInclusionState verifies the inclusion state of a value object according to the given parameters.
 func verifyValueObjectInclusionState(t *testing.T, tangle *Tangle, valueObject *payload.Payload, liked, confirmed, rejected bool) {
 	assert.True(t, tangle.PayloadMetadata(valueObject.ID()).Consume(func(payloadMetadata *PayloadMetadata) {
 		assert.Equalf(t, liked, payloadMetadata.Liked(), "value object liked state does not match")
@@ -1021,16 +1033,20 @@ func verifyValueObjectInclusionState(t *testing.T, tangle *Tangle, valueObject *
 	}))
 }
 
+// verifyInclusionState verifies the inclusion state of outputs, transaction and value object according to the given parameters.
 func verifyInclusionState(t *testing.T, tangle *Tangle, valueObject *payload.Payload, preferred, finalized, liked, confirmed, rejected bool) {
 	verifyTransactionInclusionState(t, tangle, valueObject, preferred, finalized, liked, confirmed, rejected)
 	verifyValueObjectInclusionState(t, tangle, valueObject, liked, confirmed, rejected)
 }
 
+// setTransactionPreferredWithCheck sets the transaction to preferred and makes sure that no error occurred and it's modified.
 func setTransactionPreferredWithCheck(t *testing.T, tangle *Tangle, tx *transaction.Transaction, preferred bool) {
 	modified, err := tangle.SetTransactionPreferred(tx.ID(), preferred)
 	require.NoError(t, err)
 	assert.True(t, modified)
 }
+
+// setTransactionFinalizedWithCheck sets the transaction to finalized and makes sure that no error occurred and it's modified.
 func setTransactionFinalizedWithCheck(t *testing.T, tangle *Tangle, tx *transaction.Transaction) {
 	modified, err := tangle.SetTransactionFinalized(tx.ID())
 	require.NoError(t, err)
diff --git a/dapps/valuetransfers/packages/tangle/tangle_test.go b/dapps/valuetransfers/packages/tangle/tangle_test.go
index 85309df19052b3274f3ec86911a9ccdc56109009..8f5c8d26c46ebfd34206e925cfae33883a725ad9 100644
--- a/dapps/valuetransfers/packages/tangle/tangle_test.go
+++ b/dapps/valuetransfers/packages/tangle/tangle_test.go
@@ -31,15 +31,6 @@ func TestSetTransactionPreferred(t *testing.T) {
 	assert.True(t, modified)
 }
 
-func TestPropagateValuePayloadLikeUpdates(t *testing.T) {
-
-}
-
-//TODO: missing propagateValuePayloadConfirmedUpdates (not yet implemented)
-
-func TestSetTransactionFinalized(t *testing.T) {
-}
-
 // TestBookTransaction tests the following cases:
 // - missing output
 // - transaction already booked by another process
@@ -491,7 +482,7 @@ func TestStoreTransactionModels(t *testing.T) {
 		})
 
 		// check created consumers
-		// TODO: only reason that there could be multiple consumers = conflict, e.g. 2 tx use same inputs?
+		// only reason that there could be multiple consumers = conflict, e.g. 2 tx use same inputs?
 		tx.Inputs().ForEach(func(inputId transaction.OutputID) bool {
 			expectedConsumer := NewConsumer(inputId, tx.ID())
 			tangle.Consumers(inputId).Consume(func(consumer *Consumer) {
@@ -1228,8 +1219,8 @@ func TestCheckPayloadSolidity(t *testing.T) {
 		metadata.SetBranchID(branchmanager.MasterBranchID)
 
 		transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID}
-		solid, err := tangle.checkPayloadSolidity(valueObject, metadata, transactionBranches)
-		assert.True(t, solid)
+		solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches)
+		assert.False(t, solid)
 		assert.NoError(t, err)
 	}
 
@@ -1239,7 +1230,7 @@ func TestCheckPayloadSolidity(t *testing.T) {
 		metadata := NewPayloadMetadata(valueObject.ID())
 
 		transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID}
-		solid, err := tangle.checkPayloadSolidity(valueObject, metadata, transactionBranches)
+		solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches)
 		assert.True(t, solid)
 		assert.NoError(t, err)
 	}
@@ -1255,7 +1246,7 @@ func TestCheckPayloadSolidity(t *testing.T) {
 		metadata := NewPayloadMetadata(valueObject.ID())
 
 		transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID}
-		solid, err := tangle.checkPayloadSolidity(valueObject, metadata, transactionBranches)
+		solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches)
 		assert.True(t, solid)
 		assert.NoError(t, err)
 	}
@@ -1270,22 +1261,7 @@ func TestCheckPayloadSolidity(t *testing.T) {
 		metadata := NewPayloadMetadata(valueObject.ID())
 
 		transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID}
-		solid, err := tangle.checkPayloadSolidity(valueObject, metadata, transactionBranches)
-		assert.False(t, solid)
-		assert.NoError(t, err)
-	}
-
-	// check with non-solid parents but branch set -> should not be solid
-	{
-		setParent := func(payloadMetadata *PayloadMetadata) {
-			payloadMetadata.SetBranchID(branchmanager.MasterBranchID)
-		}
-
-		valueObject := payload.New(storeParentPayloadWithMetadataFunc(t, tangle, setParent), storeParentPayloadWithMetadataFunc(t, tangle, setParent), createDummyTransaction())
-		metadata := NewPayloadMetadata(valueObject.ID())
-
-		transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID}
-		solid, err := tangle.checkPayloadSolidity(valueObject, metadata, transactionBranches)
+		solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches)
 		assert.False(t, solid)
 		assert.NoError(t, err)
 	}
@@ -1310,7 +1286,7 @@ func TestCheckPayloadSolidity(t *testing.T) {
 		metadata := NewPayloadMetadata(valueObject.ID())
 
 		transactionBranches := []branchmanager.BranchID{branchmanager.MasterBranchID}
-		solid, err := tangle.checkPayloadSolidity(valueObject, metadata, transactionBranches)
+		solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches)
 		assert.False(t, solid)
 		assert.Error(t, err)
 	}
@@ -1335,7 +1311,7 @@ func TestCheckPayloadSolidity(t *testing.T) {
 		metadata := NewPayloadMetadata(valueObject.ID())
 
 		transactionBranches := []branchmanager.BranchID{{2}}
-		solid, err := tangle.checkPayloadSolidity(valueObject, metadata, transactionBranches)
+		solid, err := tangle.payloadBecameNewlySolid(valueObject, metadata, transactionBranches)
 		assert.False(t, solid)
 		assert.Error(t, err)
 	}