diff --git a/packages/mana/balance.go b/packages/mana/balance.go
index ebb9c4e5d42ad8afd3bd01bf9ff8234f91c3642f..1c407ff90c536e2246c39124fb6b77e2929c86da 100644
--- a/packages/mana/balance.go
+++ b/packages/mana/balance.go
@@ -5,18 +5,18 @@ import (
 )
 
 type Balance struct {
-	calculator                 *Calculator
-	currentBalance             uint64
-	lastErosion                uint64
-	roundingErrorInLastErosion float64
+	calculator               *Calculator
+	currentBalance           uint64
+	lastErosion              uint64
+	accumulatedRoundingError float64
 }
 
 func NewBalance(calculator *Calculator) *Balance {
 	return &Balance{
-		calculator:                 calculator,
-		currentBalance:             0,
-		lastErosion:                0,
-		roundingErrorInLastErosion: 0,
+		calculator:               calculator,
+		currentBalance:           0,
+		lastErosion:              0,
+		accumulatedRoundingError: 0,
 	}
 }
 
@@ -25,23 +25,33 @@ func (balance *Balance) GetValue() uint64 {
 }
 
 func (balance *Balance) AddTransfer(movedCoins uint64, receivedTime uint64, spentTime uint64) {
-	gainedMana, _ := balance.calculator.GenerateMana(movedCoins, spentTime-receivedTime)
-
-	if spentTime >= balance.lastErosion {
-		balance.Erode(spentTime)
-	} else {
-		fmt.Println("empty")
-		// revert old actions
-		// apply new
-		// replay old
+	gainedMana, roundingError := balance.calculator.GenerateMana(movedCoins, spentTime-receivedTime)
+
+	if balance.currentBalance != 0 {
+		if spentTime >= balance.lastErosion {
+			balance.Erode(spentTime)
+		} else {
+			fmt.Println("empty")
+			// revert old actions
+			// apply new
+			// replay old
+		}
 	}
 
 	balance.currentBalance += gainedMana
+	balance.accumulatedRoundingError += roundingError
+	balance.lastErosion = spentTime
+
+	fmt.Println("GENERATE: ", spentTime-receivedTime, movedCoins, gainedMana)
 }
 
 func (balance *Balance) Erode(erosionTime uint64) {
 	if balance.lastErosion <= erosionTime {
-		balance.currentBalance, _ = balance.calculator.ErodeMana(balance.currentBalance, erosionTime-balance.lastErosion)
+		erodedMana, _ := balance.calculator.ErodeMana(balance.currentBalance, erosionTime-balance.lastErosion)
+
+		fmt.Println("ERODE: ", erosionTime-balance.lastErosion, balance.currentBalance, erodedMana)
+
+		balance.currentBalance = erodedMana
 	} else {
 		fmt.Println("empty")
 		// revert old erosions
diff --git a/packages/mana/balance_test.go b/packages/mana/balance_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..233458983ac1baa1fa5194d09b9c52fd58f14490
--- /dev/null
+++ b/packages/mana/balance_test.go
@@ -0,0 +1,20 @@
+package mana
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestBalance_AddTransfer(t *testing.T) {
+	calculator := NewCalculator(500, 0.1)
+
+	balance1 := NewBalance(calculator)
+	balance1.AddTransfer(1000, 0, 500)
+	balance1.AddTransfer(1000, 500, 1000)
+	balance1.AddTransfer(1000, 1000, 1700)
+	fmt.Println(balance1.GetValue())
+
+	balance2 := NewBalance(calculator)
+	balance2.AddTransfer(1000, 0, 1700)
+	fmt.Println(balance2.GetValue())
+}
diff --git a/packages/mana/calculator.go b/packages/mana/calculator.go
index d1ff397f51616f1101e2b1ce2ebd37fde8ec6084..46aa3c53046a68f3c28d5caaebe6bd09fdc77170 100644
--- a/packages/mana/calculator.go
+++ b/packages/mana/calculator.go
@@ -7,7 +7,7 @@ import (
 // A calculator that can be used to calculate the changes of mana due to erosion or mana generation.
 type Calculator struct {
 	decayInterval          float64
-	decayRate              float64
+	decayFactor            float64
 	options                *CalculatorOptions
 	tokenSupplyScalefactor float64
 }
@@ -17,13 +17,13 @@ func NewCalculator(decayInterval float64, decayRate float64, optionalOptions ...
 	return &Calculator{
 		// store key settings
 		decayInterval: decayInterval,
-		decayRate:     decayRate,
 
 		// configure optional parameters
 		options: DEFAULT_OPTIONS.Override(optionalOptions...),
 
 		// derive important factors ...
 		// ... make mana reach exactly the token supply as it's max value (n coins => n mana)
+		decayFactor:            1 - decayRate,
 		tokenSupplyScalefactor: decayRate / (1 - decayRate),
 	}
 }
@@ -31,9 +31,7 @@ func NewCalculator(decayInterval float64, decayRate float64, optionalOptions ...
 // Returns the amount of mana that was generated by holding the given amount of coins for the given time.
 func (calculator *Calculator) GenerateMana(coins uint64, heldTime uint64) (result uint64, roundingError float64) {
 	// calculate results
-	relativeDecayTime := float64(heldTime) / float64(calculator.decayInterval)
-	erosionFactor := (1 - math.Pow(1-calculator.decayRate, float64(relativeDecayTime+1)) - calculator.decayRate) / calculator.decayRate
-	gainedMana := float64(coins) * calculator.options.ManaScaleFactor * calculator.tokenSupplyScalefactor * erosionFactor
+	gainedMana := float64(coins) * calculator.options.ManaScaleFactor * (1 - math.Pow(calculator.decayFactor, float64(heldTime)/calculator.decayInterval))
 
 	// assign rounded results & determine roundingErrors
 	result = uint64(math.Round(gainedMana))
@@ -52,8 +50,7 @@ func (calculator *Calculator) ErodeMana(mana uint64, decayTime uint64) (result u
 	}
 
 	// calculate results
-	growthFactor := math.Log(1-calculator.decayRate) / float64(calculator.decayInterval)
-	erodedMana := float64(mana) * math.Pow(math.E, growthFactor*float64(decayTime))
+	erodedMana := float64(mana) * math.Pow(calculator.decayFactor, float64(decayTime)/calculator.decayInterval)
 
 	// assign rounded results & determine roundingErrors
 	result = uint64(math.Round(erodedMana))