Skip to content

Feature/osu 1490 yield forwarded#374

Open
skimaharvey wants to merge 7 commits intodevelopfrom
feature/osu-1490-yield-forwarded
Open

Feature/osu 1490 yield forwarded#374
skimaharvey wants to merge 7 commits intodevelopfrom
feature/osu-1490-yield-forwarded

Conversation

@skimaharvey
Copy link
Contributor

@skimaharvey skimaharvey commented Feb 8, 2026

Replace PaymentSplitter with YieldForwarder for Nouns DAO yield flow

Problem

The current PaymentSplitter is pull-based — it receives profit shares but doesn't redeem them or trigger reports. This requires manual claims and separate keeper logic.

Solution

YieldForwarder is a single-purpose, immutable contract that atomically reports, redeems, and forwards yield in one call:

Keeper EOA → YieldForwarder.reportAndForward()
  → strategy.report()        // triggers profit accounting, shares minted to forwarder
  → strategy.redeem()         // burns shares, sends underlying assets to receiver
  → assets arrive at receiver (Nouns Payer)

The YieldForwarder acts as both the strategy's keeper (authorized to call report()) and its donation address (receives profit shares). This eliminates the need for a separate splitter or manual redemption step.

Changes

  • src/core/YieldForwarder.sol — immutable receiver + keeper, single reportAndForward(strategy, maxLoss) function, zero-admin
  • src/factories/YieldForwarderFactory.sol — CREATE2 factory with deterministic addressing and deployment tracking for governance proposals
  • partners/nouns_dao/script/GenerateProposalCalldata.s.sol — updated proposal: TX1 deploys forwarder, TX2-4 deploy strategy with forwarder as both keeper and donation address
  • test/ — 22 unit tests + updated governance integration test

@linear
Copy link

linear bot commented Feb 8, 2026

OSU-1490 yield forwarded

@github-actions
Copy link

github-actions bot commented Feb 8, 2026

Code Coverage Report for src/ files

File % Lines % Statements % Branches % Funcs
src/core/BaseStrategy.sol ✅ 100.00% (54/54) ✅ 100.00% (39/39) ✅ 100.00% (2/2) ✅ 100.00% (19/19)
src/core/MultistrategyLockedVault.sol ✅ 100.00% (117/117) ✅ 100.00% (121/121) ✅ 100.00% (22/22) ✅ 100.00% (18/18)
src/core/MultistrategyVault.sol ✅ 100.00% (593/593) ✅ 100.00% (617/617) ✅ 98.49% (196/199) ✅ 100.00% (88/88)
src/core/PaymentSplitter.sol ✅ 100.00% (55/55) ✅ 100.00% (52/52) ✅ 100.00% (18/18) ✅ 100.00% (16/16)
src/core/Privileged.sol ✅ 100.00% (13/13) ✅ 100.00% (12/12) ✅ 100.00% (0/0) ✅ 100.00% (4/4)
src/core/TokenizedStrategy.sol ✅ 99.35% (308/310) ✅ 99.64% (275/276) ✅ 95.60% (87/91) ✅ 98.81% (83/84)
src/core/YieldForwarder.sol ✅ 100.00% (12/12) ✅ 100.00% (14/14) ✅ 100.00% (3/3) ✅ 100.00% (2/2)
src/core/libs/DebtManagementLib.sol ✅ 100.00% (76/76) ✅ 100.00% (80/80) ✅ 100.00% (20/20) ✅ 100.00% (2/2)
src/core/libs/ERC20SafeApproveLib.sol ✅ 100.00% (4/4) ✅ 100.00% (5/5) ✅ 100.00% (1/1) ✅ 100.00% (1/1)
src/factories/AaveV3StrategyFactory.sol ✅ 100.00% (13/13) ✅ 100.00% (19/19) ✅ 100.00% (2/2) ✅ 100.00% (2/2)
src/factories/AddressSetFactory.sol ✅ 100.00% (15/15) ✅ 100.00% (15/15) ✅ 100.00% (0/0) ✅ 100.00% (4/4)
src/factories/BaseERC4626StrategyFactory.sol ✅ 100.00% (15/15) ✅ 100.00% (19/19) ✅ 100.00% (0/0) ✅ 100.00% (3/3)
src/factories/BaseStrategyFactory.sol ✅ 100.00% (14/14) ✅ 100.00% (14/14) ✅ 100.00% (1/1) ✅ 100.00% (4/4)
src/factories/ERC4626StrategyFactory.sol ✅ 100.00% (2/2) ✅ 100.00% (1/1) ✅ 100.00% (0/0) ✅ 100.00% (1/1)
src/factories/LidoStrategyFactory.sol ✅ 100.00% (12/12) ✅ 100.00% (17/17) ✅ 100.00% (2/2) ✅ 100.00% (2/2)
src/factories/MorphoCompounderStrategyFactory.sol ✅ 100.00% (13/13) ✅ 100.00% (19/19) ✅ 100.00% (2/2) ✅ 100.00% (2/2)
src/factories/MultistrategyVaultFactory.sol ✅ 100.00% (74/74) ✅ 100.00% (64/64) ✅ 100.00% (31/31) ✅ 100.00% (18/18)
src/factories/PaymentSplitterFactory.sol ✅ 100.00% (58/58) ✅ 100.00% (69/69) ✅ 100.00% (22/22) ✅ 100.00% (10/10)
src/factories/RegenEarningPowerCalculatorFactory.sol ✅ 100.00% (14/14) ✅ 100.00% (14/14) ✅ 100.00% (0/0) ✅ 100.00% (4/4)
src/factories/RegenStakerFactory.sol ✅ 100.00% (32/32) ✅ 100.00% (29/29) ✅ 100.00% (2/2) ✅ 100.00% (10/10)
src/factories/SkyCompounderStrategyFactory.sol ✅ 100.00% (12/12) ✅ 100.00% (17/17) ✅ 100.00% (2/2) ✅ 100.00% (2/2)
src/factories/SparkStrategyFactory.sol ✅ 100.00% (2/2) ✅ 100.00% (1/1) ✅ 100.00% (0/0) ✅ 100.00% (1/1)
src/factories/YieldForwarderFactory.sol ✅ 100.00% (19/19) ✅ 100.00% (21/21) ✅ 100.00% (1/1) ✅ 100.00% (5/5)
src/factories/yieldDonating/YearnV3StrategyFactory.sol ✅ 100.00% (12/12) ✅ 100.00% (16/16) ✅ 100.00% (0/0) ✅ 100.00% (2/2)
src/factories/yieldSkimming/RocketPoolStrategyFactory.sol ✅ 100.00% (12/12) ✅ 100.00% (17/17) ✅ 100.00% (2/2) ✅ 100.00% (2/2)
src/guards/KeeperBotGuard.sol ✅ 100.00% (32/32) ✅ 100.00% (30/30) ✅ 100.00% (8/8) ✅ 100.00% (6/6)
src/mechanisms/AllocationMechanismFactory.sol ✅ 100.00% (26/26) ✅ 100.00% (26/26) ✅ 100.00% (3/3) ✅ 100.00% (6/6)
src/mechanisms/BaseAllocationMechanism.sol ✅ 97.01% (65/67) ✅ 97.18% (69/71) ✅ 100.00% (7/7) ✅ 95.83% (23/24)
src/mechanisms/TokenizedAllocationMechanism.sol ✅ 99.76% (422/423) ✅ 99.57% (466/468) ✅ 95.38% (124/130) ✅ 100.00% (81/81)
src/mechanisms/mechanism/OctantQFMechanism.sol ✅ 100.00% (37/37) ✅ 100.00% (37/37) ✅ 100.00% (14/14) ✅ 100.00% (7/7)
src/mechanisms/mechanism/QuadraticVotingMechanism.sol ✅ 100.00% (69/69) ✅ 100.00% (87/87) ✅ 100.00% (17/17) ✅ 100.00% (17/17)
src/mechanisms/voting-strategy/ProperQF.sol ✅ 100.00% (85/85) ✅ 100.00% (104/104) ✅ 100.00% (13/13) ✅ 100.00% (15/15)
src/regen/RegenEarningPowerCalculator.sol ✅ 100.00% (35/35) ✅ 100.00% (31/31) ✅ 100.00% (6/6) ✅ 100.00% (8/8)
src/regen/RegenStaker.sol ✅ 100.00% (16/16) ✅ 100.00% (14/14) ✅ 100.00% (1/1) ✅ 100.00% (5/5)
src/regen/RegenStakerBase.sol ✅ 99.59% (242/243) ✅ 99.59% (243/244) ✅ 97.33% (73/75) ✅ 100.00% (34/34)
src/regen/RegenStakerWithoutDelegateSurrogateVotes.sol ✅ 100.00% (20/20) ✅ 100.00% (17/17) ✅ 100.00% (4/4) ✅ 100.00% (5/5)
src/strategies/periphery/BaseHealthCheck.sol ✅ 100.00% (32/32) ✅ 100.00% (24/24) ✅ 100.00% (14/14) ✅ 100.00% (9/9)
src/strategies/periphery/BaseYieldSkimmingHealthCheck.sol ✅ 100.00% (41/41) ✅ 100.00% (39/39) ✅ 100.00% (18/18) ✅ 100.00% (10/10)
src/strategies/periphery/UniswapV3Swapper.sol ✅ 100.00% (23/23) ✅ 100.00% (30/30) ✅ 100.00% (7/7) ✅ 100.00% (4/4)
src/strategies/yieldDonating/AaveV3Strategy.sol ✅ 100.00% (39/39) ✅ 100.00% (48/48) ✅ 100.00% (9/9) ✅ 100.00% (7/7)
src/strategies/yieldDonating/ERC4626Strategy.sol ✅ 100.00% (26/26) ✅ 100.00% (30/30) ✅ 100.00% (2/2) ✅ 100.00% (7/7)
src/strategies/yieldDonating/MorphoCompounderStrategy.sol ✅ 100.00% (26/26) ✅ 100.00% (30/30) ✅ 100.00% (2/2) ✅ 100.00% (7/7)
src/strategies/yieldDonating/PrivilegedYieldDonatingTokenizedStrategy.sol ✅ 100.00% (16/16) ✅ 100.00% (14/14) ✅ 100.00% (4/4) ✅ 100.00% (6/6)
src/strategies/yieldDonating/SkyCompounderStrategy.sol ✅ 100.00% (88/88) ✅ 100.00% (77/77) ✅ 100.00% (24/24) ✅ 100.00% (19/19)
src/strategies/yieldDonating/SparkStrategy.sol ✅ 100.00% (8/8) ✅ 100.00% (9/9) ✅ 100.00% (6/6) ✅ 100.00% (1/1)
src/strategies/yieldDonating/YearnV3Strategy.sol ✅ 100.00% (26/26) ✅ 100.00% (30/30) ✅ 100.00% (2/2) ✅ 100.00% (7/7)
src/strategies/yieldDonating/YieldDonatingTokenizedStrategy.sol ✅ 100.00% (23/23) ✅ 100.00% (26/26) ✅ 100.00% (5/5) ✅ 100.00% (2/2)
src/strategies/yieldSkimming/BaseYieldSkimmingStrategy.sol ✅ 100.00% (8/8) ✅ 100.00% (5/5) ✅ 100.00% (0/0) ✅ 100.00% (5/5)
src/strategies/yieldSkimming/LidoStrategy.sol ✅ 100.00% (4/4) ✅ 100.00% (3/3) ✅ 100.00% (0/0) ✅ 100.00% (2/2)
src/strategies/yieldSkimming/PrivilegedYieldSkimmingTokenizedStrategy.sol ✅ 100.00% (16/16) ✅ 100.00% (14/14) ✅ 100.00% (4/4) ✅ 100.00% (6/6)
src/strategies/yieldSkimming/RocketPoolStrategy.sol ✅ 100.00% (4/4) ✅ 100.00% (3/3) ✅ 100.00% (0/0) ✅ 100.00% (2/2)
src/strategies/yieldSkimming/YieldSkimmingTokenizedStrategy.sol ✅ 99.61% (254/255) ✅ 99.39% (326/328) ✅ 96.43% (81/84) ✅ 100.00% (28/28)
src/utils/AddressSet.sol ✅ 100.00% (34/34) ✅ 100.00% (34/34) ✅ 100.00% (12/12) ✅ 100.00% (7/7)
src/zodiac-core/LinearAllowanceExecutor.sol ✅ 100.00% (24/24) ✅ 100.00% (24/24) ✅ 100.00% (7/7) ✅ 100.00% (7/7)
src/zodiac-core/modules/LinearAllowanceSingletonForGnosisSafe.sol ✅ 100.00% (91/91) ✅ 100.00% (100/100) ✅ 95.24% (20/21) ✅ 100.00% (16/16)

@skimaharvey skimaharvey marked this pull request as ready for review February 9, 2026 11:05
@skimaharvey skimaharvey requested review from 0xferit and qGolem February 9, 2026 11:05
0xferit
0xferit previously approved these changes Feb 10, 2026
Copy link
Contributor

@qGolem qGolem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get to 95% coverage and attack to a YDS YSS

@skimaharvey skimaharvey force-pushed the feature/osu-1490-yield-forwarded branch 2 times, most recently from eaaa209 to 99a9156 Compare February 13, 2026 13:31
@skimaharvey skimaharvey force-pushed the feature/osu-1490-yield-forwarded branch 2 times, most recently from 9cea7cc to 2cf0f19 Compare February 17, 2026 16:45
@0xferit 0xferit marked this pull request as draft February 18, 2026 14:31
@0xferit 0xferit marked this pull request as ready for review February 18, 2026 14:31
@0xferit 0xferit requested review from 0xferit and removed request for 0xferit February 18, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants