@@ -59,6 +59,56 @@ All routed targets MUST satisfy:
5959 - ` assets += IERC4626(v).convertToAssets(IERC4626(v).balanceOf(address(this))) `
6060- This is a view-only iteration. State-changing flows remain single-vault without loops.
6161
62+ ## CFA streaming integration (v2.1) — Superfluid “flow” helper
63+ Status: planned in v2.1 (docs-first; implementation next).
64+
65+ Goal
66+ - Stream SENDx (SuperToken) per user at a rate proportional to their current value in the aggregator.
67+ - Use Superfluid’s SuperTokenV1Library ` flow(ISuperToken token, address receiver, int96 rate) ` helper to create/update/delete flows.
68+
69+ Key concepts
70+ - Token: ` sendx ` (constructor arg), an ISuperToken. The aggregator must be pre-funded with SENDx to cover the flow buffer.
71+ - Triggers: Recompute a user’s flow after each state-changing event that affects the user’s value:
72+ - deposit(receiver)
73+ - withdraw(owner)
74+ - transfer(from→to): recompute for both parties after proportional re-attribution
75+ - Value basis (per user): sum across the user’s active vaults of ` convertToAssets(_userUnderlyingShares[user][vault]) ` .
76+ - Policy params:
77+ - ` annualRateBps ` : annualized rate in basis points (e.g., 300 = 3%)
78+ - ` secondsPerYear ` : denominator to convert annual to per-second
79+ - ` exchangeRateWad ` : asset→SENDx conversion (fixed-point); default 1e18 for 1:1
80+ - Flow math (per second):
81+ - ` perSecond = floor( (sumAssets * exchangeRateWad) * annualRateBps / 10_000 / secondsPerYear / 1e18 ) `
82+ - Use ` int96 ` cast; if perSecond==0, call ` flow(token, user, 0) ` to delete.
83+
84+ Integration outline (pseudocode)
85+ - Import library: ` using SuperTokenV1Library for ISuperToken; `
86+ - After event, recompute and set flow:
87+ ```
88+ function _updateFlow(address user) internal {
89+ uint256 assets = 0;
90+ for (address v in _userActiveVaults[user]) {
91+ uint256 uShares = _userUnderlyingShares[user][v];
92+ if (uShares == 0) continue;
93+ assets += IERC4626(v).convertToAssets(uShares);
94+ }
95+ uint256 wad = assets * exchangeRateWad;
96+ uint256 annual = wad * annualRateBps / 10_000;
97+ uint256 perSec = annual / secondsPerYear / 1e18;
98+ int96 rate = int96(int256(perSec));
99+ sendx.flow(user, rate); // create/update/delete as needed
100+ }
101+ ```
102+
103+ Operational notes
104+ - Pre-fund with SENDx to satisfy CFA buffer or the flow creation will revert.
105+ - Flows are per-user, from the aggregator to the user.
106+ - If you change ` annualRateBps ` /` exchangeRateWad ` , you may optionally batch-recompute flows for a set of users (future helper).
107+
108+ References
109+ - SuperTokenV1Library: https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol
110+ - CFA docs: https://docs.superfluid.finance/superfluid/developers/constant-flow-agreement-cfa
111+
62112## Transferability
63113- Aggregator shares follow normal ERC20 semantics: transfers are allowed. The aggregator does not maintain per‑user vault ledgers.
64114
0 commit comments