Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 460 - Separate logic for liquidation collateral withdraw #71

Draft
wants to merge 6 commits into
base: fix/sherlock/225
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions packages/contracts/contracts/CollateralManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -263,20 +263,22 @@ contract CollateralManager is OwnableUpgradeable, ICollateralManager {
* @notice Sends the deposited collateral to a liquidator of a bid.
* @notice Can only be called by the protocol.
* @param _bidId The id of the liquidated bid.
* @param _liquidatorAddress The address of the liquidator to send the collateral to.
* @param _recipientAddress The address of the recipient for the assets
*/
function liquidateCollateral(uint256 _bidId, address _liquidatorAddress)
function liquidateCollateral(uint256 _bidId, address _recipientAddress)
external
onlyTellerV2
{
if (isBidCollateralBacked(_bidId)) {
BidState bidState = tellerV2.getBidState(_bidId);
require(
bidState == BidState.LIQUIDATED,
"Loan has not been liquidated"
);
_withdraw(_bidId, _liquidatorAddress);
}
address _liquidatorAddress = tellerV2.getLoanLiquidator(_bidId);

require(msg.sender == _liquidatorAddress, "Not Authorized");

BidState bidState = tellerV2.getBidState(_bidId);
require(
bidState == BidState.LIQUIDATED,
"Loan has not been liquidated"
);

_withdraw(_bidId, _recipientAddress);
}

/* Internal Functions */
Expand Down
11 changes: 10 additions & 1 deletion packages/contracts/contracts/TellerV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,8 @@ contract TellerV2 is

// If loan is backed by collateral, withdraw and send to the liquidator
address liquidator = _msgSenderForMarket(bid.marketplaceId);
collateralManager.liquidateCollateral(_bidId, liquidator);

bidLiquidator[_bidId] = liquidator;

emit LoanLiquidated(_bidId, liquidator);
}
Expand Down Expand Up @@ -1019,6 +1020,14 @@ contract TellerV2 is
borrower_ = bids[_bidId].borrower;
}

function getLoanLiquidator(uint256 _bidId)
external
view
returns (address liquidator_)
{
liquidator_ = bidLiquidator[_bidId];
}

/**
* @notice Returns the lender address for a given bid. If the stored lender address is the `LenderManager` NFT address, return the `ownerOf` for the bid ID.
* @param _bidId The id of the bid/loan to get the lender for.
Expand Down
6 changes: 5 additions & 1 deletion packages/contracts/contracts/TellerV2Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,8 @@ abstract contract TellerV2Storage_G4 is TellerV2Storage_G3 {
mapping(uint256 => PaymentCycleType) public bidPaymentCycleType;
}

abstract contract TellerV2Storage is TellerV2Storage_G4 {}
abstract contract TellerV2Storage_G5 is TellerV2Storage_G4 {
mapping(uint256 => address) public bidLiquidator;
}

abstract contract TellerV2Storage is TellerV2Storage_G5 {}
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ interface ICollateralManager {
* @notice Sends the deposited collateral to a liquidator of a bid.
* @notice Can only be called by the protocol.
* @param _bidId The id of the liquidated bid.
* @param _liquidatorAddress The address of the liquidator to send the collateral to.
* @param _recipientAddress The address of the recipient of the assets
*/
function liquidateCollateral(uint256 _bidId, address _liquidatorAddress)
function liquidateCollateral(uint256 _bidId, address _recipientAddress)
external;
}
5 changes: 5 additions & 0 deletions packages/contracts/contracts/interfaces/ITellerV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ interface ITellerV2 {
view
returns (address lender_);

function getLoanLiquidator(uint256 _bidId)
external
view
returns (address liquidator_);

function getLoanLendingToken(uint256 _bidId)
external
view
Expand Down
16 changes: 16 additions & 0 deletions packages/contracts/contracts/mock/TellerV2SolMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import "../TellerV2Context.sol";
import { Collateral } from "../interfaces/escrow/ICollateralEscrowV1.sol";
import { LoanDetails, Payment, BidState } from "../TellerV2Storage.sol";

import "../../lib/forge-std/src/console.sol";

/*
This is only used for sol test so its named specifically to avoid being used for the typescript tests.
*/
Expand Down Expand Up @@ -151,6 +153,14 @@ contract TellerV2SolMock is ITellerV2, TellerV2Storage {
return bids[_bidId].loanDetails;
}

function getLoanLiquidator(uint256 _bidId)
external
view
returns (address liquidator_)
{
liquidator_ = bidLiquidator[_bidId];
}

function getBorrowerActiveLoanIds(address _borrower)
public
view
Expand Down Expand Up @@ -234,4 +244,10 @@ contract TellerV2SolMock is ITellerV2, TellerV2Storage {
function setLastRepaidTimestamp(uint256 _bidId, uint32 _timestamp) public {
bids[_bidId].loanDetails.lastRepaidTimestamp = _timestamp;
}

function setLoanLiquidator(uint256 _bidId, address _liquidator) public {
console.logAddress(_liquidator);
bidLiquidator[_bidId] = _liquidator;
console.logAddress(bidLiquidator[_bidId]);
}
}
23 changes: 17 additions & 6 deletions packages/contracts/tests/CollateralManager_Test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import "../contracts/CollateralManager.sol";

import "./CollateralManager_Override.sol";

import "../lib/forge-std/src/console.sol";

contract CollateralManager_Test is Testable {
CollateralManager_Override collateralManager;
User private borrower;
Expand Down Expand Up @@ -545,47 +547,56 @@ contract CollateralManager_Test is Testable {

tellerV2Mock.setGlobalBidState(BidState.LIQUIDATED);

vm.expectRevert("Sender not authorized");
vm.expectRevert("Not Authorized");
collateralManager.liquidateCollateral(bidId, address(liquidator));
}

function test_liquidateCollateral_invalid_state() public {
uint256 bidId = 0;

collateralManager.setBidsCollateralBackedGlobally(true);
tellerV2Mock.setLoanLiquidator(bidId, address(liquidator));

vm.prank(address(tellerV2Mock));
vm.prank(address(liquidator));
//tellerV2Mock.setGlobalBidState(BidState.LIQUIDATED);

vm.expectRevert("Loan has not been liquidated");
collateralManager.liquidateCollateral(bidId, address(liquidator));
}

function test_liquidateCollateral_not_backed() public {
/*function test_liquidateCollateral_not_backed() public {
uint256 bidId = 0;

collateralManager.setBidsCollateralBackedGlobally(false);
tellerV2Mock.setLoanLiquidator(bidId,address(liquidator));

tellerV2Mock.setGlobalBidState(BidState.PENDING);

vm.prank(address(tellerV2Mock));
vm.prank(address(liquidator));
collateralManager.liquidateCollateral(bidId, address(liquidator));

assertTrue(
collateralManager.withdrawInternalWasCalledToRecipient() ==
address(0),
"withdraw internal should not have been called"
);
}
}*/

function test_liquidateCollateral() public {
uint256 bidId = 0;

collateralManager.setBidsCollateralBackedGlobally(true);

console.logAddress(address(liquidator));

tellerV2Mock.setGlobalBidState(BidState.LIQUIDATED);
tellerV2Mock.setLoanLiquidator(bidId, address(liquidator));

vm.prank(address(tellerV2Mock));
address loanLiquidator = tellerV2Mock.getLoanLiquidator(bidId);

console.logAddress(loanLiquidator);

vm.prank(address(liquidator));
collateralManager.liquidateCollateral(bidId, address(liquidator));

assertTrue(
Expand Down
6 changes: 3 additions & 3 deletions packages/contracts/tests/TellerV2/TellerV2_Test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ contract TellerV2_Test is Testable {
lender.acceptBid(_bidId);
}

function test_collateralEscrow() public {
/* function test_collateralEscrow() public {
// Submit bid as borrower
uint256 bidId = submitCollateralBid();
// Accept bid as lender
Expand Down Expand Up @@ -203,8 +203,8 @@ contract TellerV2_Test is Testable {
collateralAmount,
borrowerBalanceAfter - borrowerBalanceBefore,
"Collateral was not sent to borrower after repayment"
);*/
}
);
}*/
}

contract TellerV2User is User {
Expand Down