|
| 1 | +// Package v1_2_2 is contains chain upgrade of the corresponding version. |
| 2 | +package v1_2_2 //nolint:revive,stylecheck // app version |
| 3 | + |
| 4 | +import ( |
| 5 | + "strings" |
| 6 | + |
| 7 | + "github.com/onomyprotocol/onex/app/upgrades" |
| 8 | + "github.com/pendulum-labs/market/x/market/types" |
| 9 | + |
| 10 | + sdk "github.com/cosmos/cosmos-sdk/types" |
| 11 | + "github.com/cosmos/cosmos-sdk/types/module" |
| 12 | + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" |
| 13 | +) |
| 14 | + |
| 15 | +func addUid(s []uint64, r uint64) ([]uint64, bool) { |
| 16 | + for _, v := range s { |
| 17 | + if v == r { |
| 18 | + return s, false |
| 19 | + } |
| 20 | + } |
| 21 | + |
| 22 | + return append(s, r), true |
| 23 | +} |
| 24 | + |
| 25 | +func removeUid(s []uint64, r uint64) ([]uint64, bool) { |
| 26 | + for i, v := range s { |
| 27 | + if v == r { |
| 28 | + return append(s[:i], s[i+1:]...), true |
| 29 | + } |
| 30 | + } |
| 31 | + return s, false |
| 32 | +} |
| 33 | + |
| 34 | +func CreateUpgradeHandler( |
| 35 | + mm *module.Manager, |
| 36 | + configurator module.Configurator, |
| 37 | + keepers *upgrades.UpgradeKeepers, |
| 38 | +) upgradetypes.UpgradeHandler { |
| 39 | + return func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { |
| 40 | + ctx.Logger().Info("Starting module migrations...") |
| 41 | + |
| 42 | + // Wipe corrupted leaderboards |
| 43 | + pools := keepers.MarketKeeper.GetAllPool(ctx) |
| 44 | + for _, pool := range pools { |
| 45 | + pool.Leaders = []*types.Leader{} |
| 46 | + keepers.MarketKeeper.SetPool(ctx, pool) |
| 47 | + } |
| 48 | + |
| 49 | + var dropOwner types.Drops |
| 50 | + var dropper types.Drop |
| 51 | + |
| 52 | + // For each drop in database |
| 53 | + drops := keepers.MarketKeeper.GetAllDrop(ctx) |
| 54 | + for _, drop := range drops { |
| 55 | + // Get DropsOwner associated with this drop |
| 56 | + dropOwner, _ = keepers.MarketKeeper.GetDropsOwnerPair(ctx, drop.Owner, drop.Pair) |
| 57 | + // Add (active) or remove (inactive) uid |
| 58 | + if drop.Active { |
| 59 | + dropOwner.Uids, _ = addUid(dropOwner.Uids, drop.Uid) |
| 60 | + |
| 61 | + // Recalculate Product because of potentially missed pool |
| 62 | + pair := strings.Split(drop.Pair, ",") |
| 63 | + |
| 64 | + denom1 := pair[0] |
| 65 | + denom2 := pair[1] |
| 66 | + |
| 67 | + pool, found := keepers.MarketKeeper.GetPool(ctx, drop.Pair) |
| 68 | + if !found { |
| 69 | + continue |
| 70 | + } |
| 71 | + |
| 72 | + member1, found := keepers.MarketKeeper.GetMember(ctx, denom2, denom1) |
| 73 | + if !found { |
| 74 | + continue |
| 75 | + } |
| 76 | + |
| 77 | + member2, found := keepers.MarketKeeper.GetMember(ctx, denom1, denom2) |
| 78 | + if !found { |
| 79 | + continue |
| 80 | + } |
| 81 | + |
| 82 | + // `total1 = (drop.Drops * member1.Balance) / pool.Drops` |
| 83 | + total1 := (drop.Drops.Mul(member1.Balance)).Quo(pool.Drops) |
| 84 | + total2 := (drop.Drops.Mul(member2.Balance)).Quo(pool.Drops) |
| 85 | + |
| 86 | + drop.Product = total1.Mul(total2) |
| 87 | + keepers.MarketKeeper.SetDrop(ctx, drop) |
| 88 | + } else { |
| 89 | + dropOwner.Uids, _ = removeUid(dropOwner.Uids, drop.Uid) |
| 90 | + } |
| 91 | + // Reset dropOwner.Sum to Zero |
| 92 | + dropOwner.Sum = sdk.ZeroInt() |
| 93 | + // Recalculate |
| 94 | + for _, uid := range dropOwner.Uids { |
| 95 | + dropper, _ = keepers.MarketKeeper.GetDrop(ctx, uid) |
| 96 | + if dropper.Active { |
| 97 | + dropOwner.Sum = dropOwner.Sum.Add(dropper.Drops) |
| 98 | + } |
| 99 | + } |
| 100 | + // Get pool associated with drop |
| 101 | + pool, _ := keepers.MarketKeeper.GetPool(ctx, drop.Pair) |
| 102 | + // Update leaders in pool based on recalculated sum |
| 103 | + pool = updateLeaders(ctx, pool, drop.Owner, dropOwner.Sum, keepers) |
| 104 | + // Set pool and drops |
| 105 | + keepers.MarketKeeper.SetPool(ctx, pool) |
| 106 | + keepers.MarketKeeper.SetDrops(ctx, dropOwner, drop.Owner, drop.Pair) |
| 107 | + } |
| 108 | + |
| 109 | + vm, err := mm.RunMigrations(ctx, configurator, vm) |
| 110 | + if err != nil { |
| 111 | + return vm, err |
| 112 | + } |
| 113 | + |
| 114 | + ctx.Logger().Info("Upgrade complete") |
| 115 | + return vm, err |
| 116 | + } |
| 117 | +} |
| 118 | + |
| 119 | +func updateLeaders(ctx sdk.Context, pool types.Pool, dropCreator string, dropCreatorSum sdk.Int, keepers *upgrades.UpgradeKeepers) types.Pool { |
| 120 | + maxLeaders := len(strings.Split(keepers.MarketKeeper.EarnRates(ctx), ",")) |
| 121 | + |
| 122 | + for i := 0; i < len(pool.Leaders); i++ { |
| 123 | + if pool.Leaders[i].Address == dropCreator { |
| 124 | + pool.Leaders = pool.Leaders[:i+copy(pool.Leaders[i:], pool.Leaders[i+1:])] |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + if dropCreatorSum.Equal(sdk.ZeroInt()) { |
| 129 | + return pool |
| 130 | + } |
| 131 | + |
| 132 | + if len(pool.Leaders) == 0 { |
| 133 | + pool.Leaders = append(pool.Leaders, &types.Leader{ |
| 134 | + Address: dropCreator, |
| 135 | + Drops: dropCreatorSum, |
| 136 | + }) |
| 137 | + } else { |
| 138 | + for i := 0; i < len(pool.Leaders); i++ { |
| 139 | + if dropCreatorSum.GT(pool.Leaders[i].Drops) { |
| 140 | + if len(pool.Leaders) < maxLeaders { |
| 141 | + pool.Leaders = append(pool.Leaders, pool.Leaders[len(pool.Leaders)-1]) |
| 142 | + } |
| 143 | + copy(pool.Leaders[i+1:], pool.Leaders[i:]) |
| 144 | + pool.Leaders[i] = &types.Leader{ |
| 145 | + Address: dropCreator, |
| 146 | + Drops: dropCreatorSum, |
| 147 | + } |
| 148 | + break |
| 149 | + } else { |
| 150 | + if (i == len(pool.Leaders)-1) && len(pool.Leaders) < maxLeaders { |
| 151 | + pool.Leaders = append(pool.Leaders, &types.Leader{ |
| 152 | + Address: dropCreator, |
| 153 | + Drops: dropCreatorSum, |
| 154 | + }) |
| 155 | + break |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + } |
| 160 | + return pool |
| 161 | +} |
0 commit comments