feat: O.U.R.COOP artist-cooperative governance on the crowdstake stack#131
Open
RonTuretzky wants to merge 5 commits into
Open
feat: O.U.R.COOP artist-cooperative governance on the crowdstake stack#131RonTuretzky wants to merge 5 commits into
RonTuretzky wants to merge 5 commits into
Conversation
Custom cooperative built on the BreadKit/CrowdStake abstractions, all deployed via CrowdStakeFactory: - CovaDollarYield: USD-pegged yield-bearing AbstractToken over an ERC-4626 vault - CovaProjectRegistry: AbstractRecipientRegistry + full/min-viable budgets - OnePersonOneVotePower: IVotingPowerStrategy (one member, one equal vote) - CovaPointsVotingModule: AbstractVotingModule, raw 100-point ballots - CovaArtFundStrategy: AbstractDistributionStrategy with single-round top-N allocation + minimum-viable redistribution, driven per cycle by the AbstractDistributionManager + AbstractCycleModule (cycle-gated, no drain) - CovaWithdrawals: four-fund propose/vote/close governance - Sepolia mocks (MockUSD, MockUSDVault) so the yield token works on testnet - DeployCova.s.sol wires the full system via the factory - CovaCrowdstake.t.sol covers the end-to-end flows (worked example exact) - foundry.toml: enable optimizer (EIP-170 size); .gitignore: ignore broadcast/
…l' into RonTuretzky/cova-coin-custom-impl # Conflicts: # test/VotingStreakNFTModule.t.sol
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new src/cova/ feature slice that composes existing CrowdStake/BreadKit abstractions into an O.U.R.COOP artist-cooperative governance system (yield token + project registry + voting + distribution strategy + withdrawals), plus a Sepolia deployment script and end-to-end Foundry tests. Also includes minor formatting/cleanup changes in existing tests/contracts and enables the Foundry optimizer.
Changes:
- Introduces COVA modules: one-person-one-vote power, raw 100-point voting, project registry with budgets/metadata, Art Fund distribution strategy, and a withdrawals governance module.
- Adds Sepolia mocks (
MockUSD,MockUSDVault), aDeployCovascript, and an end-to-endCovaCrowdstakeintegration test. - Enables Foundry optimizer and applies small formatting/cleanup tweaks across a few existing files.
Reviewed changes
Copilot reviewed 26 out of 27 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| test/VotingStreakNFTModule.t.sol | Formatting cleanup in test assertions / tuple destructuring. |
| test/mocks/MockCrowdstakeNFT.sol | Removes trailing whitespace/line; no logic change. |
| test/fuzz/VotingModuleFuzz.t.sol | Formatting cleanup for EIP-712 hash construction and tuple destructuring. |
| test/fuzz/TWVPFuzz.t.sol | Formatting cleanup for fuzz test signature and braces. |
| test/fuzz/RecipientRegistryFuzz.t.sol | Formatting cleanup for fuzz test signature and braces. |
| test/fuzz/DistributionFuzz.t.sol | Formatting cleanup for fuzz test signatures and layout. |
| test/FactoryModuleDeployment.t.sol | Formatting cleanup for vm.mockCall and initializer payload encoding. |
| test/DistributionCycleIntegration.t.sol | Formatting cleanup for init payload and vm.mockCall usage. |
| test/cova/CovaCrowdstake.t.sol | New end-to-end tests covering token yield, distribution cycle gating, voting constraints, and withdrawals flow. |
| src/interfaces/ICrowdstakeNFT.sol | Trailing whitespace cleanup. |
| src/implementation/VotingStreakNFTModule.sol | Formatting cleanup; no apparent behavior change. |
| src/implementation/strategies/VotingDistributionStrategy.sol | Formatting cleanup for initializer signature. |
| src/implementation/strategies/EqualDistributionStrategy.sol | Formatting cleanup for initializer signature. |
| src/cova/OnePersonOneVotePower.sol | New curated membership-based IVotingPowerStrategy (1 member = 1 vote unit). |
| src/cova/mocks/MockUSDVault.sol | New minimal ERC-4626-style vault mock with yield simulation for Sepolia/testing. |
| src/cova/mocks/MockUSD.sol | New faucet-mintable USD ERC20 mock for Sepolia/testing. |
| src/cova/interfaces/ICovaProjectRegistry.sol | New interface extending recipient registry with project metadata + budgets. |
| src/cova/CovaWithdrawals.sol | New four-fund governance withdrawals module (propose/vote/close). |
| src/cova/CovaProjectRegistry.sol | New recipient registry implementation with project metadata (budgets/title/summary). |
| src/cova/CovaPointsVotingModule.sol | New raw 100-point ballot voting module (membership-gated, recast supported). |
| src/cova/CovaDollarYield.sol | New AbstractToken yield wrapper over an ERC-4626 USD vault. |
| src/cova/CovaArtFundStrategy.sol | New top-N, capped, min-viable redistribution distribution strategy driven by votes/budgets. |
| src/base/BasisPointsVotingModule.sol | Minor signature keyword ordering change (virtual override). |
| src/abstract/AbstractDistributionStrategy.sol | Formatting cleanup for initializer helpers. |
| script/DeployCova.s.sol | New deployment script wiring COVA modules through CrowdStakeFactory and seeding demo data. |
| foundry.toml | Enables optimizer + sets optimizer runs. |
| .gitignore | Ignores broadcast/ deployment artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+89
to
+94
| function initialize(address token_, address membership_, address coordinator_) external initializer { | ||
| __Ownable_init(coordinator_); | ||
| Store storage $ = _s(); | ||
| $.token = IERC20(token_); | ||
| $.membership = IMembership(membership_); | ||
| } |
Comment on lines
+120
to
+125
| if (fund >= FUND_COUNT) revert InvalidFund(); | ||
| Store storage $ = _s(); | ||
| if (amount == 0 || amount > $.funds[fund]) revert InvalidAmount(); | ||
| id = $.withdrawals.length; | ||
| $.withdrawals.push(Withdrawal(msg.sender, fund, amount, recipient, purpose, Status.Voting, 0, 0)); | ||
| emit WithdrawalProposed(id, msg.sender, fund, amount, recipient, purpose); |
Comment on lines
+145
to
+149
| if (w.amount > $.funds[w.fund]) revert InvalidAmount(); | ||
| w.status = Status.Approved; | ||
| $.funds[w.fund] -= w.amount; | ||
| $.token.safeTransfer(w.recipient, w.amount); | ||
| emit Movement(_name(w.fund), "recipient", w.amount, "withdrawal", w.purpose); |
Comment on lines
+13
to
+15
| /// use. The queued add/remove + `processQueue` cycle semantics of the | ||
| /// base registry apply (changes land at the cycle boundary). | ||
| contract CovaProjectRegistry is AbstractRecipientRegistry, ICovaProjectRegistry { |
Comment on lines
+5
to
+6
| optimizer = true | ||
| optimizer_runs = 200 |
Comment on lines
+257
to
+265
| function test_withdrawalFlow() public { | ||
| _mintCusd(5350 * E); | ||
| tok.approve(address(wd), 5350 * E); | ||
| wd.allocateInflow([uint256(1200 * E), 800 * E, 950 * E, 2400 * E], "Quarterly"); | ||
| assertEq(wd.getFunds()[1], 800 * E); | ||
|
|
||
| vm.prank(m1); | ||
| uint256 id = wd.proposeWithdrawal(1, 300 * E, address(0xCAFE), "Workshop"); | ||
| vm.prank(m2); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
src/cova/— a custom O.U.R.COOP artist-cooperative built entirely on the BreadKit/CrowdStake abstractions and deployed viaCrowdStakeFactory:CovaDollarYield(USD-pegged yield-bearingAbstractTokenover an ERC-4626 vault),CovaProjectRegistry(AbstractRecipientRegistry+ full/minimum-viable budgets),OnePersonOneVotePower(IVotingPowerStrategy, one member = one equal vote),CovaPointsVotingModule(AbstractVotingModule, raw 100-point ballots),CovaArtFundStrategy(AbstractDistributionStrategysingle-round top-N allocation with minimum-viable redistribution, driven per cycle byAbstractDistributionManager+AbstractCycleModuleso funding is cycle-gated and non-drainable), andCovaWithdrawals(four-fund propose/vote/close governance). Includes Sepolia mocks (MockUSD,MockUSDVault) so the yield token works on testnet,script/DeployCova.s.solwiring the whole system through the factory, andtest/cova/CovaCrowdstake.t.solcovering the end-to-end flows (the spec's worked example matches exactly).foundry.tomlenables the optimizer (contracts exceed EIP-170 without it) and.gitignorenow excludesbroadcast/deployment artifacts. No existing protocol files are modified — this is purely additive on top of v0.0.1.