@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
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.6;
|
|
3
|
+
|
|
4
|
+
import {TestBaseWorkflow} from "../helpers/TestBaseWorkflow.sol";
|
|
5
|
+
import {IJBRulesetApprovalHook} from "../../src/interfaces/IJBRulesetApprovalHook.sol";
|
|
6
|
+
import {IJBTerminal} from "../../src/interfaces/IJBTerminal.sol";
|
|
7
|
+
import {JBConstants} from "../../src/libraries/JBConstants.sol";
|
|
8
|
+
import {JBAccountingContext} from "../../src/structs/JBAccountingContext.sol";
|
|
9
|
+
import {JBCurrencyAmount} from "../../src/structs/JBCurrencyAmount.sol";
|
|
10
|
+
import {JBFundAccessLimitGroup} from "../../src/structs/JBFundAccessLimitGroup.sol";
|
|
11
|
+
import {JBRuleset} from "../../src/structs/JBRuleset.sol";
|
|
12
|
+
import {JBRulesetConfig} from "../../src/structs/JBRulesetConfig.sol";
|
|
13
|
+
import {JBRulesetMetadata} from "../../src/structs/JBRulesetMetadata.sol";
|
|
14
|
+
import {JBSplitGroup} from "../../src/structs/JBSplitGroup.sol";
|
|
15
|
+
import {JBTerminalConfig} from "../../src/structs/JBTerminalConfig.sol";
|
|
16
|
+
|
|
17
|
+
contract CycledSurplusAllowanceResetTest is TestBaseWorkflow {
|
|
18
|
+
function test_surplusAllowanceDoesNotResetAcrossImplicitCycles() external {
|
|
19
|
+
_launchFeeProject();
|
|
20
|
+
|
|
21
|
+
JBRulesetConfig[] memory rulesetConfigurations = new JBRulesetConfig[](1);
|
|
22
|
+
rulesetConfigurations[0] = _makeRulesetConfig({
|
|
23
|
+
duration: 1 days,
|
|
24
|
+
metadata: _defaultMetadata(),
|
|
25
|
+
splitGroups: new JBSplitGroup[](0),
|
|
26
|
+
fundAccessLimitGroups: _makeFundAccessLimitGroup(1 ether)
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
uint256 projectId = jbController()
|
|
30
|
+
.launchProjectFor({
|
|
31
|
+
owner: multisig(),
|
|
32
|
+
projectUri: "cycle-allowance",
|
|
33
|
+
rulesetConfigurations: rulesetConfigurations,
|
|
34
|
+
terminalConfigurations: _makeTerminalConfig(),
|
|
35
|
+
memo: ""
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
address payer = makeAddr("payer");
|
|
39
|
+
vm.deal(payer, 5 ether);
|
|
40
|
+
vm.prank(payer);
|
|
41
|
+
jbMultiTerminal().pay{value: 5 ether}({
|
|
42
|
+
projectId: projectId,
|
|
43
|
+
amount: 5 ether,
|
|
44
|
+
token: JBConstants.NATIVE_TOKEN,
|
|
45
|
+
beneficiary: payer,
|
|
46
|
+
minReturnedTokens: 0,
|
|
47
|
+
memo: "",
|
|
48
|
+
metadata: new bytes(0)
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
vm.prank(multisig());
|
|
52
|
+
jbMultiTerminal()
|
|
53
|
+
.useAllowanceOf({
|
|
54
|
+
projectId: projectId,
|
|
55
|
+
token: JBConstants.NATIVE_TOKEN,
|
|
56
|
+
amount: 1 ether,
|
|
57
|
+
currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
58
|
+
minTokensPaidOut: 0,
|
|
59
|
+
beneficiary: payable(makeAddr("cycle1-beneficiary")),
|
|
60
|
+
feeBeneficiary: payable(multisig()),
|
|
61
|
+
memo: ""
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
JBRuleset memory cycleOneRuleset = jbRulesets().currentOf(projectId);
|
|
65
|
+
assertEq(cycleOneRuleset.cycleNumber, 1, "expected first cycle before warp");
|
|
66
|
+
|
|
67
|
+
vm.warp(block.timestamp + 1 days + 1);
|
|
68
|
+
|
|
69
|
+
JBRuleset memory cycledRuleset = jbRulesets().currentOf(projectId);
|
|
70
|
+
assertEq(cycledRuleset.cycleNumber, 2, "expected implicit second cycle");
|
|
71
|
+
assertEq(cycledRuleset.id, cycleOneRuleset.id, "cycled ruleset reuses base ruleset id");
|
|
72
|
+
|
|
73
|
+
vm.expectRevert();
|
|
74
|
+
vm.prank(multisig());
|
|
75
|
+
jbMultiTerminal()
|
|
76
|
+
.useAllowanceOf({
|
|
77
|
+
projectId: projectId,
|
|
78
|
+
token: JBConstants.NATIVE_TOKEN,
|
|
79
|
+
amount: 1 ether,
|
|
80
|
+
currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
81
|
+
minTokensPaidOut: 0,
|
|
82
|
+
beneficiary: payable(makeAddr("cycle2-beneficiary")),
|
|
83
|
+
feeBeneficiary: payable(multisig()),
|
|
84
|
+
memo: ""
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function _launchFeeProject() private returns (uint256) {
|
|
89
|
+
JBRulesetConfig[] memory rulesetConfigurations = new JBRulesetConfig[](1);
|
|
90
|
+
rulesetConfigurations[0] = _makeRulesetConfig({
|
|
91
|
+
duration: 1 days,
|
|
92
|
+
metadata: _defaultMetadata(),
|
|
93
|
+
splitGroups: new JBSplitGroup[](0),
|
|
94
|
+
fundAccessLimitGroups: new JBFundAccessLimitGroup[](0)
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return jbController()
|
|
98
|
+
.launchProjectFor({
|
|
99
|
+
owner: multisig(),
|
|
100
|
+
projectUri: "fee-project",
|
|
101
|
+
rulesetConfigurations: rulesetConfigurations,
|
|
102
|
+
terminalConfigurations: _makeTerminalConfig(),
|
|
103
|
+
memo: ""
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function _defaultMetadata() private pure returns (JBRulesetMetadata memory) {
|
|
108
|
+
return JBRulesetMetadata({
|
|
109
|
+
reservedPercent: 0,
|
|
110
|
+
cashOutTaxRate: 0,
|
|
111
|
+
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
112
|
+
pausePay: false,
|
|
113
|
+
pauseCreditTransfers: false,
|
|
114
|
+
allowOwnerMinting: true,
|
|
115
|
+
allowSetCustomToken: true,
|
|
116
|
+
allowTerminalMigration: true,
|
|
117
|
+
allowSetTerminals: true,
|
|
118
|
+
ownerMustSendPayouts: false,
|
|
119
|
+
allowSetController: true,
|
|
120
|
+
allowAddAccountingContext: true,
|
|
121
|
+
allowAddPriceFeed: true,
|
|
122
|
+
holdFees: false,
|
|
123
|
+
useTotalSurplusForCashOuts: false,
|
|
124
|
+
useDataHookForPay: false,
|
|
125
|
+
useDataHookForCashOut: false,
|
|
126
|
+
dataHook: address(0),
|
|
127
|
+
metadata: 0
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function _makeTerminalConfig() private view returns (JBTerminalConfig[] memory terminalConfigurations) {
|
|
132
|
+
terminalConfigurations = new JBTerminalConfig[](1);
|
|
133
|
+
|
|
134
|
+
JBAccountingContext[] memory accountingContexts = new JBAccountingContext[](1);
|
|
135
|
+
accountingContexts[0] = JBAccountingContext({
|
|
136
|
+
token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
terminalConfigurations[0] = JBTerminalConfig({
|
|
140
|
+
terminal: IJBTerminal(address(jbMultiTerminal())), accountingContextsToAccept: accountingContexts
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function _makeFundAccessLimitGroup(uint224 surplusAllowanceAmount)
|
|
145
|
+
private
|
|
146
|
+
view
|
|
147
|
+
returns (JBFundAccessLimitGroup[] memory groups)
|
|
148
|
+
{
|
|
149
|
+
groups = new JBFundAccessLimitGroup[](1);
|
|
150
|
+
|
|
151
|
+
JBCurrencyAmount[] memory surplusAllowances = new JBCurrencyAmount[](1);
|
|
152
|
+
surplusAllowances[0] =
|
|
153
|
+
JBCurrencyAmount({amount: surplusAllowanceAmount, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))});
|
|
154
|
+
|
|
155
|
+
groups[0] = JBFundAccessLimitGroup({
|
|
156
|
+
terminal: address(jbMultiTerminal()),
|
|
157
|
+
token: JBConstants.NATIVE_TOKEN,
|
|
158
|
+
payoutLimits: new JBCurrencyAmount[](0),
|
|
159
|
+
surplusAllowances: surplusAllowances
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function _makeRulesetConfig(
|
|
164
|
+
uint32 duration,
|
|
165
|
+
JBRulesetMetadata memory metadata,
|
|
166
|
+
JBSplitGroup[] memory splitGroups,
|
|
167
|
+
JBFundAccessLimitGroup[] memory fundAccessLimitGroups
|
|
168
|
+
)
|
|
169
|
+
private
|
|
170
|
+
pure
|
|
171
|
+
returns (JBRulesetConfig memory)
|
|
172
|
+
{
|
|
173
|
+
return JBRulesetConfig({
|
|
174
|
+
mustStartAtOrAfter: 0,
|
|
175
|
+
duration: duration,
|
|
176
|
+
weight: 1000 * 10 ** 18,
|
|
177
|
+
weightCutPercent: 0,
|
|
178
|
+
approvalHook: IJBRulesetApprovalHook(address(0)),
|
|
179
|
+
metadata: metadata,
|
|
180
|
+
splitGroups: splitGroups,
|
|
181
|
+
fundAccessLimitGroups: fundAccessLimitGroups
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity 0.8.28;
|
|
3
3
|
|
|
4
|
-
import {JBController} from "../../../../src/JBController.sol";
|
|
5
4
|
import {IJBRulesetApprovalHook} from "../../../../src/interfaces/IJBRulesetApprovalHook.sol";
|
|
6
5
|
import {IJBRulesets} from "../../../../src/interfaces/IJBRulesets.sol";
|
|
7
6
|
import {JBConstants} from "../../../../src/libraries/JBConstants.sol";
|
|
@@ -17,9 +16,11 @@ contract TestPreviewMintOf_Local is JBControllerSetup {
|
|
|
17
16
|
super.controllerSetup();
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
function test_ReturnsZeroCountsWhenTokenCountIsZero() external view {
|
|
20
|
+
(uint256 beneficiaryTokenCount, uint256 reservedTokenCount) = _controller.previewMintOf(_projectId, 0, true);
|
|
21
|
+
|
|
22
|
+
assertEq(beneficiaryTokenCount, 0);
|
|
23
|
+
assertEq(reservedTokenCount, 0);
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
function test_ReturnsSplitCountsWhenUsingReservedPercent() external {
|
|
@@ -5,7 +5,6 @@ import {MockERC20} from "../../../mock/MockERC20.sol";
|
|
|
5
5
|
import {JBMultiTerminal} from "../../../../src/JBMultiTerminal.sol";
|
|
6
6
|
import {JBPermissioned} from "../../../../src/abstract/JBPermissioned.sol";
|
|
7
7
|
import {IJBCashOutHook} from "../../../../src/interfaces/IJBCashOutHook.sol";
|
|
8
|
-
import {IJBCashOutTerminal} from "../../../../src/interfaces/IJBCashOutTerminal.sol";
|
|
9
8
|
import {IJBController} from "../../../../src/interfaces/IJBController.sol";
|
|
10
9
|
import {IJBDirectory} from "../../../../src/interfaces/IJBDirectory.sol";
|
|
11
10
|
import {IJBFeelessAddresses} from "../../../../src/interfaces/IJBFeelessAddresses.sol";
|
|
@@ -220,11 +219,7 @@ contract TestCashOutTokensOf_Local is JBMultiTerminalSetup {
|
|
|
220
219
|
// forge-lint: disable-next-line(unsafe-typecast)
|
|
221
220
|
_acceptToken(_mockToken, 18, uint32(uint160(_mockToken)));
|
|
222
221
|
|
|
223
|
-
vm.expectRevert(
|
|
224
|
-
abi.encodeWithSelector(
|
|
225
|
-
JBMultiTerminal.JBMultiTerminal_UnderMinTokensReclaimed.selector, reclaimAmount, 1e18
|
|
226
|
-
)
|
|
227
|
-
);
|
|
222
|
+
vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.JBMultiTerminal_UnderMin.selector, reclaimAmount, 1e18));
|
|
228
223
|
vm.prank(_bene);
|
|
229
224
|
_terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, _mockToken, 1e18, _bene, ""); // minReclaimAmount
|
|
230
225
|
// = 1e18 but only 1e9 reclaimed
|
|
@@ -431,10 +426,14 @@ contract TestCashOutTokensOf_Local is JBMultiTerminalSetup {
|
|
|
431
426
|
// ensure approval is set via forceApprove
|
|
432
427
|
vm.expectCall(address(_mockToken2), abi.encodeCall(IERC20.approve, (address(_mockHook), _defaultAmount)));
|
|
433
428
|
|
|
434
|
-
|
|
429
|
+
// Mock the temporary allowance as fully consumed by the hook so the cleanup guard passes.
|
|
430
|
+
vm.mockCall(
|
|
431
|
+
address(_mockToken2),
|
|
432
|
+
abi.encodeCall(IERC20.allowance, (address(_terminal), address(_mockHook))),
|
|
433
|
+
abi.encode(0)
|
|
434
|
+
);
|
|
435
435
|
|
|
436
|
-
|
|
437
|
-
emit IJBCashOutTerminal.HookAfterRecordCashOut(_mockHook, context, _defaultAmount, 0, address(_bene));
|
|
436
|
+
_acceptToken(address(_mockToken2), 18, uint32(uint160(address(_mockToken2))));
|
|
438
437
|
|
|
439
438
|
vm.prank(_bene);
|
|
440
439
|
_terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, address(_mockToken2), _minReclaimed, _bene, "");
|
|
@@ -548,6 +547,13 @@ contract TestCashOutTokensOf_Local is JBMultiTerminalSetup {
|
|
|
548
547
|
|
|
549
548
|
mockExpect(address(_mockHook), abi.encodeCall(IJBCashOutHook.afterCashOutRecordedWith, (context)), "");
|
|
550
549
|
|
|
550
|
+
// Mock the temporary allowance as fully consumed by the hook so the cleanup guard passes.
|
|
551
|
+
vm.mockCall(
|
|
552
|
+
address(_mockToken2),
|
|
553
|
+
abi.encodeCall(IERC20.allowance, (address(_terminal), address(_mockHook))),
|
|
554
|
+
abi.encode(0)
|
|
555
|
+
);
|
|
556
|
+
|
|
551
557
|
// primary terminal check
|
|
552
558
|
mockExpect(
|
|
553
559
|
address(directory),
|
|
@@ -567,9 +573,6 @@ contract TestCashOutTokensOf_Local is JBMultiTerminalSetup {
|
|
|
567
573
|
|
|
568
574
|
_acceptToken(address(_mockToken2), 18, uint32(uint160(address(_mockToken2))));
|
|
569
575
|
|
|
570
|
-
vm.expectEmit();
|
|
571
|
-
emit IJBCashOutTerminal.HookAfterRecordCashOut(_mockHook, context, passedAfterTax, hookTax, address(_bene));
|
|
572
|
-
|
|
573
576
|
vm.prank(_bene);
|
|
574
577
|
_terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, address(_mockToken2), _minReclaimed, _bene, "");
|
|
575
578
|
}
|
|
@@ -335,6 +335,9 @@ contract TestExecutePayout_Local is JBMultiTerminalSetup {
|
|
|
335
335
|
// mock call for SafeERC20s forceApprove approval
|
|
336
336
|
mockExpect(_usdc, abi.encodeCall(IERC20.approve, (_mockSecondTerminal, amountAfterTax)), "");
|
|
337
337
|
|
|
338
|
+
// Mock the forwarded allowance as fully consumed by the recipient terminal.
|
|
339
|
+
vm.mockCall(_usdc, abi.encodeCall(IERC20.allowance, (address(_terminal), _mockSecondTerminal)), abi.encode(0));
|
|
340
|
+
|
|
338
341
|
// mock call to second terminals addToBalanceOf
|
|
339
342
|
mockExpect(
|
|
340
343
|
_mockSecondTerminal,
|
|
@@ -419,6 +422,9 @@ contract TestExecutePayout_Local is JBMultiTerminalSetup {
|
|
|
419
422
|
// mock call for SafeERC20s forceApprove approval
|
|
420
423
|
mockExpect(_usdc, abi.encodeCall(IERC20.approve, (_mockSecondTerminal, amountAfterTax)), "");
|
|
421
424
|
|
|
425
|
+
// Mock the forwarded allowance as fully consumed by the recipient terminal.
|
|
426
|
+
vm.mockCall(_usdc, abi.encodeCall(IERC20.allowance, (address(_terminal), _mockSecondTerminal)), abi.encode(0));
|
|
427
|
+
|
|
422
428
|
// mock call to second terminals pay function
|
|
423
429
|
mockExpect(
|
|
424
430
|
_mockSecondTerminal,
|
|
@@ -73,6 +73,9 @@ contract TestExecuteProcessFee_Local is JBMultiTerminalSetup {
|
|
|
73
73
|
// mock approval call for forceApprove
|
|
74
74
|
mockExpect(_usdc, abi.encodeCall(IERC20.approve, (address(_feeTerminal), _defaultAmount)), "");
|
|
75
75
|
|
|
76
|
+
// Mock the forwarded allowance as fully consumed by the fee terminal.
|
|
77
|
+
vm.mockCall(_usdc, abi.encodeCall(IERC20.allowance, (address(_terminal), address(_feeTerminal))), abi.encode(0));
|
|
78
|
+
|
|
76
79
|
// mock pay call to fee terminal
|
|
77
80
|
mockExpect(
|
|
78
81
|
address(_feeTerminal),
|
|
@@ -135,6 +135,9 @@ contract TestMigrateBalanceOf_Local is JBMultiTerminalSetup {
|
|
|
135
135
|
// mock call for SafeERC20s forceApprove approval
|
|
136
136
|
mockExpect(_usdc, abi.encodeCall(IERC20.approve, (address(_newTerminal), _defaultAmount)), "");
|
|
137
137
|
|
|
138
|
+
// Mock the forwarded allowance as fully consumed by the destination terminal.
|
|
139
|
+
vm.mockCall(_usdc, abi.encodeCall(IERC20.allowance, (address(_terminal), address(_newTerminal))), abi.encode(0));
|
|
140
|
+
|
|
138
141
|
// mock call to new terminal addToBalance
|
|
139
142
|
mockExpect(
|
|
140
143
|
address(_newTerminal),
|
|
@@ -16,6 +16,7 @@ import {JBAfterPayRecordedContext} from "../../../../src/structs/JBAfterPayRecor
|
|
|
16
16
|
import {JBPayHookSpecification} from "../../../../src/structs/JBPayHookSpecification.sol";
|
|
17
17
|
import {JBRuleset} from "../../../../src/structs/JBRuleset.sol";
|
|
18
18
|
import {JBTokenAmount} from "../../../../src/structs/JBTokenAmount.sol";
|
|
19
|
+
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
19
20
|
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
|
20
21
|
import {JBMultiTerminalSetup} from "./JBMultiTerminalSetup.sol";
|
|
21
22
|
|
|
@@ -138,7 +139,7 @@ contract TestPay_Local is JBMultiTerminalSetup {
|
|
|
138
139
|
|
|
139
140
|
mockExpect(address(tokens), abi.encodeCall(IJBTokens.totalBalanceOf, (_bene, _projectId)), abi.encode(0));
|
|
140
141
|
|
|
141
|
-
vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.
|
|
142
|
+
vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.JBMultiTerminal_UnderMin.selector, 0, 1));
|
|
142
143
|
_terminal.pay{value: 1e18}({
|
|
143
144
|
projectId: _projectId,
|
|
144
145
|
token: _native,
|
|
@@ -298,21 +299,12 @@ contract TestPay_Local is JBMultiTerminalSetup {
|
|
|
298
299
|
// mock call to hook
|
|
299
300
|
mockExpect(address(_mockHook), abi.encodeCall(IJBPayHook.afterPayRecordedWith, (context)), "");
|
|
300
301
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
address(this),
|
|
307
|
-
_bene,
|
|
308
|
-
_defaultAmount,
|
|
309
|
-
_mintAmount,
|
|
310
|
-
"",
|
|
311
|
-
bytes(""),
|
|
312
|
-
address(this)
|
|
302
|
+
// Mock the temporary allowance as fully consumed by the hook so the cleanup guard passes.
|
|
303
|
+
vm.mockCall(
|
|
304
|
+
address(_mockToken),
|
|
305
|
+
abi.encodeCall(IERC20.allowance, (address(_terminal), address(_mockHook))),
|
|
306
|
+
abi.encode(0)
|
|
313
307
|
);
|
|
314
|
-
vm.expectEmit();
|
|
315
|
-
emit IJBTerminal.HookAfterRecordPay(_mockHook, context, _defaultAmount, address(this));
|
|
316
308
|
|
|
317
309
|
// Data for subsequent calls made for balance checks
|
|
318
310
|
bytes[] memory subsequentReturns = new bytes[](2);
|
|
@@ -71,7 +71,7 @@ contract TestSendPayoutsOf_Local is JBMultiTerminalSetup {
|
|
|
71
71
|
abi.encode(address(_terminal))
|
|
72
72
|
);
|
|
73
73
|
|
|
74
|
-
vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.
|
|
74
|
+
vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.JBMultiTerminal_UnderMin.selector, 0, 1));
|
|
75
75
|
_terminal.sendPayoutsOf(_projectId, address(0), 0, 0, 1);
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -62,7 +62,7 @@ contract TestUseAllowanceOf_Local is JBMultiTerminalSetup {
|
|
|
62
62
|
address(feelessAddresses), abi.encodeCall(IJBFeelessAddresses.isFeeless, (address(this))), abi.encode(true)
|
|
63
63
|
);
|
|
64
64
|
|
|
65
|
-
vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.
|
|
65
|
+
vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.JBMultiTerminal_UnderMin.selector, 0, 1));
|
|
66
66
|
_terminal.useAllowanceOf(_projectId, address(0), 0, 0, 1, payable(address(this)), payable(address(this)), "");
|
|
67
67
|
}
|
|
68
68
|
|