Source Code
Overview
ETH Balance
0 ETH
ETH 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:
VoterV5_GaugeLogic
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import {IVoterV5_GaugeLogic, IERC165} from "./IVoterV5_GaugeLogic.sol";
import {IERC20} from "../interfaces/IERC20.sol";
import {IAlgebraFactory} from "@cryptoalgebra/v1-core/contracts/interfaces/IAlgebraFactory.sol";
import {IBribeFactory} from "../interfaces/IBribeFactory.sol";
import {IGaugeFactory} from "../interfaces/IGaugeFactory.sol";
import {IPermissionsRegistry} from "../interfaces/IPermissionsRegistry.sol";
import {IHypervisor} from "../interfaces/IHypervisor.sol";
import {IMultiPositionManager} from "../dex/uniswap-v4/IMultiPositionManager.sol";
import {IPairFactory} from "../interfaces/IPairFactory.sol";
import {IPairInfo} from "../interfaces/IPairInfo.sol";
import {VoterV5_Storage} from "./VoterV5_Storage.sol";
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {UniswapV3Helper} from "../libraries/UniswapV3Helper.sol";
/**
* @notice Table showing GaugeType configurations
* ┌──────────────────────┬──────────────────────────┬────────────────────────┐
* │ GaugeType │ DEX Factory │ Gauge Factory │
* ├──────────────────────┼──────────────────────────┼────────────────────────┤
* │ PAIR_CLASSIC │ PairFactoryUpgradable │ GaugeFactoryV2 │
* │ ALM_ALGEBRA_V1 │ AlgebraFactory │ GaugeFactoryV2_CL │
* │ ALM_ICHI_UNISWAP_V3 │ UniswapV3Factory │ GaugeFactoryV2_CL │
* │ ALM_GAMMA_UNISWAP_V4 │ UniswapV4PoolManager │ GaugeFactoryV2_CL │
* └──────────────────────┴──────────────────────────┴────────────────────────┘
*/
/// @notice Enum representing different gauge types
/// @dev Make sure to use the correct gaugeType or gauge creation will fail
enum GaugeType {
PAIR_CLASSIC, // 0: Classic Stable/Volatile pair
ALM_ALGEBRA_V1, // 1: Ichi/Gamma concentrated liquidity for Algebra
ALM_ICHI_UNISWAP_V3, // 2: Ichi concentrated liquidity for UniswapV3
ALM_GAMMA_UNISWAP_V4 // 3: Gamma concentrated liquidity for UniswapV4
}
/// @title VoterV5_GaugeLogic
/// @notice This contract contains the logic for creating gauges in the VoterV5 system. It is used to save contract
/// size in VoterV5 by separating out expensive logic.
/// @dev This contract MUST be called from VoterV5 through delegatecall().
contract VoterV5_GaugeLogic is IVoterV5_GaugeLogic, VoterV5_Storage, ERC165 {
/**
* @notice changelog
* - 1.1.0: Add Support for UniswapV3 and UniswapV4 Gauges
*/
string public constant VERSION_GAUGE_LOGIC = "1.1.0";
/// @notice Maximum valid gauge type enum value
uint256 public constant MAX_GAUGE_TYPE = uint256(type(GaugeType).max);
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC165) returns (bool) {
return interfaceId == type(IVoterV5_GaugeLogic).interfaceId || super.supportsInterface(interfaceId);
}
/// @notice Validate if gauge type is within enum bounds (pure function)
function isValidGaugeType(uint256 _gaugeType) public pure returns (bool) {
return _gaugeType <= MAX_GAUGE_TYPE;
}
struct _CreateGauge_LocalVars {
address tokenA;
address tokenB;
address rewardToken;
address dexFactory;
address gaugeFactory;
address internal_bribe;
address external_bribe;
bool isPair;
}
/// @notice create a gauge
/// @param _pool LP address, which varies based on gauge type:
/// - For PAIR_CLASSIC: The actual pair contract address (similar to UniswapV2 pairs)
/// - For ALM strategies (GAMMA): The strategy contract address that manages the position
/// @param _gaugeType enum GaugeType, the type of gauge to create. The associated factory (_factories[_gaugeType])
/// represents different things based on type:
/// - For PAIR_CLASSIC: Deploy a Gauge for Solidly Classic Pairs
/// - For ALM_GAMMA_ALGEBRA: Deploy a Gauge for Gamma + Algebra ALM strategies
/// - For ALM_GAMMA_UNISWAP_V3: Deploy a Gauge for Gamma + UniswapV3 ALM strategies
/// - For ALM_GAMMA_UNISWAP_V4: Deploy a Gauge for Gamma + UniswapV4 ALM strategies
function createGauge(
address _pool,
uint256 _gaugeType
) external override returns (address _gauge, address _internal_bribe, address _external_bribe) {
// Enhanced validation
require(_gaugeType <= MAX_GAUGE_TYPE, "Invalid gauge type enum");
require(_gaugeType < _factories.length, "Gauge type not configured");
require(gauges[_pool] == address(0), "!exists");
require(_pool.code.length > 0, "!contract");
_CreateGauge_LocalVars memory vars;
vars.dexFactory = _factories[_gaugeType];
vars.gaugeFactory = _gaugeFactories[_gaugeType];
require(vars.dexFactory != address(0), "dex factory not set");
require(vars.gaugeFactory != address(0), "gauge factory not set");
(vars.tokenA) = IPairInfo(_pool).token0();
(vars.tokenB) = IPairInfo(_pool).token1();
if (_gaugeType == uint256(GaugeType.PAIR_CLASSIC)) {
/**
* @dev Classic Stable/Volatile pair
*/
vars.isPair = IPairFactory(vars.dexFactory).isPair(_pool);
} else if (_gaugeType == uint256(GaugeType.ALM_ALGEBRA_V1)) {
/**
* @dev ICHI/GAMMA + Algebra ALM strategy
*/
address _pool_factory = IAlgebraFactory(vars.dexFactory).poolByPair(vars.tokenA, vars.tokenB);
address _pool_hyper = IHypervisor(_pool).pool();
require(_pool_hyper == _pool_factory, "wrong tokens");
vars.isPair = true;
} else if (_gaugeType == uint256(GaugeType.ALM_ICHI_UNISWAP_V3)) {
/**
* @dev ICHI + Uniswap V3 ALM strategy
*/
address _pool_hyper = IHypervisor(_pool).pool();
bool isValidPool = UniswapV3Helper.validatePoolExists(vars.dexFactory, vars.tokenA, vars.tokenB, _pool_hyper);
require(isValidPool, "wrong tokens");
vars.isPair = true;
} else if (_gaugeType == uint256(GaugeType.ALM_GAMMA_UNISWAP_V4)) {
/**
* @dev GAMMA + Uniswap V4 ALM strategy
*/
address _poolManager = IMultiPositionManager(_pool).poolManager();
require(_poolManager == vars.dexFactory, "!poolManager");
/// @dev IMultiPositionManager supports token0() and token1()
// vars.tokenA = address(IMultiPositionManager(_pool).token0());
// vars.tokenB = address(IMultiPositionManager(_pool).token1());
vars.isPair = true;
}
/// @dev Gov can create for any pool, even non-lynex pairs
if (!IPermissionsRegistry(permissionRegistry).hasRole("GOVERNANCE", msg.sender)) {
require(vars.isPair, "!_pool");
if(_gaugeType != uint256(GaugeType.PAIR_CLASSIC)) {
/// @dev Assume this is an ALM strategy
require(isWhitelistedPool[_pool], "Only whitelisted strategies");
}
if(_gaugeType == uint256(GaugeType.ALM_GAMMA_UNISWAP_V4)) {
/// @dev UniswapV4 supports native tokens at address(0)
if(vars.tokenA != address(0)) {
require(isWhitelisted[vars.tokenA], "!whitelistedA");
}
} else {
require(vars.tokenA != address(0), "!pair.tokenA");
require(isWhitelisted[vars.tokenA], "!whitelistedA");
}
require(isWhitelisted[vars.tokenB], "!whitelistedB");
require(vars.tokenB != address(0), "!pair.tokenB");
}
/// -----------------------------------------------------------------------
/// Setup Bribes
/// -----------------------------------------------------------------------
// create internal and external bribe
address _owner = IPermissionsRegistry(permissionRegistry).teamMultisig();
string memory _type = string.concat(protocolName, " LP Fees: ", IERC20(_pool).symbol());
vars.internal_bribe = IBribeFactory(bribefactory).createBribe(_owner, vars.tokenA, vars.tokenB, _type);
_type = string.concat(protocolName, " Bribes: ", IERC20(_pool).symbol());
vars.external_bribe = IBribeFactory(bribefactory).createBribe(_owner, vars.tokenA, vars.tokenB, _type);
/// -----------------------------------------------------------------------
/// Setup Gauge
/// -----------------------------------------------------------------------
vars.rewardToken = oToken != address(0) ? oToken : base;
_gauge = IGaugeFactory(vars.gaugeFactory).createGaugeV2(
vars.rewardToken,
_ve,
_pool,
address(this), // distribution address
vars.internal_bribe,
vars.external_bribe,
vars.isPair
);
// approve spending for protocol token, this is set back to zero if gauge is killed
IERC20(vars.rewardToken).approve(_gauge, type(uint256).max);
/// -----------------------------------------------------------------------
/// Save Gauge Data
/// -----------------------------------------------------------------------
internal_bribes[_gauge] = vars.internal_bribe;
external_bribes[_gauge] = vars.external_bribe;
gauges[_pool] = _gauge;
poolForGauge[_gauge] = _pool;
isGauge[_gauge] = true;
isAlive[_gauge] = true;
pools.push(_pool);
// update supplyIndex (gaugeRewardsPerVoteWeight) gauge => index (globalRewardsPerVoteWeight)
supplyIndex[_gauge] = index; // new gauges are set to the default global state
return (_gauge, vars.internal_bribe, vars.external_bribe);
}
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/**
* @title The interface for the Algebra Factory
* @dev Credit to Uniswap Labs under GPL-2.0-or-later license:
* https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
*/
interface IAlgebraFactory {
/**
* @notice Emitted when the owner of the factory is changed
* @param newOwner The owner after the owner was changed
*/
event Owner(address indexed newOwner);
/**
* @notice Emitted when the vault address is changed
* @param newVaultAddress The vault address after the address was changed
*/
event VaultAddress(address indexed newVaultAddress);
/**
* @notice Emitted when a pool is created
* @param token0 The first token of the pool by address sort order
* @param token1 The second token of the pool by address sort order
* @param pool The address of the created pool
*/
event Pool(address indexed token0, address indexed token1, address pool);
/**
* @notice Emitted when the farming address is changed
* @param newFarmingAddress The farming address after the address was changed
*/
event FarmingAddress(address indexed newFarmingAddress);
event FeeConfiguration(
uint16 alpha1,
uint16 alpha2,
uint32 beta1,
uint32 beta2,
uint16 gamma1,
uint16 gamma2,
uint32 volumeBeta,
uint16 volumeGamma,
uint16 baseFee
);
/**
* @notice Returns the current owner of the factory
* @dev Can be changed by the current owner via setOwner
* @return The address of the factory owner
*/
function owner() external view returns (address);
/**
* @notice Returns the current poolDeployerAddress
* @return The address of the poolDeployer
*/
function poolDeployer() external view returns (address);
/**
* @dev Is retrieved from the pools to restrict calling
* certain functions not by a tokenomics contract
* @return The tokenomics contract address
*/
function farmingAddress() external view returns (address);
function vaultAddress() external view returns (address);
/**
* @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist
* @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order
* @param tokenA The contract address of either token0 or token1
* @param tokenB The contract address of the other token
* @return pool The pool address
*/
function poolByPair(address tokenA, address tokenB) external view returns (address pool);
/**
* @notice Creates a pool for the given two tokens and fee
* @param tokenA One of the two tokens in the desired pool
* @param tokenB The other of the two tokens in the desired pool
* @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved
* from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments
* are invalid.
* @return pool The address of the newly created pool
*/
function createPool(address tokenA, address tokenB) external returns (address pool);
/**
* @notice Updates the owner of the factory
* @dev Must be called by the current owner
* @param _owner The new owner of the factory
*/
function setOwner(address _owner) external;
/**
* @dev updates tokenomics address on the factory
* @param _farmingAddress The new tokenomics contract address
*/
function setFarmingAddress(address _farmingAddress) external;
/**
* @dev updates vault address on the factory
* @param _vaultAddress The new vault contract address
*/
function setVaultAddress(address _vaultAddress) external;
/**
* @notice Changes initial fee configuration for new pools
* @dev changes coefficients for sigmoids: α / (1 + e^( (β-x) / γ))
* alpha1 + alpha2 + baseFee (max possible fee) must be <= type(uint16).max
* gammas must be > 0
* @param alpha1 max value of the first sigmoid
* @param alpha2 max value of the second sigmoid
* @param beta1 shift along the x-axis for the first sigmoid
* @param beta2 shift along the x-axis for the second sigmoid
* @param gamma1 horizontal stretch factor for the first sigmoid
* @param gamma2 horizontal stretch factor for the second sigmoid
* @param volumeBeta shift along the x-axis for the outer volume-sigmoid
* @param volumeGamma horizontal stretch factor the outer volume-sigmoid
* @param baseFee minimum possible fee
*/
function setBaseFeeConfiguration(
uint16 alpha1,
uint16 alpha2,
uint32 beta1,
uint32 beta2,
uint16 gamma1,
uint16 gamma2,
uint32 volumeBeta,
uint16 volumeGamma,
uint16 baseFee
) external;
}// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.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 ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// 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 IERC165 {
/**
* @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: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @title The interface for the Uniswap V3 Factory
/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees
interface IUniswapV3Factory {
/// @notice Emitted when the owner of the factory is changed
/// @param oldOwner The owner before the owner was changed
/// @param newOwner The owner after the owner was changed
event OwnerChanged(address indexed oldOwner, address indexed newOwner);
/// @notice Emitted when a pool is created
/// @param token0 The first token of the pool by address sort order
/// @param token1 The second token of the pool by address sort order
/// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
/// @param tickSpacing The minimum number of ticks between initialized ticks
/// @param pool The address of the created pool
event PoolCreated(
address indexed token0,
address indexed token1,
uint24 indexed fee,
int24 tickSpacing,
address pool
);
/// @notice Emitted when a new fee amount is enabled for pool creation via the factory
/// @param fee The enabled fee, denominated in hundredths of a bip
/// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee
event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);
/// @notice Returns the current owner of the factory
/// @dev Can be changed by the current owner via setOwner
/// @return The address of the factory owner
function owner() external view returns (address);
/// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled
/// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context
/// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee
/// @return The tick spacing
function feeAmountTickSpacing(uint24 fee) external view returns (int24);
/// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist
/// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order
/// @param tokenA The contract address of either token0 or token1
/// @param tokenB The contract address of the other token
/// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
/// @return pool The pool address
function getPool(
address tokenA,
address tokenB,
uint24 fee
) external view returns (address pool);
/// @notice Creates a pool for the given two tokens and fee
/// @param tokenA One of the two tokens in the desired pool
/// @param tokenB The other of the two tokens in the desired pool
/// @param fee The desired fee for the pool
/// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved
/// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments
/// are invalid.
/// @return pool The address of the newly created pool
function createPool(
address tokenA,
address tokenB,
uint24 fee
) external returns (address pool);
/// @notice Updates the owner of the factory
/// @dev Must be called by the current owner
/// @param _owner The new owner of the factory
function setOwner(address _owner) external;
/// @notice Enables a fee amount with the given tickSpacing
/// @dev Fee amounts may never be removed once enabled
/// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)
/// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount
function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
}/// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { PoolKey } from "./PoolKey.sol";
// import {IImmutableState} from "@uniswap/v4-periphery/src/interfaces/IImmutableState.sol";
interface IImmutableState {
/// @notice The Uniswap v4 PoolManager contract
function poolManager() external view returns (address /*IPoolManager*/);
}
/**
* @title IMultiPositionManager
* @author Gamma
* @notice This interface is used to interact with Gamma ALM strategies which use UniswapV4 pools as concentrated liquidity positions.
*/
interface IMultiPositionManager is IERC20, IImmutableState {
struct Position {
PoolKey poolKey;
int24 lowerTick;
int24 upperTick;
}
struct PositionData {
uint128 liquidity;
uint256 amount0;
uint256 amount1;
}
function getPositions() external view returns (
Position[] memory,
PositionData[] memory
);
function basePositionsLength() external view returns (uint256);
function token0() external view returns (IERC20);
function token1() external view returns (IERC20);
function getTotalAmounts() external view returns (
uint256 total0,
uint256 total1,
uint256 totalFee0,
uint256 totalFee1
);
function currentTicks() external view returns (int24[] memory);
function rebalance(
Position[] memory baseRanges,
uint128[] memory liquidities,
int24 limitWidth,
uint256[2][] memory inMin,
uint256[2][] memory outMin,
int24 aimTick,
uint24 tickOffset
) external;
function compound(
uint128[] memory liquidities,
uint256[2][] memory inMin,
int24 aimTick,
uint24 tickOffset
) external;
function claimFee() external;
function setWhitelist(address _whitelist) external;
function setFeeRecipient(address _feeRecipient) external;
function setFee(uint16 fee) external;
// function setTickOffset(uint24 offset) external;
function deposit(
uint256 deposit0Desired,
uint256 deposit1Desired,
address to,
address from
) external payable returns (uint256, uint256, uint256);
function zeroBurnAll() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {PoolKey} from "./PoolKey.sol";
type PoolId is bytes32;
/// @notice Library for computing the ID of a pool
library PoolIdLibrary {
/// @notice Returns value equal to keccak256(abi.encode(poolKey))
function toId(PoolKey memory poolKey) internal pure returns (PoolId poolId) {
assembly ("memory-safe") {
// 0xa0 represents the total size of the poolKey struct (5 slots of 32 bytes)
poolId := keccak256(poolKey, 0xa0)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {PoolIdLibrary} from "./PoolIdLibrary.sol";
// import {Currency} from "./Currency.sol";
// import {IHooks} from "../interfaces/IHooks.sol";
using PoolIdLibrary for PoolKey global;
/// @notice Returns the key for identifying a pool
struct PoolKey {
/// @notice The lower currency of the pool, sorted numerically
address currency0; // NOTE: Should be Currency
/// @notice The higher currency of the pool, sorted numerically
address currency1; // NOTE: Should be Currency
/// @notice The pool LP fee, capped at 1_000_000. If the highest bit is 1, the pool has a dynamic fee and must be exactly equal to 0x800000
uint24 fee;
/// @notice Ticks that involve positions must be a multiple of tick spacing
int24 tickSpacing;
/// @notice The hooks of the pool
address hooks; // NOTE: Should be IHooks
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IBribeFactory {
function createInternalBribe(address[] memory) external returns (address);
function createExternalBribe(address[] memory) external returns (address);
function createBribe(address _owner,address _token0,address _token1, string memory _type) external returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IERC20 {
function totalSupply() external view returns (uint256);
function transfer(address recipient, uint amount) external returns (bool);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function balanceOf(address) external view returns (uint);
function transferFrom(address sender, address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IGaugeFactory {
function createGauge(address, address, address, address, bool, address[] memory) external returns (address);
function createGaugeV2(address _rewardToken,address _ve,address _token,address _distribution, address _internal_bribe, address _external_bribe, bool _isPair) external returns (address) ;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IHypervisor {
function pool() external view returns(address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IPairFactory {
function allPairsLength() external view returns (uint);
function isPair(address pair) external view returns (bool);
function getFee(bool) external view returns (uint);
function allPairs(uint index) external view returns (address);
function feeManager() external view returns (address);
function pairCodeHash() external pure returns (bytes32);
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 getInitializable() external view returns (address, address, bool);
function MAX_REFERRAL_FEE() external view returns(uint);
function dibs() external view returns(address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IPairInfo {
function token0() external view returns(address);
function reserve0() external view returns(uint);
function decimals0() external view returns(uint);
function token1() external view returns(address);
function reserve1() external view returns(uint);
function decimals1() external view returns(uint);
function isPair(address _pair) external view returns(bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
interface IPermissionsRegistry {
function adminMultisig() external view returns (address);
function teamMultisig() external view returns (address);
function emergencyCouncil() external view returns (address);
/// @notice Check if an address has a bytes role
function hasRole(bytes memory role, address caller) external view returns (bool);
/// @notice Check if an address has a role
function hasRoleString(string memory role, address _user) external view returns(bool);
/// @notice Read roles and return array of role strings
function rolesToString() external view returns(string[] memory __roles);
/// @notice Read roles return an array of roles in bytes
function roles() external view returns(bytes[] memory);
/// @notice Read the number of roles
function rolesLength() external view returns(uint);
/// @notice Return addresses for a given role
function roleToAddresses(string memory role) external view returns(address[] memory _addresses);
/// @notice Return roles for a given address
function addressToRole(address _user) external view returns(string[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IVersionable {
function VERSION() external view returns (string memory);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import {IUniswapV3Factory} from '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';
/// @title UniswapV3Helper
/// @notice Helper library for UniswapV3 pool validation and fee tier management
/// @dev Used to abstract UniswapV3-specific logic from gauge creation
library UniswapV3Helper {
/// @notice Standard UniswapV3 fee tiers (in basis points)
uint24 public constant FEE_LOW = 500; // 0.05%
uint24 public constant FEE_MEDIUM = 3000; // 0.30%
uint24 public constant FEE_HIGH = 10000; // 1.00%
/// @notice Validates that a pool exists in UniswapV3 factory for given tokens
/// @param _factory The UniswapV3Factory address
/// @param _tokenA Token A address
/// @param _tokenB Token B address
/// @param _expectedPool The expected pool address to validate
/// @return isValid True if the pool exists in the factory for any standard fee tier
function validatePoolExists(
address _factory,
address _tokenA,
address _tokenB,
address _expectedPool
) internal view returns (bool isValid) {
// Check if the pool matches any of the standard fee tiers
uint24[3] memory fees = [FEE_LOW, FEE_MEDIUM, FEE_HIGH];
for (uint256 i = 0; i < fees.length; i++) {
address factoryPool = IUniswapV3Factory(_factory).getPool(_tokenA, _tokenB, fees[i]);
if (_expectedPool == factoryPool && factoryPool != address(0)) {
return true;
}
}
return false;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
/// @title IVoterV5_GaugeLogic
interface IVoterV5_GaugeLogic is IERC165 {
function createGauge(
address _pool,
uint256 _gaugeType
) external returns (address _gauge, address _internal_bribe, address _external_bribe);
function isValidGaugeType(uint256 _gaugeType) external pure returns (bool);
function MAX_GAUGE_TYPE() external pure returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import {IVoterV5_GaugeLogic} from "./IVoterV5_GaugeLogic.sol";
/// @title IVoterV5_Storage
/// @notice Interface for accessing public and external variables of the VoterV5_Storage contract
interface IVoterV5_Storage {
/// @notice Returns the address of the ve token
function _ve() external view returns (address);
/// @notice Returns the address of the base token
function base() external view returns (address);
/// @notice Returns the address of the option token
function oToken() external view returns (address);
/// @notice Returns the address of the bribe factory
function bribefactory() external view returns (address);
/// @notice Returns the address of the minter
function minter() external view returns (address);
/// @notice Returns the address of the permission registry
function permissionRegistry() external view returns (address);
/// @notice Returns the address of a pool at a given index
/// @param index The index of the pool in the pools array
function pools(uint256 index) external view returns (address);
/// @notice Returns the global gauge index
function index() external view returns (uint256);
/// @notice Returns the delay between votes in seconds
function VOTE_DELAY() external view returns (uint256);
/// @notice Returns the maximum vote delay allowed
function MAX_VOTE_DELAY() external view returns (uint256);
/// @notice Returns the claimable amount for a given account
/// @param account The address of the account
function claimable(address account) external view returns (uint256);
/// @notice Returns the gauge address for a given pool
/// @param pool The address of the pool
function gauges(address pool) external view returns (address);
/// @notice Returns the last distribution timestamp for a given gauge
/// @param gauge The address of the gauge
function gaugesDistributionTimestamp(address gauge) external view returns (uint256);
/// @notice Returns the pool address for a given gauge
/// @param gauge The address of the gauge
function poolForGauge(address gauge) external view returns (address);
/// @notice Returns the internal bribe address for a given gauge
/// @param gauge The address of the gauge
function internal_bribes(address gauge) external view returns (address);
/// @notice Returns the external bribe address for a given gauge
/// @param gauge The address of the gauge
function external_bribes(address gauge) external view returns (address);
/// @notice Returns the votes for a given NFT and pool
/// @param nft The address of the NFT
/// @param pool The address of the pool
function votes(address nft, address pool) external view returns (uint256);
/// @notice Returns the pool address at a given index for a given NFT
/// @param nft The address of the NFT
/// @param index The index of the pool in the poolVote array
function poolVote(address nft, uint256 index) external view returns (address);
/// @notice Returns the timestamp of the last vote for a given NFT
/// @param nft The address of the NFT
function lastVoted(address nft) external view returns (uint256);
/// @notice Returns whether a given address is a gauge
/// @param gauge The address of the gauge
function isGauge(address gauge) external view returns (bool);
/// @notice Returns whether a given token is whitelisted
/// @param token The address of the token
function isWhitelisted(address token) external view returns (bool);
/// @notice Returns whether a given pool is whitelisted
/// @param token The address of the pool token
function isWhitelistedPool(address token) external view returns (bool);
/// @notice Returns whether a given gauge is alive
/// @param gauge The address of the gauge
function isAlive(address gauge) external view returns (bool);
/// @notice Returns the factory status of a given address
/// @param factory The address of the factory
function isFactory(address factory) external view returns (uint8);
/// @notice Returns whether a given address is a gauge factory
/// @param gaugeFactory The address of the gauge factory
/// @dev in 5.4.1, this returns a uint8 instead of a bool
/// This allows the same gauge factory to be used across multiple gauge types.
/// Storage-safe: bool and uint8 both occupy 1 byte, existing true/false values
/// become 1/0 counters seamlessly during upgrades.
function isGaugeFactory(address gaugeFactory) external view returns (uint8);
/// @notice Returns whether a given address is a gauge depositor
/// @param gaugeFactory The address of the gauge factory
function isGaugeDepositor(address gaugeFactory) external view returns (bool);
/// @notice Returns the address of the gauge logic contract
function gaugeLogic() external view returns (IVoterV5_GaugeLogic);
/// @notice Returns the epoch timestamp when a given gauge was killed
/// @param gauge The address of the gauge
function gaugeKilledEpoch(address gauge) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import {IVoterV5_Storage} from "./IVoterV5_Storage.sol";
import {IVoterV5_GaugeLogic} from "./IVoterV5_GaugeLogic.sol";
import {IVersionable} from "../interfaces/IVersionable.sol";
/// @title VoterV5_Storage
/// @notice This contract contains the storage variables for VoterV5.
/// @dev This contract is used to ensure both VoterV5 and VoterV5_GaugeLogic have access to the same storage variables
/// in the correct slots. They MUST both extend this.
/// - The storage layout for all version 5.x contracts MUST remain compatible for upgradeability.
contract VoterV5_Storage is IVoterV5_Storage, IVersionable {
/// @notice The current version of the contract
/// - 5.2.0: Add "protocolName", refactor to "oToken"
/// - 5.2.1: Change from require to revert CustomErrors
/// - 5.3.1: Add claim helper functions in VoterV5
/// - 5.4.0: GaugeType improvement, use setFactory to configure factories with GaugeType
/// - 5.4.1: Change isGaugeFactory mapping from bool to uint8 for reference counting.
/// This allows the same gauge factory to be used across multiple gauge types.
/// Storage-safe: bool and uint8 both occupy 1 byte, existing true/false values
/// become 1/0 counters seamlessly during upgrades.
string public constant override VERSION = "5.4.1";
bool internal initflag;
address public _ve; // ve token that governs these contracts
address[] internal _factories; // Array with all the pair factories
address public base; // underlying protocol token
address public oToken; // option protocol token
address[] internal _gaugeFactories; // array with all the gauge factories
address public bribefactory; // bribe factory (internal and external)
address public minter; // minter mints protocol tokens each epoch
address public permissionRegistry; // registry to check accesses
address[] public pools; // all pools viable for incentives
uint256 public index; // (globalRewardsPerVoteWeight) gauge index
uint256 internal DURATION; // rewards are released over 1 epoch
uint256 public VOTE_DELAY; // delay between votes in seconds
uint256 public MAX_VOTE_DELAY; // Max vote delay allowed
mapping(address => uint256) internal supplyIndex; /// (gaugeRewardsPerVoteWeight) gauge => index
mapping(address => uint256) public claimable; /// @dev deprecated, but leaving for upgradeability
mapping(address => address) public gauges; // pool => gauge
mapping(address => uint256) public gaugesDistributionTimestamp; // gauge => last Distribution Time
mapping(address => address) public poolForGauge; // gauge => pool
mapping(address => address) public internal_bribes; // gauge => internal bribe (only fees)
mapping(address => address) public external_bribes; // gauge => external bribe (real bribes)
mapping(address => mapping(address => uint256)) public votes; // nft => pool => votes
mapping(address => address[]) public poolVote; // nft => pools
mapping(uint256 => mapping(address => uint256)) internal weightsPerEpoch; // timestamp => pool => weights
mapping(uint256 => uint256) internal totalWeightsPerEpoch; // timestamp => total weights
mapping(address => uint256) public lastVoted; // nft => timestamp of last vote
mapping(address => bool) public isGauge; // gauge => boolean [is a gauge?]
mapping(address => bool) public isWhitelisted; // token => boolean [is an allowed token?]
mapping(address => bool) public isWhitelistedPool; // token => boolean [is an allowed token?]
mapping(address => bool) public isAlive; // gauge => boolean [is the gauge alive?]
mapping(address => uint8) public isFactory; // factory => boolean [the pair factory exists?]
mapping(address => uint8) public isGaugeFactory; // g.factory=> usage count [how many gauge types use this factory]
mapping(address => bool) public isGaugeDepositor; // g.factory=> boolean [the gauge factory exists?]
IVoterV5_GaugeLogic public gaugeLogic; // gauge logic contract
/**
* @dev May 2024: The state variables below this have been added in VoterV5 and the gap variable reduced accordingly.
*/
mapping(address => uint256) public gaugeKilledEpoch; // gauge => timestamp [epoch when gauge was killed]
string public protocolName; // name of the protocol for gauge creation
// Reserved space for future state variables
uint256[48] private __gap;
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"MAX_GAUGE_TYPE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VOTE_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_GAUGE_LOGIC","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VOTE_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"base","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bribefactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"uint256","name":"_gaugeType","type":"uint256"}],"name":"createGauge","outputs":[{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_internal_bribe","type":"address"},{"internalType":"address","name":"_external_bribe","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"external_bribes","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gaugeKilledEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeLogic","outputs":[{"internalType":"contract IVoterV5_GaugeLogic","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gauges","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"gaugesDistributionTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"index","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"internal_bribes","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAlive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isFactory","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGauge","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGaugeDepositor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGaugeFactory","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gaugeType","type":"uint256"}],"name":"isValidGaugeType","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelistedPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastVoted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permissionRegistry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolForGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolVote","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolName","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"votes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b50611ba1806100206000396000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c80638dd598fb11610125578063cad1b906116100ad578063e6da04571161007c578063e6da0457146105a3578063eae40f26146105c3578063f2312ab0146105ec578063ffa1ad741461060f578063ffe5195b1461063357600080fd5b8063cad1b9061461051e578063cead7a0814610549578063dcd9e47a1461055e578063e567e8691461059b57600080fd5b8063ae21c4cb116100f4578063ae21c4cb14610493578063ae9c9e3f146104bc578063b55a5c1c146104cf578063b9a09fd5146104e2578063c48f5af41461050b57600080fd5b80638dd598fb146104255780639a61df891461043d578063aa79979b1461045d578063ac4afa381461048057600080fd5b806338752a9d116101a8578063533d3e7111610177578063533d3e71146103ae57806355f168d5146103ce5780635604e235146103f1578063657021fb146103f95780636c4f2e381461041c57600080fd5b806338752a9d146103455780633af32abf14610358578063402914f51461037b5780635001f3b51461039b57600080fd5b80631703e5f9116101e45780631703e5f9146102c75780631a32aad6146102ea5780631c4a55a6146102fd5780632986c0e51461032e57600080fd5b806301ffc9a71461021657806306d6a1b21461023e578063075461721461027f5780630f04ba6714610292575b600080fd5b610229610224366004611753565b61063c565b60405190151581526020015b60405180910390f35b61026761024c36600461179c565b6011602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610235565b600654610267906001600160a01b031681565b6102b56102a036600461179c565b601d6020526000908152604090205460ff1681565b60405160ff9091168152602001610235565b6102296102d536600461179c565b601c6020526000908152604090205460ff1681565b600354610267906001600160a01b031681565b610321604051806040016040528060058152602001640312e312e360dc1b81525081565b6040516102359190611815565b61033760095481565b604051908152602001610235565b600554610267906001600160a01b031681565b61022961036636600461179c565b601a6020526000908152604090205460ff1681565b61033761038936600461179c565b600e6020526000908152604090205481565b600254610267906001600160a01b031681565b6103376103bc36600461179c565b60216020526000908152604090205481565b6102296103dc36600461179c565b601b6020526000908152604090205460ff1681565b610337600381565b6102b561040736600461179c565b601e6020526000908152604090205460ff1681565b610337600c5481565b6000546102679061010090046001600160a01b031681565b61033761044b36600461179c565b60186020526000908152604090205481565b61022961046b36600461179c565b60196020526000908152604090205460ff1681565b61026761048e366004611828565b610673565b6102676104a136600461179c565b6013602052600090815260409020546001600160a01b031681565b602054610267906001600160a01b031681565b600754610267906001600160a01b031681565b6102676104f036600461179c565b600f602052600090815260409020546001600160a01b031681565b610267610519366004611841565b61069d565b61033761052c36600461186d565b601460209081526000928352604080842090915290825290205481565b610229610557366004611828565b6003101590565b61057161056c366004611841565b6106d5565b604080516001600160a01b0394851681529284166020840152921691810191909152606001610235565b610321611593565b6103376105b136600461179c565b60106020526000908152604090205481565b6102676105d136600461179c565b6012602052600090815260409020546001600160a01b031681565b6102296105fa36600461179c565b601f6020526000908152604090205460ff1681565b61032160405180604001604052806005815260200164352e342e3160d81b81525081565b610337600b5481565b60006001600160e01b031982166344707c4760e01b148061066d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6008818154811061068357600080fd5b6000918252602090912001546001600160a01b0316905081565b601560205281600052604060002081815481106106b957600080fd5b6000918252602090912001546001600160a01b03169150829050565b60008080600384111561072f5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206761756765207479706520656e756d00000000000000000060448201526064015b60405180910390fd5b60015484106107805760405162461bcd60e51b815260206004820152601960248201527f47617567652074797065206e6f7420636f6e66696775726564000000000000006044820152606401610726565b6001600160a01b038581166000908152600f602052604090205416156107d25760405162461bcd60e51b81526020600482015260076024820152662165786973747360c81b6044820152606401610726565b6000856001600160a01b03163b116108185760405162461bcd60e51b81526020600482015260096024820152680858dbdb9d1c9858dd60ba1b6044820152606401610726565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526001858154811061086c5761086c6118a6565b6000918252602090912001546001600160a01b03166060820152600480548690811061089a5761089a6118a6565b6000918252602090912001546001600160a01b0390811660808301526060820151166108fe5760405162461bcd60e51b815260206004820152601360248201527219195e08199858dd1bdc9e481b9bdd081cd95d606a1b6044820152606401610726565b60808101516001600160a01b03166109505760405162461bcd60e51b815260206004820152601560248201527419d85d59d948199858dd1bdc9e481b9bdd081cd95d605a1b6044820152606401610726565b856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561098e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b291906118bc565b6001600160a01b0390811682526040805163d21220a760e01b815290519188169163d21220a7916004808201926020929091908290030181865afa1580156109fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2291906118bc565b6001600160a01b0316602082015284610ab157606081015160405163e5e31b1360e01b81526001600160a01b0388811660048301529091169063e5e31b1390602401602060405180830381865afa158015610a81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa591906118d9565b151560e0820152610d9e565b60018503610c0d5760608101518151602083015160405163d9a641e160e01b81526000936001600160a01b03169263d9a641e192610b06926004016001600160a01b0392831681529116602082015260400190565b602060405180830381865afa158015610b23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4791906118bc565b90506000876001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bad91906118bc565b9050816001600160a01b0316816001600160a01b031614610bff5760405162461bcd60e51b815260206004820152600c60248201526b77726f6e6720746f6b656e7360a01b6044820152606401610726565b5050600160e0820152610d9e565b60028503610cd3576000866001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7991906118bc565b90506000610c9583606001518460000151856020015185611621565b905080610bff5760405162461bcd60e51b815260206004820152600c60248201526b77726f6e6720746f6b656e7360a01b6044820152606401610726565b60038503610d9e576000866001600160a01b031663dc4c90d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3f91906118bc565b905081606001516001600160a01b0316816001600160a01b031614610d955760405162461bcd60e51b815260206004820152600c60248201526b10b837b7b626b0b730b3b2b960a11b6044820152606401610726565b50600160e08201525b60075460408051634448e1eb60e01b81526004810191909152600a604482015269474f5645524e414e434560b01b60648201523360248201526001600160a01b0390911690634448e1eb90608401602060405180830381865afa158015610e09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2d91906118d9565b611094578060e00151610e6b5760405162461bcd60e51b81526020600482015260066024820152650857dc1bdbdb60d21b6044820152606401610726565b8415610ed9576001600160a01b0386166000908152601b602052604090205460ff16610ed95760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c792077686974656c6973746564207374726174656769657300000000006044820152606401610726565b60038503610f4f5780516001600160a01b031615610f4a5780516001600160a01b03166000908152601a602052604090205460ff16610f4a5760405162461bcd60e51b815260206004820152600d60248201526c2177686974656c69737465644160981b6044820152606401610726565b610fee565b80516001600160a01b0316610f955760405162461bcd60e51b815260206004820152600c60248201526b21706169722e746f6b656e4160a01b6044820152606401610726565b80516001600160a01b03166000908152601a602052604090205460ff16610fee5760405162461bcd60e51b815260206004820152600d60248201526c2177686974656c69737465644160981b6044820152606401610726565b6020808201516001600160a01b03166000908152601a909152604090205460ff1661104b5760405162461bcd60e51b815260206004820152600d60248201526c10bbb434ba32b634b9ba32b22160991b6044820152606401610726565b60208101516001600160a01b03166110945760405162461bcd60e51b815260206004820152600c60248201526b10b830b4b9173a37b5b2b72160a11b6044820152606401610726565b6007546040805163dbc0c08560e01b815290516000926001600160a01b03169163dbc0c0859160048083019260209291908290030181865afa1580156110de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110291906118bc565b905060006022886001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611146573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261116e9190810190611911565b60405160200161117f929190611a91565b60408051601f19818403018152908290526005548551602087015161e66b60e01b85529294506001600160a01b039091169261e66b926111c89287929091908790600401611acc565b6020604051808303816000875af11580156111e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120b91906118bc565b8360a001906001600160a01b031690816001600160a01b0316815250506022886001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611268573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112909190810190611911565b6040516020016112a1929190611b0a565b60408051601f19818403018152908290526005548551602087015161e66b60e01b85529294506001600160a01b039091169261e66b926112ea9287929091908790600401611acc565b6020604051808303816000875af1158015611309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132d91906118bc565b6001600160a01b0390811660c085015260035416611356576002546001600160a01b0316611363565b6003546001600160a01b03165b6001600160a01b039081166040808601829052608086015160005460a088015160c089015160e08a015194516307379e7760e41b81526004810196909652610100909204861660248601528d8616604486015230606486015285166084850152841660a484015290151560c483015290911690637379e7709060e4016020604051808303816000875af11580156113fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142291906118bc565b604080850151905163095ea7b360e01b81526001600160a01b038084166004830152600019602483015292985091169063095ea7b3906044016020604051808303816000875af115801561147a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149e91906118d9565b50505060a0810180516001600160a01b03868116600081815260126020908152604080832080549686166001600160a01b031997881617905560c090970180516013835288842080549187169188169190911790559b909316808252600f8452868220805486168417905591815260118352858120805485168317905560198352858120805460ff199081166001908117909255601c85528783208054909116821790556008805491820190557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018054909416909117909255600954600d9091529290209190915551945192959293505050565b602280546115a0906119be565b80601f01602080910402602001604051908101604052809291908181526020018280546115cc906119be565b80156116195780601f106115ee57610100808354040283529160200191611619565b820191906000526020600020905b8154815290600101906020018083116115fc57829003601f168201915b505050505081565b604080516060810182526101f48152610bb8602082015261271091810191909152600090815b6003811015611744576000876001600160a01b0316631698ee828888868660038110611675576116756118a6565b60200201516040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015262ffffff166044820152606401602060405180830381865afa1580156116d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f591906118bc565b9050806001600160a01b0316856001600160a01b031614801561172057506001600160a01b03811615155b15611731576001935050505061174b565b508061173c81611b44565b915050611647565b5060009150505b949350505050565b60006020828403121561176557600080fd5b81356001600160e01b03198116811461177d57600080fd5b9392505050565b6001600160a01b038116811461179957600080fd5b50565b6000602082840312156117ae57600080fd5b813561177d81611784565b60005b838110156117d45781810151838201526020016117bc565b838111156117e3576000848401525b50505050565b600081518084526118018160208601602086016117b9565b601f01601f19169290920160200192915050565b60208152600061177d60208301846117e9565b60006020828403121561183a57600080fd5b5035919050565b6000806040838503121561185457600080fd5b823561185f81611784565b946020939093013593505050565b6000806040838503121561188057600080fd5b823561188b81611784565b9150602083013561189b81611784565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156118ce57600080fd5b815161177d81611784565b6000602082840312156118eb57600080fd5b8151801515811461177d57600080fd5b634e487b7160e01b600052604160045260246000fd5b60006020828403121561192357600080fd5b815167ffffffffffffffff8082111561193b57600080fd5b818401915084601f83011261194f57600080fd5b815181811115611961576119616118fb565b604051601f8201601f19908116603f01168101908382118183101715611989576119896118fb565b816040528281528760208487010111156119a257600080fd5b6119b38360208301602088016117b9565b979650505050505050565b600181811c908216806119d257607f821691505b6020821081036119f257634e487b7160e01b600052602260045260246000fd5b50919050565b8054600090600181811c9080831680611a1257607f831692505b60208084108203611a3357634e487b7160e01b600052602260045260246000fd5b818015611a475760018114611a5857611a85565b60ff19861689528489019650611a85565b60008881526020902060005b86811015611a7d5781548b820152908501908301611a64565b505084890196505b50505050505092915050565b6000611a9d82856119f8565b690102628102332b2b99d160b51b81528351611ac081600a8401602088016117b9565b01600a01949350505050565b6001600160a01b038581168252848116602083015283166040820152608060608201819052600090611b00908301846117e9565b9695505050505050565b6000611b1682856119f8565b68010213934b132b99d160bd1b81528351611b388160098401602088016117b9565b01600901949350505050565b600060018201611b6457634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220ab8f17920b2ee6132d4a63cad9af919a8e3d1734d1a82a76475b9f096792063e64736f6c634300080d0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102115760003560e01c80638dd598fb11610125578063cad1b906116100ad578063e6da04571161007c578063e6da0457146105a3578063eae40f26146105c3578063f2312ab0146105ec578063ffa1ad741461060f578063ffe5195b1461063357600080fd5b8063cad1b9061461051e578063cead7a0814610549578063dcd9e47a1461055e578063e567e8691461059b57600080fd5b8063ae21c4cb116100f4578063ae21c4cb14610493578063ae9c9e3f146104bc578063b55a5c1c146104cf578063b9a09fd5146104e2578063c48f5af41461050b57600080fd5b80638dd598fb146104255780639a61df891461043d578063aa79979b1461045d578063ac4afa381461048057600080fd5b806338752a9d116101a8578063533d3e7111610177578063533d3e71146103ae57806355f168d5146103ce5780635604e235146103f1578063657021fb146103f95780636c4f2e381461041c57600080fd5b806338752a9d146103455780633af32abf14610358578063402914f51461037b5780635001f3b51461039b57600080fd5b80631703e5f9116101e45780631703e5f9146102c75780631a32aad6146102ea5780631c4a55a6146102fd5780632986c0e51461032e57600080fd5b806301ffc9a71461021657806306d6a1b21461023e578063075461721461027f5780630f04ba6714610292575b600080fd5b610229610224366004611753565b61063c565b60405190151581526020015b60405180910390f35b61026761024c36600461179c565b6011602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610235565b600654610267906001600160a01b031681565b6102b56102a036600461179c565b601d6020526000908152604090205460ff1681565b60405160ff9091168152602001610235565b6102296102d536600461179c565b601c6020526000908152604090205460ff1681565b600354610267906001600160a01b031681565b610321604051806040016040528060058152602001640312e312e360dc1b81525081565b6040516102359190611815565b61033760095481565b604051908152602001610235565b600554610267906001600160a01b031681565b61022961036636600461179c565b601a6020526000908152604090205460ff1681565b61033761038936600461179c565b600e6020526000908152604090205481565b600254610267906001600160a01b031681565b6103376103bc36600461179c565b60216020526000908152604090205481565b6102296103dc36600461179c565b601b6020526000908152604090205460ff1681565b610337600381565b6102b561040736600461179c565b601e6020526000908152604090205460ff1681565b610337600c5481565b6000546102679061010090046001600160a01b031681565b61033761044b36600461179c565b60186020526000908152604090205481565b61022961046b36600461179c565b60196020526000908152604090205460ff1681565b61026761048e366004611828565b610673565b6102676104a136600461179c565b6013602052600090815260409020546001600160a01b031681565b602054610267906001600160a01b031681565b600754610267906001600160a01b031681565b6102676104f036600461179c565b600f602052600090815260409020546001600160a01b031681565b610267610519366004611841565b61069d565b61033761052c36600461186d565b601460209081526000928352604080842090915290825290205481565b610229610557366004611828565b6003101590565b61057161056c366004611841565b6106d5565b604080516001600160a01b0394851681529284166020840152921691810191909152606001610235565b610321611593565b6103376105b136600461179c565b60106020526000908152604090205481565b6102676105d136600461179c565b6012602052600090815260409020546001600160a01b031681565b6102296105fa36600461179c565b601f6020526000908152604090205460ff1681565b61032160405180604001604052806005815260200164352e342e3160d81b81525081565b610337600b5481565b60006001600160e01b031982166344707c4760e01b148061066d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6008818154811061068357600080fd5b6000918252602090912001546001600160a01b0316905081565b601560205281600052604060002081815481106106b957600080fd5b6000918252602090912001546001600160a01b03169150829050565b60008080600384111561072f5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206761756765207479706520656e756d00000000000000000060448201526064015b60405180910390fd5b60015484106107805760405162461bcd60e51b815260206004820152601960248201527f47617567652074797065206e6f7420636f6e66696775726564000000000000006044820152606401610726565b6001600160a01b038581166000908152600f602052604090205416156107d25760405162461bcd60e51b81526020600482015260076024820152662165786973747360c81b6044820152606401610726565b6000856001600160a01b03163b116108185760405162461bcd60e51b81526020600482015260096024820152680858dbdb9d1c9858dd60ba1b6044820152606401610726565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101919091526001858154811061086c5761086c6118a6565b6000918252602090912001546001600160a01b03166060820152600480548690811061089a5761089a6118a6565b6000918252602090912001546001600160a01b0390811660808301526060820151166108fe5760405162461bcd60e51b815260206004820152601360248201527219195e08199858dd1bdc9e481b9bdd081cd95d606a1b6044820152606401610726565b60808101516001600160a01b03166109505760405162461bcd60e51b815260206004820152601560248201527419d85d59d948199858dd1bdc9e481b9bdd081cd95d605a1b6044820152606401610726565b856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561098e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b291906118bc565b6001600160a01b0390811682526040805163d21220a760e01b815290519188169163d21220a7916004808201926020929091908290030181865afa1580156109fe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2291906118bc565b6001600160a01b0316602082015284610ab157606081015160405163e5e31b1360e01b81526001600160a01b0388811660048301529091169063e5e31b1390602401602060405180830381865afa158015610a81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa591906118d9565b151560e0820152610d9e565b60018503610c0d5760608101518151602083015160405163d9a641e160e01b81526000936001600160a01b03169263d9a641e192610b06926004016001600160a01b0392831681529116602082015260400190565b602060405180830381865afa158015610b23573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4791906118bc565b90506000876001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bad91906118bc565b9050816001600160a01b0316816001600160a01b031614610bff5760405162461bcd60e51b815260206004820152600c60248201526b77726f6e6720746f6b656e7360a01b6044820152606401610726565b5050600160e0820152610d9e565b60028503610cd3576000866001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7991906118bc565b90506000610c9583606001518460000151856020015185611621565b905080610bff5760405162461bcd60e51b815260206004820152600c60248201526b77726f6e6720746f6b656e7360a01b6044820152606401610726565b60038503610d9e576000866001600160a01b031663dc4c90d36040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3f91906118bc565b905081606001516001600160a01b0316816001600160a01b031614610d955760405162461bcd60e51b815260206004820152600c60248201526b10b837b7b626b0b730b3b2b960a11b6044820152606401610726565b50600160e08201525b60075460408051634448e1eb60e01b81526004810191909152600a604482015269474f5645524e414e434560b01b60648201523360248201526001600160a01b0390911690634448e1eb90608401602060405180830381865afa158015610e09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2d91906118d9565b611094578060e00151610e6b5760405162461bcd60e51b81526020600482015260066024820152650857dc1bdbdb60d21b6044820152606401610726565b8415610ed9576001600160a01b0386166000908152601b602052604090205460ff16610ed95760405162461bcd60e51b815260206004820152601b60248201527f4f6e6c792077686974656c6973746564207374726174656769657300000000006044820152606401610726565b60038503610f4f5780516001600160a01b031615610f4a5780516001600160a01b03166000908152601a602052604090205460ff16610f4a5760405162461bcd60e51b815260206004820152600d60248201526c2177686974656c69737465644160981b6044820152606401610726565b610fee565b80516001600160a01b0316610f955760405162461bcd60e51b815260206004820152600c60248201526b21706169722e746f6b656e4160a01b6044820152606401610726565b80516001600160a01b03166000908152601a602052604090205460ff16610fee5760405162461bcd60e51b815260206004820152600d60248201526c2177686974656c69737465644160981b6044820152606401610726565b6020808201516001600160a01b03166000908152601a909152604090205460ff1661104b5760405162461bcd60e51b815260206004820152600d60248201526c10bbb434ba32b634b9ba32b22160991b6044820152606401610726565b60208101516001600160a01b03166110945760405162461bcd60e51b815260206004820152600c60248201526b10b830b4b9173a37b5b2b72160a11b6044820152606401610726565b6007546040805163dbc0c08560e01b815290516000926001600160a01b03169163dbc0c0859160048083019260209291908290030181865afa1580156110de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110291906118bc565b905060006022886001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611146573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261116e9190810190611911565b60405160200161117f929190611a91565b60408051601f19818403018152908290526005548551602087015161e66b60e01b85529294506001600160a01b039091169261e66b926111c89287929091908790600401611acc565b6020604051808303816000875af11580156111e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120b91906118bc565b8360a001906001600160a01b031690816001600160a01b0316815250506022886001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015611268573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112909190810190611911565b6040516020016112a1929190611b0a565b60408051601f19818403018152908290526005548551602087015161e66b60e01b85529294506001600160a01b039091169261e66b926112ea9287929091908790600401611acc565b6020604051808303816000875af1158015611309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132d91906118bc565b6001600160a01b0390811660c085015260035416611356576002546001600160a01b0316611363565b6003546001600160a01b03165b6001600160a01b039081166040808601829052608086015160005460a088015160c089015160e08a015194516307379e7760e41b81526004810196909652610100909204861660248601528d8616604486015230606486015285166084850152841660a484015290151560c483015290911690637379e7709060e4016020604051808303816000875af11580156113fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142291906118bc565b604080850151905163095ea7b360e01b81526001600160a01b038084166004830152600019602483015292985091169063095ea7b3906044016020604051808303816000875af115801561147a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149e91906118d9565b50505060a0810180516001600160a01b03868116600081815260126020908152604080832080549686166001600160a01b031997881617905560c090970180516013835288842080549187169188169190911790559b909316808252600f8452868220805486168417905591815260118352858120805485168317905560198352858120805460ff199081166001908117909255601c85528783208054909116821790556008805491820190557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018054909416909117909255600954600d9091529290209190915551945192959293505050565b602280546115a0906119be565b80601f01602080910402602001604051908101604052809291908181526020018280546115cc906119be565b80156116195780601f106115ee57610100808354040283529160200191611619565b820191906000526020600020905b8154815290600101906020018083116115fc57829003601f168201915b505050505081565b604080516060810182526101f48152610bb8602082015261271091810191909152600090815b6003811015611744576000876001600160a01b0316631698ee828888868660038110611675576116756118a6565b60200201516040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015262ffffff166044820152606401602060405180830381865afa1580156116d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f591906118bc565b9050806001600160a01b0316856001600160a01b031614801561172057506001600160a01b03811615155b15611731576001935050505061174b565b508061173c81611b44565b915050611647565b5060009150505b949350505050565b60006020828403121561176557600080fd5b81356001600160e01b03198116811461177d57600080fd5b9392505050565b6001600160a01b038116811461179957600080fd5b50565b6000602082840312156117ae57600080fd5b813561177d81611784565b60005b838110156117d45781810151838201526020016117bc565b838111156117e3576000848401525b50505050565b600081518084526118018160208601602086016117b9565b601f01601f19169290920160200192915050565b60208152600061177d60208301846117e9565b60006020828403121561183a57600080fd5b5035919050565b6000806040838503121561185457600080fd5b823561185f81611784565b946020939093013593505050565b6000806040838503121561188057600080fd5b823561188b81611784565b9150602083013561189b81611784565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156118ce57600080fd5b815161177d81611784565b6000602082840312156118eb57600080fd5b8151801515811461177d57600080fd5b634e487b7160e01b600052604160045260246000fd5b60006020828403121561192357600080fd5b815167ffffffffffffffff8082111561193b57600080fd5b818401915084601f83011261194f57600080fd5b815181811115611961576119616118fb565b604051601f8201601f19908116603f01168101908382118183101715611989576119896118fb565b816040528281528760208487010111156119a257600080fd5b6119b38360208301602088016117b9565b979650505050505050565b600181811c908216806119d257607f821691505b6020821081036119f257634e487b7160e01b600052602260045260246000fd5b50919050565b8054600090600181811c9080831680611a1257607f831692505b60208084108203611a3357634e487b7160e01b600052602260045260246000fd5b818015611a475760018114611a5857611a85565b60ff19861689528489019650611a85565b60008881526020902060005b86811015611a7d5781548b820152908501908301611a64565b505084890196505b50505050505092915050565b6000611a9d82856119f8565b690102628102332b2b99d160b51b81528351611ac081600a8401602088016117b9565b01600a01949350505050565b6001600160a01b038581168252848116602083015283166040820152608060608201819052600090611b00908301846117e9565b9695505050505050565b6000611b1682856119f8565b68010213934b132b99d160bd1b81528351611b388160098401602088016117b9565b01600901949350505050565b600060018201611b6457634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220ab8f17920b2ee6132d4a63cad9af919a8e3d1734d1a82a76475b9f096792063e64736f6c634300080d0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
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.