ETH Price: $1,946.15 (-0.86%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0xd3e4d0db7eef6d0b2ccac587331faa7123f1b710207e0ab34bae82dd4cd43587 Transfer(pending)2026-03-01 1:44:2722 hrs ago1772329467IN
0x2A66F992...3c4F3f682
0 ETH(Pending)(Pending)
Repay245656772026-03-01 22:46:471 hr ago1772405207IN
0x2A66F992...3c4F3f682
0 ETH0.000032420.08819686
Redeem245610632026-03-01 7:21:1117 hrs ago1772349671IN
0x2A66F992...3c4F3f682
0 ETH0.000019840.03968792
Repay245588722026-03-01 0:00:5924 hrs ago1772323259IN
0x2A66F992...3c4F3f682
0 ETH0.00001350.03305447
Borrow245585172026-02-28 22:49:4725 hrs ago1772318987IN
0x2A66F992...3c4F3f682
0 ETH0.000024990.06572714
Redeem245583412026-02-28 22:14:1126 hrs ago1772316851IN
0x2A66F992...3c4F3f682
0 ETH0.000027880.05804482
Redeem245570932026-02-28 18:03:1130 hrs ago1772301791IN
0x2A66F992...3c4F3f682
0 ETH0.000049980.10455538
Redeem245564972026-02-28 16:03:1132 hrs ago1772294591IN
0x2A66F992...3c4F3f682
0 ETH0.000052640.11071297
Redeem245542102026-02-28 8:22:5940 hrs ago1772266979IN
0x2A66F992...3c4F3f682
0 ETH0.000055820.11740323
Repay245541262026-02-28 8:06:1140 hrs ago1772265971IN
0x2A66F992...3c4F3f682
0 ETH0.000883232.1495018
Borrow245538482026-02-28 7:09:4741 hrs ago1772262587IN
0x2A66F992...3c4F3f682
0 ETH0.000328580.86412354
Repay245538442026-02-28 7:08:5941 hrs ago1772262539IN
0x2A66F992...3c4F3f682
0 ETH0.000368780.89751832
Redeem245537382026-02-28 6:47:3541 hrs ago1772261255IN
0x2A66F992...3c4F3f682
0 ETH0.000199530.40503942
Repay245525512026-02-28 2:49:3545 hrs ago1772246975IN
0x2A66F992...3c4F3f682
0 ETH0.00002260.055
Repay245515932026-02-27 23:36:232 days ago1772235383IN
0x2A66F992...3c4F3f682
0 ETH0.000018980.04566124
Deposit245512682026-02-27 22:31:112 days ago1772231471IN
0x2A66F992...3c4F3f682
0 ETH0.000024930.04784471
Repay245495602026-02-27 16:48:232 days ago1772210903IN
0x2A66F992...3c4F3f682
0 ETH0.000421711.0143952
Redeem245484042026-02-27 12:56:232 days ago1772196983IN
0x2A66F992...3c4F3f682
0 ETH0.000111980.23548902
Repay245464732026-02-27 6:28:232 days ago1772173703IN
0x2A66F992...3c4F3f682
0 ETH0.000023360.056855
Repay245460452026-02-27 5:02:112 days ago1772168531IN
0x2A66F992...3c4F3f682
0 ETH0.000039860.09590214
Redeem245455972026-02-27 3:32:232 days ago1772163143IN
0x2A66F992...3c4F3f682
0 ETH0.000047830.1005979
Redeem245448652026-02-27 1:05:352 days ago1772154335IN
0x2A66F992...3c4F3f682
0 ETH0.000493711.00221201
Repay245442932026-02-26 23:10:593 days ago1772147459IN
0x2A66F992...3c4F3f682
0 ETH0.000027830.06775093
Repay245441292026-02-26 22:37:593 days ago1772145479IN
0x2A66F992...3c4F3f682
0 ETH0.000831422
Repay245440792026-02-26 22:27:593 days ago1772144879IN
0x2A66F992...3c4F3f682
0 ETH0.000036330.0874123
View all transactions

View more zero value Internal Transactions in Advanced View mode

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

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
Helper

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 999999 runs

Other Settings:
shanghai EvmVersion
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

import {IMorpho, IMorphoCredit, Id, Market, Position} from "./interfaces/IMorpho.sol";
import {MarketParams} from "./interfaces/IMorpho.sol";
import {IHelper} from "./interfaces/IHelper.sol";
import {IUSD3} from "./interfaces/IUSD3.sol";
import {IERC20} from "./interfaces/IERC20.sol";

import {ErrorsLib} from "./libraries/ErrorsLib.sol";
import {SafeTransferLib} from "./libraries/SafeTransferLib.sol";
import {SharesMathLib} from "./libraries/SharesMathLib.sol";
import {MarketParamsLib} from "./libraries/MarketParamsLib.sol";

import {IERC4626} from "../lib/forge-std/src/interfaces/IERC4626.sol";

/// @title Helper
/// @author 3Jane
/// @custom:contact [email protected]
contract Helper is IHelper {
    using SafeTransferLib for IERC20;
    using SharesMathLib for uint256;
    using MarketParamsLib for MarketParams;

    /// @inheritdoc IHelper
    address public immutable MORPHO;
    /// @inheritdoc IHelper
    address public immutable USD3;
    /// @inheritdoc IHelper
    address public immutable sUSD3;
    /// @inheritdoc IHelper
    address public immutable USDC;
    /// @inheritdoc IHelper
    address public immutable WAUSDC;

    /* CONSTRUCTOR */

    constructor(address morpho, address usd3, address susd3, address usdc, address wausdc) {
        if (morpho == address(0)) revert ErrorsLib.ZeroAddress();
        if (usd3 == address(0)) revert ErrorsLib.ZeroAddress();
        if (susd3 == address(0)) revert ErrorsLib.ZeroAddress();
        if (usdc == address(0)) revert ErrorsLib.ZeroAddress();
        if (wausdc == address(0)) revert ErrorsLib.ZeroAddress();

        MORPHO = morpho;
        USD3 = usd3;
        sUSD3 = susd3;
        USDC = usdc;
        WAUSDC = wausdc;

        // Set max approvals
        IERC20(USDC).approve(WAUSDC, type(uint256).max);
        IERC20(USDC).approve(USD3, type(uint256).max);
        IERC20(WAUSDC).approve(MORPHO, type(uint256).max);
        IERC20(USD3).approve(sUSD3, type(uint256).max);
    }

    /// @inheritdoc IHelper
    function deposit(uint256 assets, address receiver, bool hop, bytes32 referral) external returns (uint256 shares) {
        (shares) = deposit(assets, receiver, hop);
        emit DepositReferred(msg.sender, assets, referral);
    }

    /// @inheritdoc IHelper
    function deposit(uint256 assets, address receiver, bool hop) public returns (uint256) {
        if (msg.sender != receiver) revert ErrorsLib.Unauthorized();
        IERC20(USDC).safeTransferFrom(msg.sender, address(this), assets);

        if (hop) {
            require(IUSD3(USD3).availableDepositLimit(receiver) >= assets, "Deposit exceeds limit");
            uint256 usd3Shares = IUSD3(USD3).deposit(assets, address(this));
            return IERC4626(sUSD3).deposit(usd3Shares, receiver);
        } else {
            return IUSD3(USD3).deposit(assets, receiver);
        }
    }

    /// @inheritdoc IHelper
    function redeem(uint256 shares, address receiver) external returns (uint256) {
        uint256 usdcAssets = IUSD3(USD3).redeem(shares, receiver, msg.sender);
        return usdcAssets;
    }

    /// @inheritdoc IHelper
    function borrow(MarketParams memory marketParams, uint256 assets, bytes32 referral)
        external
        returns (uint256 amount, uint256 shares)
    {
        (amount, shares) = borrow(marketParams, assets);
        emit BorrowReferred(msg.sender, amount, referral);
    }

    /// @inheritdoc IHelper
    function borrow(MarketParams memory marketParams, uint256 assets) public returns (uint256, uint256) {
        uint256 waUsdcShares = IERC4626(WAUSDC).convertToShares(assets);
        (uint256 waUSDCAmount, uint256 shares) =
            IMorpho(MORPHO).borrow(marketParams, waUsdcShares, 0, msg.sender, address(this));
        uint256 usdcAmount = IERC4626(WAUSDC).redeem(waUSDCAmount, msg.sender, address(this));
        return (usdcAmount, shares);
    }

    /// @inheritdoc IHelper
    function repay(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes calldata data)
        external
        returns (uint256, uint256)
    {
        // Check if this is a full repayment request
        if (assets == type(uint256).max) {
            return _repayFull(marketParams, onBehalf, data);
        } else {
            // Normal partial repayment flow
            uint256 waUSDCAmount = _wrap(msg.sender, assets);
            (, uint256 shares) = IMorpho(MORPHO).repay(marketParams, waUSDCAmount, 0, onBehalf, data);
            return (assets, shares);
        }
    }

    function _repayFull(MarketParams memory marketParams, address onBehalf, bytes calldata data)
        internal
        returns (uint256, uint256)
    {
        Id id = marketParams.id();

        // Accrue premium first to get accurate borrow shares
        _accruePremiumsForBorrower(id, onBehalf);

        // Get current borrow shares after premium accrual
        Position memory pos = IMorpho(MORPHO).position(id, onBehalf);

        // If no debt, return early
        if (pos.borrowShares == 0) {
            return (0, 0);
        }

        // Get market state to calculate assets needed
        Market memory market = IMorpho(MORPHO).market(id);

        // Calculate waUSDC assets needed (rounds up like Morpho does)
        uint256 waUsdcNeeded = uint256(pos.borrowShares).toAssetsUp(market.totalBorrowAssets, market.totalBorrowShares);

        // Convert to USDC amount needed (preview how much USDC needed to mint waUsdcNeeded)
        uint256 usdcNeeded = IERC4626(WAUSDC).previewMint(waUsdcNeeded);

        // Pull USDC from user and wrap to waUSDC
        _wrap(msg.sender, usdcNeeded);

        // Repay with shares to ensure complete repayment
        (, uint256 sharesRepaid) = IMorpho(MORPHO).repay(marketParams, 0, pos.borrowShares, onBehalf, data);

        return (usdcNeeded, sharesRepaid);
    }

    function _wrap(address from, uint256 assets) internal returns (uint256) {
        IERC20(USDC).safeTransferFrom(from, address(this), assets);
        return IERC4626(WAUSDC).deposit(assets, address(this));
    }

    function _accruePremiumsForBorrower(Id id, address borrower) internal {
        address[] memory borrowers = new address[](1);
        borrowers[0] = borrower;
        IMorphoCredit(MORPHO).accruePremiumsForBorrowers(id, borrowers);
    }
}

File 2 of 12 : IMorpho.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.18;

type Id is bytes32;

struct MarketParams {
    address loanToken;
    address collateralToken;
    address oracle;
    address irm;
    uint256 lltv;
    address creditLine;
}

/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest
/// accrual.
struct Position {
    uint256 supplyShares;
    uint128 borrowShares;
    uint128 collateral;
}

/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.
/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.
/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last
/// interest accrual.
/// @dev Warning: `totalMarkdownAmount` may be stale as markdowns are only updated when borrowers are touched.
struct Market {
    uint128 totalSupplyAssets;
    uint128 totalSupplyShares;
    uint128 totalBorrowAssets;
    uint128 totalBorrowShares;
    uint128 lastUpdate;
    uint128 fee;
    uint128 totalMarkdownAmount; // Running tally of all borrower markdowns
}

/// @notice Per-borrower premium tracking
/// @param lastAccrualTime Timestamp of the last premium accrual for this borrower
/// @param rate Current risk premium rate per second (scaled by WAD)
/// @param borrowAssetsAtLastAccrual Snapshot of borrow position at last premium accrual
struct BorrowerPremium {
    uint128 lastAccrualTime;
    uint128 rate;
    uint128 borrowAssetsAtLastAccrual;
}

/// @notice Repayment tracking structures
enum RepaymentStatus {
    Current,
    GracePeriod,
    Delinquent,
    Default
}

struct PaymentCycle {
    uint256 endDate;
}

struct RepaymentObligation {
    uint128 paymentCycleId;
    uint128 amountDue;
    uint128 endingBalance;
}

/// @notice Markdown state for tracking defaulted debt value reduction
/// @param lastCalculatedMarkdown Last calculated markdown amount
struct MarkdownState {
    uint128 lastCalculatedMarkdown;
}

struct Authorization {
    address authorizer;
    address authorized;
    bool isAuthorized;
    uint256 nonce;
    uint256 deadline;
}

struct Signature {
    uint8 v;
    bytes32 r;
    bytes32 s;
}

/// @dev This interface is used for factorizing IMorphoStaticTyping and IMorpho.
/// @dev Consider using the IMorpho interface instead of this one.
interface IMorphoBase {
    /// @notice The EIP-712 domain separator.
    /// @dev Warning: Every EIP-712 signed message based on this domain separator can be reused on chains sharing the
    /// same chain id and on forks because the domain separator would be the same.
    function DOMAIN_SEPARATOR() external view returns (bytes32);

    /// @notice The owner of the contract.
    /// @dev It has the power to change the owner.
    /// @dev It has the power to set fees on markets and set the fee recipient.
    /// @dev It has the power to enable but not disable IRMs and LLTVs.
    function owner() external view returns (address);

    /// @notice The fee recipient of all markets.
    /// @dev The recipient receives the fees of a given market through a supply position on that market.
    function feeRecipient() external view returns (address);

    /// @notice Whether the `irm` is enabled.
    function isIrmEnabled(address irm) external view returns (bool);

    /// @notice Whether the `lltv` is enabled.
    function isLltvEnabled(uint256 lltv) external view returns (bool);

    /// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures.
    function nonce(address authorizer) external view returns (uint256);

    /// @notice Sets `newOwner` as `owner` of the contract.
    /// @dev Warning: No two-step transfer ownership.
    /// @dev Warning: The owner can be set to the zero address.
    function setOwner(address newOwner) external;

    /// @notice Enables `irm` as a possible IRM for market creation.
    /// @dev Warning: It is not possible to disable an IRM.
    function enableIrm(address irm) external;

    /// @notice Enables `lltv` as a possible LLTV for market creation.
    /// @dev Warning: It is not possible to disable a LLTV.
    function enableLltv(uint256 lltv) external;

    /// @notice Sets the `newFee` for the given market `marketParams`.
    /// @param newFee The new fee, scaled by WAD.
    /// @dev Warning: The recipient can be the zero address.
    function setFee(MarketParams memory marketParams, uint256 newFee) external;

    /// @notice Sets `newFeeRecipient` as `feeRecipient` of the fee.
    /// @dev Warning: If the fee recipient is set to the zero address, fees will accrue there and will be lost.
    /// @dev Modifying the fee recipient will allow the new recipient to claim any pending fees not yet accrued. To
    /// ensure that the current recipient receives all due fees, accrue interest manually prior to making any changes.
    function setFeeRecipient(address newFeeRecipient) external;

    /// @notice Creates the market `marketParams`.
    /// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees
    /// Morpho behaves as expected:
    /// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`.
    /// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with
    /// burn functions are not supported.
    /// - The token should not re-enter Morpho on `transfer` nor `transferFrom`.
    /// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount
    /// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported.
    /// - The IRM should not re-enter Morpho.
    /// - The oracle should return a price with the correct scaling.
    /// @dev Here is a list of assumptions on the market's dependencies which, if broken, could break Morpho's liveness
    /// properties (funds could get stuck):
    /// - The token should not revert on `transfer` and `transferFrom` if balances and approvals are right.
    /// - The amount of assets supplied and borrowed should not go above ~1e35 (otherwise the computation of
    /// `toSharesUp` and `toSharesDown` can overflow).
    /// - The IRM should not revert on `borrowRate`.
    /// - The IRM should not return a very high borrow rate (otherwise the computation of `interest` in
    /// `_accrueInterest` can overflow).
    /// - The oracle should not revert `price`.
    /// - The oracle should not return a very high price (otherwise the computation of `maxBorrow` in `_isHealthy` or of
    /// `assetsRepaid` in `liquidate` can overflow).
    /// @dev The borrow share price of a market with less than 1e4 assets borrowed can be decreased by manipulations, to
    /// the point where `totalBorrowShares` is very large and borrowing overflows.
    function createMarket(MarketParams memory marketParams) external;

    /// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's
    /// `onMorphoSupply` function with the given `data`.
    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the
    /// caller is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific
    /// amount of shares is given for full compatibility and precision.
    /// @dev Supplying a large amount can revert for overflow.
    /// @dev Supplying an amount of shares may lead to supply more or fewer assets than expected due to slippage.
    /// Consider using the `assets` parameter to avoid this.
    /// @param marketParams The market to supply assets to.
    /// @param assets The amount of assets to supply.
    /// @param shares The amount of shares to mint.
    /// @param onBehalf The address that will own the increased supply position.
    /// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed.
    /// @return assetsSupplied The amount of assets supplied.
    /// @return sharesSupplied The amount of shares minted.
    function supply(
        MarketParams memory marketParams,
        uint256 assets,
        uint256 shares,
        address onBehalf,
        bytes memory data
    ) external returns (uint256 assetsSupplied, uint256 sharesSupplied);

    /// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.
    /// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`.
    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
    /// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow.
    /// @dev It is advised to use the `shares` input when withdrawing the full position to avoid reverts due to
    /// conversion roundings between shares and assets.
    /// @param marketParams The market to withdraw assets from.
    /// @param assets The amount of assets to withdraw.
    /// @param shares The amount of shares to burn.
    /// @param onBehalf The address of the owner of the supply position.
    /// @param receiver The address that will receive the withdrawn assets.
    /// @return assetsWithdrawn The amount of assets withdrawn.
    /// @return sharesWithdrawn The amount of shares burned.
    function withdraw(
        MarketParams memory marketParams,
        uint256 assets,
        uint256 shares,
        address onBehalf,
        address receiver
    ) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn);

    /// @notice Borrows `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.
    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the
    /// caller is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is
    /// given for full compatibility and precision.
    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
    /// @dev Borrowing a large amount can revert for overflow.
    /// @dev Borrowing an amount of shares may lead to borrow fewer assets than expected due to slippage.
    /// Consider using the `assets` parameter to avoid this.
    /// @param marketParams The market to borrow assets from.
    /// @param assets The amount of assets to borrow.
    /// @param shares The amount of shares to mint.
    /// @param onBehalf The address that will own the increased borrow position.
    /// @param receiver The address that will receive the borrowed assets.
    /// @return assetsBorrowed The amount of assets borrowed.
    /// @return sharesBorrowed The amount of shares minted.
    function borrow(
        MarketParams memory marketParams,
        uint256 assets,
        uint256 shares,
        address onBehalf,
        address receiver
    ) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed);

    /// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's
    /// `onMorphoRepay` function with the given `data`.
    /// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`.
    /// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow.
    /// @dev It is advised to use the `shares` input when repaying the full position to avoid reverts due to conversion
    /// roundings between shares and assets.
    /// @dev An attacker can front-run a repay with a small repay making the transaction revert for underflow.
    /// @param marketParams The market to repay assets to.
    /// @param assets The amount of assets to repay.
    /// @param shares The amount of shares to burn.
    /// @param onBehalf The address of the owner of the debt position.
    /// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed.
    /// @return assetsRepaid The amount of assets repaid.
    /// @return sharesRepaid The amount of shares burned.
    function repay(
        MarketParams memory marketParams,
        uint256 assets,
        uint256 shares,
        address onBehalf,
        bytes memory data
    ) external returns (uint256 assetsRepaid, uint256 sharesRepaid);

    /// @notice Accrues interest for the given market `marketParams`.
    function accrueInterest(MarketParams memory marketParams) external;

    /// @notice Returns the data stored on the different `slots`.
    function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory);
}

/// @dev This interface is inherited by Morpho so that function signatures are checked by the compiler.
/// @dev Consider using the IMorpho interface instead of this one.
interface IMorphoStaticTyping is IMorphoBase {
    /// @notice The state of the position of `user` on the market corresponding to `id`.
    /// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest
    /// accrual.
    function position(Id id, address user)
        external
        view
        returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral);

    /// @notice The state of the market corresponding to `id`.
    /// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.
    /// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.
    /// @dev Warning: `totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last interest
    /// accrual.
    function market(Id id)
        external
        view
        returns (
            uint128 totalSupplyAssets,
            uint128 totalSupplyShares,
            uint128 totalBorrowAssets,
            uint128 totalBorrowShares,
            uint128 lastUpdate,
            uint128 fee,
            uint128 totalMarkdownAmount
        );

    /// @notice The market params corresponding to `id`.
    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer
    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.
    function idToMarketParams(Id id)
        external
        view
        returns (
            address loanToken,
            address collateralToken,
            address oracle,
            address irm,
            uint256 lltv,
            address creditLine
        );
}

/// @title IMorpho
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @dev Use this interface for Morpho to have access to all the functions with the appropriate function signatures.
interface IMorpho is IMorphoBase {
    /// @notice The state of the position of `user` on the market corresponding to `id`.
    /// @dev Warning: For `feeRecipient`, `p.supplyShares` does not contain the accrued shares since the last interest
    /// accrual.
    function position(Id id, address user) external view returns (Position memory p);

    /// @notice The state of the market corresponding to `id`.
    /// @dev Warning: `m.totalSupplyAssets` does not contain the accrued interest since the last interest accrual.
    /// @dev Warning: `m.totalBorrowAssets` does not contain the accrued interest since the last interest accrual.
    /// @dev Warning: `m.totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last
    /// interest accrual.
    function market(Id id) external view returns (Market memory m);

    /// @notice The market params corresponding to `id`.
    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer
    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.
    function idToMarketParams(Id id) external view returns (MarketParams memory);
}

/// @title IMorphoCredit
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @dev Use this interface for Morpho to have access to all the functions with the appropriate function signatures.
interface IMorphoCredit {
    /// @notice The helper of the contract.
    function helper() external view returns (address);

    /// @notice The usd3 contract
    function usd3() external view returns (address);

    /// @notice The protocol config of the contract.
    function protocolConfig() external view returns (address);

    /// @notice Sets `helper` as `helper` of the contract.
    /// @param newHelper The new helper address
    function setHelper(address newHelper) external;

    /// @notice Sets `usd3` as `usd3` of the contract.
    /// @param newUsd3 The new usd3 address
    function setUsd3(address newUsd3) external;

    /// @notice Sets the credit line and premium rate for a borrower
    /// @param id The market ID
    /// @param borrower The borrower address
    /// @param credit The credit line amount
    /// @param drp The drp per second in WAD
    function setCreditLine(Id id, address borrower, uint256 credit, uint128 drp) external;

    /// @notice Returns the premium data for a specific borrower in a market
    /// @param id The market ID
    /// @param borrower The borrower address
    /// @return lastAccrualTime Timestamp of the last premium accrual
    /// @return rate Current risk premium rate per second (scaled by WAD)
    /// @return borrowAssetsAtLastAccrual Snapshot of borrow position at last premium accrual
    function borrowerPremium(Id id, address borrower)
        external
        view
        returns (uint128 lastAccrualTime, uint128 rate, uint128 borrowAssetsAtLastAccrual);

    /// @notice Batch accrue premiums for multiple borrowers
    /// @param id Market ID
    /// @param borrowers Array of borrower addresses
    /// @dev Gas usage scales linearly with array size. Callers should manage batch sizes based on block gas limits.
    function accruePremiumsForBorrowers(Id id, address[] calldata borrowers) external;

    /// @notice Close a payment cycle and post obligations for multiple borrowers
    /// @param id Market ID
    /// @param endDate Cycle end date
    /// @param borrowers Array of borrower addresses
    /// @param repaymentBps Array of repayment basis points (e.g., 500 = 5%)
    /// @param endingBalances Array of ending balances for penalty calculations
    function closeCycleAndPostObligations(
        Id id,
        uint256 endDate,
        address[] calldata borrowers,
        uint256[] calldata repaymentBps,
        uint256[] calldata endingBalances
    ) external;

    /// @notice Add obligations to the latest payment cycle
    /// @param id Market ID
    /// @param borrowers Array of borrower addresses
    /// @param repaymentBps Array of repayment basis points (e.g., 500 = 5%)
    /// @param endingBalances Array of ending balances
    function addObligationsToLatestCycle(
        Id id,
        address[] calldata borrowers,
        uint256[] calldata repaymentBps,
        uint256[] calldata endingBalances
    ) external;

    /// @notice Get repayment obligation for a borrower
    /// @param id Market ID
    /// @param borrower Borrower address
    /// @return cycleId The payment cycle ID
    /// @return amountDue The amount due
    /// @return endingBalance The ending balance for penalty calculations
    function repaymentObligation(Id id, address borrower)
        external
        view
        returns (uint128 cycleId, uint128 amountDue, uint128 endingBalance);

    /// @notice Get payment cycle end date
    /// @param id Market ID
    /// @param cycleId Cycle ID
    /// @return endDate The cycle end date
    function paymentCycle(Id id, uint256 cycleId) external view returns (uint256 endDate);

    /// @notice Settle a borrower's account by writing off all remaining debt
    /// @dev Only callable by credit line contract
    /// @dev Should be called after any partial repayments have been made
    /// @param marketParams The market parameters
    /// @param borrower The borrower whose account to settle
    /// @return writtenOffAssets Amount of assets written off
    /// @return writtenOffShares Amount of shares written off
    function settleAccount(MarketParams memory marketParams, address borrower)
        external
        returns (uint256 writtenOffAssets, uint256 writtenOffShares);

    /// @notice Get markdown state for a borrower
    /// @param id Market ID
    /// @param borrower Borrower address
    /// @return lastCalculatedMarkdown Last calculated markdown amount
    function markdownState(Id id, address borrower) external view returns (uint128 lastCalculatedMarkdown);
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

import {IERC4626} from "../../lib/forge-std/src/interfaces/IERC4626.sol";

import {MarketParams} from "./IMorpho.sol";

/// @title IHelper
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Helper contract to simplify interactions with 3Jane's token ecosystem and Morpho protocol
/// @dev This contract handles token conversions for USD3 (post-reinitialize) and MorphoCredit operations
/// @dev After USD3's reinitialize(), the flow is: USDC → USD3 (→ sUSD3 if hop=true)
/// @dev MorphoCredit still uses waUSDC, so borrow/repay operations handle the USDC ↔ waUSDC conversion
interface IHelper {
    event DepositReferred(address indexed depositor, uint256 amount, bytes32 code);
    event BorrowReferred(address indexed borrower, uint256 amount, bytes32 code);

    /// @notice The Morpho protocol contract address
    /// @return The address of the Morpho contract
    function MORPHO() external view returns (address);

    /// @notice The USD3 token address (ERC4626 vault, accepts USDC directly after reinitialize)
    /// @return The address of the USD3 token
    function USD3() external view returns (address);

    /// @notice The sUSD3 token address (subordinate/staked USD3, also ERC4626)
    /// @return The address of the sUSD3 token
    function sUSD3() external view returns (address);

    /// @notice The USDC token address (base stablecoin)
    /// @return The address of the USDC token
    function USDC() external view returns (address);

    /// @notice The waUSDC token address (wrapped asset USDC, ERC4626 vault)
    /// @return The address of the waUSDC token
    function WAUSDC() external view returns (address);

    /// @notice Deposits USDC into USD3 (and optionally sUSD3)
    /// @dev After USD3's reinitialize(), flow is: USDC → USD3 (→ sUSD3 if hop=true)
    /// @dev USD3 handles USDC directly and manages waUSDC wrapping internally
    /// @param assets The amount of USDC to deposit
    /// @param receiver The address that will receive the USD3/sUSD3 shares
    /// @param hop If true, deposits into sUSD3; if false, stops at USD3
    /// @return The amount of shares minted (USD3 or sUSD3 depending on hop)
    function deposit(uint256 assets, address receiver, bool hop) external returns (uint256);

    /// @notice Deposits USDC into USD3 (and optionally sUSD3) with referral tracking
    /// @dev Same as deposit() but emits DepositReferred event for referral tracking
    /// @param assets The amount of USDC to deposit
    /// @param receiver The address that will receive the USD3/sUSD3 shares
    /// @param hop If true, deposits into sUSD3; if false, stops at USD3
    /// @param referral Referral code for tracking purposes
    /// @return The amount of shares minted (USD3 or sUSD3 depending on hop)
    function deposit(uint256 assets, address receiver, bool hop, bytes32 referral) external returns (uint256);

    /// @notice Redeems USD3 shares back to USDC
    /// @dev After USD3's reinitialize(), USD3 returns USDC directly
    /// @dev Caller must have approved Helper for USD3 spending
    /// @param shares The amount of USD3 shares to redeem
    /// @param receiver The address that will receive the USDC
    /// @return The amount of USDC received
    function redeem(uint256 shares, address receiver) external returns (uint256);

    /// @notice Borrows assets from a Morpho market and unwraps to USDC
    /// @dev The borrowed waUSDC is automatically unwrapped to USDC for the borrower
    /// @param marketParams The market parameters defining which market to borrow from
    /// @param assets The amount of assets to borrow (in waUSDC terms)
    /// @return usdcAmount The amount of USDC received by the borrower
    /// @return shares The amount of borrow shares created
    function borrow(MarketParams memory marketParams, uint256 assets) external returns (uint256, uint256);

    /// @notice Borrows assets from a Morpho market and unwraps to USDC with referral tracking
    /// @dev Same as borrow() but emits BorrowReferred event for referral tracking
    /// @param marketParams The market parameters defining which market to borrow from
    /// @param assets The amount of assets to borrow (in waUSDC terms)
    /// @param referral Referral code for tracking purposes
    /// @return usdcAmount The amount of USDC received by the borrower
    /// @return shares The amount of borrow shares created
    function borrow(MarketParams memory marketParams, uint256 assets, bytes32 referral)
        external
        returns (uint256, uint256);

    /// @notice Repays a loan by wrapping USDC to waUSDC
    /// @dev Flow: USDC → waUSDC → Morpho repay. Caller must have approved Helper for USDC spending
    /// @param marketParams The market parameters defining which market to repay
    /// @param assets The amount of USDC to repay
    /// @param onBehalf The address whose debt is being repaid
    /// @param data Additional data for the repay operation (e.g., for callbacks)
    /// @return usdcAmount The amount of USDC used from the caller
    /// @return shares The amount of borrow shares repaid
    function repay(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes calldata data)
        external
        returns (uint256, uint256);
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

import {IERC4626} from "../../lib/forge-std/src/interfaces/IERC4626.sol";

/// @title IUSD3
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Interface for USD3 token, which is an ERC4626 vault
interface IUSD3 is IERC4626 {
    // USD3 inherits all ERC4626 functions including:
    // - deposit(uint256 assets, address receiver) returns (uint256 shares)
    // - redeem(uint256 shares, address receiver, address owner) returns (uint256 assets)
    // - And all other ERC4626 standard functions
    function whitelist(address user) external view returns (bool);
    function availableDepositLimit(address owner) external view returns (uint256);
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title IERC20
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @dev Empty because we only call library functions. It prevents calling transfer (transferFrom) instead of
/// safeTransfer (safeTransferFrom).
interface IERC20 {
    function approve(address spender, uint256 value) external returns (bool);
}

File 6 of 12 : ErrorsLib.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

/// @title ErrorsLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library exposing custom errors.
library ErrorsLib {
    /// @notice Thrown when the caller is not the owner.
    error NotOwner();

    /// @notice Thrown when the caller is not the market's credit line.
    error NotCreditLine();

    /// @notice Thrown when the caller is not the market's helper.
    error NotHelper();

    /// @notice Thrown when the caller is not the market's usd3.
    error NotUsd3();

    /// @notice Thrown when the caller is not the owner or ozd.
    error NotOwnerOrOzd();

    /// @notice Thrown when the user is unverified.
    error Unverified();

    /// @notice Thrown when the LLTV to enable exceeds the maximum LLTV.
    error MaxLltvExceeded();

    /// @notice Thrown when the LTV to enable exceeds the maximum LTV.
    error MaxLtvExceeded();

    /// @notice Thrown when the VV to enable exceeds the maximum VV.
    error MaxVvExceeded();

    /// @notice Thrown when the credit to enable exceeds the maximum credit.
    error MaxCreditLineExceeded();

    /// @notice Thrown when the credit to enable is below the minimum credit.
    error MinCreditLineExceeded();

    /// @notice Thrown when the fee to set exceeds the maximum fee.
    error MaxFeeExceeded();

    /// @notice Thrown when the value is already set.
    error AlreadySet();

    /// @notice Thrown when the IRM is not enabled at market creation.
    error IrmNotEnabled();

    /// @notice Thrown when the LLTV is not enabled at market creation.
    error LltvNotEnabled();

    /// @notice Thrown when the market is already created.
    error MarketAlreadyCreated();

    /// @notice Thrown when a token to transfer doesn't have code.
    error NoCode();

    /// @notice Thrown when the market is not created.
    error MarketNotCreated();

    /// @notice Thrown when not exactly one of the input amount is zero.
    error InconsistentInput();

    /// @notice Thrown when zero assets is passed as input.
    error ZeroAssets();

    /// @notice Thrown when a zero address is passed as input.
    error ZeroAddress();

    /// @notice Thrown when an array has an invalid length.
    error InvalidArrayLength();

    /// @notice Thrown when the caller is not authorized to conduct an action.
    error Unauthorized();

    /// @notice Thrown when the collateral is insufficient to `borrow` or `withdrawCollateral`.
    error InsufficientCollateral();

    /// @notice Thrown when the liquidity is insufficient to `withdraw` or `borrow`.
    error InsufficientLiquidity();

    /// @notice Thrown when borrowing shares would result in borrowing zero assets.
    error InsufficientBorrowAmount();

    /// @notice Thrown when a token transfer reverted.
    error TransferReverted();

    /// @notice Thrown when a token transfer returned false.
    error TransferReturnedFalse();

    /// @notice Thrown when a token transferFrom reverted.
    error TransferFromReverted();

    /// @notice Thrown when a token transferFrom returned false
    error TransferFromReturnedFalse();

    /// @notice Thrown when the maximum uint128 is exceeded.
    error MaxUint128Exceeded();

    /// @notice Thrown when the premium rate exceeds the maximum allowed.
    error MaxDrpExceeded();

    /// @notice Thrown when the borrower has outstanding repayment obligations.
    error OutstandingRepayment();

    /// @notice Thrown when the protocol is paused.
    error Paused();

    /// @notice Thrown when trying to close a future cycle.
    error CannotCloseFutureCycle();

    /// @notice Thrown when cycle duration is invalid.
    error InvalidCycleDuration();

    /// @notice Thrown when no payment cycles exist.
    error NoCyclesExist();

    /// @notice Thrown when cycle ID is invalid.
    error InvalidCycleId();

    /// @notice Thrown when partial payment is attempted but full obligation payment is required.
    error MustPayFullObligation();

    /// @notice Thrown when repayment basis points exceed 100%.
    error RepaymentExceedsHundredPercent();

    /// @notice Thrown when an invalid markdown manager is set.
    error InvalidMarkdownManager();

    /// @notice Thrown when trying to settle non-existent debt.
    error NoAccountToSettle();

    /// @notice Thrown when the cover amount exceeds the assets amount.
    error InvalidCoverAmount();

    /// @notice Thrown when attempting operations on a frozen market.
    error MarketFrozen();

    /// @notice Thrown when a borrow would exceed the protocol debt cap.
    error DebtCapExceeded();

    /// @notice Thrown when borrow or repay would result in debt below minimum borrow amount.
    error BelowMinimumBorrow();
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {IERC20} from "../interfaces/IERC20.sol";

import {ErrorsLib} from "../libraries/ErrorsLib.sol";

interface IERC20Internal {
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

/// @title SafeTransferLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library to manage transfers of tokens, even if calls to the transfer or transferFrom functions are not
/// returning a boolean.
library SafeTransferLib {
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        if (address(token).code.length == 0) revert ErrorsLib.NoCode();

        (bool success, bytes memory returndata) =
            address(token).call(abi.encodeCall(IERC20Internal.transfer, (to, value)));
        if (!success) revert ErrorsLib.TransferReverted();
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) revert ErrorsLib.TransferReturnedFalse();
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        if (address(token).code.length == 0) revert ErrorsLib.NoCode();

        (bool success, bytes memory returndata) =
            address(token).call(abi.encodeCall(IERC20Internal.transferFrom, (from, to, value)));
        if (!success) revert ErrorsLib.TransferFromReverted();
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) revert ErrorsLib.TransferFromReturnedFalse();
    }
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {MathLib} from "./MathLib.sol";

/// @title SharesMathLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Shares management library.
/// @dev This implementation mitigates share price manipulations, using OpenZeppelin's method of virtual shares:
/// https://docs.openzeppelin.com/contracts/4.x/erc4626#inflation-attack.
library SharesMathLib {
    using MathLib for uint256;

    /// @dev The number of virtual shares has been chosen low enough to prevent overflows, and high enough to ensure
    /// high precision computations.
    /// @dev Virtual shares can never be redeemed for the assets they are entitled to, but it is assumed the share price
    /// stays low enough not to inflate these assets to a significant value.
    /// @dev Warning: The assets to which virtual borrow shares are entitled behave like unrealizable bad debt.
    uint256 internal constant VIRTUAL_SHARES = 1e6;

    /// @dev A number of virtual assets of 1 enforces a conversion rate between shares and assets when a market is
    /// empty.
    uint256 internal constant VIRTUAL_ASSETS = 1;

    /// @dev Calculates the value of `assets` quoted in shares, rounding down.
    function toSharesDown(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
        return assets.mulDivDown(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS);
    }

    /// @dev Calculates the value of `shares` quoted in assets, rounding down.
    function toAssetsDown(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
        return shares.mulDivDown(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES);
    }

    /// @dev Calculates the value of `assets` quoted in shares, rounding up.
    function toSharesUp(uint256 assets, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
        return assets.mulDivUp(totalShares + VIRTUAL_SHARES, totalAssets + VIRTUAL_ASSETS);
    }

    /// @dev Calculates the value of `shares` quoted in assets, rounding up.
    function toAssetsUp(uint256 shares, uint256 totalAssets, uint256 totalShares) internal pure returns (uint256) {
        return shares.mulDivUp(totalAssets + VIRTUAL_ASSETS, totalShares + VIRTUAL_SHARES);
    }
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {Id, MarketParams} from "../interfaces/IMorpho.sol";

/// @title MarketParamsLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library to convert a market to its id.
library MarketParamsLib {
    /// @notice The length of the data used to compute the id of a market.
    /// @dev The length is 6 * 32 because `MarketParams` has 6 variables of 32 bytes each.
    uint256 internal constant MARKET_PARAMS_BYTES_LENGTH = 6 * 32;

    /// @notice Returns the id of the market `marketParams`.
    function id(MarketParams memory marketParams) internal pure returns (Id marketParamsId) {
        assembly ("memory-safe") {
            marketParamsId := keccak256(marketParams, MARKET_PARAMS_BYTES_LENGTH)
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

import {IERC20} from "./IERC20.sol";

/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in
/// https://eips.ethereum.org/EIPS/eip-4626
interface IERC4626 is IERC20 {
    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
    );

    /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
    /// @dev
    /// - MUST be an ERC-20 token contract.
    /// - MUST NOT revert.
    function asset() external view returns (address assetTokenAddress);

    /// @notice Returns the total amount of the underlying asset that is “managed” by Vault.
    /// @dev
    /// - 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);

    /// @notice 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.
    /// @dev
    /// - 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);

    /// @notice 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.
    /// @dev
    /// - 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);

    /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
    /// through a deposit call.
    /// @dev
    /// - 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);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
    /// current on-chain conditions.
    /// @dev
    /// - 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);

    /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
    /// @dev
    /// - 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);

    /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
    /// @dev
    /// - 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);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
    /// current on-chain conditions.
    /// @dev
    /// - 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);

    /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
    /// @dev
    /// - 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);

    /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
    /// Vault, through a withdrawal call.
    /// @dev
    /// - 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);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
    /// given current on-chain conditions.
    /// @dev
    /// - 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);

    /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver.
    /// @dev
    /// - 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 withdrawal.
    /// - 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);

    /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
    /// through a redeem call.
    /// @dev
    /// - 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);

    /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
    /// given current on-chain conditions.
    /// @dev
    /// - 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);

    /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver.
    /// @dev
    /// - 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: GPL-2.0-or-later
pragma solidity ^0.8.0;

uint256 constant WAD = 1e18;

/// @title MathLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library to manage fixed-point arithmetic.
library MathLib {
    /// @dev Returns (`x` * `y`) / `WAD` rounded down.
    function wMulDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD);
    }

    /// @dev Returns (`x` * `WAD`) / `y` rounded down.
    function wDivDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y);
    }

    /// @dev Returns (`x` * `WAD`) / `y` rounded up.
    function wDivUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y);
    }

    /// @dev Returns (`x` * `y`) / `d` rounded down.
    function mulDivDown(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {
        return (x * y) / d;
    }

    /// @dev Returns (`x` * `y`) / `d` rounded up.
    function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {
        return (x * y + (d - 1)) / d;
    }

    /// @dev Returns the sum of the first three non-zero terms of a Taylor expansion of e^(nx) - 1, to approximate a
    /// continuous compound interest rate.
    function wTaylorCompounded(uint256 x, uint256 n) internal pure returns (uint256) {
        uint256 firstTerm = x * n;
        uint256 secondTerm = mulDivDown(firstTerm, firstTerm, 2 * WAD);
        uint256 thirdTerm = mulDivDown(secondTerm, firstTerm, 3 * WAD);

        return firstTerm + secondTerm + thirdTerm;
    }

    /// @dev Computes the inverse of wTaylorCompounded, finding the rate that produces the given growth factor.
    /// Uses a 3-term Taylor series approximation of ln(x) to solve for rate in the compound interest formula.
    /// Formula: rate = ln(x) / n ≈ [(x-1) - (x-1)²/2 + (x-1)³/3] / n
    ///
    /// Accuracy notes:
    /// - The Taylor approximation of ln(x) is most accurate for x close to 1
    /// - At growth factor x = 1.69*WAD (69% growth), approximation error < 2%
    /// - At growth factor x = 2*WAD (100% growth, where ln(2) ≈ 0.69), approximation error < 5%
    /// - Accuracy decreases for larger growth factors; not recommended for x > 2.5*WAD (150% growth)
    ///
    /// Example: If debt grew from 1000 to 1105 over 1 year (10.5% growth):
    /// - x = 1.105*WAD (growth factor)
    /// - n = 365 days (time period)
    /// - Returns ~10% APR as rate per second
    ///
    /// @param x The growth factor scaled by WAD (e.g., 1.1*WAD for 10% growth). Must be >= WAD.
    /// @param n The time period over which the growth occurred (in seconds)
    /// @return The continuously compounded rate per second that would produce this growth (scaled by WAD)
    function wInverseTaylorCompounded(uint256 x, uint256 n) internal pure returns (uint256) {
        require(x >= WAD, "ln undefined");

        uint256 firstTerm = x - WAD;
        uint256 secondTerm = wMulDown(firstTerm, firstTerm);
        uint256 thirdTerm = wMulDown(secondTerm, firstTerm);

        uint256 series = firstTerm - secondTerm / 2 + thirdTerm / 3;

        return series / n;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

/// @dev Interface of the ERC20 standard as defined in the EIP.
/// @dev This includes the optional name, symbol, and decimals metadata.
interface IERC20 {
    /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).
    event Transfer(address indexed from, address indexed to, uint256 value);

    /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`
    /// is the new allowance.
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /// @notice Returns the amount of tokens in existence.
    function totalSupply() external view returns (uint256);

    /// @notice Returns the amount of tokens owned by `account`.
    function balanceOf(address account) external view returns (uint256);

    /// @notice Moves `amount` tokens from the caller's account to `to`.
    function transfer(address to, uint256 amount) external returns (bool);

    /// @notice Returns the remaining number of tokens that `spender` is allowed
    /// to spend on behalf of `owner`
    function allowance(address owner, address spender) external view returns (uint256);

    /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.
    /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    function approve(address spender, uint256 amount) external returns (bool);

    /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.
    /// `amount` is then deducted from the caller's allowance.
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    /// @notice Returns the name of the token.
    function name() external view returns (string memory);

    /// @notice Returns the symbol of the token.
    function symbol() external view returns (string memory);

    /// @notice Returns the decimals places of the token.
    function decimals() external view returns (uint8);
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "halmos-cheatcodes/=lib/halmos-cheatcodes/src/",
    "@tokenized-strategy/=lib/tokenized-strategy/src/",
    "@periphery/=lib/tokenized-strategy-periphery/src/",
    "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    "@openzeppelin/=lib/tokenized-strategy-periphery/lib/openzeppelin-contracts/",
    "@yearn-vaults/=lib/tokenized-strategy-periphery/lib/yearn-vaults-v3/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/tokenized-strategy/lib/erc4626-tests/",
    "openzeppelin-contracts/=lib/tokenized-strategy/lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin/",
    "tokenized-strategy-periphery/=lib/tokenized-strategy-periphery/",
    "tokenized-strategy/=lib/tokenized-strategy/",
    "yearn-vaults-v3/=lib/tokenized-strategy-periphery/lib/yearn-vaults-v3/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "viaIR": true
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"morpho","type":"address"},{"internalType":"address","name":"usd3","type":"address"},{"internalType":"address","name":"susd3","type":"address"},{"internalType":"address","name":"usdc","type":"address"},{"internalType":"address","name":"wausdc","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NoCode","type":"error"},{"inputs":[],"name":"TransferFromReturnedFalse","type":"error"},{"inputs":[],"name":"TransferFromReverted","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"BorrowReferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"code","type":"bytes32"}],"name":"DepositReferred","type":"event"},{"inputs":[],"name":"MORPHO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USD3","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WAUSDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"},{"internalType":"address","name":"creditLine","type":"address"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"bytes32","name":"referral","type":"bytes32"}],"name":"borrow","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"},{"internalType":"address","name":"creditLine","type":"address"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"borrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bool","name":"hop","type":"bool"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bool","name":"hop","type":"bool"},{"internalType":"bytes32","name":"referral","type":"bytes32"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"},{"internalType":"address","name":"creditLine","type":"address"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"onBehalf","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"repay","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sUSD3","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6101206040818152346200031b5760a08262001c9280380380916200002582856200031f565b8339810103126200031b576200003b8262000357565b6020906200004b82850162000357565b906200005984860162000357565b906200007660806200006e6060890162000357565b970162000357565b956001600160a01b0392828416156200030a57838516156200030a57838116156200030a57838216948515620002f957848916938415620002e85760805260a05260c05260e052610100958652845163095ea7b360e01b91828252600482015284816044815f8019988960248401525af180156200029a57620002c6575b505f848360e0511660448560a051168951948593849288845260048401528960248401525af180156200029a57620002a4575b505f8483885116604485608051168951948593849288845260048401528960248401525af180156200029a579160449186949362000278575b505f8360a051169360c0511693885196879586948552600485015260248401525af180156200026e5762000239575b50505161190b9182620003878339608051828181610598015281816108d301528181610b710152818161108201528181611118015281816111ab015281816112410152611471015260a05182818160df015281816103e001528181610c270152610eb3015260c0518281816101d80152610d23015260e0518281816102b401528181610bfa0152610f5a015251818181610246015281816107c101528181610fc601526113380152f35b816200025d92903d1062000266575b6200025481836200031f565b8101906200036c565b505f806200018f565b503d62000248565b83513d5f823e3d90fd5b6200029290853d871162000266576200025481836200031f565b505f62000160565b86513d5f823e3d90fd5b620002be90853d871162000266576200025481836200031f565b505f62000127565b620002e090853d871162000266576200025481836200031f565b505f620000f4565b885163d92e233d60e01b8152600490fd5b875163d92e233d60e01b8152600490fd5b865163d92e233d60e01b8152600490fd5b5f80fd5b601f909101601f19168101906001600160401b038211908210176200034357604052565b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036200031b57565b908160209103126200031b575180151581036200031b579056fe604060808152600480361015610013575f80fd5b5f3560e01c9081632b97236d146105bc5781633acb56241461054e57816348c4cf8c146105095781635d150a29146104585781637bde82f21461032c57816383df6747146102d857816389a302711461026a578163cb6d71bc146101fc578163f7f6ba531461018e578163f866af0f14610107575063fcd72b8614610096575f80fd5b34610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5f80fd5b82346101035760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101035760209135906101566101476106a5565b61014f610781565b9084610bcf565b918151908152606435848201527f51bd79fe925d34dd35ece291269c5b8870db05f360c336d1cb6b778d2b252cc1823392a251908152f35b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b82346101035760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576103256020926103166106a5565b61031e610781565b9135610bcf565b9051908152f35b823461010357807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101035760206103c6926103696106a5565b83517fba087652000000000000000000000000000000000000000000000000000000008152823592810192835273ffffffffffffffffffffffffffffffffffffffff90911660208301523360408301529384918291606090910190565b03815f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af190811561044f575f9161041a575b6020925051908152f35b90506020823d602011610447575b8161043560209383610637565b81010312610103576020915190610410565b3d9150610428565b513d5f823e3d90fd5b905034610103576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261010357610493366106c8565b9060e4359173ffffffffffffffffffffffffffffffffffffffff8316830361010357610104359267ffffffffffffffff928385116101035736602386011215610103578401359283116101035736602484860101116101035760246104fd94019160c43590610a55565b82519182526020820152f35b82346101035760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576104fd610545366106c8565b60c435906107a6565b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b8234610103576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576105f9610545366106c8565b825182815260e43560208201527f1b7ae6a70016176e99f0d91a76a774e1209b170912caca81475e3a2d85863af1843392a282519182526020820152f35b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761067857604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361010357565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c0910112610103576040519060c0820182811067ffffffffffffffff8211176106785760405273ffffffffffffffffffffffffffffffffffffffff826004358281168103610103578152602435828116810361010357602082015260443582811681036101035760408201526064358281168103610103576060820152608435608082015260a43591821682036101035760a00152565b60443590811515820361010357565b9190826040910312610103576020825192015190565b91909173ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000166040928351957fc6e6f59200000000000000000000000000000000000000000000000000000000875260048701526020928387602481865afa968715610a0d575f976109da575b5061014485925f6108b89385519a8b9586947f107ddb03000000000000000000000000000000000000000000000000000000008652600486019060a0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015282606082015116606086015260808101516080860152015116910152565b60c48401528160e484015233610104840152306101248401527f0000000000000000000000000000000000000000000000000000000000000000165af19485156109d0575f905f96610994575b5083517fba0876520000000000000000000000000000000000000000000000000000000081526004810191909152336024820152306044820152919081908390815f81606481015b03925af192831561044f57505f92610966575b50509190565b90809250813d831161098d575b61097d8183610637565b8101031261010357515f80610960565b503d610973565b839296505f9391506109be61094d91863d88116109c9575b6109b68183610637565b810190610790565b979394509150610905565b503d6109ac565b83513d5f823e3d90fd5b919096508382813d8311610a06575b6109f38183610637565b8101031261010357905195610144610828565b503d6109e9565b85513d5f823e3d90fd5b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe093818652868601375f8582860101520116010190565b9194939291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8103610a92575093610a8e9394611016565b9091565b92610b475f60409493610b6d610aa88833610f33565b9573ffffffffffffffffffffffffffffffffffffffff958689519c8d998a9889977f58e83ce0000000000000000000000000000000000000000000000000000000008952600489019060a0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015282606082015116606086015260808101516080860152015116910152565b60c48701528660e487015216610104850152610140610124850152610144840191610a17565b03927f0000000000000000000000000000000000000000000000000000000000000000165af1928315610bc4575f93610ba557509190565b610bbf91935060403d6040116109c9576109b68183610637565b905090565b6040513d5f823e3d90fd5b9173ffffffffffffffffffffffffffffffffffffffff9182811691823303610f0957610c1f853033877f00000000000000000000000000000000000000000000000000000000000000001661176c565b15610e5b57827f0000000000000000000000000000000000000000000000000000000000000000166040948551937f46aa2f1200000000000000000000000000000000000000000000000000000000855260048501526020938481602481865afa908115610e51579082915f91610e20575b5010610dc35785517f6e553f65000000000000000000000000000000000000000000000000000000008082526004820192909252306024820152918490839060449082905f905af1918215610db9575f92610d82575b508551908152600481019190915273ffffffffffffffffffffffffffffffffffffffff90911660248201529181908390815f81604481015b03927f0000000000000000000000000000000000000000000000000000000000000000165af192831561044f57505f92610d5857505090565b90809250813d8311610d7b575b610d6f8183610637565b81010312610103575190565b503d610d65565b929150938383813d8311610db2575b610d9b8183610637565b810103126101035791519193909190610d1f610ce7565b503d610d91565b86513d5f823e3d90fd5b6064848751907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601560248201527f4465706f7369742065786365656473206c696d697400000000000000000000006044820152fd5b809250868092503d8311610e4a575b610e398183610637565b81010312610103578190515f610c91565b503d610e2f565b87513d5f823e3d90fd5b6040517f6e553f65000000000000000000000000000000000000000000000000000000008152600481019490945273ffffffffffffffffffffffffffffffffffffffff16602484015250602090829060449082905f907f0000000000000000000000000000000000000000000000000000000000000000165af1908115610bc4575f91610ee6575090565b90506020813d602011610f01575b81610d6f60209383610637565b3d9150610ef4565b60046040517f82b42900000000000000000000000000000000000000000000000000000000008152fd5b610fc26020915f93610f7f8173ffffffffffffffffffffffffffffffffffffffff933090857f00000000000000000000000000000000000000000000000000000000000000001661176c565b6040517f6e553f65000000000000000000000000000000000000000000000000000000008152600481019190915230602482015293849283919082906044820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af1908115610bc4575f91610ee6575090565b51906fffffffffffffffffffffffffffffffff8216820361010357565b93929360c08120925f956040516040810181811067ffffffffffffffff82111761067857604052600181526020368183013780511561173f5773ffffffffffffffffffffffffffffffffffffffff8516602082015273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163b156101035760405180917f78c56d650000000000000000000000000000000000000000000000000000000082528760048301526040602483015280518060448401526020606484019201905f5b8181106117105750505090805f9203818373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af18015610bc4576116f3575b506040517f93c5206200000000000000000000000000000000000000000000000000000000815285600482015273ffffffffffffffffffffffffffffffffffffffff8516602482015260608160448173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9081156114ee57889161167e575b506fffffffffffffffffffffffffffffffff6020820151161561167457604051957f5c60e39a000000000000000000000000000000000000000000000000000000008752600487015260e08660248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9586156114ee5788966115ad575b506fffffffffffffffffffffffffffffffff6020820151166fffffffffffffffffffffffffffffffff60608160408a015116980151166001880180981161158057620f42408101918282116115535788810298818a04149015171561158057620f423f908282820111611553578801018097116115265780156114f957604051967fb3d7f6b900000000000000000000000000000000000000000000000000000000885204600487015260208660248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa9586156114ee5788966114b0575b50611431926040949273ffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff6020611457956113a78c33610f33565b5001511697875198899788977f58e83ce0000000000000000000000000000000000000000000000000000000008952600489019060a0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015282606082015116606086015260808101516080860152015116910152565b8c60c488015260e487015216610104850152610140610124850152610144840191610a17565b03818773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165af19384156114a45793610ba557509190565b604051903d90823e3d90fd5b909550602093919293813d6020116114e6575b816114d060209383610637565b8101031261010357519490929190611431611368565b3d91506114c3565b6040513d8a823e3d90fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526012600452fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b90955060e0813d60e01161166c575b816115c960e09383610637565b81010312611668576040519060e0820182811067ffffffffffffffff8211176106785761165c9160c0916040526115ff81610ff9565b845261160d60208201610ff9565b602085015261161e60408201610ff9565b604085015261162f60608201610ff9565b606085015261164060808201610ff9565b608085015261165160a08201610ff9565b60a085015201610ff9565b60c0820152945f611271565b8780fd5b3d91506115bc565b5050505050508190565b90506060813d6060116116eb575b8161169960609383610637565b8101031261166857604051906060820182811067ffffffffffffffff821117610678576116e0916040918252805184526116d560208201610ff9565b602085015201610ff9565b60408201525f6111db565b3d915061168c565b90965067ffffffffffffffff8111610678576040525f955f611145565b825173ffffffffffffffffffffffffffffffffffffffff168452859450602093840193909201916001016110f0565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b91909273ffffffffffffffffffffffffffffffffffffffff80931692833b156118e157604051928160208501967f23b872dd00000000000000000000000000000000000000000000000000000000885216602485015216604483015260648201526064815260a081019167ffffffffffffffff9382841085851117610678575f809493819460405251925af13d156118d8573d918211610678576040519161183c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184610637565b82523d5f602084013e5b156118ae57805190811515918261188a575b505061186057565b60046040517f1eded19c000000000000000000000000000000000000000000000000000000008152fd5b81925090602091810103126101035760200151801590811503610103575f80611858565b60046040517fe65b7a77000000000000000000000000000000000000000000000000000000008152fd5b60609150611846565b60046040517ff046a714000000000000000000000000000000000000000000000000000000008152fd000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc000000000000000000000000056b269eb1f75477a8666ae8c7fe01b64dd55ecc000000000000000000000000f689555121e529ff0463e191f9bd9d1e496164a7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000d4fa2d31b7968e448877f69a96de69f5de8cd23e

Deployed Bytecode

0x604060808152600480361015610013575f80fd5b5f3560e01c9081632b97236d146105bc5781633acb56241461054e57816348c4cf8c146105095781635d150a29146104585781637bde82f21461032c57816383df6747146102d857816389a302711461026a578163cb6d71bc146101fc578163f7f6ba531461018e578163f866af0f14610107575063fcd72b8614610096575f80fd5b34610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000056b269eb1f75477a8666ae8c7fe01b64dd55ecc168152f35b5f80fd5b82346101035760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101035760209135906101566101476106a5565b61014f610781565b9084610bcf565b918151908152606435848201527f51bd79fe925d34dd35ece291269c5b8870db05f360c336d1cb6b778d2b252cc1823392a251908152f35b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f689555121e529ff0463e191f9bd9d1e496164a7168152f35b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d4fa2d31b7968e448877f69a96de69f5de8cd23e168152f35b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48168152f35b82346101035760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576103256020926103166106a5565b61031e610781565b9135610bcf565b9051908152f35b823461010357807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101035760206103c6926103696106a5565b83517fba087652000000000000000000000000000000000000000000000000000000008152823592810192835273ffffffffffffffffffffffffffffffffffffffff90911660208301523360408301529384918291606090910190565b03815f73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000056b269eb1f75477a8666ae8c7fe01b64dd55ecc165af190811561044f575f9161041a575b6020925051908152f35b90506020823d602011610447575b8161043560209383610637565b81010312610103576020915190610410565b3d9150610428565b513d5f823e3d90fd5b905034610103576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261010357610493366106c8565b9060e4359173ffffffffffffffffffffffffffffffffffffffff8316830361010357610104359267ffffffffffffffff928385116101035736602386011215610103578401359283116101035736602484860101116101035760246104fd94019160c43590610a55565b82519182526020820152f35b82346101035760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576104fd610545366106c8565b60c435906107a6565b8234610103575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc168152f35b8234610103576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610103576105f9610545366106c8565b825182815260e43560208201527f1b7ae6a70016176e99f0d91a76a774e1209b170912caca81475e3a2d85863af1843392a282519182526020820152f35b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761067857604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361010357565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60c0910112610103576040519060c0820182811067ffffffffffffffff8211176106785760405273ffffffffffffffffffffffffffffffffffffffff826004358281168103610103578152602435828116810361010357602082015260443582811681036101035760408201526064358281168103610103576060820152608435608082015260a43591821682036101035760a00152565b60443590811515820361010357565b9190826040910312610103576020825192015190565b91909173ffffffffffffffffffffffffffffffffffffffff807f000000000000000000000000d4fa2d31b7968e448877f69a96de69f5de8cd23e166040928351957fc6e6f59200000000000000000000000000000000000000000000000000000000875260048701526020928387602481865afa968715610a0d575f976109da575b5061014485925f6108b89385519a8b9586947f107ddb03000000000000000000000000000000000000000000000000000000008652600486019060a0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015282606082015116606086015260808101516080860152015116910152565b60c48401528160e484015233610104840152306101248401527f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc165af19485156109d0575f905f96610994575b5083517fba0876520000000000000000000000000000000000000000000000000000000081526004810191909152336024820152306044820152919081908390815f81606481015b03925af192831561044f57505f92610966575b50509190565b90809250813d831161098d575b61097d8183610637565b8101031261010357515f80610960565b503d610973565b839296505f9391506109be61094d91863d88116109c9575b6109b68183610637565b810190610790565b979394509150610905565b503d6109ac565b83513d5f823e3d90fd5b919096508382813d8311610a06575b6109f38183610637565b8101031261010357905195610144610828565b503d6109e9565b85513d5f823e3d90fd5b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe093818652868601375f8582860101520116010190565b9194939291907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8103610a92575093610a8e9394611016565b9091565b92610b475f60409493610b6d610aa88833610f33565b9573ffffffffffffffffffffffffffffffffffffffff958689519c8d998a9889977f58e83ce0000000000000000000000000000000000000000000000000000000008952600489019060a0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015282606082015116606086015260808101516080860152015116910152565b60c48701528660e487015216610104850152610140610124850152610144840191610a17565b03927f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc165af1928315610bc4575f93610ba557509190565b610bbf91935060403d6040116109c9576109b68183610637565b905090565b6040513d5f823e3d90fd5b9173ffffffffffffffffffffffffffffffffffffffff9182811691823303610f0957610c1f853033877f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481661176c565b15610e5b57827f000000000000000000000000056b269eb1f75477a8666ae8c7fe01b64dd55ecc166040948551937f46aa2f1200000000000000000000000000000000000000000000000000000000855260048501526020938481602481865afa908115610e51579082915f91610e20575b5010610dc35785517f6e553f65000000000000000000000000000000000000000000000000000000008082526004820192909252306024820152918490839060449082905f905af1918215610db9575f92610d82575b508551908152600481019190915273ffffffffffffffffffffffffffffffffffffffff90911660248201529181908390815f81604481015b03927f000000000000000000000000f689555121e529ff0463e191f9bd9d1e496164a7165af192831561044f57505f92610d5857505090565b90809250813d8311610d7b575b610d6f8183610637565b81010312610103575190565b503d610d65565b929150938383813d8311610db2575b610d9b8183610637565b810103126101035791519193909190610d1f610ce7565b503d610d91565b86513d5f823e3d90fd5b6064848751907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152601560248201527f4465706f7369742065786365656473206c696d697400000000000000000000006044820152fd5b809250868092503d8311610e4a575b610e398183610637565b81010312610103578190515f610c91565b503d610e2f565b87513d5f823e3d90fd5b6040517f6e553f65000000000000000000000000000000000000000000000000000000008152600481019490945273ffffffffffffffffffffffffffffffffffffffff16602484015250602090829060449082905f907f000000000000000000000000056b269eb1f75477a8666ae8c7fe01b64dd55ecc165af1908115610bc4575f91610ee6575090565b90506020813d602011610f01575b81610d6f60209383610637565b3d9150610ef4565b60046040517f82b42900000000000000000000000000000000000000000000000000000000008152fd5b610fc26020915f93610f7f8173ffffffffffffffffffffffffffffffffffffffff933090857f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb481661176c565b6040517f6e553f65000000000000000000000000000000000000000000000000000000008152600481019190915230602482015293849283919082906044820190565b03927f000000000000000000000000d4fa2d31b7968e448877f69a96de69f5de8cd23e165af1908115610bc4575f91610ee6575090565b51906fffffffffffffffffffffffffffffffff8216820361010357565b93929360c08120925f956040516040810181811067ffffffffffffffff82111761067857604052600181526020368183013780511561173f5773ffffffffffffffffffffffffffffffffffffffff8516602082015273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc163b156101035760405180917f78c56d650000000000000000000000000000000000000000000000000000000082528760048301526040602483015280518060448401526020606484019201905f5b8181106117105750505090805f9203818373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc165af18015610bc4576116f3575b506040517f93c5206200000000000000000000000000000000000000000000000000000000815285600482015273ffffffffffffffffffffffffffffffffffffffff8516602482015260608160448173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc165afa9081156114ee57889161167e575b506fffffffffffffffffffffffffffffffff6020820151161561167457604051957f5c60e39a000000000000000000000000000000000000000000000000000000008752600487015260e08660248173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc165afa9586156114ee5788966115ad575b506fffffffffffffffffffffffffffffffff6020820151166fffffffffffffffffffffffffffffffff60608160408a015116980151166001880180981161158057620f42408101918282116115535788810298818a04149015171561158057620f423f908282820111611553578801018097116115265780156114f957604051967fb3d7f6b900000000000000000000000000000000000000000000000000000000885204600487015260208660248173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000d4fa2d31b7968e448877f69a96de69f5de8cd23e165afa9586156114ee5788966114b0575b50611431926040949273ffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff6020611457956113a78c33610f33565b5001511697875198899788977f58e83ce0000000000000000000000000000000000000000000000000000000008952600489019060a0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015282604082015116604086015282606082015116606086015260808101516080860152015116910152565b8c60c488015260e487015216610104850152610140610124850152610144840191610a17565b03818773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc165af19384156114a45793610ba557509190565b604051903d90823e3d90fd5b909550602093919293813d6020116114e6575b816114d060209383610637565b8101031261010357519490929190611431611368565b3d91506114c3565b6040513d8a823e3d90fd5b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526012600452fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b90955060e0813d60e01161166c575b816115c960e09383610637565b81010312611668576040519060e0820182811067ffffffffffffffff8211176106785761165c9160c0916040526115ff81610ff9565b845261160d60208201610ff9565b602085015261161e60408201610ff9565b604085015261162f60608201610ff9565b606085015261164060808201610ff9565b608085015261165160a08201610ff9565b60a085015201610ff9565b60c0820152945f611271565b8780fd5b3d91506115bc565b5050505050508190565b90506060813d6060116116eb575b8161169960609383610637565b8101031261166857604051906060820182811067ffffffffffffffff821117610678576116e0916040918252805184526116d560208201610ff9565b602085015201610ff9565b60408201525f6111db565b3d915061168c565b90965067ffffffffffffffff8111610678576040525f955f611145565b825173ffffffffffffffffffffffffffffffffffffffff168452859450602093840193909201916001016110f0565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b91909273ffffffffffffffffffffffffffffffffffffffff80931692833b156118e157604051928160208501967f23b872dd00000000000000000000000000000000000000000000000000000000885216602485015216604483015260648201526064815260a081019167ffffffffffffffff9382841085851117610678575f809493819460405251925af13d156118d8573d918211610678576040519161183c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160184610637565b82523d5f602084013e5b156118ae57805190811515918261188a575b505061186057565b60046040517f1eded19c000000000000000000000000000000000000000000000000000000008152fd5b81925090602091810103126101035760200151801590811503610103575f80611858565b60046040517fe65b7a77000000000000000000000000000000000000000000000000000000008152fd5b60609150611846565b60046040517ff046a714000000000000000000000000000000000000000000000000000000008152fd

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

000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc000000000000000000000000056b269eb1f75477a8666ae8c7fe01b64dd55ecc000000000000000000000000f689555121e529ff0463e191f9bd9d1e496164a7000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000d4fa2d31b7968e448877f69a96de69f5de8cd23e

-----Decoded View---------------
Arg [0] : morpho (address): 0xDe6e08ac208088cc62812Ba30608D852c6B0EcBc
Arg [1] : usd3 (address): 0x056B269Eb1f75477a8666ae8C7fE01b64dD55eCc
Arg [2] : susd3 (address): 0xf689555121e529Ff0463e191F9Bd9d1E496164a7
Arg [3] : usdc (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [4] : wausdc (address): 0xD4fa2D31b7968E448877f69A96DE69f5de8cD23E

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000de6e08ac208088cc62812ba30608d852c6b0ecbc
Arg [1] : 000000000000000000000000056b269eb1f75477a8666ae8c7fe01b64dd55ecc
Arg [2] : 000000000000000000000000f689555121e529ff0463e191f9bd9d1e496164a7
Arg [3] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [4] : 000000000000000000000000d4fa2d31b7968e448877f69a96de69f5de8cd23e


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.