Skip to content

Commit

Permalink
fix: bug fixes and code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
0xmikko committed May 14, 2023
1 parent 0dfaa11 commit 1041e4c
Show file tree
Hide file tree
Showing 23 changed files with 128 additions and 103 deletions.
15 changes: 5 additions & 10 deletions contracts/core/AddressProviderV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ contract AddressProviderV3 is IAddressProviderV3 {
// Contract version
uint256 public constant override(IVersion) version = 3_00;

uint256 immutable aclVersion;

modifier configuratorOnly() {
if (!IACL(getAddressOrRevert(AP_ACL, aclVersion)).isConfigurator(msg.sender)) {
if (!IACL(getAddressOrRevert(AP_ACL, 0)).isConfigurator(msg.sender)) {
revert CallerNotConfiguratorException();
}
_;
Expand All @@ -31,8 +29,7 @@ contract AddressProviderV3 is IAddressProviderV3 {
constructor(address _acl) {
// @dev Emits first event for contract discovery
emit AddressSet("ADDRESS_PROVIDER", address(this), version);
aclVersion = IVersion(_acl).version();
_setAddress(AP_ACL, _acl, true);
_setAddress(AP_ACL, _acl, 0);
}

function getAddressOrRevert(bytes32 key, uint256 _version) public view override returns (address result) {
Expand All @@ -44,12 +41,10 @@ contract AddressProviderV3 is IAddressProviderV3 {
/// @param key Key in string format
/// @param value Address
function setAddress(bytes32 key, address value, bool saveVersion) external override configuratorOnly {
_setAddress(key, value, saveVersion);
_setAddress(key, value, saveVersion ? IVersion(value).version() : 0);
}

function _setAddress(bytes32 key, address value, bool saveVersion) internal {
uint256 _version;
if (saveVersion) _version = IVersion(value).version();
function _setAddress(bytes32 key, address value, uint256 _version) internal {
addresses[key][_version] = value;
emit AddressSet(key, value, _version); // F:[AP-2]
}
Expand All @@ -58,7 +53,7 @@ contract AddressProviderV3 is IAddressProviderV3 {

/// @return Address of ACL contract
function getACL() external view returns (address) {
return getAddressOrRevert(AP_ACL, 1); // F:[AP-3]
return getAddressOrRevert(AP_ACL, 0); // F:[AP-3]
}

/// @return Address of ContractsRegister
Expand Down
4 changes: 2 additions & 2 deletions contracts/credit/CreditConfiguratorV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -660,8 +660,8 @@ contract CreditConfigurator is ICreditConfigurator, ACLNonReentrantTrait {
} // F:[CC-12A,29]

// Checks that the contract has a creditManager() function, which returns a correct value
try CreditFacadeV3(_contract).creditManager() returns (ICreditManagerV3 cm) {
if (cm != creditManager) revert IncompatibleContractException(); // F:[CC-12B,29]
try CreditFacadeV3(_contract).creditManager() returns (address cm) {
if (cm != address(creditManager)) revert IncompatibleContractException(); // F:[CC-12B,29]
} catch {
revert IncompatibleContractException(); // F:[CC-12B,29]
}
Expand Down
71 changes: 39 additions & 32 deletions contracts/credit/CreditFacadeV3.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: BUSL-1.1
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Holdings, 2022
pragma solidity ^0.8.10;
pragma solidity ^0.8.17;

import "../interfaces/IAddressProviderV3.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

// LIBS & TRAITS
Expand Down Expand Up @@ -76,7 +77,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
using BitMask for uint256;

/// @dev Credit Manager connected to this Credit Facade
ICreditManagerV3 public immutable creditManager;
address public immutable creditManager;

/// @dev Whether the whitelisted mode is active
bool public immutable whitelisted;
Expand All @@ -94,7 +95,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
address public immutable wethAddress;

/// @dev Address of WETH Gateway
IWETHGateway public immutable wethGateway;
address public immutable wethGateway;

/// @dev Address of the DegenNFT that gatekeeps account openings in whitelisted mode
address public immutable override degenNFT;
Expand Down Expand Up @@ -138,7 +139,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {

/// @dev Restricts actions for users with opened credit accounts only
modifier creditConfiguratorOnly() {
if (msg.sender != creditManager.creditConfigurator()) {
if (msg.sender != ICreditManagerV3(creditManager).creditConfigurator()) {
revert CallerNotConfiguratorException();
}

Expand Down Expand Up @@ -177,15 +178,17 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
/// @param _degenNFT address of the DegenNFT or address(0) if whitelisted mode is not used
/// @param _expirable Whether the CreditFacadeV3 can expire and implements expiration-related logic
constructor(address _creditManager, address _degenNFT, bool _expirable)
ACLNonReentrantTrait(address(IPool4626(ICreditManagerV3(_creditManager).pool()).addressProvider()))
ACLNonReentrantTrait(ICreditManagerV3(_creditManager).addressProvider())
nonZeroAddress(_creditManager)
{
creditManager = ICreditManagerV3(_creditManager); // F:[FA-1A]
pool = creditManager.pool();
creditManager = _creditManager; // F:[FA-1A]
pool = ICreditManagerV3(_creditManager).pool();
underlying = ICreditManagerV3(_creditManager).underlying(); // F:[FA-1A]

wethAddress = ICreditManagerV3(_creditManager).wethAddress(); // F:[FA-1A]
wethGateway = IWETHGateway(ICreditManagerV3(_creditManager).wethGateway());
wethGateway = ICreditManagerV3(_creditManager).wethGateway();
botList =
IAddressProviderV3(ICreditManagerV3(_creditManager).addressProvider()).getAddressOrRevert(AP_BOT_LIST, 3_00);

degenNFT = _degenNFT; // F:[FA-1A]
whitelisted = _degenNFT != address(0); // F:[FA-1A]
Expand Down Expand Up @@ -252,7 +255,11 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
_wrapETH(); // F:[FA-3B]

// Requests the Credit Manager to open a Credit Account
creditAccount = creditManager.openCreditAccount({debt: debt, onBehalfOf: onBehalfOf, deployNew: deployNew}); // F:[FA-8]
creditAccount = ICreditManagerV3(creditManager).openCreditAccount({
debt: debt,
onBehalfOf: onBehalfOf,
deployNew: deployNew
}); // F:[FA-8]

// emits a new event
emit OpenCreditAccount(creditAccount, onBehalfOf, msg.sender, debt, referralCode); // F:[FA-8]
Expand Down Expand Up @@ -478,7 +485,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
{
uint256 _forbiddenTokenMask = forbiddenTokenMask;

uint256 enabledTokensMaskBefore = creditManager.enabledTokensMaskOf(creditAccount);
uint256 enabledTokensMaskBefore = ICreditManagerV3(creditManager).enabledTokensMaskOf(creditAccount);

uint256[] memory forbiddenBalances = CreditLogic.storeForbiddenBalances({
creditAccount: creditAccount,
Expand Down Expand Up @@ -517,7 +524,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
internal
returns (FullCheckParams memory fullCheckParams)
{
uint256 quotedTokenMaskInverted = ~creditManager.quotedTokenMask();
uint256 quotedTokenMaskInverted = ~ICreditManagerV3(creditManager).quotedTokenMask();
// Emits event for multicall start - used in analytics to track actions within multicalls
emit StartMultiCall(creditAccount); // F:[FA-26]

Expand Down Expand Up @@ -677,7 +684,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
// functionCall to it is strictly forbidden, even if
// the Configurator adds it as an adapter

if (creditManager.adapterToContract(mcall.target) == address(0)) {
if (ICreditManagerV3(creditManager).adapterToContract(mcall.target) == address(0)) {
revert TargetContractNotAllowedException();
} // F:[FA-24]

Expand Down Expand Up @@ -746,7 +753,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
}

function _setExternalCallCreditAccount(address creditAccount) internal {
creditManager.setCreditAccountForExternalCall(creditAccount); // F:[FA-26]
ICreditManagerV3(creditManager).setCreditAccountForExternalCall(creditAccount); // F:[FA-26]
}

function _revertIfNoPermission(uint256 flags, uint256 permission) internal pure {
Expand All @@ -757,7 +764,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {

function _onDemandPriceUpdate(bytes calldata callData) internal {
(address token, bytes memory data) = abi.decode(callData, (address, bytes));
address priceFeed = IPriceOracleV2(creditManager.priceOracle()).priceFeeds(token);
address priceFeed = IPriceOracleV2(ICreditManagerV3(creditManager).priceOracle()).priceFeeds(token);
if (priceFeed == address(0)) revert PriceFeedNotExistsException();
IPriceFeedOnDemand(priceFeed).updatePrice(data);
}
Expand All @@ -767,12 +774,12 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
(address token, int96 quotaChange) = abi.decode(callData, (address, int96));
return creditManager.updateQuota(creditAccount, token, quotaChange);
return ICreditManagerV3(creditManager).updateQuota(creditAccount, token, quotaChange);
}

function _revokeAdapterAllowances(address creditAccount, bytes calldata callData) internal {
(RevocationPair[] memory revocations) = abi.decode(callData, (RevocationPair[]));
creditManager.revokeAdapterAllowances(creditAccount, revocations);
ICreditManagerV3(creditManager).revokeAdapterAllowances(creditAccount, revocations);
}

/// @dev Adds expected deltas to current balances on a Credit account and returns the result
Expand All @@ -796,7 +803,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
uint256 newDebt;
// Requests the Credit Manager to borrow additional funds from the pool
(newDebt, tokensToEnable, tokensToDisable) =
creditManager.manageDebt(creditAccount, amount, enabledTokensMask, action); // F:[FA-17]
ICreditManagerV3(creditManager).manageDebt(creditAccount, amount, enabledTokensMask, action); // F:[FA-17]

// Checks that the new total borrowed amount is within bounds
_revertIfOutOfDebtLimits(newDebt); // F:[FA-18B]
Expand All @@ -812,7 +819,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
function _addCollateral(address creditAccount, bytes calldata callData) internal returns (uint256 tokenMaskAfter) {
(address token, uint256 amount) = abi.decode(callData, (address, uint256)); // F:[FA-26, 27]
// Requests Credit Manager to transfer collateral to the Credit Account
tokenMaskAfter = creditManager.addCollateral(msg.sender, creditAccount, token, amount); // F:[FA-21]
tokenMaskAfter = ICreditManagerV3(creditManager).addCollateral(msg.sender, creditAccount, token, amount); // F:[FA-21]

// Emits event
emit AddCollateral(creditAccount, token, amount); // F:[FA-21]
Expand All @@ -823,7 +830,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
returns (uint256 tokensToDisable)
{
(address token, uint256 amount) = abi.decode(callData, (address, uint256));
tokensToDisable = creditManager.scheduleWithdrawal(creditAccount, token, amount);
tokensToDisable = ICreditManagerV3(creditManager).scheduleWithdrawal(creditAccount, token, amount);
}

/// @dev Transfers credit account to another user
Expand Down Expand Up @@ -853,7 +860,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
_eraseAllBotPermissions(creditAccount, true);

// Requests the Credit Manager to transfer the account
creditManager.transferAccountOwnership(creditAccount, to); // F:[FA-35]
ICreditManagerV3(creditManager).transferAccountOwnership(creditAccount, to); // F:[FA-35]

// Emits event
emit TransferAccount(creditAccount, msg.sender, to); // F:[FA-35]
Expand All @@ -877,27 +884,27 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
creditAccountOwnerOnly(creditAccount)
nonReentrant
{
uint16 flags = creditManager.flagsOf(creditAccount);
uint16 flags = ICreditManagerV3(creditManager).flagsOf(creditAccount);

if (flags & BOT_PERMISSIONS_SET_FLAG == 0) {
_eraseAllBotPermissions(creditAccount, false);

if (permissions != 0) {
creditManager.setFlagFor(creditAccount, BOT_PERMISSIONS_SET_FLAG, true);
ICreditManagerV3(creditManager).setFlagFor(creditAccount, BOT_PERMISSIONS_SET_FLAG, true);
}
}

uint256 remainingBots = IBotList(botList).setBotPermissions(creditAccount, bot, permissions);
if (remainingBots == 0) {
creditManager.setFlagFor(creditAccount, BOT_PERMISSIONS_SET_FLAG, false);
ICreditManagerV3(creditManager).setFlagFor(creditAccount, BOT_PERMISSIONS_SET_FLAG, false);
}
}

function _eraseAllBotPermissions(address creditAccount, bool setFlag) internal {
IBotList(botList).eraseAllBotPermissions(creditAccount);

if (setFlag) {
creditManager.setFlagFor(creditAccount, BOT_PERMISSIONS_SET_FLAG, false);
ICreditManagerV3(creditManager).setFlagFor(creditAccount, BOT_PERMISSIONS_SET_FLAG, false);
}
}

Expand Down Expand Up @@ -965,11 +972,11 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
/// @dev Internal wrapper for `creditManager.getBorrowerOrRevert()`
/// @notice The external call is wrapped to optimize contract size
function _getBorrowerOrRevert(address borrower) internal view returns (address) {
return creditManager.getBorrowerOrRevert(borrower);
return ICreditManagerV3(creditManager).getBorrowerOrRevert(borrower);
}

function _getTokenMaskOrRevert(address token) internal view returns (uint256 mask) {
mask = creditManager.getTokenMaskOrRevert(token);
mask = ICreditManagerV3(creditManager).getTokenMaskOrRevert(token);
}

function _closeCreditAccount(
Expand All @@ -981,7 +988,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
uint256 skipTokensMask,
bool convertWETH
) internal returns (uint256 remainingFunds, uint256 reportedLoss) {
(remainingFunds, reportedLoss) = creditManager.closeCreditAccount({
(remainingFunds, reportedLoss) = ICreditManagerV3(creditManager).closeCreditAccount({
creditAccount: creditAccount,
closureAction: closureAction,
collateralDebtData: collateralDebtData,
Expand All @@ -1001,7 +1008,7 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
uint256[] memory forbiddenBalances,
uint256 _forbiddenTokenMask
) internal {
creditManager.fullCollateralCheck(
ICreditManagerV3(creditManager).fullCollateralCheck(
creditAccount,
fullCheckParams.enabledTokensMaskAfter,
fullCheckParams.collateralHints,
Expand Down Expand Up @@ -1063,22 +1070,22 @@ contract CreditFacadeV3 is ICreditFacade, ACLNonReentrantTrait {
view
returns (CollateralDebtData memory)
{
return creditManager.calcDebtAndCollateral(creditAccount, task);
return ICreditManagerV3(creditManager).calcDebtAndCollateral(creditAccount, task);
}

function _getTokenByMask(uint256 mask) internal view returns (address) {
return creditManager.getTokenByMask(mask);
return ICreditManagerV3(creditManager).getTokenByMask(mask);
}

function _claimWithdrawals(address creditAccount, address to, ClaimAction action)
internal
returns (uint256 tokensToEnable)
{
tokensToEnable = creditManager.claimWithdrawals(creditAccount, to, action);
tokensToEnable = ICreditManagerV3(creditManager).claimWithdrawals(creditAccount, to, action);
}

function _wethWithdrawTo(address to) internal {
wethGateway.withdrawTo(to);
IWETHGateway(wethGateway).withdrawTo(to);
}

//
Expand Down
12 changes: 7 additions & 5 deletions contracts/credit/CreditManagerV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ contract CreditManagerV3 is ICreditManagerV3, SanityCheckTrait, ReentrancyGuard
wethAddress = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_WETH_TOKEN, 0); // F:[CM-1]
wethGateway = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_WETH_GATEWAY, 3_00); // F:[CM-1]
priceOracle = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_PRICE_ORACLE, 2); // F:[CM-1]
accountFactory = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_ACCOUNT_FACTORY, 3_00); // F:[CM-1]
accountFactory = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_ACCOUNT_FACTORY, 1); // F:[CM-1]
withdrawalManager = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_WITHDRAWAL_MANAGER, 3_00);

deployAccountAction = IAccountFactory(accountFactory).version() == 3_00
Expand Down Expand Up @@ -384,7 +384,7 @@ contract CreditManagerV3 is ICreditManagerV3, SanityCheckTrait, ReentrancyGuard
if (supportsQuotas && collateralDebtData.quotedTokens.length > 0) {
/// In case of amy loss, PQK sets limits to zero for all quoted tokens
bool setLimitsToZero = loss > 0;
poolQuotaKeeper().removeQuotas({
IPoolQuotaKeeper(collateralDebtData._poolQuotaKeeper).removeQuotas({
creditAccount: creditAccount,
tokens: collateralDebtData.quotedTokens,
setLimitsToZero: setLimitsToZero
Expand Down Expand Up @@ -443,7 +443,9 @@ contract CreditManagerV3 is ICreditManagerV3, SanityCheckTrait, ReentrancyGuard
});

if (supportsQuotas) {
poolQuotaKeeper().accrueQuotaInterest(creditAccount, collateralDebtData.quotedTokens); // F: [CMQ-4,5]
IPoolQuotaKeeper(collateralDebtData._poolQuotaKeeper).accrueQuotaInterest(
creditAccount, collateralDebtData.quotedTokens
); // F: [CMQ-4,5]
}

// Pays the amount back to the pool
Expand Down Expand Up @@ -593,7 +595,7 @@ contract CreditManagerV3 is ICreditManagerV3, SanityCheckTrait, ReentrancyGuard
_calcDebtAndQuotedCollateral({
collateralDebtData: collateralDebtData,
creditAccount: creditAccount,
countQuotedCollateral: true
countQuotedCollateral: false
});
} else {
address _priceOracle = priceOracle;
Expand Down Expand Up @@ -670,12 +672,12 @@ contract CreditManagerV3 is ICreditManagerV3, SanityCheckTrait, ReentrancyGuard

if (supportsQuotas) {
collateralDebtData.cumulativeQuotaInterest = creditAccountInfo[creditAccount].cumulativeQuotaInterest - 1;
collateralDebtData._poolQuotaKeeper = address(poolQuotaKeeper());
collateralDebtData.calcQuotedCollateral({
creditAccount: creditAccount,
quotedTokenMask: quotedTokenMask,
maxAllowedEnabledTokenLength: maxAllowedEnabledTokenLength,
underlying: underlying,
poolQuotaKeeper: address(poolQuotaKeeper()),
collateralTokensByMaskFn: _collateralTokensByMask,
countCollateral: countQuotedCollateral
});
Expand Down
1 change: 1 addition & 0 deletions contracts/interfaces/IAddressProviderV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ bytes32 constant AP_WETH_TOKEN = "WETH_TOKEN";
bytes32 constant AP_WETH_GATEWAY = "WETH_GATEWAY";
bytes32 constant AP_WITHDRAWAL_MANAGER = "WITHDRAWAL_MANAGER";
bytes32 constant AP_ROUTER = "ROUTER";
bytes32 constant AP_BOT_LIST = "BOT_LIST";

interface IAddressProviderEvents {
/// @dev Emits when an address is set for a contract role
Expand Down
2 changes: 1 addition & 1 deletion contracts/interfaces/ICreditFacade.sol
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ interface ICreditFacade is ICreditFacadeEvents, IVersion {
function forbiddenTokenMask() external view returns (uint256);

/// @dev Returns the CreditManagerV3 connected to this Credit Facade
function creditManager() external view returns (ICreditManagerV3);
function creditManager() external view returns (address);

/// @dev Returns true if 'from' is allowed to transfer Credit Accounts to 'to'
/// @param from Sender address to check allowance for
Expand Down
Loading

0 comments on commit 1041e4c

Please sign in to comment.