DeploySEALED

░@╱~╱%□╲!%◆◇○■●○▓▓*▪╲◆~▒░▒▓▒◆@&●░╳□■~?!#^●▒*▫●█^○!%*██%?░#▒░%$!&

Transaction ID

Timestamp

Jan 09, 2026, 07:55:49 PM UTC
1mo ago

Block Height

138,375,759

Computation

0

Execution Fee

0.00438 FLOW

Transaction Summary

Deploy

Contract deployment

Contract deployment

Script Arguments

0nameString
TestHelpers
1codeString
import FungibleToken from 0xf233dcee88fe0abe import DeFiActions from 0x92195d814edf9cb0 /// TestHelpers - Production-Safe Vault Connector for Testing /// /// This contract provides secure mock implementations of DeFiActions interfaces /// for testing purposes. It follows the same security pattern as FlowYieldVaultsConnector. /// /// SECURITY MODEL: /// - Vault capabilities are stored in a Resource (VaultManager), NOT in structs /// - Resources cannot be copied, protecting the underlying vault capabilities /// - The Connector struct only holds a capability to the VaultManager resource /// - Only the VaultManager owner (account) can create Connectors /// - Public interface only exposes safe operations (deposit, balance check) /// - Withdraw operations require entitled capability that can be revoked /// - All operations emit events for transparency and monitoring /// /// USAGE: /// 1. Call createVaultManagerAndConnector() with your account to set up the manager /// 2. Use the returned VaultConnector with PrizeSavings /// 3. Fund the manager's underlying vault for testing /// /// NOTE: While this is production-safe, it should primarily be used for testing. /// For production yield sources, use proper DeFi integrations like FlowYieldVaultsConnector. /// access(all) contract TestHelpers { // Entitlement for withdraw operations - only entitled references can withdraw access(all) entitlement Withdraw // Storage paths access(all) let VaultManagerStoragePath: StoragePath access(all) let VaultManagerPublicPath: PublicPath // Events for transparency and monitoring access(all) event VaultManagerCreated(ownerAddress: Address, vaultType: String) access(all) event ConnectorCreated(managerAddress: Address, vaultType: String) access(all) event DepositedToManager(managerAddress: Address, amount: UFix64, vaultType: String) access(all) event WithdrawnFromManager(managerAddress: Address, amount: UFix64, vaultType: String) /// Public interface - exposes only safe operations /// Anyone can deposit funds and check balance, but cannot withdraw access(all) resource interface VaultManagerPublic { access(all) view fun getBalance(): UFix64 access(all) view fun getVaultType(): Type access(all) fun deposit(from: @{FungibleToken.Vault}) } /// VaultManager Resource /// /// SECURITY: This resource holds the sensitive vault capabilities. /// Resources cannot be copied, so the capabilities are protected. /// Only entitled references can call withdrawFunds. /// access(all) resource VaultManager: VaultManagerPublic { /// Private: Vault provider capability - can withdraw funds access(self) let providerCap: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider, FungibleToken.Balance}> /// Private: Vault receiver capability - can receive deposits access(self) let receiverCap: Capability<&{FungibleToken.Receiver}> /// Public: Vault type for type checking access(all) let vaultType: Type /// Public: Owner address for monitoring access(all) let ownerAddress: Address init( providerCap: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider, FungibleToken.Balance}>, receiverCap: Capability<&{FungibleToken.Receiver}>, vaultType: Type, ownerAddress: Address ) { pre { providerCap.check(): "Invalid provider capability" receiverCap.check(): "Invalid receiver capability" } self.providerCap = providerCap self.receiverCap = receiverCap self.vaultType = vaultType self.ownerAddress = ownerAddress } /// Get current balance - SAFE: read-only operation access(all) view fun getBalance(): UFix64 { if let provider = self.providerCap.borrow() { return provider.balance } return 0.0 } /// Get vault type - SAFE: read-only operation access(all) view fun getVaultType(): Type { return self.vaultType } /// Deposit funds - SAFE: adding funds doesn't risk existing funds access(all) fun deposit(from: @{FungibleToken.Vault}) { pre { from.getType() == self.vaultType: "Vault type mismatch: expected ".concat(self.vaultType.identifier) } let amount = from.balance let receiver = self.receiverCap.borrow() ?? panic("Cannot borrow receiver capability") receiver.deposit(from: <- from) emit DepositedToManager( managerAddress: self.ownerAddress, amount: amount, vaultType: self.vaultType.identifier ) } /// Withdraw funds - PROTECTED: requires Withdraw entitlement /// Only callable through an entitled reference, which can only be issued /// by the account that stores this resource. access(Withdraw) fun withdrawFunds(maxAmount: UFix64): @{FungibleToken.Vault} { let provider = self.providerCap.borrow() ?? panic("Cannot borrow provider capability") let available = provider.balance let toWithdraw = maxAmount < available ? maxAmount : available if toWithdraw == 0.0 { // Return empty vault of correct type return <- provider.withdraw(amount: 0.0) } let vault <- provider.withdraw(amount: toWithdraw) emit WithdrawnFromManager( managerAddress: self.ownerAddress, amount: toWithdraw, vaultType: self.vaultType.identifier ) return <- vault } } /// VaultConnector Struct /// /// Implements DeFiActions.Sink and DeFiActions.Source for use with PrizeSavings. /// /// SECURITY: /// - Only holds a capability to VaultManager, NOT the raw vault capability /// - Deposit uses public capability (safe - anyone can deposit) /// - Withdraw uses entitled capability (protected - requires Withdraw entitlement) /// - The entitled capability can only be issued by the VaultManager owner /// access(all) struct VaultConnector: DeFiActions.Sink, DeFiActions.Source { /// Address of the account that owns the VaultManager resource access(all) let managerAddress: Address /// Entitled capability to VaultManager for withdraw operations /// This can only be issued by the account that stores the VaultManager access(self) let withdrawCap: Capability<auth(Withdraw) &VaultManager> /// Vault type for interface compliance access(all) let vaultType: Type /// DeFiActions unique ID access(contract) var uniqueID: DeFiActions.UniqueIdentifier? init( managerAddress: Address, withdrawCap: Capability<auth(Withdraw) &VaultManager>, vaultType: Type ) { pre { withdrawCap.check(): "Invalid withdraw capability" } self.managerAddress = managerAddress self.withdrawCap = withdrawCap self.vaultType = vaultType self.uniqueID = nil } // ============================================================ // DeFiActions.Sink Implementation // ============================================================ /// Deposit funds into the managed vault /// Uses PUBLIC capability - safe operation access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) { let managerAccount = getAccount(self.managerAddress) let managerRef = managerAccount.capabilities.borrow<&{VaultManagerPublic}>( TestHelpers.VaultManagerPublicPath ) ?? panic("Cannot borrow VaultManager from ".concat(self.managerAddress.toString())) let amount = from.balance managerRef.deposit(from: <- from.withdraw(amount: amount)) } access(all) view fun getSinkType(): Type { return self.vaultType } access(all) view fun minimumCapacity(): UFix64 { return 0.0 } // ============================================================ // DeFiActions.Source Implementation // ============================================================ /// Get available balance /// Uses PUBLIC capability - safe read-only operation access(all) view fun minimumAvailable(): UFix64 { let managerAccount = getAccount(self.managerAddress) if let managerRef = managerAccount.capabilities.borrow<&{VaultManagerPublic}>( TestHelpers.VaultManagerPublicPath ) { return managerRef.getBalance() } return 0.0 } /// Withdraw funds from the managed vault /// Uses ENTITLED capability - protected operation access(FungibleToken.Withdraw) fun withdrawAvailable(maxAmount: UFix64): @{FungibleToken.Vault} { let managerRef = self.withdrawCap.borrow() ?? panic("Cannot borrow VaultManager with Withdraw entitlement. Capability may have been revoked.") return <- managerRef.withdrawFunds(maxAmount: maxAmount) } access(all) view fun getSourceType(): Type { return self.vaultType } // ============================================================ // DeFiActions Component Interface // ============================================================ access(all) fun getComponentInfo(): DeFiActions.ComponentInfo { return DeFiActions.ComponentInfo( type: self.getType(), id: self.uniqueID?.id, innerComponents: [] ) } access(contract) view fun copyID(): DeFiActions.UniqueIdentifier? { return self.uniqueID } access(contract) fun setID(_ id: DeFiActions.UniqueIdentifier?) { self.uniqueID = id } } // ============================================================ // Factory Functions // ============================================================ /// Create a VaultManager resource and store it in the caller's account. /// Returns a VaultConnector that can be used with PrizeSavings. /// /// SECURITY: This function requires auth(Storage, Capabilities) which means /// only the account owner can call it through a transaction they sign. /// /// @param account: The account to store the VaultManager in (must be signer) /// @param providerCap: Capability to withdraw from the vault (will be protected) /// @param receiverCap: Capability to deposit into the vault /// @param vaultType: Type of the fungible token vault /// @return VaultConnector struct for use with PrizeSavings /// access(all) fun createVaultManagerAndConnector( account: auth(Storage, Capabilities) &Account, providerCap: Capability<auth(FungibleToken.Withdraw) &{FungibleToken.Provider, FungibleToken.Balance}>, receiverCap: Capability<&{FungibleToken.Receiver}>, vaultType: Type ): VaultConnector { pre { providerCap.check(): "Invalid provider capability" receiverCap.check(): "Invalid receiver capability" account.storage.borrow<&VaultManager>(from: self.VaultManagerStoragePath) == nil: "VaultManager already exists at this storage path" } // Create and store the VaultManager resource let manager <- create VaultManager( providerCap: providerCap, receiverCap: receiverCap, vaultType: vaultType, ownerAddress: account.address ) account.storage.save(<-manager, to: self.VaultManagerStoragePath) // Issue and publish PUBLIC capability (deposit and balance only) let publicCap = account.capabilities.storage.issue<&{VaultManagerPublic}>( self.VaultManagerStoragePath ) account.capabilities.publish(publicCap, at: self.VaultManagerPublicPath) // Issue ENTITLED capability for withdrawals (NOT published publicly) // This capability is stored in the returned connector let withdrawCap = account.capabilities.storage.issue<auth(Withdraw) &VaultManager>( self.VaultManagerStoragePath ) emit VaultManagerCreated( ownerAddress: account.address, vaultType: vaultType.identifier ) emit ConnectorCreated( managerAddress: account.address, vaultType: vaultType.identifier ) return VaultConnector( managerAddress: account.address, withdrawCap: withdrawCap, vaultType: vaultType ) } /// Create an additional connector for an existing VaultManager. /// Useful if you need to use the same vault for multiple pools. /// /// SECURITY: Requires auth(Capabilities) - only account owner can create connectors /// access(all) fun createAdditionalConnector( account: auth(Capabilities) &Account ): VaultConnector { // Verify the account has a VaultManager by borrowing public capability let publicCap = account.capabilities.get<&{VaultManagerPublic}>(self.VaultManagerPublicPath) let managerRef = publicCap.borrow() ?? panic("No VaultManager found. Call createVaultManagerAndConnector first.") let vaultType = managerRef.getVaultType() // Issue a new entitled capability for this connector let withdrawCap = account.capabilities.storage.issue<auth(Withdraw) &VaultManager>( self.VaultManagerStoragePath ) emit ConnectorCreated( managerAddress: account.address, vaultType: vaultType.identifier ) return VaultConnector( managerAddress: account.address, withdrawCap: withdrawCap, vaultType: vaultType ) } // ============================================================ // Contract Initialization // ============================================================ init() { // Use contract address in path identifier for uniqueness let identifier = "testHelpersVaultManager_".concat(self.account.address.toString()) self.VaultManagerStoragePath = StoragePath(identifier: identifier)! self.VaultManagerPublicPath = PublicPath(identifier: identifier)! } }

Cadence Script

1transaction(name: String, code: String ) {
2		prepare(signer: auth(AddContract) &Account) {
3			signer.contracts.add(name: name, code: code.utf8 )
4		}
5	}