@bananapus/core-v6 0.0.26 → 0.0.28
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 +1 -1
- package/AUDIT_INSTRUCTIONS.md +3 -3
- package/CHANGE_LOG.md +17 -2
- package/README.md +1 -1
- package/RISKS.md +3 -3
- package/SKILLS.md +1 -1
- package/STYLE_GUIDE.md +2 -2
- package/USER_JOURNEYS.md +6 -3
- package/foundry.toml +1 -1
- package/package.json +5 -5
- package/script/Deploy.s.sol +1 -1
- package/script/DeployPeriphery.s.sol +1 -1
- package/script/helpers/CoreDeploymentLib.sol +1 -1
- package/src/JBChainlinkV3PriceFeed.sol +1 -1
- package/src/JBChainlinkV3SequencerPriceFeed.sol +1 -1
- package/src/JBController.sol +1 -1
- package/src/JBDeadline.sol +1 -1
- package/src/JBDirectory.sol +1 -1
- package/src/JBERC20.sol +1 -1
- package/src/JBFeelessAddresses.sol +1 -1
- package/src/JBFundAccessLimits.sol +1 -1
- package/src/JBMultiTerminal.sol +41 -13
- package/src/JBPermissions.sol +1 -1
- package/src/JBPrices.sol +1 -1
- package/src/JBProjects.sol +1 -1
- package/src/JBRulesets.sol +1 -1
- package/src/JBSplits.sol +1 -1
- package/src/JBTerminalStore.sol +1 -1
- package/src/JBTokens.sol +1 -1
- package/src/libraries/JBPayoutSplitGroupLib.sol +1 -1
- package/src/periphery/JBDeadline1Day.sol +1 -1
- package/src/periphery/JBDeadline3Days.sol +1 -1
- package/src/periphery/JBDeadline3Hours.sol +1 -1
- package/src/periphery/JBDeadline7Days.sol +1 -1
- package/src/periphery/JBMatchingPriceFeed.sol +1 -1
- package/test/TestFees.sol +6 -4
- package/test/TestJBERC20Inheritance.sol +1 -1
- package/test/TestMetadataOffsetOverflow.sol +1 -1
- package/test/TestMetadataParserLib.sol +1 -1
- package/test/TestTerminalMigration.sol +104 -2
- package/test/TestTerminalPreviewParity.sol +1 -1
- package/test/audit/FeeFreeSurplusLifecycle.t.sol +11 -4
- package/test/audit/FeeFreeSurplusStale.t.sol +11 -5
- package/test/audit/USDTVoidReturnCompat.t.sol +6 -0
- package/test/fork/TestChainlinkPriceFeedFork.sol +1 -1
- package/test/fork/TestSequencerPriceFeedFork.sol +1 -1
- package/test/fork/TestTerminalPreviewParityFork.sol +1 -1
- package/test/helpers/JBTest.sol +1 -1
- package/test/helpers/MetadataResolverHelper.sol +1 -1
- package/test/mock/MockERC20.sol +1 -1
- package/test/mock/MockMaliciousBeneficiary.sol +1 -1
- package/test/mock/MockMaliciousSplitHook.sol +1 -1
- package/test/mock/MockPriceFeed.sol +1 -1
- package/test/mock/MockUSDT.sol +1 -1
- package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +1 -1
- package/test/units/static/JBController/JBControllerSetup.sol +1 -1
- package/test/units/static/JBController/TestBurnTokensOf.sol +1 -1
- package/test/units/static/JBController/TestClaimTokensFor.sol +1 -1
- package/test/units/static/JBController/TestDeployErc20For.sol +1 -1
- package/test/units/static/JBController/TestLaunchProjectFor.sol +1 -1
- package/test/units/static/JBController/TestLaunchRulesetsFor.sol +1 -1
- package/test/units/static/JBController/TestMigrateController.sol +1 -1
- package/test/units/static/JBController/TestMintTokensOfUnits.sol +1 -1
- package/test/units/static/JBController/TestOmnichainRulesetOperator.sol +1 -1
- package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +1 -1
- package/test/units/static/JBController/TestPreviewMintOf.sol +1 -1
- package/test/units/static/JBController/TestReceiveMigrationFrom.sol +1 -1
- package/test/units/static/JBController/TestRulesetViews.sol +1 -1
- package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +1 -1
- package/test/units/static/JBController/TestSetSplitGroupsOf.sol +1 -1
- package/test/units/static/JBController/TestSetTokenFor.sol +1 -1
- package/test/units/static/JBController/TestSetUriOf.sol +1 -1
- package/test/units/static/JBController/TestTransferCreditsFrom.sol +1 -1
- package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +1 -1
- package/test/units/static/JBDirectory/JBDirectorySetup.sol +1 -1
- package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +1 -1
- package/test/units/static/JBDirectory/TestSetControllerOf.sol +1 -1
- package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +1 -1
- package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +1 -1
- package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +1 -1
- package/test/units/static/JBERC20/JBERC20Setup.sol +1 -1
- package/test/units/static/JBERC20/SigUtils.sol +1 -1
- package/test/units/static/JBERC20/TestInitialize.sol +1 -1
- package/test/units/static/JBERC20/TestName.sol +1 -1
- package/test/units/static/JBERC20/TestNonces.sol +1 -1
- package/test/units/static/JBERC20/TestSymbol.sol +1 -1
- package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +1 -1
- package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +1 -1
- package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +1 -1
- package/test/units/static/JBFees/TestFeesFuzz.sol +1 -1
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +1 -1
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +1 -1
- package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +1 -1
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +1 -1
- package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +1 -1
- package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +1 -1
- package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +1 -1
- package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +3 -42
- package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +16 -1
- package/test/units/static/JBMultiTerminal/TestPay.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestPreviewCashOutFrom.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestPreviewPayFor.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestSelfPayRevert.sol +55 -0
- package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +1 -1
- package/test/units/static/JBPermissions/JBPermissionsSetup.sol +1 -1
- package/test/units/static/JBPermissions/TestHasPermission.sol +1 -1
- package/test/units/static/JBPermissions/TestHasPermissions.sol +1 -1
- package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +1 -1
- package/test/units/static/JBPrices/JBPricesSetup.sol +1 -1
- package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +1 -1
- package/test/units/static/JBPrices/TestPricePerUnitOf.sol +1 -1
- package/test/units/static/JBPrices/TestPrices.sol +1 -1
- package/test/units/static/JBProjects/JBProjectsSetup.sol +1 -1
- package/test/units/static/JBProjects/TestCreateFor.sol +1 -1
- package/test/units/static/JBProjects/TestInitialProject.sol +1 -1
- package/test/units/static/JBProjects/TestInterfaces.sol +1 -1
- package/test/units/static/JBProjects/TestSetResolver.sol +1 -1
- package/test/units/static/JBProjects/TestTokenUri.sol +1 -1
- package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +1 -1
- package/test/units/static/JBRulesets/JBRulesetsSetup.sol +1 -1
- package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestCurrentOf.sol +1 -1
- package/test/units/static/JBRulesets/TestGetRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestRulesets.sol +1 -1
- package/test/units/static/JBRulesets/TestRulesetsOf.sol +1 -1
- package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +1 -1
- package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +1 -1
- package/test/units/static/JBSplits/JBSplitsSetup.sol +1 -1
- package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +1 -1
- package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +1 -1
- package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +1 -1
- package/test/units/static/JBSplits/TestSplitsOf.sol +1 -1
- package/test/units/static/JBSplits/TestSplitsPacking.sol +1 -1
- package/test/units/static/JBSurplus/TestSurplusFuzz.sol +1 -1
- package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +1 -1
- package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestPreviewCashOutFrom.sol +1 -1
- package/test/units/static/JBTerminalStore/TestPreviewPayFrom.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +1 -1
- package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +1 -1
- package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +1 -1
- package/test/units/static/JBTokens/JBTokensSetup.sol +1 -1
- package/test/units/static/JBTokens/TestBurnFrom.sol +1 -1
- package/test/units/static/JBTokens/TestClaimTokensFor.sol +1 -1
- package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +1 -1
- package/test/units/static/JBTokens/TestMintFor.sol +1 -1
- package/test/units/static/JBTokens/TestSetTokenFor.sol +1 -1
- package/test/units/static/JBTokens/TestTotalBalanceOf.sol +1 -1
- package/test/units/static/JBTokens/TestTotalSupplyOf.sol +1 -1
- package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +1 -1
|
@@ -6,6 +6,7 @@ import {JBMultiTerminal} from "../src/JBMultiTerminal.sol";
|
|
|
6
6
|
import {IJBController} from "../src/interfaces/IJBController.sol";
|
|
7
7
|
import {IJBRulesetApprovalHook} from "../src/interfaces/IJBRulesetApprovalHook.sol";
|
|
8
8
|
import {JBConstants} from "../src/libraries/JBConstants.sol";
|
|
9
|
+
import {JBFees} from "../src/libraries/JBFees.sol";
|
|
9
10
|
import {JBAccountingContext} from "../src/structs/JBAccountingContext.sol";
|
|
10
11
|
import {JBFundAccessLimitGroup} from "../src/structs/JBFundAccessLimitGroup.sol";
|
|
11
12
|
import {JBRulesetConfig} from "../src/structs/JBRulesetConfig.sol";
|
|
@@ -105,7 +106,7 @@ contract TestTerminalMigration_Local is TestBaseWorkflow {
|
|
|
105
106
|
uint256 migratedBalance = _terminalA.migrateBalanceOf(_projectId, JBConstants.NATIVE_TOKEN, _terminalB);
|
|
106
107
|
assertEq(migratedBalance, payAmount, "full balance should be migrated");
|
|
107
108
|
|
|
108
|
-
// Step 4: Verify balances after migration
|
|
109
|
+
// Step 4: Verify balances after migration (fee project is exempt from migration fee)
|
|
109
110
|
uint256 balanceAAfter = jbTerminalStore().balanceOf(address(_terminalA), _projectId, JBConstants.NATIVE_TOKEN);
|
|
110
111
|
assertEq(balanceAAfter, 0, "terminal A should have zero after migration");
|
|
111
112
|
|
|
@@ -152,7 +153,7 @@ contract TestTerminalMigration_Local is TestBaseWorkflow {
|
|
|
152
153
|
vm.prank(_projectOwner);
|
|
153
154
|
_terminalA.migrateBalanceOf(_projectId, JBConstants.NATIVE_TOKEN, _terminalB);
|
|
154
155
|
|
|
155
|
-
// Check surplus from terminal B
|
|
156
|
+
// Check surplus from terminal B (fee project exempt from migration fee)
|
|
156
157
|
uint256 surplusAfter =
|
|
157
158
|
_terminalB.currentSurplusOf(_projectId, new address[](0), 18, uint32(uint160(JBConstants.NATIVE_TOKEN)));
|
|
158
159
|
assertEq(surplusAfter, surplusBefore, "surplus should be preserved after migration");
|
|
@@ -169,4 +170,105 @@ contract TestTerminalMigration_Local is TestBaseWorkflow {
|
|
|
169
170
|
vm.expectRevert();
|
|
170
171
|
_terminalA.migrateBalanceOf(_projectId, JBConstants.NATIVE_TOKEN, _terminalB);
|
|
171
172
|
}
|
|
173
|
+
|
|
174
|
+
/// @notice Non-fee project migration charges the 2.5% fee; fee project balance increases.
|
|
175
|
+
function test_migration_nonFeeProject_chargesFee() public {
|
|
176
|
+
// Launch a second project (project 2) — this is NOT the fee project.
|
|
177
|
+
JBRulesetMetadata memory _metadata2 = JBRulesetMetadata({
|
|
178
|
+
reservedPercent: 0,
|
|
179
|
+
cashOutTaxRate: 0,
|
|
180
|
+
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
181
|
+
pausePay: false,
|
|
182
|
+
pauseCreditTransfers: false,
|
|
183
|
+
allowOwnerMinting: false,
|
|
184
|
+
allowSetCustomToken: false,
|
|
185
|
+
allowTerminalMigration: true,
|
|
186
|
+
allowSetTerminals: true,
|
|
187
|
+
allowSetController: false,
|
|
188
|
+
allowAddAccountingContext: false,
|
|
189
|
+
allowAddPriceFeed: false,
|
|
190
|
+
ownerMustSendPayouts: false,
|
|
191
|
+
holdFees: false,
|
|
192
|
+
useTotalSurplusForCashOuts: false,
|
|
193
|
+
useDataHookForPay: false,
|
|
194
|
+
useDataHookForCashOut: false,
|
|
195
|
+
dataHook: address(0),
|
|
196
|
+
metadata: 0
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
JBRulesetConfig[] memory _rulesetConfig2 = new JBRulesetConfig[](1);
|
|
200
|
+
_rulesetConfig2[0].mustStartAtOrAfter = 0;
|
|
201
|
+
_rulesetConfig2[0].duration = 0;
|
|
202
|
+
_rulesetConfig2[0].weight = 1000 * 10 ** 18;
|
|
203
|
+
_rulesetConfig2[0].weightCutPercent = 0;
|
|
204
|
+
_rulesetConfig2[0].approvalHook = IJBRulesetApprovalHook(address(0));
|
|
205
|
+
_rulesetConfig2[0].metadata = _metadata2;
|
|
206
|
+
_rulesetConfig2[0].splitGroups = new JBSplitGroup[](0);
|
|
207
|
+
_rulesetConfig2[0].fundAccessLimitGroups = new JBFundAccessLimitGroup[](0);
|
|
208
|
+
|
|
209
|
+
JBAccountingContext[] memory _tokensToAccept = new JBAccountingContext[](1);
|
|
210
|
+
_tokensToAccept[0] = JBAccountingContext({
|
|
211
|
+
token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
JBTerminalConfig[] memory _terminalConfigs2 = new JBTerminalConfig[](2);
|
|
215
|
+
_terminalConfigs2[0] = JBTerminalConfig({terminal: _terminalA, accountingContextsToAccept: _tokensToAccept});
|
|
216
|
+
_terminalConfigs2[1] = JBTerminalConfig({terminal: _terminalB, accountingContextsToAccept: _tokensToAccept});
|
|
217
|
+
|
|
218
|
+
uint256 project2 = _controller.launchProjectFor({
|
|
219
|
+
owner: _projectOwner,
|
|
220
|
+
projectUri: "non-fee-project",
|
|
221
|
+
rulesetConfigurations: _rulesetConfig2,
|
|
222
|
+
terminalConfigurations: _terminalConfigs2,
|
|
223
|
+
memo: ""
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Confirm project 2 is NOT the fee project.
|
|
227
|
+
assertGt(project2, 1, "project2 should not be the fee project");
|
|
228
|
+
|
|
229
|
+
uint256 payAmount = 10 ether;
|
|
230
|
+
|
|
231
|
+
// Pay into terminal A for project 2.
|
|
232
|
+
vm.deal(_beneficiary, payAmount);
|
|
233
|
+
vm.prank(_beneficiary);
|
|
234
|
+
_terminalA.pay{value: payAmount}(project2, JBConstants.NATIVE_TOKEN, payAmount, _beneficiary, 0, "", "");
|
|
235
|
+
|
|
236
|
+
// Snapshot fee project balance before migration.
|
|
237
|
+
uint256 feeBalanceBefore = jbTerminalStore().balanceOf(address(_terminalA), 1, JBConstants.NATIVE_TOKEN);
|
|
238
|
+
|
|
239
|
+
// Migrate project 2 from terminal A to terminal B.
|
|
240
|
+
vm.prank(_projectOwner);
|
|
241
|
+
_terminalA.migrateBalanceOf(project2, JBConstants.NATIVE_TOKEN, _terminalB);
|
|
242
|
+
|
|
243
|
+
// Fee project balance should have increased (fee was charged).
|
|
244
|
+
uint256 feeBalanceAfter = jbTerminalStore().balanceOf(address(_terminalA), 1, JBConstants.NATIVE_TOKEN);
|
|
245
|
+
assertGt(feeBalanceAfter, feeBalanceBefore, "fee project should receive migration fee");
|
|
246
|
+
|
|
247
|
+
// Terminal B should have received payAmount minus the 2.5% fee.
|
|
248
|
+
uint256 expectedFee = JBFees.feeAmountFrom({amountBeforeFee: payAmount, feePercent: 25});
|
|
249
|
+
uint256 balanceBAfter = jbTerminalStore().balanceOf(address(_terminalB), project2, JBConstants.NATIVE_TOKEN);
|
|
250
|
+
assertEq(balanceBAfter, payAmount - expectedFee, "terminal B balance should reflect fee deduction");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/// @notice Fee project (project 1) migration is exempt from fees.
|
|
254
|
+
function test_migration_feeProject_noFeeCharged() public {
|
|
255
|
+
// _projectId is project 1, which IS the fee project.
|
|
256
|
+
assertEq(_projectId, 1, "project under test should be the fee project");
|
|
257
|
+
|
|
258
|
+
uint256 payAmount = 10 ether;
|
|
259
|
+
|
|
260
|
+
// Pay into terminal A for the fee project.
|
|
261
|
+
vm.deal(_beneficiary, payAmount);
|
|
262
|
+
vm.prank(_beneficiary);
|
|
263
|
+
_terminalA.pay{value: payAmount}(_projectId, JBConstants.NATIVE_TOKEN, payAmount, _beneficiary, 0, "", "");
|
|
264
|
+
|
|
265
|
+
// Migrate fee project from terminal A to terminal B.
|
|
266
|
+
vm.prank(_projectOwner);
|
|
267
|
+
uint256 migratedBalance = _terminalA.migrateBalanceOf(_projectId, JBConstants.NATIVE_TOKEN, _terminalB);
|
|
268
|
+
assertEq(migratedBalance, payAmount, "full balance should be migrated without fee");
|
|
269
|
+
|
|
270
|
+
// Terminal B should have the full amount (no fee deducted).
|
|
271
|
+
uint256 balanceBAfter = jbTerminalStore().balanceOf(address(_terminalB), _projectId, JBConstants.NATIVE_TOKEN);
|
|
272
|
+
assertEq(balanceBAfter, payAmount, "fee project should not be charged migration fee");
|
|
273
|
+
}
|
|
172
274
|
}
|
|
@@ -114,6 +114,7 @@ contract FeeFreeSurplusLifecycleTest is TestBaseWorkflow {
|
|
|
114
114
|
splits[0] = JBSplit({
|
|
115
115
|
preferAddToBalance: true,
|
|
116
116
|
percent: JBConstants.SPLITS_TOTAL_PERCENT,
|
|
117
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
117
118
|
projectId: uint64(_recipientProjectId),
|
|
118
119
|
beneficiary: payable(address(0)),
|
|
119
120
|
lockedUntil: 0,
|
|
@@ -126,8 +127,11 @@ contract FeeFreeSurplusLifecycleTest is TestBaseWorkflow {
|
|
|
126
127
|
|
|
127
128
|
// Payout limit: allow paying out the full PAY_AMOUNT each cycle.
|
|
128
129
|
JBCurrencyAmount[] memory payoutLimits = new JBCurrencyAmount[](1);
|
|
129
|
-
payoutLimits[0] =
|
|
130
|
-
|
|
130
|
+
payoutLimits[0] = JBCurrencyAmount({
|
|
131
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
132
|
+
amount: uint224(PAY_AMOUNT),
|
|
133
|
+
currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
134
|
+
});
|
|
131
135
|
|
|
132
136
|
// Fund access limits with the payout limit defined above.
|
|
133
137
|
JBFundAccessLimitGroup[] memory payerLimits = new JBFundAccessLimitGroup[](1);
|
|
@@ -314,10 +318,13 @@ contract FeeFreeSurplusLifecycleTest is TestBaseWorkflow {
|
|
|
314
318
|
jbTerminalStore().balanceOf(address(_terminal), _recipientProjectId, JBConstants.NATIVE_TOKEN);
|
|
315
319
|
assertEq(balanceAfterOnOldTerminal, 0, "Old terminal balance should be zero after migration");
|
|
316
320
|
|
|
317
|
-
// Verify the new terminal received the balance.
|
|
321
|
+
// Verify the new terminal received the balance minus the 2.5% migration fee.
|
|
318
322
|
uint256 balanceOnNewTerminal =
|
|
319
323
|
jbTerminalStore().balanceOf(address(_terminal2), _recipientProjectId, JBConstants.NATIVE_TOKEN);
|
|
320
|
-
|
|
324
|
+
uint256 migrationFee = balanceBefore * 25 / 1000;
|
|
325
|
+
assertEq(
|
|
326
|
+
balanceOnNewTerminal, balanceBefore - migrationFee, "New terminal should have balance minus migration fee"
|
|
327
|
+
);
|
|
321
328
|
}
|
|
322
329
|
|
|
323
330
|
// --- Helpers ---
|
|
@@ -16,7 +16,6 @@ import {JBRulesetMetadata} from "../../src/structs/JBRulesetMetadata.sol";
|
|
|
16
16
|
import {JBSplit} from "../../src/structs/JBSplit.sol";
|
|
17
17
|
import {JBSplitGroup} from "../../src/structs/JBSplitGroup.sol";
|
|
18
18
|
import {JBTerminalConfig} from "../../src/structs/JBTerminalConfig.sol";
|
|
19
|
-
import {mulDiv} from "@prb/math/src/Common.sol";
|
|
20
19
|
|
|
21
20
|
contract FeeFreeSurplusStaleTest is TestBaseWorkflow {
|
|
22
21
|
IJBController private _controller;
|
|
@@ -63,8 +62,11 @@ contract FeeFreeSurplusStaleTest is TestBaseWorkflow {
|
|
|
63
62
|
});
|
|
64
63
|
|
|
65
64
|
JBCurrencyAmount[] memory surplusAllowances = new JBCurrencyAmount[](1);
|
|
66
|
-
surplusAllowances[0] =
|
|
67
|
-
|
|
65
|
+
surplusAllowances[0] = JBCurrencyAmount({
|
|
66
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
67
|
+
amount: uint224(PAY_AMOUNT),
|
|
68
|
+
currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
69
|
+
});
|
|
68
70
|
|
|
69
71
|
JBFundAccessLimitGroup[] memory fundAccessLimitGroups = new JBFundAccessLimitGroup[](1);
|
|
70
72
|
fundAccessLimitGroups[0] = JBFundAccessLimitGroup({
|
|
@@ -91,6 +93,7 @@ contract FeeFreeSurplusStaleTest is TestBaseWorkflow {
|
|
|
91
93
|
splits[0] = JBSplit({
|
|
92
94
|
preferAddToBalance: true,
|
|
93
95
|
percent: JBConstants.SPLITS_TOTAL_PERCENT,
|
|
96
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
94
97
|
projectId: uint64(_projectIdB),
|
|
95
98
|
beneficiary: payable(address(0)),
|
|
96
99
|
lockedUntil: 0,
|
|
@@ -101,8 +104,11 @@ contract FeeFreeSurplusStaleTest is TestBaseWorkflow {
|
|
|
101
104
|
splitGroups[0] = JBSplitGroup({groupId: uint32(uint160(JBConstants.NATIVE_TOKEN)), splits: splits});
|
|
102
105
|
|
|
103
106
|
JBCurrencyAmount[] memory payoutLimits = new JBCurrencyAmount[](1);
|
|
104
|
-
payoutLimits[0] =
|
|
105
|
-
|
|
107
|
+
payoutLimits[0] = JBCurrencyAmount({
|
|
108
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
109
|
+
amount: uint224(PAY_AMOUNT),
|
|
110
|
+
currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
111
|
+
});
|
|
106
112
|
|
|
107
113
|
JBFundAccessLimitGroup[] memory projectALimits = new JBFundAccessLimitGroup[](1);
|
|
108
114
|
projectALimits[0] = JBFundAccessLimitGroup({
|
|
@@ -150,6 +150,7 @@ contract USDTVoidReturnCompat is TestBaseWorkflow {
|
|
|
150
150
|
|
|
151
151
|
// Grant Permit2 allowance for the terminal to pull tokens.
|
|
152
152
|
vm.prank(payer);
|
|
153
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
153
154
|
permit2().approve(address(usdt), address(jbMultiTerminal()), uint160(payAmount), type(uint48).max);
|
|
154
155
|
|
|
155
156
|
// Execute the payment — this is the critical call that must handle void returns.
|
|
@@ -196,6 +197,7 @@ contract USDTVoidReturnCompat is TestBaseWorkflow {
|
|
|
196
197
|
|
|
197
198
|
// Grant Permit2 allowance for the terminal.
|
|
198
199
|
vm.prank(payer);
|
|
200
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
199
201
|
permit2().approve(address(usdt), address(jbMultiTerminal()), uint160(payAmount), type(uint48).max);
|
|
200
202
|
|
|
201
203
|
// Pay into the project to fund it.
|
|
@@ -254,6 +256,7 @@ contract USDTVoidReturnCompat is TestBaseWorkflow {
|
|
|
254
256
|
|
|
255
257
|
// Grant Permit2 allowance for the terminal.
|
|
256
258
|
vm.prank(payer);
|
|
259
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
257
260
|
permit2().approve(address(usdt), address(jbMultiTerminal()), uint160(payAmount), type(uint48).max);
|
|
258
261
|
|
|
259
262
|
// Pay into the project to receive project tokens.
|
|
@@ -316,6 +319,7 @@ contract USDTVoidReturnCompat is TestBaseWorkflow {
|
|
|
316
319
|
|
|
317
320
|
// Grant Permit2 allowance for the terminal.
|
|
318
321
|
vm.prank(payer);
|
|
322
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
319
323
|
permit2().approve(address(usdt), address(jbMultiTerminal()), uint160(payAmount), type(uint48).max);
|
|
320
324
|
|
|
321
325
|
// Step 1: Pay into the project.
|
|
@@ -367,6 +371,7 @@ contract USDTVoidReturnCompat is TestBaseWorkflow {
|
|
|
367
371
|
// =========================================================================
|
|
368
372
|
|
|
369
373
|
/// @notice Launches a project that accepts MockUSDT with no splits and no payout limits.
|
|
374
|
+
// forge-lint: disable-next-line(mixed-case-function)
|
|
370
375
|
function _launchUSDTProject() internal returns (uint256) {
|
|
371
376
|
// Create a single-element array for the ruleset configuration.
|
|
372
377
|
JBRulesetConfig[] memory rulesetConfig = new JBRulesetConfig[](1);
|
|
@@ -428,6 +433,7 @@ contract USDTVoidReturnCompat is TestBaseWorkflow {
|
|
|
428
433
|
}
|
|
429
434
|
|
|
430
435
|
/// @notice Launches a project that accepts MockUSDT with a 100% split to splitBeneficiary.
|
|
436
|
+
// forge-lint: disable-next-line(mixed-case-function)
|
|
431
437
|
function _launchUSDTProjectWithSplit() internal returns (uint256) {
|
|
432
438
|
// Create a single-element array for the ruleset configuration.
|
|
433
439
|
JBRulesetConfig[] memory rulesetConfig = new JBRulesetConfig[](1);
|
package/test/helpers/JBTest.sol
CHANGED
package/test/mock/MockERC20.sol
CHANGED
package/test/mock/MockUSDT.sol
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity
|
|
2
|
+
pragma solidity 0.8.28;
|
|
3
3
|
|
|
4
4
|
/// @notice Mimics Tether (USDT) whose transfer/transferFrom/approve return void instead of bool.
|
|
5
5
|
/// @dev Uses inline assembly to return empty data (no bool), matching USDT's on-chain behavior.
|