POL Price: $0.676257 (-2.15%)
Gas: 31.2 GWei
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Deposit569210412024-05-13 13:05:23209 days ago1715605523IN
0x346a7903...812FA8057
0 POL0.0064094430.00000379

Latest 1 internal transaction

Parent Transaction Hash Block From To
370280612022-12-19 18:23:21720 days ago1671474201  Contract Creation0 POL
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xBfE83097...f571cbfF0
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
AaveV3ERC4626Reinvest

Compiler Version
v0.8.14+commit.80d49f37

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2022-12-19
*/

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.13;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

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

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // Divide z by the denominator.
            z := div(z, denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // First, divide z - 1 by the denominator and add 1.
            // We allow z - 1 to underflow if z is 0, because we multiply the
            // end result by 0 if z is zero, ensuring we return 0 if z is zero.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        assembly {
            // Start off with z at 1.
            z := 1

            // Used below to help find a nearby power of 2.
            let y := x

            // Find the lowest power of 2 that is at least sqrt(x).
            if iszero(lt(y, 0x100000000000000000000000000000000)) {
                y := shr(128, y) // Like dividing by 2 ** 128.
                z := shl(64, z) // Like multiplying by 2 ** 64.
            }
            if iszero(lt(y, 0x10000000000000000)) {
                y := shr(64, y) // Like dividing by 2 ** 64.
                z := shl(32, z) // Like multiplying by 2 ** 32.
            }
            if iszero(lt(y, 0x100000000)) {
                y := shr(32, y) // Like dividing by 2 ** 32.
                z := shl(16, z) // Like multiplying by 2 ** 16.
            }
            if iszero(lt(y, 0x10000)) {
                y := shr(16, y) // Like dividing by 2 ** 16.
                z := shl(8, z) // Like multiplying by 2 ** 8.
            }
            if iszero(lt(y, 0x100)) {
                y := shr(8, y) // Like dividing by 2 ** 8.
                z := shl(4, z) // Like multiplying by 2 ** 4.
            }
            if iszero(lt(y, 0x10)) {
                y := shr(4, y) // Like dividing by 2 ** 4.
                z := shl(2, z) // Like multiplying by 2 ** 2.
            }
            if iszero(lt(y, 0x8)) {
                // Equivalent to 2 ** z.
                z := shl(1, z)
            }

            // Shifting right by 1 is like dividing by 2.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // Compute a rounded down version of z.
            let zRoundDown := div(x, z)

            // If zRoundDown is smaller, use it.
            if lt(zRoundDown, z) {
                z := zRoundDown
            }
        }
    }
}

/// @notice Minimal ERC4626 tokenized Vault implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)
abstract contract ERC4626 is ERC20 {
    using SafeTransferLib for ERC20;
    using FixedPointMathLib for uint256;

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);

    event Withdraw(
        address indexed caller,
        address indexed receiver,
        address indexed owner,
        uint256 assets,
        uint256 shares
    );

    /*//////////////////////////////////////////////////////////////
                               IMMUTABLES
    //////////////////////////////////////////////////////////////*/

    ERC20 public immutable asset;

    constructor(
        ERC20 _asset,
        string memory _name,
        string memory _symbol
    ) ERC20(_name, _symbol, _asset.decimals()) {
        asset = _asset;
    }

    /*//////////////////////////////////////////////////////////////
                        DEPOSIT/WITHDRAWAL LOGIC
    //////////////////////////////////////////////////////////////*/

    function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {
        // Check for rounding error since we round down in previewDeposit.
        require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) {
        assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual returns (uint256 shares) {
        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.

        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public virtual returns (uint256 assets) {
        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        // Check for rounding error since we round down in previewRedeem.
        require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    /*//////////////////////////////////////////////////////////////
                            ACCOUNTING LOGIC
    //////////////////////////////////////////////////////////////*/

    function totalAssets() public view virtual returns (uint256);

    function convertToShares(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());
    }

    function convertToAssets(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
    }

    function previewDeposit(uint256 assets) public view virtual returns (uint256) {
        return convertToShares(assets);
    }

    function previewMint(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
    }

    function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());
    }

    function previewRedeem(uint256 shares) public view virtual returns (uint256) {
        return convertToAssets(shares);
    }

    /*//////////////////////////////////////////////////////////////
                     DEPOSIT/WITHDRAWAL LIMIT LOGIC
    //////////////////////////////////////////////////////////////*/

    function maxDeposit(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxMint(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxWithdraw(address owner) public view virtual returns (uint256) {
        return convertToAssets(balanceOf[owner]);
    }

    function maxRedeem(address owner) public view virtual returns (uint256) {
        return balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                          INTERNAL HOOKS LOGIC
    //////////////////////////////////////////////////////////////*/

    function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}

    function afterDeposit(uint256 assets, uint256 shares) internal virtual {}
}

/**
 * @title IPool
 * @author Aave
 * @notice Defines the basic interface for an Aave Pool.
 *
 */
interface IPool {
    struct ReserveConfigurationMap {
        //bit 0-15: LTV
        //bit 16-31: Liq. threshold
        //bit 32-47: Liq. bonus
        //bit 48-55: Decimals
        //bit 56: reserve is active
        //bit 57: reserve is frozen
        //bit 58: borrowing is enabled
        //bit 59: stable rate borrowing enabled
        //bit 60: asset is paused
        //bit 61: borrowing in isolation mode is enabled
        //bit 62-63: reserved
        //bit 64-79: reserve factor
        //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap
        //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap
        //bit 152-167 liquidation protocol fee
        //bit 168-175 eMode category
        //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
        //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
        //bit 252-255 unused
        uint256 data;
    }

    struct ReserveData {
        ReserveConfigurationMap configuration;
        //the liquidity index. Expressed in ray
        uint128 liquidityIndex;
        //the current supply rate. Expressed in ray
        uint128 currentLiquidityRate;
        //variable borrow index. Expressed in ray
        uint128 variableBorrowIndex;
        //the current variable borrow rate. Expressed in ray
        uint128 currentVariableBorrowRate;
        //the current stable borrow rate. Expressed in ray
        uint128 currentStableBorrowRate;
        //timestamp of last update
        uint40 lastUpdateTimestamp;
        //the id of the reserve. Represents the position in the list of the active reserves
        uint16 id;
        //aToken address
        address aTokenAddress;
        //stableDebtToken address
        address stableDebtTokenAddress;
        //variableDebtToken address
        address variableDebtTokenAddress;
        //address of the interest rate strategy
        address interestRateStrategyAddress;
        //the current treasury balance, scaled
        uint128 accruedToTreasury;
        //the outstanding unbacked aTokens minted through the bridging feature
        uint128 unbacked;
        //the outstanding debt borrowed against this asset in isolation mode
        uint128 isolationModeTotalDebt;
    }

    /**
     * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
     * - E.g. User supplies 100 USDC and gets in return 100 aUSDC
     * @param asset The address of the underlying asset to supply
     * @param amount The amount to be supplied
     * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
     * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
     * is a different wallet
     * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
     * 0 if the action is executed directly by the user, without any middle-man
     *
     */
    function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;

    /**
     * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
     * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
     * @param asset The address of the underlying asset to withdraw
     * @param amount The underlying amount to be withdrawn
     * - Send the value type(uint256).max in order to withdraw the whole aToken balance
     * @param to The address that will receive the underlying, same as msg.sender if the user
     * wants to receive it on his own wallet, or a different address if the beneficiary is a
     * different wallet
     * @return The final amount withdrawn
     *
     */
    function withdraw(address asset, uint256 amount, address to) external returns (uint256);

    /**
     * @notice Returns the state and configuration of the reserve
     * @param asset The address of the underlying asset of the reserve
     * @return The state and configuration data of the reserve
     *
     */
    function getReserveData(address asset) external view returns (ReserveData memory);
}

/**
 * @title IRewardsController
 * @author Aave
 * @notice Defines the basic interface for a Rewards Controller.
 */
interface IRewardsController {
    function getAllUserRewards(address[] calldata assets, address user)
        external
        view
        returns (
            address[] memory rewardsList,
            uint256[] memory unclaimedAmounts
        );

    /**
     * @dev Returns the list of available reward token addresses of an incentivized asset
     * @param asset The incentivized asset
     * @return List of rewards addresses of the input asset
     **/

    function getRewardsByAsset(address asset)
        external
        view
        returns (address[] memory);

    /**
     * @dev Claims all rewards for a user to the desired address, on all the assets of the pool, accumulating the pending rewards
     * @param assets The list of assets to check eligible distributions before claiming rewards
     * @param to The address that will be receiving the rewards
     * @return rewardsList List of addresses of the reward tokens
     * @return claimedAmounts List that contains the claimed amount per reward, following same order as "rewardList"
     *
     */
    function claimAllRewards(address[] calldata assets, address to)
        external
        returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
}

interface IPair {
    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;
}

library DexSwap {
    using SafeTransferLib for ERC20;

    /**
     * @notice Swap directly through a Pair
     * @param amountIn input amount
     * @param fromToken address
     * @param toToken address
     * @param pairToken Pair used for swap
     * @return output amount
     */
    function swap(
        uint256 amountIn,
        address fromToken,
        address toToken,
        address pairToken
    ) internal returns (uint256) {
        IPair pair = IPair(pairToken);
        (address token0, ) = sortTokens(fromToken, toToken);
        (uint112 reserve0, uint112 reserve1, ) = pair.getReserves();
        if (token0 != fromToken) (reserve0, reserve1) = (reserve1, reserve0);
        uint256 amountOut1 = 0;
        uint256 amountOut2 = getAmountOut(amountIn, reserve0, reserve1);
        if (token0 != fromToken)
            (amountOut1, amountOut2) = (amountOut2, amountOut1);
        ERC20(fromToken).safeTransfer(address(pair), amountIn);
        pair.swap(amountOut1, amountOut2, address(this), new bytes(0));
        return amountOut2 > amountOut1 ? amountOut2 : amountOut1;
    }

    /**
     * @notice Given an input amount of an asset and pair reserves, returns maximum output amount of the other asset
     * @dev Assumes swap fee is 0.30%
     * @param amountIn input asset
     * @param reserveIn size of input asset reserve
     * @param reserveOut size of output asset reserve
     * @return maximum output amount
     */
    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256) {
        uint256 amountInWithFee = amountIn * 997;
        uint256 numerator = amountInWithFee * (reserveOut);
        uint256 denominator = (reserveIn * 1000) + (amountInWithFee);
        return numerator / (denominator);
    }

    /**
     * @notice Given two tokens, it'll return the tokens in the right order for the tokens pair
     * @dev TokenA must be different from TokenB, and both shouldn't be address(0), no validations
     * @param tokenA address
     * @param tokenB address
     * @return sorted tokens
     */
    function sortTokens(address tokenA, address tokenB)
        internal
        pure
        returns (address, address)
    {
        return tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    }
}

/// @title AaveV3ERC4626Reinvest - extended implementation of yield-daddy @author zefram.eth
/// @dev Reinvests rewards accrued for higher APY
/// @notice ERC4626 wrapper for Aave V3 with rewards reinvesting
contract AaveV3ERC4626Reinvest is ERC4626 {
    /// @notice Manager for setting swap routes for harvest()
    address public manager;

    /// @notice Check if rewards have been set before harvest() and setRoutes()
    bool public rewardsSet;

    /// -----------------------------------------------------------------------
    /// Libraries usage
    /// -----------------------------------------------------------------------

    using SafeTransferLib for ERC20;

    /// -----------------------------------------------------------------------
    /// Events
    /// -----------------------------------------------------------------------

    event ClaimRewards(uint256 amount);

    /// -----------------------------------------------------------------------
    /// Constants
    /// -----------------------------------------------------------------------

    uint256 internal constant DECIMALS_MASK =
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFF;
    uint256 internal constant ACTIVE_MASK =
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFF;
    uint256 internal constant FROZEN_MASK =
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF;
    uint256 internal constant PAUSED_MASK =
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFF;
    uint256 internal constant SUPPLY_CAP_MASK =
        0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

    uint256 internal constant SUPPLY_CAP_START_BIT_POSITION = 116;
    uint256 internal constant RESERVE_DECIMALS_START_BIT_POSITION = 48;

    /// -----------------------------------------------------------------------
    /// Immutable params
    /// -----------------------------------------------------------------------

    /// @notice The Aave aToken contract
    ERC20 public immutable aToken;

    /// @notice The Aave Pool contract
    IPool public immutable lendingPool;

    /// @notice The Aave RewardsController contract
    IRewardsController public immutable rewardsController;

    /// @notice The Aave reward tokens for a pool
    address[] public rewardTokens;

    /// @notice Map rewardToken to its swapInfo for harvest
    mapping(address => swapInfo) public swapInfoMap;

    /// @notice Pointer to swapInfo
    swapInfo public SwapInfo;

    /// Compact struct to make two swaps (on Uniswap v2)
    /// A => B (using pair1) then B => asset (of Wrapper) (using pair2)
    struct swapInfo {
        address token;
        address pair1;
        address pair2;
    }

    /// -----------------------------------------------------------------------
    /// Constructor
    /// -----------------------------------------------------------------------

    constructor(
        ERC20 asset_,
        ERC20 aToken_,
        IPool lendingPool_,
        IRewardsController rewardsController_,
        address manager_
    ) ERC4626(asset_, _vaultName(asset_), _vaultSymbol(asset_)) {
        aToken = aToken_;
        lendingPool = lendingPool_;
        rewardsController = rewardsController_;

        /// For all SuperForm AAVE wrappers Factory contract is the manager for the Routes
        manager = manager_;

        /// TODO: tighter checks
        rewardsSet = false;
    }

    /// -----------------------------------------------------------------------
    /// Aave liquidity mining
    /// -----------------------------------------------------------------------

    /// @notice Get all rewards from AAVE market
    /// @dev Call before setting routes
    /// @dev Requires manual management of Routes
    function setRewards() external returns (address[] memory tokens) {
        require(msg.sender == manager, "onlyOwner");
        tokens = rewardsController.getRewardsByAsset(address(aToken));

        for (uint256 i = 0; i < tokens.length; i++) {
            rewardTokens.push(tokens[i]);
        }

        rewardsSet = true;
    }

    /// @notice Set swap routes for selling rewards
    /// @dev Set route for each rewardToken separately
    /// @dev Setting wrong addresses here will revert harvest() calls
    function setRoutes(
        address rewardToken,
        address token,
        address pair1,
        address pair2
    ) external {
        require(msg.sender == manager, "onlyOwner");
        require(rewardsSet, "rewards not set"); /// @dev Soft-check

        for (uint256 i = 0; i < rewardTokens.length; i++) {
            /// @dev if rewardToken given as arg matches any rewardToken found by setRewards()
            ///      set route for that token
            if (rewardTokens[i] == rewardToken) {
                swapInfoMap[rewardToken] = swapInfo(token, pair1, pair2);
            }
        }
    }

    /// @notice Claims liquidity mining rewards from Aave and sends it to this Vault
    function harvest() external {
        /// @dev Wrapper exists only for single aToken
        address[] memory assets = new address[](1);
        assets[0] = address(aToken);

        /// @dev trusting aave
        (
            address[] memory rewardList,
            uint256[] memory claimedAmounts
        ) = rewardsController.claimAllRewards(assets, address(this));

        /// @dev if pool rewards more than one token
        /// TODO: Better control. Give ability to select what rewards to swap
        for (uint256 i = 0; i < claimedAmounts.length; i++) {
            swapRewards(rewardList[i], claimedAmounts[i]);
        }
    }

    /// @notice Swap reward token for underlying asset
    function swapRewards(address rewardToken, uint256 earned) internal {
        /// @dev Used just for approve
        ERC20 rewardToken_ = ERC20(rewardToken);

        swapInfo memory swapMap = swapInfoMap[rewardToken];

        /// @dev Swap AAVE-Fork token for asset
        if (swapMap.token == address(asset)) {
            rewardToken_.approve(swapMap.pair1, earned); /// approve only available rewards

            DexSwap.swap(
                earned, /// REWARDS amount to swap
                rewardToken, // from REWARD-TOKEN
                address(asset), /// to target underlying of this Vault
                swapMap.pair1 /// pairToken (pool)
            );
            /// If two swaps needed
        } else {
            rewardToken_.approve(swapMap.pair1, earned); /// approve only available rewards

            uint256 swapTokenAmount = DexSwap.swap(
                earned,
                rewardToken, // from AAVE-Fork
                swapMap.token, /// to intermediary token with high liquidity (no direct pools)
                swapMap.pair1 /// pairToken (pool)
            );

            ERC20(swapMap.token).approve(swapMap.pair2, swapTokenAmount);

            swapTokenAmount = DexSwap.swap(
                swapTokenAmount,
                swapMap.token, // from received token
                address(asset), /// to target underlying of this Vault
                swapMap.pair2 /// pairToken (pool)
            );
        }

        /// reinvest() without minting (no asset.totalSupply() increase == profit)
        afterDeposit(asset.balanceOf(address(this)), 0);
    }

    /// @notice Check how much rewards are available to claim, useful before harvest()
    function getAllRewardsAccrued()
        external
        view
        returns (address[] memory rewardList, uint256[] memory claimedAmounts)
    {
        address[] memory assets = new address[](1);
        assets[0] = address(aToken);

        (rewardList, claimedAmounts) = rewardsController.getAllUserRewards(
            assets,
            address(this)
        );
    }

    /// -----------------------------------------------------------------------
    /// ERC4626 overrides
    /// -----------------------------------------------------------------------

    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual override returns (uint256 shares) {
        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.

        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) {
                allowance[owner][msg.sender] = allowed - shares;
            }
        }

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        // withdraw assets directly from Aave
        lendingPool.withdraw(address(asset), assets, receiver);
    }

    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public virtual override returns (uint256 assets) {
        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) {
                allowance[owner][msg.sender] = allowed - shares;
            }
        }

        // Check for rounding error since we round down in previewRedeem.
        require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        // withdraw assets directly from Aave
        lendingPool.withdraw(address(asset), assets, receiver);
    }

    function totalAssets() public view virtual override returns (uint256) {
        // aTokens use rebasing to accrue interest, so the total assets is just the aToken balance
        return aToken.balanceOf(address(this));
    }

    function afterDeposit(
        uint256 assets,
        uint256 /*shares*/
    ) internal virtual override {
        /// -----------------------------------------------------------------------
        /// Deposit assets into Aave
        /// -----------------------------------------------------------------------

        // approve to lendingPool
        // TODO: Approve management arc. Save gas for callers
        asset.safeApprove(address(lendingPool), assets);

        // deposit into lendingPool
        lendingPool.supply(address(asset), assets, address(this), 0);
    }

    function maxDeposit(address)
        public
        view
        virtual
        override
        returns (uint256)
    {
        // check if asset is paused
        uint256 configData = lendingPool
            .getReserveData(address(asset))
            .configuration
            .data;
        if (
            !(_getActive(configData) &&
                !_getFrozen(configData) &&
                !_getPaused(configData))
        ) {
            return 0;
        }

        // handle supply cap
        uint256 supplyCapInWholeTokens = _getSupplyCap(configData);
        if (supplyCapInWholeTokens == 0) {
            return type(uint256).max;
        }

        uint8 tokenDecimals = _getDecimals(configData);
        uint256 supplyCap = supplyCapInWholeTokens * 10**tokenDecimals;
        return supplyCap - aToken.totalSupply();
    }

    function maxMint(address) public view virtual override returns (uint256) {
        // check if asset is paused
        uint256 configData = lendingPool
            .getReserveData(address(asset))
            .configuration
            .data;
        if (
            !(_getActive(configData) &&
                !_getFrozen(configData) &&
                !_getPaused(configData))
        ) {
            return 0;
        }

        // handle supply cap
        uint256 supplyCapInWholeTokens = _getSupplyCap(configData);
        if (supplyCapInWholeTokens == 0) {
            return type(uint256).max;
        }

        uint8 tokenDecimals = _getDecimals(configData);
        uint256 supplyCap = supplyCapInWholeTokens * 10**tokenDecimals;
        return convertToShares(supplyCap - aToken.totalSupply());
    }

    function maxWithdraw(address owner)
        public
        view
        virtual
        override
        returns (uint256)
    {
        // check if asset is paused
        uint256 configData = lendingPool
            .getReserveData(address(asset))
            .configuration
            .data;
        if (!(_getActive(configData) && !_getPaused(configData))) {
            return 0;
        }

        uint256 cash = asset.balanceOf(address(aToken));
        uint256 assetsBalance = convertToAssets(balanceOf[owner]);
        return cash < assetsBalance ? cash : assetsBalance;
    }

    function maxRedeem(address owner)
        public
        view
        virtual
        override
        returns (uint256)
    {
        // check if asset is paused
        uint256 configData = lendingPool
            .getReserveData(address(asset))
            .configuration
            .data;
        if (!(_getActive(configData) && !_getPaused(configData))) {
            return 0;
        }

        uint256 cash = asset.balanceOf(address(aToken));
        uint256 cashInShares = convertToShares(cash);
        uint256 shareBalance = balanceOf[owner];
        return cashInShares < shareBalance ? cashInShares : shareBalance;
    }

    /// -----------------------------------------------------------------------
    /// ERC20 metadata generation
    /// -----------------------------------------------------------------------

    function _vaultName(ERC20 asset_)
        internal
        view
        virtual
        returns (string memory vaultName)
    {
        vaultName = string.concat("ERC4626-Wrapped Aave v3 ", asset_.symbol());
    }

    function _vaultSymbol(ERC20 asset_)
        internal
        view
        virtual
        returns (string memory vaultSymbol)
    {
        vaultSymbol = string.concat("wa", asset_.symbol());
    }

    /// -----------------------------------------------------------------------
    /// Internal functions
    /// -----------------------------------------------------------------------

    function _getDecimals(uint256 configData) internal pure returns (uint8) {
        return
            uint8(
                (configData & ~DECIMALS_MASK) >>
                    RESERVE_DECIMALS_START_BIT_POSITION
            );
    }

    function _getActive(uint256 configData) internal pure returns (bool) {
        return configData & ~ACTIVE_MASK != 0;
    }

    function _getFrozen(uint256 configData) internal pure returns (bool) {
        return configData & ~FROZEN_MASK != 0;
    }

    function _getPaused(uint256 configData) internal pure returns (bool) {
        return configData & ~PAUSED_MASK != 0;
    }

    function _getSupplyCap(uint256 configData) internal pure returns (uint256) {
        return (configData & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract ERC20","name":"asset_","type":"address"},{"internalType":"contract ERC20","name":"aToken_","type":"address"},{"internalType":"contract IPool","name":"lendingPool_","type":"address"},{"internalType":"contract IRewardsController","name":"rewardsController_","type":"address"},{"internalType":"address","name":"manager_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SwapInfo","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"pair1","type":"address"},{"internalType":"address","name":"pair2","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aToken","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllRewardsAccrued","outputs":[{"internalType":"address[]","name":"rewardList","type":"address[]"},{"internalType":"uint256[]","name":"claimedAmounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lendingPool","outputs":[{"internalType":"contract IPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsController","outputs":[{"internalType":"contract IRewardsController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setRewards","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"rewardToken","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"pair1","type":"address"},{"internalType":"address","name":"pair2","type":"address"}],"name":"setRoutes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"swapInfoMap","outputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"pair1","type":"address"},{"internalType":"address","name":"pair2","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102485760003560e01c806370a082311161013b578063ba087652116100b8578063cfa8586d1161007c578063cfa8586d146105e4578063d505accf146105f8578063d905777e1461060b578063dd62ed3e1461061e578063ef8b30f71461064957600080fd5b8063ba0876521461055c578063c63d75b61461056f578063c6e6f59214610582578063ce96cb7714610595578063cf638944146105a857600080fd5b8063a0c1f15e116100ff578063a0c1f15e146104d5578063a59a9973146104fc578063a9059cbb14610523578063b3d7f6b914610536578063b460af941461054957600080fd5b806370a08231146104675780637bb7bed1146104875780637ecebe001461049a57806394bf804d146104ba57806395d89b41146104cd57600080fd5b80633644e515116101c95780634cdad5061161018d5780634cdad506146103bb57806353104b8e146103ce57806368ab8f97146104185780636bb65f531461042d5780636e553f651461045457600080fd5b80633644e5151461034657806338d52e0f1461034e578063402d267d1461038d5780634641257d146103a0578063481c6a75146103a857600080fd5b80630a28a477116102105780630a28a477146102c857806316dc94f0146102db57806318160ddd146102f157806323b872dd146102fa578063313ce5671461030d57600080fd5b806301e1d1141461024d578063041849291461026857806306fdde031461027d57806307a2d13a14610292578063095ea7b3146102a5575b600080fd5b61025561065c565b6040519081526020015b60405180910390f35b61027b6102763660046126ba565b6106ec565b005b610285610858565b60405161025f9190612763565b6102556102a0366004612776565b6108e6565b6102b86102b336600461278f565b610913565b604051901515815260200161025f565b6102556102d6366004612776565b610980565b6102e36109a0565b60405161025f9291906127ff565b61025560025481565b6102b8610308366004612856565b610aa8565b6103347f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161025f565b610255610b88565b6103757f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a381565b6040516001600160a01b03909116815260200161025f565b61025561039b366004612897565b610bde565b61027b610d9f565b600654610375906001600160a01b031681565b6102556103c9366004612776565b610f03565b600954600a54600b546103ee926001600160a01b03908116928116911683565b604080516001600160a01b039485168152928416602084015292169181019190915260600161025f565b610420610f0e565b60405161025f91906128b4565b6103757f000000000000000000000000929ec64c34a17401f460460d4b9390518e5b473e81565b6102556104623660046128c7565b61108b565b610255610475366004612897565b60036020526000908152604090205481565b610375610495366004612776565b611165565b6102556104a8366004612897565b60056020526000908152604090205481565b6102556104c83660046128c7565b61118f565b61028561122b565b6103757f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a069281565b6103757f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad81565b6102b861053136600461278f565b611238565b610255610544366004612776565b61129e565b6102556105573660046128f7565b6112bd565b61025561056a3660046128f7565b611451565b61025561057d366004612897565b6115dc565b610255610590366004612776565b611796565b6102556105a3366004612897565b6117b6565b6103ee6105b6366004612897565b6008602052600090815260409020805460018201546002909201546001600160a01b03918216928216911683565b6006546102b890600160a01b900460ff1681565b61027b610606366004612939565b61197f565b610255610619366004612897565b611bc3565b61025561062c3660046129b0565b600460209081526000928352604080842090915290825290205481565b610255610657366004612776565b611d8b565b6040516370a0823160e01b81523060048201526000907f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a06926001600160a01b0316906370a0823190602401602060405180830381865afa1580156106c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e791906129de565b905090565b6006546001600160a01b031633146107375760405162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b60448201526064015b60405180910390fd5b600654600160a01b900460ff166107825760405162461bcd60e51b815260206004820152600f60248201526e1c995dd85c991cc81b9bdd081cd95d608a1b604482015260640161072e565b60005b60075481101561085157846001600160a01b0316600782815481106107ac576107ac6129f7565b6000918252602090912001546001600160a01b03160361083f57604080516060810182526001600160a01b03868116825285811660208084019182528683168486019081528a841660009081526008909252949020925183546001600160a01b03199081169184169190911784559051600184018054831691841691909117905592516002909201805490931691161790555b8061084981612a23565b915050610785565b5050505050565b6000805461086590612a3c565b80601f016020809104026020016040519081016040528092919081815260200182805461089190612a3c565b80156108de5780601f106108b3576101008083540402835291602001916108de565b820191906000526020600020905b8154815290600101906020018083116108c157829003601f168201915b505050505081565b600254600090801561090a576109056108fd61065c565b849083611d96565b61090c565b825b9392505050565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061096e9086815260200190565b60405180910390a35060015b92915050565b600254600090801561090a576109058161099861065c565b859190611db5565b6040805160018082528183019092526060918291600091602080830190803683370190505090507f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a0692816000815181106109fb576109fb6129f7565b6001600160a01b039283166020918202929092010152604051634c0369c360e01b81527f000000000000000000000000929ec64c34a17401f460460d4b9390518e5b473e90911690634c0369c390610a599084903090600401612a8c565b600060405180830381865afa158015610a76573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a9e9190810190612bb9565b9094909350915050565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610b0457610adf8382612c74565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610b2c908490612c74565b90915550506001600160a01b038085166000818152600360205260409081902080548701905551909187169060008051602061310783398151915290610b759087815260200190565b60405180910390a3506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000894614610bb9576106e7611de3565b507fb5b475fa25341e278031a1e5ccd8ccbb34df7b8e4a48fa428555523d5a33b51990565b6040516335ea6a7560e01b81526001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a38116600483015260009182917f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad16906335ea6a75906024016101e060405180830381865afa158015610c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8e9190612d14565b51519050600160381b811615158015610cab5750600160391b8116155b8015610cbb57506001603c1b8116155b610cc85750600092915050565b640fffffffff607482901c166000819003610ce857506000199392505050565b60ff603083901c166000610cfd82600a612f1b565b610d079084612f2a565b90507f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a06926001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d8b91906129de565b610d959082612c74565b9695505050505050565b604080516001808252818301909252600091602080830190803683370190505090507f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a069281600081518110610df557610df56129f7565b6001600160a01b03928316602091820292909201015260405163bb492bf560e01b815260009182917f000000000000000000000000929ec64c34a17401f460460d4b9390518e5b473e9091169063bb492bf590610e589086903090600401612a8c565b6000604051808303816000875af1158015610e77573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e9f9190810190612bb9565b9150915060005b8151811015610efd57610eeb838281518110610ec457610ec46129f7565b6020026020010151838381518110610ede57610ede6129f7565b6020026020010151611e7d565b80610ef581612a23565b915050610ea6565b50505050565b600061097a826108e6565b6006546060906001600160a01b03163314610f575760405162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015260640161072e565b604051636657732f60e01b81526001600160a01b037f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a0692811660048301527f000000000000000000000000929ec64c34a17401f460460d4b9390518e5b473e1690636657732f90602401600060405180830381865afa158015610fdd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110059190810190612f49565b905060005b8151811015611074576007828281518110611027576110276129f7565b60209081029190910181015182546001810184556000938452919092200180546001600160a01b0319166001600160a01b039092169190911790558061106c81612a23565b91505061100a565b506006805460ff60a01b1916600160a01b17905590565b600061109683611d8b565b9050806000036110d65760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b604482015260640161072e565b61110b6001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a316333086612177565b61111582826121fa565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a361097a8382612254565b6007818154811061117557600080fd5b6000918252602090912001546001600160a01b0316905081565b600061119a8361129e565b90506111d16001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a316333084612177565b6111db82846121fa565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a361097a8184612254565b6001805461086590612a3c565b33600090815260036020526040812080548391908390611259908490612c74565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133906000805160206131078339815191529061096e9086815260200190565b600254600090801561090a576109056112b561065c565b849083611db5565b60006112c884610980565b9050336001600160a01b03831614611338576001600160a01b03821660009081526004602090815260408083203384529091529020546000198114611336576113118282612c74565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b611342828261235b565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4604051631a4ca37b60e21b81526001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3811660048301526024820186905284811660448301527f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad16906369328dec906064015b6020604051808303816000875af1158015611425573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061144991906129de565b509392505050565b6000336001600160a01b038316146114c1576001600160a01b038216600090815260046020908152604080832033845290915290205460001981146114bf5761149a8582612c74565b6001600160a01b03841660009081526004602090815260408083203384529091529020555b505b6114ca84610f03565b90508060000361150a5760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b604482015260640161072e565b611514828561235b565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4604051631a4ca37b60e21b81526001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3811660048301526024820183905284811660448301527f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad16906369328dec90606401611406565b6040516335ea6a7560e01b81526001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a38116600483015260009182917f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad16906335ea6a75906024016101e060405180830381865afa158015611668573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168c9190612d14565b51519050600160381b8116151580156116a95750600160391b8116155b80156116b957506001603c1b8116155b6116c65750600092915050565b640fffffffff607482901c1660008190036116e657506000199392505050565b60ff603083901c1660006116fb82600a612f1b565b6117059084612f2a565b9050610d957f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a06926001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061178c91906129de565b6105909083612c74565b600254600090801561090a57610905816117ae61065c565b859190611d96565b6040516335ea6a7560e01b81526001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a38116600483015260009182917f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad16906335ea6a75906024016101e060405180830381865afa158015611842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118669190612d14565b51519050600160381b81161515801561188357506001603c1b8116155b6118905750600092915050565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a0692811660048301526000917f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3909116906370a0823190602401602060405180830381865afa15801561191b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193f91906129de565b6001600160a01b03851660009081526003602052604081205491925090611965906108e6565b90508082106119745780611976565b815b95945050505050565b428410156119cf5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f45585049524544000000000000000000604482015260640161072e565b600060016119db610b88565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611ae7573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590611b1d5750876001600160a01b0316816001600160a01b0316145b611b5a5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b604482015260640161072e565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6040516335ea6a7560e01b81526001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a38116600483015260009182917f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad16906335ea6a75906024016101e060405180830381865afa158015611c4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c739190612d14565b51519050600160381b811615158015611c9057506001603c1b8116155b611c9d5750600092915050565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000008ffdf2de812095b1d19cb146e4c004587c0a0692811660048301526000917f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3909116906370a0823190602401602060405180830381865afa158015611d28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d4c91906129de565b90506000611d5982611796565b6001600160a01b038616600090815260036020526040902054909150808210611d825780610d95565b50949350505050565b600061097a82611796565b828202811515841585830485141716611dae57600080fd5b0492915050565b828202811515841585830485141716611dcd57600080fd5b6001826001830304018115150290509392505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051611e159190612f86565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6001600160a01b03808316600090815260086020908152604091829020825160608101845281548516808252600183015486169382019390935260029091015484169281019290925284927f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3169003611fa057602081015160405163095ea7b360e01b81526001600160a01b039182166004820152602481018590529083169063095ea7b3906044016020604051808303816000875af1158015611f45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f699190613021565b50611f9a83857f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a384602001516123bd565b506120e4565b602081015160405163095ea7b360e01b81526001600160a01b039182166004820152602481018590529083169063095ea7b3906044016020604051808303816000875af1158015611ff5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120199190613021565b5060006120308486846000015185602001516123bd565b8251604080850151905163095ea7b360e01b81526001600160a01b03918216600482015260248101849052929350169063095ea7b3906044016020604051808303816000875af1158015612088573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120ac9190613021565b506120e18183600001517f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a385604001516123bd565b50505b6040516370a0823160e01b8152306004820152610efd907f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a36001600160a01b0316906370a0823190602401602060405180830381865afa15801561214c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061217091906129de565b6000612254565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806108515760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b604482015260640161072e565b806002600082825461220c9190613043565b90915550506001600160a01b03821660008181526003602090815260408083208054860190555184815260008051602061310783398151915291015b60405180910390a35050565b6122a86001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a3167f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad84612533565b60405163617ba03760e01b81526001600160a01b037f0000000000000000000000009a71012b13ca4d3d0cdc72a177df3ef03b0e76a38116600483015260248201849052306044830152600060648301527f000000000000000000000000794a61358d6845594f94dc1db02a252b5b4814ad169063617ba03790608401600060405180830381600087803b15801561233f57600080fd5b505af1158015612353573d6000803e3d6000fd5b505050505050565b6001600160a01b03821660009081526003602052604081208054839290612383908490612c74565b90915550506002805482900390556040518181526000906001600160a01b0384169060008051602061310783398151915290602001612248565b600081816123cb86866125aa565b509050600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561240f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124339190613072565b5091509150876001600160a01b0316836001600160a01b03161461245357905b6000806124738b856001600160701b0316856001600160701b03166125db565b9050896001600160a01b0316856001600160a01b03161461249057905b6124a46001600160a01b038b16878d61262a565b6040805160008152602081019182905263022c0d9f60e01b9091526001600160a01b0387169063022c0d9f906124e390859085903090602481016130b7565b600060405180830381600087803b1580156124fd57600080fd5b505af1158015612511573d6000803e3d6000fd5b505050508181116125225781612524565b805b9b9a5050505050505050505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610efd5760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b604482015260640161072e565b600080826001600160a01b0316846001600160a01b0316106125cd5782846125d0565b83835b915091509250929050565b6000806125ea856103e5612f2a565b905060006125f88483612f2a565b9050600082612609876103e8612f2a565b6126139190613043565b905061261f81836130e4565b979650505050505050565b600060405163a9059cbb60e01b8152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080610efd5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b604482015260640161072e565b6001600160a01b03811681146126b757600080fd5b50565b600080600080608085870312156126d057600080fd5b84356126db816126a2565b935060208501356126eb816126a2565b925060408501356126fb816126a2565b9150606085013561270b816126a2565b939692955090935050565b6000815180845260005b8181101561273c57602081850181015186830182015201612720565b8181111561274e576000602083870101525b50601f01601f19169290920160200192915050565b60208152600061090c6020830184612716565b60006020828403121561278857600080fd5b5035919050565b600080604083850312156127a257600080fd5b82356127ad816126a2565b946020939093013593505050565b600081518084526020808501945080840160005b838110156127f45781516001600160a01b0316875295820195908201906001016127cf565b509495945050505050565b60408152600061281260408301856127bb565b82810360208481019190915284518083528582019282019060005b818110156128495784518352938301939183019160010161282d565b5090979650505050505050565b60008060006060848603121561286b57600080fd5b8335612876816126a2565b92506020840135612886816126a2565b929592945050506040919091013590565b6000602082840312156128a957600080fd5b813561090c816126a2565b60208152600061090c60208301846127bb565b600080604083850312156128da57600080fd5b8235915060208301356128ec816126a2565b809150509250929050565b60008060006060848603121561290c57600080fd5b83359250602084013561291e816126a2565b9150604084013561292e816126a2565b809150509250925092565b600080600080600080600060e0888a03121561295457600080fd5b873561295f816126a2565b9650602088013561296f816126a2565b95506040880135945060608801359350608088013560ff8116811461299357600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156129c357600080fd5b82356129ce816126a2565b915060208301356128ec816126a2565b6000602082840312156129f057600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201612a3557612a35612a0d565b5060010190565b600181811c90821680612a5057607f821691505b602082108103612a7057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b604081526000612a9f60408301856127bb565b905060018060a01b03831660208301529392505050565b6040516101e0810167ffffffffffffffff81118282101715612ada57612ada612a76565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612b0957612b09612a76565b604052919050565b600067ffffffffffffffff821115612b2b57612b2b612a76565b5060051b60200190565b8051612b40816126a2565b919050565b600082601f830112612b5657600080fd5b81516020612b6b612b6683612b11565b612ae0565b82815260059290921b84018101918181019086841115612b8a57600080fd5b8286015b84811015612bae578051612ba1816126a2565b8352918301918301612b8e565b509695505050505050565b60008060408385031215612bcc57600080fd5b825167ffffffffffffffff80821115612be457600080fd5b612bf086838701612b45565b9350602091508185015181811115612c0757600080fd5b85019050601f81018613612c1a57600080fd5b8051612c28612b6682612b11565b81815260059190911b82018301908381019088831115612c4757600080fd5b928401925b82841015612c6557835182529284019290840190612c4c565b80955050505050509250929050565b600082821015612c8657612c86612a0d565b500390565b600060208284031215612c9d57600080fd5b6040516020810181811067ffffffffffffffff82111715612cc057612cc0612a76565b6040529151825250919050565b80516fffffffffffffffffffffffffffffffff81168114612b4057600080fd5b805164ffffffffff81168114612b4057600080fd5b805161ffff81168114612b4057600080fd5b60006101e08284031215612d2757600080fd5b612d2f612ab6565b612d398484612c8b565b8152612d4760208401612ccd565b6020820152612d5860408401612ccd565b6040820152612d6960608401612ccd565b6060820152612d7a60808401612ccd565b6080820152612d8b60a08401612ccd565b60a0820152612d9c60c08401612ced565b60c0820152612dad60e08401612d02565b60e0820152610100612dc0818501612b35565b90820152610120612dd2848201612b35565b90820152610140612de4848201612b35565b90820152610160612df6848201612b35565b90820152610180612e08848201612ccd565b908201526101a0612e1a848201612ccd565b908201526101c0612e2c848201612ccd565b908201529392505050565b600181815b80851115612e72578160001904821115612e5857612e58612a0d565b80851615612e6557918102915b93841c9390800290612e3c565b509250929050565b600082612e895750600161097a565b81612e965750600061097a565b8160018114612eac5760028114612eb657612ed2565b600191505061097a565b60ff841115612ec757612ec7612a0d565b50506001821b61097a565b5060208310610133831016604e8410600b8410161715612ef5575081810a61097a565b612eff8383612e37565b8060001904821115612f1357612f13612a0d565b029392505050565b600061090c60ff841683612e7a565b6000816000190483118215151615612f4457612f44612a0d565b500290565b600060208284031215612f5b57600080fd5b815167ffffffffffffffff811115612f7257600080fd5b612f7e84828501612b45565b949350505050565b600080835481600182811c915080831680612fa257607f831692505b60208084108203612fc157634e487b7160e01b86526022600452602486fd5b818015612fd55760018114612fe657613013565b60ff19861689528489019650613013565b60008a81526020902060005b8681101561300b5781548b820152908501908301612ff2565b505084890196505b509498975050505050505050565b60006020828403121561303357600080fd5b8151801515811461090c57600080fd5b6000821982111561305657613056612a0d565b500190565b80516001600160701b0381168114612b4057600080fd5b60008060006060848603121561308757600080fd5b6130908461305b565b925061309e6020850161305b565b9150604084015163ffffffff8116811461292e57600080fd5b84815283602082015260018060a01b0383166040820152608060608201526000610d956080830184612716565b60008261310157634e487b7160e01b600052601260045260246000fd5b50049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c60e924a21d53dda6a8fc4e656afbe290f301b317f088b2260e69bb5aa45c18f64736f6c634300080e0033

Deployed Bytecode Sourcemap

36093:15129:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45744:227;;;:::i;:::-;;;160:25:1;;;148:2;133:18;45744:227:0;;;;;;;;40318:626;;;;;;:::i;:::-;;:::i;:::-;;1043:18;;;:::i;:::-;;;;;;;:::i;25147:261::-;;;;;;:::i;:::-;;:::i;2520:217::-;;;;;;:::i;:::-;;:::i;:::-;;;2380:14:1;;2373:22;2355:41;;2343:2;2328:18;2520:217:0;2215:187:1;25814:259:0;;;;;;:::i;:::-;;:::i;43493:387::-;;;:::i;:::-;;;;;;;;:::i;1326:26::-;;;;;;3138:612;;;;;;:::i;:::-;;:::i;1099:31::-;;;;;;;;4315:4:1;4303:17;;;4285:36;;4273:2;4258:18;1099:31:0;4143:184:1;5480:179:0;;;:::i;21735:28::-;;;;;;;;-1:-1:-1;;;;;4691:32:1;;;4673:51;;4661:2;4646:18;21735:28:0;4514:216:1;46580:871:0;;;;;;:::i;:::-;;:::i;41038:655::-;;;:::i;36205:22::-;;;;;-1:-1:-1;;;;;36205:22:0;;;26081:126;;;;;;:::i;:::-;;:::i;38455:24::-;;;;;;;;;-1:-1:-1;;;;;38455:24:0;;;;;;;;;;;;;;-1:-1:-1;;;;;5453:15:1;;;5435:34;;5505:15;;;5500:2;5485:18;;5478:43;5557:15;;5537:18;;;5530:43;;;;5385:2;5370:18;38455:24:0;5195:384:1;39790:340:0;;;:::i;:::-;;;;;;;:::i;38150:53::-;;;;;22150:528;;;;;;:::i;:::-;;:::i;1361:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;38263:29;;;;;;:::i;:::-;;:::i;1787:41::-;;;;;;:::i;:::-;;;;;;;;;;;;;;22686:478;;;;;;:::i;:::-;;:::i;1070:20::-;;;:::i;37976:29::-;;;;;38054:34;;;;;2745:385;;;;;;:::i;:::-;;:::i;25551:255::-;;;;;;:::i;:::-;;:::i;44079:807::-;;;;;;:::i;:::-;;:::i;44894:842::-;;;;;;:::i;:::-;;:::i;47459:835::-;;;;;;:::i;:::-;;:::i;24878:261::-;;;;;;:::i;:::-;;:::i;48302:605::-;;;;;;:::i;:::-;;:::i;38362:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38362:47:0;;;;;;;;;;36317:22;;;;;-1:-1:-1;;;36317:22:0;;;;;;3945:1527;;;;;;:::i;:::-;;:::i;48915:654::-;;;;;;:::i;:::-;;:::i;1414:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;25416:127;;;;;;:::i;:::-;;:::i;45744:227::-;45932:31;;-1:-1:-1;;;45932:31:0;;45957:4;45932:31;;;4673:51:1;45805:7:0;;45932:6;-1:-1:-1;;;;;45932:16:0;;;;4646:18:1;;45932:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45925:38;;45744:227;:::o;40318:626::-;40488:7;;-1:-1:-1;;;;;40488:7:0;40474:10;:21;40466:43;;;;-1:-1:-1;;;40466:43:0;;8706:2:1;40466:43:0;;;8688:21:1;8745:1;8725:18;;;8718:29;-1:-1:-1;;;8763:18:1;;;8756:39;8812:18;;40466:43:0;;;;;;;;;40528:10;;-1:-1:-1;;;40528:10:0;;;;40520:38;;;;-1:-1:-1;;;40520:38:0;;9043:2:1;40520:38:0;;;9025:21:1;9082:2;9062:18;;;9055:30;-1:-1:-1;;;9101:18:1;;;9094:45;9156:18;;40520:38:0;8841:339:1;40520:38:0;40596:9;40591:346;40615:12;:19;40611:23;;40591:346;;;40822:11;-1:-1:-1;;;;;40803:30:0;:12;40816:1;40803:15;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;40803:15:0;:30;40799:127;;40881:29;;;;;;;;-1:-1:-1;;;;;40881:29:0;;;;;;;;;;;;;;;;;;;;;;;;40854:24;;;-1:-1:-1;40854:24:0;;;:11;:24;;;;;;:56;;;;-1:-1:-1;;;;;;40854:56:0;;;;;;;;;;;;;;-1:-1:-1;40854:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40799:127;40636:3;;;;:::i;:::-;;;;40591:346;;;;40318:626;;;;:::o;1043:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;25147:261::-;25254:11;;25217:7;;25337:11;;:63;;25360:40;25378:13;:11;:13::i;:::-;25360:6;;25393;25360:17;:40::i;:::-;25337:63;;;25351:6;25337:63;25330:70;25147:261;-1:-1:-1;;;25147:261:0:o;2520:217::-;2621:10;2594:4;2611:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;2611:30:0;;;;;;;;;;:39;;;2668:37;2594:4;;2611:30;;2668:37;;;;2644:6;160:25:1;;148:2;133:18;;14:177;2668:37:0;;;;;;;;-1:-1:-1;2725:4:0;2520:217;;;;;:::o;25814:259::-;25921:11;;25884:7;;26004:11;;:61;;26027:38;26043:6;26051:13;:11;:13::i;:::-;26027:6;;:38;:15;:38::i;43493:387::-;43679:16;;;43693:1;43679:16;;;;;;;;;43575:27;;;;43653:23;;43679:16;;;;;;;;;;;-1:-1:-1;43679:16:0;43653:42;;43726:6;43706;43713:1;43706:9;;;;;;;;:::i;:::-;-1:-1:-1;;;;;43706:27:0;;;:9;;;;;;;;;:27;43777:95;;-1:-1:-1;;;43777:95:0;;:17;:35;;;;;;:95;;43827:6;;43856:4;;43777:95;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43777:95:0;;;;;;;;;;;;:::i;:::-;43746:126;;;;-1:-1:-1;43493:387:0;-1:-1:-1;;43493:387:0:o;3138:612::-;-1:-1:-1;;;;;3295:15:0;;3260:4;3295:15;;;:9;:15;;;;;;;;3311:10;3295:27;;;;;;;;-1:-1:-1;;3375:28:0;;3371:80;;3435:16;3445:6;3435:7;:16;:::i;:::-;-1:-1:-1;;;;;3405:15:0;;;;;;:9;:15;;;;;;;;3421:10;3405:27;;;;;;;:46;3371:80;-1:-1:-1;;;;;3464:15:0;;;;;;:9;:15;;;;;:25;;3483:6;;3464:15;:25;;3483:6;;3464:25;:::i;:::-;;;;-1:-1:-1;;;;;;;3640:13:0;;;;;;;:9;:13;;;;;;;:23;;;;;;3692:26;3640:13;;3692:26;;;-1:-1:-1;;;;;;;;;;;3692:26:0;;;3657:6;160:25:1;;148:2;133:18;;14:177;3692:26:0;;;;;;;;-1:-1:-1;3738:4:0;;3138:612;-1:-1:-1;;;;3138:612:0:o;5480:179::-;5537:7;5581:16;5564:13;:33;:87;;5627:24;:22;:24::i;5564:87::-;-1:-1:-1;5600:24:0;;5480:179::o;46580:871::-;46775:56;;-1:-1:-1;;;46775:56:0;;-1:-1:-1;;;;;46824:5:0;4691:32:1;;46775:56:0;;;4673:51:1;-1:-1:-1;;;;46775:11:0;:40;;;;4646:18:1;;46775:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;:103;;-1:-1:-1;;;;50742:25:0;;:30;;46909:66;;;;-1:-1:-1;;;;50875:25:0;;:30;46909:66;:110;;;;-1:-1:-1;;;;51008:25:0;;:30;46909:110;46889:178;;-1:-1:-1;47054:1:0;;46580:871;-1:-1:-1;;46580:871:0:o;46889:178::-;51147:64;37659:3;51147:64;;;;47109:30;47182:27;;;47178:84;;-1:-1:-1;;;47233:17:0;46580:871;-1:-1:-1;;;46580:871:0:o;47178:84::-;50535:89;37733:2;50535:89;;;;47274:19;47376:17;50535:89;47376:2;:17;:::i;:::-;47351:42;;:22;:42;:::i;:::-;47331:62;;47423:6;-1:-1:-1;;;;;47423:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47411:32;;:9;:32;:::i;:::-;47404:39;46580:871;-1:-1:-1;;;;;;46580:871:0:o;41038:655::-;41159:16;;;41173:1;41159:16;;;;;;;;;41133:23;;41159:16;;;;;;;;;;;-1:-1:-1;41159:16:0;41133:42;;41206:6;41186;41193:1;41186:9;;;;;;;;:::i;:::-;-1:-1:-1;;;;;41186:27:0;;;:9;;;;;;;;;:27;41360:56;;-1:-1:-1;;;41360:56:0;;41273:27;;;;41360:17;:33;;;;;;:56;;41394:6;;41410:4;;41360:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41360:56:0;;;;;;;;;;;;:::i;:::-;41258:158;;;;41567:9;41562:124;41586:14;:21;41582:1;:25;41562:124;;;41629:45;41641:10;41652:1;41641:13;;;;;;;;:::i;:::-;;;;;;;41656:14;41671:1;41656:17;;;;;;;;:::i;:::-;;;;;;;41629:11;:45::i;:::-;41609:3;;;;:::i;:::-;;;;41562:124;;;;41066:627;;;41038:655::o;26081:126::-;26149:7;26176:23;26192:6;26176:15;:23::i;39790:340::-;39888:7;;39830:23;;-1:-1:-1;;;;;39888:7:0;39874:10;:21;39866:43;;;;-1:-1:-1;;;39866:43:0;;8706:2:1;39866:43:0;;;8688:21:1;8745:1;8725:18;;;8718:29;-1:-1:-1;;;8763:18:1;;;8756:39;8812:18;;39866:43:0;8504:332:1;39866:43:0;39929:52;;-1:-1:-1;;;39929:52:0;;-1:-1:-1;;;;;39973:6:0;4691:32:1;;39929:52:0;;;4673:51:1;39929:17:0;:35;;;;4646:18:1;;39929:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;39929:52:0;;;;;;;;;;;;:::i;:::-;39920:61;;39999:9;39994:99;40018:6;:13;40014:1;:17;39994:99;;;40053:12;40071:6;40078:1;40071:9;;;;;;;;:::i;:::-;;;;;;;;;;;;40053:28;;;;;;;-1:-1:-1;40053:28:0;;;;;;;;;;-1:-1:-1;;;;;;40053:28:0;-1:-1:-1;;;;;40053:28:0;;;;;;;;;40033:3;;;;:::i;:::-;;;;39994:99;;;-1:-1:-1;40105:10:0;:17;;-1:-1:-1;;;;40105:17:0;-1:-1:-1;;;40105:17:0;;;39790:340;:::o;22150:528::-;22225:14;22346:22;22361:6;22346:14;:22::i;:::-;22337:31;;;22373:1;22336:38;22328:62;;;;-1:-1:-1;;;22328:62:0;;18095:2:1;22328:62:0;;;18077:21:1;18134:2;18114:18;;;18107:30;-1:-1:-1;;;18153:18:1;;;18146:41;18204:18;;22328:62:0;17893:335:1;22328:62:0;22473:57;-1:-1:-1;;;;;22473:5:0;:22;22496:10;22516:4;22523:6;22473:22;:57::i;:::-;22543:23;22549:8;22559:6;22543:5;:23::i;:::-;22584:45;;;18407:25:1;;;18463:2;18448:18;;18441:34;;;-1:-1:-1;;;;;22584:45:0;;;22592:10;;22584:45;;18380:18:1;22584:45:0;;;;;;;22642:28;22655:6;22663;22642:12;:28::i;38263:29::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38263:29:0;;-1:-1:-1;38263:29:0;:::o;22686:478::-;22758:14;22794:19;22806:6;22794:11;:19::i;:::-;22785:28;-1:-1:-1;22959:57:0;-1:-1:-1;;;;;22959:5:0;:22;22982:10;23002:4;22785:28;22959:22;:57::i;:::-;23029:23;23035:8;23045:6;23029:5;:23::i;:::-;23070:45;;;18407:25:1;;;18463:2;18448:18;;18441:34;;;-1:-1:-1;;;;;23070:45:0;;;23078:10;;23070:45;;18380:18:1;23070:45:0;;;;;;;23128:28;23141:6;23149;23128:12;:28::i;1070:20::-;;;;;;;:::i;2745:385::-;2842:10;2815:4;2832:21;;;:9;:21;;;;;:31;;2857:6;;2832:21;2815:4;;2832:31;;2857:6;;2832:31;:::i;:::-;;;;-1:-1:-1;;;;;;;3014:13:0;;;;;;:9;:13;;;;;;;:23;;;;;;3066:32;3075:10;;-1:-1:-1;;;;;;;;;;;3066:32:0;;;3031:6;160:25:1;;148:2;133:18;;14:177;25551:255:0;25654:11;;25617:7;;25737:11;;:61;;25760:38;25776:13;:11;:13::i;:::-;25760:6;;25791;25760:15;:38::i;44079:807::-;44213:14;44249:23;44265:6;44249:15;:23::i;:::-;44240:32;-1:-1:-1;44356:10:0;-1:-1:-1;;;;;44356:19:0;;;44352:266;;-1:-1:-1;;;;;44410:16:0;;44392:15;44410:16;;;:9;:16;;;;;;;;44427:10;44410:28;;;;;;;;-1:-1:-1;;44495:28:0;;44491:116;;44575:16;44585:6;44575:7;:16;:::i;:::-;-1:-1:-1;;;;;44544:16:0;;;;;;:9;:16;;;;;;;;44561:10;44544:28;;;;;;;:47;44491:116;44377:241;44352:266;44673:20;44679:5;44686:6;44673:5;:20::i;:::-;44711:53;;;18407:25:1;;;18463:2;18448:18;;18441:34;;;-1:-1:-1;;;;;44711:53:0;;;;;;;;44720:10;;44711:53;;18380:18:1;44711:53:0;;;;;;;44824:54;;-1:-1:-1;;;44824:54:0;;-1:-1:-1;;;;;44853:5:0;18744:15:1;;44824:54:0;;;18726:34:1;18776:18;;;18769:34;;;18839:15;;;18819:18;;;18812:43;44824:11:0;:20;;;;18661:18:1;;44824:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;44079:807;;;;;:::o;44894:842::-;45026:14;45057:10;-1:-1:-1;;;;;45057:19:0;;;45053:266;;-1:-1:-1;;;;;45111:16:0;;45093:15;45111:16;;;:9;:16;;;;;;;;45128:10;45111:28;;;;;;;;-1:-1:-1;;45196:28:0;;45192:116;;45276:16;45286:6;45276:7;:16;:::i;:::-;-1:-1:-1;;;;;45245:16:0;;;;;;:9;:16;;;;;;;;45262:10;45245:28;;;;;;;:47;45192:116;45078:241;45053:266;45424:21;45438:6;45424:13;:21::i;:::-;45415:30;;;45450:1;45414:37;45406:61;;;;-1:-1:-1;;;45406:61:0;;19068:2:1;45406:61:0;;;19050:21:1;19107:2;19087:18;;;19080:30;-1:-1:-1;;;19126:18:1;;;19119:41;19177:18;;45406:61:0;18866:335:1;45406:61:0;45523:20;45529:5;45536:6;45523:5;:20::i;:::-;45561:53;;;18407:25:1;;;18463:2;18448:18;;18441:34;;;-1:-1:-1;;;;;45561:53:0;;;;;;;;45570:10;;45561:53;;18380:18:1;45561:53:0;;;;;;;45674:54;;-1:-1:-1;;;45674:54:0;;-1:-1:-1;;;;;45703:5:0;18744:15:1;;45674:54:0;;;18726:34:1;18776:18;;;18769:34;;;18839:15;;;18819:18;;;18812:43;45674:11:0;:20;;;;18661:18:1;;45674:54:0;18486:375:1;47459:835:0;47601:56;;-1:-1:-1;;;47601:56:0;;-1:-1:-1;;;;;47650:5:0;4691:32:1;;47601:56:0;;;4673:51:1;-1:-1:-1;;;;47601:11:0;:40;;;;4646:18:1;;47601:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;:103;;-1:-1:-1;;;;50742:25:0;;:30;;47735:66;;;;-1:-1:-1;;;;50875:25:0;;:30;47735:66;:110;;;;-1:-1:-1;;;;51008:25:0;;:30;47735:110;47715:178;;-1:-1:-1;47880:1:0;;47459:835;-1:-1:-1;;47459:835:0:o;47715:178::-;51147:64;37659:3;51147:64;;;;47935:30;48008:27;;;48004:84;;-1:-1:-1;;;48059:17:0;47459:835;-1:-1:-1;;;47459:835:0:o;48004:84::-;50535:89;37733:2;50535:89;;;;48100:19;48202:17;50535:89;48202:2;:17;:::i;:::-;48177:42;;:22;:42;:::i;:::-;48157:62;;48237:49;48265:6;-1:-1:-1;;;;;48265:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48253:32;;:9;:32;:::i;24878:261::-;24985:11;;24948:7;;25068:11;;:63;;25091:40;25109:6;25117:13;:11;:13::i;:::-;25091:6;;:40;:17;:40::i;48302:605::-;48504:56;;-1:-1:-1;;;48504:56:0;;-1:-1:-1;;;;;48553:5:0;4691:32:1;;48504:56:0;;;4673:51:1;-1:-1:-1;;;;48504:11:0;:40;;;;4646:18:1;;48504:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;:103;;-1:-1:-1;;;;50742:25:0;;:30;;48624:49;;;;-1:-1:-1;;;;51008:25:0;;:30;48624:49;48618:93;;-1:-1:-1;48698:1:0;;48302:605;-1:-1:-1;;48302:605:0:o;48618:93::-;48738:32;;-1:-1:-1;;;48738:32:0;;-1:-1:-1;;;;;48762:6:0;4691:32:1;;48738::0;;;4673:51:1;-1:-1:-1;;48738:5:0;:15;;;;;;4646:18:1;;48738:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48821:16:0;;48781:21;48821:16;;;:9;:16;;;;;;48723:47;;-1:-1:-1;48781:21:0;48805:33;;:15;:33::i;:::-;48781:57;;48863:13;48856:4;:20;:43;;48886:13;48856:43;;;48879:4;48856:43;48849:50;48302:605;-1:-1:-1;;;;;48302:605:0:o;3945:1527::-;4173:15;4161:8;:27;;4153:63;;;;-1:-1:-1;;;4153:63:0;;19408:2:1;4153:63:0;;;19390:21:1;19447:2;19427:18;;;19420:30;19486:25;19466:18;;;19459:53;19529:18;;4153:63:0;19206:347:1;4153:63:0;4386:24;4413:827;4553:18;:16;:18::i;:::-;-1:-1:-1;;;;;5007:13:0;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;4638:458;;4683:167;4638:458;;;19845:25:1;19924:18;;;19917:43;;;;19996:15;;;19976:18;;;19969:43;20028:18;;;20021:34;;;20071:19;;;20064:35;;;;20115:19;;;;20108:35;;;4638:458:0;;;;;;;;;;19817:19:1;;;4638:458:0;;;4598:525;;;;;;;;-1:-1:-1;;;4473:673:0;;;20412:27:1;20455:11;;;20448:27;;;;20491:12;;;20484:28;;;;20528:12;;4473:673:0;;;-1:-1:-1;;4473:673:0;;;;;;;;;4441:724;;4473:673;4441:724;;;;4413:827;;;;;;;;;20778:25:1;20851:4;20839:17;;20819:18;;;20812:45;20873:18;;;20866:34;;;20916:18;;;20909:34;;;20750:19;;4413:827:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4413:827:0;;-1:-1:-1;;4413:827:0;;;-1:-1:-1;;;;;;;5265:30:0;;;;;;:59;;;5319:5;-1:-1:-1;;;;;5299:25:0;:16;-1:-1:-1;;;;;5299:25:0;;5265:59;5257:86;;;;-1:-1:-1;;;5257:86:0;;21156:2:1;5257:86:0;;;21138:21:1;21195:2;21175:18;;;21168:30;-1:-1:-1;;;21214:18:1;;;21207:44;21268:18;;5257:86:0;20954:338:1;5257:86:0;-1:-1:-1;;;;;5360:27:0;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;5433:31;160:25:1;;;5360:36:0;;5433:31;;;;;133:18:1;5433:31:0;;;;;;;3945:1527;;;;;;;:::o;48915:654::-;49115:56;;-1:-1:-1;;;49115:56:0;;-1:-1:-1;;;;;49164:5:0;4691:32:1;;49115:56:0;;;4673:51:1;-1:-1:-1;;;;49115:11:0;:40;;;;4646:18:1;;49115:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:84;:103;;-1:-1:-1;;;;50742:25:0;;:30;;49235:49;;;;-1:-1:-1;;;;51008:25:0;;:30;49235:49;49229:93;;-1:-1:-1;49309:1:0;;48915:654;-1:-1:-1;;48915:654:0:o;49229:93::-;49349:32;;-1:-1:-1;;;49349:32:0;;-1:-1:-1;;;;;49373:6:0;4691:32:1;;49349::0;;;4673:51:1;-1:-1:-1;;49349:5:0;:15;;;;;;4646:18:1;;49349:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49334:47;;49392:20;49415:21;49431:4;49415:15;:21::i;:::-;-1:-1:-1;;;;;49470:16:0;;49447:20;49470:16;;;:9;:16;;;;;;49392:44;;-1:-1:-1;49504:27:0;;;:57;;49549:12;49504:57;;;-1:-1:-1;49534:12:0;49497:64;-1:-1:-1;;;;48915:654:0:o;25416:127::-;25485:7;25512:23;25528:6;25512:15;:23::i;14267:552::-;14480:9;;;14614:19;;14607:27;14639:9;;14653;;;14650:16;;14636:31;14603:65;14593:123;;14699:1;14696;14689:12;14593:123;14782:19;;14267:552;-1:-1:-1;;14267:552:0:o;14827:771::-;15038:9;;;15172:19;;15165:27;15197:9;;15211;;;15208:16;;15194:31;15161:65;15151:123;;15257:1;15254;15247:12;15151:123;15577:1;15563:11;15559:1;15556;15552:9;15548:27;15544:35;15539:1;15532:9;15525:17;15521:59;15516:64;;14827:771;;;;;:::o;5667:457::-;5732:7;5833:95;5967:4;5951:22;;;;;;:::i;:::-;;;;;;;;;;5800:301;;;22794:25:1;;;;22835:18;;22828:34;;;;5996:14:0;22878:18:1;;;22871:34;6033:13:0;22921:18:1;;;22914:34;6077:4:0;22964:19:1;;;22957:61;22766:19;;5800:301:0;;;;;;;;;;;;5772:344;;;;;;5752:364;;5667:457;:::o;41757:1640::-;-1:-1:-1;;;;;41953:24:0;;;41875:18;41953:24;;;:11;:24;;;;;;;;;41927:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41902:11;;42068:5;42043:31;;;42039:1207;;42112:13;;;;42091:43;;-1:-1:-1;;;42091:43:0;;-1:-1:-1;;;;;23221:32:1;;;42091:43:0;;;23203:51:1;23270:18;;;23263:34;;;42091:20:0;;;;;;23176:18:1;;42091:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;42186:255;42217:6;42269:11;42328:5;42392:7;:13;;;42186:12;:255::i;:::-;;42039:1207;;;42532:13;;;;42511:43;;-1:-1:-1;;;42511:43:0;;-1:-1:-1;;;;;23221:32:1;;;42511:43:0;;;23203:51:1;23270:18;;;23263:34;;;42511:20:0;;;;;;23176:18:1;;42511:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;42606:23;42632:249;42663:6;42688:11;42736:7;:13;;;42832:7;:13;;;42632:12;:249::i;:::-;42904:13;;42927;;;;;42898:60;;-1:-1:-1;;;42898:60:0;;-1:-1:-1;;;;;23221:32:1;;;42898:60:0;;;23203:51:1;23270:18;;;23263:34;;;42606:275:0;;-1:-1:-1;42898:28:0;;;;23176:18:1;;42898:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;42993:241;43024:15;43058:7;:13;;;43121:5;43185:7;:13;;;42993:12;:241::i;:::-;-1:-1:-1;;42039:1207:0;43355:30;;-1:-1:-1;;;43355:30:0;;43379:4;43355:30;;;4673:51:1;43342:47:0;;43355:5;-1:-1:-1;;;;;43355:15:0;;;;4646:18:1;;43355:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43387:1;43342:12;:47::i;8206:1604::-;8350:12;8481:4;8475:11;-1:-1:-1;;;8607:17:0;8600:93;8741:4;8737:1;8718:17;8714:25;8707:39;8826:2;8821;8802:17;8798:26;8791:38;8907:6;8902:2;8883:17;8879:26;8872:42;9721:2;9718:1;9713:3;9694:17;9691:1;9684:5;9677;9672:52;9235:16;9228:24;9222:2;9204:16;9201:24;9197:1;9193;9187:8;9184:15;9180:46;9177:76;8974:765;8963:776;;;9770:7;9762:40;;;;-1:-1:-1;;;9762:40:0;;23792:2:1;9762:40:0;;;23774:21:1;23831:2;23811:18;;;23804:30;-1:-1:-1;;;23850:18:1;;;23843:50;23910:18;;9762:40:0;23590:344:1;6324:335:0;6410:6;6395:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;6567:13:0;;;;;;:9;:13;;;;;;;;:23;;;;;;6619:32;160:25:1;;;-1:-1:-1;;;;;;;;;;;6619:32:0;133:18:1;6619:32:0;;;;;;;;6324:335;;:::o;45979:593::-;46407:47;-1:-1:-1;;;;;46407:5:0;:17;46433:11;46447:6;46407:17;:47::i;:::-;46504:60;;-1:-1:-1;;;46504:60:0;;-1:-1:-1;;;;;46531:5:0;24366:15:1;;46504:60:0;;;24348:34:1;24398:18;;;24391:34;;;46555:4:0;24441:18:1;;;24434:43;-1:-1:-1;24493:18:1;;;24486:47;46504:11:0;:18;;;;24282:19:1;;46504:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45979:593;;:::o;6667:338::-;-1:-1:-1;;;;;6740:15:0;;;;;;:9;:15;;;;;:25;;6759:6;;6740:15;:25;;6759:6;;6740:25;:::i;:::-;;;;-1:-1:-1;;6913:11:0;:21;;;;;;;6963:34;;160:25:1;;;-1:-1:-1;;;;;;;6963:34:0;;;-1:-1:-1;;;;;;;;;;;6963:34:0;148:2:1;133:18;6963:34:0;14:177:1;33786:828:0;33934:7;33973:9;33934:7;34015:30;34026:9;34037:7;34015:10;:30::i;:::-;33994:51;;;34057:16;34075;34097:4;-1:-1:-1;;;;;34097:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34056:59;;;;;34140:9;-1:-1:-1;;;;;34130:19:0;:6;-1:-1:-1;;;;;34130:19:0;;34126:68;;34175:8;34126:68;34205:18;34238;34259:42;34272:8;34282;-1:-1:-1;;;;;34259:42:0;34292:8;-1:-1:-1;;;;;34259:42:0;:12;:42::i;:::-;34238:63;;34326:9;-1:-1:-1;;;;;34316:19:0;:6;-1:-1:-1;;;;;34316:19:0;;34312:89;;34378:10;34312:89;34412:54;-1:-1:-1;;;;;34412:29:0;;34450:4;34457:8;34412:29;:54::i;:::-;34526:12;;;34536:1;34526:12;;;;;;;;;-1:-1:-1;;;34477:62:0;;;-1:-1:-1;;;;;34477:9:0;;;;;:62;;34487:10;;34499;;34519:4;;34477:62;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34570:10;34557;:23;:49;;34596:10;34557:49;;;34583:10;34557:49;34550:56;33786:828;-1:-1:-1;;;;;;;;;;;33786:828:0:o;11311:1483::-;11427:12;11558:4;11552:11;-1:-1:-1;;;11684:17:0;11677:93;11818:2;11814:1;11795:17;11791:25;11784:37;11899:6;11894:2;11875:17;11871:26;11864:42;12711:2;12708:1;12704:2;12685:17;12682:1;12675:5;12668;12663:51;12227:16;12220:24;12214:2;12196:16;12193:24;12189:1;12185;12179:8;12176:15;12172:46;12169:76;11966:763;11955:774;;;12760:7;12752:34;;;;-1:-1:-1;;;12752:34:0;;25858:2:1;12752:34:0;;;25840:21:1;25897:2;25877:18;;;25870:30;-1:-1:-1;;;25916:18:1;;;25909:44;25970:18;;12752:34:0;25656:338:1;35671:204:0;35773:7;35782;35823:6;-1:-1:-1;;;;;35814:15:0;:6;-1:-1:-1;;;;;35814:15:0;;:53;;35852:6;35860;35814:53;;;35833:6;35841;35814:53;35807:60;;;;35671:204;;;;;:::o;34979:379::-;35115:7;;35161:14;:8;35172:3;35161:14;:::i;:::-;35135:40;-1:-1:-1;35186:17:0;35206:30;35225:10;35135:40;35206:30;:::i;:::-;35186:50;-1:-1:-1;35247:19:0;35291:15;35270:16;:9;35282:4;35270:16;:::i;:::-;35269:38;;;;:::i;:::-;35247:60;-1:-1:-1;35325:25:0;35247:60;35325:9;:25;:::i;:::-;35318:32;34979:379;-1:-1:-1;;;;;;;34979:379:0:o;9818:1485::-;9935:12;10066:4;10060:11;-1:-1:-1;;;10192:17:0;10185:93;10326:2;10322:1;10303:17;10299:25;10292:37;10407:6;10402:2;10383:17;10379:26;10372:42;11219:2;11216:1;11212:2;11193:17;11190:1;11183:5;11176;11171:51;10735:16;10728:24;10722:2;10704:16;10701:24;10697:1;10693;10687:8;10684:15;10680:46;10677:76;10474:763;10463:774;;;11268:7;11260:35;;;;-1:-1:-1;;;11260:35:0;;26423:2:1;11260:35:0;;;26405:21:1;26462:2;26442:18;;;26435:30;-1:-1:-1;;;26481:18:1;;;26474:45;26536:18;;11260:35:0;26221:339:1;196:131;-1:-1:-1;;;;;271:31:1;;261:42;;251:70;;317:1;314;307:12;251:70;196:131;:::o;332:671::-;418:6;426;434;442;495:3;483:9;474:7;470:23;466:33;463:53;;;512:1;509;502:12;463:53;551:9;538:23;570:31;595:5;570:31;:::i;:::-;620:5;-1:-1:-1;677:2:1;662:18;;649:32;690:33;649:32;690:33;:::i;:::-;742:7;-1:-1:-1;801:2:1;786:18;;773:32;814:33;773:32;814:33;:::i;:::-;866:7;-1:-1:-1;925:2:1;910:18;;897:32;938:33;897:32;938:33;:::i;:::-;332:671;;;;-1:-1:-1;332:671:1;;-1:-1:-1;;332:671:1:o;1008:472::-;1050:3;1088:5;1082:12;1115:6;1110:3;1103:19;1140:1;1150:162;1164:6;1161:1;1158:13;1150:162;;;1226:4;1282:13;;;1278:22;;1272:29;1254:11;;;1250:20;;1243:59;1179:12;1150:162;;;1330:6;1327:1;1324:13;1321:87;;;1396:1;1389:4;1380:6;1375:3;1371:16;1367:27;1360:38;1321:87;-1:-1:-1;1462:2:1;1441:15;-1:-1:-1;;1437:29:1;1428:39;;;;1469:4;1424:50;;1008:472;-1:-1:-1;;1008:472:1:o;1485:220::-;1634:2;1623:9;1616:21;1597:4;1654:45;1695:2;1684:9;1680:18;1672:6;1654:45;:::i;1710:180::-;1769:6;1822:2;1810:9;1801:7;1797:23;1793:32;1790:52;;;1838:1;1835;1828:12;1790:52;-1:-1:-1;1861:23:1;;1710:180;-1:-1:-1;1710:180:1:o;1895:315::-;1963:6;1971;2024:2;2012:9;2003:7;1999:23;1995:32;1992:52;;;2040:1;2037;2030:12;1992:52;2079:9;2066:23;2098:31;2123:5;2098:31;:::i;:::-;2148:5;2200:2;2185:18;;;;2172:32;;-1:-1:-1;;;1895:315:1:o;2407:461::-;2460:3;2498:5;2492:12;2525:6;2520:3;2513:19;2551:4;2580:2;2575:3;2571:12;2564:19;;2617:2;2610:5;2606:14;2638:1;2648:195;2662:6;2659:1;2656:13;2648:195;;;2727:13;;-1:-1:-1;;;;;2723:39:1;2711:52;;2783:12;;;;2818:15;;;;2759:1;2677:9;2648:195;;;-1:-1:-1;2859:3:1;;2407:461;-1:-1:-1;;;;;2407:461:1:o;2873:804::-;3130:2;3119:9;3112:21;3093:4;3156:56;3208:2;3197:9;3193:18;3185:6;3156:56;:::i;:::-;3269:22;;;3231:2;3249:18;;;3242:50;;;;3341:13;;3363:22;;;3439:15;;;;3401;;;3472:1;3482:169;3496:6;3493:1;3490:13;3482:169;;;3557:13;;3545:26;;3626:15;;;;3591:12;;;;3518:1;3511:9;3482:169;;;-1:-1:-1;3668:3:1;;2873:804;-1:-1:-1;;;;;;;2873:804:1:o;3682:456::-;3759:6;3767;3775;3828:2;3816:9;3807:7;3803:23;3799:32;3796:52;;;3844:1;3841;3834:12;3796:52;3883:9;3870:23;3902:31;3927:5;3902:31;:::i;:::-;3952:5;-1:-1:-1;4009:2:1;3994:18;;3981:32;4022:33;3981:32;4022:33;:::i;:::-;3682:456;;4074:7;;-1:-1:-1;;;4128:2:1;4113:18;;;;4100:32;;3682:456::o;4735:247::-;4794:6;4847:2;4835:9;4826:7;4822:23;4818:32;4815:52;;;4863:1;4860;4853:12;4815:52;4902:9;4889:23;4921:31;4946:5;4921:31;:::i;5584:261::-;5763:2;5752:9;5745:21;5726:4;5783:56;5835:2;5824:9;5820:18;5812:6;5783:56;:::i;6085:315::-;6153:6;6161;6214:2;6202:9;6193:7;6189:23;6185:32;6182:52;;;6230:1;6227;6220:12;6182:52;6266:9;6253:23;6243:33;;6326:2;6315:9;6311:18;6298:32;6339:31;6364:5;6339:31;:::i;:::-;6389:5;6379:15;;;6085:315;;;;;:::o;6627:456::-;6704:6;6712;6720;6773:2;6761:9;6752:7;6748:23;6744:32;6741:52;;;6789:1;6786;6779:12;6741:52;6825:9;6812:23;6802:33;;6885:2;6874:9;6870:18;6857:32;6898:31;6923:5;6898:31;:::i;:::-;6948:5;-1:-1:-1;7005:2:1;6990:18;;6977:32;7018:33;6977:32;7018:33;:::i;:::-;7070:7;7060:17;;;6627:456;;;;;:::o;7088:829::-;7199:6;7207;7215;7223;7231;7239;7247;7300:3;7288:9;7279:7;7275:23;7271:33;7268:53;;;7317:1;7314;7307:12;7268:53;7356:9;7343:23;7375:31;7400:5;7375:31;:::i;:::-;7425:5;-1:-1:-1;7482:2:1;7467:18;;7454:32;7495:33;7454:32;7495:33;:::i;:::-;7547:7;-1:-1:-1;7601:2:1;7586:18;;7573:32;;-1:-1:-1;7652:2:1;7637:18;;7624:32;;-1:-1:-1;7708:3:1;7693:19;;7680:33;7757:4;7744:18;;7732:31;;7722:59;;7777:1;7774;7767:12;7722:59;7088:829;;;;-1:-1:-1;7088:829:1;;;;7800:7;7854:3;7839:19;;7826:33;;-1:-1:-1;7906:3:1;7891:19;;;7878:33;;7088:829;-1:-1:-1;;7088:829:1:o;7922:388::-;7990:6;7998;8051:2;8039:9;8030:7;8026:23;8022:32;8019:52;;;8067:1;8064;8057:12;8019:52;8106:9;8093:23;8125:31;8150:5;8125:31;:::i;:::-;8175:5;-1:-1:-1;8232:2:1;8217:18;;8204:32;8245:33;8204:32;8245:33;:::i;8315:184::-;8385:6;8438:2;8426:9;8417:7;8413:23;8409:32;8406:52;;;8454:1;8451;8444:12;8406:52;-1:-1:-1;8477:16:1;;8315:184;-1:-1:-1;8315:184:1:o;9185:127::-;9246:10;9241:3;9237:20;9234:1;9227:31;9277:4;9274:1;9267:15;9301:4;9298:1;9291:15;9317:127;9378:10;9373:3;9369:20;9366:1;9359:31;9409:4;9406:1;9399:15;9433:4;9430:1;9423:15;9449:135;9488:3;9509:17;;;9506:43;;9529:18;;:::i;:::-;-1:-1:-1;9576:1:1;9565:13;;9449:135::o;9589:380::-;9668:1;9664:12;;;;9711;;;9732:61;;9786:4;9778:6;9774:17;9764:27;;9732:61;9839:2;9831:6;9828:14;9808:18;9805:38;9802:161;;9885:10;9880:3;9876:20;9873:1;9866:31;9920:4;9917:1;9910:15;9948:4;9945:1;9938:15;9802:161;;9589:380;;;:::o;9974:127::-;10035:10;10030:3;10026:20;10023:1;10016:31;10066:4;10063:1;10056:15;10090:4;10087:1;10080:15;10106:358;10313:2;10302:9;10295:21;10276:4;10333:56;10385:2;10374:9;10370:18;10362:6;10333:56;:::i;:::-;10325:64;;10454:1;10450;10445:3;10441:11;10437:19;10429:6;10425:32;10420:2;10409:9;10405:18;10398:60;10106:358;;;;;:::o;10469:252::-;10541:2;10535:9;10583:3;10571:16;;10617:18;10602:34;;10638:22;;;10599:62;10596:88;;;10664:18;;:::i;:::-;10700:2;10693:22;10469:252;:::o;10726:275::-;10797:2;10791:9;10862:2;10843:13;;-1:-1:-1;;10839:27:1;10827:40;;10897:18;10882:34;;10918:22;;;10879:62;10876:88;;;10944:18;;:::i;:::-;10980:2;10973:22;10726:275;;-1:-1:-1;10726:275:1:o;11006:183::-;11066:4;11099:18;11091:6;11088:30;11085:56;;;11121:18;;:::i;:::-;-1:-1:-1;11166:1:1;11162:14;11178:4;11158:25;;11006:183::o;11194:138::-;11273:13;;11295:31;11273:13;11295:31;:::i;:::-;11194:138;;;:::o;11337:734::-;11402:5;11455:3;11448:4;11440:6;11436:17;11432:27;11422:55;;11473:1;11470;11463:12;11422:55;11502:6;11496:13;11528:4;11552:60;11568:43;11608:2;11568:43;:::i;:::-;11552:60;:::i;:::-;11646:15;;;11732:1;11728:10;;;;11716:23;;11712:32;;;11677:12;;;;11756:15;;;11753:35;;;11784:1;11781;11774:12;11753:35;11820:2;11812:6;11808:15;11832:210;11848:6;11843:3;11840:15;11832:210;;;11921:3;11915:10;11938:31;11963:5;11938:31;:::i;:::-;11982:18;;12020:12;;;;11865;;11832:210;;;-1:-1:-1;12060:5:1;11337:734;-1:-1:-1;;;;;;11337:734:1:o;12076:1132::-;12205:6;12213;12266:2;12254:9;12245:7;12241:23;12237:32;12234:52;;;12282:1;12279;12272:12;12234:52;12315:9;12309:16;12344:18;12385:2;12377:6;12374:14;12371:34;;;12401:1;12398;12391:12;12371:34;12424:72;12488:7;12479:6;12468:9;12464:22;12424:72;:::i;:::-;12414:82;;12515:2;12505:12;;12563:2;12552:9;12548:18;12542:25;12592:2;12582:8;12579:16;12576:36;;;12608:1;12605;12598:12;12576:36;12631:24;;;-1:-1:-1;12686:4:1;12678:13;;12674:27;-1:-1:-1;12664:55:1;;12715:1;12712;12705:12;12664:55;12744:2;12738:9;12767:60;12783:43;12823:2;12783:43;:::i;12767:60::-;12861:15;;;12943:1;12939:10;;;;12931:19;;12927:28;;;12892:12;;;;12967:19;;;12964:39;;;12999:1;12996;12989:12;12964:39;13023:11;;;;13043:135;13059:6;13054:3;13051:15;13043:135;;;13125:10;;13113:23;;13076:12;;;;13156;;;;13043:135;;;13197:5;13187:15;;;;;;;12076:1132;;;;;:::o;13213:125::-;13253:4;13281:1;13278;13275:8;13272:34;;;13286:18;;:::i;:::-;-1:-1:-1;13323:9:1;;13213:125::o;13343:426::-;13424:5;13472:4;13460:9;13455:3;13451:19;13447:30;13444:50;;;13490:1;13487;13480:12;13444:50;13523:2;13517:9;13565:4;13557:6;13553:17;13636:6;13624:10;13621:22;13600:18;13588:10;13585:34;13582:62;13579:88;;;13647:18;;:::i;:::-;13683:2;13676:22;13746:16;;13731:32;;-1:-1:-1;13716:6:1;13343:426;-1:-1:-1;13343:426:1:o;13774:192::-;13853:13;;13906:34;13895:46;;13885:57;;13875:85;;13956:1;13953;13946:12;13971:169;14049:13;;14102:12;14091:24;;14081:35;;14071:63;;14130:1;14127;14120:12;14145:163;14223:13;;14276:6;14265:18;;14255:29;;14245:57;;14298:1;14295;14288:12;14313:1651;14412:6;14465:3;14453:9;14444:7;14440:23;14436:33;14433:53;;;14482:1;14479;14472:12;14433:53;14508:22;;:::i;:::-;14553:72;14617:7;14606:9;14553:72;:::i;:::-;14546:5;14539:87;14658:49;14703:2;14692:9;14688:18;14658:49;:::i;:::-;14653:2;14646:5;14642:14;14635:73;14740:49;14785:2;14774:9;14770:18;14740:49;:::i;:::-;14735:2;14728:5;14724:14;14717:73;14822:49;14867:2;14856:9;14852:18;14822:49;:::i;:::-;14817:2;14810:5;14806:14;14799:73;14905:50;14950:3;14939:9;14935:19;14905:50;:::i;:::-;14899:3;14892:5;14888:15;14881:75;14989:50;15034:3;15023:9;15019:19;14989:50;:::i;:::-;14983:3;14976:5;14972:15;14965:75;15073:49;15117:3;15106:9;15102:19;15073:49;:::i;:::-;15067:3;15060:5;15056:15;15049:74;15156:49;15200:3;15189:9;15185:19;15156:49;:::i;:::-;15150:3;15143:5;15139:15;15132:74;15225:3;15260:49;15305:2;15294:9;15290:18;15260:49;:::i;:::-;15244:14;;;15237:73;15329:3;15364:49;15394:18;;;15364:49;:::i;:::-;15348:14;;;15341:73;15433:3;15468:49;15498:18;;;15468:49;:::i;:::-;15452:14;;;15445:73;15537:3;15572:49;15602:18;;;15572:49;:::i;:::-;15556:14;;;15549:73;15641:3;15676:49;15706:18;;;15676:49;:::i;:::-;15660:14;;;15653:73;15745:3;15780:49;15810:18;;;15780:49;:::i;:::-;15764:14;;;15757:73;15849:3;15884:49;15914:18;;;15884:49;:::i;:::-;15868:14;;;15861:73;15872:5;14313:1651;-1:-1:-1;;;14313:1651:1:o;15969:422::-;16058:1;16101:5;16058:1;16115:270;16136:7;16126:8;16123:21;16115:270;;;16195:4;16191:1;16187:6;16183:17;16177:4;16174:27;16171:53;;;16204:18;;:::i;:::-;16254:7;16244:8;16240:22;16237:55;;;16274:16;;;;16237:55;16353:22;;;;16313:15;;;;16115:270;;;16119:3;15969:422;;;;;:::o;16396:806::-;16445:5;16475:8;16465:80;;-1:-1:-1;16516:1:1;16530:5;;16465:80;16564:4;16554:76;;-1:-1:-1;16601:1:1;16615:5;;16554:76;16646:4;16664:1;16659:59;;;;16732:1;16727:130;;;;16639:218;;16659:59;16689:1;16680:10;;16703:5;;;16727:130;16764:3;16754:8;16751:17;16748:43;;;16771:18;;:::i;:::-;-1:-1:-1;;16827:1:1;16813:16;;16842:5;;16639:218;;16941:2;16931:8;16928:16;16922:3;16916:4;16913:13;16909:36;16903:2;16893:8;16890:16;16885:2;16879:4;16876:12;16872:35;16869:77;16866:159;;;-1:-1:-1;16978:19:1;;;17010:5;;16866:159;17057:34;17082:8;17076:4;17057:34;:::i;:::-;17127:6;17123:1;17119:6;17115:19;17106:7;17103:32;17100:58;;;17138:18;;:::i;:::-;17176:20;;16396:806;-1:-1:-1;;;16396:806:1:o;17207:140::-;17265:5;17294:47;17335:4;17325:8;17321:19;17315:4;17294:47;:::i;17352:168::-;17392:7;17458:1;17454;17450:6;17446:14;17443:1;17440:21;17435:1;17428:9;17421:17;17417:45;17414:71;;;17465:18;;:::i;:::-;-1:-1:-1;17505:9:1;;17352:168::o;17525:363::-;17620:6;17673:2;17661:9;17652:7;17648:23;17644:32;17641:52;;;17689:1;17686;17679:12;17641:52;17722:9;17716:16;17755:18;17747:6;17744:30;17741:50;;;17787:1;17784;17777:12;17741:50;17810:72;17874:7;17865:6;17854:9;17850:22;17810:72;:::i;:::-;17800:82;17525:363;-1:-1:-1;;;;17525:363:1:o;21426:1104::-;21556:3;21585:1;21618:6;21612:13;21648:3;21670:1;21698:9;21694:2;21690:18;21680:28;;21758:2;21747:9;21743:18;21780;21770:61;;21824:4;21816:6;21812:17;21802:27;;21770:61;21850:2;21898;21890:6;21887:14;21867:18;21864:38;21861:165;;-1:-1:-1;;;21925:33:1;;21981:4;21978:1;21971:15;22011:4;21932:3;21999:17;21861:165;22042:18;22069:104;;;;22187:1;22182:323;;;;22035:470;;22069:104;-1:-1:-1;;22102:24:1;;22090:37;;22147:16;;;;-1:-1:-1;22069:104:1;;22182:323;21373:1;21366:14;;;21410:4;21397:18;;22280:1;22294:165;22308:6;22305:1;22302:13;22294:165;;;22386:14;;22373:11;;;22366:35;22429:16;;;;22323:10;;22294:165;;;22298:3;;22488:6;22483:3;22479:16;22472:23;;22035:470;-1:-1:-1;22521:3:1;;21426:1104;-1:-1:-1;;;;;;;;21426:1104:1:o;23308:277::-;23375:6;23428:2;23416:9;23407:7;23403:23;23399:32;23396:52;;;23444:1;23441;23434:12;23396:52;23476:9;23470:16;23529:5;23522:13;23515:21;23508:5;23505:32;23495:60;;23551:1;23548;23541:12;23939:128;23979:3;24010:1;24006:6;24003:1;24000:13;23997:39;;;24016:18;;:::i;:::-;-1:-1:-1;24052:9:1;;23939:128::o;24544:188::-;24623:13;;-1:-1:-1;;;;;24665:42:1;;24655:53;;24645:81;;24722:1;24719;24712:12;24737:450;24824:6;24832;24840;24893:2;24881:9;24872:7;24868:23;24864:32;24861:52;;;24909:1;24906;24899:12;24861:52;24932:40;24962:9;24932:40;:::i;:::-;24922:50;;24991:49;25036:2;25025:9;25021:18;24991:49;:::i;:::-;24981:59;;25083:2;25072:9;25068:18;25062:25;25127:10;25120:5;25116:22;25109:5;25106:33;25096:61;;25153:1;25150;25143:12;25192:459;25423:6;25412:9;25405:25;25466:6;25461:2;25450:9;25446:18;25439:34;25538:1;25534;25529:3;25525:11;25521:19;25513:6;25509:32;25504:2;25493:9;25489:18;25482:60;25578:3;25573:2;25562:9;25558:18;25551:31;25386:4;25599:46;25640:3;25629:9;25625:19;25617:6;25599:46;:::i;25999:217::-;26039:1;26065;26055:132;;26109:10;26104:3;26100:20;26097:1;26090:31;26144:4;26141:1;26134:15;26172:4;26169:1;26162:15;26055:132;-1:-1:-1;26201:9:1;;25999:217::o

Swarm Source

ipfs://c60e924a21d53dda6a8fc4e656afbe290f301b317f088b2260e69bb5aa45c18f

Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.