@bananapus/core-v6 0.0.30 → 0.0.32
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 +43 -13
- package/ARCHITECTURE.md +62 -137
- package/AUDIT_INSTRUCTIONS.md +149 -428
- package/CHANGELOG.md +73 -0
- package/README.md +90 -201
- package/RISKS.md +27 -12
- package/SKILLS.md +31 -441
- package/STYLE_GUIDE.md +52 -19
- package/USER_JOURNEYS.md +76 -627
- package/package.json +1 -2
- package/references/entrypoints.md +160 -0
- package/references/types-errors-events.md +297 -0
- package/script/Deploy.s.sol +7 -2
- package/script/DeployPeriphery.s.sol +51 -4
- package/src/JBController.sol +45 -17
- package/src/JBDirectory.sol +26 -13
- package/src/JBFundAccessLimits.sol +28 -7
- package/src/JBMultiTerminal.sol +180 -86
- package/src/JBPermissions.sol +17 -17
- package/src/JBRulesets.sol +82 -23
- package/src/JBSplits.sol +31 -12
- package/src/JBTerminalStore.sol +137 -53
- package/src/JBTokens.sol +5 -2
- package/src/abstract/JBControlled.sol +10 -3
- package/src/abstract/JBPermissioned.sol +1 -1
- package/src/interfaces/IJBRulesetDataHook.sol +5 -4
- package/src/libraries/JBCashOuts.sol +1 -1
- package/src/libraries/JBConstants.sol +1 -1
- package/src/libraries/JBCurrencyIds.sol +1 -1
- package/src/libraries/JBFees.sol +1 -1
- package/src/libraries/JBFixedPointNumber.sol +1 -1
- package/src/libraries/JBMetadataResolver.sol +5 -2
- package/src/libraries/JBPayoutSplitGroupLib.sol +7 -2
- package/src/libraries/JBRulesetMetadataResolver.sol +1 -1
- package/src/libraries/JBSplitGroupIds.sol +1 -1
- package/src/libraries/JBSurplus.sol +5 -2
- package/src/structs/JBSplit.sol +4 -1
- package/test/TestForwardedTokenConsumption.sol +419 -0
- package/test/audit/CrossTerminalSurplusSpoof.t.sol +140 -0
- package/test/audit/CycledSurplusAllowanceReset.t.sol +184 -0
- package/test/units/static/JBController/TestPreviewMintOf.sol +5 -4
- package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +15 -12
- package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +6 -0
- package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +3 -0
- package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +3 -0
- package/test/units/static/JBMultiTerminal/TestPay.sol +7 -15
- package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +1 -1
- package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +1 -1
- package/CHANGE_LOG.md +0 -479
package/src/JBController.sol
CHANGED
|
@@ -158,6 +158,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
158
158
|
RULESETS = rulesets;
|
|
159
159
|
SPLITS = splits;
|
|
160
160
|
TOKENS = tokens;
|
|
161
|
+
// slither-disable-next-line missing-zero-check
|
|
161
162
|
OMNICHAIN_RULESET_OPERATOR = omnichainRulesetOperator;
|
|
162
163
|
}
|
|
163
164
|
|
|
@@ -521,23 +522,28 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
521
522
|
// Get a reference to the project's ruleset.
|
|
522
523
|
JBRuleset memory ruleset = _currentRulesetOf(projectId);
|
|
523
524
|
|
|
525
|
+
// Cache common values used in both permission checks.
|
|
526
|
+
address sender = _msgSender();
|
|
527
|
+
bool senderIsTerminal = _isTerminalOf(projectId, sender);
|
|
528
|
+
|
|
524
529
|
// Minting is restricted to: the project's owner, addresses with permission to `MINT_TOKENS`, the project's
|
|
525
530
|
// terminals, and the project's data hook.
|
|
526
531
|
_requirePermissionAllowingOverrideFrom({
|
|
527
532
|
account: PROJECTS.ownerOf(projectId),
|
|
528
533
|
projectId: projectId,
|
|
529
534
|
permissionId: JBPermissionIds.MINT_TOKENS,
|
|
530
|
-
alsoGrantAccessIf:
|
|
531
|
-
|| _hasDataHookMintPermissionFor(projectId, ruleset,
|
|
535
|
+
alsoGrantAccessIf: senderIsTerminal || sender == ruleset.dataHook()
|
|
536
|
+
|| _hasDataHookMintPermissionFor(projectId, ruleset, sender)
|
|
532
537
|
});
|
|
533
538
|
|
|
534
539
|
// If the message sender is not the project's terminal or data hook, the ruleset must have `allowOwnerMinting`
|
|
535
540
|
// set to `true`.
|
|
536
541
|
if (
|
|
537
|
-
ruleset.id != 0 && !ruleset.allowOwnerMinting() && !
|
|
538
|
-
&&
|
|
539
|
-
|
|
540
|
-
|
|
542
|
+
ruleset.id != 0 && !ruleset.allowOwnerMinting() && !senderIsTerminal && sender != ruleset.dataHook()
|
|
543
|
+
&& !_hasDataHookMintPermissionFor(projectId, ruleset, sender)
|
|
544
|
+
) {
|
|
545
|
+
revert JBController_MintNotAllowedAndNotTerminalOrHook(sender);
|
|
546
|
+
}
|
|
541
547
|
|
|
542
548
|
// Determine the reserved percent to use.
|
|
543
549
|
reservedPercent = useReservedPercent ? ruleset.reservedPercent() : 0;
|
|
@@ -558,7 +564,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
558
564
|
beneficiaryTokenCount: beneficiaryTokenCount,
|
|
559
565
|
memo: memo,
|
|
560
566
|
reservedPercent: reservedPercent,
|
|
561
|
-
caller:
|
|
567
|
+
caller: sender
|
|
562
568
|
});
|
|
563
569
|
|
|
564
570
|
// Add any reserved tokens to the pending reserved token balance.
|
|
@@ -747,12 +753,15 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
747
753
|
rulesets = new JBRulesetWithMetadata[](numberOfRulesets);
|
|
748
754
|
|
|
749
755
|
// Populate the array with rulesets AND their metadata.
|
|
750
|
-
for (uint256 i; i < numberOfRulesets;
|
|
756
|
+
for (uint256 i; i < numberOfRulesets;) {
|
|
751
757
|
// Set the ruleset being iterated on.
|
|
752
758
|
JBRuleset memory baseRuleset = baseRulesets[i];
|
|
753
759
|
|
|
754
760
|
// Set the returned value.
|
|
755
761
|
rulesets[i] = JBRulesetWithMetadata({ruleset: baseRuleset, metadata: baseRuleset.expandMetadata()});
|
|
762
|
+
unchecked {
|
|
763
|
+
++i;
|
|
764
|
+
}
|
|
756
765
|
}
|
|
757
766
|
}
|
|
758
767
|
|
|
@@ -820,8 +829,8 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
820
829
|
override
|
|
821
830
|
returns (uint256 beneficiaryTokenCount, uint256 reservedTokenCount)
|
|
822
831
|
{
|
|
823
|
-
//
|
|
824
|
-
if (tokenCount == 0)
|
|
832
|
+
// A zero preview amount means there are no tokens to split.
|
|
833
|
+
if (tokenCount == 0) return (0, 0);
|
|
825
834
|
|
|
826
835
|
// Keep a reference to the current ruleset.
|
|
827
836
|
JBRuleset memory ruleset = _currentRulesetOf(projectId);
|
|
@@ -895,11 +904,12 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
895
904
|
// Initialize an array of terminals to populate.
|
|
896
905
|
IJBTerminal[] memory terminals = new IJBTerminal[](terminalConfigurations.length);
|
|
897
906
|
|
|
898
|
-
for (uint256 i; i < terminalConfigurations.length;
|
|
907
|
+
for (uint256 i; i < terminalConfigurations.length;) {
|
|
899
908
|
// Set the terminal configuration being iterated on.
|
|
900
909
|
JBTerminalConfig memory terminalConfig = terminalConfigurations[i];
|
|
901
910
|
|
|
902
911
|
// Add the accounting contexts for the specified tokens.
|
|
912
|
+
// slither-disable-next-line calls-loop
|
|
903
913
|
terminalConfig.terminal
|
|
904
914
|
.addAccountingContextsFor({
|
|
905
915
|
projectId: projectId, accountingContexts: terminalConfig.accountingContextsToAccept
|
|
@@ -907,6 +917,9 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
907
917
|
|
|
908
918
|
// Add the terminal.
|
|
909
919
|
terminals[i] = terminalConfig.terminal;
|
|
920
|
+
unchecked {
|
|
921
|
+
++i;
|
|
922
|
+
}
|
|
910
923
|
}
|
|
911
924
|
|
|
912
925
|
// Set the terminals in the directory.
|
|
@@ -926,7 +939,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
926
939
|
internal
|
|
927
940
|
returns (uint256 rulesetId)
|
|
928
941
|
{
|
|
929
|
-
for (uint256 i; i < rulesetConfigurations.length;
|
|
942
|
+
for (uint256 i; i < rulesetConfigurations.length;) {
|
|
930
943
|
// Get a reference to the ruleset config being iterated on.
|
|
931
944
|
JBRulesetConfig memory rulesetConfig = rulesetConfigurations[i];
|
|
932
945
|
|
|
@@ -945,6 +958,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
945
958
|
}
|
|
946
959
|
|
|
947
960
|
// Queue its ruleset.
|
|
961
|
+
// slither-disable-next-line calls-loop
|
|
948
962
|
JBRuleset memory ruleset = RULESETS.queueFor({
|
|
949
963
|
projectId: projectId,
|
|
950
964
|
duration: rulesetConfig.duration,
|
|
@@ -956,11 +970,13 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
956
970
|
});
|
|
957
971
|
|
|
958
972
|
// Set its split groups.
|
|
973
|
+
// slither-disable-next-line calls-loop
|
|
959
974
|
SPLITS.setSplitGroupsOf({
|
|
960
975
|
projectId: projectId, rulesetId: ruleset.id, splitGroups: rulesetConfig.splitGroups
|
|
961
976
|
});
|
|
962
977
|
|
|
963
978
|
// Set its fund access limits.
|
|
979
|
+
// slither-disable-next-line calls-loop
|
|
964
980
|
FUND_ACCESS_LIMITS.setFundAccessLimitsFor({
|
|
965
981
|
projectId: projectId, rulesetId: ruleset.id, fundAccessLimitGroups: rulesetConfig.fundAccessLimitGroups
|
|
966
982
|
});
|
|
@@ -969,6 +985,9 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
969
985
|
if (i == rulesetConfigurations.length - 1) {
|
|
970
986
|
rulesetId = ruleset.id;
|
|
971
987
|
}
|
|
988
|
+
unchecked {
|
|
989
|
+
++i;
|
|
990
|
+
}
|
|
972
991
|
}
|
|
973
992
|
}
|
|
974
993
|
|
|
@@ -999,8 +1018,11 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
999
1018
|
// Keep a reference to the number of splits being iterated on.
|
|
1000
1019
|
uint256 numberOfSplits = splits.length;
|
|
1001
1020
|
|
|
1021
|
+
// Cache _msgSender() before the loop.
|
|
1022
|
+
address messageSender = _msgSender();
|
|
1023
|
+
|
|
1002
1024
|
// Send the tokens to the splits.
|
|
1003
|
-
for (uint256 i; i < numberOfSplits;
|
|
1025
|
+
for (uint256 i; i < numberOfSplits;) {
|
|
1004
1026
|
// Get a reference to the split being iterated on.
|
|
1005
1027
|
JBSplit memory split = splits[i];
|
|
1006
1028
|
|
|
@@ -1023,7 +1045,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1023
1045
|
projectId: projectId, tokenCount: splitTokenCount, recipient: address(split.hook), token: token
|
|
1024
1046
|
});
|
|
1025
1047
|
|
|
1026
|
-
// slither-disable-next-line reentrancy-events
|
|
1048
|
+
// slither-disable-next-line calls-loop,reentrancy-events
|
|
1027
1049
|
try split.hook
|
|
1028
1050
|
.processSplitWith(
|
|
1029
1051
|
JBSplitHookContext({
|
|
@@ -1043,10 +1065,11 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1043
1065
|
} else {
|
|
1044
1066
|
// Pay the project using the split's beneficiary if one was provided. Otherwise, use the message
|
|
1045
1067
|
// sender.
|
|
1046
|
-
address beneficiary = split.beneficiary != address(0) ? split.beneficiary :
|
|
1068
|
+
address beneficiary = split.beneficiary != address(0) ? split.beneficiary : messageSender;
|
|
1047
1069
|
|
|
1048
1070
|
if (split.projectId != 0) {
|
|
1049
1071
|
// Get a reference to the receiving project's primary payment terminal for the token.
|
|
1072
|
+
// slither-disable-next-line calls-loop
|
|
1050
1073
|
IJBTerminal terminal = token == IJBToken(address(0))
|
|
1051
1074
|
? IJBTerminal(address(0))
|
|
1052
1075
|
: DIRECTORY.primaryTerminalOf({projectId: split.projectId, token: address(token)});
|
|
@@ -1065,6 +1088,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1065
1088
|
bytes memory metadata = bytes(abi.encodePacked(projectId));
|
|
1066
1089
|
|
|
1067
1090
|
// Try to fulfill the payment.
|
|
1091
|
+
// slither-disable-next-line calls-loop
|
|
1068
1092
|
try this.executePayReservedTokenToTerminal({
|
|
1069
1093
|
projectId: split.projectId,
|
|
1070
1094
|
terminal: terminal,
|
|
@@ -1079,7 +1103,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1079
1103
|
split: split,
|
|
1080
1104
|
tokenCount: splitTokenCount,
|
|
1081
1105
|
reason: reason,
|
|
1082
|
-
caller:
|
|
1106
|
+
caller: messageSender
|
|
1083
1107
|
});
|
|
1084
1108
|
|
|
1085
1109
|
// If it fails, transfer the tokens from this contract to the beneficiary.
|
|
@@ -1088,6 +1112,7 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1088
1112
|
}
|
|
1089
1113
|
} else if (beneficiary == address(0xdead)) {
|
|
1090
1114
|
// If the split has no project ID, and the beneficiary is 0xdead, burn.
|
|
1115
|
+
// slither-disable-next-line calls-loop
|
|
1091
1116
|
TOKENS.burnFrom({holder: address(this), projectId: projectId, count: splitTokenCount});
|
|
1092
1117
|
} else {
|
|
1093
1118
|
// If the split has no project Id, send to beneficiary.
|
|
@@ -1107,8 +1132,11 @@ contract JBController is JBPermissioned, ERC2771Context, IJBController, IJBMigra
|
|
|
1107
1132
|
groupId: groupId,
|
|
1108
1133
|
split: split,
|
|
1109
1134
|
tokenCount: splitTokenCount,
|
|
1110
|
-
caller:
|
|
1135
|
+
caller: messageSender
|
|
1111
1136
|
});
|
|
1137
|
+
unchecked {
|
|
1138
|
+
++i;
|
|
1139
|
+
}
|
|
1112
1140
|
}
|
|
1113
1141
|
}
|
|
1114
1142
|
|
package/src/JBDirectory.sol
CHANGED
|
@@ -139,6 +139,7 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
139
139
|
// slither-disable-next-line reentrancy-no-eth
|
|
140
140
|
controllerOf[projectId] = controller;
|
|
141
141
|
|
|
142
|
+
// slither-disable-next-line reentrancy-events
|
|
142
143
|
emit SetController({projectId: projectId, controller: controller, caller: msg.sender});
|
|
143
144
|
|
|
144
145
|
// Notify the new controller that migration is complete and it is now the active controller.
|
|
@@ -209,23 +210,23 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
209
210
|
/// @param projectId The ID of the project whose terminals are being set.
|
|
210
211
|
/// @param terminals An array of terminal addresses to set for the project.
|
|
211
212
|
function setTerminalsOf(uint256 projectId, IJBTerminal[] calldata terminals) external override {
|
|
213
|
+
// Cache the controller to avoid redundant storage reads.
|
|
214
|
+
IERC165 controller = controllerOf[projectId];
|
|
215
|
+
|
|
212
216
|
// Enforce permissions.
|
|
213
217
|
_requirePermissionAllowingOverrideFrom({
|
|
214
218
|
account: PROJECTS.ownerOf(projectId),
|
|
215
219
|
projectId: projectId,
|
|
216
220
|
permissionId: JBPermissionIds.SET_TERMINALS,
|
|
217
|
-
alsoGrantAccessIf: msg.sender == address(
|
|
221
|
+
alsoGrantAccessIf: msg.sender == address(controller)
|
|
218
222
|
});
|
|
219
223
|
|
|
220
|
-
// Keep a reference to the project's controller.
|
|
221
|
-
IERC165 controller = controllerOf[projectId];
|
|
222
|
-
|
|
223
224
|
// Get a reference to the flag indicating whether the project is allowed to set its terminals.
|
|
224
225
|
bool allowSetTerminals = !controller.supportsInterface(type(IJBDirectoryAccessControl).interfaceId)
|
|
225
226
|
|| IJBDirectoryAccessControl(address(controller)).setTerminalsAllowed(projectId);
|
|
226
227
|
|
|
227
228
|
// If the caller is not the project's controller, the project's ruleset must allow setting terminals.
|
|
228
|
-
if (msg.sender != address(
|
|
229
|
+
if (msg.sender != address(controller) && !allowSetTerminals) {
|
|
229
230
|
revert JBDirectory_SetTerminalsNotAllowed(projectId);
|
|
230
231
|
}
|
|
231
232
|
|
|
@@ -234,9 +235,15 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
234
235
|
|
|
235
236
|
// If there are any duplicates, revert.
|
|
236
237
|
if (terminals.length > 1) {
|
|
237
|
-
for (uint256 i; i < terminals.length;
|
|
238
|
-
for (uint256 j = i + 1; j < terminals.length;
|
|
238
|
+
for (uint256 i; i < terminals.length;) {
|
|
239
|
+
for (uint256 j = i + 1; j < terminals.length;) {
|
|
239
240
|
if (terminals[i] == terminals[j]) revert JBDirectory_DuplicateTerminals(terminals[i]);
|
|
241
|
+
unchecked {
|
|
242
|
+
++j;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
unchecked {
|
|
246
|
+
++i;
|
|
240
247
|
}
|
|
241
248
|
}
|
|
242
249
|
}
|
|
@@ -266,14 +273,14 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
266
273
|
return primaryTerminal;
|
|
267
274
|
}
|
|
268
275
|
|
|
269
|
-
// Keep a reference to the project's terminals.
|
|
270
|
-
IJBTerminal[]
|
|
276
|
+
// Keep a storage reference to the project's terminals to avoid copying the array to memory.
|
|
277
|
+
IJBTerminal[] storage terminals = _terminalsOf[projectId];
|
|
271
278
|
|
|
272
279
|
// Keep a reference to the number of terminals the project has.
|
|
273
280
|
uint256 numberOfTerminals = terminals.length;
|
|
274
281
|
|
|
275
282
|
// Return the first terminal which accepts the specified token.
|
|
276
|
-
for (uint256 i; i < numberOfTerminals;
|
|
283
|
+
for (uint256 i; i < numberOfTerminals;) {
|
|
277
284
|
// Keep a reference to the terminal being iterated on.
|
|
278
285
|
IJBTerminal terminal = terminals[i];
|
|
279
286
|
|
|
@@ -282,6 +289,9 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
282
289
|
if (terminal.accountingContextForTokenOf({projectId: projectId, token: token}).token != address(0)) {
|
|
283
290
|
return terminal;
|
|
284
291
|
}
|
|
292
|
+
unchecked {
|
|
293
|
+
++i;
|
|
294
|
+
}
|
|
285
295
|
}
|
|
286
296
|
|
|
287
297
|
// Not found.
|
|
@@ -304,15 +314,18 @@ contract JBDirectory is JBPermissioned, Ownable, IJBDirectory {
|
|
|
304
314
|
/// @param terminal The terminal to check for.
|
|
305
315
|
/// @return A flag indicating whether the project uses the terminal.
|
|
306
316
|
function isTerminalOf(uint256 projectId, IJBTerminal terminal) public view override returns (bool) {
|
|
307
|
-
// Keep a reference to the project's terminals.
|
|
308
|
-
IJBTerminal[]
|
|
317
|
+
// Keep a storage reference to the project's terminals to avoid copying the array to memory.
|
|
318
|
+
IJBTerminal[] storage terminals = _terminalsOf[projectId];
|
|
309
319
|
|
|
310
320
|
// Keep a reference to the number of terminals the project has.
|
|
311
321
|
uint256 numberOfTerminals = terminals.length;
|
|
312
322
|
|
|
313
323
|
// Loop through and return true if the terminal is found.
|
|
314
|
-
for (uint256 i; i < numberOfTerminals;
|
|
324
|
+
for (uint256 i; i < numberOfTerminals;) {
|
|
315
325
|
if (terminals[i] == terminal) return true;
|
|
326
|
+
unchecked {
|
|
327
|
+
++i;
|
|
328
|
+
}
|
|
316
329
|
}
|
|
317
330
|
|
|
318
331
|
// Otherwise, return false.
|
|
@@ -82,7 +82,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
82
82
|
uint256 numberOfFundAccessLimitGroups = fundAccessLimitGroups.length;
|
|
83
83
|
|
|
84
84
|
// Set payout limits if there are any.
|
|
85
|
-
for (uint256 i; i < numberOfFundAccessLimitGroups;
|
|
85
|
+
for (uint256 i; i < numberOfFundAccessLimitGroups;) {
|
|
86
86
|
// Set the limits being iterated on.
|
|
87
87
|
JBFundAccessLimitGroup calldata fundAccessLimitGroup = fundAccessLimitGroups[i];
|
|
88
88
|
|
|
@@ -90,7 +90,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
90
90
|
uint256 numberOfPayoutLimits = fundAccessLimitGroup.payoutLimits.length;
|
|
91
91
|
|
|
92
92
|
// Iterate through each payout limit to validate and store them.
|
|
93
|
-
for (uint256 j; j < numberOfPayoutLimits;
|
|
93
|
+
for (uint256 j; j < numberOfPayoutLimits;) {
|
|
94
94
|
// Set the payout limit being iterated on.
|
|
95
95
|
JBCurrencyAmount calldata payoutLimit = fundAccessLimitGroup.payoutLimits[j];
|
|
96
96
|
|
|
@@ -106,13 +106,16 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
106
106
|
uint256(payoutLimit.amount) | (uint256(payoutLimit.currency) << 224)
|
|
107
107
|
);
|
|
108
108
|
}
|
|
109
|
+
unchecked {
|
|
110
|
+
++j;
|
|
111
|
+
}
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
// Keep a reference to the number of surplus allowances.
|
|
112
115
|
uint256 numberOfSurplusAllowances = fundAccessLimitGroup.surplusAllowances.length;
|
|
113
116
|
|
|
114
117
|
// Iterate through each surplus allowance to validate and store them.
|
|
115
|
-
for (uint256 j; j < numberOfSurplusAllowances;
|
|
118
|
+
for (uint256 j; j < numberOfSurplusAllowances;) {
|
|
116
119
|
// Set the surplus allowance being iterated on.
|
|
117
120
|
JBCurrencyAmount calldata surplusAllowance = fundAccessLimitGroup.surplusAllowances[j];
|
|
118
121
|
|
|
@@ -128,6 +131,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
128
131
|
uint256(surplusAllowance.amount) | (uint256(surplusAllowance.currency) << 224)
|
|
129
132
|
);
|
|
130
133
|
}
|
|
134
|
+
unchecked {
|
|
135
|
+
++j;
|
|
136
|
+
}
|
|
131
137
|
}
|
|
132
138
|
|
|
133
139
|
emit SetFundAccessLimits({
|
|
@@ -136,6 +142,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
136
142
|
fundAccessLimitGroup: fundAccessLimitGroup,
|
|
137
143
|
caller: msg.sender
|
|
138
144
|
});
|
|
145
|
+
unchecked {
|
|
146
|
+
++i;
|
|
147
|
+
}
|
|
139
148
|
}
|
|
140
149
|
}
|
|
141
150
|
|
|
@@ -171,7 +180,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
171
180
|
uint256 numberOfData = data.length;
|
|
172
181
|
|
|
173
182
|
// Iterate through the stored packed values and return the value of the matching currency.
|
|
174
|
-
for (uint256 i; i < numberOfData;
|
|
183
|
+
for (uint256 i; i < numberOfData;) {
|
|
175
184
|
// Set the data being iterated on.
|
|
176
185
|
uint256 packedPayoutLimitData = data[i];
|
|
177
186
|
|
|
@@ -180,6 +189,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
180
189
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
181
190
|
return uint256(uint224(packedPayoutLimitData));
|
|
182
191
|
}
|
|
192
|
+
unchecked {
|
|
193
|
+
++i;
|
|
194
|
+
}
|
|
183
195
|
}
|
|
184
196
|
}
|
|
185
197
|
|
|
@@ -213,7 +225,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
213
225
|
payoutLimits = new JBCurrencyAmount[](numberOfData);
|
|
214
226
|
|
|
215
227
|
// Iterate through the packed values and format the returned value.
|
|
216
|
-
for (uint256 i; i < numberOfData;
|
|
228
|
+
for (uint256 i; i < numberOfData;) {
|
|
217
229
|
// Set the data being iterated on.
|
|
218
230
|
uint256 packedPayoutLimitData = packedPayoutLimitsData[i];
|
|
219
231
|
|
|
@@ -225,6 +237,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
225
237
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
226
238
|
amount: uint224(packedPayoutLimitData)
|
|
227
239
|
});
|
|
240
|
+
unchecked {
|
|
241
|
+
++i;
|
|
242
|
+
}
|
|
228
243
|
}
|
|
229
244
|
}
|
|
230
245
|
|
|
@@ -257,7 +272,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
257
272
|
uint256 numberOfData = packedSurplusAllowancesData.length;
|
|
258
273
|
|
|
259
274
|
// Iterate through the stored packed values and format the returned value.
|
|
260
|
-
for (uint256 i; i < numberOfData;
|
|
275
|
+
for (uint256 i; i < numberOfData;) {
|
|
261
276
|
// Set the data being iterated on.
|
|
262
277
|
uint256 packedSurplusAllowanceData = packedSurplusAllowancesData[i];
|
|
263
278
|
|
|
@@ -266,6 +281,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
266
281
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
267
282
|
return uint256(uint224(packedSurplusAllowanceData));
|
|
268
283
|
}
|
|
284
|
+
unchecked {
|
|
285
|
+
++i;
|
|
286
|
+
}
|
|
269
287
|
}
|
|
270
288
|
}
|
|
271
289
|
|
|
@@ -301,7 +319,7 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
301
319
|
surplusAllowances = new JBCurrencyAmount[](numberOfData);
|
|
302
320
|
|
|
303
321
|
// Iterate through the stored packed values and format the returned value.
|
|
304
|
-
for (uint256 i; i < numberOfData;
|
|
322
|
+
for (uint256 i; i < numberOfData;) {
|
|
305
323
|
// Set the data being iterated on.
|
|
306
324
|
uint256 packedSurplusAllowanceData = packedSurplusAllowancesData[i];
|
|
307
325
|
|
|
@@ -313,6 +331,9 @@ contract JBFundAccessLimits is JBControlled, IJBFundAccessLimits {
|
|
|
313
331
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
314
332
|
amount: uint224(packedSurplusAllowanceData)
|
|
315
333
|
});
|
|
334
|
+
unchecked {
|
|
335
|
+
++i;
|
|
336
|
+
}
|
|
316
337
|
}
|
|
317
338
|
}
|
|
318
339
|
}
|