2025-12-18 13:07:35 +08:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
pragma solidity ^0.8.0;
|
|
|
|
|
|
|
|
|
|
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
|
|
|
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
|
|
|
|
|
|
|
|
import "./ConfiguratorStorage.sol";
|
|
|
|
|
import "./LendingFactory.sol";
|
|
|
|
|
|
|
|
|
|
contract Configurator is
|
|
|
|
|
ConfiguratorStorage,
|
|
|
|
|
UUPSUpgradeable,
|
|
|
|
|
OwnableUpgradeable
|
|
|
|
|
{
|
|
|
|
|
event SetFactory(address indexed lendingProxy, address indexed oldFactory, address indexed newFactory);
|
|
|
|
|
event SetConfiguration(address indexed lendingProxy, Configuration oldConfiguration, Configuration newConfiguration);
|
|
|
|
|
event AddAsset(address indexed lendingProxy, AssetConfig assetConfig);
|
|
|
|
|
event UpdateAsset(address indexed lendingProxy, AssetConfig oldAssetConfig, AssetConfig newAssetConfig);
|
|
|
|
|
event LendingDeployed(address indexed lendingProxy, address indexed newLending);
|
|
|
|
|
|
|
|
|
|
error AlreadyInitialized();
|
|
|
|
|
error AssetDoesNotExist();
|
|
|
|
|
error ConfigurationAlreadyExists();
|
|
|
|
|
error InvalidAddress();
|
|
|
|
|
|
|
|
|
|
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
|
|
|
constructor() {
|
|
|
|
|
_disableInitializers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function initialize() external initializer {
|
|
|
|
|
__UUPSUpgradeable_init();
|
|
|
|
|
__Ownable_init(msg.sender);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
|
|
|
|
|
|
|
|
|
function setFactory(address lendingProxy, address newFactory) external onlyOwner {
|
|
|
|
|
if (newFactory == address(0)) revert InvalidAddress();
|
|
|
|
|
|
|
|
|
|
address oldFactory = factory[lendingProxy];
|
|
|
|
|
factory[lendingProxy] = newFactory;
|
|
|
|
|
emit SetFactory(lendingProxy, oldFactory, newFactory);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function setConfiguration(address lendingProxy, Configuration calldata newConfiguration)
|
|
|
|
|
external
|
|
|
|
|
onlyOwner
|
|
|
|
|
{
|
|
|
|
|
Configuration memory oldConfiguration = configuratorParams[lendingProxy];
|
|
|
|
|
|
|
|
|
|
if (oldConfiguration.baseToken != address(0) &&
|
2025-12-29 15:38:25 +08:00
|
|
|
oldConfiguration.baseToken != newConfiguration.baseToken)
|
2025-12-18 13:07:35 +08:00
|
|
|
revert ConfigurationAlreadyExists();
|
|
|
|
|
|
|
|
|
|
delete configuratorParams[lendingProxy];
|
|
|
|
|
|
|
|
|
|
configuratorParams[lendingProxy].baseToken = newConfiguration.baseToken;
|
2025-12-24 16:41:26 +08:00
|
|
|
configuratorParams[lendingProxy].lendingPriceSource = newConfiguration.lendingPriceSource;
|
2025-12-18 13:07:35 +08:00
|
|
|
configuratorParams[lendingProxy].supplyKink = newConfiguration.supplyKink;
|
|
|
|
|
configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeLow = newConfiguration.supplyPerYearInterestRateSlopeLow;
|
|
|
|
|
configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeHigh = newConfiguration.supplyPerYearInterestRateSlopeHigh;
|
|
|
|
|
configuratorParams[lendingProxy].supplyPerYearInterestRateBase = newConfiguration.supplyPerYearInterestRateBase;
|
|
|
|
|
configuratorParams[lendingProxy].borrowKink = newConfiguration.borrowKink;
|
|
|
|
|
configuratorParams[lendingProxy].borrowPerYearInterestRateSlopeLow = newConfiguration.borrowPerYearInterestRateSlopeLow;
|
|
|
|
|
configuratorParams[lendingProxy].borrowPerYearInterestRateSlopeHigh = newConfiguration.borrowPerYearInterestRateSlopeHigh;
|
|
|
|
|
configuratorParams[lendingProxy].borrowPerYearInterestRateBase = newConfiguration.borrowPerYearInterestRateBase;
|
|
|
|
|
configuratorParams[lendingProxy].storeFrontPriceFactor = newConfiguration.storeFrontPriceFactor;
|
|
|
|
|
configuratorParams[lendingProxy].baseBorrowMin = newConfiguration.baseBorrowMin;
|
|
|
|
|
configuratorParams[lendingProxy].targetReserves = newConfiguration.targetReserves;
|
|
|
|
|
|
|
|
|
|
for (uint i = 0; i < newConfiguration.assetConfigs.length; i++) {
|
|
|
|
|
configuratorParams[lendingProxy].assetConfigs.push(newConfiguration.assetConfigs[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
emit SetConfiguration(lendingProxy, oldConfiguration, newConfiguration);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function addAsset(address lendingProxy, AssetConfig calldata assetConfig)
|
|
|
|
|
external
|
|
|
|
|
onlyOwner
|
|
|
|
|
{
|
|
|
|
|
configuratorParams[lendingProxy].assetConfigs.push(assetConfig);
|
|
|
|
|
emit AddAsset(lendingProxy, assetConfig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updateAsset(address lendingProxy, AssetConfig calldata newAssetConfig)
|
|
|
|
|
external
|
|
|
|
|
onlyOwner
|
|
|
|
|
{
|
|
|
|
|
uint assetIndex = getAssetIndex(lendingProxy, newAssetConfig.asset);
|
|
|
|
|
AssetConfig memory oldAssetConfig = configuratorParams[lendingProxy].assetConfigs[assetIndex];
|
|
|
|
|
configuratorParams[lendingProxy].assetConfigs[assetIndex] = newAssetConfig;
|
|
|
|
|
emit UpdateAsset(lendingProxy, oldAssetConfig, newAssetConfig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updateAssetBorrowCollateralFactor(
|
|
|
|
|
address lendingProxy,
|
|
|
|
|
address asset,
|
|
|
|
|
uint64 newBorrowCF
|
|
|
|
|
)
|
|
|
|
|
external
|
|
|
|
|
onlyOwner
|
|
|
|
|
{
|
|
|
|
|
uint assetIndex = getAssetIndex(lendingProxy, asset);
|
|
|
|
|
configuratorParams[lendingProxy].assetConfigs[assetIndex].borrowCollateralFactor = newBorrowCF;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function updateAssetSupplyCap(
|
|
|
|
|
address lendingProxy,
|
|
|
|
|
address asset,
|
|
|
|
|
uint128 newSupplyCap
|
|
|
|
|
)
|
|
|
|
|
external
|
|
|
|
|
onlyOwner
|
|
|
|
|
{
|
|
|
|
|
uint assetIndex = getAssetIndex(lendingProxy, asset);
|
|
|
|
|
configuratorParams[lendingProxy].assetConfigs[assetIndex].supplyCap = newSupplyCap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function deploy(address lendingProxy) external onlyOwner returns (address) {
|
|
|
|
|
address newLending = LendingFactory(factory[lendingProxy]).deploy();
|
|
|
|
|
emit LendingDeployed(lendingProxy, newLending);
|
|
|
|
|
return newLending;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getAssetIndex(address lendingProxy, address asset) public view returns (uint) {
|
|
|
|
|
AssetConfig[] memory assetConfigs = configuratorParams[lendingProxy].assetConfigs;
|
|
|
|
|
uint numAssets = assetConfigs.length;
|
|
|
|
|
for (uint i = 0; i < numAssets; ) {
|
|
|
|
|
if (assetConfigs[i].asset == asset) {
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
unchecked { i++; }
|
|
|
|
|
}
|
|
|
|
|
revert AssetDoesNotExist();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getConfiguration(address lendingProxy) external view returns (Configuration memory) {
|
|
|
|
|
return configuratorParams[lendingProxy];
|
|
|
|
|
}
|
2025-12-26 13:23:50 +08:00
|
|
|
|
|
|
|
|
uint256[50] private __gap;
|
2025-12-26 13:38:10 +08:00
|
|
|
}
|