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

Compoundv2 repay on behalf #333

Closed
wants to merge 6 commits into from
Closed
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
18 changes: 9 additions & 9 deletions contracts/mainnet/connectors/compound/v2/events.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ contract Events {
uint256 setId
);

event LogPaybackOnBehalf(
address indexed token,
address cToken,
uint256 tokenAmt,
address indexed borrower,
uint256 getId,
uint256 setId
);

event LogPayback(
address indexed token,
address cToken,
Expand All @@ -51,13 +60,4 @@ contract Events {
uint256 getId,
uint256 setId
);

event LogLiquidate(
address indexed borrower,
address indexed tokenToPay,
address indexed tokenInReturn,
uint256 tokenAmt,
uint256 getId,
uint256 setId
);
}
156 changes: 63 additions & 93 deletions contracts/mainnet/connectors/compound/v2/main.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Helpers } from "./helpers.sol";
import { Events } from "./events.sol";
import { CETHInterface, CTokenInterface } from "./interface.sol";

abstract contract CompoundResolver is Events, Helpers {
abstract contract CompoundConnector is Events, Helpers {
/**
* @dev Deposit ETH/ERC20_Token.
* @notice Deposit a token to Compound for lending / collaterization.
Expand Down Expand Up @@ -206,6 +206,46 @@ abstract contract CompoundResolver is Events, Helpers {
_eventParam = abi.encode(token, cToken, _amt, getId, setId);
}

/**
* @dev Payback borrowed ETH/ERC20_Token.
* @notice Payback debt owed.
* @param token The address of the token to payback. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
* @param cToken The address of the corresponding cToken.
* @param amt The amount of the token to payback. (For max: `uint256(-1)`)
* @param borrower The address whose debt needs to be repaid.
* @param getId ID to retrieve amt.
* @param setId ID stores the amount of tokens paid back.
*/
function paybackRawOnBehalf(
address token,
address cToken,
uint256 amt,
address borrower,
uint256 getId,
uint256 setId
) public payable returns (string memory _eventName, bytes memory _eventParam) {
uint _amt = getUint(getId, amt);

require(token != address(0) && cToken != address(0), "invalid token/ctoken address");

CTokenInterface cTokenContract = CTokenInterface(cToken);
_amt = _amt == uint(-1) ? cTokenContract.borrowBalanceCurrent(borrower) : _amt;

if (token == ethAddr) {
require(address(this).balance >= _amt, "not-enough-eth");
CETHInterface(cToken).repayBorrowBehalf{value: _amt}(borrower);
} else {
TokenInterface tokenContract = TokenInterface(token);
require(tokenContract.balanceOf(address(this)) >= _amt, "not-enough-token");
approve(tokenContract, cToken, _amt);
require(cTokenContract.repayBorrowBehalf(borrower, _amt) == 0, "repay-failed.");
}
setUint(setId, _amt);

_eventName = "LogPaybackOnBehalf(address,address,uint256,address,uint256,uint256)";
_eventParam = abi.encode(token, cToken, _amt, borrower, getId, setId);
}

/**
* @dev Payback borrowed ETH/ERC20_Token using the Mapping.
* @notice Payback debt owed.
Expand All @@ -224,6 +264,26 @@ abstract contract CompoundResolver is Events, Helpers {
(_eventName, _eventParam) = paybackRaw(token, cToken, amt, getId, setId);
}

/**
* @dev Payback borrowed ETH/ERC20_Token using the Mapping.
* @notice Payback debt owed.
* @param tokenId The token id of the token to payback.(For eg: COMP-A)
* @param amt The amount of the token to payback. (For max: `uint256(-1)`)
* @param borrower The address whose debt needs to be repaid.
* @param getId ID to retrieve amt.
* @param setId ID stores the amount of tokens paid back.
*/
function paybackOnBehalf(
string calldata tokenId,
uint256 amt,
address borrower,
uint256 getId,
uint256 setId
) external payable returns (string memory _eventName, bytes memory _eventParam) {
(address token, address cToken) = compMapping.getMapping(tokenId);
(_eventName, _eventParam) = paybackRawOnBehalf(token, cToken, amt, borrower, getId, setId);
}

/**
* @dev Deposit ETH/ERC20_Token.
* @notice Same as depositRaw. The only difference is this method stores cToken amount in set ID.
Expand Down Expand Up @@ -345,98 +405,8 @@ abstract contract CompoundResolver is Events, Helpers {
(address token, address cToken) = compMapping.getMapping(tokenId);
(_eventName, _eventParam) = withdrawCTokenRaw(token, cToken, cTokenAmt, getId, setId);
}

/**
* @dev Liquidate a position.
* @notice Liquidate a position.
* @param borrower Borrower's Address.
* @param tokenToPay The address of the token to pay for liquidation.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
* @param cTokenPay Corresponding cToken address.
* @param tokenInReturn The address of the token to return for liquidation.
* @param cTokenColl Corresponding cToken address.
* @param amt The token amount to pay for liquidation.
* @param getId ID to retrieve amt.
* @param setId ID stores the amount of paid for liquidation.
*/
function liquidateRaw(
address borrower,
address tokenToPay,
address cTokenPay,
address tokenInReturn,
address cTokenColl,
uint256 amt,
uint256 getId,
uint256 setId
) public payable returns (string memory _eventName, bytes memory _eventParam) {
uint _amt = getUint(getId, amt);
require(tokenToPay != address(0) && cTokenPay != address(0), "invalid token/ctoken address");
require(tokenInReturn != address(0) && cTokenColl != address(0), "invalid token/ctoken address");

CTokenInterface cTokenContract = CTokenInterface(cTokenPay);

{
(,, uint shortfal) = troller.getAccountLiquidity(borrower);
require(shortfal != 0, "account-cannot-be-liquidated");
_amt = _amt == uint(-1) ? cTokenContract.borrowBalanceCurrent(borrower) : _amt;
}

if (tokenToPay == ethAddr) {
require(address(this).balance >= _amt, "not-enought-eth");
CETHInterface(cTokenPay).liquidateBorrow{value: _amt}(borrower, cTokenColl);
} else {
TokenInterface tokenContract = TokenInterface(tokenToPay);
require(tokenContract.balanceOf(address(this)) >= _amt, "not-enough-token");
approve(tokenContract, cTokenPay, _amt);
require(cTokenContract.liquidateBorrow(borrower, _amt, cTokenColl) == 0, "liquidate-failed");
}

setUint(setId, _amt);

_eventName = "LogLiquidate(address,address,address,uint256,uint256,uint256)";
_eventParam = abi.encode(
address(this),
tokenToPay,
tokenInReturn,
_amt,
getId,
setId
);
}

/**
* @dev Liquidate a position using the mapping.
* @notice Liquidate a position using the mapping.
* @param borrower Borrower's Address.
* @param tokenIdToPay token id of the token to pay for liquidation.(For eg: ETH-A)
* @param tokenIdInReturn token id of the token to return for liquidation.(For eg: USDC-A)
* @param amt token amount to pay for liquidation.
* @param getId ID to retrieve amt.
* @param setId ID stores the amount of paid for liquidation.
*/
function liquidate(
address borrower,
string calldata tokenIdToPay,
string calldata tokenIdInReturn,
uint256 amt,
uint256 getId,
uint256 setId
) external payable returns (string memory _eventName, bytes memory _eventParam) {
(address tokenToPay, address cTokenToPay) = compMapping.getMapping(tokenIdToPay);
(address tokenInReturn, address cTokenColl) = compMapping.getMapping(tokenIdInReturn);

(_eventName, _eventParam) = liquidateRaw(
borrower,
tokenToPay,
cTokenToPay,
tokenInReturn,
cTokenColl,
amt,
getId,
setId
);
}
}

contract ConnectV2Compound is CompoundResolver {
string public name = "Compound-v1.1";
contract ConnectV2Compound is CompoundConnector {
string public name = "Compound-v1.2";
}
4 changes: 2 additions & 2 deletions test/mainnet/compound/compound.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ describe("Compound", function () {
},
{
connector: connectorName,
method: "payback",
args: ["DAI-A", 0, setId, 0]
method: "paybackOnBehalf",
args: ["DAI-A", 0, dsaWallet0.address, setId, 0]
}
]

Expand Down
Loading