Smart Contract

FlowYieldVaultsConnector

A.a092c4aab33daeda.FlowYieldVaultsConnector

Valid From

142,858,733

Deployed

1w ago
Feb 16, 2026, 01:48:31 AM UTC

Dependents

1 imports
1/*
2FlowYieldVaultsConnector - Mainnet FlowYieldVaults Integration
3
4This connector enables PrizeSavings to deposit funds into FlowYieldVaults (yield-bearing strategies)
5and implements DeFiActions.Sink and DeFiActions.Source interfaces.
6
7FlowYieldVaults Contract: mainnet://b1d63873c3cc9f79.FlowYieldVaults
8*/
9
10import FungibleToken from 0xf233dcee88fe0abe
11import FlowYieldVaults from 0xb1d63873c3cc9f79
12import FlowYieldVaultsClosedBeta from 0xb1d63873c3cc9f79
13import DeFiActions from 0x92195d814edf9cb0
14
15access(all) contract FlowYieldVaultsConnector {
16    
17    // Storage paths
18    access(all) let ManagerStoragePath: StoragePath
19    access(all) let ManagerPublicPath: PublicPath
20    
21    // Events
22    access(all) event ConnectorCreated(managerAddress: Address, strategyType: String, vaultType: String)
23    access(all) event DepositedToYieldVault(yieldVaultID: UInt64, amount: UFix64, vaultType: String)
24    access(all) event WithdrawnFromYieldVault(yieldVaultID: UInt64, amount: UFix64, vaultType: String)
25    access(all) event YieldVaultCreated(yieldVaultID: UInt64, strategyType: String, initialAmount: UFix64)
26    
27    /// YieldVaultManagerWrapper Resource
28    /// Wraps FlowYieldVaults.YieldVaultManager with beta badge authentication
29    access(all) resource YieldVaultManagerWrapper {
30        access(self) let yieldVaultManagerCap: Capability<auth(FungibleToken.Withdraw) &FlowYieldVaults.YieldVaultManager>
31        access(self) let betaBadgeCap: Capability<auth(FlowYieldVaultsClosedBeta.Beta) &FlowYieldVaultsClosedBeta.BetaBadge>
32        access(self) var yieldVaultID: UInt64?
33        access(all) let vaultType: Type
34        access(all) let strategyType: Type
35        
36        init(
37            yieldVaultManagerCap: Capability<auth(FungibleToken.Withdraw) &FlowYieldVaults.YieldVaultManager>,
38            betaBadgeCap: Capability<auth(FlowYieldVaultsClosedBeta.Beta) &FlowYieldVaultsClosedBeta.BetaBadge>,
39            vaultType: Type,
40            strategyType: Type
41        ) {
42            pre {
43                yieldVaultManagerCap.check(): "Invalid YieldVaultManager capability"
44                betaBadgeCap.check(): "Invalid Beta badge capability"
45            }
46            
47            self.yieldVaultManagerCap = yieldVaultManagerCap
48            self.betaBadgeCap = betaBadgeCap
49            self.vaultType = vaultType
50            self.strategyType = strategyType
51            self.yieldVaultID = nil
52        }
53        
54        access(all) fun depositToYieldVault(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) {
55            pre {
56                from.getType() == self.vaultType: "Vault type mismatch"
57                from.balance > 0.0: "Cannot deposit zero balance"
58            }
59            
60            let amount = from.balance
61            let yieldVaultManager = self.yieldVaultManagerCap.borrow()
62                ?? panic("Cannot borrow YieldVaultManager")
63            let betaBadge = self.betaBadgeCap.borrow()
64                ?? panic("Cannot borrow Beta badge")
65            
66            // If we don't have a YieldVault yet, create one
67            if self.yieldVaultID == nil {
68                let initialVault <- from.withdraw(amount: amount)
69                
70                let newID = yieldVaultManager.createYieldVault(
71                    betaRef: betaBadge,
72                    strategyType: self.strategyType,
73                    withVault: <- initialVault
74                )
75                
76                self.yieldVaultID = newID
77                
78                emit YieldVaultCreated(
79                    yieldVaultID: self.yieldVaultID!,
80                    strategyType: self.strategyType.identifier,
81                    initialAmount: amount
82                )
83                
84                emit DepositedToYieldVault(
85                    yieldVaultID: self.yieldVaultID!,
86                    amount: amount,
87                    vaultType: self.vaultType.identifier
88                )
89            } else {
90                let depositVault <- from.withdraw(amount: amount)
91                
92                yieldVaultManager.depositToYieldVault(
93                    betaRef: betaBadge,
94                    self.yieldVaultID!,
95                    from: <- depositVault
96                )
97                
98                emit DepositedToYieldVault(
99                    yieldVaultID: self.yieldVaultID!,
100                    amount: amount,
101                    vaultType: self.vaultType.identifier
102                )
103            }
104        }
105        
106        access(all) fun getYieldVaultBalance(): UFix64 {
107            if self.yieldVaultID == nil {
108                return 0.0
109            }
110            
111            let yieldVaultManager = self.yieldVaultManagerCap.borrow()
112                ?? panic("Cannot borrow YieldVaultManager")
113            
114            let yieldVaultRef = yieldVaultManager.borrowYieldVault(id: self.yieldVaultID!)
115            if yieldVaultRef == nil {
116                return 0.0
117            }
118            
119            return yieldVaultRef!.getYieldVaultBalance()
120        }
121        
122        access(all) fun withdrawFromYieldVault(maxAmount: UFix64): @{FungibleToken.Vault} {
123            pre {
124                self.yieldVaultID != nil: "No YieldVault initialized"
125                maxAmount > 0.0: "Cannot withdraw zero amount"
126            }
127            
128            let yieldVaultManager = self.yieldVaultManagerCap.borrow()
129                ?? panic("Cannot borrow YieldVaultManager")
130            
131            let available = self.getYieldVaultBalance()
132            let withdrawAmount = maxAmount < available ? maxAmount : available
133            
134            assert(withdrawAmount > 0.0, message: "Insufficient balance in YieldVault")
135            
136            let vault <- yieldVaultManager.withdrawFromYieldVault(self.yieldVaultID!, amount: withdrawAmount)
137            
138            emit WithdrawnFromYieldVault(
139                yieldVaultID: self.yieldVaultID!,
140                amount: withdrawAmount,
141                vaultType: vault.getType().identifier
142            )
143            
144            return <- vault
145        }
146    }
147    
148    /// Connector Struct
149    /// Implements DeFiActions.Sink and DeFiActions.Source
150    /// References a stored YieldVaultManagerWrapper resource
151    access(all) struct Connector: DeFiActions.Sink, DeFiActions.Source {
152        access(all) let managerAddress: Address
153        access(contract) var uniqueID: DeFiActions.UniqueIdentifier?
154        access(all) let vaultType: Type
155        
156        init(managerAddress: Address, vaultType: Type) {
157            self.managerAddress = managerAddress
158            self.vaultType = vaultType
159            self.uniqueID = nil
160        }
161        
162        /// DeFiActions.Sink Implementation
163        access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) {
164            let managerAccount = getAccount(self.managerAddress)
165            let managerRef = managerAccount.capabilities.borrow<&YieldVaultManagerWrapper>(
166                FlowYieldVaultsConnector.ManagerPublicPath
167            ) ?? panic("Cannot borrow YieldVaultManagerWrapper from address")
168            
169            managerRef.depositToYieldVault(from: from)
170        }
171        
172        access(all) view fun getSinkType(): Type {
173            return self.vaultType
174        }
175        
176        access(all) view fun minimumCapacity(): UFix64 {
177            return 0.0
178        }
179        
180        /// DeFiActions.Source Implementation
181        access(all) fun minimumAvailable(): UFix64 {
182            let managerAccount = getAccount(self.managerAddress)
183            if let managerRef = managerAccount.capabilities.borrow<&YieldVaultManagerWrapper>(
184                FlowYieldVaultsConnector.ManagerPublicPath
185            ) {
186                return managerRef.getYieldVaultBalance()
187            }
188            return 0.0
189        }
190        
191        access(FungibleToken.Withdraw) fun withdrawAvailable(maxAmount: UFix64): @{FungibleToken.Vault} {
192            let managerAccount = getAccount(self.managerAddress)
193            let managerRef = managerAccount.capabilities.borrow<&YieldVaultManagerWrapper>(
194                FlowYieldVaultsConnector.ManagerPublicPath
195            ) ?? panic("Cannot borrow YieldVaultManagerWrapper from address")
196            
197            return <- managerRef.withdrawFromYieldVault(maxAmount: maxAmount)
198        }
199        
200        access(all) view fun getSourceType(): Type {
201            return self.vaultType
202        }
203        
204        /// DeFiActions Component Info
205        access(all) fun getComponentInfo(): DeFiActions.ComponentInfo {
206            return DeFiActions.ComponentInfo(
207                type: self.getType(),
208                id: self.uniqueID?.id,
209                innerComponents: []
210            )
211        }
212        
213        access(contract) view fun copyID(): DeFiActions.UniqueIdentifier? {
214            return self.uniqueID
215        }
216        
217        access(contract) fun setID(_ id: DeFiActions.UniqueIdentifier?) {
218            self.uniqueID = id
219        }
220    }
221    
222    /// Create a new YieldVaultManagerWrapper and store it
223    /// Returns a Connector struct that references it
224    access(all) fun createConnectorAndManager(
225        account: auth(Storage, Capabilities) &Account,
226        yieldVaultManagerCap: Capability<auth(FungibleToken.Withdraw) &FlowYieldVaults.YieldVaultManager>,
227        betaBadgeCap: Capability<auth(FlowYieldVaultsClosedBeta.Beta) &FlowYieldVaultsClosedBeta.BetaBadge>,
228        vaultType: Type,
229        strategyType: Type
230    ): Connector {
231        // Validate that the strategy supports the vault type
232        let supportedVaults = FlowYieldVaults.getSupportedInitializationVaults(forStrategy: strategyType)
233        assert(
234            supportedVaults[vaultType] == true,
235            message: "Strategy does not support vault type"
236        )
237        
238        // Create and store the YieldVaultManagerWrapper resource
239        let manager <- create YieldVaultManagerWrapper(
240            yieldVaultManagerCap: yieldVaultManagerCap,
241            betaBadgeCap: betaBadgeCap,
242            vaultType: vaultType,
243            strategyType: strategyType
244        )
245        
246        account.storage.save(<-manager, to: self.ManagerStoragePath)
247        
248        // Create public capability for the manager
249        let managerCap = account.capabilities.storage.issue<&YieldVaultManagerWrapper>(self.ManagerStoragePath)
250        account.capabilities.publish(managerCap, at: self.ManagerPublicPath)
251        
252        emit ConnectorCreated(
253            managerAddress: account.address,
254            strategyType: strategyType.identifier,
255            vaultType: vaultType.identifier
256        )
257        
258        // Return the struct connector that references this manager
259        return Connector(
260            managerAddress: account.address,
261            vaultType: vaultType
262        )
263    }
264    
265    init() {
266        let identifier = "flowYieldVaultsManager_\(self.account.address)"
267        self.ManagerStoragePath = StoragePath(identifier: identifier)!
268        self.ManagerPublicPath = PublicPath(identifier: identifier)!
269    }
270}
271
272