Skip to content

Latest commit

 

History

History
539 lines (463 loc) · 17.9 KB

LoanClosingsWith.md

File metadata and controls

539 lines (463 loc) · 17.9 KB

LoanClosingsWith contract. (LoanClosingsWith.sol)

View Source: contracts/modules/LoanClosingsWith.sol

↗ Extends: LoanClosingsShared

LoanClosingsWith contract

Close a loan w/deposit, close w/swap. There are 2 functions for ending a loan on the protocol contract: closeWithSwap and closeWithDeposit. Margin trade positions are always closed with a swap.

  • Loans are liquidated if the position goes below margin maintenance.

Functions


constructor

function () public nonpayable
Source Code
constructor() public {}

constructor

function () external nonpayable
Source Code
function() external {
        revert("fallback not allowed");
    }

initialize

function initialize(address target) external nonpayable onlyOwner 

Arguments

Name Type Description
target address
Source Code
function initialize(address target) external onlyOwner {
        address prevModuleContractAddress = logicTargets[this.closeWithDeposit.selector];
        _setTarget(this.closeWithDeposit.selector, target);
        _setTarget(this.closeWithSwap.selector, target);
        _setTarget(this.checkCloseWithDepositIsTinyPosition.selector, target);
        emit ProtocolModuleContractReplaced(prevModuleContractAddress, target, "LoanClosingsWith");
    }

closeWithDeposit

Closes a loan by doing a deposit. *

function closeWithDeposit(bytes32 loanId, address receiver, uint256 depositAmount) public payable nonReentrant globallyNonReentrant iTokenSupplyUnchanged whenNotPaused 
returns(loanCloseAmount uint256, withdrawAmount uint256, withdrawToken address)

Arguments

Name Type Description
loanId bytes32 The id of the loan.
receiver address The receiver of the remainder.
depositAmount uint256 Defines how much of the position should be closed. It is denominated in loan tokens. (e.g. rBTC on a iSUSD contract). If depositAmount > principal, the complete loan will be closed else deposit amount (partial closure). *

Returns

loanCloseAmount The amount of the collateral token of the loan.

Source Code
function closeWithDeposit(
        bytes32 loanId,
        address receiver,
        uint256 depositAmount /// Denominated in loanToken.
    )
        public
        payable
        nonReentrant
        globallyNonReentrant
        iTokenSupplyUnchanged(loanId)
        whenNotPaused
        returns (
            uint256 loanCloseAmount,
            uint256 withdrawAmount,
            address withdrawToken
        )
    {
        _checkAuthorized(loanId);
        return _closeWithDeposit(loanId, receiver, depositAmount);
    }

closeWithSwap

Close a position by swapping the collateral back to loan tokens paying the lender and withdrawing the remainder. *

function closeWithSwap(bytes32 loanId, address receiver, uint256 swapAmount, bool returnTokenIsCollateral, bytes ) public nonpayable nonReentrant globallyNonReentrant iTokenSupplyUnchanged whenNotPaused 
returns(loanCloseAmount uint256, withdrawAmount uint256, withdrawToken address)

Arguments

Name Type Description
loanId bytes32 The id of the loan.
receiver address The receiver of the remainder (unused collateral + profit).
swapAmount uint256 Defines how much of the position should be closed and is denominated in collateral tokens. If swapAmount >= collateral, the complete position will be closed. Else if returnTokenIsCollateral, (swapAmount/collateral) * principal will be swapped (partial closure). Else coveredPrincipal
returnTokenIsCollateral bool Defines if the remainder should be paid out in collateral tokens or underlying loan tokens. *
bytes loanId The id of the loan.

Returns

loanCloseAmount The amount of the collateral token of the loan.

Source Code
function closeWithSwap(
        bytes32 loanId,
        address receiver,
        uint256 swapAmount, // denominated in collateralToken
        bool returnTokenIsCollateral, // true: withdraws collateralToken, false: withdraws loanToken
        bytes memory // for future use /*loanDataBytes*/
    )
        public
        nonReentrant
        globallyNonReentrant
        iTokenSupplyUnchanged(loanId)
        whenNotPaused
        returns (
            uint256 loanCloseAmount,
            uint256 withdrawAmount,
            address withdrawToken
        )
    {
        _checkAuthorized(loanId);
        return
            _closeWithSwap(
                loanId,
                receiver,
                swapAmount,
                returnTokenIsCollateral,
                "" /// loanDataBytes
            );
    }

_closeWithDeposit

Internal function for closing a loan by doing a deposit. *

function _closeWithDeposit(bytes32 loanId, address receiver, uint256 depositAmount) internal nonpayable
returns(loanCloseAmount uint256, withdrawAmount uint256, withdrawToken address)

Arguments

Name Type Description
loanId bytes32 The id of the loan.
receiver address The receiver of the remainder.
depositAmount uint256 Defines how much of the position should be closed. It is denominated in loan tokens. If depositAmount > principal, the complete loan will be closed else deposit amount (partial closure). *

Returns

loanCloseAmount The amount of the collateral token of the loan.

Source Code
function _closeWithDeposit(
        bytes32 loanId,
        address receiver,
        uint256 depositAmount /// Denominated in loanToken.
    )
        internal
        returns (
            uint256 loanCloseAmount,
            uint256 withdrawAmount,
            address withdrawToken
        )
    {
        require(depositAmount != 0, "depositAmount == 0");

        //TODO should we skip this check if invoked from rollover ?
        (Loan storage loanLocal, LoanParams storage loanParamsLocal) = _checkLoan(loanId);

        /// Can't close more than the full principal.
        loanCloseAmount = depositAmount > loanLocal.principal
            ? loanLocal.principal
            : depositAmount;

        //revert if tiny position remains
        uint256 remainingAmount = loanLocal.principal - loanCloseAmount;
        if (remainingAmount > 0) {
            require(
                _getAmountInRbtc(loanParamsLocal.loanToken, remainingAmount) > TINY_AMOUNT,
                "Tiny amount when closing with deposit"
            );
        }

        uint256 loanCloseAmountLessInterest =
            _settleInterestToPrincipal(loanLocal, loanParamsLocal, loanCloseAmount, receiver);

        if (loanCloseAmountLessInterest != 0) {
            _returnPrincipalWithDeposit(
                loanParamsLocal.loanToken,
                loanLocal.lender,
                loanCloseAmountLessInterest
            );
        }

        if (loanCloseAmount == loanLocal.principal) {
            withdrawAmount = loanLocal.collateral;
        } else {
            withdrawAmount = loanLocal.collateral.mul(loanCloseAmount).div(loanLocal.principal);
        }

        withdrawToken = loanParamsLocal.collateralToken;

        if (withdrawAmount != 0) {
            loanLocal.collateral = loanLocal.collateral.sub(withdrawAmount);
            _withdrawAsset(withdrawToken, receiver, withdrawAmount);
        }

        _finalizeClose(
            loanLocal,
            loanParamsLocal,
            loanCloseAmount,
            withdrawAmount, /// collateralCloseAmount
            0, /// collateralToLoanSwapRate
            CloseTypes.Deposit
        );
    }

checkCloseWithDepositIsTinyPosition

Function to check whether the given loanId & deposit amount when closing with deposit will cause the tiny position *

function checkCloseWithDepositIsTinyPosition(bytes32 loanId, uint256 depositAmount) external view
returns(isTinyPosition bool, tinyPositionAmount uint256)

Arguments

Name Type Description
loanId bytes32 The id of the loan.
depositAmount uint256 Defines how much the deposit amount to close the position. *

Returns

isTinyPosition true is indicating tiny position, false otherwise.

Source Code
function checkCloseWithDepositIsTinyPosition(bytes32 loanId, uint256 depositAmount)
        external
        view
        returns (bool isTinyPosition, uint256 tinyPositionAmount)
    {
        (Loan memory loanLocal, LoanParams memory loanParamsLocal) = _checkLoan(loanId);

        if (depositAmount < loanLocal.principal) {
            uint256 remainingAmount = loanLocal.principal - depositAmount;
            uint256 remainingRBTCAmount =
                _getAmountInRbtc(loanParamsLocal.loanToken, remainingAmount);
            if (remainingRBTCAmount < TINY_AMOUNT) {
                isTinyPosition = true;
                tinyPositionAmount = remainingRBTCAmount;
            }
        }

        return (isTinyPosition, tinyPositionAmount);
    }

Contracts