mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-10 10:05:18 +00:00
Add swp token distribution (#1003)
* implement swp airdrop to usdx depositors to hard * verify swp airdrop amount, total supply, affected users * remove unused test code * add map as go file * update tests to use stored variable * re-add snapshot test * update snapshot testdata * remove unused code for generating swp airdrop map * remove snapshot test * add swp token distribution * bump test timeouts * address review comments * use global variables to simplify testing assertions on swp supply * optional: swp migration test and small refactor (#1005) * add test to ensure balances are not decreased * simplify slice manipulation * bump context deadline in circleci Co-authored-by: Ruaridh <rhuairahrighairidh@users.noreply.github.com>
This commit is contained in:
parent
346501aa58
commit
cac7398120
@ -67,13 +67,14 @@ jobs:
|
||||
- go-mod-v2-{{ checksum "go.sum" }}
|
||||
- run:
|
||||
name: Run tests
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
export VERSION="$(git describe --tags --long | sed 's/v\(.*\)/\1/')"
|
||||
export GO111MODULE=on
|
||||
mkdir -p /tmp/logs /tmp/workspace/profiles
|
||||
for pkg in $(go list ./... | grep -v -P 'simulation|migrate(?!\/v0_15)|contrib' | circleci tests split); do
|
||||
id=$(echo "$pkg" | sed 's|[/.]|_|g')
|
||||
go test -mod=readonly -timeout 8m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg" | tee "/tmp/logs/$id-$RANDOM.log"
|
||||
go test -mod=readonly -timeout 20m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg" | tee "/tmp/logs/$id-$RANDOM.log"
|
||||
done
|
||||
- persist_to_workspace:
|
||||
root: /tmp/workspace
|
||||
|
@ -18,16 +18,15 @@ import (
|
||||
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
||||
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
||||
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
|
||||
"github.com/kava-labs/kava/x/kavadist"
|
||||
v0_15swap "github.com/kava-labs/kava/x/swap/types"
|
||||
v0_14validator_vesting "github.com/kava-labs/kava/x/validator-vesting"
|
||||
)
|
||||
|
||||
var (
|
||||
// TODO: update GenesisTime and chain-id for kava-8 launch
|
||||
GenesisTime = time.Date(2021, 8, 30, 15, 0, 0, 0, time.UTC)
|
||||
GenesisTime = time.Date(2021, 8, 30, 15, 0, 0, 0, time.UTC) // 1630335600
|
||||
ChainID = "kava-8"
|
||||
// TODO: update SWP reward per second amount before production
|
||||
// TODO: add swap tokens to kavadist module account
|
||||
// TODO: update SWP reward per second amount before production
|
||||
SwpDelegatorRewardsPerSecond = sdk.NewCoin("swp", sdk.OneInt())
|
||||
SwpLiquidityProviderRewardsPerSecond = sdk.NewCoin("swp", sdk.OneInt())
|
||||
@ -112,10 +111,12 @@ func makeV014Codec() *codec.Codec {
|
||||
func Auth(cdc *codec.Codec, genesisState auth.GenesisState, genesisTime time.Time) auth.GenesisState {
|
||||
genesisStateWithAccountsMigrated := MigrateAccounts(genesisState, genesisTime)
|
||||
genesisStateWithSwpAirdrop := ApplySwpAirdrop(cdc, genesisStateWithAccountsMigrated)
|
||||
genesisStateWithSwpDistribution := DistributeSwpTokens(genesisStateWithSwpAirdrop)
|
||||
|
||||
return genesisStateWithSwpAirdrop
|
||||
return genesisStateWithSwpDistribution
|
||||
}
|
||||
|
||||
// ApplySwpAirdrop airdrops 1,000,000 SWP tokens to USDX depositors to HARD at block 1543671
|
||||
func ApplySwpAirdrop(cdc *codec.Codec, genesisState auth.GenesisState) auth.GenesisState {
|
||||
accounts := make([]authexported.GenesisAccount, len(genesisState.Accounts))
|
||||
migratedGenesisState := auth.NewGenesisState(genesisState.Params, accounts)
|
||||
@ -123,13 +124,17 @@ func ApplySwpAirdrop(cdc *codec.Codec, genesisState auth.GenesisState) auth.Gene
|
||||
cdc.MustUnmarshalJSON([]byte(swpAirdropMap), &swpAirdrop)
|
||||
for i, acc := range genesisState.Accounts {
|
||||
if swpReward, ok := swpAirdrop[acc.GetAddress().String()]; ok {
|
||||
acc.SetCoins(acc.GetCoins().Add(swpReward))
|
||||
err := acc.SetCoins(acc.GetCoins().Add(swpReward))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
accounts[i] = authexported.GenesisAccount(acc)
|
||||
}
|
||||
return migratedGenesisState
|
||||
}
|
||||
|
||||
// MigrateAccounts removes expired vesting periods from account state
|
||||
func MigrateAccounts(genesisState auth.GenesisState, genesisTime time.Time) auth.GenesisState {
|
||||
accounts := make([]authexported.GenesisAccount, len(genesisState.Accounts))
|
||||
migratedGenesisState := auth.NewGenesisState(genesisState.Params, accounts)
|
||||
@ -141,6 +146,104 @@ func MigrateAccounts(genesisState auth.GenesisState, genesisTime time.Time) auth
|
||||
return migratedGenesisState
|
||||
}
|
||||
|
||||
// global variables for swp distribution
|
||||
var (
|
||||
SwpEcoSystemAddr = mustAccAddressFromBech32("kava174crgzk006lj39s258gjxkh0p9tmmq8ugdcg0n")
|
||||
SwpTreasuryAddr = mustAccAddressFromBech32("kava1w56wrusdnrv4tvn86eyam65wwhqatmsqg9fxjm")
|
||||
SwpTeamAddr = mustAccAddressFromBech32("kava129eqnykzkc5ceyq9sv7ltxev22y8qwm94kr0ew")
|
||||
KavaDistAddr = supply.NewModuleAddress(kavadist.KavaDistMacc)
|
||||
SwpTreasuryCoins = sdk.NewCoin("swp", sdk.NewInt(62500000000000))
|
||||
SwpTreasuryOriginalVesting = sdk.NewCoin("swp", sdk.NewInt(46875000000000))
|
||||
KavaDistCoins = sdk.NewCoin("swp", sdk.NewInt(137500000e6))
|
||||
EcoSystemCoins = sdk.NewCoin("swp", sdk.NewInt(11500000000000))
|
||||
SwpTeamCoins = sdk.NewCoin("swp", sdk.NewInt(37500000000000))
|
||||
)
|
||||
|
||||
// DistributeSwpTokens sets the initial distribution of swp tokens according to the proposed token supply schedule in prop 59
|
||||
func DistributeSwpTokens(genesisState auth.GenesisState) auth.GenesisState {
|
||||
|
||||
// add SWP incentives (LP, Kava stakers) to kavadist module account
|
||||
accounts := make([]authexported.GenesisAccount, len(genesisState.Accounts))
|
||||
for i, acc := range genesisState.Accounts {
|
||||
if acc.GetAddress().Equals(KavaDistAddr) {
|
||||
err := acc.SetCoins(acc.GetCoins().Add(KavaDistCoins))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
accounts[i] = authexported.GenesisAccount(acc)
|
||||
|
||||
}
|
||||
|
||||
// Add ecosystem account
|
||||
swpEcosystemBacc := auth.NewBaseAccountWithAddress(SwpEcoSystemAddr)
|
||||
// 11.5M because 1M has already been airdropped
|
||||
err := swpEcosystemBacc.SetCoins(sdk.NewCoins(EcoSystemCoins))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Add team vesting account
|
||||
swpTeamBacc := auth.NewBaseAccountWithAddress(SwpTeamAddr)
|
||||
err = swpTeamBacc.SetCoins(sdk.NewCoins(SwpTeamCoins))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
swpTeamBva, err := vesting.NewBaseVestingAccount(&swpTeamBacc, sdk.NewCoins(SwpTeamCoins), 1693407600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
swpTeamTokenSchedule := []sdk.Coin{
|
||||
sdk.NewCoin("swp", sdk.NewInt(18750000000000)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(4687500000000)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(4687500000000)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(4687500000000)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(4687500000000)),
|
||||
}
|
||||
|
||||
swpTeamVestingLengths := []int64{31536000, 7948800, 7776000, 7948800, 7862400}
|
||||
swpTeamVestingPeriods := vesting.Periods{}
|
||||
for i, vestingCoin := range swpTeamTokenSchedule {
|
||||
period := vesting.Period{Length: swpTeamVestingLengths[i], Amount: sdk.NewCoins(vestingCoin)}
|
||||
swpTeamVestingPeriods = append(swpTeamVestingPeriods, period)
|
||||
}
|
||||
swpTeamVestingAccount := vesting.NewPeriodicVestingAccountRaw(swpTeamBva, GenesisTime.Unix(), swpTeamVestingPeriods)
|
||||
|
||||
// Add treasury vesting account
|
||||
swpTreasuryBacc := auth.NewBaseAccountWithAddress(SwpTreasuryAddr)
|
||||
|
||||
err = swpTreasuryBacc.SetCoins(sdk.NewCoins(SwpTreasuryCoins))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
swpTreasuryBva, err := vesting.NewBaseVestingAccount(&swpTreasuryBacc, sdk.NewCoins(SwpTreasuryOriginalVesting), 1693407600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
swpTreasuryTokenSchedule := []sdk.Coin{
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
sdk.NewCoin("swp", sdk.NewInt(5859375e6)),
|
||||
}
|
||||
swpTreasuryVestingLengths := []int64{7948800, 7776000, 7948800, 7862400, 7948800, 7776000, 7948800, 7862400}
|
||||
swpTreasuryVestingPeriods := vesting.Periods{}
|
||||
for i, vestingCoin := range swpTreasuryTokenSchedule {
|
||||
period := vesting.Period{Length: swpTreasuryVestingLengths[i], Amount: sdk.NewCoins(vestingCoin)}
|
||||
swpTreasuryVestingPeriods = append(swpTreasuryVestingPeriods, period)
|
||||
}
|
||||
swpTreasuryVestingAccount := vesting.NewPeriodicVestingAccountRaw(swpTreasuryBva, GenesisTime.Unix(), swpTreasuryVestingPeriods)
|
||||
|
||||
accounts = append(accounts, &swpEcosystemBacc, swpTeamVestingAccount, swpTreasuryVestingAccount)
|
||||
|
||||
return auth.NewGenesisState(genesisState.Params, accounts)
|
||||
}
|
||||
|
||||
// Committee migrates from a v0.14 committee genesis state to a v0.15 committee genesis state
|
||||
func Committee(genesisState v0_14committee.GenesisState) v0_15committee.GenesisState {
|
||||
|
||||
@ -379,3 +482,12 @@ func Swap() v0_15swap.GenesisState {
|
||||
params := v0_15swap.NewParams(pools, fee)
|
||||
return v0_15swap.NewGenesisState(params, v0_15swap.DefaultPoolRecords, v0_15swap.DefaultShareRecords)
|
||||
}
|
||||
|
||||
func mustAccAddressFromBech32(bech32Addr string) sdk.AccAddress {
|
||||
app.SetBech32AddressPrefixes(sdk.GetConfig())
|
||||
addr, err := sdk.AccAddressFromBech32(bech32Addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
@ -189,6 +189,33 @@ func TestAuth_AccountConversion(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuth_Regression_BalancesEqual(t *testing.T) {
|
||||
bz, err := ioutil.ReadFile(filepath.Join("testdata", "block-1543671-auth-state.json"))
|
||||
require.NoError(t, err)
|
||||
|
||||
cdc := app.MakeCodec()
|
||||
|
||||
var originalGenesisState auth.GenesisState
|
||||
cdc.MustUnmarshalJSON(bz, &originalGenesisState)
|
||||
|
||||
var genesisState auth.GenesisState
|
||||
cdc.MustUnmarshalJSON(bz, &genesisState)
|
||||
|
||||
genesisState = Auth(cdc, genesisState, GenesisTime)
|
||||
|
||||
for i, oldAcc := range originalGenesisState.Accounts {
|
||||
acc := genesisState.Accounts[i]
|
||||
|
||||
// total owned coins does not change, despite additional swp tokens
|
||||
swpBalance := sdk.NewCoins(sdk.NewCoin("swp", acc.GetCoins().AmountOf("swp")))
|
||||
require.Equal(t, oldAcc.GetCoins(), acc.GetCoins().Sub(swpBalance), "expected base coins to not change")
|
||||
|
||||
// ensure spendable coins at genesis time is equal, despite additional swp tokens
|
||||
swpBalance = sdk.NewCoins(sdk.NewCoin("swp", acc.SpendableCoins(GenesisTime).AmountOf("swp")))
|
||||
require.Equal(t, oldAcc.SpendableCoins(GenesisTime), acc.SpendableCoins(GenesisTime).Sub(swpBalance), "expected spendable coins to not change")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuth_MakeAirdropMap(t *testing.T) {
|
||||
cdc := app.MakeCodec()
|
||||
aidropTokenAmount := sdk.NewInt(1000000000000)
|
||||
@ -225,9 +252,8 @@ func TestAuth_TestAllDepositorsIncluded(t *testing.T) {
|
||||
require.Equal(t, depositorsInSnapShot, len(keys))
|
||||
}
|
||||
|
||||
func TestAuth_SwpSupply(t *testing.T) {
|
||||
func TestAuth_SwpSupply_AfterAirdrop(t *testing.T) {
|
||||
swpSupply := sdk.NewCoin("swp", sdk.ZeroInt())
|
||||
// TODO update when additional swp are added to migration, final supply should be 250M at genesis
|
||||
expectedSwpSupply := sdk.NewCoin("swp", sdk.NewInt(1000000000000))
|
||||
bz, err := ioutil.ReadFile(filepath.Join("testdata", "block-1543671-auth-state.json"))
|
||||
require.NoError(t, err)
|
||||
@ -236,6 +262,28 @@ func TestAuth_SwpSupply(t *testing.T) {
|
||||
cdc := app.MakeCodec()
|
||||
cdc.MustUnmarshalJSON(bz, &genesisState)
|
||||
|
||||
migratedGenesisState := ApplySwpAirdrop(cdc, genesisState)
|
||||
|
||||
for _, acc := range migratedGenesisState.Accounts {
|
||||
swpAmount := acc.GetCoins().AmountOf("swp")
|
||||
if swpAmount.IsPositive() {
|
||||
swpCoin := sdk.NewCoin("swp", swpAmount)
|
||||
swpSupply = swpSupply.Add(swpCoin)
|
||||
}
|
||||
}
|
||||
require.Equal(t, expectedSwpSupply, swpSupply)
|
||||
}
|
||||
|
||||
func TestAuth_SwpSupply_TotalSupply(t *testing.T) {
|
||||
swpSupply := sdk.NewCoin("swp", sdk.ZeroInt())
|
||||
expectedSwpSupply := sdk.NewCoin("swp", sdk.NewInt(250000000e6))
|
||||
bz, err := ioutil.ReadFile(filepath.Join("testdata", "block-1543671-auth-state.json"))
|
||||
require.NoError(t, err)
|
||||
|
||||
var genesisState auth.GenesisState
|
||||
cdc := app.MakeCodec()
|
||||
cdc.MustUnmarshalJSON(bz, &genesisState)
|
||||
|
||||
migratedGenesisState := Auth(cdc, genesisState, GenesisTime)
|
||||
|
||||
for _, acc := range migratedGenesisState.Accounts {
|
||||
@ -247,3 +295,59 @@ func TestAuth_SwpSupply(t *testing.T) {
|
||||
}
|
||||
require.Equal(t, expectedSwpSupply, swpSupply)
|
||||
}
|
||||
|
||||
func TestAuth_SwpSupply_SpendableCoins(t *testing.T) {
|
||||
bz, err := ioutil.ReadFile(filepath.Join("testdata", "block-1543671-auth-state.json"))
|
||||
require.NoError(t, err)
|
||||
|
||||
var genesisState auth.GenesisState
|
||||
cdc := app.MakeCodec()
|
||||
cdc.MustUnmarshalJSON(bz, &genesisState)
|
||||
|
||||
swpTreasuryExpectedSpendableCoins := sdk.NewCoins(SwpTreasuryCoins.Sub(SwpTreasuryOriginalVesting))
|
||||
foundTreasury := false
|
||||
|
||||
swpTeamExpectedSpendableCoins := sdk.Coins(nil)
|
||||
foundTeam := false
|
||||
|
||||
kavaDistExpectedSpendableCoins := KavaDistCoins
|
||||
foundKavadist := false
|
||||
|
||||
swpEcosystemExpectedSpendableCoins := sdk.NewCoins(EcoSystemCoins)
|
||||
foundEcosystem := false
|
||||
|
||||
migratedGenesisState := Auth(cdc, genesisState, GenesisTime)
|
||||
|
||||
for _, acc := range migratedGenesisState.Accounts {
|
||||
if acc.GetAddress().Equals(SwpTreasuryAddr) {
|
||||
foundTreasury = true
|
||||
pva, ok := acc.(*vesting.PeriodicVestingAccount)
|
||||
require.True(t, ok)
|
||||
spendableCoins := pva.SpendableCoins(GenesisTime)
|
||||
require.Equal(t, swpTreasuryExpectedSpendableCoins, spendableCoins)
|
||||
}
|
||||
if acc.GetAddress().Equals(SwpTeamAddr) {
|
||||
foundTeam = true
|
||||
pva, ok := acc.(*vesting.PeriodicVestingAccount)
|
||||
require.True(t, ok)
|
||||
spendableCoins := pva.SpendableCoins(GenesisTime)
|
||||
require.Equal(t, swpTeamExpectedSpendableCoins, spendableCoins)
|
||||
}
|
||||
if acc.GetAddress().Equals(KavaDistAddr) {
|
||||
foundKavadist = true
|
||||
spendableCoins := acc.SpendableCoins(GenesisTime)
|
||||
spendableSwp := sdk.NewCoin("swp", spendableCoins.AmountOf("swp"))
|
||||
require.Equal(t, kavaDistExpectedSpendableCoins, spendableSwp)
|
||||
}
|
||||
if acc.GetAddress().Equals(SwpEcoSystemAddr) {
|
||||
foundEcosystem = true
|
||||
spendableCoins := acc.SpendableCoins(GenesisTime)
|
||||
require.Equal(t, swpEcosystemExpectedSpendableCoins, spendableCoins)
|
||||
}
|
||||
}
|
||||
require.True(t, foundTreasury)
|
||||
require.True(t, foundTeam)
|
||||
require.True(t, foundKavadist)
|
||||
require.True(t, foundEcosystem)
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user