The close
function allows a lender or borrower to finalize a credit (whose principal has been already paid) by repaying all of the accrued interest generated by facility rates. This function won't work as intended if the lender is the caller and the credit was given in ETH, because ETH can't be pulled from the borrower.
When a lender closes a credit using the close
function in the LineOfCredit contract, the LineLib.receiveTokenOrETH
function will be used to pull payments from the borrower.
In case the credit is using an ERC20 token as the credit payment, this will work fine as long as the borrower has enough balance and has previously approved the line contract to transfer funds. The lender will be able to call the close
function, which will pull all of the interest accrued from the borrower's balance to repay all debt and finalize the credit.
But in the case the credit was created using native ETH this won't work. If the lender wants to close the credit, and assuming the borrower has enough balance to pay for it, LineLib.receiveTokenOrETH
won't be able to pull ETH payments from the borrower.
The following test creates a credit using ETH and moves forward in time to simulate some debt from facility rates. The close
function call will fail when the lender wants to finalize his credit.
Note: the context for this test (setup, variables and helper functions) is similar to the one found in the file LineOfCredit.t.sol
.
function test_close_CantPullETHFromBorrower() public {
address lender = makeAddr("lender");
_mintAndApprove(lender);
uint256 amount = 1 ether;
// Setup credit (borrower goes first to avoid error on create)
vm.prank(borrower);
line.addCredit(dRate, fRate, amount, Denominations.ETH, lender);
vm.prank(lender);
bytes32 id = line.addCredit{value: amount}(dRate, fRate, amount, Denominations.ETH, lender);
vm.warp(block.timestamp + 30 days);
// Make sure borrower has balance to pay any debt
vm.deal(borrower, 1 ether);
// LineLib.receiveTokenOrETH will pull ERC20 from borrower but can't pull ETH
vm.expectRevert(LineLib.TransferFailed.selector);
vm.prank(lender);
line.close(id);
}
Instead of using native ETH (or the equivalent in the chain this gets deployed) use the wrapped ERC20 version WETH. This will enable pull payments for ETH.