# Strategy.sol#Strategy

[Git Source](https://github.com/term-finance/yearn-v3-term-vault/blob/fdab68ac51eb0929f23686f72922fed45a3d7d1d/src/Strategy.sol)

**Inherits:** BaseStrategy, Pausable, AccessControl

The `TokenizedStrategy` variable can be used to retrieve the strategies specific storage data your contract. i.e. uint256 totalAssets = TokenizedStrategy.totalAssets() This can not be used for write functions. Any TokenizedStrategy variables that need to be updated post deployment will need to come from an external call from the strategies specific `management`.

## State Variables

### GOVERNOR\_ROLE

```solidity
bytes32 internal constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE");
```

### TERM\_VAULT\_EVENT\_EMITTER

```solidity
ITermVaultEvents internal immutable TERM_VAULT_EVENT_EMITTER;
```

### PURCHASE\_TOKEN\_PRECISION

```solidity
uint256 internal immutable PURCHASE_TOKEN_PRECISION;
```

### YEARN\_VAULT

```solidity
IERC4626 internal immutable YEARN_VAULT;
```

### depositLock

State variables

```solidity
bool internal depositLock;
```

### pendingGovernor

```solidity
address internal pendingGovernor;
```

### repoTokenListData

```solidity
RepoTokenListData internal repoTokenListData;
```

### termAuctionListData

```solidity
TermAuctionListData internal termAuctionListData;
```

### tokenSymbol

```solidity
string internal tokenSymbol;
```

### strategyState

```solidity
StrategyState public strategyState;
```

### repoTokenBlacklist

```solidity
mapping(address => bool) public repoTokenBlacklist;
```

## Functions

### notBlacklisted

```solidity
modifier notBlacklisted(address repoToken);
```

### pauseDeposit

Pause the contract

```solidity
function pauseDeposit() external onlyRole(GOVERNOR_ROLE);
```

### unpauseDeposit

Unpause the contract

```solidity
function unpauseDeposit() external onlyRole(GOVERNOR_ROLE);
```

### pauseStrategy

Pause the contract

```solidity
function pauseStrategy() external onlyRole(GOVERNOR_ROLE);
```

### unpauseStrategy

Unpause the contract

```solidity
function unpauseStrategy() external onlyRole(GOVERNOR_ROLE);
```

### setPendingGovernor

```solidity
function setPendingGovernor(address newGovernor) external onlyRole(GOVERNOR_ROLE);
```

### acceptGovernor

```solidity
function acceptGovernor() external;
```

### setTermController

Set the term controller

```solidity
function setTermController(address newTermControllerAddr) external onlyRole(GOVERNOR_ROLE);
```

**Parameters**

| Name                    | Type      | Description                            |
| ----------------------- | --------- | -------------------------------------- |
| `newTermControllerAddr` | `address` | The address of the new term controller |

### setDiscountRateAdapter

Set the discount rate adapter used to price repoTokens

```solidity
function setDiscountRateAdapter(address newAdapter) external onlyRole(GOVERNOR_ROLE);
```

**Parameters**

| Name         | Type      | Description                                  |
| ------------ | --------- | -------------------------------------------- |
| `newAdapter` | `address` | The address of the new discount rate adapter |

### setTimeToMaturityThreshold

Set the weighted time to maturity cap

```solidity
function setTimeToMaturityThreshold(uint256 newTimeToMaturityThreshold) external onlyRole(GOVERNOR_ROLE);
```

**Parameters**

| Name                         | Type      | Description                           |
| ---------------------------- | --------- | ------------------------------------- |
| `newTimeToMaturityThreshold` | `uint256` | The new weighted time to maturity cap |

### setRequiredReserveRatio

Set the required reserve ratio

*This function can only be called by management*

```solidity
function setRequiredReserveRatio(uint256 newRequiredReserveRatio) external onlyRole(GOVERNOR_ROLE);
```

**Parameters**

| Name                      | Type      | Description                                        |
| ------------------------- | --------- | -------------------------------------------------- |
| `newRequiredReserveRatio` | `uint256` | The new required reserve ratio (in 1e18 precision) |

### setRepoTokenConcentrationLimit

Set the repoToken concentration limit

```solidity
function setRepoTokenConcentrationLimit(uint256 newRepoTokenConcentrationLimit) external onlyRole(GOVERNOR_ROLE);
```

**Parameters**

| Name                             | Type      | Description                           |
| -------------------------------- | --------- | ------------------------------------- |
| `newRepoTokenConcentrationLimit` | `uint256` | The new repoToken concentration limit |

### setDiscountRateMarkup

Set the markup that the vault will receive in excess of the oracle rate

```solidity
function setDiscountRateMarkup(uint256 newDiscountRateMarkup) external onlyRole(GOVERNOR_ROLE);
```

**Parameters**

| Name                    | Type      | Description                 |
| ----------------------- | --------- | --------------------------- |
| `newDiscountRateMarkup` | `uint256` | The new auction rate markup |

### setCollateralTokenParams

Set the collateral token parameters

```solidity
function setCollateralTokenParams(address tokenAddr, uint256 minCollateralRatio) external onlyRole(GOVERNOR_ROLE);
```

**Parameters**

| Name                 | Type      | Description                                           |
| -------------------- | --------- | ----------------------------------------------------- |
| `tokenAddr`          | `address` | The address of the collateral token to be accepted    |
| `minCollateralRatio` | `uint256` | The minimum collateral ratio accepted by the strategy |

### setRepoTokenBlacklist

```solidity
function setRepoTokenBlacklist(address repoToken, bool blacklisted) external onlyRole(GOVERNOR_ROLE);
```

### symbol

```solidity
function symbol() external view returns (string memory);
```

### totalAssetValue

Calculates the total value of all assets managed by the strategy

*This function aggregates the total liquid balance, the present value of all repoTokens, and the present value of all pending offers to calculate the total asset value.*

```solidity
function totalAssetValue() external view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                           |
| -------- | --------- | ----------------------------------------------------- |
| `<none>` | `uint256` | The total asset value in the purchase token precision |

### totalLiquidBalance

Get the total liquid balance of the assets managed by the strategy

*This function aggregates the balance of the underlying asset held directly by the strategy and the balance of the asset held in the Yearn Vault to calculate the total liquid balance.*

```solidity
function totalLiquidBalance() external view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                              |
| -------- | --------- | -------------------------------------------------------- |
| `<none>` | `uint256` | The total liquid balance in the purchase token precision |

### \_liquidReserveRatio

Calculate the liquid reserve ratio

*This function calculates the ratio of liquid balance to total asset value. It returns 0 if the total asset value is 0 to avoid division by zero.*

```solidity
function _liquidReserveRatio(uint256 liquidBalance) internal view returns (uint256);
```

**Parameters**

| Name            | Type      | Description                                |
| --------------- | --------- | ------------------------------------------ |
| `liquidBalance` | `uint256` | The current liquid balance of the strategy |

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The liquid reserve ratio in 1e18 precision |

### liquidReserveRatio

Get the current liquid reserve ratio of the strategy

*This function calculates the liquid reserve ratio based on the current total liquid balance of the strategy.*

```solidity
function liquidReserveRatio() external view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                        |
| -------- | --------- | -------------------------------------------------- |
| `<none>` | `uint256` | The current liquid reserve ratio in 1e18 precision |

### repoTokenHoldings

Returns an array of addresses representing the repoTokens currently held by the strategy

*This function calls the `holdings` function from the `RepoTokenList` library to get the list of repoTokens currently held in the `RepoTokenListData` structure.*

```solidity
function repoTokenHoldings() external view returns (address[] memory);
```

**Returns**

| Name     | Type        | Description                                                             |
| -------- | ----------- | ----------------------------------------------------------------------- |
| `<none>` | `address[]` | address\[] An array of addresses of the repoTokens held by the strategy |

### pendingOffers

Get an array of pending offers submitted into Term auctions

*This function calls the `pendingOffers` function from the `TermAuctionList` library to get the list of pending offers currently submitted into Term auctions from the `TermAuctionListData` structure.*

```solidity
function pendingOffers() external view returns (bytes32[] memory);
```

**Returns**

| Name     | Type        | Description                                                                        |
| -------- | ----------- | ---------------------------------------------------------------------------------- |
| `<none>` | `bytes32[]` | bytes32\[] An array of `bytes32` values representing the IDs of the pending offers |

### getRepoTokenConcentrationRatio

Calculate the concentration ratio of a specific repoToken in the strategy

*This function computes the current concentration ratio of a specific repoToken in the strategy's portfolio. It reverts if the repoToken address is zero. The calculation is based on the current total asset value and does not consider any additional purchases or removals of the repoToken.*

```solidity
function getRepoTokenConcentrationRatio(address repoToken) external view returns (uint256);
```

**Parameters**

| Name        | Type      | Description                                                     |
| ----------- | --------- | --------------------------------------------------------------- |
| `repoToken` | `address` | The address of the repoToken to calculate the concentration for |

**Returns**

| Name     | Type      | Description                                                                  |
| -------- | --------- | ---------------------------------------------------------------------------- |
| `<none>` | `uint256` | The concentration ratio of the repoToken in the strategy (in 1e18 precision) |

### simulateTransaction

Simulates the weighted time to maturity for a specified repoToken and amount, including the impact on the entire strategy's holdings

\*This function simulates the effects of a potential transaction on the strategy's key metrics. It calculates the new weighted time to maturity and liquidity ratio, considering the specified repoToken and amount. For existing repoTokens, use address(0) as the repoToken parameter. The function performs various checks and calculations, including:

* Validating the repoToken (if not address(0))
* Calculating the present value of the transaction
* Estimating the impact on the strategy's liquid balance
* Computing the new weighted maturity and liquidity ratio\*

```solidity
function simulateTransaction(address repoToken, uint256 amount)
    external
    view
    returns (
        uint256 simulatedWeightedMaturity,
        uint256 simulatedRepoTokenConcentrationRatio,
        uint256 simulatedLiquidityRatio
    );
```

**Parameters**

| Name        | Type      | Description                                  |
| ----------- | --------- | -------------------------------------------- |
| `repoToken` | `address` | The address of the repoToken to be simulated |
| `amount`    | `uint256` | The amount of the repoToken to be simulated  |

**Returns**

| Name                                   | Type      | Description                                                                  |
| -------------------------------------- | --------- | ---------------------------------------------------------------------------- |
| `simulatedWeightedMaturity`            | `uint256` | The simulated weighted time to maturity for the entire strategy              |
| `simulatedRepoTokenConcentrationRatio` | `uint256` | The concentration ratio of the repoToken in the strategy (in 1e18 precision) |
| `simulatedLiquidityRatio`              | `uint256` | The simulated liquidity ratio after the transaction                          |

### calculateRepoTokenPresentValue

Calculates the present value of a specified repoToken based on its discount rate, redemption timestamp, and amount

*This function retrieves the redemption timestamp, calculates the repoToken precision, normalizes the repoToken amount to base asset precision, and calculates the present value using the provided discount rate and redemption timestamp.*

```solidity
function calculateRepoTokenPresentValue(address repoToken, uint256 discountRate, uint256 amount)
    public
    view
    returns (uint256);
```

**Parameters**

| Name           | Type      | Description                                                   |
| -------------- | --------- | ------------------------------------------------------------- |
| `repoToken`    | `address` | The address of the repoToken                                  |
| `discountRate` | `uint256` | The discount rate to be used in the present value calculation |
| `amount`       | `uint256` | The amount of the repoToken to be discounted                  |

**Returns**

| Name     | Type      | Description                                                     |
| -------- | --------- | --------------------------------------------------------------- |
| `<none>` | `uint256` | uint256 The present value of the specified repoToken and amount |

### getRepoTokenHoldingValue

Calculates the present value of a specified repoToken held by the strategy

*This function calculates the present value of the specified repoToken from both the `repoTokenListData` and `termAuctionListData` structures, then sums these values to provide a comprehensive valuation.*

```solidity
function getRepoTokenHoldingValue(address repoToken) public view returns (uint256);
```

**Parameters**

| Name        | Type      | Description                           |
| ----------- | --------- | ------------------------------------- |
| `repoToken` | `address` | The address of the repoToken to value |

**Returns**

| Name     | Type      | Description                                          |
| -------- | --------- | ---------------------------------------------------- |
| `<none>` | `uint256` | uint256 The present value of the specified repoToken |

### \_withdrawAsset

*Withdraw assets from the Yearn vault*

```solidity
function _withdrawAsset(uint256 amount) private;
```

**Parameters**

| Name     | Type      | Description            |
| -------- | --------- | ---------------------- |
| `amount` | `uint256` | The amount to withdraw |

### \_assetBalance

*Retrieves the asset balance from the Yearn Vault*

```solidity
function _assetBalance() private view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                           |
| -------- | --------- | ----------------------------------------------------- |
| `<none>` | `uint256` | The balance of assets in the purchase token precision |

### \_totalLiquidBalance

Calculates the total liquid balance of the assets managed by the strategy

*This function aggregates the balance of the underlying asset held directly by the strategy and the balance of the asset held in the Yearn Vault to calculate the total liquid balance.*

```solidity
function _totalLiquidBalance() private view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                    |
| -------- | --------- | ---------------------------------------------- |
| `<none>` | `uint256` | uint256 The total liquid balance of the assets |

### \_totalAssetValue

Calculates the total value of all assets managed by the strategy (internal function)

*This function aggregates the total liquid balance, the present value of all repoTokens, and the present value of all pending offers to calculate the total asset value.*

```solidity
function _totalAssetValue(uint256 liquidBalance) internal view returns (uint256 totalValue);
```

**Returns**

| Name         | Type      | Description                   |
| ------------ | --------- | ----------------------------- |
| `totalValue` | `uint256` | The total value of all assets |

### \_getRepoTokenConcentrationRatio

Calculates the concentration ratio of a specific repoToken in the strategy

*This function computes the concentration ratio of a specific repoToken, considering both existing holdings and a potential new addition. It adjusts the total asset value, normalizes values to 1e18 precision, and handles the case where total asset value might be zero.*

```solidity
function _getRepoTokenConcentrationRatio(
    address repoToken,
    uint256 repoTokenAmountInBaseAssetPrecision,
    uint256 assetValue,
    uint256 liquidBalanceToRemove
) private view returns (uint256);
```

**Parameters**

| Name                                  | Type      | Description                                                     |
| ------------------------------------- | --------- | --------------------------------------------------------------- |
| `repoToken`                           | `address` | The address of the repoToken to calculate the concentration for |
| `repoTokenAmountInBaseAssetPrecision` | `uint256` | The amount of the repoToken in base asset precision to be added |
| `assetValue`                          | `uint256` | The current total asset value of the strategy                   |
| `liquidBalanceToRemove`               | `uint256` | The amount of liquid balance to be removed from the strategy    |

**Returns**

| Name     | Type      | Description                                                                  |
| -------- | --------- | ---------------------------------------------------------------------------- |
| `<none>` | `uint256` | The concentration ratio of the repoToken in the strategy (in 1e18 precision) |

### \_validateRepoTokenConcentration

Validate the concentration of a repoToken against the strategy's limit

*This function calculates the concentration ratio of the specified repoToken and compares it against the predefined concentration limit. It reverts with a RepoTokenConcentrationTooHigh error if the concentration exceeds the limit.*

```solidity
function _validateRepoTokenConcentration(
    address repoToken,
    uint256 repoTokenAmountInBaseAssetPrecision,
    uint256 assetValue,
    uint256 liquidBalanceToRemove
) private view;
```

**Parameters**

| Name                                  | Type      | Description                                                  |
| ------------------------------------- | --------- | ------------------------------------------------------------ |
| `repoToken`                           | `address` | The address of the repoToken to validate                     |
| `repoTokenAmountInBaseAssetPrecision` | `uint256` | The amount of the repoToken in base asset precision          |
| `assetValue`                          | `uint256` | The current total asset value of the strategy                |
| `liquidBalanceToRemove`               | `uint256` | The amount of liquid balance to be removed from the strategy |

### \_calculateWeightedMaturity

Calculates the weighted time to maturity for the strategy's holdings, including the impact of a specified repoToken and amount

*This function aggregates the cumulative weighted time to maturity and the cumulative amount of both existing repoTokens and offers, then calculates the weighted time to maturity for the entire strategy. It considers both repoTokens and auction offers. The `repoToken` and `repoTokenAmount` parameters are optional and provide flexibility to adjust the calculations to include the provided repoToken amount. If `repoToken` is set to `address(0)` or `repoTokenAmount` is `0`, the function calculates the cumulative data without specific token adjustments.*

```solidity
function _calculateWeightedMaturity(address repoToken, uint256 repoTokenAmount, uint256 liquidBalance)
    private
    view
    returns (uint256);
```

**Parameters**

| Name              | Type      | Description                                                   |
| ----------------- | --------- | ------------------------------------------------------------- |
| `repoToken`       | `address` | The address of the repoToken (optional)                       |
| `repoTokenAmount` | `uint256` | The amount of the repoToken to be included in the calculation |
| `liquidBalance`   | `uint256` | The liquid balance of the strategy                            |

**Returns**

| Name     | Type      | Description                                                                                                            |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | uint256 The weighted time to maturity in seconds for the entire strategy, including the specified repoToken and amount |

### \_isTermDeployed

Checks if a term contract is marked as deployed in either the current or previous term controller

*This function first checks the current term controller, then the previous one if necessary. It handles cases where either controller might be unset (address(0)).*

```solidity
function _isTermDeployed(address termContract) private view returns (bool);
```

**Parameters**

| Name           | Type      | Description                               |
| -------------- | --------- | ----------------------------------------- |
| `termContract` | `address` | The address of the term contract to check |

**Returns**

| Name     | Type   | Description                                                 |
| -------- | ------ | ----------------------------------------------------------- |
| `<none>` | `bool` | bool True if the term contract is deployed, false otherwise |

### \_redeemRepoTokens

Rebalances the strategy's assets by sweeping assets and redeeming matured repoTokens

*This function removes completed auction offers, redeems matured repoTokens, and adjusts the underlying balance to maintain the required liquidity. It ensures that the strategy has sufficient liquid assets while optimizing asset allocation.*

```solidity
function _redeemRepoTokens(uint256 liquidAmountRequired) private;
```

**Parameters**

| Name                   | Type      | Description                                                           |
| ---------------------- | --------- | --------------------------------------------------------------------- |
| `liquidAmountRequired` | `uint256` | The amount of liquid assets required to be maintained by the strategy |

### \_validateAndGetOfferLocker

Validates a term auction and repo token, and retrieves the associated offer locker

*This function performs several validation steps: verifying term auction and repo token deployment, matching repo token to auction's term repo ID, validating repo token against strategy requirements, and ensuring the auction is open. It reverts with specific error messages on validation failures.*

```solidity
function _validateAndGetOfferLocker(ITermAuction termAuction, address repoToken)
    private
    view
    returns (ITermAuctionOfferLocker);
```

**Parameters**

| Name          | Type           | Description                           |
| ------------- | -------------- | ------------------------------------- |
| `termAuction` | `ITermAuction` | The term auction contract to validate |
| `repoToken`   | `address`      | The repo token address to validate    |

**Returns**

| Name     | Type                      | Description                                                                         |
| -------- | ------------------------- | ----------------------------------------------------------------------------------- |
| `<none>` | `ITermAuctionOfferLocker` | ITermAuctionOfferLocker The offer locker associated with the validated term auction |

### submitAuctionOffer

Submits an offer into a term auction for a specified repoToken

*This function validates the underlying repoToken, checks concentration limits, ensures the auction is open, and rebalances liquidity to support the offer submission. It handles both new offers and edits to existing offers.*

```solidity
function submitAuctionOffer(
    ITermAuction termAuction,
    address repoToken,
    bytes32 idHash,
    bytes32 offerPriceHash,
    uint256 purchaseTokenAmount
) external whenNotPaused notBlacklisted(repoToken) onlyManagement returns (bytes32[] memory offerIds);
```

**Parameters**

| Name                  | Type           | Description                                 |
| --------------------- | -------------- | ------------------------------------------- |
| `termAuction`         | `ITermAuction` | The address of the term auction             |
| `repoToken`           | `address`      | The address of the repoToken                |
| `idHash`              | `bytes32`      | The hash of the offer ID                    |
| `offerPriceHash`      | `bytes32`      | The hash of the offer price                 |
| `purchaseTokenAmount` | `uint256`      | The amount of purchase tokens being offered |

**Returns**

| Name       | Type        | Description                                    |
| ---------- | ----------- | ---------------------------------------------- |
| `offerIds` | `bytes32[]` | An array of offer IDs for the submitted offers |

### \_submitOffer

*Submits an offer to a term auction and locks it using the offer locker.*

```solidity
function _submitOffer(
    ITermAuction auction,
    ITermAuctionOfferLocker offerLocker,
    ITermAuctionOfferLocker.TermAuctionOfferSubmission memory offer,
    address repoToken,
    uint256 newOfferAmount,
    uint256 currentOfferAmount
) private returns (bytes32[] memory offerIds);
```

**Parameters**

| Name                 | Type                                                 | Description                                   |
| -------------------- | ---------------------------------------------------- | --------------------------------------------- |
| `auction`            | `ITermAuction`                                       | The term auction contract                     |
| `offerLocker`        | `ITermAuctionOfferLocker`                            | The offer locker contract                     |
| `offer`              | `ITermAuctionOfferLocker.TermAuctionOfferSubmission` | The offer details                             |
| `repoToken`          | `address`                                            | The address of the repoToken                  |
| `newOfferAmount`     | `uint256`                                            | The amount of the new offer                   |
| `currentOfferAmount` | `uint256`                                            | The amount of the current offer, if it exists |

**Returns**

| Name       | Type        | Description                                    |
| ---------- | ----------- | ---------------------------------------------- |
| `offerIds` | `bytes32[]` | An array of offer IDs for the submitted offers |

### deleteAuctionOffers

*Removes specified offers from a term auction and performs related cleanup.*

```solidity
function deleteAuctionOffers(address termAuction, bytes32[] calldata offerIds) external onlyManagement;
```

**Parameters**

| Name          | Type        | Description                                                        |
| ------------- | ----------- | ------------------------------------------------------------------ |
| `termAuction` | `address`   | The address of the term auction from which offers will be deleted. |
| `offerIds`    | `bytes32[]` | An array of offer IDs to be deleted.                               |

### auctionClosed

Required for post-processing after auction clos

```solidity
function auctionClosed() external;
```

### sellRepoToken

Allows the sale of a specified amount of a repoToken in exchange for assets.

```solidity
function sellRepoToken(address repoToken, uint256 repoTokenAmount) external whenNotPaused notBlacklisted(repoToken);
```

**Parameters**

| Name              | Type      | Description                              |
| ----------------- | --------- | ---------------------------------------- |
| `repoToken`       | `address` | The address of the repoToken to be sold. |
| `repoTokenAmount` | `uint256` | The amount of the repoToken to be sold.  |

### constructor

Constructor to initialize the Strategy contract

```solidity
constructor(string memory _name, string memory _symbol, StrategyParams memory _params)
    BaseStrategy(_params._asset, _name);
```

**Parameters**

| Name      | Type             | Description              |
| --------- | ---------------- | ------------------------ |
| `_name`   | `string`         | The name of the strategy |
| `_symbol` | `string`         |                          |
| `_params` | `StrategyParams` |                          |

### \_deployFunds

*Can deploy up to '\_amount' of 'asset' in the yield source. This function is called at the end of a {deposit} or {mint} call. Meaning that unless a whitelist is implemented it will be entirely permissionless and thus can be sandwiched or otherwise manipulated.*

```solidity
function _deployFunds(uint256 _amount) internal override whenNotPaused;
```

**Parameters**

| Name      | Type      | Description                                                                         |
| --------- | --------- | ----------------------------------------------------------------------------------- |
| `_amount` | `uint256` | The amount of 'asset' that the strategy can attempt to deposit in the yield source. |

### \_freeFunds

*Should attempt to free the '\_amount' of 'asset'. NOTE: The amount of 'asset' that is already loose has already been accounted for. This function is called during {withdraw} and {redeem} calls. Meaning that unless a whitelist is implemented it will be entirely permissionless and thus can be sandwiched or otherwise manipulated. Should not rely on asset.balanceOf(address(this)) calls other than for diff accounting purposes. Any difference between `_amount` and what is actually freed will be counted as a loss and passed on to the withdrawer. This means care should be taken in times of illiquidity. It may be better to revert if withdraws are simply illiquid so not to realize incorrect losses.*

```solidity
function _freeFunds(uint256 _amount) internal override whenNotPaused;
```

**Parameters**

| Name      | Type      | Description |
| --------- | --------- | ----------- |
| `_amount` | `uint256` |             |

### \_harvestAndReport

*Internal function to harvest all rewards, redeploy any idle funds and return an accurate accounting of all funds currently held by the Strategy. This should do any needed harvesting, rewards selling, accrual, redepositing etc. to get the most accurate view of current assets. NOTE: All applicable assets including loose assets should be accounted for in this function. Care should be taken when relying on oracles or swap values rather than actual amounts as all Strategy profit/loss accounting will be done based on this returned value. This can still be called post a shutdown, a strategist can check `TokenizedStrategy.isShutdown()` to decide if funds should be redeployed or simply realize any profits/losses.*

```solidity
function _harvestAndReport() internal override whenNotPaused returns (uint256 _totalAssets);
```

**Returns**

| Name           | Type      | Description                                                                                                       |
| -------------- | --------- | ----------------------------------------------------------------------------------------------------------------- |
| `_totalAssets` | `uint256` | A trusted and accurate account for the total amount of 'asset' the strategy currently holds including idle funds. |

### availableWithdrawLimit

Gets the max amount of `asset` that can be withdrawn.

*Defaults to an unlimited amount for any address. But can be overridden by strategists. This function will be called before any withdraw or redeem to enforce any limits desired by the strategist. This can be used for illiquid or sandwichable strategies. EX: return asset.balanceOf(yieldSource); This does not need to take into account the `_owner`'s share balance or conversion rates from shares to assets.*

```solidity
function availableWithdrawLimit(address) public view override returns (uint256);
```

**Parameters**

| Name     | Type      | Description |
| -------- | --------- | ----------- |
| `<none>` | `address` |             |

**Returns**

| Name     | Type      | Description                                                      |
| -------- | --------- | ---------------------------------------------------------------- |
| `<none>` | `uint256` | . The available amount that can be withdrawn in terms of `asset` |

## Errors

### InvalidTermAuction

```solidity
error InvalidTermAuction(address auction);
```

### TimeToMaturityAboveThreshold

```solidity
error TimeToMaturityAboveThreshold();
```

### BalanceBelowRequiredReserveRatio

```solidity
error BalanceBelowRequiredReserveRatio();
```

### InsufficientLiquidBalance

```solidity
error InsufficientLiquidBalance(uint256 have, uint256 want);
```

### RepoTokenConcentrationTooHigh

```solidity
error RepoTokenConcentrationTooHigh(address repoToken);
```

### RepoTokenBlacklisted

```solidity
error RepoTokenBlacklisted(address repoToken);
```

### DepositPaused

```solidity
error DepositPaused();
```

### AuctionNotOpen

```solidity
error AuctionNotOpen();
```

### ZeroPurchaseTokenAmount

```solidity
error ZeroPurchaseTokenAmount();
```

### OfferNotFound

```solidity
error OfferNotFound();
```

## Structs

### StrategyParams

Constructor to initialize the Strategy contract

```solidity
struct StrategyParams {
    address _asset;
    address _yearnVault;
    address _discountRateAdapter;
    address _eventEmitter;
    address _governorAddress;
    address _termController;
    uint256 _repoTokenConcentrationLimit;
    uint256 _timeToMaturityThreshold;
    uint256 _requiredReserveRatio;
    uint256 _discountRateMarkup;
}
```

**Properties**

| Name                           | Type      | Description                              |
| ------------------------------ | --------- | ---------------------------------------- |
| `_asset`                       | `address` | The address of the asset                 |
| `_yearnVault`                  | `address` | The address of the Yearn vault           |
| `_discountRateAdapter`         | `address` | The address of the discount rate adapter |
| `_eventEmitter`                | `address` | The address of the event emitter         |
| `_governorAddress`             | `address` | The address of the governor              |
| `_termController`              | `address` | The address of the term controller       |
| `_repoTokenConcentrationLimit` | `uint256` | The concentration limit for repoTokens   |
| `_timeToMaturityThreshold`     | `uint256` | The time to maturity threshold           |
| `_requiredReserveRatio`        | `uint256` | The required reserve ratio               |
| `_discountRateMarkup`          | `uint256` | The discount rate markup                 |

### StrategyState

```solidity
struct StrategyState {
    address assetVault;
    address eventEmitter;
    address governorAddress;
    ITermController prevTermController;
    ITermController currTermController;
    ITermDiscountRateAdapter discountRateAdapter;
    uint256 timeToMaturityThreshold;
    uint256 requiredReserveRatio;
    uint256 discountRateMarkup;
    uint256 repoTokenConcentrationLimit;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.term.finance/periphery-contracts/curated-vaults/solidity-api-latest/strategy.sol-strategy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
