-
Notifications
You must be signed in to change notification settings - Fork 5
/
stake.go
103 lines (91 loc) · 2.04 KB
/
stake.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
package types
import (
"fmt"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
dextypes "github.com/duality-labs/duality/x/dex/types"
)
// NewStake returns a new instance of period stake.
func NewStake(id uint64, owner sdk.AccAddress, coins sdk.Coins, startTime time.Time) *Stake {
coins = coins.Sort()
return &Stake{
ID: id,
Owner: owner.String(),
Coins: coins,
StartTime: startTime,
}
}
// OwnerAddress returns stakes owner address.
func (p Stake) OwnerAddress() sdk.AccAddress {
addr, err := sdk.AccAddressFromBech32(p.Owner)
if err != nil {
panic(err)
}
return addr
}
func (p Stake) SingleCoin() (sdk.Coin, error) {
if len(p.Coins) != 1 {
return sdk.Coin{}, fmt.Errorf("Stake %d has no single coin: %s", p.ID, p.Coins)
}
return p.Coins[0], nil
}
func (p Stake) ValidateBasic() error {
for _, coin := range p.Coins {
_, err := dextypes.NewDepositDenomFromString(coin.Denom)
if err != nil {
return err
}
}
return nil
}
func (p Stake) CoinsPassingQueryCondition(distrTo QueryCondition) sdk.Coins {
coins := p.Coins
switch len(p.Coins) {
case 0:
return nil
case 1:
coin := coins[0]
if !distrTo.Test(coin.Denom) {
return nil
}
return sdk.Coins{coin}
default:
// Binary search the amount of coins remaining
result := sdk.NewCoins()
denomPrefix := dextypes.DepositDenomPairIDPrefix(distrTo.PairID.Token0, distrTo.PairID.Token1)
low := 0
high := len(coins)
for low < high {
mid := low + ((high - low) / 2)
coin := coins[mid]
switch {
case distrTo.Test(coin.Denom):
result = result.Add(coin)
midLeft := mid - 1
for 0 <= midLeft {
coin = coins[midLeft]
if !distrTo.Test(coin.Denom) {
break
}
result = result.Add(coin)
midLeft--
}
midRight := mid + 1
for midRight < len(coins) {
coin = coins[midRight]
if !distrTo.Test(coin.Denom) {
break
}
result = result.Add(coin)
midRight++
}
return result
case denomPrefix < coin.Denom:
high = mid
default:
low = mid
}
}
return nil
}
}