2018-02-23 15:57:31 -08:00
|
|
|
package stake
|
|
|
|
|
2018-03-29 05:27:35 -07:00
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestGetInflation(t *testing.T) {
|
2018-04-01 09:05:58 -07:00
|
|
|
ctx, _, keeper := createTestInput(t, false, 0)
|
2018-03-29 05:27:35 -07:00
|
|
|
pool := keeper.GetPool(ctx)
|
|
|
|
params := keeper.GetParams(ctx)
|
|
|
|
hrsPerYrRat := sdk.NewRat(hrsPerYr)
|
|
|
|
|
|
|
|
// Governing Mechanism:
|
2018-05-12 17:21:02 -07:00
|
|
|
// bondedRatio = BondedTokens / TotalSupply
|
2018-03-29 05:27:35 -07:00
|
|
|
// inflationRateChangePerYear = (1- bondedRatio/ GoalBonded) * MaxInflationRateChange
|
|
|
|
|
|
|
|
tests := []struct {
|
2018-05-22 15:50:59 -07:00
|
|
|
name string
|
|
|
|
setBondedTokens, setLooseTokens int64
|
|
|
|
setInflation, expectedChange sdk.Rat
|
2018-03-29 05:27:35 -07:00
|
|
|
}{
|
|
|
|
// with 0% bonded atom supply the inflation should increase by InflationRateChange
|
2018-03-30 13:19:21 -07:00
|
|
|
{"test 1", 0, 0, sdk.NewRat(7, 100), params.InflationRateChange.Quo(hrsPerYrRat).Round(precision)},
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// 100% bonded, starting at 20% inflation and being reduced
|
|
|
|
// (1 - (1/0.67))*(0.13/8667)
|
2018-05-22 15:50:59 -07:00
|
|
|
{"test 2", 1, 0, sdk.NewRat(20, 100),
|
2018-04-30 14:21:14 -07:00
|
|
|
sdk.OneRat().Sub(sdk.OneRat().Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// 50% bonded, starting at 10% inflation and being increased
|
2018-05-22 15:50:59 -07:00
|
|
|
{"test 3", 1, 1, sdk.NewRat(10, 100),
|
2018-04-30 14:21:14 -07:00
|
|
|
sdk.OneRat().Sub(sdk.NewRat(1, 2).Quo(params.GoalBonded)).Mul(params.InflationRateChange).Quo(hrsPerYrRat).Round(precision)},
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// test 7% minimum stop (testing with 100% bonded)
|
2018-05-22 15:50:59 -07:00
|
|
|
{"test 4", 1, 0, sdk.NewRat(7, 100), sdk.ZeroRat()},
|
|
|
|
{"test 5", 1, 0, sdk.NewRat(70001, 1000000), sdk.NewRat(-1, 1000000).Round(precision)},
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// test 20% maximum stop (testing with 0% bonded)
|
2018-04-30 14:21:14 -07:00
|
|
|
{"test 6", 0, 0, sdk.NewRat(20, 100), sdk.ZeroRat()},
|
2018-03-30 13:19:21 -07:00
|
|
|
{"test 7", 0, 0, sdk.NewRat(199999, 1000000), sdk.NewRat(1, 1000000).Round(precision)},
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// perfect balance shouldn't change inflation
|
2018-05-22 15:50:59 -07:00
|
|
|
{"test 8", 67, 33, sdk.NewRat(15, 100), sdk.ZeroRat()},
|
2018-03-29 05:27:35 -07:00
|
|
|
}
|
|
|
|
for _, tc := range tests {
|
2018-05-22 15:50:59 -07:00
|
|
|
pool.BondedTokens, pool.LooseUnbondedTokens = tc.setBondedTokens, tc.setLooseTokens
|
2018-03-29 05:27:35 -07:00
|
|
|
pool.Inflation = tc.setInflation
|
|
|
|
keeper.setPool(ctx, pool)
|
|
|
|
|
|
|
|
inflation := keeper.nextInflation(ctx)
|
|
|
|
diffInflation := inflation.Sub(tc.setInflation)
|
|
|
|
|
|
|
|
assert.True(t, diffInflation.Equal(tc.expectedChange),
|
|
|
|
"Name: %v\nDiff: %v\nExpected: %v\n", tc.name, diffInflation, tc.expectedChange)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestProcessProvisions(t *testing.T) {
|
2018-04-01 09:05:58 -07:00
|
|
|
ctx, _, keeper := createTestInput(t, false, 0)
|
2018-03-29 05:27:35 -07:00
|
|
|
params := defaultParams()
|
2018-05-18 15:57:47 -07:00
|
|
|
params.MaxValidators = 2
|
2018-03-29 05:27:35 -07:00
|
|
|
keeper.setParams(ctx, params)
|
|
|
|
pool := keeper.GetPool(ctx)
|
|
|
|
|
2018-05-22 15:50:59 -07:00
|
|
|
var tokenSupply int64 = 550000000
|
2018-03-29 05:27:35 -07:00
|
|
|
var bondedShares int64 = 150000000
|
|
|
|
var unbondedShares int64 = 400000000
|
2018-05-18 15:57:47 -07:00
|
|
|
|
|
|
|
// create some validators some bonded, some unbonded
|
|
|
|
var validators [5]Validator
|
|
|
|
validators[0] = NewValidator(addrs[0], pks[0], Description{})
|
|
|
|
validators[0], pool, _ = validators[0].addTokensFromDel(pool, 150000000)
|
2018-05-20 14:39:04 -07:00
|
|
|
keeper.setPool(ctx, pool)
|
2018-05-22 15:50:59 -07:00
|
|
|
validators[0] = keeper.updateValidator(ctx, validators[0])
|
|
|
|
pool = keeper.GetPool(ctx)
|
|
|
|
require.Equal(t, bondedShares, pool.BondedTokens, "%v", pool)
|
|
|
|
|
2018-05-18 15:57:47 -07:00
|
|
|
validators[1] = NewValidator(addrs[1], pks[1], Description{})
|
|
|
|
validators[1], pool, _ = validators[1].addTokensFromDel(pool, 100000000)
|
|
|
|
keeper.setPool(ctx, pool)
|
2018-05-22 12:13:03 -07:00
|
|
|
validators[1] = keeper.updateValidator(ctx, validators[1])
|
2018-05-18 15:57:47 -07:00
|
|
|
validators[2] = NewValidator(addrs[2], pks[2], Description{})
|
|
|
|
validators[2], pool, _ = validators[2].addTokensFromDel(pool, 100000000)
|
|
|
|
keeper.setPool(ctx, pool)
|
2018-05-22 12:13:03 -07:00
|
|
|
validators[2] = keeper.updateValidator(ctx, validators[2])
|
2018-05-18 15:57:47 -07:00
|
|
|
validators[3] = NewValidator(addrs[3], pks[3], Description{})
|
|
|
|
validators[3], pool, _ = validators[3].addTokensFromDel(pool, 100000000)
|
|
|
|
keeper.setPool(ctx, pool)
|
2018-05-22 12:13:03 -07:00
|
|
|
validators[3] = keeper.updateValidator(ctx, validators[3])
|
2018-05-18 15:57:47 -07:00
|
|
|
validators[4] = NewValidator(addrs[4], pks[4], Description{})
|
|
|
|
validators[4], pool, _ = validators[4].addTokensFromDel(pool, 100000000)
|
|
|
|
keeper.setPool(ctx, pool)
|
2018-05-22 12:13:03 -07:00
|
|
|
validators[4] = keeper.updateValidator(ctx, validators[4])
|
2018-05-18 15:57:47 -07:00
|
|
|
|
2018-05-22 15:50:59 -07:00
|
|
|
assert.Equal(t, tokenSupply, pool.TokenSupply())
|
2018-05-12 17:21:02 -07:00
|
|
|
assert.Equal(t, bondedShares, pool.BondedTokens)
|
|
|
|
assert.Equal(t, unbondedShares, pool.UnbondedTokens)
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// initial bonded ratio ~ 27%
|
2018-05-22 15:50:59 -07:00
|
|
|
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(bondedShares, tokenSupply)), "%v", pool.bondedRatio())
|
2018-03-29 05:27:35 -07:00
|
|
|
|
2018-05-09 21:01:58 -07:00
|
|
|
// test the value of validator shares
|
2018-04-30 14:21:14 -07:00
|
|
|
assert.True(t, pool.bondedShareExRate().Equal(sdk.OneRat()), "%v", pool.bondedShareExRate())
|
2018-03-29 05:27:35 -07:00
|
|
|
|
2018-05-22 15:50:59 -07:00
|
|
|
initialSupply := pool.TokenSupply()
|
|
|
|
initialUnbonded := pool.TokenSupply() - pool.BondedTokens
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// process the provisions a year
|
|
|
|
for hr := 0; hr < 8766; hr++ {
|
|
|
|
pool := keeper.GetPool(ctx)
|
|
|
|
expInflation := keeper.nextInflation(ctx).Round(1000000000)
|
2018-05-22 15:50:59 -07:00
|
|
|
expProvisions := (expInflation.Mul(sdk.NewRat(pool.TokenSupply())).Quo(hrsPerYrRat)).Evaluate()
|
|
|
|
startBondedTokens := pool.BondedTokens
|
|
|
|
startTotalSupply := pool.TokenSupply()
|
2018-03-29 05:27:35 -07:00
|
|
|
pool = keeper.processProvisions(ctx)
|
|
|
|
keeper.setPool(ctx, pool)
|
2018-05-22 15:50:59 -07:00
|
|
|
//fmt.Printf("hr %v, startBondedTokens %v, expProvisions %v, pool.BondedTokens %v\n", hr, startBondedTokens, expProvisions, pool.BondedTokens)
|
|
|
|
require.Equal(t, startBondedTokens+expProvisions, pool.BondedTokens, "hr %v", hr)
|
|
|
|
require.Equal(t, startTotalSupply+expProvisions, pool.TokenSupply())
|
2018-03-29 05:27:35 -07:00
|
|
|
}
|
|
|
|
pool = keeper.GetPool(ctx)
|
2018-05-22 15:50:59 -07:00
|
|
|
assert.NotEqual(t, initialSupply, pool.TokenSupply())
|
2018-05-12 17:21:02 -07:00
|
|
|
assert.Equal(t, initialUnbonded, pool.UnbondedTokens)
|
2018-05-22 15:50:59 -07:00
|
|
|
//panic(fmt.Sprintf("debug total %v, bonded %v, diff %v\n", p.TotalSupply, p.BondedTokens, pool.TokenSupply()-pool.BondedTokens))
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// initial bonded ratio ~ from 27% to 40% increase for bonded holders ownership of total supply
|
2018-04-30 14:21:14 -07:00
|
|
|
assert.True(t, pool.bondedRatio().Equal(sdk.NewRat(211813022, 611813022)), "%v", pool.bondedRatio())
|
2018-03-29 05:27:35 -07:00
|
|
|
|
|
|
|
// global supply
|
2018-05-22 15:50:59 -07:00
|
|
|
assert.Equal(t, int64(611813022), pool.TokenSupply())
|
2018-05-12 17:21:02 -07:00
|
|
|
assert.Equal(t, int64(211813022), pool.BondedTokens)
|
|
|
|
assert.Equal(t, unbondedShares, pool.UnbondedTokens)
|
2018-03-29 05:27:35 -07:00
|
|
|
|
2018-05-09 21:01:58 -07:00
|
|
|
// test the value of validator shares
|
2018-04-30 14:21:14 -07:00
|
|
|
assert.True(t, pool.bondedShareExRate().Mul(sdk.NewRat(bondedShares)).Equal(sdk.NewRat(211813022)), "%v", pool.bondedShareExRate())
|
2018-03-29 05:27:35 -07:00
|
|
|
}
|