-
Notifications
You must be signed in to change notification settings - Fork 44
/
pool.go
162 lines (131 loc) · 4.41 KB
/
pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package keeper
import (
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/amm/types"
)
// SetPool set a specific pool in the store from its index
func (k Keeper) SetPool(ctx sdk.Context, pool types.Pool) error {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PoolKeyPrefix))
b := k.cdc.MustMarshal(&pool)
store.Set(types.PoolKey(pool.PoolId), b)
return nil
}
// GetPool returns a pool from its index
func (k Keeper) GetPool(ctx sdk.Context, poolId uint64) (val types.Pool, found bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PoolKeyPrefix))
b := store.Get(types.PoolKey(poolId))
if b == nil {
return val, false
}
k.cdc.MustUnmarshal(b, &val)
return val, true
}
// RemovePool removes a pool from the store
func (k Keeper) RemovePool(ctx sdk.Context, poolId uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PoolKeyPrefix))
store.Delete(types.PoolKey(poolId))
}
// GetAllPool returns all pool
func (k Keeper) GetAllPool(ctx sdk.Context) (list []types.Pool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PoolKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.Pool
k.cdc.MustUnmarshal(iterator.Value(), &val)
list = append(list, val)
}
return
}
// GetLatestPool retrieves the latest pool item from the list of pools
func (k Keeper) GetLatestPool(ctx sdk.Context) (val types.Pool, found bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PoolKeyPrefix))
iterator := sdk.KVStoreReversePrefixIterator(store, []byte{})
defer iterator.Close()
if !iterator.Valid() {
return val, false
}
k.cdc.MustUnmarshal(iterator.Value(), &val)
return val, true
}
// GetNextPoolId returns the next pool id.
func (k Keeper) GetNextPoolId(ctx sdk.Context) uint64 {
latestPool, found := k.GetLatestPool(ctx)
if !found {
return 1
}
return latestPool.PoolId + 1
}
// PoolExists checks if a pool with the given poolId exists in the list of pools
func (k Keeper) PoolExists(ctx sdk.Context, poolId uint64) bool {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PoolKeyPrefix))
b := store.Get(types.PoolKey(poolId))
return b != nil
}
// GetBestPoolWithDenoms returns the first pool id that contains all specified denominations
func (k Keeper) GetBestPoolWithDenoms(ctx sdk.Context, denoms []string) (pool types.Pool, found bool) {
// Get all pools
pools := k.GetAllPool(ctx)
maxTvl := sdk.NewDec(-1)
bestPool := types.Pool{}
for _, p := range pools {
// If the number of assets in the pool is less than the number of denoms, skip
if len(p.PoolAssets) < len(denoms) {
continue
}
allDenomsFound := true
// Check that all denoms are in the pool's assets
for _, denom := range denoms {
denomFound := false
for _, asset := range p.PoolAssets {
if denom == asset.Token.Denom {
denomFound = true
break
}
}
// If any denom is not found, mark allDenomsFound as false and break
if !denomFound {
allDenomsFound = false
break
}
}
poolTvl, err := p.TVL(ctx, k.oracleKeeper)
if err != nil {
poolTvl = sdk.ZeroDec()
}
// If all denoms are found in this pool, return the pool id
if allDenomsFound && maxTvl.LT(poolTvl) {
maxTvl = poolTvl
bestPool = p
}
}
return bestPool, !maxTvl.IsNegative()
}
// IterateLiquidty iterates over all LiquidityPools and performs a
// callback.
func (k Keeper) IterateLiquidityPools(ctx sdk.Context, handlerFn func(pool types.Pool) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PoolKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var pool types.Pool
k.cdc.MustUnmarshal(iterator.Value(), &pool)
if handlerFn(pool) {
break
}
}
return
}
// GetPoolSnapshotOrSet returns a pool snapshot or set the snapshot
func (k Keeper) GetPoolSnapshotOrSet(ctx sdk.Context, pool types.Pool) (val types.Pool) {
store := prefix.NewStore(ctx.KVStore(k.transientStoreKey), types.KeyPrefix(types.PoolKeyPrefix))
b := store.Get(types.PoolKey(pool.PoolId))
if b == nil {
b := k.cdc.MustMarshal(&pool)
store.Set(types.PoolKey(pool.PoolId), b)
return pool
}
k.cdc.MustUnmarshal(b, &val)
return val
}