Goerli Testnet

Contract

0xa66Ccb968392Cd6652E32b8768Ae6343A65400cF
Source Code

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Value
Transfer Ownersh...99012532023-10-20 17:57:00123 days 6 hrs ago1697824620IN
0xa66Ccb...A65400cF
0 ETH0.000001420.05000001
Transfer Ownersh...95696462023-08-23 23:26:12181 days 1 hr ago1692833172IN
0xa66Ccb...A65400cF
0 ETH0.000000570.01999999
0x60a0604095696202023-08-23 23:19:24181 days 1 hr ago1692832764IN
 Create: FeeController
0 ETH0.001276161.5

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
103545402024-01-11 0:51:0040 days 23 hrs ago1704934260
0xa66Ccb...A65400cF
0 ETH
103517772024-01-10 11:50:3641 days 12 hrs ago1704887436
0xa66Ccb...A65400cF
0 ETH
101798232023-12-08 17:49:2474 days 6 hrs ago1702057764
0xa66Ccb...A65400cF
0 ETH
101424672023-12-02 4:03:2480 days 20 hrs ago1701489804
0xa66Ccb...A65400cF
0 ETH
101424422023-12-02 3:57:2480 days 20 hrs ago1701489444
0xa66Ccb...A65400cF
0 ETH
101370462023-12-01 5:22:1281 days 19 hrs ago1701408132
0xa66Ccb...A65400cF
0 ETH
101369892023-12-01 5:07:3681 days 19 hrs ago1701407256
0xa66Ccb...A65400cF
0 ETH
101369732023-12-01 5:03:4881 days 19 hrs ago1701407028
0xa66Ccb...A65400cF
0 ETH
101369302023-12-01 4:51:3681 days 19 hrs ago1701406296
0xa66Ccb...A65400cF
0 ETH
101368862023-12-01 4:40:4881 days 20 hrs ago1701405648
0xa66Ccb...A65400cF
0 ETH
101368332023-12-01 4:27:4881 days 20 hrs ago1701404868
0xa66Ccb...A65400cF
0 ETH
101367462023-12-01 4:07:0081 days 20 hrs ago1701403620
0xa66Ccb...A65400cF
0 ETH
101367252023-12-01 4:01:4881 days 20 hrs ago1701403308
0xa66Ccb...A65400cF
0 ETH
101366672023-12-01 3:47:0081 days 20 hrs ago1701402420
0xa66Ccb...A65400cF
0 ETH
101239962023-11-28 22:27:2484 days 2 hrs ago1701210444
0xa66Ccb...A65400cF
0 ETH
100861072023-11-22 4:45:2490 days 20 hrs ago1700628324
0xa66Ccb...A65400cF
0 ETH
100812872023-11-21 8:37:2491 days 16 hrs ago1700555844
0xa66Ccb...A65400cF
0 ETH
100788182023-11-20 22:14:0092 days 2 hrs ago1700518440
0xa66Ccb...A65400cF
0 ETH
100780162023-11-20 18:50:3692 days 5 hrs ago1700506236
0xa66Ccb...A65400cF
0 ETH
100492732023-11-15 18:36:0097 days 6 hrs ago1700073360
0xa66Ccb...A65400cF
0 ETH
100374652023-11-13 17:13:0099 days 7 hrs ago1699895580
0xa66Ccb...A65400cF
0 ETH
99708082023-11-01 23:46:48111 days 1 hr ago1698882408
0xa66Ccb...A65400cF
0 ETH
99685782023-11-01 13:42:00111 days 11 hrs ago1698846120
0xa66Ccb...A65400cF
0 ETH
99684792023-11-01 13:16:48111 days 11 hrs ago1698844608
0xa66Ccb...A65400cF
0 ETH
99373202023-10-27 1:48:24116 days 22 hrs ago1698371304
0xa66Ccb...A65400cF
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FeeController

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 7 : FeeController.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

import "@openzeppelin/contracts/access/Ownable.sol";

import "./interfaces/IFeeController.sol";
import "./libraries/FeeLookups.sol";

import { FC_LendingFeeOverMax, FC_VaultMintFeeOverMax } from "./errors/Lending.sol";

/**
 * @title FeeController
 * @author Non-Fungible Technologies, Inc.
 *
 * The Fee Controller is used by other lending protocol contracts to query for fees
 * for different protocol operations (loan origination, rollovers, etc). All fees should
 * have setters and getters. In the future, this contract could be extended to
 * support more complex logic (introducing a mapping of users who get a discount, e.g.).
 * Since LoanCore can change the fee controller reference, any changes to this contract
 * can be newly deployed on-chain and adopted.
 */
contract FeeController is IFeeController, FeeLookups, Ownable {
    // ============================================ STATE ==============================================

    /// @dev Fee for minting a vault.
    uint64 public vaultMintFee;

    /// @dev Max fee for minting a vault.
    uint64 public immutable maxVaultMintFee;

    /// @dev Fee mapping for lending protocol operations.
    /// @dev Important: these fees are expressed in basis points. It's required that
    ///                 the consumer of this controller handle accounting properly based
    ///                 on their own knowledge of the fee type.
    mapping(bytes32 => uint16) public loanFees;

    /// @dev Max fees for lending protocol operations.
    /// @dev Functionally immutable, can only be set on deployment. Can specify a maximum fee
    ///      for any id.
    mapping(bytes32 => uint16) public maxLoanFees;

    // ========================================= CONSTRUCTOR ===========================================

    /**
     * @notice Deploy the contract, and set the required max fees to support the lending protocol.
     */
    constructor() {
        /// @dev Vault mint fee - gross
        maxVaultMintFee = 1 ether;

        /// @dev Origination fees - bps
        maxLoanFees[FL_01] = 10_00;
        maxLoanFees[FL_02] = 10_00;

        /// @dev Rollover fees - bps
        maxLoanFees[FL_03] = 20_00;
        maxLoanFees[FL_04] = 20_00;

        /// @dev Loan closure fees - bps
        maxLoanFees[FL_05] = 10_00;
        maxLoanFees[FL_06] = 50_00;
        maxLoanFees[FL_07] = 10_00;
        maxLoanFees[FL_08] = 10_00;
    }

    // ======================================== GETTER/SETTER ==========================================

    /**
     * @notice Set the protocol fee for a given operation to the given value.
     *         The caller must be the owner of the contract.
     *
     * @param id                            The bytes32 identifier for the fee.
     * @param fee                           The fee to set.
     */
    function setLendingFee(bytes32 id, uint16 fee) public override onlyOwner {
        if (maxLoanFees[id] != 0 && fee > maxLoanFees[id]) {
            revert FC_LendingFeeOverMax(id, fee, maxLoanFees[id]);
        }

        loanFees[id] = fee;

        emit SetLendingFee(id, fee);
    }

    /**
     * @notice Set the vault mint fee. The caller must be the owner of the contract.
     *
     * @param fee                           The fee to set.
     */
    function setVaultMintFee(uint64 fee) public override onlyOwner {
        if (maxVaultMintFee != 0 && fee > maxVaultMintFee) {
            revert FC_VaultMintFeeOverMax(fee, maxVaultMintFee);
        }

        vaultMintFee = fee;

        emit SetVaultMintFee(fee);
    }

    /**
     * @notice Get the fee for the given lending protocol fee id.
     *
     * @param id                      The bytes32 id for the fee.
     *
     * @return fee                    The fee for the given id.
     */
    function getLendingFee(bytes32 id) external view override returns (uint16) {
        return loanFees[id];
    }

    /**
     * @notice Get the vault mint fee.
     *
     * @return vaultMintFee            The fee for minting a vault.
     */
    function getVaultMintFee() external view override returns (uint64) {
        return vaultMintFee;
    }

    /**
     * @notice Get the fees for loan origination. Fees are returned in a struct to be used
     *         upon loan origination.
     *
     * @return FeesOrigination              Applicable fees for loan origination.
     */
    function getFeesOrigination() external view override returns (FeesOrigination memory) {
        return FeesOrigination({
            borrowerOriginationFee: loanFees[FL_01],
            lenderOriginationFee: loanFees[FL_02],
            lenderDefaultFee: loanFees[FL_05],
            lenderInterestFee: loanFees[FL_06],
            lenderPrincipalFee: loanFees[FL_07]
        });
    }

    /**
     * @notice Get the fees for loan rollover. Fees are returned in a struct to be used
     *         when a rollover occurs in the repayment controller.
     *
     * @return FeesRollover              Applicable fees for a loan rollover.
     */
    function getFeesRollover() external view override returns (FeesRollover memory) {
        return FeesRollover({
            borrowerRolloverFee: loanFees[FL_03],
            lenderRolloverFee: loanFees[FL_04]
        });
    }

    /**
     * @notice Get the max lending fee for the given id. Unset max fees return 0.
     *
     * @param id                      The bytes32 id for the fee.
     *
     * @return maxLoanFee             The maximum fee for the given id.
     */
    function getMaxLendingFee(bytes32 id) external view override returns (uint16) {
        return maxLoanFees[id];
    }

    /**
     * @notice Get the max vault mint fee.
     *
     * @return maxVaultMintFee        The maximum fee for minting a vault.
     */
    function getMaxVaultMintFee() external view override returns (uint64) {
        return maxVaultMintFee;
    }
}

File 2 of 7 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 3 of 7 : IFeeController.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

interface IFeeController {
    // ================ Structs ================

    struct FeesOrigination {
        uint16 borrowerOriginationFee;
        uint16 lenderOriginationFee;
        uint16 lenderDefaultFee;
        uint16 lenderInterestFee;
        uint16 lenderPrincipalFee;
    }

    struct FeesRollover {
        uint16 borrowerRolloverFee;
        uint16 lenderRolloverFee;
    }

    // ================ Events =================

    event SetLendingFee(bytes32 indexed id, uint64 fee);

    event SetVaultMintFee(uint64 fee);

    // ================ Getter/Setter =================

    function setLendingFee(bytes32 id, uint16 fee) external;

    function setVaultMintFee(uint64 fee) external;
    
    function getLendingFee(bytes32 id) external view returns (uint16);

    function getVaultMintFee() external view returns (uint64);

    function getFeesOrigination() external view returns (FeesOrigination memory);

    function getFeesRollover() external view returns (FeesRollover memory);

    function getMaxLendingFee(bytes32 id) external view returns (uint16);

    function getMaxVaultMintFee() external view returns (uint64);
}

File 4 of 7 : FeeLookups.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;

/**
 * @title FeeLookups
 * @author Non-Fungible Technologies, Inc.
 *
 * Enumerates unique identifiers for fee identifiers
 * that the lending protocol uses.
 */
abstract contract FeeLookups {
    /// @dev Origination fees: amount in bps, payable in loan token
    bytes32 public constant FL_01 = keccak256("BORROWER_ORIGINATION_FEE");
    bytes32 public constant FL_02 = keccak256("LENDER_ORIGINATION_FEE");

    /// @dev Rollover fees: amount in bps, payable in loan token
    bytes32 public constant FL_03 = keccak256("BORROWER_ROLLOVER_FEE");
    bytes32 public constant FL_04 = keccak256("LENDER_ROLLOVER_FEE");

    /// @dev Loan closure fees: amount in bps, payable in loan token
    bytes32 public constant FL_05 = keccak256("LENDER_DEFAULT_FEE");
    bytes32 public constant FL_06 = keccak256("LENDER_INTEREST_FEE");
    bytes32 public constant FL_07 = keccak256("LENDER_PRINCIPAL_FEE");
    bytes32 public constant FL_08 = keccak256("LENDER_REDEEM_FEE");
}

File 5 of 7 : 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 7 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 7 of 7 : 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":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"selector","type":"bytes32"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"}],"name":"FC_LendingFeeOverMax","type":"error"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"}],"name":"FC_VaultMintFeeOverMax","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"fee","type":"uint64"}],"name":"SetLendingFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"fee","type":"uint64"}],"name":"SetVaultMintFee","type":"event"},{"inputs":[],"name":"FL_01","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FL_02","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FL_03","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FL_04","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FL_05","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FL_06","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FL_07","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FL_08","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeesOrigination","outputs":[{"components":[{"internalType":"uint16","name":"borrowerOriginationFee","type":"uint16"},{"internalType":"uint16","name":"lenderOriginationFee","type":"uint16"},{"internalType":"uint16","name":"lenderDefaultFee","type":"uint16"},{"internalType":"uint16","name":"lenderInterestFee","type":"uint16"},{"internalType":"uint16","name":"lenderPrincipalFee","type":"uint16"}],"internalType":"struct IFeeController.FeesOrigination","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeesRollover","outputs":[{"components":[{"internalType":"uint16","name":"borrowerRolloverFee","type":"uint16"},{"internalType":"uint16","name":"lenderRolloverFee","type":"uint16"}],"internalType":"struct IFeeController.FeesRollover","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getLendingFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getMaxLendingFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxVaultMintFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVaultMintFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"loanFees","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"maxLoanFees","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxVaultMintFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"},{"internalType":"uint16","name":"fee","type":"uint16"}],"name":"setLendingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"fee","type":"uint64"}],"name":"setVaultMintFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultMintFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"}]

60a060405234801561001057600080fd5b5061001a336101b0565b670de0b6b3a764000060805260026020527fcfe88eee2da5edfa196a3f901993c7d378c236ff94e0997cf10b1c2742c0f620805461ffff199081166103e89081179092557fa05bced702bfc3addc707f314fd1e7aa746bc060b75f83379bfcc3eef58dee3d80548216831790557ff64e2c9a5972f4b547961681717d96837ac8876cdd3511e5f6524259f777f306805482166107d09081179091557f9f4028c8fe267a12d3a5591f81f9cb93af212514c1702340294af273943baf348054831690911790557f5eb819b11decd5bf2f964a03066c300c83c76931de316cf22ed8080a34a671f780548216831790557fa068ccbe61bda588b8c7c4c054d81adc52588b271ee5a72c8851f4a889366ab2805482166113881790557f8641de2baab4a77757f82a6f1d453185fc99b9f9a9b5032e715c541c1a6e056c80548216831790557f4714fd9784ca8c9ee16df7000f2eb0fc7a2296e457de6968bc65d71fd28737066000527f23867a81d885fea7e571e75ec487a2eaabb7d38c912a9a85dca2303b43381cbe80549091169091179055610200565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b608051610aaa61023760003960008181610308015281816104c2015281816107be015281816107e901526108440152610aaa6000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063e86f0cc61161007c578063e86f0cc614610458578063eade2f561461046b578063ededcc4114610486578063f2fde38b146104ad578063f68fe8c6146104c0578063f9acec9a146104e657600080fd5b80638da5cb5b1461037d578063a7146e7114610398578063aee758e7146103bf578063b8921e26146103e3578063db0a23c11461040a578063ddb220ec1461043157600080fd5b80634bfa4254116101155780634bfa42541461023c5780635bedebb2146102515780636c755a8214610303578063715018a61461032a57806372b7c5af146103325780637eb094981461035657600080fd5b806319b0b157146101525780632030a9411461018e578063227e8f0c146101bc57806333f6b51c146101f157806346f630ee14610218575b600080fd5b6101766101603660046109be565b60026020526000908152604090205461ffff1681565b60405161ffff90911681526020015b60405180910390f35b600054600160a01b900467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610185565b6101e37f6b9fec8a90acd71b357b3fbde8e525c5e0a0ffebe7010905e79162a4fd6421bd81565b604051908152602001610185565b6101e37fddfa60b1f3b0c3629357d48d7f8a1186bd1ff199faa6c6b792597e91bd705dc281565b6101766102263660046109be565b60009081526002602052604090205461ffff1690565b61024f61024a3660046109d7565b61064c565b005b60408051808201825260008082526020918201819052825180840184527f84b10fe9b4b7ca874a08dc2c7294295d859d4e724488ede745c4ef35e0a8e0885461ffff90811682527fc3a599955a4238a21ad67957aa12a28dc3e88efd2a54bc264ba15e23b257c352909252600183527f3877ea222bd50a271568180d34ad354b62e83bc118409ff77b9f4b3986fe12a75482168184019081528451915183168252519091169181019190915201610185565b6101a37f000000000000000000000000000000000000000000000000000000000000000081565b61024f610753565b6101766103403660046109be565b60016020526000908152604090205461ffff1681565b6101e37f4e2344e60c4b990f3c4cf2efa216c71144a011f9e4a940c6b459a8066c98e1f981565b6000546040516001600160a01b039091168152602001610185565b6101e37f41f539feb01b3a702d5e8c2e4367fa0d5a544df6b5ef24765c6836e0743db74281565b6101766103cd3660046109be565b60009081526001602052604090205461ffff1690565b6101e37f74ba47f4e32f0deada0ece4f758dd1cb5f98ba44c024c037a61f34bb066f568e81565b6101e37f6c9950464c33f914161b87af80469f5598c7ea5009d7b4464f7e3815112686a381565b6101e37fc3a599955a4238a21ad67957aa12a28dc3e88efd2a54bc264ba15e23b257c35281565b61024f610466366004610a0e565b610789565b6000546101a390600160a01b900467ffffffffffffffff1681565b6101e37f4714fd9784ca8c9ee16df7000f2eb0fc7a2296e457de6968bc65d71fd287370681565b61024f6104bb366004610a3f565b6108d3565b7f00000000000000000000000000000000000000000000000000000000000000006101a3565b6040805160a080820183526000808352602080840182905283850182905260608085018390526080948501839052855180850187527f484f59a35e3d36f96e442a7f5e1700e7a66c9ba9637a713622ab7637af5452885461ffff90811682527f60d4d788380f65ac0892d831c8208965d61fb4f223f5af7498d997c5066f1e9b5481168285019081527fd0e1c89aef15f5cced655ab7c723744cf44da742af6604b78599d82b478f7ef2548216838a019081527f11dd3bf76b4215917646a61c8660117a097b5f40d3a7a9123be22c0caf0137f85483168486019081527f6c9950464c33f914161b87af80469f5598c7ea5009d7b4464f7e3815112686a3909752600186527fc29d6b3572c743260be8dfe9df2bf3dc51104b8e5370852ceb6149d28ebbb99f548316848a019081528a51945184168552915183169584019590955293518116978201979097529251861690830152519093169183019190915201610185565b6000546001600160a01b0316331461067f5760405162461bcd60e51b815260040161067690610a68565b60405180910390fd5b60008281526002602052604090205461ffff16158015906106b5575060008281526002602052604090205461ffff908116908216115b156106f957600082815260026020526040908190205490516323766f5b60e11b81526004810184905261ffff80841660248301529091166044820152606401610676565b600082815260016020908152604091829020805461ffff191661ffff8516908117909155915191825283917f1d80efd6de29c040562d3fb0e8d1be50ea6d87f2167bfa4f49c48f17a1d8518c910160405180910390a25050565b6000546001600160a01b0316331461077d5760405162461bcd60e51b815260040161067690610a68565b610787600061096e565b565b6000546001600160a01b031633146107b35760405162461bcd60e51b815260040161067690610a68565b67ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161580159061081f57507f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168167ffffffffffffffff16115b156108715760405163159e794960e21b815267ffffffffffffffff80831660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610676565b6000805467ffffffffffffffff60a01b1916600160a01b67ffffffffffffffff8416908102919091179091556040519081527f2cb76db7b31552762fc2eaa4218b60af00a8a8c6c96c33175e2236bfd45f4d029060200160405180910390a150565b6000546001600160a01b031633146108fd5760405162461bcd60e51b815260040161067690610a68565b6001600160a01b0381166109625760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610676565b61096b8161096e565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156109d057600080fd5b5035919050565b600080604083850312156109ea57600080fd5b82359150602083013561ffff81168114610a0357600080fd5b809150509250929050565b600060208284031215610a2057600080fd5b813567ffffffffffffffff81168114610a3857600080fd5b9392505050565b600060208284031215610a5157600080fd5b81356001600160a01b0381168114610a3857600080fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260408201526060019056fea164736f6c6343000812000a

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061014d5760003560e01c80638da5cb5b116100c3578063e86f0cc61161007c578063e86f0cc614610458578063eade2f561461046b578063ededcc4114610486578063f2fde38b146104ad578063f68fe8c6146104c0578063f9acec9a146104e657600080fd5b80638da5cb5b1461037d578063a7146e7114610398578063aee758e7146103bf578063b8921e26146103e3578063db0a23c11461040a578063ddb220ec1461043157600080fd5b80634bfa4254116101155780634bfa42541461023c5780635bedebb2146102515780636c755a8214610303578063715018a61461032a57806372b7c5af146103325780637eb094981461035657600080fd5b806319b0b157146101525780632030a9411461018e578063227e8f0c146101bc57806333f6b51c146101f157806346f630ee14610218575b600080fd5b6101766101603660046109be565b60026020526000908152604090205461ffff1681565b60405161ffff90911681526020015b60405180910390f35b600054600160a01b900467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610185565b6101e37f6b9fec8a90acd71b357b3fbde8e525c5e0a0ffebe7010905e79162a4fd6421bd81565b604051908152602001610185565b6101e37fddfa60b1f3b0c3629357d48d7f8a1186bd1ff199faa6c6b792597e91bd705dc281565b6101766102263660046109be565b60009081526002602052604090205461ffff1690565b61024f61024a3660046109d7565b61064c565b005b60408051808201825260008082526020918201819052825180840184527f84b10fe9b4b7ca874a08dc2c7294295d859d4e724488ede745c4ef35e0a8e0885461ffff90811682527fc3a599955a4238a21ad67957aa12a28dc3e88efd2a54bc264ba15e23b257c352909252600183527f3877ea222bd50a271568180d34ad354b62e83bc118409ff77b9f4b3986fe12a75482168184019081528451915183168252519091169181019190915201610185565b6101a37f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b61024f610753565b6101766103403660046109be565b60016020526000908152604090205461ffff1681565b6101e37f4e2344e60c4b990f3c4cf2efa216c71144a011f9e4a940c6b459a8066c98e1f981565b6000546040516001600160a01b039091168152602001610185565b6101e37f41f539feb01b3a702d5e8c2e4367fa0d5a544df6b5ef24765c6836e0743db74281565b6101766103cd3660046109be565b60009081526001602052604090205461ffff1690565b6101e37f74ba47f4e32f0deada0ece4f758dd1cb5f98ba44c024c037a61f34bb066f568e81565b6101e37f6c9950464c33f914161b87af80469f5598c7ea5009d7b4464f7e3815112686a381565b6101e37fc3a599955a4238a21ad67957aa12a28dc3e88efd2a54bc264ba15e23b257c35281565b61024f610466366004610a0e565b610789565b6000546101a390600160a01b900467ffffffffffffffff1681565b6101e37f4714fd9784ca8c9ee16df7000f2eb0fc7a2296e457de6968bc65d71fd287370681565b61024f6104bb366004610a3f565b6108d3565b7f0000000000000000000000000000000000000000000000000de0b6b3a76400006101a3565b6040805160a080820183526000808352602080840182905283850182905260608085018390526080948501839052855180850187527f484f59a35e3d36f96e442a7f5e1700e7a66c9ba9637a713622ab7637af5452885461ffff90811682527f60d4d788380f65ac0892d831c8208965d61fb4f223f5af7498d997c5066f1e9b5481168285019081527fd0e1c89aef15f5cced655ab7c723744cf44da742af6604b78599d82b478f7ef2548216838a019081527f11dd3bf76b4215917646a61c8660117a097b5f40d3a7a9123be22c0caf0137f85483168486019081527f6c9950464c33f914161b87af80469f5598c7ea5009d7b4464f7e3815112686a3909752600186527fc29d6b3572c743260be8dfe9df2bf3dc51104b8e5370852ceb6149d28ebbb99f548316848a019081528a51945184168552915183169584019590955293518116978201979097529251861690830152519093169183019190915201610185565b6000546001600160a01b0316331461067f5760405162461bcd60e51b815260040161067690610a68565b60405180910390fd5b60008281526002602052604090205461ffff16158015906106b5575060008281526002602052604090205461ffff908116908216115b156106f957600082815260026020526040908190205490516323766f5b60e11b81526004810184905261ffff80841660248301529091166044820152606401610676565b600082815260016020908152604091829020805461ffff191661ffff8516908117909155915191825283917f1d80efd6de29c040562d3fb0e8d1be50ea6d87f2167bfa4f49c48f17a1d8518c910160405180910390a25050565b6000546001600160a01b0316331461077d5760405162461bcd60e51b815260040161067690610a68565b610787600061096e565b565b6000546001600160a01b031633146107b35760405162461bcd60e51b815260040161067690610a68565b67ffffffffffffffff7f0000000000000000000000000000000000000000000000000de0b6b3a7640000161580159061081f57507f0000000000000000000000000000000000000000000000000de0b6b3a764000067ffffffffffffffff168167ffffffffffffffff16115b156108715760405163159e794960e21b815267ffffffffffffffff80831660048301527f0000000000000000000000000000000000000000000000000de0b6b3a7640000166024820152604401610676565b6000805467ffffffffffffffff60a01b1916600160a01b67ffffffffffffffff8416908102919091179091556040519081527f2cb76db7b31552762fc2eaa4218b60af00a8a8c6c96c33175e2236bfd45f4d029060200160405180910390a150565b6000546001600160a01b031633146108fd5760405162461bcd60e51b815260040161067690610a68565b6001600160a01b0381166109625760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610676565b61096b8161096e565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156109d057600080fd5b5035919050565b600080604083850312156109ea57600080fd5b82359150602083013561ffff81168114610a0357600080fd5b809150509250929050565b600060208284031215610a2057600080fd5b813567ffffffffffffffff81168114610a3857600080fd5b9392505050565b600060208284031215610a5157600080fd5b81356001600160a01b0381168114610a3857600080fd5b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260408201526060019056fea164736f6c6343000812000a

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.