Source Code
Overview
HYPE Balance
HYPE Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
PairFactoryUpgradeable
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 2000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity =0.8.19;
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {IPairFactory} from "./interfaces/IPairFactory.sol";
import {IPair} from "./interfaces/IPair.sol";
import {IFeesVaultFactory} from "../fees/interfaces/IFeesVaultFactory.sol";
import {ICustomVolatileDynamicFee} from "./interfaces/ICustomVolatileDynamicFee.sol";
contract PairFactoryUpgradeable is IPairFactory, AccessControlUpgradeable {
bytes32 public constant override PAIRS_ADMINISTRATOR_ROLE = keccak256("PAIRS_ADMINISTRATOR");
bytes32 public constant override FEES_MANAGER_ROLE = keccak256("FEES_MANAGER");
bytes32 public constant override PAIRS_CREATOR_ROLE = keccak256("PAIRS_CREATOR");
uint256 public constant MAX_FEE = 500; // 5%
uint256 public constant PRECISION = 10000; // 100%
address public override implementation;
bool public override isPaused;
bool public override isPublicPoolCreationMode;
uint256 public protocolFee;
uint256 public stableFee;
uint256 public volatileFee;
address public communityVaultFactory;
address[] public allPairs;
mapping(address => mapping(address => mapping(bool => address))) public getPair;
mapping(address => bool) public isPair; // simplified check if its a pair, given that `stable` flag might not be available in peripherals
mapping(address => uint256) internal _customFee;
mapping(address => uint256) internal _customProtocolFee;
mapping(address => address) internal _customVolatileDynamicFeeModule;
error AddressZero();
constructor() {
_disableInitializers();
}
function initialize(address implementation_, address communityVaultFactory_) external initializer {
_checkAddressZero(implementation_);
_checkAddressZero(communityVaultFactory_);
__AccessControl_init();
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
stableFee = 4; // 0.04%
volatileFee = 18; // 0.18%
protocolFee = 10000; // 100% of stable/volatileFee to communit vaults
implementation = implementation_;
communityVaultFactory = communityVaultFactory_;
}
function upgradePairImplementation(address implementation_) external onlyRole(DEFAULT_ADMIN_ROLE) reinitializer(2) {
implementation = implementation_;
}
function setPause(bool _state) external onlyRole(PAIRS_ADMINISTRATOR_ROLE) {
isPaused = _state;
emit SetPaused(_state);
}
function setCommunityVaultFactory(address communityVaultFactory_) external onlyRole(PAIRS_ADMINISTRATOR_ROLE) {
_checkAddressZero(communityVaultFactory_);
communityVaultFactory = communityVaultFactory_;
emit SetCommunityVaultFactory(communityVaultFactory_);
}
function setIsPublicPoolCreationMode(bool mode_) external onlyRole(PAIRS_ADMINISTRATOR_ROLE) {
isPublicPoolCreationMode = mode_;
emit SetIsPublicPoolCreationMode(mode_);
}
function setProtocolFee(uint256 _newFee) external onlyRole(FEES_MANAGER_ROLE) {
if (_newFee > PRECISION) {
revert IncorrcectFee();
}
protocolFee = _newFee;
emit SetProtocolFee(_newFee);
}
function setCustomProtocolFee(address _pair, uint256 _newFee) external onlyRole(FEES_MANAGER_ROLE) {
_checkFeeAndPair(_pair, _newFee, PRECISION);
_customProtocolFee[_pair] = _newFee;
emit SetCustomProtocolFee(_pair, _newFee);
}
function setCustomVolatileDynamicFeeModule(address pair_, address module_) external onlyRole(DEFAULT_ADMIN_ROLE) {
_checkAddressZero(pair_);
/*
* @Dev Dont check for the exist of a pair, it is allowed to set
* the module for not exist pair's address in the future through the calculation of the address
*/
_customVolatileDynamicFeeModule[pair_] = module_;
emit SetCustomVolatileDynamicFeeModule(pair_, module_);
}
function setCustomFee(address _pair, uint256 _fee) external onlyRole(FEES_MANAGER_ROLE) {
_checkFeeAndPair(_pair, _fee, MAX_FEE);
_customFee[_pair] = _fee;
emit SetCustomFee(_pair, _fee);
}
function setFee(bool _stable, uint256 _fee) external onlyRole(FEES_MANAGER_ROLE) {
if (_fee == 0 || _fee > MAX_FEE) {
revert IncorrcectFee();
}
if (_stable) {
stableFee = _fee;
} else {
volatileFee = _fee;
}
emit SetFee(_stable, _fee);
}
function createPair(address tokenA, address tokenB, bool stable) external virtual override returns (address pair) {
if (!isPublicPoolCreationMode) {
_checkRole(PAIRS_CREATOR_ROLE);
}
if (tokenA == tokenB) {
revert IdenticalAddress();
}
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
if (token0 == address(0)) {
revert AddressZero();
}
if (getPair[token0][token1][stable] != address(0)) {
revert PairExist();
}
pair = Clones.cloneDeterministic(implementation, keccak256(abi.encodePacked(token0, token1, stable)));
address feesVaultForPool = IFeesVaultFactory(communityVaultFactory).createVaultForPool(pair);
IPair(pair).initialize(token0, token1, stable, feesVaultForPool);
getPair[token0][token1][stable] = pair;
getPair[token1][token0][stable] = pair; // populate mapping in the reverse direction
allPairs.push(pair);
isPair[pair] = true;
emit PairCreated(token0, token1, stable, pair, allPairs.length);
}
function hasRole(bytes32 role, address user) public view override(AccessControlUpgradeable, IPairFactory) returns (bool) {
return super.hasRole(role, user);
}
function getCustomVolatileDynamicFeeModule(address pair_) external view virtual override returns (address) {
return _customVolatileDynamicFeeModule[pair_];
}
// Stub functions for future improvments
function getHookTarget(address /*pair_*/) external view virtual override returns (address) {
return address(0);
}
function getFee(address pair_, bool stable_) external view virtual override returns (uint256) {
uint256 fee = _customFee[pair_];
if (fee != 0) {
return fee;
}
if (stable_) {
return stableFee;
}
address cDFM = _customVolatileDynamicFeeModule[pair_];
if (cDFM == address(0)) {
return volatileFee;
}
if (ICustomVolatileDynamicFee(cDFM).isEnable()) {
(bool success, uint256 dynamicFee) = ICustomVolatileDynamicFee(cDFM).getFee(pair_);
if (success) {
return dynamicFee;
}
}
return volatileFee;
}
function getProtocolFee(address pair_) external view virtual override returns (uint256) {
uint256 fee = _customProtocolFee[pair_];
if (fee != 0) {
return fee;
}
return protocolFee;
}
function allPairsLength() external view virtual override returns (uint) {
return allPairs.length;
}
function pairs() external view virtual override returns (address[] memory) {
return allPairs;
}
function _checkFeeAndPair(address pair_, uint256 fee_, uint256 upperLimit_) internal view {
if (fee_ > upperLimit_) {
revert IncorrcectFee();
}
if (!isPair[pair_]) {
revert IncorrectPair();
}
}
/**
* @dev Checked provided address on zero value, throw AddressZero error in case when addr_ is zero
*
* @param addr_ The address which will checked on zero
*/
function _checkAddressZero(address addr_) internal pure virtual {
if (addr_ == address(0)) {
revert AddressZero();
}
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @title The interface for the Algebra Vault Factory
/// @notice This contract can be used for automatic vaults creation
/// @dev Version: Algebra Integral
interface IAlgebraVaultFactory {
/// @notice returns address of the community fee vault for the pool
/// @param pool the address of Algebra Integral pool
/// @return communityFeeVault the address of community fee vault
function getVaultForPool(address pool) external view returns (address communityFeeVault);
/// @notice creates the community fee vault for the pool if needed
/// @param pool the address of Algebra Integral pool
/// @return communityFeeVault the address of community fee vault
function createVaultForPool(address pool) external returns (address communityFeeVault);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControlUpgradeable.sol";
import "../utils/ContextUpgradeable.sol";
import "../utils/StringsUpgradeable.sol";
import "../utils/introspection/ERC165Upgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function __AccessControl_init() internal onlyInitializing {
}
function __AccessControl_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `_msgSender()` is missing `role`.
* Overriding this function changes the behavior of the {onlyRole} modifier.
*
* Format of the revert message is described in {_checkRole}.
*
* _Available since v4.6._
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
StringsUpgradeable.toHexString(account),
" is missing role ",
StringsUpgradeable.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* May emit a {RoleGranted} event.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControlUpgradeable {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @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 ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
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;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeable {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMathUpgradeable {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/MathUpgradeable.sol";
import "./math/SignedMathUpgradeable.sol";
/**
* @dev String operations.
*/
library StringsUpgradeable {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = MathUpgradeable.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, MathUpgradeable.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library Clones {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(0, 0x09, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(0, 0x09, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := keccak256(add(ptr, 0x43), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
}// SPDX-License-Identifier: MIT
pragma solidity =0.8.19;
interface ICustomVolatileDynamicFee {
function isEnable() external view returns (bool);
function getFee(address pair_) external view returns (bool, uint256);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IPair {
function setCommunityVault(address communityVault_) external;
function metadata() external view returns (uint dec0, uint dec1, uint r0, uint r1, bool st, address t0, address t1);
function claimFees() external returns (uint, uint);
function tokens() external view returns (address, address);
function token0() external view returns (address);
function token1() external view returns (address);
function transferFrom(address src, address dst, uint amount) external returns (bool);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function burn(address to) external returns (uint amount0, uint amount1);
function mint(address to) external returns (uint liquidity);
function getReserves() external view returns (uint _reserve0, uint _reserve1, uint _blockTimestampLast);
function getAmountOut(uint, address) external view returns (uint);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function totalSupply() external view returns (uint);
function decimals() external view returns (uint8);
function claimable0(address _user) external view returns (uint);
function claimable1(address _user) external view returns (uint);
function isStable() external view returns (bool);
function initialize(
address token0,
address token1,
bool isStable,
address communityVault
) external;
function fees() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IPairFactory {
event PairCreated(address indexed token0, address indexed token1, bool stable, address pair, uint);
event SetPaused(bool state);
event SetCommunityVaultFactory(address indexed communityVaultFactory);
event SetIsPublicPoolCreationMode(bool mode);
event SetProtocolFee(uint256 fee);
event SetCustomProtocolFee(address indexed pair, uint256 fee);
event SetCustomFee(address indexed pair, uint256 fee);
event SetFee(bool stable, uint256 fee);
event SetCustomVolatileDynamicFeeModule(address indexed pair, address indexed module);
error IncorrcectFee();
error IncorrectPair();
error IdenticalAddress();
error PairExist();
function implementation() external view returns (address);
function PAIRS_ADMINISTRATOR_ROLE() external view returns (bytes32);
function FEES_MANAGER_ROLE() external view returns (bytes32);
function PAIRS_CREATOR_ROLE() external view returns (bytes32);
function hasRole(bytes32 role, address user) external view returns (bool);
function allPairsLength() external view returns (uint);
function isPair(address pair) external view returns (bool);
function allPairs(uint index) external view returns (address);
function getPair(address tokenA, address token, bool stable) external view returns (address);
function createPair(address tokenA, address tokenB, bool stable) external returns (address pair);
function pairs() external view returns (address[] memory);
function getFee(address pair_, bool stable_) external view returns (uint256);
function getHookTarget(address pair_) external view returns (address);
function getProtocolFee(address pair_) external view returns (uint256);
function isPaused() external view returns (bool);
function isPublicPoolCreationMode() external view returns (bool);
function getCustomVolatileDynamicFeeModule(address pair_) external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
/**
* @title Fees Vault Interface
* @dev Interface for the FeesVault contract responsible for managing fee distribution.
* Defines the essential functions and events for fee claiming and configuration.
*/
interface IFeesVault {
/**
* @dev Emitted when fees are claimed from the gauge and distributed.
* @param pool Address of the liquidity pool.
* @param token0 Address of the first token in the pool.
* @param token1 Address of the second token in the pool.
* @param totalAmount0 Total amount of token0 distributed.
* @param totalAmount1 Total amount of token1 distributed.
*/
event Fees(address indexed pool, address indexed token0, address indexed token1, uint256 totalAmount0, uint256 totalAmount1);
/**
* @notice Emitted when fees are distributed to the gauge.
* @param token Address of the token distributed.
* @param recipient Address of the gauge receiving the fees.
* @param amount Amount of fees distributed.
*/
event FeesToGauge(address indexed token, address indexed recipient, uint256 amount);
/**
* @notice Emitted when fees are distributed to a recipient other than the gauge.
* @param token Address of the token distributed.
* @param recipient Address of the entity receiving the fees.
* @param amount Amount of fees distributed.
*/
event FeesToOtherRecipient(address indexed token, address indexed recipient, uint256 amount);
/**
* @dev Reverts if the caller is not authorized to perform the operation.
*/
error AccessDenied();
/**
* @dev Reverts if the pool address provided does not match the pool address stored for a gauge.
*/
error PoolMismatch();
/**
* @notice Gets the factory address associated with this fees vault.
* @return The address of the factory contract.
*/
function factory() external view returns (address);
/**
* @notice Gets the pool address associated with this fees vault.
* @return The address of the liquidity pool.
*/
function pool() external view returns (address);
/**
* @notice Claims accumulated fees for the calling gauge and distributes them according to configured rates.
* @dev Can only be called by an authorized gauge. Distributes fees in both tokens of the associated pool.
* @return gauge0 Amount of token0 distributed to the calling gauge.
* @return gauge1 Amount of token1 distributed to the calling gauge.
*/
function claimFees() external returns (uint256 gauge0, uint256 gauge1);
/**
* @notice Allows the contract owner to recover ERC20 tokens accidentally sent to this contract.
* @param token_ The ERC20 token address to recover.
* @param amount_ The amount of tokens to recover.
*/
function emergencyRecoverERC20(address token_, uint256 amount_) external;
/**
* @dev Initializes the contract with necessary configuration parameters.
* Can only be called once by the contract factory during the deployment process.
* @param factory_ Address of the contract factory for this vault.
* @param pool_ Address of the liquidity pool associated with this vault.
*/
function initialize(address factory_, address pool_) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
import {IAccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol";
import {IAlgebraVaultFactory} from "@cryptoalgebra/integral-core/contracts/interfaces/vault/IAlgebraVaultFactory.sol";
import {IFeesVault} from "./IFeesVault.sol";
/**
* @title IFeesVaultFactory Interface
* @dev Interface for the `FeesVaultFactory` contract. It defines the events, errors,
* and functions related to the creation and management of fee vaults for pools.
*
* This interface extends `IAlgebraVaultFactory`, inheriting its functionalities
* and integrating them with specific requirements for fee vault management.
*/
interface IFeesVaultFactory is IAlgebraVaultFactory, IAccessControlUpgradeable {
/**
* @dev Structure for holding distribution configuration details.
* Used to set how fees are distributed to various recipients including gauges.
*/
struct DistributionConfig {
uint256 toGaugeRate; // The rate at which fees are distributed to the gauge.
address[] recipients; // The addresses of the recipients who will receive the fees.
uint256[] rates; // The rates at which fees are distributed to each recipient.
}
/**
* @dev Emitted when a default distribution configuration is change.
* @param config The distribution configuration applied to all fees vault.
*/
event DefaultDistributionConfig(DistributionConfig config);
/**
* @dev Emitted when a custom distribution configuration is set for a fees vault.
* @param feesVault The address of the fees vault for which the configuration is set.
* @param config The custom distribution configuration applied to the fees vault.
*/
event CustomDistributionConfig(address indexed feesVault, DistributionConfig config);
/**
* @dev Emitted when the implementation of the fees vault is changed.
* This allows the system to upgrade the fees vault logic.
* @param oldImplementation The address of the previous fees vault implementation.
* @param newImplementation The address of the new fees vault implementation.
*/
event FeesVaultImplementationChanged(address indexed oldImplementation, address indexed newImplementation);
/**
* @dev Emitted when a new FeesVault is created for a pool.
*
* @param pool Address of the pool for which the FeesVault was created.
* @param feesVault Address of the newly created FeesVault.
*/
event FeesVaultCreated(address indexed pool, address indexed feesVault);
/**
* @dev Emitted when the voter address is updated. This address is used for voting in fee vaults.
*
* @param oldVoter The address of the previous voter.
* @param newVoter The address of the new voter that has been set.
*/
event SetVoter(address indexed oldVoter, address indexed newVoter);
/**
* @dev Emitted when a custom distribution configuration is set for a creator.
* @param creator The address of the creator for which the configuration is set.
* @param config The custom distribution configuration applied to the fees vault created by creator.
*/
event CreatorDistributionConfig(address indexed creator, DistributionConfig config);
/**
* @dev Emitted when the creator for multiple fees vaults is changed.
* @param creator_ The new creator address associated with the fees vaults.
* @param feesVaults The array of fees vault addresses that had their creator changed.
*/
event ChangeCreatorForFeesVaults(address indexed creator_, address[] feesVaults);
/**
* @dev Error indicating that a fee vault creation attempt was made for a pool that already has an associated vault.
*/
error AlreadyCreated();
/**
* @dev Error indicating that an action (such as creating a fee vault) was attempted by an address that is not whitelisted.
*/
error AccessDenied();
/**
* @dev Error indicating that the lengths of two related arrays (e.g., recipients and rates) do not match.
*/
error ArraysLengthMismatch();
/**
* @dev Error indicating that the sum of rates does not meet the expected total (e.g., 10000 for 100% in basis points).
*/
error IncorrectRates();
/**
* @notice Gets the unique identifier for the role allowed to call fee claiming functions.
* @return The identifier for the claim fees caller role.
*/
function CLAIM_FEES_CALLER_ROLE() external view returns (bytes32);
/**
* @notice Gets the unique identifier for the role that can create new fee vaults.
* @return The identifier for the whitelisted creator role.
*/
function WHITELISTED_CREATOR_ROLE() external view returns (bytes32);
/**
* @notice Gets the unique identifier for the role responsible for fee vault administration.
* @return The identifier for the fees vault administrator role.
*/
function FEES_VAULT_ADMINISTRATOR_ROLE() external view returns (bytes32);
/**
* @notice Retrieves the distribution configuration for a specific fees vault.
* @param feesVault_ The address of the fees vault.
* @return toGaugeRate The rate at which fees are distributed to the gauge.
* @return recipients The addresses of the recipients.
* @return rates The rates at which fees are distributed to the recipients.
*/
function getDistributionConfig(
address feesVault_
) external view returns (uint256 toGaugeRate, address[] memory recipients, uint256[] memory rates);
/**
* @notice Retrieves the distribution configuration for a specific creator.
* @param creator_ The address of the creator.
* @return toGaugeRate The rate at which fees are distributed to the gauge.
* @return recipients The addresses of the recipients.
* @return rates The rates at which fees are distributed to the recipients.
*/
function creatorDistributionConfig(
address creator_
) external view returns (uint256 toGaugeRate, address[] memory recipients, uint256[] memory rates);
/**
* @notice Returns the default distribution configuration used by the factory.
* @return toGaugeRate The default rate at which fees are distributed to the gauge.
* @return recipients The default addresses of the recipients.
* @return rates The default rates at which fees are distributed to the recipients.
*/
function defaultDistributionConfig() external view returns (uint256 toGaugeRate, address[] memory recipients, uint256[] memory rates);
/**
* @notice Returns the custom distribution configuration for a specified fees vault.
* @param feesVault_ The address of the fees vault.
* @return toGaugeRate The rate at which fees are distributed to the gauge.
* @return recipients The addresses of the recipients.
* @return rates The rates at which fees are distributed to the recipients.
*/
function customDistributionConfig(
address feesVault_
) external view returns (uint256 toGaugeRate, address[] memory recipients, uint256[] memory rates);
/**
* @notice Checks if a fees vault has a custom configuration.
* @param feesVault_ The address of the fees vault to check.
* @return True if the fees vault has a custom configuration, false otherwise.
*/
function isCustomConfig(address feesVault_) external view returns (bool);
/**
* @notice Returns the current voter address used in fee vaults.
* @return The address of the current voter.
*/
function voter() external view returns (address);
/**
* @notice Returns the current fees vault implementation address.
* @return The address of the current fees vault implementation.
*/
function feesVaultImplementation() external view returns (address);
/**
* @notice Changes the implementation of the fees vault used by all vaults.
* @param implementation_ The new fees vault implementation address.
*/
function changeImplementation(address implementation_) external;
/**
* @notice Retrieves the creator address for a specific fees vault.
* @param feesVault_ The address of the fees vault.
* @return The address of the creator associated with the specified fees vault.
*/
function getFeesVaultCreator(address feesVault_) external view returns (address);
/**
* @dev Sets the address used for voting in the fee vaults. Only callable by the contract owner.
*
* @param voter_ The new voter address to be set.
*/
function setVoter(address voter_) external;
/**
* @notice Sets a custom distribution configuration for a specific fees vault.
* @param feesVault_ The address of the fees vault to configure.
* @param config_ The custom distribution configuration to apply.
*/
function setCustomDistributionConfig(address feesVault_, DistributionConfig memory config_) external;
/**
* @notice Sets a default distribution configuration for a fees vaults.
* @param config_ The distribution configuration to apply.
*/
function setDefaultDistributionConfig(DistributionConfig memory config_) external;
/**
* @notice Sets a custom distribution configuration for a specific creator.
* @param creator_ The address of the creator of fees vaults.
* @param config_ The custom distribution configuration to apply.
*/
function setDistributionConfigForCreator(address creator_, DistributionConfig memory config_) external;
/**
* @notice Changes the creator for multiple fees vaults.
* @param creator_ The new creator address.
* @param feesVaults_ The array of fees vault addresses.
*/
function changeCreatorForFeesVaults(address creator_, address[] calldata feesVaults_) external;
}{
"evmVersion": "paris",
"viaIR": true,
"optimizer": {
"enabled": true,
"runs": 2000
},
"metadata": {
"bytecodeHash": "none"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[],"name":"IdenticalAddress","type":"error"},{"inputs":[],"name":"IncorrcectFee","type":"error"},{"inputs":[],"name":"IncorrectPair","type":"error"},{"inputs":[],"name":"PairExist","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"communityVaultFactory","type":"address"}],"name":"SetCommunityVaultFactory","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetCustomFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetCustomProtocolFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":true,"internalType":"address","name":"module","type":"address"}],"name":"SetCustomVolatileDynamicFeeModule","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"stable","type":"bool"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"mode","type":"bool"}],"name":"SetIsPublicPoolCreationMode","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"SetPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SetProtocolFee","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEES_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAIRS_ADMINISTRATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAIRS_CREATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"communityVaultFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair_","type":"address"}],"name":"getCustomVolatileDynamicFeeModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair_","type":"address"},{"internalType":"bool","name":"stable_","type":"bool"}],"name":"getFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getHookTarget","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair_","type":"address"}],"name":"getProtocolFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"user","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation_","type":"address"},{"internalType":"address","name":"communityVaultFactory_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicPoolCreationMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairs","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"communityVaultFactory_","type":"address"}],"name":"setCommunityVaultFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setCustomFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"},{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setCustomProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair_","type":"address"},{"internalType":"address","name":"module_","type":"address"}],"name":"setCustomVolatileDynamicFeeModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_stable","type":"bool"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"mode_","type":"bool"}],"name":"setIsPublicPoolCreationMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stableFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation_","type":"address"}],"name":"upgradePairImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"volatileFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608080604052346100c1576000549060ff8260081c1661006f575060ff80821603610034575b60405161227290816100c78239f35b60ff90811916176000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a138610025565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b600080fdfe60806040908082526004908136101561001757600080fd5b600091823560e01c91826301ffc9a71461166c575081630a992e0c146116465781631e3dd18b146116035781631e993146146115dd578163248a9ca3146115b15781632f2ff15d146114ef5781633308a9111461146657816336568abe146113c757816340bbd775146113a8578163485cc955146111705781635084ed0314611151578163574f2ba3146111325781635c60da1b1461110a5781635d2493ab1461107257816360bd1cd814610ff857816363d2127314610fd15781636801cc3014610f71578163787dce3d14610f095781637b9ed09714610ece5781637f46859f14610e3c57816382dfdce4146107ba57816384d397cc1461077f57816391d148541461072a578163a217fddf1461070f578163aaf5eb68146106f2578163ad71f37d146106b7578163b0e21e8a14610698578163b187bd2614610671578163b81be49c14610649578163bc063e1a1461062c578163bedb86fb14610595578163cc56b2c514610554578163d200607b1461051a578163d49466a814610459578163d547741f14610416578163e1f76b441461038057508063e5e31b1314610344578063fbdd9ff7146102995763ffb0a4a0146101d357600080fd5b34610296578060031936011261029657908051918290609c549182855260208095018093609c84527faf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539c90845b8181106102795750505081610235910382611e65565b83519485948186019282875251809352850193925b82811061025957505050500390f35b83516001600160a01b03168552869550938101939281019260010161024a565b82546001600160a01b03168452928801926001928301920161021f565b80fd5b5090346103405760206003193601126103405760207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249891600261ffff196102de61170a565b6102e6611afa565b6001600160a01b0387549160ff8360081c161580610334575b61030890612008565b1673ffffffffffffffffffffffffffffffffffffffff196097541617609755161784555160028152a180f35b5060ff831685116102ff565b5080fd5b5090346103405760206003193601126103405760ff816020936001600160a01b0361036d61170a565b168152609e855220541690519015158152f35b82843461034057806003193601126103405761039a611783565b6024356103a56117a1565b8015801561040b575b6103fc577f1fb2cf9d6edce0746aa2a7f1eb8d4844f40803775b9475bdbaaa8bb9f87e8733939450816000146103f357806099555b825191151582526020820152a180f35b80609a556103e3565b8483516347c115ef60e11b8152fd5b506101f481116103ae565b90508234610455578060031936011261045557610452913561044d600161043b611720565b93838752606560205286200154611cc5565b611e88565b80f35b8280fd5b9050823461045557806003193601126104555761047461170a565b90602435916104816117a1565b6101f4831161050b576001600160a01b03169283600052609e60205260ff826000205416156104e457507fae468ce586f9a87660fdffc1448cee942042c16ae2f02046b134b5224f31936b91602091848652609f8352818187205551908152a280f35b90517f30e17e47000000000000000000000000000000000000000000000000000000008152fd5b8382516347c115ef60e11b8152fd5b82843461034057602060031936011261034057602091816001600160a01b03918261054361170a565b16815260a185522054169051908152f35b5050346102965781600319360112610296575061056f61170a565b906024359182151583036105905760209261058991612086565b9051908152f35b600080fd5b8284346103405760206003193601126103405760207f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b5980916105d4611783565b6105dc6119a6565b1515906097547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000008460a01b1691161760975551908152a180f35b828434610340578160031936011261034057602090516101f48152f35b8284346103405781600319360112610340576020906001600160a01b03609b54169051908152f35b82843461034057816003193601126103405760209060ff60975460a01c1690519015158152f35b8284346103405781600319360112610340576020906098549051908152f35b828434610340578160031936011261034057602090517f4f895bdce78ed3edb90e9af75173c797e6234073a00b76fc9593b754504e75208152f35b828434610340578160031936011261034057602090516127108152f35b82843461034057816003193601126103405751908152602090f35b8383346102965781600319360112610296575061077660209261074b611720565b903560005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b90519015158152f35b828434610340578160031936011261034057602090517f8bb7efba716b8bd9b59b6661dd03848105f980fb29035ebc6d805a30527f6e3d8152f35b8284346103405760609182600319360112610296576107d761170a565b936107e0611720565b936107e9611792565b6097549360ff8560a81c1615610c06575b6001600160a01b0397888816898216818114610bde571015610bd85796975b808816948515610bb157858352602099609d8b5288842097838216988986528c52898520951515958686528c52838a86205416610b895789519a8c8c01927fffffffffffffffffffffffffffffffffffffffff00000000000000000000000080928a1b168452881b1660348c01528560f81b60488c015260298b52868b019067ffffffffffffffff928c831084841117610b7657828c528c519020608882901c62ffffff16763d602d80600a3d3981f3363d3d373d3d3d363d7300000017875260789190911b7fffffffffffffffffffffffffffffffffff000000000000000000000000000000166e5af43d82803e903d91602b57fd5bf3178d5284906037600988f5169a8b15610b3657505083908b84609b541660248d8d5195869384927fcbc48015000000000000000000000000000000000000000000000000000000008452898401525af1918215610af0578592610afe575b508a3b15610afa57848960848a838f8f8a905198899687957ffb162e030000000000000000000000000000000000000000000000000000000087528c87015260248601528d60448601521660648401525af18015610af057610aca575b5050858352609d8a52878320876000528a52876000208484528a5287832073ffffffffffffffffffffffffffffffffffffffff19908a82825416179055878452609d8b52888420876000528b52886000208585528b528989852091825416179055609c549068010000000000000000821015610ab75750918791610a798460017fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc998979601609c55611736565b819291549060031b918c831b921b1916179055888152609e8a5220600160ff19825416179055609c548651918252878983015286820152a351908152f35b836041602492634e487b7160e01b835252fd5b8194929411610add578852918a806109cc565b602482604186634e487b7160e01b835252fd5b8a513d87823e3d90fd5b8480fd5b9091508b81813d8311610b2f575b610b168183611e65565b81010312610afa57518381168103610afa57908c61096f565b503d610b0c565b907f455243313136373a2063726561746532206661696c656400000000000000000060a46064938f62461bcd60e51b855285820152601760848201520152fd5b602487604187634e487b7160e01b835252fd5b828a517f148ea712000000000000000000000000000000000000000000000000000000008152fd5b87517f9fabe1c1000000000000000000000000000000000000000000000000000000008152fd5b97610819565b8689517f065af08d000000000000000000000000000000000000000000000000000000008152fd5b7f4f895bdce78ed3edb90e9af75173c797e6234073a00b76fc9593b754504e752080825260209060658252878320338452825260ff888420541615610c4c5750506107fa565b8786918685610c5a33611f23565b92845191610c6783611e33565b6042835287830193368537825115610e295760308453825190600191821015610e165790607860218501536041915b818311610dab57505050610d6a57610d61610d3085610d3f6048601f1997601f978c9760449c9b51968793610cfb8b86019b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008d528251928391603789019101611e10565b8401917f206973206d697373696e6720726f6c6520000000000000000000000000000000603784015251809386840190611e10565b01036028810185520183611e65565b5197889662461bcd60e51b885287015251809281602488015287870190611e10565b01168101030190fd5b606485878087519262461bcd60e51b845283015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f81166010811015610e03576f181899199a1a9b1b9c1cb0b131b232b360811b901a610ddb8587611f12565b53881c928015610df057600019019190610c96565b60248260118b634e487b7160e01b835252fd5b60248360328c634e487b7160e01b835252fd5b80603289634e487b7160e01b6024945252fd5b80603288634e487b7160e01b6024945252fd5b828434610340578060031936011261034057610e5661170a565b90610e5f611720565b91610e68611afa565b610e718161222b565b6001600160a01b038091169182855260a160205284209216918273ffffffffffffffffffffffffffffffffffffffff198254161790557fa34c8f8c0857528213e2969b5021064348257fffa370db24875ec58c58e2a3278380a380f35b828434610340578160031936011261034057602090517fad51469fd38cb9e4028f769761e769052a9f1f331b57ad921ac8a45c7903db288152f35b9050823461045557602060031936011261045557813591610f286117a1565b6127108311610f635750816020917fdc0410a296e1e33943a772020d333d5f99319d7fcad932a484c53889f7aaa2b19360985551908152a180f35b90516347c115ef60e11b8152fd5b8284346103405760606003193601126103405760209181610f9061170a565b91610f99611720565b610fa1611792565b906001600160a01b038095168352609d875284848420911683528652828220901515825285522054169051908152f35b82843461034057816003193601126103405760209060ff60975460a81c1690519015158152f35b8234610296576020600319360112610296576001600160a01b0361101a61170a565b6110226119a6565b61102b8161222b565b168073ffffffffffffffffffffffffffffffffffffffff19609b541617609b557fec55263cf7b30d6716a77f60e239b32ea5440e3e28db3385a6b660536019fab08280a280f35b8284346103405760206003193601126103405760207fe0d91255877f509ef94e58048122555ad1bd99f629f79a19f21331719adcc783916110b1611783565b6110b96119a6565b1515906097547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff75ff0000000000000000000000000000000000000000008460a81b1691161760975551908152a180f35b8284346103405781600319360112610340576020906001600160a01b03609754169051908152f35b828434610340578160031936011261034057602090609c549051908152f35b828434610340578160031936011261034057602090609a549051908152f35b8391503461045557816003193601126104555761118b61170a565b611193611720565b84549260ff8460081c16159384809561139b575b8015611384575b6111b790612008565b60ff1990856001838316178955611373575b506111d38461222b565b6111dc8361222b565b60ff875460081c161561130a573360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b602052604090205460ff16156112c0575b506099556012609a556127106098556001600160a01b03908173ffffffffffffffffffffffffffffffffffffffff1993168360975416176097551690609b541617609b5561126d575080f35b60207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff84541684555160018152a180f35b86805260656020528587203388526020526001868820918254161790553333877f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a486611221565b608482602088519162461bcd60e51b8352820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152fd5b61ffff1916610101178755876111c9565b50303b1580156111ae575060ff81166001146111ae565b50600160ff8216106111a7565b8284346103405781600319360112610340576020906099549051908152f35b9050346103405782600319360112610340576113e1611720565b90336001600160a01b038316036113fd57906104529135611e88565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b9050823461045557806003193601126104555761148161170a565b906024359161148e6117a1565b612710831161050b576001600160a01b031692838552609e60205260ff8286205416156104e457507f3edf569ca74e0ce148d10add24c5d2adf90acb6681c9e253179e6210492ea0f49160209184865260a08352818187205551908152a280f35b83915034610455578160031936011261045557359061150c611720565b90828452606560205261152460018286200154611cc5565b611552828460005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b1561155b578380f35b82845260656020526001600160a01b038185209216918285526020528320600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a48180808380f35b839150346104555760206003193601126104555781602093600192358152606585522001549051908152f35b82843461034057602060031936011261034057906020916115fc61170a565b5051908152f35b83915034610455576020600319360112610455573591609c5483101561029657506001600160a01b03611637602093611736565b92905490519260031b1c168152f35b8284346103405760206003193601126103405760209061058961166761170a565b612208565b91503461045557602060031936011261045557357fffffffff00000000000000000000000000000000000000000000000000000000811680910361045557602092507f7965db0b0000000000000000000000000000000000000000000000000000000081149081156116e0575b5015158152f35b7f01ffc9a700000000000000000000000000000000000000000000000000000000915014836116d9565b600435906001600160a01b038216820361059057565b602435906001600160a01b038216820361059057565b609c5481101561176d57609c6000527faf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539c0190600090565b634e487b7160e01b600052603260045260246000fd5b60043590811515820361059057565b60443590811515820361059057565b3360009081527fec8ecf116caa65c9911ee2546d1ab511e533ae7db621e6d310ee76029295d61860209081526040808320547fad51469fd38cb9e4028f769761e769052a9f1f331b57ad921ac8a45c7903db28919060ff16156118045750505050565b61180d33611f23565b9181519061181a82611e33565b6042825284820195606036883782511561199257603087538251906001918210156119925790607860218501536041915b818311611924575050506118e25760449392610d61836118be6048601f95601f1997519a8b916118af8b8401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a52610cfb8d8251928391603789019101611e10565b0103602881018b520189611e65565b5196879562461bcd60e51b8752600487015251809281602488015287870190611e10565b60648483519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f8116601081101561197e576f181899199a1a9b1b9c1cb0b131b232b360811b901a6119548587611f12565b5360041c92801561196a5760001901919061184b565b602482634e487b7160e01b81526011600452fd5b602483634e487b7160e01b81526032600452fd5b80634e487b7160e01b602492526032600452fd5b3360009081527f36bd584c1759857bde74c3d5ab74682360b4c37ab0107567f071641a51a9180f60209081526040808320547f8bb7efba716b8bd9b59b6661dd03848105f980fb29035ebc6d805a30527f6e3d919060ff1615611a095750505050565b611a1233611f23565b91815190611a1f82611e33565b6042825284820195606036883782511561199257603087538251906001918210156119925790607860218501536041915b818311611ab4575050506118e25760449392610d61836118be6048601f95601f1997519a8b916118af8b8401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a52610cfb8d8251928391603789019101611e10565b909192600f8116601081101561197e576f181899199a1a9b1b9c1cb0b131b232b360811b901a611ae48587611f12565b5360041c92801561196a57600019019190611a50565b3360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b602052604090205460ff1615611b3357565b611b3c33611f23565b604051600091611b4b82611e33565b6042825260209182810193606036863781511561199257603085538151600190811015611cb157607860218401536041905b808211611c57575050611c1457601f60449392611beb6048601f1994604051988991611bdc898401967f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008852610cfb815180928d603789019101611e10565b01036028810189520187611e65565b610d6160405196879562461bcd60e51b8752600487015251809281602488015287870190611e10565b6064836040519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f8116601081101561176d576f181899199a1a9b1b9c1cb0b131b232b360811b901a611c868486611f12565b5360041c918015611c9b576000190190611b7d565b634e487b7160e01b600052601160045260246000fd5b602482634e487b7160e01b81526032600452fd5b611cf3338260005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b15611cfb5750565b611d0433611f23565b60405190611d1182611e33565b6042825260209182810193606036863781511561176d5760308553815160019081101561176d57607860218401536041905b808211611da2575050611c1457601f60449392611beb6048601f1994604051988991611bdc898401967f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008852610cfb815180928d603789019101611e10565b9091600f81166010811015611dfb576f181899199a1a9b1b9c1cb0b131b232b360811b901a611dd18486611f12565b5360041c918015611de6576000190190611d43565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b60005b838110611e235750506000910152565b8181015183820152602001611e13565b6080810190811067ffffffffffffffff821117611e4f57604052565b634e487b7160e01b600052604160045260246000fd5b90601f601f19910116810190811067ffffffffffffffff821117611e4f57604052565b90611eb7818360005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b611ebf575050565b60009180835260656020526001600160a01b03604084209216918284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b90815181101561176d570160200190565b604051906060820182811067ffffffffffffffff821117611e4f57604052602a825260208201604036823782511561176d5760309053815160019081101561176d57607860218401536029905b808211611fc4575050611f805790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015611dfb576f181899199a1a9b1b9c1cb0b131b232b360811b901a611ff38486611f12565b5360041c918015611de6576000190190611f70565b1561200f57565b608460405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152fd5b5190811515820361059057565b906001600160a01b03809216600092818452602090609f825260409384862054806121fe57506121f35760a1825283852054169182156121015783517f4bb77d680000000000000000000000000000000000000000000000000000000081528281600481875afa9081156121e95786916121b0575b5061210c575b5050505050609a5490565b839060248251809581937fb88c914800000000000000000000000000000000000000000000000000000000835260048301525afa9384156121a55780938195612164575b505050506121615780808080612101565b90565b9294509092509083813d811161219e575b61217f8183611e65565b81010312610296575061219182612079565b9101519038808080612150565b503d612175565b8351903d90823e3d90fd5b90508281813d83116121e2575b6121c78183611e65565b810103126121de576121d890612079565b386120fb565b8580fd5b503d6121bd565b85513d88823e3d90fd5b505050505060995490565b9550505050505090565b6001600160a01b031660005260a060205260406000205480612161575060985490565b6001600160a01b03161561223b57565b60046040517f9fabe1c1000000000000000000000000000000000000000000000000000000008152fdfea164736f6c6343000813000a
Deployed Bytecode
0x60806040908082526004908136101561001757600080fd5b600091823560e01c91826301ffc9a71461166c575081630a992e0c146116465781631e3dd18b146116035781631e993146146115dd578163248a9ca3146115b15781632f2ff15d146114ef5781633308a9111461146657816336568abe146113c757816340bbd775146113a8578163485cc955146111705781635084ed0314611151578163574f2ba3146111325781635c60da1b1461110a5781635d2493ab1461107257816360bd1cd814610ff857816363d2127314610fd15781636801cc3014610f71578163787dce3d14610f095781637b9ed09714610ece5781637f46859f14610e3c57816382dfdce4146107ba57816384d397cc1461077f57816391d148541461072a578163a217fddf1461070f578163aaf5eb68146106f2578163ad71f37d146106b7578163b0e21e8a14610698578163b187bd2614610671578163b81be49c14610649578163bc063e1a1461062c578163bedb86fb14610595578163cc56b2c514610554578163d200607b1461051a578163d49466a814610459578163d547741f14610416578163e1f76b441461038057508063e5e31b1314610344578063fbdd9ff7146102995763ffb0a4a0146101d357600080fd5b34610296578060031936011261029657908051918290609c549182855260208095018093609c84527faf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539c90845b8181106102795750505081610235910382611e65565b83519485948186019282875251809352850193925b82811061025957505050500390f35b83516001600160a01b03168552869550938101939281019260010161024a565b82546001600160a01b03168452928801926001928301920161021f565b80fd5b5090346103405760206003193601126103405760207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249891600261ffff196102de61170a565b6102e6611afa565b6001600160a01b0387549160ff8360081c161580610334575b61030890612008565b1673ffffffffffffffffffffffffffffffffffffffff196097541617609755161784555160028152a180f35b5060ff831685116102ff565b5080fd5b5090346103405760206003193601126103405760ff816020936001600160a01b0361036d61170a565b168152609e855220541690519015158152f35b82843461034057806003193601126103405761039a611783565b6024356103a56117a1565b8015801561040b575b6103fc577f1fb2cf9d6edce0746aa2a7f1eb8d4844f40803775b9475bdbaaa8bb9f87e8733939450816000146103f357806099555b825191151582526020820152a180f35b80609a556103e3565b8483516347c115ef60e11b8152fd5b506101f481116103ae565b90508234610455578060031936011261045557610452913561044d600161043b611720565b93838752606560205286200154611cc5565b611e88565b80f35b8280fd5b9050823461045557806003193601126104555761047461170a565b90602435916104816117a1565b6101f4831161050b576001600160a01b03169283600052609e60205260ff826000205416156104e457507fae468ce586f9a87660fdffc1448cee942042c16ae2f02046b134b5224f31936b91602091848652609f8352818187205551908152a280f35b90517f30e17e47000000000000000000000000000000000000000000000000000000008152fd5b8382516347c115ef60e11b8152fd5b82843461034057602060031936011261034057602091816001600160a01b03918261054361170a565b16815260a185522054169051908152f35b5050346102965781600319360112610296575061056f61170a565b906024359182151583036105905760209261058991612086565b9051908152f35b600080fd5b8284346103405760206003193601126103405760207f3c70af01296aef045b2f5c9d3c30b05d4428fd257145b9c7fcd76418e65b5980916105d4611783565b6105dc6119a6565b1515906097547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000008460a01b1691161760975551908152a180f35b828434610340578160031936011261034057602090516101f48152f35b8284346103405781600319360112610340576020906001600160a01b03609b54169051908152f35b82843461034057816003193601126103405760209060ff60975460a01c1690519015158152f35b8284346103405781600319360112610340576020906098549051908152f35b828434610340578160031936011261034057602090517f4f895bdce78ed3edb90e9af75173c797e6234073a00b76fc9593b754504e75208152f35b828434610340578160031936011261034057602090516127108152f35b82843461034057816003193601126103405751908152602090f35b8383346102965781600319360112610296575061077660209261074b611720565b903560005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b90519015158152f35b828434610340578160031936011261034057602090517f8bb7efba716b8bd9b59b6661dd03848105f980fb29035ebc6d805a30527f6e3d8152f35b8284346103405760609182600319360112610296576107d761170a565b936107e0611720565b936107e9611792565b6097549360ff8560a81c1615610c06575b6001600160a01b0397888816898216818114610bde571015610bd85796975b808816948515610bb157858352602099609d8b5288842097838216988986528c52898520951515958686528c52838a86205416610b895789519a8c8c01927fffffffffffffffffffffffffffffffffffffffff00000000000000000000000080928a1b168452881b1660348c01528560f81b60488c015260298b52868b019067ffffffffffffffff928c831084841117610b7657828c528c519020608882901c62ffffff16763d602d80600a3d3981f3363d3d373d3d3d363d7300000017875260789190911b7fffffffffffffffffffffffffffffffffff000000000000000000000000000000166e5af43d82803e903d91602b57fd5bf3178d5284906037600988f5169a8b15610b3657505083908b84609b541660248d8d5195869384927fcbc48015000000000000000000000000000000000000000000000000000000008452898401525af1918215610af0578592610afe575b508a3b15610afa57848960848a838f8f8a905198899687957ffb162e030000000000000000000000000000000000000000000000000000000087528c87015260248601528d60448601521660648401525af18015610af057610aca575b5050858352609d8a52878320876000528a52876000208484528a5287832073ffffffffffffffffffffffffffffffffffffffff19908a82825416179055878452609d8b52888420876000528b52886000208585528b528989852091825416179055609c549068010000000000000000821015610ab75750918791610a798460017fc4805696c66d7cf352fc1d6bb633ad5ee82f6cb577c453024b6e0eb8306c6fc998979601609c55611736565b819291549060031b918c831b921b1916179055888152609e8a5220600160ff19825416179055609c548651918252878983015286820152a351908152f35b836041602492634e487b7160e01b835252fd5b8194929411610add578852918a806109cc565b602482604186634e487b7160e01b835252fd5b8a513d87823e3d90fd5b8480fd5b9091508b81813d8311610b2f575b610b168183611e65565b81010312610afa57518381168103610afa57908c61096f565b503d610b0c565b907f455243313136373a2063726561746532206661696c656400000000000000000060a46064938f62461bcd60e51b855285820152601760848201520152fd5b602487604187634e487b7160e01b835252fd5b828a517f148ea712000000000000000000000000000000000000000000000000000000008152fd5b87517f9fabe1c1000000000000000000000000000000000000000000000000000000008152fd5b97610819565b8689517f065af08d000000000000000000000000000000000000000000000000000000008152fd5b7f4f895bdce78ed3edb90e9af75173c797e6234073a00b76fc9593b754504e752080825260209060658252878320338452825260ff888420541615610c4c5750506107fa565b8786918685610c5a33611f23565b92845191610c6783611e33565b6042835287830193368537825115610e295760308453825190600191821015610e165790607860218501536041915b818311610dab57505050610d6a57610d61610d3085610d3f6048601f1997601f978c9760449c9b51968793610cfb8b86019b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008d528251928391603789019101611e10565b8401917f206973206d697373696e6720726f6c6520000000000000000000000000000000603784015251809386840190611e10565b01036028810185520183611e65565b5197889662461bcd60e51b885287015251809281602488015287870190611e10565b01168101030190fd5b606485878087519262461bcd60e51b845283015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f81166010811015610e03576f181899199a1a9b1b9c1cb0b131b232b360811b901a610ddb8587611f12565b53881c928015610df057600019019190610c96565b60248260118b634e487b7160e01b835252fd5b60248360328c634e487b7160e01b835252fd5b80603289634e487b7160e01b6024945252fd5b80603288634e487b7160e01b6024945252fd5b828434610340578060031936011261034057610e5661170a565b90610e5f611720565b91610e68611afa565b610e718161222b565b6001600160a01b038091169182855260a160205284209216918273ffffffffffffffffffffffffffffffffffffffff198254161790557fa34c8f8c0857528213e2969b5021064348257fffa370db24875ec58c58e2a3278380a380f35b828434610340578160031936011261034057602090517fad51469fd38cb9e4028f769761e769052a9f1f331b57ad921ac8a45c7903db288152f35b9050823461045557602060031936011261045557813591610f286117a1565b6127108311610f635750816020917fdc0410a296e1e33943a772020d333d5f99319d7fcad932a484c53889f7aaa2b19360985551908152a180f35b90516347c115ef60e11b8152fd5b8284346103405760606003193601126103405760209181610f9061170a565b91610f99611720565b610fa1611792565b906001600160a01b038095168352609d875284848420911683528652828220901515825285522054169051908152f35b82843461034057816003193601126103405760209060ff60975460a81c1690519015158152f35b8234610296576020600319360112610296576001600160a01b0361101a61170a565b6110226119a6565b61102b8161222b565b168073ffffffffffffffffffffffffffffffffffffffff19609b541617609b557fec55263cf7b30d6716a77f60e239b32ea5440e3e28db3385a6b660536019fab08280a280f35b8284346103405760206003193601126103405760207fe0d91255877f509ef94e58048122555ad1bd99f629f79a19f21331719adcc783916110b1611783565b6110b96119a6565b1515906097547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff75ff0000000000000000000000000000000000000000008460a81b1691161760975551908152a180f35b8284346103405781600319360112610340576020906001600160a01b03609754169051908152f35b828434610340578160031936011261034057602090609c549051908152f35b828434610340578160031936011261034057602090609a549051908152f35b8391503461045557816003193601126104555761118b61170a565b611193611720565b84549260ff8460081c16159384809561139b575b8015611384575b6111b790612008565b60ff1990856001838316178955611373575b506111d38461222b565b6111dc8361222b565b60ff875460081c161561130a573360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b602052604090205460ff16156112c0575b506099556012609a556127106098556001600160a01b03908173ffffffffffffffffffffffffffffffffffffffff1993168360975416176097551690609b541617609b5561126d575080f35b60207f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff84541684555160018152a180f35b86805260656020528587203388526020526001868820918254161790553333877f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a486611221565b608482602088519162461bcd60e51b8352820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152fd5b61ffff1916610101178755876111c9565b50303b1580156111ae575060ff81166001146111ae565b50600160ff8216106111a7565b8284346103405781600319360112610340576020906099549051908152f35b9050346103405782600319360112610340576113e1611720565b90336001600160a01b038316036113fd57906104529135611e88565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b9050823461045557806003193601126104555761148161170a565b906024359161148e6117a1565b612710831161050b576001600160a01b031692838552609e60205260ff8286205416156104e457507f3edf569ca74e0ce148d10add24c5d2adf90acb6681c9e253179e6210492ea0f49160209184865260a08352818187205551908152a280f35b83915034610455578160031936011261045557359061150c611720565b90828452606560205261152460018286200154611cc5565b611552828460005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b1561155b578380f35b82845260656020526001600160a01b038185209216918285526020528320600160ff1982541617905533917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8480a48180808380f35b839150346104555760206003193601126104555781602093600192358152606585522001549051908152f35b82843461034057602060031936011261034057906020916115fc61170a565b5051908152f35b83915034610455576020600319360112610455573591609c5483101561029657506001600160a01b03611637602093611736565b92905490519260031b1c168152f35b8284346103405760206003193601126103405760209061058961166761170a565b612208565b91503461045557602060031936011261045557357fffffffff00000000000000000000000000000000000000000000000000000000811680910361045557602092507f7965db0b0000000000000000000000000000000000000000000000000000000081149081156116e0575b5015158152f35b7f01ffc9a700000000000000000000000000000000000000000000000000000000915014836116d9565b600435906001600160a01b038216820361059057565b602435906001600160a01b038216820361059057565b609c5481101561176d57609c6000527faf85b9071dfafeac1409d3f1d19bafc9bc7c37974cde8df0ee6168f0086e539c0190600090565b634e487b7160e01b600052603260045260246000fd5b60043590811515820361059057565b60443590811515820361059057565b3360009081527fec8ecf116caa65c9911ee2546d1ab511e533ae7db621e6d310ee76029295d61860209081526040808320547fad51469fd38cb9e4028f769761e769052a9f1f331b57ad921ac8a45c7903db28919060ff16156118045750505050565b61180d33611f23565b9181519061181a82611e33565b6042825284820195606036883782511561199257603087538251906001918210156119925790607860218501536041915b818311611924575050506118e25760449392610d61836118be6048601f95601f1997519a8b916118af8b8401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a52610cfb8d8251928391603789019101611e10565b0103602881018b520189611e65565b5196879562461bcd60e51b8752600487015251809281602488015287870190611e10565b60648483519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f8116601081101561197e576f181899199a1a9b1b9c1cb0b131b232b360811b901a6119548587611f12565b5360041c92801561196a5760001901919061184b565b602482634e487b7160e01b81526011600452fd5b602483634e487b7160e01b81526032600452fd5b80634e487b7160e01b602492526032600452fd5b3360009081527f36bd584c1759857bde74c3d5ab74682360b4c37ab0107567f071641a51a9180f60209081526040808320547f8bb7efba716b8bd9b59b6661dd03848105f980fb29035ebc6d805a30527f6e3d919060ff1615611a095750505050565b611a1233611f23565b91815190611a1f82611e33565b6042825284820195606036883782511561199257603087538251906001918210156119925790607860218501536041915b818311611ab4575050506118e25760449392610d61836118be6048601f95601f1997519a8b916118af8b8401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a52610cfb8d8251928391603789019101611e10565b909192600f8116601081101561197e576f181899199a1a9b1b9c1cb0b131b232b360811b901a611ae48587611f12565b5360041c92801561196a57600019019190611a50565b3360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b602052604090205460ff1615611b3357565b611b3c33611f23565b604051600091611b4b82611e33565b6042825260209182810193606036863781511561199257603085538151600190811015611cb157607860218401536041905b808211611c57575050611c1457601f60449392611beb6048601f1994604051988991611bdc898401967f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008852610cfb815180928d603789019101611e10565b01036028810189520187611e65565b610d6160405196879562461bcd60e51b8752600487015251809281602488015287870190611e10565b6064836040519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f8116601081101561176d576f181899199a1a9b1b9c1cb0b131b232b360811b901a611c868486611f12565b5360041c918015611c9b576000190190611b7d565b634e487b7160e01b600052601160045260246000fd5b602482634e487b7160e01b81526032600452fd5b611cf3338260005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b15611cfb5750565b611d0433611f23565b60405190611d1182611e33565b6042825260209182810193606036863781511561176d5760308553815160019081101561176d57607860218401536041905b808211611da2575050611c1457601f60449392611beb6048601f1994604051988991611bdc898401967f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008852610cfb815180928d603789019101611e10565b9091600f81166010811015611dfb576f181899199a1a9b1b9c1cb0b131b232b360811b901a611dd18486611f12565b5360041c918015611de6576000190190611d43565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b60005b838110611e235750506000910152565b8181015183820152602001611e13565b6080810190811067ffffffffffffffff821117611e4f57604052565b634e487b7160e01b600052604160045260246000fd5b90601f601f19910116810190811067ffffffffffffffff821117611e4f57604052565b90611eb7818360005260656020526001600160a01b036040600020911660005260205260ff6040600020541690565b611ebf575050565b60009180835260656020526001600160a01b03604084209216918284526020526040832060ff1981541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4565b90815181101561176d570160200190565b604051906060820182811067ffffffffffffffff821117611e4f57604052602a825260208201604036823782511561176d5760309053815160019081101561176d57607860218401536029905b808211611fc4575050611f805790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015611dfb576f181899199a1a9b1b9c1cb0b131b232b360811b901a611ff38486611f12565b5360041c918015611de6576000190190611f70565b1561200f57565b608460405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152fd5b5190811515820361059057565b906001600160a01b03809216600092818452602090609f825260409384862054806121fe57506121f35760a1825283852054169182156121015783517f4bb77d680000000000000000000000000000000000000000000000000000000081528281600481875afa9081156121e95786916121b0575b5061210c575b5050505050609a5490565b839060248251809581937fb88c914800000000000000000000000000000000000000000000000000000000835260048301525afa9384156121a55780938195612164575b505050506121615780808080612101565b90565b9294509092509083813d811161219e575b61217f8183611e65565b81010312610296575061219182612079565b9101519038808080612150565b503d612175565b8351903d90823e3d90fd5b90508281813d83116121e2575b6121c78183611e65565b810103126121de576121d890612079565b386120fb565b8580fd5b503d6121bd565b85513d88823e3d90fd5b505050505060995490565b9550505050505090565b6001600160a01b031660005260a060205260406000205480612161575060985490565b6001600160a01b03161561223b57565b60046040517f9fabe1c1000000000000000000000000000000000000000000000000000000008152fdfea164736f6c6343000813000a
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.