Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 127 additions & 24 deletions contracts/test/suite/AttachTestBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,34 @@
// (c) Gearbox Foundation, 2025.
pragma solidity ^0.8.23;

import {Test} from "forge-std/Test.sol";
import {Test, stdStorage, StdStorage} from "forge-std/Test.sol";
import {VmSafe} from "forge-std/Vm.sol";
import {console} from "forge-std/console.sol";

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC4626} from "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol";
import {LibString} from "@solady/utils/LibString.sol";

import {ITumblerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ITumblerV3.sol";

import {IMarketConfigurator} from "../../interfaces/IMarketConfigurator.sol";
import {AuditReport, Bytecode, DeployParams} from "../../interfaces/Types.sol";
import {CreditFacadeParams, CreditManagerParams} from "../../interfaces/factories/ICreditConfigureActions.sol";
import {
ICreditConfigureActions,
CreditFacadeParams,
CreditManagerParams
} from "../../interfaces/factories/ICreditConfigureActions.sol";
import {IPoolConfigureActions} from "../../interfaces/factories/IPoolConfigureActions.sol";
import {IPriceOracleConfigureActions} from "../../interfaces/factories/IPriceOracleConfigureActions.sol";

import {Domain} from "../../libraries/Domain.sol";

import {AttachBase} from "./AttachBase.sol";

contract AttachTestBase is AttachBase, Test {
using LibString for bytes32;
using stdStorage for StdStorage;

// ---- //
// CORE //
// ---- //
Expand All @@ -40,13 +51,25 @@ contract AttachTestBase is AttachBase, Test {
}

function _addPublicDomain(bytes32 domain) internal {
if (bytecodeRepository.isPublicDomain(domain)) return;

vm.prank(crossChainGovernance);
instanceManager.configureGlobal(
address(bytecodeRepository), abi.encodeCall(bytecodeRepository.addPublicDomain, (domain))
);
}

function _uploadContract(bytes32 contractType, uint256 version, bytes memory initCode) internal {
bytes32 allowedBytecodeHash = bytecodeRepository.getAllowedBytecodeHash(contractType, version);
if (allowedBytecodeHash != 0) {
bytes memory uploadedInitCode = bytecodeRepository.getBytecode(allowedBytecodeHash).initCode;
require(
keccak256(initCode) == keccak256(uploadedInitCode),
string.concat("Bytecode mismatch for ", contractType.fromSmallString(), " v", vm.toString(version))
);
return;
}

Bytecode memory bytecode;
bytecode.contractType = contractType;
bytecode.version = version;
Expand All @@ -65,6 +88,10 @@ contract AttachTestBase is AttachBase, Test {
bytecodeRepository.submitAuditReport(bytecodeHash, auditReport);

if (bytecodeRepository.isPublicDomain(Domain.extractDomain(contractType))) {
if (bytecodeRepository.getContractTypeOwner(contractType) != address(0)) {
stdstore.target(address(bytecodeRepository)).sig("getContractTypeOwner(bytes32)").with_key(contractType)
.checked_write(author.addr);
}
bytecodeRepository.allowPublicContract(bytecodeHash);
} else {
vm.prank(crossChainGovernance);
Expand All @@ -74,6 +101,30 @@ contract AttachTestBase is AttachBase, Test {
}
}

function _deploy(bytes32 contractType, uint256 version, bytes memory constructorParams) internal returns (address) {
return bytecodeRepository.deploy({
contractType: contractType, version: version, constructorParams: constructorParams, salt: "GEARBOX"
});
}

function _addPriceFeed(address priceFeed, uint32 stalenessPeriod, string memory name) internal {
if (priceFeedStore.isKnownPriceFeed(priceFeed)) return;

vm.prank(instanceOwner);
instanceManager.configureLocal(
address(priceFeedStore), abi.encodeCall(priceFeedStore.addPriceFeed, (priceFeed, stalenessPeriod, name))
);
}

function _allowPriceFeed(address token, address priceFeed) internal {
if (priceFeedStore.isAllowedPriceFeed(token, priceFeed)) return;

vm.prank(instanceOwner);
instanceManager.configureLocal(
address(priceFeedStore), abi.encodeCall(priceFeedStore.allowPriceFeed, (token, priceFeed))
);
}

// ------- //
// MARKETS //
// ------- //
Expand Down Expand Up @@ -103,10 +154,7 @@ contract AttachTestBase is AttachBase, Test {
address curator = makeAddr("MockCurator");
vm.prank(curator);
configurator = marketConfiguratorFactory.createMarketConfigurator({
emergencyAdmin: address(0),
adminFeeTreasury: address(0),
curatorName: "MockCurator",
deployGovernor: false
emergencyAdmin: address(0), adminFeeTreasury: address(0), curatorName: "MockCurator", deployGovernor: false
});
}

Expand All @@ -117,10 +165,7 @@ contract AttachTestBase is AttachBase, Test {
deal({token: underlying, to: address(marketConfigurator), give: 1e5});

pool = marketConfigurator.previewCreateMarket({
minorVersion: 3_10,
underlying: underlying,
name: name,
symbol: symbol
minorVersion: 3_10, underlying: underlying, name: name, symbol: symbol
});

vm.prank(riskCurator);
Expand All @@ -130,15 +175,13 @@ contract AttachTestBase is AttachBase, Test {
name: name,
symbol: symbol,
interestRateModelParams: DeployParams({
postfix: "LINEAR",
salt: "SALT",
constructorParams: abi.encode(5000, 9000, 0, 100, 200, 700, false)
postfix: "LINEAR", salt: "GEARBOX", constructorParams: abi.encode(5000, 9000, 0, 100, 200, 700, false)
}),
rateKeeperParams: DeployParams({
postfix: "TUMBLER", salt: "GEARBOX", constructorParams: abi.encode(pool, 1 days)
}),
rateKeeperParams: DeployParams({postfix: "TUMBLER", salt: "SALT", constructorParams: abi.encode(pool, 1 days)}),
lossPolicyParams: DeployParams({
postfix: "ALIASED",
salt: "SALT",
constructorParams: abi.encode(pool, ADDRESS_PROVIDER)
postfix: "ALIASED", salt: "GEARBOX", constructorParams: abi.encode(pool, ADDRESS_PROVIDER)
}),
underlyingPriceFeed: priceFeed
});
Expand All @@ -157,7 +200,7 @@ contract AttachTestBase is AttachBase, Test {
pool: pool,
encdodedParams: abi.encode(
CreditManagerParams({
maxEnabledTokens: 1,
maxEnabledTokens: 2,
feeInterest: 50_00,
feeLiquidation: 100,
liquidationPremium: 100,
Expand All @@ -167,18 +210,78 @@ contract AttachTestBase is AttachBase, Test {
maxDebt: maxDebt,
name: name,
accountFactoryParams: DeployParams({
postfix: "DEFAULT",
salt: "SALT",
constructorParams: abi.encode(ADDRESS_PROVIDER)
postfix: "DEFAULT", salt: "GEARBOX", constructorParams: abi.encode(ADDRESS_PROVIDER)
})
}),
CreditFacadeParams({degenNFT: address(0), expirable: false, migrateBotList: false})
)
});

marketConfigurator.configurePool(
pool, abi.encodeCall(IPoolConfigureActions.setCreditManagerDebtLimit, (creditManager, debtLimit))
);
if (debtLimit != 0) {
marketConfigurator.configurePool(
pool, abi.encodeCall(IPoolConfigureActions.setCreditManagerDebtLimit, (creditManager, debtLimit))
);
}
vm.stopPrank();
}

struct TokenConfig {
address token;
address priceFeed;
address reservePriceFeed;
uint96 quotaLimit;
uint16 quotaRate;
}

function _addToken(address pool, TokenConfig memory config) internal {
vm.startPrank(riskCurator);

marketConfigurator.addToken({pool: pool, token: config.token, priceFeed: config.priceFeed});

if (config.reservePriceFeed != address(0)) {
marketConfigurator.configurePriceOracle(
pool,
abi.encodeCall(
IPriceOracleConfigureActions.setReservePriceFeed, (config.token, config.reservePriceFeed)
)
);
}
if (config.quotaLimit != 0) {
marketConfigurator.configurePool(
pool, abi.encodeCall(IPoolConfigureActions.setTokenLimit, (config.token, config.quotaLimit))
);
}
if (config.quotaRate != 0) {
marketConfigurator.configureRateKeeper(
pool, abi.encodeCall(ITumblerV3.setRate, (config.token, config.quotaRate))
);
}

vm.stopPrank();
}

function _addCollateralToken(address creditManager, address token, uint16 lt) internal {
vm.prank(riskCurator);
marketConfigurator.configureCreditSuite(
creditManager, abi.encodeCall(ICreditConfigureActions.addCollateralToken, (token, lt))
);
}

function _allowAdapter(address creditManager, bytes32 postfix, bytes memory constructorParams) internal {
vm.prank(riskCurator);
marketConfigurator.configureCreditSuite(
creditManager,
abi.encodeCall(
ICreditConfigureActions.allowAdapter,
(DeployParams({postfix: postfix, salt: "GEARBOX", constructorParams: constructorParams}))
)
);
}

function _configureAdapter(address creditManager, address targetContract, bytes memory data) internal {
vm.prank(riskCurator);
marketConfigurator.configureCreditSuite(
creditManager, abi.encodeCall(ICreditConfigureActions.configureAdapterFor, (targetContract, data))
);
}
}
4 changes: 2 additions & 2 deletions foundry.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
},
"lib/forge-std": {
"tag": {
"name": "v1.11.0",
"rev": "8e40513d678f392f398620b3ef2b418648b33e89"
"name": "v1.14.0",
"rev": "1801b0541f4fda118a10798fd3486bb7051c5dd6"
}
}
}
5 changes: 4 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ gas_limit = 9223372036854775807 # the gas limit in tests

[fuzz]
max_test_rejects = 1000000
runs = 256
runs = 256

[lint]
lint_on_build = false
2 changes: 1 addition & 1 deletion lib/forge-std
Submodule forge-std updated 57 files
+16 −33 .github/workflows/ci.yml
+1 −1 .github/workflows/sync.yml
+2 −2 CONTRIBUTING.md
+11 −9 README.md
+3 −12 foundry.toml
+2 −2 package.json
+2 −12 scripts/vm.py
+2 −2 src/Base.sol
+1 −1 src/Config.sol
+2 −2 src/LibVariable.sol
+2 −2 src/Script.sol
+28 −13 src/StdAssertions.sol
+13 −5 src/StdChains.sol
+9 −13 src/StdCheats.sol
+24 −4 src/StdConfig.sol
+2 −2 src/StdConstants.sol
+2 −2 src/StdError.sol
+2 −4 src/StdInvariant.sol
+4 −12 src/StdJson.sol
+6 −2 src/StdMath.sol
+11 −9 src/StdStorage.sol
+2 −2 src/StdStyle.sol
+4 −12 src/StdToml.sol
+5 −13 src/StdUtils.sol
+2 −4 src/Test.sol
+47 −41 src/Vm.sol
+10 −19 src/console.sol
+2 −2 src/console2.sol
+2 −2 src/interfaces/IERC1155.sol
+2 −2 src/interfaces/IERC165.sol
+2 −2 src/interfaces/IERC20.sol
+2 −2 src/interfaces/IERC4626.sol
+2 −2 src/interfaces/IERC6909.sol
+2 −2 src/interfaces/IERC721.sol
+4 −10 src/interfaces/IERC7540.sol
+2 −2 src/interfaces/IERC7575.sol
+3 −8 src/interfaces/IMulticall3.sol
+691 −1,380 src/safeconsole.sol
+2 −2 test/CommonBase.t.sol
+34 −5 test/Config.t.sol
+19 −1 test/LibVariable.t.sol
+2 −2 test/StdAssertions.t.sol
+24 −24 test/StdChains.t.sol
+19 −20 test/StdCheats.t.sol
+2 −2 test/StdConstants.t.sol
+3 −4 test/StdError.t.sol
+2 −2 test/StdJson.t.sol
+8 −8 test/StdMath.t.sol
+24 −27 test/StdStorage.t.sol
+2 −2 test/StdStyle.t.sol
+2 −2 test/StdToml.t.sol
+13 −13 test/StdUtils.t.sol
+3 −3 test/Vm.t.sol
+2 −4 test/compilation/CompilationScript.sol
+2 −4 test/compilation/CompilationScriptBase.sol
+2 −4 test/compilation/CompilationTest.sol
+2 −4 test/compilation/CompilationTestBase.sol