EcosystemNFTsDocs

Footer

Xchange

  • Swap
  • Liquidity
  • Loans
  • Fund
  • Vote

Tokens

  • X7R
  • X7DAO
  • X7D
  • X7101-X7105

Explore

  • Dashboard
  • Guides
  • Integration
  • Whitepaper
  • Breakdowns
  • Onchains
  • FAQs

Community

  • Telegram
  • Twitter
  • Discord
  • Warpcast
  • Blog
  • Links

Permissionless Trustless Decentralized Exchange

Launch your project on Xchange with 10-1000x the initial liquidity across multiple blockchains where anyone can Swap, Borrow and Lend!

X7 Finance·Trust No One. Trust Code. Long Live DeFi.
  • Telegram
  • Twitter
  • Discordś
  • Warpcast
  • YouTube
  • Reddit
  • GitHub
  • Pioneer 1488 avatar
    Guides
    View
  • Pioneer 1488 avatar
    Integration
    View
  • Pioneer 1488 avatar
    Whitepaper
    View
  • Pioneer 1488 avatar
    Breakdowns
    View
  • Pioneer 1488 avatar
    Onchains
    View
  • Pioneer 1488 avatar
    FAQ
    View
    • X7R Token Contract
    • X7DAO Token Contract
    • X7100 Token Contract
    • X7D
    • X7DAO Discount Authority
    • X7DAO Liquidity Hub
    • X7 Ecosystem Splitter
    • X7 Liquidity Loan Terms
    • X7 Lending Pool
    • X7 Lending Pool Reserve
    • X7 Lending Discount Authority
    • X7 Liquidity Treasury
    • X7 Profit Share Splitter
    • X7R Discount Authority
    • X7R Liquidity Hub
    • X7 Token Burner
    • X7 Token Timelock
    • X7 Treasury Splitter V3
    • X7100 Discount Authority
    • X7100 Liquidity Hub
    • X7 Borrowing Maxi NFT
    • X7 Dex Maxi NFT
    • X7 Ecosystem Maxi NFT
    • X7 Liquidity Maxi NFT
    • X7 Pioneer NFT
    • X7 Magister NFT
    • Xchange Factory
    • Xchange Pair
    • X7R Token Contract
    • X7DAO Token Contract
    • X7100 Token Contract
    • X7D
    • X7DAO Discount Authority
    • X7DAO Liquidity Hub
    • X7 Ecosystem Splitter
    • X7 Liquidity Loan Terms
    • X7 Lending Pool
    • X7 Lending Pool Reserve
    • X7 Lending Discount Authority
    • X7 Profit Share Splitter
    • X7R Discount Authority
    • X7R Liquidity Hub
    • X7 Token Burner
    • X7 Token Timelock
    • X7 Treasury Splitter V3
    • X7100 Discount Authority
    • X7100 Liquidity Hub
    • X7 Borrowing Maxi
    • X7 Dex Maxi
    • X7 Ecosystem Maxi
    • X7 Liquidity Maxi NFT
    • X7 Pioneer NFT
    • X7 Magister NFT
    • Xchange Factory
    • Xchange Pair
    • X7R Token Contract
    • X7DAO Token Contract
    • X7100 Token Contract
    • X7D
    • X7DAO Discount Authority
    • X7DAO Liquidity Hub
    • X7 Ecosystem Splitter
    • X7 Liquidity Loan Terms
    • X7 Lending Pool
    • X7 Lending Pool Reserve
    • X7 Lending Discount Authority
    • X7 Profit Share Splitter
    • X7R Discount Authority
    • X7R Liquidity Hub
    • X7 Token Burner
    • X7 Token Timelock
    • X7 Treasury Splitter V3
    • X7100 Discount Authority
    • X7100 Liquidity Hub
    • X7 Borrowing Maxi
    • X7 Dex Maxi
    • X7 Ecosystem Maxi
    • X7 Liquidity Maxi NFT
    • X7 Pioneer NFT
    • X7 Magister NFT
    • Xchange Factory
    • Xchange Pair
Contracts
breakdowns

X7 Lending Pool

The X7 Lending Pool contract includes functions for liquidating loans, buying out loans, depositing and returning ETH, calculating loan quotes and discounted quotes, splitting origination and premium fees, paying liquidation fees, and adding liquidity to an exchange pair. The contract ensures safe interactions with ERC20 tokens through the TransferHelper library, which includes functions for safe token approval and transfer. These functionalities collectively enable the contract to facilitate loan management, fee distribution, and liquidity provision in the lending platform.

interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; } interface IX7D { function mint(address to, uint256 amount) external; function burn(address from, uint256 amount) external; } interface IX7LendingTerm { function createLoan() external returns (uint256); function fundLoan(uint256 loanID) external; } // 1. Loan origination fee // 2. Loan retention premium fee schedule // 3. Principal repayment condition/maximum loan duration // 4. Liquidation conditions and Reward // 5. Loan duration interface IX7LendingDiscountAuthority { function getFeeModifiers( address borrower, uint256[3] memory loanAmountDetails, uint256[3] memory loanDurationDetails ) external view returns (uint256, uint256); function useFeeModifiers( address borrower, uint256[3] memory loanAmountDetails, uint256[3] memory loanDurationDetails ) external returns (uint256, uint256); } interface IX7InitialLiquidityLoanTerm { function ownerOf(uint256 tokenId) external view returns (address owner); function transferFrom( address from, address to, uint256 tokenId ) external; function originateLoan( uint256 loanAmount, uint256 originationFee, uint256 loanLengthSeconds_, uint256 premiumFeeModifierNumerator_, uint256 originationFeeModifierNumerator_, address receiver, uint256 tokenId ) external payable; function minimumLoanAmount() external view returns (uint256); function maximumLoanAmount() external view returns (uint256); function minimumLoanLengthSeconds() external view returns (uint256); function maximumLoanLengthSeconds() external view returns (uint256); function getPrincipalDue(uint256 loanID, uint256 asOf) external view returns (uint256); function getPremiumsDue(uint256 loanID, uint256 asOf) external view returns (uint256); function getTotalDue(uint256 loanID, uint256 asOf) external view returns (uint256); function getRemainingLiability(uint256 loanID) external view returns (uint256); function getPremiumPaymentSchedule(uint256 loanID) external view returns (uint256[] memory, uint256[] memory); function getPrincipalPaymentSchedule(uint256 loanID) external view returns (uint256[] memory, uint256[] memory); function isComplete(uint256 loanID) external view returns (bool); function getOriginationAmounts(uint256 loanAmount) external view returns (uint256 loanAmountRounded, uint256 originationFee); function getQuote(uint256 loanAmount) external view returns (uint256 loanAmountRounded, uint256 originationFee, uint256 totalPremium); function getDiscountedQuote(uint256 loanAmount_, uint256 premiumFeeModifier, uint256 originationFeeModifier) external view returns (uint256 loanAmountRounded, uint256 originationFee, uint256 totalPremium); function recordPrincipalRepayment(uint256 loanID, uint256 amount) external returns (uint256 premiumPaid, uint256 principalPaid, uint256 refundAmount, uint256 remainingLiability); function recordPayment(uint256 loanID, uint256 amount) external returns (uint256 premiumPaid, uint256 principalPaid, uint256 refundAmount, uint256 remainingLiability); function liquidationAmount(uint256 loanID) external view returns (uint256); function loanAmount(uint256 loanID) external view returns (uint256); function principalAmountPaid(uint256 loanID) external view returns (uint256); } interface IXchangeFactory { function getPair(address tokenA, address tokenB) external view returns (address pair); function createPair(address tokenA, address tokenB) external returns (address pair); } interface IXchangeRouter { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); } interface IXchangePair { function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function syncSafe(uint256, uint256) external; function withdrawTokensAgainstMinimumBalance(address tokenAddress, address to, uint112 amount) external returns (uint256); function setMinimumBalance(address tokenAddress, uint112 minimumAmount) external; function tokenMinimumBalance(address) external view returns (uint256); } interface X7DMinter { event FundsReturned(address indexed sender, uint256 amount); // Call this function to explicitly mint X7D function depositETH() external payable; // Call this function to return ETH to this contract without minting X7D function returnETH() external payable; // Call this function to mint X7D to a recipient of your choosing function depositETHForRecipient(address recipient) external payable; }

List of Interface classes that the X7 Lending Pool use to interact with other smart contracts.

mapping(address => bool) public loanTermActive; address[] public activeLoanTerms; mapping(address => uint256) loanTermIndex; mapping(uint256 => address) public loanTermLookup; mapping(uint256 => address) public loanPair; mapping(uint256 => address) public loanToken; mapping(uint256 => uint256) public loanLiquidationReward; mapping(uint256 => address) public loanLiquidationReturnTo; mapping(address => uint256[]) public loanLookupByBorrower; mapping(uint256 => address) public loanBorrower; mapping(uint256 => uint256) loanBorrowerIndex; uint256 public nextLoanID = 1; bool lendingHalted = true; bool allowLoanBuyout = false; IX7LendingDiscountAuthority public discountAuthority; mapping(address => bool) public authorizedCapitalManagers; address public lendingPoolReserve; address public ecosystemSplitter; address public X7100ReserveRecipient; address public X7DAORewardRecipient; IX7D public X7D; uint256 public ecosystemSplitterPremiumShare; uint256 public X7DAOPremiumShare; uint256 public X7100PremiumShare; uint256 public lendingPoolPremiumShare; uint256 public ecosystemSplitterOriginationShare; uint256 public X7DAOOriginationShare; uint256 public X7100OriginationShare; uint256 public lendingPoolOriginationShare; IXchangeRouter public router; address public weth; address public ecosystemRecipient; uint256 public liquidationEscrow; uint256 public liquidationReward; uint256 public retainedFeeNumerator; uint256 public retainedFeeDenominator = 100; uint256 public syncSafeGasAmount = 100000;
  1. mapping(address => bool) public loanTermActive;: This mapping keeps track of the active status of loan terms for different addresses.
  2. address[] public activeLoanTerms;: This dynamic array stores the addresses of the active loan terms.
  3. mapping(address => uint256) loanTermIndex;: This mapping maps loan term addresses to their respective indices in the activeLoanTerms array.
  4. mapping(uint256 => address) public loanTermLookup;: This mapping is used to lookup loan terms using their ID.
  5. mapping(uint256 => address) public loanPair;: This mapping associates loan IDs with loan pair addresses.
  6. mapping(uint256 => address) public loanToken;: This mapping associates loan IDs with loan token addresses.
  7. mapping(uint256 => uint256) public loanLiquidationReward;: This mapping maps loan IDs to their corresponding liquidation reward amounts.
  8. mapping(uint256 => address) public loanLiquidationReturnTo;: This mapping associates loan IDs with addresses where the liquidated funds should be returned.
  9. mapping(address => uint256[]) public loanLookupByBorrower;: This mapping allows borrowers to look up their loans by their address.
  10. mapping(uint256 => address) public loanBorrower;: This mapping maps loan IDs to their respective borrower addresses.
  11. mapping(uint256 => uint256) loanBorrowerIndex;: This mapping maps loan IDs to their respective indices in the loanLookupByBorrower array.
  12. uint256 public nextLoanID = 1;: This variable keeps track of the ID for the next loan.
  13. bool lendingHalted = true;: This boolean variable indicates whether lending is currently halted or not.
  14. bool allowLoanBuyout = false;: This boolean variable determines whether loan buyouts are allowed or not.
  15. IX7LendingDiscountAuthority public discountAuthority;: This variable refers to an interface contract for a lending discount authority.
  16. mapping(address => bool) public authorizedCapitalManagers;: This mapping stores addresses of authorized capital managers.
  17. address public lendingPoolReserve;: This variable represents the address of the lending pool reserve.
  18. address public ecosystemSplitter;: This variable represents the address of an ecosystem splitter contract.
  19. address public X7100ReserveRecipient;: This variable represents the address of the recipient for X7100 reserve.
  20. address public X7DAORewardRecipient;: This variable represents the address of the recipient for X7DAO rewards.
  21. IX7D public X7D;: This variable refers to an interface contract for X7D.
  22. uint256 public ecosystemSplitterPremiumShare;: This variable represents the premium share for the ecosystem splitter.
  23. uint256 public X7DAOPremiumShare;: This variable represents the premium share for X7DAO.
  24. uint256 public X7100PremiumShare;: This variable represents the premium share for X7100.
  25. uint256 public lendingPoolPremiumShare;: This variable represents the premium share for the lending pool.
  26. uint256 public ecosystemSplitterOriginationShare;: This variable represents the origination share for the ecosystem splitter.
  27. uint256 public X7DAOOriginationShare;: This variable represents the origination share for X7DAO.
  28. uint256 public X7100OriginationShare;: This variable represents the origination share for X7100.
  29. uint256 public lendingPoolOriginationShare;: This variable represents the origination share for the lending pool.
  30. IXchangeRouter public router;: This variable refers to an interface contract for an exchange router.
  31. address public weth;: This variable represents the address of the Wrapped Ether (WETH) contract.
  32. address public ecosystemRecipient;: This variable represents the address of the recipient for ecosystem-related transactions.
  33. uint256 public liquidationEscrow;: This variable represents the amount of funds held in the liquidation escrow.
  34. uint256 public liquidationReward;: This variable represents the amount of liquidation reward.
  35. uint256 public retainedFeeNumerator;: This variable represents the numerator for calculating the retained fee.
  36. uint256 public retainedFeeDenominator = 100;: This variable represents the denominator for calculating the retained fee.
  37. uint256 public syncSafeGasAmount = 100000;: This variable represents the amount of gas considered safe for synchronization.
event EcosystemRecipientSet(address oldAddress, address newAddress); event RouterSet(address oldAddress, address newAddress); event WETHSet(address oldAddress, address newAddress); event X7DSet(address oldAddress, address newAddress); event LoanTermActiveStateSet(address indexed newAddress, bool isActive); event LiquidationRewardSet(uint256 oldReward, uint256 newReward); event OriginationSharesSet( uint256 oldEcosystemSplitterOriginationShare, uint256 oldX7DAOOriginationShare, uint256 oldX7100OriginationShare, uint256 oldLendingPoolOriginationShare, uint256 newEcosystemSplitterOriginationShare, uint256 newX7DAOOriginationShare, uint256 newX7100OriginationShare, uint256 newLendingPoolOriginationShare ); event PremiumSharesSet( uint256 oldEcosystemSplitterOriginationShare, uint256 oldX7DAOOriginationShare, uint256 oldX7100OriginationShare, uint256 oldLendingPoolOriginationShare, uint256 newEcosystemSplitterOriginationShare, uint256 newX7DAOOriginationShare, uint256 newX7100OriginationShare, uint256 newLendingPoolOriginationShare ); event EcosystemSplitterSet(address oldAddress, address newAddress); event X7100ReserveRecipientSet(address oldAddress, address newAddress); event X7DAORewardRecipientSet(address oldAddress, address newAddress); event DiscountAuthoritySet(address oldAddress, address newAddress); event RetainedFeeNumeratorSet(uint256 oldValue, uint256 newValue); event LendingPoolReserveSet(address oldAddress, address newAddress); event LendingHalted(); event LendingCommenced(); event AuthorizedCapitalManagerSet(address managerAddress, bool isTrusted); event LoanBuyoutAllowed(bool isAllowed); event SyncSafeGasAmountSet(uint256 oldValue, uint256 newValue); event LoanBoughtOut(address indexed buyer, uint256 indexed loanID);

Events are used to emit information about specific occurrences within a smart contract. They are typically used to notify external applications or user interfaces about important state changes or actions that have taken place.

uint private unlocked = 1; modifier lock() { require(unlocked == 1, 'LendingPool: LOCKED'); unlocked = 0; _; unlocked = 1; }

The code snippet represents a modifier called lock(). Modifiers are used in Solidity to modify the behaviour of functions or other modifiers.

In this case, the lock() modifier is used to ensure that the wrapped code is executed atomically and prevents reentrancy issues. Here's how the modifier works:

  1. It begins with a require statement that checks if the unlocked the variable is equal to 1. If it is not equal to 1, it means that the modifier is already being executed or locked, and an exception with the message 'LendingPool: LOCKED' is thrown, reverting the transaction.
  2. If the unlocked the variable is equal to 1, and the modifier proceeds. It sets unlocked to 0, effectively locking the modifier and preventing reentrancy.
  3. The underscore _ is a placeholder that represents the wrapped code or function that the modifier is being applied to. It is executed at this point in the modifier.
  4. After the execution of the wrapped code is complete, the unlocked variable is set back to 1, unlocking the modifier for future executions.

By using this lock() modifier, the contract ensures that the wrapped code within the function or modifier is executed in a locked state, preventing multiple executions or reentrancy issues until it is unlocked again.

constructor(address routerAddress) Ownable(msg.sender) { router = IXchangeRouter(routerAddress); }

The constructor is executed only once during the deployment of the contract and is used to initialize the contract's state.

In this constructor, it takes an address parameter routerAddress and assigns it to the router variable of type IXchangeRouter. The IXchangeRouter is an interface contract representing a router.

Additionally, the Ownable(msg.sender) statement indicates that the contract inherits from an Ownable contract, which provides functionality for ownership control and access modifiers.

Overall, this constructor initializes the router variable with the provided routerAddress and sets the contract owner as the deployer of the contract.

receive () external payable {}

The receive() function is a special function in Solidity that allows the contract to receive Ether when it receives a direct transfer of funds. It is used as a fallback function when the contract receives Ether without any specific function call.

In this case, the receive() function is marked as external and payable. The external visibility modifier means that the function can be called from outside the contract. The payable modifier indicates that the function can receive Ether along with the function call.

The function body is empty, indicated by the {}. This means that when the contract receives Ether, no specific actions or operations are performed within the receive() function. The Ether sent to the contract will be added to the contract's balance.

This receive() function allows the contract to accept Ether and handle any logic or operations related to the received funds in other functions or code blocks within the contract.

function activeLoansByBorrower(address borrower) external view returns (uint256) { return loanLookupByBorrower[borrower].length; }

The function is defined as external and view, indicating that it can be called from outside the contract and does not modify the contract's state.

The function takes an address parameter borrower, representing the address of a borrower. It retrieves the array of loan IDs associated with the specified borrower from the loanLookupByBorrower mapping.

The function then returns the length of the array, which represents the number of active loans associated with the borrower.

In summary, this function allows external callers to retrieve the count of active loans associated with a specific borrower by querying the loanLookupByBorrower mapping.

function countOfActiveLoanTerms() external view returns (uint256) { return activeLoanTerms.length; }

The function is defined as external and view, indicating that it can be called from outside the contract and does not modify the contract's state.

The function retrieves the activeLoanTerms array, which contains the addresses of active loan terms. It then returns the length of this array, which represents the number of active loan terms currently in existence.

In summary, this function allows external callers to retrieve the count of active loan terms by querying the activeLoanTerms array.

function availableCapital() external view returns (uint256) { return address(this).balance - liquidationEscrow; }

The function is defined as external and view, indicating that it can be called from outside the contract and does not modify the contract's state.

The function calculates the available capital by subtracting the liquidationEscrow amount from the balance of the contract. The address(this).balance expression retrieves the current balance of the contract, which represents the total amount of Ether held by the contract.

By subtracting the liquidationEscrow amount from the contract's balance, the function returns the remaining available capital, which represents the amount of Ether that is not currently held in the liquidation escrow.

In summary, this function allows external callers to retrieve the available capital of the contract by calculating the difference between the contract's balance and the liquidation escrow amount.

function getDiscountedQuote( address borrower, IX7InitialLiquidityLoanTerm loanTerm, uint256 loanAmount, uint256 loanDurationSeconds ) external view returns (uint256[7] memory) { require(loanTerm.minimumLoanAmount() <= loanAmount); require(loanTerm.maximumLoanAmount() >= loanAmount); require(loanTerm.minimumLoanLengthSeconds() <= loanDurationSeconds); require(loanTerm.maximumLoanLengthSeconds() >= loanDurationSeconds); return _getDiscountedQuote(borrower, loanTerm, loanAmount, loanDurationSeconds); }

The function is defined as external and view, indicating that it can be called from outside the contract and does not modify the contract's state.

The function takes several parameters:

  • borrower: The address of the borrower.
  • loanTerm: An instance of the IX7InitialLiquidityLoanTerm interface representing the loan term.
  • loanAmount: The requested loan amount.
  • loanDurationSeconds: The duration of the loan in seconds.

The function performs several require statements to validate the loan amount and duration against the minimum and maximum values defined in the loanTerm instance.

If all the validation conditions are met, the function then calls the _getDiscountedQuote function with the provided parameters and returns the result as an array of seven uint256 values.

In summary, this function allows external callers to retrieve a discounted quote for a loan by providing the borrower's address, a loan term instance, loan amount, and loan duration. It performs validation checks and then calls an internal function to calculate and return the discounted quote.

function canLiquidate(uint256 loanID) external view returns (uint256) { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); return loanTerm.liquidationAmount( loanID ); }

The function canLiquidate is defined as an external view function. It takes a loanID parameter of type uint256 representing the ID of a loan.

Within the function, it retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

Finally, the function calls the liquidationAmount function on the loan term contract, passing the loanID as a parameter. The liquidationAmount function calculates and returns the amount that can be liquidated for the specified loan.

In summary, this function allows external callers to check the amount that can be liquidated for a given loan ID by retrieving the loan term contract associated with the loan ID and invoking its liquidationAmount function.

function getPrincipalDue(uint256 loanID, uint256 asOf) external view returns (uint256) { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); return loanTerm.getPrincipalDue(loanID, asOf); }

The function getPrincipalDue is defined as an external view function. It takes two parameters: loanID, which represents the ID of a loan, and asOf, which represents a timestamp indicating a specific point in time.

Within the function, it retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

Finally, the function calls the getPrincipalDue function on the loan term contract, passing the loanID and asOf as parameters. The getPrincipalDue function calculates and returns the principal amount due for the specified loan as of the specified timestamp.

In summary, this function allows external callers to retrieve the principal amount due for a given loan ID as of a specific timestamp by accessing the loan term contract associated with the loan ID and invoking its getPrincipalDue function.

function getPremiumsDue(uint256 loanID, uint256 asOf) external view returns (uint256) { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); return loanTerm.getPremiumsDue(loanID, asOf); }

The function getPremiumsDue is defined as an external view function. It takes two parameters: loanID, which represents the ID of a loan, and asOf, which represents a timestamp indicating a specific point in time.

Within the function, it retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

Finally, the function calls the getPremiumsDue function on the loan term contract, passing the loanID and asOf as parameters. The getPremiumsDue function calculates and returns the premiums amount due for the specified loan as of the specified timestamp.

In summary, this function allows external callers to retrieve the premiums amount due for a given loan ID as of a specific timestamp by accessing the loan term contract associated with the loan ID and invoking its getPremiumsDue function.

function getTotalDue(uint256 loanID, uint256 asOf) external view returns (uint256) { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); return loanTerm.getTotalDue(loanID, asOf); }

The function getTotalDue is defined as an external view function. It takes two parameters: loanID, which represents the ID of a loan, and asOf, which represents a timestamp indicating a specific point in time.

Within the function, it retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

Finally, the function calls the getTotalDue function on the loan term contract, passing the loanID and asOf as parameters. The getTotalDue function calculates and returns the total amount due for the specified loan as of the specified timestamp, which includes the principal amount and any accrued premiums.

In summary, this function allows external callers to retrieve the total amount due for a given loan ID as of a specific timestamp by accessing the loan term contract associated with the loan ID and invoking its getTotalDue function.

function getRemainingLiability(uint256 loanID) external view returns (uint256) { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); return loanTerm.getRemainingLiability(loanID); }

The function getRemainingLiability is defined as an external view function. It takes one parameter: loanID, which represents the ID of a loan.

Within the function, it retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

Finally, the function calls the getRemainingLiability function on the loan term contract, passing the loanID as a parameter. The getRemainingLiability function calculates and returns the remaining liability amount for the specified loan, which represents the outstanding amount that is yet to be repaid.

In summary, this function allows external callers to retrieve the remaining liability amount for a given loan ID by accessing the loan term contract associated with the loan ID and invoking its getRemainingLiability function.

function getPremiumPaymentSchedule(uint256 loanID) external view returns (uint256[] memory, uint256[] memory) { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); (uint256[] memory dueDates, uint256[] memory paymentAmounts) = loanTerm.getPremiumPaymentSchedule(loanID); return (dueDates, paymentAmounts); }

The function getPremiumPaymentSchedule is defined as an external view function. It takes one parameter: loanID, which represents the ID of a loan.

Within the function, it retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

Finally, the function calls the getPremiumPaymentSchedule function on the loan term contract, passing the loanID as a parameter. The getPremiumPaymentSchedule function returns two arrays: dueDates, which contains the due dates for premium payments, and paymentAmounts, which contains the corresponding payment amounts for each due date.

In summary, this function allows external callers to retrieve the premium payment schedule for a given loan ID by accessing the loan term contract associated with the loan ID and invoking its getPremiumPaymentSchedule function. It returns two arrays: dueDates and paymentAmounts, providing information about when premium payments are due and their respective amounts.

function getPrincipalPaymentSchedule(uint256 loanID) external view returns (uint256[] memory, uint256[] memory) { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); (uint256[] memory dueDates, uint256[] memory paymentAmounts) = loanTerm.getPrincipalPaymentSchedule(loanID); return (dueDates, paymentAmounts); }

The function getPrincipalPaymentSchedule is defined as an external view function. It takes one parameter: loanID, which represents the ID of a loan.

Within the function, it retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

Finally, the function calls the getPrincipalPaymentSchedule function on the loan term contract, passing the loanID as a parameter. The getPrincipalPaymentSchedule function returns two arrays: dueDates, which contains the due dates for principal payments, and paymentAmounts, which contains the corresponding payment amounts for each due date.

In summary, this function allows external callers to retrieve the principal payment schedule for a given loan ID by accessing the loan term contract associated with the loan ID and invoking its getPrincipalPaymentSchedule function. It returns two arrays: dueDates and paymentAmounts, providing information about when principal payments are due and their respective amounts.

function getQuote( address borrower, IX7InitialLiquidityLoanTerm loanTerm, uint256 loanAmount, uint256 loanDurationSeconds ) external view returns (uint256[5] memory) { require(loanTerm.minimumLoanAmount() <= loanAmount); require(loanTerm.maximumLoanAmount() >= loanAmount); require(loanTerm.minimumLoanLengthSeconds() <= loanDurationSeconds); require(loanTerm.maximumLoanLengthSeconds() >= loanDurationSeconds); return _getQuote(borrower, loanTerm, loanAmount, loanDurationSeconds); }

The function getQuote is defined as an external view function. It takes four parameters: borrower, which represents the address of the borrower, loanTerm, which is an instance of the IX7InitialLiquidityLoanTerm interface representing the loan term, loanAmount, which is the requested loan amount, and loanDurationSeconds, which is the duration of the loan in seconds.

The function performs several require statements to validate the input parameters. It checks that the loanAmount is within the minimum and maximum loan amount allowed by the loanTerm, and that the loanDurationSeconds is within the minimum and maximum loan duration allowed by the loanTerm. If any of these requirements are not met, the function will revert.

If the input parameters pass the validation, the function calls the internal function _getQuote with the provided parameters. The _getQuote function calculates and returns a quote for the loan based on the borrower, loan term, loan amount, and loan duration.

In summary, the getQuote function allows external callers to retrieve a quote for a loan based on the borrower's address, loan term, loan amount, and loan duration. It performs validation checks and then calls an internal function to calculate and return the quote.

function buyoutLoanQuote(uint256 loanID) external view returns (uint256) { require(allowLoanBuyout); IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); address owner_ = loanTerm.ownerOf(loanID); require(owner_ == address(this)); uint256 buyoutAmount = loanTerm.loanAmount(loanID) - loanTerm.principalAmountPaid(loanID); return buyoutAmount; }

The function buyoutLoanQuote is defined as an external view function. It takes one parameter: loanID, which represents the ID of a loan.

The function starts by checking if loan buyouts are allowed. It does this by using the require statement with the condition allowLoanBuyout. If loan buyouts are not allowed, the function will revert.

Next, the function retrieves the loan term associated with the given loanID from the loanTermLookup mapping. It does this by using loanTermLookup[loanID] to access the address of the loan term contract.

The address of the loan term contract is then cast to the IX7InitialLiquidityLoanTerm interface type, allowing the contract to interact with the loan term contract.

The function proceeds to check if the owner of the loan, obtained through the ownerOf function of the loan term contract, is equal to the contract's address (address(this)). If they are not equal, indicating that the contract does not own the loan, the function will revert.

Finally, the function calculates the buyout amount for the loan by subtracting the principal amount already paid from the total loan amount. It does this by calling the loanAmount and principalAmountPaid functions on the loan term contract.

In summary, the buyoutLoanQuote function allows external callers to retrieve a quote for buying out a loan based on a given loan ID. It performs checks to ensure loan buyouts are allowed, verifies ownership of the loan, and calculates the buyout amount based on the loan amount and principal amount already paid. It returns the buyout amount as a result.

function setEcosystemRecipientAddress(address recipient) external onlyOwner { require(ecosystemRecipient != recipient); address oldRecipient = ecosystemRecipient; ecosystemRecipient = recipient; emit EcosystemRecipientSet(oldRecipient, recipient); }

The function setEcosystemRecipientAddress is defined as an external function. It takes one parameter: recipient, which represents the new address of the ecosystem recipient.

The function starts by checking if the current ecosystem recipient address (ecosystemRecipient) is different from the new recipient address. If they are the same, the function will revert.

If the addresses are different, the function proceeds to update the ecosystem recipient address by assigning the new address to the ecosystemRecipient variable.

Before completing the function, it emits an event EcosystemRecipientSet with the old recipient address (oldRecipient) and the new recipient address (recipient) as the event parameters. This event can be used to track and log the change of the ecosystem recipient address.

In summary, the setEcosystemRecipientAddress function allows the owner of the contract to set a new address for the ecosystem recipient. It verifies that the new address is different from the current one, updates the recipient address, and emits an event to indicate the address change.

function setRouter(address routerAddress) external onlyOwner { require(address(router) != routerAddress); address oldRouter = address(router); router = IXchangeRouter(routerAddress); emit RouterSet(oldRouter, routerAddress); }

The function setRouter is defined as an external function. It takes one parameter: routerAddress, which represents the new address of the router.

The function starts by checking if the current router address (router) is different from the new routerAddress. If they are the same, the function will revert.

If the addresses are different, the function proceeds to update the router address by assigning the new address to the router variable. It does this by creating a new instance of the IXchangeRouter contract, passing the routerAddress as an argument.

Before completing the function, it emits an event RouterSet with the old router address (oldRouter) and the new router address (routerAddress) as the event parameters. This event can be used to track and log the change of the router address.

In summary, the setRouter function allows the owner of the contract to set a new address for the router. It verifies that the new address is different from the current one, updates the router address by creating a new instance of the router contract, and emits an event to indicate the address change.

function setX7D(address X7DAddress) external onlyOwner { require(address(X7D) != X7DAddress); address oldAddress = address(X7D); X7D = IX7D(X7DAddress); emit X7DSet(oldAddress, X7DAddress); }

The function setX7D is defined as an external function. It takes one parameter: X7DAddress, which represents the new address of the X7D contract.

The function starts by checking if the current X7D contract address (X7D) is different from the new X7DAddress. If they are the same, the function will revert.

If the addresses are different, the function proceeds to update the X7D contract address by assigning the new address to the X7D variable. It does this by casting the X7DAddress to the IX7D contract type.

Before completing the function, it emits an event X7DSet with the old X7D contract address (oldAddress) and the new X7D contract address (X7DAddress) as the event parameters. This event can be used to track and log the change of the X7D contract address.

In summary, the setX7D function allows the owner of the contract to set a new address for the X7D contract. It verifies that the new address is different from the current one, updates the X7D contract address by casting the new address, and emits an event to indicate the address change.

function setLoanTermActiveState(address loanTermAddress, bool isActive) external onlyOwner { require(loanTermActive[loanTermAddress] != isActive); loanTermActive[loanTermAddress] = isActive; if (isActive) { activeLoanTerms.push(loanTermAddress); loanTermIndex[loanTermAddress] = activeLoanTerms.length - 1; } else { address otherLoanTermAddress = activeLoanTerms[activeLoanTerms.length-1]; activeLoanTerms[loanTermIndex[loanTermAddress]] = otherLoanTermAddress; loanTermIndex[otherLoanTermAddress] = loanTermIndex[loanTermAddress]; delete loanTermIndex[loanTermAddress]; activeLoanTerms.pop(); } emit LoanTermActiveStateSet(loanTermAddress, isActive); }

The function setLoanTermActiveState is an external function. It is used by the contract owner to set the active state of a loan term.

The function takes two parameters: loanTermAddress, which represents the address of the loan term, and isActive, which indicates whether the loan term should be set as active or not.

The function first checks if the current active state of the loan term (loanTermActive[loanTermAddress]) is different from the desired active state (isActive). If they are the same, the function reverts.

If the active state needs to be updated, the function proceeds to update the loanTermActive mapping with the new active state for the specified loan term.

If isActive is true, indicating that the loan term should be active, the function adds the loan term address to the activeLoanTerms array and updates the loanTermIndex mapping to store the index of the loan term in the array.

If isActive is false, indicating that the loan term should be inactive, the function performs a series of steps to remove the loan term address from the activeLoanTerms array. It replaces the loan term address with the address of the last loan term in the array, updates the index of the last loan term in the loanTermIndex mapping, deletes the index of the current loan term from the mapping, and removes the last element from the activeLoanTerms array.

Finally, the function emits the LoanTermActiveStateSet event with the loan term address and the active state as parameters to indicate the change in the active state of the loan term.

In summary, the setLoanTermActiveState function allows the owner of the contract to activate or deactivate a loan term. It updates the mappings and array accordingly and emits an event to signal the change in the loan term's active state.

function setLiquidationReward(uint256 reward) external onlyOwner { require(liquidationReward != reward); uint256 oldReward = liquidationReward; liquidationReward = reward; emit LiquidationRewardSet(oldReward, reward); }

The function setLiquidationReward is an external function. It is used by the contract owner to set the liquidation reward amount.

The function takes one parameter reward, which represents the new liquidation reward amount to be set.

The function first checks if the current liquidation reward amount (liquidationReward) is different from the new reward amount (reward). If they are the same, the function reverts.

If the reward amount needs to be updated, the function proceeds to update the liquidationReward variable with the new reward amount.

Next, the function emits the LiquidationRewardSet event with the previous reward amount (oldReward) and the new reward amount (reward) as parameters. This event can be used to track and notify any listeners about the change in the liquidation reward.

In summary, the setLiquidationReward function allows the owner of the contract to set the liquidation reward amount. It updates the corresponding variable and emits an event to signal the change in the liquidation reward.

function setOriginationShares( uint256 ecosystemSplitterOriginationShare_, uint256 X7DAOOriginationShare_, uint256 X7100OriginationShare_, uint256 lendingPoolOriginationShare_ ) external onlyOwner { require(ecosystemSplitterOriginationShare_ + X7DAOOriginationShare_ + X7100OriginationShare_ + lendingPoolOriginationShare_ == 10000); uint256 oldEcosystemSplitterOriginationShare = ecosystemSplitterOriginationShare; uint256 oldX7DAOOriginationShare = X7DAOOriginationShare; uint256 oldX7100OriginationShare = X7100OriginationShare; uint256 oldLendingPoolOriginationShare = lendingPoolOriginationShare; ecosystemSplitterOriginationShare = ecosystemSplitterOriginationShare_; X7DAOOriginationShare = X7DAOOriginationShare_; X7100OriginationShare = X7100OriginationShare_; lendingPoolOriginationShare = lendingPoolOriginationShare_; emit OriginationSharesSet( oldEcosystemSplitterOriginationShare, oldX7DAOOriginationShare, oldX7100OriginationShare, oldLendingPoolOriginationShare, ecosystemSplitterOriginationShare_, X7DAOOriginationShare_, X7100OriginationShare_, lendingPoolOriginationShare_ ); }

The function setOriginationShares is an external function. It is used by the contract owner to set the origination shares for different entities.

The function takes four parameters: ecosystemSplitterOriginationShare_, X7DAOOriginationShare_, X7100OriginationShare_, and lendingPoolOriginationShare_. These parameters represent the new origination shares to be set for the ecosystem splitter, X7DAO, X7100, and the lending pool, respectively.

The function first checks if the sum of the new origination shares is equal to 10000 (which represents 100% in basis points). If the sum is not equal to 10000, the function reverts.

If the origination shares need to be updated, the function proceeds to update the corresponding variables (ecosystemSplitterOriginationShare, X7DAOOriginationShare, X7100OriginationShare, and lendingPoolOriginationShare) with the new values.

Next, the function emits the OriginationSharesSet event, providing the previous origination shares (oldEcosystemSplitterOriginationShare, oldX7DAOOriginationShare, oldX7100OriginationShare, and oldLendingPoolOriginationShare) and the new origination shares (ecosystemSplitterOriginationShare_, X7DAOOriginationShare_, X7100OriginationShare_, and lendingPoolOriginationShare_) as parameters. This event can be used to track and notify any listeners about the change in the origination shares.

In summary, the setOriginationShares function allows the owner of the contract to set the origination shares for different entities. It performs validation on the sum of the shares and updates the corresponding variables. Finally, it emits an event to signal the change in the origination shares.

function setPremiumShares( uint256 ecosystemSplitterPremiumShare_, uint256 X7DAOPremiumShare_, uint256 X7100PremiumShare_, uint256 lendingPoolPremiumShare_ ) external onlyOwner { require(ecosystemSplitterPremiumShare_ + X7DAOPremiumShare_ + X7100PremiumShare_ + lendingPoolPremiumShare_ == 10000); uint256 oldEcosystemSplitterPremiumShare = ecosystemSplitterPremiumShare; uint256 oldX7DAOPremiumShare = X7DAOPremiumShare; uint256 oldX7100PremiumShare = X7100PremiumShare; uint256 oldLendingPoolPremiumShare = lendingPoolPremiumShare; ecosystemSplitterPremiumShare = ecosystemSplitterPremiumShare_; X7DAOPremiumShare = X7DAOPremiumShare_; X7100PremiumShare = X7100PremiumShare_; lendingPoolPremiumShare = lendingPoolPremiumShare_; emit PremiumSharesSet( oldEcosystemSplitterPremiumShare, oldX7DAOPremiumShare, oldX7100PremiumShare, oldLendingPoolPremiumShare, ecosystemSplitterPremiumShare_, X7DAOPremiumShare_, X7100PremiumShare_, lendingPoolPremiumShare_ ); }

The function setPremiumShares is an external function. It is used by the contract owner to set the premium shares for different entities.

The function takes four parameters: ecosystemSplitterPremiumShare_, X7DAOPremiumShare_, X7100PremiumShare_, and lendingPoolPremiumShare_. These parameters represent the new premium shares to be set for the ecosystem splitter, X7DAO, X7100, and the lending pool, respectively.

Similar to the setOriginationShares function, the setPremiumShares function first checks if the sum of the new premium shares is equal to 10000 (which represents 100% in basis points). If the sum is not equal to 10000, the function reverts.

If the premium shares need to be updated, the function proceeds to update the corresponding variables (ecosystemSplitterPremiumShare, X7DAOPremiumShare, X7100PremiumShare, and lendingPoolPremiumShare) with the new values.

Next, the function emits the PremiumSharesSet event, providing the previous premium shares (oldEcosystemSplitterPremiumShare, oldX7DAOPremiumShare, oldX7100PremiumShare, and oldLendingPoolPremiumShare) and the new premium shares (ecosystemSplitterPremiumShare_, X7DAOPremiumShare_, X7100PremiumShare_, and lendingPoolPremiumShare_) as parameters. This event can be used to track and notify any listeners about the change in the premium shares.

In summary, the setPremiumShares function allows the owner of the contract to set the premium shares for different entities. It performs validation on the sum of the shares and updates the corresponding variables. Finally, it emits an event to signal the change in the premium shares.

function setEcosystemSplitter(address recipient) external onlyOwner { require(ecosystemSplitter != recipient); address oldEcosystemSplitterAddress = ecosystemSplitter; ecosystemSplitter = recipient; emit EcosystemSplitterSet(oldEcosystemSplitterAddress, recipient); }

The setEcosystemSplitter function is an external function. It is used by the contract owner to set the address of the ecosystem splitter.

The function takes one parameter recipient, which represents the new address of the ecosystem splitter. The function first checks if the current ecosystem splitter address is different from the new recipient address. If they are the same, the function reverts.

If the ecosystem splitter address needs to be updated, the function proceeds to update the ecosystemSplitter variable with the new recipient address.

Next, the function emits the EcosystemSplitterSet event, providing the previous ecosystem splitter address (oldEcosystemSplitterAddress) and the new recipient address as parameters. This event can be used to track and notify any listeners about the change in the ecosystem splitter address.

In summary, the setEcosystemSplitter function allows the owner of the contract to set the address of the ecosystem splitter. It performs a check to ensure that the new address is different from the current one, updates the variable, and emits an event to signal the change in the ecosystem splitter address.

function setX7100ReserveRecipient(address recipient) external onlyOwner { require(X7100ReserveRecipient != recipient); address oldX7100ReserveRecipient = X7100ReserveRecipient; X7100ReserveRecipient = recipient; emit X7100ReserveRecipientSet(oldX7100ReserveRecipient, recipient); }

The setX7100ReserveRecipient function is an external function. It is used by the contract owner to set the address of the X7100 reserve recipient.

The function takes one parameter recipient, which represents the new address of the X7100 reserve recipient. The function first checks if the current X7100 reserve recipient address is different from the new recipient address. If they are the same, the function reverts.

If the X7100 reserve recipient address needs to be updated, the function proceeds to update the X7100ReserveRecipient variable with the new recipient address.

Next, the function emits the X7100ReserveRecipientSet event, providing the previous X7100 reserve recipient address (oldX7100ReserveRecipient) and the new recipient address as parameters. This event can be used to track and notify any listeners about the change in the X7100 reserve recipient address.

In summary, the setX7100ReserveRecipient function allows the owner of the contract to set the address of the X7100 reserve recipient. It performs a check to ensure that the new address is different from the current one, updates the variable, and emits an event to signal the change in the X7100 reserve recipient address.

function setX7DAORewardRecipient(address recipient) external onlyOwner { require(X7DAORewardRecipient != recipient); address oldX7DAORewardRecipient = X7DAORewardRecipient; X7DAORewardRecipient = recipient; emit X7DAORewardRecipientSet(oldX7DAORewardRecipient, recipient); }

The setX7DAORewardRecipient function is an external function. It is used by the contract owner to set the address of the X7DAO reward recipient.

The function takes one parameter recipient, which represents the new address of the X7DAO reward recipient. The function first checks if the current X7DAO reward recipient address is different from the new recipient address. If they are the same, the function reverts.

If the X7DAO reward recipient address needs to be updated, the function proceeds to update the X7DAORewardRecipient variable with the new recipient address.

Next, the function emits the X7DAORewardRecipientSet event, providing the previous X7DAO reward recipient address (oldX7DAORewardRecipient) and the new recipient address as parameters. This event can be used to track and notify any listeners about the change in the X7DAO reward recipient address.

In summary, the setX7DAORewardRecipient function allows the owner of the contract to set the address of the X7DAO reward recipient. It performs a check to ensure that the new address is different from the current one, updates the variable, and emits an event to signal the change in the X7DAO reward recipient address.

function setDiscountAuthority(address discountAuthorityAddress) external onlyOwner { require(address(discountAuthority) != discountAuthorityAddress); address oldDiscountAuthority = address(discountAuthority); discountAuthority = IX7LendingDiscountAuthority(discountAuthorityAddress); emit DiscountAuthoritySet(oldDiscountAuthority, discountAuthorityAddress); }

The setDiscountAuthority function is an external function. It is used by the contract owner to set the address of the discount authority.

The function takes one parameter discountAuthorityAddress, which represents the new address of the discount authority. The function first checks if the current discount authority address is different from the new address. If they are the same, the function reverts.

If the discount authority address needs to be updated, the function proceeds to update the discountAuthority variable with the new address.

Next, the function emits the DiscountAuthoritySet event, providing the previous discount authority address (oldDiscountAuthority) and the new discount authority address as parameters. This event can be used to track and notify any listeners about the change in the discount authority address.

In summary, the setDiscountAuthority function allows the owner of the contract to set the address of the discount authority. It performs a check to ensure that the new address is different from the current one, updates the variable, and emits an event to signal the change in the discount authority address.

function setRetainedFeeNumerator(uint256 numerator) external onlyOwner { require(retainedFeeNumerator != numerator); uint256 oldRetainedFeeNumerator = retainedFeeDenominator; retainedFeeNumerator = numerator; emit RetainedFeeNumeratorSet(oldRetainedFeeNumerator, numerator); }

The setRetainedFeeNumerator function is an external function. It is used by the contract owner to set the numerator value for calculating the retained fee.

The function takes one parameter numerator, which represents the new numerator value. The function first checks if the current numerator value is different from the new value. If they are the same, the function reverts.

If the numerator value needs to be updated, the function proceeds to update the retainedFeeNumerator variable with the new value.

Next, the function emits the RetainedFeeNumeratorSet event, providing the previous numerator value (oldRetainedFeeNumerator) and the new numerator value as parameters. This event can be used to track and notify any listeners about the change in the retained fee numerator value.

In summary, the setRetainedFeeNumerator function allows the owner of the contract to set the numerator value for calculating the retained fee. It performs a check to ensure that the new value is different from the current one, updates the variable, and emits an event to signal the change in the retained fee numerator value.

function setLendingPoolReserve(address reserveAddress) external onlyOwner { require(lendingPoolReserve != reserveAddress); address oldLendingPoolReserve = lendingPoolReserve; lendingPoolReserve = reserveAddress; emit LendingPoolReserveSet(oldLendingPoolReserve, reserveAddress); }

The setLendingPoolReserve function is an external function. It is used by the contract owner to set the address of the lending pool reserve.

The function takes one parameter reserveAddress, which represents the new address of the lending pool reserve. The function first checks if the current lending pool reserve address is different from the new address. If they are the same, the function reverts.

If the lending pool reserve address needs to be updated, the function proceeds to update the lendingPoolReserve variable with the new address.

Next, the function emits the LendingPoolReserveSet event, providing the previous lending pool reserve address (oldLendingPoolReserve) and the new reserve address as parameters. This event can be used to track and notify any listeners about the change in the lending pool reserve address.

In summary, the setLendingPoolReserve function allows the owner of the contract to set the address of the lending pool reserve. It performs a check to ensure that the new address is different from the current one, updates the variable, and emits an event to signal the change in the lending pool reserve address.

function setLendingHalted(bool isHalted) external onlyOwner { require(lendingHalted != isHalted); lendingHalted = isHalted; if (isHalted) { emit LendingHalted(); } else { emit LendingCommenced(); } }

The setLendingHalted function is an external function. It is used by the contract owner to control the lending operations by halting or resuming them.

The function takes one parameter isHalted, which indicates whether lending operations should be halted (true) or resumed (false).

The function first checks if the current lendingHalted state is different from the desired state isHalted. If they are the same, meaning the lending state is already set to the desired state, the function reverts.

If the lending state needs to be updated, the function proceeds to update the lendingHalted variable with the new state.

Next, depending on the new state, the function emits either the LendingHalted event or the LendingCommenced event. These events can be used to notify any listeners or external systems about the change in the lending state.

In summary, the setLendingHalted function allows the owner of the contract to halt or resume lending operations. It performs a check to ensure that the new state is different from the current one, updates the variable, and emits an event to signal the change in the lending state.

function setAllowLoanBuyout(bool isAllowed) external onlyOwner { require(allowLoanBuyout != isAllowed); allowLoanBuyout = isAllowed; emit LoanBuyoutAllowed(isAllowed); }

The setAllowLoanBuyout function is an external function. It is used by the contract owner to control whether loan buyouts are allowed or not.

The function takes one parameter isAllowed, which indicates whether loan buyouts should be allowed (true) or not allowed (false).

The function first checks if the current allowLoanBuyout state is different from the desired state isAllowed. If they are the same, meaning the loan buyout state is already set to the desired state, the function reverts.

If the loan buyout state needs to be updated, the function proceeds to update the allowLoanBuyout variable with the new state.

Next, the function emits the LoanBuyoutAllowed event with the isAllowed value. This event can be used to notify any listeners or external systems about the change in the loan buyout policy.

In summary, the setAllowLoanBuyout function allows the owner of the contract to enable or disable loan buyouts. It performs a check to ensure that the new state is different from the current one, updates the variable, and emits an event to signal the change in the loan buyout policy.

function setAuthorizedCapitalManager(address manager, bool isTrusted) external onlyOwner { require(authorizedCapitalManagers[manager] != isTrusted); authorizedCapitalManagers[manager] = isTrusted; emit AuthorizedCapitalManagerSet(manager, isTrusted); }

The setAuthorizedCapitalManager function is an external function. It is used by the contract owner to authorize or revoke the trust of a capital manager.

The function takes two parameters: manager, which represents the address of the capital manager, and isTrusted, which indicates whether the capital manager should be trusted (true) or not trusted (false).

First, the function checks if the current trust status of the capital manager, stored in the authorizedCapitalManagers mapping, is different from the desired trust status isTrusted. If they are the same, meaning the trust status is already set to the desired value, the function reverts.

If the trust status needs to be updated, the function proceeds to update the authorizedCapitalManagers mapping with the new trust status for the specified capital manager.

Finally, the function emits the AuthorizedCapitalManagerSet event with the manager and isTrusted values. This event can be used to notify any listeners or external systems about the change in trust status for the capital manager.

In summary, the setAuthorizedCapitalManager function allows the owner of the contract to authorize or revoke the trust of a capital manager. It performs a check to ensure that the new trust status is different from the current one, updates the mapping, and emits an event to signal the change in trust status for the capital manager.

function setSyncSafeGasAmount(uint256 amount) external onlyOwner { require(amount != syncSafeGasAmount); uint256 oldSyncSafeGasAmount = syncSafeGasAmount; syncSafeGasAmount = amount; emit SyncSafeGasAmountSet(oldSyncSafeGasAmount, amount); }

The setSyncSafeGasAmount function is an external function. It is used by the contract owner to set the synchronization safe gas amount.

The function takes one parameter: amount, which represents the new synchronization safe gas amount to be set.

First, the function checks if the current synchronization safe gas amount, stored in the syncSafeGasAmount variable, is different from the desired amount. If they are the same, meaning the synchronization safe gas amount is already set to the desired value, the function reverts.

If the synchronization safe gas amount needs to be updated, the function proceeds to update the syncSafeGasAmount variable with the new amount.

Finally, the function emits the SyncSafeGasAmountSet event with the oldSyncSafeGasAmount and amount values. This event can be used to notify any listeners or external systems about the change in the synchronization safe gas amount.

In summary, the setSyncSafeGasAmount function allows the owner of the contract to set the synchronization safe gas amount. It performs a check to ensure that the new amount is different from the current one, updates the variable, and emits an event to signal the change in the synchronization safe gas amount.

function returnETHToLendingPoolReserve(uint256 amount) external { require(authorizedCapitalManagers[msg.sender]); require(amount > address(this).balance); require(lendingPoolReserve != address(0)); X7DMinter(lendingPoolReserve).returnETH{value: amount}(); }

It allows authorized capital managers to return excess ETH to the lending pool reserve.

The function takes one parameter: amount, which represents the amount of ETH to be returned to the lending pool reserve.

First, the function checks if the caller (msg.sender) is an authorized capital manager by verifying that authorizedCapitalManagers[msg.sender] is true. If the caller is not an authorized capital manager, the function reverts.

Next, the function checks if the specified amount is greater than the current balance of ETH held by the contract (address(this).balance). If the amount is not greater, meaning there is no excess ETH to be returned, the function reverts.

The function also checks if the lendingPoolReserve address is not zero. If the lendingPoolReserve is set to the zero address, indicating that it has not been set, the function reverts.

Finally, assuming all the requirements are met, the function calls the returnETH function of the X7DMinter contract deployed at the lendingPoolReserve address. The amount of ETH is transferred to the X7DMinter contract using the value keyword.

In summary, the returnETHToLendingPoolReserve function allows authorized capital managers to return excess ETH to the lending pool reserve. It performs checks on the caller's authorization, the amount of ETH to be returned, and the validity of the lending pool reserve address before transferring the ETH to the X7DMinter contract.

function getInitialLiquidityLoan( address tokenAddress, uint256 amount, address loanTermContract, uint256 loanAmount, uint256 loanDurationSeconds, address liquidityReceiver, uint256 deadline ) external lock payable returns (uint256 loanID) { require(!lendingHalted); loanID = nextLoanID; nextLoanID += 1; require(loanTermActive[loanTermContract]); IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermContract); loanTermLookup[loanID] = loanTermContract; uint256[5] memory quote = _useQuote( loanTerm, loanAmount, loanDurationSeconds ); // Duplicates logic from loan terms uint256 originationFee = quote[1] * quote[4] / 10000 / 1 gwei * 1 gwei; uint256 roundedLoanAmount = quote[0]; address loanOwner; uint256 amountToCollect; if (msg.value >= roundedLoanAmount + originationFee + liquidationReward) { // Case when externally funded loanOwner = msg.sender; amountToCollect = roundedLoanAmount + originationFee + liquidationReward; } else if (msg.value >= originationFee + liquidationReward) { require(address(this).balance - liquidationEscrow >= roundedLoanAmount); loanOwner = address(this); amountToCollect = originationFee + liquidationReward; } else { revert("Insufficient funds provided"); } address pair = _addLiquidity( tokenAddress, amount, roundedLoanAmount, liquidityReceiver, deadline ); loanPair[loanID] = pair; loanToken[loanID] = tokenAddress; loanLiquidationReward[loanID] = liquidationReward; loanLiquidationReturnTo[loanID] = msg.sender; liquidationEscrow += liquidationReward; loanTerm.originateLoan( roundedLoanAmount, originationFee, loanDurationSeconds, quote[3], quote[4], loanOwner, loanID ); loanBorrower[loanID] = msg.sender; loanLookupByBorrower[msg.sender].push(loanID); if ( loanOwner != address(this) ) { uint256 returnToSender = msg.value - amountToCollect; uint256 retainedFee = originationFee * retainedFeeNumerator / retainedFeeDenominator; _splitOriginationFee(retainedFee); returnToSender += (originationFee - retainedFee); if (returnToSender > 0) { (bool success,) = msg.sender.call{value: returnToSender}(""); require(success); } } else { _splitOriginationFee(originationFee); uint256 returnToSender = msg.value - amountToCollect; if (returnToSender > 0) { (bool success,) = msg.sender.call{value: returnToSender}(""); require(success); } } }

The getInitialLiquidityLoan function is a public external function. It allows users to obtain an initial liquidity loan by providing collateral and specified loan parameters.

The function takes several parameters:

  • tokenAddress: The address of the collateral token.
  • amount: The amount of collateral token to be provided.
  • loanTermContract: The address of the loan term contract that defines the terms of the loan.
  • loanAmount: The requested loan amount.
  • loanDurationSeconds: The duration of the loan in seconds.
  • liquidityReceiver: The address where the liquidity will be received.
  • deadline: The deadline for the transaction.

The function performs the following steps:

  1. It checks if lending is halted by verifying that lendingHalted is false. If lending is halted, the function reverts.
  2. It assigns a loan ID to the loan and increments the nextLoanID counter.
  3. It checks if the loan term contract specified is active by verifying that loanTermActive[loanTermContract] is true. If the loan term contract is not active, the function reverts.
  4. It sets the loan term contract for the loan by storing the loanTermContract address in the loanTermLookup mapping using the loan ID as the key.
  5. It calculates the origination fee and the rounded loan amount based on the quote obtained from the loan term contract.
  6. It determines the loan owner and the amount to collect based on the value of ETH sent with the transaction. If the value is sufficient, the loan owner is set to the sender (msg.sender), and the amount to collect includes the rounded loan amount, origination fee, and liquidation reward. If the value is not sufficient, the function reverts with an "Insufficient funds provided" error.
  7. It adds liquidity by calling the _addLiquidity function with the collateral token address, collateral amount, rounded loan amount, liquidity receiver, and deadline. The _addLiquidity function returns the address of the newly created liquidity pair.
  8. It assigns the liquidity pair address and collateral token address to the loan ID in the loanPair and loanToken mappings, respectively.
  9. It sets the liquidation reward and the return-to address for the loan in the loanLiquidationReward and loanLiquidationReturnTo mappings, respectively. The liquidation reward is also added to the liquidationEscrow counter.
  10. It calls the originateLoan function of the loan term contract to create the loan with the specified parameters.
  11. It sets the borrower of the loan by assigning msg.sender to the loanBorrower mapping using the loan ID as the key. It also adds the loan ID to the borrower's loan lookup list in the loanLookupByBorrower mapping.
  12. If the loan owner is not the contract itself, it splits the origination fee by calling the _splitOriginationFee function with the retained fee calculated based on the retainedFeeNumerator and retainedFeeDenominator parameters. Any excess ETH sent with the transaction is returned to the sender.
  13. If the loan owner is the contract itself, it splits the origination fee and returns any excess ETH to the sender.

Overall, the getInitialLiquidityLoan function facilitates the process of obtaining an initial liquidity loan by performing various calculations, interacting with the loan term contract, adding liquidity, and managing funds.

function payLiability(uint256 loanID) external lock payable { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); address owner_ = loanTerm.ownerOf(loanID); if (loanTerm.isComplete(loanID) && msg.value > 0) { (bool success,) = msg.sender.call{value: msg.value}(""); require(success); return; } (uint256 premiumPaid, uint256 principalPaid, uint256 refundAmount, uint256 remainingLiability) = loanTerm.recordPayment( loanID, msg.value ); if (owner_ != address(this)) { uint256 toPayOwner = principalPaid; uint256 retainedFee = premiumPaid * retainedFeeNumerator / retainedFeeDenominator; _splitPremiumFee(retainedFee); toPayOwner += premiumPaid - retainedFee; if (toPayOwner > 0) { // Gas limit imposed to prevent owner griefing repayment // Failure is ignored and considered a donation to lending pool owner_.call{gas: 10000, value: toPayOwner}(""); } } else { if (premiumPaid > 0) { _splitPremiumFee(premiumPaid); } } if (refundAmount > 0) { (bool success, ) = msg.sender.call{value: refundAmount}(""); require(success); } IXchangePair pair = IXchangePair(loanPair[loanID]); uint256 remainingLockedCapital = pair.tokenMinimumBalance(weth); if (remainingLiability < remainingLockedCapital) { pair.setMinimumBalance(weth, uint112(remainingLiability)); } if (remainingLiability == 0) { _payLiquidationFee(loanID, loanLiquidationReturnTo[loanID]); _removeLoanFromIndex(loanID); } }

The payLiability function is a public external function in a contract. It allows users to make payments towards a specific loan liability.

The function takes one parameter:

  • loanID: The ID of the loan for which the liability payment is being made.

The function performs the following steps:

  1. It retrieves the loan term contract associated with the loan ID from the loanTermLookup mapping and assigns it to the loanTerm variable.
  2. It retrieves the owner of the loan using the loan term contract's ownerOf function and assigns it to the owner_ variable.
  3. If the loan is complete (based on the loan term contract's isComplete function) and the value of ETH sent with the transaction is greater than 0, it forwards the ETH payment to the sender and returns from the function.
  4. It calls the loan term contract's recordPayment function to record the payment and obtain the amounts of premium paid, principal paid, refund amount, and remaining liability.
  5. If the owner of the loan is not the contract itself, it calculates the amount to pay the owner (toPayOwner) by adding the principal paid and deducting the retained fee calculated based on the retainedFeeNumerator and retainedFeeDenominator parameters.
  6. If toPayOwner is greater than 0, it attempts to transfer the ETH payment to the loan owner using the call function with a gas limit of 10000. Failure of the transfer is ignored, considering it as a donation to the lending pool.
  7. If the owner of the loan is the contract itself and the premium paid is greater than 0, it splits the premium fee by calling the _splitPremiumFee function.
  8. If the refund amount is greater than 0, it transfers the refund amount of ETH to the sender.
  9. It retrieves the loan pair contract associated with the loan ID from the loanPair mapping and assigns it to the pair variable.
  10. It retrieves the remaining locked capital (minimum balance) for the WETH token in the loan pair using the tokenMinimumBalance function and assigns it to the remainingLockedCapital variable.
  11. If the remaining liability is less than the remaining locked capital, it updates the minimum balance for the WETH token in the loan pair to the remaining liability.
  12. If the remaining liability is 0, it pays the liquidation fee by calling the _payLiquidationFee function and removes the loan from the loan index by calling the _removeLoanFromIndex function.

Overall, the payLiability function allows users to make payments towards their loan liabilities, handles the distribution of payments to the loan owner and the lending pool, manages refunds, and adjusts the minimum balance of the WETH token in the loan pair.

function liquidate(uint256 loanID) external lock { IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); address owner_ = loanTerm.ownerOf(loanID); uint256 amountToLiquidate = loanTerm.liquidationAmount( loanID ); require(amountToLiquidate > 0); IXchangePair pair = IXchangePair(loanPair[loanID]); uint256 withdrawnTokens = pair.withdrawTokensAgainstMinimumBalance(weth, address(this), uint112(amountToLiquidate)); // Try to sync the pair. If the paired token is malicious or broken it will not prevent a withdrawal. try pair.syncSafe(syncSafeGasAmount, syncSafeGasAmount) {} catch {} uint256 remainingLockedTokens = pair.tokenMinimumBalance(weth); IWETH(weth).withdraw(withdrawnTokens); (uint256 premiumPaid, uint256 principalPaid, uint256 excessAmount, uint256 remainingLiability) = loanTerm.recordPrincipalRepayment(loanID, withdrawnTokens); if (principalPaid > 0 && owner_ != address(this)) { // Gas limit imposed to prevent owner griefing repayment // Failure is ignored and considered a donation to lending pool owner_.call{gas: 10000, value: principalPaid}(""); } if (premiumPaid > 0) { _splitPremiumFee(premiumPaid); } if (remainingLiability == 0 || remainingLockedTokens == 0) { _payLiquidationFee(loanID, msg.sender); } if (remainingLiability == 0) { _removeLoanFromIndex(loanID); } if (excessAmount > 0) { X7D.mint(ecosystemRecipient, excessAmount); } }

The liquidate function is a public external function in a contract. It allows the liquidation of a loan by transferring tokens from the loan pair contract to the liquidator and performing necessary calculations and actions.

The function takes one parameter:

  • loanID: The ID of the loan to be liquidated.

The function performs the following steps:

  1. It retrieves the loan term contract associated with the loan ID from the loanTermLookup mapping and assigns it to the loanTerm variable.
  2. It retrieves the owner of the loan using the loan term contract's ownerOf function and assigns it to the owner_ variable.
  3. It calls the loan term contract's liquidationAmount function to determine the amount of tokens to be liquidated and assigns it to the amountToLiquidate variable. It then checks if the amountToLiquidate is greater than 0.
  4. It retrieves the loan pair contract associated with the loan ID from the loanPair mapping and assigns it to the pair variable.
  5. It calls the loan pair contract's withdrawTokensAgainstMinimumBalance function to withdraw the specified amount of tokens (WETH) against the minimum balance and transfers them to the contract itself.
  6. It attempts to sync the pair by calling the syncSafe function with the syncSafeGasAmount as the gas limit. If an exception occurs during the sync, it is caught and ignored.
  7. It retrieves the remaining locked tokens (minimum balance) for the WETH token in the loan pair using the tokenMinimumBalance function and assigns it to the remainingLockedTokens variable.
  8. It calls the withdraw function of the WETH contract (IWETH) to convert the withdrawn WETH tokens back to ETH and transfers them to the contract itself.
  9. It calls the loan term contract's recordPrincipalRepayment function to record the principal repayment and obtain the amounts of premium paid, principal paid, excess amount, and remaining liability.
  10. If principalPaid is greater than 0 and the owner of the loan is not the contract itself, it attempts to transfer the ETH payment to the loan owner using the call function with a gas limit of 10000. Failure of the transfer is ignored, considering it as a donation to the lending pool.
  11. If premiumPaid is greater than 0, it splits the premium fee by calling the _splitPremiumFee function.
  12. If remainingLiability is 0 or remainingLockedTokens is 0, it pays the liquidation fee by calling the _payLiquidationFee function with the msg.sender as the recipient.
  13. If remainingLiability is 0, it removes the loan from the loan index by calling the _removeLoanFromIndex function.
  14. If excessAmount is greater than 0, it mints the excess amount of tokens to the ecosystemRecipient.

Overall, the liquidate function facilitates the liquidation process by transferring tokens from the loan pair to the liquidator, performing necessary calculations and actions, and handling the payment of fees and remaining liabilities.

function buyoutLoan(uint256 loanID) external payable { _buyoutLoan(loanID, msg.sender); }

The buyoutLoan function is a public external function that allows a user to buy out a loan by making a payment. It simply calls the internal _buyoutLoan function with the provided loanID and msg.sender as arguments.

The function takes one parameter:

  • loanID: The ID of the loan to be bought out.

The function performs the following step:

  1. It calls the internal _buyoutLoan function with the loanID and msg.sender as arguments.
function buyoutLoanTo(uint256 loanID, address to) external payable { _buyoutLoan(loanID, to); }

The buyoutLoanTo function is a public external function that allows a user to buy out a loan and transfer the ownership to a specified address. It calls the internal _buyoutLoan function with the provided loanID and to address as arguments.

The function takes two parameters:

  • loanID: The ID of the loan to be bought out.
  • to: The address to which the ownership of the loan will be transferred.

The function performs the following step:

  1. It calls the internal _buyoutLoan function with the loanID and to address as arguments.
function depositETH() external payable { X7D.mint(msg.sender, msg.value); }

The depositETH function is a public external function that allows users to deposit Ether (ETH) into the contract. The deposited ETH is then converted into an equivalent amount of a token called X7D, which is minted and transferred to the sender's address.

The function does not take any parameters and relies on the msg.value property to determine the amount of ETH being deposited.

The function performs the following steps:

  1. It calls the X7D.mint function to mint a corresponding amount of X7D tokens for the sender's address.
  • The msg.sender is the address of the user who called the depositETH function.
  • The msg.value is the amount of ETH sent with the function call, which represents the deposit amount.
  • The X7D.mint function is assumed to be a minting function in the X7D token contract, which creates new tokens and assigns them to the specified address.
function depositETHForRecipient(address recipient) external payable { X7D.mint(recipient, msg.value); }

The depositETH function is a public external function that allows users to deposit Ether (ETH) into the contract. The deposited ETH is then converted into an equivalent amount of a token called X7D, which is minted and transferred to the sender's address.

The function does not take any parameters and relies on the msg.value property to determine the amount of ETH being deposited.

The function performs the following steps:

  1. It calls the X7D.mint function to mint a corresponding amount of X7D tokens for the sender's address.
  • The msg.sender is the address of the user who called the depositETH function.
  • The msg.value is the amount of ETH sent with the function call, which represents the deposit amount.
  • The X7D.mint function is assumed to be a minting function in the X7D token contract, which creates new tokens and assigns them to the specified address.
function returnETH() external payable { emit FundsReturned(msg.sender, msg.value); }

The returnETH function is a public external function in a contract that emits a FundsReturned event when called. The function does not perform any operations other than emitting the event.

The function takes no parameters and relies on the msg.sender and msg.value properties to capture the address of the caller and the amount of ETH sent with the function call, respectively.

Breakdown of what the function does:

  1. It emits a FundsReturned event using the emit keyword.
  • The event is named FundsReturned and is assumed to be defined elsewhere in the contract.
  • The msg.sender property represents the address of the caller who invoked the returnETH function.
  • The msg.value property represents the amount of ETH sent with the function call.

The purpose of emitting the FundsReturned event is to notify or log the fact that funds were returned by the contract. The handling and interpretation of this event would depend on the contract's design and the intentions of the contract's users or external systems interacting with it.

function _buyoutLoan(uint256 loanID, address to) internal { require(allowLoanBuyout); IX7InitialLiquidityLoanTerm loanTerm = IX7InitialLiquidityLoanTerm(loanTermLookup[loanID]); address owner_ = loanTerm.ownerOf(loanID); require(owner_ == address(this)); uint256 buyoutAmount = loanTerm.loanAmount(loanID) - loanTerm.principalAmountPaid(loanID); require(buyoutAmount == msg.value); loanTerm.transferFrom(address(this), to, loanID); emit LoanBoughtOut(to, loanID); }

The _buyoutLoan function is an internal function that facilitates the buyout of a loan. It performs several validations and transfers the ownership of the loan to the specified address.

Breakdown of what the function does:

  1. It checks the value of the allowLoanBuyout variable using the require statement to ensure that loan buyouts are allowed in the contract.
  2. It obtains a reference to the IX7InitialLiquidityLoanTerm contract associated with the given loanID by using loanTermLookup[loanID] and casting it to the interface type.
  3. It retrieves the current owner of the loan using the ownerOf function from the loan term contract and assigns it to the owner_ variable.
  4. It checks that the current owner of the loan is the contract itself (address(this)) using the require statement. This ensures that the contract is the current owner and is eligible to perform the buyout.
  5. It calculates the buyout amount by subtracting the principal amount paid from the total loan amount. The function verifies that the buyoutAmount is equal to the value of ETH sent with the function call using the require statement.
  6. It transfers the ownership of the loan from the contract (address(this)) to the specified address to using the transferFrom function of the loan term contract.
  7. It emits a LoanBoughtOut event using the emit keyword to notify interested parties that the loan has been bought out. The event includes the to address and the loanID.

The function assumes that the loanTermLookup mapping and the LoanBoughtOut event are defined elsewhere in the contract.

Note that since the function is marked as internal, it can only be called from within the contract or from internal functions of derived contracts.

function _removeLoanFromIndex(uint256 loanID) internal { address borrower = loanBorrower[loanID]; uint256 loanIndex = loanBorrowerIndex[loanID]; uint256 length = loanLookupByBorrower[borrower].length; uint256 lastLoanID = loanLookupByBorrower[borrower][length-1]; loanLookupByBorrower[borrower][loanIndex] = lastLoanID; loanBorrowerIndex[lastLoanID] = loanIndex; loanLookupByBorrower[borrower].pop(); delete loanBorrowerIndex[loanID]; }

The _removeLoanFromIndex function is an internal function that removes a loan from the loan index maintained by the contract. It updates the necessary mappings and arrays to ensure the consistency of the loan index.

Breakdown of what the function does:

  1. It retrieves the borrower address associated with the given loanID from the loanBorrower mapping and assigns it to the borrower variable.
  2. It retrieves the index of the loan within the loanLookupByBorrower[borrower] array using the loanBorrowerIndex mapping and assigns it to the loanIndex variable.
  3. It retrieves the length of the loanLookupByBorrower[borrower] array and assigns it to the length variable.
  4. It retrieves the loanID stored at the last position of the loanLookupByBorrower[borrower] array and assigns it to the lastLoanID variable.
  5. It updates the loanLookupByBorrower[borrower] array by replacing the loanID at loanIndex with the lastLoanID.
  6. It updates the loanBorrowerIndex mapping by updating the index of the lastLoanID to loanIndex.
  7. It removes the last element from the loanLookupByBorrower[borrower] array using the pop() function.
  8. It deletes the loanBorrowerIndex entry for the given loanID using the delete keyword.

The function assumes that the loanBorrower, loanBorrowerIndex, and loanLookupByBorrower mappings are defined elsewhere in the contract.

Note that since the function is marked as internal, it can only be called from within the contract or from internal functions of derived contracts.

function _getQuote( address borrower, IX7InitialLiquidityLoanTerm loanTerm, uint256 loanAmount, uint256 loanDurationSeconds ) internal view returns (uint256[5] memory) { uint256 roundedLoanAmount; uint256 originationFee; uint256 totalPremium; uint256 premiumFeeModifier; uint256 originationFeeModifier; (roundedLoanAmount, originationFee, totalPremium) = loanTerm.getQuote(loanAmount); (premiumFeeModifier, originationFeeModifier) = discountAuthority.getFeeModifiers( borrower, [loanTerm.minimumLoanAmount(), roundedLoanAmount, loanTerm.maximumLoanAmount()], [loanTerm.minimumLoanLengthSeconds(), loanDurationSeconds, loanTerm.maximumLoanLengthSeconds()] ); return [ roundedLoanAmount, originationFee, totalPremium, premiumFeeModifier, originationFeeModifier ]; }

The _getQuote function is an internal view function that calculates the loan quote for a given borrower, loan term contract, loan amount, and loan duration. It uses the loanTerm contract and the discountAuthority contract to determine the rounded loan amount, origination fee, total premium, premium fee modifier, and origination fee modifier.

Breakdown of what the function does:

  1. It declares local variables roundedLoanAmount, originationFee, totalPremium, premiumFeeModifier, and originationFeeModifier to store the calculated values.
  2. It calls the getQuote function of the loanTerm contract, passing the loanAmount as an argument. This function returns the rounded loan amount, origination fee, and total premium, which are assigned to their respective variables.
  3. It calls the getFeeModifiers function of the discountAuthority contract, passing the borrower address and two arrays as arguments. The first array contains the minimum loan amount, rounded loan amount, and maximum loan amount, and the second array contains the minimum loan duration, loan duration, and maximum loan duration. This function returns the premium fee modifier and origination fee modifier, which are assigned to their respective variables.
  4. It constructs and returns an array with the calculated values: [roundedLoanAmount, originationFee, totalPremium, premiumFeeModifier, originationFeeModifier].
function _getDiscountedQuote( address borrower, IX7InitialLiquidityLoanTerm loanTerm, uint256 loanAmount, uint256 loanDurationSeconds ) internal view returns ( uint256[7] memory discountedQuote // roundedLoanAmount // originationFee // totalPremium // discountedOriginationFee // discountedTotalPremium // premiumFeeModifier // originationFeeModifier ) { uint256 ret1; uint256 ret2; uint256 ret3; // roundedLoanAmount, originationFee, totalPremium (ret1, ret2, ret3) = loanTerm.getQuote(loanAmount); discountedQuote[0] = ret1; // roundedLoanAmount discountedQuote[1] = ret2; // originationFee discountedQuote[2] = ret3; // totalPremium // premiumFeeModifier, originationFeeModifier (ret1, ret2) = discountAuthority.getFeeModifiers( borrower, [loanTerm.minimumLoanAmount(), ret1, loanTerm.maximumLoanAmount()], [loanTerm.minimumLoanLengthSeconds(), loanDurationSeconds, loanTerm.maximumLoanLengthSeconds()] ); discountedQuote[5] = ret1; discountedQuote[6] = ret2; // roundedLoanAmount, discountedOriginationFee, discountedTotalPremium (ret1, ret2, ret3) = loanTerm.getDiscountedQuote(loanAmount, ret1, ret2); discountedQuote[3] = ret2; discountedQuote[4] = ret3; return discountedQuote; }

The _getDiscountedQuote function is an internal view function that calculates the discounted loan quote for a given borrower, loan term contract, loan amount, and loan duration. It uses the loanTerm contract and the discountAuthority contract to determine the rounded loan amount, origination fee, total premium, discounted origination fee, discounted total premium, premium fee modifier, and origination fee modifier.

Breakdown of what the function does:

  1. It declares a local array discountedQuote with a length of 7 to store the calculated values.
  2. It declares local variables ret1, ret2, and ret3 to store temporary return values from function calls.
  3. It calls the getQuote function of the loanTerm contract, passing the loanAmount as an argument. This function returns the rounded loan amount, origination fee, and total premium, which are assigned to ret1, ret2, and ret3, respectively. These values are then assigned to the corresponding indices in the discountedQuote array.
  4. It calls the getFeeModifiers function of the discountAuthority contract, passing the borrower address and two arrays as arguments. The first array contains the minimum loan amount, rounded loan amount, and maximum loan amount, and the second array contains the minimum loan duration, loan duration, and maximum loan duration. This function returns the premium fee modifier and origination fee modifier, which are assigned to ret1 and ret2, respectively. These values are then assigned to the corresponding indices in the discountedQuote array.
  5. It calls the getDiscountedQuote function of the loanTerm contract, passing the loan amount, premium fee modifier, and origination fee modifier as arguments. This function returns the rounded loan amount, discounted origination fee, and discounted total premium, which are assigned to ret1, ret2, and ret3, respectively. These values are then assigned to the corresponding indices in the discountedQuote array.
  6. It returns the discountedQuote array containing the calculated values.
function _useQuote( IX7InitialLiquidityLoanTerm loanTerm, uint256 loanAmount, uint256 loanDurationSeconds ) internal returns (uint256[5] memory) { uint256 roundedLoanAmount; uint256 originationFee; uint256 totalPremium; uint256 premiumFeeModifier; uint256 originationFeeModifier; (roundedLoanAmount, originationFee) = loanTerm.getOriginationAmounts(loanAmount); (premiumFeeModifier, originationFeeModifier) = discountAuthority.useFeeModifiers( msg.sender, [loanTerm.minimumLoanAmount(), roundedLoanAmount, loanTerm.maximumLoanAmount()], [loanTerm.minimumLoanLengthSeconds(), loanDurationSeconds, loanTerm.maximumLoanLengthSeconds()] ); return [ roundedLoanAmount, originationFee, totalPremium, premiumFeeModifier, originationFeeModifier ]; }

The _useQuote function is an internal function that calculates and applies a loan quote for a given loan term contract, loan amount, and loan duration. It uses the loanTerm contract and the discountAuthority contract to determine the rounded loan amount, origination fee, premium fee modifier, and origination fee modifier.

Breakdown of what the function does:

  1. It declares local variables roundedLoanAmount, originationFee, totalPremium, premiumFeeModifier, and originationFeeModifier.
  2. It calls the getOriginationAmounts function of the loanTerm contract, passing the loanAmount as an argument. This function returns the rounded loan amount and origination fee, which are assigned to roundedLoanAmount and originationFee, respectively.
  3. It calls the useFeeModifiers function of the discountAuthority contract, passing msg.sender (the caller's address) and two arrays as arguments. The first array contains the minimum loan amount, rounded loan amount, and maximum loan amount, and the second array contains the minimum loan duration, loan duration, and maximum loan duration. This function returns the premium fee modifier and origination fee modifier, which are assigned to premiumFeeModifier and originationFeeModifier, respectively.
  4. It returns an array with the calculated values [roundedLoanAmount, originationFee, totalPremium, premiumFeeModifier, originationFeeModifier].
function _splitOriginationFee(uint256 amount) internal { uint256 ecosystemSplitterAmount = amount * ecosystemSplitterOriginationShare / 10000; uint256 X7100LiquidityAmount = amount * X7100OriginationShare / 10000; uint256 X7DAOAmount = amount * X7DAOOriginationShare / 10000; uint256 lendingPoolAmount = amount - ecosystemSplitterAmount - X7100LiquidityAmount - X7DAOAmount; bool success; if (ecosystemSplitterAmount > 0) { (success, ) = ecosystemSplitter.call{value: ecosystemSplitterAmount}(""); require(success); } if (X7100LiquidityAmount > 0) { (success, ) = X7100ReserveRecipient.call{value: X7100LiquidityAmount}(""); require(success); } if (X7DAOAmount > 0) { (success,) = X7DAORewardRecipient.call{value: X7DAOAmount}(""); require(success); } if (lendingPoolAmount > 0) { X7D.mint(ecosystemRecipient, lendingPoolAmount); } }

The _splitOriginationFee function is an internal function that splits the origination fee into different portions and distributes them to various recipients. The function takes an amount as input, representing the total origination fee to be split.

Here's a breakdown of what the function does:

  1. It declares local variables ecosystemSplitterAmount, X7100LiquidityAmount, X7DAOAmount, and lendingPoolAmount to hold the calculated amounts for each recipient.
  2. It calculates the amounts for each recipient by multiplying the amount by the corresponding share and dividing by 10000 (since the share values are specified as percentages).
  3. It declares a success boolean variable.
  4. If ecosystemSplitterAmount is greater than 0, it calls the ecosystemSplitter address with the corresponding amount using the call function and transfers the funds. It checks the success of the transfer and reverts if it fails.
  5. If X7100LiquidityAmount is greater than 0, it calls the X7100ReserveRecipient address with the corresponding amount using the call function and transfers the funds. It checks the success of the transfer and reverts if it fails.
  6. If X7DAOAmount is greater than 0, it calls the X7DAORewardRecipient address with the corresponding amount using the call function and transfers the funds. It checks the success of the transfer and reverts if it fails.
  7. If lendingPoolAmount is greater than 0, it mints lendingPoolAmount of X7D tokens to the ecosystemRecipient.
  8. The function completes.

The success of the transfers is checked, and the function reverts if any transfer fails.

function _splitPremiumFee(uint256 amount) internal { uint256 ecosystemSplitterAmount = amount * ecosystemSplitterPremiumShare / 10000; uint256 X7100Amount = amount * X7100PremiumShare / 10000; uint256 X7DAOAmount = amount * X7DAOPremiumShare / 10000; uint256 lendingPoolAmount = amount - ecosystemSplitterAmount - X7100Amount - X7DAOAmount; bool success; if (ecosystemSplitterAmount > 0) { (success,) = ecosystemSplitter.call{value: ecosystemSplitterAmount}(""); require(success); } if (X7100Amount > 0) { (success,) = X7100ReserveRecipient.call{value: X7100Amount}(""); require(success); } if (X7DAOAmount > 0) { (success,) = X7DAORewardRecipient.call{value: X7DAOAmount}(""); require(success); } if (lendingPoolAmount > 0) { X7D.mint(ecosystemRecipient, lendingPoolAmount); } }

The _splitPremiumFee function is an internal function that splits the premium fee into different portions and distributes them to various recipients. The function takes an amount as input, representing the total premium fee to be split.

Here's a breakdown of what the function does:

  1. It declares local variables ecosystemSplitterAmount, X7100Amount, X7DAOAmount, and lendingPoolAmount to hold the calculated amounts for each recipient.
  2. It calculates the amounts for each recipient by multiplying the amount by the corresponding share and dividing by 10000 (since the share values are specified as percentages).
  3. It declares a success boolean variable.
  4. If ecosystemSplitterAmount is greater than 0, it calls the ecosystemSplitter address with the corresponding amount using the call function and transfers the funds. It checks the success of the transfer and reverts if it fails.
  5. If X7100Amount is greater than 0, it calls the X7100ReserveRecipient address with the corresponding amount using the call function and transfers the funds. It checks the success of the transfer and reverts if it fails.
  6. If X7DAOAmount is greater than 0, it calls the X7DAORewardRecipient address with the corresponding amount using the call function and transfers the funds. It checks the success of the transfer and reverts if it fails.
  7. If lendingPoolAmount is greater than 0, it mints lendingPoolAmount of X7D tokens to the ecosystemRecipient.
  8. The function completes.

The success of the transfers is checked, and the function reverts if any transfer fails.

function _payLiquidationFee(uint256 loanID, address recipient) internal { uint256 amount = loanLiquidationReward[loanID]; if (amount == 0) { return; } // Ensures liquidation reward is only ever paid out once loanLiquidationReward[loanID] = 0; (bool success,) = recipient.call{value: amount}(""); require(success); liquidationEscrow -= amount; }

The _payLiquidationFee function is an internal function used to pay the liquidation fee to a specified recipient. The function takes two parameters: loanID, which represents the ID of the loan being liquidated, and recipient, which is the address of the recipient who will receive the liquidation fee.

Breakdown of what the function does:

  1. It retrieves the liquidation fee amount from the loanLiquidationReward mapping using the loanID as the key and assigns it to the amount variable.
  2. If the amount is equal to 0, indicating that there is no liquidation fee to be paid, the function returns without performing any further actions.
  3. To ensure that the liquidation fee is only paid out once, the function sets the loanLiquidationReward for the specified loanID to 0.
  4. It attempts to transfer the amount of funds to the recipient address using the call function.
  5. The success of the transfer is checked, and if the transfer fails, the function reverts.
  6. If the transfer is successful, the liquidationEscrow variable is decreased by the amount to account for the paid liquidation fee.
  7. The function completes.

The success of the transfer is checked, and the function reverts if the transfer fails.

function _addLiquidity( address tokenAddress, uint256 amount, uint256 roundedLoanAmount, address liquidityTokenReceiver, uint256 timestamp ) internal returns (address) { IXchangeFactory factory = IXchangeFactory(router.factory()); address pairAddress = factory.getPair(tokenAddress, router.WETH()); IXchangePair pair; if (pairAddress != address(0)) { pair = IXchangePair(pairAddress); (uint112 reserve0, uint112 reserve1,) = pair.getReserves(); require(reserve0 == 0 && reserve1 == 0); } else { pairAddress = factory.createPair(tokenAddress, router.WETH()); pair = IXchangePair(pairAddress); } pair.setMinimumBalance( weth, uint112(roundedLoanAmount) ); TransferHelper.safeTransferFrom(tokenAddress, msg.sender, address(this), amount); TransferHelper.safeApprove(tokenAddress, address(router), amount); router.addLiquidityETH{value: roundedLoanAmount}( tokenAddress, amount, 0, 0, liquidityTokenReceiver, timestamp ); return address(pair); } }

The _addLiquidity function is an internal function used to add liquidity to a token pair in a decentralized exchange (DEX) such as Uniswap. The function takes several parameters:

  • tokenAddress: The address of the token being added to liquidity.
  • amount: The amount of the token being added to liquidity.
  • roundedLoanAmount: The rounded loan amount used as the minimum balance requirement in the DEX pair.
  • liquidityTokenReceiver: The address that will receive the liquidity tokens minted in the DEX pair.
  • timestamp: The timestamp used for the liquidity provision transaction.

Breakdown of what the function does:

  1. It gets the DEX factory address using the router contract (router.factory()) and initializes a IXchangeFactory instance.
  2. It calls the getPair function on the factory to check if a pair exists for the token and WETH (wrapped Ether). If a pair exists (pairAddress != address(0)), it verifies that the reserves of the pair are empty to ensure it's a new pair. If the pair doesn't exist, it creates a new pair using the createPair function.
  3. It initializes a IXchangePair instance with the pair address obtained in the previous step.
  4. It sets the minimum balance requirement for the WETH token in the DEX pair to roundedLoanAmount using the setMinimumBalance function.
  5. It transfers the amount of tokens from the msg.sender to the contract address using the safeTransferFrom function from the TransferHelper library.
  6. It approves the router address to spend the transferred tokens by calling the safeApprove function from the TransferHelper library.
  7. It adds liquidity to the DEX pair using the addLiquidityETH function of the router contract. This function wraps the specified amount of tokens into WETH and adds them as liquidity alongside ETH.
  8. It returns the address of the DEX pair.
library TransferHelper { function safeApprove(address token, address to, uint value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransferFrom(address token, address from, address to, uint value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } }

The code snippet you provided is an implementation of the TransferHelper library. This library contains two internal functions: safeApprove and safeTransferFrom. These functions are designed to safely interact with ERC20 tokens by using the call method and checking the success status of the calls.

Here's a brief explanation of each function:

safeApprove: This function is used to approve a spender to spend a specific amount of tokens on behalf of the owner. It takes the following parameters:

  • token: The address of the ERC20 token contract.
  • to: The address of the spender to be approved.
  • value: The amount of tokens to approve.

The function calls the approve function on the token contract by using the token.call method with the encoded function selector (0x095ea7b3). It checks the success status of the call and the decoded return data to ensure the approval was successful. If the call fails or the return data indicates a failure, it reverts the transaction with an error message.

safeTransferFrom: This function is used to transfer tokens from one address to another. It takes the following parameters:

  • token: The address of the ERC20 token contract.
  • from: The address from which the tokens will be transferred.
  • to: The address to which the tokens will be transferred.
  • value: The amount of tokens to transfer.

The function calls the transferFrom function on the token contract by using the token.call method with the encoded function selector (0x23b872dd). It checks the success status of the call and the decoded return data to ensure the transfer was successful. If the call fails or the return data indicates a failure, it reverts the transaction with an error message.

Both functions use the low-level call method to interact with the token contract, allowing them to handle tokens that may not conform to the standard ERC20 interface or have custom behavior.

Previous
← X7 Liquidity Loan Terms
Next
X7 Lending Pool Reserve →

-

  • Pioneer 1488 avatar
    Guides
    View
  • Pioneer 1488 avatar
    Integration
    View
  • Pioneer 1488 avatar
    Whitepaper
    View
  • Pioneer 1488 avatar
    Breakdowns
    View
  • Pioneer 1488 avatar
    Onchains
    View
  • Pioneer 1488 avatar
    FAQ
    View