Skip to content

Commit

Permalink
feat: add MarketHelper which returns proper ACL, CR and treasury
Browse files Browse the repository at this point in the history
  • Loading branch information
lekhovitsky committed Feb 9, 2025
1 parent 66f9b8e commit b5d572d
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 56 deletions.
5 changes: 3 additions & 2 deletions contracts/credit/CreditConfiguratorV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol";
// LIBRARIES & CONSTANTS
import {BitMask} from "../libraries/BitMask.sol";
import {PERCENTAGE_FACTOR, UNDERLYING_TOKEN_MASK, WAD} from "../libraries/Constants.sol";
import {MarketHelper} from "../libraries/MarketHelper.sol";

// CONTRACTS
import {CreditFacadeV3} from "./CreditFacadeV3.sol";
Expand All @@ -37,6 +38,7 @@ contract CreditConfiguratorV3 is ICreditConfiguratorV3, ACLTrait, SanityCheckTra
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
using BitMask for uint256;
using MarketHelper for CreditManagerV3;

/// @notice Contract version
uint256 public constant override version = 3_10;
Expand All @@ -60,10 +62,9 @@ contract CreditConfiguratorV3 is ICreditConfiguratorV3, ACLTrait, SanityCheckTra
}

/// @notice Constructor
/// @param _acl ACL contract address
/// @param _creditManager Credit manager to connect to
/// @dev Copies allowed adaprters from the currently connected configurator
constructor(address _acl, address _creditManager) ACLTrait(_acl) {
constructor(address _creditManager) ACLTrait(CreditManagerV3(_creditManager).getACL()) {
creditManager = _creditManager; // I:[CC-1]
underlying = CreditManagerV3(_creditManager).underlying(); // I:[CC-1]

Expand Down
8 changes: 4 additions & 4 deletions contracts/credit/CreditFacadeV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
UNDERLYING_TOKEN_MASK,
DEFAULT_LIMIT_PER_BLOCK_MULTIPLIER
} from "../libraries/Constants.sol";
import {MarketHelper} from "../libraries/MarketHelper.sol";

// TRAITS
import {ACLTrait} from "../traits/ACLTrait.sol";
Expand Down Expand Up @@ -68,6 +69,7 @@ contract CreditFacadeV3 is ICreditFacadeV3, Pausable, ACLTrait, ReentrancyGuardT
using BitMask for uint256;
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
using MarketHelper for ICreditManagerV3;

/// @notice Contract version
uint256 public constant override version = 3_10;
Expand Down Expand Up @@ -152,7 +154,6 @@ contract CreditFacadeV3 is ICreditFacadeV3, Pausable, ACLTrait, ReentrancyGuardT
}

/// @notice Constructor
/// @param _acl ACL contract address
/// @param _creditManager Credit manager to connect this facade to
/// @param _lossPolicy Loss policy address
/// @param _botList Bot list address
Expand All @@ -161,14 +162,13 @@ contract CreditFacadeV3 is ICreditFacadeV3, Pausable, ACLTrait, ReentrancyGuardT
/// @param _expirable Whether this facade should be expirable. If `true`, the expiration date remains unset,
/// and facade never expires, until the date is set via `setExpirationDate` in the configurator.
constructor(
address _acl,
address _creditManager,
address _lossPolicy,
address _botList,
address _weth,
address _degenNFT,
bool _expirable
) ACLTrait(_acl) nonZeroAddress(_lossPolicy) nonZeroAddress(_botList) {
) ACLTrait(ICreditManagerV3(_creditManager).getACL()) nonZeroAddress(_lossPolicy) nonZeroAddress(_botList) {
creditManager = _creditManager; // U:[FA-1]
lossPolicy = _lossPolicy; // U:[FA-1]
botList = _botList; // U:[FA-1]
Expand All @@ -177,7 +177,7 @@ contract CreditFacadeV3 is ICreditFacadeV3, Pausable, ACLTrait, ReentrancyGuardT
expirable = _expirable; // U:[FA-1]

underlying = ICreditManagerV3(_creditManager).underlying(); // U:[FA-1]
treasury = IPoolV3(ICreditManagerV3(_creditManager).pool()).treasury(); // U:[FA-1]
treasury = ICreditManagerV3(_creditManager).getTreasury(); // U:[FA-1]
}

// ------------------ //
Expand Down
67 changes: 67 additions & 0 deletions contracts/libraries/MarketHelper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: BUSL-1.1
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ICreditManagerV3} from "../interfaces/ICreditManagerV3.sol";
import {IPoolV3} from "../interfaces/IPoolV3.sol";

interface IMarketConfigurator {
function acl() external view returns (address);
function contractsRegister() external view returns (address);
function treasury() external view returns (address);
}

/// @title Market helper library
/// @notice Helper functions to retrieve ACL, contracts register and treasury from a pool or credit manager
/// @dev Accounts for different versions of markets within the new permissionless framework
library MarketHelper {
/// @notice Retrieves the ACL address from a pool
function getACL(IPoolV3 pool) internal view returns (address) {
if (_version(pool) < 3_10) return _marketConfigurator(pool).acl();
return pool.acl();
}

/// @notice Retrieves the ACL address from a credit manager
function getACL(ICreditManagerV3 creditManager) internal view returns (address) {
return getACL(_pool(creditManager));
}

/// @notice Retrieves the contracts register address from a pool
function getContractsRegister(IPoolV3 pool) internal view returns (address) {
if (_version(pool) < 3_10) return _marketConfigurator(pool).contractsRegister();
return pool.contractsRegister();
}

/// @notice Retrieves the contracts register address from a credit manager
function getContractsRegister(ICreditManagerV3 creditManager) internal view returns (address) {
return getContractsRegister(_pool(creditManager));
}

/// @notice Retrieves the treasury address from a pool
function getTreasury(IPoolV3 pool) internal view returns (address) {
if (_version(pool) < 3_10) return _marketConfigurator(pool).treasury();
return pool.treasury();
}

/// @notice Retrieves the treasury address from a credit manager
function getTreasury(ICreditManagerV3 creditManager) internal view returns (address) {
return getTreasury(_pool(creditManager));
}

/// @dev Retrieves the version of a pool
function _version(IPoolV3 pool) private view returns (uint256) {
return pool.version();
}

/// @dev Retrieves the market configurator (owner of both new and old ACLs) of a pool
function _marketConfigurator(IPoolV3 pool) private view returns (IMarketConfigurator) {
return IMarketConfigurator(Ownable(pool.acl()).owner());
}

/// @dev Retrieves the pool credit manager is connected to
function _pool(ICreditManagerV3 creditManager) private view returns (IPoolV3) {
return IPoolV3(creditManager.pool());
}
}
7 changes: 6 additions & 1 deletion contracts/pool/GaugeV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {IGearStakingV3} from "../interfaces/IGearStakingV3.sol";
import {IPoolQuotaKeeperV3} from "../interfaces/IPoolQuotaKeeperV3.sol";
import {IPoolV3} from "../interfaces/IPoolV3.sol";

// LIBRARIES
import {MarketHelper} from "../libraries/MarketHelper.sol";

// TRAITS
import {ACLTrait} from "../traits/ACLTrait.sol";
import {SanityCheckTrait} from "../traits/SanityCheckTrait.sol";
Expand All @@ -31,6 +34,8 @@ import {
/// or for LP side, which moves it towards max.
/// Rates are only updated once per epoch (1 week), to avoid manipulation and make strategies more predictable.
contract GaugeV3 is IGaugeV3, ACLTrait, SanityCheckTrait {
using MarketHelper for IPoolV3;

/// @notice Contract version
uint256 public constant override version = 3_10;

Expand Down Expand Up @@ -65,7 +70,7 @@ contract GaugeV3 is IGaugeV3, ACLTrait, SanityCheckTrait {
/// @param _pool Address of the lending pool
/// @param _gearStaking Address of the GEAR staking contract
constructor(address _pool, address _gearStaking)
ACLTrait(ACLTrait(_pool).acl())
ACLTrait(IPoolV3(_pool).getACL())
nonZeroAddress(_gearStaking) // U:[GA-1]
{
pool = _pool; // U:[GA-1]
Expand Down
6 changes: 4 additions & 2 deletions contracts/pool/PoolQuotaKeeperV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {ICreditManagerV3} from "../interfaces/ICreditManagerV3.sol";
import {IRateKeeper} from "../interfaces/base/IRateKeeper.sol";

import {PERCENTAGE_FACTOR, RAY} from "../libraries/Constants.sol";
import {MarketHelper} from "../libraries/MarketHelper.sol";

// EXCEPTIONS
import "../interfaces/IExceptions.sol";
Expand All @@ -33,6 +34,7 @@ import "../interfaces/IExceptions.sol";
contract PoolQuotaKeeperV3 is IPoolQuotaKeeperV3, ACLTrait, ContractsRegisterTrait, SanityCheckTrait {
using EnumerableSet for EnumerableSet.AddressSet;
using QuotasLogic for TokenQuotaParams;
using MarketHelper for IPoolV3;

/// @notice Contract version
uint256 public constant override version = 3_10;
Expand Down Expand Up @@ -81,8 +83,8 @@ contract PoolQuotaKeeperV3 is IPoolQuotaKeeperV3, ACLTrait, ContractsRegisterTra
/// @notice Constructor
/// @param _pool Pool address
constructor(address _pool)
ACLTrait(ACLTrait(_pool).acl())
ContractsRegisterTrait(ContractsRegisterTrait(_pool).contractsRegister())
ACLTrait(IPoolV3(_pool).getACL())
ContractsRegisterTrait(IPoolV3(_pool).getContractsRegister())
{
pool = _pool; // U:[PQK-1]
underlying = IPoolV3(_pool).asset(); // U:[PQK-1]
Expand Down
4 changes: 3 additions & 1 deletion contracts/pool/TumblerV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import {IPoolQuotaKeeperV3} from "../interfaces/IPoolQuotaKeeperV3.sol";
import {IPoolV3} from "../interfaces/IPoolV3.sol";
import {ITumblerV3} from "../interfaces/ITumblerV3.sol";
import {MarketHelper} from "../libraries/MarketHelper.sol";
import {ACLTrait} from "../traits/ACLTrait.sol";
import {SanityCheckTrait} from "../traits/SanityCheckTrait.sol";

Expand All @@ -22,6 +23,7 @@ import {SanityCheckTrait} from "../traits/SanityCheckTrait.sol";
/// instead of voting, allows configurator to set rates directly with custom epoch length
contract TumblerV3 is ITumblerV3, ACLTrait, SanityCheckTrait {
using EnumerableSet for EnumerableSet.AddressSet;
using MarketHelper for IPoolV3;

/// @notice Contract version
uint256 public constant override version = 3_10;
Expand Down Expand Up @@ -53,7 +55,7 @@ contract TumblerV3 is ITumblerV3, ACLTrait, SanityCheckTrait {
/// @param pool_ Pool whose rates to set by this contract
/// @param epochLength_ Epoch length in seconds
/// @custom:tests U:[TU-1]
constructor(address pool_, uint256 epochLength_) ACLTrait(ACLTrait(pool_).acl()) {
constructor(address pool_, uint256 epochLength_) ACLTrait(IPoolV3(pool_).getACL()) {
pool = pool_;
poolQuotaKeeper = IPoolV3(pool_).poolQuotaKeeper();
underlying = IPoolQuotaKeeperV3(poolQuotaKeeper).underlying();
Expand Down
32 changes: 7 additions & 25 deletions contracts/test/integration/credit/CreditConfigurator.int.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -798,13 +798,7 @@ contract CreditConfiguratorIntegrationTest is IntegrationTestHelper, ICreditConf

if (expirable) {
CreditFacadeV3 initialCf = new CreditFacadeV3(
address(acl),
address(creditManager),
address(lossPolicy),
address(botList),
address(0),
address(0),
true
address(creditManager), address(lossPolicy), address(botList), address(0), address(0), true
);

vm.prank(CONFIGURATOR);
Expand All @@ -820,13 +814,7 @@ contract CreditConfiguratorIntegrationTest is IntegrationTestHelper, ICreditConf
creditConfigurator.setMaxDebtPerBlockMultiplier(DEFAULT_LIMIT_PER_BLOCK_MULTIPLIER + 1);

CreditFacadeV3 cf = new CreditFacadeV3(
address(acl),
address(creditManager),
address(lossPolicy),
address(botList),
address(0),
address(0),
expirable
address(creditManager), address(lossPolicy), address(botList), address(0), address(0), expirable
);

uint8 maxDebtPerBlockMultiplier = creditFacade.maxDebtPerBlockMultiplier();
Expand Down Expand Up @@ -868,7 +856,7 @@ contract CreditConfiguratorIntegrationTest is IntegrationTestHelper, ICreditConf
vm.startPrank(CONFIGURATOR);

CreditFacadeV3 cf = new CreditFacadeV3(
address(acl), address(creditManager), address(lossPolicy), address(botList), address(0), address(0), false
address(creditManager), address(lossPolicy), address(botList), address(0), address(0), false
);
AdapterMock adapter = new AdapterMock(address(creditManager), address(cf));
TargetContractMock target = new TargetContractMock();
Expand Down Expand Up @@ -907,13 +895,7 @@ contract CreditConfiguratorIntegrationTest is IntegrationTestHelper, ICreditConf
vm.stopPrank();

CreditFacadeV3 cf = new CreditFacadeV3(
address(acl),
address(creditManager),
address(lossPolicy),
address(botList),
address(0),
address(0),
false
address(creditManager), address(lossPolicy), address(botList), address(0), address(0), false
);

vm.prank(CONFIGURATOR);
Expand Down Expand Up @@ -941,12 +923,12 @@ contract CreditConfiguratorIntegrationTest is IntegrationTestHelper, ICreditConf
vm.prank(CONFIGURATOR);
creditConfigurator.allowAdapter(address(adapter1));

CreditConfiguratorV3 cc1 = new CreditConfiguratorV3(address(acl), address(creditManager));
CreditConfiguratorV3 cc1 = new CreditConfiguratorV3(address(creditManager));

vm.prank(CONFIGURATOR);
creditConfigurator.allowAdapter(address(adapter2));

CreditConfiguratorV3 cc2 = new CreditConfiguratorV3(address(acl), address(creditManager));
CreditConfiguratorV3 cc2 = new CreditConfiguratorV3(address(creditManager));

vm.expectRevert(IncorrectAdaptersSetException.selector);
vm.prank(CONFIGURATOR);
Expand Down Expand Up @@ -1042,7 +1024,7 @@ contract CreditConfiguratorIntegrationTest is IntegrationTestHelper, ICreditConf
vm.prank(CONFIGURATOR);
creditConfigurator.allowAdapter(address(adapterMock));

CreditConfiguratorV3 newConfigurator = new CreditConfiguratorV3(address(acl), address(creditManager));
CreditConfiguratorV3 newConfigurator = new CreditConfiguratorV3(address(creditManager));

address[] memory newAllowedAdapters = newConfigurator.allowedAdapters();

Expand Down
11 changes: 1 addition & 10 deletions contracts/test/suites/CreditManagerFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,10 @@
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;

import "@openzeppelin/contracts/utils/Create2.sol";

import "../interfaces/IAddressProviderV3.sol";
import {IACLTrait} from "../../interfaces/base/IACLTrait.sol";

import {CreditManagerV3} from "../../credit/CreditManagerV3.sol";
import {CreditFacadeV3} from "../../credit/CreditFacadeV3.sol";
import {CreditConfiguratorV3} from "../../credit/CreditConfiguratorV3.sol";

import {DEFAULT_LIMIT_PER_BLOCK_MULTIPLIER} from "../../libraries/Constants.sol";

/// @title CreditManagerFactory
/// @notice Deploys 3 core interdependent contracts: CreditManage, CreditFacadeV3 and CredigConfigurator
/// and setup them by following options
Expand Down Expand Up @@ -56,9 +49,7 @@ contract CreditManagerFactory {
cmParams.name
);

address acl = IACLTrait(pool).acl();
creditFacade = new CreditFacadeV3(
acl,
address(creditManager),
cfParams.lossPolicy,
cfParams.botList,
Expand All @@ -68,7 +59,7 @@ contract CreditManagerFactory {
);
creditManager.setCreditFacade(address(creditFacade));

creditConfigurator = new CreditConfiguratorV3(acl, address(creditManager));
creditConfigurator = new CreditConfiguratorV3(address(creditManager));
creditManager.setCreditConfigurator(address(creditConfigurator));
}
}
10 changes: 1 addition & 9 deletions contracts/test/unit/credit/CreditFacadeV3.unit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ contract CreditFacadeV3UnitTest is TestHelper, BalanceHelper, ICreditFacadeV3Eve

function _deploy() internal {
creditFacade = new CreditFacadeV3Harness(
address(addressProvider),
address(creditManagerMock),
address(lossPolicyMock),
address(botListMock),
Expand All @@ -199,18 +198,11 @@ contract CreditFacadeV3UnitTest is TestHelper, BalanceHelper, ICreditFacadeV3Eve

vm.expectRevert(ZeroAddressException.selector);
new CreditFacadeV3Harness(
address(addressProvider),
address(creditManagerMock),
address(0),
address(botListMock),
address(0),
address(degenNFTMock),
expirable
address(creditManagerMock), address(0), address(botListMock), address(0), address(degenNFTMock), expirable
);

vm.expectRevert(ZeroAddressException.selector);
new CreditFacadeV3Harness(
address(addressProvider),
address(creditManagerMock),
address(lossPolicyMock),
address(0),
Expand Down
3 changes: 1 addition & 2 deletions contracts/test/unit/credit/CreditFacadeV3Harness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ import {BalanceWithMask} from "../../../libraries/BalancesLogic.sol";

contract CreditFacadeV3Harness is CreditFacadeV3 {
constructor(
address _acl,
address _creditManager,
address _lossPolicy,
address _botList,
address _weth,
address _degenNFT,
bool _expirable
) CreditFacadeV3(_acl, _creditManager, _lossPolicy, _botList, _weth, _degenNFT, _expirable) {}
) CreditFacadeV3(_creditManager, _lossPolicy, _botList, _weth, _degenNFT, _expirable) {}

function setReentrancy(uint8 _status) external {
_reentrancyStatus = _status;
Expand Down

0 comments on commit b5d572d

Please sign in to comment.