ETH Price: $3,563.69 (-1.25%)

Contract

0xe0Ae8B04922d6e3fA06c2496A94EF2875EFcC7BB
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Update Vault Max...237740702025-11-11 6:00:111 hr ago1762840811IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000005530.10458952
Update Vault Max...237723432025-11-11 0:10:597 hrs ago1762819859IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000006480.12248
Update Vault Max...237705072025-11-10 18:00:2313 hrs ago1762797623IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000024160.43721791
Update Vault Max...237687242025-11-10 12:00:2319 hrs ago1762776023IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000013380.2421844
Update Vault Max...237687232025-11-10 12:00:1119 hrs ago1762776011IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000020870.23247934
Update Vault Max...237597752025-11-09 6:00:112 days ago1762668011IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.00000430.07782762
Update Vault Max...237580382025-11-09 0:11:232 days ago1762647083IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000003690.06678481
Update Vault Max...237561922025-11-08 18:00:232 days ago1762624823IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000003980.07216659
Update Vault Max...237544002025-11-08 12:00:112 days ago1762603211IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000012480.22583465
Update Vault Max...237526142025-11-08 6:00:233 days ago1762581623IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000007810.14145795
Update Vault Max...237508832025-11-08 0:11:113 days ago1762560671IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000015090.27317007
Update Vault Max...237490392025-11-07 18:00:353 days ago1762538435IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000110131.99284212
Update Vault Max...237472512025-11-07 12:00:113 days ago1762516811IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000086511.56574887
Update Vault Max...237454662025-11-07 6:00:114 days ago1762495211IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000010230.18529892
Update Vault Max...237437412025-11-07 0:12:354 days ago1762474355IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000017220.31165697
Update Vault Max...237418882025-11-06 18:00:114 days ago1762452011IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000074621.35039628
Update Vault Max...237401022025-11-06 12:00:354 days ago1762430435IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000055411.0026827
Update Vault Max...237383132025-11-06 6:00:115 days ago1762408811IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000017820.32250057
Update Vault Max...237365692025-11-06 0:08:355 days ago1762387715IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000028620.51799702
Update Vault Max...237347442025-11-05 18:00:115 days ago1762365611IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000048540.87849178
Update Vault Max...237329592025-11-05 12:00:115 days ago1762344011IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000024050.43528702
Update Vault Max...237311722025-11-05 6:00:236 days ago1762322423IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000017380.31449593
Update Vault Max...237294372025-11-05 0:10:116 days ago1762301411IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.00004550.82342674
Update Vault Max...237276022025-11-04 18:00:116 days ago1762279211IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000309515.60061866
Update Vault Max...237258202025-11-04 12:00:116 days ago1762257611IN
0xe0Ae8B04...75EFcC7BB
0 ETH0.000038090.68950038
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
VaultUserLtvTracker

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: AGPL-3.0-only

pragma solidity ^0.8.26;

import {Math} from '@openzeppelin/contracts/utils/math/Math.sol';
import {IKeeperRewards} from '@stakewise-core/interfaces/IKeeperRewards.sol';
import {IVaultState} from '@stakewise-core/interfaces/IVaultState.sol';
import {IVaultOsToken} from '@stakewise-core/interfaces/IVaultOsToken.sol';
import {IOsTokenVaultController} from '@stakewise-core/interfaces/IOsTokenVaultController.sol';
import {IVaultUserLtvTracker} from './interfaces/IVaultUserLtvTracker.sol';

/**
 * @title VaultUserLtvTracker
 * @author StakeWise
 * @notice Stores user with a maximum LTV value for each vault
 */
contract VaultUserLtvTracker is IVaultUserLtvTracker {
    uint256 private constant _wad = 1e18;
    IKeeperRewards private immutable _keeperRewards;
    IOsTokenVaultController private immutable _osTokenVaultController;

    /**
     * @dev Constructor
     * @param keeper The address of the Keeper contract
     * @param osTokenVaultController The address of the OsTokenVaultController contract
     */
    constructor(address keeper, address osTokenVaultController) {
        _keeperRewards = IKeeperRewards(keeper);
        _osTokenVaultController = IOsTokenVaultController(osTokenVaultController);
    }

    // Mapping to store the user with the highest LTV for each vault
    mapping(address vault => address user) public vaultToUser;

    /// @inheritdoc IVaultUserLtvTracker
    function updateVaultMaxLtvUser(
        address vault,
        address newUser,
        IKeeperRewards.HarvestParams calldata harvestParams
    ) external {
        // Get the previous max LTV user for the vault
        address prevUser = vaultToUser[vault];

        if (newUser == prevUser) {
            return;
        }

        // Calculate the LTV for both users
        uint256 newLtv = _calculateLtv(vault, newUser, harvestParams);
        uint256 prevLtv = _calculateLtv(vault, prevUser, harvestParams);

        // If the new user has a higher LTV, update the record
        if (newLtv > prevLtv) {
            vaultToUser[vault] = newUser;
        }
    }

    /// @inheritdoc IVaultUserLtvTracker
    function getVaultMaxLtv(
        address vault,
        IKeeperRewards.HarvestParams calldata harvestParams
    ) external returns (uint256) {
        address user = vaultToUser[vault];

        // Calculate the latest LTV for the stored user
        return _calculateLtv(vault, user, harvestParams);
    }

    /**
     * @dev Internal function for calculating LTV
     * @param vault The address of the vault
     * @param user The address of the user
     * @param harvestParams The harvest params to use for updating the vault state
     */
    function _calculateLtv(
        address vault,
        address user,
        IKeeperRewards.HarvestParams calldata harvestParams
    ) private returns (uint256) {
        // Skip calculation for zero address
        if (user == address(0)) {
            return 0;
        }

        // Update vault state to get up-to-date value of user stake
        if (_keeperRewards.canHarvest(vault)) {
            IVaultState(vault).updateState(harvestParams);
        }

        // Get OsToken position
        uint256 osTokenShares = IVaultOsToken(vault).osTokenPositions(user);

        // Convert OsToken position to Wei
        uint256 osTokenAssets = _osTokenVaultController.convertToAssets(osTokenShares);

        if (osTokenAssets == 0) {
            return 0;
        }

        // Get user stake in a vault
        uint256 vaultShares = IVaultState(vault).getShares(user);

        // Convert user stake to Wei
        uint256 vaultAssets = IVaultState(vault).convertToAssets(vaultShares);

        if (vaultAssets == 0) {
            return 0;
        }

        // Calculate Loan-To-Value ratio
        return Math.mulDiv(osTokenAssets, _wad, vaultAssets);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

import {IKeeperOracles} from './IKeeperOracles.sol';

/**
 * @title IKeeperRewards
 * @author StakeWise
 * @notice Defines the interface for the Keeper contract rewards
 */
interface IKeeperRewards is IKeeperOracles {
  /**
   * @notice Event emitted on rewards update
   * @param caller The address of the function caller
   * @param rewardsRoot The new rewards merkle tree root
   * @param avgRewardPerSecond The new average reward per second
   * @param updateTimestamp The update timestamp used for rewards calculation
   * @param nonce The nonce used for verifying signatures
   * @param rewardsIpfsHash The new rewards IPFS hash
   */
  event RewardsUpdated(
    address indexed caller,
    bytes32 indexed rewardsRoot,
    uint256 avgRewardPerSecond,
    uint64 updateTimestamp,
    uint64 nonce,
    string rewardsIpfsHash
  );

  /**
   * @notice Event emitted on Vault harvest
   * @param vault The address of the Vault
   * @param rewardsRoot The rewards merkle tree root
   * @param totalAssetsDelta The Vault total assets delta since last sync. Can be negative in case of penalty/slashing.
   * @param unlockedMevDelta The Vault execution reward that can be withdrawn from shared MEV escrow. Only used by shared MEV Vaults.
   */
  event Harvested(
    address indexed vault,
    bytes32 indexed rewardsRoot,
    int256 totalAssetsDelta,
    uint256 unlockedMevDelta
  );

  /**
   * @notice Event emitted on rewards min oracles number update
   * @param oracles The new minimum number of oracles required to update rewards
   */
  event RewardsMinOraclesUpdated(uint256 oracles);

  /**
   * @notice A struct containing the last synced Vault's cumulative reward
   * @param assets The Vault cumulative reward earned since the start. Can be negative in case of penalty/slashing.
   * @param nonce The nonce of the last sync
   */
  struct Reward {
    int192 assets;
    uint64 nonce;
  }

  /**
   * @notice A struct containing the last unlocked Vault's cumulative execution reward that can be withdrawn from shared MEV escrow. Only used by shared MEV Vaults.
   * @param assets The shared MEV Vault's cumulative execution reward that can be withdrawn
   * @param nonce The nonce of the last sync
   */
  struct UnlockedMevReward {
    uint192 assets;
    uint64 nonce;
  }

  /**
   * @notice A struct containing parameters for rewards update
   * @param rewardsRoot The new rewards merkle root
   * @param avgRewardPerSecond The new average reward per second
   * @param updateTimestamp The update timestamp used for rewards calculation
   * @param rewardsIpfsHash The new IPFS hash with all the Vaults' rewards for the new root
   * @param signatures The concatenation of the Oracles' signatures
   */
  struct RewardsUpdateParams {
    bytes32 rewardsRoot;
    uint256 avgRewardPerSecond;
    uint64 updateTimestamp;
    string rewardsIpfsHash;
    bytes signatures;
  }

  /**
   * @notice A struct containing parameters for harvesting rewards. Can only be called by Vault.
   * @param rewardsRoot The rewards merkle root
   * @param reward The Vault cumulative reward earned since the start. Can be negative in case of penalty/slashing.
   * @param unlockedMevReward The Vault cumulative execution reward that can be withdrawn from shared MEV escrow. Only used by shared MEV Vaults.
   * @param proof The proof to verify that Vault's reward is correct
   */
  struct HarvestParams {
    bytes32 rewardsRoot;
    int160 reward;
    uint160 unlockedMevReward;
    bytes32[] proof;
  }

  /**
   * @notice Previous Rewards Root
   * @return The previous merkle tree root of the rewards accumulated by the Vaults
   */
  function prevRewardsRoot() external view returns (bytes32);

  /**
   * @notice Rewards Root
   * @return The latest merkle tree root of the rewards accumulated by the Vaults
   */
  function rewardsRoot() external view returns (bytes32);

  /**
   * @notice Rewards Nonce
   * @return The nonce used for updating rewards merkle tree root
   */
  function rewardsNonce() external view returns (uint64);

  /**
   * @notice The last rewards update
   * @return The timestamp of the last rewards update
   */
  function lastRewardsTimestamp() external view returns (uint64);

  /**
   * @notice The minimum number of oracles required to update rewards
   * @return The minimum number of oracles
   */
  function rewardsMinOracles() external view returns (uint256);

  /**
   * @notice The rewards delay
   * @return The delay in seconds between rewards updates
   */
  function rewardsDelay() external view returns (uint256);

  /**
   * @notice Get last synced Vault cumulative reward
   * @param vault The address of the Vault
   * @return assets The last synced reward assets
   * @return nonce The last synced reward nonce
   */
  function rewards(address vault) external view returns (int192 assets, uint64 nonce);

  /**
   * @notice Get last unlocked shared MEV Vault cumulative reward
   * @param vault The address of the Vault
   * @return assets The last synced reward assets
   * @return nonce The last synced reward nonce
   */
  function unlockedMevRewards(address vault) external view returns (uint192 assets, uint64 nonce);

  /**
   * @notice Checks whether Vault must be harvested
   * @param vault The address of the Vault
   * @return `true` if the Vault requires harvesting, `false` otherwise
   */
  function isHarvestRequired(address vault) external view returns (bool);

  /**
   * @notice Checks whether the Vault can be harvested
   * @param vault The address of the Vault
   * @return `true` if Vault can be harvested, `false` otherwise
   */
  function canHarvest(address vault) external view returns (bool);

  /**
   * @notice Checks whether rewards can be updated
   * @return `true` if rewards can be updated, `false` otherwise
   */
  function canUpdateRewards() external view returns (bool);

  /**
   * @notice Checks whether the Vault has registered validators
   * @param vault The address of the Vault
   * @return `true` if Vault is collateralized, `false` otherwise
   */
  function isCollateralized(address vault) external view returns (bool);

  /**
   * @notice Update rewards data
   * @param params The struct containing rewards update parameters
   */
  function updateRewards(RewardsUpdateParams calldata params) external;

  /**
   * @notice Harvest rewards. Can be called only by Vault.
   * @param params The struct containing rewards harvesting parameters
   * @return totalAssetsDelta The total reward/penalty accumulated by the Vault since the last sync
   * @return unlockedMevDelta The Vault execution reward that can be withdrawn from shared MEV escrow. Only used by shared MEV Vaults.
   * @return harvested `true` when the rewards were harvested, `false` otherwise
   */
  function harvest(
    HarvestParams calldata params
  ) external returns (int256 totalAssetsDelta, uint256 unlockedMevDelta, bool harvested);

  /**
   * @notice Set min number of oracles for confirming rewards update. Can only be called by the owner.
   * @param _rewardsMinOracles The new min number of oracles for confirming rewards update
   */
  function setRewardsMinOracles(uint256 _rewardsMinOracles) external;
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

import {IKeeperRewards} from './IKeeperRewards.sol';
import {IVaultFee} from './IVaultFee.sol';

/**
 * @title IVaultState
 * @author StakeWise
 * @notice Defines the interface for the VaultState contract
 */
interface IVaultState is IVaultFee {
  /**
   * @notice Event emitted on checkpoint creation
   * @param shares The number of burned shares
   * @param assets The amount of exited assets
   */
  event CheckpointCreated(uint256 shares, uint256 assets);

  /**
   * @notice Event emitted on minting fee recipient shares
   * @param receiver The address of the fee recipient
   * @param shares The number of minted shares
   * @param assets The amount of minted assets
   */
  event FeeSharesMinted(address receiver, uint256 shares, uint256 assets);

  /**
   * @notice Event emitted when exiting assets are penalized
   * @param penalty The total penalty amount
   */
  event ExitingAssetsPenalized(uint256 penalty);

  /**
   * @notice Total assets in the Vault
   * @return The total amount of the underlying asset that is "managed" by Vault
   */
  function totalAssets() external view returns (uint256);

  /**
   * @notice Function for retrieving total shares
   * @return The amount of shares in existence
   */
  function totalShares() external view returns (uint256);

  /**
   * @notice The Vault's capacity
   * @return The amount after which the Vault stops accepting deposits
   */
  function capacity() external view returns (uint256);

  /**
   * @notice Total assets available in the Vault. They can be staked or withdrawn.
   * @return The total amount of withdrawable assets
   */
  function withdrawableAssets() external view returns (uint256);

  /**
   * @notice Queued Shares
   * @return The total number of shares queued for exit
   */
  function queuedShares() external view returns (uint128);

  /**
   * @notice Returns the number of shares held by an account
   * @param account The account for which to look up the number of shares it has, i.e. its balance
   * @return The number of shares held by the account
   */
  function getShares(address account) external view returns (uint256);

  /**
   * @notice Converts assets to shares
   * @param assets The amount of assets to convert to shares
   * @return shares The amount of shares that the Vault would exchange for the amount of assets provided
   */
  function convertToShares(uint256 assets) external view returns (uint256 shares);

  /**
   * @notice Converts shares to assets
   * @param shares The amount of shares to convert to assets
   * @return assets The amount of assets that the Vault would exchange for the amount of shares provided
   */
  function convertToAssets(uint256 shares) external view returns (uint256 assets);

  /**
   * @notice Check whether state update is required
   * @return `true` if state update is required, `false` otherwise
   */
  function isStateUpdateRequired() external view returns (bool);

  /**
   * @notice Updates the total amount of assets in the Vault and its exit queue
   * @param harvestParams The parameters for harvesting Keeper rewards
   */
  function updateState(IKeeperRewards.HarvestParams calldata harvestParams) external;
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

import {IVaultState} from './IVaultState.sol';
import {IVaultEnterExit} from './IVaultEnterExit.sol';

/**
 * @title IVaultOsToken
 * @author StakeWise
 * @notice Defines the interface for the VaultOsToken contract
 */
interface IVaultOsToken is IVaultState, IVaultEnterExit {
  /**
   * @notice Event emitted on minting osToken
   * @param caller The address of the function caller
   * @param receiver The address of the osToken receiver
   * @param assets The amount of minted assets
   * @param shares The amount of minted shares
   * @param referrer The address of the referrer
   */
  event OsTokenMinted(
    address indexed caller,
    address receiver,
    uint256 assets,
    uint256 shares,
    address referrer
  );

  /**
   * @notice Event emitted on burning OsToken
   * @param caller The address of the function caller
   * @param assets The amount of burned assets
   * @param shares The amount of burned shares
   */
  event OsTokenBurned(address indexed caller, uint256 assets, uint256 shares);

  /**
   * @notice Event emitted on osToken position liquidation
   * @param caller The address of the function caller
   * @param user The address of the user liquidated
   * @param receiver The address of the receiver of the liquidated assets
   * @param osTokenShares The amount of osToken shares to liquidate
   * @param shares The amount of vault shares burned
   * @param receivedAssets The amount of assets received
   */
  event OsTokenLiquidated(
    address indexed caller,
    address indexed user,
    address receiver,
    uint256 osTokenShares,
    uint256 shares,
    uint256 receivedAssets
  );

  /**
   * @notice Event emitted on osToken position redemption
   * @param caller The address of the function caller
   * @param user The address of the position owner to redeem from
   * @param receiver The address of the receiver of the redeemed assets
   * @param osTokenShares The amount of osToken shares to redeem
   * @param shares The amount of vault shares burned
   * @param assets The amount of assets received
   */
  event OsTokenRedeemed(
    address indexed caller,
    address indexed user,
    address receiver,
    uint256 osTokenShares,
    uint256 shares,
    uint256 assets
  );

  /**
   * @notice Struct of osToken position
   * @param shares The total number of minted osToken shares. Will increase based on the treasury fee.
   * @param cumulativeFeePerShare The cumulative fee per share
   */
  struct OsTokenPosition {
    uint128 shares;
    uint128 cumulativeFeePerShare;
  }

  /**
   * @notice Get total amount of minted osToken shares
   * @param user The address of the user
   * @return shares The number of minted osToken shares
   */
  function osTokenPositions(address user) external view returns (uint128 shares);

  /**
   * @notice Mints OsToken shares
   * @param receiver The address that will receive the minted OsToken shares
   * @param osTokenShares The number of OsToken shares to mint to the receiver. To mint the maximum amount of shares, use 2^256 - 1.
   * @param referrer The address of the referrer
   * @return assets The number of assets minted to the receiver
   */
  function mintOsToken(
    address receiver,
    uint256 osTokenShares,
    address referrer
  ) external returns (uint256 assets);

  /**
   * @notice Burns osToken shares
   * @param osTokenShares The number of shares to burn
   * @return assets The number of assets burned
   */
  function burnOsToken(uint128 osTokenShares) external returns (uint256 assets);

  /**
   * @notice Liquidates a user position and returns the number of received assets.
   *         Can only be called when health factor is below 1 by the liquidator.
   * @param osTokenShares The number of shares to cover
   * @param owner The address of the position owner to liquidate
   * @param receiver The address of the receiver of the liquidated assets
   */
  function liquidateOsToken(uint256 osTokenShares, address owner, address receiver) external;

  /**
   * @notice Redeems osToken shares for assets. Can only be called when health factor is above redeemFromHealthFactor by the redeemer.
   * @param osTokenShares The number of osToken shares to redeem
   * @param owner The address of the position owner to redeem from
   * @param receiver The address of the receiver of the redeemed assets
   */
  function redeemOsToken(uint256 osTokenShares, address owner, address receiver) external;

  /**
   * @notice Transfers minted osToken shares to the OsTokenVaultEscrow contract, enters the exit queue for staked assets
   * @param osTokenShares The number of osToken shares to transfer
   * @return positionTicket The exit position ticket
   */
  function transferOsTokenPositionToEscrow(
    uint256 osTokenShares
  ) external returns (uint256 positionTicket);
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

/**
 * @title IOsTokenVaultController
 * @author StakeWise
 * @notice Defines the interface for the OsTokenVaultController contract
 */
interface IOsTokenVaultController {
  /**
   * @notice Event emitted on minting shares
   * @param vault The address of the Vault
   * @param receiver The address that received the shares
   * @param assets The number of assets collateralized
   * @param shares The number of tokens the owner received
   */
  event Mint(address indexed vault, address indexed receiver, uint256 assets, uint256 shares);

  /**
   * @notice Event emitted on burning shares
   * @param vault The address of the Vault
   * @param owner The address that owns the shares
   * @param assets The total number of assets withdrawn
   * @param shares The total number of shares burned
   */
  event Burn(address indexed vault, address indexed owner, uint256 assets, uint256 shares);

  /**
   * @notice Event emitted on state update
   * @param profitAccrued The profit accrued since the last update
   * @param treasuryShares The number of shares minted for the treasury
   * @param treasuryAssets The number of assets minted for the treasury
   */
  event StateUpdated(uint256 profitAccrued, uint256 treasuryShares, uint256 treasuryAssets);

  /**
   * @notice Event emitted on capacity update
   * @param capacity The amount after which the OsToken stops accepting deposits
   */
  event CapacityUpdated(uint256 capacity);

  /**
   * @notice Event emitted on treasury address update
   * @param treasury The new treasury address
   */
  event TreasuryUpdated(address indexed treasury);

  /**
   * @notice Event emitted on fee percent update
   * @param feePercent The new fee percent
   */
  event FeePercentUpdated(uint16 feePercent);

  /**
   * @notice Event emitted on average reward per second update
   * @param avgRewardPerSecond The new average reward per second
   */
  event AvgRewardPerSecondUpdated(uint256 avgRewardPerSecond);

  /**
   * @notice Event emitted on keeper address update
   * @param keeper The new keeper address
   */
  event KeeperUpdated(address keeper);

  /**
   * @notice The OsToken capacity
   * @return The amount after which the OsToken stops accepting deposits
   */
  function capacity() external view returns (uint256);

  /**
   * @notice The DAO treasury address that receives OsToken fees
   * @return The address of the treasury
   */
  function treasury() external view returns (address);

  /**
   * @notice The fee percent (multiplied by 100)
   * @return The fee percent applied by the OsToken on the rewards
   */
  function feePercent() external view returns (uint64);

  /**
   * @notice The address that can update avgRewardPerSecond
   * @return The address of the keeper contract
   */
  function keeper() external view returns (address);

  /**
   * @notice The average reward per second used to mint OsToken rewards
   * @return The average reward per second earned by the Vaults
   */
  function avgRewardPerSecond() external view returns (uint256);

  /**
   * @notice The fee per share used for calculating the fee for every position
   * @return The cumulative fee per share
   */
  function cumulativeFeePerShare() external view returns (uint256);

  /**
   * @notice The total number of shares controlled by the OsToken
   * @return The total number of shares
   */
  function totalShares() external view returns (uint256);

  /**
   * @notice Total assets controlled by the OsToken
   * @return The total amount of the underlying asset that is "managed" by OsToken
   */
  function totalAssets() external view returns (uint256);

  /**
   * @notice Converts shares to assets
   * @param assets The amount of assets to convert to shares
   * @return shares The amount of shares that the OsToken would exchange for the amount of assets provided
   */
  function convertToShares(uint256 assets) external view returns (uint256 shares);

  /**
   * @notice Converts assets to shares
   * @param shares The amount of shares to convert to assets
   * @return assets The amount of assets that the OsToken would exchange for the amount of shares provided
   */
  function convertToAssets(uint256 shares) external view returns (uint256 assets);

  /**
   * @notice Updates rewards and treasury fee checkpoint for the OsToken
   */
  function updateState() external;

  /**
   * @notice Mint OsToken shares. Can only be called by the registered vault.
   * @param receiver The address that will receive the shares
   * @param shares The amount of shares to mint
   * @return assets The amount of assets minted
   */
  function mintShares(address receiver, uint256 shares) external returns (uint256 assets);

  /**
   * @notice Burn shares for withdrawn assets. Can only be called by the registered vault.
   * @param owner The address that owns the shares
   * @param shares The amount of shares to burn
   * @return assets The amount of assets withdrawn
   */
  function burnShares(address owner, uint256 shares) external returns (uint256 assets);

  /**
   * @notice Update treasury address. Can only be called by the owner.
   * @param _treasury The new treasury address
   */
  function setTreasury(address _treasury) external;

  /**
   * @notice Update capacity. Can only be called by the owner.
   * @param _capacity The amount after which the OsToken stops accepting deposits
   */
  function setCapacity(uint256 _capacity) external;

  /**
   * @notice Update fee percent. Can only be called by the owner. Cannot be larger than 10 000 (100%).
   * @param _feePercent The new fee percent
   */
  function setFeePercent(uint16 _feePercent) external;

  /**
   * @notice Update keeper address. Can only be called by the owner.
   * @param _keeper The new keeper address
   */
  function setKeeper(address _keeper) external;

  /**
   * @notice Updates average reward per second. Can only be called by the keeper.
   * @param _avgRewardPerSecond The new average reward per second
   */
  function setAvgRewardPerSecond(uint256 _avgRewardPerSecond) external;
}

// SPDX-License-Identifier: AGPL-3.0-only

pragma solidity ^0.8.26;

import {IKeeperRewards} from '@stakewise-core/interfaces/IKeeperRewards.sol';

/**
 * @title IVaultUserLtvTracker
 * @author StakeWise
 * @notice Defines the interface for the VaultUserLtvTracker contract
 */
interface IVaultUserLtvTracker {
    /**
     * @notice Updates the vault's max LTV user
     * @param vault The address of the vault
     * @param user The address of the user
     * @param harvestParams The harvest params to use for updating the vault state
     */
    function updateVaultMaxLtvUser(
        address vault,
        address user,
        IKeeperRewards.HarvestParams calldata harvestParams
    ) external;

    /**
     * @notice Gets the current highest LTV for the vault
     * @param vault The address of the vault
     * @param harvestParams The harvest params to use for updating the vault state
     * @return The current highest LTV for the vault
     */
    function getVaultMaxLtv(
        address vault,
        IKeeperRewards.HarvestParams calldata harvestParams
    ) external returns (uint256);
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

import {IERC5267} from '@openzeppelin/contracts/interfaces/IERC5267.sol';

/**
 * @title IKeeperOracles
 * @author StakeWise
 * @notice Defines the interface for the KeeperOracles contract
 */
interface IKeeperOracles is IERC5267 {
  /**
   * @notice Event emitted on the oracle addition
   * @param oracle The address of the added oracle
   */
  event OracleAdded(address indexed oracle);

  /**
   * @notice Event emitted on the oracle removal
   * @param oracle The address of the removed oracle
   */
  event OracleRemoved(address indexed oracle);

  /**
   * @notice Event emitted on oracles config update
   * @param configIpfsHash The IPFS hash of the new config
   */
  event ConfigUpdated(string configIpfsHash);

  /**
   * @notice Function for verifying whether oracle is registered or not
   * @param oracle The address of the oracle to check
   * @return `true` for the registered oracle, `false` otherwise
   */
  function isOracle(address oracle) external view returns (bool);

  /**
   * @notice Total Oracles
   * @return The total number of oracles registered
   */
  function totalOracles() external view returns (uint256);

  /**
   * @notice Function for adding oracle to the set
   * @param oracle The address of the oracle to add
   */
  function addOracle(address oracle) external;

  /**
   * @notice Function for removing oracle from the set
   * @param oracle The address of the oracle to remove
   */
  function removeOracle(address oracle) external;

  /**
   * @notice Function for updating the config IPFS hash
   * @param configIpfsHash The new config IPFS hash
   */
  function updateConfig(string calldata configIpfsHash) external;
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

import {IVaultAdmin} from './IVaultAdmin.sol';

/**
 * @title IVaultFee
 * @author StakeWise
 * @notice Defines the interface for the VaultFee contract
 */
interface IVaultFee is IVaultAdmin {
  /**
   * @notice Event emitted on fee recipient update
   * @param caller The address of the function caller
   * @param feeRecipient The address of the new fee recipient
   */
  event FeeRecipientUpdated(address indexed caller, address indexed feeRecipient);

  /**
   * @notice The Vault's fee recipient
   * @return The address of the Vault's fee recipient
   */
  function feeRecipient() external view returns (address);

  /**
   * @notice The Vault's fee percent in BPS
   * @return The fee percent applied by the Vault on the rewards
   */
  function feePercent() external view returns (uint16);

  /**
   * @notice Function for updating the fee recipient address. Can only be called by the admin.
   * @param _feeRecipient The address of the new fee recipient
   */
  function setFeeRecipient(address _feeRecipient) external;
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

import {IVaultState} from './IVaultState.sol';

/**
 * @title IVaultEnterExit
 * @author StakeWise
 * @notice Defines the interface for the VaultEnterExit contract
 */
interface IVaultEnterExit is IVaultState {
  /**
   * @notice Event emitted on deposit
   * @param caller The address that called the deposit function
   * @param receiver The address that received the shares
   * @param assets The number of assets deposited by the caller
   * @param shares The number of shares received
   * @param referrer The address of the referrer
   */
  event Deposited(
    address indexed caller,
    address indexed receiver,
    uint256 assets,
    uint256 shares,
    address referrer
  );

  /**
   * @notice Event emitted on redeem
   * @param owner The address that owns the shares
   * @param receiver The address that received withdrawn assets
   * @param assets The total number of withdrawn assets
   * @param shares The total number of withdrawn shares
   */
  event Redeemed(address indexed owner, address indexed receiver, uint256 assets, uint256 shares);

  /**
   * @notice Event emitted on shares added to the exit queue
   * @param owner The address that owns the shares
   * @param receiver The address that will receive withdrawn assets
   * @param positionTicket The exit queue ticket that was assigned to the position
   * @param shares The number of shares that queued for the exit
   */
  event ExitQueueEntered(
    address indexed owner,
    address indexed receiver,
    uint256 positionTicket,
    uint256 shares
  );

  /**
   * @notice Event emitted on shares added to the V2 exit queue (deprecated)
   * @param owner The address that owns the shares
   * @param receiver The address that will receive withdrawn assets
   * @param positionTicket The exit queue ticket that was assigned to the position
   * @param shares The number of shares that queued for the exit
   * @param assets The number of assets that queued for the exit
   */
  event V2ExitQueueEntered(
    address indexed owner,
    address indexed receiver,
    uint256 positionTicket,
    uint256 shares,
    uint256 assets
  );

  /**
   * @notice Event emitted on claim of the exited assets
   * @param receiver The address that has received withdrawn assets
   * @param prevPositionTicket The exit queue ticket received after the `enterExitQueue` call
   * @param newPositionTicket The new exit queue ticket in case not all the shares were withdrawn. Otherwise 0.
   * @param withdrawnAssets The total number of assets withdrawn
   */
  event ExitedAssetsClaimed(
    address indexed receiver,
    uint256 prevPositionTicket,
    uint256 newPositionTicket,
    uint256 withdrawnAssets
  );

  /**
   * @notice Locks shares to the exit queue. The shares continue earning rewards until they will be burned by the Vault.
   * @param shares The number of shares to lock
   * @param receiver The address that will receive assets upon withdrawal
   * @return positionTicket The position ticket of the exit queue. Returns uint256 max if no ticket created.
   */
  function enterExitQueue(
    uint256 shares,
    address receiver
  ) external returns (uint256 positionTicket);

  /**
   * @notice Get the exit queue index to claim exited assets from
   * @param positionTicket The exit queue position ticket to get the index for
   * @return The exit queue index that should be used to claim exited assets.
   *         Returns -1 in case such index does not exist.
   */
  function getExitQueueIndex(uint256 positionTicket) external view returns (int256);

  /**
   * @notice Calculates the number of shares and assets that can be claimed from the exit queue.
   * @param receiver The address that will receive assets upon withdrawal
   * @param positionTicket The exit queue ticket received after the `enterExitQueue` call
   * @param timestamp The timestamp when the shares entered the exit queue
   * @param exitQueueIndex The exit queue index at which the shares were burned. It can be looked up by calling `getExitQueueIndex`.
   * @return leftTickets The number of tickets left in the queue
   * @return exitedTickets The number of tickets that have already exited
   * @return exitedAssets The number of assets that can be claimed
   */
  function calculateExitedAssets(
    address receiver,
    uint256 positionTicket,
    uint256 timestamp,
    uint256 exitQueueIndex
  ) external view returns (uint256 leftTickets, uint256 exitedTickets, uint256 exitedAssets);

  /**
   * @notice Claims assets that were withdrawn by the Vault. It can be called only after the `enterExitQueue` call by the `receiver`.
   * @param positionTicket The exit queue ticket received after the `enterExitQueue` call
   * @param timestamp The timestamp when the assets entered the exit queue
   * @param exitQueueIndex The exit queue index at which the shares were burned.
   *        It can be looked up by calling `getExitQueueIndex`.
   */
  function claimExitedAssets(
    uint256 positionTicket,
    uint256 timestamp,
    uint256 exitQueueIndex
  ) external;
}

File 11 of 12 : IERC5267.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.20;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}

// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.22;

/**
 * @title IVaultState
 * @author StakeWise
 * @notice Defines the interface for the VaultAdmin contract
 */
interface IVaultAdmin {
  /**
   * @notice Event emitted on metadata ipfs hash update
   * @param caller The address of the function caller
   * @param metadataIpfsHash The new metadata IPFS hash
   */
  event MetadataUpdated(address indexed caller, string metadataIpfsHash);

  /**
   * @notice The Vault admin
   * @return The address of the Vault admin
   */
  function admin() external view returns (address);

  /**
   * @notice Function for updating the metadata IPFS hash. Can only be called by Vault admin.
   * @param metadataIpfsHash The new metadata IPFS hash
   */
  function setMetadata(string calldata metadataIpfsHash) external;
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@stakewise-core/=lib/v3-core/contracts/",
    "@aave-core/=lib/aave-v3-origin/src/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "aave-v3-core/=lib/aave-v3-origin/src/core/",
    "aave-v3-origin/=lib/aave-v3-origin/",
    "aave-v3-periphery/=lib/aave-v3-origin/src/periphery/",
    "ds-test/=lib/aave-v3-origin/lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "forge-gas-snapshot/=lib/forge-gas-snapshot/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    "solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/",
    "solidity-utils/=lib/aave-v3-origin/lib/solidity-utils/",
    "v3-core/=lib/v3-core/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"keeper","type":"address"},{"internalType":"address","name":"osTokenVaultController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MathOverflowedMulDiv","type":"error"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"components":[{"internalType":"bytes32","name":"rewardsRoot","type":"bytes32"},{"internalType":"int160","name":"reward","type":"int160"},{"internalType":"uint160","name":"unlockedMevReward","type":"uint160"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"internalType":"struct IKeeperRewards.HarvestParams","name":"harvestParams","type":"tuple"}],"name":"getVaultMaxLtv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"newUser","type":"address"},{"components":[{"internalType":"bytes32","name":"rewardsRoot","type":"bytes32"},{"internalType":"int160","name":"reward","type":"int160"},{"internalType":"uint160","name":"unlockedMevReward","type":"uint160"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"internalType":"struct IKeeperRewards.HarvestParams","name":"harvestParams","type":"tuple"}],"name":"updateVaultMaxLtvUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"vaultToUser","outputs":[{"internalType":"address","name":"user","type":"address"}],"stateMutability":"view","type":"function"}]

60c034607e57601f61074438819003918201601f19168301916001600160401b038311848410176082578084926040948552833981010312607e57604b60206045836096565b92016096565b6001600160a01b039182166080521660a05260405161069a90816100aa823960805181610245015260a051816102cf0152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b0382168203607e5756fe60806040526004361015610011575f80fd5b5f3560e01c8063291697ca146100ec578063ef740a3c1461007d5763f31e65ad1461003a575f80fd5b34610079576020366003190112610079576001600160a01b0361005b610149565b165f525f602052602060018060a01b0360405f205416604051908152f35b5f80fd5b3461007957604036600319011261007957610096610149565b60243567ffffffffffffffff81116100795760806003198236030112610079576001600160a01b038083165f908152602081815260409091205490936100e493600401929190911690610205565b604051908152f35b3461007957606036600319011261007957610105610149565b602435906001600160a01b0382168203610079576044359167ffffffffffffffff8311610079576080600319843603011261007957610147926004019161015f565b005b600435906001600160a01b038216820361007957565b6001600160a01b038181165f8181526020819052604090205484831695919492168581146101c7576101958261019b9486610205565b93610205565b106101a4575050565b5f525f60205260405f20906bffffffffffffffffffffffff60a01b825416179055565b505050505050565b90601f8019910116810190811067ffffffffffffffff8211176101f157604052565b634e487b7160e01b5f52604160045260245ffd5b5f9290916001600160a01b031690811561059c57604051637db8130d60e11b81526001600160a01b039384166004820181905293602090829060249082907f0000000000000000000000000000000000000000000000000000000000000000165afa908115610556575f91610561575b5061047b575b50604051632764b59160e11b81526004810182905290602082602481865afa9182156103ee578492610433575b506040516303d1689d60e11b81526001600160801b039290921660048301526020826024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9182156103ee5784926103ff575b5081156103f9576040519063f04da65b60e01b82526004820152602081602481865afa80156103ee5784906103bb575b602091506024604051809581936303d1689d60e11b835260048301525afa9182156103b057839261037c575b5081156103775761037492506105a4565b90565b505090565b9091506020813d6020116103a8575b81610398602093836101cf565b810103126100795751905f610363565b3d915061038b565b6040513d85823e3d90fd5b506020813d6020116103e6575b816103d5602093836101cf565b810103126100795760209051610337565b3d91506103c8565b6040513d86823e3d90fd5b50505090565b9091506020813d60201161042b575b8161041b602093836101cf565b810103126100795751905f610307565b3d915061040e565b9091506020813d602011610473575b8161044f602093836101cf565b8101031261046f57516001600160801b038116810361046f57905f6102a8565b8380fd5b3d9150610442565b823b156100795760405190631a7ff55360e01b8252602060048301528035602483015260208101358060130b80910361007957604483015260408101356001600160a01b038116908190036100795760648301526060810135601e1982360301811215610079570160208135910167ffffffffffffffff8211610079578160051b918236038213610079576080608485015260a484018190526001600160fb1b03106100795760c483835f94829484840137810103018183875af18015610556571561027b5761054e9193505f906101cf565b5f915f61027b565b6040513d5f823e3d90fd5b90506020813d602011610594575b8161057c602093836101cf565b8101031261007957518015158103610079575f610275565b3d915061056f565b505050505f90565b90670de0b6b3a76400008202905f19670de0b6b3a7640000840992828085109403938085039414610643578382111561063457670de0b6b3a7640000829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b63227bc15360e01b5f5260045ffd5b5080925015610650570490565b634e487b7160e01b5f52601260045260245ffdfea264697066735822122048eed7f2a40104e5e42d1d985acffe97553109cebcbc1f87e20de4f9c3706dff64736f6c634300081a00330000000000000000000000006b5815467da09daa7dc83db21c9239d98bb487b50000000000000000000000002a261e60fb14586b474c208b1b7ac6d0f5000306

Deployed Bytecode

0x60806040526004361015610011575f80fd5b5f3560e01c8063291697ca146100ec578063ef740a3c1461007d5763f31e65ad1461003a575f80fd5b34610079576020366003190112610079576001600160a01b0361005b610149565b165f525f602052602060018060a01b0360405f205416604051908152f35b5f80fd5b3461007957604036600319011261007957610096610149565b60243567ffffffffffffffff81116100795760806003198236030112610079576001600160a01b038083165f908152602081815260409091205490936100e493600401929190911690610205565b604051908152f35b3461007957606036600319011261007957610105610149565b602435906001600160a01b0382168203610079576044359167ffffffffffffffff8311610079576080600319843603011261007957610147926004019161015f565b005b600435906001600160a01b038216820361007957565b6001600160a01b038181165f8181526020819052604090205484831695919492168581146101c7576101958261019b9486610205565b93610205565b106101a4575050565b5f525f60205260405f20906bffffffffffffffffffffffff60a01b825416179055565b505050505050565b90601f8019910116810190811067ffffffffffffffff8211176101f157604052565b634e487b7160e01b5f52604160045260245ffd5b5f9290916001600160a01b031690811561059c57604051637db8130d60e11b81526001600160a01b039384166004820181905293602090829060249082907f0000000000000000000000006b5815467da09daa7dc83db21c9239d98bb487b5165afa908115610556575f91610561575b5061047b575b50604051632764b59160e11b81526004810182905290602082602481865afa9182156103ee578492610433575b506040516303d1689d60e11b81526001600160801b039290921660048301526020826024817f0000000000000000000000002a261e60fb14586b474c208b1b7ac6d0f50003066001600160a01b03165afa9182156103ee5784926103ff575b5081156103f9576040519063f04da65b60e01b82526004820152602081602481865afa80156103ee5784906103bb575b602091506024604051809581936303d1689d60e11b835260048301525afa9182156103b057839261037c575b5081156103775761037492506105a4565b90565b505090565b9091506020813d6020116103a8575b81610398602093836101cf565b810103126100795751905f610363565b3d915061038b565b6040513d85823e3d90fd5b506020813d6020116103e6575b816103d5602093836101cf565b810103126100795760209051610337565b3d91506103c8565b6040513d86823e3d90fd5b50505090565b9091506020813d60201161042b575b8161041b602093836101cf565b810103126100795751905f610307565b3d915061040e565b9091506020813d602011610473575b8161044f602093836101cf565b8101031261046f57516001600160801b038116810361046f57905f6102a8565b8380fd5b3d9150610442565b823b156100795760405190631a7ff55360e01b8252602060048301528035602483015260208101358060130b80910361007957604483015260408101356001600160a01b038116908190036100795760648301526060810135601e1982360301811215610079570160208135910167ffffffffffffffff8211610079578160051b918236038213610079576080608485015260a484018190526001600160fb1b03106100795760c483835f94829484840137810103018183875af18015610556571561027b5761054e9193505f906101cf565b5f915f61027b565b6040513d5f823e3d90fd5b90506020813d602011610594575b8161057c602093836101cf565b8101031261007957518015158103610079575f610275565b3d915061056f565b505050505f90565b90670de0b6b3a76400008202905f19670de0b6b3a7640000840992828085109403938085039414610643578382111561063457670de0b6b3a7640000829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b63227bc15360e01b5f5260045ffd5b5080925015610650570490565b634e487b7160e01b5f52601260045260245ffdfea264697066735822122048eed7f2a40104e5e42d1d985acffe97553109cebcbc1f87e20de4f9c3706dff64736f6c634300081a0033

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

0000000000000000000000006b5815467da09daa7dc83db21c9239d98bb487b50000000000000000000000002a261e60fb14586b474c208b1b7ac6d0f5000306

-----Decoded View---------------
Arg [0] : keeper (address): 0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5
Arg [1] : osTokenVaultController (address): 0x2A261e60FB14586B474C208b1B7AC6D0f5000306

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000006b5815467da09daa7dc83db21c9239d98bb487b5
Arg [1] : 0000000000000000000000002a261e60fb14586b474c208b1b7ac6d0f5000306


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.