AssetsViewModule

Description:

Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20Upgradeable.sol";
"
    },
    "@openzeppelin/contracts-upgradeable/interfaces/IERC4626Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (interfaces/IERC4626.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20Upgradeable.sol";
import "../token/ERC20/extensions/IERC20MetadataUpgradeable.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 IERC4626Upgradeable is IERC20Upgradeable, IERC20MetadataUpgradeable {
    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);
}
"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20Upgradeable.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
    /**
     * @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);
}
"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": {
      "content": "// 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 IERC20Upgradeable {
    /**
     * @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);
}
"
    },
    "contracts/infinite-proxy/interfaces/IProxy.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

interface IProxy {
    function setAdmin(address newAdmin_) external;

    function setDummyImplementation(address newDummyImplementation_) external;

    function addImplementation(
        address implementation_,
        bytes4[] calldata sigs_
    ) external;

    function removeImplementation(address implementation_) external;

    function getAdmin() external view returns (address);

    function getDummyImplementation() external view returns (address);

    function getImplementationSigs(
        address impl_
    ) external view returns (bytes4[] memory);

    function getSigsImplementation(bytes4 sig_) external view returns (address);

    function readFromStorage(
        bytes32 slot_
    ) external view returns (uint256 result_);
}
"
    },
    "contracts/libraries/tickMath.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

/// @title library that calculates number "tick" and "ratioX96" from this: ratioX96 = (1.0015^tick) * 2^96
/// @notice this library is used in Fluid Vault protocol for optimiziation.
/// @dev "tick" supports between -32767 and 32767. "ratioX96" supports between 37075072 and 169307877264527972847801929085841449095838922544595
library TickMath {
    /// The minimum tick that can be passed in getRatioAtTick. 1.0015**-32767
    int24 internal constant MIN_TICK = -32767;
    /// The maximum tick that can be passed in getRatioAtTick. 1.0015**32767
    int24 internal constant MAX_TICK = 32767;

    uint256 internal constant FACTOR00 = 0x100000000000000000000000000000000;
    uint256 internal constant FACTOR01 = 0xff9dd7de423466c20352b1246ce4856f; // 2^128/1.0015**1 = 339772707859149738855091969477551883631
    uint256 internal constant FACTOR02 = 0xff3bd55f4488ad277531fa1c725a66d0; // 2^128/1.0015**2 = 339263812140938331358054887146831636176
    uint256 internal constant FACTOR03 = 0xfe78410fd6498b73cb96a6917f853259; // 2^128/1.0015**4 = 338248306163758188337119769319392490073
    uint256 internal constant FACTOR04 = 0xfcf2d9987c9be178ad5bfeffaa123273; // 2^128/1.0015**8 = 336226404141693512316971918999264834163
    uint256 internal constant FACTOR05 = 0xf9ef02c4529258b057769680fc6601b3; // 2^128/1.0015**16 = 332218786018727629051611634067491389875
    uint256 internal constant FACTOR06 = 0xf402d288133a85a17784a411f7aba082; // 2^128/1.0015**32 = 324346285652234375371948336458280706178
    uint256 internal constant FACTOR07 = 0xe895615b5beb6386553757b0352bda90; // 2^128/1.0015**64 = 309156521885964218294057947947195947664
    uint256 internal constant FACTOR08 = 0xd34f17a00ffa00a8309940a15930391a; // 2^128/1.0015**128 = 280877777739312896540849703637713172762
    uint256 internal constant FACTOR09 = 0xae6b7961714e20548d88ea5123f9a0ff; // 2^128/1.0015**256 = 231843708922198649176471782639349113087
    uint256 internal constant FACTOR10 = 0x76d6461f27082d74e0feed3b388c0ca1; // 2^128/1.0015**512 = 157961477267171621126394973980180876449
    uint256 internal constant FACTOR11 = 0x372a3bfe0745d8b6b19d985d9a8b85bb; // 2^128/1.0015**1024 = 73326833024599564193373530205717235131
    uint256 internal constant FACTOR12 = 0x0be32cbee48979763cf7247dd7bb539d; // 2^128/1.0015**2048 = 15801066890623697521348224657638773661
    uint256 internal constant FACTOR13 = 0x8d4f70c9ff4924dac37612d1e2921e; // 2^128/1.0015**4096 = 733725103481409245883800626999235102
    uint256 internal constant FACTOR14 = 0x4e009ae5519380809a02ca7aec77; // 2^128/1.0015**8192 = 1582075887005588088019997442108535
    uint256 internal constant FACTOR15 = 0x17c45e641b6e95dee056ff10; // 2^128/1.0015**16384 = 7355550435635883087458926352

    /// The minimum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MIN_TICK). ~ Equivalent to `(1 << 96) * (1.0015**-32767)`
    uint256 internal constant MIN_RATIOX96 = 37075072;
    /// The maximum value that can be returned from getRatioAtTick. Equivalent to getRatioAtTick(MAX_TICK).
    /// ~ Equivalent to `(1 << 96) * (1.0015**32767)`, rounding etc. leading to minor difference
    uint256 internal constant MAX_RATIOX96 =
        169307877264527972847801929085841449095838922544595;

    uint256 internal constant ZERO_TICK_SCALED_RATIO =
        0x1000000000000000000000000; // 1 << 96 // 79228162514264337593543950336
    uint256 internal constant _1E26 = 1e26;

    /// @notice ratioX96 = (1.0015^tick) * 2^96
    /// @dev Throws if |tick| > max tick
    /// @param tick The input tick for the above formula
    /// @return ratioX96 ratio = (debt amount/collateral amount)
    function getRatioAtTick(int tick) internal pure returns (uint256 ratioX96) {
        assembly {
            let absTick_ := sub(xor(tick, sar(255, tick)), sar(255, tick))

            if gt(absTick_, MAX_TICK) {
                revert(0, 0)
            }
            let factor_ := FACTOR00
            if and(absTick_, 0x1) {
                factor_ := FACTOR01
            }
            if and(absTick_, 0x2) {
                factor_ := shr(128, mul(factor_, FACTOR02))
            }
            if and(absTick_, 0x4) {
                factor_ := shr(128, mul(factor_, FACTOR03))
            }
            if and(absTick_, 0x8) {
                factor_ := shr(128, mul(factor_, FACTOR04))
            }
            if and(absTick_, 0x10) {
                factor_ := shr(128, mul(factor_, FACTOR05))
            }
            if and(absTick_, 0x20) {
                factor_ := shr(128, mul(factor_, FACTOR06))
            }
            if and(absTick_, 0x40) {
                factor_ := shr(128, mul(factor_, FACTOR07))
            }
            if and(absTick_, 0x80) {
                factor_ := shr(128, mul(factor_, FACTOR08))
            }
            if and(absTick_, 0x100) {
                factor_ := shr(128, mul(factor_, FACTOR09))
            }
            if and(absTick_, 0x200) {
                factor_ := shr(128, mul(factor_, FACTOR10))
            }
            if and(absTick_, 0x400) {
                factor_ := shr(128, mul(factor_, FACTOR11))
            }
            if and(absTick_, 0x800) {
                factor_ := shr(128, mul(factor_, FACTOR12))
            }
            if and(absTick_, 0x1000) {
                factor_ := shr(128, mul(factor_, FACTOR13))
            }
            if and(absTick_, 0x2000) {
                factor_ := shr(128, mul(factor_, FACTOR14))
            }
            if and(absTick_, 0x4000) {
                factor_ := shr(128, mul(factor_, FACTOR15))
            }

            let precision_ := 0
            if iszero(
                and(
                    tick,
                    0x8000000000000000000000000000000000000000000000000000000000000000
                )
            ) {
                factor_ := div(
                    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,
                    factor_
                )
                // we round up in the division so getTickAtRatio of the output price is always consistent
                if mod(factor_, 0x100000000) {
                    precision_ := 1
                }
            }
            ratioX96 := add(shr(32, factor_), precision_)
        }
    }

    /// @notice ratioX96 = (1.0015^tick) * 2^96
    /// @dev Throws if ratioX96 > max ratio || ratioX96 < min ratio
    /// @param ratioX96 The input ratio; ratio = (debt amount/collateral amount)
    /// @return tick The output tick for the above formula. Returns in round down form. if tick is 123.23 then 123, if tick is -123.23 then returns -124
    /// @return perfectRatioX96 perfect ratio for the above tick
    function getTickAtRatio(
        uint256 ratioX96
    ) internal pure returns (int tick, uint perfectRatioX96) {
        assembly {
            if or(gt(ratioX96, MAX_RATIOX96), lt(ratioX96, MIN_RATIOX96)) {
                revert(0, 0)
            }

            let cond := lt(ratioX96, ZERO_TICK_SCALED_RATIO)
            let factor_

            if iszero(cond) {
                // if ratioX96 >= ZERO_TICK_SCALED_RATIO
                factor_ := div(mul(ratioX96, _1E26), ZERO_TICK_SCALED_RATIO)
            }
            if cond {
                // ratioX96 < ZERO_TICK_SCALED_RATIO
                factor_ := div(mul(ZERO_TICK_SCALED_RATIO, _1E26), ratioX96)
            }

            // put in https://www.wolframalpha.com/ whole equation: (1.0015^tick) * 2^96 * 10^26 / 79228162514264337593543950336

            // for tick = 16384
            // ratioX96 = (1.0015^16384) * 2^96 = 3665252098134783297721995888537077351735
            // 3665252098134783297721995888537077351735 * 10^26 / 79228162514264337593543950336 =
            // 4626198540796508716348404308345255985.06131964639489434655721
            if iszero(lt(factor_, 4626198540796508716348404308345255985)) {
                tick := or(tick, 0x4000)
                factor_ := div(
                    mul(factor_, _1E26),
                    4626198540796508716348404308345255985
                )
            }
            // for tick = 8192
            // ratioX96 = (1.0015^8192) * 2^96 = 17040868196391020479062776466509865
            // 17040868196391020479062776466509865 * 10^26 / 79228162514264337593543950336 =
            // 21508599537851153911767490449162.3037648642153898377655505172
            if iszero(lt(factor_, 21508599537851153911767490449162)) {
                tick := or(tick, 0x2000)
                factor_ := div(
                    mul(factor_, _1E26),
                    21508599537851153911767490449162
                )
            }
            // for tick = 4096
            // ratioX96 = (1.0015^4096) * 2^96 = 36743933851015821532611831851150
            // 36743933851015821532611831851150 * 10^26 / 79228162514264337593543950336 =
            // 46377364670549310883002866648.9777607649742626173648716941385
            if iszero(lt(factor_, 46377364670549310883002866649)) {
                tick := or(tick, 0x1000)
                factor_ := div(
                    mul(factor_, _1E26),
                    46377364670549310883002866649
                )
            }
            // for tick = 2048
            // ratioX96 = (1.0015^2048) * 2^96 = 1706210527034005899209104452335
            // 1706210527034005899209104452335 * 10^26 / 79228162514264337593543950336 =
            // 2153540449365864845468344760.06357108484096046743300420319322
            if iszero(lt(factor_, 2153540449365864845468344760)) {
                tick := or(tick, 0x800)
                factor_ := div(
                    mul(factor_, _1E26),
                    2153540449365864845468344760
                )
            }
            // for tick = 1024
            // ratioX96 = (1.0015^1024) * 2^96 = 367668226692760093024536487236
            // 367668226692760093024536487236 * 10^26 / 79228162514264337593543950336 =
            // 464062544207767844008185024.950588990554136265212906454481127
            if iszero(lt(factor_, 464062544207767844008185025)) {
                tick := or(tick, 0x400)
                factor_ := div(mul(factor_, _1E26), 464062544207767844008185025)
            }
            // for tick = 512
            // ratioX96 = (1.0015^512) * 2^96 = 170674186729409605620119663668
            // 170674186729409605620119663668 * 10^26 / 79228162514264337593543950336 =
            // 215421109505955298802281577.031879604792139232258508172947569
            if iszero(lt(factor_, 215421109505955298802281577)) {
                tick := or(tick, 0x200)
                factor_ := div(mul(factor_, _1E26), 215421109505955298802281577)
            }
            // for tick = 256
            // ratioX96 = (1.0015^256) * 2^96 = 116285004205991934861656513301
            // 116285004205991934861656513301 * 10^26 / 79228162514264337593543950336 =
            // 146772309890508740607270614.667650899656438875541505058062410
            if iszero(lt(factor_, 146772309890508740607270615)) {
                tick := or(tick, 0x100)
                factor_ := div(mul(factor_, _1E26), 146772309890508740607270615)
            }
            // for tick = 128
            // ratioX96 = (1.0015^128) * 2^96 = 95984619659632141743747099590
            // 95984619659632141743747099590 * 10^26 / 79228162514264337593543950336 =
            // 121149622323187099817270416.157248837742741760456796835775887
            if iszero(lt(factor_, 121149622323187099817270416)) {
                tick := or(tick, 0x80)
                factor_ := div(mul(factor_, _1E26), 121149622323187099817270416)
            }
            // for tick = 64
            // ratioX96 = (1.0015^64) * 2^96 = 87204845308406958006717891124
            // 87204845308406958006717891124 * 10^26 / 79228162514264337593543950336 =
            // 110067989135437147685980801.568068573422377364214113968609839
            if iszero(lt(factor_, 110067989135437147685980801)) {
                tick := or(tick, 0x40)
                factor_ := div(mul(factor_, _1E26), 110067989135437147685980801)
            }
            // for tick = 32
            // ratioX96 = (1.0015^32) * 2^96 = 83120873769022354029916374475
            // 83120873769022354029916374475 * 10^26 / 79228162514264337593543950336 =
            // 104913292358707887270979599.831816586773651266562785765558183
            if iszero(lt(factor_, 104913292358707887270979600)) {
                tick := or(tick, 0x20)
                factor_ := div(mul(factor_, _1E26), 104913292358707887270979600)
            }
            // for tick = 16
            // ratioX96 = (1.0015^16) * 2^96 = 81151180492336368327184716176
            // 81151180492336368327184716176 * 10^26 / 79228162514264337593543950336 =
            // 102427189924701091191840927.762844039579442328381455567932128
            if iszero(lt(factor_, 102427189924701091191840928)) {
                tick := or(tick, 0x10)
                factor_ := div(mul(factor_, _1E26), 102427189924701091191840928)
            }
            // for tick = 8
            // ratioX96 = (1.0015^8) * 2^96 = 80183906840906820640659903620
            // 80183906840906820640659903620 * 10^26 / 79228162514264337593543950336 =
            // 101206318935480056907421312.890625
            if iszero(lt(factor_, 101206318935480056907421313)) {
                tick := or(tick, 0x8)
                factor_ := div(mul(factor_, _1E26), 101206318935480056907421313)
            }
            // for tick = 4
            // ratioX96 = (1.0015^4) * 2^96 = 79704602139525152702959747603
            // 79704602139525152702959747603 * 10^26 / 79228162514264337593543950336 =
            // 100601351350506250000000000
            if iszero(lt(factor_, 100601351350506250000000000)) {
                tick := or(tick, 0x4)
                factor_ := div(mul(factor_, _1E26), 100601351350506250000000000)
            }
            // for tick = 2
            // ratioX96 = (1.0015^2) * 2^96 = 79466025265172787701084167660
            // 79466025265172787701084167660 * 10^26 / 79228162514264337593543950336 =
            // 100300225000000000000000000
            if iszero(lt(factor_, 100300225000000000000000000)) {
                tick := or(tick, 0x2)
                factor_ := div(mul(factor_, _1E26), 100300225000000000000000000)
            }
            // for tick = 1
            // ratioX96 = (1.0015^1) * 2^96 = 79347004758035734099934266261
            // 79347004758035734099934266261 * 10^26 / 79228162514264337593543950336 =
            // 100150000000000000000000000
            if iszero(lt(factor_, 100150000000000000000000000)) {
                tick := or(tick, 0x1)
                factor_ := div(mul(factor_, _1E26), 100150000000000000000000000)
            }
            if iszero(cond) {
                // if ratioX96 >= ZERO_TICK_SCALED_RATIO
                perfectRatioX96 := div(mul(ratioX96, _1E26), factor_)
            }
            if cond {
                // ratioX96 < ZERO_TICK_SCALED_RATIO
                tick := not(tick)
                perfectRatioX96 := div(
                    mul(ratioX96, factor_),
                    100150000000000000000000000
                )
            }
        }
    }
}
"
    },
    "contracts/vault/common/interfaces/IDSA.sol": {
      "content": "//SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

interface IDSA {
    function cast(
        string[] calldata _targetNames,
        bytes[] calldata _datas,
        address _origin
    ) external payable returns (bytes32);
}
"
    },
    "contracts/vault/common/interfaces/IToken.sol": {
      "content": "//SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

interface IToken {
    function approve(address, uint256) external;

    function transfer(address, uint) external;

    function transferFrom(address, address, uint) external;

    function deposit() external payable;

    function withdraw(uint) external;

    function balanceOf(address) external view returns (uint);

    function decimals() external view returns (uint);

    function totalSupply() external view returns (uint);

    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);
}
"
    },
    "contracts/vault/common/interfaces/IVaultV3.sol": {
      "content": "//SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

interface IVaultV3 {
    function readFromStorage(bytes32 slot_) external view returns (uint256 result_);
    function getWithdrawFee(uint256 amount_) external view returns (uint256);
    function getProtocolRatio(uint8 protocolId_) external view returns (uint256 ratio_);
    function getNetAssets() external view returns (uint256 totalAssets_, uint256 totalDebt_, uint256 netAssets_, uint256 aggregatedRatio_);
    function getTokenExchangeRate(address tokenAddress_) external view returns (uint256 exchangeRate_);
}
"
    },
    "contracts/vault/common/variables/constants.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

contract Constants {
    address internal constant _TEAM_MULTISIG = 0x4F6F977aCDD1177DCD81aB83074855EcB9C2D49e;
    address internal constant _INSTA_INDEX_ADDRESS = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723;
    address internal constant _USDT_ADDRESS = 0xdAC17F958D2ee523a2206206994597C13D831ec7; // 6 decimals
}

"
    },
    "contracts/vault/common/variables/primaryHelpers.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import {Constants} from "./constants.sol";
import {StorageVariables} from "./storageVariables.sol";
import {IProxy} from "../../../infinite-proxy/interfaces/IProxy.sol";
import {Structs} from "./structs.sol";
import {IVaultV3} from "../interfaces/IVaultV3.sol";
import {IToken} from "../interfaces/IToken.sol";

contract PrimaryHelpers is Constants, StorageVariables {
    using Structs for Structs.AuthTypes;

    /***********************************|
    |              ERRORS               |
    |__________________________________*/
    error Helpers__UnsupportedProtocolId();
    error Helpers__NotRebalancer();
    error Helpers__NotPrimaryRebalancer();
    error Helpers__Reentrant();
    error Helpers__NotAuth();
    error Helpers__InvalidAuthType();
    error Helpers__NotEnoughSwapLimit();

    function _auth(
        Structs.AuthTypes authType_,
        address account_
    ) internal view {
        address admin_ = IProxy(address(this)).getAdmin();
        if (authType_ == Structs.AuthTypes.Owner) {
            if (admin_ != account_) {
                revert Helpers__NotAuth();
            }
        } else if (authType_ == Structs.AuthTypes.SecondaryAuth) {
            if (
                secondaryAuth != account_ &&
                admin_ != account_
            ) {
                revert Helpers__NotAuth();
            }
        } else if (authType_ == Structs.AuthTypes.PrimaryRebalancer) {
            if (!isPrimaryRebalancer[account_] && admin_ != account_) {
                revert Helpers__NotAuth();
            }
        } else if (authType_ == Structs.AuthTypes.Rebalancer) {
            if (
                !isSecondaryRebalancer[account_] &&
                !isPrimaryRebalancer[account_] &&
                admin_ != account_
            ) {
                revert Helpers__NotAuth();
            }
        } else {
            revert Helpers__InvalidAuthType();
        }
    }

    /***********************************|
    |              MODIFIERS            |
    |__________________________________*/
    /// @notice reverts if msg.sender is not auth.
    modifier onlyAuth() {
        _auth(Structs.AuthTypes.Owner, msg.sender);
        _;
    }

    /// @notice reverts if msg.sender is not secondaryAuth or auth
    modifier onlySecondaryAuth() {
        _auth(Structs.AuthTypes.SecondaryAuth, msg.sender);
        _;
    }

    /// @notice reverts if msg.sender is not rebalancer or auth
    modifier onlyRebalancer() {
        _auth(Structs.AuthTypes.Rebalancer, msg.sender);
        _;
    }

    /// @notice reverts if msg.sender is not primaryRebalancer or auth
    modifier onlyPrimaryRebalancer() {
        _auth(Structs.AuthTypes.PrimaryRebalancer, msg.sender);
        _;
    }

    /**
     * @dev reentrancy gaurd.
     */
    modifier nonReentrant() {
        if (_status == 2) revert Helpers__Reentrant();
        _status = 2;
        _;
        _status = 1;
    }

    /// @notice Implements a method to read uint256 data from storage at a bytes32 storage slot key.
    function readFromStorage(
        bytes32 slot_
    ) public view returns (uint256 result_) {
        assembly {
            result_ := sload(slot_) // read value from the storage slot
        }
    }

    function _getAmountInUsd(
        address tokenAddress_,
        uint256 amount_,
        uint256 exchangeRate_
    ) internal view returns (uint256 amountInUsd_) {
        uint256 tokenDecimals_ = IToken(tokenAddress_).decimals();
        amountInUsd_ =
            (amount_ * exchangeRate_) /
            10 ** (2 * tokenDecimals_ - 6);
    }

    /// @notice Checks the available swap limit.
    /// @return availableSwapLimit_ The available swap limit.
    function checkAvailableSwapLimit()
        public
        view
        returns (uint256 availableSwapLimit_)
    {
        uint256 timeElapsed_ = block.timestamp - lastSwapTimestamp;
        availableSwapLimit_ = availableSwapLimit;

        /// @dev If time has elapsed, calculate the refill.
        if (timeElapsed_ > 0) {
            uint256 refill_ = (timeElapsed_ * maxDailySwapLimit) /
                (24 * 60 * 60);

            availableSwapLimit_ += refill_;

            availableSwapLimit_ = availableSwapLimit_ > maxDailySwapLimit
                ? maxDailySwapLimit
                : availableSwapLimit_;
        }
    }

    function _handleSwapLimitCheck(uint256 amount_) internal {
        availableSwapLimit = checkAvailableSwapLimit();

        if (availableSwapLimit < amount_) {
            revert Helpers__NotEnoughSwapLimit();
        }

        availableSwapLimit -= amount_;
        lastSwapTimestamp = block.timestamp;
    }
}
"
    },
    "contracts/vault/common/variables/storageVariables.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import {IDSA} from "../../common/interfaces/IDSA.sol";
import {Structs} from "../../common/variables/structs.sol";

contract StorageVariables {
    using Structs for Structs.FluidVaultDetails;
    /****************************************************************************|
    |   @notice Protocol IDs                                                     |
    |   // AAVE-V3 : 1  (SUSDe, USDe, USDC, USDT, GHO, USDS)                     |
    |   // FLUID-WSTUSR-USDC : 2  (wstUSR, USDC)                                 |
    |   // FLUID-WSTUSR-USDT : 3  (wstUSR, USDT)                                 |
    |   // FLUID-WSTUSR-GHO : 4  (wstUSR, GHO)                                   |
    |   // FLUID-SUSDE-USDC : 5  (SUSDe, USDC)                                   |
    |   // FLUID-SUSDE-USDT : 6  (SUSDe, USDT)                                   |
    |   // FLUID-SUSDE-GHO : 7  (SUSDe, GHO)                                     |        
    |   // FLUID-syrupUSDC-USDC : 8  (syrupUSDC, USDC)                           |
    |   // FLUID-syrupUSDC-USDT : 9  (syrupUSDC, USDT)                           |
    |   // FLUID-syrupUSDC-GHO : 10  (syrupUSDC, GHO)                            |
    |___________________________________________________________________________*/

    /***********************************|
    |           STATE VARIABLES         |
    |__________________________________*/
    // 1: open
    // 2: closed
    uint8 internal _status;

    IDSA public vaultDSA;

    /// @notice Secondary auth that only has the power to reduce max risk ratio.
    address public secondaryAuth;

    /// @notice Current exchange price.
    uint256 public exchangePrice;

    /// @notice Last timestamp the exchange price was updated
    /// @dev This is used to calculate the rate of the vault
    uint256 public lastExchangePriceUpdatedAt;

    /// @notice Mapping to store allowed primary rebalancers
    /// @dev Primary rebalancers are the ones that can perform swap related actions
    /// Modifiable by auth
    mapping(address => bool) public isPrimaryRebalancer;

    /// @notice Mapping to store allowed secondary rebalancers
    /// @dev Secondary rebalancers are the ones that can perform all rebalancer actions except swap related actions
    /// Modifiable by auth
    mapping(address => bool) public isSecondaryRebalancer;

    // Mapping of protocol id => max risk ratio, scaled to use basis points. i.e. 1e4 = 100%, 1e2 = 1%
    // 1: AAVE-V3
    // 2: FLUID-WSTUSR-USDC
    // 3: FLUID-WSTUSR-USDT
    // 4: FLUID-WSTUSR-GHO
    // 5: FLUID-SUSDE-USDC
    // 6: FLUID-SUSDE-USDT
    // 7: FLUID-SUSDE-GHO
    mapping(uint8 => uint256) public maxRiskRatio;

    // Max aggregated risk ratio of the vault that can be reached, scaled to use basis points. i.e. 1e4 = 100%, 1e2 = 1%
    // i.e. 1e4 = 100%, 1e2 = 1%
    uint256 public aggrMaxVaultRatio;

    /// @notice withdraw fee is either amount in percentage or absolute minimum.
    /// @dev This var defines the percentage in basis points. i.e. 1e4 = 100%, 1e2 = 1%
    /// Modifiable by owner
    uint256 public withdrawalFeePercentage;

    /// @notice withdraw fee is either amount in percentage or absolute minimum. This var defines the absolute minimum
    /// this number is given in decimals for the respective asset of the vault.
    /// Modifiable by owner
    uint256 public withdrawFeeAbsoluteMin; // in underlying base asset, i.e. USDT

    // charge from the profits, scaled to use basis points. i.e. 1e4 = 100%, 1e2 = 1%
    uint256 public revenueFeePercentage;

    /// @notice Stores reserves for the vault (previously revenue)
    /// @dev Reserves - also serve a purpose to cover unknown users losses
    /// @dev Reserves can be negative if there is not enough revenue to cover the losses
    int256 public reserves;

    /// @notice Min APR for the vault. This is the minimum APR the vault must yield.
    /// @dev Can be modified by the owner / secondary auth.
    uint256 public minRate;

    /// @notice Max APR for the vault. This is the maximum APR the vault can yield.
    /// @dev Can be modified by the owner / secondary auth.
    uint256 public maxRate;

    /// @notice Revenue will be transffered to this address upon collection.
    address public treasury;

    ///@notice Mapping to store fluid vault details
    /// @dev Protocol ID => Fluid Vault Details (VaultAddress, NFTId)
    /// 2: FLUID-WSTUSR-USDC
    /// 3: FLUID-WSTUSR-USDT
    /// 4: FLUID-WSTUSR-GHO
    /// 5: FLUID-SUSDE-USDC
    /// 6: FLUID-SUSDE-USDT
    /// 7: FLUID-SUSDE-GHO
    /// 8: FLUID-syrupUSDC-USDC
    /// 9: FLUID-syrupUSDC-USDT
    /// 10: FLUID-syrupUSDC-GHO
    mapping(uint8 => Structs.FluidVaultDetails) public fluidVaultDetails;

    /// @notice Daily swap limit of the vault.
    /// @dev This is used to prevent abuse of the swap functionality.
    /// @dev Team multisig can update this value.
    uint256 public maxDailySwapLimit;

    /// @notice Available swap limit of the vault.
    /// @dev This is used to track the available swap limit of the vault.
    uint256 public availableSwapLimit;

    /// @notice Last timestamp the swap limit was recalculated.
    uint256 public lastSwapTimestamp;

    /// @notice Maximum loss in USD that can be incurred during a swap.
    /// In Percentage, scaled to use the basis points. i.e. 1e4 = 100%, 1e2 = 1%
    uint256 public maxSwapLossPercentage;
}
"
    },
    "contracts/vault/common/variables/structs.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

library Structs {
    struct FluidVaultDetails {
        address vaultAddress;
        uint256 nftId;
    }

    enum AuthTypes {
        Owner,
        SecondaryAuth,
        PrimaryRebalancer,
        Rebalancer
    }
}
"
    },
    "contracts/vault/common/variables/variablesBuffer.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

/// @title      VariablesBuffer
/// @notice     Allocates space of 151 slots to maintain storage
///             consistency with imported variables in VariablesPrimaryHelper.

contract VariablesBuffer {
    uint[151] internal __buffergap;
}
"
    },
    "contracts/vault/common/variables/variablesBufferHelper.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

/// @title      VariablesBufferHelper
/// @notice     Buffer Helper for variables that imports all the primary
///             helpers from the storage slot 152.

import {VariablesBuffer} from "./variablesBuffer.sol";
import {PrimaryHelpers} from "./primaryHelpers.sol";

// Buffer & variables
contract VariablesBufferHelper is VariablesBuffer, PrimaryHelpers {}
"
    },
    "contracts/vault/modules/assets-view-module/helpers.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import {IFluidVaultT1} from "./interfaces.sol";
import {TickMath} from "../../../libraries/tickMath.sol";
import {VariablesBufferHelper} from "../../common/variables/variablesBufferHelper.sol";
import {IERC4626Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC4626Upgradeable.sol";

contract ConstantHelpers {
    /***********************************|
    |           ERC20 ADDRESSES         |
    |__________________________________*/
    address internal constant _WSTUSR_ADDRESS =
        0x1202F5C7b4B9E47a1A484E8B270be34dbbC75055; // 18 decimals
    address internal constant _SUSDE_ADDRESS =
        0x9D39A5DE30e57443BfF2A8307A4256c8797A3497; // 18 decimals
    address internal constant _USDE_ADDRESS =
        0x4c9EDD5852cd905f086C759E8383e09bff1E68B3; // 18 decimals
    address internal constant _USDC_ADDRESS =
        0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; // 6 decimals
    address internal constant _USDS_ADDRESS =
        0xdC035D45d973E3EC169d2276DDab16f1e407384F; // 18 decimals
    address internal constant _GHO_ADDRESS =
        0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f; // 18 decimals
    address internal constant _SYRUP_USDC_ADDRESS =
        0x80ac24aA929eaF5013f6436cdA2a7ba190f5Cc0b; // 6 decimals

    /***********************************|
    |         AAVE V3 CONSTANTS         |
    |__________________________________*/
    // Collateral Addresses
    address internal constant _ASUSDE_ADDRESS =
        0x4579a27aF00A62C0EB156349f31B345c08386419; // 18 decimals
    address internal constant _AUSDE_ADDRESS =
        0x4F5923Fc5FD4a93352581b38B7cD26943012DECF; // 18 decimals

    // Debt Addresses
    address internal constant _D_USDC_ADDRESS =
        0x72E95b8931767C79bA4EeE721354d6E99a61D004; // 6 decimals
    address internal constant _D_USDT_ADDRESS =
        0x6df1C1E379bC5a00a7b4C6e67A203333772f45A8; // 6 decimals
    address internal constant _D_GHO_ADDRESS =
        0x786dBff3f1292ae8F92ea68Cf93c30b34B1ed04B; // 18 decimals
    address internal constant _D_USDS_ADDRESS =
        0x490E0E6255bF65b43E2e02F7acB783c5e04572Ff; // 18 decimals

    /***********************************|
    |         FLUID CONSTANTS           |
    |__________________________________*/
    uint256 internal constant _X8 = 0xff;
    uint256 internal constant _X19 = 0x7ffff;
    uint256 internal constant _X64 = 0xffffffffffffffff;
    uint256 internal constant _X128 = 0xffffffffffffffffffffffffffffffff;
}

contract Helpers is ConstantHelpers, VariablesBufferHelper {
    /***********************************|
    |              ERRORS               |
    |__________________________________*/
    error Helpers__UnsupportedTokenAddress();

    /// @notice Gets the exchange rate for a given token
    /// @param tokenAddress_ The address of the token to get the exchange rate for
    /// @return exchangeRate_ The exchange rate for the given token in 1e6 decimals
    function getTokenExchangeRate(
        address tokenAddress_
    ) public view returns (uint256 exchangeRate_) {
        // Base Tokens with 6 decimals
        if (tokenAddress_ == _USDC_ADDRESS || tokenAddress_ == _USDT_ADDRESS) {
            exchangeRate_ = 1e6;
        // Base Tokens with 18 decimals
        } else if (
            tokenAddress_ == _GHO_ADDRESS ||
            tokenAddress_ == _USDS_ADDRESS ||
            tokenAddress_ == _USDE_ADDRESS
        ) {
            exchangeRate_ = 1e18;
        // Individual Yield Tokens
        } else if (tokenAddress_ == _SUSDE_ADDRESS) {
            exchangeRate_ = IERC4626Upgradeable(_SUSDE_ADDRESS).convertToAssets(
                1e18
            );
        } else if (tokenAddress_ == _WSTUSR_ADDRESS) {
            exchangeRate_ = IERC4626Upgradeable(_WSTUSR_ADDRESS)
                .convertToAssets(1e18);
        } else if (tokenAddress_ == _SYRUP_USDC_ADDRESS) {
            exchangeRate_ = IERC4626Upgradeable(_SYRUP_USDC_ADDRESS)
                .convertToAssets(1e6);
        } else {
            revert Helpers__UnsupportedTokenAddress();
        }
    }

    // @notice Calculating the slot ID for Liquidity contract for single mapping
    // @param slot_ The slot number for the mapping
    // @param key_ The key for the mapping
    // @return The bytes32 representation of the storage slot for the mapping
    function _calculateStorageSlotUintMapping(
        uint256 slot_,
        uint256 key_
    ) private pure returns (bytes32) {
        return keccak256(abi.encode(key_, slot_));
    }

    // @notice Get the position data from the vault storage
    // @param vaultAddress_ The address of the vault contract
    // @param nftId_ The NFT ID of the position
    // @return collateralAmount_ The amount of collateral in the position
    // @return debtAmount_ The amount of debt in the position
    function _getPositionFromStorage(
        address vaultAddress_,
        uint256 nftId_
    ) internal view returns (uint256 collateralAmount_, uint256 debtAmount_) {
        IFluidVaultT1 vault_ = IFluidVaultT1(vaultAddress_);
        uint256 positionData_ = vault_.readFromStorage(
            _calculateStorageSlotUintMapping(3, nftId_)
        );

        bool isSupplyPosition_ = (positionData_ & 1) == 1;

        collateralAmount_ = (positionData_ >> 45) & _X64;
        collateralAmount_ =
            (collateralAmount_ >> 8) <<
            (collateralAmount_ & _X8);

        if (!isSupplyPosition_) {
            uint256 dustBorrow_ = (positionData_ >> 109) & _X64;
            dustBorrow_ = (dustBorrow_ >> 8) << (dustBorrow_ & _X8);

            int tick_ = (positionData_ & 2) == 2
                ? int((positionData_ >> 2) & _X19)
                : -int((positionData_ >> 2) & _X19);

            debtAmount_ =
                (TickMath.getRatioAtTick(tick_) * collateralAmount_) >>
                96;
            debtAmount_ = debtAmount_ - dustBorrow_;
        }

        (, , uint256 vaultSupplyExPrice_, uint256 vaultBorrowExPrice_) = vault_
            .updateExchangePrices(vault_.readFromStorage(bytes32(uint256(1))));

        collateralAmount_ = (collateralAmount_ * vaultSupplyExPrice_) / 1e12;
        debtAmount_ = (debtAmount_ * vaultBorrowExPrice_) / 1e12;
    }
}
"
    },
    "contracts/vault/modules/assets-view-module/interfaces.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

interface IFluidVaultT1 {
    /// @notice reads uint256 data `result_` from storage at a bytes32 storage `slot_` key.
    function readFromStorage(
        bytes32 slot_
    ) external view returns (uint256 result_);

    /// @notice calculates the updated vault exchange prices
    function updateExchangePrices(
        uint256 vaultVariables2_
    )
        external
        view
        returns (
            uint256 liqSupplyExPrice_,
            uint256 liqBorrowExPrice_,
            uint256 vaultSupplyExPrice_,
            uint256 vaultBorrowExPrice_
        );

    function operate(
        uint256 nftId_, // if 0 then new position
        int256 newCol_, // if negative then withdraw
        int256 newDebt_, // if negative then payback
        address to_ // address at which the borrow & withdraw amount should go to. If address(0) then it'll go to msg.sender
    )
        external
        payable
        returns (
            uint256, // nftId_
            int256, // final supply amount. if - then withdraw
            int256 // final borrow amount. if - then payback
        );
}

library AssetsViewStructs {    
    /// @notice Collateral tokens supported - SUSDe, USDe
    /// @notice Debt tokens supported - USDC, USDT, GHO, USDS
    /// @dev Collateral_Raw and Debt_Raw are the raw amounts of the collateral and debt tokens
    /// @dev Total_Collateral_Converted and Total_Debt_Converted are the converted amounts of the collateral and debt tokens
    /// @dev The collateral conversion is done using the conversion rates of the collateral tokens
    /// @dev The debt conversion is done on 1:1 basis with USDC
    /// @dev The conversion rates are updated every time the collateral and debt tokens are updated
    struct ProtocolAssetsAaveV3 {
        uint256 Collateral_Raw_SUSDe; // SUSDe
        uint256 Collateral_Raw_USDe; // USDe
        uint256 Debt_Raw_USDC; // USDC
        uint256 Debt_Raw_USDT; // USDT
        uint256 Debt_Raw_GHO; // GHO
        uint256 Debt_Raw_USDS; // USDS
        uint256 Total_Collateral_Converted; // USD
        uint256 Total_Debt_Converted; // USD
    }

    /// @notice Collateral tokens supported - wstUSR, SUSDe, syrupUSDC
    /// @notice Debt tokens supported - USDC, USDT, GHO
    /// @dev Collateral_Raw and Debt_Raw are the raw amounts of the collateral and debt tokens
    /// @dev Total_Collateral_Converted and Total_Debt_Converted are the converted amounts of the collateral and debt tokens
    /// @dev The collateral conversion is done using the conversion rates of the collateral tokens
    /// @dev The debt conversion is done on 1:1 basis with USDC
    struct ProtocolAssetsFluid {
        uint256 Collateral_Raw; // wstUSR / SUSDe / syrupUSDC
        uint256 Debt_Raw; // USDC / USDT / GHO
        uint256 Total_Collateral_Converted; // USD
        uint256 Total_Debt_Converted; // USD
    }

    // /// @notice Idle balances of the DSA in all supported tokens
    // /// @dev Total_Converted is the converted amount of the idle balances in USDC
    // /// @dev The conversion of wstUSR, SUSDe, USDe, syrupUSDC is done using the conversion rates of the tokens
    // /// @dev The conversion of USDC, USDT, GHO, USDS is done on 1:1 basis with USDC
    struct IdleDSABalances {
        uint256 Raw_wstUSR;
        uint256 Raw_SUSDe;
        uint256 Raw_syrupUSDC;
        uint256 Raw_USDe;
        uint256 Raw_USDC;
        uint256 Raw_USDT;
        uint256 Raw_GHO;
        uint256 Raw_USDS;
        uint256 Total_Converted; // USD
    }

    // Structs to be used directly in the Net Assets calculation
    struct ProtocolAssetsInUsd {
        uint256 totalCollateralInUsd;
        uint256 totalDebtInUsd;
    }

    struct NetAssets {
        ProtocolAssetsInUsd aaveV3;
        ProtocolAssetsInUsd fluidWstUSRUSDC;
        ProtocolAssetsInUsd fluidWstUSRUSDT;
        ProtocolAssetsInUsd fluidWstUSRGHO;
        ProtocolAssetsInUsd fluidSUSDeUSDC;
        ProtocolAssetsInUsd fluidSUSDeUSDT;
        ProtocolAssetsInUsd fluidSUSDeGHO;
        ProtocolAssetsInUsd fluidSyrupUSDCUSDC;
        ProtocolAssetsInUsd fluidSyrupUSDCUSDT;
        ProtocolAssetsInUsd fluidSyrupUSDCGHO;
        uint256 idleVaultBalanceInUsd;
        uint256 idleDsaBalanceInUsd;
    }
}"
    },
    "contracts/vault/modules/assets-view-module/main.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;

import {AssetsViewStructs} from "./interfaces.sol";
import {Helpers} from "./helpers.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol";
import {IERC4626Upgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/IERC4626Upgradeable.sol";

contract AssetsViewModule is Helpers {
    using AssetsViewStructs for AssetsViewStructs.NetAssets;
    using AssetsViewStructs for AssetsViewStructs.ProtocolAssetsAaveV3;
    using AssetsViewStructs for AssetsViewStructs.ProtocolAssetsFluid;
    using AssetsViewStructs for AssetsViewStructs.ProtocolAssetsInUsd;

    // Base functions that returns assets in raw format
    function getAaveV3Assets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsAaveV3 memory assets_)
    {
        assets_.Collateral_Raw_SUSDe = IERC20Upgradeable(_ASUSDE_ADDRESS)
            .balanceOf(address(vaultDSA));

        assets_.Collateral_Raw_USDe = IERC20Upgradeable(_AUSDE_ADDRESS)
            .balanceOf(address(vaultDSA));

        assets_.Debt_Raw_USDC = IERC20Upgradeable(_D_USDC_ADDRESS).balanceOf(
            address(vaultDSA)
        );

        assets_.Debt_Raw_USDT = IERC20Upgradeable(_D_USDT_ADDRESS).balanceOf(
            address(vaultDSA)
        );

        assets_.Debt_Raw_GHO = IERC20Upgradeable(_D_GHO_ADDRESS).balanceOf(
            address(vaultDSA)
        );

        // In 1e18 Decimals
        assets_.Total_Collateral_Converted =
            IERC4626Upgradeable(_SUSDE_ADDRESS).convertToAssets(
                assets_.Collateral_Raw_SUSDe
            ) +
            assets_.Collateral_Raw_USDe;

        // In 1e18 Decimals
        assets_.Total_Debt_Converted =
            assets_.Debt_Raw_USDC *
            1e12 +
            assets_.Debt_Raw_USDT *
            1e12 +
            assets_.Debt_Raw_GHO;
    }

    function getFluidWstUSRUSDCAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[2].vaultAddress,
            fluidVaultDetails[2].nftId
        );

        // In 1e18 Decimals
        assets_.Total_Collateral_Converted = IERC4626Upgradeable(
            _WSTUSR_ADDRESS
        ).convertToAssets(assets_.Collateral_Raw);
        assets_.Total_Debt_Converted = assets_.Debt_Raw * 1e12;
    }

    function getFluidWstUSRUSDTAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[3].vaultAddress,
            fluidVaultDetails[3].nftId
        );

        // In 1e18 Decimals
        assets_.Total_Collateral_Converted = IERC4626Upgradeable(
            _WSTUSR_ADDRESS
        ).convertToAssets(assets_.Collateral_Raw);
        assets_.Total_Debt_Converted = assets_.Debt_Raw * 1e12;
    }

    function getFluidWstUSRGHOAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[4].vaultAddress,
            fluidVaultDetails[4].nftId
        );

        // In 1e18 Decimals
        assets_.Total_Collateral_Converted = IERC4626Upgradeable(
            _WSTUSR_ADDRESS
        ).convertToAssets(assets_.Collateral_Raw);
        assets_.Total_Debt_Converted = assets_.Debt_Raw;
    }

    function getFluidSUSDeUSDCAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[5].vaultAddress,
            fluidVaultDetails[5].nftId
        );

        // In 1e18 Decimals
        assets_.Total_Collateral_Converted = IERC4626Upgradeable(_SUSDE_ADDRESS)
            .convertToAssets(assets_.Collateral_Raw);
        assets_.Total_Debt_Converted = assets_.Debt_Raw * 1e12;
    }

    function getFluidSUSDeUSDTAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[6].vaultAddress,
            fluidVaultDetails[6].nftId
        );

        // In 1e18 Decimals
        assets_.Total_Collateral_Converted = IERC4626Upgradeable(_SUSDE_ADDRESS)
            .convertToAssets(assets_.Collateral_Raw);
        assets_.Total_Debt_Converted = assets_.Debt_Raw * 1e12;
    }

    function getFluidSUSDeGHOAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[7].vaultAddress,
            fluidVaultDetails[7].nftId
        );

        // In 1e18 Decimals
        assets_.Total_Collateral_Converted = IERC4626Upgradeable(_SUSDE_ADDRESS)
            .convertToAssets(assets_.Collateral_Raw);
        assets_.Total_Debt_Converted = assets_.Debt_Raw;
    }

    function getFluidSyrupUSDCUSDCAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[8].vaultAddress,
            fluidVaultDetails[8].nftId
        );

        // In 1e6 Decimals
        assets_.Total_Collateral_Converted =
            IERC4626Upgradeable(_SYRUP_USDC_ADDRESS).convertToAssets(
                assets_.Collateral_Raw
            ) *
            1e12;
        assets_.Total_Debt_Converted = assets_.Debt_Raw * 1e12;
    }

    function getFluidSyrupUSDCUSDTAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositionFromStorage(
            fluidVaultDetails[9].vaultAddress,
            fluidVaultDetails[9].nftId
        );

        // In 1e6 Decimals
        assets_.Total_Collateral_Converted =
            IERC4626Upgradeable(_SYRUP_USDC_ADDRESS).convertToAssets(
                assets_.Collateral_Raw
            ) *
            1e12;
        assets_.Total_Debt_Converted = assets_.Debt_Raw * 1e12;
    }

    function getFluidSyrupUSDCGHOAssets()
        public
        view
        returns (AssetsViewStructs.ProtocolAssetsFluid memory assets_)
    {
        (assets_.Collateral_Raw, assets_.Debt_Raw) = _getPositio

Tags:
ERC20, Proxy, Mintable, Swap, Liquidity, Yield, Upgradeable, Factory|addr:0xfe2c8f0c05cf987556e55c13ed0feda943675476|verified:true|block:23689531|tx:0x0b87d89ea4c427ac0818e02796fbf0c091671ba22343dd90a1708c8eb3d7b6e5|first_check:1761829683

Submitted on: 2025-10-30 14:08:06

Comments

Log in to comment.

No comments yet.