@bananapus/core-v6 0.0.37 → 0.0.38
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/foundry.lock +1 -7
- package/foundry.toml +1 -1
- package/package.json +19 -7
- package/src/JBController.sol +19 -1
- package/src/JBMultiTerminal.sol +68 -34
- package/src/JBTerminalStore.sol +6 -6
- package/src/interfaces/IJBController.sol +4 -1
- package/src/libraries/JBFees.sol +47 -9
- package/src/libraries/JBPayoutSplitGroupLib.sol +2 -2
- package/src/periphery/JBMatchingPriceFeed.sol +1 -1
- package/test/mock/MockMaliciousBeneficiary.sol +15 -15
- package/ADMINISTRATION.md +0 -103
- package/ARCHITECTURE.md +0 -133
- package/AUDIT_INSTRUCTIONS.md +0 -139
- package/RISKS.md +0 -215
- package/SKILLS.md +0 -55
- package/STYLE_GUIDE.md +0 -610
- package/USER_JOURNEYS.md +0 -215
- package/script/Deploy.s.sol +0 -124
- package/script/DeployPeriphery.s.sol +0 -354
- package/slither-ci.config.json +0 -10
- package/test/AuditFixes.t.sol +0 -808
- package/test/ComprehensiveInvariant.t.sol +0 -306
- package/test/CoreExploitTests.t.sol +0 -2741
- package/test/EconomicSimulation.t.sol +0 -348
- package/test/EntryPointPermutations.t.sol +0 -684
- package/test/FlashLoanAttacks.t.sol +0 -797
- package/test/PermissionEscalation.t.sol +0 -711
- package/test/PermissionsInvariant.t.sol +0 -403
- package/test/RulesetTransitions.t.sol +0 -713
- package/test/SplitLoopTests.t.sol +0 -752
- package/test/TestAccessToFunds.sol +0 -2683
- package/test/TestAuditResponseDesignProofs.sol +0 -434
- package/test/TestCashOut.sol +0 -198
- package/test/TestCashOutCountFor.sol +0 -271
- package/test/TestCashOutHooks.sol +0 -351
- package/test/TestCashOutTimingEdge.sol +0 -241
- package/test/TestDataHookFuzzing.sol +0 -524
- package/test/TestDurationUnderflow.sol +0 -233
- package/test/TestFeeFreeCashOutBypass.sol +0 -949
- package/test/TestFeeProcessingFailure.sol +0 -218
- package/test/TestFees.sol +0 -619
- package/test/TestForwardedTokenConsumption.sol +0 -425
- package/test/TestInterfaceSupport.sol +0 -81
- package/test/TestJBERC20Inheritance.sol +0 -103
- package/test/TestL2SequencerPriceFeed.sol +0 -292
- package/test/TestLaunchProject.sol +0 -188
- package/test/TestMetaTx.sol +0 -217
- package/test/TestMetadataOffsetOverflow.sol +0 -179
- package/test/TestMetadataParserLib.sol +0 -471
- package/test/TestMigrationHeldFees.sol +0 -255
- package/test/TestMintTokensOf.sol +0 -185
- package/test/TestMultiTerminalSurplus.sol +0 -348
- package/test/TestMultiTokenSurplus.sol +0 -202
- package/test/TestMultipleAccessLimits.sol +0 -664
- package/test/TestPayBurnRedeemFlow.sol +0 -195
- package/test/TestPayHooks.sol +0 -209
- package/test/TestPermissions.sol +0 -324
- package/test/TestPermissionsEdge.sol +0 -290
- package/test/TestPermit2DataHook.t.sol +0 -360
- package/test/TestPermit2Terminal.sol +0 -372
- package/test/TestRulesetQueueing.sol +0 -1025
- package/test/TestRulesetQueuingStress.sol +0 -806
- package/test/TestRulesetWeightCaching.sol +0 -178
- package/test/TestSplits.sol +0 -391
- package/test/TestTerminalMigration.sol +0 -274
- package/test/TestTerminalPreviewParity.sol +0 -208
- package/test/TestTokenFlow.sol +0 -191
- package/test/TestWeightCacheStaleAfterRejection.sol +0 -303
- package/test/WeirdTokenTests.t.sol +0 -817
- package/test/audit/CashOutReenterPay.t.sol +0 -501
- package/test/audit/CodexHeldFeeRounding.t.sol +0 -159
- package/test/audit/CodexMigrationFeeFailure.t.sol +0 -163
- package/test/audit/CrossTerminalSurplusSpoof.t.sol +0 -140
- package/test/audit/CycledSurplusAllowanceReset.t.sol +0 -184
- package/test/audit/FeeFreeSurplusLifecycle.t.sol +0 -399
- package/test/audit/FeeFreeSurplusStale.t.sol +0 -248
- package/test/audit/USDTVoidReturnCompat.t.sol +0 -525
- package/test/fork/TestChainlinkPriceFeedFork.sol +0 -254
- package/test/fork/TestSequencerPriceFeedFork.sol +0 -168
- package/test/fork/TestTerminalPreviewParityFork.sol +0 -108
- package/test/formal/BondingCurveProperties.t.sol +0 -420
- package/test/formal/FeeProperties.t.sol +0 -252
- package/test/invariants/Phase3DeepInvariant.t.sol +0 -412
- package/test/invariants/RulesetsInvariant.t.sol +0 -125
- package/test/invariants/TerminalStoreInvariant.t.sol +0 -227
- package/test/invariants/TokensInvariant.t.sol +0 -195
- package/test/invariants/handlers/ComprehensiveHandler.sol +0 -303
- package/test/invariants/handlers/EconomicHandler.sol +0 -377
- package/test/invariants/handlers/Phase3Handler.sol +0 -443
- package/test/invariants/handlers/RulesetsHandler.sol +0 -115
- package/test/invariants/handlers/TerminalStoreHandler.sol +0 -151
- package/test/invariants/handlers/TokensHandler.sol +0 -126
- package/test/regression/HoldFeesCashOutReserved.t.sol +0 -415
- package/test/regression/WeightCacheBoundary.t.sol +0 -291
- package/test/trees/JBController/burnTokensOf.tree +0 -9
- package/test/trees/JBController/claimTokensFor.tree +0 -5
- package/test/trees/JBController/deployERC20For.tree +0 -5
- package/test/trees/JBController/getRulesetOf.tree +0 -5
- package/test/trees/JBController/launchProjectFor.tree +0 -12
- package/test/trees/JBController/launchRulesetsFor.tree +0 -8
- package/test/trees/JBController/migrateController.tree +0 -12
- package/test/trees/JBController/mintTokensOf.tree +0 -12
- package/test/trees/JBController/payReservedTokenToTerminal.tree +0 -8
- package/test/trees/JBController/receiveMigrationFrom.tree +0 -4
- package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +0 -12
- package/test/trees/JBController/setMetadataOf.tree +0 -5
- package/test/trees/JBController/setSplitGroupsOf.tree +0 -5
- package/test/trees/JBController/setTokenFor.tree +0 -5
- package/test/trees/JBController/transferCreditsFrom.tree +0 -8
- package/test/trees/JBDirectory/primaryTerminalOf.tree +0 -8
- package/test/trees/JBDirectory/setControllerOf.tree +0 -11
- package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +0 -15
- package/test/trees/JBDirectory/setTerminalsOf.tree +0 -11
- package/test/trees/JBERC20/initialize.tree +0 -7
- package/test/trees/JBERC20/name.tree +0 -5
- package/test/trees/JBERC20/nonces.tree +0 -5
- package/test/trees/JBERC20/symbol.tree +0 -5
- package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +0 -5
- package/test/trees/JBFeelessAddresses/supportsInterface.tree +0 -5
- package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +0 -5
- package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +0 -8
- package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +0 -18
- package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +0 -5
- package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +0 -8
- package/test/trees/JBMetadataResolver/getDataFor.tree +0 -8
- package/test/trees/JBMultiTerminal/accountingContextsOf.tree +0 -5
- package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +0 -10
- package/test/trees/JBMultiTerminal/addToBalanceOf.tree +0 -23
- package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +0 -23
- package/test/trees/JBMultiTerminal/executePayout.tree +0 -32
- package/test/trees/JBMultiTerminal/executeProcessFee.tree +0 -14
- package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +0 -12
- package/test/trees/JBMultiTerminal/pay.tree +0 -23
- package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +0 -8
- package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +0 -34
- package/test/trees/JBMultiTerminal/useAllowanceOf.tree +0 -16
- package/test/trees/JBPermissions/hasPermission.tree +0 -8
- package/test/trees/JBPermissions/hasPermissions.tree +0 -8
- package/test/trees/JBPermissions/setPermissionsFor.tree +0 -5
- package/test/trees/JBPrices/addPriceFeedFor.tree +0 -14
- package/test/trees/JBPrices/pricePerUnitOf.tree +0 -11
- package/test/trees/JBProjects/createFor.tree +0 -11
- package/test/trees/JBProjects/setTokenUriResolver.tree +0 -5
- package/test/trees/JBProjects/supportsInterface.tree +0 -9
- package/test/trees/JBProjects/tokenURI.tree +0 -5
- package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +0 -8
- package/test/trees/JBRulesets/currentOf.tree +0 -12
- package/test/trees/JBRulesets/getRulesetOf.tree +0 -5
- package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +0 -10
- package/test/trees/JBRulesets/rulesetsOf.tree +0 -11
- package/test/trees/JBRulesets/upcomingRulesetOf.tree +0 -20
- package/test/trees/JBRulesets/updateRulesetWeightCache.tree +0 -5
- package/test/trees/JBSplits/setSplitGroupsOf.tree +0 -17
- package/test/trees/JBSplits/splitsOf.tree +0 -5
- package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +0 -16
- package/test/trees/JBTerminalStore/currentSurplusOf.tree +0 -25
- package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +0 -5
- package/test/trees/JBTerminalStore/recordCashOutsFor.tree +0 -16
- package/test/trees/JBTerminalStore/recordPaymentFrom.tree +0 -14
- package/test/trees/JBTerminalStore/recordPayoutFor.tree +0 -10
- package/test/trees/JBTerminalStore/recordTerminalMigration.tree +0 -5
- package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +0 -10
- package/test/trees/JBTokens/burnFrom.tree +0 -10
- package/test/trees/JBTokens/claimTokensFor.tree +0 -10
- package/test/trees/JBTokens/deployERC20For.tree +0 -12
- package/test/trees/JBTokens/mintFor.tree +0 -10
- package/test/trees/JBTokens/setTokenFor.tree +0 -11
- package/test/trees/JBTokens/totalBalanceOf.tree +0 -5
- package/test/trees/JBTokens/totalSupplyOf.tree +0 -5
- package/test/trees/JBTokens/transferCreditsFrom.tree +0 -8
- package/test/trees/mintTokensOf.tree +0 -12
- package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -223
- package/test/units/static/JBController/JBControllerSetup.sol +0 -50
- package/test/units/static/JBController/TestBurnTokensOf.sol +0 -114
- package/test/units/static/JBController/TestClaimTokensFor.sol +0 -63
- package/test/units/static/JBController/TestDeployErc20For.sol +0 -86
- package/test/units/static/JBController/TestLaunchProjectFor.sol +0 -302
- package/test/units/static/JBController/TestLaunchRulesetsFor.sol +0 -342
- package/test/units/static/JBController/TestMigrateController.sol +0 -157
- package/test/units/static/JBController/TestMintTokensOfUnits.sol +0 -111
- package/test/units/static/JBController/TestOmnichainRulesetOperator.sol +0 -324
- package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +0 -74
- package/test/units/static/JBController/TestPreviewMintOf.sol +0 -117
- package/test/units/static/JBController/TestReceiveMigrationFrom.sol +0 -99
- package/test/units/static/JBController/TestRulesetViews.sol +0 -225
- package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +0 -615
- package/test/units/static/JBController/TestSetSplitGroupsOf.sol +0 -68
- package/test/units/static/JBController/TestSetTokenFor.sol +0 -239
- package/test/units/static/JBController/TestSetUriOf.sol +0 -57
- package/test/units/static/JBController/TestTransferCreditsFrom.sol +0 -169
- package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +0 -211
- package/test/units/static/JBDirectory/JBDirectorySetup.sol +0 -26
- package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +0 -126
- package/test/units/static/JBDirectory/TestSetControllerOf.sol +0 -183
- package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +0 -104
- package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +0 -179
- package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +0 -137
- package/test/units/static/JBERC20/JBERC20Setup.sol +0 -34
- package/test/units/static/JBERC20/SigUtils.sol +0 -36
- package/test/units/static/JBERC20/TestInitialize.sol +0 -60
- package/test/units/static/JBERC20/TestName.sol +0 -30
- package/test/units/static/JBERC20/TestNonces.sol +0 -62
- package/test/units/static/JBERC20/TestSymbol.sol +0 -31
- package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +0 -22
- package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +0 -30
- package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +0 -35
- package/test/units/static/JBFees/TestFeesFuzz.sol +0 -79
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -16
- package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -71
- package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +0 -24
- package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +0 -163
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +0 -59
- package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +0 -101
- package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +0 -189
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +0 -64
- package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +0 -102
- package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +0 -90
- package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +0 -247
- package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +0 -229
- package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +0 -50
- package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +0 -72
- package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +0 -289
- package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +0 -474
- package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +0 -624
- package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +0 -578
- package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +0 -202
- package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +0 -222
- package/test/units/static/JBMultiTerminal/TestPay.sol +0 -604
- package/test/units/static/JBMultiTerminal/TestPreviewCashOutFrom.sol +0 -117
- package/test/units/static/JBMultiTerminal/TestPreviewPayFor.sol +0 -114
- package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -228
- package/test/units/static/JBMultiTerminal/TestSelfPayRevert.sol +0 -55
- package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +0 -257
- package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +0 -611
- package/test/units/static/JBPermissions/JBPermissionsSetup.sol +0 -20
- package/test/units/static/JBPermissions/TestHasPermission.sol +0 -50
- package/test/units/static/JBPermissions/TestHasPermissions.sol +0 -93
- package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +0 -64
- package/test/units/static/JBPrices/JBPricesSetup.sol +0 -32
- package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +0 -107
- package/test/units/static/JBPrices/TestPricePerUnitOf.sol +0 -132
- package/test/units/static/JBPrices/TestPrices.sol +0 -265
- package/test/units/static/JBProjects/JBProjectsSetup.sol +0 -22
- package/test/units/static/JBProjects/TestCreateFor.sol +0 -71
- package/test/units/static/JBProjects/TestInitialProject.sol +0 -21
- package/test/units/static/JBProjects/TestInterfaces.sol +0 -26
- package/test/units/static/JBProjects/TestSetResolver.sol +0 -37
- package/test/units/static/JBProjects/TestTokenUri.sol +0 -40
- package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +0 -108
- package/test/units/static/JBRulesets/JBRulesetsSetup.sol +0 -24
- package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +0 -265
- package/test/units/static/JBRulesets/TestCurrentOf.sol +0 -242
- package/test/units/static/JBRulesets/TestGetRulesetOf.sol +0 -100
- package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +0 -260
- package/test/units/static/JBRulesets/TestRulesets.sol +0 -632
- package/test/units/static/JBRulesets/TestRulesetsOf.sol +0 -37
- package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +0 -522
- package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +0 -96
- package/test/units/static/JBSplits/JBSplitsSetup.sol +0 -26
- package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +0 -552
- package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +0 -377
- package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +0 -267
- package/test/units/static/JBSplits/TestSplitsOf.sol +0 -24
- package/test/units/static/JBSplits/TestSplitsPacking.sol +0 -36
- package/test/units/static/JBSurplus/TestSurplusFuzz.sol +0 -160
- package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +0 -45
- package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +0 -536
- package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +0 -463
- package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +0 -135
- package/test/units/static/JBTerminalStore/TestPreviewCashOutFrom.sol +0 -476
- package/test/units/static/JBTerminalStore/TestPreviewPayFrom.sol +0 -494
- package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +0 -652
- package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +0 -744
- package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +0 -289
- package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +0 -138
- package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +0 -415
- package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +0 -219
- package/test/units/static/JBTokens/JBTokensSetup.sol +0 -32
- package/test/units/static/JBTokens/TestBurnFrom.sol +0 -107
- package/test/units/static/JBTokens/TestClaimTokensFor.sol +0 -110
- package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +0 -92
- package/test/units/static/JBTokens/TestMintFor.sol +0 -100
- package/test/units/static/JBTokens/TestSetTokenFor.sol +0 -98
- package/test/units/static/JBTokens/TestTotalBalanceOf.sol +0 -65
- package/test/units/static/JBTokens/TestTotalSupplyOf.sol +0 -56
- package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +0 -56
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {JBPrices} from "../../../../src/JBPrices.sol";
|
|
5
|
-
import {IJBDirectory} from "../../../../src/interfaces/IJBDirectory.sol";
|
|
6
|
-
import {JBConstants} from "../../../../src/libraries/JBConstants.sol";
|
|
7
|
-
import {mulDiv} from "@prb/math/src/Common.sol";
|
|
8
|
-
import {JBPricesSetup} from "./JBPricesSetup.sol";
|
|
9
|
-
import {MockPriceFeed} from "../../../mock/MockPriceFeed.sol";
|
|
10
|
-
|
|
11
|
-
/// @notice Edge case & bug-hunting tests for JBPrices.
|
|
12
|
-
/// Covers inverse precision, feed immutability, default fallback, and the overly-restrictive
|
|
13
|
-
/// default-blocks-project-specific issue.
|
|
14
|
-
contract TestPrices_Local is JBPricesSetup {
|
|
15
|
-
uint256 constant DEFAULT_PROJECT_ID = 0;
|
|
16
|
-
uint256 constant PROJECT_ID = 1;
|
|
17
|
-
uint256 _pricingCurrency = uint32(uint160(JBConstants.NATIVE_TOKEN));
|
|
18
|
-
uint256 _unitCurrency = uint32(uint160(makeAddr("unitToken")));
|
|
19
|
-
|
|
20
|
-
function setUp() public {
|
|
21
|
-
super.pricesSetup();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// ───────────────────── Helpers
|
|
25
|
-
// ─────────────────────
|
|
26
|
-
|
|
27
|
-
/// @dev Sets a mock price feed directly into storage for a given project.
|
|
28
|
-
function _storeFeed(uint256 projectId, uint256 pricing, uint256 unit_, address feed) internal {
|
|
29
|
-
bytes32 slot0 = keccak256(abi.encode(projectId, uint256(1)));
|
|
30
|
-
bytes32 slot1 = keccak256(abi.encode(pricing, uint256(slot0)));
|
|
31
|
-
bytes32 slot2 = keccak256(abi.encode(unit_, uint256(slot1)));
|
|
32
|
-
vm.store(address(_prices), slot2, bytes32(uint256(uint160(feed))));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ───────────────────── Inverse precision tests
|
|
36
|
-
// ─────────────────────
|
|
37
|
-
|
|
38
|
-
/// @notice Feed returns 1 (minimum non-zero price). Inverse should be 10^(2*decimals).
|
|
39
|
-
function test_inversePrecision_smallPrice() external {
|
|
40
|
-
uint256 decimals = 18;
|
|
41
|
-
MockPriceFeed feed = new MockPriceFeed(1, decimals);
|
|
42
|
-
_storeFeed(PROJECT_ID, _unitCurrency, _pricingCurrency, address(feed));
|
|
43
|
-
|
|
44
|
-
// Query the inverse direction: pricing → unit requires inverting the unit→pricing feed.
|
|
45
|
-
uint256 inverse = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _unitCurrency, decimals);
|
|
46
|
-
// inverse = 10^18 * 10^18 / 1 = 10^36, but mulDiv(10^18, 10^18, 1) = 10^36
|
|
47
|
-
// Wait: the formula is mulDiv(10^decimals, 10^decimals, feedPrice) = mulDiv(10^18, 10^18, 1)
|
|
48
|
-
assertEq(inverse, 10 ** (2 * decimals), "Inverse of price=1 should be 10^(2*decimals)");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/// @notice Feed returns near-max value. Inverse should not underflow to 0.
|
|
52
|
-
function test_inversePrecision_largePrice() external {
|
|
53
|
-
uint256 decimals = 18;
|
|
54
|
-
// Price is 10^36 (very large).
|
|
55
|
-
// Inverse = mulDiv(10^18, 10^18, 10^36) = 10^36 / 10^36 = 1
|
|
56
|
-
MockPriceFeed feed = new MockPriceFeed(10 ** 36, 18);
|
|
57
|
-
_storeFeed(PROJECT_ID, _unitCurrency, _pricingCurrency, address(feed));
|
|
58
|
-
|
|
59
|
-
uint256 inverse = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _unitCurrency, decimals);
|
|
60
|
-
assertEq(inverse, 1, "Inverse of very large price should be 1 (floor)");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/// @notice Fuzz: price(A->B) * price(B->A) should approximate 10^(2*decimals).
|
|
64
|
-
/// Bounded to realistic price range where precision is expected to hold.
|
|
65
|
-
function testFuzz_inversePrecision_roundTrip(uint256 price) external {
|
|
66
|
-
uint256 decimals = 18;
|
|
67
|
-
// Bound price to [10^9, 10^27] — realistic range where inverse precision is reasonable.
|
|
68
|
-
// Outside this range, integer division precision loss is severe (see test below).
|
|
69
|
-
price = bound(price, 10 ** 9, 10 ** 27);
|
|
70
|
-
|
|
71
|
-
MockPriceFeed feed = new MockPriceFeed(price, decimals);
|
|
72
|
-
|
|
73
|
-
// Store feed as direct A->B feed.
|
|
74
|
-
_storeFeed(PROJECT_ID, _pricingCurrency, _unitCurrency, address(feed));
|
|
75
|
-
|
|
76
|
-
// Get direct price.
|
|
77
|
-
uint256 direct = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _unitCurrency, decimals);
|
|
78
|
-
assertEq(direct, price, "Direct price should match feed");
|
|
79
|
-
|
|
80
|
-
// Get inverse price (B->A).
|
|
81
|
-
uint256 inverse = _prices.pricePerUnitOf(PROJECT_ID, _unitCurrency, _pricingCurrency, decimals);
|
|
82
|
-
|
|
83
|
-
// Round-trip: direct * inverse should approximate 10^decimals.
|
|
84
|
-
uint256 product = mulDiv(direct, inverse, 10 ** decimals);
|
|
85
|
-
assertApproxEqRel(product, 10 ** decimals, 0.01e18, "Round-trip should approximate 10^decimals");
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/// @notice PRECISION BUG: At extreme prices (>10^27), inverse precision degrades severely.
|
|
89
|
-
/// For non-power-of-10 prices, round-trip error can exceed 10%.
|
|
90
|
-
function test_inversePrecision_degradesAtExtremes() external {
|
|
91
|
-
uint256 decimals = 18;
|
|
92
|
-
// Price of 3*10^35 — inverse = mulDiv(10^18, 10^18, 3*10^35) = floor(3.33) = 3
|
|
93
|
-
MockPriceFeed feed = new MockPriceFeed(3 * 10 ** 35, decimals);
|
|
94
|
-
_storeFeed(PROJECT_ID, _unitCurrency, _pricingCurrency, address(feed));
|
|
95
|
-
|
|
96
|
-
uint256 inverse = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _unitCurrency, decimals);
|
|
97
|
-
// Inverse only has 1 significant digit — massive precision loss.
|
|
98
|
-
assertEq(inverse, 3, "Extreme price inverse has only 1 digit of precision");
|
|
99
|
-
|
|
100
|
-
// Round-trip: 3*10^35 * 3 / 10^18 = 9*10^17 (should be 10^18). 10% error.
|
|
101
|
-
uint256 product = mulDiv(3 * 10 ** 35, inverse, 10 ** decimals);
|
|
102
|
-
assertEq(product, 9 * 10 ** 17, "Round-trip at extreme prices loses 10% precision");
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/// @notice inverse(inverse(price)) should approximately equal price (precision loss compounds).
|
|
106
|
-
function test_inversePrecision_asymmetry() external {
|
|
107
|
-
uint256 decimals = 18;
|
|
108
|
-
uint256 originalPrice = 3333 * 10 ** 14; // 0.3333 ETH (a price that doesn't divide evenly)
|
|
109
|
-
|
|
110
|
-
// Store A->B feed.
|
|
111
|
-
MockPriceFeed feed = new MockPriceFeed(originalPrice, decimals);
|
|
112
|
-
_storeFeed(PROJECT_ID, _pricingCurrency, _unitCurrency, address(feed));
|
|
113
|
-
|
|
114
|
-
// Get inverse (B->A).
|
|
115
|
-
uint256 inversePrice = _prices.pricePerUnitOf(PROJECT_ID, _unitCurrency, _pricingCurrency, decimals);
|
|
116
|
-
|
|
117
|
-
// Now set a NEW feed for B->A with the inverse price, and query A->B back via inversion.
|
|
118
|
-
// We need a different project to avoid the "already exists" check.
|
|
119
|
-
uint256 project2 = 2;
|
|
120
|
-
MockPriceFeed feed2 = new MockPriceFeed(inversePrice, decimals);
|
|
121
|
-
_storeFeed(project2, _unitCurrency, _pricingCurrency, address(feed2));
|
|
122
|
-
|
|
123
|
-
uint256 doubleInverse = _prices.pricePerUnitOf(project2, _pricingCurrency, _unitCurrency, decimals);
|
|
124
|
-
|
|
125
|
-
// Double-inverse should be approximately equal to original, but may lose precision.
|
|
126
|
-
// This documents the precision loss from compounding inversions.
|
|
127
|
-
assertApproxEqRel(doubleInverse, originalPrice, 0.01e18, "Double inverse should approximate original within 1%");
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// ───────────────────── Feed immutability tests
|
|
131
|
-
// ─────────────────────
|
|
132
|
-
|
|
133
|
-
/// @notice Adding a feed for an existing pair should revert.
|
|
134
|
-
function test_feedImmutability_cannotReplace() external {
|
|
135
|
-
MockPriceFeed feed1 = new MockPriceFeed(1000e18, 18);
|
|
136
|
-
MockPriceFeed feed2 = new MockPriceFeed(2000e18, 18);
|
|
137
|
-
|
|
138
|
-
// Mock controller for project.
|
|
139
|
-
vm.mockCall(
|
|
140
|
-
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (PROJECT_ID)), abi.encode(address(this))
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
_prices.addPriceFeedFor(PROJECT_ID, _pricingCurrency, _unitCurrency, feed1);
|
|
144
|
-
|
|
145
|
-
// Second add for same pair should revert.
|
|
146
|
-
vm.expectRevert(abi.encodeWithSelector(JBPrices.JBPrices_PriceFeedAlreadyExists.selector, feed1));
|
|
147
|
-
_prices.addPriceFeedFor(PROJECT_ID, _pricingCurrency, _unitCurrency, feed2);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/// @notice Adding A->B should block adding B->A for the same project.
|
|
151
|
-
function test_feedImmutability_inverseBlocksToo() external {
|
|
152
|
-
MockPriceFeed feed1 = new MockPriceFeed(1000e18, 18);
|
|
153
|
-
MockPriceFeed feed2 = new MockPriceFeed(2000e18, 18);
|
|
154
|
-
|
|
155
|
-
vm.mockCall(
|
|
156
|
-
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (PROJECT_ID)), abi.encode(address(this))
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
_prices.addPriceFeedFor(PROJECT_ID, _pricingCurrency, _unitCurrency, feed1);
|
|
160
|
-
|
|
161
|
-
// Adding inverse pair should revert.
|
|
162
|
-
vm.expectRevert(abi.encodeWithSelector(JBPrices.JBPrices_PriceFeedAlreadyExists.selector, feed1));
|
|
163
|
-
_prices.addPriceFeedFor(PROJECT_ID, _unitCurrency, _pricingCurrency, feed2);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// ───────────────────── Default fallback tests
|
|
167
|
-
// ─────────────────────
|
|
168
|
-
|
|
169
|
-
/// @notice Project-specific feed takes priority over default.
|
|
170
|
-
function test_defaultFallback_projectFeedTakesPriority() external {
|
|
171
|
-
MockPriceFeed defaultFeed = new MockPriceFeed(1000e18, 18);
|
|
172
|
-
MockPriceFeed projectFeed = new MockPriceFeed(2000e18, 18);
|
|
173
|
-
|
|
174
|
-
// Store default feed.
|
|
175
|
-
_storeFeed(DEFAULT_PROJECT_ID, _pricingCurrency, _unitCurrency, address(defaultFeed));
|
|
176
|
-
// Store project feed.
|
|
177
|
-
_storeFeed(PROJECT_ID, _pricingCurrency, _unitCurrency, address(projectFeed));
|
|
178
|
-
|
|
179
|
-
uint256 price = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _unitCurrency, 18);
|
|
180
|
-
assertEq(price, 2000e18, "Project feed should take priority over default");
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/// @notice Default inverse feed used when no project-specific direct or inverse feed exists.
|
|
184
|
-
function test_defaultFallback_inverseOfDefault() external {
|
|
185
|
-
uint256 decimals = 18;
|
|
186
|
-
// Only store default feed in the inverse direction: unit->pricing.
|
|
187
|
-
MockPriceFeed defaultFeed = new MockPriceFeed(2e18, decimals);
|
|
188
|
-
_storeFeed(DEFAULT_PROJECT_ID, _unitCurrency, _pricingCurrency, address(defaultFeed));
|
|
189
|
-
|
|
190
|
-
// Query pricing->unit on a project with no feeds — should fall back to default inverse.
|
|
191
|
-
uint256 price = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _unitCurrency, decimals);
|
|
192
|
-
|
|
193
|
-
// Expected: mulDiv(10^18, 10^18, 2*10^18) = 5*10^17
|
|
194
|
-
assertEq(price, 5e17, "Should use inverse of default feed");
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// ───────────────────── Same currency
|
|
198
|
-
// ─────────────────────
|
|
199
|
-
|
|
200
|
-
/// @notice pricePerUnitOf(X, X, decimals) == 10^decimals.
|
|
201
|
-
function test_sameCurrency_returns1() external view {
|
|
202
|
-
uint256 price18 = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _pricingCurrency, 18);
|
|
203
|
-
assertEq(price18, 1e18, "Same currency at 18 decimals should return 1e18");
|
|
204
|
-
|
|
205
|
-
uint256 price6 = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _pricingCurrency, 6);
|
|
206
|
-
assertEq(price6, 1e6, "Same currency at 6 decimals should return 1e6");
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// ───────────────────── Zero currency reverts
|
|
210
|
-
// ─────────────────────
|
|
211
|
-
|
|
212
|
-
/// @notice Both zero pricing and zero unit currency should revert on addPriceFeedFor.
|
|
213
|
-
function test_zeroCurrency_reverts() external {
|
|
214
|
-
MockPriceFeed feed = new MockPriceFeed(1000e18, 18);
|
|
215
|
-
|
|
216
|
-
vm.prank(_owner);
|
|
217
|
-
vm.expectRevert(JBPrices.JBPrices_ZeroPricingCurrency.selector);
|
|
218
|
-
_prices.addPriceFeedFor(DEFAULT_PROJECT_ID, 0, _unitCurrency, feed);
|
|
219
|
-
|
|
220
|
-
vm.prank(_owner);
|
|
221
|
-
vm.expectRevert(JBPrices.JBPrices_ZeroUnitCurrency.selector);
|
|
222
|
-
_prices.addPriceFeedFor(DEFAULT_PROJECT_ID, _pricingCurrency, 0, feed);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// ───────────────────── BUG HYPOTHESIS: default blocks project-specific
|
|
226
|
-
// ─────────────────────
|
|
227
|
-
|
|
228
|
-
/// @notice BUG: Adding a default A->B feed blocks ANY project from adding their own A->B feed.
|
|
229
|
-
/// This is overly restrictive — projects cannot use a different oracle for the same pair.
|
|
230
|
-
/// The check at JBPrices.sol:188-197 checks default feeds BEFORE project feeds.
|
|
231
|
-
function test_addFeedFor_defaultBlocksProjectSpecific() external {
|
|
232
|
-
MockPriceFeed defaultFeed = new MockPriceFeed(1000e18, 18);
|
|
233
|
-
MockPriceFeed projectFeed = new MockPriceFeed(2000e18, 18);
|
|
234
|
-
|
|
235
|
-
// Add default feed.
|
|
236
|
-
vm.prank(_owner);
|
|
237
|
-
_prices.addPriceFeedFor(DEFAULT_PROJECT_ID, _pricingCurrency, _unitCurrency, defaultFeed);
|
|
238
|
-
|
|
239
|
-
// Now try to add a project-specific feed for the SAME pair.
|
|
240
|
-
vm.mockCall(
|
|
241
|
-
address(directory), abi.encodeCall(IJBDirectory.controllerOf, (PROJECT_ID)), abi.encode(address(this))
|
|
242
|
-
);
|
|
243
|
-
|
|
244
|
-
// This reverts because default feed blocks project-specific feeds.
|
|
245
|
-
vm.expectRevert(abi.encodeWithSelector(JBPrices.JBPrices_PriceFeedAlreadyExists.selector, defaultFeed));
|
|
246
|
-
_prices.addPriceFeedFor(PROJECT_ID, _pricingCurrency, _unitCurrency, projectFeed);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// ───────────────────── Fuzz: valid feeds never overflow
|
|
250
|
-
// ─────────────────────
|
|
251
|
-
|
|
252
|
-
/// @notice Fuzz: pricePerUnitOf should never revert for valid feed values.
|
|
253
|
-
function testFuzz_pricePerUnitOf_neverReverts_forValidFeed(uint256 price, uint8 decimals) external {
|
|
254
|
-
// Bound inputs to reasonable ranges.
|
|
255
|
-
decimals = uint8(bound(decimals, 1, 18));
|
|
256
|
-
price = bound(price, 1, type(uint128).max);
|
|
257
|
-
|
|
258
|
-
MockPriceFeed feed = new MockPriceFeed(price, decimals);
|
|
259
|
-
_storeFeed(PROJECT_ID, _pricingCurrency, _unitCurrency, address(feed));
|
|
260
|
-
|
|
261
|
-
// Should not revert.
|
|
262
|
-
uint256 result = _prices.pricePerUnitOf(PROJECT_ID, _pricingCurrency, _unitCurrency, decimals);
|
|
263
|
-
assertGt(result, 0, "Price should be non-zero for valid feed");
|
|
264
|
-
}
|
|
265
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {JBProjects} from "../../../../src/JBProjects.sol";
|
|
5
|
-
import {IJBProjects} from "../../../../src/interfaces/IJBProjects.sol";
|
|
6
|
-
import {JBTest} from "../../../helpers/JBTest.sol";
|
|
7
|
-
|
|
8
|
-
/*
|
|
9
|
-
Contract that deploys a target contract with other mock contracts to satisfy the constructor.
|
|
10
|
-
Tests relative to this contract will be dependent on mock calls/emits and stdStorage.
|
|
11
|
-
*/
|
|
12
|
-
contract JBProjectsSetup is JBTest {
|
|
13
|
-
address _owner = makeAddr("owner");
|
|
14
|
-
|
|
15
|
-
// Target Contract
|
|
16
|
-
IJBProjects public _projects;
|
|
17
|
-
|
|
18
|
-
function projectsSetup() public virtual {
|
|
19
|
-
// Instantiate the contract being tested
|
|
20
|
-
_projects = new JBProjects(_owner, address(0), address(0));
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {StdStorage, stdStorage} from "forge-std/StdStorage.sol";
|
|
5
|
-
import {stdError} from "forge-std/StdError.sol";
|
|
6
|
-
import {IJBProjects} from "../../../../src/interfaces/IJBProjects.sol";
|
|
7
|
-
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
|
|
8
|
-
import {JBProjectsSetup} from "./JBProjectsSetup.sol";
|
|
9
|
-
|
|
10
|
-
contract TestCreateFor_Local is JBProjectsSetup {
|
|
11
|
-
using stdStorage for StdStorage;
|
|
12
|
-
|
|
13
|
-
address _user = makeAddr("sudoer");
|
|
14
|
-
|
|
15
|
-
function setUp() public {
|
|
16
|
-
super.projectsSetup();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function test_WhenProjectIdPlusOneIsGtUint256Max() external {
|
|
20
|
-
// it will revert with overflow
|
|
21
|
-
|
|
22
|
-
// set storage to uint256 max
|
|
23
|
-
stdstore.target(address(_projects)).sig("count()").checked_write(type(uint256).max);
|
|
24
|
-
|
|
25
|
-
assertEq(_projects.count(), type(uint256).max);
|
|
26
|
-
|
|
27
|
-
vm.expectRevert(stdError.arithmeticError);
|
|
28
|
-
_projects.createFor(address(this));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
modifier whenProjectIdPlusOneIsLtOrEqToUint256Max() {
|
|
32
|
-
_;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function test_GivenOwnerIsNotAContract() external whenProjectIdPlusOneIsLtOrEqToUint256Max {
|
|
36
|
-
// it will mint and emit Create
|
|
37
|
-
|
|
38
|
-
// created on behalf of user by this contract
|
|
39
|
-
vm.expectEmit();
|
|
40
|
-
emit IJBProjects.Create(1, _user, address(this));
|
|
41
|
-
|
|
42
|
-
_projects.createFor(_user);
|
|
43
|
-
|
|
44
|
-
// check count is incrementing
|
|
45
|
-
assertEq(_projects.count(), 1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function test_GivenItIsIERC721Receiver() external whenProjectIdPlusOneIsLtOrEqToUint256Max {
|
|
49
|
-
// it will mint and emit Create
|
|
50
|
-
|
|
51
|
-
// mock IERC721Receiver support (return interface selector for onERC721Received)
|
|
52
|
-
bytes memory receiverCall =
|
|
53
|
-
abi.encodeCall(IERC721Receiver.onERC721Received, (address(this), address(0), 1, bytes("")));
|
|
54
|
-
bytes memory returned = abi.encode(IERC721Receiver.onERC721Received.selector);
|
|
55
|
-
|
|
56
|
-
mockExpect(address(this), receiverCall, returned);
|
|
57
|
-
|
|
58
|
-
_projects.createFor(address(this));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function test_GivenItDoesNotSupportIERC721Receiver() external whenProjectIdPlusOneIsLtOrEqToUint256Max {
|
|
62
|
-
// it will revert
|
|
63
|
-
|
|
64
|
-
// encode custom error
|
|
65
|
-
bytes4 selector = bytes4(keccak256("ERC721InvalidReceiver(address)"));
|
|
66
|
-
bytes memory expectedError = abi.encodeWithSelector(selector, address(this));
|
|
67
|
-
|
|
68
|
-
vm.expectRevert(expectedError);
|
|
69
|
-
_projects.createFor(address(this));
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {JBProjects} from "../../../../src/JBProjects.sol";
|
|
5
|
-
import {IJBProjects} from "../../../../src/interfaces/IJBProjects.sol";
|
|
6
|
-
import {JBTest} from "../../../helpers/JBTest.sol";
|
|
7
|
-
|
|
8
|
-
contract TestInitialProject_Local is JBTest {
|
|
9
|
-
address _owner = makeAddr("owner");
|
|
10
|
-
IJBProjects _projects;
|
|
11
|
-
|
|
12
|
-
function setUp() public {}
|
|
13
|
-
|
|
14
|
-
function test_WhenInitialOwnerDNEQZeroAddress() external {
|
|
15
|
-
// It will create a project
|
|
16
|
-
|
|
17
|
-
vm.expectEmit();
|
|
18
|
-
emit IJBProjects.Create(1, _owner, address(this));
|
|
19
|
-
_projects = new JBProjects(_owner, _owner, address(0));
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {JBProjectsSetup} from "./JBProjectsSetup.sol";
|
|
5
|
-
|
|
6
|
-
contract TestSupportsInterface_Local is JBProjectsSetup {
|
|
7
|
-
function setUp() public {
|
|
8
|
-
super.projectsSetup();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function test_WhenInterfaceIdIsIJBProjects() external {
|
|
12
|
-
// it will return true
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function test_WhenInterfaceIdIsIERC721() external {
|
|
16
|
-
// it will return true
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function test_WhenInterfaceIdIsIERC721Metadata() external {
|
|
20
|
-
// it will return true
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function test_WhenInterfaceIdIsAnythingElse() external {
|
|
24
|
-
// it will return false
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {IJBProjects} from "../../../../src/interfaces/IJBProjects.sol";
|
|
5
|
-
import {IJBTokenUriResolver} from "../../../../src/interfaces/IJBTokenUriResolver.sol";
|
|
6
|
-
import {JBProjectsSetup} from "./JBProjectsSetup.sol";
|
|
7
|
-
|
|
8
|
-
contract TestSetTokenURIResolver_Local is JBProjectsSetup {
|
|
9
|
-
IJBTokenUriResolver _resolver = IJBTokenUriResolver(makeAddr("uri"));
|
|
10
|
-
|
|
11
|
-
function setUp() public {
|
|
12
|
-
super.projectsSetup();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function test_WhenCallerIsOwner() external {
|
|
16
|
-
// it will set resolver and emit SetTokenUriResolver
|
|
17
|
-
|
|
18
|
-
// expect call from owner since we prank
|
|
19
|
-
vm.expectEmit();
|
|
20
|
-
emit IJBProjects.SetTokenUriResolver(_resolver, _owner);
|
|
21
|
-
|
|
22
|
-
vm.prank(_owner);
|
|
23
|
-
_projects.setTokenUriResolver(_resolver);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function test_WhenCallerIsNotOwner() external {
|
|
27
|
-
// it will revert
|
|
28
|
-
|
|
29
|
-
// encode custom error
|
|
30
|
-
bytes4 selector = bytes4(keccak256("OwnableUnauthorizedAccount(address)"));
|
|
31
|
-
bytes memory expectedError = abi.encodeWithSelector(selector, address(this));
|
|
32
|
-
|
|
33
|
-
vm.expectRevert(expectedError);
|
|
34
|
-
|
|
35
|
-
_projects.setTokenUriResolver(_resolver);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {StdStorage, stdStorage} from "forge-std/StdStorage.sol";
|
|
5
|
-
import {IJBTokenUriResolver} from "../../../../src/interfaces/IJBTokenUriResolver.sol";
|
|
6
|
-
import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
|
|
7
|
-
import {JBProjectsSetup} from "./JBProjectsSetup.sol";
|
|
8
|
-
|
|
9
|
-
contract TestTokenURI_Local is JBProjectsSetup {
|
|
10
|
-
using stdStorage for StdStorage;
|
|
11
|
-
|
|
12
|
-
IJBTokenUriResolver _resolver = IJBTokenUriResolver(makeAddr("uri"));
|
|
13
|
-
|
|
14
|
-
function setUp() public {
|
|
15
|
-
super.projectsSetup();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function test_WhenTheresNoResolver() external view {
|
|
19
|
-
// it will return empty string
|
|
20
|
-
string memory uri = IERC721Metadata(address(_projects)).tokenURI(0);
|
|
21
|
-
|
|
22
|
-
assertEq(bytes(uri), "");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function test_WhenTheresAResolver() external {
|
|
26
|
-
// it will return the resolved URI
|
|
27
|
-
|
|
28
|
-
// set tokenUriResolver
|
|
29
|
-
stdstore.target(address(_projects)).sig("tokenUriResolver()").checked_write(address(_resolver));
|
|
30
|
-
|
|
31
|
-
// mock call to mock resolver
|
|
32
|
-
bytes memory resolverCall = abi.encodeCall(IJBTokenUriResolver.getUri, (0));
|
|
33
|
-
bytes memory returned = abi.encode("JUICAY");
|
|
34
|
-
|
|
35
|
-
mockExpect(address(_resolver), resolverCall, returned);
|
|
36
|
-
|
|
37
|
-
string memory uri = IERC721Metadata(address(_projects)).tokenURI(0);
|
|
38
|
-
assertEq(bytes(uri), bytes("JUICAY"));
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {JBConstants} from "../../../../src/libraries/JBConstants.sol";
|
|
5
|
-
import {JBRulesetMetadataResolver} from "../../../../src/libraries/JBRulesetMetadataResolver.sol";
|
|
6
|
-
import {JBRuleset} from "../../../../src/structs/JBRuleset.sol";
|
|
7
|
-
import {JBRulesetMetadata} from "../../../../src/structs/JBRulesetMetadata.sol";
|
|
8
|
-
import {JBTest} from "../../../helpers/JBTest.sol";
|
|
9
|
-
|
|
10
|
-
contract TestSetCashOutTaxRateTo_Local is JBTest {
|
|
11
|
-
using JBRulesetMetadataResolver for JBRulesetMetadata;
|
|
12
|
-
|
|
13
|
-
function setUp() external {}
|
|
14
|
-
|
|
15
|
-
function testFuzzEnsureCorrectlyPackedBits(
|
|
16
|
-
uint16 _fuzzReservedPercent,
|
|
17
|
-
uint16 _fuzzCashOutTaxRate,
|
|
18
|
-
uint16 _fuzzMetadata
|
|
19
|
-
)
|
|
20
|
-
external
|
|
21
|
-
{
|
|
22
|
-
// cash out tax rate should be re-set and re-packed correctly
|
|
23
|
-
|
|
24
|
-
address _hookAddress = makeAddr("someting");
|
|
25
|
-
|
|
26
|
-
_fuzzReservedPercent = uint16(bound(_fuzzReservedPercent, 0, JBConstants.MAX_RESERVED_PERCENT));
|
|
27
|
-
_fuzzCashOutTaxRate = uint16(bound(_fuzzCashOutTaxRate, 0, JBConstants.MAX_CASH_OUT_TAX_RATE));
|
|
28
|
-
// Ensure the metadata is a max of 14 bits.
|
|
29
|
-
_fuzzMetadata = uint16(bound(_fuzzCashOutTaxRate, 0, 16_383));
|
|
30
|
-
|
|
31
|
-
JBRulesetMetadata memory _rulesMetadata = JBRulesetMetadata({
|
|
32
|
-
reservedPercent: _fuzzReservedPercent,
|
|
33
|
-
cashOutTaxRate: _fuzzCashOutTaxRate,
|
|
34
|
-
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
35
|
-
pausePay: true,
|
|
36
|
-
pauseCreditTransfers: true,
|
|
37
|
-
allowOwnerMinting: true,
|
|
38
|
-
allowSetCustomToken: true,
|
|
39
|
-
allowTerminalMigration: true,
|
|
40
|
-
allowSetTerminals: true,
|
|
41
|
-
ownerMustSendPayouts: true,
|
|
42
|
-
allowSetController: true,
|
|
43
|
-
allowAddAccountingContext: true,
|
|
44
|
-
allowAddPriceFeed: true,
|
|
45
|
-
holdFees: true,
|
|
46
|
-
useTotalSurplusForCashOuts: true,
|
|
47
|
-
useDataHookForPay: true,
|
|
48
|
-
useDataHookForCashOut: true,
|
|
49
|
-
dataHook: _hookAddress,
|
|
50
|
-
metadata: _fuzzMetadata
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
uint256 _packed = _rulesMetadata.packRulesetMetadata();
|
|
54
|
-
|
|
55
|
-
// Reserved Rate
|
|
56
|
-
// forge-lint: disable-next-line(unsafe-typecast)
|
|
57
|
-
uint256 _reservedPercent = uint256(uint16(_packed >> 4));
|
|
58
|
-
|
|
59
|
-
// Cash out tax rate
|
|
60
|
-
// forge-lint: disable-next-line(unsafe-typecast)
|
|
61
|
-
uint256 _cashOutTaxRate = uint256(uint16(_packed >> 20));
|
|
62
|
-
|
|
63
|
-
assertEq(_reservedPercent, _fuzzReservedPercent);
|
|
64
|
-
assertEq(_cashOutTaxRate, _fuzzCashOutTaxRate);
|
|
65
|
-
|
|
66
|
-
for (uint256 _i = 68; _i < 81; _i++) {
|
|
67
|
-
// forge-lint: disable-next-line(unsafe-typecast)
|
|
68
|
-
uint256 _flag = uint256(uint16(_packed >> _i) & 1);
|
|
69
|
-
assertEq(_flag, 1);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Data source address
|
|
73
|
-
// forge-lint: disable-next-line(unsafe-typecast)
|
|
74
|
-
address _packedDataHook = address(uint160(_packed >> 82));
|
|
75
|
-
assertEq(_packedDataHook, _hookAddress);
|
|
76
|
-
|
|
77
|
-
// Metadata
|
|
78
|
-
// forge-lint: disable-next-line(unsafe-typecast)
|
|
79
|
-
uint256 _packedMetadata = uint256(uint16(_packed >> 242));
|
|
80
|
-
assertEq(_packedMetadata, uint256(_fuzzMetadata));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function testFuzzEnsureCorrectlyPackedBits_implementationIndependent(JBRulesetMetadata memory _rulesMetadata)
|
|
84
|
-
external
|
|
85
|
-
pure
|
|
86
|
-
{
|
|
87
|
-
// Handle the unique constraints of the JBRulesetMetadata.
|
|
88
|
-
{
|
|
89
|
-
// First 2 bits of `metadata.metadata` are ignored
|
|
90
|
-
_rulesMetadata.metadata = _rulesMetadata.metadata % 16_383;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Get the keccak from before.
|
|
94
|
-
bytes32 _before = keccak256(abi.encode(_rulesMetadata));
|
|
95
|
-
|
|
96
|
-
// Pack the metadata.
|
|
97
|
-
uint256 _packed = _rulesMetadata.packRulesetMetadata();
|
|
98
|
-
|
|
99
|
-
// Unpack the metadata and calculate the new keccak.
|
|
100
|
-
JBRuleset memory _ruleset;
|
|
101
|
-
_ruleset.metadata = _packed;
|
|
102
|
-
JBRulesetMetadata memory _unpackedMetadata = JBRulesetMetadataResolver.expandMetadata(_ruleset);
|
|
103
|
-
bytes32 _after = keccak256(abi.encode(_unpackedMetadata));
|
|
104
|
-
|
|
105
|
-
// Compare the before and the after.
|
|
106
|
-
assertEq(_before, _after);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {JBRulesets} from "../../../../src/JBRulesets.sol";
|
|
5
|
-
import {IJBDirectory} from "../../../../src/interfaces/IJBDirectory.sol";
|
|
6
|
-
import {IJBRulesets} from "../../../../src/interfaces/IJBRulesets.sol";
|
|
7
|
-
import {JBTest} from "../../../helpers/JBTest.sol";
|
|
8
|
-
|
|
9
|
-
/*
|
|
10
|
-
Contract that deploys a target contract with other mock contracts to satisfy the constructor.
|
|
11
|
-
Tests relative to this contract will be dependent on mock calls/emits and stdStorage.
|
|
12
|
-
*/
|
|
13
|
-
contract JBRulesetsSetup is JBTest {
|
|
14
|
-
// Target Contract
|
|
15
|
-
IJBRulesets public _rulesets;
|
|
16
|
-
|
|
17
|
-
// Mocks
|
|
18
|
-
IJBDirectory public directory = IJBDirectory(makeAddr("directory"));
|
|
19
|
-
|
|
20
|
-
function rulesetsSetup() public virtual {
|
|
21
|
-
// Instantiate the contract being tested
|
|
22
|
-
_rulesets = new JBRulesets(directory);
|
|
23
|
-
}
|
|
24
|
-
}
|