Skip to content

Convert fixed-price payouts to pull credits#60

Merged
punk6529 merged 4 commits into
mainfrom
codex/fixed-price-pull-payments
Jun 10, 2026
Merged

Convert fixed-price payouts to pull credits#60
punk6529 merged 4 commits into
mainfrom
codex/fixed-price-pull-payments

Conversation

@punk6529

@punk6529 punk6529 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Converts fixed-price StreamDrops mint payments from synchronous ETH pushes into ADR 0003 pull-payment accounting.

  • Records fixed-price poster, protocol, and curator-reserve credits during paid mint execution.
  • Removes mint-path calls to poster, payout, and curators-pool recipients so reverting recipients cannot block minting.
  • Adds guarded poster/protocol fixed-price credit withdrawal with failed-withdrawal rollback.
  • Keeps curator reserve accounted in owed/surplus views but not ordinary withdrawable credit; curator-claim reserve movement remains a later payment workstream.
  • Converts fixed-price characterization tests to target-state assertions and adds focused fixed-price payment coverage.
  • Updates ADR, roadmap, status docs, test docs, and autonomous run state.

Closes #27.

Roadmap

Security And Maturity

  • This PR does not claim production readiness unless the relevant launch gate evidence is merged.
  • Security-sensitive behavior is identified, or this PR is docs/tooling-only.
  • New external behavior is documented.
  • No private keys, signer material, RPC secrets, or production deployment secrets are included.

Review Routing

  • Protocol review is required or not applicable.
  • Security review is required or not applicable.
  • Tooling/CI review is required or not applicable.
  • Docs review is required or not applicable.

Validation

Local commands run:

forge test --match-contract StreamFixedPricePaymentsTest -vvv
# pass: 12 tests, 0 failed

forge test --match-contract "Stream(FixedPricePayments|DropsIntegrationCharacterization|DropsCharacterization)Test" -vvv
# pass: 33 tests, 0 failed

forge fmt --check smart-contracts\StreamDrops.sol test\StreamDropsIntegrationCharacterization.t.sol test\StreamFixedPricePayments.t.sol
# pass

git diff --check
# pass

make check
# pass: 97 tests, 0 failed, known compiler/NatSpec/lint warnings only

powershell -ExecutionPolicy Bypass -File scripts\check.ps1
# pass: 97 tests, 0 failed, known compiler/NatSpec/lint warnings only

.\.venv-tools\Scripts\slither.exe . --config-file slither.config.json --foundry-compile-all --json <temp-file>
# expected non-zero baseline-finding exit; current counts: 11 High, 27 Medium, 54 Low, 519 Informational, 6 Optimization
# arbitrary-send-eth high set is now the three remaining non-StreamDrops emergency-withdrawal rows
  • make check or platform equivalent passed.
  • Tests were added/updated, or this PR explains why no tests are required.
  • CI is green.
  • Bot and human review comments are resolved or explicitly accepted with rationale.

Impact

  • Test impact: adds test/StreamFixedPricePayments.t.sol and converts fixed-price integration characterization away from unsafe push-payment expectations.
  • Docs impact: updates ADR 0003, roadmap/test matrix, status docs, known blockers, and test README.
  • Known limitations or follow-up issues: broader payment ledger/invariants, curator reward claims, randomizer reserves, and remaining emergency surplus boundaries remain open.

Reviewer Notes

Please focus on the fixed-price accounting boundary: poster/protocol credits are withdrawable now; curator reserve is included in fixed-price owed/surplus accounting but intentionally remains reserved for the later curator-claim workstream rather than ordinary recipient withdrawal.

Summary by CodeRabbit

  • New Features

    • Fixed-price mints now record poster, protocol, and curator-reserve credits (no immediate ETH push); minting and withdrawals are protected against reentrancy and require valid payout/curator configuration. Views expose owed totals and emergency-withdrawable surplus; users can withdraw fixed-price credits.
  • Documentation

    • Updated roadmap, status, known blockers, ops/run guidance, ADR, and test README to reflect fixed-price credit accounting, rollout status, and next work items.
  • Tests

    • Added/updated tests for credit creation, withdrawals, odd-wei handling, forced-ETH surplus, failure cases, and reentrancy/regression coverage.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.

Once credits are available, push a new commit or reopen this pull request to trigger a review.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6cf32a92-c1fe-495b-a65c-dc0022a7642f

📥 Commits

Reviewing files that changed from the base of the PR and between b2d0a74 and 5f2770b.

📒 Files selected for processing (1)
  • ops/AUTONOMOUS_RUN.md

📝 Walkthrough

Walkthrough

This PR implements P0-PAY-003: fixed-price minting now records poster, protocol, and curator-reserve credits in StreamDrops (no push-paying during mint), adds reentrancy protection, credit ledgers, withdrawal APIs and accounting views, extensive tests, and aligned docs/ops updates.

Changes

Fixed-Price Pull-Payment Credit Accounting

Layer / File(s) Summary
Credit Accounting Contracts & Data Model
smart-contracts/StreamDrops.sol
StreamDrops imports ReentrancyGuard; adds FixedPriceCreditType, per-address fixed-price credit mappings (poster/protocol/curator-reserve), aggregate owed totals, FixedPriceCreditCreated/FixedPriceCreditWithdrawn events, and non-zero payout/curator validations.
Fixed-Price Credit Recording in Mint
smart-contracts/StreamDrops.sol
mintDrop is nonReentrant; when msg.value > 0 proceeds are credited via _creditFixedPriceProceeds instead of pushing ETH. The helper splits payment, updates per-address balances and aggregate totals, emits credit events, and handles odd-wei remainder logic.
Credit Withdrawal & Accounting Queries
smart-contracts/StreamDrops.sol
Adds withdrawFixedPriceCredit / withdrawFixedPriceCreditTo (protected by nonReentrant) and view helpers totalFixedPriceOwed, totalOwed, and emergencyWithdrawable (contract balance minus owed credits).
Integration Characterization Test Updates
test/StreamDropsIntegrationCharacterization.t.sol
Renamed/updated tests assert credit/proceeds ledger behavior and expect successful minting when recipients reject ETH, validating credit entries and owed/surplus views alongside token assertions.
Comprehensive Fixed-Price Payment Test Suite
test/StreamFixedPricePayments.t.sol
New suite validates credit creation without push payouts, handling of reverting recipients, withdraw-to-recipient, withdrawal failure preservation, reentrancy resistance, odd/1-wei remainder handling, free-mint zero-credit behavior, zero-recipient/zero-address validation, forced-ETH surplus isolation, and mint-failure cleanup; includes test helpers and mocks.
Test Guidance & README
test/README.md
Clarifies unsafe-characterization tests as regression tripwires and expands target-state fixed-price payment notes (rounding, reentrancy/mint-failure rollback, surplus vs owed, curator-reserve semantics).
ADR, Blockers, Status, Roadmap Alignment
docs/adr/0003-payment-accounting.md, docs/known-blockers.md, docs/status.md, ops/ROADMAP.md
Docs updated to record fixed-price credit behavior, clarify curator-reserve inclusion in owed totals (not yet individual withdrawable credit), change test file references, and enumerate remaining payment/accounting work.
Operations State & Worklog
ops/AUTONOMOUS_RUN.md
AUTONOMOUS_RUN and ROADMAP entries updated to record PR #59 merge, advance fixed-price pull-payment candidate, require explicit Claude review requests per PR, and log P0-PAY-003 start details and decision entries.

Sequence Diagram(s)

sequenceDiagram
  participant Poster as Poster/Caller
  participant mintDrop as StreamDrops.mintDrop
  participant credit as _creditFixedPriceProceeds
  participant Ledger as CreditLedger
  participant Minter as MinterContract
  participant Recipient as Recipient
  Poster->>mintDrop: mintDrop(msg.value,...)
  mintDrop->>credit: when msg.value > 0, split & credit proceeds
  credit->>Ledger: update poster/protocol/curator mappings & totals
  credit-->>mintDrop: emit FixedPriceCreditCreated
  mintDrop->>Minter: mint token (no ETH)
  Minter-->>mintDrop: mint succeeds or reverts (rollback)
  Poster->>mintDrop: withdrawFixedPriceCreditTo(recipient)
  mintDrop->>Recipient: transfer credit funds
  Recipient--xmintDrop: may revert (credit preserved)
  mintDrop->>Ledger: emit FixedPriceCreditWithdrawn (if transfer succeeded)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • #26: Implements credit-ledger storage and aggregate owed totals that overlap this PR's storage and views.
  • #25: Adds fixed-price pull-payment accounting and withdrawal semantics closely related to these contract changes.
  • #27: P0-PAY-003 objective (convert fixed-price payouts to credits) is implemented by this PR.

Possibly related PRs

Poem

🐇 I tuck the tiny wei in rows,

No sudden pushes, quiet flows.
Curator seeds sit in reserve,
Withdrawals wait till we observe.
Ledger hums — the credits keep their pose.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Convert fixed-price payouts to pull credits' directly and clearly summarizes the main change: replacing synchronous ETH pushes with pull-payment credit accounting for fixed-price minting.
Linked Issues check ✅ Passed The PR implements all primary objectives from issue #27: removes push-payment ETH calls from fixed-price minting, implements ADR 0003 pull-payment credit accounting (poster/protocol/curator-reserve), validates payment amounts, emits credit events, and includes comprehensive tests for reverting recipients, odd-wei handling, free mints, and zero-address rejection.
Out of Scope Changes check ✅ Passed All changes are within scope: fixed-price pull-payment implementation in StreamDrops.sol, related test coverage, documentation updates (ADR 0003, roadmap, status), and operational tracking. No unrelated functionality or refactoring appears introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fixed-price-pull-payments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor Author

@claude please review this fixed-price payment PR.

Focus areas:

  • fixed-price mint path no longer push-pays poster, payout, or curators-pool recipients
  • poster/protocol withdrawal rollback and reentrancy behavior
  • curator reserve is accounted/protected but intentionally not ordinary withdrawable credit pending curator-claim work
  • docs do not overclaim full ADR 0003 / P0-PAY-001 completion

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

Please review the latest head 507a47cac7e5c1fc258972ad731e1760210b4366; CI is green, and the prior CodeRabbit status appears to still be pending from the initial run.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

@punk6529 Triggering a full review of the latest head 507a47cac7e5c1fc258972ad731e1760210b4366. I'll focus on:

  • Fixed-price mint path no longer push-paying poster, payout, or curators-pool recipients
  • Poster/protocol withdrawal rollback and reentrancy behavior
  • Curator reserve accounting (protected but not ordinary-withdrawable pending curator-claim work)
  • Docs not overclaiming full ADR 0003 / P0-PAY-001 completion
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/StreamFixedPricePayments.t.sol (1)

402-408: 💤 Low value

Note: selfdestruct is deprecated but acceptable for testing in Solidity 0.8.19.

The FixedPriceForceEth contract uses selfdestruct to force ETH into the target contract for testing surplus handling. While selfdestruct is deprecated and will be removed in future Solidity versions, it remains valid in 0.8.19 and is a standard pattern for testing forced ETH scenarios. This test helper serves its purpose correctly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/StreamFixedPricePayments.t.sol` around lines 402 - 408, The
FixedPriceForceEth test helper uses the deprecated selfdestruct pattern; update
the file to explicitly document and allow it by adding a short comment above the
FixedPriceForceEth contract (and/or a linter pragma) stating this is
intentionally using selfdestruct for forced-ETH testing under Solidity 0.8.19,
and if your linter flags selfdestruct, add a local linter disable for that rule
around the constructor/force function so the FixedPriceForceEth constructor and
force(address payable target) remain unchanged for tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/StreamFixedPricePayments.t.sol`:
- Around line 402-408: The FixedPriceForceEth test helper uses the deprecated
selfdestruct pattern; update the file to explicitly document and allow it by
adding a short comment above the FixedPriceForceEth contract (and/or a linter
pragma) stating this is intentionally using selfdestruct for forced-ETH testing
under Solidity 0.8.19, and if your linter flags selfdestruct, add a local linter
disable for that rule around the constructor/force function so the
FixedPriceForceEth constructor and force(address payable target) remain
unchanged for tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 209ccfe3-dc69-4efc-b6ed-89d075b74961

📥 Commits

Reviewing files that changed from the base of the PR and between 48e7031 and e7b4efe.

📒 Files selected for processing (9)
  • docs/adr/0003-payment-accounting.md
  • docs/known-blockers.md
  • docs/status.md
  • ops/AUTONOMOUS_RUN.md
  • ops/ROADMAP.md
  • smart-contracts/StreamDrops.sol
  • test/README.md
  • test/StreamDropsIntegrationCharacterization.t.sol
  • test/StreamFixedPricePayments.t.sol

punk6529 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Merge decision for PR #60:

  • Latest head: 5f2770b0d82c04ecb49fc19c20c12665766389b1.
  • GitHub CI run 27270187899 passed on the latest head.
  • Claude was explicitly requested in comment 4669058148 and skipped due to organization overage (claude[bot] review 4466782762).
  • CodeRabbit was nudged in comment 4669093106; it acknowledged the full-review request in comment 4669095051.
  • CodeRabbit left one low-value nitpick in review 4466835437 to document intentional selfdestruct usage in the forced-ETH test helper. Commit b2d0a7481bc8392b1504b3a8687a12f274d4226e addresses that nitpick.
  • Final state commit 5f2770b0d82c04ecb49fc19c20c12665766389b1 only records merge-decision evidence in ops/AUTONOMOUS_RUN.md.
  • No inline review threads are open.
  • CodeRabbit commit status is still pending, but the available review evidence is clean after the fix and matches the stale-status behavior seen on prior merged PRs.

Proceeding with merge unless a new actionable review artifact appears before merge.

@punk6529 punk6529 merged commit f7390f2 into main Jun 10, 2026
1 of 2 checks passed
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.

[P0-PAY-003] Convert fixed-price payouts to credits

1 participant