diff --git a/.github/workflows/coverage-check.yml b/.github/workflows/coverage-check.yml index 43efe2ba4..a6b0510e2 100644 --- a/.github/workflows/coverage-check.yml +++ b/.github/workflows/coverage-check.yml @@ -21,7 +21,7 @@ jobs: ref: development - name: Setup Foundry - uses: onbjerg/foundry-toolchain@v1 + uses: foundry-rs/foundry-toolchain@v1 with: version: nightly-5be158ba6dc7c798a6f032026fe60fc01686b33b @@ -70,6 +70,10 @@ jobs: - name: Checkout code in PR branch uses: actions/checkout@v3 + - name: Update Forge Dependencies + working-directory: packages/contracts + run: forge update lib/forge-std + - name: Get PR branch coverage id: coverage-pr run: | diff --git a/.gitmodules b/.gitmodules index 8eda756c8..b0c49efb7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,7 +17,7 @@ [submodule "packages/contracts/lib/forge-std"] path = packages/contracts/lib/forge-std url = https://github.com/foundry-rs/forge-std - branch = chore/v1.5.6 + branch = chore/reorder-vm # v1.6.1 [submodule "packages/contracts/lib/abdk-libraries-solidity"] path = packages/contracts/lib/abdk-libraries-solidity url = https://github.com/abdk-consulting/abdk-libraries-solidity diff --git a/cspell.json b/cspell.json index 3183e89ff..719935d43 100644 --- a/cspell.json +++ b/cspell.json @@ -46,6 +46,7 @@ "coef", "collateralized", "commitlint", + "concat", "connectkit", "Consts", "Cpath", diff --git a/packages/contracts/lib/forge-std b/packages/contracts/lib/forge-std index c8227be36..805aa1f43 160000 --- a/packages/contracts/lib/forge-std +++ b/packages/contracts/lib/forge-std @@ -1 +1 @@ -Subproject commit c8227be36b1fe518e4140af4012c55553237f181 +Subproject commit 805aa1f4385905aa25ff9221bd23b67b5da9af0b diff --git a/packages/contracts/scripts/deploy/dollar/solidityScripting/00_Constants.s.sol b/packages/contracts/scripts/deploy/dollar/solidityScripting/00_Constants.s.sol index 3fbcc3702..5788fa61e 100644 --- a/packages/contracts/scripts/deploy/dollar/solidityScripting/00_Constants.s.sol +++ b/packages/contracts/scripts/deploy/dollar/solidityScripting/00_Constants.s.sol @@ -2,9 +2,10 @@ pragma solidity 0.8.19; import "../../../../src/dollar/libraries/Constants.sol"; +import {DiamondTestHelper} from "../../../../test/helpers/DiamondTestHelper.sol"; import "forge-std/Script.sol"; -contract Constants is Script { +contract Constants is DiamondTestHelper, Script { address constant curve3PoolToken = 0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490; address constant basePool = 0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7; diff --git a/packages/contracts/scripts/deploy/dollar/solidityScripting/01_Diamond.s.sol b/packages/contracts/scripts/deploy/dollar/solidityScripting/01_Diamond.s.sol index ad90cd859..275def2ee 100644 --- a/packages/contracts/scripts/deploy/dollar/solidityScripting/01_Diamond.s.sol +++ b/packages/contracts/scripts/deploy/dollar/solidityScripting/01_Diamond.s.sol @@ -27,29 +27,28 @@ import {UbiquityDollarToken} from "../../../../src/dollar/core/UbiquityDollarTok import {StakingShare} from "../../../../src/dollar/core/StakingShare.sol"; import {UbiquityGovernanceToken} from "../../../../src/dollar/core/UbiquityGovernanceToken.sol"; import {IDiamondCut} from "../../../../src/dollar/interfaces/IDiamondCut.sol"; -//import "../../src/dollar/interfaces/IDiamondLoupe.sol"; import "./00_Constants.s.sol"; contract DiamondScript is Constants { - bytes4[] selectorsOfDiamondCutFacet; - bytes4[] selectorsOfDiamondLoupeFacet; - bytes4[] selectorsOfOwnershipFacet; - bytes4[] selectorsOfManagerFacet; + // selectors of the facets bytes4[] selectorsOfAccessControlFacet; - bytes4[] selectorsOfTWAPOracleDollar3poolFacet; - bytes4[] selectorsOfCollectableDustFacet; bytes4[] selectorsOfChefFacet; - bytes4[] selectorsOfStakingFacet; - bytes4[] selectorsOfStakingFormulasFacet; - + bytes4[] selectorsOfCollectableDustFacet; + bytes4[] selectorsOfCreditClockFacet; bytes4[] selectorsOfCreditNftManagerFacet; bytes4[] selectorsOfCreditNftRedemptionCalculatorFacet; bytes4[] selectorsOfCreditRedemptionCalculatorFacet; - + bytes4[] selectorsOfDiamondCutFacet; + bytes4[] selectorsOfDiamondLoupeFacet; bytes4[] selectorsOfDollarMintCalculatorFacet; bytes4[] selectorsOfDollarMintExcessFacet; - bytes4[] selectorsOfCreditClockFacet; + bytes4[] selectorsOfManagerFacet; + bytes4[] selectorsOfOwnershipFacet; + bytes4[] selectorsOfStakingFacet; + bytes4[] selectorsOfStakingFormulasFacet; + bytes4[] selectorsOfTWAPOracleDollar3poolFacet; + // contract types of facets to be deployed Diamond diamond; DiamondCutFacet dCutFacet; @@ -272,278 +271,53 @@ contract DiamondScript is Constants { function getSelectors() internal { // set all function selectors - // Diamond Cut selectors - selectorsOfDiamondCutFacet.push(IDiamondCut.diamondCut.selector); - - // Diamond Loupe - selectorsOfDiamondLoupeFacet.push(IDiamondLoupe.facets.selector); - selectorsOfDiamondLoupeFacet.push( - IDiamondLoupe.facetFunctionSelectors.selector - ); - selectorsOfDiamondLoupeFacet.push( - IDiamondLoupe.facetAddresses.selector - ); - selectorsOfDiamondLoupeFacet.push(IDiamondLoupe.facetAddress.selector); - selectorsOfDiamondLoupeFacet.push(IERC165.supportsInterface.selector); - - // Ownership - selectorsOfOwnershipFacet.push(IERC173.transferOwnership.selector); - selectorsOfOwnershipFacet.push(IERC173.owner.selector); - - // Manager selectors - selectorsOfManagerFacet.push( - managerFacet.setCreditTokenAddress.selector - ); - selectorsOfManagerFacet.push(managerFacet.setCreditNftAddress.selector); - selectorsOfManagerFacet.push( - managerFacet.setGovernanceTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.setDollarTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.setSushiSwapPoolAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.setDollarMintCalculatorAddress.selector + selectorsOfAccessControlFacet = getSelectorsFromAbi( + "/out/AccessControlFacet.sol/AccessControlFacet.json" ); - selectorsOfManagerFacet.push( - managerFacet.setExcessDollarsDistributor.selector + selectorsOfChefFacet = getSelectorsFromAbi( + "/out/ChefFacet.sol/ChefFacet.json" ); - selectorsOfManagerFacet.push( - managerFacet.setMasterChefAddress.selector + selectorsOfCollectableDustFacet = getSelectorsFromAbi( + "/out/CollectableDustFacet.sol/CollectableDustFacet.json" ); - selectorsOfManagerFacet.push(managerFacet.setFormulasAddress.selector); - selectorsOfManagerFacet.push( - managerFacet.setStakingShareAddress.selector + selectorsOfCreditClockFacet = getSelectorsFromAbi( + "/out/CreditClockFacet.sol/CreditClockFacet.json" ); - selectorsOfManagerFacet.push( - managerFacet.setStableSwapMetaPoolAddress.selector + selectorsOfCreditNftManagerFacet = getSelectorsFromAbi( + "/out/CreditNftManagerFacet.sol/CreditNftManagerFacet.json" ); - selectorsOfManagerFacet.push( - managerFacet.setStakingContractAddress.selector + selectorsOfCreditNftRedemptionCalculatorFacet = getSelectorsFromAbi( + "/out/CreditNftRedemptionCalculatorFacet.sol/CreditNftRedemptionCalculatorFacet.json" ); - selectorsOfManagerFacet.push(managerFacet.setTreasuryAddress.selector); - selectorsOfManagerFacet.push( - managerFacet.setIncentiveToDollar.selector + selectorsOfCreditRedemptionCalculatorFacet = getSelectorsFromAbi( + "/out/CreditRedemptionCalculatorFacet.sol/CreditRedemptionCalculatorFacet.json" ); - selectorsOfManagerFacet.push( - managerFacet.deployStableSwapPool.selector + selectorsOfDiamondCutFacet = getSelectorsFromAbi( + "/out/DiamondCutFacet.sol/DiamondCutFacet.json" ); - selectorsOfManagerFacet.push(managerFacet.twapOracleAddress.selector); - selectorsOfManagerFacet.push(managerFacet.dollarTokenAddress.selector); - selectorsOfManagerFacet.push(managerFacet.creditTokenAddress.selector); - selectorsOfManagerFacet.push(managerFacet.creditNftAddress.selector); - selectorsOfManagerFacet.push( - managerFacet.curve3PoolTokenAddress.selector + selectorsOfDiamondLoupeFacet = getSelectorsFromAbi( + "/out/DiamondLoupeFacet.sol/DiamondLoupeFacet.json" ); - selectorsOfManagerFacet.push( - managerFacet.governanceTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.sushiSwapPoolAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.creditCalculatorAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.creditNftCalculatorAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.dollarMintCalculatorAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.excessDollarsDistributor.selector - ); - selectorsOfManagerFacet.push(managerFacet.masterChefAddress.selector); - selectorsOfManagerFacet.push(managerFacet.formulasAddress.selector); - selectorsOfManagerFacet.push(managerFacet.stakingShareAddress.selector); - selectorsOfManagerFacet.push( - managerFacet.stableSwapMetaPoolAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacet.stakingContractAddress.selector - ); - selectorsOfManagerFacet.push(managerFacet.treasuryAddress.selector); - - // Access Control - selectorsOfAccessControlFacet.push( - accessControlFacet.grantRole.selector + selectorsOfDollarMintCalculatorFacet = getSelectorsFromAbi( + "/out/DollarMintCalculatorFacet.sol/DollarMintCalculatorFacet.json" ); - selectorsOfAccessControlFacet.push(accessControlFacet.hasRole.selector); - selectorsOfAccessControlFacet.push( - accessControlFacet.renounceRole.selector + selectorsOfDollarMintExcessFacet = getSelectorsFromAbi( + "/out/DollarMintExcessFacet.sol/DollarMintExcessFacet.json" ); - selectorsOfAccessControlFacet.push( - accessControlFacet.getRoleAdmin.selector + selectorsOfManagerFacet = getSelectorsFromAbi( + "/out/ManagerFacet.sol/ManagerFacet.json" ); - selectorsOfAccessControlFacet.push( - accessControlFacet.revokeRole.selector + selectorsOfOwnershipFacet = getSelectorsFromAbi( + "/out/OwnershipFacet.sol/OwnershipFacet.json" ); - selectorsOfAccessControlFacet.push(accessControlFacet.pause.selector); - selectorsOfAccessControlFacet.push(accessControlFacet.unpause.selector); - selectorsOfAccessControlFacet.push(accessControlFacet.paused.selector); - - // TWAP Oracle - selectorsOfTWAPOracleDollar3poolFacet.push( - twapOracleDollar3PoolFacet.setPool.selector - ); - selectorsOfTWAPOracleDollar3poolFacet.push( - twapOracleDollar3PoolFacet.update.selector - ); - selectorsOfTWAPOracleDollar3poolFacet.push( - twapOracleDollar3PoolFacet.consult.selector - ); - - // Collectable Dust - selectorsOfCollectableDustFacet.push( - collectableDustFacet.addProtocolToken.selector - ); - selectorsOfCollectableDustFacet.push( - collectableDustFacet.removeProtocolToken.selector - ); - selectorsOfCollectableDustFacet.push( - collectableDustFacet.sendDust.selector - ); - // Chef - selectorsOfChefFacet.push(chefFacet.governanceMultiplier.selector); - selectorsOfChefFacet.push(chefFacet.setGovernancePerBlock.selector); - selectorsOfChefFacet.push(chefFacet.governancePerBlock.selector); - selectorsOfChefFacet.push(chefFacet.governanceDivider.selector); - selectorsOfChefFacet.push( - chefFacet.minPriceDiffToUpdateMultiplier.selector - ); - selectorsOfChefFacet.push( - chefFacet.setGovernanceShareForTreasury.selector - ); - selectorsOfChefFacet.push( - chefFacet.setMinPriceDiffToUpdateMultiplier.selector - ); - selectorsOfChefFacet.push(chefFacet.getRewards.selector); - selectorsOfChefFacet.push(chefFacet.pendingGovernance.selector); - selectorsOfChefFacet.push(chefFacet.getStakingShareInfo.selector); - selectorsOfChefFacet.push(chefFacet.totalShares.selector); - selectorsOfChefFacet.push(chefFacet.pool.selector); - - // Staking - selectorsOfStakingFacet.push(stakingFacet.dollarPriceReset.selector); - selectorsOfStakingFacet.push(stakingFacet.crvPriceReset.selector); - selectorsOfStakingFacet.push( - stakingFacet.setStakingDiscountMultiplier.selector - ); - selectorsOfStakingFacet.push( - stakingFacet.stakingDiscountMultiplier.selector - ); - selectorsOfStakingFacet.push( - stakingFacet.setBlockCountInAWeek.selector - ); - selectorsOfStakingFacet.push(stakingFacet.blockCountInAWeek.selector); - selectorsOfStakingFacet.push(stakingFacet.deposit.selector); - selectorsOfStakingFacet.push(stakingFacet.addLiquidity.selector); - selectorsOfStakingFacet.push(stakingFacet.removeLiquidity.selector); - selectorsOfStakingFacet.push(stakingFacet.pendingLpRewards.selector); - selectorsOfStakingFacet.push(stakingFacet.lpRewardForShares.selector); - selectorsOfStakingFacet.push(stakingFacet.currentShareValue.selector); - - // Staking Formulas - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacet.sharesForLP.selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacet.lpRewardsRemoveLiquidityNormalization.selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacet.lpRewardsAddLiquidityNormalization.selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacet.correctedAmountToWithdraw.selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacet.durationMultiply.selector - ); - - // Credit facets - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.creditNftLengthBlocks.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.expiredCreditNftConversionRate.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.setExpiredCreditNftConversionRate.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.setCreditNftLength.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.exchangeDollarsForCreditNft.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.exchangeDollarsForCredit.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.getCreditNftReturnedForDollars.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.getCreditReturnedForDollars.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.onERC1155Received.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.onERC1155BatchReceived.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.burnExpiredCreditNftForGovernance.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.burnCreditNftForCredit.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.burnCreditTokensForDollars.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.redeemCreditNft.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacet.mintClaimableDollars.selector - ); - - // Credit NFT Redemption Calculator - selectorsOfCreditNftRedemptionCalculatorFacet.push( - creditNftRedemptionCalculatorFacet.getCreditNftAmount.selector - ); - - // Credit Redemption Calculator - selectorsOfCreditRedemptionCalculatorFacet.push( - (creditRedemptionCalculatorFacet.setConstant.selector) - ); - selectorsOfCreditRedemptionCalculatorFacet.push( - (creditRedemptionCalculatorFacet.getConstant.selector) - ); - selectorsOfCreditRedemptionCalculatorFacet.push( - (creditRedemptionCalculatorFacet.getCreditAmount.selector) - ); - - // Dollar Mint Calculator - selectorsOfDollarMintCalculatorFacet.push( - (dollarMintCalculatorFacet.getDollarsToMint.selector) - ); - // Dollar Mint Excess - selectorsOfDollarMintExcessFacet.push( - (dollarMintExcessFacet.distributeDollars.selector) - ); - - // Credit Clock Facet - selectorsOfCreditClockFacet.push((creditClockFacet.getRate.selector)); - selectorsOfCreditClockFacet.push( - creditClockFacet.setRatePerBlock.selector + selectorsOfStakingFacet = getSelectorsFromAbi( + "/out/StakingFacet.sol/StakingFacet.json" ); - selectorsOfCreditClockFacet.push( - (creditClockFacet.setManager.selector) + selectorsOfStakingFormulasFacet = getSelectorsFromAbi( + "/out/StakingFormulasFacet.sol/StakingFormulasFacet.json" ); - selectorsOfCreditClockFacet.push( - (creditClockFacet.getManager.selector) + selectorsOfTWAPOracleDollar3poolFacet = getSelectorsFromAbi( + "/out/TWAPOracleDollar3poolFacet.sol/TWAPOracleDollar3poolFacet.json" ); } } diff --git a/packages/contracts/test/diamond/DiamondTestSetup.sol b/packages/contracts/test/diamond/DiamondTestSetup.sol index 4a5b0170f..7756d8552 100644 --- a/packages/contracts/test/diamond/DiamondTestSetup.sol +++ b/packages/contracts/test/diamond/DiamondTestSetup.sol @@ -28,12 +28,13 @@ import {TWAPOracleDollar3poolFacet} from "../../src/dollar/facets/TWAPOracleDoll import {UbiquityPoolFacet} from "../../src/dollar/facets/UbiquityPoolFacet.sol"; import {DiamondInit} from "../../src/dollar/upgradeInitializers/DiamondInit.sol"; import {DiamondTestHelper} from "../helpers/DiamondTestHelper.sol"; +import {UUPSTestHelper} from "../helpers/UUPSTestHelper.sol"; import {CREDIT_NFT_MANAGER_ROLE, CREDIT_TOKEN_BURNER_ROLE, CREDIT_TOKEN_MINTER_ROLE, CURVE_DOLLAR_MANAGER_ROLE, DOLLAR_TOKEN_BURNER_ROLE, DOLLAR_TOKEN_MINTER_ROLE, GOVERNANCE_TOKEN_BURNER_ROLE, GOVERNANCE_TOKEN_MANAGER_ROLE, GOVERNANCE_TOKEN_MINTER_ROLE, STAKING_SHARE_MINTER_ROLE} from "../../src/dollar/libraries/Constants.sol"; /** * @notice Deploys diamond contract with all of the facets */ -abstract contract DiamondTestSetup is DiamondTestHelper { +abstract contract DiamondTestSetup is DiamondTestHelper, UUPSTestHelper { // diamond related contracts Diamond diamond; DiamondInit diamondInit; @@ -43,6 +44,7 @@ abstract contract DiamondTestSetup is DiamondTestHelper { BondingCurveFacet bondingCurveFacet; ChefFacet chefFacet; CollectableDustFacet collectableDustFacet; + CreditClockFacet creditClockFacet; CreditNftManagerFacet creditNftManagerFacet; CreditNftRedemptionCalculatorFacet creditNftRedemptionCalculationFacet; CreditRedemptionCalculatorFacet creditRedemptionCalculationFacet; @@ -57,13 +59,13 @@ abstract contract DiamondTestSetup is DiamondTestHelper { StakingFormulasFacet stakingFormulasFacet; TWAPOracleDollar3poolFacet twapOracleDollar3PoolFacet; UbiquityPoolFacet ubiquityPoolFacet; - CreditClockFacet creditClockFacet; // diamond facet implementation instances (should not be used in tests, use only on upgrades) AccessControlFacet accessControlFacetImplementation; BondingCurveFacet bondingCurveFacetImplementation; ChefFacet chefFacetImplementation; CollectableDustFacet collectableDustFacetImplementation; + CreditClockFacet creditClockFacetImplementation; CreditNftManagerFacet creditNftManagerFacetImplementation; CreditNftRedemptionCalculatorFacet creditNftRedemptionCalculatorFacetImplementation; CreditRedemptionCalculatorFacet creditRedemptionCalculatorFacetImplementation; @@ -78,7 +80,6 @@ abstract contract DiamondTestSetup is DiamondTestHelper { StakingFormulasFacet stakingFormulasFacetImplementation; TWAPOracleDollar3poolFacet twapOracleDollar3PoolFacetImplementation; UbiquityPoolFacet ubiquityPoolFacetImplementation; - CreditClockFacet creditClockFacetImplementation; // facet names with addresses string[] facetNames; @@ -96,6 +97,7 @@ abstract contract DiamondTestSetup is DiamondTestHelper { bytes4[] selectorsOfBondingCurveFacet; bytes4[] selectorsOfChefFacet; bytes4[] selectorsOfCollectableDustFacet; + bytes4[] selectorsOfCreditClockFacet; bytes4[] selectorsOfCreditNftManagerFacet; bytes4[] selectorsOfCreditNftRedemptionCalculatorFacet; bytes4[] selectorsOfCreditRedemptionCalculatorFacet; @@ -110,7 +112,6 @@ abstract contract DiamondTestSetup is DiamondTestHelper { bytes4[] selectorsOfStakingFormulasFacet; bytes4[] selectorsOfTWAPOracleDollar3poolFacet; bytes4[] selectorsOfUbiquityPoolFacet; - bytes4[] selectorsOfCreditClockFacet; /// @notice Deploys diamond and connects facets function setUp() public virtual { @@ -122,463 +123,62 @@ abstract contract DiamondTestSetup is DiamondTestHelper { contract2 = generateAddress("Contract2", true, 10 ether); // set all function selectors - // Diamond Cut selectors - selectorsOfDiamondCutFacet.push(IDiamondCut.diamondCut.selector); - - // Diamond Loupe - selectorsOfDiamondLoupeFacet.push( - diamondLoupeFacetImplementation.facets.selector - ); - selectorsOfDiamondLoupeFacet.push( - diamondLoupeFacetImplementation.facetFunctionSelectors.selector - ); - selectorsOfDiamondLoupeFacet.push( - diamondLoupeFacetImplementation.facetAddresses.selector - ); - selectorsOfDiamondLoupeFacet.push( - diamondLoupeFacetImplementation.facetAddress.selector - ); - selectorsOfDiamondLoupeFacet.push( - diamondLoupeFacetImplementation.supportsInterface.selector - ); - - // Ownership - selectorsOfOwnershipFacet.push(IERC173.transferOwnership.selector); - selectorsOfOwnershipFacet.push(IERC173.owner.selector); - - // Manager selectors - selectorsOfManagerFacet.push( - managerFacetImplementation.setCreditTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setCreditNftAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setGovernanceTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setDollarTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setUbiquistickAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setSushiSwapPoolAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setDollarMintCalculatorAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setExcessDollarsDistributor.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setMasterChefAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setFormulasAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setStakingShareAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setCurveDollarIncentiveAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setStableSwapMetaPoolAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setStakingContractAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setBondingCurveAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setTreasuryAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.setIncentiveToDollar.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.deployStableSwapPool.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.twapOracleAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.dollarTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.creditTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.creditNftAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.curve3PoolTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.governanceTokenAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.sushiSwapPoolAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.creditCalculatorAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.creditNftCalculatorAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.dollarMintCalculatorAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.excessDollarsDistributor.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.masterChefAddress.selector - ); - selectorsOfManagerFacet.push( - managerFacetImplementation.formulasAddress.selector + selectorsOfAccessControlFacet = getSelectorsFromAbi( + "/out/AccessControlFacet.sol/AccessControlFacet.json" ); - selectorsOfManagerFacet.push( - managerFacetImplementation.stakingShareAddress.selector + selectorsOfBondingCurveFacet = getSelectorsFromAbi( + "/out/BondingCurveFacet.sol/BondingCurveFacet.json" ); - selectorsOfManagerFacet.push( - managerFacetImplementation.stableSwapMetaPoolAddress.selector + selectorsOfChefFacet = getSelectorsFromAbi( + "/out/ChefFacet.sol/ChefFacet.json" ); - selectorsOfManagerFacet.push( - managerFacetImplementation.stakingContractAddress.selector + selectorsOfCollectableDustFacet = getSelectorsFromAbi( + "/out/CollectableDustFacet.sol/CollectableDustFacet.json" ); - selectorsOfManagerFacet.push( - managerFacetImplementation.treasuryAddress.selector + selectorsOfCreditClockFacet = getSelectorsFromAbi( + "/out/CreditClockFacet.sol/CreditClockFacet.json" ); - - // Access Control - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.grantRole.selector - ); - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.hasRole.selector - ); - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.renounceRole.selector - ); - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.getRoleAdmin.selector - ); - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.revokeRole.selector - ); - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.pause.selector - ); - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.unpause.selector - ); - selectorsOfAccessControlFacet.push( - accessControlFacetImplementation.paused.selector - ); - - // TWAP Oracle - selectorsOfTWAPOracleDollar3poolFacet.push( - twapOracleDollar3PoolFacetImplementation.setPool.selector - ); - selectorsOfTWAPOracleDollar3poolFacet.push( - twapOracleDollar3PoolFacetImplementation.update.selector - ); - selectorsOfTWAPOracleDollar3poolFacet.push( - twapOracleDollar3PoolFacetImplementation.consult.selector - ); - - // Collectable Dust - selectorsOfCollectableDustFacet.push( - collectableDustFacetImplementation.addProtocolToken.selector - ); - selectorsOfCollectableDustFacet.push( - collectableDustFacetImplementation.removeProtocolToken.selector - ); - selectorsOfCollectableDustFacet.push( - collectableDustFacetImplementation.sendDust.selector - ); - // Chef - selectorsOfChefFacet.push( - chefFacetImplementation.setGovernancePerBlock.selector - ); - selectorsOfChefFacet.push( - chefFacetImplementation.governancePerBlock.selector - ); - selectorsOfChefFacet.push( - chefFacetImplementation.governanceDivider.selector - ); - selectorsOfChefFacet.push( - chefFacetImplementation.minPriceDiffToUpdateMultiplier.selector - ); - selectorsOfChefFacet.push( - chefFacetImplementation.setGovernanceShareForTreasury.selector - ); - selectorsOfChefFacet.push( - chefFacetImplementation.setMinPriceDiffToUpdateMultiplier.selector + selectorsOfCreditNftManagerFacet = getSelectorsFromAbi( + "/out/CreditNftManagerFacet.sol/CreditNftManagerFacet.json" ); - selectorsOfChefFacet.push(chefFacetImplementation.getRewards.selector); - selectorsOfChefFacet.push( - chefFacetImplementation.pendingGovernance.selector + selectorsOfCreditNftRedemptionCalculatorFacet = getSelectorsFromAbi( + "/out/CreditNftRedemptionCalculatorFacet.sol/CreditNftRedemptionCalculatorFacet.json" ); - selectorsOfChefFacet.push( - chefFacetImplementation.getStakingShareInfo.selector + selectorsOfCreditRedemptionCalculatorFacet = getSelectorsFromAbi( + "/out/CreditRedemptionCalculatorFacet.sol/CreditRedemptionCalculatorFacet.json" ); - selectorsOfChefFacet.push(chefFacetImplementation.totalShares.selector); - selectorsOfChefFacet.push(chefFacetImplementation.pool.selector); - - // Staking - selectorsOfStakingFacet.push( - stakingFacetImplementation.dollarPriceReset.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.crvPriceReset.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.setStakingDiscountMultiplier.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.stakingDiscountMultiplier.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.setBlockCountInAWeek.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.blockCountInAWeek.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.deposit.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.addLiquidity.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.removeLiquidity.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.pendingLpRewards.selector - ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.lpRewardForShares.selector + selectorsOfCurveDollarIncentiveFacet = getSelectorsFromAbi( + "/out/CurveDollarIncentiveFacet.sol/CurveDollarIncentiveFacet.json" ); - selectorsOfStakingFacet.push( - stakingFacetImplementation.currentShareValue.selector + selectorsOfDiamondCutFacet = getSelectorsFromAbi( + "/out/DiamondCutFacet.sol/DiamondCutFacet.json" ); - - // UbiquityPool - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.mintDollar.selector + selectorsOfDiamondLoupeFacet = getSelectorsFromAbi( + "/out/DiamondLoupeFacet.sol/DiamondLoupeFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.redeemDollar.selector + selectorsOfDollarMintCalculatorFacet = getSelectorsFromAbi( + "/out/DollarMintCalculatorFacet.sol/DollarMintCalculatorFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.collectRedemption.selector + selectorsOfDollarMintExcessFacet = getSelectorsFromAbi( + "/out/DollarMintExcessFacet.sol/DollarMintExcessFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.addToken.selector + selectorsOfManagerFacet = getSelectorsFromAbi( + "/out/ManagerFacet.sol/ManagerFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.setRedeemActive.selector + selectorsOfOwnershipFacet = getSelectorsFromAbi( + "/out/OwnershipFacet.sol/OwnershipFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.getRedeemActive.selector + selectorsOfStakingFacet = getSelectorsFromAbi( + "/out/StakingFacet.sol/StakingFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.setMintActive.selector + selectorsOfStakingFormulasFacet = getSelectorsFromAbi( + "/out/StakingFormulasFacet.sol/StakingFormulasFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.getRedeemCollateralBalances.selector + selectorsOfTWAPOracleDollar3poolFacet = getSelectorsFromAbi( + "/out/TWAPOracleDollar3poolFacet.sol/TWAPOracleDollar3poolFacet.json" ); - selectorsOfUbiquityPoolFacet.push( - ubiquityPoolFacetImplementation.getMintActive.selector - ); - - // Staking Formulas - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacetImplementation.sharesForLP.selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacetImplementation - .lpRewardsRemoveLiquidityNormalization - .selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacetImplementation - .lpRewardsAddLiquidityNormalization - .selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacetImplementation - .correctedAmountToWithdraw - .selector - ); - selectorsOfStakingFormulasFacet.push( - stakingFormulasFacetImplementation.durationMultiply.selector - ); - - // Bonding Curve - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.setParams.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.connectorWeight.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.baseY.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.poolBalance.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.deposit.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.getShare.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.withdraw.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation.purchaseTargetAmount.selector - ); - selectorsOfBondingCurveFacet.push( - bondingCurveFacetImplementation - .purchaseTargetAmountFromZero - .selector - ); - - // Curve Dollar Incentive Facet - selectorsOfCurveDollarIncentiveFacet.push( - curveDollarIncentiveFacetImplementation.incentivize.selector - ); - selectorsOfCurveDollarIncentiveFacet.push( - curveDollarIncentiveFacetImplementation.setExemptAddress.selector - ); - selectorsOfCurveDollarIncentiveFacet.push( - curveDollarIncentiveFacetImplementation.switchSellPenalty.selector - ); - selectorsOfCurveDollarIncentiveFacet.push( - curveDollarIncentiveFacetImplementation.switchBuyIncentive.selector - ); - selectorsOfCurveDollarIncentiveFacet.push( - curveDollarIncentiveFacetImplementation.isExemptAddress.selector - ); - selectorsOfCurveDollarIncentiveFacet.push( - curveDollarIncentiveFacetImplementation.isSellPenaltyOn.selector - ); - selectorsOfCurveDollarIncentiveFacet.push( - curveDollarIncentiveFacetImplementation.isBuyIncentiveOn.selector - ); - - // Credit facets - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation.creditNftLengthBlocks.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .expiredCreditNftConversionRate - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .setExpiredCreditNftConversionRate - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation.setCreditNftLength.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .exchangeDollarsForCreditNft - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .exchangeDollarsForCredit - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .getCreditNftReturnedForDollars - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .getCreditReturnedForDollars - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation.onERC1155Received.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation.onERC1155BatchReceived.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .burnExpiredCreditNftForGovernance - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation.burnCreditNftForCredit.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation - .burnCreditTokensForDollars - .selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation.redeemCreditNft.selector - ); - selectorsOfCreditNftManagerFacet.push( - creditNftManagerFacetImplementation.mintClaimableDollars.selector - ); - - // Credit NFT Redemption Calculator - selectorsOfCreditNftRedemptionCalculatorFacet.push( - creditNftRedemptionCalculatorFacetImplementation - .getCreditNftAmount - .selector - ); - - // Credit Redemption Calculator - selectorsOfCreditRedemptionCalculatorFacet.push( - (creditRedemptionCalculatorFacetImplementation.setConstant.selector) - ); - selectorsOfCreditRedemptionCalculatorFacet.push( - (creditRedemptionCalculatorFacetImplementation.getConstant.selector) - ); - selectorsOfCreditRedemptionCalculatorFacet.push( - ( - creditRedemptionCalculatorFacetImplementation - .getCreditAmount - .selector - ) - ); - - // Dollar Mint Calculator - selectorsOfDollarMintCalculatorFacet.push( - (dollarMintCalculatorFacetImplementation.getDollarsToMint.selector) - ); - // Dollar Mint Excess - selectorsOfDollarMintExcessFacet.push( - (dollarMintExcessFacetImplementation.distributeDollars.selector) - ); - - // Credit Clock Facet - selectorsOfCreditClockFacet.push( - (creditClockFacetImplementation.getRate.selector) - ); - selectorsOfCreditClockFacet.push( - creditClockFacetImplementation.setRatePerBlock.selector - ); - selectorsOfCreditClockFacet.push( - (creditClockFacetImplementation.setManager.selector) - ); - selectorsOfCreditClockFacet.push( - (creditClockFacetImplementation.getManager.selector) + selectorsOfUbiquityPoolFacet = getSelectorsFromAbi( + "/out/UbiquityPoolFacet.sol/UbiquityPoolFacet.json" ); // deploy facet implementation instances @@ -586,6 +186,7 @@ abstract contract DiamondTestSetup is DiamondTestHelper { bondingCurveFacetImplementation = new BondingCurveFacet(); chefFacetImplementation = new ChefFacet(); collectableDustFacetImplementation = new CollectableDustFacet(); + creditClockFacetImplementation = new CreditClockFacet(); creditNftManagerFacetImplementation = new CreditNftManagerFacet(); creditNftRedemptionCalculatorFacetImplementation = new CreditNftRedemptionCalculatorFacet(); creditRedemptionCalculatorFacetImplementation = new CreditRedemptionCalculatorFacet(); @@ -600,7 +201,6 @@ abstract contract DiamondTestSetup is DiamondTestHelper { stakingFormulasFacetImplementation = new StakingFormulasFacet(); twapOracleDollar3PoolFacetImplementation = new TWAPOracleDollar3poolFacet(); ubiquityPoolFacetImplementation = new UbiquityPoolFacet(); - creditClockFacetImplementation = new CreditClockFacet(); // prepare diamond init args diamondInit = new DiamondInit(); @@ -609,6 +209,7 @@ abstract contract DiamondTestSetup is DiamondTestHelper { "BondingCurveFacet", "ChefFacet", "CollectableDustFacet", + "CreditClockFacet", "CreditNftManagerFacet", "CreditNftRedemptionCalculatorFacet", "CreditRedemptionCalculatorFacet", @@ -622,8 +223,7 @@ abstract contract DiamondTestSetup is DiamondTestHelper { "StakingFacet", "StakingFormulasFacet", "TWAPOracleDollar3poolFacet", - "UbiquityPoolFacet", - "CreditClockFacet" + "UbiquityPoolFacet" ]; DiamondInit.Args memory initArgs = DiamondInit.Args({ admin: admin, @@ -674,13 +274,20 @@ abstract contract DiamondTestSetup is DiamondTestHelper { }) ); cuts[4] = ( + FacetCut({ + facetAddress: address(creditClockFacetImplementation), + action: FacetCutAction.Add, + functionSelectors: selectorsOfCreditClockFacet + }) + ); + cuts[5] = ( FacetCut({ facetAddress: address(creditNftManagerFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfCreditNftManagerFacet }) ); - cuts[5] = ( + cuts[6] = ( FacetCut({ facetAddress: address( creditNftRedemptionCalculatorFacetImplementation @@ -689,7 +296,7 @@ abstract contract DiamondTestSetup is DiamondTestHelper { functionSelectors: selectorsOfCreditNftRedemptionCalculatorFacet }) ); - cuts[6] = ( + cuts[7] = ( FacetCut({ facetAddress: address( creditRedemptionCalculatorFacetImplementation @@ -698,90 +305,83 @@ abstract contract DiamondTestSetup is DiamondTestHelper { functionSelectors: selectorsOfCreditRedemptionCalculatorFacet }) ); - cuts[7] = ( + cuts[8] = ( FacetCut({ facetAddress: address(curveDollarIncentiveFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfCurveDollarIncentiveFacet }) ); - cuts[8] = ( + cuts[9] = ( FacetCut({ facetAddress: address(diamondCutFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfDiamondCutFacet }) ); - cuts[9] = ( + cuts[10] = ( FacetCut({ facetAddress: address(diamondLoupeFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfDiamondLoupeFacet }) ); - cuts[10] = ( + cuts[11] = ( FacetCut({ facetAddress: address(dollarMintCalculatorFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfDollarMintCalculatorFacet }) ); - cuts[11] = ( + cuts[12] = ( FacetCut({ facetAddress: address(dollarMintExcessFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfDollarMintExcessFacet }) ); - cuts[12] = ( + cuts[13] = ( FacetCut({ facetAddress: address(managerFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfManagerFacet }) ); - cuts[13] = ( + cuts[14] = ( FacetCut({ facetAddress: address(ownershipFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfOwnershipFacet }) ); - cuts[14] = ( + cuts[15] = ( FacetCut({ facetAddress: address(stakingFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfStakingFacet }) ); - cuts[15] = ( + cuts[16] = ( FacetCut({ facetAddress: address(stakingFormulasFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfStakingFormulasFacet }) ); - cuts[16] = ( + cuts[17] = ( FacetCut({ facetAddress: address(twapOracleDollar3PoolFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfTWAPOracleDollar3poolFacet }) ); - cuts[17] = ( + cuts[18] = ( FacetCut({ facetAddress: address(ubiquityPoolFacetImplementation), action: FacetCutAction.Add, functionSelectors: selectorsOfUbiquityPoolFacet }) ); - cuts[18] = ( - FacetCut({ - facetAddress: address(creditClockFacetImplementation), - action: FacetCutAction.Add, - functionSelectors: selectorsOfCreditClockFacet - }) - ); // deploy diamond vm.prank(owner); @@ -792,6 +392,7 @@ abstract contract DiamondTestSetup is DiamondTestHelper { bondingCurveFacet = BondingCurveFacet(address(diamond)); chefFacet = ChefFacet(address(diamond)); collectableDustFacet = CollectableDustFacet(address(diamond)); + creditClockFacet = CreditClockFacet(address(diamond)); creditNftManagerFacet = CreditNftManagerFacet(address(diamond)); creditNftRedemptionCalculationFacet = CreditNftRedemptionCalculatorFacet( address(diamond) @@ -812,7 +413,6 @@ abstract contract DiamondTestSetup is DiamondTestHelper { address(diamond) ); ubiquityPoolFacet = UbiquityPoolFacet(address(diamond)); - creditClockFacet = CreditClockFacet(address(diamond)); // get all addresses facetAddressList = diamondLoupeFacet.facetAddresses(); diff --git a/packages/contracts/test/helpers/DiamondTestHelper.sol b/packages/contracts/test/helpers/DiamondTestHelper.sol index 91c434d37..280620591 100644 --- a/packages/contracts/test/helpers/DiamondTestHelper.sol +++ b/packages/contracts/test/helpers/DiamondTestHelper.sol @@ -1,12 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.19; +import "forge-std/Test.sol"; import "../../src/dollar/interfaces/IDiamondCut.sol"; import "../../src/dollar/interfaces/IDiamondLoupe.sol"; -import "./UUPSTestHelper.sol"; - -contract DiamondTestHelper is IDiamondCut, IDiamondLoupe, UUPSTestHelper, Test { +contract DiamondTestHelper is IDiamondCut, IDiamondLoupe, Test { uint256 private seed; modifier prankAs(address caller) { @@ -142,6 +141,35 @@ contract DiamondTestHelper is IDiamondCut, IDiamondLoupe, UUPSTestHelper, Test { keccak256(abi.encodePacked((b)))); } + /** + * @notice Returns array of function selectors by the provided contract's ABI path + * @dev Foundry's build output ABI files contain the "methodIdentifiers" object which + * is a "key:value" mapping of function signatures to their 4 bytes selectors. + * Example: + * "methodIdentifiers": { + * "getRoleAdmin(bytes32)": "248a9ca3", + * "grantRole(bytes32,address)": "2f2ff15d" + * } + * @param abiPath Path to ABI (relative to foundry project root) + * @return Array of selectors + */ + function getSelectorsFromAbi( + string memory abiPath + ) public view returns (bytes4[] memory) { + string memory path = string.concat(vm.projectRoot(), abiPath); + string memory abiJson = vm.readFile(path); + string[] memory keys = vm.parseJsonKeys(abiJson, "$.methodIdentifiers"); + bytes4[] memory selectorsArray = new bytes4[](keys.length); + for (uint i = 0; i < keys.length; i++) { + bytes memory selector = vm.parseJsonBytes( + abiJson, + string.concat('$.methodIdentifiers.["', keys[i], '"]') + ); + selectorsArray[i] = bytes4(selector); + } + return selectorsArray; + } + // implement dummy override functions function diamondCut( FacetCut[] calldata _diamondCut,