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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#![allow(unexpected_cfgs)]
use anchor_lang::prelude::*;
pub mod state;
pub use state::*;
pub mod utils;
pub use utils::*;
pub mod instructions;
use instructions::*;
declare_id!("HDtNkcgMfN4CARCF4DgFo7BGBqyNjQ6LGNYKwQLkshTR");
#[program]
pub mod multisig {
use super::*;
/// Registers a new token mint that is controlled by the multisig
pub fn add_asset_mint(
ctx: Context<AddAssetMintInstructionAccounts>,
args: AddAssetMintInstructionArgs,
) -> Result<()> {
add_asset_mint_handler(ctx, args)
}
/// Registers a new token account that is controlled by the multisig
pub fn add_asset_token(
ctx: Context<AddAssetTokenInstructionAccounts>,
args: AddAssetTokenInstructionArgs,
) -> Result<()> {
add_asset_token_handler(ctx, args)
}
/// Adds a group member to a group, storing their key and weight
/// and permissions, as well as the group key for indexing.
pub fn add_group_member(
ctx: Context<AddGroupMemberInstructionAccounts>,
args: AddGroupMemberInstructionArgs,
) -> Result<()> {
add_group_member_handler(ctx, args)
}
/// Adds a pre-existing group member to govern an existing asset, storing their key and weight
/// and permissions, as well as the group key and asset key for indexing.
pub fn add_asset_member(
ctx: Context<AddAssetMemberInstructionAccounts>,
args: AddAssetMemberInstructionArgs,
) -> Result<()> {
add_asset_member_handler(ctx, args)
}
/// Updates group-wide configuration (e.g, timelock, thresholds, expiry),
/// it must be triggered by an approved proposal.
pub fn change_group_config(ctx: Context<ChangeGroupConfigInstructionAccounts>) -> Result<()> {
change_group_config_handler(ctx)
}
/// Updates asset-wide configuration (e.g, timelock, thresholds, expiry),
/// it must be triggered by an approved proposal.
pub fn change_asset_config(ctx: Context<ChangeAssetConfigInstructionAccounts>) -> Result<()> {
change_asset_config_handler(ctx)
}
/// Initializes a new governance group account with its initial configuration, seeds,
/// and proposal index tracking as well as other state for maintaining the multisig.
pub fn create_group(
ctx: Context<CreateGroupInstructionAccounts>,
args: CreateGroupInstructionArgs,
) -> Result<()> {
create_group_handler(ctx, args)
}
/// Create a transaction associated with a particular proposal
pub fn create_proposal_transaction(
ctx: Context<CreateProposalTransactionInstructionAccounts>,
args: CreateProposalTransactionInstructionArgs,
) -> Result<()> {
create_proposal_transaction_handler(ctx, args)
}
/// Creates a proposal with a transaction that uses specific assets and requires
/// meeting a quorom for each individual asset.
pub fn create_normal_proposal(
ctx: Context<CreateNormalProposalInstructionAccounts>,
args: CreateNormalProposalInstructionArgs,
) -> Result<()> {
create_normal_proposal_handler(ctx, args)
}
/// Creates a proposal that targets a group or a specific asset and requires
/// meeting a quorom for that group or asset to change it's config
pub fn create_config_proposal(
ctx: Context<CreateConfigProposalInstructionAccounts>,
args: CreateConfigProposalInstructionArgs,
) -> Result<()> {
create_config_proposal_handler(ctx, args)
}
/// Execute a transaction associated with a particular proposal
pub fn execute_proposal_transaction(
ctx: Context<ExecuteProposalTransactionInstructionAccounts>,
) -> Result<()> {
execute_proposal_transaction_handler(ctx)
}
/// Removes an existing group member once a proposal to remove them has passed,
/// closes their GroupMember account and sends the rent to the rent_collector.
pub fn remove_group_member(ctx: Context<RemoveGroupMemberInstructionAccounts>) -> Result<()> {
remove_group_member_handler(ctx)
}
/// Removes an existing asset member once a proposal to remove them has passed,
/// closes their AssetMember account and sends the rent to the rent_collector.
/// It is not checked that they have a corresponding group account since one(AssetMember) could
/// exist without the other(GroupMember).
pub fn remove_asset_member(ctx: Context<RemoveAssetMemberInstructionAccounts>) -> Result<()> {
remove_asset_member_handler(ctx)
}
/// Vote on a proposal that would execute a transaction and uses assets
/// controlled by the multisig if passed.
pub fn vote_on_normal_proposal(
ctx: Context<VoteOnNormalProposalInstructionAccounts>,
args: VoteOnNormalProposalInstructionArgs,
) -> Result<()> {
vote_on_normal_proposal_handler(ctx, args)
}
/// Vote on a proposal that changes the configuration of a group or asset if passed.
pub fn vote_on_config_proposal(
ctx: Context<VoteOnConfigProposalInstructionAccounts>,
args: VoteOnConfigProposalInstructionArgs,
) -> Result<()> {
vote_on_config_proposal_handler(ctx, args)
}
/// Close a proposal transaction that though was finalized after the proposal was passed
/// and active(no config had changed), execution was delayed till after a config changed
/// and refund the rent to the proposal
pub fn close_proposal_transaction_instruction(
ctx: Context<CloseProposalTransactionInstructionAccounts>,
) -> Result<()> {
close_proposal_transaction_handler(ctx)
}
/// Close a config proposal that failed or expired and refund the rent to the proposer
pub fn close_proposal_instruction(
ctx: Context<CloseProposalInstructionAccounts>,
) -> Result<()> {
close_proposal_handler(ctx)
}
/// Close a normal proposal that failed, expired, or became stale and refund the rent to the proposer
pub fn close_normal_proposal_instruction(
ctx: Context<CloseNormalProposalInstructionAccounts>,
) -> Result<()> {
close_normal_proposal_handler(ctx)
}
/// Close an asset member account that has had it's group member account removed(by a proposal)
/// the rent is sent to the rent collector
pub fn clean_up_asset_member_instruction(
ctx: Context<CleanUpAssetMemberInstructionAccounts>,
) -> Result<()> {
clean_up_asset_member_handler(ctx)
}
/// Close a vote record for a normal proposal, the rent is refunded to the voter
pub fn close_normal_vote_record_instruction(
ctx: Context<CloseNormalVoteRecordInstructionAccounts>,
args: CloseNormalVoteRecordInstructionArgs,
) -> Result<()> {
close_normal_vote_record_handler(ctx, args)
}
/// Close a vote record for a config proposal, the rent is refunded to the voter
pub fn close_config_vote_record_instruction(
ctx: Context<CloseConfigVoteRecordInstructionAccounts>,
) -> Result<()> {
close_config_vote_record_handler(ctx)
}
/// Creates an emergency reset proposal with three designated trusted members.
/// If all group members vote For it passes; if all vote Against it fails.
/// No stake checks are bypassed - the proposal simply requires unanimous agreement.
pub fn create_emergency_reset_proposal(
ctx: Context<CreateEmergencyResetProposalAccounts>,
args: CreateEmergencyResetProposalArgs,
) -> Result<()> {
create_emergency_reset_proposal_handler(ctx, args)
}
/// Cast or change a vote on an emergency reset proposal.
pub fn vote_on_emergency_reset_proposal(
ctx: Context<VoteOnEmergencyResetAccounts>,
args: VoteOnEmergencyResetArgs,
) -> Result<()> {
vote_on_emergency_reset_handler(ctx, args)
}
/// Execute a passed emergency reset proposal, pausing the group and
/// storing the three trusted member keys for pause-mode governance.
pub fn execute_emergency_reset(ctx: Context<ExecuteEmergencyResetAccounts>) -> Result<()> {
execute_emergency_reset_handler(ctx)
}
/// Close an emergency reset proposal that has failed or expired, refunding rent.
pub fn close_emergency_reset_proposal(
ctx: Context<CloseEmergencyResetProposalAccounts>,
) -> Result<()> {
close_emergency_reset_proposal_handler(ctx)
}
/// Close a vote record for an emergency reset proposal, refunding rent to the voter.
pub fn close_emergency_reset_vote_record(
ctx: Context<CloseEmergencyResetVoteRecordAccounts>,
) -> Result<()> {
close_emergency_reset_vote_record_handler(ctx)
}
/// Add a group member while the group is in emergency pause mode.
/// Requires all three trusted members to sign.
pub fn add_member_in_reset_mode(
ctx: Context<AddMemberInResetModeAccounts>,
args: AddMemberInResetModeArgs,
) -> Result<()> {
add_member_in_reset_mode_handler(ctx, args)
}
/// Remove a group member while the group is in emergency pause mode.
/// Requires all three trusted members to sign.
pub fn remove_member_in_reset_mode(
ctx: Context<RemoveMemberInResetModeAccounts>,
) -> Result<()> {
remove_member_in_reset_mode_handler(ctx)
}
/// Lift the emergency pause mode, restoring normal group operation.
/// Requires all three trusted members to sign and the group to pass validity checks.
pub fn exit_pause_mode(
ctx: Context<ExitPauseModeAccounts>,
args: ExitPauseModeArgs,
) -> Result<()> {
exit_pause_mode_handler(ctx, args)
}
}