Smart Contract
FlowYieldVaultsScheduler
A.b1d63873c3cc9f79.FlowYieldVaultsScheduler
1// standards
2import FungibleToken from 0xf233dcee88fe0abe
3import FlowToken from 0x1654653399040a61
4// Flow system contracts
5import FlowTransactionScheduler from 0xe467b9dd11fa00df
6// DeFiActions
7import DeFiActions from 0x6d888f175c158410
8// Registry storage (separate contract)
9import FlowYieldVaultsSchedulerRegistry from 0xb1d63873c3cc9f79
10// AutoBalancer management (for detecting stuck yield vaults)
11import FlowYieldVaultsAutoBalancers from 0xb1d63873c3cc9f79
12
13/// THIS CONTRACT HAS BEEN DEPRECATED IN FAVOR OF NEWER SCHEDULER CONTRACTS
14///
15/// FlowYieldVaultsScheduler
16///
17/// This contract provides the Supervisor for recovery of stuck AutoBalancers.
18///
19/// Architecture:
20/// - AutoBalancers are configured with recurringConfig at creation in FlowYieldVaultsStrategies
21/// - AutoBalancers self-schedule subsequent executions via their native mechanism
22/// - FlowYieldVaultsAutoBalancers handles registration with the registry and starts scheduling
23/// - The Supervisor is a recovery mechanism for AutoBalancers that fail to self-schedule
24///
25/// Key Features:
26/// - Supervisor detects stuck yield vaults (failed to self-schedule) and recovers them
27/// - Uses Schedule capability to directly call AutoBalancer.scheduleNextRebalance()
28/// - Query and estimation functions for scripts
29///
30access(all) contract FlowYieldVaultsScheduler {
31
32 /* --- CONSTANTS --- */
33
34 /// Default recurring interval in seconds (used when not specified)
35 access(all) let DEFAULT_RECURRING_INTERVAL: UFix64
36
37 /// Default priority for recurring schedules
38 access(all) let DEFAULT_PRIORITY: UInt8 // 1 = Medium
39
40 /// Default execution effort for scheduled transactions
41 access(all) let DEFAULT_EXECUTION_EFFORT: UInt64
42
43 /// Minimum fee fallback when estimation returns nil
44 access(all) let MIN_FEE_FALLBACK: UFix64
45
46 /// Fee margin multiplier to add buffer to estimated fees (1.2 = 20% buffer)
47 access(all) let FEE_MARGIN_MULTIPLIER: UFix64
48
49 /// Default lookahead seconds for scheduling first execution
50 access(all) let DEFAULT_LOOKAHEAD_SECS: UFix64
51
52 /* --- PATHS --- */
53
54 /// Storage path for the Supervisor resource
55 access(all) let SupervisorStoragePath: StoragePath
56
57 /* --- EVENTS --- */
58
59 /// Emitted when the Supervisor successfully recovers a stuck yield vault
60 access(all) event YieldVaultRecovered(
61 yieldVaultID: UInt64
62 )
63
64 /// Emitted when Supervisor fails to recover a yield vault
65 access(all) event YieldVaultRecoveryFailed(
66 yieldVaultID: UInt64,
67 error: String
68 )
69
70 /// Emitted when Supervisor detects a stuck yield vault via state-based scanning
71 access(all) event StuckYieldVaultDetected(
72 yieldVaultID: UInt64
73 )
74
75 /// Emitted when Supervisor self-reschedules
76 access(all) event SupervisorRescheduled(
77 scheduledTransactionID: UInt64,
78 timestamp: UFix64
79 )
80
81 /* --- RESOURCES --- */
82
83 /// Supervisor - The recovery mechanism for stuck AutoBalancers
84 ///
85 /// The Supervisor:
86 /// - Detects stuck yield vaults (AutoBalancers that failed to self-schedule)
87 /// - Recovers stuck yield vaults by directly calling scheduleNextRebalance() via Schedule capability
88 /// - Can self-reschedule for perpetual operation
89 ///
90 /// Primary scheduling is done by AutoBalancers themselves via their native recurringConfig.
91 /// The Supervisor is only for recovery when that fails.
92 ///
93 access(all) resource Supervisor: FlowTransactionScheduler.TransactionHandler {
94 /// Capability to withdraw FLOW for Supervisor's own scheduling fees
95 access(self) let feesCap: Capability<auth(FungibleToken.Withdraw) &FlowToken.Vault>
96
97 init(
98 feesCap: Capability<auth(FungibleToken.Withdraw) &FlowToken.Vault>
99 ) {
100 self.feesCap = feesCap
101 }
102
103 /* --- TRANSACTION HANDLER --- */
104
105 /// Detects and recovers stuck yield vaults by directly calling their scheduleNextRebalance().
106 ///
107 /// Detection methods:
108 /// 1. State-based: Scans for registered yield vaults with no active schedule that are overdue
109 ///
110 /// Recovery method:
111 /// - Uses Schedule capability to call AutoBalancer.scheduleNextRebalance() directly
112 /// - The AutoBalancer schedules itself using its own fee source
113 /// - This is simpler than the previous approach of Supervisor scheduling on behalf of AutoBalancer
114 ///
115 /// data accepts optional config:
116 /// {
117 /// "priority": UInt8 (0=High,1=Medium,2=Low) - for Supervisor self-rescheduling
118 /// "executionEffort": UInt64 - for Supervisor self-rescheduling
119 /// "recurringInterval": UFix64 (for Supervisor self-rescheduling)
120 /// "scanForStuck": Bool (default true - scan all registered yield vaults for stuck ones)
121 /// }
122 access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) {}
123 }
124
125 /* --- PRIVATE FUNCTIONS (access(self)) --- */
126
127 /// Creates a Supervisor handler.
128 access(self) fun createSupervisor(): @Supervisor {
129 panic("Invalid call: FlowYieldVaultsScheduler has been tombstoned")
130 }
131
132 /* --- PUBLIC FUNCTIONS (access(all)) --- */
133
134 /// Estimates the cost of scheduling a transaction at a given timestamp
135 access(all) fun estimateSchedulingCost(
136 timestamp: UFix64,
137 priority: FlowTransactionScheduler.Priority,
138 executionEffort: UInt64
139 ): FlowTransactionScheduler.EstimatedScheduledTransaction {
140 panic("Invalid call: FlowYieldVaultsScheduler has been tombstoned")
141 }
142
143 /* --- ACCOUNT FUNCTIONS --- */
144
145 /// Ensures the Supervisor is configured and registered.
146 /// Creates Supervisor if not exists, issues capability, and registers with Registry.
147 /// Note: This is access(all) because the Supervisor is owned by the contract account
148 /// and uses contract account funds. The function is idempotent and safe to call multiple times.
149 access(all) fun ensureSupervisorConfigured() {
150 panic("Invalid call: FlowYieldVaultsScheduler has been tombstoned")
151 }
152
153 /// Borrows the Supervisor reference (account-restricted for internal use)
154 access(account) fun borrowSupervisor(): &Supervisor? {
155 panic("Invalid call: FlowYieldVaultsScheduler has been tombstoned")
156 }
157
158 /// Manually enqueues a registered yield vault to the pending queue for recovery.
159 /// This allows manual triggering of recovery for a specific yield vault.
160 ///
161 /// @param yieldVaultID: The ID of the registered yield vault to enqueue
162 ///
163 access(account) fun enqueuePendingYieldVault(yieldVaultID: UInt64) {
164 panic("Invalid call: FlowYieldVaultsScheduler has been tombstoned")
165 }
166
167 init() {
168 // Initialize constants
169 self.DEFAULT_RECURRING_INTERVAL = 60.0 // 60 seconds
170 self.DEFAULT_PRIORITY = 1 // Medium
171 self.DEFAULT_EXECUTION_EFFORT = 800
172 self.MIN_FEE_FALLBACK = 0.00005
173 self.FEE_MARGIN_MULTIPLIER = 1.2
174 self.DEFAULT_LOOKAHEAD_SECS = 10.0
175
176 // Initialize paths
177 self.SupervisorStoragePath = /storage/FlowYieldVaultsSupervisor
178 }
179}
180