Skip to content

Commit

Permalink
feat: code dump
Browse files Browse the repository at this point in the history
In this commit:
- factories upgradability
- versioning
- some roles management
- small fixes and improvements here and there
  • Loading branch information
lekhovitsky committed Dec 27, 2024
1 parent 5464ebf commit 7654517
Show file tree
Hide file tree
Showing 24 changed files with 606 additions and 395 deletions.
Binary file removed .DS_Store
Binary file not shown.
18 changes: 13 additions & 5 deletions contracts/factories/AbstractFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ abstract contract AbstractFactory is AbstractDeployer, IFactory {
// ----------- //

constructor(address addressProvider_) AbstractDeployer(addressProvider_) {
marketConfiguratorFactory = _getContract(AP_MARKET_CONFIGURATOR_FACTORY, NO_VERSION_CONTROL);
marketConfiguratorFactory = _getAddressOrRevert(AP_MARKET_CONFIGURATOR_FACTORY, NO_VERSION_CONTROL);
}

// ------------- //
Expand Down Expand Up @@ -79,17 +79,25 @@ abstract contract AbstractFactory is AbstractDeployer, IFactory {
});
}

function _addToAccessList(address marketConfigurator, address target) internal view returns (Call memory) {
function _authorizeFactory(address marketConfigurator, address suite, address target)
internal
view
returns (Call memory)
{
return Call({
target: marketConfigurator,
callData: abi.encodeCall(IMarketConfigurator.addToAccessList, (target, address(this)))
callData: abi.encodeCall(IMarketConfigurator.authorizeFactory, (address(this), suite, target))
});
}

function _removeFromAccessList(address marketConfigurator, address target) internal view returns (Call memory) {
function _unauthorizeFactory(address marketConfigurator, address suite, address target)
internal
view
returns (Call memory)
{
return Call({
target: marketConfigurator,
callData: abi.encodeCall(IMarketConfigurator.removeFromAccessList, (target, address(this)))
callData: abi.encodeCall(IMarketConfigurator.unauthorizeFactory, (address(this), suite, target))
});
}
}
4 changes: 4 additions & 0 deletions contracts/factories/AbstractMarketFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ abstract contract AbstractMarketFactory is AbstractFactory, IMarketFactory {
return IPoolQuotaKeeperV3(quotaKeeper).gauge();
}

function _quotedTokens(address quotaKeeper) internal view returns (address[] memory) {
return IPoolQuotaKeeperV3(quotaKeeper).quotedTokens();
}

function _isQuotedToken(address quotaKeeper, address token) internal view returns (bool) {
return IPoolQuotaKeeperV3(quotaKeeper).isQuotedToken(token);
}
Expand Down
61 changes: 23 additions & 38 deletions contracts/factories/CreditFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
/// @param addressProvider_ Address provider contract address
constructor(address addressProvider_) AbstractFactory(addressProvider_) {
// TODO: introduce some kind of `StuffRegister` for account factories, bot lists and degen NFTs
weth = _tryGetContract(AP_WETH_TOKEN, NO_VERSION_CONTROL);
weth = _tryGetAddress(AP_WETH_TOKEN, NO_VERSION_CONTROL);
}

// ---------- //
Expand Down Expand Up @@ -121,8 +121,8 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
return DeployResult({
newContract: creditManager,
onInstallOps: CallBuilder.build(
_addToAccessList(msg.sender, creditConfigurator),
_addToAccessList(msg.sender, creditFacade),
_authorizeFactory(msg.sender, creditManager, creditConfigurator),
_authorizeFactory(msg.sender, creditManager, creditFacade),
_setCreditFacade(creditConfigurator, creditFacade, false),
_setLossLiquidator(creditConfigurator, lossLiquidator),
_setDebtLimits(creditConfigurator, params.minDebt, params.maxDebt)
Expand Down Expand Up @@ -168,28 +168,30 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
address newCreditConfigurator = _deployCreditConfigurator(msg.sender, creditManager);
return CallBuilder.build(
_upgradeCreditConfigurator(creditConfigurator, newCreditConfigurator),
_removeFromAccessList(msg.sender, creditConfigurator),
_addToAccessList(msg.sender, newCreditConfigurator)
_unauthorizeFactory(msg.sender, creditManager, creditConfigurator),
_authorizeFactory(msg.sender, creditManager, newCreditConfigurator)
);
} else if (selector == IConfigureActions.upgradeCreditFacade.selector) {
CreditFacadeParams memory params = abi.decode(callData[4:], (CreditFacadeParams));
address creditFacade = _creditFacade(creditManager);
address newCreditFacade = _deployCreditFacade(msg.sender, creditManager, params);
return CallBuilder.build(
_setCreditFacade(_creditConfigurator(creditManager), newCreditFacade, true),
_removeFromAccessList(msg.sender, creditFacade),
_addToAccessList(msg.sender, newCreditFacade)
_unauthorizeFactory(msg.sender, creditManager, creditFacade),
_authorizeFactory(msg.sender, creditManager, newCreditFacade)
);
} else if (selector == IConfigureActions.allowAdapter.selector) {
DeployParams memory params = abi.decode(callData[4:], (DeployParams));
address adapter = _deployAdapter(msg.sender, creditManager, params);
return CallBuilder.build(
_addToAccessList(msg.sender, adapter), _allowAdapter(_creditConfigurator(creditManager), adapter)
_authorizeFactory(msg.sender, creditManager, adapter),
_allowAdapter(_creditConfigurator(creditManager), adapter)
);
} else if (selector == IConfigureActions.forbidAdapter.selector) {
address adapter = abi.decode(callData[4:], (address));
return CallBuilder.build(
_removeFromAccessList(msg.sender, adapter), _forbidAdapter(_creditConfigurator(creditManager), adapter)
_authorizeFactory(msg.sender, creditManager, adapter),
_forbidAdapter(_creditConfigurator(creditManager), adapter)
);
} else if (
selector == IConfigureActions.setFees.selector
Expand Down Expand Up @@ -217,7 +219,8 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
if (selector == IEmergencyConfigureActions.forbidAdapter.selector) {
address adapter = abi.decode(callData[4:], (address));
return CallBuilder.build(
_removeFromAccessList(msg.sender, adapter), _forbidAdapter(_creditConfigurator(creditManager), adapter)
_unauthorizeFactory(msg.sender, creditManager, adapter),
_forbidAdapter(_creditConfigurator(creditManager), adapter)
);
} else if (
selector == IEmergencyConfigureActions.forbidBorrowing.selector
Expand Down Expand Up @@ -257,10 +260,9 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
params.name
);

return _deployByDomain({
domain: DOMAIN_CREDIT_MANAGER,
postfix: postfix,
version: version,
return _deployLatestPatch({
contractType: _getContractType(DOMAIN_CREDIT_MANAGER, postfix),
minorVersion: version,
constructorParams: constructorParams,
salt: bytes32(bytes20(marketConfigurator))
});
Expand All @@ -269,9 +271,9 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
function _deployCreditConfigurator(address marketConfigurator, address creditManager) internal returns (address) {
bytes memory constructorParams = abi.encode(creditManager);

return _deploy({
return _deployLatestPatch({
contractType: AP_CREDIT_CONFIGURATOR,
version: version,
minorVersion: version,
constructorParams: constructorParams,
salt: bytes32(bytes20(marketConfigurator))
});
Expand All @@ -287,9 +289,9 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
bytes memory constructorParams =
abi.encode(acl, creditManager, params.botList, weth, params.degenNFT, params.expirable);

return _deploy({
return _deployLatestPatch({
contractType: AP_CREDIT_FACADE,
version: version,
minorVersion: version,
constructorParams: constructorParams,
salt: bytes32(bytes20(marketConfigurator))
});
Expand All @@ -304,10 +306,9 @@ contract CreditFactory is AbstractFactory, ICreditFactory {

// NOTE: unlike other contracts, this might be deployed multiple times, so using the same salt
// can be an issue. Same thing can happen to rate keepers, IRMs, etc.
return _deployByDomain({
domain: DOMAIN_ADAPTER,
postfix: params.postfix,
version: version,
return _deployLatestPatch({
contractType: _getContractType(DOMAIN_ADAPTER, params.postfix),
minorVersion: version,
constructorParams: params.constructorParams,
salt: bytes32(bytes20(marketConfigurator))
});
Expand Down Expand Up @@ -361,22 +362,6 @@ contract CreditFactory is AbstractFactory, ICreditFactory {
return Call(creditConfigurator, abi.encodeCall(ICreditConfiguratorV3.forbidAdapter, adapter));
}

function _setFees(
address creditConfigurator,
uint16 feeLiquidation,
uint16 liquidationPremium,
uint16 feeLiquidationExpired,
uint16 liquidationPremiumExpired
) internal pure returns (Call memory) {
return Call(
creditConfigurator,
abi.encodeCall(
ICreditConfiguratorV3.setFees,
(feeLiquidation, liquidationPremium, feeLiquidationExpired, liquidationPremiumExpired)
)
);
}

function _setDebtLimits(address creditConfigurator, uint128 minDebt, uint128 maxDebt)
internal
pure
Expand Down
13 changes: 7 additions & 6 deletions contracts/factories/InterestRateModelFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,24 @@ contract InterestRateModelFactory is AbstractMarketFactory, IInterestRateModelFa
_validateDefaultConstructorParams(pool, params.constructorParams);
}

address interestRateModel = _deployByDomain({
domain: DOMAIN_IRM,
postfix: params.postfix,
version: version,
address interestRateModel = _deployLatestPatch({
contractType: _getContractType(DOMAIN_IRM, params.postfix),
minorVersion: version,
constructorParams: params.constructorParams,
salt: bytes32(bytes20(msg.sender))
});

return DeployResult({
newContract: interestRateModel,
onInstallOps: CallBuilder.build(_addToAccessList(msg.sender, interestRateModel))
onInstallOps: CallBuilder.build(_authorizeFactory(msg.sender, pool, interestRateModel))
});
}

// ------------ //
// MARKET HOOKS //
// ------------ //

function onUpdateInterestRateModel(address, address newInterestRateModel, address oldInterestRateModel)
function onUpdateInterestRateModel(address pool, address newInterestRateModel, address oldInterestRateModel)
external
view
override(AbstractMarketFactory, IMarketFactory)
Expand All @@ -71,6 +70,8 @@ contract InterestRateModelFactory is AbstractMarketFactory, IInterestRateModelFa
if (_isVotingContract(newInterestRateModel)) {
calls = calls.append(_setVotingContractStatus(newInterestRateModel, true));
}

calls = calls.append(_unauthorizeFactory(msg.sender, pool, oldInterestRateModel));
}

// ------------- //
Expand Down
23 changes: 18 additions & 5 deletions contracts/factories/LossLiquidatorFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
pragma solidity ^0.8.23;

import {IFactory} from "../interfaces/factories/IFactory.sol";
import {IMarketFactory} from "../interfaces/factories/IMarketFactory.sol";
import {ILossLiquidatorFactory} from "../interfaces/factories/ILossLiquidatorFactory.sol";
import {Call, DeployParams, DeployResult} from "../interfaces/Types.sol";

Expand Down Expand Up @@ -41,20 +42,32 @@ contract LossLiquidatorFactory is AbstractMarketFactory, ILossLiquidatorFactory
_validateDefaultConstructorParams(pool, params.constructorParams);
}

address lossLiquidator = _deployByDomain({
domain: DOMAIN_LOSS_LIQUIDATOR,
postfix: params.postfix,
version: version,
address lossLiquidator = _deployLatestPatch({
contractType: _getContractType(DOMAIN_LOSS_LIQUIDATOR, params.postfix),
minorVersion: version,
constructorParams: params.constructorParams,
salt: bytes32(bytes20(msg.sender))
});

return DeployResult({
newContract: lossLiquidator,
onInstallOps: CallBuilder.build(_addToAccessList(msg.sender, lossLiquidator))
onInstallOps: CallBuilder.build(_authorizeFactory(msg.sender, pool, lossLiquidator))
});
}

// ------------ //
// MARKET HOOKS //
// ------------ //

function onUpdateLossLiquidator(address pool, address, address oldLossLiquidator)
external
view
override(AbstractMarketFactory, IMarketFactory)
returns (Call[] memory calls)
{
calls = CallBuilder.build(_unauthorizeFactory(msg.sender, pool, oldLossLiquidator));
}

// ------------- //
// CONFIGURATION //
// ------------- //
Expand Down
17 changes: 8 additions & 9 deletions contracts/factories/PoolFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ contract PoolFactory is AbstractMarketFactory, IPoolFactory {
/// @notice Constructor
/// @param addressProvider_ Address provider contract address
constructor(address addressProvider_) AbstractFactory(addressProvider_) {
defaultInterestRateModel = _getContract(AP_DEFAULT_IRM, NO_VERSION_CONTROL);
defaultInterestRateModel = _getAddressOrRevert(AP_DEFAULT_IRM, NO_VERSION_CONTROL);
}

// ---------- //
Expand All @@ -97,8 +97,8 @@ contract PoolFactory is AbstractMarketFactory, IPoolFactory {
return DeployResult({
newContract: pool,
onInstallOps: CallBuilder.build(
_addToAccessList(msg.sender, pool),
_addToAccessList(msg.sender, quotaKeeper),
_authorizeFactory(msg.sender, pool, pool),
_authorizeFactory(msg.sender, pool, quotaKeeper),
_setQuotaKeeper(pool, quotaKeeper)
)
});
Expand Down Expand Up @@ -246,19 +246,18 @@ contract PoolFactory is AbstractMarketFactory, IPoolFactory {
acl, contractsRegister, underlying, treasury, defaultInterestRateModel, type(uint256).max, name, symbol
);
bytes32 salt = bytes32(bytes20(marketConfigurator));
return _deployByDomain({
domain: DOMAIN_POOL,
postfix: postfix,
version: version,
return _deployLatestPatch({
contractType: _getContractType(DOMAIN_POOL, postfix),
minorVersion: version,
constructorParams: constructorParams,
salt: salt
});
}

function _deployQuotaKeeper(address marketConfigurator, address pool) internal returns (address) {
return _deploy({
return _deployLatestPatch({
contractType: AP_POOL_QUOTA_KEEPER,
version: version,
minorVersion: version,
constructorParams: abi.encode(pool),
salt: bytes32(bytes20(marketConfigurator))
});
Expand Down
20 changes: 13 additions & 7 deletions contracts/factories/PriceOracleFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,24 @@ contract PriceOracleFactory is AbstractMarketFactory, IPriceOracleFactory {
/// @notice Constructor
/// @param addressProvider_ Address provider contract address
constructor(address addressProvider_) AbstractFactory(addressProvider_) {
priceFeedStore = _getContract(AP_PRICE_FEED_STORE, NO_VERSION_CONTROL);
priceFeedStore = _getAddressOrRevert(AP_PRICE_FEED_STORE, NO_VERSION_CONTROL);
}

// ---------- //
// DEPLOYMENT //
// ---------- //

function deployPriceOracle(address pool) external override onlyMarketConfigurators returns (DeployResult memory) {
address priceOracle = _deploy({
address priceOracle = _deployLatestPatch({
contractType: AP_PRICE_ORACLE,
version: version,
minorVersion: version,
constructorParams: abi.encode(_acl(pool)),
salt: bytes32(bytes20(msg.sender))
});

return DeployResult({
newContract: priceOracle,
onInstallOps: CallBuilder.build(_addToAccessList(msg.sender, priceOracle))
onInstallOps: CallBuilder.build(_authorizeFactory(msg.sender, pool, priceOracle))
});
}

Expand All @@ -94,14 +94,20 @@ contract PriceOracleFactory is AbstractMarketFactory, IPriceOracleFactory {
return _setPriceFeed(priceOracle, underlying, underlyingPriceFeed, false);
}

function onUpdatePriceOracle(address, address newPriceOracle, address oldPriceOracle)
function onUpdatePriceOracle(address pool, address newPriceOracle, address oldPriceOracle)
external
view
override(AbstractMarketFactory, IMarketFactory)
returns (Call[] memory calls)
{
// QUESTION: maybe migrate pool's tokens instead?
address[] memory tokens = IPriceOracleV3(oldPriceOracle).getTokens();
calls = CallBuilder.build(_unauthorizeFactory(msg.sender, pool, oldPriceOracle));

address underlying = _underlying(pool);
calls = calls.extend(
_setPriceFeed(newPriceOracle, underlying, _getPriceFeed(oldPriceOracle, underlying, false), false)
);

address[] memory tokens = _quotedTokens(_quotaKeeper(pool));
uint256 numTokens = tokens.length;
for (uint256 i; i < numTokens; ++i) {
// FIXME: reallocating the whole array is not the most optimal solution
Expand Down
Loading

0 comments on commit 7654517

Please sign in to comment.