diff --git a/dapps/valuetransfers/packages/branchmanager/branchmanager.go b/dapps/valuetransfers/packages/branchmanager/branchmanager.go
index 07bc1bef733d39d63e3decf7612a9df150f8f9a9..0fc7717cd01caeec302adb4e3c89578a44c8ad20 100644
--- a/dapps/valuetransfers/packages/branchmanager/branchmanager.go
+++ b/dapps/valuetransfers/packages/branchmanager/branchmanager.go
@@ -416,11 +416,67 @@ 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())
 
 	return
 }
 
+// propagateFinalizedToAggregatedChildBranches propagates the finalized flag to the aggregated child branches of the
+// given branch. An aggregated branch is finalized if all of its parents are finalized.
+func (branchManager *BranchManager) propagateFinalizedToAggregatedChildBranches(cachedBranch *CachedBranch) (err error) {
+	// initialize stack with the child branches of the given branch
+	propagationStack := list.New()
+	cachedBranch.Consume(func(branch *Branch) {
+		branchManager.ChildBranches(branch.ID()).Consume(func(childBranch *ChildBranch) {
+			propagationStack.PushBack(branchManager.Branch(childBranch.ChildID()))
+		})
+	})
+
+	// iterate through stack to propagate the changes to child branches
+	for propagationStack.Len() >= 1 {
+		stackElement := propagationStack.Front()
+		stackElement.Value.(*CachedBranch).Consume(func(branch *Branch) {
+			// abort if the branch is not aggregated
+			if !branch.IsAggregated() {
+				return
+			}
+
+			// abort if not all parents are confirmed
+			for _, parentBranchID := range branch.ParentBranches() {
+				cachedParentBranch := branchManager.Branch(parentBranchID)
+				if parentBranch := cachedParentBranch.Unwrap(); parentBranch == nil || !parentBranch.Finalized() {
+					cachedParentBranch.Release()
+
+					return
+				}
+				cachedParentBranch.Release()
+			}
+
+			// abort if the branch was finalized already
+			if !branch.setFinalized(true) {
+				return
+			}
+
+			// trigger events
+			branchManager.Events.BranchFinalized.Trigger(cachedBranch)
+
+			// schedule confirmed checks of children
+			branchManager.ChildBranches(branch.ID()).Consume(func(childBranch *ChildBranch) {
+				propagationStack.PushBack(branchManager.Branch(childBranch.childID))
+			})
+		})
+		propagationStack.Remove(stackElement)
+	}
+
+	return
+}
+
 func (branchManager *BranchManager) propagateRejectedToChildBranches(cachedBranch *CachedBranch) {
 	branchStack := list.New()
 	branchStack.PushBack(cachedBranch)
diff --git a/dapps/valuetransfers/packages/branchmanager/objectstorage.go b/dapps/valuetransfers/packages/branchmanager/objectstorage.go
index b3a95c655131c13951f7e7ccd3dd814863bfe131..fede032fbef8ed4df734b530299f7752fe865974 100644
--- a/dapps/valuetransfers/packages/branchmanager/objectstorage.go
+++ b/dapps/valuetransfers/packages/branchmanager/objectstorage.go
@@ -18,7 +18,7 @@ const (
 )
 
 var (
-	osLeakDetectionOption = objectstorage.LeakDetectionEnabled(true, objectstorage.LeakDetectionOptions{
+	osLeakDetectionOption = objectstorage.LeakDetectionEnabled(false, objectstorage.LeakDetectionOptions{
 		MaxConsumersPerObject: 10,
 		MaxConsumerHoldTime:   10 * time.Second,
 	})
diff --git a/dapps/valuetransfers/packages/tangle/objectstorage.go b/dapps/valuetransfers/packages/tangle/objectstorage.go
index 4488dc8540f62622f5f95508c9c6d553abc2886f..29fee08f3ce8419119ce562dbe67707adc1cd3c3 100644
--- a/dapps/valuetransfers/packages/tangle/objectstorage.go
+++ b/dapps/valuetransfers/packages/tangle/objectstorage.go
@@ -25,7 +25,7 @@ const (
 )
 
 var (
-	osLeakDetectionOption = objectstorage.LeakDetectionEnabled(true, objectstorage.LeakDetectionOptions{
+	osLeakDetectionOption = objectstorage.LeakDetectionEnabled(false, objectstorage.LeakDetectionOptions{
 		MaxConsumersPerObject: 20,
 		MaxConsumerHoldTime:   10 * time.Second,
 	})
diff --git a/dapps/valuetransfers/packages/tangle/tangle.go b/dapps/valuetransfers/packages/tangle/tangle.go
index d678d8682e12b0f64a32e8d3d49e7b8affa650df..30482cd932047805bdb901381f793307f762009b 100644
--- a/dapps/valuetransfers/packages/tangle/tangle.go
+++ b/dapps/valuetransfers/packages/tangle/tangle.go
@@ -7,18 +7,19 @@ import (
 	"math"
 	"time"
 
-	"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/transaction"
-	"github.com/iotaledger/goshimmer/packages/binary/storageprefix"
 	"github.com/iotaledger/hive.go/async"
 	"github.com/iotaledger/hive.go/events"
 	"github.com/iotaledger/hive.go/kvstore"
 	"github.com/iotaledger/hive.go/marshalutil"
 	"github.com/iotaledger/hive.go/objectstorage"
 	"github.com/iotaledger/hive.go/types"
+
+	"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/transaction"
+	"github.com/iotaledger/goshimmer/packages/binary/storageprefix"
 )
 
 // Tangle represents the value tangle that consists out of value payloads.
@@ -668,18 +669,15 @@ func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdates(transactionI
 		})
 	})
 
-	// keep track of the seen payloads so we do not process them twice
-	seenPayloads := make(map[payload.ID]types.Empty)
-
 	// iterate through stack (future cone of transactions)
 	for propagationStack.Len() >= 1 {
 		currentAttachmentEntry := propagationStack.Front()
-		tangle.propagateValuePayloadConfirmedRejectedUpdateStackEntry(propagationStack, seenPayloads, currentAttachmentEntry.Value.(*valuePayloadPropagationStackEntry), confirmed)
+		tangle.propagateValuePayloadConfirmedRejectedUpdateStackEntry(propagationStack, currentAttachmentEntry.Value.(*valuePayloadPropagationStackEntry), confirmed)
 		propagationStack.Remove(currentAttachmentEntry)
 	}
 }
 
-func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdateStackEntry(propagationStack *list.List, processedPayloads map[payload.ID]types.Empty, propagationStackEntry *valuePayloadPropagationStackEntry, confirmed bool) {
+func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdateStackEntry(propagationStack *list.List, propagationStackEntry *valuePayloadPropagationStackEntry, confirmed bool) {
 	// release the entry when we are done
 	defer propagationStackEntry.Release()
 
@@ -729,7 +727,7 @@ func (tangle *Tangle) propagateValuePayloadConfirmedRejectedUpdateStackEntry(pro
 	}
 
 	// schedule checks of approvers and consumers
-	tangle.ForEachConsumersAndApprovers(currentPayload, tangle.createValuePayloadFutureConeIterator(propagationStack, processedPayloads))
+	tangle.ForEachConsumersAndApprovers(currentPayload, tangle.createValuePayloadFutureConeIterator(propagationStack, make(map[payload.ID]types.Empty)))
 }
 
 // setTransactionPreferred is an internal utility method that updates the preferred flag and triggers changes to the
@@ -796,13 +794,10 @@ func (tangle *Tangle) propagateValuePayloadLikeUpdates(transactionID transaction
 		})
 	})
 
-	// keep track of the seen payloads so we do not process them twice
-	seenPayloads := make(map[payload.ID]types.Empty)
-
 	// iterate through stack (future cone of transactions)
 	for propagationStack.Len() >= 1 {
 		currentAttachmentEntry := propagationStack.Front()
-		tangle.processValuePayloadLikedUpdateStackEntry(propagationStack, seenPayloads, liked, currentAttachmentEntry.Value.(*valuePayloadPropagationStackEntry))
+		tangle.processValuePayloadLikedUpdateStackEntry(propagationStack, liked, currentAttachmentEntry.Value.(*valuePayloadPropagationStackEntry))
 		propagationStack.Remove(currentAttachmentEntry)
 	}
 }
@@ -811,7 +806,7 @@ func (tangle *Tangle) propagateValuePayloadLikeUpdates(transactionID transaction
 // propagation stack for the update of the liked flag when iterating through the future cone of a transactions
 // attachments. It checks if a ValuePayloads has become liked (or disliked), updates the flag an schedules its future
 // cone for additional checks.
-func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack *list.List, processedPayloads map[payload.ID]types.Empty, liked bool, propagationStackEntry *valuePayloadPropagationStackEntry) {
+func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack *list.List, liked bool, propagationStackEntry *valuePayloadPropagationStackEntry) {
 	// release the entry when we are done
 	defer propagationStackEntry.Release()
 
@@ -880,7 +875,7 @@ func (tangle *Tangle) processValuePayloadLikedUpdateStackEntry(propagationStack
 	}
 
 	// schedule checks of approvers and consumers
-	tangle.ForEachConsumersAndApprovers(currentPayload, tangle.createValuePayloadFutureConeIterator(propagationStack, processedPayloads))
+	tangle.ForEachConsumersAndApprovers(currentPayload, tangle.createValuePayloadFutureConeIterator(propagationStack, make(map[payload.ID]types.Empty)))
 }
 
 // createValuePayloadFutureConeIterator returns a function that can be handed into the ForEachConsumersAndApprovers
diff --git a/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
index 28a60ee20e6eaff34f290a951bf0f372e224a899..bdfd386aa0d98382f25c2baf8e32346cf19e3a37 100644
--- a/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
+++ b/dapps/valuetransfers/packages/tangle/tangle_scenario_test.go
@@ -751,18 +751,13 @@ func TestPropagationScenario1(t *testing.T) {
 		verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, false, false)
 
 		// now finalize [-GENESIS, A+, B+, C+]
-		debugger.Enable()
 		setTransactionFinalizedWithCheck(t, tangle, transactions["[-GENESIS, A+, B+, C+]"])
-		debugger.Disable()
-
 		verifyInclusionState(t, tangle, valueObjects["[-GENESIS, A+, B+, C+]"], true, true, true, true, false)
 
 		// and [-B, -C, E+] should be confirmed now too
 		verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+]"], true, true, true, true, false)
 		// as well as the reattachment
-
 		verifyInclusionState(t, tangle, valueObjects["[-B, -C, E+] (Reattachment)"], true, true, true, true, false)
-		// TODO: sometimes this check does fail. "value object confirmed state does not match" expected: true - actual  : false
 	}
 
 	// test future cone monotonicity simple - everything MUST be rejected and finalized if spending funds from rejected tx
@@ -960,10 +955,8 @@ func TestPropagationScenario2(t *testing.T) {
 	verifyInclusionState(t, tangle, valueObjects["[-E, -F, G+]"], false, true, false, false, true)
 
 	// simulate vote result to like [-C, H+] -> [-C, H+] becomes confirmed and [-B, -C, E+], [-B, -C, E+] (Reattachment) rejected
-	debugger.Enable()
 	setTransactionPreferredWithCheck(t, tangle, transactions["[-C, H+]"], true)
 	setTransactionFinalizedWithCheck(t, tangle, transactions["[-C, H+]"])
-	debugger.Disable()
 
 	verifyBranchState(t, tangle, branches["AC"], true, true, true, false)
 	verifyInclusionState(t, tangle, valueObjects["[-C, H+]"], true, true, true, true, false)