Skip to content
This repository was archived by the owner on Apr 2, 2026. It is now read-only.

Commit 8cb63b7

Browse files
committed
Merge branch 'next' of github.com:Gearbox-protocol/governance into next
2 parents e938f32 + 1df5e22 commit 8cb63b7

20 files changed

Lines changed: 301 additions & 185 deletions

contracts/factories/AbstractFactory.sol

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
// (c) Gearbox Foundation, 2024.
44
pragma solidity ^0.8.23;
55

6-
import {IVotingContract} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVotingContract.sol";
7-
import {VotingContractStatus} from "@gearbox-protocol/core-v3/contracts/interfaces/IGearStakingV3.sol";
8-
96
import {AbstractDeployer} from "../helpers/AbstractDeployer.sol";
107

118
import {IFactory} from "../interfaces/factories/IFactory.sol";
@@ -16,28 +13,12 @@ import {Call} from "../interfaces/Types.sol";
1613
import {AP_MARKET_CONFIGURATOR_FACTORY, NO_VERSION_CONTROL} from "../libraries/ContractLiterals.sol";
1714

1815
abstract contract AbstractFactory is AbstractDeployer, IFactory {
19-
// --------------- //
20-
// STATE VARIABLES //
21-
// --------------- //
22-
23-
address public immutable override marketConfiguratorFactory;
24-
25-
// --------- //
26-
// MODIFIERS //
27-
// --------- //
28-
2916
modifier onlyMarketConfigurators() {
3017
_ensureCallerIsMarketConfigurator();
3118
_;
3219
}
3320

34-
// ----------- //
35-
// CONSTRUCTOR //
36-
// ----------- //
37-
38-
constructor(address addressProvider_) AbstractDeployer(addressProvider_) {
39-
marketConfiguratorFactory = _getAddressOrRevert(AP_MARKET_CONFIGURATOR_FACTORY, NO_VERSION_CONTROL);
40-
}
21+
constructor(address addressProvider_) AbstractDeployer(addressProvider_) {}
4122

4223
// ------------- //
4324
// CONFIGURATION //
@@ -56,29 +37,13 @@ abstract contract AbstractFactory is AbstractDeployer, IFactory {
5637
// --------- //
5738

5839
function _ensureCallerIsMarketConfigurator() internal view {
40+
// QUESTION: can MCF be upgraded?
41+
address marketConfiguratorFactory = _getAddressOrRevert(AP_MARKET_CONFIGURATOR_FACTORY, NO_VERSION_CONTROL);
5942
if (IMarketConfiguratorFactory(marketConfiguratorFactory).isMarketConfigurator(msg.sender)) {
6043
revert CallerIsNotMarketConfiguratorException(msg.sender);
6144
}
6245
}
6346

64-
function _isVotingContract(address votingContract) internal view returns (bool) {
65-
try IVotingContract(votingContract).voter() returns (address) {
66-
return true;
67-
} catch {
68-
return false;
69-
}
70-
}
71-
72-
function _setVotingContractStatus(address votingContract, bool allowed) internal view returns (Call memory) {
73-
return Call({
74-
target: marketConfiguratorFactory,
75-
callData: abi.encodeCall(
76-
IMarketConfiguratorFactory.setVotingContractStatus,
77-
(votingContract, allowed ? VotingContractStatus.ALLOWED : VotingContractStatus.UNVOTE_ONLY)
78-
)
79-
});
80-
}
81-
8247
function _authorizeFactory(address marketConfigurator, address suite, address target)
8348
internal
8449
view

contracts/factories/InterestRateModelFactory.sol

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ import {AbstractFactory} from "./AbstractFactory.sol";
1515
import {AbstractMarketFactory} from "./AbstractMarketFactory.sol";
1616

1717
contract InterestRateModelFactory is AbstractMarketFactory, IInterestRateModelFactory {
18-
using CallBuilder for Call[];
19-
2018
/// @notice Contract version
2119
uint256 public constant override version = 3_10;
2220

@@ -58,20 +56,13 @@ contract InterestRateModelFactory is AbstractMarketFactory, IInterestRateModelFa
5856
// MARKET HOOKS //
5957
// ------------ //
6058

61-
function onUpdateInterestRateModel(address pool, address newInterestRateModel, address oldInterestRateModel)
59+
function onUpdateInterestRateModel(address pool, address, address oldInterestRateModel)
6260
external
6361
view
6462
override(AbstractMarketFactory, IMarketFactory)
65-
returns (Call[] memory calls)
63+
returns (Call[] memory)
6664
{
67-
if (_isVotingContract(oldInterestRateModel)) {
68-
calls = calls.append(_setVotingContractStatus(oldInterestRateModel, false));
69-
}
70-
if (_isVotingContract(newInterestRateModel)) {
71-
calls = calls.append(_setVotingContractStatus(newInterestRateModel, true));
72-
}
73-
74-
calls = calls.append(_unauthorizeFactory(msg.sender, pool, oldInterestRateModel));
65+
return CallBuilder.build(_unauthorizeFactory(msg.sender, pool, oldInterestRateModel));
7566
}
7667

7768
// ------------- //
@@ -82,7 +73,7 @@ contract InterestRateModelFactory is AbstractMarketFactory, IInterestRateModelFa
8273
external
8374
view
8475
override(AbstractFactory, IFactory)
85-
returns (Call[] memory calls)
76+
returns (Call[] memory)
8677
{
8778
return CallBuilder.build(Call(_interestRateModel(pool), callData));
8879
}

contracts/factories/PoolFactory.sol

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import {AbstractFactory} from "./AbstractFactory.sol";
2929
import {AbstractMarketFactory} from "./AbstractMarketFactory.sol";
3030

3131
interface IConfigureActions {
32-
function setWithdrawFee(uint256 fee) external;
3332
function setTotalDebtLimit(uint256 limit) external;
3433
function setCreditManagerDebtLimit(address creditManager, uint256 limit) external;
3534
function setTokenLimit(address token, uint96 limit) external;
@@ -110,9 +109,9 @@ contract PoolFactory is AbstractMarketFactory, IPoolFactory {
110109
external
111110
view
112111
override(AbstractMarketFactory, IMarketFactory)
113-
returns (Call[] memory calls)
112+
returns (Call[] memory)
114113
{
115-
calls = CallBuilder.build(
114+
return CallBuilder.build(
116115
_setInterestRateModel(pool, interestRateModel), _setRateKeeper(_quotaKeeper(pool), rateKeeper)
117116
);
118117
}
@@ -121,13 +120,13 @@ contract PoolFactory is AbstractMarketFactory, IPoolFactory {
121120
external
122121
view
123122
override(AbstractMarketFactory, IMarketFactory)
124-
returns (Call[] memory calls)
123+
returns (Call[] memory)
125124
{
126125
if (IPoolV3(pool).totalBorrowed() != 0) {
127126
revert CantShutdownMarketWithNonZeroDebtException(pool);
128127
}
129128

130-
calls = CallBuilder.build(_setTotalDebtLimit(pool, 0), _setWithdrawFee(pool, 0));
129+
return CallBuilder.build(_setTotalDebtLimit(pool, 0));
131130
}
132131

133132
function onCreateCreditSuite(address creditManager)
@@ -188,8 +187,7 @@ contract PoolFactory is AbstractMarketFactory, IPoolFactory {
188187
{
189188
bytes4 selector = bytes4(callData);
190189
if (
191-
selector == IConfigureActions.setWithdrawFee.selector
192-
|| selector == IConfigureActions.setTotalDebtLimit.selector
190+
selector == IConfigureActions.setTotalDebtLimit.selector
193191
|| selector == IConfigureActions.setCreditManagerDebtLimit.selector
194192
|| selector == IConfigureActions.pause.selector || selector == IConfigureActions.unpause.selector
195193
) {
@@ -281,10 +279,6 @@ contract PoolFactory is AbstractMarketFactory, IPoolFactory {
281279
return Call(pool, abi.encodeCall(IPoolV3.setCreditManagerDebtLimit, (creditManager, limit)));
282280
}
283281

284-
function _setWithdrawFee(address pool, uint256 fee) internal pure returns (Call memory) {
285-
return Call(pool, abi.encodeCall(IPoolV3.setWithdrawFee, (fee)));
286-
}
287-
288282
function _setRateKeeper(address quotaKeeper, address rateKeeper) internal pure returns (Call memory) {
289283
return Call(quotaKeeper, abi.encodeCall(IPoolQuotaKeeperV3.setGauge, (rateKeeper)));
290284
}

contracts/factories/RateKeeperFactory.sol

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ contract RateKeeperFactory is AbstractMarketFactory, IRateKeeperFactory {
8282
override(AbstractMarketFactory, IMarketFactory)
8383
returns (Call[] memory)
8484
{
85-
return _installRateKeeper(rateKeeper, _getRateKeeperType(rateKeeper));
85+
if (_getRateKeeperType(rateKeeper) == "RATE_KEEPER::GAUGE") {
86+
return CallBuilder.build(_setFrozenEpoch(rateKeeper, false));
87+
}
88+
return CallBuilder.build();
8689
}
8790

8891
function onShutdownMarket(address pool)
@@ -92,7 +95,10 @@ contract RateKeeperFactory is AbstractMarketFactory, IRateKeeperFactory {
9295
returns (Call[] memory)
9396
{
9497
address rateKeeper = _rateKeeper(_quotaKeeper(pool));
95-
return _uninstallRateKeeper(rateKeeper, _getRateKeeperType(rateKeeper));
98+
if (_getRateKeeperType(rateKeeper) == "RATE_KEEPER::GAUGE") {
99+
return CallBuilder.build(_setFrozenEpoch(rateKeeper, true));
100+
}
101+
return CallBuilder.build();
96102
}
97103

98104
function onUpdateRateKeeper(address pool, address newRateKeeper, address oldRateKeeper)
@@ -108,11 +114,13 @@ contract RateKeeperFactory is AbstractMarketFactory, IRateKeeperFactory {
108114
for (uint256 i; i < numTokens; ++i) {
109115
calls[i] = _addToken(newRateKeeper, tokens[i], type_);
110116
}
111-
calls = calls.extend(
112-
_uninstallRateKeeper(oldRateKeeper, _getRateKeeperType(oldRateKeeper)).extend(
113-
_installRateKeeper(newRateKeeper, type_)
114-
).append(_unauthorizeFactory(msg.sender, pool, oldRateKeeper))
115-
);
117+
if (_getRateKeeperType(oldRateKeeper) == "RATE_KEEPER::GAUGE") {
118+
calls = calls.append(_setFrozenEpoch(oldRateKeeper, true));
119+
}
120+
if (type_ == "RATE_KEEPER::GAUGE") {
121+
calls = calls.append(_setFrozenEpoch(oldRateKeeper, false));
122+
}
123+
calls = calls.append(_unauthorizeFactory(msg.sender, pool, oldRateKeeper));
116124
}
117125

118126
function onAddToken(address pool, address token, address)
@@ -149,44 +157,28 @@ contract RateKeeperFactory is AbstractMarketFactory, IRateKeeperFactory {
149157
try IRateKeeper(rateKeeper).contractType() returns (bytes32 type_) {
150158
return type_;
151159
} catch {
152-
return "RK_GAUGE";
160+
return "RATE_KEEPER::GAUGE";
153161
}
154162
}
155163

156164
function _isForbiddenConfigurationCall(address rateKeeper, bytes4 selector) internal view returns (bool) {
157-
if (_getRateKeeperType(rateKeeper) == "RK_GAUGE") {
165+
if (_getRateKeeperType(rateKeeper) == "RATE_KEEPER::GAUGE") {
158166
return selector == IRateKeeper.addToken.selector || selector == IGaugeV3.addQuotaToken.selector
159167
|| selector == IGaugeV3.setFrozenEpoch.selector || selector == bytes4(keccak256("setController(address)"));
160168
}
161169
return selector == IRateKeeper.addToken.selector;
162170
}
163171

164-
function _installRateKeeper(address rateKeeper, bytes32 type_) internal view returns (Call[] memory calls) {
165-
if (type_ == "RK_GAUGE") {
166-
calls = CallBuilder.build(Call(rateKeeper, abi.encodeCall(IGaugeV3.setFrozenEpoch, false)));
167-
}
168-
169-
if (_isVotingContract(rateKeeper)) {
170-
calls = calls.append(_setVotingContractStatus(rateKeeper, true));
171-
}
172-
}
173-
174-
function _uninstallRateKeeper(address rateKeeper, bytes32 type_) internal view returns (Call[] memory calls) {
175-
if (type_ == "RK_GAUGE") {
176-
calls = CallBuilder.build(Call(rateKeeper, abi.encodeCall(IGaugeV3.setFrozenEpoch, true)));
177-
}
178-
179-
if (_isVotingContract(rateKeeper)) {
180-
calls = calls.append(_setVotingContractStatus(rateKeeper, false));
181-
}
182-
}
183-
184172
function _addToken(address rateKeeper, address token, bytes32 type_) internal pure returns (Call memory) {
185173
return Call(
186174
rateKeeper,
187-
type_ == "RK_GAUGE"
175+
type_ == "RATE_KEEPER::GAUGE"
188176
? abi.encodeCall(IGaugeV3.addQuotaToken, (token, 1, 1))
189177
: abi.encodeCall(IRateKeeper.addToken, token)
190178
);
191179
}
180+
181+
function _setFrozenEpoch(address gauge, bool status) internal pure returns (Call memory) {
182+
return Call(gauge, abi.encodeCall(IGaugeV3.setFrozenEpoch, status));
183+
}
192184
}

contracts/helpers/AbstractDeployer.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ abstract contract AbstractDeployer {
3939

4040
function _getContractType(bytes32 domain, bytes32 postfix) internal pure returns (bytes32) {
4141
if (postfix == 0) return domain;
42-
return string.concat(domain.fromSmallString(), "_", postfix.fromSmallString()).toSmallString();
42+
return string.concat(domain.fromSmallString(), "::", postfix.fromSmallString()).toSmallString();
4343
}
4444

4545
function _deploy(bytes32 contractType, uint256 version, bytes memory constructorParams, bytes32 salt)

contracts/helpers/DefaultIRM.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {IInterestRateModel} from "@gearbox-protocol/core-v3/contracts/interfaces
77

88
contract DefaultIRM is IInterestRateModel {
99
uint256 public constant override version = 3_10;
10-
bytes32 public constant override contractType = "IRM_DEFAULT";
10+
bytes32 public constant override contractType = "IRM::DEFAULT";
1111

1212
function calcBorrowRate(uint256, uint256, bool) external pure override returns (uint256) {
1313
return 0;

contracts/helpers/DefaultLossPolicy.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {ACLTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLTrait.sol"
77

88
contract DefaultLossPolicy is ACLTrait {
99
uint256 public constant version = 3_10;
10-
bytes32 public constant contractType = "LOSS_POLICY_DEFAULT";
10+
bytes32 public constant contractType = "LOSS_POLICY::DEFAULT";
1111

1212
bool public enabled;
1313

contracts/interfaces/IMarketConfigurator.sol

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ interface IMarketConfigurator is IVersion {
4141
function emergencyAdmin() external view returns (address);
4242

4343
function addressProvider() external view returns (address);
44-
function marketConfiguratorFactory() external view returns (address);
4544
function acl() external view returns (address);
4645
function contractsRegister() external view returns (address);
4746
function treasury() external view returns (address);

contracts/interfaces/IMarketConfiguratorFactory.sol

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,28 @@
44
pragma solidity ^0.8.23;
55

66
import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
7-
import {VotingContractStatus} from "@gearbox-protocol/core-v3/contracts/interfaces/IGearStakingV3.sol";
87

98
interface IMarketConfiguratorFactory is IVersion {
109
event CreateMarketConfigurator(address indexed marketConfigurator, string name);
1110
event ShutdownMarketConfigurator(address indexed marketConfigurator);
1211

13-
error AddressIsNotMarketConfiguratorException();
12+
error AddressIsNotMarketConfiguratorException(address addr);
13+
error CallerIsNotCrossChainGovernanceException(address caller);
1414
error CallerIsNotMarketConfiguratorException(address caller);
1515
error CallerIsNotMarketConfiguratorAdminException(address caller);
1616
error CantShutdownMarketConfiguratorException();
17+
error MarketConfiguratorIsAlreadyAddedException(address marketConfigurator);
18+
error MarketConfiguratorIsAlreadyShutdownException(address marketConfigruator);
1719

1820
function isMarketConfigurator(address account) external view returns (bool);
1921
function getMarketConfigurators() external view returns (address[] memory);
2022
function getShutdownMarketConfigurators() external view returns (address[] memory);
21-
function createMarketConfigurator(string calldata name) external returns (address marketConfigurator);
23+
function createMarketConfigurator(
24+
address admin,
25+
address emergencyAdmin,
26+
string calldata curatorName,
27+
bool deployGovernor
28+
) external returns (address marketConfigurator);
2229
function shutdownMarketConfigurator(address marketConfigurator) external;
23-
24-
function configureGearStaking(bytes calldata data) external;
25-
function setVotingContractStatus(address votingContract, VotingContractStatus status) external;
30+
function addMarketConfigurator(address marketConfigurator) external;
2631
}

0 commit comments

Comments
 (0)