Source Code
Overview
HYPE Balance
HYPE Value
$0.00Cross-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
Contract Source Code (Solidity Standard Json-Input format)
// 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;
}// 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);
}{
"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
- No Contract Security Audit Submitted- Submit Audit Here
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"}]Contract Creation Code
6080806040523461001657610272908161001b8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c639f73641814610024575f80fd5b346100ae576003196080368201126100ae57600435906001600160401b03908183116100ae576101a09083360301126100ae576024356001600160a01b03811681036100ae57606435928284116100ae57366023850112156100ae5783600401359283116100ae5736602484860101116100ae5760246100ac940191604435916004016100cb565b005b5f80fd5b6001600160a01b0390911681525f602082015260400190565b919490939092916001600160a01b03916080820135838116908190036100ae57610221578301956040848803126100ae5783359081151582036100ae57602092838601356001600160401b03968782116100ae57019880601f8b0112156100ae57893587811161020d5760059a8160051b9160405199601f19603f8501168b01908b82109082111761020d57604052895286808a01928201019283116100ae578601905b8282106101f557505050826101e6575b50506101d4578251925f5b8481106101b057604051631445ab7b60e01b8152806101ac89600483016100b2565b0390fd5b8383828a1b8401015116848816146101ca5760010161018a565b5050505050915050565b60405163734d5b5f60e11b8152600490fd5b60a00135141590505f8061017f565b813588811681036100ae57815290860190860161016f565b634e487b7160e01b5f52604160045260245ffd5b604051631445ab7b60e01b8152806101ac88600483016100b256fea2646970667358221220b36c6f59bcd48647c8b3b465c399867698ebe18581e6350c67054641e28cc53164736f6c63430008180033
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c639f73641814610024575f80fd5b346100ae576003196080368201126100ae57600435906001600160401b03908183116100ae576101a09083360301126100ae576024356001600160a01b03811681036100ae57606435928284116100ae57366023850112156100ae5783600401359283116100ae5736602484860101116100ae5760246100ac940191604435916004016100cb565b005b5f80fd5b6001600160a01b0390911681525f602082015260400190565b919490939092916001600160a01b03916080820135838116908190036100ae57610221578301956040848803126100ae5783359081151582036100ae57602092838601356001600160401b03968782116100ae57019880601f8b0112156100ae57893587811161020d5760059a8160051b9160405199601f19603f8501168b01908b82109082111761020d57604052895286808a01928201019283116100ae578601905b8282106101f557505050826101e6575b50506101d4578251925f5b8481106101b057604051631445ab7b60e01b8152806101ac89600483016100b2565b0390fd5b8383828a1b8401015116848816146101ca5760010161018a565b5050505050915050565b60405163734d5b5f60e11b8152600490fd5b60a00135141590505f8061017f565b813588811681036100ae57815290860190860161016f565b634e487b7160e01b5f52604160045260245ffd5b604051631445ab7b60e01b8152806101ac88600483016100b256fea2646970667358221220b36c6f59bcd48647c8b3b465c399867698ebe18581e6350c67054641e28cc53164736f6c63430008180033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.