MON Price: $0.018964 (+3.52%)

Contract

0x1310f352f1389969Ece6741671c4B919523912fF

Overview

MON Balance

Monad Chain LogoMonad Chain LogoMonad Chain Logo0 MON

MON Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Add Market Manag...485770382026-01-14 3:46:4010 days ago1768362400IN
0x1310f352...9523912fF
0 MON0.01506611102
Add Market Permi...433776122025-12-21 0:09:0234 days ago1766275742IN
0x1310f352...9523912fF
0 MON0.00812052102
Transfer Timeloc...433776062025-12-21 0:09:0034 days ago1766275740IN
0x1310f352...9523912fF
0 MON0.0286827102
Set External Cal...427572812025-12-18 3:04:4537 days ago1766027085IN
0x1310f352...9523912fF
0 MON0.0058308102.68402032
Set External Cal...427572762025-12-18 3:04:4337 days ago1766027083IN
0x1310f352...9523912fF
0 MON0.00820671102.68402032
Add Market Manag...386962702025-11-29 5:10:4056 days ago1764393040IN
0x1310f352...9523912fF
0 MON0.01510332102.2519562
Set External Cal...382759202025-11-27 6:15:4558 days ago1764224145IN
0x1310f352...9523912fF
0 MON0.0092956116.355
Transfer Dao Per...379791422025-11-25 21:11:0860 days ago1764105068IN
0x1310f352...9523912fF
0 MON0.00901669101.94
Transfer Emergen...378341822025-11-25 4:59:1960 days ago1764046759IN
0x1310f352...9523912fF
0 MON0.0211643105.3312288
Transfer Dao Per...378341772025-11-25 4:59:1760 days ago1764046757IN
0x1310f352...9523912fF
0 MON0.01211161105.3312288
Add Auction Perm...378341712025-11-25 4:59:1560 days ago1764046755IN
0x1310f352...9523912fF
0 MON0.0083871105.3312288
Add Market Manag...378340612025-11-25 4:58:3160 days ago1764046711IN
0x1310f352...9523912fF
0 MON0.01920191130
Add Market Manag...378339452025-11-25 4:57:4460 days ago1764046664IN
0x1310f352...9523912fF
0 MON0.01920191130
Add Market Manag...378338262025-11-25 4:56:5660 days ago1764046616IN
0x1310f352...9523912fF
0 MON0.01920191130
Add Market Manag...378337172025-11-25 4:56:1360 days ago1764046573IN
0x1310f352...9523912fF
0 MON0.01920191130
Add Market Manag...378336162025-11-25 4:55:3260 days ago1764046532IN
0x1310f352...9523912fF
0 MON0.01919983130
Add Market Manag...378335062025-11-25 4:54:4860 days ago1764046488IN
0x1310f352...9523912fF
0 MON0.01920191130
Add Market Manag...378333352025-11-25 4:53:4060 days ago1764046420IN
0x1310f352...9523912fF
0 MON0.01532312103.74
Add Market Manag...378332312025-11-25 4:52:5860 days ago1764046378IN
0x1310f352...9523912fF
0 MON0.01532146103.74
Add Market Manag...378331262025-11-25 4:52:1660 days ago1764046336IN
0x1310f352...9523912fF
0 MON0.01532312103.74
Add Market Manag...378330302025-11-25 4:51:3760 days ago1764046297IN
0x1310f352...9523912fF
0 MON0.01532146103.74
Add Market Manag...378329432025-11-25 4:51:0260 days ago1764046262IN
0x1310f352...9523912fF
0 MON0.01532312103.74
Add Market Manag...378328482025-11-25 4:50:2460 days ago1764046224IN
0x1310f352...9523912fF
0 MON0.01763839103.74
Set Multicall Ch...378322742025-11-25 4:46:3460 days ago1764045994IN
0x1310f352...9523912fF
0 MON0.0087088109.01
Set Oracle Manag...378322352025-11-25 4:46:1960 days ago1764045979IN
0x1310f352...9523912fF
0 MON0.00859096109.01
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CentralRegistry

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion, BSL 1.1 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at monadscan.com on 2025-11-25
*/

// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.28;

// contracts/libraries/ConstantsLib.sol

/// @dev Scalar for math. `WAD` * `WAD`.
uint256 constant WAD_SQUARED = 1e36;

/// @dev Scalar for math. `WAD` * `WAD` / `BPS`.
///      1e18 * 1e18 / 1e4
uint256 constant WAD_SQUARED_BPS_OFFSET = 1e32;

/// @dev Scalar for math. Increased precision when WAD is insufficient
///      but WAD_SQUARED runs the risk of overflow.
uint256 constant RAY = 1e27;

/// @dev Scalar for math. `WAD` * `BPS`.
uint256 constant WAD_BPS = 1e22;

/// @dev Scalar for math. Base precision matching ether.
uint256 constant WAD = 1e18;

/// @dev Scalar for math. Represents basis points typically used in TradFi.
uint256 constant BPS = 1e4;

/// @dev Return value indicating no price returned at all.
uint256 constant BAD_SOURCE = 2;

/// @dev Return value indicating price divergence or a missing price feed.
uint256 constant CAUTION = 1;

/// @dev Return value indicating no price error.
uint256 constant NO_ERROR = 0;

/// @dev Extra time added to top end Oracle feed heartbeat incase of
///      transaction congestion delaying an update.
uint256 constant HEARTBEAT_GRACE_PERIOD = 120;

/// @dev Unix time has 31,536,000 seconds per year.
///      All my homies hate leap seconds and leap years.
uint256 constant SECONDS_PER_YEAR = 31_536_000;

// contracts/interfaces/IActionRegistry.sol

interface IActionRegistry {
    /// @notice Checks whether `user` has transferability enabled or disabled
    ///         for their tokens.
    /// @param user The address to check whether transferability is enabled or
    ///             disabled for.
    /// @return result Indicates whether `user` has transferability disabled
    ///                or not, true = disabled, false = not disabled.
    function checkTransfersDisabled(
        address user
    ) external view returns (bool result);

    /// @notice Checks whether `user` has disabled creating new delegations
    ///         for actions inside Curvance.
    /// @param user The address to check whether delegation is enabled or
    ///             disabled for.
    /// @return result Indicates whether `user` has delegation disabled
    ///                or not, true = disabled, false = not disabled.
    function checkNewDelegationDisabled(
        address user
    ) external view returns (bool result);

    /// @notice Returns `user`'s approval index.
    /// @dev The approval index is a way to revoke approval on all tokens,
    ///      and features at once if a malicious delegation was allowed by
    ///      `user`.
    /// @param user The user to check delegated approval index for.
    /// @return result The `user`'s current approval index value.
    function userApprovalIndex(
        address user
    ) external view returns (uint256 result);
}

// contracts/interfaces/ICentralRegistry.sol

/// TYPES ///

/// @notice Configuration data for a separately supported blockchain.
/// @param isSupported Whether the chain is supported or not.
/// @param messagingChainId Messaging Chain ID where this address authorized.
/// @param domain Domain for the chain.
/// @param messagingHub Messaging Hub address on the chain.
/// @param votingHub Voting Hub address on the chain.
/// @param cveAddress CVE address on the chain.
/// @param feeTokenAddress Fee token address on the chain.
/// @param crosschainRelayer Crosschain relayer address on the chain.
struct ChainConfig {
    bool isSupported;
    uint16 messagingChainId;
    uint32 domain;
    address messagingHub;
    address votingHub;
    address cveAddress;
    address feeTokenAddress;
    address crosschainRelayer;
}

interface ICentralRegistry {
    /// @notice The length of one protocol epoch, in seconds.
    function EPOCH_DURATION() external view returns (uint256);

    /// @notice Sequencer uptime oracle on this chain (for L2s).
    function SEQUENCER_ORACLE() external view returns (address);

    /// @notice Returns Genesis Epoch Timestamp of Curvance.
    function genesisEpoch() external view returns (uint256);

    /// @notice Returns Protocol DAO address.
    function daoAddress() external view returns (address);

    /// @notice Returns Protocol Emergency Council address.
    function emergencyCouncil() external view returns (address);

    /// @notice Indicates if address has DAO permissions or not.
    function hasDaoPermissions(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Indicates if address has elevated DAO permissions or not.
    function hasElevatedPermissions(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Indicates if address has lock creation permissions or not.
    function hasLockingPermissions(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Indicates if address has auction permissions or not.
    function hasAuctionPermissions(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Indicates if address has market permissions or not.
    function hasMarketPermissions(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Indicates if address has harvest permissions or not.
    function hasHarvestPermissions(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Returns Reward Manager address.
    function rewardManager() external view returns (address);

    /// @notice Returns Gauge Manager address.
    function gaugeManager() external view returns (address);

    /// @notice Returns CVE address.
    function cve() external view returns (address);

    /// @notice Returns veCVE address.
    function veCVE() external view returns (address);

    /// @notice Returns Voting Hub address.
    function votingHub() external view returns (address);

    /// @notice Returns Messaging Hub address.
    function messagingHub() external view returns (address);

    /// @notice Returns Oracle Manager address.
    function oracleManager() external view returns (address);

    /// @notice Returns Fee Manager address.
    function feeManager() external view returns (address);

    /// @notice Returns Fee Token address.
    function feeToken() external view returns (address);

    /// @notice Returns Crosschain Core contract address.
    function crosschainCore() external view returns (address);

    /// @notice Returns Crosschain Relayer contract address.
    function crosschainRelayer() external view returns (address);

    /// @notice Returns Token Messenger contract address.
    function tokenMessager() external view returns (address);

    /// @notice Returns Messenger Transmitter contract address.
    function messageTransmitter() external view returns (address);

    /// @notice Returns domain value.
    function domain() external view returns (uint32);

    /// @notice Returns protocol gas fee on harvest, in `BPS`.
    function protocolCompoundFee() external view returns (uint256);

    /// @notice Returns protocol yield fee on strategy harvest, in `BPS`.
    function protocolYieldFee() external view returns (uint256);

    /// @notice Returns protocol yield + gas fee on strategy harvest,
    ///         in `BPS`.
    function protocolHarvestFee() external view returns (uint256);

    /// @notice Returns protocol fee on leverage actions, in `BPS`.
    function protocolLeverageFee() external view returns (uint256);

    /// @notice Returns default fee on interest generated from active loans,
    ///         in `BPS`.
    function defaultProtocolInterestFee() external view returns (uint256);

    /// @notice Returns earlyUnlockPenaltyMultiplier value, in `BPS`.
    function earlyUnlockPenaltyMultiplier() external view returns (uint256);

    /// @notice Returns voteBoostMultiplier value, in `BPS`.
    function voteBoostMultiplier() external view returns (uint256);

    /// @notice Returns lockBoostMultiplier value, in `BPS`.
    function lockBoostMultiplier() external view returns (uint256);

    /// @notice Returns swap slippage limit, in `BPS`.
    function slippageLimit() external view returns (uint256);

    /// @notice Returns an array of Chain IDs recorded in the Crosschain
    ///         Protocol's Chain ID format.
    function foreignChainIds() external view returns (uint256[] memory);

    /// @notice Returns an array of Curvance markets on this chain.
    function marketManagers() external view returns (address[] memory);

    /// @notice Increments a caller's approval index.
    /// @dev By incrementing their approval index, a user's delegates will all
    ///      have their delegation authority revoked across all Curvance
    ///      contracts.
    ///      Emits an {ApprovalIndexIncremented} event.
    function incrementApprovalIndex() external;

    /// @notice Returns `user`'s approval index.
    /// @param user The user to check approval index for.
    function userApprovalIndex(address user) external view returns (uint256);

    /// @notice Returns whether a user has delegation disabled.
    /// @param user The user to check delegation status for.
    function checkNewDelegationDisabled(
        address user
    ) external view returns (bool);

    /// @notice Returns whether a particular GETH chainId is supported.
    /// ChainId => messagingHub address, 2 = supported; 1 = unsupported.
    function chainConfig(
        uint256 chainId
    ) external view returns (ChainConfig memory);

    /// @notice Returns the GETH chainId corresponding chainId corresponding
    ///         to Crosschain Messaging Protocol's `chainId`.
    /// @param chainId The Crosschain Messaging Protocol's chainId.
    /// @return The GETH chainId corresponding chainId corresponding to
    ///         Crosschain Messaging Protocol's `chainId`.
    function messagingToGETHChainId(
        uint16 chainId
    ) external view returns (uint256);

    /// @notice Returns the Crosschain Messaging Protocol's ChainId
    ///         corresponding to the GETH `chainId`.
    /// @param chainId The GETH chainId.
    /// @return The Crosschain Messaging Protocol's ChainId
    ///         corresponding to the GETH `chainId`.
    function GETHToMessagingChainId(
        uint256 chainId
    ) external view returns (uint256);

    /// @notice Indicates if an address is a market manager or not.
    function isMarketManager(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Maps an intent target address to the contract that will
    ///         inspect provided external calldata.
    function externalCalldataChecker(
        address addressToCheck
    ) external view returns (address);

    /// @notice Maps a Multicall target address to the contract that will
    ///         inspect provided multicall calldata.
    function multicallChecker(
        address addressToCheck
    ) external view returns (address);

    /// @notice Indicates the amount of token rewards allocated on this chain,
    ///         for an epoch.
    function emissionsAllocatedByEpoch(
        uint256 epoch
    ) external view returns (uint256);

    /// @notice Indicates the amount of token rewards allocated across all
    ///         chains, for an era. An era is a particular period in time in
    ///         which rewards are constant, before a halvening event moves the
    ///         protocol to a new era.
    function targetEmissionAllocationByEra(
        uint256 era
    ) external view returns (uint256);

    /// @notice Unlocks a market to process auction-based liquidations.
    /// @param marketToUnlock The address of the market manager to unlock
    ///                       auction-based liquidations with a specific
    ///                       liquidation bonus.
    function unlockAuctionForMarket(address marketToUnlock) external;

    /// @notice Checks if a market is unlocked for auction operations.
    /// @return Whether the caller is an unlocked market, approved for
    ///         auction-based liquidations.
    function isMarketUnlocked() external view returns (bool);

    /// @notice Sets the amount of token rewards allocated on this chain,
    ///         for an epoch.
    /// @dev Only callable by the Voting Hub.
    /// @param epoch The epoch having its token emission values set.
    /// @param emissionsAllocated The amount of token rewards allocated on
    ///                           this chain, for an epoch.
    function setEmissionsAllocatedByEpoch(
        uint256 epoch,
        uint256 emissionsAllocated
    ) external;

    /// @notice Checks whether `user` has transferability enabled or disabled
    ///         for their tokens.
    /// @dev This is inherited from ActionRegistry portion of centralRegistry.
    /// @param user The address to check whether transferability is enabled or
    ///             disabled for.
    /// @return result Indicates whether `user` has transferability disabled
    ///                or not, true = disabled, false = not disabled.
    function checkTransfersDisabled(
        address user
    ) external view returns (bool result);
}

// contracts/interfaces/IERC165.sol

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(
        bytes4 interfaceId
    ) external view returns (bool);
}

// contracts/interfaces/IERC20.sol

// @dev Interface of the ERC20 standard
interface IERC20 {
    // @dev Returns the name of the token.
    function name() external view returns (string memory);

    // @dev Returns the symbol of the token.
    function symbol() external view returns (string memory);

    // @dev Returns the decimals of the token.
    function decimals() external view returns (uint8);

    // @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 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);

    // @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.
    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);
}

// contracts/interfaces/IMarketManager.sol

interface IMarketManager {
    /// TYPES ///

    /// @notice Data structure passed communicating the intended liquidation
    ///         scenario to review based on current liquidity levels.
    /// @param collateralToken The token which was used as collateral
    ///                        by `account` and may be seized.
    /// @param debtToken The token to potentially repay which has
    ///                  outstanding debt by `account`.
    /// @param numAccounts The number of accounts to be, potentially,
    ///                    liquidated.
    /// @param liquidateExact Whether the liquidator desires a specific
    ///                       liquidation amount.
    /// @param liquidatedShares Empty variable slot to store how much
    ///                         `collateralToken` will be seized as
    ///                         part of a particular liquidation.
    /// @param debtRepaid Empty variable slot to store how much
    ///                   `debtToken` will be repaid as part of a
    ///                   particular liquidation.
    /// @param badDebt Empty variable slot to store how much bad debt will
    ///                be realized by lenders as part of a particular
    ///                liquidation.
    struct LiqAction {
        address collateralToken;
        address debtToken;
        uint256 numAccounts;
        bool liquidateExact;
        uint256 liquidatedShares;
        uint256 debtRepaid;
        uint256 badDebt;
    }

    /// @notice Data structure returned communicating outcome of a liquidity
    ///         scenario review based on current liquidity levels.
    /// @param liquidatedShares An array containing the collateral amounts to
    ///                         liquidate from accounts, in shares.
    /// @param debtRepaid The total amount of debt to repay from accounts,
    ///                   in assets.
    /// @param badDebtRealized The total amount of debt to realize as losses
    ///                        for lenders, in assets.
    struct LiqResult {
        uint256[] liquidatedShares;
        uint256 debtRepaid;
        uint256 badDebtRealized;
    }

    /// @notice Returns whether minting, collateralization, borrowing of
    ///         `cToken` is paused.
    /// @param cToken The address of the Curvance token to return
    ///               action statuses of.
    /// @return bool Whether minting `cToken` is paused or not.
    /// @return bool Whether collateralization `cToken` is paused or not.
    /// @return bool Whether borrowing `cToken` is paused or not.
    function actionsPaused(
        address cToken
    ) external view returns (bool, bool, bool);

    /// @notice Returns the current collateralization configuration
    ///         of `cToken`.
    /// @param cToken The address of the Curvance token to return
    ///               collateralization configuration of.
    /// @return The ratio at which this token can be borrowed against
    ///         when collateralized.
    /// @return The collateral requirement where dipping below this
    ///         will cause a soft liquidation.
    /// @return The collateral requirement where dipping below
    ///         this will cause a hard liquidation.
    function collConfig(address cToken) external view returns (
         uint256, uint256, uint256
    );

    /// @notice Returns the current liquidation configuration
    ///         of `cToken`.
    /// @param cToken The address of the Curvance token to return
    ///               liquidation configuration of.
    /// @return The base ratio at which this token will be
    ///         compensated on soft liquidation.
    /// @return The liquidation incentive curve length between soft
    ///         liquidation to hard liquidation, in `WAD`. e.g. 5% base
    ///         incentive with 8% curve length results in 13% liquidation
    ///         incentive on hard liquidation.
    /// @return The minimum possible liquidation incentive for during an
    ///         auction, in `WAD`.
    /// @return The maximum possible liquidation incentive for during an
    ///         auction, in `WAD`.
    /// @return Maximum % that a liquidator can repay when soft
    ///         liquidating an account, in `WAD`.
    /// @return Curve length between soft liquidation and hard liquidation,
    ///         should be equal to 100% - `closeFactorBase`, in `WAD`.
    /// @return The minimum possible close factor for during an auction,
    ///         in `WAD`.
    /// @return The maximum possible close factor for during an auction,
    ///         in `WAD`.
    function liquidationConfig(address cToken) external view returns (
        uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256
    );

    /// @notice Enables an auction-based liquidation, potentially with a dynamic
    ///         close factor and liquidation penalty values in transient storage.
    /// @dev Transient storage enforces any liquidator outside auction-based
    ///      liquidations uses the default risk parameters.
    /// @param cToken The Curvance token to configure liquidations for during
    ///               an auction-based liquidation.
    /// @param incentive The auction liquidation incentive value, in `BPS`.
    /// @param closeFactor The auction close factor value, in `BPS`.
    function setTransientLiquidationConfig(
        address cToken,
        uint256 incentive,
        uint256 closeFactor
    ) external;

    /// @notice Called from the AuctionManager as a post hook after liquidations
    ///         are tried to enable all collateral to be liquidated outside
    ///         an Auction tx.
    /// @notice Resets the liquidation risk parameters in transient storage to
    ///         zero.
    /// @dev This is redundant since the transient values will be reset after
    ///      the liquidation transaction, but can be useful during meta calls
    ///      with multiple liquidations during a single transaction. 
    function resetTransientLiquidationConfig() external;

    /// @notice Checks if the account should be allowed to mint tokens
    ///         in the given market.
    /// @param cToken The token to verify mints against.
    function canMint(address cToken) external;

    /// @notice Checks if the account should be allowed to collateralize
    ///         their shares of the given market.
    ///         Prunes unused positions in `account` data.
    /// @dev May emit a {PositionUpdated} event.
    /// @param cToken The token to verify collateralization of.
    /// @param account The account which would collateralize the asset.
    /// @param newNetCollateral The amount of shares that would be
    ///                         collateralized in total if allowed.
    function canCollateralize(
        address cToken,
        address account,
        uint256 newNetCollateral
    ) external;

    /// @notice Checks if the account should be allowed to redeem tokens
    ///         in the given market, and then redeems.
    /// @dev This can only be called by the cToken itself.
    /// @param cToken The token to verify the redemption against.
    /// @param shares The number of cToken shares to redeem for the
    ///               underlying asset in the market.
    /// @param account The account which would redeem `shares`.
    /// @param balanceOf The current cToken share balance of `account`.
    /// @param collateralPosted The current cToken shares posted as
    ///                         collateral by `account`.
    /// @param forceRedeemCollateral Whether the collateral should be always
    ///                              reduced.
    function canRedeemWithCollateralRemoval(
        address cToken,
        uint256 shares,
        address account,
        uint256 balanceOf,
        uint256 collateralPosted,
        bool forceRedeemCollateral
    ) external returns (uint256);

    /// @notice Checks if the account should be allowed to borrow
    ///         the underlying asset of the given market.
    ///         Prunes unused positions in `account` data.
    /// @dev May emit a {PositionUpdated} event.
    /// @param cToken The token to verify borrowability of.
    /// @param assets The amount of underlying assets `account` would borrow.
    /// @param account The account which would borrow the asset.
    /// @param newNetDebt The amount of assets that would be
    ///                   outstanding debt in total if allowed.
    function canBorrow(
        address cToken,
        uint256 assets,
        address account,
        uint256 newNetDebt
    ) external;

    /// @notice Checks if the account should be allowed to borrow
    ///         the underlying asset of the given market,
    ///         and notifies the market of the borrow.
    /// @dev This can only be called by the market itself.
    /// @param cToken The market to verify the borrow against.
    /// @param assets The amount of underlying assets `account` would borrow.
    /// @param account The account which would borrow the asset.
    /// @param newNetDebt The amount of assets that would be
    ///                   outstanding debt in total if allowed.
    function canBorrowWithNotify(
        address cToken,
        uint256 assets,
        address account,
        uint256 newNetDebt
    ) external;

    /// @notice Checks if the account should be allowed to repay a borrow
    ///         in the given market, may clean up positions.
    /// @param cToken The Curvance token to verify the repayment of.
    /// @param newNetDebt The new debt amount owed by `account` after
    ///                   repayment.
    /// @param debtAsset The debt asset being repaid to `cToken`.
    /// @param decimals The decimals that `debtToken` is measured in.
    /// @param account The account who will have their loan repaid.
    function canRepayWithReview(
        address cToken,
        uint256 newNetDebt,
        address debtAsset,
        uint256 decimals,
        address account
    ) external;

    /// @notice Checks if the liquidation should be allowed to occur,
    ///         and returns how many collateralized shares should be seized
    ///         on liquidation.
    /// @param debtAmounts The amounts of outstanding debt the liquidator
    ///                    wishes to repay, in underlying assets, empty if
    ///                    intention is to liquidate maximum amount possible
    ///                    for each account.
    /// @param liquidator The address of the account trying to liquidate
    ///                   `accounts`.
    /// @param accounts The addresses of the accounts to be liquidated.
    /// @param action A LiqAction struct containing:
    ///               collateralToken The token which is used as collateral
    ///                               by `account` and may be seized.
    ///               debtToken The token to potentially repay which has
    ///                         outstanding debt by `account`.
    ///               numAccounts The number of accounts to be, potentially,
    ///                           liquidated.
    ///               liquidateExact Whether the liquidator desires a
    ///                              specific liquidation amount.
    ///               collateralLiquidated Empty variable slot to store how
    ///                                    much `collateralToken` will be
    ///                                    seized as part of a particular
    ///                                    liquidation.
    ///               debtRepaid Empty variable slot to store how much
    ///                          `debtToken` will be repaid as part of a
    ///                          particular liquidation.
    ///               badDebt Empty variable slot to store how much bad debt
    ///                       will be realized as part of a particular
    ///                       liquidation.
    /// @return result A LiqResult struct containing:
    ///                liquidatedShares An array containing the collateral
    ///                                 amounts to liquidate from
    ///                                 `accounts`.
    ///                debtRepaid The total amount of debt to repay from
    ///                           `accounts`.
    ///                badDebtRealized The total amount of debt to realize as
    ///                                losses for lenders inside this market.
    /// @return An array containing the debt amounts to repay from
    ///        `accounts`, in assets.
    function canLiquidate(
        uint256[] memory debtAmounts,
        address liquidator,
        address[] calldata accounts,
        IMarketManager.LiqAction memory action
    ) external returns (LiqResult memory, uint256[] memory);

    /// @notice Checks if the seizing of `collateralToken` by repayment of
    ///         `debtToken` should be allowed.
    /// @param collateralToken The Curvance token which was used as collateral
    ///                        and will be seized.
    /// @param debtToken The Curvance token which has outstanding debt to and
    ///                  would be repaid during `collateralToken` seizure.
    function canSeize(address collateralToken, address debtToken) external;

    /// @notice Checks if the account should be allowed to transfer collateral
    ///         tokens in the given market.
    /// @param cToken The Curvance token to verify the transfer of.
    /// @param shares The amount of `cToken` to transfer.
    /// @param account The account which will transfer `shares`.
    /// @param balanceOf The current balance that `account` has of `cToken`
    ///                  shares.
    /// @param collateralPosted The amount of `cToken` shares posted as
    ///                         collateral by `account`.
    /// @param isCollateral Boolean indicating whether the token is currently
    ///                     being used as collateral.
    function canTransfer(
        address cToken,
        uint256 shares,
        address account,
        uint256 balanceOf,
        uint256 collateralPosted,
        bool isCollateral
    ) external returns (uint256);

    /// @notice Updates `account` cooldownTimestamp to the current block
    ///         timestamp.
    /// @dev The caller must be a listed cToken in the `markets` mapping.
    /// @param cToken The address of the token that the account is borrowing.
    /// @param account The address of the account that has just borrowed.
    function notifyBorrow(address cToken, address account) external;

    /// @notice A list of all tokens inside this market for
    ///         offchain querying.
    function queryTokensListed() external view returns (address[] memory);

    /// @notice Returns whether `cToken` is listed in the lending market.
    /// @param cToken market token address.
    function isListed(address cToken) external view returns (bool);

    /// @notice The total amount of `cToken` that can be posted as collateral,
    ///         in shares.
    function collateralCaps(address cToken) external view returns (uint256);

    /// @notice The total amount of `cToken` underlying that can be borrowed,
    ///         in assets.
    function debtCaps(address cToken) external view returns (uint256);

    /// @notice Returns whether `addressToCheck` is an approved position
    ///         manager or not.
    /// @param addressToCheck Address to check for position management
    ///                       authority.
    function isPositionManager(
        address addressToCheck
    ) external view returns (bool);

    /// @notice Returns the assets an account has entered.
    /// @param account The address of the account to pull assets for.
    /// @return A dynamic list with the assets `account` has entered.
    function assetsOf(
        address account
    ) external view returns (address[] memory);

    /// @notice Determine `account`'s current status between collateral,
    ///         debt, and additional liquidity.
    /// @param account The account to determine liquidity for.
    /// @return The current total collateral amount of `account`.
    /// @return The maximum debt amount of `account` can take out with
    ///         their current collateral.
    /// @return The current total borrow amount of `account`.
    function statusOf(
        address account
    ) external returns (uint256, uint256, uint256);
}

// contracts/interfaces/ITimelock.sol

interface ITimelock {
    /// @notice Cancels a queued action.
    /// @dev Only callable by `CANCELLER_ROLE` or the Emergency Council.
    ///      May emit a {Cancelled} event.
    /// @param id The queued action to cancel.
    function cancel(bytes32 id) external;

    /// @notice Permissionlessly update DAO address if it has been changed.
    ///         through the Protocol Central Registry.
    function updateRoles() external;

    /// @notice Updates the minimum delay between an action queue and
    ///         execution.
    /// @dev `newDelay` cannot be less than `MINIMUM_DELAY`.
    ///      May emit a {MinDelayChange} event.
    /// @param newDelay The new minimum delay between action queue and
    ///                 execution.
    function updateDelay(uint256 newDelay) external;
}

// contracts/interfaces/IVotingHub.sol

interface IVotingHub {
    function protocolRewardEras() external view returns (uint256);
}

// contracts/libraries/external/SafeTransferLib.sol

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
/// - For ERC20s, this implementation won't check that a token has code,
///   responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
    //
    // The regular variants:
    // - Forwards all remaining gas to the target.
    // - Reverts if the target reverts.
    // - Reverts if the current contract has insufficient balance.
    //
    // The force variants:
    // - Forwards with an optional gas stipend
    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
    // - If the target reverts, or if the gas stipend is exhausted,
    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
    // - Reverts if the current contract has insufficient balance.
    //
    // The try variants:
    // - Forwards with a mandatory gas stipend.
    // - Instead of reverting, returns whether the transfer succeeded.

    /// @dev Sends `amount` (in wei) ETH to `to`.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`.
    function safeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer all the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // forgefmt: disable-next-item
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function trySafeTransferAllETH(address to, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have their entire balance approved for
    /// the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x14, to) // Store the `to` argument.
            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
    /// then retries the approval again (some tokens, e.g. USDT, requires this).
    /// Reverts upon failure.
    function safeApproveWithRetry(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, retrying upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x34, 0) // Store 0 for the `amount`.
                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
                pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.
                mstore(0x34, amount) // Store back the original `amount`.
                // Retry the approval, reverting upon failure.
                if iszero(
                    and(
                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                    )
                ) {
                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            amount :=
                mul(
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }
}

// contracts/libraries/external/ERC165.sol

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// contracts/libraries/external/ERC165Checker.sol

// @author Modified from OpenZeppelin Contracts (utils/introspection/ERC165Checker.sol)

/**
 * @dev Library used to query support of an interface declared via {IERC165}.
 *
 * Note that these functions return the actual result of the query: they do not
 * `revert` if an interface is not supported. It is up to the caller to decide
 * what to do in these cases.
 */
library ERC165Checker {
    // As per the EIP-165 spec, no interface should ever match 0xffffffff
    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;

    /**
     * @dev Returns true if `account` supports the {IERC165} interface.
     */
    function supportsERC165(address account) internal view returns (bool) {
        // Any contract that implements ERC165 must explicitly indicate support of
        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
        return
            supportsERC165InterfaceUnchecked(
                account,
                type(IERC165).interfaceId
            ) &&
            !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);
    }

    /**
     * @dev Returns true if `account` supports the interface defined by
     * `interfaceId`. Support for {IERC165} itself is queried automatically.
     *
     * See {IERC165-supportsInterface}.
     */
    function supportsInterface(
        address account,
        bytes4 interfaceId
    ) internal view returns (bool) {
        // query support of both ERC165 as per the spec and support of _interfaceId
        return
            supportsERC165(account) &&
            supportsERC165InterfaceUnchecked(account, interfaceId);
    }

    /**
     * @notice Query if a contract implements an interface, does not check ERC165 support
     * @param account The address of the contract to query for support of an interface
     * @param interfaceId The interface identifier, as specified in ERC-165
     * @return true if the contract at account indicates support of the interface with
     * identifier interfaceId, false otherwise
     * @dev Assumes that account contains a contract that supports ERC165, otherwise
     * the behavior of this method is undefined. This precondition can be checked
     * with {supportsERC165}.
     *
     * Some precompiled contracts will falsely indicate support for a given interface, so caution
     * should be exercised when using this function.
     *
     * Interface identification is specified in ERC-165.
     */
    function supportsERC165InterfaceUnchecked(
        address account,
        bytes4 interfaceId
    ) internal view returns (bool) {
        // prepare call
        bytes memory encodedParams = abi.encodeCall(
            IERC165.supportsInterface,
            (interfaceId)
        );

        // perform static call
        bool success;
        uint256 returnSize;
        uint256 returnValue;
        assembly {
            success := staticcall(
                30000,
                account,
                add(encodedParams, 0x20),
                mload(encodedParams),
                0x00,
                0x20
            )
            returnSize := returndatasize()
            returnValue := mload(0x00)
        }

        return success && returnSize >= 0x20 && returnValue > 0;
    }
}

// contracts/libraries/ActionRegistry.sol

/// @title Curvance Action Registry.
/// @notice Facilitates locking a users token transferability or plugin
///         approvals as a secondary protective layer against phishing
///         attempts.
/// @dev `ActionRegistry` enables the plugin system. A new
///      primitive allowing for "delegation" of specific actions to any
///      address, providing that address authority on behalf of the user in
///      the smart contract. Approvals can also be mass revoked via the
///      "approval index" system. By incrementing one's approval index, a user
///      can revoke all approved address' delegation privileges at the same
///      time. This facilitates better management of approvals inside
///      Curvance versus conventional implementations on top of the EVM.
///
///      Second, `ActionRegistry` enables a locking system. This operates as
///      an optional "2FA" setting to reduce the potential of a successful
///      phishing attempt on a user. A cooldown can be set for token transfers
///      and plugin delegation that activates after an action lock is enabled.
///      Modifying this cooldown downward will automatically apply the full
///      unmodified cooldown as an additional safety measure against malicious
///      signatures attempting to bypass it.
///      NOTE: This does not apply to second order actions such as Zapping to
///            external addresses, borrowing to external addresses, etc.
///
///      Integrators of the transfer lock call can expect roughly a
///      3% increase to transfer calls for optimized ERC20 implementations.
///
abstract contract ActionRegistry is IActionRegistry {
    /// TYPES ///

    /// @title User Configuration for supported actions.
    /// @notice Struct containing information on a user's configuration values
    ///         for transfers and delegation inside Curvance.
    /// @param lockCooldown The cooldown period for the user's transfers and
    ///                     delegations.
    /// @param transferEnabledTimestamp The timestamp that the user's
    ///                                 transfers have been enabled.
    /// @param transferDisabled Whether the user intends on enabling or
    ///                         disabling transferability
    /// @param approvalIndex The approval index for the user's delegates. Revokes
    ///                     all delegates at once if incremented.
    /// @param delegationEnabledTimestamp The timestamp that the user's
    ///                                  delegations have been enabled.
    /// @param delegationDisabled Whether the user intends on enabling or
    ///                          disabling delegation.
    struct UserConfig {
        uint120 approvalIndex;
        uint40 lockCooldown;
        uint40 transferEnabledTimestamp;
        bool transferDisabled;
        uint40 delegationEnabledTimestamp;
        bool delegationDisabled;
    }

    /// STORAGE ///

    /// @notice Contains a user's configuration values for transfers and
    ///         delegation inside Curvance.
    /// @dev By incrementing their approval index, a user's delegates will all
    ///      have their delegation authority revoked across all Curvance
    ///      contracts. A user can apply a cooldown to their transfers and
    ///      delegations if they have enabled `lockCooldown`.
    ///      User => User configuration values.
    mapping(address => UserConfig) internal _userConfig;

    /// EVENTS ///

    event CooldownSet(address indexed user, uint256 userLockCooldown);
    event ApprovalIndexIncremented(address indexed user, uint256 newIndex);
    event TransferableStatusChanged(
        address indexed user,
        bool isLocked,
        uint256 transferEnabledTimestamp
    );
    event DelegableStatusChanged(
        address indexed user,
        bool delegable,
        uint256 delegationEnabledTimestamp
    );

    /// ERRORS ///

    error ActionRegistry__InvalidParams();
    error ActionRegistry__CooldownActive();

    /// EXTERNAL FUNCTIONS ///

    /// @notice Sets token transferability unlock cooldown.
    /// @dev Emits a {CooldownSet} event. If a user decreases their cooldown,
    ///      the unmodified lock cooldown will automatically apply, delaying
    ///      when actions are re-enabled, preventing a malicious party from
    ///      tricking a user into decreasing their cooldown to 0 and then
    ///      phishing them.
    /// @param cooldown The length of time transferability and plugin approval
    ///                 should remain restricted after their lock has been
    ///                 disabled, in seconds.
    function setCooldown(uint256 cooldown) external {
        // Maximum `cooldown` enforced of 1 year to prevent accidentally
        // locking your tokens until the heat death of the universe.
        if (cooldown > SECONDS_PER_YEAR) {
            revert ActionRegistry__InvalidParams();
        }

        UserConfig storage config = _userConfig[msg.sender];
        // If a user is decreasing their cooldown, lock cooldown
        // will automatically apply, delaying when transferability and plugin
        // approval can be re-enabled, preventing a malicious party from
        // tracking a user to decrease their cooldown to 0 and then enabling
        // transferability.
        uint256 userCooldown = config.lockCooldown;
        if (userCooldown > cooldown) {
            // Validate the user does not currently have a cooldown active.
            if (
                block.timestamp < config.transferEnabledTimestamp ||
                block.timestamp < config.delegationEnabledTimestamp
            ) {
                revert ActionRegistry__CooldownActive();
            }
            uint40 newCooldown = uint40(userCooldown + block.timestamp);
            config.transferEnabledTimestamp = newCooldown;
            config.delegationEnabledTimestamp = newCooldown;
        }

        config.lockCooldown = uint40(cooldown);
        emit CooldownSet(msg.sender, cooldown);
    }

    /// TRANSFER MANAGEMENT ///

    /// @notice Checks whether `user` has transferability enabled or disabled
    ///         for their tokens.
    /// @param user The address to check whether transferability is enabled or
    ///             disabled for.
    /// @return result Indicates whether `user` has transferability disabled
    ///                or not, true = disabled, false = not disabled.
    function checkTransfersDisabled(
        address user
    ) external view returns (bool result) {
        UserConfig memory config = _userConfig[user];
        result = (config.transferDisabled ||
            config.transferEnabledTimestamp > block.timestamp);
    }

    /// @notice Sets token transferability for the caller, if enabling
    ///         transferability, the caller's opt in transfer cooldown will
    ///         be applied.
    /// @dev Emits a {TransferableStatusChanged} event.
    /// @param transferDisabled Whether the user intends on enabling or
    ///                         disabling transferability, while flipping
    ///                         their transferability status can be assumed,
    ///                         it's best to make sure the caller intends on
    ///                         flipping their status for onchain integrators.
    function setTransferableStatus(bool transferDisabled) external {
        UserConfig storage config = _userConfig[msg.sender];

        // Validates that user is intending on flipping their transfer
        // lock status, even though we could assume they want to flip
        // by calling this function, it helps to validate for human error.
        if (transferDisabled == config.transferDisabled) {
            revert ActionRegistry__InvalidParams();
        }

        uint256 enableTimestamp;

        // If the user is trying to enable transferability again,
        // add their cooldown period, an added layer against phishing
        // attempts.
        if (!transferDisabled) {
            enableTimestamp = _enableTime(config.transferEnabledTimestamp);
            config.transferEnabledTimestamp = uint40(enableTimestamp);
        }

        config.transferDisabled = transferDisabled;

        // Timestamp emitted is 0 if locking transferability.
        emit TransferableStatusChanged(
            msg.sender,
            transferDisabled,
            enableTimestamp
        );
    }

    /// PLUGIN DELEGATION MANAGEMENT ///

    /// @notice Returns `user`'s current approval index value.
    /// @dev The approval index is a way to revoke approval on all tokens,
    ///      and features at once if a malicious delegation was allowed by
    ///      `user`.
    /// @param user The user to check delegated approval index for.
    /// @return r The `user`'s current approval index value.
    function userApprovalIndex(address user) external view returns (uint256 r) {
        r = _userConfig[user].approvalIndex;
    }

    /// @notice Increments a caller's approval index.
    /// @dev By incrementing their approval index, a user's delegates will
    ///      all have their delegation authority revoked across all Curvance
    ///      contracts.
    ///      Emits an {ApprovalIndexIncremented} event.
    function incrementApprovalIndex() external {
        // Technically this hits overflow if a user calls 1e36 times but
        // thats economically impossible.
        emit ApprovalIndexIncremented(
            msg.sender,
            ++_userConfig[msg.sender].approvalIndex
        );
    }

    /// @notice Checks whether `user` has new delegation configuration enabled
    ///         or disabled for user actions inside Curvance.
    /// @param user The address to check whether new delegation configuration
    ///        is enabled or disabled for.
    /// @return result Indicates whether `user` has new delegations disabled
    ///                or not, true = disabled, false = not disabled.
    function checkNewDelegationDisabled(
        address user
    ) external view returns (bool result) {
        UserConfig memory config = _userConfig[user];
        result = (config.delegationDisabled ||
            config.delegationEnabledTimestamp > block.timestamp);
    }

    /// @notice Sets a callers status for whether to allow new delegation
    ///         configuration or not.
    /// @param delegationDisabled Whether caller wants to allow new delegation
    ///                           configuration or not.
    ///      Emits a {DelegableStatusChanged} event.
    function setDelegableStatus(bool delegationDisabled) external {
        UserConfig storage config = _userConfig[msg.sender];

        // Validates that user is intending on flipping their delegation
        // status, even though we could assume they want to flip
        // by calling this function, it helps to validate for human error.
        if (delegationDisabled == config.delegationDisabled) {
            revert ActionRegistry__InvalidParams();
        }

        uint256 enableTimestamp;

        // If the user is trying to enable delegation configuration again,
        // add their cooldown period, an added layer against phishing
        // attempts.
        if (!delegationDisabled) {
            enableTimestamp = _enableTime(config.delegationEnabledTimestamp);
            config.delegationEnabledTimestamp = uint40(enableTimestamp);
        }

        config.delegationDisabled = delegationDisabled;

        emit DelegableStatusChanged(
            msg.sender,
            delegationDisabled,
            enableTimestamp
        );
    }

    /// INTERNAL FUNCTIONS ///

    /// @dev Checks that action timestamp was not recently updated and
    ///      calculates the timestamp that the desired action will be
    ///      enabled.
    /// @param time_ The timestamp that an action will be
    ///              enabled (if disabled).
    /// @return r The timestamp at which action(s) will be enabled again.
    function _enableTime(uint256 time_) internal view returns (uint256 r) {
        // Validate the user did not recently reduce their action cooldown
        // period, triggering their action cooldown.
        if (time_ > block.timestamp) {
            revert ActionRegistry__CooldownActive();
        }
        
        r = _userConfig[msg.sender].lockCooldown + block.timestamp;
    }
}

// contracts/architecture/CentralRegistry.sol

/// @title Curvance DAO Central Registry.
/// @notice Manages permissions and protocol contract registration
///         within the Curvance Protocol.
/// @dev The Central Registry acts as a single source of truth for the Curvance
///      Protocol. This covers everything from multichain operations, to
///      contract locations, to protocol fees, to protocol multipliers
///      associated with various actions.
///
///      Permissions inside Curvance have two tiers:
///      - Standard DAO permissions: This is associated with actions that
///        reduce risk inside the Curvance system, or need to be continually
///        managed by the DAO elected operating team.
///      - Elevated DAO permissions: This is associated with actions that
///        increase risk inside the Curvance system, the most sensitive of
///        controls. This requires a 5-day delay from the DAO elected
///        operating team for any action, or the "Emergency Council" made up
///        of both Curvance Collective members and external stakeholders.
///
///      All values inside Curvance are entered and stored in
///      `BPS` (basis points) form. However, fees are often accessed
///      simultaneously at run time while multipliers are accessed separately
///      meaning we store multipliers in uint256 storage slots to save
///      conversion costs and save fees in uint16 storage slots to saved SLOAD
///      costs. 
///
///      The Central Registry manages the plugin system, creating a new
///      primitive allowing for "delegation" of specific actions to any
///      address, providing that address authority on behalf of the user in
///      the smart contract. Approvals can also be mass revoked via the
///      "approval index" system. By incrementing one's approval index, a user
///      can revoke all approved address' delegation privileges at the same
///      time. This facilitates better management of approvals inside
///      Curvance versus conventional implementations on top of the EVM.
///
///      The Central Registry also manages the locking system,
///      which operates as an optional 2FA setting to reduce the potential of
///      a successful phishing attempt on a user. A cooldown can be set for
///      token transfers and plugin delegation that activates after an action
///      lock is enabled.
///
contract CentralRegistry is ERC165, ActionRegistry {
    /// CONSTANTS ///

    /// @notice The length of one protocol epoch, in seconds.
    uint256 public constant EPOCH_DURATION = 2 weeks;

    /// @notice Sequencer uptime oracle on this chain (for L2s).
    address public immutable SEQUENCER_ORACLE;

    /// STORAGE ///

    /// @notice Genesis Epoch timestamp.
    uint256 public genesisEpoch;

    // DAO GOVERNANCE OPERATORS

    /// @notice DAO multisig, the primary address that the Curvance
    ///         Collective operates from.
    address public daoAddress;
    /// @notice DAO multisig, with an execution time delay.
    address public timelock;
    /// @notice Multi-protocol multisig, intended to be used only for
    ///         emergencies.
    address public emergencyCouncil;

    // TOKEN CONTRACTS

    /// @notice Address of fee token which Curvance Protocol compounds
    ///         strategy fees into.
    address public feeToken;
    /// @notice CVE contract address on this chain.
    address public cve;
    /// @notice veCVE contract address on this chain.
    address public veCVE;

    // PROTOCOL CONTRACTS

    /// @notice Reward Manager contract address, distributes rewards in
    ///         `feeToken` to token lockers every epoch.
    address public rewardManager;
    /// @notice Gauge Manager contract address, distributes native token
    ///         rewards to depositors and lenders inside the Curvance
    ///         Protocol based on decentralized governance outcomes.
    address public gaugeManager;
    /// @notice Oracle Manager contract address, manages oracle prices
    ///         for supported assets.
    address public oracleManager;
    /// @notice Fee Manager contract address, manages fees for decentralized
    ///         strategies for distribution.
    address public feeManager;
    /// @notice Messaging Hub contract address, processes crosschain messages
    ///         across all supported blockchains.
    address public messagingHub;
    /// @notice Voting Hub contract address, receives decentralized governance
    ///         vote outcomes to update onchain across all blockchains.
    address public votingHub;

    /// @notice Array of all the addresses for all Curvance Market Managers
    ///         on this chain.
    address[] internal _marketManagers;

    // ACTION MULTIPLIER VALUES
    // @dev We save these in uint256 slots since they are accessed separately.

    /// @notice Penalty multiplier for unlocking a veCVE lock early,
    ///         in `BPS`.
    uint256 public earlyUnlockPenaltyMultiplier;
    /// @notice Voting power multiplier for Continuous Lock mode,
    ///         in `BPS`.
    uint256 public voteBoostMultiplier;
    /// @notice Rewards multiplier for locking gauge emissions as veCVE,
    ///         in `BPS`.
    uint256 public lockBoostMultiplier;

    // SLIPPAGE VALUES

    /// @notice Protocol slippage limit for "untrusted" strategy managers,
    ///         addresses with `hasHarvestPermissions`, in WAD.
    /// @dev 300e14 = 3%.
    ///      This slippage configurable variable is not for an end all be all
    ///      slippage check, any external swap natively includes slippage and
    ///      only acts as a protective layer against secondary actions such as
    ///      providing liquidity into an LP token or from untrusted executed
    ///      like a harvester that could at some point be compromised.
    uint256 public slippageLimit = 300e14;

    // PROTOCOL VALUES

    /// @notice Fee on yield generated from strategies to pay for network gas
    ///         costs, in `BPS`.
    /// @dev 100 = 1%.
    uint16 public protocolCompoundFee = 100;
    /// @notice Fee on yield generated from strategies distributed to veCVE
    ///         lockers, in `BPS`.
    /// @dev 1500 = 15%.
    uint16 public protocolYieldFee = 1500;
    /// @notice Joint strategy fee value so that we can perform one less
    ///         external call in strategy contracts, in `BPS`.
    /// @dev 1600 = 16%.
    uint16 public protocolHarvestFee = protocolCompoundFee + protocolYieldFee;
    /// @notice Protocol fee on leverage usage, in `BPS`.
    uint16 public protocolLeverageFee;

    /// @notice Returns default fee on interest generated from active loans,
    ///         in `BPS`.
    /// @dev 2000 = 20%. Can be overridden inside particular token contracts.
    uint16 public defaultProtocolInterestFee = 2000;

    // AUCTION TRANSACTION STORAGE

    /// Controls which Market Manager auction liquidators can act inside.
    /// @dev Key value = `uint256(keccak256(_TRANSIENT_MARKET_UNLOCKED_KEY))`.
    uint256 internal constant _TRANSIENT_MARKET_UNLOCKED_KEY
        = 0x7cbd46c789962ee73435d84bcd3c0927fb55fd04ce92deedbdae7e783739544c;

    // CROSSCHAIN CONFIGURATION DATA

    /// @notice Address of Crosschain Core contract on this chain.
    address public crosschainCore;
    /// @notice Address of Crosschain Relayer contract on this chain.
    address public crosschainRelayer;
    /// @notice Address of Token Messenger contract on this chain.
    address public tokenMessager;
    /// @notice Address of Message Transmitter contract on this chain.
    address public messageTransmitter;
    /// @notice Domain value on this chain.
    uint32 public domain;
    /// @notice The number of chains supported by the Curvance Protocol.
    /// @dev Stored redundantly to reduce gas overhead.
    uint256 public supportedChains;

    /// @notice Array of Chain IDs recorded in GETH format.
    /// @dev Stored redundantly to reduce gas overhead.
    uint256[] internal _foreignChainIds;
    
    /// @notice Configuration data for a separately supported blockchain.
    mapping(uint256 => ChainConfig) public chainConfig;
    /// @notice Returns the GETH chainId corresponding chainId corresponding
    ///         to Crosschain Messaging Protocol's `chainId`.
    /// @dev Messaging ChainId => GETH ChainId.
    mapping(uint16 => uint256) public messagingToGETHChainId;

    /// @notice Indicates the amount of token rewards allocated on this chain,
    ///         for an epoch.
    /// @dev Epoch # => Token rewards allocated.
    mapping(uint256 => uint256) public emissionsAllocatedByEpoch;

    /// @notice Indicates the amount of token rewards allocated across all
    ///         chains, for an era. An era is a particular period in time in
    ///         which rewards are constant, before a halvening event moves the
    ///         protocol to a new era.
    /// @dev Era # => Token rewards allocated.
    mapping(uint256 => uint256) public targetEmissionAllocationByEra;

    // CONTRACT MAPPINGS
    
    /// @notice Indicates if an address is a Market Manager or not.
    /// @dev Address => Market Manager status.
    mapping(address => bool) public isMarketManager;

    /// @notice Maps an intent target address to the contract that will
    ///         inspect provided external calldata.
    /// @dev Address => External calldata checker address.
    mapping(address => address) public externalCalldataChecker;
    /// @notice Maps a Multicall target address to the contract that will
    ///         inspect provided multicall calldata.
    /// @dev Address => Multicall checker address.
    mapping(address => address) public multicallChecker;

    // PERMISSION MAPPINGS

    /// @notice Indicates if address has DAO permissions or not.
    /// @dev Address => DAO permission status.
    mapping(address => bool) public hasDaoPermissions;
    /// @notice Indicates if address has elevated DAO permissions or not.
    /// @dev Address => Elevated DAO permission status.
    mapping(address => bool) public hasElevatedPermissions;
    /// @notice Indicates if address has lock creation permissions or not.
    /// @dev Address => Lock creation permission status.
    mapping(address => bool) public hasLockingPermissions;
    /// @notice Indicates if an address has auction permissions or not.
    /// @dev Address => Auction permission status.
    mapping(address => bool) public hasAuctionPermissions;
    /// @notice Indicates if an address has market permissions or not.
    /// @dev Market Perms double as a check for `hasElevatedPermissions` in
    ///      many cases as long as a "risk council" contract is not explicitly
    ///      hooked up to the a particular permissioned function.
    ///      Address => Market permission status.
    mapping(address => bool) public hasMarketPermissions;
    /// @notice Indicates if an address has harvest permissions or not.
    /// @dev Address => Harvest permission status.
    mapping(address => bool) public hasHarvestPermissions;

    /// EVENTS ///

    event GenesisEpochUpdated(uint256 newGenesisEpoch);
    event FeeSet(string indexed fee, uint256 newFee);
    event FeeTokenSet(address newAddress);
    event DefaultInterestFeeSet(uint256 newFee);
    event MultiplierSet(string indexed multiplier, uint256 newMultiplier);
    event SlippageLimit(uint256 newSlippage);
    event CoreContractUpdated(string indexed coreType, address core);
    event ContractUpdated(
        string indexed contractType,
        address addressUpdated,
        bool isAdded
    );
    event PermissionsTransferred(
        string indexed permissionsType,
        address previousAddress,
        address newAddress
    );
    event PermissionsUpdated(
        string indexed permissionsType,
        address addressUpdated,
        bool isAdded
    );
    event DomainSet(uint32 newDomain);
    event NewChain(uint256 chainId, ChainConfig config);
    event RemovedChain(uint256 chainId, address messagingHub, address votingHub);
    event CalldataCheckerSet(
        string indexed calldataType,
        address targetAddress,
        address calldataChecker
    );
    event EraEmissionsAllotmentSet(uint256 epochEmissionAllotment);

    /// ERRORS ///

    error CentralRegistry__InvalidParameter();
    error CentralRegistry__Unauthorized();
    error CentralRegistry__EpochHasStarted();

    /// CONSTRUCTOR ///

    /// @param dao The address of `daoAddress`, DAO multisig, the primary
    ///            address that the Curvance Collective operates from.
    /// @param ec The address of `emergencyCouncil`, Multi-protocol multisig,
    ///           intended to be used only for emergencies.
    /// @param genesisEpoch_ Genesis Epoch timestamp, in unix seconds.
    /// @param sequencer_ The address of the Chainlink aggregator proxy for
    ///                   identifying if a sequencer has recently been down
    ///                   for grace period calculations.
    /// @param feeToken_ Address of fee token which Curvance Protocol
    ///                  compounds strategy fees into.
    constructor(
        address dao,
        address ec,
        uint256 genesisEpoch_,
        address sequencer_,
        address feeToken_
    ) {
        if (dao == address(0)) {
            dao = msg.sender;
        }

        if (ec == address(0)) {
            ec = msg.sender;
        }

        // Check to make sure that genesis epoch is at least at the beginning
        // of 2022 (Jan 1 12:00 EST) so we know the value is not accidently
        // misconverted or missing with a value of 0.
        if (genesisEpoch_ < 1640926800) {
            revert CentralRegistry__InvalidParameter();
        }

        // Configure DAO permission data.
        daoAddress = dao;
        emergencyCouncil = ec;

        emit PermissionsTransferred("DAO Permissions", address(0), dao);
        emit PermissionsTransferred("Emergency Council", address(0), ec);

        // Provide base dao permissions to `dao`,
        // and `ec`.
        hasDaoPermissions[dao] = true;
        hasDaoPermissions[ec] = true;

        // Provide market and elevated dao permissions to `emergencyCouncil`.
        hasMarketPermissions[ec] = true;
        hasElevatedPermissions[ec] = true;

        emit PermissionsUpdated("Market", ec, true);

        genesisEpoch = genesisEpoch_;
        SEQUENCER_ORACLE = sequencer_;
        feeToken = feeToken_;
    }

    /// EXTERNAL FUNCTIONS ///

    /// @notice Withdraw fees in `feeToken` from this central registry.
    function withdrawFees() external {
        _checkDaoPermissions();

        SafeTransferLib.safeTransfer(
            feeToken,
            daoAddress,
            IERC20(feeToken).balanceOf(address(this))
        );
    }

    /// @notice Sets a new genesis epoch.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {GenesisEpochUpdated} event.
    /// @param newGenesisEpoch The new genesis epoch.
    function setGenesisEpoch(uint256 newGenesisEpoch) external {
        // Its not possible for `genesisEpoch` to be 0 based on constructor
        // restrictions, so we do not need to check for 0 input here as this
        // check would catch `newGenesisEpoch` == 0.
        if (newGenesisEpoch < genesisEpoch) {
            revert CentralRegistry__InvalidParameter();
        }

        _checkElevatedPermissions();
        if (genesisEpoch <= block.timestamp) {
            revert CentralRegistry__EpochHasStarted();
        }

        genesisEpoch = newGenesisEpoch;

        emit GenesisEpochUpdated(newGenesisEpoch);
    }

    /// @notice Sets the fee token address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Settable before genesis epoch start.
    ///      Emits a {FeeTokenSet} event.
    /// @param newFeeToken The new address of fee token.
    function setFeeToken(address newFeeToken) external {
        _checkCanSetCoreContract(feeToken);
        _checkElevatedPermissions();

        feeToken = newFeeToken;
        emit FeeTokenSet(newFeeToken);
    }

    /// @notice Sets the CVE contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Settable before genesis epoch start.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newCVE The new address of cve.
    function setCVE(address newCVE) external {
        _checkCanSetCoreContract(cve);
        _checkElevatedPermissions();

        cve = newCVE;
        emit CoreContractUpdated("CVE", newCVE);
    }

    /// @notice Sets the veCVE contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Settable before genesis epoch start.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newVeCVE The new address of veCVE.
    function setVeCVE(address newVeCVE) external {
        _checkCanSetCoreContract(veCVE);
        _checkElevatedPermissions();

        veCVE = newVeCVE;
        emit CoreContractUpdated("VeCVE", newVeCVE);
    }

    /// @notice Sets the Reward Manager contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Settable before genesis epoch start.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newRewardManager The new address of rewardManager.
    function setRewardManager(address newRewardManager) external {
        _checkCanSetCoreContract(rewardManager);
        _checkElevatedPermissions();

        rewardManager = newRewardManager;
        emit CoreContractUpdated("Reward Manager", newRewardManager);
    }

    /// @notice Sets the Gauge Manager contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Settable before genesis epoch start.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newGaugeManager The new address of Gauge Manager.
    function setGaugeManager(address newGaugeManager) external {
        _checkCanSetCoreContract(gaugeManager);
        _checkElevatedPermissions();

        gaugeManager = newGaugeManager;
        emit CoreContractUpdated("Gauge Manager", newGaugeManager);
    }

    /// @notice Sets the voting hub contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newVotingHub The new address of votingHub.
    function setVotingHub(address newVotingHub) external {
        _checkElevatedPermissions();

        votingHub = newVotingHub;
        emit CoreContractUpdated("Voting Hub", newVotingHub);
    }

    /// @notice Sets the messaging hub contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newMessagingHub The new address of messagingHub.
    function setMessagingHub(address newMessagingHub) external {
        _checkElevatedPermissions();

        messagingHub = newMessagingHub;
        emit CoreContractUpdated("Messaging Hub", newMessagingHub);
    }

    /// @notice Sets the Oracle Manager contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newOracleManager The new address of oracleManager.
    function setOracleManager(address newOracleManager) external {
        _checkElevatedPermissions();

        oracleManager = newOracleManager;
        emit CoreContractUpdated("Oracle Manager", newOracleManager);
    }

    /// @notice Sets the Fee Manager contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newFeeManager The new address of feeManager.
    function setFeeManager(address newFeeManager) external {
        _checkElevatedPermissions();

        feeManager = newFeeManager;
        emit CoreContractUpdated("Fee Manager", newFeeManager);
    }

    /// @notice Sets the Crosschain Core contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newCrosschainCore The new Crosschain Core address.
    function setCrosschainCore(address newCrosschainCore) external {
        _checkElevatedPermissions();

        crosschainCore = newCrosschainCore;
        emit CoreContractUpdated("Crosschain Core", newCrosschainCore);
    }

    /// @notice Sets the Crosschain Relayer contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newCrosschainRelayer The new crosschainRelayer address.
    function setCrosschainRelayer(address newCrosschainRelayer) external {
        _checkElevatedPermissions();

        crosschainRelayer = newCrosschainRelayer;
        emit CoreContractUpdated("Crosschain Relayer", newCrosschainRelayer);
    }

    /// @notice Sets the Token Messager contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newTokenMessager The new Token Messager address.
    function setTokenMessager(address newTokenMessager) external {
        _checkElevatedPermissions();

        tokenMessager = newTokenMessager;
        emit CoreContractUpdated("Token Messager", newTokenMessager);
    }

    /// @notice Sets the Message Transmitter contract address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CoreContractUpdated} event.
    /// @param newTransmitter The new Message Transmitter address.
    function setMessageTransmitter(address newTransmitter) external {
        _checkElevatedPermissions();

        messageTransmitter = newTransmitter;
        emit CoreContractUpdated("Message Transmitter", newTransmitter);
    }

    /// @notice Sets the domain.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {DomainsSet} event.
    /// @param newDomain The new domain value.
    function setDomain(uint32 newDomain) external {
        _checkElevatedPermissions();

        domain = newDomain;
        emit DomainSet(newDomain);
    }

    /// @notice Sets the fee from yield by Curvance DAO to use as gas
    ///         to compound rewards for users.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      can only have a maximum value of 5%.
    ///      Emits a {FeeSet} event.
    /// @param value The new fee to take on compound to fund future
    ///              auto compounding, in `BPS`.
    function setProtocolCompoundFee(uint256 value) external {
        _checkElevatedPermissions();

        // Compound fee cannot be more than 5%.
        if (value > 500) {
            revert CentralRegistry__InvalidParameter();
        }

        // Update `protocolCompoundFee` and `protocolHarvestFee`
        // with new fee.
        protocolCompoundFee = uint16(value);
        protocolHarvestFee = uint16(protocolYieldFee + value);
        emit FeeSet("Compound", value);
    }

    /// @notice Sets the fee taken by Curvance DAO on all yield generated
    ///         by the protocol.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      can only have a maximum value of 50%.
    ///      Emits a {FeeSet} event.
    /// @param value The new fee to take on compound to distribute to veCVE
    ///              lockers, in `BPS`.
    function setProtocolYieldFee(uint256 value) external {
        _checkElevatedPermissions();

        // Compound fee cannot be more than 50%.
        if (value > 5000) {
            revert CentralRegistry__InvalidParameter();
        }

        // Update `protocolYieldFee` and `protocolHarvestFee`
        // with new fee.
        protocolYieldFee = uint16(value);
        protocolHarvestFee = uint16(protocolCompoundFee + value);
        emit FeeSet("Yield", value);
    }

    /// @notice Sets the fee taken by Curvance DAO on leverage/deleverage
    ///         via position managers.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      can only have a maximum value of 2%.
    ///      Emits a {FeeSet} event.
    /// @param value The new fee to take on leverage/deleverage when done
    ///              by position managers, in `BPS`.
    function setProtocolLeverageFee(uint256 value) external {
        _checkElevatedPermissions();

        // Leverage fee cannot be more than 2%.
        if (value > 200) {
            revert CentralRegistry__InvalidParameter();
        }

        protocolLeverageFee = uint16(value);
        emit FeeSet("Leverage", value);
    }

    /// @notice Sets the fee taken by Curvance DAO on interest generated.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      can only have a maximum value of 60%.
    ///      Emits an {DefaultInterestFeeSet} event.
    ///      NOTE: `protocolInterestFee` is only used for new markets deployed
    ///            after this function is called and will not impact already
    ///            deployed markets or borrowableCTokens.
    /// @param value The new fee to take on interest generated
    ///              by a debt token, in `BPS`.
    function setDefaultProtocolInterestFee(uint256 value) external {
        _checkElevatedPermissions();

        // Interest fee cannot be more than 60%.
        if (value > 6000) {
            revert CentralRegistry__InvalidParameter();
        }

        defaultProtocolInterestFee = uint16(value);
        emit DefaultInterestFeeSet(value);
    }

    /// @notice Sets the early unlock penalty value for when users unlock
    ///         their veCVE early.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      must be between 30% and 90%, or off, with a value of 0%.
    ///      Emits a {MultiplierSet} event.
    /// @param value The new penalty on early expiring a vote escrowed
    ///              cve position, in `BPS`.
    function setEarlyUnlockPenaltyMultiplier(uint256 value) external {
        _checkElevatedPermissions();

        // Early unlock penalty cannot be more than 90%.
        if (value > 9000) {
            revert CentralRegistry__InvalidParameter();
        }

        // Early unlock penalty cannot be less than 30%,
        // unless its being turned off.
        if (value < 3000 && value != 0) {
            revert CentralRegistry__InvalidParameter();
        }

        earlyUnlockPenaltyMultiplier = value;
        emit MultiplierSet("Early Unlock Penalty", value);
    }

    /// @notice Sets the voting power boost received by locks using
    ///         Continuous Lock mode.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      must be a positive boost i.e. > 1 or greater multiplier.
    ///      Emits a {MultiplierSet} event.
    /// @param value The new voting power boost for continuous lock mode
    ///              vote escrowed cve positions, in `BPS`.
    function setVoteBoostMultiplier(uint256 value) external {
        _checkElevatedPermissions();

        // Voting power boost cannot be less than or equal to 1,
        // unless its being turned off, which is represented with a
        // value of 0.
        if (value <= BPS && value != 0) {
            revert CentralRegistry__InvalidParameter();
        }

        voteBoostMultiplier = value;
        emit MultiplierSet("Vote Boost", value);
    }

    /// @notice Sets the emissions boost received by choosing to lock
    ///         emissions in veCVE.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      must be a positive boost i.e. > 1 or greater multiplier.
    ///      Emits a {MultiplierSet} event.
    /// @param value The new emissions boost for opting to take emissions
    ///              in a vote escrowed cve position instead of liquid CVE,
    ///              in `BPS`.
    function setLockBoostMultiplier(uint256 value) external {
        _checkElevatedPermissions();

        // Locking emissions boost cannot be less than or equal to 1,
        // unless its being turned off, which is represented with a
        // value of 0.
        if (value <= BPS && value != 0) {
            revert CentralRegistry__InvalidParameter();
        }

        lockBoostMultiplier = value;
        emit MultiplierSet("Lock Boost", value);
    }

    /// @notice Sets the maximum slippage users can input with swap
    ///         instructions.
    /// @dev Only callable on a 5-day delay or by the Emergency Council,
    ///      must have a minimum value of 1%, and a maximum value of 20%.
    ///      Emits a {SlippageLimit} event.
    /// @param value The new slippage limit users can input on swap
    ///              instructions, in `BPS`.
    function setSlippageLimit(uint256 value) external {
        _checkElevatedPermissions();

        // Slippage limit cannot be less than 1%, or more than 20%.
        if (value < 100 || value > 2000) {
            revert CentralRegistry__InvalidParameter();
        }

        // Convert input into `WAD` denomination for consistency with strategy
        // calldata denomination.
        slippageLimit = value * 1e14;
        emit SlippageLimit(value);
    }

    /// EMISSIONS LOGIC

    /// @notice Sets the amount of token rewards allocated on this chain,
    ///         for an epoch.
    /// @dev Only callable by the Voting Hub.
    /// @param epoch The epoch having its token emission values set.
    /// @param emissionsAllocated The amount of token rewards allocated on
    ///                           this chain, for an epoch.
    function setEmissionsAllocatedByEpoch(
        uint256 epoch,
        uint256 emissionsAllocated
    ) external {
        if (msg.sender != votingHub) {
            revert CentralRegistry__Unauthorized();
        }

        emissionsAllocatedByEpoch[epoch] = emissionsAllocated;
    }

    /// @notice Sets the target token emissions for each Protocol Era.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    /// @param epochEmissions The initial token emissions value that the
    ///                       protocol should allocate, per epoch.
    function setEraTargetEmissions(uint256 epochEmissions) external {
        _checkElevatedPermissions();

        uint256 numEras = IVotingHub(votingHub).protocolRewardEras();

        for (uint256 i; i < numEras; ++i) {
            targetEmissionAllocationByEra[i] = epochEmissions;
            epochEmissions = epochEmissions / 2;
        }

        emit EraEmissionsAllotmentSet(epochEmissions);
    }

    /// OWNERSHIP LOGIC

    /// @notice Transfers DAO permissions to another address.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {PermissionsTransferred} event.
    /// @param newDaoAddress The new DAO steward address.
    function transferDaoPermissions(address newDaoAddress) public virtual {
        _checkElevatedPermissions();

        // Cache old dao address.
        address previousDaoAddress = daoAddress;
        daoAddress = newDaoAddress;

        // Delete permission data only if the old dao address does not also
        // have Timelock or Emergency Council permissions.
        if (previousDaoAddress != emergencyCouncil) {
            if (previousDaoAddress != timelock) {
                delete hasDaoPermissions[previousDaoAddress];
            }
        }

        // Add new permission data.
        hasDaoPermissions[newDaoAddress] = true;
        emit PermissionsTransferred(
            "DAO Permissions",
            previousDaoAddress,
            newDaoAddress
        );

        // Notify Timelock of a DAO address update.
        if (timelock != address(0)) {
            if (
                ERC165Checker.supportsInterface(
                    timelock,
                    type(ITimelock).interfaceId
                )
            ) {
                ITimelock(timelock).updateRoles();
            }
        }
    }

    /// @notice Transfers Timelock permissions to another address.
    /// @dev Only callable by the Emergency Council.
    ///      Emits a {PermissionsTransferred} event.
    /// @param newTimelock The new timelock address.
    function transferTimelockPermissions(address newTimelock) external {
        _checkEmergencyCouncilPermissions();

        if (
            !ERC165Checker.supportsInterface(
                newTimelock,
                type(ITimelock).interfaceId
            )
        ) {
            revert CentralRegistry__InvalidParameter();
        }

        // Cache old timelock.
        address previousTimelock = timelock;
        timelock = newTimelock;

        // If the previous Timelock also has Emergency Council permissions
        // for some reason, do not remove their elevated permissioning.
        if (previousTimelock != emergencyCouncil) {
            delete hasElevatedPermissions[previousTimelock];
            delete hasMarketPermissions[previousTimelock];
            emit PermissionsUpdated("Market", previousTimelock, false);

            // If the previous Timelock also has DAO permissions
            // for some reason, do not remove their permissioning.
            if (previousTimelock != daoAddress) {
                delete hasDaoPermissions[previousTimelock];
            }
        }

        // Add new permission data.
        hasDaoPermissions[newTimelock] = true;
        hasElevatedPermissions[newTimelock] = true;
        emit PermissionsTransferred(
            "Timelock",
            previousTimelock,
            newTimelock
        );

        // Assign market permissions only if the new address does
        // not already have them.
        if (!hasMarketPermissions[newTimelock]) {
            hasMarketPermissions[newTimelock] = true;
            emit PermissionsUpdated("Market", newTimelock, true);
        }

        // Update timelock roles.
        ITimelock(newTimelock).updateRoles();
    }

    /// @notice Transfers Emergency Council permissions to another address.
    /// @dev Only callable by the Emergency Council.
    ///      Emits a {PermissionsTransferred} event.
    /// @param newEmergencyCouncil The new emergency council address.
    function transferEmergencyCouncil(address newEmergencyCouncil) external {
        _checkEmergencyCouncilPermissions();

        // Cache old emergency council.
        address previousEmergencyCouncil = emergencyCouncil;
        emergencyCouncil = newEmergencyCouncil;
        
        // If the previous Emergency Council also has timelock permissions
        // for some reason, do not remove their elevated permissioning.
        if (previousEmergencyCouncil != timelock) {
            delete hasElevatedPermissions[previousEmergencyCouncil];
            delete hasMarketPermissions[previousEmergencyCouncil];
            emit PermissionsUpdated(
                "Market",
                previousEmergencyCouncil,
                false
            );

            // If the previous Emergency Council also has DAO permissions
            // for some reason, do not remove their permissioning.
            if (previousEmergencyCouncil != daoAddress) {
                delete hasDaoPermissions[previousEmergencyCouncil];
            }
        }

        // Add new permission data.
        hasDaoPermissions[newEmergencyCouncil] = true;
        hasElevatedPermissions[newEmergencyCouncil] = true;
        emit PermissionsTransferred(
            "Emergency Council",
            previousEmergencyCouncil,
            newEmergencyCouncil
        );

        // Assign market permissions only if the new address does
        // not already have them.
        if (!hasMarketPermissions[newEmergencyCouncil]) {
            hasMarketPermissions[newEmergencyCouncil] = true;
            emit PermissionsUpdated("Market", newEmergencyCouncil, true);
        }

        // Notify Timelock of an Emergency Council address update.
        if (timelock != address(0)) {
            if (
                ERC165Checker.supportsInterface(
                    timelock,
                    type(ITimelock).interfaceId
                )
            ) {
                ITimelock(timelock).updateRoles();
            }
        }
    }

    /// @notice Adds a new Market Manager.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {PermissionsUpdated} events.
    /// @param newMarket The new Market Manager contract to support for use
    ///                  in Curvance.
    function addMarketManager(address newMarket) external virtual {
        _checkElevatedPermissions();

        // Validate `newMarket` is not currently supported.
        if (isMarketManager[newMarket]) {
            revert CentralRegistry__InvalidParameter();
        }

        // Validate that `newMarket` is a Market Manager.
        if (
            !ERC165Checker.supportsInterface(
                newMarket,
                type(IMarketManager).interfaceId
            )
        ) {
            revert CentralRegistry__InvalidParameter();
        }

        // We store supported markets semi redundantly for offchain querying.
        _marketManagers.push(newMarket);
        isMarketManager[newMarket] = true;

        emit PermissionsUpdated("Market Manager", newMarket, true);
    }

    /// @notice Removes a current Market Manager from Curvance.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Has to be a supported Market Manager contract prior.
    ///      Emits a {PermissionsUpdated} event.
    /// @param marketApproved The supported Market Manager contract to remove
    ///                       from Curvance.
    function removeMarketManager(address marketApproved) public virtual {
        _checkElevatedPermissions();

        // Validate `marketApproved` is a currently recognized Market Manager.
        if (!isMarketManager[marketApproved]) {
            revert CentralRegistry__InvalidParameter();
        }

        delete isMarketManager[marketApproved];

        // Cache market list.
        uint256 numMarkets = _marketManagers.length;
        uint256 marketIndex = numMarkets;

        for (uint256 i; i < numMarkets; ++i) {
            if (_marketManagers[i] == marketApproved) {
                marketIndex = i;
                break;
            }
        }

        // Validate we found the market and remove 1 from numMarkets
        // so it corresponds to last element index now (starting at index 0).
        // This is an additional runtime invariant check for extra security.
        if (marketIndex >= numMarkets--) {
            revert CentralRegistry__InvalidParameter();
        }

        // Copy last `_marketManagers` slot to `marketIndex` slot.
        _marketManagers[marketIndex] = _marketManagers[numMarkets];
        // Remove the last element to remove `marketApproved`
        // from _marketManagers list.
        _marketManagers.pop();
        emit PermissionsUpdated("Market Manager", marketApproved, false);
    }

    /// @notice Adds an approved address to create locks for other
    ///         addresses inside Curvance.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Cannot have locking permissions prior.
    ///      Emits a {PermissionsUpdated} event.
    /// @param newAddress The new address to approve lock creation authority
    ///                   inside Curvance.
    function addLockingPermissions(address newAddress) external {
        _checkElevatedPermissions();

        // Validate `newAddress` is not currently supported.
        if (hasLockingPermissions[newAddress]) {
            revert CentralRegistry__InvalidParameter();
        }

        hasLockingPermissions[newAddress] = true;
        emit PermissionsUpdated("Locking", newAddress, true);
    }

    /// @notice Removes an approved address to create locks for other
    ///         addresses inside Curvance.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Has to have locking permissions prior.
    ///      Emits a {PermissionsUpdated} event.
    /// @param addressApproved The approved address to remove lock
    ///                        creation authority inside Curvance.
    function removeLockingPermissions(address addressApproved) external {
        _checkElevatedPermissions();

        // Validate `addressApproved` is currently supported.
        if (!hasLockingPermissions[addressApproved]) {
            revert CentralRegistry__InvalidParameter();
        }

        delete hasLockingPermissions[addressApproved];
        emit PermissionsUpdated("Locking", addressApproved, false);
    }

    /// @notice Authorizes an address to manage auction process.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Cannot be a supported Atlas controller address prior.
    ///      Emits a {AtlasControlAuthorized} event.
    /// @param newAddress The address to add auction permissions to
    ///                   inside Curvance.
    function addAuctionPermissions(address newAddress) external {
        _checkElevatedPermissions();

        // Validate `newAddress` is not currently supported.
        if (hasAuctionPermissions[newAddress]) {
            revert CentralRegistry__InvalidParameter();
        }

        hasAuctionPermissions[newAddress] = true;
        emit PermissionsUpdated("Auction", newAddress, true);
    }

    /// @notice Deauthorizes an address to manage auction process.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Cannot be a supported Atlas controller address prior.
    ///      Emits a {AtlasControlAuthorized} event.
    /// @param addressApproved The address to remove auction permissions from
    ///                        inside Curvance.
    function removeAuctionPermissions(address addressApproved) external {
        _checkElevatedPermissions();

        // Validate `addressApproved` is currently supported.
        if (!hasAuctionPermissions[addressApproved]) {
            revert CentralRegistry__InvalidParameter();
        }

        delete hasAuctionPermissions[addressApproved];
        emit PermissionsUpdated("Auction", addressApproved, false);
    }

    /// @notice Authorizes an address to manage markets.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Cannot be a supported Harvester contract prior.
    ///      Emits a {PermissionsUpdated} event.
    ///      NOTE: Market Permissioned contracts should have corresponding
    ///            restrictions handled within the contract itself such as
    ///            enforcing a specific party to pause but not unpause
    ///            markets.
    /// @param newAddress The address to add market permissions to
    ///                   inside Curvance.
    function addMarketPermissions(address newAddress) external {
        _checkElevatedPermissions();

        // Validate `newAddress` is not currently supported.
        if (hasMarketPermissions[newAddress]) {
            revert CentralRegistry__InvalidParameter();
        }

        hasMarketPermissions[newAddress] = true;
        emit PermissionsUpdated("Market", newAddress, true);
    }

    //// @notice Deauthorizes an address to manage markets.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {PermissionsUpdated} event.
    ///      NOTE: Market Permissioned contracts should have corresponding
    ///            restrictions handled within the contract itself such as
    ///            enforcing a specific party to pause but not unpause
    ///            markets.
    /// @param addressApproved The address to remove market permissions from
    ///                        inside Curvance.
    function removeMarketPermissions(address addressApproved) external {
        _checkElevatedPermissions();

        // Validate `addressApproved` is currently supported.
        if (!hasMarketPermissions[addressApproved]) {
            revert CentralRegistry__InvalidParameter();
        }

        delete hasMarketPermissions[addressApproved];
        emit PermissionsUpdated("Market", addressApproved, false);
    }

    //// @notice Authorizes an address to manage harvest process.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Cannot be a supported Harvester contract prior.
    ///      Emits a {PermissionsUpdated} event.
    /// @param newAddress The address to add harvest permissions to
    ///                   inside Curvance.
    function addHarvestPermissions(address newAddress) external {
        _checkElevatedPermissions();

        // Validate `newAddress` is not currently supported.
        if (hasHarvestPermissions[newAddress]) {
            revert CentralRegistry__InvalidParameter();
        }

        hasHarvestPermissions[newAddress] = true;
        emit PermissionsUpdated("Harvest", newAddress, true);
    }

    //// @notice Deauthorizes an address to manage harvest process.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Has to be a supported Harvester contract prior.
    ///      Emits a {PermissionsUpdated} event.
    /// @param addressApproved The address to remove harvest permissions from
    ///                        from inside Curvance.
    function removeHarvestPermissions(address addressApproved) external {
        _checkElevatedPermissions();

        // Validate `addressApproved` is currently supported.
        if (!hasHarvestPermissions[addressApproved]) {
            revert CentralRegistry__InvalidParameter();
        }

        delete hasHarvestPermissions[addressApproved];
        emit PermissionsUpdated("Harvest", addressApproved, false);
    }

    /// CROSSCHAIN SUPPORT LOGIC

    /// @notice Adds support for a new chain.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {NewChainAdded} event.
    /// @param chainId GETH Chain ID of the chain to support.
    /// @param config ChainConfig struct for new chain to support.
    ///               Containing:
    ///               isSupported Whether `chainId` is currently supported
    ///                           or not.
    ///               messagingChainId Messaging Chain ID where this address
    ///                         authorized.
    ///               domain Domain for the chain.
    ///               messagingHub Address for new chain's Messaging Hub.
    ///               votingHub Address for new chain's Voting Hub.
    ///               cveAddress CVE address on the chain.
    ///               feeTokenAddress Fee token address on the chain.
    ///               crosschainRelayer Crosschain relayer address on the chain.
    function addChain(
        uint256 chainId,
        ChainConfig memory config
    ) external {
        _checkElevatedPermissions();

        // Validate `chainId` is not currently supported, and `config`
        // is configured properly to support `chainId`.
        if (chainConfig[chainId].isSupported || !config.isSupported) {
            revert CentralRegistry__InvalidParameter();
        }

        // Prevent `chainId` from being 0 to avoid confusion with
        // non-existent mappings.
        if (chainId == 0) {
            revert CentralRegistry__InvalidParameter();
        }

        // Ensure `messagingChainId` is not already mapped to another chain.
        if (messagingToGETHChainId[config.messagingChainId] != 0) {
            revert CentralRegistry__InvalidParameter();
        }

        chainConfig[chainId] = config;
        messagingToGETHChainId[config.messagingChainId] = chainId;
        _foreignChainIds.push(chainId);
        ++supportedChains;

        emit NewChain(chainId, config);
    }

    /// @notice Removes support for a chain.
    /// @dev Callable by an address with DAO Authority or higher.
    ///      Emits a {RemovedChain} event.
    /// @param chainId GETH Chain ID where `currentMessagingHub` is
    ///                authorized.
    /// @param expectedMessagingHub Expected Address for `chainId` Messaging
    ///                             Hub.
    /// @param expectedVotingHub Expected Address for `chainId` Voting Hub.
    function removeChain(
        uint256 chainId,
        address expectedMessagingHub,
        address expectedVotingHub
    ) external {
        _checkElevatedPermissions();

        ChainConfig memory c = chainConfig[chainId];

        // Validate that `chainId` is currently supported and parameters
        // are correct.
        if (!c.isSupported || c.messagingHub != expectedMessagingHub ||
            c.votingHub != expectedVotingHub
        ) {
            revert CentralRegistry__InvalidParameter();
        }

        // Remove chain support from protocol.
        delete chainConfig[chainId];
        // Remove messagingChainId <> GETH chainId mapping table reference.
        delete messagingToGETHChainId[c.messagingChainId];
        // Decrease supportedChains.
        --supportedChains;

        uint256 numForeignChainIds = _foreignChainIds.length;
        uint256 i;
        for (; i < numForeignChainIds; ++i) {
            if (_foreignChainIds[i] == chainId) {
                break;
            }
        }

        numForeignChainIds--;

        for (; i < numForeignChainIds; ++i) {
            _foreignChainIds[i] = _foreignChainIds[i + 1];
        }

        _foreignChainIds.pop();
        emit RemovedChain(chainId, expectedMessagingHub, expectedVotingHub);
    }

    /// @notice Returns the Crosschain Messaging Protocol's internal ChainId
    ///         corresponding to GETH's `chainId`.
    /// @param chainId The GETH chainId.
    /// @return The Crosschain Messaging Protocol's internal ChainId
    ///         corresponding to GETH's `chainId`.
    function GETHToMessagingChainId(
        uint256 chainId
    ) external view returns(uint256) {
        return chainConfig[chainId].messagingChainId;
    }

    /// AUCTION CONFIGURATION LOGIC

    /// @notice Unlocks a market to process auction-based liquidations.
    /// @param marketToUnlock The address of the Market Manager to unlock
    ///                       auction-based liquidations.
    function unlockAuctionForMarket(address marketToUnlock) external {
        if (!hasAuctionPermissions[msg.sender]) {
            revert CentralRegistry__Unauthorized();
        }

        // Validate that they are unlocking an approved Market Manager.
        if (!isMarketManager[marketToUnlock]) {
            revert CentralRegistry__InvalidParameter();
        }

        uint256 marketToUnlockUint = uint256(uint160(marketToUnlock));
        /// @solidity memory-safe-assembly
        assembly {
            tstore(_TRANSIENT_MARKET_UNLOCKED_KEY, marketToUnlockUint)
        }
    }

    /// @notice Relocks a market for auction-based liquidations.
    /// @param marketToLock The address of the Market Manager to lock
    ///                     auction-based liquidations.
    function resetAuctionForMarket(address marketToLock) external {
        if (!hasAuctionPermissions[msg.sender]) {
            revert CentralRegistry__Unauthorized();
        }

        uint256 result;
        /// @solidity memory-safe-assembly
        assembly {
            result := tload(_TRANSIENT_MARKET_UNLOCKED_KEY)
        }

        // Validate that they are locking the currently unlocked
        // Market Manager.
        if (uint256(uint160(marketToLock)) != result) {
            revert CentralRegistry__InvalidParameter();
        }

        /// @solidity memory-safe-assembly
        assembly {
            tstore(_TRANSIENT_MARKET_UNLOCKED_KEY, 0)
        }
    }

    /// @notice Returns whether the caller is approved to execute
    ///         auction-based liquidations with a specific liquidation bonus.
    function isMarketUnlocked() public view returns (bool isUnlocked) {
        uint256 result;
        /// @solidity memory-safe-assembly
        assembly {
            result := tload(_TRANSIENT_MARKET_UNLOCKED_KEY)
        }

        // CASE: This is not an Auction tx, so allow all markets,
        // and return false, the caller is not approved for auction-based
        // liquidations. 
        if (result == 0) {
            return isUnlocked;
        }

        // True if the caller is approved for auction-based liquidations,
        // otherwise false.
        isUnlocked = uint256(uint160(msg.sender)) == result;
    }

    /// CONTRACT MAPPING LOGIC

    /// @notice Sets an external calldata checker contract.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CalldataCheckerSet} event.
    /// @param target The target contract for external calldata
    ///               such as 1Inch V5.
    /// @param checker The contract that will check calldata prior to
    ///                execution in `target`.
    function setExternalCalldataChecker(
        address target,
        address checker
    ) external {
        _checkElevatedPermissions();

        externalCalldataChecker[target] = checker;
        emit CalldataCheckerSet("External", target, checker);
    }

    /// @notice Sets a multicall calldata checker contract.
    /// @dev Only callable on a 5-day delay or by the Emergency Council.
    ///      Emits a {CalldataCheckerSet} event.
    /// @param target The target contract for external calldata
    ///               such as Pyth or Redstone.
    /// @param checker The contract that will check calldata prior to
    ///                execution in `target`.
    function setMulticallChecker(address target, address checker) external {
        _checkElevatedPermissions();

        multicallChecker[target] = checker;
        emit CalldataCheckerSet("Multicall", target, checker);
    }

    /// @notice Returns an array of Chain IDs recorded in the GETH format.
    function foreignChainIds() external view returns (uint256[] memory) {
        return _foreignChainIds;
    }

    /// @notice Returns an array of Curvance markets on this chain.
    function marketManagers() external view returns (address[] memory) {
        return _marketManagers;
    }

    /// PUBLIC FUNCTIONS ///

    /// @notice Returns true if this contract implements the interface defined
    ///         by `interfaceId`.
    /// @param interfaceId The interface to check for implementation.
    /// @return Whether `interfaceId` is implemented or not.
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override returns (bool) {
        return
            interfaceId == type(ICentralRegistry).interfaceId ||
            interfaceId == type(IActionRegistry).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /// INTERNAL FUNCTIONS ///

    /// @dev Checks whether the caller has sufficient permissioning.
    function _checkEmergencyCouncilPermissions() internal view {
        if (msg.sender != emergencyCouncil) {
            revert CentralRegistry__Unauthorized();
        }
    }

    /// @dev Checks whether the caller has sufficient permissioning.
    function _checkDaoPermissions() internal view {
        if (!hasDaoPermissions[msg.sender]) {
            revert CentralRegistry__Unauthorized();
        }
    }

    /// @dev Checks whether the caller has sufficient permissioning.
    function _checkElevatedPermissions() internal view {
        if (!hasElevatedPermissions[msg.sender]) {
            revert CentralRegistry__Unauthorized();
        }
    }

    /// @notice Checks whether a core contract should be allowed to be set.
    /// @dev If the contract is already set and needs to be updated, make sure
    ///      reward system as not already started, ossifying contracts.
    function _checkCanSetCoreContract(address coreContract) internal view {
        if (coreContract == address(0)) {
            return;
        }

        if (genesisEpoch <= block.timestamp) {
            revert CentralRegistry__EpochHasStarted();
        }
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"dao","type":"address"},{"internalType":"address","name":"ec","type":"address"},{"internalType":"uint256","name":"genesisEpoch_","type":"uint256"},{"internalType":"address","name":"sequencer_","type":"address"},{"internalType":"address","name":"feeToken_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ActionRegistry__CooldownActive","type":"error"},{"inputs":[],"name":"ActionRegistry__InvalidParams","type":"error"},{"inputs":[],"name":"CentralRegistry__EpochHasStarted","type":"error"},{"inputs":[],"name":"CentralRegistry__InvalidParameter","type":"error"},{"inputs":[],"name":"CentralRegistry__Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"newIndex","type":"uint256"}],"name":"ApprovalIndexIncremented","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"calldataType","type":"string"},{"indexed":false,"internalType":"address","name":"targetAddress","type":"address"},{"indexed":false,"internalType":"address","name":"calldataChecker","type":"address"}],"name":"CalldataCheckerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"contractType","type":"string"},{"indexed":false,"internalType":"address","name":"addressUpdated","type":"address"},{"indexed":false,"internalType":"bool","name":"isAdded","type":"bool"}],"name":"ContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"userLockCooldown","type":"uint256"}],"name":"CooldownSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"coreType","type":"string"},{"indexed":false,"internalType":"address","name":"core","type":"address"}],"name":"CoreContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"DefaultInterestFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"delegable","type":"bool"},{"indexed":false,"internalType":"uint256","name":"delegationEnabledTimestamp","type":"uint256"}],"name":"DelegableStatusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newDomain","type":"uint32"}],"name":"DomainSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochEmissionAllotment","type":"uint256"}],"name":"EraEmissionsAllotmentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"fee","type":"string"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"FeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"FeeTokenSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newGenesisEpoch","type":"uint256"}],"name":"GenesisEpochUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"multiplier","type":"string"},{"indexed":false,"internalType":"uint256","name":"newMultiplier","type":"uint256"}],"name":"MultiplierSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"components":[{"internalType":"bool","name":"isSupported","type":"bool"},{"internalType":"uint16","name":"messagingChainId","type":"uint16"},{"internalType":"uint32","name":"domain","type":"uint32"},{"internalType":"address","name":"messagingHub","type":"address"},{"internalType":"address","name":"votingHub","type":"address"},{"internalType":"address","name":"cveAddress","type":"address"},{"internalType":"address","name":"feeTokenAddress","type":"address"},{"internalType":"address","name":"crosschainRelayer","type":"address"}],"indexed":false,"internalType":"struct ChainConfig","name":"config","type":"tuple"}],"name":"NewChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"permissionsType","type":"string"},{"indexed":false,"internalType":"address","name":"previousAddress","type":"address"},{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"PermissionsTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"permissionsType","type":"string"},{"indexed":false,"internalType":"address","name":"addressUpdated","type":"address"},{"indexed":false,"internalType":"bool","name":"isAdded","type":"bool"}],"name":"PermissionsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"address","name":"messagingHub","type":"address"},{"indexed":false,"internalType":"address","name":"votingHub","type":"address"}],"name":"RemovedChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newSlippage","type":"uint256"}],"name":"SlippageLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"isLocked","type":"bool"},{"indexed":false,"internalType":"uint256","name":"transferEnabledTimestamp","type":"uint256"}],"name":"TransferableStatusChanged","type":"event"},{"inputs":[],"name":"EPOCH_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"GETHToMessagingChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SEQUENCER_ORACLE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"addAuctionPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"components":[{"internalType":"bool","name":"isSupported","type":"bool"},{"internalType":"uint16","name":"messagingChainId","type":"uint16"},{"internalType":"uint32","name":"domain","type":"uint32"},{"internalType":"address","name":"messagingHub","type":"address"},{"internalType":"address","name":"votingHub","type":"address"},{"internalType":"address","name":"cveAddress","type":"address"},{"internalType":"address","name":"feeTokenAddress","type":"address"},{"internalType":"address","name":"crosschainRelayer","type":"address"}],"internalType":"struct ChainConfig","name":"config","type":"tuple"}],"name":"addChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"addHarvestPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"addLockingPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMarket","type":"address"}],"name":"addMarketManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"addMarketPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"chainConfig","outputs":[{"internalType":"bool","name":"isSupported","type":"bool"},{"internalType":"uint16","name":"messagingChainId","type":"uint16"},{"internalType":"uint32","name":"domain","type":"uint32"},{"internalType":"address","name":"messagingHub","type":"address"},{"internalType":"address","name":"votingHub","type":"address"},{"internalType":"address","name":"cveAddress","type":"address"},{"internalType":"address","name":"feeTokenAddress","type":"address"},{"internalType":"address","name":"crosschainRelayer","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"checkNewDelegationDisabled","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"checkTransfersDisabled","outputs":[{"internalType":"bool","name":"result","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crosschainCore","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"crosschainRelayer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultProtocolInterestFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"domain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"earlyUnlockPenaltyMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyCouncil","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"emissionsAllocatedByEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"externalCalldataChecker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"foreignChainIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gaugeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasAuctionPermissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasDaoPermissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasElevatedPermissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasHarvestPermissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasLockingPermissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasMarketPermissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incrementApprovalIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isMarketManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMarketUnlocked","outputs":[{"internalType":"bool","name":"isUnlocked","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockBoostMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketManagers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messageTransmitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messagingHub","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"messagingToGETHChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"multicallChecker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolCompoundFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolHarvestFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolLeverageFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolYieldFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addressApproved","type":"address"}],"name":"removeAuctionPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"expectedMessagingHub","type":"address"},{"internalType":"address","name":"expectedVotingHub","type":"address"}],"name":"removeChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addressApproved","type":"address"}],"name":"removeHarvestPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addressApproved","type":"address"}],"name":"removeLockingPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketApproved","type":"address"}],"name":"removeMarketManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addressApproved","type":"address"}],"name":"removeMarketPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketToLock","type":"address"}],"name":"resetAuctionForMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newCVE","type":"address"}],"name":"setCVE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"cooldown","type":"uint256"}],"name":"setCooldown","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newCrosschainCore","type":"address"}],"name":"setCrosschainCore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newCrosschainRelayer","type":"address"}],"name":"setCrosschainRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setDefaultProtocolInterestFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"delegationDisabled","type":"bool"}],"name":"setDelegableStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"newDomain","type":"uint32"}],"name":"setDomain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setEarlyUnlockPenaltyMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"internalType":"uint256","name":"emissionsAllocated","type":"uint256"}],"name":"setEmissionsAllocatedByEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"epochEmissions","type":"uint256"}],"name":"setEraTargetEmissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"checker","type":"address"}],"name":"setExternalCalldataChecker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newFeeToken","type":"address"}],"name":"setFeeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newGaugeManager","type":"address"}],"name":"setGaugeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newGenesisEpoch","type":"uint256"}],"name":"setGenesisEpoch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setLockBoostMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTransmitter","type":"address"}],"name":"setMessageTransmitter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMessagingHub","type":"address"}],"name":"setMessagingHub","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"checker","type":"address"}],"name":"setMulticallChecker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOracleManager","type":"address"}],"name":"setOracleManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setProtocolCompoundFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setProtocolLeverageFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setProtocolYieldFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRewardManager","type":"address"}],"name":"setRewardManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setSlippageLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTokenMessager","type":"address"}],"name":"setTokenMessager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"transferDisabled","type":"bool"}],"name":"setTransferableStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVeCVE","type":"address"}],"name":"setVeCVE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setVoteBoostMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newVotingHub","type":"address"}],"name":"setVotingHub","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slippageLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supportedChains","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"targetEmissionAllocationByEra","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelock","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenMessager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newDaoAddress","type":"address"}],"name":"transferDaoPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newEmergencyCouncil","type":"address"}],"name":"transferEmergencyCouncil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTimelock","type":"address"}],"name":"transferTimelockPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketToUnlock","type":"address"}],"name":"unlockAuctionForMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"userApprovalIndex","outputs":[{"internalType":"uint256","name":"r","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"veCVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voteBoostMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"votingHub","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a0604052666a94d74f4300006012556013805463ffffffff19166305dc0064179081905561003a9061ffff620100009091041660646102a4565b6013805465ffff0000ffff60201b191664010000000061ffff939093169290920261ffff60401b1916919091176907d00000000000000000179055348015610080575f5ffd5b50604051613cf2380380613cf283398101604081905261009f916102eb565b6001600160a01b0385166100b1573394505b6001600160a01b0384166100c3573393505b6361ce8e508310156100e85760405163ee3a89bd60e01b815260040160405180910390fd5b600280546001600160a01b038088166001600160a01b031992831617909255600480549287169290911691909117905560405161013a906e44414f205065726d697373696f6e7360881b8152600f0190565b604080519182900382205f83526001600160a01b0388166020840152915f516020613cd25f395f51905f52910160405180910390a260405170115b595c99d95b98de4810dbdd5b98da5b607a1b8152601101604080519182900382205f83526001600160a01b0387166020840152915f516020613cd25f395f51905f52910160405180910390a26001600160a01b038581165f908152602080805260408083208054600160ff19918216811790925594891684528184208054861682179055602483528184208054861682179055602190925291829020805490931617909155516513585c9ad95d60d21b8152600601604080519182900382206001600160a01b038716835260016020840152917f40f7b3ef64c9e38288873dda008188d6c3cd146f84d77b978478a8731f71feb9910160405180910390a26001929092556001600160a01b03908116608052600580546001600160a01b03191691909216179055506103459050565b61ffff81811683821601908111156102ca57634e487b7160e01b5f52601160045260245ffd5b92915050565b80516001600160a01b03811681146102e6575f5ffd5b919050565b5f5f5f5f5f60a086880312156102ff575f5ffd5b610308866102d0565b9450610316602087016102d0565b93506040860151925061032b606087016102d0565b9150610339608087016102d0565b90509295509295909350565b60805161397561035d5f395f610b7e01526139755ff3fe608060405234801561000f575f5ffd5b5060043610610587575f3560e01c80637d793087116102d9578063cb58bf2711610186578063dc75d503116100ef578063e6248d55116100a9578063f07125b311610084578063f07125b314610e69578063f0a8efce14610e7c578063fe57648414610e85578063ff7127eb14610e9d575f5ffd5b8063e6248d5514610dfd578063ea3437e814610e2e578063ec32249814610e56575f5ffd5b8063dc75d50314610d7b578063de0c7a7114610d8f578063df018e4214610db1578063e2dfa13014610dc4578063e3a9841c14610dd7578063e524d12a14610dea575f5ffd5b8063d7dd0b2b11610140578063d7dd0b2b14610cf4578063d8cfc7f014610d07578063da88d9d314610d1a578063db2a1a8114610d42578063db8a5fd814610d55578063dc0aae5414610d68575f5ffd5b8063cb58bf2714610c80578063cbda3cee14610c93578063ce517dc714610ca6578063d0fb020314610cb9578063d33219b414610ccc578063d68dbfe414610cdf575f5ffd5b8063b0990e2111610242578063b9237f7d116101fc578063c19b4bfa116101d7578063c19b4bfa14610c1b578063c2fb26a614610c2e578063c3a1ebb714610c5a578063c4f63cb514610c6d575f5ffd5b8063b9237f7d14610be2578063bdd8400714610bf5578063bf8d223414610c08575f5ffd5b8063b0990e2114610b63578063b0ff43f514610b79578063b128de9d14610ba0578063b51665f914610bb3578063b70e6be614610bc6578063b86c886f14610bcf575f5ffd5b80639874482d116102935780639874482d14610aec5780639dd9fd1714610aff578063a409870e14610b12578063a70b9f0c14610b25578063abd5d9d214610b2f578063ae50130e14610b50575f5ffd5b80637d79308714610a765780637e602baa14610a89578063816949b514610a9c5780638a0828bc14610aa5578063929e2e0814610ac65780639616756e14610ad9575f5ffd5b806340370e3d116104375780635b5c6b77116103a05780636cd54a741161035a57806376b4a6231161033557806376b4a62314610a195780637778960e14610a2e5780637b04c18114610a415780637d5528bd14610a54575f5ffd5b80636cd54a74146109e0578063731a555d146109f357806373578c6714610a06575f5ffd5b80635b5c6b771461095b5780635f486a5414610975578063647846a51461099457806364f82aa4146109a75780636888ce09146109ba5780636bee0479146109cd575f5ffd5b80634fc3f41a116103f15780634fc3f41a146108fc5780635123f92c1461090f5780635331272314610922578063565d878c14610937578063572e2fa21461094a5780635b07871a14610952575f5ffd5b806340370e3d146108aa57806345c18b2e146108bd578063472d35b9146108d0578063476343ee146108e35780634a01623d146108eb5780634b6ffb18146108f3575f5ffd5b8063153ee554116104f3578063254c3175116104ad5780632c3400ea116104885780632c3400ea146108495780632dd74d1d1461085c578063323a198a1461086f5780633a88faf114610897575f5ffd5b8063254c3175146107f5578063264b1dc014610814578063287530f714610827575f5ffd5b8063153ee5541461078357806315cce2241461079657806315d02493146107a95780631fe4ba17146107bc5780632131c68c146107cf578063231fa01f146107e2575f5ffd5b80630c9cefdd116105445780630c9cefdd146106da5780630d34766b146107075780630df00074146107105780630f4ef8a61461072357806310eec0001461074e578063119e4f3014610770575f5ffd5b80630168956a1461058b57806301ffc9a7146105a05780630225e243146105c85780630a456bbc146105ea5780630a70b056146105fd5780630b6893df146106c7575b5f5ffd5b61059e610599366004613467565b610ebf565b005b6105b36105ae366004613480565b610f4e565b60405190151581526020015b60405180910390f35b6105b36105d6366004613467565b60246020525f908152604090205460ff1681565b61059e6105f8366004613467565b610f9e565b61066e61060b3660046134a7565b60196020525f90815260409020805460018201546002830154600384015460049094015460ff84169461ffff6101008604169463ffffffff6301000000820416946001600160a01b03600160381b90920482169490821693908216928216911688565b60408051981515895261ffff909716602089015263ffffffff909516958701959095526001600160a01b0392831660608701529082166080860152811660a085015291821660c08401521660e0820152610100016105bf565b61059e6106d53660046134cd565b611019565b6106f96106e83660046134a7565b601c6020525f908152604090205481565b6040519081526020016105bf565b6106f9600f5481565b61059e61071e366004613467565b6110f3565b600854610736906001600160a01b031681565b6040516001600160a01b0390911681526020016105bf565b6105b361075c366004613467565b60256020525f908152604090205460ff1681565b61059e61077e3660046134e6565b61118c565b61059e610791366004613467565b6111c8565b61059e6107a4366004613467565b61121f565b61059e6107b7366004613467565b611291565b61059e6107ca3660046134a7565b611308565b600254610736906001600160a01b031681565b61059e6107f03660046134a7565b611381565b6106f96108033660046134a7565b601b6020525f908152604090205481565b61059e6108223660046134a7565b611437565b6105b3610835366004613467565b60236020525f908152604090205460ff1681565b61059e610857366004613467565b6114fb565b600d54610736906001600160a01b031681565b61073661087d366004613467565b601f6020525f90815260409020546001600160a01b031681565b61059e6108a53660046134a7565b611541565b61059e6108b8366004613467565b61161e565b61059e6108cb3660046134cd565b61167f565b61059e6108de366004613467565b61174e565b61059e61178b565b61059e61180f565b6106f960105481565b61059e61090a3660046134a7565b611886565b601454610736906001600160a01b031681565b61092a6119b4565b6040516105bf9190613506565b600a54610736906001600160a01b031681565b6105b3611a14565b6106f960125481565b60135461073690600160501b90046001600160a01b031681565b6106f9610983366004613562565b601a6020525f908152604090205481565b600554610736906001600160a01b031681565b61059e6109b5366004613467565b611a36565b61059e6109c8366004613467565b611a7d565b61059e6109db366004613467565b611b21565b61059e6109ee366004613467565b611ba6565b61059e610a013660046134a7565b611bf4565b6105b3610a14366004613467565b611c6e565b610a21611d14565b6040516105bf919061357b565b600454610736906001600160a01b031681565b601654610736906001600160a01b031681565b6105b3610a62366004613467565b601d6020525f908152604090205460ff1681565b61059e610a843660046134a7565b611d69565b61059e610a973660046135b2565b611dc0565b6106f960175481565b601354610ab39061ffff1681565b60405161ffff90911681526020016105bf565b61059e610ad4366004613467565b61204f565b6105b3610ae7366004613467565b612091565b61059e610afa366004613467565b612135565b61059e610b0d3660046134a7565b612173565b61059e610b20366004613467565b6121ca565b6106f96212750081565b6105b3610b3d366004613467565b602080525f908152604090205460ff1681565b61059e610b5e3660046134a7565b612247565b601354610ab390640100000000900461ffff1681565b6107367f000000000000000000000000000000000000000000000000000000000000000081565b61059e610bae366004613467565b6122aa565b61059e610bc1366004613467565b6122eb565b6106f960015481565b61059e610bdd3660046135eb565b6124a5565b61059e610bf0366004613467565b61253e565b61059e610c03366004613467565b61262e565b61059e610c1636600461362f565b612896565b61059e610c293660046134a7565b6128f2565b601654610c4590600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016105bf565b61059e610c68366004613467565b612977565b61059e610c7b366004613648565b6129e6565b600c54610736906001600160a01b031681565b600954610736906001600160a01b031681565b61059e610cb43660046134a7565b612bf0565b600b54610736906001600160a01b031681565b600354610736906001600160a01b031681565b601354610ab390600160401b900461ffff1681565b61059e610d02366004613467565b612c81565b61059e610d15366004613467565b612cc3565b6106f9610d283660046134a7565b5f90815260196020526040902054610100900461ffff1690565b61059e610d50366004613467565b612d19565b61059e610d63366004613467565b612f8d565b61059e610d76366004613467565b61300a565b601354610ab39062010000900461ffff1681565b6105b3610d9d366004613467565b60216020525f908152604090205460ff1681565b600654610736906001600160a01b031681565b601554610736906001600160a01b031681565b61059e610de53660046135eb565b6130fc565b61059e610df8366004613467565b61314c565b6106f9610e0b366004613467565b6001600160a01b03165f908152602081905260409020546001600160781b031690565b610736610e3c366004613467565b601e6020525f90815260409020546001600160a01b031681565b61059e610e64366004613467565b6131c3565b600754610736906001600160a01b031681565b6106f960115481565b601354610ab3906601000000000000900461ffff1681565b6105b3610eab366004613467565b60226020525f908152604090205460ff1681565b600654610ed4906001600160a01b031661322e565b610edc613267565b600680546001600160a01b0319166001600160a01b0383161790556040516243564560e81b81526003015b6040519081900381206001600160a01b0383168252907fa83dfbe7150d28f66e1f9b5ddf614f902943f9a3e91a5fa927850d411f135939906020015b60405180910390a250565b5f6001600160e01b031982166399011ef160e01b1480610f7d57506001600160e01b0319821662d95d1760e21b145b80610f9857506301ffc9a760e01b6001600160e01b03198316145b92915050565b335f9081526023602052604090205460ff16610fcd5760405163733ac1c560e11b815260040160405180910390fd5b5f5160206139205f395f51905f525c6001600160a01b03821681146110055760405163ee3a89bd60e01b815260040160405180910390fd5b5f5f5160206139205f395f51905f525d5050565b335f9081526020819052604090208054600160f81b900460ff16151582151503611056576040516351b33a3160e01b815260040160405180910390fd5b5f8261109657815461107590600160d01b900464ffffffffff16613296565b825464ffffffffff60d01b1916600160d01b64ffffffffff83160217835590505b81546001600160f81b0316600160f81b841515908102919091178355604080519182526020820183905233917f3a4485d5abacb17eae979fafd17c188d7b3c1cd08688fa670972f257cdecc10291015b60405180910390a2505050565b6110fb613267565b6001600160a01b0381165f9081526025602052604090205460ff166111335760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526025602052604090819020805460ff19169055516612185c9d995cdd60ca1b81526007015b60405180910390205f5160206139005f395f51905f52825f604051610f43929190613736565b600d546001600160a01b031633146111b75760405163733ac1c560e11b815260040160405180910390fd5b5f918252601b602052604090912055565b6008546111dd906001600160a01b031661322e565b6111e5613267565b600880546001600160a01b0319166001600160a01b0383161790556040516d2932bbb0b9321026b0b730b3b2b960911b8152600e01610f07565b600554611234906001600160a01b031661322e565b61123c613267565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f3906020015b60405180910390a150565b611299613267565b6001600160a01b0381165f9081526022602052604090205460ff166112d15760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526022602052604090819020805460ff1916905551664c6f636b696e6760c81b8152600701611166565b611310613267565b606481108061132057506107d081115b1561133e5760405163ee3a89bd60e01b815260040160405180910390fd5b61134e81655af3107a4000613765565b6012556040518181527fb1f7d6008ad6372d51d3ce13724cacfc9917f029cf39c50df8a83364da5724d290602001611286565b611389613267565b6123288111156113ac5760405163ee3a89bd60e01b815260040160405180910390fd5b610bb8811080156113bc57508015155b156113da5760405163ee3a89bd60e01b815260040160405180910390fd5b600f819055604051734561726c7920556e6c6f636b2050656e616c747960601b81526014015b604051908190038120828252907f14b078fcb9b47e380b86af6c14baa9a7d4bbc3cf6bd2b7b4c3b7f3f9d731da2590602001610f43565b61143f613267565b6113888111156114625760405163ee3a89bd60e01b815260040160405180910390fd5b6013805461ffff808416620100000263ffff0000198316811790935561148f92849290821691161761377c565b6013805461ffff929092166401000000000265ffff000000001990921691909117905560405164165a595b1960da1b81526005015b604051908190038120828252907f58747ad374788daae8193883efaa1210ccc2c4072fbf0f0d707893b316a9505e90602001610f43565b611503613267565b601480546001600160a01b0319166001600160a01b0383161790556040517121b937b9b9b1b430b4b7102932b630bcb2b960711b8152601201610f07565b611549613267565b600d5460408051630df7675f60e31b815290515f926001600160a01b031691636fbb3af89160048083019260209291908290030181865afa158015611590573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115b4919061378f565b90505f5b818110156115e5575f818152601c602052604090208390556115db6002846137a6565b92506001016115b8565b506040518281527f0d7513d01c44d97849d9b5c5599ef675255f66633c5fff4fdebe9cfcabccd0eb906020015b60405180910390a15050565b611626613267565b601380547fffff0000000000000000000000000000000000000000ffffffffffffffffffff16600160501b6001600160a01b038416021790556040516e43726f7373636861696e20436f726560881b8152600f01610f07565b335f9081526020819052604090208054600160c81b900460ff161515821515036116bc576040516351b33a3160e01b815260040160405180910390fd5b5f826116fc5781546116db90600160a01b900464ffffffffff16613296565b825464ffffffffff60a01b1916600160a01b64ffffffffff83160217835590505b815460ff60c81b1916600160c81b841515908102919091178355604080519182526020820183905233917f74262b7ab0f4e42859a5a10ed30bf39c838f1572c179ed27ce4f2108c3a11f5091016110e6565b611756613267565b600b80546001600160a01b0319166001600160a01b0383161781556040516a2332b29026b0b730b3b2b960a91b815201610f07565b6117936132e0565b6005546002546040516370a0823160e01b815230600482015261180d926001600160a01b0390811692169082906370a0823190602401602060405180830381865afa1580156117e4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611808919061378f565b61330e565b565b335f81815260208190526040812080547fa2385cc72d7cd31000a99d670d31f10d5950ed2ea60937faf26453c440552c9e9290611854906001600160781b03166137c5565b82546001600160781b039182166101009390930a838102920219161790915560405190815260200160405180910390a2565b6301e133808111156118ab576040516351b33a3160e01b815260040160405180910390fd5b335f9081526020819052604090208054600160781b900464ffffffffff1682811115611964578154600160a01b900464ffffffffff164210806118fc57508154600160d01b900464ffffffffff1642105b1561191a57604051638471b00160e01b815260040160405180910390fd5b5f611925428361377c565b83546affffffffff00ffffffffff60a01b1916600160a01b64ffffffffff9290921691820264ffffffffff60d01b191617600160d01b91909102178355505b815464ffffffffff60781b1916600160781b64ffffffffff85160217825560405183815233907fa162f0703cbc0c48ea2c9e9bed5743aabc058e7532e594490e3a35bfb0f75ab8906020016110e6565b6060600e805480602002602001604051908101604052809291908181526020018280548015611a0a57602002820191905f5260205f20905b81546001600160a01b031681526001909101906020018083116119ec575b5050505050905090565b5f5f5160206139205f395f51905f525c808203611a2f575090565b3314919050565b611a3e613267565b601680546001600160a01b0319166001600160a01b0383161790556040517226b2b9b9b0b3b2902a3930b739b6b4ba3a32b960691b8152601301610f07565b611a85613267565b6001600160a01b0381165f9081526025602052604090205460ff1615611abe5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526025602052604090819020805460ff1916600117905551611afa906612185c9d995cdd60ca1b815260070190565b60405180910390205f5160206139005f395f51905f52826001604051610f43929190613736565b335f9081526023602052604090205460ff16611b505760405163733ac1c560e11b815260040160405180910390fd5b6001600160a01b0381165f908152601d602052604090205460ff16611b885760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b038116805f5160206139205f395f51905f525d5050565b600754611bbb906001600160a01b031661322e565b611bc3613267565b600780546001600160a01b0319166001600160a01b03831617905560405164566543564560d81b8152600501610f07565b611bfc613267565b611770811115611c1f5760405163ee3a89bd60e01b815260040160405180910390fd5b6013805469ffff00000000000000001916600160401b61ffff8416021790556040518181527f4ad17f4ac5cffa804d522c1def75773d0a2f84f696c5e1c56f7ab52f9af51b7e90602001611286565b6001600160a01b0381165f90815260208181526040808320815160c08101835290546001600160781b038116825264ffffffffff600160781b8204811694830194909452600160a01b810484169282019290925260ff600160c81b83048116151560608301819052600160d01b84049094166080830152600160f81b909204909116151560a08201529080611d0d575042816040015164ffffffffff16115b9392505050565b60606018805480602002602001604051908101604052809291908181526020018280548015611a0a57602002820191905f5260205f20905b815481526020019060010190808311611d4c575050505050905090565b611d71613267565b6127108111158015611d8257508015155b15611da05760405163ee3a89bd60e01b815260040160405180910390fd5b601081905560405169159bdd1948109bdbdcdd60b21b8152600a01611400565b611dc8613267565b5f8381526019602090815260409182902082516101008082018552825460ff8116158015845291810461ffff16948301949094526301000000840463ffffffff1694820194909452600160381b9092046001600160a01b0390811660608401526001820154811660808401526002820154811660a08401526003820154811660c08401526004909101541660e08201529080611e7a5750826001600160a01b031681606001516001600160a01b031614155b80611e9b5750816001600160a01b031681608001516001600160a01b031614155b15611eb95760405163ee3a89bd60e01b815260040160405180910390fd5b5f84815260196020908152604080832080546001600160d81b03191681556001810180546001600160a01b031990811690915560028201805482169055600382018054821690556004909101805490911690558382015161ffff168352601a909152812081905560178054909190611f30906137ef565b909155506018545f5b81811015611f6c578560188281548110611f5557611f55613804565b905f5260205f2001540315611f6c57600101611f39565b81611f76816137ef565b9250505b81811015611fce576018611f8f82600161377c565b81548110611f9f57611f9f613804565b905f5260205f20015460188281548110611fbb57611fbb613804565b5f91825260209091200155600101611f7a565b6018805480611fdf57611fdf613818565b600190038181905f5260205f20015f905590557f3021e6b943a69808fba661870a077c7d206099a082e29aad652ee9225229b1f486868660405161203f939291909283526001600160a01b03918216602084015216604082015260600190565b60405180910390a1505050505050565b612057613267565b600a80546001600160a01b0319166001600160a01b0383161790556040516d27b930b1b6329026b0b730b3b2b960911b8152600e01610f07565b6001600160a01b0381165f90815260208181526040808320815160c08101835290546001600160781b038116825264ffffffffff600160781b8204811694830194909452600160a01b810484169282019290925260ff600160c81b8304811615156060830152600160d01b83049093166080820152600160f81b909104909116151560a0820181905280611d0d575042816080015164ffffffffff16119392505050565b61213d613267565b600d80546001600160a01b0319166001600160a01b038316179055604051692b37ba34b73390243ab160b11b8152600a01610f07565b61217b613267565b612710811115801561218c57508015155b156121aa5760405163ee3a89bd60e01b815260040160405180910390fd5b601181905560405169131bd8dac8109bdbdcdd60b21b8152600a01611400565b6121d2613267565b6001600160a01b0381165f9081526022602052604090205460ff161561220b5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526022602052604090819020805460ff1916600117905551611afa90664c6f636b696e6760c81b815260070190565b61224f613267565b60c88111156122715760405163ee3a89bd60e01b815260040160405180910390fd5b6013805467ffff0000000000001916660100000000000061ffff841602179055604051674c6576657261676560c01b81526008016114c4565b6122b2613267565b600c80546001600160a01b0319166001600160a01b0383161790556040516c26b2b9b9b0b3b4b73390243ab160991b8152600d01610f07565b6122f3613267565b6001600160a01b0381165f908152601d602052604090205460ff1661232b5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f908152601d60205260408120805460ff19169055600e549081905b8281101561239f57836001600160a01b0316600e828154811061237657612376613804565b5f918252602090912001546001600160a01b0316036123975780915061239f565b600101612351565b50816123aa816137ef565b925081106123cb5760405163ee3a89bd60e01b815260040160405180910390fd5b600e82815481106123de576123de613804565b5f91825260209091200154600e80546001600160a01b03909216918390811061240957612409613804565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600e80548061244557612445613818565b5f828152602090205f19908201810180546001600160a01b03191690550190556040516d26b0b935b2ba1026b0b730b3b2b960911b8152600e0160405180910390205f5160206139005f395f51905f52845f6040516110e6929190613736565b6124ad613267565b6001600160a01b038281165f908152601e60205260409081902080546001600160a01b031916928416929092179091555167115e1d195c9b985b60c21b81526008015b604080519182900382206001600160a01b03808616845284166020840152917f6e55aa47cd39e72b0bcde6bced4ab643e8ed9173ac61676839e654ab5cf0fcbc910160405180910390a25050565b612546613267565b6001600160a01b0381165f908152601d602052604090205460ff161561257f5760405163ee3a89bd60e01b815260040160405180910390fd5b61259081634d6978eb60e11b61334e565b6125ad5760405163ee3a89bd60e01b815260040160405180910390fd5b600e8054600180820183557fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd90910180546001600160a01b0319166001600160a01b0385169081179091555f908152601d602052604090819020805460ff1916909217909155516d26b0b935b2ba1026b0b730b3b2b960911b815201611afa565b612636613369565b612647816346804c7360e11b61334e565b6126645760405163ee3a89bd60e01b815260040160405180910390fd5b600380546001600160a01b038381166001600160a01b031983161790925560045490821691168114612731576001600160a01b0381165f908152602160209081526040808320805460ff1990811690915560249092529182902080549091169055516126cf9061382c565b60405180910390205f5160206139005f395f51905f52825f6040516126f5929190613736565b60405180910390a26002546001600160a01b03828116911614612731576001600160a01b0381165f9081526020805260409020805460ff191690555b6001600160a01b0382165f908152602080805260408083208054600160ff19918216811790925560219093529281902080549092169092179055516754696d656c6f636b60c01b8152600801604080519182900382206001600160a01b03808516845285166020840152917fd8e127776f279a25ebbafc660f7deba16e71dcb8ff27626f743010802c27211d910160405180910390a26001600160a01b0382165f9081526024602052604090205460ff16612844576001600160a01b0382165f9081526024602052604090819020805460ff19166001179055516128149061382c565b60405180910390205f5160206139005f395f51905f5283600160405161283b929190613736565b60405180910390a25b816001600160a01b0316632d04e9406040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561287c575f5ffd5b505af115801561288e573d5f5f3e3d5ffd5b505050505050565b61289e613267565b6016805463ffffffff60a01b1916600160a01b63ffffffff8416908102919091179091556040519081527fc7be9211ec952c9e28c7dcfa4006637b033650e4b706a83f53aab6e4f18f5d4190602001611286565b6001548110156129155760405163ee3a89bd60e01b815260040160405180910390fd5b61291d613267565b426001541161294257604051600162012c6360e61b0319815260040160405180910390fd5b60018190556040518181527f5004b8dec1035052128f5440d20a89b9a5595773c7b6cd57b341b2e6fe22633590602001611286565b61297f613267565b6001600160a01b0381165f9081526024602052604090205460ff16156129b85760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526024602052604090819020805460ff1916600117905551611afa9061382c565b6129ee613267565b5f8281526019602052604090205460ff1680612a0957508051155b15612a275760405163ee3a89bd60e01b815260040160405180910390fd5b815f03612a475760405163ee3a89bd60e01b815260040160405180910390fd5b60208082015161ffff165f908152601a909152604090205415612a7d5760405163ee3a89bd60e01b815260040160405180910390fd5b5f828152601960209081526040808320845181548685015187850151606089015162ffffff1990931693151562ffff0019169390931761010061ffff909216918202176301000000600160d81b031916630100000063ffffffff90941693909302670100000000000000600160d81b03191692909217600160381b6001600160a01b03928316021783556080870151600180850180546001600160a01b031990811693851693909317905560a0890151600286018054841691851691909117905560c0890151600386018054841691851691909117905560e08901516004909501805490921694909216939093179092558452601a909252822084905560188054918201815582527fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e0183905560178054909190612bba9061383e565b909155506040517f6a1d0638b354b38ee458624b89be1806c52a50b6a4284cd2f241ae759648149a906116129084908490613856565b612bf8613267565b6101f4811115612c1b5760405163ee3a89bd60e01b815260040160405180910390fd5b6013805461ffff191661ffff8381169190911791829055612c45918391620100009091041661377c565b6013805461ffff929092166401000000000265ffff00000000199092169190911790556040516710dbdb5c1bdd5b9960c21b81526008016114c4565b612c89613267565b601580546001600160a01b0319166001600160a01b0383161790556040516d2a37b5b2b71026b2b9b9b0b3b2b960911b8152600e01610f07565b600954612cd8906001600160a01b031661322e565b612ce0613267565b600980546001600160a01b0319166001600160a01b0383161790556040516c23b0bab3b29026b0b730b3b2b960991b8152600d01610f07565b612d21613369565b600480546001600160a01b038381166001600160a01b031983161790925560035490821691168114612dee576001600160a01b0381165f908152602160209081526040808320805460ff199081169091556024909252918290208054909116905551612d8c9061382c565b60405180910390205f5160206139005f395f51905f52825f604051612db2929190613736565b60405180910390a26002546001600160a01b03828116911614612dee576001600160a01b0381165f9081526020805260409020805460ff191690555b6001600160a01b0382165f908152602080805260408083208054600160ff199182168117909255602190935292819020805490921690921790555170115b595c99d95b98de4810dbdd5b98da5b607a1b8152601101604080519182900382206001600160a01b03808516845285166020840152917fd8e127776f279a25ebbafc660f7deba16e71dcb8ff27626f743010802c27211d910160405180910390a26001600160a01b0382165f9081526024602052604090205460ff16612f0a576001600160a01b0382165f9081526024602052604090819020805460ff1916600117905551612eda9061382c565b60405180910390205f5160206139005f395f51905f52836001604051612f01929190613736565b60405180910390a25b6003546001600160a01b031615612f8957600354612f38906001600160a01b03166346804c7360e11b61334e565b15612f895760035f9054906101000a90046001600160a01b03166001600160a01b0316632d04e9406040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561287c575f5ffd5b5050565b612f95613267565b6001600160a01b0381165f9081526023602052604090205460ff1615612fce5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526023602052604090819020805460ff1916600117905551611afa906620bab1ba34b7b760c91b815260070190565b613012613267565b600280546001600160a01b038381166001600160a01b031983161790925560045490821691168114613072576003546001600160a01b03828116911614613072576001600160a01b0381165f9081526020805260409020805460ff191690555b6001600160a01b0382165f90815260208052604090819020805460ff19166001179055516130b5906e44414f205065726d697373696f6e7360881b8152600f0190565b604080519182900382206001600160a01b03808516845285166020840152917fd8e127776f279a25ebbafc660f7deba16e71dcb8ff27626f743010802c27211d9101612f01565b613104613267565b6001600160a01b038281165f908152601f60205260409081902080546001600160a01b031916928416929092179091555168135d5b1d1a58d85b1b60ba1b81526009016124f0565b613154613267565b6001600160a01b0381165f9081526023602052604090205460ff1661318c5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526023602052604090819020805460ff19169055516620bab1ba34b7b760c91b8152600701611166565b6131cb613267565b6001600160a01b0381165f9081526024602052604090205460ff166132035760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526024602052604090819020805460ff19169055516111669061382c565b6001600160a01b03811661323f5750565b426001541161326457604051600162012c6360e61b0319815260040160405180910390fd5b50565b335f9081526021602052604090205460ff1661180d5760405163733ac1c560e11b815260040160405180910390fd5b5f428211156132b857604051638471b00160e01b815260040160405180910390fd5b335f90815260208190526040902054610f98904290600160781b900464ffffffffff1661377c565b335f90815260208052604090205460ff1661180d5760405163733ac1c560e11b815260040160405180910390fd5b816014528060345263a9059cbb60601b5f5260205f604460105f875af13d1560015f51141716613345576390b8ec185f526004601cfd5b5f603452505050565b5f61335883613394565b8015611d0d5750611d0d83836133c6565b6004546001600160a01b0316331461180d5760405163733ac1c560e11b815260040160405180910390fd5b5f6133a6826301ffc9a760e01b6133c6565b8015610f9857506133bf826001600160e01b03196133c6565b1592915050565b6040516001600160e01b0319821660248201525f90819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b17815282519293505f9283928392909183918a617530fa92503d91505f519050828015613436575060208210155b801561344157505f81115b979650505050505050565b80356001600160a01b0381168114613462575f5ffd5b919050565b5f60208284031215613477575f5ffd5b611d0d8261344c565b5f60208284031215613490575f5ffd5b81356001600160e01b031981168114611d0d575f5ffd5b5f602082840312156134b7575f5ffd5b5035919050565b80358015158114613462575f5ffd5b5f602082840312156134dd575f5ffd5b611d0d826134be565b5f5f604083850312156134f7575f5ffd5b50508035926020909101359150565b602080825282518282018190525f918401906040840190835b818110156135465783516001600160a01b031683526020938401939092019160010161351f565b509095945050505050565b803561ffff81168114613462575f5ffd5b5f60208284031215613572575f5ffd5b611d0d82613551565b602080825282518282018190525f918401906040840190835b81811015613546578351835260209384019390920191600101613594565b5f5f5f606084860312156135c4575f5ffd5b833592506135d46020850161344c565b91506135e26040850161344c565b90509250925092565b5f5f604083850312156135fc575f5ffd5b6136058361344c565b91506136136020840161344c565b90509250929050565b803563ffffffff81168114613462575f5ffd5b5f6020828403121561363f575f5ffd5b611d0d8261361c565b5f5f82840361012081121561365b575f5ffd5b83359250610100601f1982011215613671575f5ffd5b50604051610100810181811067ffffffffffffffff821117156136a257634e487b7160e01b5f52604160045260245ffd5b6040526136b1602085016134be565b81526136bf60408501613551565b60208201526136d06060850161361c565b60408201526136e16080850161344c565b60608201526136f260a0850161344c565b608082015261370360c0850161344c565b60a082015261371460e0850161344c565b60c0820152613726610100850161344c565b60e0820152809150509250929050565b6001600160a01b039290921682521515602082015260400190565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610f9857610f98613751565b80820180821115610f9857610f98613751565b5f6020828403121561379f575f5ffd5b5051919050565b5f826137c057634e487b7160e01b5f52601260045260245ffd5b500490565b5f6001600160781b0382166001600160781b0381036137e6576137e6613751565b60010192915050565b5f816137fd576137fd613751565b505f190190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b6513585c9ad95d60d21b815260060190565b5f6001820161384f5761384f613751565b5060010190565b5f6101208201905083825282511515602083015261ffff602084015116604083015263ffffffff604084015116606083015260608301516138a260808401826001600160a01b03169052565b5060808301516001600160a01b03811660a08401525060a08301516001600160a01b03811660c08401525060c08301516001600160a01b03811660e08401525060e08301516001600160a01b03811661010084015250939250505056fe40f7b3ef64c9e38288873dda008188d6c3cd146f84d77b978478a8731f71feb97cbd46c789962ee73435d84bcd3c0927fb55fd04ce92deedbdae7e783739544ca2646970667358221220439cdd9789fa974154b8e848e9b3eede275480b9c5035b54f2a6fdd16e7ac89564736f6c634300081c0033d8e127776f279a25ebbafc660f7deba16e71dcb8ff27626f743010802c27211d00000000000000000000000097f6886d04c804a278caf904e1adf5864b38452100000000000000000000000097f6886d04c804a278caf904e1adf5864b384521000000000000000000000000000000000000000000000000000000006a13ddd30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000754704bc059f8c67012fed69bc8a327a5aafb603

Deployed Bytecode

0x608060405234801561000f575f5ffd5b5060043610610587575f3560e01c80637d793087116102d9578063cb58bf2711610186578063dc75d503116100ef578063e6248d55116100a9578063f07125b311610084578063f07125b314610e69578063f0a8efce14610e7c578063fe57648414610e85578063ff7127eb14610e9d575f5ffd5b8063e6248d5514610dfd578063ea3437e814610e2e578063ec32249814610e56575f5ffd5b8063dc75d50314610d7b578063de0c7a7114610d8f578063df018e4214610db1578063e2dfa13014610dc4578063e3a9841c14610dd7578063e524d12a14610dea575f5ffd5b8063d7dd0b2b11610140578063d7dd0b2b14610cf4578063d8cfc7f014610d07578063da88d9d314610d1a578063db2a1a8114610d42578063db8a5fd814610d55578063dc0aae5414610d68575f5ffd5b8063cb58bf2714610c80578063cbda3cee14610c93578063ce517dc714610ca6578063d0fb020314610cb9578063d33219b414610ccc578063d68dbfe414610cdf575f5ffd5b8063b0990e2111610242578063b9237f7d116101fc578063c19b4bfa116101d7578063c19b4bfa14610c1b578063c2fb26a614610c2e578063c3a1ebb714610c5a578063c4f63cb514610c6d575f5ffd5b8063b9237f7d14610be2578063bdd8400714610bf5578063bf8d223414610c08575f5ffd5b8063b0990e2114610b63578063b0ff43f514610b79578063b128de9d14610ba0578063b51665f914610bb3578063b70e6be614610bc6578063b86c886f14610bcf575f5ffd5b80639874482d116102935780639874482d14610aec5780639dd9fd1714610aff578063a409870e14610b12578063a70b9f0c14610b25578063abd5d9d214610b2f578063ae50130e14610b50575f5ffd5b80637d79308714610a765780637e602baa14610a89578063816949b514610a9c5780638a0828bc14610aa5578063929e2e0814610ac65780639616756e14610ad9575f5ffd5b806340370e3d116104375780635b5c6b77116103a05780636cd54a741161035a57806376b4a6231161033557806376b4a62314610a195780637778960e14610a2e5780637b04c18114610a415780637d5528bd14610a54575f5ffd5b80636cd54a74146109e0578063731a555d146109f357806373578c6714610a06575f5ffd5b80635b5c6b771461095b5780635f486a5414610975578063647846a51461099457806364f82aa4146109a75780636888ce09146109ba5780636bee0479146109cd575f5ffd5b80634fc3f41a116103f15780634fc3f41a146108fc5780635123f92c1461090f5780635331272314610922578063565d878c14610937578063572e2fa21461094a5780635b07871a14610952575f5ffd5b806340370e3d146108aa57806345c18b2e146108bd578063472d35b9146108d0578063476343ee146108e35780634a01623d146108eb5780634b6ffb18146108f3575f5ffd5b8063153ee554116104f3578063254c3175116104ad5780632c3400ea116104885780632c3400ea146108495780632dd74d1d1461085c578063323a198a1461086f5780633a88faf114610897575f5ffd5b8063254c3175146107f5578063264b1dc014610814578063287530f714610827575f5ffd5b8063153ee5541461078357806315cce2241461079657806315d02493146107a95780631fe4ba17146107bc5780632131c68c146107cf578063231fa01f146107e2575f5ffd5b80630c9cefdd116105445780630c9cefdd146106da5780630d34766b146107075780630df00074146107105780630f4ef8a61461072357806310eec0001461074e578063119e4f3014610770575f5ffd5b80630168956a1461058b57806301ffc9a7146105a05780630225e243146105c85780630a456bbc146105ea5780630a70b056146105fd5780630b6893df146106c7575b5f5ffd5b61059e610599366004613467565b610ebf565b005b6105b36105ae366004613480565b610f4e565b60405190151581526020015b60405180910390f35b6105b36105d6366004613467565b60246020525f908152604090205460ff1681565b61059e6105f8366004613467565b610f9e565b61066e61060b3660046134a7565b60196020525f90815260409020805460018201546002830154600384015460049094015460ff84169461ffff6101008604169463ffffffff6301000000820416946001600160a01b03600160381b90920482169490821693908216928216911688565b60408051981515895261ffff909716602089015263ffffffff909516958701959095526001600160a01b0392831660608701529082166080860152811660a085015291821660c08401521660e0820152610100016105bf565b61059e6106d53660046134cd565b611019565b6106f96106e83660046134a7565b601c6020525f908152604090205481565b6040519081526020016105bf565b6106f9600f5481565b61059e61071e366004613467565b6110f3565b600854610736906001600160a01b031681565b6040516001600160a01b0390911681526020016105bf565b6105b361075c366004613467565b60256020525f908152604090205460ff1681565b61059e61077e3660046134e6565b61118c565b61059e610791366004613467565b6111c8565b61059e6107a4366004613467565b61121f565b61059e6107b7366004613467565b611291565b61059e6107ca3660046134a7565b611308565b600254610736906001600160a01b031681565b61059e6107f03660046134a7565b611381565b6106f96108033660046134a7565b601b6020525f908152604090205481565b61059e6108223660046134a7565b611437565b6105b3610835366004613467565b60236020525f908152604090205460ff1681565b61059e610857366004613467565b6114fb565b600d54610736906001600160a01b031681565b61073661087d366004613467565b601f6020525f90815260409020546001600160a01b031681565b61059e6108a53660046134a7565b611541565b61059e6108b8366004613467565b61161e565b61059e6108cb3660046134cd565b61167f565b61059e6108de366004613467565b61174e565b61059e61178b565b61059e61180f565b6106f960105481565b61059e61090a3660046134a7565b611886565b601454610736906001600160a01b031681565b61092a6119b4565b6040516105bf9190613506565b600a54610736906001600160a01b031681565b6105b3611a14565b6106f960125481565b60135461073690600160501b90046001600160a01b031681565b6106f9610983366004613562565b601a6020525f908152604090205481565b600554610736906001600160a01b031681565b61059e6109b5366004613467565b611a36565b61059e6109c8366004613467565b611a7d565b61059e6109db366004613467565b611b21565b61059e6109ee366004613467565b611ba6565b61059e610a013660046134a7565b611bf4565b6105b3610a14366004613467565b611c6e565b610a21611d14565b6040516105bf919061357b565b600454610736906001600160a01b031681565b601654610736906001600160a01b031681565b6105b3610a62366004613467565b601d6020525f908152604090205460ff1681565b61059e610a843660046134a7565b611d69565b61059e610a973660046135b2565b611dc0565b6106f960175481565b601354610ab39061ffff1681565b60405161ffff90911681526020016105bf565b61059e610ad4366004613467565b61204f565b6105b3610ae7366004613467565b612091565b61059e610afa366004613467565b612135565b61059e610b0d3660046134a7565b612173565b61059e610b20366004613467565b6121ca565b6106f96212750081565b6105b3610b3d366004613467565b602080525f908152604090205460ff1681565b61059e610b5e3660046134a7565b612247565b601354610ab390640100000000900461ffff1681565b6107367f000000000000000000000000000000000000000000000000000000000000000081565b61059e610bae366004613467565b6122aa565b61059e610bc1366004613467565b6122eb565b6106f960015481565b61059e610bdd3660046135eb565b6124a5565b61059e610bf0366004613467565b61253e565b61059e610c03366004613467565b61262e565b61059e610c1636600461362f565b612896565b61059e610c293660046134a7565b6128f2565b601654610c4590600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016105bf565b61059e610c68366004613467565b612977565b61059e610c7b366004613648565b6129e6565b600c54610736906001600160a01b031681565b600954610736906001600160a01b031681565b61059e610cb43660046134a7565b612bf0565b600b54610736906001600160a01b031681565b600354610736906001600160a01b031681565b601354610ab390600160401b900461ffff1681565b61059e610d02366004613467565b612c81565b61059e610d15366004613467565b612cc3565b6106f9610d283660046134a7565b5f90815260196020526040902054610100900461ffff1690565b61059e610d50366004613467565b612d19565b61059e610d63366004613467565b612f8d565b61059e610d76366004613467565b61300a565b601354610ab39062010000900461ffff1681565b6105b3610d9d366004613467565b60216020525f908152604090205460ff1681565b600654610736906001600160a01b031681565b601554610736906001600160a01b031681565b61059e610de53660046135eb565b6130fc565b61059e610df8366004613467565b61314c565b6106f9610e0b366004613467565b6001600160a01b03165f908152602081905260409020546001600160781b031690565b610736610e3c366004613467565b601e6020525f90815260409020546001600160a01b031681565b61059e610e64366004613467565b6131c3565b600754610736906001600160a01b031681565b6106f960115481565b601354610ab3906601000000000000900461ffff1681565b6105b3610eab366004613467565b60226020525f908152604090205460ff1681565b600654610ed4906001600160a01b031661322e565b610edc613267565b600680546001600160a01b0319166001600160a01b0383161790556040516243564560e81b81526003015b6040519081900381206001600160a01b0383168252907fa83dfbe7150d28f66e1f9b5ddf614f902943f9a3e91a5fa927850d411f135939906020015b60405180910390a250565b5f6001600160e01b031982166399011ef160e01b1480610f7d57506001600160e01b0319821662d95d1760e21b145b80610f9857506301ffc9a760e01b6001600160e01b03198316145b92915050565b335f9081526023602052604090205460ff16610fcd5760405163733ac1c560e11b815260040160405180910390fd5b5f5160206139205f395f51905f525c6001600160a01b03821681146110055760405163ee3a89bd60e01b815260040160405180910390fd5b5f5f5160206139205f395f51905f525d5050565b335f9081526020819052604090208054600160f81b900460ff16151582151503611056576040516351b33a3160e01b815260040160405180910390fd5b5f8261109657815461107590600160d01b900464ffffffffff16613296565b825464ffffffffff60d01b1916600160d01b64ffffffffff83160217835590505b81546001600160f81b0316600160f81b841515908102919091178355604080519182526020820183905233917f3a4485d5abacb17eae979fafd17c188d7b3c1cd08688fa670972f257cdecc10291015b60405180910390a2505050565b6110fb613267565b6001600160a01b0381165f9081526025602052604090205460ff166111335760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526025602052604090819020805460ff19169055516612185c9d995cdd60ca1b81526007015b60405180910390205f5160206139005f395f51905f52825f604051610f43929190613736565b600d546001600160a01b031633146111b75760405163733ac1c560e11b815260040160405180910390fd5b5f918252601b602052604090912055565b6008546111dd906001600160a01b031661322e565b6111e5613267565b600880546001600160a01b0319166001600160a01b0383161790556040516d2932bbb0b9321026b0b730b3b2b960911b8152600e01610f07565b600554611234906001600160a01b031661322e565b61123c613267565b600580546001600160a01b0319166001600160a01b0383169081179091556040519081527f722ff84c1234b2482061def5c82c6b5080c117b3cbb69d686844a051e4b8e7f3906020015b60405180910390a150565b611299613267565b6001600160a01b0381165f9081526022602052604090205460ff166112d15760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526022602052604090819020805460ff1916905551664c6f636b696e6760c81b8152600701611166565b611310613267565b606481108061132057506107d081115b1561133e5760405163ee3a89bd60e01b815260040160405180910390fd5b61134e81655af3107a4000613765565b6012556040518181527fb1f7d6008ad6372d51d3ce13724cacfc9917f029cf39c50df8a83364da5724d290602001611286565b611389613267565b6123288111156113ac5760405163ee3a89bd60e01b815260040160405180910390fd5b610bb8811080156113bc57508015155b156113da5760405163ee3a89bd60e01b815260040160405180910390fd5b600f819055604051734561726c7920556e6c6f636b2050656e616c747960601b81526014015b604051908190038120828252907f14b078fcb9b47e380b86af6c14baa9a7d4bbc3cf6bd2b7b4c3b7f3f9d731da2590602001610f43565b61143f613267565b6113888111156114625760405163ee3a89bd60e01b815260040160405180910390fd5b6013805461ffff808416620100000263ffff0000198316811790935561148f92849290821691161761377c565b6013805461ffff929092166401000000000265ffff000000001990921691909117905560405164165a595b1960da1b81526005015b604051908190038120828252907f58747ad374788daae8193883efaa1210ccc2c4072fbf0f0d707893b316a9505e90602001610f43565b611503613267565b601480546001600160a01b0319166001600160a01b0383161790556040517121b937b9b9b1b430b4b7102932b630bcb2b960711b8152601201610f07565b611549613267565b600d5460408051630df7675f60e31b815290515f926001600160a01b031691636fbb3af89160048083019260209291908290030181865afa158015611590573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115b4919061378f565b90505f5b818110156115e5575f818152601c602052604090208390556115db6002846137a6565b92506001016115b8565b506040518281527f0d7513d01c44d97849d9b5c5599ef675255f66633c5fff4fdebe9cfcabccd0eb906020015b60405180910390a15050565b611626613267565b601380547fffff0000000000000000000000000000000000000000ffffffffffffffffffff16600160501b6001600160a01b038416021790556040516e43726f7373636861696e20436f726560881b8152600f01610f07565b335f9081526020819052604090208054600160c81b900460ff161515821515036116bc576040516351b33a3160e01b815260040160405180910390fd5b5f826116fc5781546116db90600160a01b900464ffffffffff16613296565b825464ffffffffff60a01b1916600160a01b64ffffffffff83160217835590505b815460ff60c81b1916600160c81b841515908102919091178355604080519182526020820183905233917f74262b7ab0f4e42859a5a10ed30bf39c838f1572c179ed27ce4f2108c3a11f5091016110e6565b611756613267565b600b80546001600160a01b0319166001600160a01b0383161781556040516a2332b29026b0b730b3b2b960a91b815201610f07565b6117936132e0565b6005546002546040516370a0823160e01b815230600482015261180d926001600160a01b0390811692169082906370a0823190602401602060405180830381865afa1580156117e4573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611808919061378f565b61330e565b565b335f81815260208190526040812080547fa2385cc72d7cd31000a99d670d31f10d5950ed2ea60937faf26453c440552c9e9290611854906001600160781b03166137c5565b82546001600160781b039182166101009390930a838102920219161790915560405190815260200160405180910390a2565b6301e133808111156118ab576040516351b33a3160e01b815260040160405180910390fd5b335f9081526020819052604090208054600160781b900464ffffffffff1682811115611964578154600160a01b900464ffffffffff164210806118fc57508154600160d01b900464ffffffffff1642105b1561191a57604051638471b00160e01b815260040160405180910390fd5b5f611925428361377c565b83546affffffffff00ffffffffff60a01b1916600160a01b64ffffffffff9290921691820264ffffffffff60d01b191617600160d01b91909102178355505b815464ffffffffff60781b1916600160781b64ffffffffff85160217825560405183815233907fa162f0703cbc0c48ea2c9e9bed5743aabc058e7532e594490e3a35bfb0f75ab8906020016110e6565b6060600e805480602002602001604051908101604052809291908181526020018280548015611a0a57602002820191905f5260205f20905b81546001600160a01b031681526001909101906020018083116119ec575b5050505050905090565b5f5f5160206139205f395f51905f525c808203611a2f575090565b3314919050565b611a3e613267565b601680546001600160a01b0319166001600160a01b0383161790556040517226b2b9b9b0b3b2902a3930b739b6b4ba3a32b960691b8152601301610f07565b611a85613267565b6001600160a01b0381165f9081526025602052604090205460ff1615611abe5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526025602052604090819020805460ff1916600117905551611afa906612185c9d995cdd60ca1b815260070190565b60405180910390205f5160206139005f395f51905f52826001604051610f43929190613736565b335f9081526023602052604090205460ff16611b505760405163733ac1c560e11b815260040160405180910390fd5b6001600160a01b0381165f908152601d602052604090205460ff16611b885760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b038116805f5160206139205f395f51905f525d5050565b600754611bbb906001600160a01b031661322e565b611bc3613267565b600780546001600160a01b0319166001600160a01b03831617905560405164566543564560d81b8152600501610f07565b611bfc613267565b611770811115611c1f5760405163ee3a89bd60e01b815260040160405180910390fd5b6013805469ffff00000000000000001916600160401b61ffff8416021790556040518181527f4ad17f4ac5cffa804d522c1def75773d0a2f84f696c5e1c56f7ab52f9af51b7e90602001611286565b6001600160a01b0381165f90815260208181526040808320815160c08101835290546001600160781b038116825264ffffffffff600160781b8204811694830194909452600160a01b810484169282019290925260ff600160c81b83048116151560608301819052600160d01b84049094166080830152600160f81b909204909116151560a08201529080611d0d575042816040015164ffffffffff16115b9392505050565b60606018805480602002602001604051908101604052809291908181526020018280548015611a0a57602002820191905f5260205f20905b815481526020019060010190808311611d4c575050505050905090565b611d71613267565b6127108111158015611d8257508015155b15611da05760405163ee3a89bd60e01b815260040160405180910390fd5b601081905560405169159bdd1948109bdbdcdd60b21b8152600a01611400565b611dc8613267565b5f8381526019602090815260409182902082516101008082018552825460ff8116158015845291810461ffff16948301949094526301000000840463ffffffff1694820194909452600160381b9092046001600160a01b0390811660608401526001820154811660808401526002820154811660a08401526003820154811660c08401526004909101541660e08201529080611e7a5750826001600160a01b031681606001516001600160a01b031614155b80611e9b5750816001600160a01b031681608001516001600160a01b031614155b15611eb95760405163ee3a89bd60e01b815260040160405180910390fd5b5f84815260196020908152604080832080546001600160d81b03191681556001810180546001600160a01b031990811690915560028201805482169055600382018054821690556004909101805490911690558382015161ffff168352601a909152812081905560178054909190611f30906137ef565b909155506018545f5b81811015611f6c578560188281548110611f5557611f55613804565b905f5260205f2001540315611f6c57600101611f39565b81611f76816137ef565b9250505b81811015611fce576018611f8f82600161377c565b81548110611f9f57611f9f613804565b905f5260205f20015460188281548110611fbb57611fbb613804565b5f91825260209091200155600101611f7a565b6018805480611fdf57611fdf613818565b600190038181905f5260205f20015f905590557f3021e6b943a69808fba661870a077c7d206099a082e29aad652ee9225229b1f486868660405161203f939291909283526001600160a01b03918216602084015216604082015260600190565b60405180910390a1505050505050565b612057613267565b600a80546001600160a01b0319166001600160a01b0383161790556040516d27b930b1b6329026b0b730b3b2b960911b8152600e01610f07565b6001600160a01b0381165f90815260208181526040808320815160c08101835290546001600160781b038116825264ffffffffff600160781b8204811694830194909452600160a01b810484169282019290925260ff600160c81b8304811615156060830152600160d01b83049093166080820152600160f81b909104909116151560a0820181905280611d0d575042816080015164ffffffffff16119392505050565b61213d613267565b600d80546001600160a01b0319166001600160a01b038316179055604051692b37ba34b73390243ab160b11b8152600a01610f07565b61217b613267565b612710811115801561218c57508015155b156121aa5760405163ee3a89bd60e01b815260040160405180910390fd5b601181905560405169131bd8dac8109bdbdcdd60b21b8152600a01611400565b6121d2613267565b6001600160a01b0381165f9081526022602052604090205460ff161561220b5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526022602052604090819020805460ff1916600117905551611afa90664c6f636b696e6760c81b815260070190565b61224f613267565b60c88111156122715760405163ee3a89bd60e01b815260040160405180910390fd5b6013805467ffff0000000000001916660100000000000061ffff841602179055604051674c6576657261676560c01b81526008016114c4565b6122b2613267565b600c80546001600160a01b0319166001600160a01b0383161790556040516c26b2b9b9b0b3b4b73390243ab160991b8152600d01610f07565b6122f3613267565b6001600160a01b0381165f908152601d602052604090205460ff1661232b5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f908152601d60205260408120805460ff19169055600e549081905b8281101561239f57836001600160a01b0316600e828154811061237657612376613804565b5f918252602090912001546001600160a01b0316036123975780915061239f565b600101612351565b50816123aa816137ef565b925081106123cb5760405163ee3a89bd60e01b815260040160405180910390fd5b600e82815481106123de576123de613804565b5f91825260209091200154600e80546001600160a01b03909216918390811061240957612409613804565b905f5260205f20015f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550600e80548061244557612445613818565b5f828152602090205f19908201810180546001600160a01b03191690550190556040516d26b0b935b2ba1026b0b730b3b2b960911b8152600e0160405180910390205f5160206139005f395f51905f52845f6040516110e6929190613736565b6124ad613267565b6001600160a01b038281165f908152601e60205260409081902080546001600160a01b031916928416929092179091555167115e1d195c9b985b60c21b81526008015b604080519182900382206001600160a01b03808616845284166020840152917f6e55aa47cd39e72b0bcde6bced4ab643e8ed9173ac61676839e654ab5cf0fcbc910160405180910390a25050565b612546613267565b6001600160a01b0381165f908152601d602052604090205460ff161561257f5760405163ee3a89bd60e01b815260040160405180910390fd5b61259081634d6978eb60e11b61334e565b6125ad5760405163ee3a89bd60e01b815260040160405180910390fd5b600e8054600180820183557fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd90910180546001600160a01b0319166001600160a01b0385169081179091555f908152601d602052604090819020805460ff1916909217909155516d26b0b935b2ba1026b0b730b3b2b960911b815201611afa565b612636613369565b612647816346804c7360e11b61334e565b6126645760405163ee3a89bd60e01b815260040160405180910390fd5b600380546001600160a01b038381166001600160a01b031983161790925560045490821691168114612731576001600160a01b0381165f908152602160209081526040808320805460ff1990811690915560249092529182902080549091169055516126cf9061382c565b60405180910390205f5160206139005f395f51905f52825f6040516126f5929190613736565b60405180910390a26002546001600160a01b03828116911614612731576001600160a01b0381165f9081526020805260409020805460ff191690555b6001600160a01b0382165f908152602080805260408083208054600160ff19918216811790925560219093529281902080549092169092179055516754696d656c6f636b60c01b8152600801604080519182900382206001600160a01b03808516845285166020840152917fd8e127776f279a25ebbafc660f7deba16e71dcb8ff27626f743010802c27211d910160405180910390a26001600160a01b0382165f9081526024602052604090205460ff16612844576001600160a01b0382165f9081526024602052604090819020805460ff19166001179055516128149061382c565b60405180910390205f5160206139005f395f51905f5283600160405161283b929190613736565b60405180910390a25b816001600160a01b0316632d04e9406040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561287c575f5ffd5b505af115801561288e573d5f5f3e3d5ffd5b505050505050565b61289e613267565b6016805463ffffffff60a01b1916600160a01b63ffffffff8416908102919091179091556040519081527fc7be9211ec952c9e28c7dcfa4006637b033650e4b706a83f53aab6e4f18f5d4190602001611286565b6001548110156129155760405163ee3a89bd60e01b815260040160405180910390fd5b61291d613267565b426001541161294257604051600162012c6360e61b0319815260040160405180910390fd5b60018190556040518181527f5004b8dec1035052128f5440d20a89b9a5595773c7b6cd57b341b2e6fe22633590602001611286565b61297f613267565b6001600160a01b0381165f9081526024602052604090205460ff16156129b85760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526024602052604090819020805460ff1916600117905551611afa9061382c565b6129ee613267565b5f8281526019602052604090205460ff1680612a0957508051155b15612a275760405163ee3a89bd60e01b815260040160405180910390fd5b815f03612a475760405163ee3a89bd60e01b815260040160405180910390fd5b60208082015161ffff165f908152601a909152604090205415612a7d5760405163ee3a89bd60e01b815260040160405180910390fd5b5f828152601960209081526040808320845181548685015187850151606089015162ffffff1990931693151562ffff0019169390931761010061ffff909216918202176301000000600160d81b031916630100000063ffffffff90941693909302670100000000000000600160d81b03191692909217600160381b6001600160a01b03928316021783556080870151600180850180546001600160a01b031990811693851693909317905560a0890151600286018054841691851691909117905560c0890151600386018054841691851691909117905560e08901516004909501805490921694909216939093179092558452601a909252822084905560188054918201815582527fb13d2d76d1f4b7be834882e410b3e3a8afaf69f83600ae24db354391d2378d2e0183905560178054909190612bba9061383e565b909155506040517f6a1d0638b354b38ee458624b89be1806c52a50b6a4284cd2f241ae759648149a906116129084908490613856565b612bf8613267565b6101f4811115612c1b5760405163ee3a89bd60e01b815260040160405180910390fd5b6013805461ffff191661ffff8381169190911791829055612c45918391620100009091041661377c565b6013805461ffff929092166401000000000265ffff00000000199092169190911790556040516710dbdb5c1bdd5b9960c21b81526008016114c4565b612c89613267565b601580546001600160a01b0319166001600160a01b0383161790556040516d2a37b5b2b71026b2b9b9b0b3b2b960911b8152600e01610f07565b600954612cd8906001600160a01b031661322e565b612ce0613267565b600980546001600160a01b0319166001600160a01b0383161790556040516c23b0bab3b29026b0b730b3b2b960991b8152600d01610f07565b612d21613369565b600480546001600160a01b038381166001600160a01b031983161790925560035490821691168114612dee576001600160a01b0381165f908152602160209081526040808320805460ff199081169091556024909252918290208054909116905551612d8c9061382c565b60405180910390205f5160206139005f395f51905f52825f604051612db2929190613736565b60405180910390a26002546001600160a01b03828116911614612dee576001600160a01b0381165f9081526020805260409020805460ff191690555b6001600160a01b0382165f908152602080805260408083208054600160ff199182168117909255602190935292819020805490921690921790555170115b595c99d95b98de4810dbdd5b98da5b607a1b8152601101604080519182900382206001600160a01b03808516845285166020840152917fd8e127776f279a25ebbafc660f7deba16e71dcb8ff27626f743010802c27211d910160405180910390a26001600160a01b0382165f9081526024602052604090205460ff16612f0a576001600160a01b0382165f9081526024602052604090819020805460ff1916600117905551612eda9061382c565b60405180910390205f5160206139005f395f51905f52836001604051612f01929190613736565b60405180910390a25b6003546001600160a01b031615612f8957600354612f38906001600160a01b03166346804c7360e11b61334e565b15612f895760035f9054906101000a90046001600160a01b03166001600160a01b0316632d04e9406040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561287c575f5ffd5b5050565b612f95613267565b6001600160a01b0381165f9081526023602052604090205460ff1615612fce5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526023602052604090819020805460ff1916600117905551611afa906620bab1ba34b7b760c91b815260070190565b613012613267565b600280546001600160a01b038381166001600160a01b031983161790925560045490821691168114613072576003546001600160a01b03828116911614613072576001600160a01b0381165f9081526020805260409020805460ff191690555b6001600160a01b0382165f90815260208052604090819020805460ff19166001179055516130b5906e44414f205065726d697373696f6e7360881b8152600f0190565b604080519182900382206001600160a01b03808516845285166020840152917fd8e127776f279a25ebbafc660f7deba16e71dcb8ff27626f743010802c27211d9101612f01565b613104613267565b6001600160a01b038281165f908152601f60205260409081902080546001600160a01b031916928416929092179091555168135d5b1d1a58d85b1b60ba1b81526009016124f0565b613154613267565b6001600160a01b0381165f9081526023602052604090205460ff1661318c5760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526023602052604090819020805460ff19169055516620bab1ba34b7b760c91b8152600701611166565b6131cb613267565b6001600160a01b0381165f9081526024602052604090205460ff166132035760405163ee3a89bd60e01b815260040160405180910390fd5b6001600160a01b0381165f9081526024602052604090819020805460ff19169055516111669061382c565b6001600160a01b03811661323f5750565b426001541161326457604051600162012c6360e61b0319815260040160405180910390fd5b50565b335f9081526021602052604090205460ff1661180d5760405163733ac1c560e11b815260040160405180910390fd5b5f428211156132b857604051638471b00160e01b815260040160405180910390fd5b335f90815260208190526040902054610f98904290600160781b900464ffffffffff1661377c565b335f90815260208052604090205460ff1661180d5760405163733ac1c560e11b815260040160405180910390fd5b816014528060345263a9059cbb60601b5f5260205f604460105f875af13d1560015f51141716613345576390b8ec185f526004601cfd5b5f603452505050565b5f61335883613394565b8015611d0d5750611d0d83836133c6565b6004546001600160a01b0316331461180d5760405163733ac1c560e11b815260040160405180910390fd5b5f6133a6826301ffc9a760e01b6133c6565b8015610f9857506133bf826001600160e01b03196133c6565b1592915050565b6040516001600160e01b0319821660248201525f90819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b17815282519293505f9283928392909183918a617530fa92503d91505f519050828015613436575060208210155b801561344157505f81115b979650505050505050565b80356001600160a01b0381168114613462575f5ffd5b919050565b5f60208284031215613477575f5ffd5b611d0d8261344c565b5f60208284031215613490575f5ffd5b81356001600160e01b031981168114611d0d575f5ffd5b5f602082840312156134b7575f5ffd5b5035919050565b80358015158114613462575f5ffd5b5f602082840312156134dd575f5ffd5b611d0d826134be565b5f5f604083850312156134f7575f5ffd5b50508035926020909101359150565b602080825282518282018190525f918401906040840190835b818110156135465783516001600160a01b031683526020938401939092019160010161351f565b509095945050505050565b803561ffff81168114613462575f5ffd5b5f60208284031215613572575f5ffd5b611d0d82613551565b602080825282518282018190525f918401906040840190835b81811015613546578351835260209384019390920191600101613594565b5f5f5f606084860312156135c4575f5ffd5b833592506135d46020850161344c565b91506135e26040850161344c565b90509250925092565b5f5f604083850312156135fc575f5ffd5b6136058361344c565b91506136136020840161344c565b90509250929050565b803563ffffffff81168114613462575f5ffd5b5f6020828403121561363f575f5ffd5b611d0d8261361c565b5f5f82840361012081121561365b575f5ffd5b83359250610100601f1982011215613671575f5ffd5b50604051610100810181811067ffffffffffffffff821117156136a257634e487b7160e01b5f52604160045260245ffd5b6040526136b1602085016134be565b81526136bf60408501613551565b60208201526136d06060850161361c565b60408201526136e16080850161344c565b60608201526136f260a0850161344c565b608082015261370360c0850161344c565b60a082015261371460e0850161344c565b60c0820152613726610100850161344c565b60e0820152809150509250929050565b6001600160a01b039290921682521515602082015260400190565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610f9857610f98613751565b80820180821115610f9857610f98613751565b5f6020828403121561379f575f5ffd5b5051919050565b5f826137c057634e487b7160e01b5f52601260045260245ffd5b500490565b5f6001600160781b0382166001600160781b0381036137e6576137e6613751565b60010192915050565b5f816137fd576137fd613751565b505f190190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b6513585c9ad95d60d21b815260060190565b5f6001820161384f5761384f613751565b5060010190565b5f6101208201905083825282511515602083015261ffff602084015116604083015263ffffffff604084015116606083015260608301516138a260808401826001600160a01b03169052565b5060808301516001600160a01b03811660a08401525060a08301516001600160a01b03811660c08401525060c08301516001600160a01b03811660e08401525060e08301516001600160a01b03811661010084015250939250505056fe40f7b3ef64c9e38288873dda008188d6c3cd146f84d77b978478a8731f71feb97cbd46c789962ee73435d84bcd3c0927fb55fd04ce92deedbdae7e783739544ca2646970667358221220439cdd9789fa974154b8e848e9b3eede275480b9c5035b54f2a6fdd16e7ac89564736f6c634300081c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000097f6886d04c804a278caf904e1adf5864b38452100000000000000000000000097f6886d04c804a278caf904e1adf5864b384521000000000000000000000000000000000000000000000000000000006a13ddd30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000754704bc059f8c67012fed69bc8a327a5aafb603

-----Decoded View---------------
Arg [0] : dao (address): 0x97f6886d04C804A278Caf904e1aDF5864B384521
Arg [1] : ec (address): 0x97f6886d04C804A278Caf904e1aDF5864B384521
Arg [2] : genesisEpoch_ (uint256): 1779686867
Arg [3] : sequencer_ (address): 0x0000000000000000000000000000000000000000
Arg [4] : feeToken_ (address): 0x754704Bc059F8C67012fEd69BC8A327a5aafb603

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000097f6886d04c804a278caf904e1adf5864b384521
Arg [1] : 00000000000000000000000097f6886d04c804a278caf904e1adf5864b384521
Arg [2] : 000000000000000000000000000000000000000000000000000000006a13ddd3
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 000000000000000000000000754704bc059f8c67012fed69bc8a327a5aafb603


Deployed Bytecode Sourcemap

73399:55189:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87725:202;;;;;;:::i;:::-;;:::i;:::-;;126978:313;;;;;;:::i;:::-;;:::i;:::-;;;839:14:1;;832:22;814:41;;802:2;787:18;126978:313:0;;;;;;;;81992:52;;;;;;:::i;:::-;;;;;;;;;;;;;;;;123441:701;;;;;;:::i;:::-;;:::i;79239:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;79239:50:0;;;;;;;;;;;;;;;;;;;;;;;;1564:14:1;;1557:22;1539:41;;1628:6;1616:19;;;1611:2;1596:18;;1589:47;1684:10;1672:23;;;1652:18;;;1645:51;;;;-1:-1:-1;;;;;1732:32:1;;;1727:2;1712:18;;1705:60;1802:32;;;1796:3;1781:19;;1774:61;1872:32;;1752:3;1851:19;;1844:61;1942:32;;;1936:3;1921:19;;1914:61;2012:32;2006:3;1991:19;;1984:61;1526:3;1511:19;79239:50:0;1206:845:1;69089:1083:0;;;;;;:::i;:::-;;:::i;80103:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2552:25:1;;;2540:2;2525:18;80103:64:0;2406:177:1;76017:43:0;;;;;;117615:430;;;;;;:::i;:::-;;:::i;74717:28::-;;;;;-1:-1:-1;;;;;74717:28:0;;;;;;-1:-1:-1;;;;;2752:32:1;;;2734:51;;2722:2;2707:18;74717:28:0;2588:203:1;82176:53:0;;;;;;:::i;:::-;;;;;;;;;;;;;;;;101442:293;;;;;;:::i;:::-;;:::i;88738:273::-;;;;;;:::i;:::-;;:::i;87229:217::-;;;;;;:::i;:::-;;:::i;112378:430::-;;;;;;:::i;:::-;;:::i;100576:471::-;;;;;;:::i;:::-;;:::i;73966:25::-;;;;;-1:-1:-1;;;;;73966:25:0;;;97706:589;;;;;;:::i;:::-;;:::i;79712:60::-;;;;;;:::i;:::-;;;;;;;;;;;;;;95089:487;;;;;;:::i;:::-;;:::i;81585:53::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;92198:247;;;;;;:::i;:::-;;:::i;75620:24::-;;;;;-1:-1:-1;;;;;75620:24:0;;;80813:51;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;80813:51:0;;;102031:413;;;;;;:::i;:::-;;:::i;91701:229::-;;;;;;:::i;:::-;;:::i;65798:1128::-;;;;;;:::i;:::-;;:::i;91236:205::-;;;;;;:::i;:::-;;:::i;85846:230::-;;;:::i;67775:298::-;;;:::i;76161:34::-;;;;;;63056:1422;;;;;;:::i;:::-;;:::i;78502:32::-;;;;;-1:-1:-1;;;;;78502:32:0;;;126582:108;;;:::i;:::-;;;;;;;:::i;75112:28::-;;;;;-1:-1:-1;;;;;75112:28:0;;;124296:645;;;:::i;76928:37::-;;;;;;78395:29;;;;;-1:-1:-1;;;78395:29:0;;-1:-1:-1;;;;;78395:29:0;;;79486:56;;;;;;:::i;:::-;;;;;;;;;;;;;;74365:23;;;;;-1:-1:-1;;;;;74365:23:0;;;93190:232;;;;;;:::i;:::-;;:::i;116815:404::-;;;;;;:::i;:::-;;:::i;122638:601::-;;;;;;:::i;:::-;;:::i;88212:216::-;;;;;;:::i;:::-;;:::i;96922:357::-;;;;;;:::i;:::-;;:::i;64899:272::-;;;;;;:::i;:::-;;:::i;126395:110::-;;;:::i;:::-;;;;;;;:::i;74190:31::-;;;;;-1:-1:-1;;;;;74190:31:0;;;78716:33;;;;;-1:-1:-1;;;;;78716:33:0;;;80325:47;;;;;;:::i;:::-;;;;;;;;;;;;;;;;98736:464;;;;;;:::i;:::-;;:::i;120592:1331::-;;;;;;:::i;:::-;;:::i;78959:30::-;;;;;;77137:39;;;;;;;;;;;;5311:6:1;5299:19;;;5281:38;;5269:2;5254:18;77137:39:0;5137:188:1;90763:223:0;;;;;;:::i;:::-;;:::i;68496:280::-;;;;;;:::i;:::-;;:::i;89832:199::-;;;;;;:::i;:::-;;:::i;99690:469::-;;;;;;:::i;:::-;;:::i;111538:404::-;;;;;;:::i;:::-;;:::i;73545:48::-;;73586:7;73545:48;;81017:49;;;;;;:::i;:::-;;;;;;;;;;;;;;;;95991:338;;;;;;:::i;:::-;;:::i;77530:73::-;;;;;;;;;;;;73668:41;;;;;90287:217;;;;;;:::i;:::-;;:::i;109745:1374::-;;;;;;:::i;:::-;;:::i;73783:27::-;;;;;;125392:266;;;;;;:::i;:::-;;:::i;108540:816::-;;;;;;:::i;:::-;;:::i;104128:1784::-;;;;;;:::i;:::-;;:::i;93628:159::-;;;;;;:::i;:::-;;:::i;86307:643::-;;;;;;:::i;:::-;;:::i;78801:20::-;;;;;-1:-1:-1;;;78801:20:0;;;;;;;;;6126:10:1;6114:23;;;6096:42;;6084:2;6069:18;78801:20:0;5952:192:1;115042:400:0;;;;;;:::i;:::-;;:::i;119072:1053::-;;;;;;:::i;:::-;;:::i;75433:27::-;;;;;-1:-1:-1;;;;;75433:27:0;;;74967;;;;;-1:-1:-1;;;;;74967:27:0;;;94196:494;;;;;;:::i;:::-;;:::i;75271:25::-;;;;;-1:-1:-1;;;;;75271:25:0;;;74059:23;;;;;-1:-1:-1;;;;;74059:23:0;;;77895:47;;;;;-1:-1:-1;;;77895:47:0;;;;;;92702:223;;;;;;:::i;:::-;;:::i;89319:266::-;;;;;;:::i;:::-;;:::i;122225:159::-;;;;;;:::i;:::-;122312:7;122339:20;;;:11;:20;;;;;:37;;;;;;;122225:159;106176:2071;;;;;;:::i;:::-;;:::i;113191:404::-;;;;;;:::i;:::-;;:::i;102729:1161::-;;;;;;:::i;:::-;;:::i;77322:37::-;;;;;;;;;;;;81205:54;;;;;;:::i;:::-;;;;;;;;;;;;;;;;74448:18;;;;;-1:-1:-1;;;;;74448:18:0;;;78609:28;;;;;-1:-1:-1;;;;;78609:28:0;;;126083:228;;;;;;:::i;:::-;;:::i;113995:430::-;;;;;;:::i;:::-;;:::i;67347:129::-;;;;;;:::i;:::-;-1:-1:-1;;;;;67437:17:0;67411:9;67437:17;;;;;;;;;;:31;-1:-1:-1;;;;;67437:31:0;;67347:129;80567:58;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;80567:58:0;;;116015:426;;;;;;:::i;:::-;;:::i;74528:20::-;;;;;-1:-1:-1;;;;;74528:20:0;;;76303:34;;;;;;77669:33;;;;;;;;;;;;81400:53;;;;;;:::i;:::-;;;;;;;;;;;;;;;;87725:202;87802:3;;87777:29;;-1:-1:-1;;;;;87802:3:0;87777:24;:29::i;:::-;87817:27;:25;:27::i;:::-;87857:3;:12;;-1:-1:-1;;;;;;87857:12:0;-1:-1:-1;;;;;87857:12:0;;;;;87885:34;;-1:-1:-1;;;7608:18:1;;7651:1;7642:11;87885:34:0;;;;;;;;;-1:-1:-1;;;;;2752:32:1;;2734:51;;87885:34:0;;;2722:2:1;2707:18;87885:34:0;;;;;;;;87725:202;:::o;126978:313::-;127079:4;-1:-1:-1;;;;;;127116:49:0;;-1:-1:-1;;;127116:49:0;;:114;;-1:-1:-1;;;;;;;127182:48:0;;-1:-1:-1;;;127182:48:0;127116:114;:167;;;-1:-1:-1;;;;;;;;;;54820:40:0;;;127247:36;127096:187;126978:313;-1:-1:-1;;126978:313:0:o;123441:701::-;123541:10;123519:33;;;;:21;:33;;;;;;;;123514:105;;123576:31;;-1:-1:-1;;;123576:31:0;;;;;;;;;;;123514:105;-1:-1:-1;;;;;;;;;;;123734:37:0;-1:-1:-1;;;;;123892:30:0;;:40;;123888:115;;123956:35;;-1:-1:-1;;;123956:35:0;;;;;;;;;;;123888:115;124122:1;-1:-1:-1;;;;;;;;;;;124083:41:0;124068:67;123441:701;:::o;69089:1083::-;69202:10;69162:25;69190:23;;;;;;;;;;69468:25;;-1:-1:-1;;;69468:25:0;;;;69446:47;;;;;;69442:118;;69517:31;;-1:-1:-1;;;69517:31:0;;;;;;;;;;;69442:118;69572:23;69782:18;69777:190;;69847:33;;69835:46;;-1:-1:-1;;;69847:33:0;;;;69835:11;:46::i;:::-;69896:59;;-1:-1:-1;;;;69896:59:0;-1:-1:-1;;;69896:59:0;;;;;;;;-1:-1:-1;69777:190:0;69979:46;;-1:-1:-1;;;;;69979:46:0;-1:-1:-1;;;69979:46:0;;;;;;;;;;;;70043:121;;;7832:41:1;;;7904:2;7889:18;;7882:34;;;70080:10:0;;70043:121;;7805:18:1;70043:121:0;;;;;;;;69151:1021;;69089:1083;:::o;117615:430::-;117694:27;:25;:27::i;:::-;-1:-1:-1;;;;;117802:38:0;;;;;;:21;:38;;;;;;;;117797:114;;117864:35;;-1:-1:-1;;;117864:35:0;;;;;;;;;;;117797:114;-1:-1:-1;;;;;117930:38:0;;;;;;:21;:38;;;;;;;117923:45;;-1:-1:-1;;117923:45:0;;;117984:53;-1:-1:-1;;;8129:22:1;;8176:1;8167:11;117984:53:0;;;;;;;;-1:-1:-1;;;;;;;;;;;118014:15:0;118031:5;117984:53;;;;;;;:::i;101442:293::-;101586:9;;-1:-1:-1;;;;;101586:9:0;101572:10;:23;101568:94;;101619:31;;-1:-1:-1;;;101619:31:0;;;;;;;;;;;101568:94;101674:32;;;;:25;:32;;;;;;:53;101442:293::o;88738:273::-;88835:13;;88810:39;;-1:-1:-1;;;;;88835:13:0;88810:24;:39::i;:::-;88860:27;:25;:27::i;:::-;88900:13;:32;;-1:-1:-1;;;;;;88900:32:0;-1:-1:-1;;;;;88900:32:0;;;;;88948:55;;-1:-1:-1;;;8680:29:1;;8734:2;8725:12;88948:55:0;8478:265:1;87229:217:0;87316:8;;87291:34;;-1:-1:-1;;;;;87316:8:0;87291:24;:34::i;:::-;87336:27;:25;:27::i;:::-;87376:8;:22;;-1:-1:-1;;;;;;87376:22:0;-1:-1:-1;;;;;87376:22:0;;;;;;;;87414:24;;2734:51:1;;;87414:24:0;;2722:2:1;2707:18;87414:24:0;;;;;;;;87229:217;:::o;112378:430::-;112457:27;:25;:27::i;:::-;-1:-1:-1;;;;;112565:38:0;;;;;;:21;:38;;;;;;;;112560:114;;112627:35;;-1:-1:-1;;;112627:35:0;;;;;;;;;;;112560:114;-1:-1:-1;;;;;112693:38:0;;;;;;:21;:38;;;;;;;112686:45;;-1:-1:-1;;112686:45:0;;;112747:53;-1:-1:-1;;;8950:22:1;;8997:1;8988:11;112747:53:0;8748:257:1;100576:471:0;100637:27;:25;:27::i;:::-;100758:3;100750:5;:11;:27;;;;100773:4;100765:5;:12;100750:27;100746:102;;;100801:35;;-1:-1:-1;;;100801:35:0;;;;;;;;;;;100746:102;100991:12;:5;100999:4;100991:12;:::i;:::-;100975:13;:28;101019:20;;2552:25:1;;;101019:20:0;;2540:2:1;2525:18;101019:20:0;2406:177:1;97706:589:0;97782:27;:25;:27::i;:::-;97892:4;97884:5;:12;97880:87;;;97920:35;;-1:-1:-1;;;97920:35:0;;;;;;;;;;;97880:87;98090:4;98082:5;:12;:26;;;;-1:-1:-1;98098:10:0;;;98082:26;98078:101;;;98132:35;;-1:-1:-1;;;98132:35:0;;;;;;;;;;;98078:101;98191:28;:36;;;98243:44;;-1:-1:-1;;;9517:35:1;;9577:2;9568:12;98243:44:0;;;;;;;;;2552:25:1;;;98243:44:0;;;2540:2:1;2525:18;98243:44:0;2406:177:1;95089:487:0;95153:27;:25;:27::i;:::-;95255:4;95247:5;:12;95243:87;;;95283:35;;-1:-1:-1;;;95283:35:0;;;;;;;;;;;95243:87;95431:16;:32;;;;;;;;-1:-1:-1;;95431:32:0;;;;;;;95502:27;;95457:5;;95502:19;;;;;;:27;:::i;:::-;95474:18;:56;;;;;;;;;-1:-1:-1;;95474:56:0;;;;;;;;;95546:22;;-1:-1:-1;;;9923:20:1;;9968:1;9959:11;95546:22:0;;;;;;;;;2552:25:1;;;95546:22:0;;;2540:2:1;2525:18;95546:22:0;2406:177:1;92198:247:0;92278:27;:25;:27::i;:::-;92318:17;:40;;-1:-1:-1;;;;;;92318:40:0;-1:-1:-1;;;;;92318:40:0;;;;;92374:63;;-1:-1:-1;;;10183:33:1;;10241:2;10232:12;92374:63:0;9981:269:1;102031:413:0;102106:27;:25;:27::i;:::-;102175:9;;102164:42;;;-1:-1:-1;;;102164:42:0;;;;102146:15;;-1:-1:-1;;;;;102175:9:0;;102164:40;;:42;;;;;;;;;;;;;;102175:9;102164:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;102146:60;;102224:9;102219:160;102239:7;102235:1;:11;102219:160;;;102268:32;;;;:29;:32;;;;;:49;;;102349:18;102366:1;102303:14;102349:18;:::i;:::-;102332:35;-1:-1:-1;102248:3:0;;102219:160;;;-1:-1:-1;102396:40:0;;2552:25:1;;;102396:40:0;;2540:2:1;2525:18;102396:40:0;;;;;;;;102095:349;102031:413;:::o;91701:229::-;91775:27;:25;:27::i;:::-;91815:14;:34;;;;-1:-1:-1;;;;;;;;91815:34:0;;;;;;91865:57;;-1:-1:-1;;;10868:30:1;;10923:2;10914:12;91865:57:0;10666:266:1;65798:1128:0;65912:10;65872:25;65900:23;;;;;;;;;;66179;;-1:-1:-1;;;66179:23:0;;;;66159:43;;;;;;66155:114;;66226:31;;-1:-1:-1;;;66226:31:0;;;;;;;;;;;66155:114;66281:23;66482:16;66477:184;;66545:31;;66533:44;;-1:-1:-1;;;66545:31:0;;;;66533:11;:44::i;:::-;66592:57;;-1:-1:-1;;;;66592:57:0;-1:-1:-1;;;66592:57:0;;;;;;;;-1:-1:-1;66477:184:0;66673:42;;-1:-1:-1;;;;66673:42:0;-1:-1:-1;;;66673:42:0;;;;;;;;;;;;66796:122;;;7832:41:1;;;7904:2;7889:18;;7882:34;;;66836:10:0;;66796:122;;7805:18:1;66796:122:0;7664:258:1;91236:205:0;91302:27;:25;:27::i;:::-;91342:10;:26;;-1:-1:-1;;;;;;91342:26:0;-1:-1:-1;;;;;91342:26:0;;;;;91384:49;;-1:-1:-1;;;11139:26:1;;11181:12;91384:49:0;10937:262:1;85846:230:0;85890:22;:20;:22::i;:::-;85968:8;;85991:10;;86016:41;;-1:-1:-1;;;86016:41:0;;86051:4;86016:41;;;2734:51:1;85925:143:0;;-1:-1:-1;;;;;85968:8:0;;;;85991:10;;85968:8;;86016:26;;2707:18:1;;86016:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85925:28;:143::i;:::-;85846:230::o;67775:298::-;67990:10;68017:11;:23;;;;;;;;;;68015:39;;67951:114;;68017:11;68015:39;;-1:-1:-1;;;;;68015:39:0;;:::i;:::-;;;-1:-1:-1;;;;;68015:39:0;;;;;;;;;;;;;;;;;;;67951:114;;11588:64:1;;;11576:2;11561:18;67951:114:0;;;;;;;67775:298::o;63056:1422::-;1362:10;63263:8;:27;63259:98;;;63314:31;;-1:-1:-1;;;63314:31:0;;;;;;;;;;;63259:98;63409:10;63369:25;63397:23;;;;;;;;;;63780:19;;-1:-1:-1;;;63780:19:0;;;;63814:23;;;63810:561;;;63971:31;;-1:-1:-1;;;63971:31:0;;;;63953:15;:49;;:121;;-1:-1:-1;64041:33:0;;-1:-1:-1;;;64041:33:0;;;;64023:15;:51;63953:121;63931:233;;;64116:32;;-1:-1:-1;;;64116:32:0;;;;;;;;;;;63931:233;64178:18;64206:30;64221:15;64206:12;:30;:::i;:::-;64252:45;;-1:-1:-1;;;;64312:47:0;-1:-1:-1;;;64252:45:0;;;;;;;;-1:-1:-1;;;;64312:47:0;;-1:-1:-1;;;64312:47:0;;;;;;;-1:-1:-1;63810:561:0;64383:38;;-1:-1:-1;;;;64383:38:0;-1:-1:-1;;;64383:38:0;;;;;;;64437:33;;2552:25:1;;;64449:10:0;;64437:33;;2540:2:1;2525:18;64437:33:0;2406:177:1;126582:108:0;126631:16;126667:15;126660:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;126660:22:0;;;;;;;;;;;;;;;;;;;;;;;126582:108;:::o;124296:645::-;124345:15;-1:-1:-1;;;;;;;;;;;124476:37:0;124709:11;;;124705:61;;124737:17;124296:645;:::o;124705:61::-;124911:10;124895:38;;124296:645;-1:-1:-1;124296:645:0:o;93190:232::-;93265:27;:25;:27::i;:::-;93305:18;:35;;-1:-1:-1;;;;;;93305:35:0;-1:-1:-1;;;;;93305:35:0;;;;;93356:58;;-1:-1:-1;;;11865:34:1;;11924:2;11915:12;93356:58:0;11663:270:1;116815:404:0;116886:27;:25;:27::i;:::-;-1:-1:-1;;;;;116992:33:0;;;;;;:21;:33;;;;;;;;116988:108;;;117049:35;;-1:-1:-1;;;117049:35:0;;;;;;;;;;;116988:108;-1:-1:-1;;;;;117108:33:0;;;;;;:21;:33;;;;;;;:40;;-1:-1:-1;;117108:40:0;117144:4;117108:40;;;117164:47;;;-1:-1:-1;;;8129:22:1;;8176:1;8167:11;;7927:257;117164:47:0;;;;;;;;-1:-1:-1;;;;;;;;;;;117194:10:0;117206:4;117164:47;;;;;;;:::i;122638:601::-;122741:10;122719:33;;;;:21;:33;;;;;;;;122714:105;;122776:31;;-1:-1:-1;;;122776:31:0;;;;;;;;;;;122714:105;-1:-1:-1;;;;;122909:31:0;;;;;;:15;:31;;;;;;;;122904:107;;122964:35;;-1:-1:-1;;;122964:35:0;;;;;;;;;;;122904:107;-1:-1:-1;;;;;123052:32:0;;;-1:-1:-1;;;;;;;;;;;123163:58:0;123148:84;122638:601;:::o;88212:216::-;88293:5;;88268:31;;-1:-1:-1;;;;;88293:5:0;88268:24;:31::i;:::-;88310:27;:25;:27::i;:::-;88350:5;:16;;-1:-1:-1;;;;;;88350:16:0;-1:-1:-1;;;;;88350:16:0;;;;;88382:38;;-1:-1:-1;;;12140:20:1;;12185:1;12176:11;88382:38:0;11938:255:1;96922:357:0;96996:27;:25;:27::i;:::-;97098:4;97090:5;:12;97086:87;;;97126:35;;-1:-1:-1;;;97126:35:0;;;;;;;;;;;97086:87;97185:26;:42;;-1:-1:-1;;97185:42:0;-1:-1:-1;;;97185:42:0;;;;;;;97243:28;;2552:25:1;;;97243:28:0;;2540:2:1;2525:18;97243:28:0;2406:177:1;64899:272:0;-1:-1:-1;;;;;65035:17:0;;64984:11;65035:17;;;;;;;;;;;65008:44;;;;;;;;;-1:-1:-1;;;;;65008:44:0;;;;;-1:-1:-1;;;65008:44:0;;;;;;;;;;;-1:-1:-1;;;65008:44:0;;;;;;;;;;;;-1:-1:-1;;;65008:44:0;;;;;;;;;;;;-1:-1:-1;;;65008:44:0;;;;;;;;;-1:-1:-1;;;65008:44:0;;;;;;;;;;;;;;65073:89;;;65147:15;65113:6;:31;;;:49;;;65073:89;65063:100;64899:272;-1:-1:-1;;;64899:272:0:o;126395:110::-;126445:16;126481;126474:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;126395:110;:::o;98736:464::-;98803:27;:25;:27::i;:::-;745:3;99006:5;:12;;:26;;;;-1:-1:-1;99022:10:0;;;99006:26;99002:101;;;99056:35;;-1:-1:-1;;;99056:35:0;;;;;;;;;;;99002:101;99115:19;:27;;;99158:34;;-1:-1:-1;;;12400:25:1;;12450:2;12441:12;99158:34:0;12198:261:1;120592:1331:0;120741:27;:25;:27::i;:::-;120781:20;120804;;;:11;:20;;;;;;;;;120781:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;120781:43:0;;;-1:-1:-1;;;;;120781:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;120940:56;;;120976:20;-1:-1:-1;;;;;120958:38:0;:1;:14;;;-1:-1:-1;;;;;120958:38:0;;;120940:56;:105;;;;121028:17;-1:-1:-1;;;;;121013:32:0;:1;:11;;;-1:-1:-1;;;;;121013:32:0;;;120940:105;120936:190;;;121079:35;;-1:-1:-1;;;121079:35:0;;;;;;;;;;;120936:190;121193:20;;;;:11;:20;;;;;;;;121186:27;;-1:-1:-1;;;;;;121186:27:0;;;;;;;;-1:-1:-1;;;;;;121186:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121331:18;;;;121186:27;121308:42;;;:22;:42;;;;;121301:49;;;121401:15;121399:17;;121401:15;;121193:20;121399:17;;;:::i;:::-;;;;-1:-1:-1;121458:16:0;:23;121429:26;121512:138;121523:18;121519:1;:22;121512:138;;;121590:7;121567:16;121584:1;121567:19;;;;;;;;:::i;:::-;;;;;;;;;:30;121563:76;121618:5;121563:76;121543:3;;121512:138;;;121662:20;;;;:::i;:::-;;;;121695:108;121706:18;121702:1;:22;121695:108;;;121768:16;121785:5;:1;121789;121785:5;:::i;:::-;121768:23;;;;;;;;:::i;:::-;;;;;;;;;121746:16;121763:1;121746:19;;;;;;;;:::i;:::-;;;;;;;;;;:45;121726:3;;121695:108;;;121815:16;:22;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;121853:62;121866:7;121875:20;121897:17;121853:62;;;;;;;13071:25:1;;;-1:-1:-1;;;;;13132:32:1;;;13127:2;13112:18;;13105:60;13201:32;13196:2;13181:18;;13174:60;13059:2;13044:18;;12869:371;121853:62:0;;;;;;;;120730:1193;;;120592:1331;;;:::o;90763:223::-;90835:27;:25;:27::i;:::-;90875:13;:32;;-1:-1:-1;;;;;;90875:32:0;-1:-1:-1;;;;;90875:32:0;;;;;90923:55;;-1:-1:-1;;;13447:29:1;;13501:2;13492:12;90923:55:0;13245:265:1;68496:280:0;-1:-1:-1;;;;;68636:17:0;;68585:11;68636:17;;;;;;;;;;;68609:44;;;;;;;;;-1:-1:-1;;;;;68609:44:0;;;;;-1:-1:-1;;;68609:44:0;;;;;;;;;;;-1:-1:-1;;;68609:44:0;;;;;;;;;;;;-1:-1:-1;;;68609:44:0;;;;;;;;;;-1:-1:-1;;;68609:44:0;;;;;;;;;-1:-1:-1;;;68609:44:0;;;;;;;;;;;;;;;68674:93;;;68752:15;68716:6;:33;;;:51;;;68664:104;68496:280;-1:-1:-1;;;68496:280:0:o;89832:199::-;89896:27;:25;:27::i;:::-;89936:9;:24;;-1:-1:-1;;;;;;89936:24:0;-1:-1:-1;;;;;89936:24:0;;;;;89976:47;;-1:-1:-1;;;13717:25:1;;13767:2;13758:12;89976:47:0;13515:261:1;99690:469:0;99757:27;:25;:27::i;:::-;745:3;99965:5;:12;;:26;;;;-1:-1:-1;99981:10:0;;;99965:26;99961:101;;;100015:35;;-1:-1:-1;;;100015:35:0;;;;;;;;;;;99961:101;100074:19;:27;;;100117:34;;-1:-1:-1;;;13983:25:1;;14033:2;14024:12;100117:34:0;13781:261:1;111538:404:0;111609:27;:25;:27::i;:::-;-1:-1:-1;;;;;111715:33:0;;;;;;:21;:33;;;;;;;;111711:108;;;111772:35;;-1:-1:-1;;;111772:35:0;;;;;;;;;;;111711:108;-1:-1:-1;;;;;111831:33:0;;;;;;:21;:33;;;;;;;:40;;-1:-1:-1;;111831:40:0;111867:4;111831:40;;;111887:47;;;-1:-1:-1;;;8950:22:1;;8997:1;8988:11;;8748:257;95991:338:0;96058:27;:25;:27::i;:::-;96159:3;96151:5;:11;96147:86;;;96186:35;;-1:-1:-1;;;96186:35:0;;;;;;;;;;;96147:86;96245:19;:35;;-1:-1:-1;;96245:35:0;;;;;;;;;96296:25;;-1:-1:-1;;;14249:23:1;;14297:1;14288:11;96296:25:0;14047:258:1;90287:217:0;90357:27;:25;:27::i;:::-;90397:12;:30;;-1:-1:-1;;;;;;90397:30:0;-1:-1:-1;;;;;90397:30:0;;;;;90443:53;;-1:-1:-1;;;14512:28:1;;14565:2;14556:12;90443:53:0;14310:264:1;109745:1374:0;109824:27;:25;:27::i;:::-;-1:-1:-1;;;;;109949:31:0;;;;;;:15;:31;;;;;;;;109944:107;;110004:35;;-1:-1:-1;;;110004:35:0;;;;;;;;;;;109944:107;-1:-1:-1;;;;;110070:31:0;;;;;;:15;:31;;;;;110063:38;;-1:-1:-1;;110063:38:0;;;110166:15;:22;;;;110244:179;110264:10;110260:1;:14;110244:179;;;110322:14;-1:-1:-1;;;;;110300:36:0;:15;110316:1;110300:18;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;110300:18:0;:36;110296:116;;110371:1;110357:15;;110391:5;;110296:116;110276:3;;110244:179;;;-1:-1:-1;110681:12:0;;;;:::i;:::-;;;110666:11;:27;110662:102;;110717:35;;-1:-1:-1;;;110717:35:0;;;;;;;;;;;110662:102;110875:15;110891:10;110875:27;;;;;;;;:::i;:::-;;;;;;;;;;;110844:15;:28;;-1:-1:-1;;;;;110875:27:0;;;;110860:11;;110844:28;;;;;;:::i;:::-;;;;;;;;;:58;;;;;-1:-1:-1;;;;;110844:58:0;;;;;-1:-1:-1;;;;;110844:58:0;;;;;;111015:15;:21;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;111015:21:0;;;;;;;-1:-1:-1;;;;;;111015:21:0;;;;;;111052:59;;-1:-1:-1;;;14781:29:1;;14835:2;14826:12;111052:59:0;;;;;;;-1:-1:-1;;;;;;;;;;;111089:14:0;111105:5;111052:59;;;;;;;:::i;125392:266::-;125506:27;:25;:27::i;:::-;-1:-1:-1;;;;;125546:31:0;;;;;;;:23;:31;;;;;;;:41;;-1:-1:-1;;;;;;125546:41:0;;;;;;;;;;;125603:47;-1:-1:-1;;;15051:23:1;;15099:1;15090:11;125603:47:0;;;;;;;;;;-1:-1:-1;;;;;15304:32:1;;;15286:51;;15373:32;;15368:2;15353:18;;15346:60;125603:47:0;;;15259:18:1;125603:47:0;;;;;;;125392:266;;:::o;108540:816::-;108613:27;:25;:27::i;:::-;-1:-1:-1;;;;;108718:26:0;;;;;;:15;:26;;;;;;;;108714:101;;;108768:35;;-1:-1:-1;;;108768:35:0;;;;;;;;;;;108714:101;108905:125;108955:9;-1:-1:-1;;;108905:31:0;:125::i;:::-;108886:225;;109064:35;;-1:-1:-1;;;109064:35:0;;;;;;;;;;;108886:225;109202:15;:31;;;;;;;;;;;;;;-1:-1:-1;;;;;;109202:31:0;-1:-1:-1;;;;;109202:31:0;;;;;;;;-1:-1:-1;109244:26:0;;;:15;109202:31;109244:26;;;;;;:33;;-1:-1:-1;;109244:33:0;;;;;;;109295:53;-1:-1:-1;;;14781:29:1;;14826:12;109295:53:0;14579:265:1;104128:1784:0;104206:35;:33;:35::i;:::-;104273:122;104323:11;-1:-1:-1;;;104273:31:0;:122::i;:::-;104254:222;;104429:35;;-1:-1:-1;;;104429:35:0;;;;;;;;;;;104254:222;104547:8;;;-1:-1:-1;;;;;104566:22:0;;;-1:-1:-1;;;;;;104566:22:0;;;;;;104774:16;;104547:8;;;;104774:16;104754:36;;104750:512;;-1:-1:-1;;;;;104814:40:0;;;;;;:22;:40;;;;;;;;104807:47;;-1:-1:-1;;104807:47:0;;;;;;104876:20;:38;;;;;;;104869:45;;;;;;;104934:53;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;;;;;;;104963:16:0;104981:5;104934:53;;;;;;;:::i;:::-;;;;;;;;105162:10;;-1:-1:-1;;;;;105142:30:0;;;105162:10;;105142:30;105138:113;;-1:-1:-1;;;;;105200:35:0;;;;;;:17;:35;;;;;105193:42;;-1:-1:-1;;105193:42:0;;;105138:113;-1:-1:-1;;;;;105311:30:0;;;;;;:17;:30;;;;;;;:37;;105344:4;-1:-1:-1;;105311:37:0;;;;;;;;105359:22;:35;;;;;;;:42;;;;;;;;;;105417:115;-1:-1:-1;;;15880:23:1;;15928:1;15919:11;105417:115:0;;;;;;;;;-1:-1:-1;;;;;15304:32:1;;;15286:51;;15373:32;;15368:2;15353:18;;15346:60;105417:115:0;;;15259:18:1;105417:115:0;;;;;;;-1:-1:-1;;;;;105652:33:0;;;;;;:20;:33;;;;;;;;105647:174;;-1:-1:-1;;;;;105702:33:0;;;;;;:20;:33;;;;;;;:40;;-1:-1:-1;;105702:40:0;105738:4;105702:40;;;105762:47;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;;;;;;;105791:11:0;105804:4;105762:47;;;;;;;:::i;:::-;;;;;;;;105647:174;105878:11;-1:-1:-1;;;;;105868:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104195:1717;104128:1784;:::o;93628:159::-;93685:27;:25;:27::i;:::-;93725:6;:18;;-1:-1:-1;;;;93725:18:0;-1:-1:-1;;;93725:18:0;;;;;;;;;;;;;93759:20;;6096:42:1;;;93759:20:0;;6084:2:1;6069:18;93759:20:0;5952:192:1;86307:643:0;86608:12;;86590:15;:30;86586:105;;;86644:35;;-1:-1:-1;;;86644:35:0;;;;;;;;;;;86586:105;86703:27;:25;:27::i;:::-;86761:15;86745:12;;:31;86741:105;;86800:34;;-1:-1:-1;;;;;;86800:34:0;;;;;;;;;;;86741:105;86858:12;:30;;;86906:36;;2552:25:1;;;86906:36:0;;2540:2:1;2525:18;86906:36:0;2406:177:1;115042:400:0;115112:27;:25;:27::i;:::-;-1:-1:-1;;;;;115218:32:0;;;;;;:20;:32;;;;;;;;115214:107;;;115274:35;;-1:-1:-1;;;115274:35:0;;;;;;;;;;;115214:107;-1:-1:-1;;;;;115333:32:0;;;;;;:20;:32;;;;;;;:39;;-1:-1:-1;;115333:39:0;115368:4;115333:39;;;115388:46;;;;:::i;119072:1053::-;119179:27;:25;:27::i;:::-;119352:20;;;;:11;:20;;;;;:32;;;;:55;;-1:-1:-1;119389:18:0;;119388:19;119352:55;119348:130;;;119431:35;;-1:-1:-1;;;119431:35:0;;;;;;;;;;;119348:130;119596:7;119607:1;119596:12;119592:87;;119632:35;;-1:-1:-1;;;119632:35:0;;;;;;;;;;;119592:87;119796:23;;;;;119773:47;;;;;;:22;:47;;;;;;;:52;119769:127;;119849:35;;-1:-1:-1;;;119849:35:0;;;;;;;;;;;119769:127;119908:20;;;;:11;:20;;;;;;;;:29;;;;;;;;;;;;;;;;-1:-1:-1;;119908:29:0;;;;;;-1:-1:-1;;119908:29:0;;;;;;;;;;;;;;-1:-1:-1;;;;;;119908:29:0;;;;;;;;;;-1:-1:-1;;;;;;119908:29:0;;;;;-1:-1:-1;;;;;;;;119908:29:0;;;;;;;;;;;-1:-1:-1;119908:29:0;;;;;-1:-1:-1;;;;;;119908:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;119948:47;;:22;:47;;;;;:57;;;120016:16;:30;;;;;;;;;;;;;;120059:15;120057:17;;120059:15;;119908:20;120057:17;;;:::i;:::-;;;;-1:-1:-1;120092:25:0;;;;;;120101:7;;120110:6;;120092:25;:::i;94196:494::-;94263:27;:25;:27::i;:::-;94364:3;94356:5;:11;94352:86;;;94391:35;;-1:-1:-1;;;94391:35:0;;;;;;;;;;;94352:86;94542:19;:35;;-1:-1:-1;;94542:35:0;;;;;;;;;;;;;94616:24;;94542:35;;94616:16;;;;;:24;:::i;:::-;94588:18;:53;;;;;;;;;-1:-1:-1;;94588:53:0;;;;;;;;;94657:25;;-1:-1:-1;;;17347:23:1;;17395:1;17386:11;94657:25:0;17145:258:1;92702:223:0;92774:27;:25;:27::i;:::-;92814:13;:32;;-1:-1:-1;;;;;;92814:32:0;-1:-1:-1;;;;;92814:32:0;;;;;92862:55;;-1:-1:-1;;;17610:29:1;;17664:2;17655:12;92862:55:0;17408:265:1;89319:266:0;89414:12;;89389:38;;-1:-1:-1;;;;;89414:12:0;89389:24;:38::i;:::-;89438:27;:25;:27::i;:::-;89478:12;:30;;-1:-1:-1;;;;;;89478:30:0;-1:-1:-1;;;;;89478:30:0;;;;;89524:53;;-1:-1:-1;;;17880:28:1;;17933:2;17924:12;89524:53:0;17678:264:1;106176:2071:0;106259:35;:33;:35::i;:::-;106383:16;;;-1:-1:-1;;;;;106410:38:0;;;-1:-1:-1;;;;;;106410:38:0;;;;;;106650:8;;106383:16;;;;106650:8;106622:36;;106618:627;;-1:-1:-1;;;;;106682:48:0;;;;;;:22;:48;;;;;;;;106675:55;;-1:-1:-1;;106675:55:0;;;;;;106752:20;:46;;;;;;;106745:53;;;;;;;106818:127;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;;;;;;;106882:24:0;106925:5;106818:127;;;;;;;:::i;:::-;;;;;;;;107137:10;;-1:-1:-1;;;;;107109:38:0;;;107137:10;;107109:38;107105:129;;-1:-1:-1;;;;;107175:43:0;;;;;;:17;:43;;;;;107168:50;;-1:-1:-1;;107168:50:0;;;107105:129;-1:-1:-1;;;;;107294:38:0;;;;;;:17;:38;;;;;;;:45;;107335:4;-1:-1:-1;;107294:45:0;;;;;;;;107350:22;:43;;;;;;;:50;;;;;;;;;;107416:140;-1:-1:-1;;;18149:32:1;;18206:2;18197:12;107416:140:0;;;;;;;;;-1:-1:-1;;;;;15304:32:1;;;15286:51;;15373:32;;15368:2;15353:18;;15346:60;107416:140:0;;;15259:18:1;107416:140:0;;;;;;;-1:-1:-1;;;;;107676:41:0;;;;;;:20;:41;;;;;;;;107671:198;;-1:-1:-1;;;;;107734:41:0;;;;;;:20;:41;;;;;;;:48;;-1:-1:-1;;107734:48:0;107778:4;107734:48;;;107802:55;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;;;;;;;107831:19:0;107852:4;107802:55;;;;;;;:::i;:::-;;;;;;;;107671:198;107953:8;;-1:-1:-1;;;;;107953:8:0;:22;107949:291;;108068:8;;108014:131;;-1:-1:-1;;;;;108068:8:0;-1:-1:-1;;;108014:31:0;:131::i;:::-;107992:237;;;108190:8;;;;;;;;;-1:-1:-1;;;;;108190:8:0;-1:-1:-1;;;;;108180:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107992:237;106248:1999;106176:2071;:::o;113191:404::-;113262:27;:25;:27::i;:::-;-1:-1:-1;;;;;113368:33:0;;;;;;:21;:33;;;;;;;;113364:108;;;113425:35;;-1:-1:-1;;;113425:35:0;;;;;;;;;;;113364:108;-1:-1:-1;;;;;113484:33:0;;;;;;:21;:33;;;;;;;:40;;-1:-1:-1;;113484:40:0;113520:4;113484:40;;;113540:47;;;-1:-1:-1;;;18422:22:1;;18469:1;18460:11;;18220:257;102729:1161:0;102810:27;:25;:27::i;:::-;102914:10;;;-1:-1:-1;;;;;102935:26:0;;;-1:-1:-1;;;;;;102935:26:0;;;;;;103137:16;;102914:10;;;;103137:16;103115:38;;103111:185;;103196:8;;-1:-1:-1;;;;;103174:30:0;;;103196:8;;103174:30;103170:115;;-1:-1:-1;;;;;103232:37:0;;;;;;:17;:37;;;;;103225:44;;-1:-1:-1;;103225:44:0;;;103170:115;-1:-1:-1;;;;;103345:32:0;;;;;;:17;:32;;;;;;;:39;;-1:-1:-1;;103345:39:0;103380:4;103345:39;;;103400:126;;;-1:-1:-1;;;18684:30:1;;18739:2;18730:12;;18482:266;103400:126:0;;;;;;;;;;-1:-1:-1;;;;;15304:32:1;;;15286:51;;15373:32;;15368:2;15353:18;;15346:60;103400:126:0;;;15259:18:1;103400:126:0;15112:300:1;126083:228:0;126165:27;:25;:27::i;:::-;-1:-1:-1;;;;;126205:24:0;;;;;;;:16;:24;;;;;;;:34;;-1:-1:-1;;;;;;126205:34:0;;;;;;;;;;;126255:48;-1:-1:-1;;;18955:24:1;;19004:1;18995:11;126255:48:0;18753:259:1;113995:430:0;114074:27;:25;:27::i;:::-;-1:-1:-1;;;;;114182:38:0;;;;;;:21;:38;;;;;;;;114177:114;;114244:35;;-1:-1:-1;;;114244:35:0;;;;;;;;;;;114177:114;-1:-1:-1;;;;;114310:38:0;;;;;;:21;:38;;;;;;;114303:45;;-1:-1:-1;;114303:45:0;;;114364:53;-1:-1:-1;;;18422:22:1;;18469:1;18460:11;114364:53:0;18220:257:1;116015:426:0;116093:27;:25;:27::i;:::-;-1:-1:-1;;;;;116201:37:0;;;;;;:20;:37;;;;;;;;116196:113;;116262:35;;-1:-1:-1;;;116262:35:0;;;;;;;;;;;116196:113;-1:-1:-1;;;;;116328:37:0;;;;;;:20;:37;;;;;;;116321:44;;-1:-1:-1;;116321:44:0;;;116381:52;;;;:::i;128315:270::-;-1:-1:-1;;;;;128400:26:0;;128396:65;;128315:270;:::o;128396:65::-;128493:15;128477:12;;:31;128473:105;;128532:34;;-1:-1:-1;;;;;;128532:34:0;;;;;;;;;;;128473:105;128315:270;:::o;127902:175::-;127992:10;127969:34;;;;:22;:34;;;;;;;;127964:106;;128027:31;;-1:-1:-1;;;128027:31:0;;;;;;;;;;;70559:392;70618:9;70782:15;70774:5;:23;70770:95;;;70821:32;;-1:-1:-1;;;70821:32:0;;;;;;;;;;;70770:95;70901:10;70889:11;:23;;;;;;;;;;:36;:54;;70928:15;;-1:-1:-1;;;70889:36:0;;;;:54;:::i;127659:165::-;127739:10;127721:29;;;;:17;:29;;;;;;;;127716:101;;127774:31;;-1:-1:-1;;;127774:31:0;;;;;;;;;;;47343:957;47509:2;47503:4;47496:16;47567:6;47561:4;47554:20;-1:-1:-1;;;47627:4:0;47620:48;48027:4;48021;48015;48009;48006:1;47999:5;47992;47987:45;47920:16;47913:24;47909:1;47902:4;47896:11;47893:18;47890:48;47804:247;47776:408;;48099:10;48093:4;48086:24;48164:4;48158;48151:18;47776:408;48211:1;48205:4;48198:15;47343:957;;;:::o;56274:336::-;56386:4;56508:23;56523:7;56508:14;:23::i;:::-;:94;;;;;56548:54;56581:7;56590:11;56548:32;:54::i;127403:178::-;127491:16;;-1:-1:-1;;;;;127491:16:0;127477:10;:30;127473:101;;127531:31;;-1:-1:-1;;;127531:31:0;;;;;;;;;;;55566:482;55630:4;55841:117;55892:7;-1:-1:-1;;;55841:32:0;:117::i;:::-;:199;;;;-1:-1:-1;55976:64:0;56009:7;-1:-1:-1;;;;;;55976:32:0;:64::i;:::-;55975:65;55821:219;55566:482;-1:-1:-1;;55566:482:0:o;57455:826::-;57653:93;;-1:-1:-1;;;;;;19179:33:1;;57653:93:0;;;19161:52:1;57582:4:0;;;;19134:18:1;;57653:93:0;;;-1:-1:-1;;57653:93:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;57653:93:0;-1:-1:-1;;;57653:93:0;;;58030:20;;57653:93;;-1:-1:-1;;;;;;;57653:93:0;;-1:-1:-1;;57961:7:0;57937:5;57908:203;57897:214;;58139:16;58125:30;;58190:4;58184:11;58169:26;;58225:7;:29;;;;;58250:4;58236:10;:18;;58225:29;:48;;;;;58272:1;58258:11;:15;58225:48;58218:55;57455:826;-1:-1:-1;;;;;;;57455:826:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:186::-;251:6;304:2;292:9;283:7;279:23;275:32;272:52;;;320:1;317;310:12;272:52;343:29;362:9;343:29;:::i;383:286::-;441:6;494:2;482:9;473:7;469:23;465:32;462:52;;;510:1;507;500:12;462:52;536:23;;-1:-1:-1;;;;;;588:32:1;;578:43;;568:71;;635:1;632;625:12;866:226;925:6;978:2;966:9;957:7;953:23;949:32;946:52;;;994:1;991;984:12;946:52;-1:-1:-1;1039:23:1;;866:226;-1:-1:-1;866:226:1:o;2056:160::-;2121:20;;2177:13;;2170:21;2160:32;;2150:60;;2206:1;2203;2196:12;2221:180;2277:6;2330:2;2318:9;2309:7;2305:23;2301:32;2298:52;;;2346:1;2343;2336:12;2298:52;2369:26;2385:9;2369:26;:::i;2796:346::-;2864:6;2872;2925:2;2913:9;2904:7;2900:23;2896:32;2893:52;;;2941:1;2938;2931:12;2893:52;-1:-1:-1;;2986:23:1;;;3106:2;3091:18;;;3078:32;;-1:-1:-1;2796:346:1:o;3147:637::-;3337:2;3349:21;;;3419:13;;3322:18;;;3441:22;;;3289:4;;3520:15;;;3494:2;3479:18;;;3289:4;3563:195;3577:6;3574:1;3571:13;3563:195;;;3642:13;;-1:-1:-1;;;;;3638:39:1;3626:52;;3707:2;3733:15;;;;3698:12;;;;3674:1;3592:9;3563:195;;;-1:-1:-1;3775:3:1;;3147:637;-1:-1:-1;;;;;3147:637:1:o;3789:159::-;3856:20;;3916:6;3905:18;;3895:29;;3885:57;;3938:1;3935;3928:12;3953:184;4011:6;4064:2;4052:9;4043:7;4039:23;4035:32;4032:52;;;4080:1;4077;4070:12;4032:52;4103:28;4121:9;4103:28;:::i;4142:611::-;4332:2;4344:21;;;4414:13;;4317:18;;;4436:22;;;4284:4;;4515:15;;;4489:2;4474:18;;;4284:4;4558:169;4572:6;4569:1;4566:13;4558:169;;;4633:13;;4621:26;;4676:2;4702:15;;;;4667:12;;;;4594:1;4587:9;4558:169;;4758:374;4835:6;4843;4851;4904:2;4892:9;4883:7;4879:23;4875:32;4872:52;;;4920:1;4917;4910:12;4872:52;4965:23;;;-1:-1:-1;5031:38:1;5065:2;5050:18;;5031:38;:::i;:::-;5021:48;;5088:38;5122:2;5111:9;5107:18;5088:38;:::i;:::-;5078:48;;4758:374;;;;;:::o;5330:260::-;5398:6;5406;5459:2;5447:9;5438:7;5434:23;5430:32;5427:52;;;5475:1;5472;5465:12;5427:52;5498:29;5517:9;5498:29;:::i;:::-;5488:39;;5546:38;5580:2;5569:9;5565:18;5546:38;:::i;:::-;5536:48;;5330:260;;;;;:::o;5595:163::-;5662:20;;5722:10;5711:22;;5701:33;;5691:61;;5748:1;5745;5738:12;5763:184;5821:6;5874:2;5862:9;5853:7;5849:23;5845:32;5842:52;;;5890:1;5887;5880:12;5842:52;5913:28;5931:9;5913:28;:::i;6149:1252::-;6244:6;6252;6296:9;6287:7;6283:23;6326:3;6322:2;6318:12;6315:32;;;6343:1;6340;6333:12;6315:32;6388:23;;;-1:-1:-1;6469:6:1;-1:-1:-1;;6451:16:1;;6447:29;6444:49;;;6489:1;6486;6479:12;6444:49;;6522:2;6516:9;6564:6;6556;6552:19;6637:6;6625:10;6622:22;6601:18;6589:10;6586:34;6583:62;6580:185;;;6687:10;6682:3;6678:20;6675:1;6668:31;6722:4;6719:1;6712:15;6750:4;6747:1;6740:15;6580:185;6781:2;6774:22;6820:35;6851:2;6836:18;;6820:35;:::i;:::-;6812:6;6805:51;6889:37;6922:2;6911:9;6907:18;6889:37;:::i;:::-;6884:2;6876:6;6872:15;6865:62;6960:37;6993:2;6982:9;6978:18;6960:37;:::i;:::-;6955:2;6947:6;6943:15;6936:62;7031:39;7065:3;7054:9;7050:19;7031:39;:::i;:::-;7026:2;7018:6;7014:15;7007:64;7105:39;7139:3;7128:9;7124:19;7105:39;:::i;:::-;7099:3;7091:6;7087:16;7080:65;7179:39;7213:3;7202:9;7198:19;7179:39;:::i;:::-;7173:3;7165:6;7161:16;7154:65;7253:39;7287:3;7276:9;7272:19;7253:39;:::i;:::-;7247:3;7239:6;7235:16;7228:65;7327:42;7361:6;7350:9;7346:22;7327:42;:::i;:::-;7321:3;7313:6;7309:16;7302:68;7389:6;7379:16;;;6149:1252;;;;;:::o;8189:284::-;-1:-1:-1;;;;;8375:32:1;;;;8357:51;;8451:14;8444:22;8439:2;8424:18;;8417:50;8345:2;8330:18;;8189:284::o;9010:127::-;9071:10;9066:3;9062:20;9059:1;9052:31;9102:4;9099:1;9092:15;9126:4;9123:1;9116:15;9142:168;9215:9;;;9246;;9263:15;;;9257:22;;9243:37;9233:71;;9284:18;;:::i;9591:125::-;9656:9;;;9677:10;;;9674:36;;;9690:18;;:::i;10255:184::-;10325:6;10378:2;10366:9;10357:7;10353:23;10349:32;10346:52;;;10394:1;10391;10384:12;10346:52;-1:-1:-1;10417:16:1;;10255:184;-1:-1:-1;10255:184:1:o;10444:217::-;10484:1;10510;10500:132;;10554:10;10549:3;10545:20;10542:1;10535:31;10589:4;10586:1;10579:15;10617:4;10614:1;10607:15;10500:132;-1:-1:-1;10646:9:1;;10444:217::o;11204:233::-;11243:3;-1:-1:-1;;;;;11280:5:1;11276:44;-1:-1:-1;;;;;11335:7:1;11332:45;11329:71;;11380:18;;:::i;:::-;11429:1;11416:15;;11204:233;-1:-1:-1;;11204:233:1:o;12464:136::-;12503:3;12531:5;12521:39;;12540:18;;:::i;:::-;-1:-1:-1;;;12576:18:1;;12464:136::o;12605:127::-;12666:10;12661:3;12657:20;12654:1;12647:31;12697:4;12694:1;12687:15;12721:4;12718:1;12711:15;12737:127;12798:10;12793:3;12789:20;12786:1;12779:31;12829:4;12826:1;12819:15;12853:4;12850:1;12843:15;15417:256;-1:-1:-1;;;15619:21:1;;15665:1;15656:11;;15417:256::o;15941:135::-;15980:3;16001:17;;;15998:43;;16021:18;;:::i;:::-;-1:-1:-1;16068:1:1;16057:13;;15941:135::o;16081:1059::-;16255:4;16297:3;16286:9;16282:19;16274:27;;16328:6;16317:9;16310:25;16391:6;16385:13;16378:21;16371:29;16366:2;16355:9;16351:18;16344:57;16465:6;16459:2;16451:6;16447:15;16441:22;16437:35;16432:2;16421:9;16417:18;16410:63;16537:10;16531:2;16523:6;16519:15;16513:22;16509:39;16504:2;16493:9;16489:18;16482:67;16596:2;16588:6;16584:15;16578:22;16609:53;16657:3;16646:9;16642:19;16628:12;-1:-1:-1;;;;;1163:31:1;1151:44;;1097:104;16609:53;-1:-1:-1;16711:3:1;16699:16;;16693:23;-1:-1:-1;;;;;1163:31:1;;16775:3;16760:19;;1151:44;-1:-1:-1;16829:3:1;16817:16;;16811:23;-1:-1:-1;;;;;1163:31:1;;16893:3;16878:19;;1151:44;-1:-1:-1;16947:3:1;16935:16;;16929:23;-1:-1:-1;;;;;1163:31:1;;17011:3;16996:19;;1151:44;-1:-1:-1;17065:3:1;17053:16;;17047:23;-1:-1:-1;;;;;1163:31:1;;17129:3;17114:19;;1151:44;17079:55;16081:1059;;;;;:::o

Swarm Source

ipfs://439cdd9789fa974154b8e848e9b3eede275480b9c5035b54f2a6fdd16e7ac895

Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.