-
Notifications
You must be signed in to change notification settings - Fork 1
/
SiennaRewards.ts
134 lines (111 loc) · 3.95 KB
/
SiennaRewards.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
import {
Client,
ClientConsole,
VersionedDeployment,
ViewingKeyClient,
bold,
colors,
linkStruct,
randomBase64,
} from './Core';
import type {
Address,
ClientClass,
Contract,
ContractLink,
Deployment,
Emigration,
Immigration,
IntoLink,
Message,
Snip20,
Uint128,
} from './Core';
import { AuthClient, AuthMethod } from './Auth';
import { LPToken } from './SiennaSwap';
import SiennaTGE from './SiennaTGE';
import type { Rewards_v2 } from './SiennaRewards_v2'
import type { Rewards_v3, Rewards_v3_1 } from './SiennaRewards_v3'
import type { Rewards_v4_1 } from './SiennaRewards_v4'
import { RewardsVersion, RewardsToAMMVersion, AMMVersion } from './Versions'
export default class SiennaRewards extends VersionedDeployment<RewardsVersion> {
tge = new SiennaTGE(this as Deployment)
rewardPools: Contract<Rewards>[] = Object.entries(this.state)
.filter(([name, contract]: [string, unknown])=>name.includes('Rewards'))
.map(([name, contract]: [unknown, Contract<any>])=>contract as Contract<Rewards>)
showStatus = async () => { log.rewardsContracts(this.name, this.state) }
}
/** Universal init parameters for all versions of rewards. */
export interface RewardsInitParams {
rewardToken: IntoLink;
stakedToken: IntoLink;
admin?: Address;
timekeeper?: Address;
authProvider?: IntoLink;
threshold?: number;
cooldown?: number;
bonding?: number;
unbonding?: number;
}
/** A reward pool. */
export abstract class Rewards extends Client {
log = new ClientConsole(this.constructor.name)
/** Rewards v1/v2 with the buggy algo. Counts time in blocks. */
static 'v2': typeof Rewards_v2;
/** Rewards v3 with the fixed algo. Counts time in seconds. */
static 'v3': typeof Rewards_v3;
/** Rewards v3.1 adds depositing using SNIP20 Send instead of IncreaseAllowance+Transfer. */
static 'v3.1': typeof Rewards_v3_1;
/** Rewards v4 adds admin authentication via AuthProvider. */
static 'v4.1': typeof Rewards_v4_1;
/** Get a LPToken interface to the staked token. */
abstract getStakedToken(): Promise<LPToken | null>;
/** Deposit some amount of staked token. */
abstract deposit(amount: Uint128): Promise<unknown>;
/** Try to withdraw some amount of staked token. */
abstract withdraw(amount: Uint128): Promise<unknown>;
/** Try to claim a reward. */
abstract claim(): Promise<unknown>;
get vk (): ViewingKeyClient {
const { address, codeHash } = this
return new ViewingKeyClient(this.agent, address, codeHash)
}
get emigration (): Emigration {
throw new Error('Migration is only available in Rewards >=3');
}
get immigration (): Immigration {
throw new Error('Migration is only available in Rewards >=3');
}
get auth (): AuthClient {
throw new Error('Auth provider is only available in Rewards >=4.1');
}
/** Point this pool to the governance contract that will be using it for voting power. */
async setGovernanceLink<T>(link: ContractLink): Promise<T> {
throw new Error('Governance integration is only available in Rewards >=4.1');
}
}
/** Constructs a reward pool of some version. */
export interface RewardsCtor extends ClientClass<Rewards> {
/** Generate the correct format of Rewards init message for the given version */
init(params: RewardsInitParams): Message;
}
export interface StakingTokens {
stakedToken: Snip20
rewardToken: Snip20
}
const log = new class SiennaRewardsConsole extends ClientConsole {
name = 'Sienna Rewards'
rewardsContracts = (name: string, state: Record<string, any>) => {
const isRewardPool = (x: string) => x.startsWith('SiennaRewards_')
const rewardsContracts = Object.keys(state).filter(isRewardPool)
if (rewardsContracts.length > 0) {
this.info(`\nRewards contracts in ${bold(name)}:`)
for (const name of rewardsContracts) {
this.info(` ${colors.green('✓')} ${name}`)
}
} else {
this.info(`\nNo rewards contracts.`)
}
return rewardsContracts
}
}