From 5a5d1aa63f64d0bf00701a9c817ab111f10ae0f5 Mon Sep 17 00:00:00 2001
From: joelkrusala <joel@golem.foundation>
Date: Mon, 30 Dec 2024 18:03:03 +0200
Subject: [PATCH 1/7] chore: update dependencies

---
 .gitmodules                      | 10 ----------
 lib/openzeppelin-contracts       |  1 -
 lib/tokenized-strategy           |  1 -
 lib/tokenized-strategy-periphery |  1 -
 4 files changed, 13 deletions(-)
 delete mode 160000 lib/openzeppelin-contracts
 delete mode 160000 lib/tokenized-strategy
 delete mode 160000 lib/tokenized-strategy-periphery

diff --git a/.gitmodules b/.gitmodules
index c3327f0f..7db1428a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,13 +2,3 @@
 	path = lib/forge-std
 	url = https://github.com/foundry-rs/forge-std
 	branch = master
-[submodule "lib/openzeppelin-contracts"]
-	path = lib/openzeppelin-contracts
-	url = https://github.com/OpenZeppelin/openzeppelin-contracts
-	branch = v4.9.5
-[submodule "lib/tokenized-strategy"]
-	path = lib/tokenized-strategy
-	url = https://github.com/yearn/tokenized-strategy
-[submodule "lib/tokenized-strategy-periphery"]
-	path = lib/tokenized-strategy-periphery
-	url = https://github.com/yearn/tokenized-strategy-periphery
diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts
deleted file mode 160000
index bd325d56..00000000
--- a/lib/openzeppelin-contracts
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bd325d56b4c62c9c5c1aff048c37c6bb18ac0290
diff --git a/lib/tokenized-strategy b/lib/tokenized-strategy
deleted file mode 160000
index 82806289..00000000
--- a/lib/tokenized-strategy
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 82806289f967590c4efbf6bc3d237e4e7f0a0966
diff --git a/lib/tokenized-strategy-periphery b/lib/tokenized-strategy-periphery
deleted file mode 160000
index fc802464..00000000
--- a/lib/tokenized-strategy-periphery
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit fc802464cb8ec6dacea20d8309dc7f82a2739710

From 96e0f831b6b8805899bf90f603862da5f45370f6 Mon Sep 17 00:00:00 2001
From: joelkrusala <joel@golem.foundation>
Date: Mon, 30 Dec 2024 18:10:15 +0200
Subject: [PATCH 2/7] forge install: octant-v2-core

---
 .gitmodules        | 3 +++
 lib/octant-v2-core | 1 +
 2 files changed, 4 insertions(+)
 create mode 160000 lib/octant-v2-core

diff --git a/.gitmodules b/.gitmodules
index 7db1428a..56678619 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,3 +2,6 @@
 	path = lib/forge-std
 	url = https://github.com/foundry-rs/forge-std
 	branch = master
+[submodule "lib/octant-v2-core"]
+	path = lib/octant-v2-core
+	url = https://github.com/golemfoundation/octant-v2-core
diff --git a/lib/octant-v2-core b/lib/octant-v2-core
new file mode 160000
index 00000000..e7e7c5fc
--- /dev/null
+++ b/lib/octant-v2-core
@@ -0,0 +1 @@
+Subproject commit e7e7c5fc711523976ad3759294ebf092b267c28f

From 8d4e59ebf4890f6db1cefe7fe799d561b9568719 Mon Sep 17 00:00:00 2001
From: joelkrusala <joel@golem.foundation>
Date: Mon, 30 Dec 2024 18:35:55 +0200
Subject: [PATCH 3/7] feat: update strategy

---
 .vscode/settings.json                 |  11 +++
 foundry.toml                          |  37 ++++++---
 remappings.txt                        |   9 ++
 src/Strategy.sol                      | 113 +++++++++++++++++---------
 src/StrategyFactory.sol               |  26 ++----
 src/interfaces/IStrategyInterface.sol |   4 +-
 src/periphery/StrategyAprOracle.sol   |   5 +-
 src/test/FunctionSignature.t.sol      |  14 +---
 src/test/Operation.t.sol              |  52 +++---------
 src/test/Oracle.t.sol                 |  36 ++++----
 src/test/Shutdown.t.sol               |  12 +--
 src/test/utils/ExtendedTest.sol       |  19 +----
 src/test/utils/Setup.sol              |  33 ++------
 13 files changed, 172 insertions(+), 199 deletions(-)
 create mode 100644 remappings.txt

diff --git a/.vscode/settings.json b/.vscode/settings.json
index eb095a44..bc492b7d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -5,5 +5,16 @@
     "forge-std/=lib/forge-std/src/",
     "@tokenized-strategy/=./lib/tokenized-strategy/src/",
     "@periphery/=./lib/tokenized-strategy-periphery/src/"
+  ],
+  "wake.compiler.solc.remappings": [
+    "@gnosis.pm/safe-contracts/=lib/octant-v2-core/lib/safe-smart-account",
+    "@openzeppelin/contracts-upgradeable/=lib/octant-v2-core/lib/openzeppelin-contracts-upgradeable/contracts/",
+    "@openzeppelin/contracts/=lib/octant-v2-core/lib/openzeppelin-contracts/contracts/",
+    "forge-std/=lib/forge-std/src/",
+    "octant-v2-core/=lib/octant-v2-core/",
+    "openzeppelin-contracts-upgradeable/=lib/octant-v2-core/lib/openzeppelin-contracts-upgradeable/",
+    "openzeppelin-contracts/=lib/octant-v2-core/lib/openzeppelin-contracts/",
+    "tokenized-strategy-periphery/=lib/tokenized-strategy-periphery/",
+    "zodiac/=lib/octant-v2-core/lib/zodiac/contracts/",
   ]
 }
diff --git a/foundry.toml b/foundry.toml
index 262de881..64c6aae1 100644
--- a/foundry.toml
+++ b/foundry.toml
@@ -1,14 +1,25 @@
 [profile.default]
-src = 'src'
-out = 'out'
-libs = ['lib']
-solc = "0.8.23"
-
-remappings = [
-    "@openzeppelin/=lib/openzeppelin-contracts/",
-    "forge-std/=lib/forge-std/src/",
-    "@tokenized-strategy/=lib/tokenized-strategy/src/",
-    "@periphery/=lib/tokenized-strategy-periphery/src/",
-]
-
-# See more config options https://github.com/foundry-rs/foundry/tree/master/config
\ No newline at end of file
+src = "src"
+out = "out"
+libs = ["node_modules", "lib"]
+evm_version = "cancun"
+optimizer = true
+optimizer_runs = 10_000_000
+solc = "0.8.25"
+verbosity = 3
+
+[profile.ci]
+fuzz = { runs = 5000 }
+invariant = { runs = 1000 }
+verbosity = 4
+
+[profile.local]
+  fuzz = { runs = 50 }
+  invariant = { runs = 10 }
+  # Speed up compilation and tests during development.
+  optimizer = true
+
+[rpc_endpoints]
+mainnet = "${ETHEREUM_NODE_MAINNET}"
+
+# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
diff --git a/remappings.txt b/remappings.txt
new file mode 100644
index 00000000..1d103976
--- /dev/null
+++ b/remappings.txt
@@ -0,0 +1,9 @@
+@gnosis.pm/safe-contracts/=lib/octant-v2-core/lib/safe-smart-account
+@openzeppelin/contracts-upgradeable/=lib/octant-v2-core/lib/openzeppelin-contracts-upgradeable/contracts/
+@openzeppelin/contracts/=lib/octant-v2-core/lib/openzeppelin-contracts/contracts/
+forge-std/=lib/forge-std/src/
+octant-v2-core/=lib/octant-v2-core/
+openzeppelin-contracts-upgradeable/=lib/octant-v2-core/lib/openzeppelin-contracts-upgradeable/
+openzeppelin-contracts/=lib/octant-v2-core/lib/openzeppelin-contracts/
+tokenized-strategy-periphery/=lib/tokenized-strategy-periphery/
+zodiac/=lib/octant-v2-core/lib/zodiac/contracts/
\ No newline at end of file
diff --git a/src/Strategy.sol b/src/Strategy.sol
index def08717..cbaf8868 100644
--- a/src/Strategy.sol
+++ b/src/Strategy.sol
@@ -1,8 +1,10 @@
 // SPDX-License-Identifier: AGPL-3.0
 pragma solidity ^0.8.18;
 
-import {BaseStrategy, ERC20} from "@tokenized-strategy/BaseStrategy.sol";
+import {BaseStrategy, ERC20} from "octant-v2-core/src/dragons/BaseStrategy.sol";
+import {Module} from "zodiac/core/Module.sol";
 import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+import {IStrategyInterface} from "./interfaces/IStrategyInterface.sol";
 
 // Import interfaces for many popular DeFi projects, or add your own!
 //import "../interfaces/<protocol>/<Interface>.sol";
@@ -20,13 +22,57 @@ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
 
 // NOTE: To implement permissioned functions you can use the onlyManagement, onlyEmergencyAuthorized and onlyKeepers modifiers
 
-contract Strategy is BaseStrategy {
+contract Strategy is Module, BaseStrategy {
     using SafeERC20 for ERC20;
 
-    constructor(
-        address _asset,
-        string memory _name
-    ) BaseStrategy(_asset, _name) {}
+    address public yieldSource;
+    bool public trigger;
+    bool public managed;
+    bool public kept;
+    bool public emergentizated;
+
+    /// @dev Initialize function, will be triggered when a new proxy is deployed
+    /// @dev owner of this module will the safe multisig that calls setUp function
+    /// @param initializeParams Parameters of initialization encoded
+    function setUp(bytes memory initializeParams) public override initializer {
+        (address _owner, bytes memory data) = abi.decode(initializeParams, (address, bytes));
+
+        (
+            address _tokenizedStrategyImplementation,
+            address _asset,
+            address _yieldSource,
+            address _management,
+            address _keeper,
+            address _dragonRouter,
+            uint256 _maxReportDelay,
+            string memory _name
+        ) = abi.decode(data, (address, address, address, address, address, address, uint256, string));
+
+        __Ownable_init(msg.sender);
+        __BaseStrategy_init(
+            _tokenizedStrategyImplementation,
+            _asset,
+            _owner,
+            _management,
+            _keeper,
+            _dragonRouter,
+            _maxReportDelay,
+            _name
+        );
+
+        yieldSource = _yieldSource;
+        if (_asset != ETH) ERC20(_asset).approve(_yieldSource, type(uint256).max);
+
+        setAvatar(_owner);
+        setTarget(_owner);
+        transferOwnership(_owner);
+    }
+
+    function initialize(address _asset, address _yieldSource) public {
+        require(yieldSource == address(0));
+        yieldSource = _yieldSource;
+        ERC20(_asset).approve(_yieldSource, type(uint256).max);
+    }
 
     /*//////////////////////////////////////////////////////////////
                 NEEDED TO BE OVERRIDDEN BY STRATEGIST
@@ -98,11 +144,7 @@ contract Strategy is BaseStrategy {
      * @return _totalAssets A trusted and accurate account for the total
      * amount of 'asset' the strategy currently holds including idle funds.
      */
-    function _harvestAndReport()
-        internal
-        override
-        returns (uint256 _totalAssets)
-    {
+    function _harvestAndReport() internal override returns (uint256 _totalAssets) {
         // TODO: Implement harvesting logic and accurate accounting EX:
         //
         //      if(!TokenizedStrategy.isShutdown()) {
@@ -135,9 +177,7 @@ contract Strategy is BaseStrategy {
      * @param . The address that is withdrawing from the strategy.
      * @return . The available amount that can be withdrawn in terms of `asset`
      */
-    function availableWithdrawLimit(
-        address /*_owner*/
-    ) public view override returns (uint256) {
+    function availableWithdrawLimit(address /*_owner*/ ) public view override returns (uint256) {
         // NOTE: Withdraw limitations such as liquidity constraints should be accounted for HERE
         //  rather than _freeFunds in order to not count them as losses on withdraws.
 
@@ -171,16 +211,16 @@ contract Strategy is BaseStrategy {
      * @param . The address that is depositing into the strategy.
      * @return . The available amount the `_owner` can deposit in terms of `asset`
      *
-    function availableDepositLimit(
-        address _owner
-    ) public view override returns (uint256) {
-        TODO: If desired Implement deposit limit logic and any needed state variables .
-        
-        EX:    
-            uint256 totalAssets = TokenizedStrategy.totalAssets();
-            return totalAssets >= depositLimit ? 0 : depositLimit - totalAssets;
-    }
-    */
+     * function availableDepositLimit(
+     *     address _owner
+     * ) public view override returns (uint256) {
+     *     TODO: If desired Implement deposit limit logic and any needed state variables .
+     *
+     *     EX:
+     *         uint256 totalAssets = TokenizedStrategy.totalAssets();
+     *         return totalAssets >= depositLimit ? 0 : depositLimit - totalAssets;
+     * }
+     */
 
     /**
      * @dev Optional function for strategist to override that can
@@ -203,8 +243,8 @@ contract Strategy is BaseStrategy {
      *
      * @param _totalIdle The current amount of idle funds that are available to deploy.
      *
-    function _tend(uint256 _totalIdle) internal override {}
-    */
+     * function _tend(uint256 _totalIdle) internal override {}
+     */
 
     /**
      * @dev Optional trigger to override if tend() will be used by the strategy.
@@ -212,8 +252,8 @@ contract Strategy is BaseStrategy {
      *
      * @return . Should return true if tend() should be called by keeper or false if not.
      *
-    function _tendTrigger() internal view override returns (bool) {}
-    */
+     * function _tendTrigger() internal view override returns (bool) {}
+     */
 
     /**
      * @dev Optional function for a strategist to override that will
@@ -236,13 +276,12 @@ contract Strategy is BaseStrategy {
      *
      * @param _amount The amount of asset to attempt to free.
      *
-    function _emergencyWithdraw(uint256 _amount) internal override {
-        TODO: If desired implement simple logic to free deployed funds.
-
-        EX:
-            _amount = min(_amount, aToken.balanceOf(address(this)));
-            _freeFunds(_amount);
-    }
-
-    */
+     * function _emergencyWithdraw(uint256 _amount) internal override {
+     *     TODO: If desired implement simple logic to free deployed funds.
+     *
+     *     EX:
+     *         _amount = min(_amount, aToken.balanceOf(address(this)));
+     *         _freeFunds(_amount);
+     * }
+     */
 }
diff --git a/src/StrategyFactory.sol b/src/StrategyFactory.sol
index db02a734..e68b258c 100644
--- a/src/StrategyFactory.sol
+++ b/src/StrategyFactory.sol
@@ -16,12 +16,7 @@ contract StrategyFactory {
     /// @notice Track the deployments. asset => pool => strategy
     mapping(address => address) public deployments;
 
-    constructor(
-        address _management,
-        address _performanceFeeRecipient,
-        address _keeper,
-        address _emergencyAdmin
-    ) {
+    constructor(address _management, address _performanceFeeRecipient, address _keeper, address _emergencyAdmin) {
         management = _management;
         performanceFeeRecipient = _performanceFeeRecipient;
         keeper = _keeper;
@@ -33,14 +28,9 @@ contract StrategyFactory {
      * @param _asset The underlying asset for the strategy to use.
      * @return . The address of the new strategy.
      */
-    function newStrategy(
-        address _asset,
-        string calldata _name
-    ) external virtual returns (address) {
+    function newStrategy(address _asset, string calldata _name) external virtual returns (address) {
         // tokenized strategies available setters.
-        IStrategyInterface _newStrategy = IStrategyInterface(
-            address(new Strategy(_asset, _name))
-        );
+        IStrategyInterface _newStrategy = IStrategyInterface(address(new Strategy(_asset, _name)));
 
         _newStrategy.setPerformanceFeeRecipient(performanceFeeRecipient);
 
@@ -56,20 +46,14 @@ contract StrategyFactory {
         return address(_newStrategy);
     }
 
-    function setAddresses(
-        address _management,
-        address _performanceFeeRecipient,
-        address _keeper
-    ) external {
+    function setAddresses(address _management, address _performanceFeeRecipient, address _keeper) external {
         require(msg.sender == management, "!management");
         management = _management;
         performanceFeeRecipient = _performanceFeeRecipient;
         keeper = _keeper;
     }
 
-    function isDeployedStrategy(
-        address _strategy
-    ) external view returns (bool) {
+    function isDeployedStrategy(address _strategy) external view returns (bool) {
         address _asset = IStrategyInterface(_strategy).asset();
         return deployments[_asset] == _strategy;
     }
diff --git a/src/interfaces/IStrategyInterface.sol b/src/interfaces/IStrategyInterface.sol
index 917e2d0c..8a3f84ed 100644
--- a/src/interfaces/IStrategyInterface.sol
+++ b/src/interfaces/IStrategyInterface.sol
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: AGPL-3.0
 pragma solidity ^0.8.18;
 
-import {IStrategy} from "@tokenized-strategy/interfaces/IStrategy.sol";
+import {IStrategy} from "octant-v2-core/src/interfaces/IStrategy.sol";
 
 interface IStrategyInterface is IStrategy {
-    //TODO: Add your specific implementation interface in here.
+//TODO: Add your specific implementation interface in here.
 }
diff --git a/src/periphery/StrategyAprOracle.sol b/src/periphery/StrategyAprOracle.sol
index 1c0bfb8f..9a20cabb 100644
--- a/src/periphery/StrategyAprOracle.sol
+++ b/src/periphery/StrategyAprOracle.sol
@@ -25,10 +25,7 @@ contract StrategyAprOracle is AprOracleBase {
      * @param _delta The difference in debt.
      * @return . The expected apr for the strategy represented as 1e18.
      */
-    function aprAfterDebtChange(
-        address _strategy,
-        int256 _delta
-    ) external view override returns (uint256) {
+    function aprAfterDebtChange(address _strategy, int256 _delta) external view override returns (uint256) {
         // TODO: Implement any necessary logic to return the most accurate
         //      APR estimation for the strategy.
         return 1e17;
diff --git a/src/test/FunctionSignature.t.sol b/src/test/FunctionSignature.t.sol
index 6df721b4..bdad09f4 100644
--- a/src/test/FunctionSignature.t.sol
+++ b/src/test/FunctionSignature.t.sol
@@ -15,13 +15,7 @@ contract FunctionSignatureTest is Setup {
     function test_functionCollisions() public {
         uint256 wad = 1e18;
         vm.expectRevert("initialized");
-        strategy.initialize(
-            address(asset),
-            "name",
-            management,
-            performanceFeeRecipient,
-            keeper
-        );
+        strategy.initialize(address(asset), "name", management, performanceFeeRecipient, keeper);
 
         // Check view functions
         assertEq(strategy.convertToAssets(wad), wad, "convert to assets");
@@ -41,11 +35,7 @@ contract FunctionSignatureTest is Setup {
         assertGt(strategy.lastReport(), 0, "last report");
         assertEq(strategy.pricePerShare(), 10 ** asset.decimals(), "pps");
         assertTrue(!strategy.isShutdown());
-        assertEq(
-            strategy.symbol(),
-            string(abi.encodePacked("ys", asset.symbol())),
-            "symbol"
-        );
+        assertEq(strategy.symbol(), string(abi.encodePacked("ys", asset.symbol())), "symbol");
         assertEq(strategy.decimals(), asset.decimals(), "decimals");
 
         // Assure modifiers are working
diff --git a/src/test/Operation.t.sol b/src/test/Operation.t.sol
index 9a3f25be..91f4c470 100644
--- a/src/test/Operation.t.sol
+++ b/src/test/Operation.t.sol
@@ -46,17 +46,10 @@ contract OperationTest is Setup {
         vm.prank(user);
         strategy.redeem(_amount, user, user);
 
-        assertGe(
-            asset.balanceOf(user),
-            balanceBefore + _amount,
-            "!final balance"
-        );
+        assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
     }
 
-    function test_profitableReport(
-        uint256 _amount,
-        uint16 _profitFactor
-    ) public {
+    function test_profitableReport(uint256 _amount, uint16 _profitFactor) public {
         vm.assume(_amount > minFuzzAmount && _amount < maxFuzzAmount);
         _profitFactor = uint16(bound(uint256(_profitFactor), 10, MAX_BPS));
 
@@ -88,17 +81,10 @@ contract OperationTest is Setup {
         vm.prank(user);
         strategy.redeem(_amount, user, user);
 
-        assertGe(
-            asset.balanceOf(user),
-            balanceBefore + _amount,
-            "!final balance"
-        );
+        assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
     }
 
-    function test_profitableReport_withFees(
-        uint256 _amount,
-        uint16 _profitFactor
-    ) public {
+    function test_profitableReport_withFees(uint256 _amount, uint16 _profitFactor) public {
         vm.assume(_amount > minFuzzAmount && _amount < maxFuzzAmount);
         _profitFactor = uint16(bound(uint256(_profitFactor), 10, MAX_BPS));
 
@@ -138,62 +124,50 @@ contract OperationTest is Setup {
         vm.prank(user);
         strategy.redeem(_amount, user, user);
 
-        assertGe(
-            asset.balanceOf(user),
-            balanceBefore + _amount,
-            "!final balance"
-        );
+        assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
 
         vm.prank(performanceFeeRecipient);
-        strategy.redeem(
-            expectedShares,
-            performanceFeeRecipient,
-            performanceFeeRecipient
-        );
+        strategy.redeem(expectedShares, performanceFeeRecipient, performanceFeeRecipient);
 
         checkStrategyTotals(strategy, 0, 0, 0);
 
-        assertGe(
-            asset.balanceOf(performanceFeeRecipient),
-            expectedShares,
-            "!perf fee out"
-        );
+        assertGe(asset.balanceOf(performanceFeeRecipient), expectedShares, "!perf fee out");
     }
 
     function test_tendTrigger(uint256 _amount) public {
         vm.assume(_amount > minFuzzAmount && _amount < maxFuzzAmount);
 
-        (bool trigger, ) = strategy.tendTrigger();
+        (bool trigger,) = strategy.tendTrigger();
         assertTrue(!trigger);
 
         // Deposit into strategy
         mintAndDepositIntoStrategy(strategy, user, _amount);
 
-        (trigger, ) = strategy.tendTrigger();
+        (trigger,) = strategy.tendTrigger();
         assertTrue(!trigger);
 
         // Skip some time
         skip(1 days);
 
-        (trigger, ) = strategy.tendTrigger();
+        (trigger,) = strategy.tendTrigger();
         assertTrue(!trigger);
 
         vm.prank(keeper);
         strategy.report();
 
-        (trigger, ) = strategy.tendTrigger();
+        (trigger,) = strategy.tendTrigger();
         assertTrue(!trigger);
 
         // Unlock Profits
         skip(strategy.profitMaxUnlockTime());
 
-        (trigger, ) = strategy.tendTrigger();
+        (trigger,) = strategy.tendTrigger();
         assertTrue(!trigger);
 
         vm.prank(user);
         strategy.redeem(_amount, user, user);
 
-        (trigger, ) = strategy.tendTrigger();
+        (trigger,) = strategy.tendTrigger();
         assertTrue(!trigger);
     }
 }
diff --git a/src/test/Oracle.t.sol b/src/test/Oracle.t.sol
index f7c349c4..63d922b8 100644
--- a/src/test/Oracle.t.sol
+++ b/src/test/Oracle.t.sol
@@ -25,27 +25,27 @@ contract OracleTest is Setup {
 
         // TODO: Uncomment to test the apr goes up and down based on debt changes
         /**
-        uint256 negativeDebtChangeApr = oracle.aprAfterDebtChange(_strategy, -int256(_delta));
-
-        // The apr should go up if deposits go down
-        assertLt(currentApr, negativeDebtChangeApr, "negative change");
-
-        uint256 positiveDebtChangeApr = oracle.aprAfterDebtChange(_strategy, int256(_delta));
-
-        assertGt(currentApr, positiveDebtChangeApr, "positive change");
-        */
+         * uint256 negativeDebtChangeApr = oracle.aprAfterDebtChange(_strategy, -int256(_delta));
+         *
+         *     // The apr should go up if deposits go down
+         *     assertLt(currentApr, negativeDebtChangeApr, "negative change");
+         *
+         *     uint256 positiveDebtChangeApr = oracle.aprAfterDebtChange(_strategy, int256(_delta));
+         *
+         *     assertGt(currentApr, positiveDebtChangeApr, "positive change");
+         */
 
         // TODO: Uncomment if there are setter functions to test.
         /**
-        vm.expectRevert("!governance");
-        vm.prank(user);
-        oracle.setterFunction(setterVariable);
-
-        vm.prank(management);
-        oracle.setterFunction(setterVariable);
-
-        assertEq(oracle.setterVariable(), setterVariable);
-        */
+         * vm.expectRevert("!governance");
+         *     vm.prank(user);
+         *     oracle.setterFunction(setterVariable);
+         *
+         *     vm.prank(management);
+         *     oracle.setterFunction(setterVariable);
+         *
+         *     assertEq(oracle.setterVariable(), setterVariable);
+         */
     }
 
     function test_oracle(uint256 _amount, uint16 _percentChange) public {
diff --git a/src/test/Shutdown.t.sol b/src/test/Shutdown.t.sol
index 5e498b9f..851d89cd 100644
--- a/src/test/Shutdown.t.sol
+++ b/src/test/Shutdown.t.sol
@@ -32,11 +32,7 @@ contract ShutdownTest is Setup {
         vm.prank(user);
         strategy.redeem(_amount, user, user);
 
-        assertGe(
-            asset.balanceOf(user),
-            balanceBefore + _amount,
-            "!final balance"
-        );
+        assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
     }
 
     function test_emergencyWithdraw_maxUint(uint256 _amount) public {
@@ -67,11 +63,7 @@ contract ShutdownTest is Setup {
         vm.prank(user);
         strategy.redeem(_amount, user, user);
 
-        assertGe(
-            asset.balanceOf(user),
-            balanceBefore + _amount,
-            "!final balance"
-        );
+        assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
     }
 
     // TODO: Add tests for any emergency function added.
diff --git a/src/test/utils/ExtendedTest.sol b/src/test/utils/ExtendedTest.sol
index 4dfd4f1f..a9314bcf 100644
--- a/src/test/utils/ExtendedTest.sol
+++ b/src/test/utils/ExtendedTest.sol
@@ -18,11 +18,7 @@ contract ExtendedTest is Test {
     // @a actual value
     // @b expected value
     // solhint-disable-next-line
-    function assertRelApproxEq(
-        uint256 a,
-        uint256 b,
-        uint256 maxPercentDelta
-    ) internal virtual {
+    function assertRelApproxEq(uint256 a, uint256 b, uint256 maxPercentDelta) internal virtual {
         uint256 delta = a > b ? a - b : b - a;
         uint256 maxRelDelta = b / maxPercentDelta;
 
@@ -38,11 +34,7 @@ contract ExtendedTest is Test {
 
     // Can be removed once https://github.com/dapphub/ds-test/pull/25 is merged and we update submodules, but useful for now
     // solhint-disable-next-line
-    function assertApproxEq(
-        uint256 a,
-        uint256 b,
-        uint256 margin_of_error
-    ) internal {
+    function assertApproxEq(uint256 a, uint256 b, uint256 margin_of_error) internal {
         if (a > b) {
             if (a - b > margin_of_error) {
                 emit log("Error a not equal to b");
@@ -61,12 +53,7 @@ contract ExtendedTest is Test {
     }
 
     // solhint-disable-next-line
-    function assertApproxEq(
-        uint256 a,
-        uint256 b,
-        uint256 margin_of_error,
-        string memory err
-    ) internal {
+    function assertApproxEq(uint256 a, uint256 b, uint256 margin_of_error, string memory err) internal {
         if (a > b) {
             if (a - b > margin_of_error) {
                 emit log_named_string("Error", err);
diff --git a/src/test/utils/Setup.sol b/src/test/utils/Setup.sol
index 42042f1d..ce552416 100644
--- a/src/test/utils/Setup.sol
+++ b/src/test/utils/Setup.sol
@@ -58,12 +58,7 @@ contract Setup is ExtendedTest, IEvents {
         // Set decimals
         decimals = asset.decimals();
 
-        strategyFactory = new StrategyFactory(
-            management,
-            performanceFeeRecipient,
-            keeper,
-            emergencyAdmin
-        );
+        strategyFactory = new StrategyFactory(management, performanceFeeRecipient, keeper, emergencyAdmin);
 
         // Deploy strategy and set variables
         strategy = IStrategyInterface(setUpStrategy());
@@ -81,14 +76,8 @@ contract Setup is ExtendedTest, IEvents {
 
     function setUpStrategy() public returns (address) {
         // we save the strategy as a IStrategyInterface to give it the needed interface
-        IStrategyInterface _strategy = IStrategyInterface(
-            address(
-                strategyFactory.newStrategy(
-                    address(asset),
-                    "Tokenized Strategy"
-                )
-            )
-        );
+        IStrategyInterface _strategy =
+            IStrategyInterface(address(strategyFactory.newStrategy(address(asset), "Tokenized Strategy")));
 
         vm.prank(management);
         _strategy.acceptManagement();
@@ -96,11 +85,7 @@ contract Setup is ExtendedTest, IEvents {
         return address(_strategy);
     }
 
-    function depositIntoStrategy(
-        IStrategyInterface _strategy,
-        address _user,
-        uint256 _amount
-    ) public {
+    function depositIntoStrategy(IStrategyInterface _strategy, address _user, uint256 _amount) public {
         vm.prank(_user);
         asset.approve(address(_strategy), _amount);
 
@@ -108,11 +93,7 @@ contract Setup is ExtendedTest, IEvents {
         _strategy.deposit(_amount, _user);
     }
 
-    function mintAndDepositIntoStrategy(
-        IStrategyInterface _strategy,
-        address _user,
-        uint256 _amount
-    ) public {
+    function mintAndDepositIntoStrategy(IStrategyInterface _strategy, address _user, uint256 _amount) public {
         airdrop(asset, _user, _amount);
         depositIntoStrategy(_strategy, _user, _amount);
     }
@@ -125,9 +106,7 @@ contract Setup is ExtendedTest, IEvents {
         uint256 _totalIdle
     ) public {
         uint256 _assets = _strategy.totalAssets();
-        uint256 _balance = ERC20(_strategy.asset()).balanceOf(
-            address(_strategy)
-        );
+        uint256 _balance = ERC20(_strategy.asset()).balanceOf(address(_strategy));
         uint256 _idle = _balance > _assets ? _assets : _balance;
         uint256 _debt = _assets - _idle;
         assertEq(_assets, _totalAssets, "!totalAssets");

From 31aa45939b6a5f01e6d2a603d494bf3c02c0d37c Mon Sep 17 00:00:00 2001
From: joelkrusala <joel@golem.foundation>
Date: Mon, 30 Dec 2024 19:10:44 +0200
Subject: [PATCH 4/7] feat: update strategy factory

---
 .vscode/settings.json                 |  2 +-
 src/StrategyFactory.sol               | 64 ++++++++++++---------------
 src/interfaces/IStrategyInterface.sol |  2 +-
 3 files changed, 30 insertions(+), 38 deletions(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index bc492b7d..e4a38ecc 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -15,6 +15,6 @@
     "openzeppelin-contracts-upgradeable/=lib/octant-v2-core/lib/openzeppelin-contracts-upgradeable/",
     "openzeppelin-contracts/=lib/octant-v2-core/lib/openzeppelin-contracts/",
     "tokenized-strategy-periphery/=lib/tokenized-strategy-periphery/",
-    "zodiac/=lib/octant-v2-core/lib/zodiac/contracts/",
+    "zodiac/=lib/octant-v2-core/lib/zodiac/contracts/"
   ]
 }
diff --git a/src/StrategyFactory.sol b/src/StrategyFactory.sol
index e68b258c..cfdd2b29 100644
--- a/src/StrategyFactory.sol
+++ b/src/StrategyFactory.sol
@@ -5,56 +5,48 @@ import {Strategy, ERC20} from "./Strategy.sol";
 import {IStrategyInterface} from "./interfaces/IStrategyInterface.sol";
 
 contract StrategyFactory {
-    event NewStrategy(address indexed strategy, address indexed asset);
+    error InvalidStrategyId();
 
-    address public immutable emergencyAdmin;
+    event NewStrategy(address indexed strategy, uint256 indexed strategyId);
 
-    address public management;
-    address public performanceFeeRecipient;
-    address public keeper;
+    /// @notice Track the deployments. strategyId => strategy address
+    mapping(uint256 => address) public deployments;
 
-    /// @notice Track the deployments. asset => pool => strategy
-    mapping(address => address) public deployments;
+    uint256 public strategyId;
 
-    constructor(address _management, address _performanceFeeRecipient, address _keeper, address _emergencyAdmin) {
-        management = _management;
-        performanceFeeRecipient = _performanceFeeRecipient;
-        keeper = _keeper;
-        emergencyAdmin = _emergencyAdmin;
+    constructor() {
+        strategyId = 0;
     }
 
     /**
-     * @notice Deploy a new Strategy.
-     * @param _asset The underlying asset for the strategy to use.
-     * @return . The address of the new strategy.
+     * @notice Deploy a new Strategy
+     * @param initializeParams The encoded parameters to initialize the strategy with
+     * @return address The address of the newly deployed strategy
      */
-    function newStrategy(address _asset, string calldata _name) external virtual returns (address) {
-        // tokenized strategies available setters.
-        IStrategyInterface _newStrategy = IStrategyInterface(address(new Strategy(_asset, _name)));
+    function newStrategy(bytes calldata initializeParams) external virtual returns (address) {
+        IStrategyInterface _newStrategy = IStrategyInterface(address(new Strategy()));
+        _newStrategy.setUp(initializeParams);
 
-        _newStrategy.setPerformanceFeeRecipient(performanceFeeRecipient);
+        uint256 currentId = strategyId;
+        deployments[currentId] = address(_newStrategy);
 
-        _newStrategy.setKeeper(keeper);
+        emit NewStrategy(address(_newStrategy), currentId);
 
-        _newStrategy.setPendingManagement(management);
+        unchecked {
+            strategyId = currentId + 1;
+        }
 
-        _newStrategy.setEmergencyAdmin(emergencyAdmin);
-
-        emit NewStrategy(address(_newStrategy), _asset);
-
-        deployments[_asset] = address(_newStrategy);
         return address(_newStrategy);
     }
 
-    function setAddresses(address _management, address _performanceFeeRecipient, address _keeper) external {
-        require(msg.sender == management, "!management");
-        management = _management;
-        performanceFeeRecipient = _performanceFeeRecipient;
-        keeper = _keeper;
-    }
-
-    function isDeployedStrategy(address _strategy) external view returns (bool) {
-        address _asset = IStrategyInterface(_strategy).asset();
-        return deployments[_asset] == _strategy;
+    /**
+     * @notice Retrieve a deployed strategy address by ID
+     * @param _strategyId The ID of the strategy to look up
+     * @return address The strategy contract address
+     */
+    function getStrategy(uint256 _strategyId) external view returns (address) {
+        address strategy = deployments[_strategyId];
+        if (strategy == address(0)) revert InvalidStrategyId();
+        return strategy;
     }
 }
diff --git a/src/interfaces/IStrategyInterface.sol b/src/interfaces/IStrategyInterface.sol
index 8a3f84ed..09bde845 100644
--- a/src/interfaces/IStrategyInterface.sol
+++ b/src/interfaces/IStrategyInterface.sol
@@ -4,5 +4,5 @@ pragma solidity ^0.8.18;
 import {IStrategy} from "octant-v2-core/src/interfaces/IStrategy.sol";
 
 interface IStrategyInterface is IStrategy {
-//TODO: Add your specific implementation interface in here.
+    function setUp(bytes calldata initializeParams) external;
 }

From 7aa1fedce4cd6bcdeef3c40c538d1bc77d339d3b Mon Sep 17 00:00:00 2001
From: joelkrusala <joel@golem.foundation>
Date: Mon, 30 Dec 2024 19:21:35 +0200
Subject: [PATCH 5/7] forge install: tokenized-strategy-periphery

v3.0.2
---
 .gitmodules                      | 3 +++
 lib/tokenized-strategy-periphery | 1 +
 2 files changed, 4 insertions(+)
 create mode 160000 lib/tokenized-strategy-periphery

diff --git a/.gitmodules b/.gitmodules
index 56678619..48bdd05f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -5,3 +5,6 @@
 [submodule "lib/octant-v2-core"]
 	path = lib/octant-v2-core
 	url = https://github.com/golemfoundation/octant-v2-core
+[submodule "lib/tokenized-strategy-periphery"]
+	path = lib/tokenized-strategy-periphery
+	url = https://github.com/golemfoundation/tokenized-strategy-periphery
diff --git a/lib/tokenized-strategy-periphery b/lib/tokenized-strategy-periphery
new file mode 160000
index 00000000..d732e918
--- /dev/null
+++ b/lib/tokenized-strategy-periphery
@@ -0,0 +1 @@
+Subproject commit d732e918b208a9b2c33c71ea0ea9e8eb880cfc6e

From 3c8bcb4a284a183c097b932035eeb623e83cc2fa Mon Sep 17 00:00:00 2001
From: joelkrusala <joel@golem.foundation>
Date: Mon, 30 Dec 2024 19:23:18 +0200
Subject: [PATCH 6/7] feat: update strategy apr oracle

---
 src/periphery/StrategyAprOracle.sol | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/periphery/StrategyAprOracle.sol b/src/periphery/StrategyAprOracle.sol
index 9a20cabb..d75f5f2d 100644
--- a/src/periphery/StrategyAprOracle.sol
+++ b/src/periphery/StrategyAprOracle.sol
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: AGPL-3.0
 pragma solidity ^0.8.18;
 
-import {AprOracleBase} from "@periphery/AprOracle/AprOracleBase.sol";
+import {AprOracleBase} from "tokenized-strategy-periphery/src/AprOracle/AprOracleBase.sol";
 
 contract StrategyAprOracle is AprOracleBase {
     constructor() AprOracleBase("Strategy Apr Oracle Example", msg.sender) {}

From d1ae0d75810d7360ae316adc4e1f4d0c449a89b8 Mon Sep 17 00:00:00 2001
From: joelkrusala <joel@golem.foundation>
Date: Mon, 6 Jan 2025 09:59:31 +0200
Subject: [PATCH 7/7] feat: update test

---
 src/Strategy.sol                      |  6 ---
 src/StrategyFactory.sol               | 15 ++++--
 src/interfaces/IStrategyInterface.sol |  2 +-
 src/test/FunctionSignature.t.sol      | 35 ++++++-------
 src/test/Operation.t.sol              | 75 ++++++++++++++-------------
 src/test/utils/Setup.sol              | 66 ++++++++++++++---------
 6 files changed, 110 insertions(+), 89 deletions(-)

diff --git a/src/Strategy.sol b/src/Strategy.sol
index cbaf8868..c8095fad 100644
--- a/src/Strategy.sol
+++ b/src/Strategy.sol
@@ -68,12 +68,6 @@ contract Strategy is Module, BaseStrategy {
         transferOwnership(_owner);
     }
 
-    function initialize(address _asset, address _yieldSource) public {
-        require(yieldSource == address(0));
-        yieldSource = _yieldSource;
-        ERC20(_asset).approve(_yieldSource, type(uint256).max);
-    }
-
     /*//////////////////////////////////////////////////////////////
                 NEEDED TO BE OVERRIDDEN BY STRATEGIST
     //////////////////////////////////////////////////////////////*/
diff --git a/src/StrategyFactory.sol b/src/StrategyFactory.sol
index cfdd2b29..ebc5d4e8 100644
--- a/src/StrategyFactory.sol
+++ b/src/StrategyFactory.sol
@@ -1,6 +1,9 @@
 // SPDX-License-Identifier: GPL-3.0
 pragma solidity ^0.8.18;
 
+import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
+import "octant-v2-core/src/dragons/DragonTokenizedStrategy.sol";
+import "forge-std/console2.sol";
 import {Strategy, ERC20} from "./Strategy.sol";
 import {IStrategyInterface} from "./interfaces/IStrategyInterface.sol";
 
@@ -12,10 +15,14 @@ contract StrategyFactory {
     /// @notice Track the deployments. strategyId => strategy address
     mapping(uint256 => address) public deployments;
 
+    address public strategyImplementation;
+    address public dragonTokenizedStrategyImplementation;
     uint256 public strategyId;
 
     constructor() {
         strategyId = 0;
+        strategyImplementation = address(new Strategy());
+        dragonTokenizedStrategyImplementation = address(new DragonTokenizedStrategy());
     }
 
     /**
@@ -23,9 +30,11 @@ contract StrategyFactory {
      * @param initializeParams The encoded parameters to initialize the strategy with
      * @return address The address of the newly deployed strategy
      */
-    function newStrategy(bytes calldata initializeParams) external virtual returns (address) {
-        IStrategyInterface _newStrategy = IStrategyInterface(address(new Strategy()));
-        _newStrategy.setUp(initializeParams);
+    function newStrategy(bytes memory initializeParams) external virtual returns (address) {
+        ERC1967Proxy _newStrategy = new ERC1967Proxy(
+            strategyImplementation,
+            abi.encodeWithSelector(Strategy(payable(address(0))).setUp.selector, initializeParams)
+        );
 
         uint256 currentId = strategyId;
         deployments[currentId] = address(_newStrategy);
diff --git a/src/interfaces/IStrategyInterface.sol b/src/interfaces/IStrategyInterface.sol
index 09bde845..83054655 100644
--- a/src/interfaces/IStrategyInterface.sol
+++ b/src/interfaces/IStrategyInterface.sol
@@ -4,5 +4,5 @@ pragma solidity ^0.8.18;
 import {IStrategy} from "octant-v2-core/src/interfaces/IStrategy.sol";
 
 interface IStrategyInterface is IStrategy {
-    function setUp(bytes calldata initializeParams) external;
+    function setUp(bytes memory initializeParams) external;
 }
diff --git a/src/test/FunctionSignature.t.sol b/src/test/FunctionSignature.t.sol
index bdad09f4..fafc5e42 100644
--- a/src/test/FunctionSignature.t.sol
+++ b/src/test/FunctionSignature.t.sol
@@ -14,8 +14,8 @@ contract FunctionSignatureTest is Setup {
     // Does not check functions that are strategy dependant and will be checked in other tests
     function test_functionCollisions() public {
         uint256 wad = 1e18;
-        vm.expectRevert("initialized");
-        strategy.initialize(address(asset), "name", management, performanceFeeRecipient, keeper);
+        // vm.expectRevert("initialized");
+        // strategy.initialize(address(asset), yieldSource);
 
         // Check view functions
         assertEq(strategy.convertToAssets(wad), wad, "convert to assets");
@@ -26,16 +26,15 @@ contract FunctionSignatureTest is Setup {
         assertEq(strategy.previewRedeem(wad), wad, "preview redeem");
         assertEq(strategy.totalAssets(), 0, "total assets");
         assertEq(strategy.totalSupply(), 0, "total supply");
-        assertEq(strategy.unlockedShares(), 0, "unlocked shares");
+        assertEq(strategy.unlockedShares(user), 0, "unlocked shares");
         assertEq(strategy.asset(), address(asset), "asset");
-        assertEq(strategy.apiVersion(), "3.0.4", "api");
-        assertEq(strategy.MAX_FEE(), 5_000, "max fee");
-        assertEq(strategy.fullProfitUnlockDate(), 0, "unlock date");
-        assertEq(strategy.profitUnlockingRate(), 0, "unlock rate");
+        assertEq(strategy.apiVersion(), "1.0.0", "api");
+        // assertEq(strategy.fullProfitUnlockDate(), 0, "unlock date");
+        // assertEq(strategy.profitUnlockingRate(), 0, "unlock rate");
         assertGt(strategy.lastReport(), 0, "last report");
         assertEq(strategy.pricePerShare(), 10 ** asset.decimals(), "pps");
         assertTrue(!strategy.isShutdown());
-        assertEq(strategy.symbol(), string(abi.encodePacked("ys", asset.symbol())), "symbol");
+        assertEq(strategy.symbol(), string(abi.encodePacked("dgn", asset.symbol())), "symbol");
         assertEq(strategy.decimals(), asset.decimals(), "decimals");
 
         // Assure modifiers are working
@@ -48,20 +47,20 @@ contract FunctionSignatureTest is Setup {
         strategy.setKeeper(user);
         vm.expectRevert("!management");
         strategy.setEmergencyAdmin(user);
-        vm.expectRevert("!management");
-        strategy.setPerformanceFee(uint16(2_000));
-        vm.expectRevert("!management");
-        strategy.setPerformanceFeeRecipient(user);
-        vm.expectRevert("!management");
-        strategy.setProfitMaxUnlockTime(1);
+        // vm.expectRevert("!management");
+        // strategy.setPerformanceFee(uint16(2_000));
+        // vm.expectRevert("!management");
+        // strategy.setPerformanceFeeRecipient(user);
+        // vm.expectRevert("!management");
+        // strategy.setProfitMaxUnlockTime(1);
         vm.stopPrank();
 
         // Assure checks are being used
         vm.startPrank(strategy.management());
-        vm.expectRevert("Cannot be self");
-        strategy.setPerformanceFeeRecipient(address(strategy));
-        vm.expectRevert("too long");
-        strategy.setProfitMaxUnlockTime(type(uint256).max);
+        // vm.expectRevert("Cannot be self");
+        // strategy.setPerformanceFeeRecipient(address(strategy));
+        // vm.expectRevert("too long");
+        // strategy.setProfitMaxUnlockTime(type(uint256).max);
         vm.stopPrank();
 
         // Mint some shares to the user
diff --git a/src/test/Operation.t.sol b/src/test/Operation.t.sol
index 91f4c470..d1b01df4 100644
--- a/src/test/Operation.t.sol
+++ b/src/test/Operation.t.sol
@@ -14,8 +14,9 @@ contract OperationTest is Setup {
         assertTrue(address(0) != address(strategy));
         assertEq(strategy.asset(), address(asset));
         assertEq(strategy.management(), management);
-        assertEq(strategy.performanceFeeRecipient(), performanceFeeRecipient);
         assertEq(strategy.keeper(), keeper);
+        assertEq(strategy.dragonRouter(), dragonRouter);
+        assertEq(strategy.name(), "Tokenized Strategy");
         // TODO: add additional check on strat params
     }
 
@@ -38,7 +39,7 @@ contract OperationTest is Setup {
         assertGe(profit, 0, "!profit");
         assertEq(loss, 0, "!loss");
 
-        skip(strategy.profitMaxUnlockTime());
+        // skip(strategy.profitMaxUnlockTime());
 
         uint256 balanceBefore = asset.balanceOf(user);
 
@@ -73,7 +74,7 @@ contract OperationTest is Setup {
         assertGe(profit, toAirdrop, "!profit");
         assertEq(loss, 0, "!loss");
 
-        skip(strategy.profitMaxUnlockTime());
+        // skip(strategy.profitMaxUnlockTime());
 
         uint256 balanceBefore = asset.balanceOf(user);
 
@@ -84,55 +85,55 @@ contract OperationTest is Setup {
         assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
     }
 
-    function test_profitableReport_withFees(uint256 _amount, uint16 _profitFactor) public {
-        vm.assume(_amount > minFuzzAmount && _amount < maxFuzzAmount);
-        _profitFactor = uint16(bound(uint256(_profitFactor), 10, MAX_BPS));
+    // function test_profitableReport_withFees(uint256 _amount, uint16 _profitFactor) public {
+    //     vm.assume(_amount > minFuzzAmount && _amount < maxFuzzAmount);
+    //     _profitFactor = uint16(bound(uint256(_profitFactor), 10, MAX_BPS));
 
-        // Set protocol fee to 0 and perf fee to 10%
-        setFees(0, 1_000);
+    //     // Set protocol fee to 0 and perf fee to 10%
+    //     setFees(0, 1_000);
 
-        // Deposit into strategy
-        mintAndDepositIntoStrategy(strategy, user, _amount);
+    //     // Deposit into strategy
+    //     mintAndDepositIntoStrategy(strategy, user, _amount);
 
-        assertEq(strategy.totalAssets(), _amount, "!totalAssets");
+    //     assertEq(strategy.totalAssets(), _amount, "!totalAssets");
 
-        // Earn Interest
-        skip(1 days);
+    //     // Earn Interest
+    //     skip(1 days);
 
-        // TODO: implement logic to simulate earning interest.
-        uint256 toAirdrop = (_amount * _profitFactor) / MAX_BPS;
-        airdrop(asset, address(strategy), toAirdrop);
+    //     // TODO: implement logic to simulate earning interest.
+    //     uint256 toAirdrop = (_amount * _profitFactor) / MAX_BPS;
+    //     airdrop(asset, address(strategy), toAirdrop);
 
-        // Report profit
-        vm.prank(keeper);
-        (uint256 profit, uint256 loss) = strategy.report();
+    //     // Report profit
+    //     vm.prank(keeper);
+    //     (uint256 profit, uint256 loss) = strategy.report();
 
-        // Check return Values
-        assertGe(profit, toAirdrop, "!profit");
-        assertEq(loss, 0, "!loss");
+    //     // Check return Values
+    //     assertGe(profit, toAirdrop, "!profit");
+    //     assertEq(loss, 0, "!loss");
 
-        skip(strategy.profitMaxUnlockTime());
+    //     skip(strategy.profitMaxUnlockTime());
 
-        // Get the expected fee
-        uint256 expectedShares = (profit * 1_000) / MAX_BPS;
+    //     // Get the expected fee
+    //     uint256 expectedShares = (profit * 1_000) / MAX_BPS;
 
-        assertEq(strategy.balanceOf(performanceFeeRecipient), expectedShares);
+    //     assertEq(strategy.balanceOf(performanceFeeRecipient), expectedShares);
 
-        uint256 balanceBefore = asset.balanceOf(user);
+    //     uint256 balanceBefore = asset.balanceOf(user);
 
-        // Withdraw all funds
-        vm.prank(user);
-        strategy.redeem(_amount, user, user);
+    //     // Withdraw all funds
+    //     vm.prank(user);
+    //     strategy.redeem(_amount, user, user);
 
-        assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
+    //     assertGe(asset.balanceOf(user), balanceBefore + _amount, "!final balance");
 
-        vm.prank(performanceFeeRecipient);
-        strategy.redeem(expectedShares, performanceFeeRecipient, performanceFeeRecipient);
+    //     vm.prank(performanceFeeRecipient);
+    //     strategy.redeem(expectedShares, performanceFeeRecipient, performanceFeeRecipient);
 
-        checkStrategyTotals(strategy, 0, 0, 0);
+    //     checkStrategyTotals(strategy, 0, 0, 0);
 
-        assertGe(asset.balanceOf(performanceFeeRecipient), expectedShares, "!perf fee out");
-    }
+    //     assertGe(asset.balanceOf(performanceFeeRecipient), expectedShares, "!perf fee out");
+    // }
 
     function test_tendTrigger(uint256 _amount) public {
         vm.assume(_amount > minFuzzAmount && _amount < maxFuzzAmount);
@@ -159,7 +160,7 @@ contract OperationTest is Setup {
         assertTrue(!trigger);
 
         // Unlock Profits
-        skip(strategy.profitMaxUnlockTime());
+        // skip(strategy.profitMaxUnlockTime());
 
         (trigger,) = strategy.tendTrigger();
         assertTrue(!trigger);
diff --git a/src/test/utils/Setup.sol b/src/test/utils/Setup.sol
index ce552416..b5ccbb3a 100644
--- a/src/test/utils/Setup.sol
+++ b/src/test/utils/Setup.sol
@@ -9,7 +9,7 @@ import {StrategyFactory} from "../../StrategyFactory.sol";
 import {IStrategyInterface} from "../../interfaces/IStrategyInterface.sol";
 
 // Inherit the events so they can be checked if desired.
-import {IEvents} from "@tokenized-strategy/interfaces/IEvents.sol";
+import {IEvents} from "octant-v2-core/src/interfaces/IEvents.sol";
 
 interface IFactory {
     function governance() external view returns (address);
@@ -29,11 +29,16 @@ contract Setup is ExtendedTest, IEvents {
     mapping(string => address) public tokenAddrs;
 
     // Addresses for different roles we will use repeatedly.
-    address public user = address(10);
-    address public keeper = address(4);
-    address public management = address(1);
-    address public performanceFeeRecipient = address(3);
+    address public user = address(1);
+    address public keeper = address(2);
+    address public management = address(3);
+    address public dragonRouter = address(4);
     address public emergencyAdmin = address(5);
+    address public yieldSource = address(6);
+    address public deployer = address(7);
+    address public owner = address(8);
+    address public tokenizedStrategyImplementation;
+    address public dragonTokenizedStrategyImplementation;
 
     // Address of the real deployed Factory
     address public factory;
@@ -41,6 +46,7 @@ contract Setup is ExtendedTest, IEvents {
     // Integer variables that will be used repeatedly.
     uint256 public decimals;
     uint256 public MAX_BPS = 10_000;
+    uint256 public maxReportDelay = 1 days;
 
     // Fuzz from $0.01 of 1e6 stable coins up to 1 trillion of a 1e18 coin
     uint256 public maxFuzzAmount = 1e30;
@@ -58,12 +64,14 @@ contract Setup is ExtendedTest, IEvents {
         // Set decimals
         decimals = asset.decimals();
 
-        strategyFactory = new StrategyFactory(management, performanceFeeRecipient, keeper, emergencyAdmin);
-
+        strategyFactory = new StrategyFactory();
+        tokenizedStrategyImplementation = address(strategyFactory.strategyImplementation());
+        dragonTokenizedStrategyImplementation = address(strategyFactory.dragonTokenizedStrategyImplementation());
         // Deploy strategy and set variables
         strategy = IStrategyInterface(setUpStrategy());
 
-        factory = strategy.FACTORY();
+        // factory = strategy.FACTORY();
+        factory = address(strategyFactory);
 
         // label all the used addresses for traces
         vm.label(keeper, "keeper");
@@ -71,16 +79,26 @@ contract Setup is ExtendedTest, IEvents {
         vm.label(address(asset), "asset");
         vm.label(management, "management");
         vm.label(address(strategy), "strategy");
-        vm.label(performanceFeeRecipient, "performanceFeeRecipient");
+        vm.label(dragonRouter, "dragonRouter");
     }
 
     function setUpStrategy() public returns (address) {
+        // Encode initialization parameters
+        bytes memory initParams = abi.encode(
+            owner,
+            abi.encode(
+                dragonTokenizedStrategyImplementation,
+                address(asset),
+                yieldSource,
+                management,
+                keeper,
+                dragonRouter,
+                maxReportDelay,
+                "Tokenized Strategy"
+            )
+        );
         // we save the strategy as a IStrategyInterface to give it the needed interface
-        IStrategyInterface _strategy =
-            IStrategyInterface(address(strategyFactory.newStrategy(address(asset), "Tokenized Strategy")));
-
-        vm.prank(management);
-        _strategy.acceptManagement();
+        IStrategyInterface _strategy = IStrategyInterface(address(strategyFactory.newStrategy(initParams)));
 
         return address(_strategy);
     }
@@ -120,19 +138,19 @@ contract Setup is ExtendedTest, IEvents {
         deal(address(_asset), _to, balanceBefore + _amount);
     }
 
-    function setFees(uint16 _protocolFee, uint16 _performanceFee) public {
-        address gov = IFactory(factory).governance();
+    // function setFees(uint16 _protocolFee, uint16 _performanceFee) public {
+    //     address gov = IFactory(factory).governance();
 
-        // Need to make sure there is a protocol fee recipient to set the fee.
-        vm.prank(gov);
-        IFactory(factory).set_protocol_fee_recipient(gov);
+    //     // Need to make sure there is a protocol fee recipient to set the fee.
+    //     vm.prank(gov);
+    //     IFactory(factory).set_protocol_fee_recipient(gov);
 
-        vm.prank(gov);
-        IFactory(factory).set_protocol_fee_bps(_protocolFee);
+    //     vm.prank(gov);
+    //     IFactory(factory).set_protocol_fee_bps(_protocolFee);
 
-        vm.prank(management);
-        strategy.setPerformanceFee(_performanceFee);
-    }
+    //     vm.prank(management);
+    //     strategy.setPerformanceFee(_performanceFee);
+    // }
 
     function _setTokenAddrs() internal {
         tokenAddrs["WBTC"] = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;