Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 18152871 | 2 hrs ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PropLib
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 1 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC20, SafeERC20} from "lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC4626} from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IAsset} from "src/interfaces/utils/tokens/IAsset.sol";
import {IPositionManager} from "src/interfaces/utils/IPositionManager.sol";
import {IBorrowerOperations} from "src/interfaces/utils/IBorrowerOperations.sol";
import {ILSTCollateralVault} from "src/interfaces/utils/ILSTCollateralVault.sol";
import {IEverlongCore} from "src/interfaces/core/IEverlongCore.sol";
import {IPriceFeed} from "src/interfaces/core/oracles/IPriceFeed.sol";
import {IBaseManagedLeveragedVaultGetters} from "src/interfaces/core/mlv/helpers/base/IBaseManagedLeveragedVaultGetters.sol";
import {PriceLib} from "src/libraries/PriceLib.sol";
/**
* @title PropLib
* @notice This contract implements a managed leveraged vault for the CDP protocol.
* @dev `$.collateral` is different that `asset()`, the first is a CDP CollateralVault, the former is also the asset of the CollateralVault.
*/
library PropLib {
using SafeERC20 for IERC20;
using PriceLib for uint256;
enum PositionStatus { nonExistent, active, closedByOwner, closedByLiquidation, closedByRedemption }
enum Tolerance { ABOVE, BOTH }
uint8 constant MAX_BORROWING_FEE_MULTIPLIER = 5; // x5
uint256 constant MIN_OPERATION_ICR = 0.2e18; // 20% above CCR (relative)
uint256 constant WAD = 1e18;
error AlreadyOpened();
error BelowCR(uint256 currentICR);
error SurpassedMaxFeePercentage(uint256 maxFeePercentage, uint256 constrainedMaxFeePercentage);
error VaultSlippage(uint256 minCollVaultShares, uint256 mintedShares);
event NewBorrowerOperations(address borrowerOperations);
event NewPositionManager(address positionManager);
struct Context {
address asset;
IPositionManager positionManager;
IBorrowerOperations borrowerOperations;
IERC20 collateral;
IEverlongCore everlongCore;
IBaseManagedLeveragedVaultGetters getters;
}
function _withdrawDebt(Context memory $, bytes memory withdrawDebtPayload, uint256 _debtTokenAmount) external {
(
uint256 _maxFeePercentage,
address _upperHint,
address _lowerHint
) = abi.decode(
withdrawDebtPayload,
(uint256, address, address)
);
_checkMaxFeePercentage($, _maxFeePercentage);
$.borrowerOperations.withdrawDebt(
address($.positionManager),
address(this),
_maxFeePercentage,
_debtTokenAmount,
_upperHint,
_lowerHint
);
}
function _repayDebt(
Context memory $,
bytes memory repayDebtPayload,
uint256 debtTokenAmount
) external {
(
address _upperHint,
address _lowerHint
) = abi.decode(
repayDebtPayload,
(address, address)
);
$.borrowerOperations.repayDebt(
address($.positionManager),
address(this),
debtTokenAmount,
_upperHint,
_lowerHint
);
}
function _addColl(
Context memory $,
bytes memory addCollateralPayload,
uint256 coll
) external {
(
address upperHint,
address lowerHint
) = abi.decode(
addCollateralPayload,
(address, address)
);
$.collateral.forceApprove(address($.borrowerOperations), coll);
$.borrowerOperations.addColl(
address($.positionManager),
address(this),
coll,
upperHint,
lowerHint
);
}
function _modifyCollAndRepayDebt(
Context memory $,
bytes memory modifyPositionPayload,
int256 missingExposure,
uint256 debt
) external {
(
address upperHint,
address lowerHint
) = abi.decode(modifyPositionPayload, (address, address));
bool isCollDeposit = missingExposure >= 0;
uint256 collDeposit = isCollDeposit ? uint256(missingExposure) : 0;
uint256 collWithdrawal = isCollDeposit ? 0 : uint256(-missingExposure);
if (missingExposure != 0 || debt != 0) {
$.collateral.forceApprove(address($.borrowerOperations), collDeposit);
$.borrowerOperations.adjustPosition({
positionManager: address($.positionManager),
account: address(this),
_maxFeePercentage: 0,
_collDeposit: collDeposit,
_collWithdrawal: collWithdrawal,
_debtChange: debt,
_isDebtIncrease: false,
_upperHint: upperHint,
_lowerHint: lowerHint
});
}
}
function _repayDebtAndWithdrawCollateral(
Context memory $,
bytes memory modifyPositionPayload,
uint256 collToReceive,
uint256 receivedDebtToken
) external {
(
address upperHint,
address lowerHint
) = abi.decode(modifyPositionPayload, (address, address));
$.borrowerOperations.adjustPosition({
positionManager: address($.positionManager),
account: address(this),
_maxFeePercentage: 0,
_collDeposit: 0,
_collWithdrawal: collToReceive,
_debtChange: receivedDebtToken,
_isDebtIncrease: false,
_upperHint: upperHint,
_lowerHint: lowerHint
});
}
function _addCollAndWithdrawDebt(
Context memory $,
bytes memory depositPayload,
uint256 collVaultShares,
uint256 debtTokenToReceive
) external {
(
uint256 maxFeePercentage,
address upperHint,
address lowerHint
) = abi.decode(
depositPayload,
(uint256, address, address)
);
IERC20(address($.collateral)).forceApprove(address($.borrowerOperations), collVaultShares);
$.borrowerOperations.adjustPosition({
positionManager: address($.positionManager),
account: address(this),
_maxFeePercentage: maxFeePercentage,
_collDeposit: collVaultShares,
_collWithdrawal: 0,
_debtChange: debtTokenToReceive,
_isDebtIncrease: true,
_upperHint: upperHint,
_lowerHint: lowerHint
});
}
function _openPosition(
Context memory $,
bytes memory openPositionPayload
) external {
(
uint256 _maxFeePercentage,
uint256 _debtMinted,
address _upperHint,
address _lowerHint
) = abi.decode(openPositionPayload, (uint256, uint256, address, address));
uint256 status = $.positionManager.getPositionStatus(address(this));
if (PositionStatus(status) == PositionStatus.active) revert AlreadyOpened();
uint256 collVaultShares = $.collateral.balanceOf(address(this));
collVaultShares += _claimCollateral($);
$.collateral.forceApprove(address($.borrowerOperations), collVaultShares);
$.borrowerOperations.openPosition(
address($.positionManager),
address(this),
_maxFeePercentage,
collVaultShares,
_debtMinted,
_upperHint,
_lowerHint
);
}
function _claimCollateral(Context memory $) private returns (uint256 collVaultAmount) {
IPositionManager positionManager = $.positionManager;
collVaultAmount = positionManager.surplusBalances(address(this));
if (collVaultAmount != 0) {
positionManager.claimCollateral(address(this), address(this));
}
}
function _preDeposit(Context memory $, uint256 assetsAmount) external returns (uint256 coll) {
IERC20($.asset).forceApprove(address($.collateral), assetsAmount);
coll = ILSTCollateralVault(address($.collateral)).deposit(assetsAmount, address(this));
}
function _preRedeemEffects(Context memory $) external view {
// Position should be above a certain threshold (MIN_OPERATION_ICR) over closest possible liquidation CR (CCR or MCR)
uint256 CCR = $.borrowerOperations.CORE().CCR();
uint256 minICROverCCR = CCR + (MIN_OPERATION_ICR * (CCR - WAD) / WAD); // Relative
uint256 mincICROverMCR = $.positionManager.MCR() + MIN_OPERATION_ICR; // Absolute
uint256 minICR = Math.max(minICROverCCR, mincICROverMCR);
uint256 currentICR = $.getters.getCurrentPositionICR();
if (currentICR < minICR) revert BelowCR(currentICR);
}
function _afterRedeemEffects(Context memory $, address collVaultAsset, uint256 coll, address receiver, bytes memory) external returns (uint256 assets) {
uint256 prevIdleAssets = IERC20(collVaultAsset).balanceOf(receiver);
ILSTCollateralVault(address($.collateral)).redeem(coll, receiver, address(this));
assets = IERC20(collVaultAsset).balanceOf(receiver) - prevIdleAssets;
}
function _collConversion(Context memory $, uint256 assets) external view returns (uint256 coll) {
coll = ILSTCollateralVault(address($.collateral)).convertToShares(assets);
}
function _getPositionCollAndDebt(Context memory $) external view returns (uint256 coll, uint256 debt) {
(coll, debt) = $.positionManager.getPositionCollAndDebt(address(this));
}
function _pullRewards(Context memory $) external {
ILSTCollateralVault(address($.collateral)).pullRewards();
}
function _collateralDecimals() external pure returns (uint8) {
return 18; // COLL_VAULT_DECIMALS
}
function _checkMaxFeePercentage(
Context memory $,
uint256 maxFeePercentage
) public view {
uint256 constrainedMaxFeePercentage = $.positionManager.borrowingFeeFloor() * MAX_BORROWING_FEE_MULTIPLIER;
if (maxFeePercentage > constrainedMaxFeePercentage) {
revert SurpassedMaxFeePercentage(maxFeePercentage, constrainedMaxFeePercentage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC4626.sol)
pragma solidity ^0.8.0;
import "../token/ERC20/IERC20.sol";
import "../token/ERC20/extensions/IERC20Metadata.sol";
/**
* @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in
* https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].
*
* _Available since v4.7._
*/
interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the total amount of the underlying asset that is “managed” by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(
uint256 assets,
address receiver,
address owner
) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(
uint256 shares,
address receiver,
address owner
) external returns (uint256 assets);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @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 up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (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; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1);
///////////////////////////////////////////////
// 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.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
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 (rounding == Rounding.Up && 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 down.
*
* 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* 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 + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* 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 10, 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 + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";
interface IAsset is IERC20 {
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC3156FlashBorrower} from "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IFactory} from "src/interfaces/utils/IFactory.sol";
interface IPositionManager {
event BaseRateUpdated(uint256 _baseRate);
event CollateralSent(address _to, uint256 _amount);
event LTermsUpdated(uint256 _L_collateral, uint256 _L_debt);
event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime);
event Redemption(
address indexed _redeemer,
uint256 _attemptedDebtAmount,
uint256 _actualDebtAmount,
uint256 _collateralSent,
uint256 _collateralFee
);
event SystemSnapshotsUpdated(uint256 _totalStakesSnapshot, uint256 _totalCollateralSnapshot);
event TotalStakesUpdated(uint256 _newTotalStakes);
event PositionIndexUpdated(address _borrower, uint256 _newIndex);
event PositionSnapshotsUpdated(uint256 _L_collateral, uint256 _L_debt);
event PositionUpdated(address indexed _borrower, uint256 _debt, uint256 _coll, uint256 _stake, uint8 _operation);
function addCollateralSurplus(address borrower, uint256 collSurplus) external;
function applyPendingRewards(address _borrower) external returns (uint256 coll, uint256 debt);
function claimCollateral(address borrower, address _receiver) external;
function closePosition(address _borrower, address _receiver, uint256 collAmount, uint256 debtAmount) external;
function closePositionByLiquidation(address _borrower) external;
function setCollVaultRouter(address _collVaultRouter) external;
function collectInterests() external;
function decayBaseRateAndGetBorrowingFee(uint256 _debt) external returns (uint256);
function decreaseDebtAndSendCollateral(address account, uint256 debt, uint256 coll) external;
function fetchPrice() external view returns (uint256);
function finalizeLiquidation(
address _liquidator,
uint256 _debt,
uint256 _coll,
uint256 _collSurplus,
uint256 _debtGasComp,
uint256 _collGasComp
) external;
function getEntireSystemBalances() external view returns (uint256, uint256, uint256);
function movePendingPositionRewardsToActiveBalances(uint256 _debt, uint256 _collateral) external;
function openPosition(
address _borrower,
uint256 _collateralAmount,
uint256 _compositeDebt,
uint256 NICR,
address _upperHint,
address _lowerHint
) external returns (uint256 stake, uint256 arrayIndex);
function redeemCollateral(
uint256 _debtAmount,
address _firstRedemptionHint,
address _upperPartialRedemptionHint,
address _lowerPartialRedemptionHint,
uint256 _partialRedemptionHintNICR,
uint256 _maxIterations,
uint256 _maxFeePercentage
) external;
function setAddresses(address _priceFeedAddress, address _sortedPositionsAddress, address _collateralToken) external;
function setParameters(
IFactory.DeploymentParams calldata _params
) external;
function setPaused(bool _paused) external;
function setPriceFeed(address _priceFeedAddress) external;
function startSunset() external;
function updateBalances() external;
function updatePositionFromAdjustment(
bool _isDebtIncrease,
uint256 _debtChange,
uint256 _netDebtChange,
bool _isCollIncrease,
uint256 _collChange,
address _upperHint,
address _lowerHint,
address _borrower,
address _receiver
) external returns (uint256, uint256, uint256);
function DEBT_GAS_COMPENSATION() external view returns (uint256);
function DECIMAL_PRECISION() external view returns (uint256);
function L_collateral() external view returns (uint256);
function L_debt() external view returns (uint256);
function MCR() external view returns (uint256);
function PERCENT_DIVISOR() external view returns (uint256);
function CORE() external view returns (address);
function SUNSETTING_INTEREST_RATE() external view returns (uint256);
function Positions(
address
)
external
view
returns (
uint256 debt,
uint256 coll,
uint256 stake,
uint8 status,
uint128 arrayIndex,
uint256 activeInterestIndex
);
function activeInterestIndex() external view returns (uint256);
function baseRate() external view returns (uint256);
function borrowerOperations() external view returns (address);
function borrowingFeeFloor() external view returns (uint256);
function collateralToken() external view returns (address);
function debtToken() external view returns (address);
function collVaultRouter() external view returns (address);
function defaultedCollateral() external view returns (uint256);
function defaultedDebt() external view returns (uint256);
function getBorrowingFee(uint256 _debt) external view returns (uint256);
function getBorrowingFeeWithDecay(uint256 _debt) external view returns (uint256);
function getBorrowingRate() external view returns (uint256);
function getBorrowingRateWithDecay() external view returns (uint256);
function getCurrentICR(address _borrower, uint256 _price) external view returns (uint256);
function getEntireDebtAndColl(
address _borrower
) external view returns (uint256 debt, uint256 coll, uint256 pendingDebtReward, uint256 pendingCollateralReward);
function getEntireSystemColl() external view returns (uint256);
function getEntireSystemDebt() external view returns (uint256);
function getNominalICR(address _borrower) external view returns (uint256);
function getPendingCollAndDebtRewards(address _borrower) external view returns (uint256, uint256);
function getRedemptionFeeWithDecay(uint256 _collateralDrawn) external view returns (uint256);
function getRedemptionRate() external view returns (uint256);
function getRedemptionRateWithDecay() external view returns (uint256);
function getTotalActiveCollateral() external view returns (uint256);
function getTotalActiveDebt() external view returns (uint256);
function getPositionCollAndDebt(address _borrower) external view returns (uint256 coll, uint256 debt);
function getPositionFromPositionOwnersArray(uint256 _index) external view returns (address);
function getPositionOwnersCount() external view returns (uint256);
function getPositionStake(address _borrower) external view returns (uint256);
function getPositionStatus(address _borrower) external view returns (uint256);
function guardian() external view returns (address);
function hasPendingRewards(address _borrower) external view returns (bool);
function interestPayable() external view returns (uint256);
function interestRate() external view returns (uint256);
function lastActiveIndexUpdate() external view returns (uint256);
function lastCollateralError_Redistribution() external view returns (uint256);
function lastDebtError_Redistribution() external view returns (uint256);
function lastFeeOperationTime() external view returns (uint256);
function liquidationManager() external view returns (address);
function maxBorrowingFee() external view returns (uint256);
function maxRedemptionFee() external view returns (uint256);
function maxSystemDebt() external view returns (uint256);
function minuteDecayFactor() external view returns (uint256);
function owner() external view returns (address);
function paused() external view returns (bool);
function priceFeed() external view returns (address);
function redemptionFeeFloor() external view returns (uint256);
function rewardSnapshots(address) external view returns (uint256 collateral, uint256 debt);
function sortedPositions() external view returns (address);
function sunsetting() external view returns (bool);
function surplusBalances(address) external view returns (uint256);
function systemDeploymentTime() external view returns (uint256);
function totalCollateralSnapshot() external view returns (uint256);
function totalStakes() external view returns (uint256);
function totalStakesSnapshot() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {ICore} from "./ICore.sol";
interface IBorrowerOperations {
struct Balances {
uint256[] collaterals;
uint256[] debts;
uint256[] prices;
}
event BorrowingFeePaid(address indexed borrower, uint256 amount);
event CollateralConfigured(address positionManager, address collateralToken);
event PositionCreated(address indexed _borrower, uint256 arrayIndex);
event PositionManagerRemoved(address positionManager);
event PositionUpdated(address indexed _borrower, uint256 _debt, uint256 _coll, uint256 stake, uint8 operation);
function addColl(
address positionManager,
address account,
uint256 _collateralAmount,
address _upperHint,
address _lowerHint
) external;
function adjustPosition(
address positionManager,
address account,
uint256 _maxFeePercentage,
uint256 _collDeposit,
uint256 _collWithdrawal,
uint256 _debtChange,
bool _isDebtIncrease,
address _upperHint,
address _lowerHint
) external;
function closePosition(address positionManager, address account) external;
function configureCollateral(address positionManager, address collateralToken) external;
function fetchBalances() external view returns (Balances memory balances);
function getGlobalSystemBalances() external view returns (uint256 totalPricedCollateral, uint256 totalDebt);
function getTCR() external view returns (uint256 globalTotalCollateralRatio);
function openPosition(
address positionManager,
address account,
uint256 _maxFeePercentage,
uint256 _collateralAmount,
uint256 _debtAmount,
address _upperHint,
address _lowerHint
) external;
function removePositionManager(address positionManager) external;
function repayDebt(
address positionManager,
address account,
uint256 _debtAmount,
address _upperHint,
address _lowerHint
) external;
function setDelegateApproval(address _delegate, bool _isApproved) external;
function setMinNetDebt(uint256 _minNetDebt) external;
function withdrawColl(
address positionManager,
address account,
uint256 _collWithdrawal,
address _upperHint,
address _lowerHint
) external;
function withdrawDebt(
address positionManager,
address account,
uint256 _maxFeePercentage,
uint256 _debtAmount,
address _upperHint,
address _lowerHint
) external;
function positionManagers(uint256) external view returns (address);
function checkRecoveryMode(uint256 TCR) external view returns (bool);
function DEBT_GAS_COMPENSATION() external view returns (uint256);
function DECIMAL_PRECISION() external view returns (uint256);
function PERCENT_DIVISOR() external view returns (uint256);
function CORE() external view returns (ICore);
function debtToken() external view returns (address);
function factory() external view returns (address);
function getCompositeDebt(uint256 _debt) external view returns (uint256);
function guardian() external view returns (address);
function isApprovedDelegate(address owner, address caller) external view returns (bool isApproved);
function minNetDebt() external view returns (uint256);
function owner() external view returns (address);
function positionManagersData(address) external view returns (address collateralToken, uint16 index);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {IBaseCollateralVault} from "src/interfaces/utils/IBaseCollateralVault.sol";
import {EmissionsLib} from "src/libraries/EmissionsLib.sol";
interface ILSTCollateralVault is IBaseCollateralVault {
struct LSTCollVaultStorage {
uint16 minPerformanceFee;
uint16 maxPerformanceFee;
uint16 performanceFee; // over yield, in basis points
/// @dev We currently don't know the lstVault implementation, but if it were to be possible for them to remove tokens from the rewardTokens
/// There would be no need to remove it from here since the amounts should continue being accounted for in the virtual balance
EnumerableSet.AddressSet rewardedTokens;
address _lstVault;
address mainRewardTokenVault;
address mainRewardToken;
address lstWrapper;
uint96 lastUpdate;
mapping(address tokenIn => uint) threshold;
}
struct LSTInitParams {
BaseInitParams _baseParams;
uint16 _minPerformanceFee;
uint16 _maxPerformanceFee;
uint16 _performanceFee; // over yield, in basis points
address _lstVault;
address _mainRewardTokenVault;
address _lstWrapper;
}
struct RebalanceParams {
address sentCurrency;
uint sentAmount;
address swapper;
bytes payload;
}
function rebalance(RebalanceParams calldata p) external;
function pullRewards() external;
function setUnlockRatePerSecond(address token, uint64 _unlockRatePerSecond) external;
function internalizeDonations(address[] memory tokens, uint128[] memory amounts) external;
function setPairThreshold(address tokenIn, uint thresholdInBP) external;
function setPerformanceFee(uint16 _performanceFee) external;
function setWithdrawFee(uint16 _withdrawFee) external;
function getBalance(address token) external view returns (uint);
function getBalanceOfWithFutureEmissions(address token) external view returns (uint);
function getFullProfitUnlockTimestamp(address token) external view returns (uint);
function unlockRatePerSecond(address token) external view returns (uint);
function getLockedEmissions(address token) external view returns (uint);
function getPerformanceFee() external view returns (uint16);
function rewardedTokens() external view returns (address[] memory);
function lstVault() external view returns (address);
function mainRewardToken() external view returns (address);
function mainRewardTokenVault() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
/**
* @title EverlongCore
* @author Everlong Labs
* @notice Single source of truth across all Everlong contracts for key administrative data
*/
interface IEverlongCore {
function owner() external view returns (address);
function feeReceiver() external view returns (address);
function priceFeed() external view returns (address);
function setFeeReceiver(address _feeReceiver) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IPriceFeed {
struct FeedType {
address spotOracle;
bool isCollVault;
}
event NewOracleRegistered(address token, address chainlinkAggregator, address underlyingDerivative);
event PriceFeedStatusUpdated(address token, address oracle, bool isWorking);
event PriceRecordUpdated(address indexed token, uint256 _price);
event NewCollVaultRegistered(address collVault, bool enable);
event NewSpotOracleRegistered(address token, address spotOracle);
function fetchPrice(address _token) external view returns (uint256);
function getMultiplePrices(address[] memory _tokens) external view returns (uint256[] memory prices);
function setOracle(
address _token,
address _chainlinkOracle,
uint32 _heartbeat,
uint16 _staleThreshold,
address underlyingDerivative
) external;
function whitelistCollateralVault(address _collateralVaultShareToken, bool enable) external;
function setSpotOracle(address _token, address _spotOracle) external;
function MAX_PRICE_DEVIATION_FROM_PREVIOUS_ROUND() external view returns (uint256);
function CORE() external view returns (address);
function RESPONSE_TIMEOUT() external view returns (uint256);
function TARGET_DIGITS() external view returns (uint256);
function guardian() external view returns (address);
function oracleRecords(
address
)
external
view
returns (
address chainLinkOracle,
uint8 decimals,
uint32 heartbeat,
uint16 staleThreshold,
address underlyingDerivative
);
function isCollVault(address _collateralVaultShareToken) external view returns (bool);
function isStableBPT(address _oracle) external view returns (bool);
function isWeightedBPT(address _oracle) external view returns (bool);
function getSpotOracle(address _token) external view returns (address);
function feedType(address _token) external view returns (FeedType memory);
function owner() external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IBaseManagedLeveragedVault} from "src/interfaces/core/mlv/base/IBaseManagedLeveragedVault.sol";
interface IBaseManagedLeveragedVaultGetters {
error PositionOutOfTargetCR(uint256 currentICR, uint256 targetICR, uint256 maxDelta);
error TotalAssetsDeviation(uint256 prevTotalAssets, uint256 newTotalAssets, uint256 maxDelta);
error VaultSlippage(uint256 expected, uint256 actual);
function getPrice(address token) external view returns (uint256);
function vault() external view returns (IBaseManagedLeveragedVault);
function getCollateralBalance() external view returns (uint256);
function getCollateralValue() external view returns (uint256);
function getCollateralValue(uint256 amount) external view returns (uint256);
function getDebtBalance() external view returns (uint256);
function getDebtValue() external view returns (uint256);
function getDebtValue(uint256 amount) external view returns (uint256);
function getCurrentPositionICR() external view returns (uint256);
function getTargetICR() external view returns (uint256);
function entryFeeInBP(uint256 amount, address caller) external view returns (uint256);
function exitFeeInBP(uint256 amount, address caller) external view returns (uint256);
function checkInvariantICR(uint256 currentICR, uint256 targetICR, IBaseManagedLeveragedVault.Tolerance tolerance) external view;
function checkMaxOperationCost(address inputToken, uint256 amountToSwap, uint256 prevTotalAssets) external view;
function computeNetColl(uint256 nectSurplusInAssets, uint256 collToReceive, uint256 prevTotalAssets) external view returns (uint256 netColl);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
library PriceLib {
using Math for uint;
// WAD adjusted result
function convertToValue(uint amount, uint price, uint8 decimals) internal pure returns (uint) {
return amount * price / 10 ** decimals;
}
function convertToAmount(uint amountInUsd, uint collPrice, uint8 collDecimals, Math.Rounding rounding) internal pure returns (uint) {
if (collPrice == 0 || amountInUsd == 0) {
return 0;
}
return amountInUsd.mulDiv(10 ** collDecimals, collPrice, rounding);
}
// Coll decimal adjust amount result
function convertAssetsToCollAmount(uint assets, uint collPrice, uint debtTokenPrice, uint8 vaultDecimals, uint8 collDecimals, Math.Rounding rounding) internal pure returns (uint) {
uint assetsUsdValue = assets.mulDiv(debtTokenPrice, 10 ** vaultDecimals, rounding);
if (collPrice != 0) {
return convertToAmount(assetsUsdValue, collPrice, collDecimals, rounding);
} else {
return 0;
}
}
function convertCollAmountToAssets(uint collAmount, uint collPrice, uint debtTokenPrice, uint8 vaultDecimals, uint8 collDecimals) internal pure returns (uint) {
uint collUsdValue = collAmount * collPrice / 10 ** collDecimals;
if (debtTokenPrice != 0) {
return collUsdValue * 10 ** vaultDecimals / debtTokenPrice;
} else {
return 0;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1363.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert Errors.FailedCall();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {Errors.FailedCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
* of an unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {Errors.FailedCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert Errors.FailedCall();
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC3156 FlashBorrower, as defined in
* https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].
*
* _Available since v4.1._
*/
interface IERC3156FlashBorrower {
/**
* @dev Receive a flash loan.
* @param initiator The initiator of the loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param fee The additional amount of tokens to repay.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
* @return The keccak256 hash of "IERC3156FlashBorrower.onFlashLoan"
*/
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
interface IFactory {
// commented values are suggested default parameters
struct DeploymentParams {
uint256 minuteDecayFactor; // 999037758833783000 (half life of 12 hours)
uint256 redemptionFeeFloor; // 1e18 / 1000 * 5 (0.5%)
uint256 maxRedemptionFee; // 1e18 (100%)
uint256 borrowingFeeFloor; // 1e18 / 1000 * 5 (0.5%)
uint256 maxBorrowingFee; // 1e18 / 100 * 5 (5%)
uint256 interestRateInBps; // 100 (1%)
uint256 maxDebt;
uint256 MCR; // 12 * 1e17 (120%)
address collVaultRouter; // set to address(0) if DenManager coll is not CollateralVault
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
interface ICore {
// --- Public variables ---
function metaCore() external view returns (address);
function startTime() external view returns (uint256);
function CCR() external view returns (uint256);
function dmBootstrapPeriod() external view returns (uint64);
function isPeriphery(address peripheryContract) external view returns (bool);
// --- External functions ---
function setPeripheryEnabled(address _periphery, bool _enabled) external;
function setPMBootstrapPeriod(address dm, uint64 _bootstrapPeriod) external;
function setNewCCR(uint256 _CCR) external;
function priceFeed() external view returns (address);
function owner() external view returns (address);
function pendingOwner() external view returns (address);
function guardian() external view returns (address);
function feeReceiver() external view returns (address);
function paused() external view returns (bool);
function lspBootstrapPeriod() external view returns (uint64);
function getLspEntryFee(address rebalancer) external view returns (uint16);
function getLspExitFee(address rebalancer) external view returns (uint16);
function interestProtocolShare() external view returns (uint16);
function defaultInterestReceiver() external view returns (address);
// --- Events ---
event CCRSet(uint256 initialCCR);
event PMBootstrapPeriodSet(address dm, uint64 bootstrapPeriod);
event PeripheryEnabled(address indexed periphery, bool enabled);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastValue;
// Update the index for the moved value
set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC4626, IERC20} from "@openzeppelin/contracts/interfaces/IERC4626.sol";
import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
import {EmissionsLib} from "src/libraries/EmissionsLib.sol";
interface IBaseCollateralVault is IERC4626, IERC1822Proxiable {
struct BaseInitParams {
uint16 _minWithdrawFee;
uint16 _maxWithdrawFee;
uint16 _withdrawFee;
address _metaCore;
// ERC4626
IERC20 _asset;
// ERC20
string _sharesName;
string _sharesSymbol;
}
struct BaseCollVaultStorage {
uint16 minWithdrawFee;
uint16 maxWithdrawFee;
uint16 withdrawFee; // over rewarded tokens, in basis points
uint8 assetDecimals;
address _metaCore;
// Second mapping of this struct is usless, but it's for retrocompatibility with LSTCollateralVault
EmissionsLib.BalanceData balanceData;
}
function initialize(BaseInitParams calldata params) external;
function totalAssets() external view returns (uint);
function fetchPrice() external view returns (uint);
function getPrice(address token) external view returns (uint);
function receiveDonations(address[] memory tokens, uint[] memory amounts, address receiver) external;
function setWithdrawFee(uint16 _withdrawFee) external;
function getBalance(address token) external view returns (uint);
function getWithdrawFee() external view returns (uint16);
function getEverlongCore() external view returns (address);
function getPriceFeed() external view returns (address);
function assetDecimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
library EmissionsLib {
using SafeCast for uint256;
uint64 constant internal DEFAULT_UNLOCK_RATE = 1e11; // 10% per second
uint64 constant internal MAX_UNLOCK_RATE = 1e12; // 100%
struct BalanceData {
mapping(address token => uint) balance;
mapping(address token => EmissionSchedule) emissionSchedule;
}
struct EmissionSchedule {
uint128 emissions;
uint64 lockTimestamp;
uint64 _unlockRatePerSecond; // rate points
}
error AmountCannotBeZero();
error EmissionRateExceedsMax();
// error UnsupportedEmissionConfig();
event EmissionsAdded(address indexed token, uint128 amount);
event EmissionsSub(address indexed token, uint128 amount);
event NewUnlockRatePerSecond(address indexed token, uint64 unlockRatePerSecond);
/// @dev zero _unlockRatePerSecond parameter resets rate back to DEFAULT_UNLOCK_RATE
function setUnlockRatePerSecond(BalanceData storage $, address token, uint64 _unlockRatePerSecond) internal {
if (_unlockRatePerSecond > MAX_UNLOCK_RATE) revert EmissionRateExceedsMax();
_addEmissions($, token, 0); // update lockTimestamp and emissions
$.emissionSchedule[token]._unlockRatePerSecond = _unlockRatePerSecond;
emit NewUnlockRatePerSecond(token, _unlockRatePerSecond);
}
function addEmissions(BalanceData storage $, address token, uint128 amount) internal {
if (amount == 0) revert AmountCannotBeZero();
_addEmissions($, token, amount);
emit EmissionsAdded(token, amount);
}
function _addEmissions(BalanceData storage $, address token, uint128 amount) private {
EmissionSchedule memory schedule = $.emissionSchedule[token];
uint256 _unlockTimestamp = unlockTimestamp(schedule);
uint128 nextEmissions = (lockedEmissions(schedule, _unlockTimestamp) + amount).toUint128();
schedule.emissions = nextEmissions;
schedule.lockTimestamp = block.timestamp.toUint64();
$.balance[token] += amount;
$.emissionSchedule[token] = schedule;
}
function subEmissions(BalanceData storage $, address token, uint128 amount) internal {
if (amount == 0) revert AmountCannotBeZero();
_subEmissions($, token, amount);
emit EmissionsSub(token, amount);
}
function _subEmissions(BalanceData storage $, address token, uint128 amount) private {
EmissionSchedule memory schedule = $.emissionSchedule[token];
uint256 _unlockTimestamp = unlockTimestamp(schedule);
uint128 nextEmissions = (lockedEmissions(schedule, _unlockTimestamp) - amount).toUint128();
schedule.emissions = nextEmissions;
schedule.lockTimestamp = block.timestamp.toUint64();
$.balance[token] -= amount;
$.emissionSchedule[token] = schedule;
}
/// @dev Doesn't include locked emissions
function unlockedEmissions(EmissionSchedule memory schedule) internal view returns (uint256) {
return schedule.emissions - lockedEmissions(schedule, unlockTimestamp(schedule));
}
function balanceOfWithFutureEmissions(BalanceData storage $, address token) internal view returns (uint256) {
return $.balance[token];
}
/**
* @notice Returns the unlocked token emissions
*/
function balanceOf(BalanceData storage $, address token) internal view returns (uint256) {
EmissionSchedule memory schedule = $.emissionSchedule[token];
return $.balance[token] - lockedEmissions(schedule, unlockTimestamp(schedule));
}
/**
* @notice Returns locked emissions
*/
function lockedEmissions(EmissionSchedule memory schedule, uint256 _unlockTimestamp) internal view returns (uint256) {
if (block.timestamp >= _unlockTimestamp) {
// all emissions were unlocked
return 0;
} else {
// emissions are still unlocking, calculate the amount of already unlocked emissions
uint256 secondsSinceLockup = block.timestamp - schedule.lockTimestamp;
// design decision - use dimensionless 'unlock rate units' to unlock emissions over a fixed time window
uint256 ratePointsUnlocked = unlockRatePerSecond(schedule) * secondsSinceLockup;
// emissions remainder is designed to be added to balance in unlockTimestamp
return schedule.emissions - ratePointsUnlocked * schedule.emissions / MAX_UNLOCK_RATE;
}
}
// timestamp at which all emissions are fully unlocked
function unlockTimestamp(EmissionSchedule memory schedule) internal pure returns (uint256) {
// ceil to account for remainder seconds left after integer division
return divRoundUp(MAX_UNLOCK_RATE, unlockRatePerSecond(schedule)) + schedule.lockTimestamp;
}
function unlockRatePerSecond(EmissionSchedule memory schedule) internal pure returns (uint256) {
return schedule._unlockRatePerSecond == 0 ? DEFAULT_UNLOCK_RATE : schedule._unlockRatePerSecond;
}
function divRoundUp(uint256 dividend, uint256 divisor) internal pure returns (uint256) {
return (dividend + divisor - 1) / divisor;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IBaseManagedLeveragedVault {
// --- Enums ------------------------------------------------
enum Tolerance { ABOVE, BOTH }
enum Operation { LEVERAGE, DELEVERAGE}
struct BaseInitParams {
IERC20 asset;
string name;
string symbol;
address everlongCore;
address debtToken;
address collateral;
uint16 maxDeviationICRinBP;
uint16 maxDeviationTotalAssetsInBP;
uint16 maxSlippageSwapInBP;
address keeper;
address targetICRHook;
address feeHook;
address getters;
}
// --- Errors ------------------------------------------------
error ZeroAmount();
error ZeroAddress();
error SurpassedPrecision(uint256 precision);
error AlreadyOpened();
error NotOwner(address caller);
error NotSupportedMethod();
error VaultSlippage(uint256 expected, uint256 actual);
// --- Events -----------------------------------------------
event NewTargetICRHook(address targetICRHook);
event NewKeeper(address keeper);
event NewMaxDeviationICRInBP(uint16 maxDeviationICRInBP);
event NewMaxDeviationTotalAssetsInBP(uint16 maxDeviationTotalAssetsInBP);
event NewMaxSlippageSwapInBP(uint16 maxSlippageSwapInBP);
event NewFeeHook(address feeHook);
event NewGetters(address getters);
// --- Functions ---------------------------------------------
function totalAssets() external view returns (uint256);
function setMaxDeviationICRinBP(uint16 _maxDeviationICRinBP) external;
function setMaxDeviationTotalAssetsInBP(uint16 _maxDeviationTotalAssetsInBP) external;
function setMaxSlippageSwapInBP(uint16 _maxSlippageSwapInBP) external;
function setKeeper(address _keeper) external;
function setTargetICRHook(address _targetICRHook) external;
function setFeeHook(address _feeHook) external;
function setGetters(address _getters) external;
function getPrice(address token) external view returns (uint256 scaledPriceInUsdWad);
function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory values);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822Proxiable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin-upgradeable/contracts/=lib/openzeppelin-contracts-upgradeable/contracts/",
"forge-std/=lib/forge-std/src/",
"@uniswap/v3-core/=lib/v3-core/",
"@uniswap/v3-periphery/=lib/v3-periphery/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"v3-core/=lib/v3-core/contracts/",
"v3-periphery/=lib/v3-periphery/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 1
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"AlreadyOpened","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentICR","type":"uint256"}],"name":"BelowCR","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"uint256","name":"maxFeePercentage","type":"uint256"},{"internalType":"uint256","name":"constrainedMaxFeePercentage","type":"uint256"}],"name":"SurpassedMaxFeePercentage","type":"error"},{"inputs":[{"internalType":"uint256","name":"minCollVaultShares","type":"uint256"},{"internalType":"uint256","name":"mintedShares","type":"uint256"}],"name":"VaultSlippage","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"borrowerOperations","type":"address"}],"name":"NewBorrowerOperations","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"positionManager","type":"address"}],"name":"NewPositionManager","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"contract IPositionManager","name":"positionManager","type":"IPositionManager"},{"internalType":"contract IBorrowerOperations","name":"borrowerOperations","type":"IBorrowerOperations"},{"internalType":"contract IERC20","name":"collateral","type":"IERC20"},{"internalType":"contract IEverlongCore","name":"everlongCore","type":"IEverlongCore"},{"internalType":"contract IBaseManagedLeveragedVaultGetters","name":"getters","type":"IBaseManagedLeveragedVaultGetters"}],"internalType":"struct PropLib.Context","name":"$","type":"tuple"},{"internalType":"uint256","name":"maxFeePercentage","type":"uint256"}],"name":"_checkMaxFeePercentage","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"contract IPositionManager","name":"positionManager","type":"IPositionManager"},{"internalType":"contract IBorrowerOperations","name":"borrowerOperations","type":"IBorrowerOperations"},{"internalType":"contract IERC20","name":"collateral","type":"IERC20"},{"internalType":"contract IEverlongCore","name":"everlongCore","type":"IEverlongCore"},{"internalType":"contract IBaseManagedLeveragedVaultGetters","name":"getters","type":"IBaseManagedLeveragedVaultGetters"}],"internalType":"struct PropLib.Context","name":"$","type":"tuple"},{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"_collConversion","outputs":[{"internalType":"uint256","name":"coll","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_collateralDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"contract IPositionManager","name":"positionManager","type":"IPositionManager"},{"internalType":"contract IBorrowerOperations","name":"borrowerOperations","type":"IBorrowerOperations"},{"internalType":"contract IERC20","name":"collateral","type":"IERC20"},{"internalType":"contract IEverlongCore","name":"everlongCore","type":"IEverlongCore"},{"internalType":"contract IBaseManagedLeveragedVaultGetters","name":"getters","type":"IBaseManagedLeveragedVaultGetters"}],"internalType":"struct PropLib.Context","name":"$","type":"tuple"}],"name":"_getPositionCollAndDebt","outputs":[{"internalType":"uint256","name":"coll","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"contract IPositionManager","name":"positionManager","type":"IPositionManager"},{"internalType":"contract IBorrowerOperations","name":"borrowerOperations","type":"IBorrowerOperations"},{"internalType":"contract IERC20","name":"collateral","type":"IERC20"},{"internalType":"contract IEverlongCore","name":"everlongCore","type":"IEverlongCore"},{"internalType":"contract IBaseManagedLeveragedVaultGetters","name":"getters","type":"IBaseManagedLeveragedVaultGetters"}],"internalType":"struct PropLib.Context","name":"$","type":"tuple"}],"name":"_preRedeemEffects","outputs":[],"stateMutability":"view","type":"function"}]Contract Creation Code
611674610034600b8282823980515f1a607314602857634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100ce575f3560e01c806320daa1e0146100d257806333b475a8146100e657806359492bb1146101075780635fc6e58d146101265780636113be14146101455780637d2584101461016457806385e9726d14610185578063badf3308146101a4578063bcc04622146101b7578063cf221848146101d6578063d1fc4acc146101f5578063e080c14c14610214578063eca6c04f1461023c578063ecc134c71461025b578063fe17eec41461026e575b5f80fd5b604051601281526020015b60405180910390f35b8180156100f1575f80fd5b50610105610100366004611221565b61028d565b005b818015610112575f80fd5b5061010561012136600461127d565b610320565b818015610131575f80fd5b506101056101403660046112c8565b610531565b818015610150575f80fd5b5061010561015f3660046112e2565b610586565b610177610172366004611337565b610609565b6040519081526020016100dd565b818015610190575f80fd5b5061017761019f366004611360565b61067d565b6101056101b23660046112c8565b6107eb565b8180156101c2575f80fd5b506101056101d1366004611221565b610a0c565b8180156101e1575f80fd5b506101056101f03660046112e2565b610aca565b818015610200575f80fd5b5061017761020f366004611337565b610b54565b6102276102223660046112c8565b610bc1565b604080519283526020830191909152016100dd565b818015610247575f80fd5b50610105610256366004611221565b610c3b565b610105610269366004611337565b610d37565b818015610279575f80fd5b506101056102883660046112e2565b610ddd565b5f80848060200190518101906102a391906113db565b9150915085604001516001600160a01b0316639efeaeb28760200151305f8089895f8a8a6040518a63ffffffff1660e01b81526004016102eb99989796959493929190611413565b5f604051808303815f87803b158015610302575f80fd5b505af1158015610314573d5f803e3d5ffd5b50505050505050505050565b5f805f80848060200190518101906103389190611463565b93509350935093505f86602001516001600160a01b0316631983fb40306040518263ffffffff1660e01b815260040161037191906114ac565b602060405180830381865afa15801561038c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103b091906114c0565b905060018160048111156103c6576103c66114d7565b60048111156103d7576103d76114d7565b036103f557604051630ed2159360e11b815260040160405180910390fd5b60608701516040516370a0823160e01b81525f916001600160a01b0316906370a08231906104279030906004016114ac565b602060405180830381865afa158015610442573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061046691906114c0565b905061047188610e59565b61047b90826114ff565b604089015160608a015191925061049c916001600160a01b03169083610f36565b60408089015160208a015191516326caa39d60e01b81526001600160a01b03928316600482015230602482015260448101899052606481018490526084810188905286831660a482015285831660c48201529116906326caa39d9060e4015f604051808303815f87803b158015610511575f80fd5b505af1158015610523573d5f803e3d5ffd5b505050505050505050505050565b80606001516001600160a01b0316634a25f38a6040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561056d575f80fd5b505af115801561057f573d5f803e3d5ffd5b5050505050565b5f805f8480602001905181019061059d9190611512565b9250925092506105ad8684610d37565b604080870151602088015191516361578f6560e11b81526001600160a01b0392831660048201523060248201526044810186905260648101879052848316608482015283831660a482015291169063c2af1eca9060c4016102eb565b60608201516040516363737ac960e11b8152600481018390525f916001600160a01b03169063c6e6f59290602401602060405180830381865afa158015610652573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061067691906114c0565b9392505050565b5f80856001600160a01b03166370a08231856040518263ffffffff1660e01b81526004016106ab91906114ac565b602060405180830381865afa1580156106c6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106ea91906114c0565b6060880151604051635d043b2960e11b8152600481018890526001600160a01b03878116602483015230604483015292935091169063ba087652906064016020604051808303815f875af1158015610744573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061076891906114c0565b506040516370a0823160e01b815281906001600160a01b038816906370a08231906107979088906004016114ac565b602060405180830381865afa1580156107b2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107d691906114c0565b6107e09190611553565b979650505050505050565b5f81604001516001600160a01b0316636b6c07746040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108509190611566565b6001600160a01b0316635733d58f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561088b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108af91906114c0565b90505f670de0b6b3a76400006108c58184611553565b6108d7906702c68af0bb140000611581565b6108e19190611598565b6108eb90836114ff565b90505f6702c68af0bb14000084602001516001600160a01b031663794e57246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610937573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095b91906114c0565b61096591906114ff565b90505f6109728383610ffe565b90505f8560a001516001600160a01b03166391b58ae86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109b5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d991906114c0565b905081811015610a045760405163f88713f760e01b8152600481018290526024015b60405180910390fd5b505050505050565b5f805f85806020019051810190610a239190611512565b925092509250610a4f87604001518689606001516001600160a01b0316610f369092919063ffffffff16565b86604001516001600160a01b0316639efeaeb288602001513086895f8a60018a8a6040518a63ffffffff1660e01b8152600401610a9499989796959493929190611413565b5f604051808303815f87803b158015610aab575f80fd5b505af1158015610abd573d5f803e3d5ffd5b5050505050505050505050565b5f8083806020019051810190610ae091906113db565b9150915084604001516001600160a01b031663a2e8dc0a8660200151308686866040518663ffffffff1660e01b8152600401610b209594939291906115b7565b5f604051808303815f87803b158015610b37575f80fd5b505af1158015610b49573d5f803e3d5ffd5b505050505050505050565b606082015182515f91610b71916001600160a01b03169084610f36565b6060830151604051636e553f6560e01b8152600481018490523060248201526001600160a01b0390911690636e553f65906044016020604051808303815f875af1158015610652573d5f803e3d5ffd5b5f8082602001516001600160a01b031663eb7a7f7e306040518263ffffffff1660e01b8152600401610bf391906114ac565b6040805180830381865afa158015610c0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3191906115e9565b9094909350915050565b5f8084806020019051810190610c5191906113db565b90925090505f808512159081610c67575f610c69565b855b90505f82610c7f57610c7a8761160b565b610c81565b5f5b905086151580610c9057508515155b15610b4957610cbb8960400151838b606001516001600160a01b0316610f369092919063ffffffff16565b88604001516001600160a01b0316639efeaeb28a60200151305f86868c5f8d8d6040518a63ffffffff1660e01b8152600401610cff99989796959493929190611413565b5f604051808303815f87803b158015610d16575f80fd5b505af1158015610d28573d5f803e3d5ffd5b50505050505050505050505050565b5f600560ff1683602001516001600160a01b03166331c7a2616040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d7d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da191906114c0565b610dab9190611581565b905080821115610dd8576040516385c914cb60e01b815260048101839052602481018290526044016109fb565b505050565b5f8083806020019051810190610df391906113db565b91509150610e1d85604001518487606001516001600160a01b0316610f369092919063ffffffff16565b84604001516001600160a01b031663fded3d358660200151308686866040518663ffffffff1660e01b8152600401610b209594939291906115b7565b602081015160405163ec38a05d60e01b81525f91906001600160a01b0382169063ec38a05d90610e8d9030906004016114ac565b602060405180830381865afa158015610ea8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ecc91906114c0565b91508115610f3057604051632b946eed60e11b8152306004820181905260248201526001600160a01b03821690635728ddda906044015f604051808303815f87803b158015610f19575f80fd5b505af1158015610f2b573d5f803e3d5ffd5b505050505b50919050565b5f836001600160a01b031663095ea7b38484604051602401610f59929190611625565b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050509050610f928482611015565b610ff857610fee84856001600160a01b031663095ea7b3865f604051602401610fbc929190611625565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061105e565b610ff8848261105e565b50505050565b5f81831161100c5781610676565b50815b92915050565b5f805f8060205f8651602088015f8a5af192503d91505f519050828015611054575081156110465780600114611054565b5f866001600160a01b03163b115b9695505050505050565b5f8060205f8451602086015f885af18061107d576040513d5f823e3d81fd5b50505f513d915081156110945780600114156110a1565b6001600160a01b0384163b155b15610ff85783604051635274afe760e01b81526004016109fb91906114ac565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b03811681146110e9575f80fd5b50565b5f60c082840312156110fc575f80fd5b60405160c081016001600160401b038111828210171561111e5761111e6110c1565b604052905080823561112f816110d5565b8152602083013561113f816110d5565b60208201526040830135611152816110d5565b60408201526060830135611165816110d5565b60608201526080830135611178816110d5565b608082015260a083013561118b816110d5565b60a0919091015292915050565b5f82601f8301126111a7575f80fd5b81356001600160401b038111156111c0576111c06110c1565b604051601f8201601f19908116603f011681016001600160401b03811182821017156111ee576111ee6110c1565b604052818152838201602001851015611205575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f806101208587031215611235575f80fd5b61123f86866110ec565b935060c08501356001600160401b03811115611259575f80fd5b61126587828801611198565b949794965050505060e0830135926101000135919050565b5f8060e0838503121561128e575f80fd5b61129884846110ec565b915060c08301356001600160401b038111156112b2575f80fd5b6112be85828601611198565b9150509250929050565b5f60c082840312156112d8575f80fd5b61067683836110ec565b5f805f61010084860312156112f5575f80fd5b6112ff85856110ec565b925060c08401356001600160401b03811115611319575f80fd5b61132586828701611198565b939693955050505060e0919091013590565b5f8060e08385031215611348575f80fd5b61135284846110ec565b9460c0939093013593505050565b5f805f805f6101408688031215611375575f80fd5b61137f87876110ec565b945060c086013561138f816110d5565b935060e086013592506101008601356113a7816110d5565b91506101208601356001600160401b038111156113c2575f80fd5b6113ce88828901611198565b9150509295509295909350565b5f80604083850312156113ec575f80fd5b82516113f7816110d5565b6020840151909250611408816110d5565b809150509250929050565b6001600160a01b03998a168152978916602089015260408801969096526060870194909452608086019290925260a0850152151560c0840152831660e08301529091166101008201526101200190565b5f805f8060808587031215611476575f80fd5b8451602086015160408701519195509350611490816110d5565b60608601519092506114a1816110d5565b939692955090935050565b6001600160a01b0391909116815260200190565b5f602082840312156114d0575f80fd5b5051919050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561100f5761100f6114eb565b5f805f60608486031215611524575f80fd5b83516020850151909350611537816110d5565b6040850151909250611548816110d5565b809150509250925092565b8181038181111561100f5761100f6114eb565b5f60208284031215611576575f80fd5b8151610676816110d5565b808202811582820484141761100f5761100f6114eb565b5f826115b257634e487b7160e01b5f52601260045260245ffd5b500490565b6001600160a01b0395861681529385166020850152604084019290925283166060830152909116608082015260a00190565b5f80604083850312156115fa575f80fd5b505080516020909101519092909150565b5f600160ff1b820161161f5761161f6114eb565b505f0390565b6001600160a01b0392909216825260208201526040019056fea26469706673582212201a0dcc8e8e692b076928ab05e7f352ff8347a1acf24bb4365d31fefe9115993564736f6c634300081a0033
Deployed Bytecode
0x735a91f87c9e72240bc1b780be0557a61164fd9ffd30146080604052600436106100ce575f3560e01c806320daa1e0146100d257806333b475a8146100e657806359492bb1146101075780635fc6e58d146101265780636113be14146101455780637d2584101461016457806385e9726d14610185578063badf3308146101a4578063bcc04622146101b7578063cf221848146101d6578063d1fc4acc146101f5578063e080c14c14610214578063eca6c04f1461023c578063ecc134c71461025b578063fe17eec41461026e575b5f80fd5b604051601281526020015b60405180910390f35b8180156100f1575f80fd5b50610105610100366004611221565b61028d565b005b818015610112575f80fd5b5061010561012136600461127d565b610320565b818015610131575f80fd5b506101056101403660046112c8565b610531565b818015610150575f80fd5b5061010561015f3660046112e2565b610586565b610177610172366004611337565b610609565b6040519081526020016100dd565b818015610190575f80fd5b5061017761019f366004611360565b61067d565b6101056101b23660046112c8565b6107eb565b8180156101c2575f80fd5b506101056101d1366004611221565b610a0c565b8180156101e1575f80fd5b506101056101f03660046112e2565b610aca565b818015610200575f80fd5b5061017761020f366004611337565b610b54565b6102276102223660046112c8565b610bc1565b604080519283526020830191909152016100dd565b818015610247575f80fd5b50610105610256366004611221565b610c3b565b610105610269366004611337565b610d37565b818015610279575f80fd5b506101056102883660046112e2565b610ddd565b5f80848060200190518101906102a391906113db565b9150915085604001516001600160a01b0316639efeaeb28760200151305f8089895f8a8a6040518a63ffffffff1660e01b81526004016102eb99989796959493929190611413565b5f604051808303815f87803b158015610302575f80fd5b505af1158015610314573d5f803e3d5ffd5b50505050505050505050565b5f805f80848060200190518101906103389190611463565b93509350935093505f86602001516001600160a01b0316631983fb40306040518263ffffffff1660e01b815260040161037191906114ac565b602060405180830381865afa15801561038c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103b091906114c0565b905060018160048111156103c6576103c66114d7565b60048111156103d7576103d76114d7565b036103f557604051630ed2159360e11b815260040160405180910390fd5b60608701516040516370a0823160e01b81525f916001600160a01b0316906370a08231906104279030906004016114ac565b602060405180830381865afa158015610442573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061046691906114c0565b905061047188610e59565b61047b90826114ff565b604089015160608a015191925061049c916001600160a01b03169083610f36565b60408089015160208a015191516326caa39d60e01b81526001600160a01b03928316600482015230602482015260448101899052606481018490526084810188905286831660a482015285831660c48201529116906326caa39d9060e4015f604051808303815f87803b158015610511575f80fd5b505af1158015610523573d5f803e3d5ffd5b505050505050505050505050565b80606001516001600160a01b0316634a25f38a6040518163ffffffff1660e01b81526004015f604051808303815f87803b15801561056d575f80fd5b505af115801561057f573d5f803e3d5ffd5b5050505050565b5f805f8480602001905181019061059d9190611512565b9250925092506105ad8684610d37565b604080870151602088015191516361578f6560e11b81526001600160a01b0392831660048201523060248201526044810186905260648101879052848316608482015283831660a482015291169063c2af1eca9060c4016102eb565b60608201516040516363737ac960e11b8152600481018390525f916001600160a01b03169063c6e6f59290602401602060405180830381865afa158015610652573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061067691906114c0565b9392505050565b5f80856001600160a01b03166370a08231856040518263ffffffff1660e01b81526004016106ab91906114ac565b602060405180830381865afa1580156106c6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106ea91906114c0565b6060880151604051635d043b2960e11b8152600481018890526001600160a01b03878116602483015230604483015292935091169063ba087652906064016020604051808303815f875af1158015610744573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061076891906114c0565b506040516370a0823160e01b815281906001600160a01b038816906370a08231906107979088906004016114ac565b602060405180830381865afa1580156107b2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107d691906114c0565b6107e09190611553565b979650505050505050565b5f81604001516001600160a01b0316636b6c07746040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108509190611566565b6001600160a01b0316635733d58f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561088b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108af91906114c0565b90505f670de0b6b3a76400006108c58184611553565b6108d7906702c68af0bb140000611581565b6108e19190611598565b6108eb90836114ff565b90505f6702c68af0bb14000084602001516001600160a01b031663794e57246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610937573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095b91906114c0565b61096591906114ff565b90505f6109728383610ffe565b90505f8560a001516001600160a01b03166391b58ae86040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109b5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d991906114c0565b905081811015610a045760405163f88713f760e01b8152600481018290526024015b60405180910390fd5b505050505050565b5f805f85806020019051810190610a239190611512565b925092509250610a4f87604001518689606001516001600160a01b0316610f369092919063ffffffff16565b86604001516001600160a01b0316639efeaeb288602001513086895f8a60018a8a6040518a63ffffffff1660e01b8152600401610a9499989796959493929190611413565b5f604051808303815f87803b158015610aab575f80fd5b505af1158015610abd573d5f803e3d5ffd5b5050505050505050505050565b5f8083806020019051810190610ae091906113db565b9150915084604001516001600160a01b031663a2e8dc0a8660200151308686866040518663ffffffff1660e01b8152600401610b209594939291906115b7565b5f604051808303815f87803b158015610b37575f80fd5b505af1158015610b49573d5f803e3d5ffd5b505050505050505050565b606082015182515f91610b71916001600160a01b03169084610f36565b6060830151604051636e553f6560e01b8152600481018490523060248201526001600160a01b0390911690636e553f65906044016020604051808303815f875af1158015610652573d5f803e3d5ffd5b5f8082602001516001600160a01b031663eb7a7f7e306040518263ffffffff1660e01b8152600401610bf391906114ac565b6040805180830381865afa158015610c0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3191906115e9565b9094909350915050565b5f8084806020019051810190610c5191906113db565b90925090505f808512159081610c67575f610c69565b855b90505f82610c7f57610c7a8761160b565b610c81565b5f5b905086151580610c9057508515155b15610b4957610cbb8960400151838b606001516001600160a01b0316610f369092919063ffffffff16565b88604001516001600160a01b0316639efeaeb28a60200151305f86868c5f8d8d6040518a63ffffffff1660e01b8152600401610cff99989796959493929190611413565b5f604051808303815f87803b158015610d16575f80fd5b505af1158015610d28573d5f803e3d5ffd5b50505050505050505050505050565b5f600560ff1683602001516001600160a01b03166331c7a2616040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d7d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da191906114c0565b610dab9190611581565b905080821115610dd8576040516385c914cb60e01b815260048101839052602481018290526044016109fb565b505050565b5f8083806020019051810190610df391906113db565b91509150610e1d85604001518487606001516001600160a01b0316610f369092919063ffffffff16565b84604001516001600160a01b031663fded3d358660200151308686866040518663ffffffff1660e01b8152600401610b209594939291906115b7565b602081015160405163ec38a05d60e01b81525f91906001600160a01b0382169063ec38a05d90610e8d9030906004016114ac565b602060405180830381865afa158015610ea8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ecc91906114c0565b91508115610f3057604051632b946eed60e11b8152306004820181905260248201526001600160a01b03821690635728ddda906044015f604051808303815f87803b158015610f19575f80fd5b505af1158015610f2b573d5f803e3d5ffd5b505050505b50919050565b5f836001600160a01b031663095ea7b38484604051602401610f59929190611625565b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050509050610f928482611015565b610ff857610fee84856001600160a01b031663095ea7b3865f604051602401610fbc929190611625565b604051602081830303815290604052915060e01b6020820180516001600160e01b03838183161783525050505061105e565b610ff8848261105e565b50505050565b5f81831161100c5781610676565b50815b92915050565b5f805f8060205f8651602088015f8a5af192503d91505f519050828015611054575081156110465780600114611054565b5f866001600160a01b03163b115b9695505050505050565b5f8060205f8451602086015f885af18061107d576040513d5f823e3d81fd5b50505f513d915081156110945780600114156110a1565b6001600160a01b0384163b155b15610ff85783604051635274afe760e01b81526004016109fb91906114ac565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b03811681146110e9575f80fd5b50565b5f60c082840312156110fc575f80fd5b60405160c081016001600160401b038111828210171561111e5761111e6110c1565b604052905080823561112f816110d5565b8152602083013561113f816110d5565b60208201526040830135611152816110d5565b60408201526060830135611165816110d5565b60608201526080830135611178816110d5565b608082015260a083013561118b816110d5565b60a0919091015292915050565b5f82601f8301126111a7575f80fd5b81356001600160401b038111156111c0576111c06110c1565b604051601f8201601f19908116603f011681016001600160401b03811182821017156111ee576111ee6110c1565b604052818152838201602001851015611205575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f806101208587031215611235575f80fd5b61123f86866110ec565b935060c08501356001600160401b03811115611259575f80fd5b61126587828801611198565b949794965050505060e0830135926101000135919050565b5f8060e0838503121561128e575f80fd5b61129884846110ec565b915060c08301356001600160401b038111156112b2575f80fd5b6112be85828601611198565b9150509250929050565b5f60c082840312156112d8575f80fd5b61067683836110ec565b5f805f61010084860312156112f5575f80fd5b6112ff85856110ec565b925060c08401356001600160401b03811115611319575f80fd5b61132586828701611198565b939693955050505060e0919091013590565b5f8060e08385031215611348575f80fd5b61135284846110ec565b9460c0939093013593505050565b5f805f805f6101408688031215611375575f80fd5b61137f87876110ec565b945060c086013561138f816110d5565b935060e086013592506101008601356113a7816110d5565b91506101208601356001600160401b038111156113c2575f80fd5b6113ce88828901611198565b9150509295509295909350565b5f80604083850312156113ec575f80fd5b82516113f7816110d5565b6020840151909250611408816110d5565b809150509250929050565b6001600160a01b03998a168152978916602089015260408801969096526060870194909452608086019290925260a0850152151560c0840152831660e08301529091166101008201526101200190565b5f805f8060808587031215611476575f80fd5b8451602086015160408701519195509350611490816110d5565b60608601519092506114a1816110d5565b939692955090935050565b6001600160a01b0391909116815260200190565b5f602082840312156114d0575f80fd5b5051919050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082018082111561100f5761100f6114eb565b5f805f60608486031215611524575f80fd5b83516020850151909350611537816110d5565b6040850151909250611548816110d5565b809150509250925092565b8181038181111561100f5761100f6114eb565b5f60208284031215611576575f80fd5b8151610676816110d5565b808202811582820484141761100f5761100f6114eb565b5f826115b257634e487b7160e01b5f52601260045260245ffd5b500490565b6001600160a01b0395861681529385166020850152604084019290925283166060830152909116608082015260a00190565b5f80604083850312156115fa575f80fd5b505080516020909101519092909150565b5f600160ff1b820161161f5761161f6114eb565b505f0390565b6001600160a01b0392909216825260208201526040019056fea26469706673582212201a0dcc8e8e692b076928ab05e7f352ff8347a1acf24bb4365d31fefe9115993564736f6c634300081a0033
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.