@ballkidz/defifa 0.0.17 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ADMINISTRATION.md +34 -6
- package/ARCHITECTURE.md +54 -102
- package/AUDIT_INSTRUCTIONS.md +96 -504
- package/CHANGELOG.md +26 -0
- package/README.md +61 -207
- package/RISKS.md +19 -2
- package/SKILLS.md +29 -281
- package/STYLE_GUIDE.md +57 -18
- package/USER_JOURNEYS.md +45 -1011
- package/foundry.lock +17 -0
- package/package.json +5 -6
- package/references/operations.md +27 -0
- package/references/runtime.md +32 -0
- package/script/Deploy.s.sol +5 -3
- package/src/DefifaDeployer.sol +33 -9
- package/src/DefifaGovernor.sol +63 -30
- package/src/DefifaHook.sol +33 -13
- package/src/interfaces/IDefifaDeployer.sol +28 -1
- package/src/interfaces/IDefifaGovernor.sol +26 -0
- package/src/interfaces/IDefifaHook.sol +30 -1
- package/src/libraries/DefifaHookLib.sol +8 -0
- package/test/DefifaGovernor.t.sol +55 -32
- package/test/DefifaSecurity.t.sol +1 -3
- package/test/Fork.t.sol +3 -9
- package/test/audit/CodexRegistryMismatch.t.sol +191 -0
- package/test/audit/PendingReserveSnapshotBypass.t.sol +40 -0
- package/test/regression/AttestationDelegateBeneficiary.t.sol +3 -5
- package/CHANGE_LOG.md +0 -164
package/CHANGE_LOG.md
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
# defifa-collection-deployer-v6 Changelog (v5 → v6)
|
|
2
|
-
|
|
3
|
-
This document describes the changes between `defifa-collection-deployer` (v5) and `defifa-collection-deployer-v6` (v6). Defifa is an on-chain prediction game framework built on Juicebox where players mint NFTs representing outcomes, a governor ratifies scorecard distributions, and winners burn NFTs to claim proportional shares.
|
|
4
|
-
|
|
5
|
-
## Summary
|
|
6
|
-
|
|
7
|
-
- **V6 hook migration**: All 721 hook interactions updated from `nana-721-hook-v5` to `nana-721-hook-v6`, including the new tier splits system and `splitPercent` field in `JB721TierConfig`.
|
|
8
|
-
- **Dependency modernization**: Core, permission IDs, address registry, and ownable dependencies all updated to v6. New ecosystem dependencies on `croptop-core-v6` and `revnet-core-v6`.
|
|
9
|
-
- **Error naming standardized**: Error names changed from bare names (e.g., `InvalidCashoutWeights`) to contract-prefixed names (e.g., `DefifaHook_InvalidCashoutWeights`).
|
|
10
|
-
- **Cash out hook spec gains `noop` field**: `beforeCashOutRecordedWith` now returns `noop=false` in all specifications, ensuring the terminal always calls the hook callback.
|
|
11
|
-
- **Compiler/tooling updated**: The v6 repo now builds and tests on Solidity `0.8.28`, matching the rest of the V6 ecosystem.
|
|
12
|
-
- **Game lifecycle preserved**: The core game phases (COUNTDOWN → MINT → REFUND → SCORING → COMPLETE) and governance model (50% quorum, scorecard ratification) remain the same at the product level even though the underlying hook/controller integrations changed.
|
|
13
|
-
|
|
14
|
-
## ABI Status
|
|
15
|
-
|
|
16
|
-
This repo does have meaningful ABI migration surface. The main ABI-facing contracts for integrators are:
|
|
17
|
-
- `IDefifaDeployer`
|
|
18
|
-
- `IDefifaHook`
|
|
19
|
-
- `IDefifaGovernor`
|
|
20
|
-
|
|
21
|
-
The largest ABI risks are:
|
|
22
|
-
- inherited 721-hook/core-v6 struct and return-shape changes flowing through Defifa interfaces;
|
|
23
|
-
- event families now living on v6 interfaces/contracts with prefixed errors and updated dependent types;
|
|
24
|
-
- hook return values that now include v6 `noop`-aware hook-spec structures.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 1. Breaking Changes
|
|
29
|
-
|
|
30
|
-
### 1.1 Dependency Updates
|
|
31
|
-
|
|
32
|
-
| Dependency | v5 | v6 |
|
|
33
|
-
|------------|----|----|
|
|
34
|
-
| `@bananapus/core` | `v5` | `v6` |
|
|
35
|
-
| `@bananapus/721-hook` | `v5` | `v6` |
|
|
36
|
-
| `@bananapus/address-registry` | `v5` | `v6` |
|
|
37
|
-
| `@bananapus/permission-ids` | `v5` | `v6` (new dependency) |
|
|
38
|
-
| `@openzeppelin/contracts` | `^5.4.0` | `5.2.0` (pinned) |
|
|
39
|
-
| `@croptop/core` | N/A | `v6` (new) |
|
|
40
|
-
| `@rev-net/core` | N/A | `v6` (new) |
|
|
41
|
-
|
|
42
|
-
### 1.2 Error Naming Convention
|
|
43
|
-
|
|
44
|
-
All custom errors now use a contract-name prefix:
|
|
45
|
-
|
|
46
|
-
| v5 | v6 |
|
|
47
|
-
|----|----|
|
|
48
|
-
| `InvalidCashoutWeights` | `DefifaHook_InvalidCashoutWeights` |
|
|
49
|
-
| `InvalidPhase` | `DefifaHook_InvalidPhase` |
|
|
50
|
-
| (and similar for all other errors) | Contract prefix added throughout |
|
|
51
|
-
|
|
52
|
-
### 1.3 `JBCashOutHookSpecification` Gains `noop` Field
|
|
53
|
-
|
|
54
|
-
The v6 `JBCashOutHookSpecification` struct has a `noop` boolean field. `DefifaHook.beforeCashOutRecordedWith` returns `noop=false` in all specifications, ensuring the terminal always invokes `afterCashOutRecordedWith` for game-phase-aware cashout processing.
|
|
55
|
-
|
|
56
|
-
### 1.4 Solidity Version
|
|
57
|
-
|
|
58
|
-
- **v5:** `pragma solidity 0.8.23`
|
|
59
|
-
- **v6:** `pragma solidity 0.8.28`
|
|
60
|
-
|
|
61
|
-
### 1.5 721 Hook API Changes
|
|
62
|
-
|
|
63
|
-
Inherited from `nana-721-hook-v6`:
|
|
64
|
-
- `cashOutWeightOf()` and `totalCashOutWeight()` signatures simplified (removed `JBBeforeCashOutRecordedContext` parameter)
|
|
65
|
-
- `pricingContext()` returns 2 values instead of 3
|
|
66
|
-
- `JB721TierConfig` gained `splitPercent` and `splits` fields
|
|
67
|
-
- `JB721TiersHookFlags` gained `issueTokensForSplits` field
|
|
68
|
-
|
|
69
|
-
### 1.6 Function-Level Integration Changes
|
|
70
|
-
|
|
71
|
-
These are the main V6 surface changes integrators should care about:
|
|
72
|
-
- `beforeCashOutRecordedWith(...)` now returns a `JBCashOutHookSpecification` that includes the new `noop` field from core-v6.
|
|
73
|
-
- Any integration constructing or decoding `JB721TierConfig` must account for the added `splitPercent` and `splits` fields.
|
|
74
|
-
- Any integration reading pricing context from the inherited 721 hook must expect 2 return values, not 3.
|
|
75
|
-
- Defifa deployer integrations should re-check `launchGameWith(...)`, `fulfillCommitmentsOf(...)`, `triggerNoContestFor(...)`, `nextPhaseNeedsQueueing(...)`, `safetyParamsOf(...)`, and `timesFor(...)` against the v6 ABIs and dependent core-v6 structs.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## 2. Game Lifecycle (Unchanged)
|
|
80
|
-
|
|
81
|
-
The core game phases remain identical between v5 and v6:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
COUNTDOWN (ruleset 0) → MINT (ruleset 1) → REFUND (ruleset 2)
|
|
85
|
-
→ SCORING (ruleset 3+) → COMPLETE (after ratification)
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Safety mechanisms:
|
|
89
|
-
- **NO_CONTEST**: Triggered if `minParticipation` not met or `scorecardTimeout` exceeded
|
|
90
|
-
- **Scorecard governance**: 50% quorum, tier-delegated voting power with checkpointed snapshots
|
|
91
|
-
- **Grace period**: Minimum 1 day for governance proposals
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## 3. Architecture
|
|
96
|
-
|
|
97
|
-
### 3.1 Key Contracts
|
|
98
|
-
|
|
99
|
-
| Contract | Role |
|
|
100
|
-
|----------|------|
|
|
101
|
-
| `DefifaDeployer` | Game factory -- launches projects with phased rulesets, manages fulfillment |
|
|
102
|
-
| `DefifaHook` | ERC-721 hook with game logic, attestation, per-tier cashout weights |
|
|
103
|
-
| `DefifaGovernor` | Shared singleton for scorecard submission/attestation/ratification |
|
|
104
|
-
| `DefifaProjectOwner` | Proxy that receives project NFT and grants deployer permissions |
|
|
105
|
-
| `DefifaTokenUriResolver` | On-chain SVG metadata with dynamic game state |
|
|
106
|
-
|
|
107
|
-
### 3.2 Deployment Pattern
|
|
108
|
-
|
|
109
|
-
DefifaHook instances are deployed as minimal proxy clones via `Clones.cloneDeterministic()`:
|
|
110
|
-
- Salt includes `msg.sender` + nonce (prevents cross-caller collision)
|
|
111
|
-
- One-time `initialize()` call per clone
|
|
112
|
-
- Owned by DefifaGovernor for scorecard weight setting
|
|
113
|
-
|
|
114
|
-
## 4. Events and Errors
|
|
115
|
-
|
|
116
|
-
The most important integration-facing patterns are:
|
|
117
|
-
- Errors are now consistently contract-prefixed (`DefifaHook_*`, `DefifaDeployer_*`, `DefifaGovernor_*`, `DefifaProjectOwner_*`) instead of using the older unprefixed style.
|
|
118
|
-
- Defifa-specific events remain centered around game launch, phase transitions, fulfillment, scoring, minting, claims, and delegation, but they now live against the V6 hook/controller stack and should be indexed using the V6 ABIs.
|
|
119
|
-
- `CommitmentPayoutFailed`, `LaunchGame`, `QueuedRefundPhase`, `QueuedScoringPhase`, `QueuedNoContest`, `GameInitialized`, `ScorecardSubmitted`, `ScorecardAttested`, `ScorecardRatified`, `Mint`, `MintReservedToken`, `ClaimedTokens`, and `TierCashOutWeightsSet` are the key integration events to watch across the deployer, governor, and hook.
|
|
120
|
-
- Other hook-level events worth indexing for governance clients are `TierDelegateAttestationsChanged` and `DelegateChanged`.
|
|
121
|
-
|
|
122
|
-
Key runtime errors now exposed by the v6 contracts include:
|
|
123
|
-
- `DefifaDeployer_*` errors such as `DefifaDeployer_InvalidGameConfiguration`, `DefifaDeployer_TerminalNotFound`, `DefifaDeployer_SplitsDontAddUp`, `DefifaDeployer_CantFulfillYet`, and `DefifaDeployer_NoContestAlreadyTriggered`.
|
|
124
|
-
- `DefifaHook_*` errors such as `DefifaHook_InvalidCashoutWeights`, `DefifaHook_InvalidTierId`, `DefifaHook_ReservedTokenMintingPaused`, `DefifaHook_TransfersPaused`, and `DefifaHook_Unauthorized(...)`.
|
|
125
|
-
- `DefifaGovernor_*` errors such as `DefifaGovernor_AlreadyAttested`, `DefifaGovernor_AlreadyRatified`, `DefifaGovernor_DuplicateScorecard`, `DefifaGovernor_NotAllowed`, and `DefifaGovernor_UnknownProposal`.
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## 5. Migration Table
|
|
130
|
-
|
|
131
|
-
| Aspect | v5 | v6 |
|
|
132
|
-
|--------|----|----|
|
|
133
|
-
| Core dependency | `@bananapus/core-v5` | `@bananapus/core-v6` |
|
|
134
|
-
| 721 hook dependency | `@bananapus/721-hook-v5` | `@bananapus/721-hook-v6` |
|
|
135
|
-
| Permission IDs | Not a direct dependency | `@bananapus/permission-ids-v6` |
|
|
136
|
-
| Error naming | Bare names | Contract-prefixed names |
|
|
137
|
-
| `JBCashOutHookSpecification` | No `noop` field | `noop=false` on all specs |
|
|
138
|
-
| Solidity version | `0.8.23` | `0.8.28` |
|
|
139
|
-
| Game lifecycle | COUNTDOWN->MINT->REFUND->SCORING->COMPLETE | Identical |
|
|
140
|
-
| Governance model | 50% quorum, tier-delegated | Identical |
|
|
141
|
-
|
|
142
|
-
> **Cross-repo impact**: Uses `nana-721-hook-v6` for all tier management and cashout weight distribution. The `nana-permission-ids-v6` ID shifts affect any hardcoded permission checks. `deploy-all-v6` now includes Defifa as Phase 10, so canonical deployments can source Defifa addresses from the top-level rollout.
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## 6. Post-Audit Fixes (Codex R2)
|
|
147
|
-
|
|
148
|
-
### 6.1 H-1: Prevent same-block double attestation via checkpoint snapshot
|
|
149
|
-
|
|
150
|
-
**File:** `DefifaGovernor.sol` -- `attestToScorecardFrom()`
|
|
151
|
-
|
|
152
|
-
Previously, attestation weight was snapshot at `_scorecard.attestationsBegin`, which could equal `block.timestamp` during the same block as a transfer. This allowed a holder to attest, transfer the NFT, and have the recipient also attest in the same block -- both counting because `upperLookup(block.timestamp)` includes same-block checkpoints.
|
|
153
|
-
|
|
154
|
-
**Fix:** Changed the checkpoint timestamp to `attestationsBegin - 1`, ensuring only state from before the attestation window opens is visible. Same-block transfer recipients now receive zero attestation weight. Note: NFTs minted in the same block as `attestationsBegin` have zero weight for attestation -- a negligible trade-off since attestation typically happens well after minting.
|
|
155
|
-
|
|
156
|
-
### 6.2 H-2: Snapshot pending reserves at scorecard submission and include in denominators
|
|
157
|
-
|
|
158
|
-
**Files:** `DefifaGovernor.sol` -- `submitScorecardFor()`, `getBWAAttestationWeight()`; `DefifaHook.sol` -- `afterCashOutRecordedWith()`
|
|
159
|
-
|
|
160
|
-
Two related fixes to prevent gaming via pending reserve manipulation:
|
|
161
|
-
|
|
162
|
-
**Governance (attestation weight):** Previously, `getBWAAttestationWeight()` read pending reserve counts live from the store. Minting reserves between scorecard submission and attestation could inflate a holder's BWA power by removing the pending-reserve dilution. **Fix:** `submitScorecardFor()` now snapshots `numberOfPendingReservesFor()` for every tier into `_pendingReservesSnapshotOf[gameId][scorecardId][tierId]`. `getBWAAttestationWeight()` reads from this snapshot instead of live state, locking the dilution in place regardless of subsequent reserve minting.
|
|
163
|
-
|
|
164
|
-
**Cash-out (fee token distribution):** Previously, the fee token claim denominator (`_totalMintCost`) only counted minted tokens. Pending (unminted) reserve NFTs were excluded, allowing paid holders to cash out before reserves were minted and claim a disproportionate share of fee tokens ($DEFIFA/$NANA). **Fix:** `afterCashOutRecordedWith()` now passes `_totalMintCost + _pendingReserveMintCost()` as the denominator when distributing fee tokens. The new `_pendingReserveMintCost()` function iterates all tiers and sums `pendingReserves * tier.price`, ensuring pending reserves are accounted for in fee token distribution.
|