diff --git a/.gitignore b/.gitignore index 482ba8e..f5b07b6 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,4 @@ dist # Forge output out cache +broadcast \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index c766bcd..0537f7d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,12 @@ -{ - "solidity.packageDefaultDependenciesContractsDirectory": "contracts", - "solidity.packageDefaultDependenciesDirectory": "node_modules", - "solidity.compileUsingRemoteVersion": "v0.8.22", - "solidity.formatter": "forge", - "[solidity]": { - "editor.defaultFormatter": "JuanBlanco.solidity", - "editor.formatOnSave": true, - "editor.tabSize": 4, - }, +{ + "solidity.packageDefaultDependenciesContractsDirectory": "contracts", + "solidity.packageDefaultDependenciesDirectory": "node_modules", + "solidity.compileUsingRemoteVersion": "v0.8.22", + "solidity.formatter": "forge", + "[solidity]": { + "editor.defaultFormatter": "JuanBlanco.solidity", + "editor.formatOnSave": true, + "editor.tabSize": 4 + }, + "editor.formatOnSave": true } diff --git a/contracts/factories/AbstractFactory.sol b/contracts/factories/AbstractFactory.sol index 0591343..72d30bd 100644 --- a/contracts/factories/AbstractFactory.sol +++ b/contracts/factories/AbstractFactory.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.17; import {APOwnerTrait} from "../traits/APOwnerTrait.sol"; -import {IAddressProviderV3} from "../interfaces/IAddressProviderV3.sol"; +import {IAddressProviderV3_1} from "../interfaces/IAddressProviderV3_1.sol"; import {AP_BYTECODE_REPOSITORY, NO_VERSION_CONTROL} from "../libraries/ContractLiterals.sol"; abstract contract AbstractFactory is APOwnerTrait { @@ -13,7 +13,7 @@ abstract contract AbstractFactory is APOwnerTrait { error CallerIsNotMarketConfiguratorException(); modifier marketConfiguratorOnly() { - if (IAddressProviderV3(addressProvider).isMarketConfigurator(msg.sender)) { + if (IAddressProviderV3_1(addressProvider).isMarketConfigurator(msg.sender)) { revert CallerIsNotMarketConfiguratorException(); } _; @@ -21,6 +21,6 @@ abstract contract AbstractFactory is APOwnerTrait { constructor(address _addressProvider) APOwnerTrait(_addressProvider) { bytecodeRepository = - IAddressProviderV3(_addressProvider).getAddressOrRevert(AP_BYTECODE_REPOSITORY, NO_VERSION_CONTROL); + IAddressProviderV3_1(_addressProvider).getAddressOrRevert(AP_BYTECODE_REPOSITORY, NO_VERSION_CONTROL); } } diff --git a/contracts/factories/MarketConfiguratorFactoryV3.sol b/contracts/factories/MarketConfiguratorFactoryV3.sol index d501f47..95ad120 100644 --- a/contracts/factories/MarketConfiguratorFactoryV3.sol +++ b/contracts/factories/MarketConfiguratorFactoryV3.sol @@ -8,7 +8,7 @@ import {AbstractFactory} from "./AbstractFactory.sol"; import {MarketConfigurator} from "../market/MarketConfigurator.sol"; import {ACL} from "../market/ACL.sol"; import {ContractsRegister} from "../market/ContractsRegister.sol"; -import {IAddressProviderV3} from "../interfaces/IAddressProviderV3.sol"; +import {IAddressProviderV3_1} from "../interfaces/IAddressProviderV3_1.sol"; import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol"; import {IBytecodeRepository} from "../interfaces/IBytecodeRepository.sol"; @@ -54,13 +54,13 @@ contract MarketConfiguratorFactoryV3 is AbstractFactory, IVersion { /// Makes market configurator contract owner acl.transferOwnership(_marketConfigurator); - IAddressProviderV3(addressProvider).addMarketConfigurator(_marketConfigurator); + IAddressProviderV3_1(addressProvider).addMarketConfigurator(_marketConfigurator); } function removeMarketConfigurator(address _marketConfigurator) external apOwnerOnly { if (MarketConfigurator(_marketConfigurator).pools().length != 0) { revert CantRemoveMarketConfiguratorWithExistingPoolsException(); } - IAddressProviderV3(addressProvider).removeMarketConfigurator(_marketConfigurator); + IAddressProviderV3_1(addressProvider).removeMarketConfigurator(_marketConfigurator); } } diff --git a/contracts/global/AddressProviderV3.sol b/contracts/global/AddressProviderV3.sol index 7a3d365..f731677 100644 --- a/contracts/global/AddressProviderV3.sol +++ b/contracts/global/AddressProviderV3.sol @@ -9,7 +9,7 @@ import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/I import {IMarketConfiguratorV3} from "../interfaces/IMarketConfiguratorV3.sol"; import {IContractsRegister} from "../interfaces/IContractsRegister.sol"; -import {IAddressProviderV3} from "../interfaces/IAddressProviderV3.sol"; +import {IAddressProviderV3_1, ContractValue} from "../interfaces/IAddressProviderV3_1.sol"; import { AddressNotFoundException, CallerNotConfiguratorException @@ -29,9 +29,14 @@ import { import {LibString} from "@solady/utils/LibString.sol"; +struct ContractKey { + string key; + uint256 version; +} + /// @title Address provider V3 /// @notice Stores addresses of important contracts -contract AddressProviderV3_1 is Ownable2Step, IAddressProviderV3 { +contract AddressProviderV3_1 is Ownable2Step, IAddressProviderV3_1 { using EnumerableSet for EnumerableSet.AddressSet; // using LibString for string; using LibString for bytes32; @@ -55,6 +60,8 @@ contract AddressProviderV3_1 is Ownable2Step, IAddressProviderV3 { mapping(string => uint256) public latestVersions; + ContractKey[] internal contractKeys; + modifier marketConfiguratorFactoryOnly() { if (msg.sender != getAddressOrRevert(AP_MARKET_CONFIGURATOR_FACTORY, NO_VERSION_CONTROL)) { revert MarketConfiguratorsOnlyException(); @@ -123,6 +130,7 @@ contract AddressProviderV3_1 is Ownable2Step, IAddressProviderV3 { if (_version > latestVersion) { latestVersions[key] = _version; } + contractKeys.push(ContractKey(key, _version)); emit SetAddress(key, value, _version); } @@ -181,7 +189,17 @@ contract AddressProviderV3_1 is Ownable2Step, IAddressProviderV3 { return marketConfigurator; } - function owner() public view override(Ownable, IAddressProviderV3) returns (address) { + function owner() public view override(Ownable, IAddressProviderV3_1) returns (address) { return Ownable.owner(); } + + function getAllSavedContracts() external view returns (ContractValue[] memory) { + ContractValue[] memory result = new ContractValue[](contractKeys.length); + for (uint256 i = 0; i < contractKeys.length; i++) { + result[i] = ContractValue( + contractKeys[i].key, addresses[contractKeys[i].key][contractKeys[i].version], contractKeys[i].version + ); + } + return result; + } } diff --git a/contracts/interfaces/IAddressProviderV3Leagcy.sol b/contracts/interfaces/IAddressProviderV3Leagcy.sol index e69de29..8b13789 100644 --- a/contracts/interfaces/IAddressProviderV3Leagcy.sol +++ b/contracts/interfaces/IAddressProviderV3Leagcy.sol @@ -0,0 +1 @@ + diff --git a/contracts/interfaces/IAddressProviderV3.sol b/contracts/interfaces/IAddressProviderV3_1.sol similarity index 70% rename from contracts/interfaces/IAddressProviderV3.sol rename to contracts/interfaces/IAddressProviderV3_1.sol index 7a7cde2..9e1c6c3 100644 --- a/contracts/interfaces/IAddressProviderV3.sol +++ b/contracts/interfaces/IAddressProviderV3_1.sol @@ -5,24 +5,11 @@ pragma solidity ^0.8.17; import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol"; -// uint256 constant NO_VERSION_CONTROL = 0; - -// // string constant AP_CONTRACTS_REGISTER = "CONTRACTS_REGISTER"; -// // string constant AP_ACL = "ACL"; -// string constant AP_PRICE_ORACLE = "PRICE_ORACLE"; -// string constant AP_ACCOUNT_FACTORY = "ACCOUNT_FACTORY"; - -// // string constant AP_DATA_COMPRESSOR = "DATA_COMPRESSOR"; -// string constant AP_TREASURY = "TREASURY"; -// string constant AP_GEAR_TOKEN = "GEAR_TOKEN"; -// string constant AP_WETH_TOKEN = "WETH_TOKEN"; -// // string constant AP_WETH_GATEWAY = "WETH_GATEWAY"; -// string constant AP_ROUTER = "ROUTER"; -// string constant AP_BOT_LIST = "BOT_LIST"; -// string constant AP_GEAR_STAKING = "GEAR_STAKING"; -// string constant AP_ZAPPER_REGISTER = "ZAPPER_REGISTER"; - -// string constant AP_BYTECODE_REPOSITORY = "BYTECODE_REPOSITORY"; +struct ContractValue { + string key; + address value; + uint256 version; +} interface IAddressProviderV3Events { /// @notice Emitted when an address is set for a contract key @@ -36,7 +23,7 @@ interface IAddressProviderV3Events { } /// @title Address provider V3 interface -interface IAddressProviderV3 is IAddressProviderV3Events, IVersion { +interface IAddressProviderV3_1 is IAddressProviderV3Events, IVersion { function owner() external view returns (address); function addresses(string memory key, uint256 _version) external view returns (address); @@ -45,6 +32,8 @@ interface IAddressProviderV3 is IAddressProviderV3Events, IVersion { function getAddressOrRevert(bytes32 key, uint256 _version) external view returns (address); + function getAllSavedContracts() external view returns (ContractValue[] memory); + function getLatestAddressOrRevert(string memory key) external view returns (address); function getLatestAddressOrRevert(bytes32 _key) external view virtual returns (address result); diff --git a/contracts/interfaces/IMarketConfiguratorV3.sol b/contracts/interfaces/IMarketConfiguratorV3.sol index e661674..f605d52 100644 --- a/contracts/interfaces/IMarketConfiguratorV3.sol +++ b/contracts/interfaces/IMarketConfiguratorV3.sol @@ -29,4 +29,8 @@ interface IMarketConfiguratorV3 is IVersion { function adapterFactory() external view returns (address); function controller() external view returns (address); + + function pools() external view returns (address[] memory); + + function owner() external view returns (address); } diff --git a/contracts/market/MarketConfigurator.sol b/contracts/market/MarketConfigurator.sol index 866a39e..1b40cd5 100644 --- a/contracts/market/MarketConfigurator.sol +++ b/contracts/market/MarketConfigurator.sol @@ -27,7 +27,7 @@ import {IContractsRegister} from "../interfaces/IContractsRegister.sol"; import {IPoolV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolV3.sol"; import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol"; -import {IAddressProviderV3} from "../interfaces/IAddressProviderV3.sol"; +import {IAddressProviderV3_1} from "../interfaces/IAddressProviderV3_1.sol"; import {IContractsRegister} from "../interfaces/IContractsRegister.sol"; import {IACL} from "../interfaces/IACL.sol"; @@ -121,11 +121,12 @@ contract MarketConfigurator is ACLTrait, IMarketConfiguratorV3 { name = _name; treasury = _treasury; - interestModelFactory = IAddressProviderV3(_addressProvider).getLatestAddressOrRevert(AP_INTEREST_MODEL_FACTORY); - poolFactory = IAddressProviderV3(_addressProvider).getLatestAddressOrRevert(AP_POOL_FACTORY); - creditFactory = IAddressProviderV3(_addressProvider).getLatestAddressOrRevert(AP_CREDIT_FACTORY); - priceOracleFactory = IAddressProviderV3(_addressProvider).getLatestAddressOrRevert(AP_PRICE_ORACLE_FACTORY); - adapterFactory = IAddressProviderV3(_addressProvider).getLatestAddressOrRevert(AP_ADAPTER_FACTORY); + interestModelFactory = + IAddressProviderV3_1(_addressProvider).getLatestAddressOrRevert(AP_INTEREST_MODEL_FACTORY); + poolFactory = IAddressProviderV3_1(_addressProvider).getLatestAddressOrRevert(AP_POOL_FACTORY); + creditFactory = IAddressProviderV3_1(_addressProvider).getLatestAddressOrRevert(AP_CREDIT_FACTORY); + priceOracleFactory = IAddressProviderV3_1(_addressProvider).getLatestAddressOrRevert(AP_PRICE_ORACLE_FACTORY); + adapterFactory = IAddressProviderV3_1(_addressProvider).getLatestAddressOrRevert(AP_ADAPTER_FACTORY); controller = address(new ControllerTimelockV3(_acl, _vetoAdmin)); } @@ -207,14 +208,14 @@ contract MarketConfigurator is ACLTrait, IMarketConfiguratorV3 { address creditManager = CreditFactoryV3(creditFactory).deployCreditManager( pool, - IAddressProviderV3(addressProvider).getLatestAddressOrRevert(AP_ACCOUNT_FACTORY), + IAddressProviderV3_1(addressProvider).getLatestAddressOrRevert(AP_ACCOUNT_FACTORY), priceOracles[pool], _name, latestVersions[AP_CREDIT_MANAGER], // TODO: Fee token case(?) salt ); - IAddressProviderV3(addressProvider).registerCreditManager(creditManager); + IAddressProviderV3_1(addressProvider).registerCreditManager(creditManager); bool expirable = expirationDate != 0; @@ -238,7 +239,7 @@ contract MarketConfigurator is ACLTrait, IMarketConfiguratorV3 { address pqk = IPoolV3(pool).poolQuotaKeeper(); IPoolQuotaKeeperV3(pqk).addCreditManager(creditManager); - IAddressProviderV3(addressProvider).registerCreditManager(creditManager); + IAddressProviderV3_1(addressProvider).registerCreditManager(creditManager); } function updateCreditFacade(address creditManager, address _degenNFT, bool _expirable, uint256 _version) @@ -397,13 +398,13 @@ contract MarketConfigurator is ACLTrait, IMarketConfiguratorV3 { emit SetName(_newName); } - // - function pools() external view virtual returns (address[] memory) { + // returns all pools + function pools() external view virtual override returns (address[] memory) { return IContractsRegister(acl).getPools(); } - // - function owner() external view returns (address) { + // returns owner + function owner() external view override returns (address) { return IACL(acl).owner(); } } diff --git a/contracts/market/MarketConfiguratorLegacy.sol b/contracts/market/MarketConfiguratorLegacy.sol index de68742..a821278 100644 --- a/contracts/market/MarketConfiguratorLegacy.sol +++ b/contracts/market/MarketConfiguratorLegacy.sol @@ -28,7 +28,7 @@ import {IPoolV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolV3.so import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol"; import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol"; -import {IAddressProviderV3} from "../interfaces/IAddressProviderV3.sol"; +import {IAddressProviderV3_1} from "../interfaces/IAddressProviderV3_1.sol"; import {IContractsRegister} from "../interfaces/IContractsRegister.sol"; import {IACL} from "../interfaces/IACL.sol"; @@ -82,7 +82,7 @@ contract MarketConfiguratorLegacy is MarketConfigurator { address pool = _pools[i]; priceOracles[pool] = priceOracle; - IAddressProviderV3(addressProvider).registerPool(pool); + IAddressProviderV3_1(addressProvider).registerPool(pool); emit CreateMarket(pool, IPoolV3(pool).asset(), IPoolV3(pool).name(), IPoolV3(pool).symbol()); } diff --git a/contracts/traits/APOwnerTrait.sol b/contracts/traits/APOwnerTrait.sol index a0769f9..f984235 100644 --- a/contracts/traits/APOwnerTrait.sol +++ b/contracts/traits/APOwnerTrait.sol @@ -3,7 +3,7 @@ // (c) Gearbox Foundation, 2024. pragma solidity ^0.8.17; -import {IAddressProviderV3} from "../interfaces/IAddressProviderV3.sol"; +import {IAddressProviderV3_1} from "../interfaces/IAddressProviderV3_1.sol"; import {CallerNotConfiguratorException} from "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol"; import {SanityCheckTrait} from "@gearbox-protocol/core-v3/contracts/traits/SanityCheckTrait.sol"; @@ -28,7 +28,7 @@ abstract contract APOwnerTrait is SanityCheckTrait { /// @dev Reverts if the caller is not the configurator /// @dev Used to cut contract size on modifiers function _ensureCallerIsConfigurator() internal view { - if (IAddressProviderV3(addressProvider).owner() != msg.sender) { + if (IAddressProviderV3_1(addressProvider).owner() != msg.sender) { revert CallerNotConfiguratorException(); } } diff --git a/remappings.txt b/remappings.txt index b86ce0a..92ee351 100644 --- a/remappings.txt +++ b/remappings.txt @@ -2,4 +2,5 @@ ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ @1inch/=lib/@1inch/ @openzeppelin/=lib/@openzeppelin/ -@gearbox-protocol=lib/@gearbox-protocol/ \ No newline at end of file +@gearbox-protocol=lib/@gearbox-protocol/ +@solady=lib/@solady/src/ \ No newline at end of file diff --git a/script/Migrate.sol b/script/Migrate.sol index 716e2a5..5f08bd2 100644 --- a/script/Migrate.sol +++ b/script/Migrate.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.17; import "forge-std/Script.sol"; -import {IAddressProviderV3} from "../contracts/interfaces/IAddressProviderV3.sol"; +import {IAddressProviderV3_1} from "../contracts/interfaces/IAddressProviderV3_1.sol"; import {AddressProviderV3_1} from "../contracts/global/AddressProviderV3.sol"; import { @@ -89,7 +89,8 @@ contract Migrate is Script { _addressProvider.transferOwnership(IACL(acl).owner()); /// AddressProvider migration - APMigration[16] memory migrations = [ + APMigration[17] memory migrations = [ + APMigration({name: AP_GEAR_TOKEN, version: 0}), APMigration({name: AP_WETH_TOKEN, version: 0}), APMigration({name: AP_GEAR_TOKEN, version: 0}), APMigration({name: AP_BOT_LIST, version: 300}), @@ -111,11 +112,13 @@ contract Migrate is Script { uint256 len = migrations.length; for (uint256 i; i < len; i++) { - string memory key = string(abi.encodePacked(migrations[i].name)); + string memory key = migrations[i].name.fromSmallString(); try IAddressProviderV3Legacy(oldAddressProvider).getAddressOrRevert( migrations[i].name, migrations[i].version ) returns (address oldAddress) { + console.log("migrating", key, oldAddress); + _addressProvider.setAddress({ key: key, value: oldAddress,