HYPE Price: $42.78 (+2.52%)
 

Overview

HYPE Balance

HyperEVM LogoHyperEVM LogoHyperEVM Logo0 HYPE

HYPE Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions
Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultiAddressValidator

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 20 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.24;

import "../../interfaces/validators/IOfferValidator.sol";

contract MultiAddressValidator is IOfferValidator {

    function validateOffer(IMultiSourceLoan.LoanOffer calldata offer, address nftCollateralAddress, uint256 tokenId, bytes calldata validatorData)
        external
        pure
    {
        if (offer.nftCollateralAddress != address(0)) {
            revert InvalidAddressError(nftCollateralAddress, address(0));
        }
        (bool shouldMatchId, address[] memory addresses) = abi.decode(validatorData, (bool, address[]));
        if (shouldMatchId && offer.nftCollateralTokenId != tokenId) {
            revert InvalidCollateralIdError();
        }
        for (uint256 i = 0; i < addresses.length; ++i) {
            if (addresses[i] == nftCollateralAddress) {
                return;
            }
        }
        revert InvalidAddressError(nftCollateralAddress, address(0));
    }
}

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

import "../loans/IMultiSourceLoan.sol";

/// @title Interface for  Loan Offer Validators.
/// @author Florida St
/// @notice Verify the given `_offer` is valid for `_tokenId` and `_validatorData`.
interface IOfferValidator {
    error InvalidAddressError(address one, address two);
    error InvalidCollateralIdError();

    /// @notice Validate a loan offer.
    /// @param _offer The loan offer to validate.
    /// @param _nftCollateralAddress The NFT collateral address to validate.
    /// @param _tokenId The token ID to validate.
    /// @param _validatorData The validator data to validate.
    function validateOffer(IMultiSourceLoan.LoanOffer calldata _offer, address _nftCollateralAddress, uint256 _tokenId, bytes calldata _validatorData)
        external
        view;
}

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.21;

import "./IBaseLoan.sol";

/// @title Multi Source Loan Interface
/// @author Florida St
/// @notice A multi source loan is one with multiple tranches.
interface IMultiSourceLoan {
    /// @notice Borrowers receive offers that are then validated.
    /// @dev Setting the nftCollateralTokenId to 0 triggers validation through `validators`.
    /// @param offerId Offer ID. Used for canceling/setting as executed.
    /// @param lender Lender of the offer.
    /// @param fee Origination fee.
    /// @param capacity Capacity of the offer.
    /// @param nftCollateralAddress Address of the NFT collateral.
    /// @param nftCollateralTokenId NFT collateral token ID.
    /// @param principalAddress Address of the principal.
    /// @param principalAmount Principal amount of the loan.
    /// @param aprBps APR in BPS.
    /// @param expirationTime Expiration time of the offer.
    /// @param duration Duration of the loan in seconds.
    /// @param maxSeniorRepayment Max amount of senior capital ahead (principal + interest).
    /// @param validators Arbitrary contract to validate offers implementing `IBaseOfferValidator`.
    struct LoanOffer {
        uint256 offerId;
        address lender;
        uint256 fee;
        uint256 capacity;
        address nftCollateralAddress;
        uint256 nftCollateralTokenId;
        address principalAddress;
        uint256 principalAmount;
        uint256 aprBps;
        uint256 expirationTime;
        uint256 duration;
        uint256 maxSeniorRepayment;
        IBaseLoan.OfferValidator[] validators;
    }

    /// @notice Offer + how much will be filled (always <= principalAmount).
    /// @param offer Offer.
    /// @param amount Amount to be filled.
    struct OfferExecution {
        LoanOffer offer;
        uint256 amount;
        bytes lenderOfferSignature;
    }

    /// @notice Offer + necessary fields to execute a specific loan. This has a separate expirationTime to avoid
    /// someone holding an offer and executing much later, without the borrower's awareness.
    /// @dev It's advised that borrowers only set an expirationTime close to the actual time they will execute the loan
    ///      to avoid replays.
    /// @param offerExecution List of offers to be filled and amount for each.
    /// @param loanId Loan ID. Optionally used in refinances from borrower for an existing loan.
    /// @param nftCollateralAddress Address of the NFT collateral.
    /// @param tokenId NFT collateral token ID.
    /// @param amount The amount the borrower is willing to take (must be <= _loanOffer principalAmount)
    /// @param expirationTime Expiration time of the signed offer by the borrower.
    /// @param callbackData Data to pass to the callback.
    struct ExecutionData {
        OfferExecution[] offerExecution;
        uint256 loanId;
        address nftCollateralAddress;
        uint256 tokenId;
        uint256 duration;
        uint256 expirationTime;
        address principalReceiver;
        bytes callbackData;
    }

    /// @param executionData Execution data.
    /// @param borrower Address that owns the NFT and will take over the loan.
    /// @param borrowerOfferSignature Signature of the offer (signed by borrower).
    /// @param callbackData Whether to call the afterPrincipalTransfer callback
    struct LoanExecutionData {
        ExecutionData executionData;
        address borrower;
        bytes borrowerOfferSignature;
    }

    /// @param loanId Loan ID.
    /// @param callbackData Whether to call the afterNFTTransfer callback
    /// @param shouldDelegate Whether to delegate ownership of the NFT (avoid seaport flags).
    struct SignableRepaymentData {
        uint256 loanId;
        bytes callbackData;
        bool shouldDelegate;
    }

    /// @param loan Loan.
    /// @param borrowerLoanSignature Signature of the loan (signed by borrower).
    struct LoanRepaymentData {
        SignableRepaymentData data;
        Loan loan;
        bytes borrowerSignature;
    }

    /// @notice Tranches have different seniority levels.
    /// @param loanId Loan ID.
    /// @param floor Amount of principal more senior to this tranche.
    /// @param principalAmount Total principal in this tranche.
    /// @param lender Lender for this given tranche.
    /// @param accruedInterest Accrued Interest.
    /// @param startTime Start Time. Either the time at which the loan initiated / was refinanced.
    /// @param aprBps APR in basis points.
    struct Tranche {
        uint256 loanId;
        uint256 floor;
        uint256 principalAmount;
        address lender;
        uint256 accruedInterest;
        uint256 startTime;
        uint256 aprBps;
    }

    /// @dev Principal Amount is equal to the sum of all tranches principalAmount.
    /// We keep it for caching purposes. Since we are not saving this on chain but the hash,
    /// it does not have a huge impact on gas.
    /// @param borrower Borrower.
    /// @param nftCollateralTokenId NFT Collateral Token ID.
    /// @param nftCollateralAddress NFT Collateral Address.
    /// @param principalAddress Principal Address.
    /// @param principalAmount Principal Amount.
    /// @param startTime Start Time.
    /// @param duration Duration.
    /// @param tranche Tranches.
    /// @param protocolFee Protocol Fee.
    struct Loan {
        address borrower;
        uint256 nftCollateralTokenId;
        address nftCollateralAddress;
        address principalAddress;
        uint256 principalAmount;
        uint256 startTime;
        uint256 duration;
        Tranche[] tranche;
        uint256 protocolFee;
    }

    /// @notice Renegotiation offer.
    /// @param renegotiationId Renegotiation ID.
    /// @param loanId Loan ID.
    /// @param lender Lender.
    /// @param fee Fee.
    /// @param trancheIndex Tranche Indexes to be refinanced.
    /// @param principalAmount Principal Amount. If more than one tranche, it must be the sum.
    /// @param aprBps APR in basis points.
    /// @param expirationTime Expiration Time.
    /// @param duration Duration.
    struct RenegotiationOffer {
        uint256 renegotiationId;
        uint256 loanId;
        address lender;
        uint256 fee;
        uint256[] trancheIndex;
        uint256 principalAmount;
        uint256 aprBps;
        uint256 expirationTime;
        uint256 duration;
    }

    event LoanLiquidated(uint256 loanId);
    event LoanEmitted(uint256 loanId, uint256[] offerId, Loan loan, uint256 fee);
    event LoanRefinanced(uint256 renegotiationId, uint256 oldLoanId, uint256 newLoanId, Loan loan, uint256 fee);
    event LoanRepaid(uint256 loanId, uint256 totalRepayment, uint256 fee);
    event LoanRefinancedFromNewOffers(
        uint256 loanId, uint256 newLoanId, Loan loan, uint256[] offerIds, uint256 totalFee
    );
    event Delegated(uint256 loanId, address delegate, bytes32 _rights, bool value);
    event FlashActionContractUpdated(address newFlashActionContract);
    event FlashActionExecuted(uint256 loanId, address target, bytes data);
    event RevokeDelegate(address delegate, address collection, uint256 tokenId, bytes32 _rights);
    event MinLockPeriodUpdated(uint256 minLockPeriod);

    /// @notice Call by the borrower when emiting a new loan.
    /// @param _loanExecutionData Loan execution data.
    /// @return loanId Loan ID.
    /// @return loan Loan.
    function emitLoan(LoanExecutionData calldata _loanExecutionData) external returns (uint256, Loan memory);

    /// @notice Refinance whole loan (leaving just one tranche).
    /// @param _renegotiationOffer Offer to refinance a loan.
    /// @param _loan Current loan.
    /// @param _renegotiationOfferSignature Signature of the offer.
    /// @return loanId New Loan Id, New Loan.
    function refinanceFull(
        RenegotiationOffer calldata _renegotiationOffer,
        Loan memory _loan,
        bytes calldata _renegotiationOfferSignature
    ) external returns (uint256, Loan memory);

    /// @notice Add a new tranche to a loan.
    /// @param _renegotiationOffer Offer for new tranche.
    /// @param _loan Current loan.
    /// @param _renegotiationOfferSignature Signature of the offer.
    /// @return loanId New Loan Id
    /// @return loan New Loan.
    function addNewTranche(
        RenegotiationOffer calldata _renegotiationOffer,
        Loan memory _loan,
        bytes calldata _renegotiationOfferSignature
    ) external returns (uint256, Loan memory);

    /// @notice Refinance a loan partially. It can only be called by the new lender
    /// (they are always a strict improvement on apr).
    /// @param _renegotiationOffer Offer to refinance a loan partially.
    /// @param _loan Current loan.
    /// @return loanId New Loan Id, New Loan.
    /// @return loan New Loan.
    function refinancePartial(RenegotiationOffer calldata _renegotiationOffer, Loan memory _loan)
        external
        returns (uint256, Loan memory);

    /// @notice Refinance a loan from LoanExecutionData. We let borrowers use outstanding offers for new loans
    ///         to refinance their current loan.
    /// @param _loanId Loan ID.
    /// @param _loan Current loan.
    /// @param _loanExecutionData Loan Execution Data.
    /// @return loanId New Loan Id.
    /// @return loan New Loan.
    function refinanceFromLoanExecutionData(
        uint256 _loanId,
        Loan calldata _loan,
        LoanExecutionData calldata _loanExecutionData
    ) external returns (uint256, Loan memory);

    /// @notice Repay loan. Interest is calculated pro-rata based on time. Lender is defined by nft ownership.
    /// @param _repaymentData Repayment data.
    function repayLoan(LoanRepaymentData calldata _repaymentData) external;

    /// @notice Call when a loan is past its due date.
    /// @param _loanId Loan ID.
    /// @param _loan Loan.
    /// @return Liquidation Struct of the liquidation.
    function liquidateLoan(uint256 _loanId, Loan calldata _loan) external returns (bytes memory);

    /// @return getMaxTranches Maximum number of tranches per loan.
    function getMaxTranches() external view returns (uint256);

    /// @notice Set min lock period (in BPS).
    /// @param _minLockPeriod Min lock period.
    function setMinLockPeriod(uint256 _minLockPeriod) external;

    /// @notice Get min lock period (in BPS).
    /// @return minLockPeriod Min lock period.
    function getMinLockPeriod() external view returns (uint256);

    /// @notice Get delegation registry.
    /// @return delegateRegistry Delegate registry.
    function getDelegateRegistry() external view returns (address);

    /// @notice Delegate ownership.
    /// @param _loanId Loan ID.
    /// @param _loan Loan.
    /// @param _rights Delegation Rights. Empty for all.
    /// @param _delegate Delegate address.
    /// @param _value True if delegate, false if undelegate.
    function delegate(uint256 _loanId, Loan calldata _loan, address _delegate, bytes32 _rights, bool _value) external;

    /// @notice Anyone can reveke a delegation on an NFT that's no longer in escrow.
    /// @param _delegate Delegate address.
    /// @param _collection Collection address.
    /// @param _tokenId Token ID.
    /// @param _rights Delegation Rights. Empty for all.
    function revokeDelegate(address _delegate, address _collection, uint256 _tokenId, bytes32 _rights) external;

    /// @notice Get Flash Action Contract.
    /// @return flashActionContract Flash Action Contract.
    function getFlashActionContract() external view returns (address);

    /// @notice Update Flash Action Contract.
    /// @param _newFlashActionContract Flash Action Contract.
    function setFlashActionContract(address _newFlashActionContract) external;

    /// @notice Get Loan Hash.
    /// @param _loanId Loan ID.
    /// @return loanHash Loan Hash.
    function getLoanHash(uint256 _loanId) external view returns (bytes32);

    /// @notice Transfer NFT to the flash action contract (expected use cases here are for airdrops and similar scenarios).
    /// The flash action contract would implement specific interactions with given contracts.
    /// Only the the borrower can call this function for a given loan. By the end of the transaction, the NFT must have
    /// been returned to escrow.
    /// @param _loanId Loan ID.
    /// @param _loan Loan.
    /// @param _target Target address for the flash action contract to interact with.
    /// @param _data Data to be passed to be passed to the ultimate contract.
    function executeFlashAction(uint256 _loanId, Loan calldata _loan, address _target, bytes calldata _data) external;

    /// @notice Called by the liquidator for accounting purposes.
    /// @param _loanId The id of the loan.
    /// @param _loan The loan object.
    function loanLiquidated(uint256 _loanId, Loan calldata _loan) external;
}

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

import "../../interfaces/ILoanLiquidator.sol";

/// @title Interface for Loans.
/// @author Florida St
/// @notice Basic Loan
interface IBaseLoan {
    /// @notice Minimum improvement (in BPS) required for a strict improvement.
    /// @param principalAmount Minimum delta of principal amount.
    /// @param interest Minimum delta of interest.
    /// @param duration Minimum delta of duration.
    struct ImprovementMinimum {
        uint256 principalAmount;
        uint256 interest;
        uint256 duration;
    }

    /// @notice Arbitrary contract to validate offers implementing `IBaseOfferValidator`.
    /// @param validator Address of the validator contract.
    /// @param arguments Arguments to pass to the validator.
    struct OfferValidator {
        address validator;
        bytes arguments;
    }

    /// @notice Total number of loans issued by this contract.
    function getTotalLoansIssued() external view returns (uint256);

    /// @notice Cancel offer for `msg.sender`. Each lender has unique offerIds.
    /// @param _offerId Offer ID.
    function cancelOffer(uint256 _offerId) external;

    /// @notice Cancel renegotiation offer. Similar to offers.
    /// @param _renegotiationId Renegotiation offer ID.
    function cancelRenegotiationOffer(uint256 _renegotiationId) external;
}

File 5 of 5 : ILoanLiquidator.sol
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

import "../interfaces/loans/IMultiSourceLoan.sol";

/// @title Liquidates Collateral for Defaulted Loans
/// @author Florida St
/// @notice It liquidates collateral corresponding to defaulted loans
///         and sends back the proceeds to the loan contract for distribution.
interface ILoanLiquidator {
    /// @notice Given a loan, it takes posession of the NFT and liquidates it.
    /// @param _loanId The loan id.
    /// @param _contract The loan contract address.
    /// @param _tokenId The NFT id.
    /// @param _asset The asset address.
    /// @param _duration The liquidation duration.
    /// @param _minBid The minimum bid.
    /// @param _originator The address that trigger the liquidation.
    /// @return encodedAuction Encoded struct.
    function liquidateLoan(
        uint256 _loanId,
        address _contract,
        uint256 _tokenId,
        address _asset,
        uint96 _duration,
        uint256 _minBid,
        address _originator
    ) external returns (bytes memory);
}

Settings
{
  "remappings": [
    "@forge-std/=lib/forge-std/src/",
    "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "@solady/=lib/solady/src/",
    "@solmate/=lib/solmate/src/",
    "@zora/=lib/v3/contracts/",
    "@chainlink/=lib/chainlink/contracts/src/v0.8/",
    "@delegate/=lib/delegate-registry/src/",
    "@seaport/=lib/seaport/lib/",
    "@aave/=lib/aave/src/contracts/",
    "@florida-v2/=lib/florida-contracts-v2/",
    "@permit2/=lib/permit2/src/",
    "test/=test/",
    "@const/=src/const/default/",
    "@manifoldxyz/=lib/v3/node_modules/@manifoldxyz/",
    "@rari-capital/=lib/v3/node_modules/@rari-capital/",
    "aave/=lib/aave/",
    "chainlink/=lib/chainlink/contracts/",
    "delegate-registry/=lib/delegate-registry/",
    "ds-test/=lib/seaport/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "florida-contracts-v2/=lib/florida-contracts-v2/src/",
    "forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/",
    "forge-std/=lib/forge-std/src/",
    "halmos-cheatcodes/=lib/aave/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
    "murky/=lib/seaport/lib/murky/src/",
    "openzeppelin-contracts-upgradeable/=lib/aave/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/delegate-registry/lib/openzeppelin-contracts/contracts/",
    "permit2/=lib/permit2/",
    "seaport-core/=lib/seaport/lib/seaport-core/",
    "seaport-sol/=lib/seaport/lib/seaport-sol/",
    "seaport-types/=lib/seaport/lib/seaport-types/",
    "seaport/=lib/seaport/",
    "solady/=lib/solady/src/",
    "solarray/=lib/seaport/lib/solarray/src/",
    "solidity-utils/=lib/aave/lib/solidity-utils/",
    "solmate/=lib/solmate/src/",
    "v3/=lib/v3/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 20
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"one","type":"address"},{"internalType":"address","name":"two","type":"address"}],"name":"InvalidAddressError","type":"error"},{"inputs":[],"name":"InvalidCollateralIdError","type":"error"},{"inputs":[{"components":[{"internalType":"uint256","name":"offerId","type":"uint256"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"capacity","type":"uint256"},{"internalType":"address","name":"nftCollateralAddress","type":"address"},{"internalType":"uint256","name":"nftCollateralTokenId","type":"uint256"},{"internalType":"address","name":"principalAddress","type":"address"},{"internalType":"uint256","name":"principalAmount","type":"uint256"},{"internalType":"uint256","name":"aprBps","type":"uint256"},{"internalType":"uint256","name":"expirationTime","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"maxSeniorRepayment","type":"uint256"},{"components":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"bytes","name":"arguments","type":"bytes"}],"internalType":"struct IBaseLoan.OfferValidator[]","name":"validators","type":"tuple[]"}],"internalType":"struct IMultiSourceLoan.LoanOffer","name":"offer","type":"tuple"},{"internalType":"address","name":"nftCollateralAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"validatorData","type":"bytes"}],"name":"validateOffer","outputs":[],"stateMutability":"pure","type":"function"}]

6080806040523461001657610272908161001b8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c639f73641814610024575f80fd5b346100ae576003196080368201126100ae57600435906001600160401b03908183116100ae576101a09083360301126100ae576024356001600160a01b03811681036100ae57606435928284116100ae57366023850112156100ae5783600401359283116100ae5736602484860101116100ae5760246100ac940191604435916004016100cb565b005b5f80fd5b6001600160a01b0390911681525f602082015260400190565b919490939092916001600160a01b03916080820135838116908190036100ae57610221578301956040848803126100ae5783359081151582036100ae57602092838601356001600160401b03968782116100ae57019880601f8b0112156100ae57893587811161020d5760059a8160051b9160405199601f19603f8501168b01908b82109082111761020d57604052895286808a01928201019283116100ae578601905b8282106101f557505050826101e6575b50506101d4578251925f5b8481106101b057604051631445ab7b60e01b8152806101ac89600483016100b2565b0390fd5b8383828a1b8401015116848816146101ca5760010161018a565b5050505050915050565b60405163734d5b5f60e11b8152600490fd5b60a00135141590505f8061017f565b813588811681036100ae57815290860190860161016f565b634e487b7160e01b5f52604160045260245ffd5b604051631445ab7b60e01b8152806101ac88600483016100b256fea2646970667358221220b36c6f59bcd48647c8b3b465c399867698ebe18581e6350c67054641e28cc53164736f6c63430008180033

Deployed Bytecode

0x60806040526004361015610011575f80fd5b5f3560e01c639f73641814610024575f80fd5b346100ae576003196080368201126100ae57600435906001600160401b03908183116100ae576101a09083360301126100ae576024356001600160a01b03811681036100ae57606435928284116100ae57366023850112156100ae5783600401359283116100ae5736602484860101116100ae5760246100ac940191604435916004016100cb565b005b5f80fd5b6001600160a01b0390911681525f602082015260400190565b919490939092916001600160a01b03916080820135838116908190036100ae57610221578301956040848803126100ae5783359081151582036100ae57602092838601356001600160401b03968782116100ae57019880601f8b0112156100ae57893587811161020d5760059a8160051b9160405199601f19603f8501168b01908b82109082111761020d57604052895286808a01928201019283116100ae578601905b8282106101f557505050826101e6575b50506101d4578251925f5b8481106101b057604051631445ab7b60e01b8152806101ac89600483016100b2565b0390fd5b8383828a1b8401015116848816146101ca5760010161018a565b5050505050915050565b60405163734d5b5f60e11b8152600490fd5b60a00135141590505f8061017f565b813588811681036100ae57815290860190860161016f565b634e487b7160e01b5f52604160045260245ffd5b604051631445ab7b60e01b8152806101ac88600483016100b256fea2646970667358221220b36c6f59bcd48647c8b3b465c399867698ebe18581e6350c67054641e28cc53164736f6c63430008180033

Block Transaction Gas Used Reward
view all blocks ##produced##

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

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.