Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x61022060 | 19255932 | 662 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ConvexV1BaseRewardPoolAdapter
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 1000 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
import {AbstractAdapter} from "../AbstractAdapter.sol";
import {AdapterType} from "@gearbox-protocol/sdk-gov/contracts/AdapterType.sol";
import {BitMask} from "@gearbox-protocol/core-v3/contracts/libraries/BitMask.sol";
import {IBooster} from "../../integrations/convex/IBooster.sol";
import {IBaseRewardPool} from "../../integrations/convex/IBaseRewardPool.sol";
import {IRewards, IExtraRewardWrapper} from "../../integrations/convex/Interfaces.sol";
import {IConvexV1BaseRewardPoolAdapter} from "../../interfaces/convex/IConvexV1BaseRewardPoolAdapter.sol";
/// @title Convex V1 BaseRewardPool adapter interface
/// @notice Implements logic for interacting with Convex reward pool
contract ConvexV1BaseRewardPoolAdapter is AbstractAdapter, IConvexV1BaseRewardPoolAdapter {
using BitMask for uint256;
AdapterType public constant override _gearboxAdapterType = AdapterType.CONVEX_V1_BASE_REWARD_POOL;
uint16 public constant override _gearboxAdapterVersion = 3_00;
/// @notice Address of a Curve LP token deposited into the Convex pool
address public immutable override curveLPtoken;
/// @notice Address of a Convex LP token staked in the reward pool
address public immutable override stakingToken;
/// @notice Address of a phantom token representing account's stake in the reward pool
address public immutable override stakedPhantomToken;
/// @notice Address of a reward token of the first extra reward pool, if any
address public immutable override extraReward1;
/// @notice Address of a reward token of the second extra reward pool, if any
address public immutable override extraReward2;
/// @notice Collateral token mask of a Curve LP token in the credit manager
uint256 public immutable override curveLPTokenMask;
/// @notice Collateral token mask of a Convex LP token in the credit manager
uint256 public immutable override stakingTokenMask;
/// @notice Collateral token mask of a reward pool stake token
uint256 public immutable override stakedTokenMask;
/// @notice Bitmask of all reward tokens of the pool (CRV, CVX, extra reward tokens, if any) in the credit manager
uint256 public immutable override rewardTokensMask;
/// @notice Constructor
/// @param _creditManager Credit manager address
/// @param _baseRewardPool BaseRewardPool address
/// @param _stakedPhantomToken Reward pool stake token address
constructor(address _creditManager, address _baseRewardPool, address _stakedPhantomToken)
AbstractAdapter(_creditManager, _baseRewardPool) // U:[CVX1R-1]
{
stakingToken = address(IBaseRewardPool(_baseRewardPool).stakingToken()); // U:[CVX1R-1]
stakingTokenMask = _getMaskOrRevert(stakingToken); // U:[CVX1R-1]
stakedPhantomToken = _stakedPhantomToken; // U:[CVX1R-1]
stakedTokenMask = _getMaskOrRevert(stakedPhantomToken); // U:[CVX1R-1]
address booster = IBaseRewardPool(_baseRewardPool).operator();
IBooster.PoolInfo memory poolInfo = IBooster(booster).poolInfo(IBaseRewardPool(_baseRewardPool).pid());
curveLPtoken = poolInfo.lptoken; // U:[CVX1R-1]
curveLPTokenMask = _getMaskOrRevert(curveLPtoken); // U:[CVX1R-1]
uint256 _rewardTokensMask;
address rewardToken = address(IBaseRewardPool(_baseRewardPool).rewardToken());
_rewardTokensMask = _rewardTokensMask.enable(_getMaskOrRevert(rewardToken)); // U:[CVX1R-1]
address cvx = IBooster(booster).minter();
_rewardTokensMask = _rewardTokensMask.enable(_getMaskOrRevert(cvx)); // U:[CVX1R-1]
address _extraReward1;
address _extraReward2;
uint256 extraRewardLength = IBaseRewardPool(_baseRewardPool).extraRewardsLength();
if (extraRewardLength >= 1) {
uint256 _extraRewardMask;
(_extraReward1, _extraRewardMask) = _getExtraReward(0);
_rewardTokensMask = _rewardTokensMask.enable(_extraRewardMask);
if (extraRewardLength >= 2) {
(_extraReward2, _extraRewardMask) = _getExtraReward(1);
_rewardTokensMask = _rewardTokensMask.enable(_extraRewardMask);
}
}
extraReward1 = _extraReward1; // U:[CVX1R-2]
extraReward2 = _extraReward2; // U:[CVX1R-2]
rewardTokensMask = _rewardTokensMask; // U:[CVX1R-2]
}
/// @dev Returns `i`-th extra reward token and its collateral mask in the credit mnager
function _getExtraReward(uint256 i) internal view returns (address extraReward, uint256 extraRewardMask) {
extraReward = IRewards(IBaseRewardPool(targetContract).extraRewards(i)).rewardToken();
// `extraReward` might be a wrapper around the reward token, and there seems to be no reliable way to check it
// programatically, so we assume that it's a wrapper if it's not recognized as collateral in the credit manager
try ICreditManagerV3(creditManager).getTokenMaskOrRevert(extraReward) returns (uint256 mask) {
extraRewardMask = mask;
} catch {
try IExtraRewardWrapper(extraReward).token() returns (address baseToken) {
extraReward = baseToken;
} catch {
extraReward = IExtraRewardWrapper(extraReward).baseToken();
}
extraRewardMask = _getMaskOrRevert(extraReward);
}
}
// ----- //
// STAKE //
// ----- //
/// @notice Stakes Convex LP token in the reward pool
/// @dev `amount` parameter is ignored since calldata is passed directly to the target contract
function stake(uint256)
external
override
creditFacadeOnly // U:[CVX1R-3]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
(tokensToEnable, tokensToDisable) = _stake(msg.data, false); // U:[CVX1R-4]
}
/// @notice Stakes the entire balance of Convex LP token in the reward pool, except the specified amount
/// @param leftoverAmount Amount of Convex LP to keep on the account
function stakeDiff(uint256 leftoverAmount)
external
override
creditFacadeOnly // U:[CVX1R-3]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address creditAccount = _creditAccount(); // U:[CVX1R-5]
uint256 balance = IERC20(stakingToken).balanceOf(creditAccount); // U:[CVX1R-5]
if (balance > leftoverAmount) {
unchecked {
(tokensToEnable, tokensToDisable) =
_stake(abi.encodeCall(IBaseRewardPool.stake, (balance - leftoverAmount)), leftoverAmount <= 1); // U:[CVX1R-5]
}
}
}
/// @dev Internal implementation of `stake` and `stakeDiff`
/// - Staking token is approved because reward pool needs permission to transfer it
/// - Staked token is enabled after the call
/// - Staking token is only disabled when staking the entire balance
function _stake(bytes memory callData, bool disableStakingToken)
internal
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
_approveToken(stakingToken, type(uint256).max); // U:[CVX1R-4,5]
_execute(callData); // U:[CVX1R-4,5]
_approveToken(stakingToken, 1); // U:[CVX1R-4,5]
(tokensToEnable, tokensToDisable) = (stakedTokenMask, disableStakingToken ? stakingTokenMask : 0);
}
// ----- //
// CLAIM //
// ----- //
/// @notice Claims rewards on the current position, enables reward tokens
function getReward()
external
override
creditFacadeOnly // U:[CVX1R-3]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
_execute(msg.data); // U:[CVX1R-6]
(tokensToEnable, tokensToDisable) = (rewardTokensMask, 0); // U:[CVX1R-6]
}
// -------- //
// WITHDRAW //
// -------- //
/// @notice Withdraws Convex LP token from the reward pool
/// @param claim Whether to claim staking rewards
/// @dev `amount` parameter is ignored since calldata is passed directly to the target contract
function withdraw(uint256, bool claim)
external
override
creditFacadeOnly // U:[CVX1R-3]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
(tokensToEnable, tokensToDisable) = _withdraw(msg.data, claim, false); // U:[CVX1R-7]
}
/// @notice Withdraws the entire balance of Convex LP token from the reward pool, except the specified amount
/// @param leftoverAmount Amount of staked Convex LP to keep on the account
/// @param claim Whether to claim staking rewards
function withdrawDiff(uint256 leftoverAmount, bool claim)
external
override
creditFacadeOnly // U:[CVX1R-3]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address creditAccount = _creditAccount(); // U:[CVX1R-6]
uint256 balance = IERC20(stakedPhantomToken).balanceOf(creditAccount); // U:[CVX1R-6]
if (balance > leftoverAmount) {
unchecked {
(tokensToEnable, tokensToDisable) = _withdraw(
abi.encodeCall(IBaseRewardPool.withdraw, (balance - leftoverAmount, claim)),
claim,
leftoverAmount <= 1
); // U:[CVX1R-6]
}
}
}
/// @dev Internal implementation of `withdraw` and `withdrawDiff`
/// - Staking token is enabled after the call
/// - Staked token is only disabled when withdrawing the entire balance
/// - Rewards tokens are enabled if `claim` is true
function _withdraw(bytes memory callData, bool claim, bool disableStakedToken)
internal
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
_execute(callData); // U:[CVX1R-7,8]
(tokensToEnable, tokensToDisable) =
(stakingTokenMask.enable(claim ? rewardTokensMask : 0), disableStakedToken ? stakedTokenMask : 0);
}
// ------ //
// UNWRAP //
// ------ //
/// @notice Withdraws Convex LP token from the reward pool and unwraps it into Curve LP token
/// @param claim Whether to claim staking rewards
/// @dev `amount` parameter is ignored since calldata is passed directly to the target contract
function withdrawAndUnwrap(uint256, bool claim)
external
override
creditFacadeOnly // U:[CVX1R-3]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
(tokensToEnable, tokensToDisable) = _withdrawAndUnwrap(msg.data, claim, false); // U:[CVX1R-9]
}
/// @notice Withdraws the entire balance of Convex LP token from the reward pool, except the specified amount
/// disables staked token
/// @param leftoverAmount Amount of staked token to keep on the account
/// @param claim Whether to claim staking rewards
function withdrawDiffAndUnwrap(uint256 leftoverAmount, bool claim)
external
override
creditFacadeOnly // U:[CVX1R-3]
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
address creditAccount = _creditAccount(); // U:[CVX1R-10]
uint256 balance = IERC20(stakedPhantomToken).balanceOf(creditAccount); // U:[CVX1R-10]
if (balance > leftoverAmount) {
unchecked {
(tokensToEnable, tokensToDisable) = _withdrawAndUnwrap(
abi.encodeCall(IBaseRewardPool.withdrawAndUnwrap, (balance - leftoverAmount, claim)),
claim,
leftoverAmount <= 1
); // U:[CVX1R-10]
}
}
}
/// @dev Internal implementation of `withdrawAndUnwrap` and `withdrawDiffAndUnwrap`
/// - Curve LP token is enabled after the call
/// - Staked token is only disabled when withdrawing the entire balance
/// - Rewards tokens are enabled if `claim` is true
function _withdrawAndUnwrap(bytes memory callData, bool claim, bool disableStakedToken)
internal
returns (uint256 tokensToEnable, uint256 tokensToDisable)
{
_execute(callData); // U:[CVX1R-9,10]
(tokensToEnable, tokensToDisable) =
(curveLPTokenMask.enable(claim ? rewardTokensMask : 0), disableStakedToken ? stakedTokenMask : 0);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {IVersion} from "@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol";
uint8 constant BOT_PERMISSIONS_SET_FLAG = 1;
uint8 constant DEFAULT_MAX_ENABLED_TOKENS = 4;
address constant INACTIVE_CREDIT_ACCOUNT_ADDRESS = address(1);
/// @notice Debt management type
/// - `INCREASE_DEBT` borrows additional funds from the pool, updates account's debt and cumulative interest index
/// - `DECREASE_DEBT` repays debt components (quota interest and fees -> base interest and fees -> debt principal)
/// and updates all corresponding state varibles (base interest index, quota interest and fees, debt).
/// When repaying all the debt, ensures that account has no enabled quotas.
enum ManageDebtAction {
INCREASE_DEBT,
DECREASE_DEBT
}
/// @notice Collateral/debt calculation mode
/// - `GENERIC_PARAMS` returns generic data like account debt and cumulative indexes
/// - `DEBT_ONLY` is same as `GENERIC_PARAMS` but includes more detailed debt info, like accrued base/quota
/// interest and fees
/// - `FULL_COLLATERAL_CHECK_LAZY` checks whether account is sufficiently collateralized in a lazy fashion,
/// i.e. it stops iterating over collateral tokens once TWV reaches the desired target.
/// Since it may return underestimated TWV, it's only available for internal use.
/// - `DEBT_COLLATERAL` is same as `DEBT_ONLY` but also returns total value and total LT-weighted value of
/// account's tokens, this mode is used during account liquidation
/// - `DEBT_COLLATERAL_SAFE_PRICES` is same as `DEBT_COLLATERAL` but uses safe prices from price oracle
enum CollateralCalcTask {
GENERIC_PARAMS,
DEBT_ONLY,
FULL_COLLATERAL_CHECK_LAZY,
DEBT_COLLATERAL,
DEBT_COLLATERAL_SAFE_PRICES
}
struct CreditAccountInfo {
uint256 debt;
uint256 cumulativeIndexLastUpdate;
uint128 cumulativeQuotaInterest;
uint128 quotaFees;
uint256 enabledTokensMask;
uint16 flags;
uint64 lastDebtUpdate;
address borrower;
}
struct CollateralDebtData {
uint256 debt;
uint256 cumulativeIndexNow;
uint256 cumulativeIndexLastUpdate;
uint128 cumulativeQuotaInterest;
uint256 accruedInterest;
uint256 accruedFees;
uint256 totalDebtUSD;
uint256 totalValue;
uint256 totalValueUSD;
uint256 twvUSD;
uint256 enabledTokensMask;
uint256 quotedTokensMask;
address[] quotedTokens;
address _poolQuotaKeeper;
}
struct CollateralTokenData {
address token;
uint16 ltInitial;
uint16 ltFinal;
uint40 timestampRampStart;
uint24 rampDuration;
}
struct RevocationPair {
address spender;
address token;
}
interface ICreditManagerV3Events {
/// @notice Emitted when new credit configurator is set
event SetCreditConfigurator(address indexed newConfigurator);
}
/// @title Credit manager V3 interface
interface ICreditManagerV3 is IVersion, ICreditManagerV3Events {
function pool() external view returns (address);
function underlying() external view returns (address);
function creditFacade() external view returns (address);
function creditConfigurator() external view returns (address);
function addressProvider() external view returns (address);
function accountFactory() external view returns (address);
function name() external view returns (string memory);
// ------------------ //
// ACCOUNT MANAGEMENT //
// ------------------ //
function openCreditAccount(address onBehalfOf) external returns (address);
function closeCreditAccount(address creditAccount) external;
function liquidateCreditAccount(
address creditAccount,
CollateralDebtData calldata collateralDebtData,
address to,
bool isExpired
) external returns (uint256 remainingFunds, uint256 loss);
function manageDebt(address creditAccount, uint256 amount, uint256 enabledTokensMask, ManageDebtAction action)
external
returns (uint256 newDebt, uint256 tokensToEnable, uint256 tokensToDisable);
function addCollateral(address payer, address creditAccount, address token, uint256 amount)
external
returns (uint256 tokensToEnable);
function withdrawCollateral(address creditAccount, address token, uint256 amount, address to)
external
returns (uint256 tokensToDisable);
function externalCall(address creditAccount, address target, bytes calldata callData)
external
returns (bytes memory result);
function approveToken(address creditAccount, address token, address spender, uint256 amount) external;
function revokeAdapterAllowances(address creditAccount, RevocationPair[] calldata revocations) external;
// -------- //
// ADAPTERS //
// -------- //
function adapterToContract(address adapter) external view returns (address targetContract);
function contractToAdapter(address targetContract) external view returns (address adapter);
function execute(bytes calldata data) external returns (bytes memory result);
function approveCreditAccount(address token, uint256 amount) external;
function setActiveCreditAccount(address creditAccount) external;
function getActiveCreditAccountOrRevert() external view returns (address creditAccount);
// ----------------- //
// COLLATERAL CHECKS //
// ----------------- //
function priceOracle() external view returns (address);
function fullCollateralCheck(
address creditAccount,
uint256 enabledTokensMask,
uint256[] calldata collateralHints,
uint16 minHealthFactor,
bool useSafePrices
) external returns (uint256 enabledTokensMaskAfter);
function isLiquidatable(address creditAccount, uint16 minHealthFactor) external view returns (bool);
function calcDebtAndCollateral(address creditAccount, CollateralCalcTask task)
external
view
returns (CollateralDebtData memory cdd);
// ------ //
// QUOTAS //
// ------ //
function poolQuotaKeeper() external view returns (address);
function quotedTokensMask() external view returns (uint256);
function updateQuota(address creditAccount, address token, int96 quotaChange, uint96 minQuota, uint96 maxQuota)
external
returns (uint256 tokensToEnable, uint256 tokensToDisable);
// --------------------- //
// CREDIT MANAGER PARAMS //
// --------------------- //
function maxEnabledTokens() external view returns (uint8);
function fees()
external
view
returns (
uint16 feeInterest,
uint16 feeLiquidation,
uint16 liquidationDiscount,
uint16 feeLiquidationExpired,
uint16 liquidationDiscountExpired
);
function collateralTokensCount() external view returns (uint8);
function getTokenMaskOrRevert(address token) external view returns (uint256 tokenMask);
function getTokenByMask(uint256 tokenMask) external view returns (address token);
function liquidationThresholds(address token) external view returns (uint16 lt);
function ltParams(address token)
external
view
returns (uint16 ltInitial, uint16 ltFinal, uint40 timestampRampStart, uint24 rampDuration);
function collateralTokenByMask(uint256 tokenMask)
external
view
returns (address token, uint16 liquidationThreshold);
// ------------ //
// ACCOUNT INFO //
// ------------ //
function creditAccountInfo(address creditAccount)
external
view
returns (
uint256 debt,
uint256 cumulativeIndexLastUpdate,
uint128 cumulativeQuotaInterest,
uint128 quotaFees,
uint256 enabledTokensMask,
uint16 flags,
uint64 lastDebtUpdate,
address borrower
);
function getBorrowerOrRevert(address creditAccount) external view returns (address borrower);
function flagsOf(address creditAccount) external view returns (uint16);
function setFlagFor(address creditAccount, uint16 flag, bool value) external;
function enabledTokensMaskOf(address creditAccount) external view returns (uint256);
function creditAccounts() external view returns (address[] memory);
function creditAccounts(uint256 offset, uint256 limit) external view returns (address[] memory);
function creditAccountsLen() external view returns (uint256);
// ------------- //
// CONFIGURATION //
// ------------- //
function addToken(address token) external;
function setCollateralTokenData(
address token,
uint16 ltInitial,
uint16 ltFinal,
uint40 timestampRampStart,
uint24 rampDuration
) external;
function setFees(
uint16 feeInterest,
uint16 feeLiquidation,
uint16 liquidationDiscount,
uint16 feeLiquidationExpired,
uint16 liquidationDiscountExpired
) external;
function setQuotedMask(uint256 quotedTokensMask) external;
function setMaxEnabledTokens(uint8 maxEnabledTokens) external;
function setContractAllowance(address adapter, address targetContract) external;
function setCreditFacade(address creditFacade) external;
function setPriceOracle(address priceOracle) external;
function setCreditConfigurator(address creditConfigurator) external;
}// SPDX-License-Identifier: GPL-2.0-or-later
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/IAdapter.sol";
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
import {CallerNotCreditFacadeException} from "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
import {ACLTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLTrait.sol";
/// @title Abstract adapter
/// @dev Inheriting adapters MUST use provided internal functions to perform all operations with credit accounts
abstract contract AbstractAdapter is IAdapter, ACLTrait {
/// @notice Credit manager the adapter is connected to
address public immutable override creditManager;
/// @notice Address provider contract
address public immutable override addressProvider;
/// @notice Address of the contract the adapter is interacting with
address public immutable override targetContract;
/// @notice Constructor
/// @param _creditManager Credit manager to connect the adapter to
/// @param _targetContract Address of the adapted contract
constructor(address _creditManager, address _targetContract)
ACLTrait(ICreditManagerV3(_creditManager).addressProvider())
nonZeroAddress(_targetContract)
{
creditManager = _creditManager;
addressProvider = ICreditManagerV3(_creditManager).addressProvider();
targetContract = _targetContract;
}
/// @dev Ensures that caller of the function is credit facade connected to the credit manager
/// @dev Inheriting adapters MUST use this modifier in all external functions that operate on credit accounts
modifier creditFacadeOnly() {
_revertIfCallerNotCreditFacade();
_;
}
/// @dev Ensures that caller is credit facade connected to the credit manager
function _revertIfCallerNotCreditFacade() internal view {
if (msg.sender != ICreditManagerV3(creditManager).creditFacade()) {
revert CallerNotCreditFacadeException();
}
}
/// @dev Ensures that active credit account is set and returns its address
function _creditAccount() internal view returns (address) {
return ICreditManagerV3(creditManager).getActiveCreditAccountOrRevert();
}
/// @dev Ensures that token is registered as collateral in the credit manager and returns its mask
function _getMaskOrRevert(address token) internal view returns (uint256 tokenMask) {
tokenMask = ICreditManagerV3(creditManager).getTokenMaskOrRevert(token);
}
/// @dev Approves target contract to spend given token from the active credit account
/// Reverts if active credit account is not set or token is not registered as collateral
/// @param token Token to approve
/// @param amount Amount to approve
function _approveToken(address token, uint256 amount) internal {
ICreditManagerV3(creditManager).approveCreditAccount(token, amount);
}
/// @dev Executes an external call from the active credit account to the target contract
/// Reverts if active credit account is not set
/// @param callData Data to call the target contract with
/// @return result Call result
function _execute(bytes memory callData) internal returns (bytes memory result) {
return ICreditManagerV3(creditManager).execute(callData);
}
/// @dev Executes a swap operation without input token approval
/// Reverts if active credit account is not set or any of passed tokens is not registered as collateral
/// @param tokenIn Input token that credit account spends in the call
/// @param tokenOut Output token that credit account receives after the call
/// @param callData Data to call the target contract with
/// @param disableTokenIn Whether `tokenIn` should be disabled after the call
/// (for operations that spend the entire account's balance of the input token)
/// @return tokensToEnable Bit mask of tokens that should be enabled after the call
/// @return tokensToDisable Bit mask of tokens that should be disabled after the call
/// @return result Call result
function _executeSwapNoApprove(address tokenIn, address tokenOut, bytes memory callData, bool disableTokenIn)
internal
returns (uint256 tokensToEnable, uint256 tokensToDisable, bytes memory result)
{
tokensToEnable = _getMaskOrRevert(tokenOut);
uint256 tokenInMask = _getMaskOrRevert(tokenIn);
if (disableTokenIn) tokensToDisable = tokenInMask;
result = _execute(callData);
}
/// @dev Executes a swap operation with maximum input token approval, and revokes approval after the call
/// Reverts if active credit account is not set or any of passed tokens is not registered as collateral
/// @param tokenIn Input token that credit account spends in the call
/// @param tokenOut Output token that credit account receives after the call
/// @param callData Data to call the target contract with
/// @param disableTokenIn Whether `tokenIn` should be disabled after the call
/// (for operations that spend the entire account's balance of the input token)
/// @return tokensToEnable Bit mask of tokens that should be enabled after the call
/// @return tokensToDisable Bit mask of tokens that should be disabled after the call
/// @return result Call result
/// @custom:expects Credit manager reverts when trying to approve non-collateral token
function _executeSwapSafeApprove(address tokenIn, address tokenOut, bytes memory callData, bool disableTokenIn)
internal
returns (uint256 tokensToEnable, uint256 tokensToDisable, bytes memory result)
{
tokensToEnable = _getMaskOrRevert(tokenOut);
if (disableTokenIn) tokensToDisable = _getMaskOrRevert(tokenIn);
_approveToken(tokenIn, type(uint256).max);
result = _execute(callData);
_approveToken(tokenIn, 1);
}
}// SPDX-License-Identifier: UNLICENSED
// Gearbox. Generalized leverage protocol that allows to take leverage and then use it across other DeFi protocols and platforms in a composable way.
// (c) Gearbox Foundation, 2023
pragma solidity ^0.8.17;
enum AdapterType {
ABSTRACT,
UNISWAP_V2_ROUTER,
UNISWAP_V3_ROUTER,
CURVE_V1_EXCHANGE_ONLY,
YEARN_V2,
CURVE_V1_2ASSETS,
CURVE_V1_3ASSETS,
CURVE_V1_4ASSETS,
CURVE_V1_STECRV_POOL,
CURVE_V1_WRAPPER,
CONVEX_V1_BASE_REWARD_POOL,
CONVEX_V1_BOOSTER,
CONVEX_V1_CLAIM_ZAP,
LIDO_V1,
UNIVERSAL,
LIDO_WSTETH_V1,
BALANCER_VAULT,
AAVE_V2_LENDING_POOL,
AAVE_V2_WRAPPED_ATOKEN,
COMPOUND_V2_CERC20,
COMPOUND_V2_CETHER,
ERC4626_VAULT,
VELODROME_V2_ROUTER
}// SPDX-License-Identifier: BUSL-1.1
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {IncorrectParameterException} from "../interfaces/IExceptions.sol";
uint256 constant UNDERLYING_TOKEN_MASK = 1;
/// @title Bit mask library
/// @notice Implements functions that manipulate bit masks
/// Bit masks are utilized extensively by Gearbox to efficiently store token sets (enabled tokens on accounts
/// or forbidden tokens) and check for set inclusion. A mask is a uint256 number that has its i-th bit set to
/// 1 if i-th item is included into the set. For example, each token has a mask equal to 2**i, so set inclusion
/// can be checked by checking tokenMask & setMask != 0.
library BitMask {
/// @dev Calculates an index of an item based on its mask (using a binary search)
/// @dev The input should always have only 1 bit set, otherwise the result may be unpredictable
function calcIndex(uint256 mask) internal pure returns (uint8 index) {
if (mask == 0) revert IncorrectParameterException(); // U:[BM-1]
uint16 lb = 0; // U:[BM-2]
uint16 ub = 256; // U:[BM-2]
uint16 mid = 128; // U:[BM-2]
unchecked {
while (true) {
uint256 newMask = 1 << mid;
if (newMask & mask != 0) return uint8(mid); // U:[BM-2]
if (newMask > mask) ub = mid; // U:[BM-2]
else lb = mid; // U:[BM-2]
mid = (lb + ub) >> 1; // U:[BM-2]
}
}
}
/// @dev Calculates the number of `1` bits
/// @param enabledTokensMask Bit mask to compute the number of `1` bits in
function calcEnabledTokens(uint256 enabledTokensMask) internal pure returns (uint256 totalTokensEnabled) {
unchecked {
while (enabledTokensMask > 0) {
enabledTokensMask &= enabledTokensMask - 1; // U:[BM-3]
++totalTokensEnabled; // U:[BM-3]
}
}
}
/// @dev Enables bits from the second mask in the first mask
/// @param enabledTokenMask The initial mask
/// @param bitsToEnable Mask of bits to enable
function enable(uint256 enabledTokenMask, uint256 bitsToEnable) internal pure returns (uint256) {
return enabledTokenMask | bitsToEnable; // U:[BM-4]
}
/// @dev Disables bits from the second mask in the first mask
/// @param enabledTokenMask The initial mask
/// @param bitsToDisable Mask of bits to disable
function disable(uint256 enabledTokenMask, uint256 bitsToDisable) internal pure returns (uint256) {
return enabledTokenMask & ~bitsToDisable; // U:[BM-4]
}
/// @dev Computes a new mask with sets of new enabled and disabled bits
/// @dev bitsToEnable and bitsToDisable are applied sequentially to original mask
/// @param enabledTokensMask The initial mask
/// @param bitsToEnable Mask with bits to enable
/// @param bitsToDisable Mask with bits to disable
function enableDisable(uint256 enabledTokensMask, uint256 bitsToEnable, uint256 bitsToDisable)
internal
pure
returns (uint256)
{
return (enabledTokensMask | bitsToEnable) & (~bitsToDisable); // U:[BM-5]
}
/// @dev Enables bits from the second mask in the first mask, skipping specified bits
/// @param enabledTokenMask The initial mask
/// @param bitsToEnable Mask with bits to enable
/// @param invertedSkipMask An inversion of mask of immutable bits
function enable(uint256 enabledTokenMask, uint256 bitsToEnable, uint256 invertedSkipMask)
internal
pure
returns (uint256)
{
return enabledTokenMask | (bitsToEnable & invertedSkipMask); // U:[BM-6]
}
/// @dev Disables bits from the second mask in the first mask, skipping specified bits
/// @param enabledTokenMask The initial mask
/// @param bitsToDisable Mask with bits to disable
/// @param invertedSkipMask An inversion of mask of immutable bits
function disable(uint256 enabledTokenMask, uint256 bitsToDisable, uint256 invertedSkipMask)
internal
pure
returns (uint256)
{
return enabledTokenMask & (~(bitsToDisable & invertedSkipMask)); // U:[BM-6]
}
/// @dev Computes a new mask with sets of new enabled and disabled bits, skipping some bits
/// @dev bitsToEnable and bitsToDisable are applied sequentially to original mask. Skipmask is applied in both cases.
/// @param enabledTokensMask The initial mask
/// @param bitsToEnable Mask with bits to enable
/// @param bitsToDisable Mask with bits to disable
/// @param invertedSkipMask An inversion of mask of immutable bits
function enableDisable(
uint256 enabledTokensMask,
uint256 bitsToEnable,
uint256 bitsToDisable,
uint256 invertedSkipMask
) internal pure returns (uint256) {
return (enabledTokensMask | (bitsToEnable & invertedSkipMask)) & (~(bitsToDisable & invertedSkipMask)); // U:[BM-7]
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
interface IBooster {
struct PoolInfo {
address lptoken;
address token;
address gauge;
address crvRewards;
address stash;
bool shutdown;
}
function deposit(uint256 _pid, uint256 _amount, bool _stake) external returns (bool);
function depositAll(uint256 _pid, bool _stake) external returns (bool);
function withdraw(uint256 _pid, uint256 _amount) external returns (bool);
function withdrawAll(uint256 _pid) external returns (bool);
// function earmarkRewards(uint256 _pid) external returns (bool);
// function earmarkFees() external returns (bool);
//
// GETTERS
//
function poolInfo(uint256 i) external view returns (PoolInfo memory);
function poolLength() external view returns (uint256);
function staker() external view returns (address);
function minter() external view returns (address);
function crv() external view returns (address);
function registry() external view returns (address);
function stakerRewards() external view returns (address);
function lockRewards() external view returns (address);
function lockFees() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IBaseRewardPool {
//
// STATE CHANGING FUNCTIONS
//
function stake(uint256 _amount) external returns (bool);
function stakeAll() external returns (bool);
function stakeFor(address _for, uint256 _amount) external returns (bool);
function withdraw(uint256 amount, bool claim) external returns (bool);
function withdrawAll(bool claim) external;
function withdrawAndUnwrap(uint256 amount, bool claim) external returns (bool);
function withdrawAllAndUnwrap(bool claim) external;
function getReward(address _account, bool _claimExtras) external returns (bool);
function getReward() external returns (bool);
function donate(uint256 _amount) external returns (bool);
//
// GETTERS
//
function earned(address account) external view returns (uint256);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function extraRewardsLength() external view returns (uint256);
function lastTimeRewardApplicable() external view returns (uint256);
function rewardPerToken() external view returns (uint256);
function rewardToken() external view returns (IERC20);
function stakingToken() external view returns (IERC20);
function duration() external view returns (uint256);
function operator() external view returns (address);
function rewardManager() external view returns (address);
function pid() external view returns (uint256);
function periodFinish() external view returns (uint256);
function rewardRate() external view returns (uint256);
function lastUpdateTime() external view returns (uint256);
function rewardPerTokenStored() external view returns (uint256);
function queuedRewards() external view returns (uint256);
function currentRewards() external view returns (uint256);
function historicalRewards() external view returns (uint256);
function newRewardRatio() external view returns (uint256);
function userRewardPerTokenPaid(address account) external view returns (uint256);
function rewards(address account) external view returns (uint256);
function extraRewards(uint256 i) external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
pragma abicoder v1;
interface ICurveGaugeV3 {
function deposit(uint256) external;
function balanceOf(address) external view returns (uint256);
function withdraw(uint256) external;
function claim_rewards() external;
function reward_tokens(uint256) external view returns (address); //v2
function rewarded_token() external view returns (address); //v1
function lp_token() external view returns (address);
}
interface ICurveVoteEscrow {
function create_lock(uint256, uint256) external;
function increase_amount(uint256) external;
function increase_unlock_time(uint256) external;
function withdraw() external;
function smart_wallet_checker() external view returns (address);
}
interface IWalletChecker {
function check(address) external view returns (bool);
}
interface IVoting {
function vote(uint256, bool, bool) external; //voteId, support, executeIfDecided
function getVote(uint256)
external
view
returns (bool, bool, uint64, uint64, uint64, uint64, uint256, uint256, uint256, bytes memory);
function vote_for_gauge_weights(address, uint256) external;
}
interface IMinter {
function mint(address) external;
}
interface IRegistry {
function get_registry() external view returns (address);
function get_address(uint256 _id) external view returns (address);
function gauge_controller() external view returns (address);
function get_lp_token(address) external view returns (address);
function get_gauges(address) external view returns (address[10] memory, uint128[10] memory);
}
interface IStaker {
function deposit(address, address) external;
function withdraw(address) external;
function withdraw(address, address, uint256) external;
function withdrawAll(address, address) external;
function createLock(uint256, uint256) external;
function increaseAmount(uint256) external;
function increaseTime(uint256) external;
function release() external;
function claimCrv(address) external returns (uint256);
function claimRewards(address) external;
function claimFees(address, address) external;
function setStashAccess(address, bool) external;
function vote(uint256, address, bool) external;
function voteGaugeV3Weight(address, uint256) external;
function balanceOfPool(address) external view returns (uint256);
function operator() external view returns (address);
function execute(address _to, uint256 _value, bytes calldata _data) external returns (bool, bytes memory);
}
interface IRewards {
function stake(address, uint256) external;
function stakeFor(address, uint256) external;
function withdraw(address, uint256) external;
function exit(address) external;
function getReward(address) external;
function queueNewRewards(uint256) external;
function notifyRewardAmount(uint256) external;
function addExtraReward(address) external;
function stakingToken() external view returns (address);
function rewardToken() external view returns (address);
function earned(address account) external view returns (uint256);
}
interface IStash {
function stashRewards() external returns (bool);
function processStash() external returns (bool);
function claimRewards() external returns (bool);
function initialize(uint256 _pid, address _operator, address _staker, address _gauge, address _rewardFactory)
external;
}
interface IFeeDistro {
function claim() external;
function token() external view returns (address);
}
interface ITokenMinter {
function mint(address, uint256) external;
function burn(address, uint256) external;
}
interface IDeposit {
function isShutdown() external view returns (bool);
function balanceOf(address _account) external view returns (uint256);
function totalSupply() external view returns (uint256);
function poolInfo(uint256) external view returns (address, address, address, address, address, bool);
function rewardClaimed(uint256, address, uint256) external;
function withdrawTo(uint256, uint256, address) external;
function claimRewards(uint256, address) external returns (bool);
function rewardArbitrator() external returns (address);
function setGaugeV3Redirect(uint256 _pid) external returns (bool);
function owner() external returns (address);
}
interface ICrvDeposit {
function deposit(uint256, bool) external;
function lockIncentive() external view returns (uint256);
}
interface IRewardFactory {
function setAccess(address, bool) external;
function CreateCrvRewards(uint256, address) external returns (address);
function CreateTokenRewards(address, address, address) external returns (address);
function activeRewardCount(address) external view returns (uint256);
function addActiveReward(address, uint256) external returns (bool);
function removeActiveReward(address, uint256) external returns (bool);
}
interface IStashFactory {
function CreateStash(uint256, address, address, uint256) external returns (address);
}
interface ITokenFactory {
function CreateDepositToken(address) external returns (address);
}
interface IPools {
function addPool(address _lptoken, address _gauge, uint256 _stashVersion) external returns (bool);
function forceAddPool(address _lptoken, address _gauge, uint256 _stashVersion) external returns (bool);
function shutdownPool(uint256 _pid) external returns (bool);
function poolInfo(uint256) external view returns (address, address, address, address, address, bool);
function poolLength() external view returns (uint256);
function gaugeMap(address) external view returns (bool);
function setPoolManager(address _poolM) external;
}
interface IVestedEscrow {
function fund(address[] calldata _recipient, uint256[] calldata _amount) external returns (bool);
}
interface IExtraRewardWrapper {
function booster() external view returns (address);
function token() external view returns (address);
function baseToken() external view returns (address);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {IAdapter} from "@gearbox-protocol/core-v2/contracts/interfaces/IAdapter.sol";
/// @title Convex V1 BaseRewardPool adapter interface
interface IConvexV1BaseRewardPoolAdapter is IAdapter {
function curveLPtoken() external view returns (address);
function stakingToken() external view returns (address);
function stakedPhantomToken() external view returns (address);
function extraReward1() external view returns (address);
function extraReward2() external view returns (address);
function curveLPTokenMask() external view returns (uint256);
function stakingTokenMask() external view returns (uint256);
function stakedTokenMask() external view returns (uint256);
function rewardTokensMask() external view returns (uint256);
function stake(uint256) external returns (uint256 tokensToEnable, uint256 tokensToDisable);
function stakeDiff(uint256 leftoverAmount) external returns (uint256 tokensToEnable, uint256 tokensToDisable);
function getReward() external returns (uint256 tokensToEnable, uint256 tokensToDisable);
function withdraw(uint256, bool claim) external returns (uint256 tokensToEnable, uint256 tokensToDisable);
function withdrawDiff(uint256 leftoverAmount, bool claim)
external
returns (uint256 tokensToEnable, uint256 tokensToDisable);
function withdrawAndUnwrap(uint256, bool claim)
external
returns (uint256 tokensToEnable, uint256 tokensToDisable);
function withdrawDiffAndUnwrap(uint256 leftoverAmount, bool claim)
external
returns (uint256 tokensToEnable, uint256 tokensToDisable);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Holdings, 2022
pragma solidity ^0.8.10;
/// @title Version interface
/// @notice Defines contract version
interface IVersion {
/// @notice Contract version
function version() external view returns (uint256);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.0;
import { AdapterType } from "@gearbox-protocol/sdk-gov/contracts/AdapterType.sol";
/// @title Adapter interface
interface IAdapter {
function _gearboxAdapterType() external view returns (AdapterType);
function _gearboxAdapterVersion() external view returns (uint16);
function creditManager() external view returns (address);
function addressProvider() external view returns (address);
function targetContract() external view returns (address);
}// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Foundation, 2023. pragma solidity ^0.8.17; // ------- // // GENERAL // // ------- // /// @notice Thrown on attempting to set an important address to zero address error ZeroAddressException(); /// @notice Thrown when attempting to pass a zero amount to a funding-related operation error AmountCantBeZeroException(); /// @notice Thrown on incorrect input parameter error IncorrectParameterException(); /// @notice Thrown when balance is insufficient to perform an operation error InsufficientBalanceException(); /// @notice Thrown if parameter is out of range error ValueOutOfRangeException(); /// @notice Thrown when trying to send ETH to a contract that is not allowed to receive ETH directly error ReceiveIsNotAllowedException(); /// @notice Thrown on attempting to set an EOA as an important contract in the system error AddressIsNotContractException(address); /// @notice Thrown on attempting to receive a token that is not a collateral token or was forbidden error TokenNotAllowedException(); /// @notice Thrown on attempting to add a token that is already in a collateral list error TokenAlreadyAddedException(); /// @notice Thrown when attempting to use quota-related logic for a token that is not quoted in quota keeper error TokenIsNotQuotedException(); /// @notice Thrown on attempting to interact with an address that is not a valid target contract error TargetContractNotAllowedException(); /// @notice Thrown if function is not implemented error NotImplementedException(); // ------------------ // // CONTRACTS REGISTER // // ------------------ // /// @notice Thrown when an address is expected to be a registered credit manager, but is not error RegisteredCreditManagerOnlyException(); /// @notice Thrown when an address is expected to be a registered pool, but is not error RegisteredPoolOnlyException(); // ---------------- // // ADDRESS PROVIDER // // ---------------- // /// @notice Reverts if address key isn't found in address provider error AddressNotFoundException(); // ----------------- // // POOL, PQK, GAUGES // // ----------------- // /// @notice Thrown by pool-adjacent contracts when a credit manager being connected has a wrong pool address error IncompatibleCreditManagerException(); /// @notice Thrown when attempting to set an incompatible successor staking contract error IncompatibleSuccessorException(); /// @notice Thrown when attempting to vote in a non-approved contract error VotingContractNotAllowedException(); /// @notice Thrown when attempting to unvote more votes than there are error InsufficientVotesException(); /// @notice Thrown when attempting to borrow more than the second point on a two-point curve error BorrowingMoreThanU2ForbiddenException(); /// @notice Thrown when a credit manager attempts to borrow more than its limit in the current block, or in general error CreditManagerCantBorrowException(); /// @notice Thrown when attempting to connect a quota keeper to an incompatible pool error IncompatiblePoolQuotaKeeperException(); /// @notice Thrown when the quota is outside of min/max bounds error QuotaIsOutOfBoundsException(); // -------------- // // CREDIT MANAGER // // -------------- // /// @notice Thrown on failing a full collateral check after multicall error NotEnoughCollateralException(); /// @notice Thrown if an attempt to approve a collateral token to adapter's target contract fails error AllowanceFailedException(); /// @notice Thrown on attempting to perform an action for a credit account that does not exist error CreditAccountDoesNotExistException(); /// @notice Thrown on configurator attempting to add more than 255 collateral tokens error TooManyTokensException(); /// @notice Thrown if more than the maximum number of tokens were enabled on a credit account error TooManyEnabledTokensException(); /// @notice Thrown when attempting to execute a protocol interaction without active credit account set error ActiveCreditAccountNotSetException(); /// @notice Thrown when trying to update credit account's debt more than once in the same block error DebtUpdatedTwiceInOneBlockException(); /// @notice Thrown when trying to repay all debt while having active quotas error DebtToZeroWithActiveQuotasException(); /// @notice Thrown when a zero-debt account attempts to update quota error UpdateQuotaOnZeroDebtAccountException(); /// @notice Thrown when attempting to close an account with non-zero debt error CloseAccountWithNonZeroDebtException(); /// @notice Thrown when value of funds remaining on the account after liquidation is insufficient error InsufficientRemainingFundsException(); /// @notice Thrown when Credit Facade tries to write over a non-zero active Credit Account error ActiveCreditAccountOverridenException(); // ------------------- // // CREDIT CONFIGURATOR // // ------------------- // /// @notice Thrown on attempting to use a non-ERC20 contract or an EOA as a token error IncorrectTokenContractException(); /// @notice Thrown if the newly set LT if zero or greater than the underlying's LT error IncorrectLiquidationThresholdException(); /// @notice Thrown if borrowing limits are incorrect: minLimit > maxLimit or maxLimit > blockLimit error IncorrectLimitsException(); /// @notice Thrown if the new expiration date is less than the current expiration date or current timestamp error IncorrectExpirationDateException(); /// @notice Thrown if a contract returns a wrong credit manager or reverts when trying to retrieve it error IncompatibleContractException(); /// @notice Thrown if attempting to forbid an adapter that is not registered in the credit manager error AdapterIsNotRegisteredException(); // ------------- // // CREDIT FACADE // // ------------- // /// @notice Thrown when attempting to perform an action that is forbidden in whitelisted mode error ForbiddenInWhitelistedModeException(); /// @notice Thrown if credit facade is not expirable, and attempted aciton requires expirability error NotAllowedWhenNotExpirableException(); /// @notice Thrown if a selector that doesn't match any allowed function is passed to the credit facade in a multicall error UnknownMethodException(); /// @notice Thrown when trying to close an account with enabled tokens error CloseAccountWithEnabledTokensException(); /// @notice Thrown if a liquidator tries to liquidate an account with a health factor above 1 error CreditAccountNotLiquidatableException(); /// @notice Thrown if too much new debt was taken within a single block error BorrowedBlockLimitException(); /// @notice Thrown if the new debt principal for a credit account falls outside of borrowing limits error BorrowAmountOutOfLimitsException(); /// @notice Thrown if a user attempts to open an account via an expired credit facade error NotAllowedAfterExpirationException(); /// @notice Thrown if expected balances are attempted to be set twice without performing a slippage check error ExpectedBalancesAlreadySetException(); /// @notice Thrown if attempting to perform a slippage check when excepted balances are not set error ExpectedBalancesNotSetException(); /// @notice Thrown if balance of at least one token is less than expected during a slippage check error BalanceLessThanExpectedException(); /// @notice Thrown when trying to perform an action that is forbidden when credit account has enabled forbidden tokens error ForbiddenTokensException(); /// @notice Thrown when new forbidden tokens are enabled during the multicall error ForbiddenTokenEnabledException(); /// @notice Thrown when enabled forbidden token balance is increased during the multicall error ForbiddenTokenBalanceIncreasedException(); /// @notice Thrown when the remaining token balance is increased during the liquidation error RemainingTokenBalanceIncreasedException(); /// @notice Thrown if `botMulticall` is called by an address that is not approved by account owner or is forbidden error NotApprovedBotException(); /// @notice Thrown when attempting to perform a multicall action with no permission for it error NoPermissionException(uint256 permission); /// @notice Thrown when attempting to give a bot unexpected permissions error UnexpectedPermissionsException(); /// @notice Thrown when a custom HF parameter lower than 10000 is passed into the full collateral check error CustomHealthFactorTooLowException(); /// @notice Thrown when submitted collateral hint is not a valid token mask error InvalidCollateralHintException(); // ------ // // ACCESS // // ------ // /// @notice Thrown on attempting to call an access restricted function not as credit account owner error CallerNotCreditAccountOwnerException(); /// @notice Thrown on attempting to call an access restricted function not as configurator error CallerNotConfiguratorException(); /// @notice Thrown on attempting to call an access-restructed function not as account factory error CallerNotAccountFactoryException(); /// @notice Thrown on attempting to call an access restricted function not as credit manager error CallerNotCreditManagerException(); /// @notice Thrown on attempting to call an access restricted function not as credit facade error CallerNotCreditFacadeException(); /// @notice Thrown on attempting to call an access restricted function not as controller or configurator error CallerNotControllerException(); /// @notice Thrown on attempting to pause a contract without pausable admin rights error CallerNotPausableAdminException(); /// @notice Thrown on attempting to unpause a contract without unpausable admin rights error CallerNotUnpausableAdminException(); /// @notice Thrown on attempting to call an access restricted function not as gauge error CallerNotGaugeException(); /// @notice Thrown on attempting to call an access restricted function not as quota keeper error CallerNotPoolQuotaKeeperException(); /// @notice Thrown on attempting to call an access restricted function not as voter error CallerNotVoterException(); /// @notice Thrown on attempting to call an access restricted function not as allowed adapter error CallerNotAdapterException(); /// @notice Thrown on attempting to call an access restricted function not as migrator error CallerNotMigratorException(); /// @notice Thrown when an address that is not the designated executor attempts to execute a transaction error CallerNotExecutorException(); /// @notice Thrown on attempting to call an access restricted function not as veto admin error CallerNotVetoAdminException(); // ------------------- // // CONTROLLER TIMELOCK // // ------------------- // /// @notice Thrown when the new parameter values do not satisfy required conditions error ParameterChecksFailedException(); /// @notice Thrown when attempting to execute a non-queued transaction error TxNotQueuedException(); /// @notice Thrown when attempting to execute a transaction that is either immature or stale error TxExecutedOutsideTimeWindowException(); /// @notice Thrown when execution of a transaction fails error TxExecutionRevertedException(); /// @notice Thrown when the value of a parameter on execution is different from the value on queue error ParameterChangedAfterQueuedTxException(); // -------- // // BOT LIST // // -------- // /// @notice Thrown when attempting to set non-zero permissions for a forbidden or special bot error InvalidBotException(); // --------------- // // ACCOUNT FACTORY // // --------------- // /// @notice Thrown when trying to deploy second master credit account for a credit manager error MasterCreditAccountAlreadyDeployedException(); /// @notice Thrown when trying to rescue funds from a credit account that is currently in use error CreditAccountIsInUseException(); // ------------ // // PRICE ORACLE // // ------------ // /// @notice Thrown on attempting to set a token price feed to an address that is not a correct price feed error IncorrectPriceFeedException(); /// @notice Thrown on attempting to interact with a price feed for a token not added to the price oracle error PriceFeedDoesNotExistException(); /// @notice Thrown when price feed returns incorrect price for a token error IncorrectPriceException(); /// @notice Thrown when token's price feed becomes stale error StalePriceException();
// SPDX-License-Identifier: BUSL-1.1
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {IACL} from "@gearbox-protocol/core-v2/contracts/interfaces/IACL.sol";
import {AP_ACL, IAddressProviderV3, NO_VERSION_CONTROL} from "../interfaces/IAddressProviderV3.sol";
import {CallerNotConfiguratorException} from "../interfaces/IExceptions.sol";
import {SanityCheckTrait} from "./SanityCheckTrait.sol";
/// @title ACL trait
/// @notice Utility class for ACL (access-control list) consumers
abstract contract ACLTrait is SanityCheckTrait {
/// @notice ACL contract address
address public immutable acl;
/// @notice Constructor
/// @param addressProvider Address provider contract address
constructor(address addressProvider) nonZeroAddress(addressProvider) {
acl = IAddressProviderV3(addressProvider).getAddressOrRevert(AP_ACL, NO_VERSION_CONTROL);
}
/// @dev Ensures that function caller has configurator role
modifier configuratorOnly() {
_ensureCallerIsConfigurator();
_;
}
/// @dev Reverts if the caller is not the configurator
/// @dev Used to cut contract size on modifiers
function _ensureCallerIsConfigurator() internal view {
if (!_isConfigurator({account: msg.sender})) {
revert CallerNotConfiguratorException();
}
}
/// @dev Checks whether given account has configurator role
function _isConfigurator(address account) internal view returns (bool) {
return IACL(acl).isConfigurator(account);
}
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Holdings, 2022
pragma solidity ^0.8.10;
import { IVersion } from "./IVersion.sol";
interface IACLExceptions {
/// @dev Thrown when attempting to delete an address from a set that is not a pausable admin
error AddressNotPausableAdminException(address addr);
/// @dev Thrown when attempting to delete an address from a set that is not a unpausable admin
error AddressNotUnpausableAdminException(address addr);
}
interface IACLEvents {
/// @dev Emits when a new admin is added that can pause contracts
event PausableAdminAdded(address indexed newAdmin);
/// @dev Emits when a Pausable admin is removed
event PausableAdminRemoved(address indexed admin);
/// @dev Emits when a new admin is added that can unpause contracts
event UnpausableAdminAdded(address indexed newAdmin);
/// @dev Emits when an Unpausable admin is removed
event UnpausableAdminRemoved(address indexed admin);
}
/// @title ACL interface
interface IACL is IACLEvents, IACLExceptions, IVersion {
/// @dev Returns true if the address is a pausable admin and false if not
/// @param addr Address to check
function isPausableAdmin(address addr) external view returns (bool);
/// @dev Returns true if the address is unpausable admin and false if not
/// @param addr Address to check
function isUnpausableAdmin(address addr) external view returns (bool);
/// @dev Returns true if an address has configurator rights
/// @param account Address to check
function isConfigurator(address account) external view returns (bool);
/// @dev Returns address of configurator
function owner() external view returns (address);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {IVersion} from "@gearbox-protocol/core-v2/contracts/interfaces/IVersion.sol";
uint256 constant NO_VERSION_CONTROL = 0;
bytes32 constant AP_CONTRACTS_REGISTER = "CONTRACTS_REGISTER";
bytes32 constant AP_ACL = "ACL";
bytes32 constant AP_PRICE_ORACLE = "PRICE_ORACLE";
bytes32 constant AP_ACCOUNT_FACTORY = "ACCOUNT_FACTORY";
bytes32 constant AP_DATA_COMPRESSOR = "DATA_COMPRESSOR";
bytes32 constant AP_TREASURY = "TREASURY";
bytes32 constant AP_GEAR_TOKEN = "GEAR_TOKEN";
bytes32 constant AP_WETH_TOKEN = "WETH_TOKEN";
bytes32 constant AP_WETH_GATEWAY = "WETH_GATEWAY";
bytes32 constant AP_ROUTER = "ROUTER";
bytes32 constant AP_BOT_LIST = "BOT_LIST";
bytes32 constant AP_GEAR_STAKING = "GEAR_STAKING";
bytes32 constant AP_ZAPPER_REGISTER = "ZAPPER_REGISTER";
interface IAddressProviderV3Events {
/// @notice Emitted when an address is set for a contract key
event SetAddress(bytes32 indexed key, address indexed value, uint256 indexed version);
}
/// @title Address provider V3 interface
interface IAddressProviderV3 is IAddressProviderV3Events, IVersion {
function addresses(bytes32 key, uint256 _version) external view returns (address);
function getAddressOrRevert(bytes32 key, uint256 _version) external view returns (address result);
function setAddress(bytes32 key, address value, bool saveVersion) external;
}// SPDX-License-Identifier: BUSL-1.1
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;
import {ZeroAddressException} from "../interfaces/IExceptions.sol";
/// @title Sanity check trait
abstract contract SanityCheckTrait {
/// @dev Ensures that passed address is non-zero
modifier nonZeroAddress(address addr) {
_revertIfZeroAddress(addr);
_;
}
/// @dev Reverts if address is zero
function _revertIfZeroAddress(address addr) private pure {
if (addr == address(0)) revert ZeroAddressException();
}
}{
"remappings": [
"@1inch/=node_modules/@1inch/",
"@chainlink/=node_modules/@chainlink/",
"@eth-optimism/=node_modules/@eth-optimism/",
"@gearbox-protocol/=node_modules/@gearbox-protocol/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@redstone-finance/=node_modules/@redstone-finance/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"eth-gas-reporter/=node_modules/eth-gas-reporter/",
"forge-std/=lib/forge-std/src/"
],
"optimizer": {
"enabled": true,
"runs": 1000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_creditManager","type":"address"},{"internalType":"address","name":"_baseRewardPool","type":"address"},{"internalType":"address","name":"_stakedPhantomToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotCreditFacadeException","type":"error"},{"inputs":[],"name":"ZeroAddressException","type":"error"},{"inputs":[],"name":"_gearboxAdapterType","outputs":[{"internalType":"enum AdapterType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_gearboxAdapterVersion","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acl","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addressProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creditManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curveLPTokenMask","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"curveLPtoken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extraReward1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extraReward2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReward","outputs":[{"internalType":"uint256","name":"tokensToEnable","type":"uint256"},{"internalType":"uint256","name":"tokensToDisable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardTokensMask","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stake","outputs":[{"internalType":"uint256","name":"tokensToEnable","type":"uint256"},{"internalType":"uint256","name":"tokensToDisable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"leftoverAmount","type":"uint256"}],"name":"stakeDiff","outputs":[{"internalType":"uint256","name":"tokensToEnable","type":"uint256"},{"internalType":"uint256","name":"tokensToDisable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedPhantomToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakedTokenMask","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingTokenMask","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"claim","type":"bool"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"tokensToEnable","type":"uint256"},{"internalType":"uint256","name":"tokensToDisable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"claim","type":"bool"}],"name":"withdrawAndUnwrap","outputs":[{"internalType":"uint256","name":"tokensToEnable","type":"uint256"},{"internalType":"uint256","name":"tokensToDisable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"leftoverAmount","type":"uint256"},{"internalType":"bool","name":"claim","type":"bool"}],"name":"withdrawDiff","outputs":[{"internalType":"uint256","name":"tokensToEnable","type":"uint256"},{"internalType":"uint256","name":"tokensToDisable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"leftoverAmount","type":"uint256"},{"internalType":"bool","name":"claim","type":"bool"}],"name":"withdrawDiffAndUnwrap","outputs":[{"internalType":"uint256","name":"tokensToEnable","type":"uint256"},{"internalType":"uint256","name":"tokensToDisable","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6102206040523480156200001257600080fd5b5060405162001b1038038062001b108339810160408190526200003591620008ee565b8282816001600160a01b0316632954018c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000076573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009c919062000942565b80620000a881620005ef565b604051632bdad0e360e11b8152621050d360ea1b6004820152600060248201526001600160a01b038316906357b5a1c690604401602060405180830381865afa158015620000fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000120919062000942565b6001600160a01b0316608052508190506200013b81620005ef565b6001600160a01b03831660a081905260408051630a55006360e21b81529051632954018c916004808201926020929091908290030181865afa15801562000186573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001ac919062000942565b6001600160a01b0390811660c05291821660e05250604080516372f702f360e01b8152905191851692506372f702f39160048083019260209291908290030181865afa15801562000201573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000227919062000942565b6001600160a01b031661012081905262000241906200061a565b6101c0526001600160a01b03811661014081905262000260906200061a565b6101e081815250506000826001600160a01b031663570ca7356040518163ffffffff1660e01b8152600401602060405180830381865afa158015620002a9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002cf919062000942565b90506000816001600160a01b0316631526fe27856001600160a01b031663f10684546040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000321573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000347919062000969565b6040518263ffffffff1660e01b81526004016200036691815260200190565b60c060405180830381865afa15801562000384573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003aa919062000994565b80516001600160a01b0316610100819052909150620003c9906200061a565b6101a08181525050600080856001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000413573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000439919062000942565b90506200045f6200044a826200061a565b836200069260201b620009351790919060201c565b91506000846001600160a01b031663075461726040518163ffffffff1660e01b8152600401602060405180830381865afa158015620004a2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c8919062000942565b9050620004ee620004d9826200061a565b846200069260201b620009351790919060201c565b92506000806000896001600160a01b031663d55a23f46040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000534573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200055a919062000969565b905060018110620005c8576000620005728162000696565b90945090506200058f878262000692602090811b6200093517901c565b965060028210620005c657620005a6600162000696565b9093509050620005c3878262000692602090811b6200093517901c565b96505b505b506001600160a01b039182166101605216610180525050610200525062000a4e9350505050565b6001600160a01b0381166200061757604051635919af9760e11b815260040160405180910390fd5b50565b60a051604051636ae17a4360e11b81526001600160a01b038381166004830152600092169063d5c2f48690602401602060405180830381865afa15801562000666573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200068c919062000969565b92915050565b1790565b60008060e0516001600160a01b03166340c35446846040518263ffffffff1660e01b8152600401620006ca91815260200190565b602060405180830381865afa158015620006e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200070e919062000942565b6001600160a01b031663f7c618c16040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200074c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000772919062000942565b60a051604051636ae17a4360e11b81526001600160a01b03808416600483015292945091169063d5c2f48690602401602060405180830381865afa925050508015620007dd575060408051601f3d908101601f19168201909252620007da9181019062000969565b60015b620008bf57816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156200083f575060408051601f3d908101601f191682019092526200083c9181019062000942565b60015b620008b157816001600160a01b031663c55dae636040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000883573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620008a9919062000942565b9150620008b4565b91505b620008bf826200061a565b9050915091565b6001600160a01b03811681146200061757600080fd5b8051620008e981620008c6565b919050565b6000806000606084860312156200090457600080fd5b83516200091181620008c6565b60208501519093506200092481620008c6565b60408501519092506200093781620008c6565b809150509250925092565b6000602082840312156200095557600080fd5b81516200096281620008c6565b9392505050565b6000602082840312156200097c57600080fd5b5051919050565b80518015158114620008e957600080fd5b600060c08284031215620009a757600080fd5b60405160c081016001600160401b0381118282101715620009d857634e487b7160e01b600052604160045260246000fd5b604052620009e683620008dc565b8152620009f660208401620008dc565b602082015262000a0960408401620008dc565b604082015262000a1c60608401620008dc565b606082015262000a2f60808401620008dc565b608082015262000a4260a0840162000983565b60a08201529392505050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610fae62000b62600039600081816104110152818161051301528181610a250152610cbb01526000818161018c01528181610a780152610c4801526000818161044b01528181610a470152610c7601526000818161039c0152610cdd015260006102d9015260006103c30152600081816101c60152818161057501526106f001526000818161026f0152818161085401528181610bea0152610c20015260006102b2015260006103260152600061020501526000818161034d0152818161093b01528181610ad701528181610b5d0152610d3f015260006103ea0152610fae6000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063b25547d5116100d8578063d599105c1161008c578063e4b02d8e11610066578063e4b02d8e1461040c578063f205399e14610433578063f56b4b031461044657600080fd5b8063d599105c14610397578063da5b383f146103be578063de287359146103e557600080fd5b8063c12c21c0116100bd578063c12c21c014610348578063c32e72021461036f578063ce30bbdb1461038257600080fd5b8063b25547d51461030e578063bd90df701461032157600080fd5b80633e263b9b1161013a578063927188d911610114578063927188d9146102ad57806397c3413b146102d4578063a694fc3a146102fb57600080fd5b80633e263b9b1461025757806372f702f31461026a57806378aa73a41461029157600080fd5b80632954018c1161016b5780632954018c1461020057806338d07436146102275780633d18b9121461024f57600080fd5b806319178c2a1461018757806320b2c151146101c1575b600080fd5b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101b8565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b61023a610235366004610d9f565b61046d565b604080519283526020830191909152016101b8565b61023a6104c5565b61023a610265366004610d9f565b61053b565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b61029a61012c81565b60405161ffff90911681526020016101b8565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b61023a610309366004610dd4565b610661565b61023a61031c366004610d9f565b6106b6565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b61023a61037d366004610d9f565b6107cd565b61038a600a81565b6040516101b89190610ded565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b61023a610441366004610dd4565b61081a565b6101ae7f000000000000000000000000000000000000000000000000000000000000000081565b600080610478610939565b6104ba6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508893509150610a079050565b909590945092505050565b6000806104d0610939565b6105106000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610aa492505050565b507f000000000000000000000000000000000000000000000000000000000000000092600092509050565b600080610546610939565b6000610550610b59565b6040516370a0823160e01b81526001600160a01b0380831660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156105bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e09190610e15565b90508581111561065857604051868203602482015285151560448201526106529060640160408051601f198184030181529190526020810180516001600160e01b03167f38d0743600000000000000000000000000000000000000000000000000000000179052866001891115610a07565b90945092505b50509250929050565b60008061066c610939565b6106ac6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250610be2915050565b9094909350915050565b6000806106c1610939565b60006106cb610b59565b6040516370a0823160e01b81526001600160a01b0380831660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610737573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075b9190610e15565b90508581111561065857604051868203602482015285151560448201526106529060640160408051601f198184030181529190526020810180516001600160e01b03167fc32e720200000000000000000000000000000000000000000000000000000000179052866001891115610c9d565b6000806107d8610939565b6104ba6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508893509150610c9d9050565b600080610825610939565b600061082f610b59565b6040516370a0823160e01b81526001600160a01b0380831660048301529192506000917f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190610e15565b90508481111561092e5760405185820360248201526109289060440160408051601f198184030181529190526020810180516001600160e01b03167fa694fc3a000000000000000000000000000000000000000000000000000000001790526001871115610be2565b90945092505b5050915091565b1790565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632f7a18816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb9190610e2e565b6001600160a01b0316336001600160a01b031614610a05576040517f0c1d6a3f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080610a1385610aa4565b50610a6a84610a23576000610a45565b7f00000000000000000000000000000000000000000000000000000000000000005b7f00000000000000000000000000000000000000000000000000000000000000001790565b83610a76576000610a98565b7f00000000000000000000000000000000000000000000000000000000000000005b90969095509350505050565b6040517f09c5eabe0000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906309c5eabe90610b0c908590600401610e82565b6000604051808303816000875af1158015610b2b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b539190810190610ecb565b92915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166334878f546040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdd9190610e2e565b905090565b600080610c117f0000000000000000000000000000000000000000000000000000000000000000600019610d00565b610c1a84610aa4565b50610c467f00000000000000000000000000000000000000000000000000000000000000006001610d00565b7f000000000000000000000000000000000000000000000000000000000000000083610c735760006104ba565b947f0000000000000000000000000000000000000000000000000000000000000000945092505050565b600080610ca985610aa4565b50610a6a84610cb9576000610cdb565b7f00000000000000000000000000000000000000000000000000000000000000005b7f00000000000000000000000000000000000000000000000000000000000000001790565b6040517ffa30b30f0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063fa30b30f90604401600060405180830381600087803b158015610d8357600080fd5b505af1158015610d97573d6000803e3d6000fd5b505050505050565b60008060408385031215610db257600080fd5b8235915060208301358015158114610dc957600080fd5b809150509250929050565b600060208284031215610de657600080fd5b5035919050565b6020810160178310610e0f57634e487b7160e01b600052602160045260246000fd5b91905290565b600060208284031215610e2757600080fd5b5051919050565b600060208284031215610e4057600080fd5b81516001600160a01b0381168114610e5757600080fd5b9392505050565b60005b83811015610e79578181015183820152602001610e61565b50506000910152565b6020815260008251806020840152610ea1816040850160208701610e5e565b601f01601f19169190910160400192915050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215610edd57600080fd5b815167ffffffffffffffff80821115610ef557600080fd5b818401915084601f830112610f0957600080fd5b815181811115610f1b57610f1b610eb5565b604051601f8201601f19908116603f01168101908382118183101715610f4357610f43610eb5565b81604052828152876020848701011115610f5c57600080fd5b610f6d836020830160208801610e5e565b97965050505050505056fea26469706673582212209bbee7cec34085aa6bcc6de9bc7e8836513a4ba5965952b7657839e8c524e3b164736f6c634300081100330000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101825760003560e01c8063b25547d5116100d8578063d599105c1161008c578063e4b02d8e11610066578063e4b02d8e1461040c578063f205399e14610433578063f56b4b031461044657600080fd5b8063d599105c14610397578063da5b383f146103be578063de287359146103e557600080fd5b8063c12c21c0116100bd578063c12c21c014610348578063c32e72021461036f578063ce30bbdb1461038257600080fd5b8063b25547d51461030e578063bd90df701461032157600080fd5b80633e263b9b1161013a578063927188d911610114578063927188d9146102ad57806397c3413b146102d4578063a694fc3a146102fb57600080fd5b80633e263b9b1461025757806372f702f31461026a57806378aa73a41461029157600080fd5b80632954018c1161016b5780632954018c1461020057806338d07436146102275780633d18b9121461024f57600080fd5b806319178c2a1461018757806320b2c151146101c1575b600080fd5b6101ae7f000000000000000000000000000000000000000000000000000000000000040081565b6040519081526020015b60405180910390f35b6101e87f000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d81565b6040516001600160a01b0390911681526020016101b8565b6101e87f0000000000000000000000009ea7b04da02a5373317d745c1571c84aad03321d81565b61023a610235366004610d9f565b61046d565b604080519283526020830191909152016101b8565b61023a6104c5565b61023a610265366004610d9f565b61053b565b6101e87f0000000000000000000000009497df26e5bd669cb925ec68e730492b9300c48281565b61029a61012c81565b60405161ffff90911681526020016101b8565b6101e87f0000000000000000000000001e19cf2d73a72ef1332c882f20534b6519be027681565b6101e87f000000000000000000000000000000000000000000000000000000000000000081565b61023a610309366004610dd4565b610661565b61023a61031c366004610d9f565b6106b6565b6101e87f000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d81565b6101e87f0000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e81565b61023a61037d366004610d9f565b6107cd565b61038a600a81565b6040516101b89190610ded565b6101ae7f000000000000000000000000000000000000000000000000000000000010000081565b6101e87f000000000000000000000000c0c293ce456ff0ed870add98a0828dd4d2903dbf81565b6101e87f000000000000000000000000523da3a8961e4dd4f6206dbf7e6c749f51796bb381565b6101ae7f000000000000000000000000000000000000000000000000000000000000600081565b61023a610441366004610dd4565b61081a565b6101ae7f000000000000000000000000000000000000000000000000000000000020000081565b600080610478610939565b6104ba6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508893509150610a079050565b909590945092505050565b6000806104d0610939565b6105106000368080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610aa492505050565b507f000000000000000000000000000000000000000000000000000000000000600092600092509050565b600080610546610939565b6000610550610b59565b6040516370a0823160e01b81526001600160a01b0380831660048301529192506000917f000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d16906370a0823190602401602060405180830381865afa1580156105bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e09190610e15565b90508581111561065857604051868203602482015285151560448201526106529060640160408051601f198184030181529190526020810180516001600160e01b03167f38d0743600000000000000000000000000000000000000000000000000000000179052866001891115610a07565b90945092505b50509250929050565b60008061066c610939565b6106ac6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250610be2915050565b9094909350915050565b6000806106c1610939565b60006106cb610b59565b6040516370a0823160e01b81526001600160a01b0380831660048301529192506000917f000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d16906370a0823190602401602060405180830381865afa158015610737573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075b9190610e15565b90508581111561065857604051868203602482015285151560448201526106529060640160408051601f198184030181529190526020810180516001600160e01b03167fc32e720200000000000000000000000000000000000000000000000000000000179052866001891115610c9d565b6000806107d8610939565b6104ba6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508893509150610c9d9050565b600080610825610939565b600061082f610b59565b6040516370a0823160e01b81526001600160a01b0380831660048301529192506000917f0000000000000000000000009497df26e5bd669cb925ec68e730492b9300c48216906370a0823190602401602060405180830381865afa15801561089b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108bf9190610e15565b90508481111561092e5760405185820360248201526109289060440160408051601f198184030181529190526020810180516001600160e01b03167fa694fc3a000000000000000000000000000000000000000000000000000000001790526001871115610be2565b90945092505b5050915091565b1790565b7f0000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e6001600160a01b0316632f7a18816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610997573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109bb9190610e2e565b6001600160a01b0316336001600160a01b031614610a05576040517f0c1d6a3f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600080610a1385610aa4565b50610a6a84610a23576000610a45565b7f00000000000000000000000000000000000000000000000000000000000060005b7f00000000000000000000000000000000000000000000000000000000002000001790565b83610a76576000610a98565b7f00000000000000000000000000000000000000000000000000000000000004005b90969095509350505050565b6040517f09c5eabe0000000000000000000000000000000000000000000000000000000081526060906001600160a01b037f0000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e16906309c5eabe90610b0c908590600401610e82565b6000604051808303816000875af1158015610b2b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b539190810190610ecb565b92915050565b60007f0000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e6001600160a01b03166334878f546040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bdd9190610e2e565b905090565b600080610c117f0000000000000000000000009497df26e5bd669cb925ec68e730492b9300c482600019610d00565b610c1a84610aa4565b50610c467f0000000000000000000000009497df26e5bd669cb925ec68e730492b9300c4826001610d00565b7f000000000000000000000000000000000000000000000000000000000000040083610c735760006104ba565b947f0000000000000000000000000000000000000000000000000000000000200000945092505050565b600080610ca985610aa4565b50610a6a84610cb9576000610cdb565b7f00000000000000000000000000000000000000000000000000000000000060005b7f00000000000000000000000000000000000000000000000000000000001000001790565b6040517ffa30b30f0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390527f0000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e169063fa30b30f90604401600060405180830381600087803b158015610d8357600080fd5b505af1158015610d97573d6000803e3d6000fd5b505050505050565b60008060408385031215610db257600080fd5b8235915060208301358015158114610dc957600080fd5b809150509250929050565b600060208284031215610de657600080fd5b5035919050565b6020810160178310610e0f57634e487b7160e01b600052602160045260246000fd5b91905290565b600060208284031215610e2757600080fd5b5051919050565b600060208284031215610e4057600080fd5b81516001600160a01b0381168114610e5757600080fd5b9392505050565b60005b83811015610e79578181015183820152602001610e61565b50506000910152565b6020815260008251806020840152610ea1816040850160208701610e5e565b601f01601f19169190910160400192915050565b634e487b7160e01b600052604160045260246000fd5b600060208284031215610edd57600080fd5b815167ffffffffffffffff80821115610ef557600080fd5b818401915084601f830112610f0957600080fd5b815181811115610f1b57610f1b610eb5565b604051601f8201601f19908116603f01168101908382118183101715610f4357610f43610eb5565b81604052828152876020848701011115610f5c57600080fd5b610f6d836020830160208801610e5e565b97965050505050505056fea26469706673582212209bbee7cec34085aa6bcc6de9bc7e8836513a4ba5965952b7657839e8c524e3b164736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d
-----Decoded View---------------
Arg [0] : _creditManager (address): 0x6dc0EB1980fa6b3fa89F5b29937b9baab5865B3E
Arg [1] : _baseRewardPool (address): 0xDd1fE5AD401D4777cE89959b7fa587e569Bf125D
Arg [2] : _stakedPhantomToken (address): 0xDd1fE5AD401D4777cE89959b7fa587e569Bf125D
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000006dc0eb1980fa6b3fa89f5b29937b9baab5865b3e
Arg [1] : 000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d
Arg [2] : 000000000000000000000000dd1fe5ad401d4777ce89959b7fa587e569bf125d
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.