Overview
MNT Balance
MNT Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
CommandCenter
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 800 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/IVoter.sol"; import "./interfaces/IXToken.sol"; import "./interfaces/IPairFactory.sol"; import "./v2/interfaces/pool/IClPoolImmutables.sol"; import "./v2/interfaces/IClPoolFactory.sol"; import "./interfaces/IVotingEscrow.sol"; import "./interfaces/IFeeDistributor.sol"; import "./interfaces/IGauge.sol"; import "./interfaces/IMinter.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol"; import "@openzeppelin/contracts/interfaces/IERC20.sol"; contract CommandCenter is Initializable, AccessControlEnumerableUpgradeable { error InvalidFee(); bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); bytes32 public constant FEE_SETTER_ROLE = keccak256("FEE_SETTER_ROLE"); IXToken public xToken; IVoter public voter; IPairFactory public legacyFactory; IClPoolFactory public factoryCL; uint256 public constant MAX_BPS_LEGACY = 500; //Max fee of 500bps = 5% uint24 public constant MAX_BPS_CL = 100_000; // Max fee of 10% uint256 public constant MAX_LOCK = 126144000; // 4 years address public multisig; address public votingEscrow; address public emissionsToken; address public minter; event feeChangeV1(address _pair, uint256 _newrate); event feeChangeV2(address _pair, uint256 _newrate); event newGlobalVolatileFee(uint256 _newBps); event newGlobalCorrelatedFee(uint256 _newBps); event Rebase(uint256 _veID, uint256 _amount); event AddNewNFT(address _for, uint256 _amount); event VoteIncentives(address[] _pools, uint256[] _amounts); event LPIncentives(address[] _gauge, uint256[] _amount); constructor() { _disableInitializers(); } function initialize( IVoter _voter, IXToken _xToken, address _multisig, address _operator, IPairFactory _legacyFactory, IClPoolFactory _factoryCL ) external initializer { _grantRole(DEFAULT_ADMIN_ROLE, _multisig); _grantRole(OPERATOR_ROLE, _multisig); _grantRole(OPERATOR_ROLE, _operator); voter = _voter; xToken = _xToken; legacyFactory = _legacyFactory; factoryCL = _factoryCL; } function initializeNewVars() external reinitializer(2) { votingEscrow = IVoter(voter)._ve(); emissionsToken = IVoter(voter).base(); multisig = IVoter(voter).governor(); minter = IVoter(voter).minter(); IERC20(emissionsToken).approve(address(xToken), type(uint256).max); } function fixDumbMistake() external reinitializer(3) { IERC20(emissionsToken).approve(votingEscrow, type(uint256).max); } /********************************************** */ // Whitelisting Functions /********************************************** */ /// @notice add an xToken whitelist function whitelistAddress( address _whitelistee ) external onlyRole(OPERATOR_ROLE) { xToken.addWhitelist(_whitelistee); } /// @notice remove an xToken whitelist function removeWhitelistedAddress( address _whitelistee ) external onlyRole(OPERATOR_ROLE) { xToken.removeWhitelist(_whitelistee); } /// @notice whitelist xToken addresses in batches function batchAddWhitelist( address[] calldata _whitelistees ) external onlyRole(OPERATOR_ROLE) { for (uint256 i; i < _whitelistees.length; ++i) { xToken.addWhitelist(_whitelistees[i]); } } /// @notice remove xToken whitelists in batches function batchRemoveWhitelist( address[] calldata _whitelistees ) external onlyRole(OPERATOR_ROLE) { for (uint256 i; i < _whitelistees.length; ++i) { xToken.removeWhitelist(_whitelistees[i]); } } /********************************************** */ // Ratio-Setting Functions /********************************************** */ /// @notice sets the default xTokenRatio function setDefaultRatio( uint256 _xTokenRatio ) external onlyRole(OPERATOR_ROLE) { voter.setXRatio(_xTokenRatio); } /// @notice sets the xTokenRatio of specifics gauges function setGaugeRatios( address[] calldata _gauges, uint256[] calldata _xTokenRatios ) external onlyRole(OPERATOR_ROLE) { voter.setGaugeXRatio(_gauges, _xTokenRatios); } /// @notice set gauge ratios using the pair address function setGaugeRatiosByPair( address[] calldata _pairs, uint256[] calldata _xTokenRatios ) external onlyRole(OPERATOR_ROLE) { require(_pairs.length == _xTokenRatios.length, "len!"); address[] memory _gauges = new address[](_pairs.length); for (uint256 i; i < _pairs.length; i++) { _gauges[i] = voter.gauges(_pairs[i]); } voter.setGaugeXRatio(_gauges, _xTokenRatios); } /// @notice resets the xToken Ratio of specific gauges back to default function resetGaugeRatios( address[] calldata _gauges ) external onlyRole(OPERATOR_ROLE) { voter.resetGaugeXRatio(_gauges); } /// @notice reset xToken ratios back to default by specific pairs function resetRatiosByPair( address[] calldata _pairs ) external onlyRole(OPERATOR_ROLE) { address[] memory _gauges = new address[](_pairs.length); for (uint256 i; i < _pairs.length; ++i) { _gauges[i] = voter.gauges(_pairs[i]); } voter.resetGaugeXRatio(_gauges); } /// @notice reset xToken ratios back to the default through given indices function batchChangeDefaultRatiosByIndex( uint256 startIndex, uint256 endIndex ) external onlyRole(OPERATOR_ROLE) { uint256 len = voter.length(); address[] memory _gauges = new address[](endIndex - startIndex); require(startIndex < len && endIndex <= len, "!R"); uint256 x; for (uint256 i = startIndex; i < endIndex; ++i) { _gauges[x] = voter.gauges(voter.pools(i)); unchecked { ++x; } } voter.resetGaugeXRatio(_gauges); } function alterExitRatios( uint256 _newExitRatio, uint256 _newVeExitRatio ) external onlyRole(OPERATOR_ROLE) { xToken.alterExitRatios(_newExitRatio, _newVeExitRatio); } function reinitializeVestingParameters( uint256 _min, uint256 _max, uint256 _veMax ) external onlyRole(OPERATOR_ROLE) { xToken.reinitializeVestingParameters(_min, _max, _veMax); } function changeMinimumVestingLength( uint256 _minVest ) external onlyRole(OPERATOR_ROLE) { xToken.changeMinimumVestingLength(_minVest); } function changeMaximumVestingLength( uint256 _maxVest ) external onlyRole(OPERATOR_ROLE) { xToken.changeMaximumVestingLength(_maxVest); } function changeVeMaximumVestingLength( uint256 _veMax ) external onlyRole(OPERATOR_ROLE) { xToken.changeVeMaximumVestingLength(_veMax); } /********************************************** */ // Gauge Controller Functions /********************************************** */ function clawBackEmissionsGivenPairs( address[] calldata _pair ) external onlyRole(OPERATOR_ROLE) { voter.clawBackUnusedEmissions(getGaugeArray(_pair)); } function clawBackEmissionsGivenRanges( uint256 _start, uint256 _end ) external onlyRole(OPERATOR_ROLE) { address[] memory _pairs = new address[](_end - _start); uint256 x; for (uint256 i = _start; i < _end; ++i) { _pairs[x] = voter.pools(i); unchecked { x++; } } voter.clawBackUnusedEmissions(getGaugeArray(_pairs)); } /// @notice whitelists a token to be used in gauge creation function whitelistToken(address _token) external onlyRole(OPERATOR_ROLE) { voter.whitelist(_token); } /// @notice forbids a non-supported token from creating a new gauge function forbidToken( address _token, bool _status ) external onlyRole(OPERATOR_ROLE) { voter.forbid(_token, _status); } function killGauge(address _pair) external onlyRole(OPERATOR_ROLE) { voter.killGauge(getGauge(_pair)); } function reviveGauge(address _pair) external onlyRole(OPERATOR_ROLE) { voter.reviveGauge(getGauge(_pair)); } function addInitialRewardPerGauge( address gauge, address token ) external onlyRole(OPERATOR_ROLE) { voter.addInitialRewardPerGauge(gauge, token); } function addClGaugeReward( address pair, address reward ) external onlyRole(OPERATOR_ROLE) { address gauge = getGauge(pair); voter.addClGaugeReward(gauge, reward); } function removeClGaugeReward( address pair, address reward ) external onlyRole(OPERATOR_ROLE) { address gauge = getGauge(pair); voter.removeClGaugeReward(gauge, reward); } /********************************************** */ // Reserve Contract Functionality /********************************************** */ /// @notice accept the candidate position function acceptFeeAccess() external onlyRole(DEFAULT_ADMIN_ROLE) { legacyFactory.acceptFeeManager(); } /// @notice changes the Fee of a V1 pair /// @param _pair is an array of all the V1 pairs that are to be altered /// @param _bps is an array of all the fee variables to adjust the pairs function setFeeLegacy( address[] calldata _pair, uint256[] calldata _bps ) external onlyRole(FEE_SETTER_ROLE) { for (uint256 i = 0; i < _pair.length; ++i) { require((_bps[i] > 0) && (_bps[i] <= MAX_BPS_LEGACY), "!valid"); if (legacyFactory.pairFee(_pair[i]) == _bps[i]) continue; legacyFactory.setPairFee(_pair[i], _bps[i]); emit feeChangeV1(_pair[i], _bps[i]); } } ///@notice sets the default fee split for all new pairs function setFeeSplitDefault( uint8 _feeDist, uint8 _treasury ) external onlyRole(OPERATOR_ROLE) { legacyFactory.setFeeSplit(_feeDist, _treasury); } ///@notice set Pool(s) fee splits individually function setPoolSplit( address[] calldata _pools, uint8[] calldata _feeDist, uint8[] calldata _treasury ) external onlyRole(OPERATOR_ROLE) { require( _pools.length == _feeDist.length && _feeDist.length == _treasury.length, "!L" ); for (uint256 i = 0; i < _pools.length; ++i) { legacyFactory.setPoolFeeSplit(_pools[i], _feeDist[i], _treasury[i]); } } /// @notice sets the uint24 fee variable for each V2 pair in the array /// @param _pair is an array of all the V2 (CL) pairs that are to be changed /// @param _fee is an array of all the fee variables (as uint24) to adjust to function setFeeCL( address[] calldata _pair, uint24[] calldata _fee ) external onlyRole(FEE_SETTER_ROLE) { for (uint256 i = 0; i < _pair.length; ++i) { if (isValidFee(false, _fee[i])) { factoryCL.setFee(_pair[i], _fee[i]); emit feeChangeV2(_pair[i], _fee[i]); } else { revert InvalidFee(); } } } /// @notice Changes the fees of all CorrelatedPairs /// @param _bps is the global fee to change the correlated pairs to function changeDefaultCorrelated( uint256 _bps ) external onlyRole(OPERATOR_ROLE) { if (isValidFee(true, _bps)) { legacyFactory.setFee(true, _bps); emit newGlobalCorrelatedFee(_bps); } else { revert InvalidFee(); } } /// @notice Changes the fees of all volatile pairs /// @param _bps is the global fee to change the volatile pairs to function changeDefaultVolatile( uint256 _bps ) external onlyRole(OPERATOR_ROLE) { if (isValidFee(true, _bps)) { legacyFactory.setFee(false, _bps); emit newGlobalVolatileFee(_bps); } else { revert InvalidFee(); } } /// @notice for altering the addresses of the factories if something was the be upgraded/migrated /// @param _newFactory is the new factory's address function setLegacyFactory( address _newFactory ) external onlyRole(DEFAULT_ADMIN_ROLE) { legacyFactory = IPairFactory(_newFactory); } /// @notice for altering the addresses of the factories if something was the be upgraded/migrated /// @param _newFactory is the new factory's address function setClFactory( address _newFactory ) external onlyRole(DEFAULT_ADMIN_ROLE) { factoryCL = IClPoolFactory(_newFactory); } /********************************************** */ // Getter/Read Functions /********************************************** */ /// @notice checks to ensure this contract has the proper permissions to perform its tasks function isActive() public view returns (bool) { if ( xToken.whitelistOperator() == address(this) && voter.whitelistOperator() == address(this) ) return true; return false; } /// @notice get the xToken ratio for the gauge through the pair function getRatioByPair(address _pair) external view returns (uint256) { return voter.gaugeXRatio(voter.gauges(_pair)); } ///@dev send a direct rebase to an NFT ID function rebase( uint256 _veID, uint256 _amount ) external onlyRole(OPERATOR_ROLE) { IVotingEscrow(votingEscrow).depositFor(_veID, _amount); emit Rebase(_veID, _amount); } ///@dev initiate a new veNFT using amounts in the contract function newLock( uint256 _amount, address _for ) external onlyRole(OPERATOR_ROLE) { IVotingEscrow(votingEscrow).createLockFor(_amount, MAX_LOCK, _for); emit AddNewNFT(_for, _amount); } ///@dev distribute as xRAM voting incentives for a pool function incentivizeVotes( address[] calldata _pools, uint256[] calldata _xTokenAmounts ) external onlyRole(OPERATOR_ROLE) { for (uint256 i = 0; i < _pools.length; ++i) { xToken.convertEmissionsToken(_xTokenAmounts[i]); IFeeDistributor _feeDist = IFeeDistributor( voter.feeDistributors(voter.gauges(_pools[i])) ); IERC20(address(xToken)).approve( address(_feeDist), _xTokenAmounts[i] ); _feeDist.incentivize(address(xToken), _xTokenAmounts[i]); } emit VoteIncentives(_pools, _xTokenAmounts); } ///@dev distribute as xRAM LP incentives for a pool function incentivizePool( address[] calldata _pools, uint256[] calldata _xTokenAmounts ) external onlyRole(OPERATOR_ROLE) { for (uint256 i = 0; i < _pools.length; ++i) { xToken.convertEmissionsToken(_xTokenAmounts[i]); IGauge gauge = IGauge(voter.gauges(_pools[i])); IERC20(address(xToken)).approve(address(gauge), _xTokenAmounts[i]); gauge.notifyRewardAmount(address(xToken), _xTokenAmounts[i]); } emit LPIncentives(_pools, _xTokenAmounts); } function incentivizeVotesNative( address[] calldata _pools, uint256[] calldata _emissionsTokenAmounts ) external onlyRole(OPERATOR_ROLE) { for (uint256 i = 0; i < _pools.length; ++i) { IFeeDistributor _feeDist = IFeeDistributor( voter.feeDistributors(voter.gauges(_pools[i])) ); IERC20(emissionsToken).approve( address(_feeDist), _emissionsTokenAmounts[i] ); _feeDist.incentivize(emissionsToken, _emissionsTokenAmounts[i]); } emit VoteIncentives(_pools, _emissionsTokenAmounts); } function incentivizePoolNative( address[] calldata _pools, uint256[] calldata _emissionsTokenAmounts ) external onlyRole(OPERATOR_ROLE) { for (uint256 i = 0; i < _pools.length; ++i) { IGauge gauge = IGauge(getGauge(_pools[i])); IERC20(emissionsToken).approve( address(gauge), _emissionsTokenAmounts[i] ); gauge.notifyRewardAmount(emissionsToken, _emissionsTokenAmounts[i]); } emit LPIncentives(_pools, _emissionsTokenAmounts); } ///@dev multisig gated call to get the underlying RAM function multisigWithdraw( address token, uint256 amount ) external onlyRole(OPERATOR_ROLE) { IERC20(token).transfer(multisig, amount); } function updateIncentivesSize( uint256 _newSize ) external onlyRole(OPERATOR_ROLE) { IMinter(minter).updateIncentivesSize(_newSize); } function updateFlation(uint256 _newRate) external onlyRole(OPERATOR_ROLE) { IMinter(minter).updateFlation(_newRate); } function updateGrowthCap( uint256 _newGrowth ) external onlyRole(OPERATOR_ROLE) { IMinter(minter).updateGrowthCap(_newGrowth); } function setXRamPriceFeed( bool legacy, address pool ) external onlyRole(OPERATOR_ROLE) { xToken.useLegacyPair(legacy); xToken.setPool(pool); } function getGauge(address _pair) public view returns (address) { return voter.gauges(_pair); } function getGaugeArray( address[] memory _pair ) public view returns (address[] memory gauges) { for (uint256 i = 0; i < _pair.length; ++i) { _pair[i] = getGauge(_pair[i]); } return _pair; } function isValidFee(bool _legacy, uint256 _bps) public pure returns (bool) { if (_legacy) { if (_bps > 0 && _bps <= MAX_BPS_LEGACY) return true; return false; } else { if (_bps > 0 && _bps <= MAX_BPS_CL) return true; } return false; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControlEnumerableUpgradeable.sol"; import "./AccessControlUpgradeable.sol"; import "../utils/structs/EnumerableSetUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers; function __AccessControlEnumerable_init() internal onlyInitializing { } function __AccessControlEnumerable_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } function __AccessControl_init() internal onlyInitializing { } function __AccessControl_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(account), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; import "./math/SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.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 pragma solidity ^0.8.13; interface IFeeDistributor { function initialize(address _voter, address _pairFees) external; function _deposit(uint256 amount, uint256 tokenId) external; function _withdraw(uint256 amount, uint256 tokenId) external; function getRewardForOwner( uint256 tokenId, address[] memory tokens ) external; function notifyRewardAmount(address token, uint256 amount) external; function getRewardTokens() external view returns (address[] memory); function earned( address token, uint256 tokenId ) external view returns (uint256 reward); function incentivize(address token, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IGauge { function initialize( address _stake, address _feeDist, address _ve, address _voter, bool _forPair, address[] memory _initialRewards ) external; function getReward(address account, address[] calldata tokens) external; function claimFees() external returns (uint256 claimed0, uint256 claimed1); function left(address token) external view returns (uint256); function rewardsListLength() external view returns (uint256); function rewardsList() external view returns (address[] memory); function earned( address token, address account ) external view returns (uint256); function balanceOf(address) external view returns (uint256); function derivedBalances(address) external view returns (uint256); function notifyRewardAmount(address token, uint256 amount) external; struct Reward { uint256 rewardRate; uint256 periodFinish; uint256 lastUpdateTime; uint256 rewardPerTokenStored; } function rewardData(address token) external view returns (Reward memory); function addInitialReward(address reward) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "contracts/interfaces/IRewardsDistributor.sol"; interface IMinter { function updatePeriod() external returns (uint256); function activePeriod() external view returns (uint256); function rewardsDistributor() external view returns (IRewardsDistributor); function timelock() external view returns (address); function updateFlation(uint256 _flation) external; function updateGrowthCap(uint256 _newGrowthCap) external; function updateIncentivesSize(uint256 _newGrowth) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13 || =0.7.6; interface IPairFactory { function allPairsLength() external view returns (uint256); function isPair(address pair) external view returns (bool); function pairCodeHash() external view 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 voter() external view returns (address); function allPairs(uint256) external view returns (address); function pairFee(address) external view returns (uint256); function getFee(bool) external view returns (uint256); function isPaused() external view returns (bool); function acceptFeeManager() external; function setFeeManager(address _feeManager) external; function setPairFee(address _pair, uint256 _fee) external; function setFee(bool _stable, uint256 _fee) external; function treasury() external view returns (address); function feeSplit() external view returns (uint8); function getPoolFeeSplit( address _pool ) external view returns (uint8 _poolFeeSplit); function setFeeSplit(uint8 _toFees, uint8 _toTreasury) external; function setPoolFeeSplit( address _pool, uint8 _toFees, uint8 _toTreasury ) external; function getPairFee( address _pair, bool _stable ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IRewardsDistributor { function checkpointToken() external; function checkpointTotalSupply() external; function claimable(uint256 _tokenId) external view returns (uint256); function claim(uint256 _tokenId) external returns (uint256); function claimMany(uint256[] memory _tokenIds) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity =0.7.6 || ^0.8.13; pragma abicoder v2; interface IVoter { function _ve() external view returns (address); function governor() external view returns (address); function emergencyCouncil() external view returns (address); function attachTokenToGauge(uint256 _tokenId, address account) external; function detachTokenFromGauge(uint256 _tokenId, address account) external; function emitDeposit( uint256 _tokenId, address account, uint256 amount ) external; function emitWithdraw( uint256 _tokenId, address account, uint256 amount ) external; function isWhitelisted(address token) external view returns (bool); function notifyRewardAmount(uint256 amount) external; function distribute(address _gauge) external; function gauges(address pool) external view returns (address); function feeDistributors(address gauge) external view returns (address); function gaugefactory() external view returns (address); function feeDistributorFactory() external view returns (address); function minter() external view returns (address); function factory() external view returns (address); function length() external view returns (uint256); function pools(uint256) external view returns (address); function isAlive(address) external view returns (bool); function setXRatio(uint256 _xRatio) external; function setGaugeXRatio( address[] calldata _gauges, uint256[] calldata _xRaRatios ) external; function resetGaugeXRatio(address[] calldata _gauges) external; function whitelist(address _token) external; function forbid(address _token, bool _status) external; function whitelistOperator() external view returns (address); function gaugeXRatio(address gauge) external view returns (uint256); function isGauge(address gauge) external view returns (bool); function killGauge(address _gauge) external; function reviveGauge(address _gauge) external; function stale(uint256 _tokenID) external view returns (bool); function partnerNFT(uint256 _tokenID) external view returns (bool); function addInitialRewardPerGauge(address _gauge, address token) external; function base() external view returns (address); function xToken() external view returns (address); function addClGaugeReward(address gauge, address reward) external; function removeClGaugeReward(address gauge, address reward) external; function clawBackUnusedEmissions(address[] calldata _gauges) external; }
// SPDX-License-Identifier: MIT pragma solidity =0.7.6 || ^0.8.13; pragma abicoder v2; interface IVotingEscrow { struct Point { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block } struct LockedBalance { int128 amount; uint256 end; } function emissionsToken() external view returns (address); function team() external returns (address); function epoch() external view returns (uint256); function pointHistory(uint256 loc) external view returns (Point memory); function userPointHistory( uint256 tokenId, uint256 loc ) external view returns (Point memory); function userPointEpoch(uint256 tokenId) external view returns (uint256); function ownerOf(uint256) external view returns (address); function isApprovedOrOwner(address, uint256) external view returns (bool); function transferFrom(address, address, uint256) external; function voting(uint256 tokenId) external; function abstain(uint256 tokenId) external; function attach(uint256 tokenId) external; function detach(uint256 tokenId) external; function checkpoint() external; function depositFor(uint256 tokenId, uint256 value) external; function createLockFor( uint256, uint256, address ) external returns (uint256); function balanceOfNFT(uint256) external view returns (uint256); function balanceOfNFTAt(uint256, uint256) external view returns (uint256); function totalSupply() external view returns (uint256); function locked__end(uint256) external view returns (uint256); function balanceOf(address) external view returns (uint256); function tokenOfOwnerByIndex( address, uint256 ) external view returns (uint256); function increaseUnlockTime(uint256 tokenID, uint256 duration) external; function locked( uint256 tokenID ) external view returns (uint256 amount, uint256 unlockTime); function increaseAmount(uint256 _tokenId, uint256 _value) external; function isDelegate( address _operator, uint256 _tokenId ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0 <0.9.0; interface IXToken { event CancelVesting( address indexed user, uint256 indexed vestId, uint256 amount ); event ExitVesting( address indexed user, uint256 indexed vestId, uint256 amount ); event InstantExit(address indexed user, uint256); event NewExitRatios(uint256 exitRatio, uint256 veExitRatio); event NewVest( address indexed user, uint256 indexed vestId, uint256 indexed amount ); event NewVestingTimes(uint256 min, uint256 max, uint256 veMaxVest); event Converted(address indexed user, uint256); event WhitelistStatus(address indexed candidate, bool status); event XTokensRedeemed(address indexed user, uint256); function MAXTIME() external view returns (uint256); function PRECISION() external view returns (uint256); function addWhitelist(address _whitelistee) external; function adjustWhitelist( address[] memory _candidates, bool[] memory _status ) external; function alterExitRatios( uint256 _newExitRatio, uint256 _newVeExitRatio ) external; function changeMaximumVestingLength(uint256 _maxVest) external; function changeMinimumVestingLength(uint256 _minVest) external; function changeVeMaximumVestingLength(uint256 _veMax) external; function changeWhitelistOperator(address _newOperator) external; function convertEmissionsToken(uint256 _amount) external; function createVest(uint256 _amount) external; function protocolWhitelist() external view returns (address); function exitRatio() external view returns (uint256); function exitVest(uint256 _vestID, bool _ve) external returns (bool); function getBalanceResiding() external view returns (uint256); function initialize( address _emissionsToken, address _votingEscrow, address _voter, address _timelock, address _multisig, address _whitelistOperator, address _enneadWhitelist ) external; function instantExit(uint256 _amount, uint256 maxPayAmount) external; function isWhitelisted(address) external view returns (bool); function maxVest() external view returns (uint256); function migrateProtocolWhitelist(address _enneadWhitelist) external; function migrateMultisig(address _multisig) external; function migrateTimelock(address _timelock) external; function minVest() external view returns (uint256); function multisig() external view returns (address); function multisigRedeem(uint256 _amount) external; function emissionsToken() external view returns (address); function reinitializeVestingParameters( uint256 _min, uint256 _max, uint256 _veMax ) external; function removeWhitelist(address _whitelistee) external; function rescueTrappedTokens( address[] memory _tokens, uint256[] memory _amounts ) external; function syncAndCheckIsWhitelisted( address _address ) external returns (bool); function timelock() external view returns (address); function usersTotalVests(address _user) external view returns (uint256); function veExitRatio() external view returns (uint256); function veMaxVest() external view returns (uint256); function votingEscrow() external view returns (address); function vestInfo( address user, uint256 ) external view returns (uint256 amount, uint256 start, uint256 maxEnd, uint256 vestID); function voter() external view returns (address); function whitelistOperator() external view returns (address); function xTokenConvertToNft( uint256 _amount ) external returns (uint256 veRaTokenId); function xTokenIncreaseNft(uint256 _amount, uint256 _tokenID) external; function useLegacyPair(bool legacy) external; function setPool(address newPool) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; pragma abicoder v2; /// @title The interface for the CL Factory /// @notice The CL Factory facilitates creation of CL pools and control over the protocol fees interface IClPoolFactory { /// @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 Emitted when pairs implementation is changed /// @param oldImplementation The previous implementation /// @param newImplementation The new implementation event ImplementationChanged( address indexed oldImplementation, address indexed newImplementation ); /// @notice Emitted when the fee collector is changed /// @param oldFeeCollector The previous implementation /// @param newFeeCollector The new implementation event FeeCollectorChanged( address indexed oldFeeCollector, address indexed newFeeCollector ); /// @notice Emitted when the protocol fee is changed /// @param feeProtocol0Old The previous value of the token0 protocol fee /// @param feeProtocol1Old The previous value of the token1 protocol fee /// @param feeProtocol0New The updated value of the token0 protocol fee /// @param feeProtocol1New The updated value of the token1 protocol fee event SetFeeProtocol( uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New ); /// @notice Emitted when the protocol fee is changed /// @param pool The pool address /// @param feeProtocol0Old The previous value of the token0 protocol fee /// @param feeProtocol1Old The previous value of the token1 protocol fee /// @param feeProtocol0New The updated value of the token0 protocol fee /// @param feeProtocol1New The updated value of the token1 protocol fee event SetPoolFeeProtocol( address pool, uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New ); /// @notice Emitted when the feeSetter of the factory is changed /// @param oldSetter The feeSetter before the setter was changed /// @param newSetter The feeSetter after the setter was changed event FeeSetterChanged( address indexed oldSetter, address indexed newSetter ); /// @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 CL NFP Manager function nfpManager() external view returns (address); /// @notice Returns the votingEscrow address function votingEscrow() external view returns (address); /// @notice Returns Voter address function voter() 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 Returns the address of the fee collector contract /// @dev Fee collector decides where the protocol fees go (fee distributor, treasury, etc.) function feeCollector() external view returns (address); /// @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 /// @param sqrtPriceX96 initial sqrtPriceX96 of 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, uint160 sqrtPriceX96 ) 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; /// @notice returns the default protocol fee. function feeProtocol() external view returns (uint8); /// @notice returns the protocol fee for both tokens of a pool. function poolFeeProtocol(address pool) external view returns (uint8); /// @notice Sets the default protocol's % share of the fees /// @param _feeProtocol new default protocol fee for token0 and token1 function setFeeProtocol(uint8 _feeProtocol) external; /// @notice Sets the default protocol's % share of the fees /// @param pool the pool address /// @param feeProtocol0 new protocol fee for token0 of the pool /// @param feeProtocol1 new protocol fee for token1 of the pool function setPoolFeeProtocol( address pool, uint8 feeProtocol0, uint8 feeProtocol1 ) external; /// @notice Sets the fee collector address /// @param _feeCollector the fee collector address function setFeeCollector(address _feeCollector) external; function setFeeSetter(address _newFeeSetter) external; function setFee(address _pool, uint24 _fee) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Pool state that never changes /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values interface IClPoolImmutables { /// @notice The contract that deployed the pool, which must adhere to the IClPoolFactory interface /// @return The contract address function factory() external view returns (address); /// @notice The contract that manages CL NFPs, which must adhere to the INonfungiblePositionManager interface /// @return The contract address function nfpManager() external view returns (address); /// @notice The contract that manages veNFTs, which must adhere to the IVotingEscrow interface /// @return The contract address function votingEscrow() external view returns (address); /// @notice The contract that manages RA votes, which must adhere to the IVoter interface /// @return The contract address function voter() external view returns (address); /// @notice The first of the two tokens of the pool, sorted by address /// @return The token contract address function token0() external view returns (address); /// @notice The second of the two tokens of the pool, sorted by address /// @return The token contract address function token1() external view returns (address); /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 /// @return The fee function fee() external view returns (uint24); /// @notice The pool tick spacing /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... /// This value is an int24 to avoid casting even though it is always positive. /// @return The tick spacing function tickSpacing() external view returns (int24); /// @notice The maximum amount of position liquidity that can use any tick in the range /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool /// @return The max amount of liquidity per tick function maxLiquidityPerTick() external view returns (uint128); /// @notice returns the current fee set for the pool function currentFee() external view returns (uint24); }
{ "optimizer": { "enabled": true, "runs": 800 }, "evmVersion": "paris", "viaIR": true, "metadata": { "bytecodeHash": "none" }, "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":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidFee","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_for","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"AddNewNFT","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"_gauge","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"_amount","type":"uint256[]"}],"name":"LPIncentives","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_veID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Rebase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"_pools","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"VoteIncentives","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newrate","type":"uint256"}],"name":"feeChangeV1","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newrate","type":"uint256"}],"name":"feeChangeV2","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newBps","type":"uint256"}],"name":"newGlobalCorrelatedFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newBps","type":"uint256"}],"name":"newGlobalVolatileFee","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BPS_CL","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BPS_LEGACY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptFeeAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"addClGaugeReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"addInitialRewardPerGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newExitRatio","type":"uint256"},{"internalType":"uint256","name":"_newVeExitRatio","type":"uint256"}],"name":"alterExitRatios","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_whitelistees","type":"address[]"}],"name":"batchAddWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"batchChangeDefaultRatiosByIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_whitelistees","type":"address[]"}],"name":"batchRemoveWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bps","type":"uint256"}],"name":"changeDefaultCorrelated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bps","type":"uint256"}],"name":"changeDefaultVolatile","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxVest","type":"uint256"}],"name":"changeMaximumVestingLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minVest","type":"uint256"}],"name":"changeMinimumVestingLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_veMax","type":"uint256"}],"name":"changeVeMaximumVestingLength","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pair","type":"address[]"}],"name":"clawBackEmissionsGivenPairs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"clawBackEmissionsGivenRanges","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emissionsToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factoryCL","outputs":[{"internalType":"contract IClPoolFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fixDumbMistake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"forbidToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"getGauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pair","type":"address[]"}],"name":"getGaugeArray","outputs":[{"internalType":"address[]","name":"gauges","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"getRatioByPair","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pools","type":"address[]"},{"internalType":"uint256[]","name":"_xTokenAmounts","type":"uint256[]"}],"name":"incentivizePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pools","type":"address[]"},{"internalType":"uint256[]","name":"_emissionsTokenAmounts","type":"uint256[]"}],"name":"incentivizePoolNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pools","type":"address[]"},{"internalType":"uint256[]","name":"_xTokenAmounts","type":"uint256[]"}],"name":"incentivizeVotes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pools","type":"address[]"},{"internalType":"uint256[]","name":"_emissionsTokenAmounts","type":"uint256[]"}],"name":"incentivizeVotesNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IVoter","name":"_voter","type":"address"},{"internalType":"contract IXToken","name":"_xToken","type":"address"},{"internalType":"address","name":"_multisig","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"contract IPairFactory","name":"_legacyFactory","type":"address"},{"internalType":"contract IClPoolFactory","name":"_factoryCL","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initializeNewVars","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_legacy","type":"bool"},{"internalType":"uint256","name":"_bps","type":"uint256"}],"name":"isValidFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"killGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"legacyFactory","outputs":[{"internalType":"contract IPairFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multisig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"multisigWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_for","type":"address"}],"name":"newLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_veID","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_min","type":"uint256"},{"internalType":"uint256","name":"_max","type":"uint256"},{"internalType":"uint256","name":"_veMax","type":"uint256"}],"name":"reinitializeVestingParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"reward","type":"address"}],"name":"removeClGaugeReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_whitelistee","type":"address"}],"name":"removeWhitelistedAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"}],"name":"resetGaugeRatios","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pairs","type":"address[]"}],"name":"resetRatiosByPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"reviveGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newFactory","type":"address"}],"name":"setClFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_xTokenRatio","type":"uint256"}],"name":"setDefaultRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pair","type":"address[]"},{"internalType":"uint24[]","name":"_fee","type":"uint24[]"}],"name":"setFeeCL","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pair","type":"address[]"},{"internalType":"uint256[]","name":"_bps","type":"uint256[]"}],"name":"setFeeLegacy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_feeDist","type":"uint8"},{"internalType":"uint8","name":"_treasury","type":"uint8"}],"name":"setFeeSplitDefault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_gauges","type":"address[]"},{"internalType":"uint256[]","name":"_xTokenRatios","type":"uint256[]"}],"name":"setGaugeRatios","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pairs","type":"address[]"},{"internalType":"uint256[]","name":"_xTokenRatios","type":"uint256[]"}],"name":"setGaugeRatiosByPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newFactory","type":"address"}],"name":"setLegacyFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_pools","type":"address[]"},{"internalType":"uint8[]","name":"_feeDist","type":"uint8[]"},{"internalType":"uint8[]","name":"_treasury","type":"uint8[]"}],"name":"setPoolSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"legacy","type":"bool"},{"internalType":"address","name":"pool","type":"address"}],"name":"setXRamPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRate","type":"uint256"}],"name":"updateFlation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newGrowth","type":"uint256"}],"name":"updateGrowthCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newSize","type":"uint256"}],"name":"updateIncentivesSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"contract IVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingEscrow","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_whitelistee","type":"address"}],"name":"whitelistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"whitelistToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xToken","outputs":[{"internalType":"contract IXToken","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60808060405234620000c6576000549060ff8260081c1662000074575060ff8082160362000038575b6040516141269081620000cc8239f35b60ff90811916176000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a13862000028565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b600080fdfe6080604081815260048036101561001557600080fd5b600092833560e01c90816301ffc9a7146130e25750806304b0133c1461307457838163058ecdb414612fc7575080630754617214612f9f578063088b699e14612f77578381631a980b5a14612f2057508063210ca05d14612ef857806322f3e2d414612edb578063248a9ca314612eb15780632af6303914612dff5780632da5347b14612dd75780632f2ff15d14612d1657806336568abe14612c76578063394bf5bd14612c375780633c0ac8a014612a65578381634156658514612a0057508063430e1c6a1461299a57806343acc3af146128b957806346c96aac146128915780634783c35b146128695780634f2bfe5b146128415783816350d976fc146127cd578163530cd5ab14612768578163536d0e111461270a5750806356ffe7e81461268f5780635eff8aa0146124395780635f635ed014612411578381636247f6f2146123ac5750806364a806cc1461224057806365a5d5f014612221578381636bb4483c14612159575080637284c45b14612008578381637396411914611faa5750806373e3336814611f165780637d6e9d9a14611d0a578381637d8d4b8b14611c535781638d60cd6214611bf5575080639010d07c14611bb45783816390a5701214611b565750806391d1485414611b1057838163953e092f14611ab2578163992a793314611a43575080639d66e323146119615780639d7c169e1461177d578381639e9ecc22146117055781639f06247b14611696578163a13d3e6f1461158757508063a217fddf1461156c578063b1c6f0e91461153b578063b60240771461151d578063b6f26e0614611500578063bef766a714611487578063c7a81b421461134a578063ca15c87314611323578063ca91ed01146112e4578063cc2a9a5b146110f757838163cd3e888d14611099578163ce3419831461103b57508063d1494c3a14610e18578063d212953714610d32578063d547741f14610cf4578063d824f8b614610c29578063d930053b14610b30578063df464a7614610afe57838163e252a4dc14610a9057508063e40a2b011461082657838163e923ffe4146107c857508063e93476831461078d57838163efd9bf921461070b578163f14c131114610680578163f250df621461060f57508063f5b541a6146105d057838163f797eee314610502575063ffea49c61461037157600080fd5b346104fe5760603660031901126104fe5767ffffffffffffffff9181358381116104fa576103a29036908401613150565b93602480358281116104f6576103bb9036908701613150565b9190966044936044359081116104f2576103d89036908901613150565b94906103e2613722565b848314806104e9575b156104c157908a969594939291875b838110610405578880f35b8b886001600160a01b0361043a610435858b61042f61042a838d8860cb54169961362f565b61363f565b9661362f565b613714565b92610449610435868d8961362f565b90833b156104bd578f948f948f95916064948793519889978896636b47cd7960e11b885216908601528d60ff80931690860152168a8401525af180156104b357908a9161049b575b50506001016103fa565b6104a490613222565b6104af578838610491565b8880fd5b8b513d8c823e3d90fd5b8d80fd5b875162461bcd60e51b81526020818b01526002602482015261085360f21b6044820152606490fd5b508585146103eb565b8980fd5b8780fd5b8480fd5b8280fd5b929050346105cc5760203660031901126105cc57813567ffffffffffffffff81116105c7576105349036908401613150565b61053f949194613722565b815b81811061054c578280f35b6001600160a01b038060c954169061056861042a84868b61362f565b90823b156105c35760248692838951958694859363f80f5dd560e01b8552168c8401525af180156105b9579084916105a5575b5050600101610541565b6105ae90613222565b6104fe57823861059b565b85513d86823e3d90fd5b8580fd5b505050fd5b5050fd5b50503461060b578160031936011261060b57602090517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5080fd5b929050346105cc57826003193601126105cc5761062a613967565b6001600160a01b0360cb541691823b156105c757815163f94c53c760e01b81529284918491829084905af190811561067757506106645750f35b61066d90613222565b6106745780f35b80fd5b513d84823e3d90fd5b929050346105cc5760203660031901126105cc57813567ffffffffffffffff81116105c7576106b29036908401613150565b6106bd939193613722565b6001600160a01b0360ca5416803b156105c35760208680946106f887519889968795869463e7264b6560e01b86528501526024840191613344565b03925af190811561067757506106645750f35b929050346105cc57806003193601126105cc576107266131f8565b916107406107326131e2565b9361073b613722565b613663565b926001600160a01b0360ca5416803b156105c35783516377ecdfc960e11b81526001600160a01b0395861693810193845294909116602083015284918491908290849082906040016106f8565b50503461060b578160031936011261060b57602090517fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f881820608152f35b929050346105cc5760203660031901126105cc576107e4613722565b6001600160a01b0360d0541691823b156105c75783926024849284519586938492633a48fff960e21b84528035908401525af190811561067757506106645750f35b50346104fe5761083536613181565b919361083f613722565b865b8581106108815750509061087b917f07863f4e082a43727444dbaa22fa383af1e8bc428560a4c92fa68f5553440ac89551948594856133c7565b0390a180f35b876001600160a01b0360c990808254169161089d85898961362f565b35833b156104fa578b9385809286519283916304ba099d60e21b83528b8301528160249586925af18015610a66578c878d938a93610a70575b505061042a8693926108ed928560ca54169461362f565b865163b9a09fd560e01b8152921689830152602092839183919082905afa908115610a665787958a8c898c6109388a610969988a988591610a39575b50169b8c948c8c54169661362f565b3594519687958694859363095ea7b360e01b85528401602090939291936001600160a01b0360408201951681520152565b03925af18015610a2f57610a01575b5050541661098784888861362f565b35823b156109fd576109c6928492838d5180968195829463b66503cf60e01b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f3576109df575b5050600101610841565b6109e890613222565b6104f65787386109d5565b89513d84823e3d90fd5b8380fd5b81610a2092903d10610a28575b610a188183613268565b810190613617565b503880610978565b503d610a0e565b8d513d88823e3d90fd5b610a599150893d8b11610a5f575b610a518183613268565b8101906133f1565b38610929565b503d610a47565b85513d88823e3d90fd5b925093965050610a809150613222565b6109fd578a9289868c87386108d6565b929050346105cc5760603660031901126105cc57610aac613722565b6001600160a01b0360c9541691823b156105c75783926064849284519586938492633894a93760e21b8452803590840152602435602484015260443560448401525af190811561067757506106645750f35b50503461060b578060031936011261060b57602090610b27610b1e613335565b602435906136fc565b90519015158152f35b5091903461060b57610b41366131cc565b610b4c949194613722565b610b5e610b5986836134e1565b613504565b908495906001600160a01b038060ca5416975b828410610bb65787808a8989610b868a613560565b833b156104fa576106f893602086809486519788958694859363525ac10360e11b855284015260248301906132f8565b86516315895f4760e31b815286810185905260209081816024818e5afa918215610c1f57916001939184938c92610c02575b505084610bf5838a613536565b9116905201930192610b71565b610c189250803d10610a5f57610a518183613268565b3880610be8565b89513d8c823e3d90fd5b5090346104fe5760203660031901126104fe57813591610c47613722565b610c50836136ba565b15610ce65783906001600160a01b0360cb541690813b156104fe57600160448492838751958694859363387ddad160e21b85528401528960248401525af18015610cdc57610cc8575b50507fa2fc94ed8ceee756ec75a07ca0d8f3b9918372930efd43ef20de9d3ee6f5ad239160209151908152a180f35b610cd190613222565b6104fe578238610c99565b83513d84823e3d90fd5b90516358d620b360e01b8152fd5b5090346104fe57806003193601126104fe57610d2f9135610d2a6001610d186131e2565b93838752606560205286200154613be5565b613dbc565b80f35b50346104fe57826003193601126104fe57610103835460ff8160081c161580610e0b575b610d5f906135a5565b61ffff191617835560206001600160a01b039160448360cf54169360ce541691868651958694859363095ea7b360e01b855284015260001960248401525af18015610dff57916020917f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249893610de2575b50835461ff00191684555160038152a180f35b610df890833d8511610a2857610a188183613268565b5038610dcf565b505051903d90823e3d90fd5b50600360ff821610610d56565b50346104fe57610e2736613181565b9193610e31613722565b865b858110610e6d5750509061087b917fd402dbc146639547cb1f2290e713e99e8a2200d1c7fa294b5d198e20496b7c4d9551948594856133c7565b876001600160a01b0360c9908082541691610e8985898961362f565b35833b156104fa578b9385809286519283916304ba099d60e21b83528b8301528160249586925af18015610a66578c878d938a9361101b575b5050610ed79161042a918760ca54169461362f565b855163b9a09fd560e01b8152908516898201526020929083818381865afa91821561101157849287928a91610ff4575b50885194859384926324f24ba560e11b8452168d8301525afa908115610a665787958a8c898c6109388a610f4c988a988591610a395750169b8c948c8c54169661362f565b03925af18015610a2f57610fd6575b50505416610f6a84888861362f565b35823b156109fd57610fa9928492838d51809681958294637c8afcc160e11b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f357610fc2575b5050600101610e33565b610fcb90613222565b6104f6578738610fb8565b81610fec92903d10610a2857610a188183613268565b503880610f5b565b61100b9150843d8611610a5f57610a518183613268565b38610f07565b87513d8a823e3d90fd5b92509396505061102b9150613222565b6109fd578a9289868c8738610ec2565b929050346105cc5760203660031901126105cc57611057613722565b6001600160a01b0360ca541691823b156105c7578392602484928451958693849263e5bc3de160e01b84528035908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc576110b5613722565b6001600160a01b0360c9541691823b156105c7578392602484928451958693849263cd3e888d60e01b84528035908401525af190811561067757506106645750f35b50346104fe5760c03660031901126104fe57356001600160a01b03908181168091036109fd57602435918083168093036104fa5760443591818316938484036112df576064359083821682036112df578794608435928584168094036112db5760a4359586168096036112db576111e56111ea926111df8b9a8a5460ff8160081c16159b8c809d6112ce575b80156112b7575b611193906135a5565b60ff198281166001178255918d6112a5575b5050600080526020809d606582528060002084600052825260ff81600020541615611256575b5050506000805260978c528c600020613f9f565b50613cf8565b613cf8565b6001600160a01b0319928360ca54161760ca558260c954161760c9558160cb54161760cb5560cc54161760cc5561121f578280f35b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989161ff001984541684555160018152a138808280f35b60019160008052606581528160002090856000525260002091825416179055338160007f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4388c8e6111cb565b61ffff19166101011790558e386111a5565b50303b15801561118a575060ff821660011461118a565b50600160ff831610611183565b8680fd5b600080fd5b8334610674576020366003190112610674576001600160a01b036113066131f8565b61130e613967565b166001600160a01b031960cc54161760cc5580f35b50346104fe5760203660031901126104fe5760209282913581526097845220549051908152f35b5082903461060b5761135b36613181565b959261136994929194613722565b86820361145d5790859661137c82613504565b9287926001600160a01b03908160ca5416945b8181106113df5750505050813b156112db578680946106f86113cd98889485519a8b98899788966360339aa560e11b885287015260448601906132f8565b8481036003190160248601529161338a565b6113ed61042a82848761362f565b895163b9a09fd560e01b81529084168982015260209081816024818b5afa918215611453579060019392918e92611436575b50508461142c838b613536565b911690520161138f565b61144c9250803d10610a5f57610a518183613268565b8e8061141f565b8b513d8f823e3d90fd5b835162461bcd60e51b815260208185015260248101849052636c656e2160e01b6044820152606490fd5b50346104fe57816003193601126104fe576114a06131f8565b916024358015158091036112df5784936114b8613722565b6001600160a01b03908160ca541690813b156112db578660449281958751988996879563de7d72e560e01b8752169085015260248401525af190811561067757506106645750f35b50503461060b578160031936011261060b57602090516101f48152f35b50503461060b578160031936011261060b5760209051620186a08152f35b50503461060b57602036600319011261060b576020906001600160a01b0361156461073b6131f8565b915191168152f35b50503461060b578160031936011261060b5751908152602090f35b929050346105cc5760209160206003193601126105c757803567ffffffffffffffff81116104fa576115bc9036908301613150565b906115c5613722565b6115ce82613504565b9186956001600160a01b03918260ca5416975b81811061161d575050505050833b156104fa576106f893602086809486519788958694859363e7264b6560e01b855284015260248301906132f8565b61162b61042a82848861362f565b885163b9a09fd560e01b81529085168882015283816024818d5afa90811561168c5790600192918c9161166f575b5085611665838a613536565b91169052016115e1565b6116869150853d8711610a5f57610a518183613268565b38611659565b89513d8d823e3d90fd5b929050346105cc5760203660031901126105cc576116b26131f8565b6116ba613722565b6001600160a01b036116d08160ca541692613663565b91803b156105c35785928360249286519788958694639f06247b60e01b865216908401525af190811561067757506106645750f35b929050346105cc57806003193601126105cc576117206131f8565b916117296131e2565b611731613722565b6001600160a01b0360ca5416803b156105c3578351634f4f661160e11b81526001600160a01b0395861693810193845294909116602083015284918491908290849082906040016106f8565b50346104fe5761178c36613181565b9193611796613722565b865b8581106117d25750509061087b917fd402dbc146639547cb1f2290e713e99e8a2200d1c7fa294b5d198e20496b7c4d9551948594856133c7565b876001600160a01b038060ca5416906117ef61042a858b8b61362f565b8a5163b9a09fd560e01b815290821686820152602092908b90602485828281875afa801561195757869386938992611938575b505194859384926324f24ba560e11b8452168b8301525afa90811561192e57889183918691611911575b501692611869818d8a87898c6109388d60cf9a8c8c54169661362f565b03925af18015610a2f576118f3575b5050541661188784888861362f565b35823b156109fd576118c6928492838d51809681958294637c8afcc160e11b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f3576118df575b5050600101611798565b6118e890613222565b6104f65787386118d5565b8161190992903d10610a2857610a188183613268565b503880611878565b6119289150853d8711610a5f57610a518183613268565b3861184c565b8b513d86823e3d90fd5b611950919250853d8711610a5f57610a518183613268565b9038611822565b83513d89823e3d90fd5b5091903461060b57602092836003193601126104fe5761197f6131f8565b60ca54835163b9a09fd560e01b81526001600160a01b03928316848201529082168682602481845afa918215610a6657916024918894938892611a24575b5086519586948593630e4bf54360e01b855216908301525afa928315611a1957926119ea575b5051908152f35b9091508281813d8311611a12575b611a028183613268565b810103126112df575190386119e3565b503d6119f8565b8251903d90823e3d90fd5b611a3c919250853d8711610a5f57610a518183613268565b90386119bd565b929050346105cc5760203660031901126105cc57611a5f6131f8565b611a67613722565b6001600160a01b03611a7d8160ca541692613663565b91803b156105c3578592836024928651978895869463992a793360e01b865216908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc57611ace613722565b6001600160a01b0360d0541691823b156105c7578392602484928451958693849263953e092f60e01b84528035908401525af190811561067757506106645750f35b50346104fe57816003193601126104fe576001600160a01b0382602094611b356131e2565b9335815260658652209116600052825260ff81600020541690519015158152f35b929050346105cc57611b67366131cc565b9290611b71613722565b6001600160a01b0360c95416803b156105c35785928360449286519788958694634852b80960e11b865285015260248401525af190811561067757506106645750f35b50346104fe57816003193601126104fe57611be66020936001600160a01b039235815260978552836024359120613e66565b92905490519260031b1c168152f35b929050346105cc5760203660031901126105cc57611c11613722565b6001600160a01b0360c9541691823b156105c757839260248492845195869384926346b066b160e11b84528035908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc57813567ffffffffffffffff81116105c757611c859036908401613150565b611c90949194613722565b815b818110611c9d578280f35b6001600160a01b038060c9541690611cb961042a84868b61362f565b90823b156105c3576024869283895195869485936378c8cda760e01b8552168c8401525af180156105b957908491611cf6575b5050600101611c92565b611cff90613222565b6104fe578238611cec565b50346104fe57611d1936613181565b919092611d24613a94565b865b828110611d31578780f35b611d3c81858761362f565b35151580611eff575b15611ebc57876001600160a01b038060cb541690611d6761042a85888861362f565b8a5163841fa66b60e01b81529116898201526020908181602481865afa91821561192e578492611e8b575b5050611d9f84888a61362f565b3514611e8157611db361042a84878761362f565b611dbe84888a61362f565b35823b156109fd57611dfe928492838c8e519687958694859363a93a897d60e01b85528401602090939291936001600160a01b0360408201951681520152565b03925af180156109f357611e6d575b5050807faad33d2acde4329b1c27ca0561954b24793925d0c7e22dc9711ff66a6beffe23611e4161042a600194878761362f565b611e4c83888a61362f565b8a516001600160a01b03929092168252356020820152604090a15b01611d26565b611e7690613222565b6104f6578738611e0d565b5050600190611e67565b8194508092503d8311611eb5575b611ea38183613268565b810103126112df578991513880611d92565b503d611e99565b865162461bcd60e51b8152602081880152600660248201527f2176616c696400000000000000000000000000000000000000000000000000006044820152606490fd5b506101f4611f0e82868861362f565b351115611d45565b5090346104fe57806003193601126104fe576020611f7992611f366131f8565b611f3e613722565b60cd54845163a9059cbb60e01b81526001600160a01b0391821693810193845260243560208501529586938492899290918491604090910190565b0393165af19081156106775750611f8e575080f35b611fa69060203d602011610a2857610a188183613268565b5080f35b929050346105cc5760203660031901126105cc57611fc6613722565b6001600160a01b0360d0541691823b156105c75783926024849284519586938492637396411960e01b84528035908401525af190811561067757506106645750f35b50346104fe5761201736613181565b90929391612023613a94565b865b818110612030578780f35b62ffffff906120528261204c61204784888b61362f565b613653565b166136db565b15612149576001600160a01b038060cc541661207261042a84878c61362f565b918b612082612047868a8d61362f565b93833b1561060b578c5163ba364c3d60e01b8152908316818b015293861660248501528b939281908490604490829084905af192831561213d578b899289928d9661211b575b5050612047876001999461042f61042a837f3b972fda5270142c6b6ba50a6e54a6b1859fee77b92de18244f39c96958ffa0d9b9a99976121079761362f565b90845193168352166020820152a101612025565b93509450505061212c919350613222565b6104f25786899186868b8e386120c8565b508351903d90823e3d90fd5b87516358d620b360e01b81528590fd5b929050346105cc57806003193601126105cc57612174613335565b61217c6131e2565b90612185613722565b6001600160a01b03908160c9541690813b156112db5786916024839287519485938492633e4ed1dd60e21b845215158b8401525af1801561221757908691612203575b50508060c95416803b156105c3578592836024928651978895869463221b8a9560e11b865216908401525af190811561067757506106645750f35b61220c90613222565b6104fa5784386121c8565b84513d88823e3d90fd5b50503461060b578160031936011261060b5760209051630784ce008152f35b50346104fe5761224f36613181565b9193612259613722565b865b8581106122955750509061087b917f07863f4e082a43727444dbaa22fa383af1e8bc428560a4c92fa68f5553440ac89551948594856133c7565b878387868a84876123048c6122ba61073b61042a8c6001600160a01b039a8b9561362f565b169687946122cf8b60cf988a8a54169461362f565b35905194858094819363095ea7b360e01b83526020998a988401602090939291936001600160a01b0360408201951681520152565b03925af18015610a2f5761238e575b5050541661232284888861362f565b35823b156109fd57612361928492838d5180968195829463b66503cf60e01b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f35761237a575b505060010161225b565b61238390613222565b6104f6578738612370565b816123a492903d10610a2857610a188183613268565b503880612313565b929050346105cc5760203660031901126105cc576123c86131f8565b6123d0613722565b6001600160a01b038060ca5416803b156105c35785928360249286519788958694634d8c928d60e11b865216908401525af190811561067757506106645750f35b50503461060b578160031936011261060b576020906001600160a01b0360cc54169051908152f35b5090346104fe57826003193601126104fe57610102835460ff8160081c161580612682575b612467906135a5565b61ffff191617835560ca548151638dd598fb60e01b81526001600160a01b0391821693602093928690858484818a5afa938415612678578294612659575b50806001600160a01b031994168460ce54161760ce558451635001f3b560e01b8152868185818b5afa90811561264f579082918491612632575b50169360cf549785828a161760cf55865163030d028960e21b815288818781855afa9081156126285791848a928894889161260b575b50168460cd54161760cd558851928380926303aa30b960e11b82525afa90811561260157918389979694928694604497916125e4575b50169060d054161760d05560c9541693818751998a96879563095ea7b360e01b8752860152600019602486015216175af19283156125da577f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498936125bd575b50835461ff00191684555160028152a180f35b6125d390833d8511610a2857610a188183613268565b50386125aa565b81513d86823e3d90fd5b6125fb9150893d8b11610a5f57610a518183613268565b3861254b565b87513d86823e3d90fd5b6126229150843d8611610a5f57610a518183613268565b38612515565b88513d87823e3d90fd5b6126499150883d8a11610a5f57610a518183613268565b386124df565b86513d85823e3d90fd5b612671919450863d8811610a5f57610a518183613268565b92386124a5565b85513d84823e3d90fd5b50600260ff82161061245e565b50346104fe57816003193601126104fe5780359160ff83168093036112df576024359160ff83168093036112df5784936126c7613722565b6001600160a01b0360cb5416803b156105c35785928360449286519788958694631cb8e3a760e01b865285015260248401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc57612726613722565b6001600160a01b0360c9541691823b156105c7578392602484928451958693849263536d0e1160e01b84528035908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc576127846131f8565b61278c613722565b6001600160a01b038060c95416803b156105c357859283602492865197889586946378c8cda760e01b865216908401525af190811561067757506106645750f35b929050346105cc57806003193601126105cc576127e86131f8565b916127f46107326131e2565b926001600160a01b0360ca5416803b156105c35783516314365dbf60e21b81526001600160a01b0395861693810193845294909116602083015284918491908290849082906040016106f8565b50503461060b578160031936011261060b576020906001600160a01b0360ce54169051908152f35b50503461060b578160031936011261060b576020906001600160a01b0360cd54169051908152f35b50503461060b578160031936011261060b576020906001600160a01b0360ca54169051908152f35b50346104fe57816003193601126104fe578035906128d56131e2565b906128de613722565b60208360646001600160a01b0393888560ce54168951968795869463ec32e6df60e01b8652850152630784ce006024850152881660448401525af1801561299057612965575b5091516001600160a01b03909216825260208201527fc0252bbdefb2e33bb149dde65e2f203f2957aef3cf2c77917b57823f9c4963d890806040810161087b565b602090813d8311612989575b61297b8183613268565b810103126112df5738612924565b503d612971565b84513d87823e3d90fd5b5091346106745760203660031901126106745782359067ffffffffffffffff8211610674573660238301121561067457506129e46129fc938260246129e9943693013591016132a2565b613560565b90519182916020835260208301906132f8565b0390f35b929050346105cc5760203660031901126105cc57612a1c6131f8565b612a24613722565b6001600160a01b038060c95416803b156105c3578592836024928651978895869463f80f5dd560e01b865216908401525af190811561067757506106645750f35b5091903461060b57612a76366131cc565b919093612a81613722565b6001600160a01b03928360ca5416835191630fbdb69960e11b835260209586848681865afa938415612c2d578894612bfe575b50612ac2610b598a846134e1565b93808a109081612bf3575b5015612bcb57875b828a10612b1057505050859650803b156105c3576106f89486809486519788958694859363e7264b6560e01b855284015260248301906132f8565b86516315895f4760e31b81528681018b9052602489828281895afa91821561168c57918a9185938d92612bac575b508a5193849263b9a09fd560e01b8452168a83015281885afa908115612ba257916001929183928c91612b85575b5084612b78838a613536565b9116905201990198612ad5565b612b9c91508b3d8d11610a5f57610a518183613268565b38612b6c565b88513d8c823e3d90fd5b612bc4919250833d8511610a5f57610a518183613268565b9038612b3e565b855162461bcd60e51b8152808601889052600260248201526110a960f11b6044820152606490fd5b905082111538612acd565b9093508681813d8311612c26575b612c168183613268565b810103126112df57519238612ab4565b503d612c0c565b86513d8a823e3d90fd5b8334610674576020366003190112610674576001600160a01b03612c596131f8565b612c61613967565b166001600160a01b031960cb54161760cb5580f35b5082903461060b578260031936011261060b57612c916131e2565b90336001600160a01b03831603612cad5790610d2f9135613dbc565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b5090346104fe57806003193601126104fe57611fa69135906097612d386131e2565b9280865260209060658252612d5260018589200154613be5565b80600052606582526001600160a01b038460002095169485600052825260ff84600020541615612d89575b60005252600020613f9f565b80600052606582528360002085600052825283600020600160ff198254161790553385827f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d600080a4612d7d565b50503461060b578160031936011261060b576020906001600160a01b0360cb54169051908152f35b5090346104fe5760203660031901126104fe57813591612e1d613722565b612e26836136ba565b15610ce65783906001600160a01b0360cb541690813b156104fe578260448192828751958694859363387ddad160e21b85528401528960248401525af18015610cdc57612e9d575b50507f09c7e5889341a30b241ed708718f55daa0607a3441916ac8139fa2b641e58e999160209151908152a180f35b612ea690613222565b6104fe578238612e6e565b50346104fe5760203660031901126104fe5781602093600192358152606585522001549051908152f35b50503461060b578160031936011261060b57602090610b27613410565b50503461060b578160031936011261060b576020906001600160a01b0360cf54169051908152f35b929050346105cc5760203660031901126105cc5781359167ffffffffffffffff83116105c757610b86612f596129e49436908401613150565b9490612f63613722565b6001600160a01b0360ca54169536916132a2565b50503461060b578160031936011261060b576020906001600160a01b0360c954169051908152f35b50503461060b578160031936011261060b576020906001600160a01b0360d054169051908152f35b808484346105cc57612fd8366131cc565b939091612fe3613722565b6001600160a01b0360ce541690813b156104fe578360448492838851958694859363076426ed60e11b85528401528a60248401525af1801561306a57613056575b50507f11c6bf55864ff83827df712625d7a80e5583eef0264921025e7cd22003a215119282519182526020820152a180f35b61305f90613222565b6109fd578385613024565b84513d84823e3d90fd5b5090346104fe578261308536613181565b6130929692939196613722565b6001600160a01b0360ca541692833b156105c3576130c586928851998a97889687956360339aa560e11b875286016133c7565b03925af190811561067757506130d9575080f35b610d2f90613222565b925050346104fe5760203660031901126104fe573563ffffffff60e01b81168091036104fe5760209250635a05180f60e01b8114908115613125575b5015158152f35b637965db0b60e01b81149150811561313f575b503861311e565b6301ffc9a760e01b14905038613138565b9181601f840112156112df5782359167ffffffffffffffff83116112df576020808501948460051b0101116112df57565b60406003198201126112df5767ffffffffffffffff916004358381116112df57826131ae91600401613150565b939093926024359182116112df576131c891600401613150565b9091565b60409060031901126112df576004359060243590565b602435906001600160a01b03821682036112df57565b600435906001600160a01b03821682036112df57565b35906001600160a01b03821682036112df57565b67ffffffffffffffff811161323657604052565b634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761323657604052565b90601f8019910116810190811067ffffffffffffffff82111761323657604052565b67ffffffffffffffff81116132365760051b60200190565b92916132ad8261328a565b916132bb6040519384613268565b829481845260208094019160051b81019283116112df57905b8282106132e15750505050565b8380916132ed8461320e565b8152019101906132d4565b90815180825260208080930193019160005b828110613318575050505090565b83516001600160a01b03168552938101939281019260010161330a565b6004359081151582036112df57565b91908082526020809201929160005b828110613361575050505090565b9091929382806001926001600160a01b0361337b8961320e565b16815201950193929101613353565b90918281527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83116112df5760209260051b809284830137010190565b92906133e0906133ee9593604086526040860191613344565b92602081850391015261338a565b90565b908160209103126112df57516001600160a01b03811681036112df5790565b6001600160a01b038060c954169060405190816322621bc160e11b9384825281600460209586935afa9081156134b8576000916134c4575b50811630149283613465575b50505061346057600090565b600190565b90918093508260ca54169160046040518094819382525afa9283156134b857600093613499575b5050163014388080613454565b6134b0929350803d10610a5f57610a518183613268565b90388061348c565b6040513d6000823e3d90fd5b6134db9150833d8511610a5f57610a518183613268565b38613448565b919082039182116134ee57565b634e487b7160e01b600052601160045260246000fd5b9061350e8261328a565b61351b6040519182613268565b828152809261352c601f199161328a565b0190602036910137565b805182101561354a5760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b60005b81518110156135a1576001906001600160a01b0361358c816135858487613536565b5116613663565b906135978386613536565b9116905201613563565b5090565b156135ac57565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608490fd5b908160209103126112df575180151581036112df5790565b919081101561354a5760051b0190565b356001600160a01b03811681036112df5790565b3562ffffff811681036112df5790565b60206001600160a01b0360248160ca541693604051948593849263b9a09fd560e01b84521660048301525afa9081156134b8576000916136a1575090565b6133ee915060203d602011610a5f57610a518183613268565b80151590816136ce575b5061346057600090565b6101f491501115386136c4565b80151590816136ee575061346057600090565b620186a091501115386136c4565b156136db5780151590816136ce575061346057600090565b3560ff811681036112df5790565b3360009081527fbdd154b7c599a43e8b8410b62e84571cd69a79e95c9fc5b630a687cb7c97edf96020908152604080832054909291907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff16156137885750505050565b61379133613e8f565b9084519061379e8261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b8183116138e5575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b8401917f206973206d697373696e6720726f6c6520000000000000000000000000000000603784015251809386840190613e43565b01036028810189520187613268565b5194859362461bcd60e51b8552600485015251809281602486015285850190613e43565b601f01601f19168101030190fd5b60648386519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a6139158587613e7e565b5360041c92801561392b576000190191906137d0565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b3360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b60209081526040808320549092919060ff16156139aa57505050565b6139b333613e8f565b8351836139bf8261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b818311613a4e575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a613a7e8587613e7e565b5360041c92801561392b576000190191906139f1565b3360009081527fb8856e02d8db4f86d5561f04ba0fd00f302915fcd46f5dd1dd5d4c6dc0a5aabb6020908152604080832054909291907fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f881820609060ff1615613afa5750505050565b613b0333613e8f565b90845190613b108261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b818311613b9f575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a613bcf8587613e7e565b5360041c92801561392b57600019019190613b42565b6000818152602060658152604092838320338452825260ff848420541615613c0d5750505050565b613c1633613e8f565b90845190613c238261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b818311613cb2575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a613ce28587613e7e565b5360041c92801561392b57600019019190613c55565b6001600160a01b031660008181527fbdd154b7c599a43e8b8410b62e84571cd69a79e95c9fc5b630a687cb7c97edf9602052604080822054613d6e9392907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff1615613d71575b8152609760205220613f9f565b50565b8082526065602052828220848352602052828220600160ff198254161790553384827f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8580a4613d61565b906040613d6e9260009080825260656020526001600160a01b0383832094169384835260205260ff8383205416613dfb575b8152609760205220614029565b808252606560205282822084835260205282822060ff1981541690553384827ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b8580a4613dee565b60005b838110613e565750506000910152565b8181015183820152602001613e46565b805482101561354a5760005260206000200190600090565b90815181101561354a570160200190565b604051906060820182811067ffffffffffffffff82111761323657604052602a825260208201604036823782511561354a576030905381516001906001101561354a57607860218401536029905b808211613f31575050613eed5790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015613f8a576f181899199a1a9b1b9c1cb0b131b232b360811b901a613f608486613e7e565b5360041c918015613f75576000190190613edd565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b91906001830160009082825280602052604082205415600014614023578454946801000000000000000086101561400f5783613fff613fe8886001604098999a01855584613e66565b819391549060031b91821b91600019901b19161790565b9055549382526020522055600190565b634e487b7160e01b83526041600452602483fd5b50925050565b9060018201906000928184528260205260408420549081151560001461411257600019918083018181116140fe578254908482019182116140ea578082036140b5575b505050805480156140a1578201916140848383613e66565b909182549160031b1b191690555582526020526040812055600190565b634e487b7160e01b86526031600452602486fd5b6140d56140c5613fe89386613e66565b90549060031b1c92839286613e66565b9055865284602052604086205538808061406c565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b87526011600452602487fd5b505050509056fea164736f6c6343000816000a
Deployed Bytecode
0x6080604081815260048036101561001557600080fd5b600092833560e01c90816301ffc9a7146130e25750806304b0133c1461307457838163058ecdb414612fc7575080630754617214612f9f578063088b699e14612f77578381631a980b5a14612f2057508063210ca05d14612ef857806322f3e2d414612edb578063248a9ca314612eb15780632af6303914612dff5780632da5347b14612dd75780632f2ff15d14612d1657806336568abe14612c76578063394bf5bd14612c375780633c0ac8a014612a65578381634156658514612a0057508063430e1c6a1461299a57806343acc3af146128b957806346c96aac146128915780634783c35b146128695780634f2bfe5b146128415783816350d976fc146127cd578163530cd5ab14612768578163536d0e111461270a5750806356ffe7e81461268f5780635eff8aa0146124395780635f635ed014612411578381636247f6f2146123ac5750806364a806cc1461224057806365a5d5f014612221578381636bb4483c14612159575080637284c45b14612008578381637396411914611faa5750806373e3336814611f165780637d6e9d9a14611d0a578381637d8d4b8b14611c535781638d60cd6214611bf5575080639010d07c14611bb45783816390a5701214611b565750806391d1485414611b1057838163953e092f14611ab2578163992a793314611a43575080639d66e323146119615780639d7c169e1461177d578381639e9ecc22146117055781639f06247b14611696578163a13d3e6f1461158757508063a217fddf1461156c578063b1c6f0e91461153b578063b60240771461151d578063b6f26e0614611500578063bef766a714611487578063c7a81b421461134a578063ca15c87314611323578063ca91ed01146112e4578063cc2a9a5b146110f757838163cd3e888d14611099578163ce3419831461103b57508063d1494c3a14610e18578063d212953714610d32578063d547741f14610cf4578063d824f8b614610c29578063d930053b14610b30578063df464a7614610afe57838163e252a4dc14610a9057508063e40a2b011461082657838163e923ffe4146107c857508063e93476831461078d57838163efd9bf921461070b578163f14c131114610680578163f250df621461060f57508063f5b541a6146105d057838163f797eee314610502575063ffea49c61461037157600080fd5b346104fe5760603660031901126104fe5767ffffffffffffffff9181358381116104fa576103a29036908401613150565b93602480358281116104f6576103bb9036908701613150565b9190966044936044359081116104f2576103d89036908901613150565b94906103e2613722565b848314806104e9575b156104c157908a969594939291875b838110610405578880f35b8b886001600160a01b0361043a610435858b61042f61042a838d8860cb54169961362f565b61363f565b9661362f565b613714565b92610449610435868d8961362f565b90833b156104bd578f948f948f95916064948793519889978896636b47cd7960e11b885216908601528d60ff80931690860152168a8401525af180156104b357908a9161049b575b50506001016103fa565b6104a490613222565b6104af578838610491565b8880fd5b8b513d8c823e3d90fd5b8d80fd5b875162461bcd60e51b81526020818b01526002602482015261085360f21b6044820152606490fd5b508585146103eb565b8980fd5b8780fd5b8480fd5b8280fd5b929050346105cc5760203660031901126105cc57813567ffffffffffffffff81116105c7576105349036908401613150565b61053f949194613722565b815b81811061054c578280f35b6001600160a01b038060c954169061056861042a84868b61362f565b90823b156105c35760248692838951958694859363f80f5dd560e01b8552168c8401525af180156105b9579084916105a5575b5050600101610541565b6105ae90613222565b6104fe57823861059b565b85513d86823e3d90fd5b8580fd5b505050fd5b5050fd5b50503461060b578160031936011261060b57602090517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5080fd5b929050346105cc57826003193601126105cc5761062a613967565b6001600160a01b0360cb541691823b156105c757815163f94c53c760e01b81529284918491829084905af190811561067757506106645750f35b61066d90613222565b6106745780f35b80fd5b513d84823e3d90fd5b929050346105cc5760203660031901126105cc57813567ffffffffffffffff81116105c7576106b29036908401613150565b6106bd939193613722565b6001600160a01b0360ca5416803b156105c35760208680946106f887519889968795869463e7264b6560e01b86528501526024840191613344565b03925af190811561067757506106645750f35b929050346105cc57806003193601126105cc576107266131f8565b916107406107326131e2565b9361073b613722565b613663565b926001600160a01b0360ca5416803b156105c35783516377ecdfc960e11b81526001600160a01b0395861693810193845294909116602083015284918491908290849082906040016106f8565b50503461060b578160031936011261060b57602090517fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f881820608152f35b929050346105cc5760203660031901126105cc576107e4613722565b6001600160a01b0360d0541691823b156105c75783926024849284519586938492633a48fff960e21b84528035908401525af190811561067757506106645750f35b50346104fe5761083536613181565b919361083f613722565b865b8581106108815750509061087b917f07863f4e082a43727444dbaa22fa383af1e8bc428560a4c92fa68f5553440ac89551948594856133c7565b0390a180f35b876001600160a01b0360c990808254169161089d85898961362f565b35833b156104fa578b9385809286519283916304ba099d60e21b83528b8301528160249586925af18015610a66578c878d938a93610a70575b505061042a8693926108ed928560ca54169461362f565b865163b9a09fd560e01b8152921689830152602092839183919082905afa908115610a665787958a8c898c6109388a610969988a988591610a39575b50169b8c948c8c54169661362f565b3594519687958694859363095ea7b360e01b85528401602090939291936001600160a01b0360408201951681520152565b03925af18015610a2f57610a01575b5050541661098784888861362f565b35823b156109fd576109c6928492838d5180968195829463b66503cf60e01b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f3576109df575b5050600101610841565b6109e890613222565b6104f65787386109d5565b89513d84823e3d90fd5b8380fd5b81610a2092903d10610a28575b610a188183613268565b810190613617565b503880610978565b503d610a0e565b8d513d88823e3d90fd5b610a599150893d8b11610a5f575b610a518183613268565b8101906133f1565b38610929565b503d610a47565b85513d88823e3d90fd5b925093965050610a809150613222565b6109fd578a9289868c87386108d6565b929050346105cc5760603660031901126105cc57610aac613722565b6001600160a01b0360c9541691823b156105c75783926064849284519586938492633894a93760e21b8452803590840152602435602484015260443560448401525af190811561067757506106645750f35b50503461060b578060031936011261060b57602090610b27610b1e613335565b602435906136fc565b90519015158152f35b5091903461060b57610b41366131cc565b610b4c949194613722565b610b5e610b5986836134e1565b613504565b908495906001600160a01b038060ca5416975b828410610bb65787808a8989610b868a613560565b833b156104fa576106f893602086809486519788958694859363525ac10360e11b855284015260248301906132f8565b86516315895f4760e31b815286810185905260209081816024818e5afa918215610c1f57916001939184938c92610c02575b505084610bf5838a613536565b9116905201930192610b71565b610c189250803d10610a5f57610a518183613268565b3880610be8565b89513d8c823e3d90fd5b5090346104fe5760203660031901126104fe57813591610c47613722565b610c50836136ba565b15610ce65783906001600160a01b0360cb541690813b156104fe57600160448492838751958694859363387ddad160e21b85528401528960248401525af18015610cdc57610cc8575b50507fa2fc94ed8ceee756ec75a07ca0d8f3b9918372930efd43ef20de9d3ee6f5ad239160209151908152a180f35b610cd190613222565b6104fe578238610c99565b83513d84823e3d90fd5b90516358d620b360e01b8152fd5b5090346104fe57806003193601126104fe57610d2f9135610d2a6001610d186131e2565b93838752606560205286200154613be5565b613dbc565b80f35b50346104fe57826003193601126104fe57610103835460ff8160081c161580610e0b575b610d5f906135a5565b61ffff191617835560206001600160a01b039160448360cf54169360ce541691868651958694859363095ea7b360e01b855284015260001960248401525af18015610dff57916020917f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249893610de2575b50835461ff00191684555160038152a180f35b610df890833d8511610a2857610a188183613268565b5038610dcf565b505051903d90823e3d90fd5b50600360ff821610610d56565b50346104fe57610e2736613181565b9193610e31613722565b865b858110610e6d5750509061087b917fd402dbc146639547cb1f2290e713e99e8a2200d1c7fa294b5d198e20496b7c4d9551948594856133c7565b876001600160a01b0360c9908082541691610e8985898961362f565b35833b156104fa578b9385809286519283916304ba099d60e21b83528b8301528160249586925af18015610a66578c878d938a9361101b575b5050610ed79161042a918760ca54169461362f565b855163b9a09fd560e01b8152908516898201526020929083818381865afa91821561101157849287928a91610ff4575b50885194859384926324f24ba560e11b8452168d8301525afa908115610a665787958a8c898c6109388a610f4c988a988591610a395750169b8c948c8c54169661362f565b03925af18015610a2f57610fd6575b50505416610f6a84888861362f565b35823b156109fd57610fa9928492838d51809681958294637c8afcc160e11b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f357610fc2575b5050600101610e33565b610fcb90613222565b6104f6578738610fb8565b81610fec92903d10610a2857610a188183613268565b503880610f5b565b61100b9150843d8611610a5f57610a518183613268565b38610f07565b87513d8a823e3d90fd5b92509396505061102b9150613222565b6109fd578a9289868c8738610ec2565b929050346105cc5760203660031901126105cc57611057613722565b6001600160a01b0360ca541691823b156105c7578392602484928451958693849263e5bc3de160e01b84528035908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc576110b5613722565b6001600160a01b0360c9541691823b156105c7578392602484928451958693849263cd3e888d60e01b84528035908401525af190811561067757506106645750f35b50346104fe5760c03660031901126104fe57356001600160a01b03908181168091036109fd57602435918083168093036104fa5760443591818316938484036112df576064359083821682036112df578794608435928584168094036112db5760a4359586168096036112db576111e56111ea926111df8b9a8a5460ff8160081c16159b8c809d6112ce575b80156112b7575b611193906135a5565b60ff198281166001178255918d6112a5575b5050600080526020809d606582528060002084600052825260ff81600020541615611256575b5050506000805260978c528c600020613f9f565b50613cf8565b613cf8565b6001600160a01b0319928360ca54161760ca558260c954161760c9558160cb54161760cb5560cc54161760cc5561121f578280f35b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989161ff001984541684555160018152a138808280f35b60019160008052606581528160002090856000525260002091825416179055338160007f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4388c8e6111cb565b61ffff19166101011790558e386111a5565b50303b15801561118a575060ff821660011461118a565b50600160ff831610611183565b8680fd5b600080fd5b8334610674576020366003190112610674576001600160a01b036113066131f8565b61130e613967565b166001600160a01b031960cc54161760cc5580f35b50346104fe5760203660031901126104fe5760209282913581526097845220549051908152f35b5082903461060b5761135b36613181565b959261136994929194613722565b86820361145d5790859661137c82613504565b9287926001600160a01b03908160ca5416945b8181106113df5750505050813b156112db578680946106f86113cd98889485519a8b98899788966360339aa560e11b885287015260448601906132f8565b8481036003190160248601529161338a565b6113ed61042a82848761362f565b895163b9a09fd560e01b81529084168982015260209081816024818b5afa918215611453579060019392918e92611436575b50508461142c838b613536565b911690520161138f565b61144c9250803d10610a5f57610a518183613268565b8e8061141f565b8b513d8f823e3d90fd5b835162461bcd60e51b815260208185015260248101849052636c656e2160e01b6044820152606490fd5b50346104fe57816003193601126104fe576114a06131f8565b916024358015158091036112df5784936114b8613722565b6001600160a01b03908160ca541690813b156112db578660449281958751988996879563de7d72e560e01b8752169085015260248401525af190811561067757506106645750f35b50503461060b578160031936011261060b57602090516101f48152f35b50503461060b578160031936011261060b5760209051620186a08152f35b50503461060b57602036600319011261060b576020906001600160a01b0361156461073b6131f8565b915191168152f35b50503461060b578160031936011261060b5751908152602090f35b929050346105cc5760209160206003193601126105c757803567ffffffffffffffff81116104fa576115bc9036908301613150565b906115c5613722565b6115ce82613504565b9186956001600160a01b03918260ca5416975b81811061161d575050505050833b156104fa576106f893602086809486519788958694859363e7264b6560e01b855284015260248301906132f8565b61162b61042a82848861362f565b885163b9a09fd560e01b81529085168882015283816024818d5afa90811561168c5790600192918c9161166f575b5085611665838a613536565b91169052016115e1565b6116869150853d8711610a5f57610a518183613268565b38611659565b89513d8d823e3d90fd5b929050346105cc5760203660031901126105cc576116b26131f8565b6116ba613722565b6001600160a01b036116d08160ca541692613663565b91803b156105c35785928360249286519788958694639f06247b60e01b865216908401525af190811561067757506106645750f35b929050346105cc57806003193601126105cc576117206131f8565b916117296131e2565b611731613722565b6001600160a01b0360ca5416803b156105c3578351634f4f661160e11b81526001600160a01b0395861693810193845294909116602083015284918491908290849082906040016106f8565b50346104fe5761178c36613181565b9193611796613722565b865b8581106117d25750509061087b917fd402dbc146639547cb1f2290e713e99e8a2200d1c7fa294b5d198e20496b7c4d9551948594856133c7565b876001600160a01b038060ca5416906117ef61042a858b8b61362f565b8a5163b9a09fd560e01b815290821686820152602092908b90602485828281875afa801561195757869386938992611938575b505194859384926324f24ba560e11b8452168b8301525afa90811561192e57889183918691611911575b501692611869818d8a87898c6109388d60cf9a8c8c54169661362f565b03925af18015610a2f576118f3575b5050541661188784888861362f565b35823b156109fd576118c6928492838d51809681958294637c8afcc160e11b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f3576118df575b5050600101611798565b6118e890613222565b6104f65787386118d5565b8161190992903d10610a2857610a188183613268565b503880611878565b6119289150853d8711610a5f57610a518183613268565b3861184c565b8b513d86823e3d90fd5b611950919250853d8711610a5f57610a518183613268565b9038611822565b83513d89823e3d90fd5b5091903461060b57602092836003193601126104fe5761197f6131f8565b60ca54835163b9a09fd560e01b81526001600160a01b03928316848201529082168682602481845afa918215610a6657916024918894938892611a24575b5086519586948593630e4bf54360e01b855216908301525afa928315611a1957926119ea575b5051908152f35b9091508281813d8311611a12575b611a028183613268565b810103126112df575190386119e3565b503d6119f8565b8251903d90823e3d90fd5b611a3c919250853d8711610a5f57610a518183613268565b90386119bd565b929050346105cc5760203660031901126105cc57611a5f6131f8565b611a67613722565b6001600160a01b03611a7d8160ca541692613663565b91803b156105c3578592836024928651978895869463992a793360e01b865216908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc57611ace613722565b6001600160a01b0360d0541691823b156105c7578392602484928451958693849263953e092f60e01b84528035908401525af190811561067757506106645750f35b50346104fe57816003193601126104fe576001600160a01b0382602094611b356131e2565b9335815260658652209116600052825260ff81600020541690519015158152f35b929050346105cc57611b67366131cc565b9290611b71613722565b6001600160a01b0360c95416803b156105c35785928360449286519788958694634852b80960e11b865285015260248401525af190811561067757506106645750f35b50346104fe57816003193601126104fe57611be66020936001600160a01b039235815260978552836024359120613e66565b92905490519260031b1c168152f35b929050346105cc5760203660031901126105cc57611c11613722565b6001600160a01b0360c9541691823b156105c757839260248492845195869384926346b066b160e11b84528035908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc57813567ffffffffffffffff81116105c757611c859036908401613150565b611c90949194613722565b815b818110611c9d578280f35b6001600160a01b038060c9541690611cb961042a84868b61362f565b90823b156105c3576024869283895195869485936378c8cda760e01b8552168c8401525af180156105b957908491611cf6575b5050600101611c92565b611cff90613222565b6104fe578238611cec565b50346104fe57611d1936613181565b919092611d24613a94565b865b828110611d31578780f35b611d3c81858761362f565b35151580611eff575b15611ebc57876001600160a01b038060cb541690611d6761042a85888861362f565b8a5163841fa66b60e01b81529116898201526020908181602481865afa91821561192e578492611e8b575b5050611d9f84888a61362f565b3514611e8157611db361042a84878761362f565b611dbe84888a61362f565b35823b156109fd57611dfe928492838c8e519687958694859363a93a897d60e01b85528401602090939291936001600160a01b0360408201951681520152565b03925af180156109f357611e6d575b5050807faad33d2acde4329b1c27ca0561954b24793925d0c7e22dc9711ff66a6beffe23611e4161042a600194878761362f565b611e4c83888a61362f565b8a516001600160a01b03929092168252356020820152604090a15b01611d26565b611e7690613222565b6104f6578738611e0d565b5050600190611e67565b8194508092503d8311611eb5575b611ea38183613268565b810103126112df578991513880611d92565b503d611e99565b865162461bcd60e51b8152602081880152600660248201527f2176616c696400000000000000000000000000000000000000000000000000006044820152606490fd5b506101f4611f0e82868861362f565b351115611d45565b5090346104fe57806003193601126104fe576020611f7992611f366131f8565b611f3e613722565b60cd54845163a9059cbb60e01b81526001600160a01b0391821693810193845260243560208501529586938492899290918491604090910190565b0393165af19081156106775750611f8e575080f35b611fa69060203d602011610a2857610a188183613268565b5080f35b929050346105cc5760203660031901126105cc57611fc6613722565b6001600160a01b0360d0541691823b156105c75783926024849284519586938492637396411960e01b84528035908401525af190811561067757506106645750f35b50346104fe5761201736613181565b90929391612023613a94565b865b818110612030578780f35b62ffffff906120528261204c61204784888b61362f565b613653565b166136db565b15612149576001600160a01b038060cc541661207261042a84878c61362f565b918b612082612047868a8d61362f565b93833b1561060b578c5163ba364c3d60e01b8152908316818b015293861660248501528b939281908490604490829084905af192831561213d578b899289928d9661211b575b5050612047876001999461042f61042a837f3b972fda5270142c6b6ba50a6e54a6b1859fee77b92de18244f39c96958ffa0d9b9a99976121079761362f565b90845193168352166020820152a101612025565b93509450505061212c919350613222565b6104f25786899186868b8e386120c8565b508351903d90823e3d90fd5b87516358d620b360e01b81528590fd5b929050346105cc57806003193601126105cc57612174613335565b61217c6131e2565b90612185613722565b6001600160a01b03908160c9541690813b156112db5786916024839287519485938492633e4ed1dd60e21b845215158b8401525af1801561221757908691612203575b50508060c95416803b156105c3578592836024928651978895869463221b8a9560e11b865216908401525af190811561067757506106645750f35b61220c90613222565b6104fa5784386121c8565b84513d88823e3d90fd5b50503461060b578160031936011261060b5760209051630784ce008152f35b50346104fe5761224f36613181565b9193612259613722565b865b8581106122955750509061087b917f07863f4e082a43727444dbaa22fa383af1e8bc428560a4c92fa68f5553440ac89551948594856133c7565b878387868a84876123048c6122ba61073b61042a8c6001600160a01b039a8b9561362f565b169687946122cf8b60cf988a8a54169461362f565b35905194858094819363095ea7b360e01b83526020998a988401602090939291936001600160a01b0360408201951681520152565b03925af18015610a2f5761238e575b5050541661232284888861362f565b35823b156109fd57612361928492838d5180968195829463b66503cf60e01b84528c8401602090939291936001600160a01b0360408201951681520152565b03925af180156109f35761237a575b505060010161225b565b61238390613222565b6104f6578738612370565b816123a492903d10610a2857610a188183613268565b503880612313565b929050346105cc5760203660031901126105cc576123c86131f8565b6123d0613722565b6001600160a01b038060ca5416803b156105c35785928360249286519788958694634d8c928d60e11b865216908401525af190811561067757506106645750f35b50503461060b578160031936011261060b576020906001600160a01b0360cc54169051908152f35b5090346104fe57826003193601126104fe57610102835460ff8160081c161580612682575b612467906135a5565b61ffff191617835560ca548151638dd598fb60e01b81526001600160a01b0391821693602093928690858484818a5afa938415612678578294612659575b50806001600160a01b031994168460ce54161760ce558451635001f3b560e01b8152868185818b5afa90811561264f579082918491612632575b50169360cf549785828a161760cf55865163030d028960e21b815288818781855afa9081156126285791848a928894889161260b575b50168460cd54161760cd558851928380926303aa30b960e11b82525afa90811561260157918389979694928694604497916125e4575b50169060d054161760d05560c9541693818751998a96879563095ea7b360e01b8752860152600019602486015216175af19283156125da577f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498936125bd575b50835461ff00191684555160028152a180f35b6125d390833d8511610a2857610a188183613268565b50386125aa565b81513d86823e3d90fd5b6125fb9150893d8b11610a5f57610a518183613268565b3861254b565b87513d86823e3d90fd5b6126229150843d8611610a5f57610a518183613268565b38612515565b88513d87823e3d90fd5b6126499150883d8a11610a5f57610a518183613268565b386124df565b86513d85823e3d90fd5b612671919450863d8811610a5f57610a518183613268565b92386124a5565b85513d84823e3d90fd5b50600260ff82161061245e565b50346104fe57816003193601126104fe5780359160ff83168093036112df576024359160ff83168093036112df5784936126c7613722565b6001600160a01b0360cb5416803b156105c35785928360449286519788958694631cb8e3a760e01b865285015260248401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc57612726613722565b6001600160a01b0360c9541691823b156105c7578392602484928451958693849263536d0e1160e01b84528035908401525af190811561067757506106645750f35b929050346105cc5760203660031901126105cc576127846131f8565b61278c613722565b6001600160a01b038060c95416803b156105c357859283602492865197889586946378c8cda760e01b865216908401525af190811561067757506106645750f35b929050346105cc57806003193601126105cc576127e86131f8565b916127f46107326131e2565b926001600160a01b0360ca5416803b156105c35783516314365dbf60e21b81526001600160a01b0395861693810193845294909116602083015284918491908290849082906040016106f8565b50503461060b578160031936011261060b576020906001600160a01b0360ce54169051908152f35b50503461060b578160031936011261060b576020906001600160a01b0360cd54169051908152f35b50503461060b578160031936011261060b576020906001600160a01b0360ca54169051908152f35b50346104fe57816003193601126104fe578035906128d56131e2565b906128de613722565b60208360646001600160a01b0393888560ce54168951968795869463ec32e6df60e01b8652850152630784ce006024850152881660448401525af1801561299057612965575b5091516001600160a01b03909216825260208201527fc0252bbdefb2e33bb149dde65e2f203f2957aef3cf2c77917b57823f9c4963d890806040810161087b565b602090813d8311612989575b61297b8183613268565b810103126112df5738612924565b503d612971565b84513d87823e3d90fd5b5091346106745760203660031901126106745782359067ffffffffffffffff8211610674573660238301121561067457506129e46129fc938260246129e9943693013591016132a2565b613560565b90519182916020835260208301906132f8565b0390f35b929050346105cc5760203660031901126105cc57612a1c6131f8565b612a24613722565b6001600160a01b038060c95416803b156105c3578592836024928651978895869463f80f5dd560e01b865216908401525af190811561067757506106645750f35b5091903461060b57612a76366131cc565b919093612a81613722565b6001600160a01b03928360ca5416835191630fbdb69960e11b835260209586848681865afa938415612c2d578894612bfe575b50612ac2610b598a846134e1565b93808a109081612bf3575b5015612bcb57875b828a10612b1057505050859650803b156105c3576106f89486809486519788958694859363e7264b6560e01b855284015260248301906132f8565b86516315895f4760e31b81528681018b9052602489828281895afa91821561168c57918a9185938d92612bac575b508a5193849263b9a09fd560e01b8452168a83015281885afa908115612ba257916001929183928c91612b85575b5084612b78838a613536565b9116905201990198612ad5565b612b9c91508b3d8d11610a5f57610a518183613268565b38612b6c565b88513d8c823e3d90fd5b612bc4919250833d8511610a5f57610a518183613268565b9038612b3e565b855162461bcd60e51b8152808601889052600260248201526110a960f11b6044820152606490fd5b905082111538612acd565b9093508681813d8311612c26575b612c168183613268565b810103126112df57519238612ab4565b503d612c0c565b86513d8a823e3d90fd5b8334610674576020366003190112610674576001600160a01b03612c596131f8565b612c61613967565b166001600160a01b031960cb54161760cb5580f35b5082903461060b578260031936011261060b57612c916131e2565b90336001600160a01b03831603612cad5790610d2f9135613dbc565b608490602085519162461bcd60e51b8352820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152fd5b5090346104fe57806003193601126104fe57611fa69135906097612d386131e2565b9280865260209060658252612d5260018589200154613be5565b80600052606582526001600160a01b038460002095169485600052825260ff84600020541615612d89575b60005252600020613f9f565b80600052606582528360002085600052825283600020600160ff198254161790553385827f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d600080a4612d7d565b50503461060b578160031936011261060b576020906001600160a01b0360cb54169051908152f35b5090346104fe5760203660031901126104fe57813591612e1d613722565b612e26836136ba565b15610ce65783906001600160a01b0360cb541690813b156104fe578260448192828751958694859363387ddad160e21b85528401528960248401525af18015610cdc57612e9d575b50507f09c7e5889341a30b241ed708718f55daa0607a3441916ac8139fa2b641e58e999160209151908152a180f35b612ea690613222565b6104fe578238612e6e565b50346104fe5760203660031901126104fe5781602093600192358152606585522001549051908152f35b50503461060b578160031936011261060b57602090610b27613410565b50503461060b578160031936011261060b576020906001600160a01b0360cf54169051908152f35b929050346105cc5760203660031901126105cc5781359167ffffffffffffffff83116105c757610b86612f596129e49436908401613150565b9490612f63613722565b6001600160a01b0360ca54169536916132a2565b50503461060b578160031936011261060b576020906001600160a01b0360c954169051908152f35b50503461060b578160031936011261060b576020906001600160a01b0360d054169051908152f35b808484346105cc57612fd8366131cc565b939091612fe3613722565b6001600160a01b0360ce541690813b156104fe578360448492838851958694859363076426ed60e11b85528401528a60248401525af1801561306a57613056575b50507f11c6bf55864ff83827df712625d7a80e5583eef0264921025e7cd22003a215119282519182526020820152a180f35b61305f90613222565b6109fd578385613024565b84513d84823e3d90fd5b5090346104fe578261308536613181565b6130929692939196613722565b6001600160a01b0360ca541692833b156105c3576130c586928851998a97889687956360339aa560e11b875286016133c7565b03925af190811561067757506130d9575080f35b610d2f90613222565b925050346104fe5760203660031901126104fe573563ffffffff60e01b81168091036104fe5760209250635a05180f60e01b8114908115613125575b5015158152f35b637965db0b60e01b81149150811561313f575b503861311e565b6301ffc9a760e01b14905038613138565b9181601f840112156112df5782359167ffffffffffffffff83116112df576020808501948460051b0101116112df57565b60406003198201126112df5767ffffffffffffffff916004358381116112df57826131ae91600401613150565b939093926024359182116112df576131c891600401613150565b9091565b60409060031901126112df576004359060243590565b602435906001600160a01b03821682036112df57565b600435906001600160a01b03821682036112df57565b35906001600160a01b03821682036112df57565b67ffffffffffffffff811161323657604052565b634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff82111761323657604052565b90601f8019910116810190811067ffffffffffffffff82111761323657604052565b67ffffffffffffffff81116132365760051b60200190565b92916132ad8261328a565b916132bb6040519384613268565b829481845260208094019160051b81019283116112df57905b8282106132e15750505050565b8380916132ed8461320e565b8152019101906132d4565b90815180825260208080930193019160005b828110613318575050505090565b83516001600160a01b03168552938101939281019260010161330a565b6004359081151582036112df57565b91908082526020809201929160005b828110613361575050505090565b9091929382806001926001600160a01b0361337b8961320e565b16815201950193929101613353565b90918281527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83116112df5760209260051b809284830137010190565b92906133e0906133ee9593604086526040860191613344565b92602081850391015261338a565b90565b908160209103126112df57516001600160a01b03811681036112df5790565b6001600160a01b038060c954169060405190816322621bc160e11b9384825281600460209586935afa9081156134b8576000916134c4575b50811630149283613465575b50505061346057600090565b600190565b90918093508260ca54169160046040518094819382525afa9283156134b857600093613499575b5050163014388080613454565b6134b0929350803d10610a5f57610a518183613268565b90388061348c565b6040513d6000823e3d90fd5b6134db9150833d8511610a5f57610a518183613268565b38613448565b919082039182116134ee57565b634e487b7160e01b600052601160045260246000fd5b9061350e8261328a565b61351b6040519182613268565b828152809261352c601f199161328a565b0190602036910137565b805182101561354a5760209160051b010190565b634e487b7160e01b600052603260045260246000fd5b60005b81518110156135a1576001906001600160a01b0361358c816135858487613536565b5116613663565b906135978386613536565b9116905201613563565b5090565b156135ac57565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608490fd5b908160209103126112df575180151581036112df5790565b919081101561354a5760051b0190565b356001600160a01b03811681036112df5790565b3562ffffff811681036112df5790565b60206001600160a01b0360248160ca541693604051948593849263b9a09fd560e01b84521660048301525afa9081156134b8576000916136a1575090565b6133ee915060203d602011610a5f57610a518183613268565b80151590816136ce575b5061346057600090565b6101f491501115386136c4565b80151590816136ee575061346057600090565b620186a091501115386136c4565b156136db5780151590816136ce575061346057600090565b3560ff811681036112df5790565b3360009081527fbdd154b7c599a43e8b8410b62e84571cd69a79e95c9fc5b630a687cb7c97edf96020908152604080832054909291907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff16156137885750505050565b61379133613e8f565b9084519061379e8261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b8183116138e5575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b8401917f206973206d697373696e6720726f6c6520000000000000000000000000000000603784015251809386840190613e43565b01036028810189520187613268565b5194859362461bcd60e51b8552600485015251809281602486015285850190613e43565b601f01601f19168101030190fd5b60648386519062461bcd60e51b825280600483015260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a6139158587613e7e565b5360041c92801561392b576000190191906137d0565b634e487b7160e01b82526011600452602482fd5b634e487b7160e01b83526032600452602483fd5b634e487b7160e01b81526032600452602490fd5b3360009081527fffdfc1249c027f9191656349feb0761381bb32c9f557e01f419fd08754bf5a1b60209081526040808320549092919060ff16156139aa57505050565b6139b333613e8f565b8351836139bf8261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b818311613a4e575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a613a7e8587613e7e565b5360041c92801561392b576000190191906139f1565b3360009081527fb8856e02d8db4f86d5561f04ba0fd00f302915fcd46f5dd1dd5d4c6dc0a5aabb6020908152604080832054909291907fe6ad9a47fbda1dc18de1eb5eeb7d935e5e81b4748f3cfc61e233e64f881820609060ff1615613afa5750505050565b613b0333613e8f565b90845190613b108261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b818311613b9f575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a613bcf8587613e7e565b5360041c92801561392b57600019019190613b42565b6000818152602060658152604092838320338452825260ff848420541615613c0d5750505050565b613c1633613e8f565b90845190613c238261324c565b604282528382019460603687378251156139535760308653825190600191600110156139535790607860218501536041915b818311613cb2575050506138a357846138716048613895936044979851988991613862898401987f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008a5261382d815180928d603789019101613e43565b909192600f8116601081101561393f576f181899199a1a9b1b9c1cb0b131b232b360811b901a613ce28587613e7e565b5360041c92801561392b57600019019190613c55565b6001600160a01b031660008181527fbdd154b7c599a43e8b8410b62e84571cd69a79e95c9fc5b630a687cb7c97edf9602052604080822054613d6e9392907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff1615613d71575b8152609760205220613f9f565b50565b8082526065602052828220848352602052828220600160ff198254161790553384827f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8580a4613d61565b906040613d6e9260009080825260656020526001600160a01b0383832094169384835260205260ff8383205416613dfb575b8152609760205220614029565b808252606560205282822084835260205282822060ff1981541690553384827ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b8580a4613dee565b60005b838110613e565750506000910152565b8181015183820152602001613e46565b805482101561354a5760005260206000200190600090565b90815181101561354a570160200190565b604051906060820182811067ffffffffffffffff82111761323657604052602a825260208201604036823782511561354a576030905381516001906001101561354a57607860218401536029905b808211613f31575050613eed5790565b606460405162461bcd60e51b815260206004820152602060248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152fd5b9091600f81166010811015613f8a576f181899199a1a9b1b9c1cb0b131b232b360811b901a613f608486613e7e565b5360041c918015613f75576000190190613edd565b60246000634e487b7160e01b81526011600452fd5b60246000634e487b7160e01b81526032600452fd5b91906001830160009082825280602052604082205415600014614023578454946801000000000000000086101561400f5783613fff613fe8886001604098999a01855584613e66565b819391549060031b91821b91600019901b19161790565b9055549382526020522055600190565b634e487b7160e01b83526041600452602483fd5b50925050565b9060018201906000928184528260205260408420549081151560001461411257600019918083018181116140fe578254908482019182116140ea578082036140b5575b505050805480156140a1578201916140848383613e66565b909182549160031b1b191690555582526020526040812055600190565b634e487b7160e01b86526031600452602486fd5b6140d56140c5613fe89386613e66565b90549060031b1c92839286613e66565b9055865284602052604086205538808061406c565b634e487b7160e01b88526011600452602488fd5b634e487b7160e01b87526011600452602487fd5b505050509056fea164736f6c6343000816000a
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.