ETH Price: $2,902.32 (+0.74%)

Contract

0xC5CCc20f6A4CD65fda979A2E292DBCF2C450C067

Overview

ETH Balance

Linea Mainnet LogoLinea Mainnet LogoLinea Mainnet Logo0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Deposit265440502025-12-10 20:56:4746 days ago1765400207IN
0xC5CCc20f...2C450C067
0 ETH0.000015140.03336863
Deposit257130192025-11-16 14:02:0371 days ago1763301723IN
0xC5CCc20f...2C450C067
0 ETH0.00002480.03600851
Deposit254407032025-11-09 5:17:5778 days ago1762665477IN
0xC5CCc20f...2C450C067
0 ETH0.000024020.03646188
Deposit245604212025-10-15 13:19:52103 days ago1760534392IN
0xC5CCc20f...2C450C067
0 ETH0.00002750.04008789
Deposit245155902025-10-14 8:06:18104 days ago1760429178IN
0xC5CCc20f...2C450C067
0 ETH0.0000250.03644355
Deposit244457302025-10-12 11:21:57106 days ago1760268117IN
0xC5CCc20f...2C450C067
0 ETH0.000029370.0447613
Deposit242226262025-10-06 17:48:12111 days ago1759772892IN
0xC5CCc20f...2C450C067
0 ETH0.000017120.04038909
Deposit242107022025-10-06 10:53:58112 days ago1759748038IN
0xC5CCc20f...2C450C067
0 ETH0.00002750.0400879
Deposit238686492025-09-27 13:59:50121 days ago1758981590IN
0xC5CCc20f...2C450C067
0 ETH0.000016640.03667025
Deposit235786252025-09-20 16:07:14128 days ago1758384434IN
0xC5CCc20f...2C450C067
0 ETH0.000026250.03826572
Deposit234585342025-09-17 20:14:22130 days ago1758140062IN
0xC5CCc20f...2C450C067
0 ETH0.000027440.04
Deposit234210202025-09-16 22:18:44131 days ago1758061124IN
0xC5CCc20f...2C450C067
0 ETH0.00002750.04008789
Deposit233733232025-09-15 19:44:51132 days ago1757965491IN
0xC5CCc20f...2C450C067
0 ETH0.000025940.03827137
Deposit233721432025-09-15 19:05:29132 days ago1757963129IN
0xC5CCc20f...2C450C067
0 ETH0.000019020.03659419
Deposit229307212025-09-05 1:10:57143 days ago1757034657IN
0xC5CCc20f...2C450C067
0 ETH0.000016810.04040765
Deposit229259132025-09-04 22:18:50143 days ago1757024330IN
0xC5CCc20f...2C450C067
0 ETH0.000030390.0442908
Deposit223271042025-08-21 13:43:26158 days ago1755783806IN
0xC5CCc20f...2C450C067
0 ETH0.000018390.04033642
Deposit220430282025-08-14 19:54:52164 days ago1755201292IN
0xC5CCc20f...2C450C067
0 ETH0.000028830.04375743
Deposit217364542025-08-07 15:14:16172 days ago1754579656IN
0xC5CCc20f...2C450C067
0 ETH0.000043890.08952423
Deposit217363042025-08-07 15:09:16172 days ago1754579356IN
0xC5CCc20f...2C450C067
0 ETH0.000061430.08952423
Deposit216816412025-08-06 7:49:10173 days ago1754466550IN
0xC5CCc20f...2C450C067
0 ETH0.000030750.04685738
Deposit216377062025-08-05 0:31:29174 days ago1754353889IN
0xC5CCc20f...2C450C067
0 ETH0.000034710.04078707
Deposit213213052025-07-26 17:05:56184 days ago1753549556IN
0xC5CCc20f...2C450C067
0 ETH0.000026740.03897027
Deposit210245902025-07-19 5:39:50191 days ago1752903590IN
0xC5CCc20f...2C450C067
0 ETH0.000020250.04131462
Deposit210244012025-07-19 5:31:51191 days ago1752903111IN
0xC5CCc20f...2C450C067
0 ETH0.000028010.04082602
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
265440502025-12-10 20:56:4746 days ago1765400207
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
257130192025-11-16 14:02:0371 days ago1763301723
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
254407032025-11-09 5:17:5778 days ago1762665477
0xC5CCc20f...2C450C067
0 ETH
245604212025-10-15 13:19:52103 days ago1760534392
0xC5CCc20f...2C450C067
0 ETH
View All Internal Transactions
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Depositor

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at lineascan.build/ on 2025-03-11
*/

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity <0.9.0 =0.8.19 >=0.7.0 ^0.8.0 ^0.8.19 ^0.8.4 ^0.8.7;

// node_modules/@openzeppelin/contracts/governance/utils/IVotes.sol

// OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol)

/**
 * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
 *
 * _Available since v4.5._
 */
interface IVotes {
    /**
     * @dev Emitted when an account changes their delegate.
     */
    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

    /**
     * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.
     */
    event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);

    /**
     * @dev Returns the current amount of votes that `account` has.
     */
    function getVotes(address account) external view returns (uint256);

    /**
     * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     */
    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);

    /**
     * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is
     * configured to use block numbers, this will return the value at the end of the corresponding block.
     *
     * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
     * Votes that have not been delegated are still part of total supply, even though they would not participate in a
     * vote.
     */
    function getPastTotalSupply(uint256 timepoint) external view returns (uint256);

    /**
     * @dev Returns the delegate that `account` has chosen.
     */
    function delegates(address account) external view returns (address);

    /**
     * @dev Delegates votes from the sender to `delegatee`.
     */
    function delegate(address delegatee) external;

    /**
     * @dev Delegates votes from signer to `delegatee`.
     */
    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
}

// node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol

// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20_0 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

// node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol

// OpenZeppelin Contracts v4.4.1 (utils/introspection/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);
}

// node_modules/@safe/contracts/libraries/Enum.sol

/**
 * @title Enum - Collection of enums used in Safe Smart Account contracts.
 * @author @safe-global/safe-protocol
 */
library Enum {
    enum Operation {
        Call,
        DelegateCall
    }
}

// node_modules/solady/src/utils/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)
/// @author Permit2 operations from (https://github.com/Uniswap/permit2/blob/main/src/libraries/Permit2Lib.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();

    /// @dev The Permit2 operation has failed.
    error Permit2Failed();

    /// @dev The Permit2 amount must be less than `2**160 - 1`.
    error Permit2AmountOverflow();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         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;

    /// @dev The unique EIP-712 domain domain separator for the DAI token contract.
    bytes32 internal constant DAI_DOMAIN_SEPARATOR =
        0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7;

    /// @dev The address for the WETH9 contract on Ethereum mainnet.
    address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    /// @dev The canonical Permit2 address.
    /// [Github](https://github.com/Uniswap/permit2)
    /// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3)
    address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       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 `amount` of ERC20 `token` from `from` to `to`.
    ///
    /// The `from` account must have at least `amount` approved for the current contract to manage.
    function trySafeTransferFrom(address token, address from, address to, uint256 amount)
        internal
        returns (bool success)
    {
        /// @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)`.
            success :=
                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(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( // The arguments of `mul` are evaluated from right to left.
                    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)
                    )
                )
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// If the initial attempt fails, try to use Permit2 to transfer the token.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for the current contract to manage.
    function safeTransferFrom2(address token, address from, address to, uint256 amount) internal {
        if (!trySafeTransferFrom(token, from, to, amount)) {
            permit2TransferFrom(token, from, to, amount);
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to` via Permit2.
    /// Reverts upon failure.
    function permit2TransferFrom(address token, address from, address to, uint256 amount)
        internal
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(add(m, 0x74), shr(96, shl(96, token)))
            mstore(add(m, 0x54), amount)
            mstore(add(m, 0x34), to)
            mstore(add(m, 0x20), shl(96, from))
            // `transferFrom(address,address,uint160,address)`.
            mstore(m, 0x36c78516000000000000000000000000)
            let p := PERMIT2
            let exists := eq(chainid(), 1)
            if iszero(exists) { exists := iszero(iszero(extcodesize(p))) }
            if iszero(and(call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00), exists)) {
                mstore(0x00, 0x7939f4248757f0fd) // `TransferFromFailed()` or `Permit2AmountOverflow()`.
                revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04)
            }
        }
    }

    /// @dev Permit a user to spend a given amount of
    /// another user's tokens via native EIP-2612 permit if possible, falling
    /// back to Permit2 if native permit fails or is not implemented on the token.
    function permit2(
        address token,
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        bool success;
        /// @solidity memory-safe-assembly
        assembly {
            for {} shl(96, xor(token, WETH9)) {} {
                mstore(0x00, 0x3644e515) // `DOMAIN_SEPARATOR()`.
                if iszero(
                    and( // The arguments of `and` are evaluated from right to left.
                        lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)), // Returns 1 non-zero word.
                        // Gas stipend to limit gas burn for tokens that don't refund gas when
                        // an non-existing function is called. 5K should be enough for a SLOAD.
                        staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20)
                    )
                ) { break }
                // After here, we can be sure that token is a contract.
                let m := mload(0x40)
                mstore(add(m, 0x34), spender)
                mstore(add(m, 0x20), shl(96, owner))
                mstore(add(m, 0x74), deadline)
                if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) {
                    mstore(0x14, owner)
                    mstore(0x00, 0x7ecebe00000000000000000000000000) // `nonces(address)`.
                    mstore(add(m, 0x94), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20))
                    mstore(m, 0x8fcbaf0c000000000000000000000000) // `IDAIPermit.permit`.
                    // `nonces` is already at `add(m, 0x54)`.
                    // `1` is already stored at `add(m, 0x94)`.
                    mstore(add(m, 0xb4), and(0xff, v))
                    mstore(add(m, 0xd4), r)
                    mstore(add(m, 0xf4), s)
                    success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00)
                    break
                }
                mstore(m, 0xd505accf000000000000000000000000) // `IERC20Permit.permit`.
                mstore(add(m, 0x54), amount)
                mstore(add(m, 0x94), and(0xff, v))
                mstore(add(m, 0xb4), r)
                mstore(add(m, 0xd4), s)
                success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00)
                break
            }
        }
        if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s);
    }

    /// @dev Simple permit on the Permit2 contract.
    function simplePermit2(
        address token,
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, 0x927da105) // `allowance(address,address,address)`.
            {
                let addressMask := shr(96, not(0))
                mstore(add(m, 0x20), and(addressMask, owner))
                mstore(add(m, 0x40), and(addressMask, token))
                mstore(add(m, 0x60), and(addressMask, spender))
                mstore(add(m, 0xc0), and(addressMask, spender))
            }
            let p := mul(PERMIT2, iszero(shr(160, amount)))
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x5f), // Returns 3 words: `amount`, `expiration`, `nonce`.
                    staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60)
                )
            ) {
                mstore(0x00, 0x6b836e6b8757f0fd) // `Permit2Failed()` or `Permit2AmountOverflow()`.
                revert(add(0x18, shl(2, iszero(p))), 0x04)
            }
            mstore(m, 0x2b67b570) // `Permit2.permit` (PermitSingle variant).
            // `owner` is already `add(m, 0x20)`.
            // `token` is already at `add(m, 0x40)`.
            mstore(add(m, 0x60), amount)
            mstore(add(m, 0x80), 0xffffffffffff) // `expiration = type(uint48).max`.
            // `nonce` is already at `add(m, 0xa0)`.
            // `spender` is already at `add(m, 0xc0)`.
            mstore(add(m, 0xe0), deadline)
            mstore(add(m, 0x100), 0x100) // `signature` offset.
            mstore(add(m, 0x120), 0x41) // `signature` length.
            mstore(add(m, 0x140), r)
            mstore(add(m, 0x160), s)
            mstore(add(m, 0x180), shl(248, v))
            if iszero(call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00)) {
                mstore(0x00, 0x6b836e6b) // `Permit2Failed()`.
                revert(0x1c, 0x04)
            }
        }
    }
}

// src/common/interfaces/IERC20.sol

// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

interface IERC20_1 {
    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);

    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    function transfer(address to, uint256 amount) external returns (bool);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);

    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);
}

// src/common/interfaces/ILiquidityGauge.sol

interface ILiquidityGauge {
    struct Reward {
        address token;
        address distributor;
        // solhint-disable-next-line
        uint256 period_finish;
        uint256 rate;
        // solhint-disable-next-line
        uint256 last_update;
        uint256 integral;
    }

    // solhint-disable-next-line
    function deposit_reward_token(address _rewardToken, uint256 _amount) external;

    // solhint-disable-next-line
    function claim_rewards_for(address _user, address _recipient) external;

    // solhint-disable-next-line
    function working_balances(address _address) external view returns (uint256);

    // solhint-disable-next-line
    function deposit(uint256 _value, address _addr) external;

    // solhint-disable-next-line
    function reward_tokens(uint256 _i) external view returns (address);

    // solhint-disable-next-line
    function reward_data(address _tokenReward) external view returns (Reward memory);

    function balanceOf(address) external returns (uint256);

    // solhint-disable-next-line
    function claimable_reward(address _user, address _reward_token) external view returns (uint256);

    // solhint-disable-next-line
    function claimable_tokens(address _user) external returns (uint256);

    // solhint-disable-next-line
    function user_checkpoint(address _user) external returns (bool);

    // solhint-disable-next-line
    function commit_transfer_ownership(address) external;

    // solhint-disable-next-line
    function claim_rewards() external;

    // solhint-disable-next-line
    function claim_rewards(address) external;

    // solhint-disable-next-line
    function claim_rewards(address, address) external;

    // solhint-disable-next-line
    function add_reward(address, address) external;

    // solhint-disable-next-line
    function set_claimer(address) external;

    function admin() external view returns (address);

    function future_admin() external view returns (address);

    // solhint-disable-next-line
    function set_reward_distributor(address _rewardToken, address _newDistrib) external;

    function initialize(
        // solhint-disable-next-line
        address staking_token,
        address admin,
        address sdt,
        // solhint-disable-next-line
        address voting_escrow,
        // solhint-disable-next-line
        address veBoost_proxy,
        address distributor
    ) external;

    function totalSupply() external returns (uint256);

    function withdraw(uint256 _value, bool _claimReward) external;

    function withdraw(uint256 _valut, address _user, bool _claimReward) external;

    // solhint-disable-next-line
    function accept_transfer_ownership() external;

    // solhint-disable-next-line
    function claimed_reward(address _addr, address _token) external view returns (uint256);

    // solhint-disable-next-line
    function set_rewards_receiver(address _receiver) external;
}

// src/common/interfaces/ILocker.sol

interface ILocker_0 {
    /// @notice Throws if caller is not the governance.
    error GOVERNANCE();

    /// @notice Throws if caller is not the governance or depositor.
    error GOVERNANCE_OR_DEPOSITOR();

    /// @notice Throws if caller is not the governance or depositor.
    error GOVERNANCE_OR_ACCUMULATOR();

    function createLock(uint256, uint256) external;

    function claimAllRewards(address[] calldata _tokens, address _recipient) external;

    function increaseAmount(uint256) external;

    function increaseAmount(uint128) external;

    function increaseUnlockTime(uint256) external;

    function release() external;

    function claimRewards(address, address) external;

    function claimRewards(address, address, address) external;

    function claimFXSRewards(address) external;

    function claimFPISRewards(address) external;

    function execute(address, uint256, bytes calldata) external returns (bool, bytes memory);

    function setGovernance(address) external;

    function voteGaugeWeight(address, uint256) external;

    function setAngleDepositor(address) external;

    function setPendleDepositor(address) external;

    function pendleDepositor() external view returns (address);

    function setDepositor(address) external;

    function setFxsDepositor(address) external;

    function setYFIDepositor(address) external;

    function setYieldDistributor(address) external;

    function setGaugeController(address) external;

    function setAccumulator(address _accumulator) external;

    function governance() external view returns (address);

    function increaseLock(uint256 _value, uint256 _duration) external;

    function release(address _recipient) external;

    function transferGovernance(address _governance) external;

    function acceptGovernance() external;

    function setStrategy(address _strategy) external;

    function claimRewards(address _recipient, address[] calldata _pools) external;
}

// src/common/interfaces/ISdToken.sol

interface ISdToken {
    function balanceOf(address account) external view returns (uint256);

    function burn(uint256 amount) external;

    function burn(address _to, uint256 _amount) external;

    function mint(address _to, uint256 _amount) external;

    function operator() external view returns (address);

    function burner() external view returns (address);

    function setOperator(address _operator) external;

    function setBurnerOperator(address _burner) external;
}

// src/common/interfaces/ITokenMinter.sol

interface ITokenMinter {
    function mint(address, uint256) external;
    function burn(address, uint256) external;
}

// node_modules/@openzeppelin/contracts/interfaces/IERC20.sol

// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

// node_modules/@openzeppelin/contracts/interfaces/IERC721Receiver.sol

// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Receiver.sol)

// node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol

// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

// src/common/interfaces/zerolend/stakedao/ILocker.sol

interface ISafe {
    /**
     * @notice Enables the module `module` for the Safe.
     * @dev This can only be done via a Safe transaction.
     * @param module Module to be whitelisted.
     */
    function enableModule(address module) external;

    /**
     * @notice Execute `operation` (0: Call, 1: DelegateCall) to `to` with `value` (Native Token)
     * @dev Function is virtual to allow overriding for L2 singleton to emit an event for indexing.
     * @param to Destination address of module transaction.
     * @param value Ether value of module transaction.
     * @param data Data payload of module transaction.
     * @param operation Operation type of module transaction.
     * @return success Boolean flag indicating if the call succeeded.
     */
    function execTransactionFromModule(address to, uint256 value, bytes memory data, Enum.Operation operation)
        external
        returns (bool success);

    /**
     * @notice Execute `operation` (0: Call, 1: DelegateCall) to `to` with `value` (Native Token) and return data
     * @param to Destination address of module transaction.
     * @param value Ether value of module transaction.
     * @param data Data payload of module transaction.
     * @param operation Operation type of module transaction.
     * @return success Boolean flag indicating if the call succeeded.
     * @return returnData Data returned by the call.
     */
    function execTransactionFromModuleReturnData(address to, uint256 value, bytes memory data, Enum.Operation operation)
        external
        returns (bool success, bytes memory returnData);

    /**
     * @notice Executes a `operation` {0: Call, 1: DelegateCall}} transaction to `to` with `value` (Native Currency)
     *          and pays `gasPrice` * `gasLimit` in `gasToken` token to `refundReceiver`.
     * @dev The fees are always transferred, even if the user transaction fails.
     *      This method doesn't perform any sanity check of the transaction, such as:
     *      - if the contract at `to` address has code or not
     *      - if the `gasToken` is a contract or not
     *      It is the responsibility of the caller to perform such checks.
     * @param to Destination address of Safe transaction.
     * @param value Ether value of Safe transaction.
     * @param data Data payload of Safe transaction.
     * @param operation Operation type of Safe transaction.
     * @param safeTxGas Gas that should be used for the Safe transaction.
     * @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)
     * @param gasPrice Gas price that should be used for the payment calculation.
     * @param gasToken Token address (or 0 if ETH) that is used for the payment.
     * @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).
     * @param signatures Signature data that should be verified.
     *                   Can be packed ECDSA signature ({bytes32 r}{bytes32 s}{uint8 v}), contract signature (EIP-1271) or approved hash.
     * @return success Boolean indicating transaction's success.
     */
    function execTransaction(
        address to,
        uint256 value,
        bytes calldata data,
        Enum.Operation operation,
        uint256 safeTxGas,
        uint256 baseGas,
        uint256 gasPrice,
        address gasToken,
        address payable refundReceiver,
        bytes memory signatures
    ) external returns (bool success);

    /**
     * @notice Returns a list of Safe owners.
     * @return Array of Safe owners.
     */
    function getOwners() external view returns (address[] memory);

    /**
     * @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.
     * @dev This can only be done via a Safe transaction.
     * @param owner New owner address.
     * @param _threshold New threshold.
     */
    function addOwnerWithThreshold(address owner, uint256 _threshold) external;

    /**
     * @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.
     * @dev This can only be done via a Safe transaction.
     * @param prevOwner Owner that pointed to the owner to be removed in the linked list
     * @param owner Owner address to be removed.
     * @param _threshold New threshold.
     */
    function removeOwner(address prevOwner, address owner, uint256 _threshold) external;
}

interface ILocker_1 is ISafe {}

// src/common/interfaces/zerolend/zerolend/IZeroVp.sol

// ███████╗███████╗██████╗  ██████╗
// ╚══███╔╝██╔════╝██╔══██╗██╔═══██╗
//   ███╔╝ █████╗  ██████╔╝██║   ██║
//  ███╔╝  ██╔══╝  ██╔══██╗██║   ██║
// ███████╗███████╗██║  ██║╚██████╔╝
// ╚══════╝╚══════╝╚═╝  ╚═╝ ╚═════╝

// Website: https://zerolend.xyz
// Discord: https://discord.gg/zerolend
// Twitter: https://twitter.com/zerolendxyz

interface IZeroVp is IVotes {
    // An omni-chain staking contract that allows users to stake their veNFT
    // and get some voting power. Once staked the voting power is available cross-chain.

    /**
     * @notice Structure to store locked balance information
     * @param amount Amount of tokens locked
     * @param end End time of the lock period (timestamp)
     * @param start Start time of the lock period (timestamp)
     * @param power Additional parameter, potentially for governance or staking power
     */
    struct LockedBalance {
        uint256 amount;
        uint256 end;
        uint256 start;
        uint256 power;
    }

    error ERC721NonexistentToken(uint256);

    function rewards(address) external view returns (uint256);

    function increaseLockAmount(uint256 tokenId, uint256 newLockAmount) external;

    function increaseLockDuration(uint256 tokenId, uint256 newLockDuration) external;

    function rewardRate() external returns (uint256);

    function getReward() external;

    function unstakeToken(uint256 tokenId) external;

    function getLockedNftDetails(address _user) external view returns (uint256[] memory, LockedBalance[] memory);

    function lockedTokenIdNfts(address _user, uint256 _index) external view returns (uint256);

    function earned(address account) external view returns (uint256);

    function totalSupply() external view returns (uint256);
}

// node_modules/@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol

// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// node_modules/@openzeppelin/contracts/interfaces/IERC721Enumerable.sol

// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol)

// src/common/depositor/BaseDepositor.sol

/// @title BaseDepositor
/// @notice Contract that accepts tokens and locks them in the Locker, minting sdToken in return
/// @dev Adapted for veCRV like Locker.
/// @author StakeDAO
/// @custom:contact [email protected]
abstract contract BaseDepositor {
    /// @notice Denominator for fixed point math.
    uint256 public constant DENOMINATOR = 1e18;

    /// @notice Maximum lock duration.
    uint256 public immutable MAX_LOCK_DURATION;

    /// @notice Address of the token to be locked.
    address public immutable token;

    /// @notice Address of the locker contract.
    address public immutable locker;

    /// @notice Address of the sdToken minter contract.
    address public minter;

    /// @notice Fee percent to users who spend gas to increase lock.
    uint256 public lockIncentivePercent = 0.001e18; // 0.1%

    /// @notice Incentive accrued in token to users who spend gas to increase lock.
    uint256 public incentiveToken;

    /// @notice Gauge to deposit sdToken into.
    address public gauge;

    /// @notice Address of the governance.
    address public governance;

    /// @notice Address of the future governance contract.
    address public futureGovernance;

    ////////////////////////////////////////////////////////////////
    /// --- EVENTS & ERRORS
    ///////////////////////////////////////////////////////////////

    /// @notice Throws if caller is not the governance.
    error GOVERNANCE();

    /// @notice Throws if the deposit amount is zero.
    error AMOUNT_ZERO();

    /// @notice Throws if the address is zero.
    error ADDRESS_ZERO();

    /// @notice Throws if the lock incentive is too high.
    error LOCK_INCENTIVE_TOO_HIGH();

    /// @notice Event emitted when the gauge is updated
    event GaugeUpdated(address newGauge);

    /// @notice Event emitted when the lock incentive is updated
    event LockIncentiveUpdated(uint256 newLockIncentive);

    /// @notice Event emitted when the governance update is proposed
    event GovernanceUpdateProposed(address newFutureGovernance);

    /// @notice Event emitted when the governance update is accepted
    event GovernanceUpdateAccepted(address newGovernance);

    ////////////////////////////////////////////////////////////////
    /// --- MODIFIERS
    ///////////////////////////////////////////////////////////////

    modifier onlyGovernance() {
        if (msg.sender != governance) revert GOVERNANCE();
        _;
    }

    constructor(address _token, address _locker, address _minter, address _gauge, uint256 _maxLockDuration) {
        if (_token == address(0) || _locker == address(0) || _minter == address(0) || _gauge == address(0)) {
            revert ADDRESS_ZERO();
        }

        governance = msg.sender;

        token = _token;
        gauge = _gauge;
        minter = _minter;
        locker = _locker;

        MAX_LOCK_DURATION = _maxLockDuration;

        /// Approve sdToken to gauge.
        if (gauge != address(0)) {
            SafeTransferLib.safeApprove(minter, gauge, type(uint256).max);
        }
    }

    ////////////////////////////////////////////////////////////////
    /// --- DEPOSIT & LOCK
    ///////////////////////////////////////////////////////////////

    /// @notice Initiate a lock in the Locker contract.
    /// @param _amount Amount of tokens to lock.
    function createLock(uint256 _amount) external virtual {
        /// Transfer tokens to this contract
        SafeTransferLib.safeTransferFrom(token, msg.sender, address(locker), _amount);

        /// Can be called only once.
        ILocker_0(locker).createLock(_amount, block.timestamp + MAX_LOCK_DURATION);

        /// Mint sdToken to msg.sender.
        ITokenMinter(minter).mint(msg.sender, _amount);
    }

    /// @notice Deposit tokens, and receive sdToken or sdTokenGauge in return.
    /// @param _amount Amount of tokens to deposit.
    /// @param _lock Whether to lock the tokens in the locker contract.
    /// @param _stake Whether to stake the sdToken in the gauge.
    /// @param _user Address of the user to receive the sdToken.
    /// @dev If the lock is true, the tokens are directly sent to the locker and increase the lock amount as veToken.
    /// If the lock is false, the tokens are sent to this contract until someone locks them. A small percent of the deposit
    /// is used to incentivize users to lock the tokens.
    /// If the stake is true, the sdToken is staked in the gauge that distributes rewards. If the stake is false, the sdToken
    /// is sent to the user.
    function deposit(uint256 _amount, bool _lock, bool _stake, address _user) public {
        if (_amount == 0) revert AMOUNT_ZERO();
        if (_user == address(0)) revert ADDRESS_ZERO();

        /// If _lock is true, lock tokens in the locker contract.
        if (_lock) {
            /// Transfer tokens to the locker contract.
            SafeTransferLib.safeTransferFrom(token, msg.sender, locker, _amount);

            /// Transfer the balance
            uint256 balance = IERC20_1(token).balanceOf(address(this));

            if (balance != 0) {
                SafeTransferLib.safeTransfer(token, locker, balance);
            }

            /// Lock the amount sent + balance of the contract.
            _lockToken(balance + _amount);

            /// If an incentive is available, add it to the amount.
            if (incentiveToken != 0) {
                _amount += incentiveToken;

                incentiveToken = 0;
            }
        } else {
            /// Transfer tokens to this contract.
            SafeTransferLib.safeTransferFrom(token, msg.sender, address(this), _amount);

            /// Compute call incentive and add to incentiveToken
            uint256 callIncentive = (_amount * lockIncentivePercent) / DENOMINATOR;

            /// Subtract call incentive from _amount
            _amount -= callIncentive;

            /// Add call incentive to incentiveToken
            incentiveToken += callIncentive;
        }
        // Mint sdtoken to the user if the gauge is not set
        if (_stake && gauge != address(0)) {
            /// Mint sdToken to this contract.
            ITokenMinter(minter).mint(address(this), _amount);

            /// Deposit sdToken into gauge for _user.
            ILiquidityGauge(gauge).deposit(_amount, _user);
        } else {
            /// Mint sdToken to _user.
            ITokenMinter(minter).mint(_user, _amount);
        }
    }

    /// @notice Lock tokens held by the contract
    /// @dev The contract must have Token to lock
    function lockToken() external {
        uint256 tokenBalance = IERC20_1(token).balanceOf(address(this));

        if (tokenBalance != 0) {
            /// Transfer tokens to the locker contract and lock them.
            SafeTransferLib.safeTransfer(token, locker, tokenBalance);

            /// Lock the amount sent.
            _lockToken(tokenBalance);
        }

        /// If there is incentive available give it to the user calling lockToken.
        if (incentiveToken != 0) {
            /// Mint incentiveToken to msg.sender.
            ITokenMinter(minter).mint(msg.sender, incentiveToken);

            /// Reset incentiveToken.
            incentiveToken = 0;
        }
    }

    /// @notice Locks the tokens held by the contract
    /// @dev The contract must have tokens to lock
    function _lockToken(uint256 _amount) internal virtual {
        // If there is Token available in the contract transfer it to the locker
        if (_amount != 0) {
            /// Increase the lock.
            ILocker_0(locker).increaseLock(_amount, block.timestamp + MAX_LOCK_DURATION);
        }
    }

    ////////////////////////////////////////////////////////////////
    /// --- GOVERNANCE PARAMETERS
    ///////////////////////////////////////////////////////////////

    /// @notice Transfer the governance to a new address.
    /// @param _governance Address of the new governance.
    function transferGovernance(address _governance) external onlyGovernance {
        emit GovernanceUpdateProposed(futureGovernance = _governance);
    }

    /// @notice Accept the governance transfer.
    function acceptGovernance() external {
        if (msg.sender != futureGovernance) revert GOVERNANCE();

        emit GovernanceUpdateAccepted(governance = msg.sender);

        futureGovernance = address(0);
    }

    /// @notice Set the new operator for minting sdToken
    /// @param _minter operator minter address
    function setSdTokenMinterOperator(address _minter) external virtual onlyGovernance {
        ISdToken(minter).setOperator(_minter);
    }

    /// @notice Set the gauge to deposit sdToken
    /// @param _gauge gauge address
    function setGauge(address _gauge) external virtual onlyGovernance {
        /// Set and emit the new gauge.
        emit GaugeUpdated(gauge = _gauge);

        if (_gauge != address(0)) {
            /// Approve sdToken to gauge.
            SafeTransferLib.safeApprove(minter, gauge, type(uint256).max);
        }
    }

    /// @notice Set the percentage of the lock incentive
    /// @param _lockIncentive Percentage of the lock incentive
    function setFees(uint256 _lockIncentive) external onlyGovernance {
        if (_lockIncentive > 0.003e18) revert LOCK_INCENTIVE_TOO_HIGH();
        emit LockIncentiveUpdated(lockIncentivePercent = _lockIncentive);
    }

    function name() external view returns (string memory) {
        return string(abi.encodePacked(IERC20_1(token).symbol(), " Depositor"));
    }

    /// @notice Get the version of the contract
    /// Version follows the Semantic Versioning (https://semver.org/)
    /// Major version is increased when backward compatibility is broken in this base contract.
    /// Minor version is increased when new features are added in this base contract.
    /// Patch version is increased when child contracts are updated.
    function version() external pure returns (string memory) {
        return "4.0.0";
    }
}

// src/common/interfaces/zerolend/zerolend/IZeroLocker.sol

interface IZeroLocker is IERC721Enumerable {
    function balanceOfNFT(uint256) external view returns (uint256);

    function merge(uint256 _from, uint256 _to) external;

    function depositFor(uint256 _tokenId, uint256 _value) external;

    function createLockFor(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT)
        external
        returns (uint256);

    function createLock(uint256 _value, uint256 _lockDuration, bool _stakeNFT) external returns (uint256);

    enum DepositType {
        DEPOSIT_FOR_TYPE,
        CREATE_LOCK_TYPE,
        INCREASE_LOCK_AMOUNT,
        INCREASE_UNLOCK_TIME,
        MERGE_TYPE
    }

    struct LockedBalance {
        uint256 amount;
        uint256 end;
        uint256 start;
        uint256 power;
    }

    event Deposit(
        address indexed provider,
        uint256 tokenId,
        uint256 value,
        uint256 indexed locktime,
        DepositType deposit_type,
        uint256 ts
    );

    event Withdraw(address indexed provider, uint256 tokenId, uint256 value, uint256 ts);

    event Supply(uint256 prevSupply, uint256 supply);
}

// src/common/interfaces/zerolend/zerolend/ILockerToken.sol

/**
 *   @title Voting Escrow
 *   @author Curve Finance
 *   @notice Votes have a weight depending on time, so that users are
 *   committed to the future of (whatever they are voting for)
 *   @dev Vote weight decays linearly over time. Lock time cannot be
 *   more than `MAXTIME` (4 years).
 *
 *   # Voting escrow to have time-weighted votes
 *   # Votes have a weight depending on time, so that users are committed
 *   # to the future of (whatever they are voting for).
 *   # The weight in this implementation is linear, and lock cannot be more than maxtime:
 *   # w ^
 *   # 1 +        /
 *   #   |      /
 *   #   |    /
 *   #   |  /
 *   #   |/c
 *   # 0 +--------+------> time
 *   # maxtime (4 years?)
 */
interface ILockerToken is IZeroLocker {
    function locked(uint256 _tokenId) external view returns (LockedBalance memory);

    /// @notice Get timestamp when `_tokenId`'s lock finishes
    /// @param _tokenId User NFT
    /// @return Epoch time of the lock end
    function lockedEnd(uint256 _tokenId) external view returns (uint256);

    /// @dev Returns the voting power of the `_owner`.
    ///      Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid.
    /// @param _owner Address for whom to query the voting power of.
    function votingPowerOf(address _owner) external view returns (uint256 _power);

    function merge(uint256 _from, uint256 _to) external override;

    /// @notice Deposit `_value` tokens for `_tokenId` and add to the lock
    /// @dev Anyone (even a smart contract) can deposit for someone else, but
    ///      cannot extend their locktime and deposit for a brand new user
    /// @param _tokenId lock NFT
    /// @param _value Amount to add to user's lock
    function depositFor(uint256 _tokenId, uint256 _value) external override;

    /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration`
    /// @param _value Amount to deposit
    /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)
    /// @param _to Address to deposit
    function createLockFor(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT)
        external
        override
        returns (uint256);

    /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lockDuration`
    /// @param _value Amount to deposit
    /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)
    /// @param _stakeNFT Should we also stake the NFT as well?
    function createLock(uint256 _value, uint256 _lockDuration, bool _stakeNFT) external override returns (uint256);

    /// @notice Deposit `_value` additional tokens for `_tokenId` without modifying the unlock time
    /// @param _value Amount of tokens to deposit and add to the lock
    function increaseAmount(uint256 _tokenId, uint256 _value) external;

    /// @notice Extend the unlock time for `_tokenId`
    /// @param _lockDuration New number of seconds until tokens unlock
    function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external;

    /// @notice Withdraw all tokens for `_tokenId`
    /// @dev Only possible if the lock has expired
    function withdraw(uint256 _tokenId) external;

    function withdraw(uint256[] calldata _tokenIds) external;

    function withdraw(address _user) external;

    function balanceOfNFT(uint256 _tokenId) external view returns (uint256);

    function tokenURI(uint256) external view returns (string memory);
}

// src/linea/zerolend/Depositor.sol

/// @title Stake DAO ZERO Depositor
/// @notice Contract responsible for managing ZERO token deposits, locking them in the Locker,
///         and minting sdZERO tokens in return.
/// @author StakeDAO
/// @custom:contact [email protected]
contract Depositor is BaseDepositor {
    ///////////////////////////////////////////////////////////////
    /// --- STATE VARIABLES & CONSTANTS
    ///////////////////////////////////////////////////////////////

    /// @notice ZeroLend locker NFT contract interface
    ILockerToken public immutable zeroLocker;

    /// @notice Voting Escrow contract interface for managing voting power
    IZeroVp public immutable veToken;

    /// @notice Token ID representing the locked ZERO tokens in the locker ERC721
    uint256 public zeroLockedTokenId;

    ///////////////////////////////////////////////////////////////
    /// --- ERRORS
    ///////////////////////////////////////////////////////////////

    error ZeroValue();
    error ZeroAddress();
    error EmptyTokenIdList();
    error NotOwnerOfToken(uint256 tokenId);
    error ExecFromSafeModuleFailed();

    ////////////////////////////////////////////////////////////////
    /// --- EVENTS
    ////////////////////////////////////////////////////////////////

    /// @notice Emitted when an existing lock is increased
    /// @param value Additional amount of tokens locked
    /// @param duration New duration of the lock in seconds
    event LockIncreased(uint256 value, uint256 duration);

    ////////////////////////////////////////////////////////////////
    /// --- CONSTRUCTOR
    ///////////////////////////////////////////////////////////////

    /// @notice Initializes the Depositor contract with required dependencies
    /// @param _token Address of the ZERO token
    /// @param _locker Address of the SD locker contract
    /// @param _minter Address of the sdZERO minter contract
    /// @param _gauge Address of the sdZERO-gauge contract
    /// @param _zeroLocker Address of the ZeroLend locker NFT contract
    /// @param _veToken Address of the ZEROvp token contract
    constructor(address _token, address _locker, address _minter, address _gauge, address _zeroLocker, address _veToken)
        BaseDepositor(_token, _locker, _minter, _gauge, 4 * 365 days)
    {
        if (_zeroLocker == address(0) || _veToken == address(0)) {
            revert ZeroAddress();
        }

        zeroLocker = ILockerToken(_zeroLocker);
        veToken = IZeroVp(_veToken);
    }

    ////////////////////////////////////////////////////////////////
    /// --- BASE CONTRACT OVERRIDE
    ///////////////////////////////////////////////////////////////

    /// @notice Locks tokens held by the contract
    /// @dev Overrides BaseDepositor's _lockToken function
    /// @param _amount Amount of tokens to lock
    function _lockToken(uint256 _amount) internal virtual override {
        if (_amount == 0) revert ZeroValue();

        uint256 _unlockTime = block.timestamp + MAX_LOCK_DURATION;
        uint256 _newZeroLockedTokenId = _createLock(_amount);

        if (zeroLockedTokenId != 0) {
            _unstakeNFTFromLocker();
            _merge(zeroLockedTokenId, _newZeroLockedTokenId);
            emit LockIncreased(_amount, _unlockTime);
        }

        _stakeNFTFromLocker(_newZeroLockedTokenId);
        zeroLockedTokenId = _newZeroLockedTokenId;
    }

    /// @notice Creates a new lock in the ZeroLend locker
    /// @dev Executes the lock creation through the Safe module
    /// @param _amount Amount of tokens to lock
    /// @return _tokenId ID of the newly created lock
    function _createLock(uint256 _amount) internal returns (uint256 _tokenId) {
        (bool _success, bytes memory _data) = ILocker_1(locker).execTransactionFromModuleReturnData(
            address(zeroLocker),
            0,
            abi.encodeWithSelector(ILockerToken.createLock.selector, _amount, MAX_LOCK_DURATION, false),
            Enum.Operation.Call
        );

        if (!_success) revert ExecFromSafeModuleFailed();
        _tokenId = abi.decode(_data, (uint256));
    }

    /// @notice Merges two lock positions
    /// @param _tokenIdFrom Source token ID to merge from
    /// @param _tokenIdTo Destination token ID to merge into
    function _merge(uint256 _tokenIdFrom, uint256 _tokenIdTo) internal {
        (bool _success,) = ILocker_1(locker).execTransactionFromModuleReturnData(
            address(zeroLocker),
            0,
            abi.encodeWithSelector(ILockerToken.merge.selector, _tokenIdFrom, _tokenIdTo),
            Enum.Operation.Call
        );
        if (!_success) revert ExecFromSafeModuleFailed();
    }

    /// @notice Unstakes the current locked token from ZEROvp
    function _unstakeNFTFromLocker() internal {
        (bool _success,) = ILocker_1(locker).execTransactionFromModuleReturnData(
            address(veToken),
            0,
            abi.encodeWithSelector(IZeroVp.unstakeToken.selector, zeroLockedTokenId),
            Enum.Operation.Call
        );
        if (!_success) revert ExecFromSafeModuleFailed();
    }

    /// @notice Stakes an NFT in the ZEROvp contract
    /// @param _tokenId Token ID to stake
    function _stakeNFTFromLocker(uint256 _tokenId) internal {
        (bool _success,) = ILocker_1(locker).execTransactionFromModuleReturnData(
            address(zeroLocker),
            0,
            abi.encodeWithSignature("safeTransferFrom(address,address,uint256)", locker, veToken, _tokenId),
            Enum.Operation.Call
        );
        if (!_success) revert ExecFromSafeModuleFailed();
    }

    ////////////////////////////////////////////////////////////////
    /// --- NFT DEPOSIT FUNCTIONS
    ///////////////////////////////////////////////////////////////

    /// @notice Deposits ZeroLend locker NFTs and mints sdZero or sdZeroGauge tokens
    /// @param _tokenIds Array of token IDs to deposit
    /// @param _stake If true, stakes sdToken in gauge; if false, sends to user
    /// @param _user Address to receive the sdToken
    function deposit(uint256[] calldata _tokenIds, bool _stake, address _user) external {
        if (_user == address(0)) revert ADDRESS_ZERO();

        uint256 _amount = _mergeLocksAndStake(_tokenIds);

        if (_stake && gauge != address(0)) {
            // Mint sdToken to this contract and stake in gauge
            ITokenMinter(minter).mint(address(this), _amount);
            ILiquidityGauge(gauge).deposit(_amount, _user);
        } else {
            // Mint sdToken directly to user
            ITokenMinter(minter).mint(_user, _amount);
        }
    }

    /// @notice Merges multiple locks and stakes the resulting token
    /// @param _tokenIds Array of token IDs to merge
    /// @return _amount Total amount of tokens merged
    function _mergeLocksAndStake(uint256[] calldata _tokenIds) internal returns (uint256 _amount) {
        if (_tokenIds.length == 0) revert EmptyTokenIdList();

        _unstakeNFTFromLocker();

        for (uint256 index = 0; index < _tokenIds.length;) {
            if (zeroLocker.ownerOf(_tokenIds[index]) != msg.sender) revert NotOwnerOfToken(_tokenIds[index]);

            _amount += zeroLocker.locked(_tokenIds[index]).amount;
            _merge(_tokenIds[index], zeroLockedTokenId);

            unchecked {
                ++index;
            }
        }

        _stakeNFTFromLocker(zeroLockedTokenId);

        uint256 _lockEnd = zeroLocker.lockedEnd(zeroLockedTokenId);
        emit LockIncreased(_amount, _lockEnd);
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_locker","type":"address"},{"internalType":"address","name":"_minter","type":"address"},{"internalType":"address","name":"_gauge","type":"address"},{"internalType":"address","name":"_zeroLocker","type":"address"},{"internalType":"address","name":"_veToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ADDRESS_ZERO","type":"error"},{"inputs":[],"name":"AMOUNT_ZERO","type":"error"},{"inputs":[],"name":"EmptyTokenIdList","type":"error"},{"inputs":[],"name":"ExecFromSafeModuleFailed","type":"error"},{"inputs":[],"name":"GOVERNANCE","type":"error"},{"inputs":[],"name":"LOCK_INCENTIVE_TOO_HIGH","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NotOwnerOfToken","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newGauge","type":"address"}],"name":"GaugeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceUpdateAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newFutureGovernance","type":"address"}],"name":"GovernanceUpdateProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newLockIncentive","type":"uint256"}],"name":"LockIncentiveUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"LockIncreased","type":"event"},{"inputs":[],"name":"DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_LOCK_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"createLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_stake","type":"bool"},{"internalType":"address","name":"_user","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_lock","type":"bool"},{"internalType":"bool","name":"_stake","type":"bool"},{"internalType":"address","name":"_user","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"futureGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentiveToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockIncentivePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"locker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockIncentive","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"setGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"setSdTokenMinterOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"veToken","outputs":[{"internalType":"contract IZeroVp","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"zeroLockedTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zeroLocker","outputs":[{"internalType":"contract ILockerToken","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

61012060405266038d7ea4c680006001553480156200001d57600080fd5b50604051620035fd380380620035fd83398181016040528101906200004391906200052f565b85858585630784ce00600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161480620000b45750600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16145b80620000ec5750600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16145b80620001245750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b156200015c576040517f66e7950900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508473ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff168152505081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508373ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250508060808181525050600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146200035b576200035a60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6200047560201b60201c565b5b5050505050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161480620003c85750600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b1562000400576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff1681525050505050505050620005cb565b81601452806034526f095ea7b300000000000000000000000060005260206000604460106000875af13d156001600051141716620004bb57633e3f8f736000526004601cfd5b6000603452505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620004f782620004ca565b9050919050565b6200050981620004ea565b81146200051557600080fd5b50565b6000815190506200052981620004fe565b92915050565b60008060008060008060c087890312156200054f576200054e620004c5565b5b60006200055f89828a0162000518565b96505060206200057289828a0162000518565b95505060406200058589828a0162000518565b94505060606200059889828a0162000518565b9350506080620005ab89828a0162000518565b92505060a0620005be89828a0162000518565b9150509295509295509295565b60805160a05160c05160e05161010051612f22620006db600039600081816108a901528181611c550152611f99015260008181610f1601528181611732015281816118560152818161195801528181611dd401528181611f550152612132015260008181610e4001528181611005015281816110f6015281816114eb015281816115340152818161155b01528181611c1901528181611d9801528181611f1901528181611f7801526120f601526000818161068601528181610d7801528181610e1f01528181610fe30152818161102e015281816110d50152818161115e0152818161151201526116a30152600081816109d40152818161159801528181611b10015261215e0152612f226000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c8063638126f8116100c3578063c628b7831161007c578063c628b78314610349578063d0f492f714610367578063d38bfff414610383578063d7b96d4e1461039f578063f7d9d0c4146103bd578063fc0c546a146103d957610158565b8063638126f8146102a95780638070c503146102c7578063918f8674146102e5578063a6f19c8414610303578063b7fa1ba714610321578063bca7a9e21461033f57610158565b80633d18678e116101155780633d18678e146101fb5780634f1bfc9e1461021757806354fd4d501461023557806355a68ed3146102535780635aa6e6751461026f578063601aff121461028d57610158565b8063057b72531461015d57806306fdde03146101795780630754617214610197578063238efcbc146101b55780632eef5e6c146101bf5780633b92eb23146101dd575b600080fd5b610177600480360381019061017291906123be565b6103f7565b005b610181610682565b60405161018e91906124c2565b60405180910390f35b61019f61073c565b6040516101ac91906124f3565b60405180910390f35b6101bd610760565b005b6101c76108a1565b6040516101d49190612527565b60405180910390f35b6101e56108a7565b6040516101f291906125a1565b60405180910390f35b610215600480360381019061021091906125e8565b6108cb565b005b61021f6109d2565b60405161022c9190612527565b60405180910390f35b61023d6109f6565b60405161024a91906124c2565b60405180910390f35b61026d60048036038101906102689190612615565b610a33565b005b610277610bd5565b60405161028491906124f3565b60405180910390f35b6102a760048036038101906102a29190612615565b610bfb565b005b6102b1610d10565b6040516102be9190612527565b60405180910390f35b6102cf610d16565b6040516102dc91906124f3565b60405180910390f35b6102ed610d3c565b6040516102fa9190612527565b60405180910390f35b61030b610d48565b60405161031891906124f3565b60405180910390f35b610329610d6e565b6040516103369190612527565b60405180910390f35b610347610d74565b005b610351610f14565b60405161035e9190612663565b60405180910390f35b610381600480360381019061037c919061267e565b610f38565b005b61039d60048036038101906103989190612615565b6113e9565b005b6103a76114e9565b6040516103b491906124f3565b60405180910390f35b6103d760048036038101906103d291906125e8565b61150d565b005b6103e16116a1565b6040516103ee91906124f3565b60405180910390f35b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361045d576040517f66e7950900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061046985856116c5565b90508280156104c75750600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b156105ed5760008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105279291906126e5565b600060405180830381600087803b15801561054157600080fd5b505af1158015610555573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e553f6582846040518363ffffffff1660e01b81526004016105b692919061270e565b600060405180830381600087803b1580156105d057600080fd5b505af11580156105e4573d6000803e3d6000fd5b5050505061067b565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b81526004016106489291906126e5565b600060405180830381600087803b15801561066257600080fd5b505af1158015610676573d6000803e3d6000fd5b505050505b5050505050565b60607f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106ef573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906107189190612858565b6040516020016107289190612929565b604051602081830303815290604052905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107e7576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fc5a7796de4cb7d91f6bcb5802c4f7173093d17e39aa683b1c73d1b0707fb52d133600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905560405161085591906124f3565b60405180910390a16000600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610952576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b660aa87bee538000811115610993576040517f981a4af500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fadd28dbd52f3fa3e93c97aa1b8110f0a76710adf2c1d636b60005c7b7bc6ecec8160018190556040516109c79190612527565b60405180910390a150565b7f000000000000000000000000000000000000000000000000000000000000000081565b60606040518060400160405280600581526020017f342e302e30000000000000000000000000000000000000000000000000000000815250905090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aba576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f629d40c6cf2ac89d7ffe5746f80af769a9d19c37a5c5bd61ca861444f50c370c81600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055604051610b2891906124f3565b60405180910390a1600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bd257610bd160008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611a34565b5b50565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c82576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b3ab15fb826040518263ffffffff1660e01b8152600401610cdb91906124f3565b600060405180830381600087803b158015610cf557600080fd5b505af1158015610d09573d6000803e3d6000fd5b5050505050565b60025481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a764000081565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60015481565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610dcf91906124f3565b602060405180830381865afa158015610dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e109190612960565b905060008114610e6f57610e657f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083611a83565b610e6e81611ad2565b5b600060025414610f115760008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f19336002546040518363ffffffff1660e01b8152600401610ed69291906126e5565b600060405180830381600087803b158015610ef057600080fd5b505af1158015610f04573d6000803e3d6000fd5b5050505060006002819055505b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008403610f72576040517f1f4d907000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fd8576040517f66e7950900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156111595761102a7f0000000000000000000000000000000000000000000000000000000000000000337f000000000000000000000000000000000000000000000000000000000000000087611bb6565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161108591906124f3565b602060405180830381865afa1580156110a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c69190612960565b90506000811461111c5761111b7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083611a83565b5b611130858261112b91906129bc565b611ad2565b600060025414611153576002548561114891906129bc565b945060006002819055505b506111d3565b6111857f0000000000000000000000000000000000000000000000000000000000000000333087611bb6565b6000670de0b6b3a76400006001548661119e91906129f0565b6111a89190612a61565b905080856111b69190612a92565b945080600260008282546111ca91906129bc565b92505081905550505b81801561122f5750600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b156113555760008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930866040518363ffffffff1660e01b815260040161128f9291906126e5565b600060405180830381600087803b1580156112a957600080fd5b505af11580156112bd573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e553f6585836040518363ffffffff1660e01b815260040161131e92919061270e565b600060405180830381600087803b15801561133857600080fd5b505af115801561134c573d6000803e3d6000fd5b505050506113e3565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1982866040518363ffffffff1660e01b81526004016113b09291906126e5565b600060405180830381600087803b1580156113ca57600080fd5b505af11580156113de573d6000803e3d6000fd5b505050505b50505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611470576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fe381cc22523c80718541282d3850cc1991dabfa0414670e3d348f1e732434e2a81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790556040516114de91906124f3565b60405180910390a150565b7f000000000000000000000000000000000000000000000000000000000000000081565b6115597f0000000000000000000000000000000000000000000000000000000000000000337f000000000000000000000000000000000000000000000000000000000000000084611bb6565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b52c05fe827f0000000000000000000000000000000000000000000000000000000000000000426115c291906129bc565b6040518363ffffffff1660e01b81526004016115df929190612ac6565b600060405180830381600087803b1580156115f957600080fd5b505af115801561160d573d6000803e3d6000fd5b5050505060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933836040518363ffffffff1660e01b815260040161166c9291906126e5565b600060405180830381600087803b15801561168657600080fd5b505af115801561169a573d6000803e3d6000fd5b5050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000808383905003611703576040517f8ca2843b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61170b611c15565b60005b83839050811015611948573373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636352211e86868581811061177f5761177e612aef565b5b905060200201356040518263ffffffff1660e01b81526004016117a29190612527565b602060405180830381865afa1580156117bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e39190612b33565b73ffffffffffffffffffffffffffffffffffffffff16146118545783838281811061181157611810612aef565b5b905060200201356040517f3b94a19900000000000000000000000000000000000000000000000000000000815260040161184b9190612527565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b45a3c0e8585848181106118a3576118a2612aef565b5b905060200201356040518263ffffffff1660e01b81526004016118c69190612527565b608060405180830381865afa1580156118e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119079190612bdd565b600001518261191691906129bc565b915061193d84848381811061192e5761192d612aef565b5b90506020020135600654611d94565b80600101905061170e565b50611954600654611f15565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663626944df6006546040518263ffffffff1660e01b81526004016119b19190612527565b602060405180830381865afa1580156119ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f29190612960565b90507f4879f53821b44fc745aeaf3081ec8771f44cac3bc5783d84c0024a2842b684478282604051611a25929190612ac6565b60405180910390a15092915050565b81601452806034526f095ea7b300000000000000000000000060005260206000604460106000875af13d156001600051141716611a7957633e3f8f736000526004601cfd5b6000603452505050565b81601452806034526fa9059cbb00000000000000000000000060005260206000604460106000875af13d156001600051141716611ac8576390b8ec186000526004601cfd5b6000603452505050565b60008103611b0c576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000042611b3a91906129bc565b90506000611b47836120ef565b9050600060065414611ba157611b5b611c15565b611b6760065482611d94565b7f4879f53821b44fc745aeaf3081ec8771f44cac3bc5783d84c0024a2842b684478383604051611b98929190612ac6565b60405180910390a15b611baa81611f15565b80600681905550505050565b60405181606052826040528360601b602c526f23b872dd000000000000000000000000600c52602060006064601c6000895af13d156001600051141716611c0557637939f4246000526004601cfd5b6000606052806040525050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635229073f7f00000000000000000000000000000000000000000000000000000000000000006000632cfb668860e01b600654604051602401611c919190612527565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b8152600401611d0f9493929190612d11565b6000604051808303816000875af1158015611d2e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611d579190612e13565b50905080611d91576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635229073f7f0000000000000000000000000000000000000000000000000000000000000000600063d1c2babb60e01b8787604051602401611e10929190612ac6565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b8152600401611e8e9493929190612d11565b6000604051808303816000875af1158015611ead573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ed69190612e13565b50905080611f10576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635229073f7f000000000000000000000000000000000000000000000000000000000000000060007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000087604051602401611fcb93929190612e6f565b6040516020818303038152906040527f42842e0e000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b81526004016120699493929190612d11565b6000604051808303816000875af1158015612088573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906120b19190612e13565b509050806120eb576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635229073f7f0000000000000000000000000000000000000000000000000000000000000000600063d60371a760e01b887f0000000000000000000000000000000000000000000000000000000000000000600060405160240161219193929190612eb5565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b815260040161220f9493929190612d11565b6000604051808303816000875af115801561222e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122579190612e13565b9150915081612292576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808060200190518101906122a69190612960565b92505050919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126122e8576122e76122c3565b5b8235905067ffffffffffffffff811115612305576123046122c8565b5b602083019150836020820283011115612321576123206122cd565b5b9250929050565b60008115159050919050565b61233d81612328565b811461234857600080fd5b50565b60008135905061235a81612334565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061238b82612360565b9050919050565b61239b81612380565b81146123a657600080fd5b50565b6000813590506123b881612392565b92915050565b600080600080606085870312156123d8576123d76122b9565b5b600085013567ffffffffffffffff8111156123f6576123f56122be565b5b612402878288016122d2565b945094505060206124158782880161234b565b9250506040612426878288016123a9565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b60005b8381101561246c578082015181840152602081019050612451565b60008484015250505050565b6000601f19601f8301169050919050565b600061249482612432565b61249e818561243d565b93506124ae81856020860161244e565b6124b781612478565b840191505092915050565b600060208201905081810360008301526124dc8184612489565b905092915050565b6124ed81612380565b82525050565b600060208201905061250860008301846124e4565b92915050565b6000819050919050565b6125218161250e565b82525050565b600060208201905061253c6000830184612518565b92915050565b6000819050919050565b600061256761256261255d84612360565b612542565b612360565b9050919050565b60006125798261254c565b9050919050565b600061258b8261256e565b9050919050565b61259b81612580565b82525050565b60006020820190506125b66000830184612592565b92915050565b6125c58161250e565b81146125d057600080fd5b50565b6000813590506125e2816125bc565b92915050565b6000602082840312156125fe576125fd6122b9565b5b600061260c848285016125d3565b91505092915050565b60006020828403121561262b5761262a6122b9565b5b6000612639848285016123a9565b91505092915050565b600061264d8261256e565b9050919050565b61265d81612642565b82525050565b60006020820190506126786000830184612654565b92915050565b60008060008060808587031215612698576126976122b9565b5b60006126a6878288016125d3565b94505060206126b78782880161234b565b93505060406126c88782880161234b565b92505060606126d9878288016123a9565b91505092959194509250565b60006040820190506126fa60008301856124e4565b6127076020830184612518565b9392505050565b60006040820190506127236000830185612518565b61273060208301846124e4565b9392505050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61277482612478565b810181811067ffffffffffffffff821117156127935761279261273c565b5b80604052505050565b60006127a66122af565b90506127b2828261276b565b919050565b600067ffffffffffffffff8211156127d2576127d161273c565b5b6127db82612478565b9050602081019050919050565b60006127fb6127f6846127b7565b61279c565b90508281526020810184848401111561281757612816612737565b5b61282284828561244e565b509392505050565b600082601f83011261283f5761283e6122c3565b5b815161284f8482602086016127e8565b91505092915050565b60006020828403121561286e5761286d6122b9565b5b600082015167ffffffffffffffff81111561288c5761288b6122be565b5b6128988482850161282a565b91505092915050565b600081905092915050565b60006128b782612432565b6128c181856128a1565b93506128d181856020860161244e565b80840191505092915050565b7f204465706f7369746f7200000000000000000000000000000000000000000000600082015250565b6000612913600a836128a1565b915061291e826128dd565b600a82019050919050565b600061293582846128ac565b915061294082612906565b915081905092915050565b60008151905061295a816125bc565b92915050565b600060208284031215612976576129756122b9565b5b60006129848482850161294b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006129c78261250e565b91506129d28361250e565b92508282019050808211156129ea576129e961298d565b5b92915050565b60006129fb8261250e565b9150612a068361250e565b9250828202612a148161250e565b91508282048414831517612a2b57612a2a61298d565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612a6c8261250e565b9150612a778361250e565b925082612a8757612a86612a32565b5b828204905092915050565b6000612a9d8261250e565b9150612aa88361250e565b9250828203905081811115612ac057612abf61298d565b5b92915050565b6000604082019050612adb6000830185612518565b612ae86020830184612518565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050612b2d81612392565b92915050565b600060208284031215612b4957612b486122b9565b5b6000612b5784828501612b1e565b91505092915050565b600080fd5b600060808284031215612b7b57612b7a612b60565b5b612b85608061279c565b90506000612b958482850161294b565b6000830152506020612ba98482850161294b565b6020830152506040612bbd8482850161294b565b6040830152506060612bd18482850161294b565b60608301525092915050565b600060808284031215612bf357612bf26122b9565b5b6000612c0184828501612b65565b91505092915050565b6000819050919050565b6000612c2f612c2a612c2584612c0a565b612542565b61250e565b9050919050565b612c3f81612c14565b82525050565b600081519050919050565b600082825260208201905092915050565b6000612c6c82612c45565b612c768185612c50565b9350612c8681856020860161244e565b612c8f81612478565b840191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110612cda57612cd9612c9a565b5b50565b6000819050612ceb82612cc9565b919050565b6000612cfb82612cdd565b9050919050565b612d0b81612cf0565b82525050565b6000608082019050612d2660008301876124e4565b612d336020830186612c36565b8181036040830152612d458185612c61565b9050612d546060830184612d02565b95945050505050565b600081519050612d6c81612334565b92915050565b600067ffffffffffffffff821115612d8d57612d8c61273c565b5b612d9682612478565b9050602081019050919050565b6000612db6612db184612d72565b61279c565b905082815260208101848484011115612dd257612dd1612737565b5b612ddd84828561244e565b509392505050565b600082601f830112612dfa57612df96122c3565b5b8151612e0a848260208601612da3565b91505092915050565b60008060408385031215612e2a57612e296122b9565b5b6000612e3885828601612d5d565b925050602083015167ffffffffffffffff811115612e5957612e586122be565b5b612e6585828601612de5565b9150509250929050565b6000606082019050612e8460008301866124e4565b612e916020830185612592565b612e9e6040830184612518565b949350505050565b612eaf81612328565b82525050565b6000606082019050612eca6000830186612518565b612ed76020830185612518565b612ee46040830184612ea6565b94935050505056fea264697066735822122077852540be67ccf1287b06560e2af9a855ab8aa094c4b2944d89e3b1e20e259464736f6c6343000813003300000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a7000000000000000000000000c0295f271c4fd531d436f55b0cef4cc316188046000000000000000000000000930b866491549f6f5716cea94723187e45e22ee5000000000000000000000000c6973841dc130597df3cb8be2f57440d856fd7c400000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f8000000000000000000000000f374229a18ff691406f99ccbd93e8a3f16b68888

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101585760003560e01c8063638126f8116100c3578063c628b7831161007c578063c628b78314610349578063d0f492f714610367578063d38bfff414610383578063d7b96d4e1461039f578063f7d9d0c4146103bd578063fc0c546a146103d957610158565b8063638126f8146102a95780638070c503146102c7578063918f8674146102e5578063a6f19c8414610303578063b7fa1ba714610321578063bca7a9e21461033f57610158565b80633d18678e116101155780633d18678e146101fb5780634f1bfc9e1461021757806354fd4d501461023557806355a68ed3146102535780635aa6e6751461026f578063601aff121461028d57610158565b8063057b72531461015d57806306fdde03146101795780630754617214610197578063238efcbc146101b55780632eef5e6c146101bf5780633b92eb23146101dd575b600080fd5b610177600480360381019061017291906123be565b6103f7565b005b610181610682565b60405161018e91906124c2565b60405180910390f35b61019f61073c565b6040516101ac91906124f3565b60405180910390f35b6101bd610760565b005b6101c76108a1565b6040516101d49190612527565b60405180910390f35b6101e56108a7565b6040516101f291906125a1565b60405180910390f35b610215600480360381019061021091906125e8565b6108cb565b005b61021f6109d2565b60405161022c9190612527565b60405180910390f35b61023d6109f6565b60405161024a91906124c2565b60405180910390f35b61026d60048036038101906102689190612615565b610a33565b005b610277610bd5565b60405161028491906124f3565b60405180910390f35b6102a760048036038101906102a29190612615565b610bfb565b005b6102b1610d10565b6040516102be9190612527565b60405180910390f35b6102cf610d16565b6040516102dc91906124f3565b60405180910390f35b6102ed610d3c565b6040516102fa9190612527565b60405180910390f35b61030b610d48565b60405161031891906124f3565b60405180910390f35b610329610d6e565b6040516103369190612527565b60405180910390f35b610347610d74565b005b610351610f14565b60405161035e9190612663565b60405180910390f35b610381600480360381019061037c919061267e565b610f38565b005b61039d60048036038101906103989190612615565b6113e9565b005b6103a76114e9565b6040516103b491906124f3565b60405180910390f35b6103d760048036038101906103d291906125e8565b61150d565b005b6103e16116a1565b6040516103ee91906124f3565b60405180910390f35b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361045d576040517f66e7950900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061046985856116c5565b90508280156104c75750600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b156105ed5760008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930836040518363ffffffff1660e01b81526004016105279291906126e5565b600060405180830381600087803b15801561054157600080fd5b505af1158015610555573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e553f6582846040518363ffffffff1660e01b81526004016105b692919061270e565b600060405180830381600087803b1580156105d057600080fd5b505af11580156105e4573d6000803e3d6000fd5b5050505061067b565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b81526004016106489291906126e5565b600060405180830381600087803b15801561066257600080fd5b505af1158015610676573d6000803e3d6000fd5b505050505b5050505050565b60607f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a773ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106ef573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906107189190612858565b6040516020016107289190612929565b604051602081830303815290604052905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107e7576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fc5a7796de4cb7d91f6bcb5802c4f7173093d17e39aa683b1c73d1b0707fb52d133600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905560405161085591906124f3565b60405180910390a16000600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b7f000000000000000000000000f374229a18ff691406f99ccbd93e8a3f16b6888881565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610952576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b660aa87bee538000811115610993576040517f981a4af500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fadd28dbd52f3fa3e93c97aa1b8110f0a76710adf2c1d636b60005c7b7bc6ecec8160018190556040516109c79190612527565b60405180910390a150565b7f000000000000000000000000000000000000000000000000000000000784ce0081565b60606040518060400160405280600581526020017f342e302e30000000000000000000000000000000000000000000000000000000815250905090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aba576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f629d40c6cf2ac89d7ffe5746f80af769a9d19c37a5c5bd61ca861444f50c370c81600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055604051610b2891906124f3565b60405180910390a1600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610bd257610bd160008054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611a34565b5b50565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c82576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b3ab15fb826040518263ffffffff1660e01b8152600401610cdb91906124f3565b600060405180830381600087803b158015610cf557600080fd5b505af1158015610d09573d6000803e3d6000fd5b5050505050565b60025481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b670de0b6b3a764000081565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60015481565b60007f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a773ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610dcf91906124f3565b602060405180830381865afa158015610dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e109190612960565b905060008114610e6f57610e657f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a77f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804683611a83565b610e6e81611ad2565b5b600060025414610f115760008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f19336002546040518363ffffffff1660e01b8152600401610ed69291906126e5565b600060405180830381600087803b158015610ef057600080fd5b505af1158015610f04573d6000803e3d6000fd5b5050505060006002819055505b50565b7f00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f881565b60008403610f72576040517f1f4d907000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610fd8576040517f66e7950900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82156111595761102a7f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a7337f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804687611bb6565b60007f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a773ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161108591906124f3565b602060405180830381865afa1580156110a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c69190612960565b90506000811461111c5761111b7f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a77f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804683611a83565b5b611130858261112b91906129bc565b611ad2565b600060025414611153576002548561114891906129bc565b945060006002819055505b506111d3565b6111857f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a7333087611bb6565b6000670de0b6b3a76400006001548661119e91906129f0565b6111a89190612a61565b905080856111b69190612a92565b945080600260008282546111ca91906129bc565b92505081905550505b81801561122f5750600073ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b156113555760008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1930866040518363ffffffff1660e01b815260040161128f9291906126e5565b600060405180830381600087803b1580156112a957600080fd5b505af11580156112bd573d6000803e3d6000fd5b50505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636e553f6585836040518363ffffffff1660e01b815260040161131e92919061270e565b600060405180830381600087803b15801561133857600080fd5b505af115801561134c573d6000803e3d6000fd5b505050506113e3565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1982866040518363ffffffff1660e01b81526004016113b09291906126e5565b600060405180830381600087803b1580156113ca57600080fd5b505af11580156113de573d6000803e3d6000fd5b505050505b50505050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611470576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fe381cc22523c80718541282d3850cc1991dabfa0414670e3d348f1e732434e2a81600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790556040516114de91906124f3565b60405180910390a150565b7f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804681565b6115597f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a7337f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804684611bb6565b7f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804673ffffffffffffffffffffffffffffffffffffffff1663b52c05fe827f000000000000000000000000000000000000000000000000000000000784ce00426115c291906129bc565b6040518363ffffffff1660e01b81526004016115df929190612ac6565b600060405180830381600087803b1580156115f957600080fd5b505af115801561160d573d6000803e3d6000fd5b5050505060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1933836040518363ffffffff1660e01b815260040161166c9291906126e5565b600060405180830381600087803b15801561168657600080fd5b505af115801561169a573d6000803e3d6000fd5b5050505050565b7f00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a781565b6000808383905003611703576040517f8ca2843b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61170b611c15565b60005b83839050811015611948573373ffffffffffffffffffffffffffffffffffffffff167f00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f873ffffffffffffffffffffffffffffffffffffffff16636352211e86868581811061177f5761177e612aef565b5b905060200201356040518263ffffffff1660e01b81526004016117a29190612527565b602060405180830381865afa1580156117bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e39190612b33565b73ffffffffffffffffffffffffffffffffffffffff16146118545783838281811061181157611810612aef565b5b905060200201356040517f3b94a19900000000000000000000000000000000000000000000000000000000815260040161184b9190612527565b60405180910390fd5b7f00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f873ffffffffffffffffffffffffffffffffffffffff1663b45a3c0e8585848181106118a3576118a2612aef565b5b905060200201356040518263ffffffff1660e01b81526004016118c69190612527565b608060405180830381865afa1580156118e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119079190612bdd565b600001518261191691906129bc565b915061193d84848381811061192e5761192d612aef565b5b90506020020135600654611d94565b80600101905061170e565b50611954600654611f15565b60007f00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f873ffffffffffffffffffffffffffffffffffffffff1663626944df6006546040518263ffffffff1660e01b81526004016119b19190612527565b602060405180830381865afa1580156119ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f29190612960565b90507f4879f53821b44fc745aeaf3081ec8771f44cac3bc5783d84c0024a2842b684478282604051611a25929190612ac6565b60405180910390a15092915050565b81601452806034526f095ea7b300000000000000000000000060005260206000604460106000875af13d156001600051141716611a7957633e3f8f736000526004601cfd5b6000603452505050565b81601452806034526fa9059cbb00000000000000000000000060005260206000604460106000875af13d156001600051141716611ac8576390b8ec186000526004601cfd5b6000603452505050565b60008103611b0c576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000784ce0042611b3a91906129bc565b90506000611b47836120ef565b9050600060065414611ba157611b5b611c15565b611b6760065482611d94565b7f4879f53821b44fc745aeaf3081ec8771f44cac3bc5783d84c0024a2842b684478383604051611b98929190612ac6565b60405180910390a15b611baa81611f15565b80600681905550505050565b60405181606052826040528360601b602c526f23b872dd000000000000000000000000600c52602060006064601c6000895af13d156001600051141716611c0557637939f4246000526004601cfd5b6000606052806040525050505050565b60007f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804673ffffffffffffffffffffffffffffffffffffffff16635229073f7f000000000000000000000000f374229a18ff691406f99ccbd93e8a3f16b688886000632cfb668860e01b600654604051602401611c919190612527565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b8152600401611d0f9493929190612d11565b6000604051808303816000875af1158015611d2e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611d579190612e13565b50905080611d91576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b60007f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804673ffffffffffffffffffffffffffffffffffffffff16635229073f7f00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f8600063d1c2babb60e01b8787604051602401611e10929190612ac6565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b8152600401611e8e9493929190612d11565b6000604051808303816000875af1158015611ead573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190611ed69190612e13565b50905080611f10576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60007f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804673ffffffffffffffffffffffffffffffffffffffff16635229073f7f00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f860007f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc3161880467f000000000000000000000000f374229a18ff691406f99ccbd93e8a3f16b6888887604051602401611fcb93929190612e6f565b6040516020818303038152906040527f42842e0e000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b81526004016120699493929190612d11565b6000604051808303816000875af1158015612088573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906120b19190612e13565b509050806120eb576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b60008060007f000000000000000000000000c0295f271c4fd531d436f55b0cef4cc31618804673ffffffffffffffffffffffffffffffffffffffff16635229073f7f00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f8600063d60371a760e01b887f000000000000000000000000000000000000000000000000000000000784ce00600060405160240161219193929190612eb5565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060006040518563ffffffff1660e01b815260040161220f9493929190612d11565b6000604051808303816000875af115801561222e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122579190612e13565b9150915081612292576040517fa0a0d54700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808060200190518101906122a69190612960565b92505050919050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126122e8576122e76122c3565b5b8235905067ffffffffffffffff811115612305576123046122c8565b5b602083019150836020820283011115612321576123206122cd565b5b9250929050565b60008115159050919050565b61233d81612328565b811461234857600080fd5b50565b60008135905061235a81612334565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061238b82612360565b9050919050565b61239b81612380565b81146123a657600080fd5b50565b6000813590506123b881612392565b92915050565b600080600080606085870312156123d8576123d76122b9565b5b600085013567ffffffffffffffff8111156123f6576123f56122be565b5b612402878288016122d2565b945094505060206124158782880161234b565b9250506040612426878288016123a9565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b60005b8381101561246c578082015181840152602081019050612451565b60008484015250505050565b6000601f19601f8301169050919050565b600061249482612432565b61249e818561243d565b93506124ae81856020860161244e565b6124b781612478565b840191505092915050565b600060208201905081810360008301526124dc8184612489565b905092915050565b6124ed81612380565b82525050565b600060208201905061250860008301846124e4565b92915050565b6000819050919050565b6125218161250e565b82525050565b600060208201905061253c6000830184612518565b92915050565b6000819050919050565b600061256761256261255d84612360565b612542565b612360565b9050919050565b60006125798261254c565b9050919050565b600061258b8261256e565b9050919050565b61259b81612580565b82525050565b60006020820190506125b66000830184612592565b92915050565b6125c58161250e565b81146125d057600080fd5b50565b6000813590506125e2816125bc565b92915050565b6000602082840312156125fe576125fd6122b9565b5b600061260c848285016125d3565b91505092915050565b60006020828403121561262b5761262a6122b9565b5b6000612639848285016123a9565b91505092915050565b600061264d8261256e565b9050919050565b61265d81612642565b82525050565b60006020820190506126786000830184612654565b92915050565b60008060008060808587031215612698576126976122b9565b5b60006126a6878288016125d3565b94505060206126b78782880161234b565b93505060406126c88782880161234b565b92505060606126d9878288016123a9565b91505092959194509250565b60006040820190506126fa60008301856124e4565b6127076020830184612518565b9392505050565b60006040820190506127236000830185612518565b61273060208301846124e4565b9392505050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61277482612478565b810181811067ffffffffffffffff821117156127935761279261273c565b5b80604052505050565b60006127a66122af565b90506127b2828261276b565b919050565b600067ffffffffffffffff8211156127d2576127d161273c565b5b6127db82612478565b9050602081019050919050565b60006127fb6127f6846127b7565b61279c565b90508281526020810184848401111561281757612816612737565b5b61282284828561244e565b509392505050565b600082601f83011261283f5761283e6122c3565b5b815161284f8482602086016127e8565b91505092915050565b60006020828403121561286e5761286d6122b9565b5b600082015167ffffffffffffffff81111561288c5761288b6122be565b5b6128988482850161282a565b91505092915050565b600081905092915050565b60006128b782612432565b6128c181856128a1565b93506128d181856020860161244e565b80840191505092915050565b7f204465706f7369746f7200000000000000000000000000000000000000000000600082015250565b6000612913600a836128a1565b915061291e826128dd565b600a82019050919050565b600061293582846128ac565b915061294082612906565b915081905092915050565b60008151905061295a816125bc565b92915050565b600060208284031215612976576129756122b9565b5b60006129848482850161294b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006129c78261250e565b91506129d28361250e565b92508282019050808211156129ea576129e961298d565b5b92915050565b60006129fb8261250e565b9150612a068361250e565b9250828202612a148161250e565b91508282048414831517612a2b57612a2a61298d565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612a6c8261250e565b9150612a778361250e565b925082612a8757612a86612a32565b5b828204905092915050565b6000612a9d8261250e565b9150612aa88361250e565b9250828203905081811115612ac057612abf61298d565b5b92915050565b6000604082019050612adb6000830185612518565b612ae86020830184612518565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050612b2d81612392565b92915050565b600060208284031215612b4957612b486122b9565b5b6000612b5784828501612b1e565b91505092915050565b600080fd5b600060808284031215612b7b57612b7a612b60565b5b612b85608061279c565b90506000612b958482850161294b565b6000830152506020612ba98482850161294b565b6020830152506040612bbd8482850161294b565b6040830152506060612bd18482850161294b565b60608301525092915050565b600060808284031215612bf357612bf26122b9565b5b6000612c0184828501612b65565b91505092915050565b6000819050919050565b6000612c2f612c2a612c2584612c0a565b612542565b61250e565b9050919050565b612c3f81612c14565b82525050565b600081519050919050565b600082825260208201905092915050565b6000612c6c82612c45565b612c768185612c50565b9350612c8681856020860161244e565b612c8f81612478565b840191505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60028110612cda57612cd9612c9a565b5b50565b6000819050612ceb82612cc9565b919050565b6000612cfb82612cdd565b9050919050565b612d0b81612cf0565b82525050565b6000608082019050612d2660008301876124e4565b612d336020830186612c36565b8181036040830152612d458185612c61565b9050612d546060830184612d02565b95945050505050565b600081519050612d6c81612334565b92915050565b600067ffffffffffffffff821115612d8d57612d8c61273c565b5b612d9682612478565b9050602081019050919050565b6000612db6612db184612d72565b61279c565b905082815260208101848484011115612dd257612dd1612737565b5b612ddd84828561244e565b509392505050565b600082601f830112612dfa57612df96122c3565b5b8151612e0a848260208601612da3565b91505092915050565b60008060408385031215612e2a57612e296122b9565b5b6000612e3885828601612d5d565b925050602083015167ffffffffffffffff811115612e5957612e586122be565b5b612e6585828601612de5565b9150509250929050565b6000606082019050612e8460008301866124e4565b612e916020830185612592565b612e9e6040830184612518565b949350505050565b612eaf81612328565b82525050565b6000606082019050612eca6000830186612518565b612ed76020830185612518565b612ee46040830184612ea6565b94935050505056fea264697066735822122077852540be67ccf1287b06560e2af9a855ab8aa094c4b2944d89e3b1e20e259464736f6c63430008130033

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

00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a7000000000000000000000000c0295f271c4fd531d436f55b0cef4cc316188046000000000000000000000000930b866491549f6f5716cea94723187e45e22ee5000000000000000000000000c6973841dc130597df3cb8be2f57440d856fd7c400000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f8000000000000000000000000f374229a18ff691406f99ccbd93e8a3f16b68888

-----Decoded View---------------
Arg [0] : _token (address): 0x78354f8DcCB269a615A7e0a24f9B0718FDC3C7A7
Arg [1] : _locker (address): 0xC0295F271c4fD531d436F55b0ceF4Cc316188046
Arg [2] : _minter (address): 0x930b866491549F6F5716CEA94723187e45e22ee5
Arg [3] : _gauge (address): 0xC6973841dC130597dF3Cb8bE2F57440d856FD7C4
Arg [4] : _zeroLocker (address): 0x08D5FEA625B1dBf9Bae0b97437303a0374ee02F8
Arg [5] : _veToken (address): 0xf374229a18ff691406f99CCBD93e8a3f16B68888

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000078354f8dccb269a615a7e0a24f9b0718fdc3c7a7
Arg [1] : 000000000000000000000000c0295f271c4fd531d436f55b0cef4cc316188046
Arg [2] : 000000000000000000000000930b866491549f6f5716cea94723187e45e22ee5
Arg [3] : 000000000000000000000000c6973841dc130597df3cb8be2f57440d856fd7c4
Arg [4] : 00000000000000000000000008d5fea625b1dbf9bae0b97437303a0374ee02f8
Arg [5] : 000000000000000000000000f374229a18ff691406f99ccbd93e8a3f16b68888


Deployed Bytecode Sourcemap

70070:7469:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76017:579;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64280:144;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55340:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63024:220;;;:::i;:::-;;70599:32;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70475;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64050:222;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55052:42;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64806:90;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63592:328;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55747:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63358:139;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55588:29;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55841:31;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54961:42;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55674:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55440:46;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61377:709;;;:::i;:::-;;70350:40;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59306:1962;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62814:153;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55243:31;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58080:421;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55155:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76017:579;76133:1;76116:19;;:5;:19;;;76112:46;;76144:14;;;;;;;;;;;;;;76112:46;76171:15;76189:30;76209:9;;76189:19;:30::i;:::-;76171:48;;76236:6;:29;;;;;76263:1;76246:19;;:5;;;;;;;;;;;:19;;;;76236:29;76232:357;;;76360:6;;;;;;;;;;76347:25;;;76381:4;76388:7;76347:49;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76427:5;;;;;;;;;;;76411:30;;;76442:7;76451:5;76411:46;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76232:357;;;76549:6;;;;;;;;;;76536:25;;;76562:5;76569:7;76536:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76232:357;76101:495;76017:579;;;;:::o;64280:144::-;64319:13;64385:5;64376:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64359:56;;;;;;;;:::i;:::-;;;;;;;;;;;;;64345:71;;64280:144;:::o;55340:21::-;;;;;;;;;;;;:::o;63024:220::-;63090:16;;;;;;;;;;;63076:30;;:10;:30;;;63072:55;;63115:12;;;;;;;;;;;;;;63072:55;63145:49;63183:10;63170;;:23;;;;;;;;;;;;;;;;;63145:49;;;;;;:::i;:::-;;;;;;;;63234:1;63207:16;;:29;;;;;;;;;;;;;;;;;;63024:220::o;70599:32::-;;;;:::o;70475:::-;;;:::o;64050:222::-;57112:10;;;;;;;;;;;57098:24;;:10;:24;;;57094:49;;57131:12;;;;;;;;;;;;;;57094:49;64147:8:::1;64130:14;:25;64126:63;;;64164:25;;;;;;;;;;;;;;64126:63;64205:59;64249:14;64226:20;:37;;;64205:59;;;;;;:::i;:::-;;;;;;;;64050:222:::0;:::o;55052:42::-;;;:::o;64806:90::-;64848:13;64874:14;;;;;;;;;;;;;;;;;;;64806:90;:::o;63592:328::-;57112:10;;;;;;;;;;;57098:24;;:10;:24;;;57094:49;;57131:12;;;;;;;;;;;;;;57094:49;63715:28:::1;63736:6;63728:5;;:14;;;;;;;;;;;;;;;;;63715:28;;;;;;:::i;:::-;;;;;;;;63778:1;63760:20;;:6;:20;;;63756:157;;63840:61;63868:6;::::0;::::1;;;;;;;;63876:5;;;;;;;;;;;63883:17;63840:27;:61::i;:::-;63756:157;63592:328:::0;:::o;55747:25::-;;;;;;;;;;;;;:::o;63358:139::-;57112:10;;;;;;;;;;;57098:24;;:10;:24;;;57094:49;;57131:12;;;;;;;;;;;;;;57094:49;63461:6:::1;::::0;::::1;;;;;;;;63452:28;;;63481:7;63452:37;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;63358:139:::0;:::o;55588:29::-;;;;:::o;55841:31::-;;;;;;;;;;;;;:::o;54961:42::-;54999:4;54961:42;:::o;55674:20::-;;;;;;;;;;;;;:::o;55440:46::-;;;;:::o;61377:709::-;61418:20;61450:5;61441:25;;;61475:4;61441:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61418:63;;61514:1;61498:12;:17;61494:258;;61603:57;61632:5;61639:6;61647:12;61603:28;:57::i;:::-;61716:24;61727:12;61716:10;:24::i;:::-;61494:258;61870:1;61852:14;;:19;61848:231;;61953:6;;;;;;;;;;61940:25;;;61966:10;61978:14;;61940:53;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62066:1;62049:14;:18;;;;61848:231;61407:679;61377:709::o;70350:40::-;;;:::o;59306:1962::-;59413:1;59402:7;:12;59398:38;;59423:13;;;;;;;;;;;;;;59398:38;59468:1;59451:19;;:5;:19;;;59447:46;;59479:14;;;;;;;;;;;;;;59447:46;59577:5;59573:1226;;;59656:68;59689:5;59696:10;59708:6;59716:7;59656:32;:68::i;:::-;59779:15;59806:5;59797:25;;;59831:4;59797:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59779:58;;59869:1;59858:7;:12;59854:105;;59891:52;59920:5;59927:6;59935:7;59891:28;:52::i;:::-;59854:105;60040:29;60061:7;60051;:17;;;;:::i;:::-;60040:10;:29::i;:::-;60177:1;60159:14;;:19;60155:124;;60210:14;;60199:25;;;;;:::i;:::-;;;60262:1;60245:14;:18;;;;60155:124;59584:706;59573:1226;;;60362:75;60395:5;60402:10;60422:4;60429:7;60362:32;:75::i;:::-;60520:21;54999:4;60555:20;;60545:7;:30;;;;:::i;:::-;60544:46;;;;:::i;:::-;60520:70;;60672:13;60661:24;;;;;:::i;:::-;;;60774:13;60756:14;;:31;;;;;;;:::i;:::-;;;;;;;;60296:503;59573:1226;60874:6;:29;;;;;60901:1;60884:19;;:5;;;;;;;;;;;:19;;;;60874:29;60870:391;;;60981:6;;;;;;;;;;60968:25;;;61002:4;61009:7;60968:49;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61105:5;;;;;;;;;;;61089:30;;;61120:7;61129:5;61089:46;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60870:391;;;61221:6;;;;;;;;;;61208:25;;;61234:5;61241:7;61208:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60870:391;59306:1962;;;;:::o;62814:153::-;57112:10;;;;;;;;;;;57098:24;;:10;:24;;;57094:49;;57131:12;;;;;;;;;;;;;;57094:49;62903:56:::1;62947:11;62928:16;;:30;;;;;;;;;;;;;;;;;62903:56;;;;;;:::i;:::-;;;;;;;;62814:153:::0;:::o;55243:31::-;;;:::o;58080:421::-;58191:77;58224:5;58231:10;58251:6;58260:7;58191:32;:77::i;:::-;58329:6;58319:28;;;58348:7;58375:17;58357:15;:35;;;;:::i;:::-;58319:74;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58460:6;;;;;;;;;;58447:25;;;58473:10;58485:7;58447:46;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58080:421;:::o;55155:30::-;;;:::o;76783:753::-;76860:15;76912:1;76892:9;;:16;;:21;76888:52;;76922:18;;;;;;;;;;;;;;76888:52;76953:23;:21;:23::i;:::-;76994:13;76989:370;77021:9;;:16;;77013:5;:24;76989:370;;;77099:10;77059:50;;:10;:18;;;77078:9;;77088:5;77078:16;;;;;;;:::i;:::-;;;;;;;;77059:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;77055:96;;77134:9;;77144:5;77134:16;;;;;;;:::i;:::-;;;;;;;;77118:33;;;;;;;;;;;:::i;:::-;;;;;;;;77055:96;77179:10;:17;;;77197:9;;77207:5;77197:16;;;;;;;:::i;:::-;;;;;;;;77179:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;;;77168:53;;;;;:::i;:::-;;;77236:43;77243:9;;77253:5;77243:16;;;;;;;:::i;:::-;;;;;;;;77261:17;;77236:6;:43::i;:::-;77325:7;;;;;76989:370;;;;77371:38;77391:17;;77371:19;:38::i;:::-;77422:16;77441:10;:20;;;77462:17;;77441:39;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77422:58;;77496:32;77510:7;77519:8;77496:32;;;;;;;:::i;:::-;;;;;;;;76877:659;76783:753;;;;:::o;24042:954::-;24207:2;24201:4;24194:16;24265:6;24259:4;24252:20;24331:34;24325:4;24318:48;24724:4;24718;24712;24706;24703:1;24696:5;24689;24684:45;24617:16;24610:24;24606:1;24599:4;24593:11;24590:18;24587:48;24501:247;24473:407;;24796:10;24790:4;24783:24;24860:4;24854;24847:18;24473:407;24907:1;24901:4;24894:15;24042:954;;;:::o;21190:957::-;21356:2;21350:4;21343:16;21414:6;21408:4;21401:20;21480:34;21474:4;21467:48;21874:4;21868;21862;21856;21853:1;21846:5;21839;21834:45;21767:16;21760:24;21756:1;21749:4;21743:11;21740:18;21737:48;21651:247;21623:408;;21946:10;21940:4;21933:24;22011:4;22005;21998:18;21623:408;22058:1;22052:4;22045:15;21190:957;;;:::o;72725:566::-;72814:1;72803:7;:12;72799:36;;72824:11;;;;;;;;;;;;;;72799:36;72848:19;72888:17;72870:15;:35;;;;:::i;:::-;72848:57;;72916:29;72948:20;72960:7;72948:11;:20::i;:::-;72916:52;;73006:1;72985:17;;:22;72981:196;;73024:23;:21;:23::i;:::-;73062:48;73069:17;;73088:21;73062:6;:48::i;:::-;73130:35;73144:7;73153:11;73130:35;;;;;;;:::i;:::-;;;;;;;;72981:196;73189:42;73209:21;73189:19;:42::i;:::-;73262:21;73242:17;:41;;;;72788:503;;72725:566;:::o;16743:1160::-;16929:4;16923:11;16995:6;16989:4;16982:20;17061:2;17055:4;17048:16;17127:4;17123:2;17119:13;17113:4;17106:27;17190:34;17184:4;17177:48;17596:4;17590;17584;17578;17575:1;17568:5;17561;17556:45;17489:16;17482:24;17478:1;17471:4;17465:11;17462:18;17459:48;17373:247;17345:412;;17668:10;17662:4;17655:24;17737:4;17731;17724:18;17345:412;17784:1;17778:4;17771:15;17847:1;17841:4;17834:15;16899:997;16743:1160;;;;:::o;74670:371::-;74724:13;74752:6;74742:53;;;74818:7;74841:1;74880:29;;;74911:17;;74857:72;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74944:19;74742:232;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74723:251;;;74990:8;74985:48;;75007:26;;;;;;;;;;;;;;74985:48;74712:329;74670:371::o;74195:404::-;74274:13;74302:6;74292:53;;;74368:10;74394:1;74433:27;;;74462:12;74476:10;74410:77;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74502:19;74292:240;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74273:259;;;74548:8;74543:48;;74565:26;;;;;;;;;;;;;;74543:48;74262:337;74195:404;;:::o;75146:411::-;75214:13;75242:6;75232:53;;;75308:10;75334:1;75419:6;75427:7;75436:8;75350:95;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75460:19;75232:258;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75213:277;;;75506:8;75501:48;;75523:26;;;;;;;;;;;;;;75501:48;75202:355;75146:411;:::o;73527:496::-;73583:16;73613:13;73628:18;73660:6;73650:53;;;73726:10;73752:1;73791:32;;;73825:7;73834:17;73853:5;73768:91;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73874:19;73650:254;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;73612:292;;;;73922:8;73917:48;;73939:26;;;;;;;;;;;;;;73917:48;73998:5;73987:28;;;;;;;;;;;;:::i;:::-;73976:39;;73601:422;;73527:496;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:117;566:1;563;556:12;580:117;689:1;686;679:12;720:568;793:8;803:6;853:3;846:4;838:6;834:17;830:27;820:122;;861:79;;:::i;:::-;820:122;974:6;961:20;951:30;;1004:18;996:6;993:30;990:117;;;1026:79;;:::i;:::-;990:117;1140:4;1132:6;1128:17;1116:29;;1194:3;1186:4;1178:6;1174:17;1164:8;1160:32;1157:41;1154:128;;;1201:79;;:::i;:::-;1154:128;720:568;;;;;:::o;1294:90::-;1328:7;1371:5;1364:13;1357:21;1346:32;;1294:90;;;:::o;1390:116::-;1460:21;1475:5;1460:21;:::i;:::-;1453:5;1450:32;1440:60;;1496:1;1493;1486:12;1440:60;1390:116;:::o;1512:133::-;1555:5;1593:6;1580:20;1571:29;;1609:30;1633:5;1609:30;:::i;:::-;1512:133;;;;:::o;1651:126::-;1688:7;1728:42;1721:5;1717:54;1706:65;;1651:126;;;:::o;1783:96::-;1820:7;1849:24;1867:5;1849:24;:::i;:::-;1838:35;;1783:96;;;:::o;1885:122::-;1958:24;1976:5;1958:24;:::i;:::-;1951:5;1948:35;1938:63;;1997:1;1994;1987:12;1938:63;1885:122;:::o;2013:139::-;2059:5;2097:6;2084:20;2075:29;;2113:33;2140:5;2113:33;:::i;:::-;2013:139;;;;:::o;2158:843::-;2259:6;2267;2275;2283;2332:2;2320:9;2311:7;2307:23;2303:32;2300:119;;;2338:79;;:::i;:::-;2300:119;2486:1;2475:9;2471:17;2458:31;2516:18;2508:6;2505:30;2502:117;;;2538:79;;:::i;:::-;2502:117;2651:80;2723:7;2714:6;2703:9;2699:22;2651:80;:::i;:::-;2633:98;;;;2429:312;2780:2;2806:50;2848:7;2839:6;2828:9;2824:22;2806:50;:::i;:::-;2796:60;;2751:115;2905:2;2931:53;2976:7;2967:6;2956:9;2952:22;2931:53;:::i;:::-;2921:63;;2876:118;2158:843;;;;;;;:::o;3007:99::-;3059:6;3093:5;3087:12;3077:22;;3007:99;;;:::o;3112:169::-;3196:11;3230:6;3225:3;3218:19;3270:4;3265:3;3261:14;3246:29;;3112:169;;;;:::o;3287:246::-;3368:1;3378:113;3392:6;3389:1;3386:13;3378:113;;;3477:1;3472:3;3468:11;3462:18;3458:1;3453:3;3449:11;3442:39;3414:2;3411:1;3407:10;3402:15;;3378:113;;;3525:1;3516:6;3511:3;3507:16;3500:27;3349:184;3287:246;;;:::o;3539:102::-;3580:6;3631:2;3627:7;3622:2;3615:5;3611:14;3607:28;3597:38;;3539:102;;;:::o;3647:377::-;3735:3;3763:39;3796:5;3763:39;:::i;:::-;3818:71;3882:6;3877:3;3818:71;:::i;:::-;3811:78;;3898:65;3956:6;3951:3;3944:4;3937:5;3933:16;3898:65;:::i;:::-;3988:29;4010:6;3988:29;:::i;:::-;3983:3;3979:39;3972:46;;3739:285;3647:377;;;;:::o;4030:313::-;4143:4;4181:2;4170:9;4166:18;4158:26;;4230:9;4224:4;4220:20;4216:1;4205:9;4201:17;4194:47;4258:78;4331:4;4322:6;4258:78;:::i;:::-;4250:86;;4030:313;;;;:::o;4349:118::-;4436:24;4454:5;4436:24;:::i;:::-;4431:3;4424:37;4349:118;;:::o;4473:222::-;4566:4;4604:2;4593:9;4589:18;4581:26;;4617:71;4685:1;4674:9;4670:17;4661:6;4617:71;:::i;:::-;4473:222;;;;:::o;4701:77::-;4738:7;4767:5;4756:16;;4701:77;;;:::o;4784:118::-;4871:24;4889:5;4871:24;:::i;:::-;4866:3;4859:37;4784:118;;:::o;4908:222::-;5001:4;5039:2;5028:9;5024:18;5016:26;;5052:71;5120:1;5109:9;5105:17;5096:6;5052:71;:::i;:::-;4908:222;;;;:::o;5136:60::-;5164:3;5185:5;5178:12;;5136:60;;;:::o;5202:142::-;5252:9;5285:53;5303:34;5312:24;5330:5;5312:24;:::i;:::-;5303:34;:::i;:::-;5285:53;:::i;:::-;5272:66;;5202:142;;;:::o;5350:126::-;5400:9;5433:37;5464:5;5433:37;:::i;:::-;5420:50;;5350:126;;;:::o;5482:142::-;5548:9;5581:37;5612:5;5581:37;:::i;:::-;5568:50;;5482:142;;;:::o;5630:163::-;5733:53;5780:5;5733:53;:::i;:::-;5728:3;5721:66;5630:163;;:::o;5799:254::-;5908:4;5946:2;5935:9;5931:18;5923:26;;5959:87;6043:1;6032:9;6028:17;6019:6;5959:87;:::i;:::-;5799:254;;;;:::o;6059:122::-;6132:24;6150:5;6132:24;:::i;:::-;6125:5;6122:35;6112:63;;6171:1;6168;6161:12;6112:63;6059:122;:::o;6187:139::-;6233:5;6271:6;6258:20;6249:29;;6287:33;6314:5;6287:33;:::i;:::-;6187:139;;;;:::o;6332:329::-;6391:6;6440:2;6428:9;6419:7;6415:23;6411:32;6408:119;;;6446:79;;:::i;:::-;6408:119;6566:1;6591:53;6636:7;6627:6;6616:9;6612:22;6591:53;:::i;:::-;6581:63;;6537:117;6332:329;;;;:::o;6667:::-;6726:6;6775:2;6763:9;6754:7;6750:23;6746:32;6743:119;;;6781:79;;:::i;:::-;6743:119;6901:1;6926:53;6971:7;6962:6;6951:9;6947:22;6926:53;:::i;:::-;6916:63;;6872:117;6667:329;;;;:::o;7002:147::-;7073:9;7106:37;7137:5;7106:37;:::i;:::-;7093:50;;7002:147;;;:::o;7155:173::-;7263:58;7315:5;7263:58;:::i;:::-;7258:3;7251:71;7155:173;;:::o;7334:264::-;7448:4;7486:2;7475:9;7471:18;7463:26;;7499:92;7588:1;7577:9;7573:17;7564:6;7499:92;:::i;:::-;7334:264;;;;:::o;7604:753::-;7684:6;7692;7700;7708;7757:3;7745:9;7736:7;7732:23;7728:33;7725:120;;;7764:79;;:::i;:::-;7725:120;7884:1;7909:53;7954:7;7945:6;7934:9;7930:22;7909:53;:::i;:::-;7899:63;;7855:117;8011:2;8037:50;8079:7;8070:6;8059:9;8055:22;8037:50;:::i;:::-;8027:60;;7982:115;8136:2;8162:50;8204:7;8195:6;8184:9;8180:22;8162:50;:::i;:::-;8152:60;;8107:115;8261:2;8287:53;8332:7;8323:6;8312:9;8308:22;8287:53;:::i;:::-;8277:63;;8232:118;7604:753;;;;;;;:::o;8363:332::-;8484:4;8522:2;8511:9;8507:18;8499:26;;8535:71;8603:1;8592:9;8588:17;8579:6;8535:71;:::i;:::-;8616:72;8684:2;8673:9;8669:18;8660:6;8616:72;:::i;:::-;8363:332;;;;;:::o;8701:::-;8822:4;8860:2;8849:9;8845:18;8837:26;;8873:71;8941:1;8930:9;8926:17;8917:6;8873:71;:::i;:::-;8954:72;9022:2;9011:9;9007:18;8998:6;8954:72;:::i;:::-;8701:332;;;;;:::o;9039:117::-;9148:1;9145;9138:12;9162:180;9210:77;9207:1;9200:88;9307:4;9304:1;9297:15;9331:4;9328:1;9321:15;9348:281;9431:27;9453:4;9431:27;:::i;:::-;9423:6;9419:40;9561:6;9549:10;9546:22;9525:18;9513:10;9510:34;9507:62;9504:88;;;9572:18;;:::i;:::-;9504:88;9612:10;9608:2;9601:22;9391:238;9348:281;;:::o;9635:129::-;9669:6;9696:20;;:::i;:::-;9686:30;;9725:33;9753:4;9745:6;9725:33;:::i;:::-;9635:129;;;:::o;9770:308::-;9832:4;9922:18;9914:6;9911:30;9908:56;;;9944:18;;:::i;:::-;9908:56;9982:29;10004:6;9982:29;:::i;:::-;9974:37;;10066:4;10060;10056:15;10048:23;;9770:308;;;:::o;10084:434::-;10173:5;10198:66;10214:49;10256:6;10214:49;:::i;:::-;10198:66;:::i;:::-;10189:75;;10287:6;10280:5;10273:21;10325:4;10318:5;10314:16;10363:3;10354:6;10349:3;10345:16;10342:25;10339:112;;;10370:79;;:::i;:::-;10339:112;10460:52;10505:6;10500:3;10495;10460:52;:::i;:::-;10179:339;10084:434;;;;;:::o;10538:355::-;10605:5;10654:3;10647:4;10639:6;10635:17;10631:27;10621:122;;10662:79;;:::i;:::-;10621:122;10772:6;10766:13;10797:90;10883:3;10875:6;10868:4;10860:6;10856:17;10797:90;:::i;:::-;10788:99;;10611:282;10538:355;;;;:::o;10899:524::-;10979:6;11028:2;11016:9;11007:7;11003:23;10999:32;10996:119;;;11034:79;;:::i;:::-;10996:119;11175:1;11164:9;11160:17;11154:24;11205:18;11197:6;11194:30;11191:117;;;11227:79;;:::i;:::-;11191:117;11332:74;11398:7;11389:6;11378:9;11374:22;11332:74;:::i;:::-;11322:84;;11125:291;10899:524;;;;:::o;11429:148::-;11531:11;11568:3;11553:18;;11429:148;;;;:::o;11583:390::-;11689:3;11717:39;11750:5;11717:39;:::i;:::-;11772:89;11854:6;11849:3;11772:89;:::i;:::-;11765:96;;11870:65;11928:6;11923:3;11916:4;11909:5;11905:16;11870:65;:::i;:::-;11960:6;11955:3;11951:16;11944:23;;11693:280;11583:390;;;;:::o;11979:160::-;12119:12;12115:1;12107:6;12103:14;12096:36;11979:160;:::o;12145:402::-;12305:3;12326:85;12408:2;12403:3;12326:85;:::i;:::-;12319:92;;12420:93;12509:3;12420:93;:::i;:::-;12538:2;12533:3;12529:12;12522:19;;12145:402;;;:::o;12553:541::-;12786:3;12808:95;12899:3;12890:6;12808:95;:::i;:::-;12801:102;;12920:148;13064:3;12920:148;:::i;:::-;12913:155;;13085:3;13078:10;;12553:541;;;;:::o;13100:143::-;13157:5;13188:6;13182:13;13173:22;;13204:33;13231:5;13204:33;:::i;:::-;13100:143;;;;:::o;13249:351::-;13319:6;13368:2;13356:9;13347:7;13343:23;13339:32;13336:119;;;13374:79;;:::i;:::-;13336:119;13494:1;13519:64;13575:7;13566:6;13555:9;13551:22;13519:64;:::i;:::-;13509:74;;13465:128;13249:351;;;;:::o;13606:180::-;13654:77;13651:1;13644:88;13751:4;13748:1;13741:15;13775:4;13772:1;13765:15;13792:191;13832:3;13851:20;13869:1;13851:20;:::i;:::-;13846:25;;13885:20;13903:1;13885:20;:::i;:::-;13880:25;;13928:1;13925;13921:9;13914:16;;13949:3;13946:1;13943:10;13940:36;;;13956:18;;:::i;:::-;13940:36;13792:191;;;;:::o;13989:410::-;14029:7;14052:20;14070:1;14052:20;:::i;:::-;14047:25;;14086:20;14104:1;14086:20;:::i;:::-;14081:25;;14141:1;14138;14134:9;14163:30;14181:11;14163:30;:::i;:::-;14152:41;;14342:1;14333:7;14329:15;14326:1;14323:22;14303:1;14296:9;14276:83;14253:139;;14372:18;;:::i;:::-;14253:139;14037:362;13989:410;;;;:::o;14405:180::-;14453:77;14450:1;14443:88;14550:4;14547:1;14540:15;14574:4;14571:1;14564:15;14591:185;14631:1;14648:20;14666:1;14648:20;:::i;:::-;14643:25;;14682:20;14700:1;14682:20;:::i;:::-;14677:25;;14721:1;14711:35;;14726:18;;:::i;:::-;14711:35;14768:1;14765;14761:9;14756:14;;14591:185;;;;:::o;14782:194::-;14822:4;14842:20;14860:1;14842:20;:::i;:::-;14837:25;;14876:20;14894:1;14876:20;:::i;:::-;14871:25;;14920:1;14917;14913:9;14905:17;;14944:1;14938:4;14935:11;14932:37;;;14949:18;;:::i;:::-;14932:37;14782:194;;;;:::o;14982:332::-;15103:4;15141:2;15130:9;15126:18;15118:26;;15154:71;15222:1;15211:9;15207:17;15198:6;15154:71;:::i;:::-;15235:72;15303:2;15292:9;15288:18;15279:6;15235:72;:::i;:::-;14982:332;;;;;:::o;15320:180::-;15368:77;15365:1;15358:88;15465:4;15462:1;15455:15;15489:4;15486:1;15479:15;15506:143;15563:5;15594:6;15588:13;15579:22;;15610:33;15637:5;15610:33;:::i;:::-;15506:143;;;;:::o;15655:351::-;15725:6;15774:2;15762:9;15753:7;15749:23;15745:32;15742:119;;;15780:79;;:::i;:::-;15742:119;15900:1;15925:64;15981:7;15972:6;15961:9;15957:22;15925:64;:::i;:::-;15915:74;;15871:128;15655:351;;;;:::o;16012:117::-;16121:1;16118;16111:12;16298:960;16389:5;16433:4;16421:9;16416:3;16412:19;16408:30;16405:117;;;16441:79;;:::i;:::-;16405:117;16540:21;16556:4;16540:21;:::i;:::-;16531:30;;16622:1;16662:60;16718:3;16709:6;16698:9;16694:22;16662:60;:::i;:::-;16655:4;16648:5;16644:16;16637:86;16571:163;16792:2;16833:60;16889:3;16880:6;16869:9;16865:22;16833:60;:::i;:::-;16826:4;16819:5;16815:16;16808:86;16744:161;16965:2;17006:60;17062:3;17053:6;17042:9;17038:22;17006:60;:::i;:::-;16999:4;16992:5;16988:16;16981:86;16915:163;17138:2;17179:60;17235:3;17226:6;17215:9;17211:22;17179:60;:::i;:::-;17172:4;17165:5;17161:16;17154:86;17088:163;16298:960;;;;:::o;17264:414::-;17365:6;17414:3;17402:9;17393:7;17389:23;17385:33;17382:120;;;17421:79;;:::i;:::-;17382:120;17541:1;17566:95;17653:7;17644:6;17633:9;17629:22;17566:95;:::i;:::-;17556:105;;17512:159;17264:414;;;;:::o;17684:85::-;17729:7;17758:5;17747:16;;17684:85;;;:::o;17775:158::-;17833:9;17866:61;17884:42;17893:32;17919:5;17893:32;:::i;:::-;17884:42;:::i;:::-;17866:61;:::i;:::-;17853:74;;17775:158;;;:::o;17939:147::-;18034:45;18073:5;18034:45;:::i;:::-;18029:3;18022:58;17939:147;;:::o;18092:98::-;18143:6;18177:5;18171:12;18161:22;;18092:98;;;:::o;18196:168::-;18279:11;18313:6;18308:3;18301:19;18353:4;18348:3;18344:14;18329:29;;18196:168;;;;:::o;18370:373::-;18456:3;18484:38;18516:5;18484:38;:::i;:::-;18538:70;18601:6;18596:3;18538:70;:::i;:::-;18531:77;;18617:65;18675:6;18670:3;18663:4;18656:5;18652:16;18617:65;:::i;:::-;18707:29;18729:6;18707:29;:::i;:::-;18702:3;18698:39;18691:46;;18460:283;18370:373;;;;:::o;18749:180::-;18797:77;18794:1;18787:88;18894:4;18891:1;18884:15;18918:4;18915:1;18908:15;18935:118;19021:1;19014:5;19011:12;19001:46;;19027:18;;:::i;:::-;19001:46;18935:118;:::o;19059:137::-;19109:7;19138:5;19127:16;;19144:46;19184:5;19144:46;:::i;:::-;19059:137;;;:::o;19202:::-;19263:9;19296:37;19327:5;19296:37;:::i;:::-;19283:50;;19202:137;;;:::o;19345:153::-;19443:48;19485:5;19443:48;:::i;:::-;19438:3;19431:61;19345:153;;:::o;19504:678::-;19718:4;19756:3;19745:9;19741:19;19733:27;;19770:71;19838:1;19827:9;19823:17;19814:6;19770:71;:::i;:::-;19851:80;19927:2;19916:9;19912:18;19903:6;19851:80;:::i;:::-;19978:9;19972:4;19968:20;19963:2;19952:9;19948:18;19941:48;20006:76;20077:4;20068:6;20006:76;:::i;:::-;19998:84;;20092:83;20171:2;20160:9;20156:18;20147:6;20092:83;:::i;:::-;19504:678;;;;;;;:::o;20188:137::-;20242:5;20273:6;20267:13;20258:22;;20289:30;20313:5;20289:30;:::i;:::-;20188:137;;;;:::o;20331:307::-;20392:4;20482:18;20474:6;20471:30;20468:56;;;20504:18;;:::i;:::-;20468:56;20542:29;20564:6;20542:29;:::i;:::-;20534:37;;20626:4;20620;20616:15;20608:23;;20331:307;;;:::o;20644:432::-;20732:5;20757:65;20773:48;20814:6;20773:48;:::i;:::-;20757:65;:::i;:::-;20748:74;;20845:6;20838:5;20831:21;20883:4;20876:5;20872:16;20921:3;20912:6;20907:3;20903:16;20900:25;20897:112;;;20928:79;;:::i;:::-;20897:112;21018:52;21063:6;21058:3;21053;21018:52;:::i;:::-;20738:338;20644:432;;;;;:::o;21095:353::-;21161:5;21210:3;21203:4;21195:6;21191:17;21187:27;21177:122;;21218:79;;:::i;:::-;21177:122;21328:6;21322:13;21353:89;21438:3;21430:6;21423:4;21415:6;21411:17;21353:89;:::i;:::-;21344:98;;21167:281;21095:353;;;;:::o;21454:672::-;21539:6;21547;21596:2;21584:9;21575:7;21571:23;21567:32;21564:119;;;21602:79;;:::i;:::-;21564:119;21722:1;21747:61;21800:7;21791:6;21780:9;21776:22;21747:61;:::i;:::-;21737:71;;21693:125;21878:2;21867:9;21863:18;21857:25;21909:18;21901:6;21898:30;21895:117;;;21931:79;;:::i;:::-;21895:117;22036:73;22101:7;22092:6;22081:9;22077:22;22036:73;:::i;:::-;22026:83;;21828:291;21454:672;;;;;:::o;22132:474::-;22297:4;22335:2;22324:9;22320:18;22312:26;;22348:71;22416:1;22405:9;22401:17;22392:6;22348:71;:::i;:::-;22429:88;22513:2;22502:9;22498:18;22489:6;22429:88;:::i;:::-;22527:72;22595:2;22584:9;22580:18;22571:6;22527:72;:::i;:::-;22132:474;;;;;;:::o;22612:109::-;22693:21;22708:5;22693:21;:::i;:::-;22688:3;22681:34;22612:109;;:::o;22727:430::-;22870:4;22908:2;22897:9;22893:18;22885:26;;22921:71;22989:1;22978:9;22974:17;22965:6;22921:71;:::i;:::-;23002:72;23070:2;23059:9;23055:18;23046:6;23002:72;:::i;:::-;23084:66;23146:2;23135:9;23131:18;23122:6;23084:66;:::i;:::-;22727:430;;;;;;:::o

Swarm Source

ipfs://77852540be67ccf1287b06560e2af9a855ab8aa094c4b2944d89e3b1e20e2594

Block Transaction Gas Used Reward
view all blocks sequenced

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
Loading...
Loading
[ Download: CSV Export  ]
[ 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.