Overview
MON Balance
MON Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 35732753 | 70 days ago | Contract Creation | 0 MON |
Loading...
Loading
Contract Name:
BotListV3
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 1000 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {IBotListV3, BotInfo} from "../interfaces/IBotListV3.sol";
import {ICreditAccountV3} from "../interfaces/ICreditAccountV3.sol";
import {ICreditManagerV3} from "../interfaces/ICreditManagerV3.sol";
import {
AddressIsNotContractException,
CallerNotCreditFacadeException,
IncorrectBotPermissionsException,
InvalidBotException,
TooManyActiveBotsException
} from "../interfaces/IExceptions.sol";
import {IAddressProvider} from "../interfaces/base/IAddressProvider.sol";
import {IBot} from "../interfaces/base/IBot.sol";
import {AP_INSTANCE_MANAGER_PROXY, MAX_SANE_ACTIVE_BOTS, NO_VERSION_CONTROL} from "../libraries/Constants.sol";
import {SanityCheckTrait} from "../traits/SanityCheckTrait.sol";
/// @title Bot list V3
/// @notice Stores bot permissions (bit masks dictating which actions can be performed with credit accounts in multicall).
contract BotListV3 is IBotListV3, SanityCheckTrait, Ownable {
using EnumerableSet for EnumerableSet.AddressSet;
/// @notice Contract version
uint256 public constant override version = 3_10;
/// @notice Contract type
bytes32 public constant override contractType = "BOT_LIST";
/// @dev Mapping bot => info
mapping(address => BotInfo) internal _botInfo;
/// @dev Mapping credit manager => credit account => set of bots with non-zero permissions
mapping(address => mapping(address => EnumerableSet.AddressSet)) internal _activeBots;
/// @notice Constructor
/// @param addressProvider_ Address provider contract address
constructor(address addressProvider_) {
transferOwnership(
IAddressProvider(addressProvider_).getAddressOrRevert(AP_INSTANCE_MANAGER_PROXY, NO_VERSION_CONTROL)
);
}
// ----------- //
// PERMISSIONS //
// ----------- //
/// @notice Returns `bot`'s permissions for `creditAccount` in its credit manager
function botPermissions(address bot, address creditAccount) external view override returns (uint192) {
address creditManager = ICreditAccountV3(creditAccount).creditManager();
return _botInfo[bot].permissions[creditManager][creditAccount];
}
/// @notice Returns all bots with non-zero permissions for `creditAccount` in its credit manager
function activeBots(address creditAccount) external view override returns (address[] memory) {
address creditManager = ICreditAccountV3(creditAccount).creditManager();
return _activeBots[creditManager][creditAccount].values();
}
/// @notice Returns `bot`'s permissions for `creditAccount` in its credit manager and whether it is forbidden
function getBotStatus(address bot, address creditAccount)
external
view
override
returns (uint192 permissions, bool forbidden)
{
BotInfo storage info = _botInfo[bot];
if (info.forbidden) return (0, true);
address creditManager = ICreditAccountV3(creditAccount).creditManager();
return (info.permissions[creditManager][creditAccount], false);
}
/// @notice Sets `bot`'s permissions for `creditAccount` in its credit manager to `permissions`
/// @return activeBotsRemaining Number of bots with non-zero permissions remaining after the update
/// @dev Reverts if `creditAccount` is not opened in its credit manager or caller is not a facade connected to it
/// @dev Reverts if trying to set non-zero permissions that don't meet bot's requirements
/// @dev Reverts if trying to set non-zero permissions for a forbidden bot
/// @dev Reverts if trying to set non-zero permissions for too many bots
/// @custom:tests U:[BL-1]
function setBotPermissions(address bot, address creditAccount, uint192 permissions)
external
override
nonZeroAddress(bot)
returns (uint256 activeBotsRemaining)
{
address creditManager = ICreditAccountV3(creditAccount).creditManager();
_validateCreditAccountAndCaller(creditManager, creditAccount);
BotInfo storage info = _botInfo[bot];
EnumerableSet.AddressSet storage accountBots = _activeBots[creditManager][creditAccount];
if (permissions != 0) {
if (IBot(bot).requiredPermissions() != permissions) revert IncorrectBotPermissionsException();
if (info.forbidden) revert InvalidBotException();
accountBots.add(bot);
} else {
accountBots.remove(bot);
}
activeBotsRemaining = accountBots.length();
if (activeBotsRemaining > MAX_SANE_ACTIVE_BOTS) revert TooManyActiveBotsException();
if (info.permissions[creditManager][creditAccount] != permissions) {
info.permissions[creditManager][creditAccount] = permissions;
emit SetBotPermissions(bot, creditManager, creditAccount, permissions);
}
}
/// @notice Removes all bots' permissions for `creditAccount` in its credit manager
/// @dev Reverts if `creditAccount` is not opened in its credit manager or caller is not a facade connected to it
/// @custom:tests U:[BL-2]
function eraseAllBotPermissions(address creditAccount) external override {
address creditManager = ICreditAccountV3(creditAccount).creditManager();
_validateCreditAccountAndCaller(creditManager, creditAccount);
EnumerableSet.AddressSet storage accountBots = _activeBots[creditManager][creditAccount];
unchecked {
for (uint256 i = accountBots.length(); i != 0; --i) {
address bot = accountBots.at(i - 1);
accountBots.remove(bot);
_botInfo[bot].permissions[creditManager][creditAccount] = 0;
emit SetBotPermissions(bot, creditManager, creditAccount, 0);
}
}
}
// ------------- //
// CONFIGURATION //
// ------------- //
/// @notice Returns `bot`'s forbidden status
function botForbiddenStatus(address bot) external view override returns (bool) {
return _botInfo[bot].forbidden;
}
/// @notice Forbid's `bot`
function forbidBot(address bot) external override onlyOwner {
BotInfo storage info = _botInfo[bot];
if (!info.forbidden) {
info.forbidden = true;
emit ForbidBot(bot);
}
}
// --------- //
// INTERNALS //
// --------- //
/// @dev Reverts if `creditAccount` is not opened in `creditManager` or caller is not a facade connected to it
function _validateCreditAccountAndCaller(address creditManager, address creditAccount) internal view {
ICreditManagerV3(creditManager).getBorrowerOrRevert(creditAccount);
if (ICreditManagerV3(creditManager).creditFacade() != msg.sender) {
revert CallerNotCreditFacadeException();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastValue;
// Update the index for the moved value
set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: BUSL-1.1 // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Foundation, 2024. pragma solidity ^0.8.17; bytes32 constant AP_GEAR_TOKEN = "GLOBAL::GEAR_TOKEN"; bytes32 constant AP_INSTANCE_MANAGER_PROXY = "INSTANCE_MANAGER_PROXY"; bytes32 constant AP_CROSS_CHAIN_GOVERNANCE_PROXY = "CROSS_CHAIN_GOVERNANCE_PROXY"; bytes32 constant AP_PRICE_FEED_STORE = "PRICE_FEED_STORE"; uint256 constant NO_VERSION_CONTROL = 0; uint256 constant WAD = 1e18; uint256 constant RAY = 1e27; uint16 constant PERCENTAGE_FACTOR = 1e4; uint256 constant SECONDS_PER_YEAR = 365 days; uint256 constant EPOCH_LENGTH = 7 days; uint256 constant FIRST_EPOCH_TIMESTAMP = 1702900800; uint256 constant EPOCHS_TO_WITHDRAW = 4; uint8 constant MAX_SANE_ENABLED_TOKENS = 20; uint256 constant MAX_SANE_EPOCH_LENGTH = 28 days; uint256 constant MAX_SANE_ACTIVE_BOTS = 5; uint8 constant MAX_WITHDRAW_FEE = 100; uint8 constant DEFAULT_LIMIT_PER_BLOCK_MULTIPLIER = 2; uint8 constant BOT_PERMISSIONS_SET_FLAG = 1; uint256 constant UNDERLYING_TOKEN_MASK = 1; address constant INACTIVE_CREDIT_ACCOUNT_ADDRESS = address(1);
// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {IVersion} from "./IVersion.sol";
import {IStateSerializer} from "./IStateSerializer.sol";
/// @title Bot interface
/// @notice Minimal interface contracts must conform to in order to be used as bots in Gearbox V3
/// @dev Bots must have type `BOT::{POSTFIX}`
interface IBot is IVersion, IStateSerializer {
/// @notice Mask of permissions required for bot operation, see `ICreditFacadeV3Multicall`
function requiredPermissions() external view returns (uint192);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {IVersion} from "./base/IVersion.sol";
/// @notice Bot info
/// @param forbidden Whether bot is forbidden
/// @param permissions Mapping credit manager => credit account => bot's permissions
struct BotInfo {
bool forbidden;
mapping(address => mapping(address => uint192)) permissions;
}
interface IBotListV3Events {
// ----------- //
// PERMISSIONS //
// ----------- //
/// @notice Emitted when new `bot`'s permissions are set for `creditAccount` in `creditManager`
event SetBotPermissions(
address indexed bot, address indexed creditManager, address indexed creditAccount, uint192 permissions
);
// ------------- //
// CONFIGURATION //
// ------------- //
/// @notice Emitted when `bot` is forbidden
event ForbidBot(address indexed bot);
}
/// @title Bot list V3 interface
interface IBotListV3 is IBotListV3Events, IVersion {
// ----------- //
// PERMISSIONS //
// ----------- //
function botPermissions(address bot, address creditAccount) external view returns (uint192);
function activeBots(address creditAccount) external view returns (address[] memory);
function getBotStatus(address bot, address creditAccount)
external
view
returns (uint192 permissions, bool forbidden);
function setBotPermissions(address bot, address creditAccount, uint192 permissions)
external
returns (uint256 activeBotsRemaining);
function eraseAllBotPermissions(address creditAccount) external;
// ------------- //
// CONFIGURATION //
// ------------- //
function botForbiddenStatus(address bot) external view returns (bool);
function forbidBot(address bot) external;
}// SPDX-License-Identifier: MIT // Gearbox Protocol. Generalized leverage for DeFi protocols // (c) Gearbox Foundation, 2024. 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 attempting to connect a gauge to an incompatible pool quota keeper error IncompatibleGaugeException(); /// @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(); /// @notice Thrown if new credit configurator's set of allowed adapters differs from the current one error IncorrectAdaptersSetException(); /// @notice Thrown if attempting to schedule a token's LT ramping that is too short in duration error RampDurationTooShortException(); /// @notice Thrown if attempting to set liquidation fees such that the sum of premium and fee changes error InconsistentLiquidationFeesException(); /// @notice Thrown if attempting to set expired liquidation fees such that the sum of premium and fee changes error InconsistentExpiredLiquidationFeesException(); // ------------- // // 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(bytes4 selector); /// @notice Thrown if a liquidator tries to liquidate an account with a health factor above 1 error CreditAccountNotLiquidatableException(); /// @notice Thrown if a liquidator tries to liquidate an account with loss but violates the loss policy error CreditAccountNotLiquidatableWithLossException(); /// @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(address token); /// @notice Thrown when trying to perform an action that is forbidden when credit account has enabled forbidden tokens error ForbiddenTokensException(uint256 forbiddenTokensMask); /// @notice Thrown when forbidden token quota is increased during the multicall error ForbiddenTokenQuotaIncreasedException(address token); /// @notice Thrown when enabled forbidden token balance is increased during the multicall error ForbiddenTokenBalanceIncreasedException(address token); /// @notice Thrown when the remaining token balance is increased during the liquidation error RemainingTokenBalanceIncreasedException(address token); /// @notice Thrown if `botMulticall` is called by an address that is not approved by account owner or is forbidden error NotApprovedBotException(address bot); /// @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(uint256 permissions); /// @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(uint256 mask); /// @notice Thrown when trying to seize underlying token during partial liquidation error UnderlyingIsNotLiquidatableException(); /// @notice Thrown when amount of collateral seized during partial liquidation is less than required error SeizedLessThanRequiredException(uint256 seizedAmount); // ------ // // 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 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(); // -------- // // BOT LIST // // -------- // /// @notice Thrown when attempting to set non-zero permissions for a forbidden bot error InvalidBotException(); /// @notice Thrown when attempting to set permissions for a bot that don't meet its requirements error IncorrectBotPermissionsException(); /// @notice Thrown when attempting to set non-zero permissions for too many bots error TooManyActiveBotsException(); // --------------- // // 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 trying to apply an on-demand price update to a non-updatable price feed error PriceFeedIsNotUpdatableException(); /// @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, 2024.
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();
}
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
/// @title Version interface
/// @notice Defines contract version and type
interface IVersion {
/// @notice Contract version
function version() external view returns (uint256);
/// @notice Contract type
function contractType() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {IVersion} from "./base/IVersion.sol";
/// @title Credit account V3 interface
interface ICreditAccountV3 is IVersion {
function factory() external view returns (address);
function creditManager() external view returns (address);
function safeTransfer(address token, address to, uint256 amount) external;
function execute(address target, bytes calldata data) external returns (bytes memory result);
function rescue(address target, bytes calldata data) external;
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
import {IVersion} from "./base/IVersion.sol";
/// @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 variables (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;
}
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 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, uint256);
function addCollateral(address payer, address creditAccount, address token, uint256 amount)
external
returns (uint256);
function withdrawCollateral(address creditAccount, address token, uint256 amount, address to)
external
returns (uint256);
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;
// -------- //
// 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);
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 setContractAllowance(address adapter, address targetContract) external;
function setCreditFacade(address creditFacade) external;
function setPriceOracle(address priceOracle) external;
function setCreditConfigurator(address creditConfigurator) external;
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
interface IAddressProvider {
function getAddressOrRevert(bytes32 key, uint256 version) external view returns (address);
}// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;
/// @title State serializer interface
/// @notice Generic interface for a contract that can serialize its state into a bytes array
interface IStateSerializer {
/// @notice Serializes the state of the contract into a bytes array `serializedData`
function serialize() external view returns (bytes memory serializedData);
}{
"remappings": [
"@1inch/=lib/@1inch/",
"@gearbox-protocol/=lib/@gearbox-protocol/",
"@openzeppelin/=lib/@openzeppelin/",
"@redstone-finance/=node_modules/@redstone-finance/",
"@solady/=lib/@solady/src/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/@openzeppelin/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin/=lib/@openzeppelin/contracts/"
],
"optimizer": {
"runs": 1000,
"enabled": true
},
"metadata": {
"bytecodeHash": "none",
"useLiteralContent": true
},
"evmVersion": "shanghai",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"addressProvider_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotCreditFacadeException","type":"error"},{"inputs":[],"name":"IncorrectBotPermissionsException","type":"error"},{"inputs":[],"name":"InvalidBotException","type":"error"},{"inputs":[],"name":"TooManyActiveBotsException","type":"error"},{"inputs":[],"name":"ZeroAddressException","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bot","type":"address"}],"name":"ForbidBot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bot","type":"address"},{"indexed":true,"internalType":"address","name":"creditManager","type":"address"},{"indexed":true,"internalType":"address","name":"creditAccount","type":"address"},{"indexed":false,"internalType":"uint192","name":"permissions","type":"uint192"}],"name":"SetBotPermissions","type":"event"},{"inputs":[{"internalType":"address","name":"creditAccount","type":"address"}],"name":"activeBots","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bot","type":"address"}],"name":"botForbiddenStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bot","type":"address"},{"internalType":"address","name":"creditAccount","type":"address"}],"name":"botPermissions","outputs":[{"internalType":"uint192","name":"","type":"uint192"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractType","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"creditAccount","type":"address"}],"name":"eraseAllBotPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bot","type":"address"}],"name":"forbidBot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bot","type":"address"},{"internalType":"address","name":"creditAccount","type":"address"}],"name":"getBotStatus","outputs":[{"internalType":"uint192","name":"permissions","type":"uint192"},{"internalType":"bool","name":"forbidden","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bot","type":"address"},{"internalType":"address","name":"creditAccount","type":"address"},{"internalType":"uint192","name":"permissions","type":"uint192"}],"name":"setBotPermissions","outputs":[{"internalType":"uint256","name":"activeBotsRemaining","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801562000010575f80fd5b50604051620011a4380380620011a483398101604081905262000033916200020e565b6200003e33620000df565b604051632bdad0e360e11b81527f494e5354414e43455f4d414e414745525f50524f58590000000000000000000060048201525f6024820152620000d8906001600160a01b038316906357b5a1c690604401602060405180830381865afa158015620000ac573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620000d291906200020e565b6200012e565b506200023d565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b62000138620001b1565b6001600160a01b038116620001a35760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001ae81620000df565b50565b5f546001600160a01b031633146200020c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016200019a565b565b5f602082840312156200021f575f80fd5b81516001600160a01b038116811462000236575f80fd5b9392505050565b610f59806200024b5f395ff3fe608060405234801561000f575f80fd5b50600436106100cf575f3560e01c80638da5cb5b1161007d578063cb2ef6f711610058578063cb2ef6f7146101cd578063f2fde38b146101f4578063f439dc6714610207575f80fd5b80638da5cb5b1461016e578063997a072314610188578063c5b73ed0146101ba575f80fd5b806354fd4d50116100ad57806354fd4d501461012457806356e0381a1461013b578063715018a614610166575f80fd5b80630e2b0c94146100d3578063348f46ab146100fc57806342a3b4d614610111575b5f80fd5b6100e66100e1366004610dd5565b610242565b6040516100f39190610df0565b60405180910390f35b61010f61010a366004610dd5565b6102dc565b005b61010f61011f366004610dd5565b610347565b61012d61013681565b6040519081526020016100f3565b61014e610149366004610e3c565b6104a3565b6040516001600160c01b0390911681526020016100f3565b61010f61054c565b5f546040516001600160a01b0390911681526020016100f3565b61019b610196366004610e3c565b61055f565b604080516001600160c01b0390931683529015156020830152016100f3565b61012d6101c8366004610e87565b610631565b61012d7f424f545f4c49535400000000000000000000000000000000000000000000000081565b61010f610202366004610dd5565b61090a565b610232610215366004610dd5565b6001600160a01b03165f9081526001602052604090205460ff1690565b60405190151581526020016100f3565b60605f826001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610281573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102a59190610ecf565b6001600160a01b038082165f9081526002602090815260408083209388168352929052209091506102d59061099f565b9392505050565b6102e46109ab565b6001600160a01b0381165f908152600160205260409020805460ff1661034357805460ff191660011781556040516001600160a01b038316907fd4f28d440c8ecafba8352a114af75945a172e5b26ef0b7d79f5edfe6a1dc65cd905f90a25b5050565b5f816001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610384573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a89190610ecf565b90506103b48183610a04565b6001600160a01b038082165f9081526002602090815260408083209386168352929052908120906103e482610b30565b90505b801561049d575f6103fb835f198401610b39565b90506104078382610b44565b506001600160a01b038181165f8181526001602081815260408084208a871680865293018252808420958b1680855295825280842080547fffffffffffffffff000000000000000000000000000000000000000000000000169055519283529092917f802ff2032a278b366ea5f1bafd7e2e4ffb3d106da98810fa7cd9b495be1e33a4910160405180910390a4505f19016103e7565b50505050565b5f80826001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105059190610ecf565b6001600160a01b038086165f908152600160208181526040808420958516845294909101815283822092871682529190915220546001600160c01b03169150505b92915050565b6105546109ab565b61055d5f610b58565b565b6001600160a01b0382165f908152600160205260408120805482919060ff1615610590575f6001925092505061062a565b5f846001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f19190610ecf565b6001600160a01b039081165f90815260019093016020908152604080852092881685529190528220546001600160c01b03169350909150505b9250929050565b5f8361063c81610bbf565b5f846001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610679573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069d9190610ecf565b90506106a98186610a04565b6001600160a01b038087165f908152600160209081526040808320858516845260028352818420948a1684529390915290206001600160c01b038616156107e057856001600160c01b0316886001600160a01b0316632e7ad41f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610730573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107549190610eea565b6001600160c01b031614610794576040517f3f7a58ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815460ff16156107d0576040517ff472068000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107da8189610bff565b506107ec565b6107ea8189610b44565b505b6107f581610b30565b94506005851115610832576040517f0d02d57000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381165f9081526001840160209081526040808320938b16835292905220546001600160c01b038781169116146108ff576001600160a01b038381165f81815260018501602090815260408083208c86168085529083529281902080547fffffffffffffffff000000000000000000000000000000000000000000000000166001600160c01b038d16908117909155905190815291938c16917f802ff2032a278b366ea5f1bafd7e2e4ffb3d106da98810fa7cd9b495be1e33a4910160405180910390a45b505050509392505050565b6109126109ab565b6001600160a01b0381166109935760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61099c81610b58565b50565b60605f6102d583610c13565b5f546001600160a01b0316331461055d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161098a565b6040517fc53afb1e0000000000000000000000000000000000000000000000000000000081526001600160a01b03828116600483015283169063c53afb1e90602401602060405180830381865afa158015610a61573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a859190610ecf565b50336001600160a01b0316826001600160a01b0316632f7a18816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610acc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610af09190610ecf565b6001600160a01b031614610343576040517f0c1d6a3f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610546825490565b5f6102d58383610c6c565b5f6102d5836001600160a01b038416610c92565b5f80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811661099c576040517fb2335f2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6102d5836001600160a01b038416610d75565b6060815f01805480602002602001604051908101604052809291908181526020018280548015610c6057602002820191905f5260205f20905b815481526020019060010190808311610c4c575b50505050509050919050565b5f825f018281548110610c8157610c81610f05565b905f5260205f200154905092915050565b5f8181526001830160205260408120548015610d6c575f610cb4600183610f19565b85549091505f90610cc790600190610f19565b9050818114610d26575f865f018281548110610ce557610ce5610f05565b905f5260205f200154905080875f018481548110610d0557610d05610f05565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080610d3757610d37610f38565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610546565b5f915050610546565b5f818152600183016020526040812054610dba57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610546565b505f610546565b6001600160a01b038116811461099c575f80fd5b5f60208284031215610de5575f80fd5b81356102d581610dc1565b602080825282518282018190525f9190848201906040850190845b81811015610e305783516001600160a01b031683529284019291840191600101610e0b565b50909695505050505050565b5f8060408385031215610e4d575f80fd5b8235610e5881610dc1565b91506020830135610e6881610dc1565b809150509250929050565b6001600160c01b038116811461099c575f80fd5b5f805f60608486031215610e99575f80fd5b8335610ea481610dc1565b92506020840135610eb481610dc1565b91506040840135610ec481610e73565b809150509250925092565b5f60208284031215610edf575f80fd5b81516102d581610dc1565b5f60208284031215610efa575f80fd5b81516102d581610e73565b634e487b7160e01b5f52603260045260245ffd5b8181038181111561054657634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603160045260245ffdfea164736f6c6343000817000a000000000000000000000000f7f0a609bfab9a0a98786951ef10e5fe26cc1e38
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100cf575f3560e01c80638da5cb5b1161007d578063cb2ef6f711610058578063cb2ef6f7146101cd578063f2fde38b146101f4578063f439dc6714610207575f80fd5b80638da5cb5b1461016e578063997a072314610188578063c5b73ed0146101ba575f80fd5b806354fd4d50116100ad57806354fd4d501461012457806356e0381a1461013b578063715018a614610166575f80fd5b80630e2b0c94146100d3578063348f46ab146100fc57806342a3b4d614610111575b5f80fd5b6100e66100e1366004610dd5565b610242565b6040516100f39190610df0565b60405180910390f35b61010f61010a366004610dd5565b6102dc565b005b61010f61011f366004610dd5565b610347565b61012d61013681565b6040519081526020016100f3565b61014e610149366004610e3c565b6104a3565b6040516001600160c01b0390911681526020016100f3565b61010f61054c565b5f546040516001600160a01b0390911681526020016100f3565b61019b610196366004610e3c565b61055f565b604080516001600160c01b0390931683529015156020830152016100f3565b61012d6101c8366004610e87565b610631565b61012d7f424f545f4c49535400000000000000000000000000000000000000000000000081565b61010f610202366004610dd5565b61090a565b610232610215366004610dd5565b6001600160a01b03165f9081526001602052604090205460ff1690565b60405190151581526020016100f3565b60605f826001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610281573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102a59190610ecf565b6001600160a01b038082165f9081526002602090815260408083209388168352929052209091506102d59061099f565b9392505050565b6102e46109ab565b6001600160a01b0381165f908152600160205260409020805460ff1661034357805460ff191660011781556040516001600160a01b038316907fd4f28d440c8ecafba8352a114af75945a172e5b26ef0b7d79f5edfe6a1dc65cd905f90a25b5050565b5f816001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610384573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a89190610ecf565b90506103b48183610a04565b6001600160a01b038082165f9081526002602090815260408083209386168352929052908120906103e482610b30565b90505b801561049d575f6103fb835f198401610b39565b90506104078382610b44565b506001600160a01b038181165f8181526001602081815260408084208a871680865293018252808420958b1680855295825280842080547fffffffffffffffff000000000000000000000000000000000000000000000000169055519283529092917f802ff2032a278b366ea5f1bafd7e2e4ffb3d106da98810fa7cd9b495be1e33a4910160405180910390a4505f19016103e7565b50505050565b5f80826001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105059190610ecf565b6001600160a01b038086165f908152600160208181526040808420958516845294909101815283822092871682529190915220546001600160c01b03169150505b92915050565b6105546109ab565b61055d5f610b58565b565b6001600160a01b0382165f908152600160205260408120805482919060ff1615610590575f6001925092505061062a565b5f846001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f19190610ecf565b6001600160a01b039081165f90815260019093016020908152604080852092881685529190528220546001600160c01b03169350909150505b9250929050565b5f8361063c81610bbf565b5f846001600160a01b031663c12c21c06040518163ffffffff1660e01b8152600401602060405180830381865afa158015610679573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069d9190610ecf565b90506106a98186610a04565b6001600160a01b038087165f908152600160209081526040808320858516845260028352818420948a1684529390915290206001600160c01b038616156107e057856001600160c01b0316886001600160a01b0316632e7ad41f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610730573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107549190610eea565b6001600160c01b031614610794576040517f3f7a58ea00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815460ff16156107d0576040517ff472068000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107da8189610bff565b506107ec565b6107ea8189610b44565b505b6107f581610b30565b94506005851115610832576040517f0d02d57000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381165f9081526001840160209081526040808320938b16835292905220546001600160c01b038781169116146108ff576001600160a01b038381165f81815260018501602090815260408083208c86168085529083529281902080547fffffffffffffffff000000000000000000000000000000000000000000000000166001600160c01b038d16908117909155905190815291938c16917f802ff2032a278b366ea5f1bafd7e2e4ffb3d106da98810fa7cd9b495be1e33a4910160405180910390a45b505050509392505050565b6109126109ab565b6001600160a01b0381166109935760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61099c81610b58565b50565b60605f6102d583610c13565b5f546001600160a01b0316331461055d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161098a565b6040517fc53afb1e0000000000000000000000000000000000000000000000000000000081526001600160a01b03828116600483015283169063c53afb1e90602401602060405180830381865afa158015610a61573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a859190610ecf565b50336001600160a01b0316826001600160a01b0316632f7a18816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610acc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610af09190610ecf565b6001600160a01b031614610343576040517f0c1d6a3f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f610546825490565b5f6102d58383610c6c565b5f6102d5836001600160a01b038416610c92565b5f80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811661099c576040517fb2335f2e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6102d5836001600160a01b038416610d75565b6060815f01805480602002602001604051908101604052809291908181526020018280548015610c6057602002820191905f5260205f20905b815481526020019060010190808311610c4c575b50505050509050919050565b5f825f018281548110610c8157610c81610f05565b905f5260205f200154905092915050565b5f8181526001830160205260408120548015610d6c575f610cb4600183610f19565b85549091505f90610cc790600190610f19565b9050818114610d26575f865f018281548110610ce557610ce5610f05565b905f5260205f200154905080875f018481548110610d0557610d05610f05565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080610d3757610d37610f38565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610546565b5f915050610546565b5f818152600183016020526040812054610dba57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610546565b505f610546565b6001600160a01b038116811461099c575f80fd5b5f60208284031215610de5575f80fd5b81356102d581610dc1565b602080825282518282018190525f9190848201906040850190845b81811015610e305783516001600160a01b031683529284019291840191600101610e0b565b50909695505050505050565b5f8060408385031215610e4d575f80fd5b8235610e5881610dc1565b91506020830135610e6881610dc1565b809150509250929050565b6001600160c01b038116811461099c575f80fd5b5f805f60608486031215610e99575f80fd5b8335610ea481610dc1565b92506020840135610eb481610dc1565b91506040840135610ec481610e73565b809150509250925092565b5f60208284031215610edf575f80fd5b81516102d581610dc1565b5f60208284031215610efa575f80fd5b81516102d581610e73565b634e487b7160e01b5f52603260045260245ffd5b8181038181111561054657634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603160045260245ffdfea164736f6c6343000817000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f7f0a609bfab9a0a98786951ef10e5fe26cc1e38
-----Decoded View---------------
Arg [0] : addressProvider_ (address): 0xF7f0a609BfAb9a0A98786951ef10e5FE26cC1E38
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f7f0a609bfab9a0a98786951ef10e5fe26cc1e38
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in MON
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.