YieldShift
Inherits: Initializable, ReentrancyGuardUpgradeable, AccessControlUpgradeable, PausableUpgradeable, SecureUpgradeable
Title: YieldShift
Author: Quantillon Labs - Nicolas Bellengé - @chewbaccoin
Dynamic yield distribution system balancing rewards between users and hedgers
Main characteristics:
- Dynamic yield allocation based on pool balance ratios
- Time-weighted average price (TWAP) calculations for stability
- Multiple yield sources integration (Aave, fees, interest differentials)
- Automatic yield distribution with holding period requirements
- Emergency pause mechanism for crisis situations
- Upgradeable via UUPS pattern
Yield shift mechanics:
- Base yield shift determines default allocation (default 50/50)
- Maximum yield shift caps allocation changes (default 90/10)
- Adjustment speed controls how quickly shifts occur
- Target pool ratio defines optimal balance point
- Real-time calculations based on pool metrics
Distribution algorithm:
- Monitors user pool vs hedger pool size ratios
- Adjusts yield allocation to incentivize balance
- Higher user pool → more yield to hedgers (attract hedging)
- Higher hedger pool → more yield to users (attract deposits)
- Gradual adjustments prevent dramatic shifts
- Flash deposit protection through eligible pool size calculations
- Only deposits meeting holding period requirements count toward yield distribution
Yield sources:
- Aave yield from USDC deposits in lending protocols
- Protocol fees from minting, redemption, and trading
- Interest rate differentials from hedging operations
- External yield farming opportunities
- Authorized source validation for security
Time-weighted calculations:
- 24-hour TWAP for pool size measurements
- Historical data tracking for trend analysis
- Maximum history length prevents unbounded storage
- Drift tolerance for timestamp validation
- Automatic data cleanup and optimization
Holding period requirements:
- Minimum 7-day holding period for yield claims
- Prevents yield farming attacks and speculation
- Encourages long-term protocol participation
- Tracked per user with deposit timestamps
- Enhanced protection against flash deposit manipulation
- Eligible pool sizes exclude recent deposits from yield calculations
- Dynamic discount system based on deposit timing and activity
Security features:
- Role-based access control for all critical operations
- Reentrancy protection for all external calls
- Emergency pause mechanism for crisis situations
- Upgradeable architecture for future improvements
- Authorized yield source validation
- Secure yield distribution mechanisms
- Flash deposit attack prevention through holding period requirements
- Eligible pool size calculations for yield distribution
- Time-weighted protection against yield manipulation
Integration points:
- User pool for deposit and staking metrics
- Hedger pool for hedging exposure metrics
- Aave vault for yield generation and harvesting
- stQEURO token for user yield distribution
- USDC for yield payments and transfers
Note: security-contact: team@quantillon.money
State Variables
GOVERNANCE_ROLE
bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE")
YIELD_MANAGER_ROLE
bytes32 public constant YIELD_MANAGER_ROLE = keccak256("YIELD_MANAGER_ROLE")
EMERGENCY_ROLE
bytes32 public constant EMERGENCY_ROLE = keccak256("EMERGENCY_ROLE")
usdc
IERC20 public usdc
userPool
IUserPool public userPool
hedgerPool
IHedgerPool public hedgerPool
aaveVault
IAaveVault public aaveVault
stQEUROFactory
IStQEUROFactory public stQEUROFactory
TIME_PROVIDER
TimeProvider contract for centralized time management
Used to replace direct block.timestamp usage for testability and consistency
TimeProvider public immutable TIME_PROVIDER
baseYieldShift
uint256 public baseYieldShift
maxYieldShift
uint256 public maxYieldShift
adjustmentSpeed
uint256 public adjustmentSpeed
targetPoolRatio
uint256 public targetPoolRatio
MIN_HOLDING_PERIOD
uint256 public constant MIN_HOLDING_PERIOD = 7 days
TWAP_PERIOD
uint256 public constant TWAP_PERIOD = 24 hours
MAX_TIME_ELAPSED
uint256 public constant MAX_TIME_ELAPSED = 365 days
currentYieldShift
uint256 public currentYieldShift
lastUpdateTime
uint256 public lastUpdateTime
totalYieldGenerated
uint256 public totalYieldGenerated
totalYieldDistributed
uint256 public totalYieldDistributed
userYieldPool
uint256 public userYieldPool
hedgerYieldPool
uint256 public hedgerYieldPool
treasury
address public treasury
yieldSources
mapping(bytes32 => uint256) public yieldSources
yieldSourceNames
bytes32[] public yieldSourceNames
authorizedYieldSources
mapping(address => bool) public authorizedYieldSources
sourceToYieldType
mapping(address => bytes32) public sourceToYieldType
userPendingYield
mapping(address => uint256) public userPendingYield
hedgerPendingYield
mapping(address => uint256) public hedgerPendingYield
userLastClaim
mapping(address => uint256) public userLastClaim
hedgerLastClaim
mapping(address => uint256) public hedgerLastClaim
lastDepositTime
mapping(address => uint256) public lastDepositTime
userPoolHistory
PoolSnapshot[] public userPoolHistory
hedgerPoolHistory
PoolSnapshot[] public hedgerPoolHistory
MAX_HISTORY_LENGTH
uint256 public constant MAX_HISTORY_LENGTH = 1000
yieldShiftHistory
YieldShiftSnapshot[] public yieldShiftHistory
sourceToVaultId
mapping(address => uint256) public sourceToVaultId
enforceSourceVaultBinding
bool public enforceSourceVaultBinding
Functions
constructor
Constructor for YieldShift implementation
Sets up the time provider and disables initialization on implementation for security
Notes:
-
security: Validates time provider address and disables initialization on implementation
-
validation: Validates time provider is not zero address
-
state-changes: Sets time provider and disables initializers
-
events: No events emitted
-
errors: Throws ZeroAddress if time provider is zero
-
reentrancy: Not protected - constructor only
-
access: Public constructor
-
oracle: No oracle dependencies
constructor(TimeProvider _TIME_PROVIDER) ;
Parameters
| Name | Type | Description |
|---|---|---|
_TIME_PROVIDER | TimeProvider | Address of the time provider contract |
initialize
Initialize the YieldShift contract
Sets up the contract with all required addresses and roles
Notes:
-
security: Validates all addresses are not zero
-
validation: Validates all input addresses
-
state-changes: Initializes ReentrancyGuard, AccessControl, and Pausable
-
events: Emits initialization events
-
errors: Throws if any address is zero
-
reentrancy: Protected by initializer modifier
-
access: Public initializer
-
oracle: No oracle dependencies
function initialize(
address admin,
address _usdc,
address _userPool,
address _hedgerPool,
address _aaveVault,
address _stQEUROFactory,
address _timelock,
address _treasury
) public initializer;
Parameters
| Name | Type | Description |
|---|---|---|
admin | address | Address of the admin role |
_usdc | address | Address of the USDC token contract |
_userPool | address | Address of the user pool contract |
_hedgerPool | address | Address of the hedger pool contract |
_aaveVault | address | Address of the Aave vault contract |
_stQEUROFactory | address | Address of the stQEURO factory contract |
_timelock | address | Address of the timelock contract |
_treasury | address | Address of the treasury |
bootstrapDefaults
Governance bootstrap to set initial histories and source metadata after minimal init
Lazily initializes historical arrays and default authorized yield sources
Notes:
-
security: Restricted to governance; reads trusted state only
-
validation: Relies on prior initialization guarantees
-
state-changes: Records initial snapshots and default yield source metadata
-
events: Emits none (pure bookkeeping)
-
errors: Reverts if caller lacks governance role
-
reentrancy: Not applicable
-
access: Governance-only
-
oracle: Not applicable
function bootstrapDefaults() external;
updateYieldDistribution
Updates the yield distribution between users and hedgers
Recalculates and applies new yield distribution ratios based on current pool states
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function updateYieldDistribution() external nonReentrant whenNotPaused;
addYield
Add yield from authorized sources
Adds yield from authorized sources and distributes it according to current yield shift
Notes:
-
security: Validates caller is authorized for the yield source
-
validation: Validates yield amount is positive and matches actual received
-
state-changes: Updates yield sources and total yield generated
-
events: Emits YieldAdded event
-
errors: Throws if caller is unauthorized or yield amount mismatch
-
reentrancy: Protected by nonReentrant modifier
-
access: Restricted to authorized yield sources
-
oracle: No oracle dependencies
function addYield(uint256 vaultId, uint256 yieldAmount, bytes32 source) external nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
vaultId | uint256 | Registered vault identifier used to resolve the target stQEURO token |
yieldAmount | uint256 | Amount of yield to add (6 decimals) |
source | bytes32 | Source identifier for the yield |
claimUserYield
Claim user yield
Claims yield for a user after holding period requirements are met
Notes:
-
security: Validates caller is authorized and holding period is met
-
validation: Validates user has pending yield and meets holding period
-
state-changes: Updates user pending yield and transfers USDC
-
events: Emits YieldClaimed event
-
errors: Throws if caller is unauthorized or holding period not met
-
reentrancy: Protected by nonReentrant modifier
-
access: Restricted to user or user pool
-
oracle: No oracle dependencies
function claimUserYield(address user) external nonReentrant returns (uint256 yieldAmount);
Parameters
| Name | Type | Description |
|---|---|---|
user | address | Address of the user to claim yield for |
Returns
| Name | Type | Description |
|---|---|---|
yieldAmount | uint256 | Amount of yield claimed |
claimHedgerYield
Claim hedger yield
Claims yield for a hedger
Notes:
-
security: Validates caller is authorized
-
validation: Validates hedger has pending yield
-
state-changes: Updates hedger pending yield and transfers USDC
-
events: Emits HedgerYieldClaimed event
-
errors: Throws if caller is unauthorized or insufficient yield
-
reentrancy: Protected by nonReentrant modifier
-
access: Restricted to hedger or hedger pool
-
oracle: No oracle dependencies
function claimHedgerYield(address hedger) external nonReentrant returns (uint256 yieldAmount);
Parameters
| Name | Type | Description |
|---|---|---|
hedger | address | Address of the hedger to claim yield for |
Returns
| Name | Type | Description |
|---|---|---|
yieldAmount | uint256 | Amount of yield claimed |
_calculateOptimalYieldShift
Calculate optimal yield shift based on current pool ratio
Calculates optimal yield allocation to incentivize pool balance
Notes:
-
security: Uses tolerance checks to prevent excessive adjustments
-
validation: No input validation required - view function
-
state-changes: No state changes - view function only
-
events: No events emitted
-
errors: No errors thrown - safe arithmetic used
-
reentrancy: Not applicable - view function
-
access: Internal function - no access restrictions
-
oracle: No oracle dependencies
function _calculateOptimalYieldShift(uint256 poolRatio) internal view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
poolRatio | uint256 | Current ratio between user and hedger pools (basis points) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Optimal yield shift percentage (basis points) |
_applyGradualAdjustment
Apply gradual adjustment to yield shift to prevent sudden changes
Gradually adjusts yield shift based on adjustmentSpeed to prevent volatility
Notes:
-
security: Limits adjustment speed to prevent sudden changes
-
validation: No input validation required - view function
-
state-changes: No state changes - view function only
-
events: No events emitted
-
errors: No errors thrown - safe arithmetic used
-
reentrancy: Not applicable - view function
-
access: Internal function - no access restrictions
-
oracle: No oracle dependencies
function _applyGradualAdjustment(uint256 targetShift) internal view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
targetShift | uint256 | Target yield shift percentage (basis points) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Adjusted yield shift percentage (basis points) |
_getCurrentPoolMetrics
Get current pool metrics
Returns current pool sizes and ratio for yield shift calculations
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function _getCurrentPoolMetrics()
internal
view
returns (uint256 userPoolSize, uint256 hedgerPoolSize, uint256 poolRatio);
Returns
| Name | Type | Description |
|---|---|---|
userPoolSize | uint256 | Current user pool size |
hedgerPoolSize | uint256 | Current hedger pool size |
poolRatio | uint256 | Ratio of user to hedger pool sizes |
_getEligiblePoolMetrics
Get eligible pool metrics that only count deposits meeting holding period requirements
SECURITY: Prevents flash deposit attacks by excluding recent deposits from yield calculations
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function _getEligiblePoolMetrics()
internal
view
returns (uint256 userPoolSize, uint256 hedgerPoolSize, uint256 poolRatio);
Returns
| Name | Type | Description |
|---|---|---|
userPoolSize | uint256 | Eligible user pool size (deposits older than MIN_HOLDING_PERIOD) |
hedgerPoolSize | uint256 | Eligible hedger pool size (deposits older than MIN_HOLDING_PERIOD) |
poolRatio | uint256 | Ratio of eligible pool sizes |
_calculateHoldingPeriodDiscount
Calculate holding period discount based on recent deposit activity
Returns a percentage (in basis points) representing eligible deposits
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function _calculateHoldingPeriodDiscount() internal view returns (uint256 discountBps);
Returns
| Name | Type | Description |
|---|---|---|
discountBps | uint256 | Discount in basis points (10000 = 100%) |
_isWithinTolerance
Check if a value is within tolerance of a target value
Helper function for yield shift calculations
Notes:
-
security: Uses safe arithmetic to prevent overflow
-
validation: No input validation required - pure function
-
state-changes: No state changes - pure function
-
events: No events emitted
-
errors: No errors thrown - safe arithmetic used
-
reentrancy: Not applicable - pure function
-
access: Internal function - no access restrictions
-
oracle: No oracle dependencies
function _isWithinTolerance(uint256 value, uint256 target, uint256 toleranceBps) internal pure returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
value | uint256 | The value to check |
target | uint256 | The target value |
toleranceBps | uint256 | Tolerance in basis points (e.g., 1000 = 10%) |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if value is within tolerance, false otherwise |
updateLastDepositTime
Updates the last deposit timestamp for a user
Called by UserPool to track user deposit timing for yield calculations
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function updateLastDepositTime(address user) external;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | The user address to update |
getYieldDistributionBreakdown
Returns detailed breakdown of yield distribution
Shows how yield is allocated between different pools and stakeholders
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function getYieldDistributionBreakdown()
external
view
returns (uint256 userYieldPool_, uint256 hedgerYieldPool_, uint256 distributionRatio);
Returns
| Name | Type | Description |
|---|---|---|
userYieldPool_ | uint256 | Yield allocated to user pool |
hedgerYieldPool_ | uint256 | Yield allocated to hedger pool |
distributionRatio | uint256 | Current distribution ratio between pools |
getPoolMetrics
Returns comprehensive metrics for both user and hedger pools
Provides detailed analytics about pool performance and utilization
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function getPoolMetrics()
external
view
returns (uint256 userPoolSize, uint256 hedgerPoolSize, uint256 poolRatio, uint256 targetRatio);
Returns
| Name | Type | Description |
|---|---|---|
userPoolSize | uint256 | Total size of user pool |
hedgerPoolSize | uint256 | Total size of hedger pool |
poolRatio | uint256 | Current ratio between pools |
targetRatio | uint256 | Target ratio between pools |
calculateOptimalYieldShift
Calculates the optimal yield shift based on current market conditions
Uses algorithms to determine best yield distribution strategy
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function calculateOptimalYieldShift() external view returns (uint256 optimalShift, uint256 currentDeviation);
Returns
| Name | Type | Description |
|---|---|---|
optimalShift | uint256 | Recommended yield shift percentage |
currentDeviation | uint256 | Current deviation from optimal shift |
getYieldSources
Returns information about all yield sources
Provides details about different yield-generating mechanisms
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function getYieldSources()
external
view
returns (uint256 aaveYield, uint256 protocolFees, uint256 interestDifferential, uint256 otherSources);
Returns
| Name | Type | Description |
|---|---|---|
aaveYield | uint256 | Yield from Aave protocol |
protocolFees | uint256 | Protocol fees collected |
interestDifferential | uint256 | Interest rate differential yield |
otherSources | uint256 | Other miscellaneous yield sources |
getHistoricalYieldShift
Returns a lightweight historical yield-shift summary for a period
Uses the latest in-period snapshot (or current shift) to avoid O(n) scans.
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function getHistoricalYieldShift(uint256 period)
external
view
returns (uint256 averageShift, uint256 maxShift, uint256 minShift, uint256 volatility);
Parameters
| Name | Type | Description |
|---|---|---|
period | uint256 | The time period to analyze (in seconds) |
Returns
| Name | Type | Description |
|---|---|---|
averageShift | uint256 | Representative shift for the period |
maxShift | uint256 | Same as averageShift in compact summary mode |
minShift | uint256 | Same as averageShift in compact summary mode |
volatility | uint256 | Always 0 in compact summary mode |
getYieldPerformanceMetrics
Returns compact performance metrics for yield operations
Uses aggregate pools directly to avoid cross-contract reads.
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function getYieldPerformanceMetrics()
external
view
returns (
uint256 totalYieldDistributed_,
uint256 averageUserYield,
uint256 averageHedgerYield,
uint256 yieldEfficiency
);
Returns
| Name | Type | Description |
|---|---|---|
totalYieldDistributed_ | uint256 | Total yield distributed to date |
averageUserYield | uint256 | Aggregate user yield pool |
averageHedgerYield | uint256 | Aggregate hedger yield pool |
yieldEfficiency | uint256 | Distributed / generated ratio (bps) |
_calculateUserAllocation
Calculate user allocation from current yield shift
Calculates how much yield should be allocated to users
Notes:
-
security: Uses safe arithmetic to prevent overflow
-
validation: No input validation required - view function
-
state-changes: No state changes - view function only
-
events: No events emitted
-
errors: No errors thrown - safe arithmetic used
-
reentrancy: Not applicable - view function
-
access: Internal function - no access restrictions
-
oracle: No oracle dependencies
function _calculateUserAllocation() internal view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | User allocation amount based on current yield shift percentage |
_calculateHedgerAllocation
Calculate hedger allocation from current yield shift
Calculates how much yield should be allocated to hedgers
Notes:
-
security: Uses safe arithmetic to prevent overflow
-
validation: No input validation required - view function
-
state-changes: No state changes - view function only
-
events: No events emitted
-
errors: No errors thrown - safe arithmetic used
-
reentrancy: Not applicable - view function
-
access: Internal function - no access restrictions
-
oracle: No oracle dependencies
function _calculateHedgerAllocation() internal view returns (uint256);
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Hedger allocation amount based on current yield shift percentage |
configureYieldModel
Batch-updates all yield model parameters.
Applies a new configuration for baseYieldShift, maxYieldShift, adjustmentSpeed
and targetPoolRatio in a single governance transaction.
Uses YieldValidationLibrary to enforce sane bounds and invariants.
Notes:
-
security: Only governance may call; validates that
maxYieldShift >= baseYieldShiftand that all parameters stay within library-defined limits. -
validation: Reverts if yield shifts, adjustment speed or target ratio are out of bounds.
-
state-changes: Updates
baseYieldShift,maxYieldShift,adjustmentSpeed,targetPoolRatio. -
events: None – consumers should read the updated state via view functions.
-
errors: InvalidShiftRange if
maxYieldShift < baseYieldShift; library errors otherwise. -
reentrancy: Not applicable – no external calls after state updates.
-
access: Restricted to governance via
AccessControlLibrary.onlyGovernance. -
oracle: No direct oracle access – operates purely on configuration values.
function configureYieldModel(YieldModelConfig calldata cfg) external;
Parameters
| Name | Type | Description |
|---|---|---|
cfg | YieldModelConfig | Struct containing the new yield model configuration: - baseYieldShift: baseline user share (bps) when pools are balanced. - maxYieldShift: maximum deviation from baseline (bps). - adjustmentSpeed: how fast the shift moves toward the optimal value. - targetPoolRatio: desired user/hedger pool ratio (bps). |
configureDependencies
Batch-updates external dependency addresses used for yield distribution.
Wires or re-wires the userPool, hedgerPool, aaveVault, stQEUROFactory and treasury
references in a single governance transaction.
Notes:
-
security: Only governance may call; validates all addresses are non-zero and sane.
-
validation: Uses
AccessControlLibrary/YieldValidationLibraryto check addresses. -
state-changes: Updates
userPool,hedgerPool,aaveVault,stQEUROFactory,treasury. -
events: None – downstream contracts emit their own events on meaningful actions.
-
errors: Library validation errors on zero/invalid addresses.
-
reentrancy: Not applicable – no external calls after state updates.
-
access: Restricted to governance via
AccessControlLibrary.onlyGovernance. -
oracle: No direct oracle access – configuration only.
function configureDependencies(YieldDependencyConfig calldata cfg) external;
Parameters
| Name | Type | Description |
|---|---|---|
cfg | YieldDependencyConfig | Struct containing the new dependency configuration: - userPool: UserPool contract address. - hedgerPool: HedgerPool contract address. - aaveVault: AaveVault contract address. - stQEUROFactory: stQEURO factory contract address. - treasury: treasury address receiving recovered funds. |
setYieldSourceAuthorization
Sets authorization status and yield type for a yield source.
Governance function mapping a source address to a logical yield type (e.g. "aave", "fees")
and toggling whether that source is allowed to push yield via addYield.
Notes:
-
security: Only governance may call; prevents untrusted contracts from minting yield.
-
validation: Reverts on zero
sourceaddress; clears mapping whenauthorizedis false. -
state-changes: Updates
authorizedYieldSources[source]andsourceToYieldType[source]. -
events: None – yield events are emitted when yield is actually added.
-
errors: Library validation errors for invalid addresses.
-
reentrancy: Not applicable – no external calls after state updates.
-
access: Restricted to governance via
AccessControlLibrary.onlyGovernance. -
oracle: No oracle dependencies.
function setYieldSourceAuthorization(address source, bytes32 yieldType, bool authorized) external;
Parameters
| Name | Type | Description |
|---|---|---|
source | address | Address of the yield source whose authorization is being updated. |
yieldType | bytes32 | Logical yield category identifier (e.g., keccak256("aave")). |
authorized | bool | True to authorize the source, false to revoke authorization. |
setSourceVaultBinding
Binds a yield source to a single vault id for optional strict routing.
When strict mode is enabled, calls from source can only route yield to vaultId.
Notes:
-
security: Governance-only control over source/vault routing boundaries.
-
validation: Reverts on zero source address or zero vault id.
-
state-changes: Updates
sourceToVaultId[source]. -
events: Emits
SourceVaultBindingUpdated. -
errors:
ZeroAddress/InvalidVaulton invalid inputs. -
reentrancy: Not applicable.
-
access: Restricted to governance.
-
oracle: No oracle dependencies.
function setSourceVaultBinding(address source, uint256 vaultId) external;
Parameters
| Name | Type | Description |
|---|---|---|
source | address | Yield source address to bind. |
vaultId | uint256 | Vault id that this source is allowed to target. |
clearSourceVaultBinding
Clears the vault binding for a yield source.
In strict mode, a cleared source must be rebound before it can call addYield.
Notes:
-
security: Governance-only.
-
validation: Reverts on zero source address.
-
state-changes: Resets
sourceToVaultId[source]to zero. -
events: Emits
SourceVaultBindingUpdatedwith vault id0. -
errors:
ZeroAddresson invalid input. -
reentrancy: Not applicable.
-
access: Restricted to governance.
-
oracle: No oracle dependencies.
function clearSourceVaultBinding(address source) external;
Parameters
| Name | Type | Description |
|---|---|---|
source | address | Yield source address to unbind. |
setSourceVaultBindingEnforcement
Enables or disables strict source-to-vault enforcement.
When enabled, addYield requires sourceToVaultId[msg.sender] == vaultId.
Notes:
-
security: Governance-only mode toggle.
-
validation: No extra validation required.
-
state-changes: Updates
enforceSourceVaultBinding. -
events: Emits
SourceVaultBindingModeUpdated. -
errors: None.
-
reentrancy: Not applicable.
-
access: Restricted to governance.
-
oracle: No oracle dependencies.
function setSourceVaultBindingEnforcement(bool enabled) external;
Parameters
| Name | Type | Description |
|---|---|---|
enabled | bool | True to enforce source/vault binding, false for permissive routing. |
updateYieldAllocation
Updates yield allocation for a specific user or hedger
Called by pools to update individual yield allocations
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function updateYieldAllocation(address user, uint256 amount, bool isUser) external;
Parameters
| Name | Type | Description |
|---|---|---|
user | address | The user or hedger address |
amount | uint256 | The allocation amount |
isUser | bool | True if user, false if hedger |
emergencyYieldDistribution
Executes emergency yield distribution with specified amounts
Emergency function to manually distribute yield during critical situations
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function emergencyYieldDistribution(uint256 userAmount, uint256 hedgerAmount) external;
Parameters
| Name | Type | Description |
|---|---|---|
userAmount | uint256 | Amount to distribute to user pool |
hedgerAmount | uint256 | Amount to distribute to hedger pool |
pauseYieldDistribution
Pauses all yield distribution operations
Emergency function to halt yield distribution during critical situations
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function pauseYieldDistribution() external;
resumeYieldDistribution
Resumes yield distribution operations after being paused
Restarts yield distribution when emergency is resolved
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function resumeYieldDistribution() external;
isYieldSourceAuthorized
Check if a yield source is authorized
Checks if a yield source is authorized for a specific yield type
Checks if a yield source is authorized for a specific yield type
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function isYieldSourceAuthorized(address source, bytes32 yieldType) external view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
source | address | Source address |
yieldType | bytes32 | Yield type identifier |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if authorized |
checkAndUpdateYieldDistribution
Checks current conditions and updates yield distribution if needed
Automated function to maintain optimal yield distribution
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function checkAndUpdateYieldDistribution() external;
forceUpdateYieldDistribution
Forces an immediate update of yield distribution
Emergency function to bypass normal update conditions and force distribution
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function forceUpdateYieldDistribution() external;
getTimeWeightedAverage
Get time weighted average of pool history
Calculates time weighted average of pool history over a specified period
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function getTimeWeightedAverage(PoolSnapshot[] storage poolHistory, uint256 period, bool isUserPool)
internal
view
returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
poolHistory | PoolSnapshot[] | Array of pool snapshots |
period | uint256 | Time period for calculation |
isUserPool | bool | Whether this is for user pool or hedger pool |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | uint256 Time weighted average value |
_recordPoolSnapshot
Record pool snapshot
Records current pool metrics as a snapshot for historical tracking
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function _recordPoolSnapshot() internal;
_recordPoolSnapshotWithEligibleSizes
Record pool snapshot using eligible pool sizes to prevent manipulation
SECURITY: Uses eligible pool sizes that respect holding period requirements
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function _recordPoolSnapshotWithEligibleSizes(uint256 eligibleUserPoolSize, uint256 eligibleHedgerPoolSize)
internal;
Parameters
| Name | Type | Description |
|---|---|---|
eligibleUserPoolSize | uint256 | Eligible user pool size for yield calculations |
eligibleHedgerPoolSize | uint256 | Eligible hedger pool size for yield calculations |
_addToPoolHistory
Add pool snapshot to history
Adds a pool snapshot to the history array with size management
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function _addToPoolHistory(PoolSnapshot[] storage poolHistory, uint256 poolSize, bool isUserPool) internal;
Parameters
| Name | Type | Description |
|---|---|---|
poolHistory | PoolSnapshot[] | Array of pool snapshots to add to |
poolSize | uint256 | Size of the pool to record |
isUserPool | bool | Whether this is for user pool or hedger pool |
recoverToken
Recovers accidentally sent ERC20 tokens from the contract
Emergency function to recover tokens that are not part of normal operations
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function recoverToken(address token, uint256 amount) external;
Parameters
| Name | Type | Description |
|---|---|---|
token | address | The token address to recover |
amount | uint256 | The amount of tokens to recover |
recoverETH
Recovers accidentally sent ETH from the contract
Emergency function to recover ETH that shouldn't be in the contract
Notes:
-
security: Validates input parameters and enforces security checks
-
validation: Validates input parameters and business logic constraints
-
state-changes: Updates contract state variables
-
events: Emits relevant events for state changes
-
errors: Throws custom errors for invalid conditions
-
reentrancy: Protected by reentrancy guard
-
access: Restricted to authorized roles
-
oracle: Requires fresh oracle price data
function recoverETH() external;
Events
YieldDistributionUpdated
OPTIMIZED: Indexed timestamp for efficient time-based filtering
event YieldDistributionUpdated(
uint256 newYieldShift, uint256 userYieldAllocation, uint256 hedgerYieldAllocation, uint256 indexed timestamp
);
UserYieldClaimed
event UserYieldClaimed(address indexed user, uint256 yieldAmount, uint256 timestamp);
HedgerYieldClaimed
event HedgerYieldClaimed(address indexed hedger, uint256 yieldAmount, uint256 timestamp);
YieldAdded
OPTIMIZED: Indexed source and timestamp for efficient filtering
event YieldAdded(uint256 yieldAmount, string indexed source, uint256 indexed timestamp);
SourceVaultBindingUpdated
event SourceVaultBindingUpdated(address indexed source, uint256 indexed vaultId);
SourceVaultBindingModeUpdated
event SourceVaultBindingModeUpdated(bool enabled);
Structs
PoolSnapshot
OPTIMIZED: Packed struct for gas efficiency in historical arrays
struct PoolSnapshot {
uint128 userPoolSize;
uint128 hedgerPoolSize;
uint64 timestamp; // Timestamp (8 bytes, until year 2554)
}
YieldShiftSnapshot
OPTIMIZED: Packed struct for gas efficiency in yield shift tracking
struct YieldShiftSnapshot {
uint128 yieldShift;
uint64 timestamp; // Timestamp (8 bytes, until year 2554)
}
YieldModelConfig
struct YieldModelConfig {
uint256 baseYieldShift;
uint256 maxYieldShift;
uint256 adjustmentSpeed;
uint256 targetPoolRatio;
}
YieldDependencyConfig
struct YieldDependencyConfig {
address userPool;
address hedgerPool;
address aaveVault;
address stQEUROFactory;
address treasury;
}