Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 238 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Update Vault Max... | 23774070 | 1 hr ago | IN | 0 ETH | 0.00000553 | ||||
| Update Vault Max... | 23772343 | 7 hrs ago | IN | 0 ETH | 0.00000648 | ||||
| Update Vault Max... | 23770507 | 13 hrs ago | IN | 0 ETH | 0.00002416 | ||||
| Update Vault Max... | 23768724 | 19 hrs ago | IN | 0 ETH | 0.00001338 | ||||
| Update Vault Max... | 23768723 | 19 hrs ago | IN | 0 ETH | 0.00002087 | ||||
| Update Vault Max... | 23759775 | 2 days ago | IN | 0 ETH | 0.0000043 | ||||
| Update Vault Max... | 23758038 | 2 days ago | IN | 0 ETH | 0.00000369 | ||||
| Update Vault Max... | 23756192 | 2 days ago | IN | 0 ETH | 0.00000398 | ||||
| Update Vault Max... | 23754400 | 2 days ago | IN | 0 ETH | 0.00001248 | ||||
| Update Vault Max... | 23752614 | 3 days ago | IN | 0 ETH | 0.00000781 | ||||
| Update Vault Max... | 23750883 | 3 days ago | IN | 0 ETH | 0.00001509 | ||||
| Update Vault Max... | 23749039 | 3 days ago | IN | 0 ETH | 0.00011013 | ||||
| Update Vault Max... | 23747251 | 3 days ago | IN | 0 ETH | 0.00008651 | ||||
| Update Vault Max... | 23745466 | 4 days ago | IN | 0 ETH | 0.00001023 | ||||
| Update Vault Max... | 23743741 | 4 days ago | IN | 0 ETH | 0.00001722 | ||||
| Update Vault Max... | 23741888 | 4 days ago | IN | 0 ETH | 0.00007462 | ||||
| Update Vault Max... | 23740102 | 4 days ago | IN | 0 ETH | 0.00005541 | ||||
| Update Vault Max... | 23738313 | 5 days ago | IN | 0 ETH | 0.00001782 | ||||
| Update Vault Max... | 23736569 | 5 days ago | IN | 0 ETH | 0.00002862 | ||||
| Update Vault Max... | 23734744 | 5 days ago | IN | 0 ETH | 0.00004854 | ||||
| Update Vault Max... | 23732959 | 5 days ago | IN | 0 ETH | 0.00002405 | ||||
| Update Vault Max... | 23731172 | 6 days ago | IN | 0 ETH | 0.00001738 | ||||
| Update Vault Max... | 23729437 | 6 days ago | IN | 0 ETH | 0.0000455 | ||||
| Update Vault Max... | 23727602 | 6 days ago | IN | 0 ETH | 0.00030951 | ||||
| Update Vault Max... | 23725820 | 6 days ago | IN | 0 ETH | 0.00003809 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
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
Contract Source Code (Solidity Standard Json-Input format)
// 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;
}// 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;
}{
"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
- No Contract Security Audit Submitted- Submit Audit Here
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"}]Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.