Goerli Testnet

Contract

0x122a2d5D54A546708a80e7275b96D772f3826ffA
Source Code

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Value
0x6080604095696312023-08-23 23:22:12181 days 1 hr ago1692832932IN
 Create: CollectionWideOfferVerifier
0 ETH0.000002520.01199999

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
101424672023-12-02 4:03:2480 days 20 hrs ago1701489804
0x122a2d...f3826ffA
0 ETH
101424422023-12-02 3:57:2480 days 20 hrs ago1701489444
0x122a2d...f3826ffA
0 ETH
101370462023-12-01 5:22:1281 days 19 hrs ago1701408132
0x122a2d...f3826ffA
0 ETH
101369892023-12-01 5:07:3681 days 19 hrs ago1701407256
0x122a2d...f3826ffA
0 ETH
101369732023-12-01 5:03:4881 days 19 hrs ago1701407028
0x122a2d...f3826ffA
0 ETH
101369302023-12-01 4:51:3681 days 19 hrs ago1701406296
0x122a2d...f3826ffA
0 ETH
101368862023-12-01 4:40:4881 days 19 hrs ago1701405648
0x122a2d...f3826ffA
0 ETH
101368332023-12-01 4:27:4881 days 20 hrs ago1701404868
0x122a2d...f3826ffA
0 ETH
101367462023-12-01 4:07:0081 days 20 hrs ago1701403620
0x122a2d...f3826ffA
0 ETH
101367252023-12-01 4:01:4881 days 20 hrs ago1701403308
0x122a2d...f3826ffA
0 ETH
101366672023-12-01 3:47:0081 days 20 hrs ago1701402420
0x122a2d...f3826ffA
0 ETH
101239962023-11-28 22:27:2484 days 2 hrs ago1701210444
0x122a2d...f3826ffA
0 ETH
100861072023-11-22 4:45:2490 days 19 hrs ago1700628324
0x122a2d...f3826ffA
0 ETH
100812872023-11-21 8:37:2491 days 15 hrs ago1700555844
0x122a2d...f3826ffA
0 ETH
100788182023-11-20 22:14:0092 days 2 hrs ago1700518440
0x122a2d...f3826ffA
0 ETH
100780162023-11-20 18:50:3692 days 5 hrs ago1700506236
0x122a2d...f3826ffA
0 ETH
100492732023-11-15 18:36:0097 days 5 hrs ago1700073360
0x122a2d...f3826ffA
0 ETH
98613842023-10-13 21:35:12130 days 2 hrs ago1697232912
0x122a2d...f3826ffA
0 ETH
96954122023-09-14 20:52:12159 days 3 hrs ago1694724732
0x122a2d...f3826ffA
0 ETH
96954122023-09-14 20:52:12159 days 3 hrs ago1694724732
0x122a2d...f3826ffA
0 ETH
96954122023-09-14 20:52:12159 days 3 hrs ago1694724732
0x122a2d...f3826ffA
0 ETH
96836742023-09-12 20:15:36161 days 4 hrs ago1694549736
0x122a2d...f3826ffA
0 ETH
96449362023-09-06 4:31:24167 days 20 hrs ago1693974684
0x122a2d...f3826ffA
0 ETH
96448352023-09-06 4:06:48167 days 20 hrs ago1693973208
0x122a2d...f3826ffA
0 ETH
96427692023-09-05 19:19:36168 days 5 hrs ago1693941576
0x122a2d...f3826ffA
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CollectionWideOfferVerifier

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 8 : CollectionWideOfferVerifier.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

import "../interfaces/ISignatureVerifier.sol";
import "../interfaces/IVaultFactory.sol";

import { IV_InvalidCollateralId } from "../errors/Lending.sol";

/**
 * @title CollectionWideOfferVerifier
 * @author Non-Fungible Technologies, Inc.
 *
 * This contract can be used for verifying a collection-wide offer for
 * an ERC721, and is agnostic in that it can verify both vaulted
 * and unbundled collateral. This is a common use case for many lenders,
 * who do not care whether the collateral is vauled.
 *
 * Predicates for this verify are _always_ wildcards: the caller's
 * predicate payload is a NFT address only, and the verifier will
 * check for _any_ balance of that asset.
 */
contract CollectionWideOfferVerifier is ISignatureVerifier {
    // ==================================== COLLATERAL VERIFICATION =====================================

    /**
     * @notice Verify that the items specified by the predicate calldata match the loan terms
     *         based on reported collateral address and ID, or that the collateral address
     *         is a vault factory and the vault contains the specified item.
     *
     * @param collateralAddress             The address of the loan's collateral.
     * @param collateralId                  The tokenId of the loan's collateral.
     * @param data                          The calldata needed for the verifier.
     *
     * @return verified                     Whether the bundle contains the specified items.
     */
    function verifyPredicates(
        address, address,
        address collateralAddress,
        uint256 collateralId,
        bytes calldata data
    ) external view override returns (bool) {
        // Unpack items
        (address token) = abi.decode(data, (address));

        // Unvaulted case - collateral will be escrowed directly
        if (collateralAddress == token) return true;

        // Do vault check
        address vaultAddress = IVaultFactory(collateralAddress).instanceAt(collateralId);

        // Make sure vault address, converted back into uint256, matches the original
        // collateralId. An arbitrary collateralId could theoretically collide with the
        // another vault's address, meaning the wrong vault would be checked.
        if (collateralId != uint256(uint160(vaultAddress))) revert IV_InvalidCollateralId(collateralId);

        return IERC721(token).balanceOf(vaultAddress) > 0;
    }
}

File 2 of 8 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

File 3 of 8 : ISignatureVerifier.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

interface ISignatureVerifier {
    // ============== Collateral Verification ==============

    function verifyPredicates(
        address borrower,
        address lender,
        address collateralAddress,
        uint256 collateralId,
        bytes calldata predicates
    ) external view returns (bool);
}

File 4 of 8 : IVaultFactory.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import "./INFTWithDescriptor.sol";

interface IVaultFactory is INFTWithDescriptor {
    // ============= Events ==============

    event VaultCreated(address vault, address to);
    event ClaimFees(address owner, uint256 amount);

    // ================ View Functions ================

    function isInstance(address instance) external view returns (bool validity);

    function instanceCount() external view returns (uint256);

    function instanceAt(uint256 tokenId) external view returns (address);

    function instanceAtIndex(uint256 index) external view returns (address);

    // ================ Factory Operations ================

    function initializeBundle(address to) external payable returns (uint256);
}

File 5 of 8 : Lending.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import "../libraries/LoanLibrary.sol";

/**
 * @title LendingErrors
 * @author Non-Fungible Technologies, Inc.
 *
 * This file contains custom errors for the core lending protocol contracts, with errors
 * prefixed by the contract that throws them (e.g., "OC_" for OriginationController).
 * Errors located in one place to make it possible to holistically look at all
 * protocol failure cases.
 */

// ==================================== ORIGINATION CONTROLLER ======================================
/// @notice All errors prefixed with OC_, to separate from other contracts in the protocol.

/**
 * @notice Zero address passed in where not allowed.
 *
 * @param addressType                  The name of the parameter for which a zero address was provided.
 */
error OC_ZeroAddress(string addressType);

/**
 * @notice Ensure valid loan state for loan lifceycle operations.
 *
 * @param state                         Current state of a loan according to LoanState enum.
 */
error OC_InvalidState(LoanLibrary.LoanState state);

/**
 * @notice Loan duration must be greater than 1hr and less than 3yrs.
 *
 * @param durationSecs                 Total amount of time in seconds.
 */
error OC_LoanDuration(uint256 durationSecs);

/**
 * @notice Interest must be greater than 0.01% and less than 10,000%. (interestRate / 1e18 >= 1)
 *
 * @param interestRate                  InterestRate with 1e18 multiplier.
 */
error OC_InterestRate(uint256 interestRate);

/**
 * @notice One of the predicates for item verification failed.
 *
 * @param borrower                      The address of the borrower.
 * @param lender                        The address of the lender.
 * @param verifier                      The address of the verifier contract.
 * @param collateralAddress             The address of the collateral token.
 * @param collateralId                  The token ID of the collateral.
 * @param data                          The verification data (to be parsed by verifier).
 */
error OC_PredicateFailed(
    address borrower,
    address lender,
    address verifier,
    address collateralAddress,
    uint256 collateralId,
    bytes data
);

/**
 * @notice The predicates array is empty.
 */
error OC_PredicatesArrayEmpty();

/**
 * @notice A caller attempted to approve themselves.
 *
 * @param caller                        The caller of the approve function.
 */
error OC_SelfApprove(address caller);

/**
 * @notice A caller attempted to originate a loan with their own signature.
 *
 * @param caller                        The caller of the approve function, who was also the signer.
 */
error OC_ApprovedOwnLoan(address caller);

/**
 * @notice The signature could not be recovered to the counterparty or approved party.
 *
 * @param target                        The target party of the signature, which should either be the signer,
 *                                      or someone who has approved the signer.
 * @param signer                        The signer determined from ECDSA.recover.
 */
error OC_InvalidSignature(address target, address signer);

/**
 * @notice The verifier contract specified in a predicate has not been whitelisted.
 *
 * @param verifier                      The verifier the caller attempted to use.
 */
error OC_InvalidVerifier(address verifier);

/**
 * @notice The function caller was neither borrower or lender, and was not approved by either.
 *
 * @param caller                        The unapproved function caller.
 */
error OC_CallerNotParticipant(address caller);

/**
 * @notice Signer is attempting to take the wrong side of the loan.
 *
 * @param signer                       The address of the external signer.
 */
error OC_SideMismatch(address signer);

/**
 * @notice Two related parameters for batch operations did not match in length.
 */
error OC_BatchLengthMismatch();

/**
 * @notice Principal must be greater than 9999 Wei.
 *
 * @param principal                     Principal in ether.
 */
error OC_PrincipalTooLow(uint256 principal);

/**
 * @notice Signature must not be expired.
 *
 * @param deadline                      Deadline in seconds.
 */
error OC_SignatureIsExpired(uint256 deadline);

/**
 * @notice New currency does not match for a loan rollover request.
 *
 * @param oldCurrency                   The currency of the active loan.
 * @param newCurrency                   The currency of the new loan.
 */
error OC_RolloverCurrencyMismatch(address oldCurrency, address newCurrency);

/**
 * @notice New currency does not match for a loan rollover request.
 *
 * @param oldCollateralAddress          The address of the active loan's collateral.
 * @param newCollateralAddress          The token ID of the active loan's collateral.
 * @param oldCollateralId               The address of the new loan's collateral.
 * @param newCollateralId               The token ID of the new loan's collateral.
 */
error OC_RolloverCollateralMismatch(
    address oldCollateralAddress,
    uint256 oldCollateralId,
    address newCollateralAddress,
    uint256 newCollateralId
);

/**
 * @notice Provided payable currency address is not approved for lending.
 *
 * @param payableCurrency       ERC20 token address supplied in loan terms.
 */
error OC_InvalidCurrency(address payableCurrency);

/**
 * @notice Provided collateral address is not approved for lending.
 *
 * @param collateralAddress       ERC721 or ERC1155 token address supplied in loan terms.
 */
error OC_InvalidCollateral(address collateralAddress);

/**
 * @notice Provided token array does not hold any token addresses.
 */
error OC_ZeroArrayElements();

/**
 * @notice Provided token array holds more than 50 token addresses.
 */
error OC_ArrayTooManyElements();

// ==================================== ITEMS VERIFIER ======================================
/// @notice All errors prefixed with IV_, to separate from other contracts in the protocol.

/**
 * @notice The predicate payload was decoded successfully, but list of predicates is empty.
 */
error IV_NoPredicates();

/**
 * @notice Provided SignatureItem is missing an address.
 */
error IV_ItemMissingAddress();

/**
 * @notice Provided SignatureItem has an invalid collateral type.
 * @dev    Should never actually fire, since cType is defined by an enum, so will fail on decode.
 *
 * @param asset                        The NFT contract being checked.
 * @param cType                        The collateralTytpe provided.
 */
error IV_InvalidCollateralType(address asset, uint256 cType);

/**
 * @notice Provided signature item with no required amount. For single ERC721s, specify 1.
 *
 * @param asset                         The NFT contract being checked.
 * @param amount                        The amount provided (should be 0).
 */
error IV_NoAmount(address asset, uint256 amount);

/**
 * @notice Provided a wildcard for a non-ERC721.
 *
 * @param asset                         The NFT contract being checked.
 */
error IV_InvalidWildcard(address asset);

/**
 * @notice The provided token ID is out of bounds for the given collection.
 *
 * @param tokenId                       The token ID provided.
 */
error IV_InvalidTokenId(int256 tokenId);

/**
 * @notice The provided project ID does not exist on the target contract. Only
 *         used for ArtBlocks.
 *
 * @param projectId                     The project ID provided.
 * @param nextProjectId                 The contract's reported nextProjectId.
 */
error IV_InvalidProjectId(uint256 projectId, uint256 nextProjectId);

/**
 * @notice The provided collateralId converts to a vault, but
 *         the vault's address does not convert back to the provided collateralId
 *         when casted to a uint256.
 */
error IV_InvalidCollateralId(uint256 collateralId);

// ==================================== REPAYMENT CONTROLLER ======================================
/// @notice All errors prefixed with RC_, to separate from other contracts in the protocol.

/**
 * @notice Zero address passed in where not allowed.
 *
 * @param addressType                  The name of the parameter for which a zero address was provided.
 */
error RC_ZeroAddress(string addressType);

/**
 * @notice Could not dereference loan from loan ID.
 *
 * @param target                     The loanId being checked.
 */
error RC_CannotDereference(uint256 target);

/**
 * @notice Ensure valid loan state for loan lifceycle operations.
 *
 * @param state                         Current state of a loan according to LoanState enum.
 */
error RC_InvalidState(LoanLibrary.LoanState state);

/**
 * @notice Caller is not the owner of lender note.
 *
 * @param lender                     The owner of the lender note.
 * @param caller                     Msg.sender of the function call.
 */
error RC_OnlyLender(address lender, address caller);

// ==================================== Loan Core ======================================
/// @notice All errors prefixed with LC_, to separate from other contracts in the protocol.

/**
 * @notice Zero address passed in where not allowed.
 *
 * @param addressType                  The name of the parameter for which a zero address was provided.
 */
error LC_ZeroAddress(string addressType);

/// @notice Borrower address is same as lender address.
error LC_ReusedNote();

/// @notice Zero amount passed in where not allowed.
error LC_ZeroAmount();

/**
 * @notice Check collateral is not already used in a active loan.
 *
 * @param collateralAddress             Address of the collateral.
 * @param collateralId                  ID of the collateral token.
 */
error LC_CollateralInUse(address collateralAddress, uint256 collateralId);

/**
 * @notice The reported settlements are invalid, and LoanCore would lose tokens
 *         attempting to perform the requested operations.
 *
 *
 * @param payout                        Amount of tokens to be paid out.
 * @param collected                     Amount of tokens to collect - should be fewer than payout.
 */
error LC_CannotSettle(uint256 payout, uint256 collected);

/**
 * @notice User attempted to withdraw a pending balance that was in excess
 *         of what is available.
 *
 * @param amount                        Amount of tokens to be withdrawn.
 * @param available                     Amount of tokens available to withdraw.
 */
error LC_CannotWithdraw(uint256 amount, uint256 available);

/**
 * @notice Two arrays were provided that must be of matching length, but were not.
 *
 */
error LC_ArrayLengthMismatch();

/**
 * @notice A proposed affiliate split was submitted that is over the maximum.
 *
 * @param splitBps                     The proposed affiliate split.
 * @param maxSplitBps                  The maximum allowed affiliate split.
 *
 */
error LC_OverMaxSplit(uint96 splitBps, uint96 maxSplitBps);

/**
 * @notice Ensure valid loan state for loan lifceycle operations.
 *
 * @param state                         Current state of a loan according to LoanState enum.
 */
error LC_InvalidState(LoanLibrary.LoanState state);

/**
 * @notice Loan duration has not expired.
 *
 * @param dueDate                       Timestamp of the end of the loan duration.
 */
error LC_NotExpired(uint256 dueDate);

/**
 * @notice User address and the specified nonce have already been used.
 *
 * @param user                          Address of collateral owner.
 * @param nonce                         Represents the number of transactions sent by address.
 */
error LC_NonceUsed(address user, uint160 nonce);

/**
 * @notice Protocol attempted to set an affiliate code which already exists. Affiliate
 *         codes are immutable.
 *
 * @param affiliateCode                 The affiliate code being set.
 */
error LC_AffiliateCodeAlreadySet(bytes32 affiliateCode);

/**
 * @notice Specified note token ID does not have a redeemable receipt.
 *
 * @param loanId                     The loanId being checked.
 */
error LC_NoReceipt(uint256 loanId);

/**
 * @notice Only Loan Core contract can call this function.
 */
error LC_CallerNotLoanCore();

/**
 * @notice The loan core contract has been irreversibly shut down.
 */
error LC_Shutdown();

// ==================================== Promissory Note ======================================
/// @notice All errors prefixed with PN_, to separate from other contracts in the protocol.

/**
 * @notice Zero address passed in where not allowed.
 *
 * @param addressType                  The name of the parameter for which a zero address was provided.
 */
error PN_ZeroAddress(string addressType);

/**
 * @notice Caller of mint function must have the MINTER_ROLE in AccessControl.
 *
 * @param caller                        Address of the function caller.
 */
error PN_MintingRole(address caller);

/**
 * @notice Caller of burn function must have the BURNER_ROLE in AccessControl.
 *
 * @param caller                        Address of the function caller.
 */
error PN_BurningRole(address caller);

/**
 * @notice Non-existant token id provided as argument.
 *
 * @param tokenId                       The ID of the token to lookup the URI for.
 */
error PN_DoesNotExist(uint256 tokenId);

// ==================================== Fee Controller ======================================
/// @notice All errors prefixed with FC_, to separate from other contracts in the protocol.

/**
 * @notice Caller attempted to set a lending fee which is larger than the global maximum.
 */
error FC_LendingFeeOverMax(bytes32 selector, uint256 fee, uint256 maxFee);

/**
 * @notice Caller attempted to set a vault mint fee which is larger than the global maximum.
 */
error FC_VaultMintFeeOverMax(uint256 fee, uint256 maxFee);

// ==================================== ERC721 Permit ======================================
/// @notice All errors prefixed with ERC721P_, to separate from other contracts in the protocol.

/**
 * @notice Deadline for the permit has expired.
 *
 * @param deadline                      Permit deadline parameter as a timestamp.
 */
error ERC721P_DeadlineExpired(uint256 deadline);

/**
 * @notice Address of the owner to also be the owner of the tokenId.
 *
 * @param owner                        Owner parameter for the function call.
 */
error ERC721P_NotTokenOwner(address owner);

/**
 * @notice Invalid signature.
 *
 * @param signer                        Signer recovered from ECDSA sugnature hash.
 */
error ERC721P_InvalidSignature(address signer);

File 6 of 8 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 7 of 8 : INFTWithDescriptor.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

interface INFTWithDescriptor {
    // ============= Events ==============

    event SetDescriptor(address indexed caller, address indexed descriptor);

    // ================ Resource Metadata ================

    function tokenURI(uint256 tokenId) external view returns (string memory);

    function setDescriptor(address descriptor) external;
}

File 8 of 8 : LoanLibrary.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

/**
 * @title LoanLibrary
 * @author Non-Fungible Technologies, Inc.
 *
 * Contains all data types used across Arcade lending contracts.
 */
library LoanLibrary {
    /**
     * @dev Enum describing the current state of a loan.
     * State change flow:
     * Created -> Active -> Repaid
     *                   -> Defaulted
     */
    enum LoanState {
        // We need a default that is not 'Created' - this is the zero value
        DUMMY_DO_NOT_USE,
        // The loan has been initialized, funds have been delivered to the borrower and the collateral is held.
        Active,
        // The loan has been repaid, and the collateral has been returned to the borrower. This is a terminal state.
        Repaid,
        // The loan was delinquent and collateral claimed by the lender. This is a terminal state.
        Defaulted
    }

    /**
     * @dev The raw terms of a loan.
     */
    struct LoanTerms {
        // Interest expressed as a rate, unlike V1 gross value.
        // Input conversion: 0.01% = (1 * 10**18) ,  10.00% = (1000 * 10**18)
        // This represents the rate over the lifetime of the loan, not APR.
        // 0.01% is the minimum interest rate allowed by the protocol.
        uint256 proratedInterestRate;
        /// @dev Full-slot variables
        // The amount of principal in terms of the payableCurrency.
        uint256 principal;
        // The token ID of the address holding the collateral.
        /// @dev Can be an AssetVault, or the NFT contract for unbundled collateral
        address collateralAddress;
        /// @dev Packed variables
        // The number of seconds representing relative due date of the loan.
        /// @dev Max is 94,608,000, fits in 96 bits
        uint96 durationSecs;
        // The token ID of the collateral.
        uint256 collateralId;
        // The payable currency for the loan principal and interest.
        address payableCurrency;
        // Timestamp for when signature for terms expires
        uint96 deadline;
        // Affiliate code used to start the loan.
        bytes32 affiliateCode;
    }

    /**
     * @dev Modification of loan terms, used for signing only.
     *      Instead of a collateralId, a list of predicates
     *      is defined by 'bytes' in items.
     */
    struct LoanTermsWithItems {
        // Interest expressed as a rate, unlike V1 gross value.
        // Input conversion: 0.01% = (1 * 10**18) ,  10.00% = (1000 * 10**18)
        // This represents the rate over the lifetime of the loan, not APR.
        // 0.01% is the minimum interest rate allowed by the protocol.
        uint256 proratedInterestRate;
        /// @dev Full-slot variables
        // The amount of principal in terms of the payableCurrency.
        uint256 principal;
        // The tokenID of the address holding the collateral
        address collateralAddress;
        /// @dev Packed variables
        // The number of seconds representing relative due date of the loan.
        /// @dev Max is 94,608,000, fits in 96 bits
        uint96 durationSecs;
        // An encoded list of predicates, along with their verifiers.
        bytes items;
        // The payable currency for the loan principal and interest.
        address payableCurrency;
        // Timestamp for when signature for terms expires
        uint96 deadline;
        // Affiliate code used to start the loan.
        bytes32 affiliateCode;
    }

    /**
     * @dev Predicate for item-based verifications
     */
    struct Predicate {
        // The encoded predicate, to decoded and parsed by the verifier contract.
        bytes data;
        // The verifier contract.
        address verifier;
    }

    /**
     * @dev Snapshot of lending fees at the time of loan creation.
     */
    struct FeeSnapshot {
        // The fee taken when lender claims defaulted collateral.
        uint16 lenderDefaultFee;
        // The fee taken from the borrower's interest repayment.
        uint16 lenderInterestFee;
        // The fee taken from the borrower's principal repayment.
        uint16 lenderPrincipalFee;
    }

    /**
     * @dev The data of a loan. This is stored once the loan is Active
     */
    struct LoanData {
        /// @dev Packed variables
        // The current state of the loan.
        LoanState state;
        // Start date of the loan, using block.timestamp.
        uint160 startDate;
        /// @dev Full-slot variables
        // The raw terms of the loan.
        LoanTerms terms;
        // Record of lending fees at the time of loan creation.
        FeeSnapshot feeSnapshot;
    }
}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"collateralId","type":"uint256"}],"name":"IV_InvalidCollateralId","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"collateralAddress","type":"address"},{"internalType":"uint256","name":"collateralId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"verifyPredicates","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b506102d9806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063fc5a582114610030575b600080fd5b61004361003e3660046101bf565b610057565b604051901515815260200160405180910390f35b60008061006683850185610272565b9050806001600160a01b0316866001600160a01b03160361008b57600191505061019d565b6040516308ec149f60e11b8152600481018690526000906001600160a01b038816906311d8293e90602401602060405180830381865afa1580156100d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f79190610296565b9050806001600160a01b0316861461012957604051630a83d9db60e41b81526004810187905260240160405180910390fd5b6040516370a0823160e01b81526001600160a01b038281166004830152600091908416906370a0823190602401602060405180830381865afa158015610173573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019791906102b3565b11925050505b9695505050505050565b6001600160a01b03811681146101bc57600080fd5b50565b60008060008060008060a087890312156101d857600080fd5b86356101e3816101a7565b955060208701356101f3816101a7565b94506040870135610203816101a7565b935060608701359250608087013567ffffffffffffffff8082111561022757600080fd5b818901915089601f83011261023b57600080fd5b81358181111561024a57600080fd5b8a602082850101111561025c57600080fd5b6020830194508093505050509295509295509295565b60006020828403121561028457600080fd5b813561028f816101a7565b9392505050565b6000602082840312156102a857600080fd5b815161028f816101a7565b6000602082840312156102c557600080fd5b505191905056fea164736f6c6343000812000a

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063fc5a582114610030575b600080fd5b61004361003e3660046101bf565b610057565b604051901515815260200160405180910390f35b60008061006683850185610272565b9050806001600160a01b0316866001600160a01b03160361008b57600191505061019d565b6040516308ec149f60e11b8152600481018690526000906001600160a01b038816906311d8293e90602401602060405180830381865afa1580156100d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f79190610296565b9050806001600160a01b0316861461012957604051630a83d9db60e41b81526004810187905260240160405180910390fd5b6040516370a0823160e01b81526001600160a01b038281166004830152600091908416906370a0823190602401602060405180830381865afa158015610173573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061019791906102b3565b11925050505b9695505050505050565b6001600160a01b03811681146101bc57600080fd5b50565b60008060008060008060a087890312156101d857600080fd5b86356101e3816101a7565b955060208701356101f3816101a7565b94506040870135610203816101a7565b935060608701359250608087013567ffffffffffffffff8082111561022757600080fd5b818901915089601f83011261023b57600080fd5b81358181111561024a57600080fd5b8a602082850101111561025c57600080fd5b6020830194508093505050509295509295509295565b60006020828403121561028457600080fd5b813561028f816101a7565b9392505050565b6000602082840312156102a857600080fd5b815161028f816101a7565b6000602082840312156102c557600080fd5b505191905056fea164736f6c6343000812000a

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ 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.