-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathVesting.ts
185 lines (161 loc) · 4.66 KB
/
Vesting.ts
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
import {
Address,
Client,
CodeHash,
Duration,
Uint128,
Snip20
} from './Core'
/** A MGMT vesting contract of either version. */
export abstract class MGMT extends Client {
/** See the full schedule */
schedule () {
return this.query({ schedule: {} })
}
/** Load a schedule */
configure (schedule: any) {
return this.execute({ configure: { schedule } })
}
/** Add a new account to a pool */
add (pool_name: any, account: any) {
return this.execute({ add_account: { pool_name, account } })
}
/** Launch the vesting */
launch () {
return this.execute({ launch: {} })
}
/** Claim accumulated portions */
claim () {
return this.execute({ claim: {} })
}
/** take over a SNIP20 token */
async acquire (token: Snip20) {
const tx1 = await token.setMinters([this.address!])
const tx2 = await token.changeAdmin(this.address!)
return [tx1, tx2]
}
/** Check how much is claimable by someone at a certain time */
async progress (address: Address, time = +new Date()): Promise<VestingProgress> {
time = Math.floor(time / 1000) // JS msec -> CosmWasm seconds
const { progress }: { progress: VestingProgress } =
await this.query({ progress: { address, time } })
return progress
}
}
/** A MGMT schedule. */
export interface VestingSchedule {
total: Uint128
pools: Array<VestingPool>
}
export interface VestingPool {
name: string
total: Uint128
partial: boolean
accounts: Array<VestingAccount>
}
export interface VestingAccount {
name: string
amount: Uint128
address: Address
start_at: Duration
interval: Duration
duration: Duration
cliff: Uint128
portion_size: Uint128
remainder: Uint128
}
export interface VestingProgress {
time: number
launcher: number
elapsed: number
unlocked: string
claimed: string
}
/** A RPT (redistribution) contract of each version. */
export abstract class RPT extends Client {
/** Claim from mgmt and distribute to recipients. Anyone can call this method as:
* - the recipients can only be changed by the admin
* - the amount is determined by MGMT */
vest() {
return this.execute({ vest: {} })
}
}
export type RPTRecipient = string
export type RPTAmount = string
export type RPTConfig = [RPTRecipient, RPTAmount][]
export type RPTStatus = unknown
export interface PFRConfig {
name: string
rewards: {
name: string
address: Address
codeHash: Address
decimals: number
timekeeper: Address
}
lp: {
name: string
address: Address
codeHash: CodeHash
}
schedule: VestingSchedule
account: VestingAccount
}
export function findInSchedule (
schedule: VestingSchedule|undefined,
pool: string,
account: string
): VestingAccount|undefined {
if (!schedule) throw new Error('No schedule.')
return schedule.pools
.filter((x: VestingPool)=>x.name===pool)[0]?.accounts
.filter((x: VestingAccount)=>x.name===account)[0]
}
/** The **RPT account** (Remaining Pool Tokens) is a special entry
* in MGMT's vesting schedule; its funds are vested to **the RPT contract's address**,
* and the RPT contract uses them to fund the Reward pools.
* However, the RPT address is only available after deploying the RPT contract,
* which in turn nees MGMT's address, therefore establishing a
* circular dependency. To resolve it, the RPT account in the schedule
* is briefly mutated to point to the deployer's address (before any funds are vested). */
export const rptAccountName = 'RPT'
/** The **LPF account** (Liquidity Provision Fund) is an entry in MGMT's vesting schedule
* which is vested immediately in full. On devnet and testnet, this can be used
* to provide funding for tester accounts. In practice, testers are funded with an extra
* mint operation in `deployTGE`. */
export const lpfAccountName = 'LPF'
export const mintingPoolName = 'MintingPool'
export const emptySchedule = (address: Address) => ({
total: "0",
pools: [
{
name: mintingPoolName,
total: "0",
partial: false,
accounts: [
{
name: lpfAccountName,
amount: "0",
address,
start_at: 0,
interval: 0,
duration: 0,
cliff: "0",
portion_size: "0",
remainder: "0"
},
{
name: rptAccountName,
amount: "0",
address,
start_at: 0,
interval: 0,
duration: 0,
cliff: "0",
portion_size: "0",
remainder: "0"
}
]
}
]
})