@ballkidz/defifa 0.0.25 → 0.0.27

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.
Files changed (65) hide show
  1. package/AUDIT_INSTRUCTIONS.md +6 -2
  2. package/README.md +11 -2
  3. package/RISKS.md +3 -1
  4. package/STYLE_GUIDE.md +14 -11
  5. package/package.json +31 -14
  6. package/script/Deploy.s.sol +4 -1
  7. package/src/DefifaDeployer.sol +79 -47
  8. package/src/DefifaGovernor.sol +57 -12
  9. package/src/DefifaHook.sol +83 -26
  10. package/src/DefifaProjectOwner.sol +4 -3
  11. package/src/DefifaTokenUriResolver.sol +113 -20
  12. package/src/enums/DefifaGamePhase.sol +6 -0
  13. package/src/enums/DefifaScorecardState.sol +4 -0
  14. package/src/interfaces/IDefifaDeployer.sol +5 -0
  15. package/src/interfaces/IDefifaGamePhaseReporter.sol +4 -0
  16. package/src/interfaces/IDefifaGamePotReporter.sol +10 -0
  17. package/src/interfaces/IDefifaGovernor.sol +4 -0
  18. package/src/interfaces/IDefifaHook.sol +5 -0
  19. package/src/interfaces/IDefifaTokenUriResolver.sol +3 -0
  20. package/src/libraries/DefifaFontImporter.sol +1 -1
  21. package/src/libraries/DefifaHookLib.sol +9 -10
  22. package/src/structs/DefifaAttestations.sol +3 -2
  23. package/src/structs/DefifaDelegation.sol +1 -0
  24. package/src/structs/DefifaLaunchProjectData.sol +2 -3
  25. package/src/structs/DefifaOpsData.sol +1 -0
  26. package/src/structs/DefifaScorecard.sol +2 -0
  27. package/src/structs/DefifaTierCashOutWeight.sol +3 -1
  28. package/src/structs/DefifaTierParams.sol +1 -0
  29. package/CRYPTO_ECON.pdf +0 -0
  30. package/CRYPTO_ECON.tex +0 -997
  31. package/foundry.lock +0 -17
  32. package/references/operations.md +0 -32
  33. package/references/runtime.md +0 -43
  34. package/slither-ci.config.json +0 -10
  35. package/sphinx.lock +0 -521
  36. package/test/BWAFunctionComparison.t.sol +0 -1320
  37. package/test/DefifaAdversarialQuorum.t.sol +0 -617
  38. package/test/DefifaAuditLowGuards.t.sol +0 -308
  39. package/test/DefifaFeeAccounting.t.sol +0 -581
  40. package/test/DefifaGovernanceHardening.t.sol +0 -1315
  41. package/test/DefifaGovernor.t.sol +0 -1378
  42. package/test/DefifaHookRegressions.t.sol +0 -415
  43. package/test/DefifaMintCostInvariant.t.sol +0 -319
  44. package/test/DefifaNoContest.t.sol +0 -941
  45. package/test/DefifaSecurity.t.sol +0 -741
  46. package/test/DefifaUSDC.t.sol +0 -480
  47. package/test/Fork.t.sol +0 -2388
  48. package/test/TestAuditGaps.sol +0 -984
  49. package/test/TestQALastMile.t.sol +0 -514
  50. package/test/audit/AttestationDoubleCount.t.sol +0 -218
  51. package/test/audit/CodexNemesisCurrencyMismatchBypass.t.sol +0 -112
  52. package/test/audit/CodexNemesisNoContestReserveDrain.t.sol +0 -238
  53. package/test/audit/CodexNemesisOneTierZeroTimeoutLockVerified.t.sol +0 -218
  54. package/test/audit/CodexNemesisSingleTierTimeoutLock.t.sol +0 -237
  55. package/test/audit/CodexRegistryMismatch.t.sol +0 -191
  56. package/test/audit/CodexTierCapMismatch.t.sol +0 -171
  57. package/test/audit/CurrencyMismatchFix.t.sol +0 -265
  58. package/test/audit/FixPendingReserveDilution.t.sol +0 -366
  59. package/test/audit/H5TierCapValidation.t.sol +0 -184
  60. package/test/audit/PendingReserveDilution.t.sol +0 -298
  61. package/test/audit/PendingReserveQuorumGrief.t.sol +0 -355
  62. package/test/audit/PendingReserveSnapshotBypass.t.sol +0 -319
  63. package/test/regression/AttestationDelegateBeneficiary.t.sol +0 -271
  64. package/test/regression/FulfillmentBlocksRatification.t.sol +0 -279
  65. package/test/regression/GracePeriodBypass.t.sol +0 -302
@@ -1,218 +0,0 @@
1
- // SPDX-License-Identifier: UNLICENSED
2
- pragma solidity 0.8.28;
3
-
4
- import {DefifaDeployer} from "../../src/DefifaDeployer.sol";
5
- import {DefifaGamePhase} from "../../src/enums/DefifaGamePhase.sol";
6
- import {DefifaGovernor} from "../../src/DefifaGovernor.sol";
7
- import {DefifaHook} from "../../src/DefifaHook.sol";
8
- import {DefifaTokenUriResolver} from "../../src/DefifaTokenUriResolver.sol";
9
- import {DefifaLaunchProjectData} from "../../src/structs/DefifaLaunchProjectData.sol";
10
- import {DefifaTierCashOutWeight} from "../../src/structs/DefifaTierCashOutWeight.sol";
11
- import {DefifaTierParams} from "../../src/structs/DefifaTierParams.sol";
12
- import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
13
- import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
14
- import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
15
- import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
16
- import {JBCurrencyIds} from "@bananapus/core-v6/src/libraries/JBCurrencyIds.sol";
17
- import {JBFundAccessLimitGroup} from "@bananapus/core-v6/src/structs/JBFundAccessLimitGroup.sol";
18
- import {JBMultiTerminal} from "@bananapus/core-v6/src/JBMultiTerminal.sol";
19
- import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
20
- import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
21
- import {JBRulesetMetadata} from "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
22
- import {JBRulesetMetadataResolver} from "@bananapus/core-v6/src/libraries/JBRulesetMetadataResolver.sol";
23
- import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
24
- import {JBSplitGroup} from "@bananapus/core-v6/src/structs/JBSplitGroup.sol";
25
- import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
26
- import {IJBRulesetApprovalHook} from "@bananapus/core-v6/src/interfaces/IJBRulesetApprovalHook.sol";
27
- import {JBTest} from "@bananapus/core-v6/test/helpers/JBTest.sol";
28
- import {TestBaseWorkflow} from "@bananapus/core-v6/test/helpers/TestBaseWorkflow.sol";
29
- import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
30
- import {IJB721TokenUriResolver} from "@bananapus/721-hook-v6/src/interfaces/IJB721TokenUriResolver.sol";
31
- import {ITypeface} from "lib/typeface/contracts/interfaces/ITypeface.sol";
32
-
33
- contract CodexNemesisOneTierZeroTimeoutLockVerifiedTest is JBTest, TestBaseWorkflow {
34
- using JBRulesetMetadataResolver for JBRuleset;
35
-
36
- uint256 internal constant GAME_ID = 3;
37
-
38
- DefifaDeployer internal deployer;
39
- DefifaGovernor internal governor;
40
- DefifaHook internal hook;
41
-
42
- uint256 internal projectId;
43
- DefifaHook internal gameHook;
44
-
45
- address internal projectOwner = address(bytes20(keccak256("projectOwner")));
46
- address internal player = address(bytes20(keccak256("player")));
47
-
48
- function setUp() public override {
49
- super.setUp();
50
-
51
- JBAccountingContext[] memory tokens = new JBAccountingContext[](1);
52
- tokens[0] = JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: JBCurrencyIds.ETH});
53
-
54
- JBTerminalConfig[] memory terminalConfigs = new JBTerminalConfig[](1);
55
- terminalConfigs[0] = JBTerminalConfig({terminal: jbMultiTerminal(), accountingContextsToAccept: tokens});
56
-
57
- JBRulesetConfig[] memory rulesetConfigs = new JBRulesetConfig[](1);
58
- rulesetConfigs[0] = JBRulesetConfig({
59
- mustStartAtOrAfter: 0,
60
- duration: 10 days,
61
- weight: 1e18,
62
- weightCutPercent: 0,
63
- approvalHook: IJBRulesetApprovalHook(address(0)),
64
- metadata: JBRulesetMetadata({
65
- reservedPercent: 0,
66
- cashOutTaxRate: 0,
67
- baseCurrency: JBCurrencyIds.ETH,
68
- pausePay: false,
69
- pauseCreditTransfers: false,
70
- allowOwnerMinting: false,
71
- allowSetCustomToken: false,
72
- allowTerminalMigration: false,
73
- allowSetTerminals: false,
74
- allowSetController: false,
75
- allowAddAccountingContext: false,
76
- allowAddPriceFeed: false,
77
- ownerMustSendPayouts: false,
78
- holdFees: false,
79
- useTotalSurplusForCashOuts: false,
80
- useDataHookForPay: true,
81
- useDataHookForCashOut: true,
82
- dataHook: address(0),
83
- metadata: 0
84
- }),
85
- splitGroups: new JBSplitGroup[](0),
86
- fundAccessLimitGroups: new JBFundAccessLimitGroup[](0)
87
- });
88
-
89
- uint256 protocolFeeProjectId =
90
- jbController().launchProjectFor(projectOwner, "", rulesetConfigs, terminalConfigs, "");
91
- vm.prank(projectOwner);
92
- address protocolFeeToken =
93
- address(jbController().deployERC20For(protocolFeeProjectId, "Bananapus", "NANA", bytes32(0)));
94
-
95
- uint256 defifaProjectId = jbController().launchProjectFor(projectOwner, "", rulesetConfigs, terminalConfigs, "");
96
- vm.prank(projectOwner);
97
- address defifaToken = address(jbController().deployERC20For(defifaProjectId, "Defifa", "DEFIFA", bytes32(0)));
98
-
99
- hook = new DefifaHook(jbDirectory(), IERC20(defifaToken), IERC20(protocolFeeToken));
100
- governor = new DefifaGovernor(jbController(), address(this));
101
- deployer = new DefifaDeployer(
102
- address(hook),
103
- new DefifaTokenUriResolver(ITypeface(address(0))),
104
- governor,
105
- jbController(),
106
- new JBAddressRegistry(),
107
- defifaProjectId,
108
- protocolFeeProjectId
109
- );
110
-
111
- hook.transferOwnership(address(deployer));
112
- governor.transferOwnership(address(deployer));
113
- }
114
-
115
- function test_oneTier_zeroTimeout_permanentlyLocksGameInScoring() external {
116
- projectId = deployer.launchGameWith(_launchData());
117
-
118
- JBRuleset memory ruleset = jbRulesets().currentOf(projectId);
119
- if (ruleset.dataHook() == address(0)) {
120
- (ruleset,) = jbRulesets().latestQueuedOf(projectId);
121
- }
122
- gameHook = DefifaHook(ruleset.dataHook());
123
-
124
- vm.warp(block.timestamp + 1 days);
125
- _mintSingleTier(player, 1 ether);
126
-
127
- vm.warp(block.timestamp + 3 days + 1);
128
- assertEq(uint256(deployer.currentGamePhaseOf(projectId)), uint256(DefifaGamePhase.SCORING));
129
-
130
- DefifaTierCashOutWeight[] memory scorecard = new DefifaTierCashOutWeight[](1);
131
- scorecard[0] = DefifaTierCashOutWeight({id: 1, cashOutWeight: gameHook.TOTAL_CASHOUT_WEIGHT()});
132
- uint256 scorecardId = governor.submitScorecardFor(GAME_ID, scorecard);
133
-
134
- vm.warp(block.timestamp + 1);
135
- vm.prank(player);
136
- vm.expectRevert(DefifaGovernor.DefifaGovernor_NotAllowed.selector);
137
- governor.attestToScorecardFrom(GAME_ID, scorecardId);
138
-
139
- vm.warp(block.timestamp + 365 days);
140
- assertEq(uint256(deployer.currentGamePhaseOf(projectId)), uint256(DefifaGamePhase.SCORING));
141
-
142
- vm.expectRevert(DefifaDeployer.DefifaDeployer_NotNoContest.selector);
143
- deployer.triggerNoContestFor(projectId);
144
-
145
- bytes memory cashOutMetadata = _cashOutMetadata();
146
- vm.prank(player);
147
- vm.expectRevert(DefifaHook.DefifaHook_NothingToClaim.selector);
148
- JBMultiTerminal(payable(address(jbMultiTerminal())))
149
- .cashOutTokensOf({
150
- holder: player,
151
- projectId: projectId,
152
- cashOutCount: 0,
153
- tokenToReclaim: JBConstants.NATIVE_TOKEN,
154
- minTokensReclaimed: 0,
155
- beneficiary: payable(player),
156
- metadata: cashOutMetadata
157
- });
158
- }
159
-
160
- function _launchData() internal returns (DefifaLaunchProjectData memory) {
161
- DefifaTierParams[] memory tiers = new DefifaTierParams[](1);
162
- tiers[0] = DefifaTierParams({
163
- reservedRate: 1001,
164
- reservedTokenBeneficiary: address(0),
165
- encodedIPFSUri: bytes32(0),
166
- shouldUseReservedTokenBeneficiaryAsDefault: false,
167
- name: "ONLY_TEAM"
168
- });
169
-
170
- return DefifaLaunchProjectData({
171
- name: "ONE_TIER_LOCK",
172
- projectUri: "",
173
- contractUri: "",
174
- baseUri: "",
175
- tiers: tiers,
176
- tierPrice: 1 ether,
177
- token: JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: JBCurrencyIds.ETH}),
178
- mintPeriodDuration: 1 days,
179
- refundPeriodDuration: 1 days,
180
- start: uint48(block.timestamp + 3 days),
181
- splits: new JBSplit[](0),
182
- attestationStartTime: 0,
183
- attestationGracePeriod: 100_381,
184
- defaultAttestationDelegate: address(0),
185
- defaultTokenUriResolver: IJB721TokenUriResolver(address(0)),
186
- terminal: jbMultiTerminal(),
187
- store: new JB721TiersHookStore(),
188
- minParticipation: 0,
189
- scorecardTimeout: 0,
190
- timelockDuration: 0
191
- });
192
- }
193
-
194
- function _mintSingleTier(address user, uint256 amount) internal {
195
- vm.deal(user, amount);
196
- uint16[] memory mintIds = new uint16[](1);
197
- mintIds[0] = 1;
198
- bytes[] memory data = new bytes[](1);
199
- data[0] = abi.encode(user, mintIds);
200
- bytes4[] memory ids = new bytes4[](1);
201
- ids[0] = metadataHelper().getId("pay", address(hook));
202
-
203
- vm.prank(user);
204
- jbMultiTerminal().pay{value: amount}(
205
- projectId, JBConstants.NATIVE_TOKEN, amount, user, 0, "", metadataHelper().createMetadata(ids, data)
206
- );
207
- }
208
-
209
- function _cashOutMetadata() internal view returns (bytes memory) {
210
- uint256[] memory tokenIds = new uint256[](1);
211
- tokenIds[0] = 1_000_000_001;
212
- bytes[] memory data = new bytes[](1);
213
- data[0] = abi.encode(tokenIds);
214
- bytes4[] memory ids = new bytes4[](1);
215
- ids[0] = metadataHelper().getId("cashOut", address(hook));
216
- return metadataHelper().createMetadata(ids, data);
217
- }
218
- }
@@ -1,237 +0,0 @@
1
- // SPDX-License-Identifier: UNLICENSED
2
- pragma solidity 0.8.28;
3
-
4
- import {TestBaseWorkflow} from "@bananapus/core-v6/test/helpers/TestBaseWorkflow.sol";
5
- import {JBTest} from "@bananapus/core-v6/test/helpers/JBTest.sol";
6
-
7
- import {DefifaDeployer} from "../../src/DefifaDeployer.sol";
8
- import {DefifaGovernor} from "../../src/DefifaGovernor.sol";
9
- import {DefifaHook} from "../../src/DefifaHook.sol";
10
- import {DefifaTokenUriResolver} from "../../src/DefifaTokenUriResolver.sol";
11
- import {DefifaGamePhase} from "../../src/enums/DefifaGamePhase.sol";
12
- import {DefifaTierCashOutWeight} from "../../src/structs/DefifaTierCashOutWeight.sol";
13
- import {DefifaLaunchProjectData} from "../../src/structs/DefifaLaunchProjectData.sol";
14
- import {DefifaTierParams} from "../../src/structs/DefifaTierParams.sol";
15
- import {DefifaDelegation} from "../../src/structs/DefifaDelegation.sol";
16
- import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
17
- import {IJB721TokenUriResolver} from "@bananapus/721-hook-v6/src/interfaces/IJB721TokenUriResolver.sol";
18
- import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
19
- import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
20
- import {JBCurrencyIds} from "@bananapus/core-v6/src/libraries/JBCurrencyIds.sol";
21
- import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
22
- import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
23
- import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
24
- import {JBRulesetMetadata} from "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
25
- import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
26
- import {JBRulesetMetadataResolver} from "@bananapus/core-v6/src/libraries/JBRulesetMetadataResolver.sol";
27
- import {JBSplitGroup} from "@bananapus/core-v6/src/structs/JBSplitGroup.sol";
28
- import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
29
- import {JBFundAccessLimitGroup} from "@bananapus/core-v6/src/structs/JBFundAccessLimitGroup.sol";
30
- import {IJBRulesetApprovalHook} from "@bananapus/core-v6/src/interfaces/IJBRulesets.sol";
31
- import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
32
- import {ITypeface} from "lib/typeface/contracts/interfaces/ITypeface.sol";
33
-
34
- contract CodexNemesisSingleTierTimeoutLockTest is JBTest, TestBaseWorkflow {
35
- using JBRulesetMetadataResolver for JBRuleset;
36
-
37
- uint256 internal _protocolFeeProjectId;
38
- uint256 internal _defifaProjectId;
39
- uint256 internal _gameId = 3;
40
-
41
- DefifaDeployer internal _deployer;
42
- DefifaHook internal _hookImpl;
43
- DefifaGovernor internal _governorImpl;
44
-
45
- address internal _projectOwner = address(bytes20(keccak256("projectOwner")));
46
- address internal _player = address(bytes20(keccak256("player")));
47
-
48
- function setUp() public virtual override {
49
- super.setUp();
50
-
51
- JBAccountingContext[] memory tokens = new JBAccountingContext[](1);
52
- tokens[0] = JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: JBCurrencyIds.ETH});
53
-
54
- JBTerminalConfig[] memory terminalConfigs = new JBTerminalConfig[](1);
55
- terminalConfigs[0] = JBTerminalConfig({terminal: jbMultiTerminal(), accountingContextsToAccept: tokens});
56
-
57
- JBRulesetConfig[] memory rulesetConfigs = new JBRulesetConfig[](1);
58
- rulesetConfigs[0] = JBRulesetConfig({
59
- mustStartAtOrAfter: 0,
60
- duration: 10 days,
61
- weight: 1e18,
62
- weightCutPercent: 0,
63
- approvalHook: IJBRulesetApprovalHook(address(0)),
64
- metadata: JBRulesetMetadata({
65
- reservedPercent: 0,
66
- cashOutTaxRate: 0,
67
- baseCurrency: JBCurrencyIds.ETH,
68
- pausePay: false,
69
- pauseCreditTransfers: false,
70
- allowOwnerMinting: false,
71
- allowSetCustomToken: false,
72
- allowTerminalMigration: false,
73
- allowSetTerminals: false,
74
- allowSetController: false,
75
- allowAddAccountingContext: false,
76
- allowAddPriceFeed: false,
77
- ownerMustSendPayouts: false,
78
- holdFees: false,
79
- useTotalSurplusForCashOuts: false,
80
- useDataHookForPay: true,
81
- useDataHookForCashOut: true,
82
- dataHook: address(0),
83
- metadata: 0
84
- }),
85
- splitGroups: new JBSplitGroup[](0),
86
- fundAccessLimitGroups: new JBFundAccessLimitGroup[](0)
87
- });
88
-
89
- _protocolFeeProjectId =
90
- jbController().launchProjectFor(address(_projectOwner), "", rulesetConfigs, terminalConfigs, "");
91
- vm.prank(_projectOwner);
92
- address nanaToken =
93
- address(jbController().deployERC20For(_protocolFeeProjectId, "Bananapus", "NANA", bytes32(0)));
94
-
95
- _defifaProjectId =
96
- jbController().launchProjectFor(address(_projectOwner), "", rulesetConfigs, terminalConfigs, "");
97
- vm.prank(_projectOwner);
98
- address defifaToken = address(jbController().deployERC20For(_defifaProjectId, "Defifa", "DEFIFA", bytes32(0)));
99
-
100
- _hookImpl = new DefifaHook(jbDirectory(), IERC20(defifaToken), IERC20(nanaToken));
101
- _governorImpl = new DefifaGovernor(jbController(), address(this));
102
- _deployer = new DefifaDeployer(
103
- address(_hookImpl),
104
- new DefifaTokenUriResolver(ITypeface(address(0))),
105
- _governorImpl,
106
- jbController(),
107
- new JBAddressRegistry(),
108
- _defifaProjectId,
109
- _protocolFeeProjectId
110
- );
111
-
112
- _hookImpl.transferOwnership(address(_deployer));
113
- _governorImpl.transferOwnership(address(_deployer));
114
- }
115
-
116
- function test_singleTierGameWithZeroTimeoutLocksFunds() external {
117
- DefifaLaunchProjectData memory data = _launchData();
118
- uint256 projectId = _deployer.launchGameWith(data);
119
- JBRuleset memory ruleset = jbRulesets().currentOf(projectId);
120
- if (ruleset.dataHook() == address(0)) {
121
- (ruleset,) = jbRulesets().latestQueuedOf(projectId);
122
- }
123
- DefifaHook hook = DefifaHook(ruleset.dataHook());
124
-
125
- vm.warp(data.start - data.mintPeriodDuration - data.refundPeriodDuration);
126
- vm.deal(_player, 1 ether);
127
-
128
- uint16[] memory tierIds = new uint16[](1);
129
- tierIds[0] = 1;
130
- vm.prank(_player);
131
- jbMultiTerminal().pay{value: 1 ether}(
132
- projectId,
133
- JBConstants.NATIVE_TOKEN,
134
- 1 ether,
135
- _player,
136
- 0,
137
- "",
138
- _buildPayMetadata(abi.encode(_player, tierIds))
139
- );
140
-
141
- DefifaDelegation[] memory delegations = new DefifaDelegation[](1);
142
- delegations[0] = DefifaDelegation({delegatee: _player, tierId: 1});
143
- vm.prank(_player);
144
- hook.setTierDelegatesTo(delegations);
145
-
146
- vm.warp(data.start + 1);
147
- assertEq(uint256(_deployer.currentGamePhaseOf(projectId)), uint256(DefifaGamePhase.SCORING));
148
-
149
- DefifaTierCashOutWeight[] memory scorecard = new DefifaTierCashOutWeight[](1);
150
- scorecard[0] = DefifaTierCashOutWeight({id: 1, cashOutWeight: hook.TOTAL_CASHOUT_WEIGHT()});
151
- uint256 scorecardId = _governorImpl.submitScorecardFor(_gameId, scorecard);
152
-
153
- assertEq(_governorImpl.quorum(_gameId), 500_000_000, "single tier quorum remains positive");
154
- assertEq(
155
- _governorImpl.getBWAAttestationWeight(_gameId, scorecardId, _player, uint48(block.timestamp)),
156
- 0,
157
- "sole beneficiary has zero BWA power"
158
- );
159
-
160
- vm.prank(_player);
161
- vm.expectRevert(DefifaGovernor.DefifaGovernor_NotAllowed.selector);
162
- _governorImpl.attestToScorecardFrom(_gameId, scorecardId);
163
-
164
- vm.warp(block.timestamp + 365 days);
165
- assertEq(
166
- uint256(_deployer.currentGamePhaseOf(projectId)),
167
- uint256(DefifaGamePhase.SCORING),
168
- "timeout disabled keeps the game in scoring forever"
169
- );
170
-
171
- vm.expectRevert(DefifaDeployer.DefifaDeployer_NotNoContest.selector);
172
- _deployer.triggerNoContestFor(projectId);
173
-
174
- uint256[] memory tokenIds = new uint256[](1);
175
- tokenIds[0] = _generateTokenId(1, 1);
176
- bytes memory cashOutMetadata = _buildCashOutMetadata(tokenIds);
177
-
178
- vm.prank(_player);
179
- vm.expectRevert(DefifaHook.DefifaHook_NothingToClaim.selector);
180
- jbMultiTerminal()
181
- .cashOutTokensOf(_player, projectId, 0, JBConstants.NATIVE_TOKEN, 0, payable(_player), cashOutMetadata);
182
- }
183
-
184
- function _launchData() internal returns (DefifaLaunchProjectData memory) {
185
- DefifaTierParams[] memory tierParams = new DefifaTierParams[](1);
186
- tierParams[0] = DefifaTierParams({
187
- reservedRate: 1001,
188
- reservedTokenBeneficiary: address(0),
189
- encodedIPFSUri: bytes32(0),
190
- shouldUseReservedTokenBeneficiaryAsDefault: false,
191
- name: "SOLE"
192
- });
193
-
194
- return DefifaLaunchProjectData({
195
- name: "DEFIFA",
196
- projectUri: "",
197
- contractUri: "",
198
- baseUri: "",
199
- tiers: tierParams,
200
- tierPrice: 1 ether,
201
- token: JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: JBCurrencyIds.ETH}),
202
- mintPeriodDuration: 1 days,
203
- refundPeriodDuration: 1 days,
204
- start: uint48(block.timestamp + 3 days),
205
- splits: new JBSplit[](0),
206
- attestationStartTime: 0,
207
- attestationGracePeriod: 100_381,
208
- defaultAttestationDelegate: address(0),
209
- defaultTokenUriResolver: IJB721TokenUriResolver(address(0)),
210
- terminal: jbMultiTerminal(),
211
- store: new JB721TiersHookStore(),
212
- minParticipation: 0,
213
- scorecardTimeout: 0,
214
- timelockDuration: 0
215
- });
216
- }
217
-
218
- function _buildPayMetadata(bytes memory decodedData) internal view returns (bytes memory) {
219
- bytes4[] memory ids = new bytes4[](1);
220
- ids[0] = metadataHelper().getId("pay", address(_hookImpl));
221
- bytes[] memory datas = new bytes[](1);
222
- datas[0] = decodedData;
223
- return metadataHelper().createMetadata(ids, datas);
224
- }
225
-
226
- function _buildCashOutMetadata(uint256[] memory tokenIds) internal view returns (bytes memory) {
227
- bytes4[] memory ids = new bytes4[](1);
228
- ids[0] = metadataHelper().getId("cashOut", address(_hookImpl));
229
- bytes[] memory datas = new bytes[](1);
230
- datas[0] = abi.encode(tokenIds);
231
- return metadataHelper().createMetadata(ids, datas);
232
- }
233
-
234
- function _generateTokenId(uint256 tierId, uint256 tokenNumber) internal pure returns (uint256) {
235
- return (tierId * 1_000_000_000) + tokenNumber;
236
- }
237
- }
@@ -1,191 +0,0 @@
1
- // SPDX-License-Identifier: UNLICENSED
2
- pragma solidity 0.8.28;
3
-
4
- import {DefifaDeployer} from "../../src/DefifaDeployer.sol";
5
- import {DefifaGovernor} from "../../src/DefifaGovernor.sol";
6
- import {DefifaHook} from "../../src/DefifaHook.sol";
7
- import {DefifaTokenUriResolver} from "../../src/DefifaTokenUriResolver.sol";
8
- import {DefifaLaunchProjectData} from "../../src/structs/DefifaLaunchProjectData.sol";
9
- import {DefifaTierParams} from "../../src/structs/DefifaTierParams.sol";
10
-
11
- import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
12
- import {IJB721TokenUriResolver} from "@bananapus/721-hook-v6/src/interfaces/IJB721TokenUriResolver.sol";
13
- import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
14
- import {JBTest} from "@bananapus/core-v6/test/helpers/JBTest.sol";
15
- import {TestBaseWorkflow} from "@bananapus/core-v6/test/helpers/TestBaseWorkflow.sol";
16
- import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
17
- import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
18
- import {JBCurrencyIds} from "@bananapus/core-v6/src/libraries/JBCurrencyIds.sol";
19
- import {JBFundAccessLimitGroup} from "@bananapus/core-v6/src/structs/JBFundAccessLimitGroup.sol";
20
- import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
21
- import {JBRulesetMetadata} from "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
22
- import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
23
- import {JBSplitGroup} from "@bananapus/core-v6/src/structs/JBSplitGroup.sol";
24
- import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
25
- import {IJBRulesetApprovalHook} from "@bananapus/core-v6/src/interfaces/IJBRulesets.sol";
26
-
27
- import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
28
- import {ITypeface} from "lib/typeface/contracts/interfaces/ITypeface.sol";
29
-
30
- contract CodexRegistryMismatchTest is JBTest, TestBaseWorkflow {
31
- JBAddressRegistry internal registry;
32
- DefifaDeployer internal deployer;
33
-
34
- function setUp() public virtual override {
35
- super.setUp();
36
-
37
- JBAccountingContext[] memory tokens = new JBAccountingContext[](1);
38
- tokens[0] = JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: JBCurrencyIds.ETH});
39
-
40
- JBTerminalConfig[] memory terminalConfigs = new JBTerminalConfig[](1);
41
- terminalConfigs[0] = JBTerminalConfig({terminal: jbMultiTerminal(), accountingContextsToAccept: tokens});
42
-
43
- JBRulesetConfig[] memory rulesetConfigs = new JBRulesetConfig[](1);
44
- rulesetConfigs[0] = JBRulesetConfig({
45
- mustStartAtOrAfter: 0,
46
- duration: 10 days,
47
- weight: 1e18,
48
- weightCutPercent: 0,
49
- approvalHook: IJBRulesetApprovalHook(address(0)),
50
- metadata: JBRulesetMetadata({
51
- reservedPercent: 0,
52
- cashOutTaxRate: 0,
53
- baseCurrency: JBCurrencyIds.ETH,
54
- pausePay: false,
55
- pauseCreditTransfers: false,
56
- allowOwnerMinting: false,
57
- allowSetCustomToken: false,
58
- allowTerminalMigration: false,
59
- allowSetTerminals: false,
60
- allowSetController: false,
61
- allowAddAccountingContext: false,
62
- allowAddPriceFeed: false,
63
- ownerMustSendPayouts: false,
64
- holdFees: false,
65
- useTotalSurplusForCashOuts: false,
66
- useDataHookForPay: true,
67
- useDataHookForCashOut: true,
68
- dataHook: address(0),
69
- metadata: 0
70
- }),
71
- splitGroups: new JBSplitGroup[](0),
72
- fundAccessLimitGroups: new JBFundAccessLimitGroup[](0)
73
- });
74
-
75
- address projectOwner = address(bytes20(keccak256("projectOwner")));
76
- uint256 protocolFeeProjectId =
77
- jbController().launchProjectFor(projectOwner, "", rulesetConfigs, terminalConfigs, "");
78
- vm.prank(projectOwner);
79
- address nanaToken =
80
- address(jbController().deployERC20For(protocolFeeProjectId, "Bananapus", "NANA", bytes32(0)));
81
-
82
- uint256 defifaProjectId = jbController().launchProjectFor(projectOwner, "", rulesetConfigs, terminalConfigs, "");
83
- vm.prank(projectOwner);
84
- address defifaToken = address(jbController().deployERC20For(defifaProjectId, "Defifa", "DEFIFA", bytes32(0)));
85
-
86
- DefifaHook hookCodeOrigin = new DefifaHook(jbDirectory(), IERC20(defifaToken), IERC20(nanaToken));
87
- DefifaGovernor governor = new DefifaGovernor(jbController(), address(this));
88
- registry = new JBAddressRegistry();
89
- deployer = new DefifaDeployer(
90
- address(hookCodeOrigin),
91
- new DefifaTokenUriResolver(ITypeface(address(0))),
92
- governor,
93
- jbController(),
94
- registry,
95
- defifaProjectId,
96
- protocolFeeProjectId
97
- );
98
-
99
- hookCodeOrigin.transferOwnership(address(deployer));
100
- governor.transferOwnership(address(deployer));
101
- }
102
-
103
- function test_launchRegistersActualHookAddressInRegistry() external {
104
- uint256 projectId = deployer.launchGameWith(_launchData());
105
- (, JBRulesetMetadata memory metadata,) = jbController().latestQueuedRulesetOf(projectId);
106
- address actualHook = metadata.dataHook;
107
-
108
- address expectedCreateAddress = _createAddress(address(deployer), 1);
109
-
110
- assertNotEq(actualHook, address(0), "queued ruleset should reference the deployed hook");
111
- assertNotEq(actualHook, expectedCreateAddress, "cloneDeterministic did not use CREATE");
112
- assertEq(registry.deployerOf(actualHook), address(deployer), "actual hook should be registered");
113
- assertEq(
114
- registry.deployerOf(expectedCreateAddress), address(0), "legacy CREATE address should stay unregistered"
115
- );
116
- }
117
-
118
- function _launchData() internal returns (DefifaLaunchProjectData memory) {
119
- DefifaTierParams[] memory tiers = new DefifaTierParams[](1);
120
- tiers[0] = DefifaTierParams({
121
- name: "Team 1",
122
- reservedRate: 0,
123
- reservedTokenBeneficiary: address(0),
124
- encodedIPFSUri: bytes32(0),
125
- shouldUseReservedTokenBeneficiaryAsDefault: false
126
- });
127
-
128
- return DefifaLaunchProjectData({
129
- name: "DEFIFA",
130
- projectUri: "",
131
- contractUri: "",
132
- baseUri: "",
133
- tiers: tiers,
134
- tierPrice: 1 ether,
135
- token: JBAccountingContext({token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: JBCurrencyIds.ETH}),
136
- mintPeriodDuration: 1 days,
137
- refundPeriodDuration: 1 days,
138
- start: uint48(block.timestamp + 3 days),
139
- splits: new JBSplit[](0),
140
- attestationStartTime: 0,
141
- attestationGracePeriod: 100_381,
142
- defaultAttestationDelegate: address(0),
143
- defaultTokenUriResolver: IJB721TokenUriResolver(address(0)),
144
- terminal: jbMultiTerminal(),
145
- store: new JB721TiersHookStore(),
146
- minParticipation: 0,
147
- scorecardTimeout: 0,
148
- timelockDuration: 0
149
- });
150
- }
151
-
152
- function _createAddress(address origin, uint256 nonce) internal pure returns (address addr) {
153
- bytes memory data;
154
- if (nonce == 0x00) {
155
- data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), origin, bytes1(0x80));
156
- } else if (nonce <= 0x7f) {
157
- // forge-lint: disable-next-line(unsafe-typecast)
158
- data = abi.encodePacked(bytes1(0xd6), bytes1(0x94), origin, uint8(nonce));
159
- } else if (nonce <= 0xff) {
160
- // forge-lint: disable-next-line(unsafe-typecast)
161
- data = abi.encodePacked(bytes1(0xd7), bytes1(0x94), origin, bytes1(0x81), uint8(nonce));
162
- } else if (nonce <= 0xffff) {
163
- // forge-lint: disable-next-line(unsafe-typecast)
164
- data = abi.encodePacked(bytes1(0xd8), bytes1(0x94), origin, bytes1(0x82), uint16(nonce));
165
- } else if (nonce <= 0xffffff) {
166
- // forge-lint: disable-next-line(unsafe-typecast)
167
- data = abi.encodePacked(bytes1(0xd9), bytes1(0x94), origin, bytes1(0x83), uint24(nonce));
168
- } else if (nonce <= 0xffffffff) {
169
- // forge-lint: disable-next-line(unsafe-typecast)
170
- data = abi.encodePacked(bytes1(0xda), bytes1(0x94), origin, bytes1(0x84), uint32(nonce));
171
- } else if (nonce <= 0xffffffffff) {
172
- // forge-lint: disable-next-line(unsafe-typecast)
173
- data = abi.encodePacked(bytes1(0xdb), bytes1(0x94), origin, bytes1(0x85), uint40(nonce));
174
- } else if (nonce <= 0xffffffffffff) {
175
- // forge-lint: disable-next-line(unsafe-typecast)
176
- data = abi.encodePacked(bytes1(0xdc), bytes1(0x94), origin, bytes1(0x86), uint48(nonce));
177
- } else if (nonce <= 0xffffffffffffff) {
178
- // forge-lint: disable-next-line(unsafe-typecast)
179
- data = abi.encodePacked(bytes1(0xdd), bytes1(0x94), origin, bytes1(0x87), uint56(nonce));
180
- } else {
181
- // forge-lint: disable-next-line(unsafe-typecast)
182
- data = abi.encodePacked(bytes1(0xde), bytes1(0x94), origin, bytes1(0x88), uint64(nonce));
183
- }
184
-
185
- bytes32 hash = keccak256(data);
186
- assembly {
187
- mstore(0, hash)
188
- addr := mload(0)
189
- }
190
- }
191
- }