Skip to content

Commit

Permalink
Merge pull request #25 from Gearbox-protocol/next-cleanup-adapter
Browse files Browse the repository at this point in the history
feat: cleanup abstract adapter, new adapter & price feed types
  • Loading branch information
Van0k authored Feb 17, 2023
2 parents 533768c + ac085b7 commit 1b2125c
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 34 deletions.
125 changes: 93 additions & 32 deletions contracts/adapters/AbstractAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ import { ICreditManagerV2 } from "../interfaces/ICreditManagerV2.sol";
import { IAdapter } from "../interfaces/adapters/IAdapter.sol";
import { ZeroAddressException } from "../interfaces/IErrors.sol";

/// @title Abstract adapter
/// @dev Must be inherited by other adapters
abstract contract AbstractAdapter is IAdapter {
error CreditFacadeOnlyException();

using Address for address;

/// @inheritdoc IAdapter
ICreditManagerV2 public immutable override creditManager;
/// @inheritdoc IAdapter
address public immutable override targetContract;

/// @dev Constructor
/// @param _creditManager Credit Manager to connect this adapter to
/// @param _targetContract Address of the contract this adapter should interact with
constructor(address _creditManager, address _targetContract) {
if (_creditManager == address(0) || _targetContract == address(0)) {
revert ZeroAddressException();
Expand All @@ -26,18 +31,23 @@ abstract contract AbstractAdapter is IAdapter {
targetContract = _targetContract; // F:[AA-1]
}

/// @dev Reverts if the caller of the function is not the Credit Facade
/// Adapter functions are only allowed to be called from within the multicall
/// Since at this point Credit Account is owned by the Credit Facade, all
/// functions that perform actions on account must have this modifier
modifier creditFacadeOnly() {
if (msg.sender != _creditFacade()) {
revert CreditFacadeOnlyException();
}

_;
}

/// @dev Returns the Credit Facade connected to the Credit Manager
function _creditFacade() internal view returns (address) {
return creditManager.creditFacade();
}

/// @dev Returns the Credit Account currently owned by the Credit Facade
function _creditAccount() internal view returns (address) {
return creditManager.getCreditAccountOrRevert(_creditFacade());
}
Expand All @@ -49,27 +59,78 @@ abstract contract AbstractAdapter is IAdapter {
creditManager.approveCreditAccount(targetContract, token, amount);
}

/// @dev Executes an arbitrary call from the Credit Account to the target contract
/// @param callData Data to call the target contract with
/// @return result Call output
function _execute(bytes memory callData)
internal
returns (bytes memory result)
{
return creditManager.executeOrder(targetContract, callData);
}

/// @dev Calls a target contract with maximal allowance and performs a fast check after
/// @param creditAccount A credit account from which a call is made
/// @param tokenIn The token that the interaction is expected to spend
/// @param tokenOut The token that the interaction is expected to produce
/// @param callData Data to call targetContract with
/// @param allowTokenIn Whether the input token must be approved beforehand
/// @param disableTokenIn Whether the input token should be disable afterwards (for interaction that spend the entire balance)
/// @dev Executes a swap operation on the target contract from the Credit Account
/// @param creditAccount Credit Account from which the call is made
/// @param tokenIn The token that the call is expected to spend
/// @param tokenOut The token that the call is expected to produce
/// @param callData Data to call the target contract with
/// @param disableTokenIn Whether the input token should be disabled afterwards
/// (for operations that spend the entire balance)
/// @return result Call output
function _executeSwap(
address creditAccount,
address tokenIn,
address tokenOut,
bytes memory callData,
bool disableTokenIn
) internal returns (bytes memory result) {
return
_executeSwap(
creditAccount,
tokenIn,
tokenOut,
callData,
false,
disableTokenIn,
0
);
}

/// @dev Wrapper for `_executeSwap` that computes the Credit Account on the spot
/// See params and other details above
function _executeSwap(
address tokenIn,
address tokenOut,
bytes memory callData,
bool disableTokenIn
) internal returns (bytes memory result) {
return
_executeSwap(
_creditAccount(),
tokenIn,
tokenOut,
callData,
false,
disableTokenIn,
0
);
}

/// @dev Executes a swap operation on the target contract from the Credit Account
/// with maximal allowance, and then resets the allowance back to max
/// @param creditAccount Credit Account from which the call is made
/// @param tokenIn The token that the call is expected to spend
/// @param tokenOut The token that the call is expected to produce
/// @param callData Data to call the target contract with
/// @param disableTokenIn Whether the input token should be disabled afterwards
/// (for operations that spend the entire balance)
/// @return result Call output
/// @notice Must only be used for highly secure and immutable protocols, such as Uniswap & Curve
function _executeMaxAllowance(
function _executeSwapMaxAllowance(
address creditAccount,
address tokenIn,
address tokenOut,
bytes memory callData,
bool allowTokenIn,
bool disableTokenIn
) internal returns (bytes memory result) {
return
Expand All @@ -78,46 +139,46 @@ abstract contract AbstractAdapter is IAdapter {
tokenIn,
tokenOut,
callData,
allowTokenIn,
true,
disableTokenIn,
type(uint256).max
);
}

/// @dev Wrapper for _executeMaxAllowance that computes the Credit Account on the spot
/// @dev Wrapper for `_executeSwapMaxAllowance` that computes the Credit Account on the spot
/// See params and other details above
function _executeMaxAllowance(
function _executeSwapMaxAllowance(
address tokenIn,
address tokenOut,
bytes memory callData,
bool allowTokenIn,
bool disableTokenIn
) internal creditFacadeOnly returns (bytes memory result) {
) internal returns (bytes memory result) {
return
_executeSwap(
_creditAccount(),
tokenIn,
tokenOut,
callData,
allowTokenIn,
true,
disableTokenIn,
type(uint256).max
);
}

/// @dev Calls a target contract with maximal allowance, then sets allowance to 1 and performs a fast check
/// @param creditAccount A credit account from which a call is made
/// @param tokenIn The token that the interaction is expected to spend
/// @param tokenOut The token that the interaction is expected to produce
/// @param callData Data to call targetContract with
/// @param allowTokenIn Whether the input token must be approved beforehand
/// @param disableTokenIn Whether the input token should be disable afterwards (for interaction that spend the entire balance)
function _safeExecute(
/// @dev Executes a swap operation on the target contract from the Credit Account
/// with maximal allowance, and then sets it to 1
/// @param creditAccount Credit Account from which the call is made
/// @param tokenIn The token that the call is expected to spend
/// @param tokenOut The token that the call is expected to produce
/// @param callData Data to call the target contract with
/// @param disableTokenIn Whether the input token should be disabled afterwards
/// (for operations that spend the entire balance)
/// @return result Call output
function _executeSwapSafeAllowance(
address creditAccount,
address tokenIn,
address tokenOut,
bytes memory callData,
bool allowTokenIn,
bool disableTokenIn
) internal returns (bytes memory result) {
return
Expand All @@ -126,19 +187,18 @@ abstract contract AbstractAdapter is IAdapter {
tokenIn,
tokenOut,
callData,
allowTokenIn,
true,
disableTokenIn,
1
);
}

/// @dev Wrapper for _safeExecute that computes the Credit Account on the spot
/// @dev Wrapper for `_executeSwapSafeAllowance` that computes the Credit Account on the spot
/// See params and other details above
function _safeExecute(
function _executeSwapSafeAllowance(
address tokenIn,
address tokenOut,
bytes memory callData,
bool allowTokenIn,
bool disableTokenIn
) internal returns (bytes memory result) {
return
Expand All @@ -147,12 +207,13 @@ abstract contract AbstractAdapter is IAdapter {
tokenIn,
tokenOut,
callData,
allowTokenIn,
true,
disableTokenIn,
1
);
}

/// @dev Implementation of `_executeSwap...` operations above
function _executeSwap(
address creditAccount,
address tokenIn,
Expand Down
7 changes: 6 additions & 1 deletion contracts/interfaces/IPriceFeedType.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ enum PriceFeedType {
ZERO_ORACLE,
WSTETH_ORACLE,
BOUNDED_ORACLE,
COMPOSITE_ORACLE
COMPOSITE_ORACLE,
BALANCER_WEIGHTED_LP_ORACLE,
BALANCER_STABLE_LP_ORACLE,
AAVE_ORACLE,
EULER_ORACLE,
COMPOUND_ORACLE
}

interface IPriceFeedType {
Expand Down
13 changes: 12 additions & 1 deletion contracts/interfaces/adapters/IAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,27 @@ enum AdapterType {
CONVEX_V1_CLAIM_ZAP,
LIDO_V1,
UNIVERSAL,
LIDO_WSTETH_V1
LIDO_WSTETH_V1,
BALANCER_VAULT,
AAVE_V2_LENDING_POOL,
AAVE_V2_WRAPPED_ATOKEN,
EULER_V1_ETOKEN,
COMPOUND_V2_CERC20,
COMPOUND_V2_CETHER
}

interface IAdapterExceptions {
/// @dev Thrown when the adapter attempts to use a token
/// that is not recognized as collateral in the connected
/// Credit Manager
error TokenIsNotInAllowedList(address);

/// @dev Thrown when the caller of a `creditFacadeOnly` function
/// is not the Credit Facade
error CreditFacadeOnlyException();
}

/// @title Adapter interface
interface IAdapter is IAdapterExceptions {
/// @dev Returns the Credit Manager connected to the adapter
function creditManager() external view returns (ICreditManagerV2);
Expand Down

0 comments on commit 1b2125c

Please sign in to comment.