From 63dcad8189413fa200acefc506a09bde85aed279 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Thu, 15 Jan 2026 21:32:11 -0500 Subject: [PATCH 1/2] pyusd strategy --- .../FlowYieldVaultsStrategiesV1_1.cdc | 86 +++++++++++++++++-- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/cadence/contracts/FlowYieldVaultsStrategiesV1_1.cdc b/cadence/contracts/FlowYieldVaultsStrategiesV1_1.cdc index 7cfe055..231f9a5 100644 --- a/cadence/contracts/FlowYieldVaultsStrategiesV1_1.cdc +++ b/cadence/contracts/FlowYieldVaultsStrategiesV1_1.cdc @@ -131,6 +131,65 @@ access(all) contract FlowYieldVaultsStrategiesV1_1 { } } + access(all) resource FUSDEVStrategy : FlowYieldVaults.Strategy, DeFiActions.IdentifiableResource { + /// An optional identifier allowing protocols to identify stacked connector operations by defining a protocol- + /// specific Identifier to associated connectors on construction + access(contract) var uniqueID: DeFiActions.UniqueIdentifier? + access(self) let position: FlowCreditMarket.Position + access(self) var sink: {DeFiActions.Sink} + access(self) var source: {DeFiActions.Source} + + init(id: DeFiActions.UniqueIdentifier, collateralType: Type, position: FlowCreditMarket.Position) { + self.uniqueID = id + self.position = position + self.sink = position.createSink(type: collateralType) + self.source = position.createSourceWithOptions(type: collateralType, pullFromTopUpSource: true) + } + + // Inherited from FlowYieldVaults.Strategy default implementation + // access(all) view fun isSupportedCollateralType(_ type: Type): Bool + + access(all) view fun getSupportedCollateralTypes(): {Type: Bool} { + return { self.sink.getSinkType(): true } + } + /// Returns the amount available for withdrawal via the inner Source + access(all) fun availableBalance(ofToken: Type): UFix64 { + return ofToken == self.source.getSourceType() ? self.source.minimumAvailable() : 0.0 + } + /// Deposits up to the inner Sink's capacity from the provided authorized Vault reference + access(all) fun deposit(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) { + self.sink.depositCapacity(from: from) + } + /// Withdraws up to the max amount, returning the withdrawn Vault. If the requested token type is unsupported, + /// an empty Vault is returned. + access(FungibleToken.Withdraw) fun withdraw(maxAmount: UFix64, ofToken: Type): @{FungibleToken.Vault} { + if ofToken != self.source.getSourceType() { + return <- DeFiActionsUtils.getEmptyVault(ofToken) + } + return <- self.source.withdrawAvailable(maxAmount: maxAmount) + } + /// Executed when a Strategy is burned, cleaning up the Strategy's stored AutoBalancer + access(contract) fun burnCallback() { + FlowYieldVaultsAutoBalancers._cleanupAutoBalancer(id: self.id()!) + } + access(all) fun getComponentInfo(): DeFiActions.ComponentInfo { + return DeFiActions.ComponentInfo( + type: self.getType(), + id: self.id(), + innerComponents: [ + self.sink.getComponentInfo(), + self.source.getComponentInfo() + ] + ) + } + access(contract) view fun copyID(): DeFiActions.UniqueIdentifier? { + return self.uniqueID + } + access(contract) fun setID(_ id: DeFiActions.UniqueIdentifier?) { + self.uniqueID = id + } + } + access(all) struct TokenBundle { access(all) let moetTokenType: Type access(all) let moetTokenEVMAddress: EVM.EVMAddress @@ -306,11 +365,22 @@ access(all) contract FlowYieldVaultsStrategiesV1_1 { // Set AutoBalancer sink for overflow -> recollateralize balancerIO.autoBalancer.setSink(positionSwapSink, updateSinkID: true) - return <-create FlowYieldVaultsStrategiesV1_1.mUSDFStrategy( - id: uniqueID, - collateralType: collateralType, - position: position - ) + switch type { + case Type<@mUSDFStrategy>(): + return <-create mUSDFStrategy( + id: uniqueID, + collateralType: collateralType, + position: position + ) + case Type<@FUSDEVStrategy>(): + return <-create FUSDEVStrategy( + id: uniqueID, + collateralType: collateralType, + position: position + ) + default: + panic("Unsupported strategy type \(type.identifier)") + } } /* =========================== @@ -671,7 +741,8 @@ access(all) contract FlowYieldVaultsStrategiesV1_1 { access(Configure) fun purgeConfig() { self.configs = { Type<@mUSDFStrategyComposer>(): { - Type<@mUSDFStrategy>(): {} as {Type: FlowYieldVaultsStrategiesV1_1.CollateralConfig} + Type<@mUSDFStrategy>(): {} as {Type: FlowYieldVaultsStrategiesV1_1.CollateralConfig}, + Type<@FUSDEVStrategy>(): {} as {Type: FlowYieldVaultsStrategiesV1_1.CollateralConfig} } } } @@ -757,7 +828,8 @@ access(all) contract FlowYieldVaultsStrategiesV1_1 { let configs = { Type<@mUSDFStrategyComposer>(): { - Type<@mUSDFStrategy>(): ({} as {Type: FlowYieldVaultsStrategiesV1_1.CollateralConfig}) + Type<@mUSDFStrategy>(): {} as {Type: FlowYieldVaultsStrategiesV1_1.CollateralConfig}, + Type<@FUSDEVStrategy>(): {} as {Type: FlowYieldVaultsStrategiesV1_1.CollateralConfig} } } self.account.storage.save(<-create StrategyComposerIssuer(configs: configs), to: self.IssuerStoragePath) From dc00223c8846c0981731d37c3347df41e2a72a28 Mon Sep 17 00:00:00 2001 From: Alex <12097569+nialexsan@users.noreply.github.com> Date: Thu, 15 Jan 2026 22:09:46 -0500 Subject: [PATCH 2/2] config transaction scripts --- .../admin/upsert_musdf_config.cdc | 9 +++- local/setup_mainnet.sh | 41 +++++++++++++++++ local/setup_testnet.sh | 45 +++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) diff --git a/cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc b/cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc index 80f2244..1a5414c 100644 --- a/cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc +++ b/cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc @@ -8,7 +8,13 @@ import "FlowYieldVaultsStrategiesV1_1" /// - Must be signed by the account that deployed FlowYieldVaultsStrategies /// - You can omit some collaterals by passing empty arrays and guarding in prepare{} transaction( + // e.g. "A.0x...FlowYieldVaultsStrategiesV1_1.mUSDFStrategy" + strategyTypeIdentifier: String, + + // collateral vault type (e.g. "A.0x...FlowToken.Vault") tokenTypeIdentifier: String, + + // yield token (EVM) address yieldTokenEVMAddress: String, // collateral path/fees: [YIELD, ..., ] @@ -17,6 +23,8 @@ transaction( ) { prepare(acct: auth(Storage, Capabilities, BorrowValue) &Account) { + let strategyType = CompositeType(strategyTypeIdentifier) + ?? panic("Invalid strategyTypeIdentifier \(strategyTypeIdentifier)") let tokenType = CompositeType(tokenTypeIdentifier) ?? panic("Invalid tokenTypeIdentifier \(tokenTypeIdentifier)") // This tx must run on the same account that stores the issuer @@ -38,7 +46,6 @@ transaction( } let composerType = Type<@FlowYieldVaultsStrategiesV1_1.mUSDFStrategyComposer>() - let strategyType = Type<@FlowYieldVaultsStrategiesV1_1.mUSDFStrategy>() if swapPath.length > 0 { issuer.addOrUpdateCollateralConfig( diff --git a/local/setup_mainnet.sh b/local/setup_mainnet.sh index 5982c6d..4de0b4f 100755 --- a/local/setup_mainnet.sh +++ b/local/setup_mainnet.sh @@ -118,6 +118,7 @@ flow transactions send ./lib/FlowCreditMarket/FlowActions/cadence/transactions/f # Setup UniV3 path tauUSDFv -> USDF -> WFLOW flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.mUSDFStrategy' 'A.1654653399040a61.FlowToken.Vault' \ "0xc52E820d2D6207D18667a97e2c6Ac22eB26E803c" \ '["0xc52E820d2D6207D18667a97e2c6Ac22eB26E803c","0x2aaBea2058b5aC2D339b163C6Ab6f2b6d53aabED","0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e"]' \ @@ -128,6 +129,7 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_mus # Setup UniV3 path tauUSDFv -> USDF -> WBTC flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.mUSDFStrategy' 'A.1e4aa0b87d10b141.EVMVMBridgedToken_717dae2baf7656be9a9b01dee31d571a9d4c9579.Vault' \ "0xc52E820d2D6207D18667a97e2c6Ac22eB26E803c" \ '["0xc52E820d2D6207D18667a97e2c6Ac22eB26E803c","0x2aaBea2058b5aC2D339b163C6Ab6f2b6d53aabED","0x717DAE2BaF7656BE9a9B01deE31d571a9d4c9579"]' \ @@ -137,6 +139,7 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_mus # Setup UniV3 path tauUSDFv -> USDF -> WETH flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.mUSDFStrategy' 'A.1e4aa0b87d10b141.EVMVMBridgedToken_2f6f07cdcf3588944bf4c42ac74ff24bf56e7590.Vault' \ "0xc52E820d2D6207D18667a97e2c6Ac22eB26E803c" \ '["0xc52E820d2D6207D18667a97e2c6Ac22eB26E803c","0x2aaBea2058b5aC2D339b163C6Ab6f2b6d53aabED","0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590"]' \ @@ -144,6 +147,37 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_mus --network mainnet \ --signer mainnet-admin + +# Setup UniV3 path FUSDEV -> PYUSD0 -> WFLOW +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' + 'A.1654653399040a61.FlowToken.Vault' \ + "0xd069d989e2F44B70c65347d1853C0c67e10a9F8D" \ + '["0xd069d989e2F44B70c65347d1853C0c67e10a9F8D","0x99aF3EeA856556646C98c8B9b2548Fe815240750","0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e"]' \ + '[100,3000]' \ + --network mainnet \ + --signer mainnet-admin + + +# Setup UniV3 path FUSDEV -> PYUSD0 -> WBTC +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' + 'A.1e4aa0b87d10b141.EVMVMBridgedToken_717dae2baf7656be9a9b01dee31d571a9d4c9579.Vault' \ + "0xd069d989e2F44B70c65347d1853C0c67e10a9F8D" \ + '["0xd069d989e2F44B70c65347d1853C0c67e10a9F8D","0x99aF3EeA856556646C98c8B9b2548Fe815240750","0x717DAE2BaF7656BE9a9B01deE31d571a9d4c9579"]' \ + '[100,3000]' \ + --network mainnet \ + --signer mainnet-admin + +# Setup UniV3 path FUSDEV -> PYUSD0 -> WETH +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' + 'A.1e4aa0b87d10b141.EVMVMBridgedToken_2f6f07cdcf3588944bf4c42ac74ff24bf56e7590.Vault' \ + "0xd069d989e2F44B70c65347d1853C0c67e10a9F8D" \ + '["0xd069d989e2F44B70c65347d1853C0c67e10a9F8D","0x99aF3EeA856556646C98c8B9b2548Fe815240750","0x2F6F07CDcf3588944Bf4C42aC74ff24bF56e7590"]' \ + '[100,3000]' \ + --network mainnet \ + --signer mainnet-admin # # add mUSDFStrategy as supported Strategy with the ability to initialize when new YieldVaults are created flow transactions send ./cadence/transactions/flow-yield-vaults/admin/add_strategy_composer.cdc \ @@ -153,6 +187,13 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/add_strate --network mainnet \ --signer mainnet-admin +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/add_strategy_composer.cdc \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' \ + 'A.b1d63873c3cc9f79.FlowYieldVaultsStrategiesV1_1.mUSDFStrategyComposer' \ + /storage/FlowYieldVaultsStrategyV1_1ComposerIssuer_0xb1d63873c3cc9f79 \ + --network mainnet \ + --signer mainnet-admin + # configure PMStrategies strategy configs flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert-pm-strategy-config.cdc \ 'A.b1d63873c3cc9f79.PMStrategiesV1.syWFLOWvStrategy' \ diff --git a/local/setup_testnet.sh b/local/setup_testnet.sh index c8cfb0f..aeec38e 100755 --- a/local/setup_testnet.sh +++ b/local/setup_testnet.sh @@ -89,6 +89,7 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/add_strate --signer testnet-admin flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.mUSDFStrategy' 'A.7e60df042a9c0868.FlowToken.Vault' \ "0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95" \ '["0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95", "0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e"]' \ @@ -98,6 +99,7 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_mus # WETH univ3 path and fees flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.mUSDFStrategy' 'A.dfc20aee650fcbdf.EVMVMBridgedToken_059a77239dafa770977dd9f1e98632c3e4559848.Vault' \ "0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95" \ '["0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95","0x02d3575e2516a515E9B91a52b294Edc80DC7987c", "0x059A77239daFa770977DD9f1E98632C3E4559848"]' \ @@ -107,6 +109,7 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_mus # WBTC univ3 path and fees flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.mUSDFStrategy' 'A.dfc20aee650fcbdf.EVMVMBridgedToken_208d09d2a6dd176e3e95b3f0de172a7471c5b2d6.Vault' \ "0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95" \ '["0x4154d5B0E2931a0A1E5b733f19161aa7D2fc4b95","0x02d3575e2516a515E9B91a52b294Edc80DC7987c","0x208d09d2a6Dd176e3e95b3F0DE172A7471C5B2d6"]' \ @@ -114,6 +117,41 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_mus --network testnet \ --signer testnet-admin + +## PYUSD0 Vault +# WFLOW univ3 path and fees +# path: FUSDEV - WFLOW +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' + 'A.7e60df042a9c0868.FlowToken.Vault' \ + "0x61b44D19486EE492449E83C1201581C754e9e1E1" \ + '["0x61b44D19486EE492449E83C1201581C754e9e1E1", "0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e"]' \ + '[3000]' \ + --network testnet \ + --signer testnet-admin + +# WETH univ3 path and fees +# path: FUSDEV - MOET - WETH +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' + 'A.dfc20aee650fcbdf.EVMVMBridgedToken_059a77239dafa770977dd9f1e98632c3e4559848.Vault' \ + "0x61b44D19486EE492449E83C1201581C754e9e1E1" \ + '["0x61b44D19486EE492449E83C1201581C754e9e1E1","0x02d3575e2516a515E9B91a52b294Edc80DC7987c", "0x059A77239daFa770977DD9f1E98632C3E4559848"]' \ + '[3000,3000]' \ + --network testnet \ + --signer testnet-admin + +# WBTC univ3 path and fees +# path: FUSDEV - MOET - WETH +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert_musdf_config.cdc \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' + 'A.dfc20aee650fcbdf.EVMVMBridgedToken_208d09d2a6dd176e3e95b3f0de172a7471c5b2d6.Vault' \ + "0x61b44D19486EE492449E83C1201581C754e9e1E1" \ + '["0x61b44D19486EE492449E83C1201581C754e9e1E1","0x02d3575e2516a515E9B91a52b294Edc80DC7987c","0x208d09d2a6Dd176e3e95b3F0DE172A7471C5B2d6"]' \ + '[3000,3000]' \ + --network testnet \ + --signer testnet-admin + flow transactions send ./cadence/transactions/flow-yield-vaults/admin/add_strategy_composer.cdc \ 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.mUSDFStrategy' \ 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.mUSDFStrategyComposer' \ @@ -121,6 +159,13 @@ flow transactions send ./cadence/transactions/flow-yield-vaults/admin/add_strate --network testnet \ --signer testnet-admin +flow transactions send ./cadence/transactions/flow-yield-vaults/admin/add_strategy_composer.cdc \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.FUSDEVStrategy' \ + 'A.d2580caf2ef07c2f.FlowYieldVaultsStrategiesV1_1.mUSDFStrategyComposer' \ + /storage/FlowYieldVaultsStrategyV1_1ComposerIssuer_0xd2580caf2ef07c2f \ + --network testnet \ + --signer testnet-admin + # PYUSD0 Vault flow transactions send ./cadence/transactions/flow-yield-vaults/admin/upsert-pm-strategy-config.cdc \ 'A.d2580caf2ef07c2f.PMStrategiesV1.FUSDEVStrategy' \