ERC4626Strategy
Inherits: BaseHealthCheck
Title: ERC4626Strategy
Author: Golem Foundation
Yield-donating strategy that compounds rewards from any ERC4626-compliant vault
Deposits assets into an ERC4626 vault to earn yield which is donated via BaseHealthCheck's profit minting mechanism YIELD FLOW:
- Deposits assets into ERC4626 vault
- Vault generates yield through its specific strategies
- On report, profit is minted as shares to donation address COMPATIBILITY:
- Works with any standard ERC4626 vault (Spark, Yearn v3, etc.)
- Vault must have manipulation-resistant convertToAssets implementation
INTEGRATOR WARNING — per-target audit required:
ERC-4626 compliance is a spec-level claim. Several production vaults that
advertise conformance still have edge cases that break the semantics this
strategy relies on (in particular
availableDepositLimit/availableWithdrawLimit, which trust the target vault'smaxDeposit/maxWithdrawat face value): - MetaMorpho-style vaults can return
maxDeposit == 0as a normal operating state while their curator reallocates liquidity across markets. Deposits must be expected to fail with "deposit more than max" during those windows even though the strategy code is correct. - Euler-V2-style vaults'
max*values can be inaccurate once hooks are installed on the vault — the vault's own documentation notes that "some hook configurations may cause the vault to not be fully ERC-4626 compliant". Every target vault MUST be studied and audited individually before this strategy is deployed against it. Do not treat ERC-4626 conformance as a blanket security guarantee.
Notes:
-
security-contact: [email protected]
-
security: ERC4626 vault convertToAssets must be manipulation-resistant
-
security: Target vault must be audited individually before deployment
ERC-4626 compatibility alone is not enough. Each target vault needs protocol-specific review before use, especially around previews, fees, liquidity, and share inflation behavior.
Quick Start - What Matters Most
This is the generic ERC-4626 yield-donating adapter. In .6 it uses exact per-deposit approvals, reverts when a deposit mints zero shares, clears allowances after deposit, preserves unlimited target-vault capacity sentinels, and reports assets with previewRedeem.
State Variables
targetVault
Address of the ERC4626 vault this strategy deposits into
Must implement IERC4626 interface and use the same asset as this strategy
address public immutable targetVault
Functions
constructor
Initializes the ERC4626 strategy
Validates asset matches target vault's asset. Approval is issued per-deposit inside _deployFunds and explicitly cleared after the target vault call, so no standing allowance against the external (upgradeable) target vault exists between calls.
constructor(
address _targetVault,
address _asset,
string memory _name,
string memory _symbol,
address _management,
address _keeper,
address _emergencyAdmin,
address _donationAddress,
bool _enableBurning,
address _tokenizedStrategyAddress
)
BaseHealthCheck(
_asset,
_name,
_symbol,
_management,
_keeper,
_emergencyAdmin,
_donationAddress,
_enableBurning,
_tokenizedStrategyAddress
);
Parameters
| Name | Type | Description |
|---|---|---|
_targetVault | address | Address of the ERC4626 vault this strategy deposits into |
_asset | address | Address of the underlying asset (must match target vault's asset) |
_name | string | Strategy display name (e.g., "Octant ERC4626 Strategy") |
_symbol | string | Strategy token symbol (e.g., "osERC4626") |
_management | address | Address with management permissions |
_keeper | address | Address authorized to call report() and tend() |
_emergencyAdmin | address | Address authorized for emergency shutdown |
_donationAddress | address | Address receiving minted profit shares |
_enableBurning | bool | True to enable loss protection via share burning |
_tokenizedStrategyAddress | address | Address of TokenizedStrategy implementation contract |
availableDepositLimit
Returns maximum additional assets that can be deposited
Queries target vault's maxDeposit and subtracts idle balance
function availableDepositLimit(
address /*_owner*/
)
public
view
override
returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | limit Maximum additional deposit amount in asset base units |
availableWithdrawLimit
Returns maximum assets withdrawable without expected loss
Sums idle balance and target vault's maxWithdraw
function availableWithdrawLimit(
address /*_owner*/
)
public
view
override
returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | limit Maximum withdrawal amount in asset base units |
_deployFunds
Deposits idle assets into ERC4626 vault
function _deployFunds(uint256 _amount) internal override;
Parameters
| Name | Type | Description |
|---|---|---|
_amount | uint256 | Amount of assets to deploy in asset base units |
_freeFunds
Withdraws assets from ERC4626 vault
Note:
security: withdraw returns shares burned, not assets received.
TokenizedStrategy._withdraw measures the post-call
asset balance and applies the caller's max-loss limit.
function _freeFunds(uint256 _amount) internal override;
Parameters
| Name | Type | Description |
|---|---|---|
_amount | uint256 | Amount of assets to withdraw in asset base units |
_emergencyWithdraw
Emergency withdrawal after strategy shutdown
function _emergencyWithdraw(uint256 _amount) internal override;
Parameters
| Name | Type | Description |
|---|---|---|
_amount | uint256 | Amount of assets to withdraw in asset base units |
_harvestAndReport
Reports current total assets under management
function _harvestAndReport() internal view override returns (uint256 _totalAssets);
Returns
| Name | Type | Description |
|---|---|---|
_totalAssets | uint256 | Sum of target vault value and idle assets in asset base units |