diff --git a/pluginmgr/core/plugins.go b/pluginmgr/core/plugins.go
index 9bc1f4dbd255823086918afd234f772705eb7ec9..eb4ff3b619c6ea1cd48a61d4325d54ddf5dd7241 100644
--- a/pluginmgr/core/plugins.go
+++ b/pluginmgr/core/plugins.go
@@ -17,8 +17,8 @@ import (
 	"github.com/iotaledger/goshimmer/plugins/metrics"
 	"github.com/iotaledger/goshimmer/plugins/portcheck"
 	"github.com/iotaledger/goshimmer/plugins/profiling"
-	"github.com/iotaledger/goshimmer/plugins/testsnapshots"
 	"github.com/iotaledger/goshimmer/plugins/sync"
+	"github.com/iotaledger/goshimmer/plugins/testsnapshots"
 
 	"github.com/iotaledger/hive.go/node"
 )
diff --git a/tools/integration-tests/tester/framework/parameters.go b/tools/integration-tests/tester/framework/parameters.go
index 7041a77bed7da0d68c6b11e9e0a2ff814265b5c2..fb4e14353b68638eebb4f53a2266a99a8e1253b0 100644
--- a/tools/integration-tests/tester/framework/parameters.go
+++ b/tools/integration-tests/tester/framework/parameters.go
@@ -25,8 +25,6 @@ const (
 	dkgMaxTries = 50
 
 	exitStatusSuccessful = 0
-
-	SnapShotFirstAddress = "JaMauTaTSVBNc13edCCvBK9fZxZ1KKW5fXegT1B7N9jY"
 )
 
 var (
diff --git a/tools/integration-tests/tester/tests/testutil.go b/tools/integration-tests/tester/tests/testutil.go
index 5a4945017c42279552c8c8bd8a44dc44b1686b05..d998da3541d8d1a93964995985478b14c396e727 100644
--- a/tools/integration-tests/tester/tests/testutil.go
+++ b/tools/integration-tests/tester/tests/testutil.go
@@ -100,94 +100,143 @@ func CheckForMessageIds(t *testing.T, peers []*framework.Peer, ids map[string]Da
 	}
 }
 
-// SendValueMessage sends a value message on a given peer and returns the transaction ID.
-func SendValueMessagesOnFaucet(t *testing.T, peers []*framework.Peer) (txId string, addrBalance map[string]int64) {
+// SendValueMessagesOnFaucet sends funds to peers from the faucet and returns the transaction ID.
+func SendValueMessagesOnFaucet(t *testing.T, peers []*framework.Peer) (txIds []string, addrBalance map[string]map[balance.Color]int64) {
+	// initiate addrBalance map
+	addrBalance = make(map[string]map[balance.Color]int64)
+	for _, p := range peers {
+		addr := p.Seed().Address(0).String()
+		addrBalance[addr] = make(map[balance.Color]int64)
+		addrBalance[addr][balance.ColorIOTA] = 0
+	}
+
 	faucetPeer := peers[0]
-	sigScheme := signaturescheme.ED25519(*faucetPeer.Seed().KeyPair(0))
-	// send the same funds to the original address
-	remainAddr := faucetPeer.Seed().Address(0)
-	var sentValue int64 = 0
+	faucetAddrStr := faucetPeer.Seed().Address(0).String()
 
-	// prepare inputs
-	unspentOutputs, err := faucetPeer.GetUnspentOutputs([]string{framework.SnapShotFirstAddress})
+	// get faucet balances
+	unspentOutputs, err := faucetPeer.GetUnspentOutputs([]string{faucetAddrStr})
 	require.NoErrorf(t, err, "Could not get unspent outputs on %s", faucetPeer.String())
-	value := unspentOutputs.UnspentOutputs[0].OutputIDs[0].Balances[0].Value
+	addrBalance[faucetAddrStr][balance.ColorIOTA] = unspentOutputs.UnspentOutputs[0].OutputIDs[0].Balances[0].Value
+
+	// send funds to other peers
+	for i := 1; i < len(peers); i++ {
+		fail, txId := SendIotaValueMessages(t, faucetPeer, peers[i], addrBalance)
+		require.False(t, fail)
+		txIds = append(txIds, txId)
+
+		// let the transaction propagate
+		time.Sleep(1 * time.Second)
+	}
+	return
+}
+
+// SendValueMessagesOnRandomPeer sends IOTA tokens on random peer and saves the sent message token to a map.
+func SendValueMessagesOnRandomPeer(t *testing.T, peers []*framework.Peer, addrBalance map[string]map[balance.Color]int64, numMessages int) (txIds []string) {
+	for i := 0; i < numMessages; i++ {
+		from := rand.Intn(len(peers))
+		to := rand.Intn(len(peers))
+		fail, txId := SendIotaValueMessages(t, peers[from], peers[to], addrBalance)
+		if fail {
+			i--
+			continue
+		}
+
+		// attach tx id
+		txIds = append(txIds, txId)
 
-	out, err := transaction.OutputIDFromBase58(unspentOutputs.UnspentOutputs[0].OutputIDs[0].ID)
-	require.NoErrorf(t, err, "Invalid unspent outputs ID on %s", faucetPeer.String())
+		// let the transaction propagate
+		time.Sleep(1 * time.Second)
+	}
+
+	return
+}
+
+// SendIotaValueMessages sends IOTA token from and to a given peer and returns the transaction ID.
+// The same addresses are used in each round
+func SendIotaValueMessages(t *testing.T, from *framework.Peer, to *framework.Peer, addrBalance map[string]map[balance.Color]int64) (fail bool, txId string) {
+	var sentValue int64 = 100
+	sigScheme := signaturescheme.ED25519(*from.Seed().KeyPair(0))
+	inputAddr := from.Seed().Address(0)
+	outputAddr := to.Seed().Address(0)
+
+	// abort if no unspent outputs
+	if addrBalance[inputAddr.String()][balance.ColorIOTA] < sentValue {
+		return true, ""
+	}
+
+	// prepare inputs
+	resp, err := from.GetUnspentOutputs([]string{inputAddr.String()})
+	require.NoErrorf(t, err, "Could not get unspent outputs on %s", from.String())
+	availableValue := resp.UnspentOutputs[0].OutputIDs[0].Balances[0].Value
+
+	out, err := transaction.OutputIDFromBase58(resp.UnspentOutputs[0].OutputIDs[0].ID)
+	require.NoErrorf(t, err, "Invalid unspent outputs ID on %s", from.String())
 	inputs := transaction.NewInputs([]transaction.OutputID{out}...)
 
 	// prepare outputs
 	outmap := map[address.Address][]*balance.Balance{}
-	addrBalance = make(map[string]int64)
-
-	// send funds to other peers, skip faucet node
-	for i := 1; i < len(peers); i++ {
-		addr := peers[i].Seed().Address(0)
-
-		// set balances
-		balances := []*balance.Balance{balance.New(balance.ColorIOTA, 100)}
-		outmap[addr] = balances
-		sentValue += 100
-		// set return map
-		addrBalance[addr.String()] = 100
+	if inputAddr == outputAddr {
+		sentValue = availableValue
 	}
+
+	// set balances
+	outmap[outputAddr] = []*balance.Balance{balance.New(balance.ColorIOTA, sentValue)}
 	outputs := transaction.NewOutputs(outmap)
 
 	// handle remain address
-	outputs.Add(remainAddr, []*balance.Balance{balance.New(balance.ColorIOTA, value-sentValue)})
-	addrBalance[remainAddr.String()] = value - sentValue
+	if availableValue > sentValue {
+		outputs.Add(inputAddr, []*balance.Balance{balance.New(balance.ColorIOTA, availableValue-sentValue)})
+	}
 
 	// sign transaction
 	txn := transaction.New(inputs, outputs).Sign(sigScheme)
 
 	// send transaction
-	txId, err = faucetPeer.SendTransaction(txn.Bytes())
-	require.NoErrorf(t, err, "Could not send transaction on %s", faucetPeer.String())
+	txId, err = from.SendTransaction(txn.Bytes())
+	require.NoErrorf(t, err, "Could not send transaction on %s", from.String())
 
-	return
-}
+	addrBalance[inputAddr.String()][balance.ColorIOTA] -= sentValue
+	addrBalance[outputAddr.String()][balance.ColorIOTA] += sentValue
 
-// SendDataMessagesOnRandomPeer sends data messages on a random peer and saves the sent message to a map.
-func SendValueMessagesOnRandomPeer(t *testing.T, peers []*framework.Peer, addrBalance map[string]int64, numMessages int) {
-	addrMap := make(map[int]string)
-	for i, p := range peers {
-		addrMap[i] = p.Seed().Address(0).String()
-	}
+	return false, txId
+}
 
+// SendColoredValueMessagesOnRandomPeer sends colored token on a random peer and saves the sent token to a map.
+func SendColoredValueMessagesOnRandomPeer(t *testing.T, peers []*framework.Peer, addrBalance map[string]map[balance.Color]int64, numMessages int) (txIds []string) {
 	for i := 0; i < numMessages; i++ {
 		from := rand.Intn(len(peers))
 		to := rand.Intn(len(peers))
-		sentValue := SendValueMessages(t, peers[from], peers[to], addrBalance)
-
-		// update balance
-		addrBalance[addrMap[from]] -= sentValue
-		addrBalance[addrMap[to]] += sentValue
-
-		if sentValue == 0 {
+		fail, txId := SendColoredValueMessage(t, peers[from], peers[to], addrBalance)
+		if fail {
 			i--
+			continue
 		}
-		time.Sleep(5 * time.Second)
+
+		// attach tx id
+		txIds = append(txIds, txId)
+
+		// let the transaction propagate
+		time.Sleep(1 * time.Second)
 	}
 
 	return
 }
 
-// SendValueMessage sends a value message from and to a given peer and returns the transaction ID.
-// for testing convenience, the same addresses are used in each round
-func SendValueMessages(t *testing.T, from *framework.Peer, to *framework.Peer, addrBalance map[string]int64) (sent int64) {
+// SendColoredValueMessage sends a colored tokens from and to a given peer and returns the transaction ID.
+// The same addresses are used in each round
+func SendColoredValueMessage(t *testing.T, from *framework.Peer, to *framework.Peer, addrBalance map[string]map[balance.Color]int64) (fail bool, txId string) {
 	sigScheme := signaturescheme.ED25519(*from.Seed().KeyPair(0))
 	inputAddr := from.Seed().Address(0)
 	outputAddr := to.Seed().Address(0)
-	// skip if from peer has no balance
-	if addrBalance[inputAddr.String()] == 0 {
-		return 0
-	}
 
 	// prepare inputs
 	resp, err := from.GetUnspentOutputs([]string{inputAddr.String()})
 	require.NoErrorf(t, err, "Could not get unspent outputs on %s", from.String())
-	value := resp.UnspentOutputs[0].OutputIDs[0].Balances[0].Value
+
+	// abort if no unspent outputs
+	if len(resp.UnspentOutputs[0].OutputIDs) == 0 {
+		return true, ""
+	}
 
 	out, err := transaction.OutputIDFromBase58(resp.UnspentOutputs[0].OutputIDs[0].ID)
 	require.NoErrorf(t, err, "Invalid unspent outputs ID on %s", from.String())
@@ -195,24 +244,105 @@ func SendValueMessages(t *testing.T, from *framework.Peer, to *framework.Peer, a
 
 	// prepare outputs
 	outmap := map[address.Address][]*balance.Balance{}
+	bs := []*balance.Balance{}
+	var outputs *transaction.Outputs
+	var availableIOTA int64
+	availableBalances := resp.UnspentOutputs[0].OutputIDs[0].Balances
+	newColor := false
 
 	// set balances
-	balances := []*balance.Balance{balance.New(balance.ColorIOTA, value)}
-	outmap[outputAddr] = balances
-	outputs := transaction.NewOutputs(outmap)
+	if len(availableBalances) > 1 {
+		// the balances contain more than one color, send it all
+		for _, b := range availableBalances {
+			value := b.Value
+			color := getColorFromString(b.Color)
+			bs = append(bs, balance.New(color, value))
+
+			// update balance list
+			addrBalance[inputAddr.String()][color] -= value
+			if _, ok := addrBalance[outputAddr.String()][color]; ok {
+				addrBalance[outputAddr.String()][color] += value
+			} else {
+				addrBalance[outputAddr.String()][color] = value
+			}
+		}
+	} else {
+		// create new colored token if inputs only contain IOTA
+		// half of availableIota tokens remain IOTA, else get recolored
+		newColor = true
+		availableIOTA = availableBalances[0].Value
+
+		bs = append(bs, balance.New(balance.ColorIOTA, availableIOTA/2))
+		bs = append(bs, balance.New(balance.ColorNew, availableIOTA/2))
+
+		// update balance list
+		addrBalance[inputAddr.String()][balance.ColorIOTA] -= availableIOTA
+		addrBalance[outputAddr.String()][balance.ColorIOTA] += availableIOTA / 2
+	}
+	outmap[outputAddr] = bs
+
+	outputs = transaction.NewOutputs(outmap)
 
 	// sign transaction
 	txn := transaction.New(inputs, outputs).Sign(sigScheme)
 
 	// send transaction
-	_, err = from.SendTransaction(txn.Bytes())
+	txId, err = from.SendTransaction(txn.Bytes())
 	require.NoErrorf(t, err, "Could not send transaction on %s", from.String())
 
-	return value
+	// FIXME: the new color should be txn ID
+	if newColor {
+		if _, ok := addrBalance[outputAddr.String()][balance.ColorNew]; ok {
+			addrBalance[outputAddr.String()][balance.ColorNew] += availableIOTA / 2
+		} else {
+			addrBalance[outputAddr.String()][balance.ColorNew] = availableIOTA / 2
+		}
+		//addrBalance[outputAddr.String()][getColorFromString(txId)] = availableIOTA / 2
+	}
+	return false, txId
+}
+
+func getColorFromString(colorStr string) (color balance.Color) {
+	if colorStr == "IOTA" {
+		color = balance.ColorIOTA
+	} else {
+		t, _ := transaction.IDFromBase58(colorStr)
+		color, _, _ = balance.ColorFromBytes(t.Bytes())
+	}
+	return
 }
 
 // CheckBalances performs checks to make sure that all peers have the same ledger state.
-func CheckBalances(t *testing.T, peers []*framework.Peer, addrBalance map[string]int64, checkSynchronized bool) {
+func CheckBalances(t *testing.T, peers []*framework.Peer, addrBalance map[string]map[balance.Color]int64) {
+	for _, peer := range peers {
+		for addr, b := range addrBalance {
+			sum := make(map[balance.Color]int64)
+			resp, err := peer.GetUnspentOutputs([]string{addr})
+			require.NoError(t, err)
+			assert.Equal(t, addr, resp.UnspentOutputs[0].Address)
+
+			// calculate the balances of each color coin
+			for _, unspents := range resp.UnspentOutputs[0].OutputIDs {
+				for _, b := range unspents.Balances {
+					color := getColorFromString(b.Color)
+					if _, ok := sum[color]; ok {
+						sum[color] += b.Value
+					} else {
+						sum[color] = b.Value
+					}
+				}
+			}
+
+			// check balances
+			for color, value := range sum {
+				assert.Equal(t, b[color], value)
+			}
+		}
+	}
+}
+
+// CheckTransactions performs checks to make sure that all peers have received all transactions .
+func CheckTransactions(t *testing.T, peers []*framework.Peer, transactionIDs []string, checkSynchronized bool) {
 	for _, peer := range peers {
 		if checkSynchronized {
 			// check that the peer sees itself as synchronized
@@ -221,18 +351,12 @@ func CheckBalances(t *testing.T, peers []*framework.Peer, addrBalance map[string
 			require.True(t, info.Synced)
 		}
 
-		for addr, b := range addrBalance {
-			var iotas int64 = 0
-			resp, err := peer.GetUnspentOutputs([]string{addr})
+		for _, txId := range transactionIDs {
+			resp, err := peer.GetTransactionByID(txId)
 			require.NoError(t, err)
-			assert.Equal(t, addr, resp.UnspentOutputs[0].Address)
 
-			// calculate the total iotas of an address
-			for _, unspents := range resp.UnspentOutputs[0].OutputIDs {
-				iotas += unspents.Balances[0].Value
-				assert.Equal(t, balance.ColorIOTA.String(), unspents.Balances[0].Color)
-			}
-			assert.Equal(t, b, iotas)
+			// check inclusion state
+			assert.True(t, resp.InclusionState.Confirmed)
 		}
 	}
 }
diff --git a/tools/integration-tests/tester/tests/value/value_test.go b/tools/integration-tests/tester/tests/value/value_test.go
index 9696ac26cf75b76f92d1609693bd5eb7a38bd548..48777a8c9d4f9df0f8ab36587577af0b3ac47032 100644
--- a/tools/integration-tests/tester/tests/value/value_test.go
+++ b/tools/integration-tests/tester/tests/value/value_test.go
@@ -9,31 +9,38 @@ import (
 )
 
 // TestPersistence issues messages on random peers, restarts them and checks for persistence after restart.
-func TestPersistence(t *testing.T) {
-	n, err := f.CreateNetwork("value_TestPersistence", 4, 2)
+func TestValueIotaPersistence(t *testing.T) {
+	n, err := f.CreateNetwork("valueIota_TestPersistence", 4, 2)
 	require.NoError(t, err)
 	defer tests.ShutdownNetwork(t, n)
 
 	// wait for peers to change their state to synchronized
 	time.Sleep(5 * time.Second)
 
-	// master node issue transaction to all peers in the network
-	_, addrBalance := tests.SendValueMessagesOnFaucet(t, n.Peers())
+	// master node sends funds to all peers in the network
+	txIds, addrBalance := tests.SendValueMessagesOnFaucet(t, n.Peers())
 
 	// wait for messages to be gossiped
 	time.Sleep(10 * time.Second)
 
-	// 2. check whether all issued messages are available on all nodes
-	tests.CheckBalances(t, n.Peers(), addrBalance, true)
+	// check whether the first issued transaction is available on all nodes, and confirmed
+	tests.CheckTransactions(t, n.Peers(), txIds, true)
+
+	// check ledger state
+	tests.CheckBalances(t, n.Peers(), addrBalance)
 
 	// send value message randomly
-	tests.SendValueMessagesOnRandomPeer(t, n.Peers(), addrBalance, 10)
+	randomTxIds := tests.SendValueMessagesOnRandomPeer(t, n.Peers(), addrBalance, 10)
+	txIds = append(txIds, randomTxIds...)
 
 	// wait for messages to be gossiped
 	time.Sleep(10 * time.Second)
 
-	// check whether all issued messages are available on all nodes
-	tests.CheckBalances(t, n.Peers(), addrBalance, true)
+	// check whether all issued transactions are persistently available on all nodes, and confirmed
+	tests.CheckTransactions(t, n.Peers(), txIds, true)
+
+	// check ledger state
+	tests.CheckBalances(t, n.Peers(), addrBalance)
 
 	// 3. stop all nodes
 	for _, peer := range n.Peers() {
@@ -50,6 +57,65 @@ func TestPersistence(t *testing.T) {
 	// wait for peers to start
 	time.Sleep(10 * time.Second)
 
-	// 5. check whether all issued messages are persistently available on all nodes
-	tests.CheckBalances(t, n.Peers(), addrBalance, true)
+	// check whether all issued transactions are persistently available on all nodes, and confirmed
+	tests.CheckTransactions(t, n.Peers(), txIds, true)
+
+	// 5. check ledger state
+	tests.CheckBalances(t, n.Peers(), addrBalance)
+}
+
+// TestColoredPersistence issues colored tokens on random peers, restarts them and checks for persistence after restart.
+func TestValueColoredPersistence(t *testing.T) {
+	n, err := f.CreateNetwork("valueColor_TestPersistence", 4, 2)
+	require.NoError(t, err)
+	defer tests.ShutdownNetwork(t, n)
+
+	// wait for peers to change their state to synchronized
+	time.Sleep(5 * time.Second)
+
+	// master node sends funds to all peers in the network
+	txIds, addrBalance := tests.SendValueMessagesOnFaucet(t, n.Peers())
+
+	// wait for messages to be gossiped
+	time.Sleep(10 * time.Second)
+
+	// check whether the transactions are available on all nodes, and confirmed
+	tests.CheckTransactions(t, n.Peers(), txIds, true)
+
+	// check ledger state
+	tests.CheckBalances(t, n.Peers(), addrBalance)
+
+	// send funds around
+	randomTxIds := tests.SendColoredValueMessagesOnRandomPeer(t, n.Peers(), addrBalance, 10)
+	txIds = append(txIds, randomTxIds...)
+
+	// wait for value messages to be gossiped
+	time.Sleep(10 * time.Second)
+
+	// check whether all issued transactions are persistently available on all nodes, and confirmed
+	tests.CheckTransactions(t, n.Peers(), txIds, true)
+
+	// check ledger state
+	tests.CheckBalances(t, n.Peers(), addrBalance)
+
+	// stop all nodes
+	for _, peer := range n.Peers() {
+		err = peer.Stop()
+		require.NoError(t, err)
+	}
+
+	// start all nodes
+	for _, peer := range n.Peers() {
+		err = peer.Start()
+		require.NoError(t, err)
+	}
+
+	// wait for peers to start
+	time.Sleep(10 * time.Second)
+
+	// check whether all issued transactions are persistently available on all nodes, and confirmed
+	tests.CheckTransactions(t, n.Peers(), txIds, true)
+
+	// 5. check ledger state
+	tests.CheckBalances(t, n.Peers(), addrBalance)
 }