Contract Name:
LauncherPlugin
Contract Source Code:
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import {ILauncherPlugin} from "./interfaces/ILauncherPlugin.sol";
import {Errors} from "contracts/libraries/Errors.sol";
import {IVoter} from "./interfaces/IVoter.sol";
/// @author ShadowDEX on Sonic
/// @title LauncherPlugins contract for modular plug-n-play with memes
/**
* @dev There are two trusted roles in the LauncherPlugin system
* Authority: Whitelisted external launchers, e.g. launchpads
* Operator: Shadow operational multisig, or other timelocked/secure system
* AccessHub: central authority management contract
* These roles are to be managed securely, and with diligence to prevent abuse
* However, the system already has checks in place to mitigate any possible abuse situations ahead of time
*/
contract LauncherPlugin is ILauncherPlugin {
/// @inheritdoc ILauncherPlugin
address public operator;
/// @notice the voter contract
IVoter public immutable voter;
/// @inheritdoc ILauncherPlugin
mapping(address pool => bool isEnabled) public launcherPluginEnabled;
/// @inheritdoc ILauncherPlugin
mapping(address pool => LauncherConfigs) public poolConfigs;
/// @inheritdoc ILauncherPlugin
mapping(address pool => address feeDist) public feeDistToPool;
/// @inheritdoc ILauncherPlugin
mapping(address who => bool authority) public authorityMap;
/// @inheritdoc ILauncherPlugin
mapping(address authority => string name) public nameOfAuthority;
/// @inheritdoc ILauncherPlugin
uint256 public constant DENOM = 1_000_000;
modifier onlyAuthority() {
/// @dev authority check of either the operator of authority in the mapping
require(authorityMap[msg.sender] || msg.sender == IVoter(voter).accessHub(), Errors.NOT_AUTHORITY());
_;
}
modifier onlyOperator() {
/// @dev redundant `operator` address put here as a safeguard for input errors on transferring roles
require(msg.sender == IVoter(voter).accessHub() || msg.sender == operator, Errors.NOT_OPERATOR());
_;
}
constructor(address _voter, address _operator) {
/// @dev initialize the voter
voter = IVoter(_voter);
/// @dev operator and team initially are the same
operator = _operator;
}
/// @inheritdoc ILauncherPlugin
function accessHub() external view returns (address) {
return IVoter(voter).accessHub();
}
/// @inheritdoc ILauncherPlugin
/// @dev should be called by another contract with proper batching of function calls
function setConfigs(address _pool, uint256 _take, address _recipient) external onlyAuthority {
/// @dev ensure launcherPlugins are enabled
require(launcherPluginEnabled[_pool], Errors.NOT_ENABLED(_pool));
/// @dev ensure the fee is <= 100%
require(_take <= DENOM, Errors.INVALID_TAKE());
/// @dev store launcher configs in pool to struct mapping
LauncherConfigs memory lc = LauncherConfigs(_take, _recipient);
/// @dev store the pool configs in the mapping
poolConfigs[_pool] = lc;
/// @dev emit an event for configuration
emit Configured(_pool, _take, _recipient);
}
/// @inheritdoc ILauncherPlugin
/// @dev should be called by another contract with proper batching of function calls
function enablePool(address _pool) external onlyAuthority {
/// @dev require that the plugin is enabled
require(!launcherPluginEnabled[_pool], Errors.ENABLED());
/// @dev fetch the feeDistributor address
address _feeDist = voter.feeDistributorForGauge(voter.gaugeForPool(_pool));
/// @dev check that _feeDist is not the zero addresss
require(_feeDist != address(0), Errors.NO_FEEDIST());
/// @dev set the feeDist for the pool
feeDistToPool[_feeDist] = _pool;
launcherPluginEnabled[_pool] = true;
/// @dev emit with the name of the authority
emit EnabledPool(_pool, nameOfAuthority[msg.sender]);
}
/// @inheritdoc ILauncherPlugin
function migratePool(address _oldPool, address _newPool) external {
/// @dev gate to accessHub and the current operator
require(msg.sender == IVoter(voter).accessHub() || msg.sender == operator, Errors.NOT_AUTHORIZED(msg.sender));
require(launcherPluginEnabled[_oldPool], Errors.NOT_ENABLED(_oldPool));
launcherPluginEnabled[_newPool] = true;
/// @dev fetch the feedists for each pool
(address _feeDist, address _newFeeDist) = (
voter.feeDistributorForGauge(voter.gaugeForPool(_oldPool)),
voter.feeDistributorForGauge(voter.gaugeForPool(_newPool))
);
/// @dev set the new pool's feedist
feeDistToPool[_newFeeDist] = _newPool;
/// @dev copy over the values
poolConfigs[_newPool] = poolConfigs[_oldPool];
/// @dev delete old values
delete poolConfigs[_oldPool];
/// @dev set to disabled
launcherPluginEnabled[_oldPool] = false;
/// @dev set the old fee dist to the new one as a safety measure
feeDistToPool[_feeDist] = feeDistToPool[_newFeeDist];
emit MigratedPool(_oldPool, _newPool);
}
/// @inheritdoc ILauncherPlugin
function disablePool(address _pool) external onlyOperator {
/// @dev require the plugin is already enabled
require(launcherPluginEnabled[_pool], Errors.NOT_ENABLED(_pool));
/// @dev wipe struct
delete poolConfigs[_pool];
/// @dev wipe the mapping for feeDist to the pool, incase the feeDist is overwritten
delete feeDistToPool[
voter.feeDistributorForGauge(voter.gaugeForPool(_pool))
];
/// @dev set to disabled
launcherPluginEnabled[_pool] = false;
/// @dev emit an event
emit DisabledPool(_pool);
}
/// @inheritdoc ILauncherPlugin
function setOperator(address _newOperator) external onlyOperator {
/// @dev ensure the new operator is not already the operator
require(operator != _newOperator, Errors.ALREADY_OPERATOR());
/// @dev store the oldOperator to use in the event, for info purposes
address oldOperator = operator;
/// @dev set operator as the new operator
operator = _newOperator;
/// @dev emit operator change event
emit NewOperator(oldOperator, operator);
}
/// @inheritdoc ILauncherPlugin
function grantAuthority(address _newAuthority, string calldata _name) external onlyOperator {
/// @dev ensure the proposed _newAuthority is not already one
require(!authorityMap[_newAuthority], Errors.ALREADY_AUTHORITY());
/// @dev set the mapping to true
authorityMap[_newAuthority] = true;
/// @dev emit the new authority event
emit NewAuthority(_newAuthority);
/// @dev label the authority
_labelAuthority(_newAuthority, _name);
}
/// @inheritdoc ILauncherPlugin
function revokeAuthority(address _oldAuthority) external onlyOperator {
/// @dev ensure _oldAuthority is already an authority
require(authorityMap[_oldAuthority], Errors.NOT_AUTHORITY());
/// @dev set the mapping to false
authorityMap[_oldAuthority] = false;
/// @dev emit the remove authority event
emit RemovedAuthority(_oldAuthority);
}
/// @inheritdoc ILauncherPlugin
function label(address _authority, string calldata _label) external onlyOperator {
_labelAuthority(_authority, _label);
}
/// @inheritdoc ILauncherPlugin
function values(address _feeDist) external view returns (uint256 _take, address _recipient) {
/// @dev fetch the poolConfigs from the mapping
LauncherConfigs memory _tmp = poolConfigs[feeDistToPool[_feeDist]];
/// @dev return the existing values
return (_tmp.launcherTake, _tmp.takeRecipient);
}
/// @dev internal function called on creation and manually
function _labelAuthority(address _authority, string calldata _label) internal {
/// @dev ensure they are an authority
require(authorityMap[_authority], Errors.NOT_AUTHORITY());
/// @dev label the authority
nameOfAuthority[_authority] = _label;
/// @dev emit on label
emit Labeled(_authority, _label);
}
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
interface ILauncherPlugin {
/// @dev struct that holds the configurations of each specific pool
struct LauncherConfigs {
uint256 launcherTake;
address takeRecipient;
}
event NewOperator(address indexed _old, address indexed _new);
event NewAuthority(address indexed _newAuthority);
event RemovedAuthority(address indexed _previousAuthority);
event EnabledPool(address indexed pool, string indexed _name);
event DisabledPool(address indexed pool);
event MigratedPool(address indexed oldPool, address indexed newPool);
event Configured(address indexed pool, uint256 take, address indexed recipient);
event Labeled(address indexed authority, string indexed label);
/// @notice address of the accessHub
function accessHub() external view returns (address _accessHub);
/// @notice protocol operator address
function operator() external view returns (address _operator);
/// @notice the denominator constant
function DENOM() external view returns (uint256 _denominator);
/// @notice whether configs are enabled for a pool
/// @param _pool address of the pool
/// @return bool
function launcherPluginEnabled(address _pool) external view returns (bool);
/// @notice maps whether an address is an authority or not
/// @param _who the address to check
/// @return _is true or false
function authorityMap(address _who) external view returns (bool _is);
/// @notice allows migrating the parameters from one pool to the other
/// @param _oldPool the current address of the pair
/// @param _newPool the new pool's address
function migratePool(address _oldPool, address _newPool) external;
/// @notice fetch the launcher configs if any
/// @param _pool address of the pool
/// @return LauncherConfigs the configs
function poolConfigs(address _pool) external view returns (uint256, address);
/// @notice view functionality to see who is an authority
function nameOfAuthority(address) external view returns (string memory);
/// @notice returns the pool address for a feeDist
/// @param _feeDist address of the feeDist
/// @return _pool the pool address from the mapping
function feeDistToPool(address _feeDist) external view returns (address _pool);
/// @notice set launcher configurations for a pool
/// @param _pool address of the pool
/// @param _take the fee that goes to the designated recipient
/// @param _recipient the address that receives the fees
function setConfigs(address _pool, uint256 _take, address _recipient) external;
/// @notice enables the pool for LauncherConfigs
/// @param _pool address of the pool
function enablePool(address _pool) external;
/// @notice disables the pool for LauncherConfigs
/// @dev clears mappings
/// @param _pool address of the pool
function disablePool(address _pool) external;
/// @notice sets a new operator address
/// @param _newOperator new operator address
function setOperator(address _newOperator) external;
/// @notice gives authority to a new contract/address
/// @param _newAuthority the suggested new authority
function grantAuthority(address _newAuthority, string calldata) external;
/// @notice removes authority from a contract/address
/// @param _oldAuthority the to-be-removed authority
function revokeAuthority(address _oldAuthority) external;
/// @notice labels an authority
function label(address, string calldata) external;
/// @notice returns the values for the launcherConfig of the specific feeDist
/// @param _feeDist the address of the feeDist
/// @return _launcherTake fee amount taken
/// @return _recipient address that receives the fees
function values(address _feeDist) external view returns (uint256 _launcherTake, address _recipient);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @title Central Errors Library
/// @notice Contains all custom errors used across the protocol
/// @dev Centralized error definitions to prevent redundancy
library Errors {
/*//////////////////////////////////////////////////////////////
VOTER ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when attempting to interact with an already active gauge
/// @param gauge The address of the gauge
error ACTIVE_GAUGE(address gauge);
/// @notice Thrown when attempting to interact with an inactive gauge
/// @param gauge The address of the gauge
error GAUGE_INACTIVE(address gauge);
/// @notice Thrown when attempting to whitelist an already whitelisted token
/// @param token The address of the token
error ALREADY_WHITELISTED(address token);
/// @notice Thrown when caller is not authorized to perform an action
/// @param caller The address of the unauthorized caller
error NOT_AUTHORIZED(address caller);
/// @notice Thrown when token is not whitelisted
/// @param token The address of the non-whitelisted token
error NOT_WHITELISTED(address token);
/// @notice Thrown when both tokens in a pair are not whitelisted
error BOTH_NOT_WHITELISTED();
/// @notice Thrown when address is not a valid pool
/// @param pool The invalid pool address
error NOT_POOL(address pool);
/// @notice Thrown when pool is not seeded in PoolUpdater
/// @param pool The invalid pool address
error NOT_SEEDED(address pool);
/// @notice Thrown when contract is not initialized
error NOT_INIT();
/// @notice Thrown when array lengths don't match
error LENGTH_MISMATCH();
/// @notice Thrown when pool doesn't have an associated gauge
/// @param pool The address of the pool
error NO_GAUGE(address pool);
/// @notice Thrown when rewards are already distributed for a period
/// @param gauge The gauge address
/// @param period The distribution period
error ALREADY_DISTRIBUTED(address gauge, uint256 period);
/// @notice Thrown when attempting to vote with zero amount
/// @param pool The pool address
error ZERO_VOTE(address pool);
/// @notice Thrown when ratio exceeds maximum allowed
/// @param _xRatio The excessive ratio value
error RATIO_TOO_HIGH(uint256 _xRatio);
/// @notice Thrown when vote operation fails
error VOTE_UNSUCCESSFUL();
/*//////////////////////////////////////////////////////////////
GAUGE V3 ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when the pool already has a gauge
/// @param pool The address of the pool
error GAUGE_EXISTS(address pool);
/// @notice Thrown when caller is not the voter
/// @param caller The address of the invalid caller
error NOT_VOTER(address caller);
/// @notice Thrown when amount is not greater than zero
/// @param amt The invalid amount
error NOT_GT_ZERO(uint256 amt);
/// @notice Thrown when attempting to claim future rewards
error CANT_CLAIM_FUTURE();
/// @notice Throw when gauge can't determine if using secondsInRange from the pool is safe
error NEED_TEAM_TO_UPDATE();
/*//////////////////////////////////////////////////////////////
GAUGE ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when amount is zero
error ZERO_AMOUNT();
/// @notice Thrown when stake notification fails
error CANT_NOTIFY_STAKE();
/// @notice Thrown when reward amount is too high
error REWARD_TOO_HIGH();
/// @notice Thrown when amount exceeds remaining balance
/// @param amount The requested amount
/// @param remaining The remaining balance
error NOT_GREATER_THAN_REMAINING(uint256 amount, uint256 remaining);
/// @notice Thrown when token operation fails
/// @param token The address of the problematic token
error TOKEN_ERROR(address token);
/// @notice Thrown when an address is not an NfpManager
error NOT_NFP_MANAGER(address nfpManager);
/*//////////////////////////////////////////////////////////////
FEE DISTRIBUTOR ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when period is not finalized
/// @param period The unfinalized period
error NOT_FINALIZED(uint256 period);
/// @notice Thrown when the destination of a redirect is not a feeDistributor
/// @param destination Destination of the redirect
error NOT_FEE_DISTRIBUTOR(address destination);
/// @notice Thrown when the destination of a redirect's pool/pair has completely different tokens
error DIFFERENT_DESTINATION_TOKENS();
/*//////////////////////////////////////////////////////////////
PAIR ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when ratio is unstable
error UNSTABLE_RATIO();
/// @notice Thrown when safe transfer fails
error SAFE_TRANSFER_FAILED();
/// @notice Thrown on arithmetic overflow
error OVERFLOW();
/// @notice Thrown when skim operation is disabled
error SKIM_DISABLED();
/// @notice Thrown when insufficient liquidity is minted
error INSUFFICIENT_LIQUIDITY_MINTED();
/// @notice Thrown when insufficient liquidity is burned
error INSUFFICIENT_LIQUIDITY_BURNED();
/// @notice Thrown when output amount is insufficient
error INSUFFICIENT_OUTPUT_AMOUNT();
/// @notice Thrown when input amount is insufficient
error INSUFFICIENT_INPUT_AMOUNT();
/// @notice Generic insufficient liquidity error
error INSUFFICIENT_LIQUIDITY();
/// @notice Invalid transfer error
error INVALID_TRANSFER();
/// @notice K value error in AMM
error K();
/*//////////////////////////////////////////////////////////////
PAIR FACTORY ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when fee is too high
error FEE_TOO_HIGH();
/// @notice Thrown when fee is zero
error ZERO_FEE();
/// @notice Thrown when token assortment is invalid
error INVALID_ASSORTMENT();
/// @notice Thrown when address is zero
error ZERO_ADDRESS();
/// @notice Thrown when pair already exists
error PAIR_EXISTS();
/// @notice Thrown when fee split is invalid
error INVALID_FEE_SPLIT();
/*//////////////////////////////////////////////////////////////
FEE RECIPIENT FACTORY ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when treasury fee is invalid
error INVALID_TREASURY_FEE();
/*//////////////////////////////////////////////////////////////
ROUTER ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when deadline has expired
error EXPIRED();
/// @notice Thrown when tokens are identical
error IDENTICAL();
/// @notice Thrown when amount is insufficient
error INSUFFICIENT_AMOUNT();
/// @notice Thrown when path is invalid
error INVALID_PATH();
/// @notice Thrown when token B amount is insufficient
error INSUFFICIENT_B_AMOUNT();
/// @notice Thrown when token A amount is insufficient
error INSUFFICIENT_A_AMOUNT();
/// @notice Thrown when input amount is excessive
error EXCESSIVE_INPUT_AMOUNT();
/// @notice Thrown when ETH transfer fails
error ETH_TRANSFER_FAILED();
/// @notice Thrown when reserves are invalid
error INVALID_RESERVES();
/*//////////////////////////////////////////////////////////////
MINTER ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when epoch 0 has already started
error STARTED();
/// @notice Thrown when emissions haven't started
error EMISSIONS_NOT_STARTED();
/// @notice Thrown when deviation is too high
error TOO_HIGH();
/// @notice Thrown when no value change detected
error NO_CHANGE();
/// @notice Thrown when updating emissions in same period
error SAME_PERIOD();
/// @notice Thrown when contract setup is invalid
error INVALID_CONTRACT();
/// @notice Thrown when legacy factory doesn't have feeSplitWhenNoGauge on
error FEE_SPLIT_WHEN_NO_GAUGE_IS_OFF();
/*//////////////////////////////////////////////////////////////
ACCESS HUB ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when addresses are identical
error SAME_ADDRESS();
/// @notice Thrown when caller is not timelock
/// @param caller The invalid caller address
error NOT_TIMELOCK(address caller);
/// @notice Thrown when manual execution fails
/// @param reason The failure reason
error MANUAL_EXECUTION_FAILURE(bytes reason);
/// @notice Thrown when kick operation is forbidden
/// @param target The target address
error KICK_FORBIDDEN(address target);
/*//////////////////////////////////////////////////////////////
VOTE MODULE ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when caller is not xShadow
error NOT_XSHADOW();
/// @notice Thrown when cooldown period is still active
error COOLDOWN_ACTIVE();
/// @notice Thrown when caller is not vote module
error NOT_VOTEMODULE();
/// @notice Thrown when caller is unauthorized
error UNAUTHORIZED();
/// @notice Thrown when caller is not access hub
error NOT_ACCESSHUB();
/// @notice Thrown when address is invalid
error INVALID_ADDRESS();
/*//////////////////////////////////////////////////////////////
LAUNCHER PLUGIN ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when caller is not authority
error NOT_AUTHORITY();
/// @notice Thrown when already an authority
error ALREADY_AUTHORITY();
/// @notice Thrown when caller is not operator
error NOT_OPERATOR();
/// @notice Thrown when already an operator
error ALREADY_OPERATOR();
/// @notice Thrown when pool is not enabled
/// @param pool The disabled pool address
error NOT_ENABLED(address pool);
/// @notice Thrown when fee distributor is missing
error NO_FEEDIST();
/// @notice Thrown when already enabled
error ENABLED();
/// @notice Thrown when take value is invalid
error INVALID_TAKE();
/*//////////////////////////////////////////////////////////////
X33 ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when value is zero
error ZERO();
/// @notice Thrown when amount is insufficient
error NOT_ENOUGH();
/// @notice Thrown when value doesn't conform to scale
/// @param value The non-conforming value
error NOT_CONFORMED_TO_SCALE(uint256 value);
/// @notice Thrown when contract is locked
error LOCKED();
/// @notice Thrown when rebase is in progress
error REBASE_IN_PROGRESS();
/// @notice Thrown when aggregator reverts
/// @param reason The revert reason
error AGGREGATOR_REVERTED(bytes reason);
/// @notice Thrown when output amount is too low
/// @param amount The insufficient amount
error AMOUNT_OUT_TOO_LOW(uint256 amount);
/// @notice Thrown when aggregator is not whitelisted
/// @param aggregator The non-whitelisted aggregator address
error AGGREGATOR_NOT_WHITELISTED(address aggregator);
/// @notice Thrown when token is forbidden
/// @param token The forbidden token address
error FORBIDDEN_TOKEN(address token);
/*//////////////////////////////////////////////////////////////
XSHADOW ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when caller is not minter
error NOT_MINTER();
/// @notice Thrown when no vest exists
error NO_VEST();
/// @notice Thrown when already exempt
error ALREADY_EXEMPT();
/// @notice Thrown when not exempt
error NOT_EXEMPT();
/// @notice Thrown when rescue operation is not allowed
error CANT_RESCUE();
/// @notice Thrown when array lengths mismatch
error ARRAY_LENGTHS();
/// @notice Thrown when vesting periods overlap
error VEST_OVERLAP();
/*//////////////////////////////////////////////////////////////
V3 FACTORY ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when tokens are identical
error IDENTICAL_TOKENS();
/// @notice Thrown when fee is too large
error FEE_TOO_LARGE();
/// @notice Address zero error
error ADDRESS_ZERO();
/// @notice Fee zero error
error F0();
/// @notice Thrown when value is out of bounds
/// @param value The out of bounds value
error OOB(uint8 value);
/*//////////////////////////////////////////////////////////////
POOL UPDATER ERRORS
//////////////////////////////////////////////////////////////*/
/// @notice Thrown when seeding for a pool fails
error TRANSFER_FROM_FOR_SEEDING_FAILED(address token, uint256 amount);
/// @notice Thrown when seeding for a pool fails
error SEEDING_FAILED();
/// @notice Thrown when updatePools is called too early
error TOO_EARLY();
/// @notice Thrown when a callback is called when an update isn't running
error NOT_RUNNING();
/// @notice Thrown when updatePools didn't perform any updates
error NO_UPDATES();
}
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
pragma abicoder v2;
interface IVoter {
event GaugeCreated(address indexed gauge, address creator, address feeDistributor, address indexed pool);
event GaugeKilled(address indexed gauge);
event GaugeRevived(address indexed gauge);
event Voted(address indexed owner, uint256 weight, address indexed pool);
event Abstained(address indexed owner, uint256 weight);
event Deposit(address indexed lp, address indexed gauge, address indexed owner, uint256 amount);
event Withdraw(address indexed lp, address indexed gauge, address indexed owner, uint256 amount);
event NotifyReward(address indexed sender, address indexed reward, uint256 amount);
event DistributeReward(address indexed sender, address indexed gauge, uint256 amount);
event EmissionsRatio(address indexed caller, uint256 oldRatio, uint256 newRatio);
event NewGovernor(address indexed sender, address indexed governor);
event Whitelisted(address indexed whitelister, address indexed token);
event WhitelistRevoked(address indexed forbidder, address indexed token, bool status);
event MainTickSpacingChanged(address indexed token0, address indexed token1, int24 indexed newMainTickSpacing);
event Poke(address indexed user);
event EmissionsRedirected(address indexed sourceGauge, address indexed destinationGauge);
struct InitializationParams {
address shadow;
address legacyFactory;
address gauges;
address feeDistributorFactory;
address minter;
address msig;
address xShadow;
address clFactory;
address clGaugeFactory;
address nfpManager;
address feeRecipientFactory;
address voteModule;
address launcherPlugin;
address poolUpdater;
}
function initialize(InitializationParams memory inputs) external;
/// @notice denominator basis
function BASIS() external view returns (uint256);
/// @notice ratio of xShadow emissions globally
function xRatio() external view returns (uint256);
/// @notice xShadow contract address
function xShadow() external view returns (address);
/// @notice legacy factory address (uni-v2/stableswap)
function legacyFactory() external view returns (address);
/// @notice concentrated liquidity factory
function clFactory() external view returns (address);
/// @notice gauge factory for CL
function clGaugeFactory() external view returns (address);
/// @notice pool updater for CL
function poolUpdater() external view returns (address);
/// @notice legacy fee recipient factory
function feeRecipientFactory() external view returns (address);
/// @notice peripheral NFPManager contract
function nfpManager() external view returns (address);
/// @notice returns the address of the current governor
/// @return _governor address of the governor
function governor() external view returns (address _governor);
/// @notice the address of the vote module
/// @return _voteModule the vote module contract address
function voteModule() external view returns (address _voteModule);
/// @notice address of the central access Hub
function accessHub() external view returns (address);
/// @notice the address of the shadow launcher plugin to enable third party launchers
/// @return _launcherPlugin the address of the plugin
function launcherPlugin() external view returns (address _launcherPlugin);
/// @notice distributes emissions from the minter to the voter
/// @param amount the amount of tokens to notify
function notifyRewardAmount(uint256 amount) external;
/// @notice distributes the emissions for a specific gauge
/// @param _gauge the gauge address
function distribute(address _gauge) external;
/// @notice returns the address of the gauge factory
/// @param _gaugeFactory gauge factory address
function gaugeFactory() external view returns (address _gaugeFactory);
/// @notice returns the address of the feeDistributor factory
/// @return _feeDistributorFactory feeDist factory address
function feeDistributorFactory() external view returns (address _feeDistributorFactory);
/// @notice returns the address of the minter contract
/// @return _minter address of the minter
function minter() external view returns (address _minter);
/// @notice check if the gauge is active for governance use
/// @param _gauge address of the gauge
/// @return _trueOrFalse if the gauge is alive
function isAlive(address _gauge) external view returns (bool _trueOrFalse);
/// @notice allows the token to be paired with other whitelisted assets to participate in governance
/// @param _token the address of the token
function whitelist(address _token) external;
/// @notice effectively disqualifies a token from governance
/// @param _token the address of the token
function revokeWhitelist(address _token) external;
/// @notice returns if the address is a gauge
/// @param gauge address of the gauge
/// @return _trueOrFalse boolean if the address is a gauge
function isGauge(address gauge) external view returns (bool _trueOrFalse);
/// @notice disable a gauge from governance
/// @param _gauge address of the gauge
function killGauge(address _gauge) external;
/// @notice re-activate a dead gauge
/// @param _gauge address of the gauge
function reviveGauge(address _gauge) external;
/// @notice re-cast a tokenID's votes
/// @param owner address of the owner
function poke(address owner) external;
/// @notice sets the main destinationGauge of a token pairing
/// @param tokenA address of tokenA
/// @param tokenB address of tokenB
/// @param destinationGauge the main gauge to set to
function redirectEmissions(address tokenA, address tokenB, address destinationGauge) external;
/// @notice returns if the address is a fee distributor
/// @param _feeDistributor address of the feeDist
/// @return _trueOrFalse if the address is a fee distributor
function isFeeDistributor(address _feeDistributor) external view returns (bool _trueOrFalse);
/// @notice returns the address of the emission's token
/// @return _shadow emissions token contract address
function shadow() external view returns (address _shadow);
/// @notice returns the address of the pool's gauge, if any
/// @param _pool pool address
/// @return _gauge gauge address
function gaugeForPool(address _pool) external view returns (address _gauge);
/// @notice returns the address of the pool's feeDistributor, if any
/// @param _gauge address of the gauge
/// @return _feeDistributor address of the pool's feedist
function feeDistributorForGauge(address _gauge) external view returns (address _feeDistributor);
/// @notice returns the gauge address of a CL pool
/// @param tokenA address of token A in the pair
/// @param tokenB address of token B in the pair
/// @param tickSpacing tickspacing of the pool
/// @return gauge address of the gauge
function gaugeForClPool(address tokenA, address tokenB, int24 tickSpacing) external view returns (address gauge);
/// @notice returns the array of all tickspacings for the tokenA/tokenB combination
/// @param tokenA address of token A in the pair
/// @param tokenB address of token B in the pair
/// @return _ts array of all the tickspacings
function tickSpacingsForPair(address tokenA, address tokenB) external view returns (int24[] memory _ts);
/// @notice returns the destination of a gauge redirect
/// @param gauge address of gauge
function gaugeRedirect(address gauge) external view returns (address);
/// @notice returns the block.timestamp divided by 1 week in seconds
/// @return period the period used for gauges
function getPeriod() external view returns (uint256 period);
/// @notice cast a vote to direct emissions to gauges and earn incentives
/// @param owner address of the owner
/// @param _pools the list of pools to vote on
/// @param _weights an arbitrary weight per pool which will be normalized to 100% regardless of numerical inputs
function vote(address owner, address[] calldata _pools, uint256[] calldata _weights) external;
/// @notice reset the vote of an address
/// @param owner address of the owner
function reset(address owner) external;
/// @notice set the governor address
/// @param _governor the new governor address
function setGovernor(address _governor) external;
/// @notice recover stuck emissions
/// @param _gauge the gauge address
/// @param _period the period
function stuckEmissionsRecovery(address _gauge, uint256 _period) external;
/// @notice creates a legacy gauge for the pool
/// @param _pool pool's address
/// @return _gauge address of the new gauge
function createGauge(address _pool) external returns (address _gauge);
/// @notice create a concentrated liquidity gauge
/// @param tokenA the address of tokenA
/// @param tokenB the address of tokenB
/// @param tickSpacing the tickspacing of the pool
/// @return _clGauge address of the new gauge
function createCLGauge(address tokenA, address tokenB, int24 tickSpacing) external returns (address _clGauge);
/// @notice claim concentrated liquidity gauge rewards for specific NFP token ids
/// @param _gauges array of gauges
/// @param _tokens two dimensional array for the tokens to claim
/// @param _nfpTokenIds two dimensional array for the NFPs
function claimClGaugeRewards(
address[] calldata _gauges,
address[][] calldata _tokens,
uint256[][] calldata _nfpTokenIds
) external;
/// @notice claim arbitrary rewards from specific feeDists
/// @param owner address of the owner
/// @param _feeDistributors address of the feeDists
/// @param _tokens two dimensional array for the tokens to claim
function claimIncentives(address owner, address[] calldata _feeDistributors, address[][] calldata _tokens)
external;
/// @notice claim arbitrary rewards from specific feeDists and break up legacy pairs
/// @param owner address of the owner
/// @param _feeDistributors address of the feeDists
/// @param _tokens two dimensional array for the tokens to claim
function claimLegacyIncentives(address owner, address[] calldata _feeDistributors, address[][] calldata _tokens)
external;
/// @notice claim arbitrary rewards from specific gauges
/// @param _gauges address of the gauges
/// @param _tokens two dimensional array for the tokens to claim
function claimRewards(address[] calldata _gauges, address[][] calldata _tokens) external;
/// @notice claim arbitrary rewards from specific legacy gauges, and exit to shadow
/// @param _gauges address of the gauges
/// @param _tokens two dimensional array for the tokens to claim
function claimLegacyRewardsAndExit(address[] calldata _gauges, address[][] calldata _tokens) external;
/// @notice claim arbitrary rewards from specific cl gauges, and exit to shadow
/// @param _gauges address of the gauges
/// @param _tokens two dimensional array for the tokens to claim
/// @param _nfpTokenIds two dimensional array for the nfp to claim
function claimClGaugeRewardsAndExit(
address[] memory _gauges,
address[][] memory _tokens,
uint256[][] memory _nfpTokenIds
) external;
/// @notice distribute emissions to a gauge for a specific period
/// @param _gauge address of the gauge
/// @param _period value of the period
function distributeForPeriod(address _gauge, uint256 _period) external;
/// @notice attempt distribution of emissions to all gauges
function distributeAll() external;
/// @notice distribute emissions to gauges by index
/// @param startIndex start of the loop
/// @param endIndex end of the loop
function batchDistributeByIndex(uint256 startIndex, uint256 endIndex) external;
/// @notice lets governance update lastDistro period for a gauge
/// @dev should only be used if distribute() is running out of gas
/// @dev gaugePeriodDistributed will stop double claiming
/// @param _gauge gauge to update
/// @param _period period to update to
function updateLastDistro(address _gauge, uint256 _period) external;
/// @notice returns the votes cast for a tokenID
/// @param owner address of the owner
/// @return votes an array of votes casted
/// @return weights an array of the weights casted per pool
function getVotes(address owner, uint256 period)
external
view
returns (address[] memory votes, uint256[] memory weights);
/// @notice returns an array of all the pools
/// @return _pools the array of pools
function getAllPools() external view returns (address[] memory _pools);
/// @notice returns the length of pools
function getPoolsLength() external view returns (uint256);
/// @notice returns the pool at index
function getPool(uint256 index) external view returns (address);
/// @notice returns an array of all the gauges
/// @return _gauges the array of gauges
function getAllGauges() external view returns (address[] memory _gauges);
/// @notice returns the length of gauges
function getGaugesLength() external view returns (uint256);
/// @notice returns the gauge at index
function getGauge(uint256 index) external view returns (address);
/// @notice returns an array of all the feeDists
/// @return _feeDistributors the array of feeDists
function getAllFeeDistributors() external view returns (address[] memory _feeDistributors);
/// @notice sets the xShadowRatio default
function setGlobalRatio(uint256 _xRatio) external;
/// @notice whether the token is whitelisted in governance
function isWhitelisted(address _token) external view returns (bool _tf);
/// @notice function for removing malicious or stuffed tokens
function removeFeeDistributorReward(address _feeDist, address _token) external;
/// @notice returns the total votes for a pool in a specific period
/// @param pool the pool address to check
/// @param period the period to check
/// @return votes the total votes for the pool in that period
function poolTotalVotesPerPeriod(address pool, uint256 period) external view returns (uint256 votes);
/// @notice returns the pool address for a given gauge
/// @param gauge address of the gauge
/// @return pool address of the pool
function poolForGauge(address gauge) external view returns (address pool);
/// @notice returns the pool address for a given feeDistributor
/// @param feeDistributor address of the feeDistributor
/// @return pool address of the pool
function poolForFeeDistributor(address feeDistributor) external view returns (address pool);
/// @notice returns the voting power used by a voter for a period
/// @param user address of the user
/// @param period the period to check
function userVotingPowerPerPeriod(address user, uint256 period) external view returns (uint256 votingPower);
/// @notice returns the total votes for a specific period
/// @param period the period to check
/// @return weight the total votes for that period
function totalVotesPerPeriod(uint256 period) external view returns (uint256 weight);
/// @notice returns the total rewards allocated for a specific period
/// @param period the period to check
/// @return amount the total rewards for that period
function totalRewardPerPeriod(uint256 period) external view returns (uint256 amount);
/// @notice returns the last distribution period for a gauge
/// @param _gauge address of the gauge
/// @return period the last period distributions occurred
function lastDistro(address _gauge) external view returns (uint256 period);
/// @notice returns if the gauge is a Cl gauge
/// @param gauge the gauge to check
function isClGauge(address gauge) external view returns (bool);
/// @notice returns if the gauge is a legacy gauge
/// @param gauge the gauge to check
function isLegacyGauge(address gauge) external view returns (bool);
/// @notice sets a new NFP manager
function setNfpManager(address _nfpManager) external;
}