templar_common/vault/
event.rs

1use super::*;
2
3#[derive(Debug, Clone)]
4#[near(serializers = [borsh, json])]
5pub enum Reason {
6    NoRoom,
7    ZeroTarget,
8    RouteExhaustedNoFunds,
9    Other(String),
10}
11
12#[derive(Debug, Clone)]
13#[near(serializers = [borsh, json])]
14pub enum QueueAction {
15    Dequeued,
16    Parked,
17}
18
19#[derive(Debug, Clone)]
20#[near(serializers = [borsh, json])]
21pub enum QueueStatus {
22    NextFound,
23    Empty,
24}
25
26#[derive(Debug, Clone)]
27#[near(serializers = [borsh, json])]
28pub enum WithdrawProgressPhase {
29    ExecutionStarted,
30    SkippedDust,
31    CoveredByIdle,
32    ExecutionRequired,
33}
34
35#[derive(Debug, Clone)]
36#[near(serializers = [borsh, json])]
37pub enum AllocationPositionIssueKind {
38    Missing,
39    ReadFailed,
40}
41
42#[derive(Debug, Clone)]
43#[near(serializers = [borsh, json])]
44pub enum WithdrawalAccountingKind {
45    InflowMismatch,
46    OverpayCredited,
47}
48
49#[derive(Debug, Clone)]
50#[near(serializers = [borsh, json])]
51pub enum PositionReportOutcome {
52    Ok,
53    Missing,
54    ReadFailed,
55}
56
57#[derive(Debug, Clone)]
58#[near(serializers = [borsh, json])]
59pub enum UnbrickPhase {
60    Withdrawing,
61    Payout,
62}
63
64#[near(event_json(standard = "templar-vault"))]
65pub enum Event {
66    #[event_version("1.0.0")]
67    IdleBalanceUpdated { prev: U128, delta: IdleBalanceDelta },
68    #[event_version("1.0.0")]
69    PerformanceFeeAccrued { recipient: AccountId, shares: U128 },
70    #[event_version("1.0.0")]
71    PerformanceFeeMintFailed { error: String },
72    #[event_version("1.0.0")]
73    ManagementFeeAccrued { recipient: AccountId, shares: U128 },
74    #[event_version("1.0.0")]
75    ManagementFeeMintFailed { error: String },
76    #[event_version("1.0.0")]
77    ManagementFeeSet { fee: U128 },
78    #[event_version("1.0.0")]
79    ManagementFeeRecipientSet { account: AccountId },
80    #[event_version("1.0.0")]
81    LockChange { is_locked: bool, market: MarketId },
82
83    #[event_version("1.0.0")]
84    AllocationPlanSet {
85        op_id: U64,
86        total: U128,
87        plan: Vec<(MarketId, U128)>,
88    },
89    #[event_version("1.0.0")]
90    AllocationStarted { op_id: U64, remaining: U128 },
91    #[event_version("1.0.0")]
92    AllocationStepPlan {
93        op_id: U64,
94        index: u32,
95        market: MarketId,
96        target: U128,
97        room: U128,
98        to_supply: U128,
99        remaining_before: U128,
100        planned: bool,
101        reason: Option<Reason>,
102    },
103    #[event_version("1.0.0")]
104    AllocationTransferFailed {
105        op_id: U64,
106        index: u32,
107        market: MarketId,
108        attempted: U128,
109    },
110    #[event_version("1.0.0")]
111    AllocationStepSettled {
112        op_id: U64,
113        index: u32,
114        market: MarketId,
115        before: U128,
116        new_principal: U128,
117        accepted: U128,
118        attempted: U128,
119        refunded: U128,
120        remaining_after: U128,
121    },
122    #[event_version("1.0.0")]
123    AllocationCompleted { op_id: U64 },
124    #[event_version("1.0.0")]
125    AllocationStopped {
126        op_id: U64,
127        index: u32,
128        remaining: U128,
129        reason: Option<Reason>,
130    },
131
132    #[event_version("1.0.0")]
133    RefreshStarted {
134        op_id: U64,
135        markets: Vec<MarketId>,
136        caller: AccountId,
137    },
138    #[event_version("1.0.0")]
139    RefreshCompleted {
140        op_id: U64,
141        markets: Vec<MarketId>,
142        total_assets: U128,
143        refreshed_at: U64,
144    },
145
146    #[event_version("1.0.0")]
147    CuratorSet { account: AccountId },
148    #[event_version("1.0.0")]
149    GuardianSet { account: AccountId },
150    #[event_version("1.0.0")]
151    SentinelSet { account: AccountId },
152    #[event_version("1.0.0")]
153    AllocatorRoleSet { account: AccountId, allowed: bool },
154    #[event_version("1.0.0")]
155    SkimRecipientSet { account: AccountId },
156    #[event_version("1.0.0")]
157    FeeRecipientSet { account: AccountId },
158    #[event_version("1.0.0")]
159    PerformanceFeeSet { fee: U128 },
160    #[event_version("1.0.0")]
161    MaxTotalAssetsGrowthRateSet { max_rate: Option<U128> },
162    #[event_version("1.0.0")]
163    RestrictionsSet { restrictions: Option<Restrictions> },
164    #[event_version("1.0.0")]
165    TimelockSet { seconds: U64 },
166    #[event_version("1.0.0")]
167    TimelockChangeSubmitted { valid_at_ns: U64 },
168    #[event_version("1.0.0")]
169    FeesChangeSubmitted { fees: Fees<U128>, valid_at_ns: U64 },
170    #[event_version("1.0.0")]
171    FeesChangeRevoked,
172    #[event_version("1.0.0")]
173    RestrictionsChangeSubmitted {
174        restrictions: Option<Restrictions>,
175        valid_at_ns: U64,
176    },
177    #[event_version("1.0.0")]
178    RestrictionsChangeRevoked,
179    #[event_version("1.0.0")]
180    PendingTimelockRevoked,
181
182    #[event_version("1.0.0")]
183    Abdicated { method_name: String },
184
185    #[event_version("1.0.0")]
186    MarketCreated { market: MarketId },
187    #[event_version("1.0.0")]
188    MarketEnabled { market: MarketId },
189    #[event_version("1.0.0")]
190    MarketRemovalSubmitted { market: MarketId, removable_at: U64 },
191    #[event_version("1.0.0")]
192    MarketRemovalRevoked { market: MarketId },
193    #[event_version("1.0.0")]
194    SupplyCapRaiseSubmitted {
195        market: MarketId,
196        new_cap: U128,
197        valid_at_ns: U64,
198    },
199    #[event_version("1.0.0")]
200    SupplyCapRaiseRevoked { market: MarketId },
201    #[event_version("1.0.0")]
202    SupplyCapSet { market: MarketId, new_cap: U128 },
203    #[event_version("1.0.0")]
204    CapGroupRaiseSubmitted {
205        cap_group: CapGroupId,
206        new_cap: U128,
207        valid_at_ns: U64,
208    },
209    #[event_version("1.0.0")]
210    CapGroupRaiseRevoked { cap_group: CapGroupId },
211    #[event_version("1.0.0")]
212    CapGroupSet {
213        cap_group: CapGroupId,
214        new_cap: U128,
215    },
216    #[event_version("1.0.0")]
217    CapGroupRelativeCapRaiseSubmitted {
218        cap_group: CapGroupId,
219        new_relative_cap: U128,
220        valid_at_ns: U64,
221    },
222    #[event_version("1.0.0")]
223    CapGroupRelativeCapRaiseRevoked { cap_group: CapGroupId },
224    #[event_version("1.0.0")]
225    CapGroupRelativeCapSet {
226        cap_group: CapGroupId,
227        new_relative_cap: U128,
228    },
229    #[event_version("1.0.0")]
230    CapGroupPrincipalUpdated {
231        cap_group: CapGroupId,
232        principal: U128,
233    },
234    #[event_version("1.0.0")]
235    CapGroupMembershipSet {
236        market: MarketId,
237        cap_group: Option<CapGroupId>,
238    },
239    #[event_version("1.0.0")]
240    CapGroupMembershipRevoked { market: MarketId },
241
242    #[event_version("1.0.0")]
243    WithdrawQueueUpdate { action: QueueAction, id: U64 },
244    #[event_version("1.0.0")]
245    WithdrawParkedDetail {
246        id: U64,
247        failed_route: Vec<MarketId>,
248        reason: Reason,
249    },
250    #[event_version("1.0.0")]
251    WithdrawQueueStatus {
252        status: QueueStatus,
253        id: Option<U64>,
254    },
255
256    #[event_version("1.0.0")]
257    RebalanceWithdrawCompleted { op_id: U64, market: MarketId },
258    #[event_version("1.0.0")]
259    RebalanceWithdrawStopped {
260        op_id: U64,
261        market: MarketId,
262        reason: Option<Reason>,
263    },
264
265    #[event_version("1.0.0")]
266    RedeemRequested {
267        shares: U128,
268        estimated_assets: U128,
269    },
270    #[event_version("1.0.0")]
271    WithdrawalQueued {
272        id: U64,
273        owner: AccountId,
274        receiver: AccountId,
275        escrow_shares: U128,
276        expected_assets: U128,
277        requested_at: U64,
278    },
279    #[event_version("1.0.0")]
280    WithdrawPreview { shares: U128, receiver: AccountId },
281    #[event_version("1.0.0")]
282    WithdrawProgress {
283        phase: WithdrawProgressPhase,
284        op_id: Option<U64>,
285        id: Option<U64>,
286        market: Option<MarketId>,
287        owner: Option<AccountId>,
288        receiver: Option<AccountId>,
289        escrow_shares: Option<U128>,
290        expected_assets: Option<U128>,
291        requested_at: Option<U64>,
292    },
293    #[event_version("1.0.0")]
294    SupplyWithdrawRequestCreated { market: MarketId, amount: U128 },
295    #[event_version("1.0.0")]
296    WithdrawRequestCreated { market: MarketId, amount: U128 },
297    #[event_version("1.0.0")]
298    AllocationPositionIssue {
299        op_id: U64,
300        index: u32,
301        market: MarketId,
302        attempted: U128,
303        accepted: U128,
304        kind: AllocationPositionIssueKind,
305    },
306
307    #[event_version("1.0.0")]
308    CreateWithdrawalFailed {
309        op_id: U64,
310        market: MarketId,
311        need: U128,
312    },
313
314    #[event_version("1.0.0")]
315    WithdrawalAccounting {
316        kind: WithdrawalAccountingKind,
317        op_id: U64,
318        market: MarketId,
319        delta: Option<U128>,
320        inflow: Option<U128>,
321        extra: Option<U128>,
322    },
323
324    #[event_version("1.0.0")]
325    PayoutUnexpectedState {
326        op_id: U64,
327        receiver: AccountId,
328        amount: U128,
329    },
330    #[event_version("1.0.0")]
331    WithdrawalStopped {
332        op_id: U64,
333        index: u32,
334        remaining: U128,
335        collected: U128,
336        reason: Option<Reason>,
337    },
338    #[event_version("1.0.0")]
339    PayoutStopped {
340        op_id: U64,
341        receiver: AccountId,
342        amount: U128,
343        reason: Option<Reason>,
344    },
345    #[event_version("1.0.0")]
346    OperationStoppedWhileIdle { reason: Option<Reason> },
347    #[event_version("1.0.0")]
348    UnbrickInvoked {
349        phase: UnbrickPhase,
350        op_id: Option<U64>,
351        id: Option<U64>,
352    },
353
354    #[event_version("1.0.0")]
355    WithdrawPositionReport {
356        outcome: PositionReportOutcome,
357        op_id: U64,
358        market: MarketId,
359        position: Option<SupplyPosition>,
360        before: Option<U128>,
361    },
362
363    #[event_version("1.0.0")]
364    VaultBalance { amount: U128 },
365
366    #[event_version("1.0.0")]
367    IdleResyncStarted {
368        op_id: U64,
369        caller: AccountId,
370        before_idle: U128,
371        started_at_ns: U64,
372    },
373    #[event_version("1.0.0")]
374    IdleResyncCompleted {
375        op_id: U64,
376        caller: AccountId,
377        before_idle: U128,
378        actual_idle: U128,
379        after_idle: U128,
380        increased_by: U128,
381        decreased_by: U128,
382        fee_anchor_bump: U128,
383        finished_at_ns: U64,
384    },
385    #[event_version("1.0.0")]
386    IdleResyncStopped {
387        op_id: U64,
388        caller: AccountId,
389        before_idle: U128,
390        reason: Option<Reason>,
391        finished_at_ns: U64,
392    },
393    #[event_version("1.0.0")]
394    IdleResyncCallbackIgnored { op_id: U64, reason: Reason },
395}
396
397#[cfg(test)]
398mod tests {
399    use super::{Event, QueueAction, QueueStatus, Reason, UnbrickPhase};
400    use crate::vault::{IdleBalanceDelta, MarketId};
401    use near_sdk::{json_types::U128, test_utils::VMContextBuilder, testing_env, AccountId};
402
403    #[test]
404    fn helper_enums_keep_expected_debug_labels() {
405        assert_eq!(format!("{:?}", Reason::NoRoom), "NoRoom");
406        assert_eq!(format!("{:?}", QueueAction::Parked), "Parked");
407        assert_eq!(format!("{:?}", QueueStatus::Empty), "Empty");
408        assert_eq!(format!("{:?}", UnbrickPhase::Payout), "Payout");
409    }
410
411    #[test]
412    fn event_variants_can_be_constructed_and_emitted() {
413        testing_env!(VMContextBuilder::new().build());
414
415        Event::LockChange {
416            is_locked: true,
417            market: MarketId(7),
418        }
419        .emit();
420
421        Event::IdleBalanceUpdated {
422            prev: U128(10),
423            delta: IdleBalanceDelta::Increase(U128(5)),
424        }
425        .emit();
426
427        Event::UnbrickInvoked {
428            phase: UnbrickPhase::Withdrawing,
429            op_id: Some(1.into()),
430            id: Some(2.into()),
431        }
432        .emit();
433
434        Event::PayoutStopped {
435            op_id: 1.into(),
436            receiver: "receiver.testnet"
437                .parse::<AccountId>()
438                .expect("valid account id"),
439            amount: U128(33),
440            reason: Some(Reason::Other("stopped".to_string())),
441        }
442        .emit();
443    }
444}