library CloseWithoutCounterpartyImpl {
    using SafeMath for uint256;

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

    /**
     * A position was closed or partially closed
     */
    event PositionClosed(
        bytes32 indexed positionId,
        address indexed closer,
        address indexed payoutRecipient,
        uint256 closeAmount,
        uint256 remainingAmount,
        uint256 owedTokenPaidToLender,
        uint256 payoutAmount,
        uint256 buybackCostInHeldToken,
        bool payoutInHeldToken
    );

    // ============ Public Implementation Functions ============

    function closeWithoutCounterpartyImpl(
        MarginState.State storage state,
        bytes32 positionId,
        uint256 requestedCloseAmount,
        address payoutRecipient
    )
        public
        returns (uint256, uint256)
    {
        ClosePositionShared.CloseTx memory transaction = ClosePositionShared.createCloseTx(
            state,
            positionId,
            requestedCloseAmount,
            payoutRecipient,
            address(0),
            true,
            true
        );

        uint256 heldTokenPayout = ClosePositionShared.sendTokensToPayoutRecipient(
            state,
            transaction,
            0, // No buyback cost
            0  // Did not receive any owedToken
        );

        ClosePositionShared.closePositionStateUpdate(state, transaction);

        logEventOnCloseWithoutCounterparty(transaction);

        return (
            transaction.closeAmount,
            heldTokenPayout
        );
    }

    // ============ Private Helper-Functions ============

    function logEventOnCloseWithoutCounterparty(
        ClosePositionShared.CloseTx transaction
    )
        private
    {
        emit PositionClosed(
            transaction.positionId,
            msg.sender,
            transaction.payoutRecipient,
            transaction.closeAmount,
            transaction.originalPrincipal.sub(transaction.closeAmount),
            0,
            transaction.availableHeldToken,
            0,
            true
        );
    }
}
/**
 * @title CloseWithoutCounterpartyImpl
 * @author dYdX
 *
 * This library contains the implementation for the closeWithoutCounterpartyImpl function of
 * Margin
 */
function closeWithoutCounterpartyImpl(
    MarginState.State storage state,
    bytes32 positionId,
    uint256 requestedCloseAmount,
    address payoutRecipient
)
    public
    returns (uint256, uint256)
{
    ClosePositionShared.CloseTx memory transaction = ClosePositionShared.createCloseTx(
        state,
        positionId,
        requestedCloseAmount,
        payoutRecipient,
        address(0),
        true,
        true
    );

    uint256 heldTokenPayout = ClosePositionShared.sendTokensToPayoutRecipient(
        state,
        transaction,
        0, // No buyback cost
        0  // Did not receive any owedToken
    );

    ClosePositionShared.closePositionStateUpdate(state, transaction);

    logEventOnCloseWithoutCounterparty(transaction);

    return (
        transaction.closeAmount,
        heldTokenPayout
    );
}

// ============ Public Implementation Functions ============