On-chain rebate transparency for independent pharmacies and patients.
Caution
This contract has NOT yet been audited by an independent security firm. Do NOT deploy, deposit, or route real capital to this treasury on mainnet until a formal cryptographic and safety audit has been completed and published.
Prereqs: Node.js + npm.
Windows PowerShell note: if npm is blocked by script execution policy, use npm.cmd instead.
npm.cmd ci
npm.cmd run compile
npm.cmd testGenerate Merkle roots + proofs (internal tooling):
npm.cmd run merkle:allocations -- --in allocations.json --out merkle.jsonThe Pharmacy Fiduciary Commons is designed as a structural mechanism for routing corporate PBM surplus away from extraction and toward the community's preventative health floor. Off-chain arbitration, design constraints, and ethical drift checks should remain portable, reviewable, and independent of any single local workspace.
PBMRebateTreasury is an Ethereum smart contract that:
- Records every rebate deposit permanently on-chain with depositor identity, amount, quarter, drug class, and source — in a format that cannot be altered retroactively
- Routes captured funds directly to independent pharmacies via Merkle-proof claims (tracked per epoch under individual
epochEscrowvaults to avoid over-allocation) - Allocates 10% of every gross claim to a dedicated patient fund, automatically, at claim time
- Makes every missing deposit equally visible — a Ledger of Omissions in which every quarter a PBM does not deposit is a timestamped, permanent, documented record
The project avoids generic "greenwashing" by explicitly linking health access to resource efficiency. The Patient Fund supports community-led programs targeting:
- Medication Waste Reduction: Systems to prevent shelf expiration and recover unopened medications.
- Cold-Chain Efficiency: Solar-powered medical refrigeration for independent local pharmacies.
- Local Delivery Route Efficiency: Shared, low-carbon delivery systems for homebound patients.
- Pharmacy Energy Resilience: Small-scale solar + storage systems for community pharmacy back-up power.
- Safe Disposal Programs: Community drug take-back boxes and eco-friendly disposal kits.
- Low-Waste Refill Logistics: Bulk refill dispensing and reusable container packaging.
- Disaster-Resilient Medication Access: Pre-positioned emergency medicine supplies and secure mobile pharmacy units.
To preserve the simplicity and security of the audited rebate treasury, adjacent systems must remain strictly decoupled:
- Pharmacy Mutual-Aid Credit Lines: Decoupled from the treasury; handled by separate mutual credit systems.
- Emergency Medication Voucher Ledger: Decoupled from on-chain escrow; managed on separate coordination layers.
- Cooperative Procurement: Shared formulary and pricing intelligence services run off-chain.
California SB 41 (signed October 2025, effective January 2026) mandates 100% rebate pass-through — but explicitly exempts Taft-Hartley self-insured union plans, which cover tens of millions of American workers. The FTC's January 2025 report documented $7.3 billion in excess PBM revenue. Federal law currently requires nothing comparable to SB 41 for these plans.
The gap is not in the law. It is in the infrastructure. This contract is that infrastructure.
DOL CAR 2025-01 (May 2025) formally removed the prior "extreme care" standard for cryptocurrency in ERISA plans. Stablecoins (DAI, USDC) are now evaluated under the standard prudent process applicable to any asset class.
| Bucket | Allocation | Purpose |
|---|---|---|
| Distribution Pool | 99% | Pharmacy Merkle claims |
| Governance Reserve | 1% | Council operations (EXECUTOR_ROLE access only) |
| Source | Amount |
|---|---|
| Every gross claim | 10% routed to patientFund |
| Unclaimed epoch funds after 30-day recall delay | 100% to patientFund |
| Non-payout token sweeps | 100% to patientFund |
| Role | Holder | Permissions |
|---|---|---|
COUNCIL_ROLE |
3/5 Gnosis Safe | Epoch management, root co-sign, recall, sanctions, unpause |
EXECUTOR_ROLE |
TimelockController | Cap changes, governance reserve withdrawal, env fund update |
GUARDIAN_ROLE |
Separate fast-response address | Emergency pause only — cannot unpause, cannot access funds |
- PBM (or any party) calls
depositRebate()— funds enter escrow, source logged permanently - Council member calls
proposeRoot()— Merkle root proposed for current epoch - Second distinct council member calls
confirmRoot()— root goes live (co-sign gate) - Pharmacies (or delegated claims agent) call
claim()orclaimBatch()(array compatibility wrapper — enforces exactly one entry) - Council calls
finalizeEpoch()to close epoch and open the next - After 30-day
RECALL_DELAY, unclaimed funds recalled topatientFund
- Hard cap enforced at root proposal and claim (monotonic decrease only — ratchet)
- Daily cap enforced at root proposal and claim
- Root total enforced at claim
- Per-pharmacy cap enforced via Merkle leaf encoding
- Double-hash leaf construction (second-preimage protection)
- Root publication requires co-sign from two distinct
COUNCIL_ROLEmembers - Daily cap bounded by hard cap at all times
- Recall only after
RECALL_DELAY, only unclaimed amount, sent topatientFund - Payout token cannot be swept
- Non-payout tokens swept to
patientFund(not general fund) GUARDIAN_ROLEis a separate address fromCOUNCIL_ROLEflagClaimrequires a valid Merkle proof — pool-locking griefing preventedflagClaimincrementsepochClaimedTotal,epochVolume, and setshasClaimed— caps and recall math fully consistent on disputed epochs- Sanctioned addresses cannot flag claims — pool-locking via dispute prevented
- Open dispute flag blocks
claim()— no parallel claim and dispute on same epoch - ETH rejected via
receive()andfallback()with typed custom errors throughout — no string reverts - No upgradeability
// Double-hash — second-preimage protection
// abi.encodePacked is safe here: all fields are fixed-size (address + uint256 + uint256)
bytes32 leaf = keccak256(
bytes.concat(keccak256(abi.encodePacked(pharmacy, grossAmount, eligibleCap)))
);Each leaf encodes:
pharmacy— claimant addressgrossAmount— gross allocation this epoch (patient share drawn from this)eligibleCap— per-pharmacy maximum enforced on-chain
Off-chain tooling note: Merkle tree generators and proof scripts must use
encodePacked(notencode) when hashing leaves, or proofs will be invalid on-chain.
@openzeppelin/contracts ^4.x
- token/ERC20/utils/SafeERC20
- token/ERC20/IERC20
- security/ReentrancyGuard
- security/Pausable
- access/AccessControlEnumerable
- utils/cryptography/MerkleProof
The canonical contract source is:
contracts/PBMRebateTreasury.sol
constructor(
address _token, // DAI or USDC contract address
address _patientFund, // Immutable — receives patient allocations
address _environmentalFund, // Receives accidentally sent ETH
uint256 _initialDailyCap, // Starting daily volume cap (hardCap = dailyCap * 10)
address _council, // 3/5 Gnosis Safe — COUNCIL_ROLE + DEFAULT_ADMIN_ROLE
address _executor, // TimelockController — EXECUTOR_ROLE
address _guardian // Separate address — GUARDIAN_ROLE only, must != _council
)Before deploying to mainnet:
- Complete a formal security audit
- Configure a 3/5 Gnosis Safe for
_council- Deploy and configure a
TimelockControllerfor_executor- Confirm
_guardianis a separate, dedicated address- Verify all addresses on the target network
This repo includes a convenience script that deploys a TimelockController and then deploys PBMRebateTreasury with the timelock address wired in as _executor:
scripts/deploy-timelock-and-treasury.js
Required environment variables:
TOKENPATIENT_FUNDENVIRONMENTAL_FUNDINITIAL_DAILY_CAP(integer string, token base units)COUNCILGUARDIAN
Optional timelock configuration:
TIMELOCK_MIN_DELAY_SECONDS(default: 172800 / 2 days)TIMELOCK_PROPOSERS(comma-separated; default:COUNCIL)TIMELOCK_EXECUTORS(comma-separated; default:0x0000000000000000000000000000000000000000= anyone can execute)TIMELOCK_ADMIN(default:COUNCIL)
| Status | Detail |
|---|---|
| ✅ Internal review complete | Architecture and security properties reviewed by contract author |
| ⏳ External audit | Pending — budgeted for pre-mainnet deployment |
| ❌ Mainnet deployment | Not yet deployed — do not use with real funds |
Audit inquiries: open an issue or see contact below.
| Component | Status |
|---|---|
| Smart contract | ✅ Complete |
| Public dashboard (epochStats / Ledger of Omissions) | 🔨 In development |
| Merkle tree generator + proof tooling | 🔨 In development |
| ERISA counsel review of model procurement clause | ⏳ Pending funding |
| Mainnet deployment | ⏳ Pending audit |
This is an open-source public goods project. Contributions welcome — particularly:
- Merkle tree generation tooling (JavaScript / Python)
- Dashboard frontend
- Test suite expansion
- Documentation improvements
Open an issue to discuss before submitting a large PR.
MIT — see LICENSE
Independent pharmacies serve the communities that large chains abandon. They dispense prescriptions on thin margins, absorb retroactive clawbacks they cannot audit, and have no ledger to point to when the numbers don't add up.
This contract is that ledger.
Every deposit is permanent. Every omission is equally permanent. PBM silence is the evidence.
This repository does not constitute legal, financial, or investment advice. All procurement clause language referenced in project documentation requires review by qualified ERISA counsel before use in any plan document or RFP.