> For the complete documentation index, see [llms.txt](https://flowdex-fi.gitbook.io/flowdex/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://flowdex-fi.gitbook.io/flowdex/for-developers/strategy-contract.md).

# Strategy Contract

Strategy Contracts are the core of FlowDex's yield generation, enabling autocompounding of rewards from various staking protocols. They handle three key steps: (1) staking deposited tokens, (2) harvesting rewards, and (3) reinvesting rewards to maximize yield.

Each Strategy Contract interacts with a Vault Contract to manage user deposits, ensuring risks are isolated from user funds.

### **Dependencies**

* **StratFeeManager Contract:** Manages fee distribution.
* **GasOptimizer Contract:** Optimizes gas usage for transactions.

### **Interfaces**

* **Router Interface:** Facilitates token swaps (e.g., IUniswapRouterETH.sol).
* **Liquidity Pool Interface:** Interacts with underlying liquidity pools (e.g., IUniswapV2Pair.sol).
* **Chef Interface:** Manages staking farms and rewards (e.g., IMiniChefV2.sol).

### **View Functions**

**1. `balanceOf()`**

Returns the total amount of the underlying token (e.g., ETH) stored in the strategy.

```solidity
function balanceOf() public view returns (uint256) {
    return balanceOfWant() + balanceOfPool();
}
```

**2. `balanceOfWant()`**

Returns the amount of the underlying token held directly by the strategy.

```solidity
function balanceOfWant() public view returns (uint256) {
    return IERC20(want).balanceOf(address(this));
}
```

**3. `balanceOfPool()`**

Returns the amount of the underlying token staked in the external protocol.

```solidity
function balanceOfPool() public view returns (uint256) {
    (uint256 _amount, ) = IMiniChefV2(chef).userInfo(poolId, address(this));
    return _amount;
}
```

**4. `rewardsAvailable()`**

Returns the amount of pending rewards available for harvest.

```solidity
function rewardsAvailable() public view returns (uint256) {
    return IMiniChefV2(chef).pendingSushi(poolId, address(this));
}
```

### **Write Functions**

**1. `deposit()`**

Deposits the underlying token into the external staking protocol.

```solidity
function deposit() public whenNotPaused {
    uint256 wantBal = IERC20(want).balanceOf(address(this));
    if (wantBal > 0) {
        IMiniChefV2(chef).deposit(poolId, wantBal, address(this));
        emit Deposit(balanceOf());
    }
}
```

**2. `withdraw(uint256 _amount)`**

Withdraws the underlying token from the external protocol and transfers it back to the Vault.

```solidity
function withdraw(uint256 _amount) external {
    require(msg.sender == vault, "!vault");
    uint256 wantBal = IERC20(want).balanceOf(address(this));
    if (wantBal < _amount) {
        IMiniChefV2(chef).withdraw(poolId, _amount.sub(wantBal), address(this));
    }
    IERC20(want).safeTransfer(vault, wantBal);
    emit Withdraw(balanceOf());
}
```

**3. `harvest()`**

Harvests rewards, charges fees, and reinvests the remaining rewards.

```solidity
function harvest() external virtual gasThrottle {
    IMiniChefV2(chef).harvest(poolId, address(this));
    uint256 outputBal = IERC20(output).balanceOf(address(this));
    if (outputBal > 0) {
        chargeFees(tx.origin);
        addLiquidity();
        deposit();
        emit StratHarvest(msg.sender, balanceOfWant(), balanceOf());
    }
}
```

**4. `panic()`**

Withdraws all funds from the external protocol in case of emergencies.

```solidity
function panic() public onlyManager {
    pause();
    IMiniChefV2(chef).emergencyWithdraw(poolId, address(this));
}
```

### **Additional Functions**

* **`setHarvestOnDeposit(bool _harvestOnDeposit)`:** Toggles harvesting on deposit.
* **`beforeDeposit()`:** Ensures rewards are harvested before new deposits.
* **`retireStrat()`:** Withdraws all funds and transfers them back to the Vault.

### **Security**

* **ReentrancyGuard:** Prevents reentrancy attacks.
* **Pausable:** Allows pausing of critical functions during emergencies.
* **Fee Management:** Ensures fair distribution of fees.
