From a9ed4a2fcb4ec0125fabc3618cdaf796063f31c0 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Tue, 30 Aug 2022 21:12:32 +0530 Subject: [PATCH] updated onBehalfOf, from methods --- .../connectors/compound-iii/events.sol | 160 +++++-- .../connectors/compound-iii/helpers.sol | 63 ++- .../mainnet/connectors/compound-iii/main.sol | 437 +++++++++++++++++- 3 files changed, 596 insertions(+), 64 deletions(-) diff --git a/contracts/mainnet/connectors/compound-iii/events.sol b/contracts/mainnet/connectors/compound-iii/events.sol index a83641f4..9a78dc96 100644 --- a/contracts/mainnet/connectors/compound-iii/events.sol +++ b/contracts/mainnet/connectors/compound-iii/events.sol @@ -2,53 +2,123 @@ pragma solidity ^0.7.0; contract Events { - event LogDeposit( - address indexed token, - address cToken, - uint256 tokenAmt, - uint256 getId, - uint256 setId - ); + event LogDeposit( + address indexed market, + address indexed asset, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); - event LogWithdraw( - address indexed token, - address cToken, - uint256 tokenAmt, - uint256 getId, - uint256 setId - ); + event LogDepositOnBehalfOf( + address indexed market, + address indexed asset, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); - event LogBorrow( - address indexed token, - address cToken, - uint256 tokenAmt, - uint256 getId, - uint256 setId - ); + event LogDepositFrom( + address indexed market, + address indexed asset, + address from, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); - event LogPayback( - address indexed token, - address cToken, - uint256 tokenAmt, - uint256 getId, - uint256 setId - ); + event LogWithdraw( + address indexed market, + address indexed asset, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); - event LogRewardsClaimed( - address indexed token, - address cToken, - uint256 tokenAmt, - uint256 cTokenAmt, - uint256 getId, - uint256 setId - ); - - event LogLiquidate( - address indexed borrower, - address indexed tokenToPay, - address indexed tokenInReturn, - uint256 tokenAmt, - uint256 getId, - uint256 setId - ); + event LogWithdrawOnBehalfOf( + address indexed market, + address indexed asset, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogWithdrawFrom( + address indexed market, + address indexed asset, + address from, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogBorrow( + address indexed market, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogBorrowOnBehalfOf( + address indexed market, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogBorrowFrom( + address indexed market, + address from, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogPayback( + address indexed market, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogPaybackOnBehalfOf( + address indexed market, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogPaybackFrom( + address indexed market, + address from, + address to, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogRewardsClaimed( + address indexed token, + address cToken, + uint256 tokenAmt, + uint256 cTokenAmt, + uint256 getId, + uint256 setId + ); + + event LogLiquidate( + address indexed borrower, + address indexed tokenToPay, + address indexed tokenInReturn, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); } diff --git a/contracts/mainnet/connectors/compound-iii/helpers.sol b/contracts/mainnet/connectors/compound-iii/helpers.sol index d25925be..08d4ae3a 100644 --- a/contracts/mainnet/connectors/compound-iii/helpers.sol +++ b/contracts/mainnet/connectors/compound-iii/helpers.sol @@ -17,26 +17,69 @@ abstract contract Helpers is DSMath, Basic { function _supply( address market, address token, + address from, + address to, uint256 amt ) internal payable returns (bool success) { - bytes memory data = abi.encodeWithSignature( - "supply(address, uint256)", - token, - amt - ); + bytes memory data; + + if (from == address(0) && to == address(0)) { + data = abi.encodeWithSignature( + "supply(address, uint256)", + token, + amt + ); + } else if (from == address(0)) { + data = abi.encodeWithSignature( + "supplyTo(address, address, uint256)", + to, + token, + amt + ); + } else if (from != address(0) && to != address(0)) { + data = abi.encodeWithSignature( + "supplyFrom(address, address, address, uint256)", + from, + to, + token, + amt + ); + } + (success, ) = market.delegateCall(data); } function _withdraw( address market, address token, + address from, + address to, uint256 amt ) internal payable returns (bool success) { - bytes memory data = abi.encodeWithSignature( - "withdraw(address, uint256)", - token, - amt - ); + bytes memory data; + + if (from == address(0) && to == address(0)) { + data = abi.encodeWithSignature( + "withdraw(address, uint256)", + token, + amt + ); + } else if (from == address(0)) { + data = abi.encodeWithSignature( + "withdrawTo(address, address, uint256)", + to, + token, + amt + ); + } else if (from != address(0) && to != address(0)) { + data = abi.encodeWithSignature( + "withdrawFrom(address, address, address, uint256)", + from, + to, + token, + amt + ); + } (success, ) = market.delegateCall(data); } diff --git a/contracts/mainnet/connectors/compound-iii/main.sol b/contracts/mainnet/connectors/compound-iii/main.sol index 5bd56a14..3e2f0991 100644 --- a/contracts/mainnet/connectors/compound-iii/main.sol +++ b/contracts/mainnet/connectors/compound-iii/main.sol @@ -15,9 +15,9 @@ import { CometInterface } from "./interface.sol"; abstract contract CompoundIIIResolver is Events, Helpers { /** - * @dev Deposit base asset or collateral asset supported by the . + * @dev Deposit base asset or collateral asset supported by the market. * @notice Deposit a token to Compound for lending / collaterization. - * @param market The address of the market from where to supply. + * @param market The address of the market where to supply. * @param token The address of the token to be supplied. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) * @param amt The amount of the token to deposit. (For max: `uint256(-1)`) * @param getId ID to retrieve amt. @@ -51,7 +51,7 @@ abstract contract CompoundIIIResolver is Events, Helpers { approve(tokenContract, market, _amt); - bool success = _supply(market, _token, _amt); + bool success = _supply(market, _token, 0x00, 0x00, _amt); require(success, "supply-failed"); setUint(setId, _amt); @@ -60,6 +60,104 @@ abstract contract CompoundIIIResolver is Events, Helpers { _eventParam = abi.encode(market, token, _amt, getId, setId); } + /** + * @dev Deposit base asset or collateral asset supported by the market on behalf of 'to'. + * @notice Deposit a token to Compound for lending / collaterization on behalf of 'to'. + * @param market The address of the market where to supply. + * @param token The address of the token to be supplied. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE). + * @param to The address on behalf of which the supply is made. + * @param amt The amount of the token to deposit. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens deposited. + */ + function depositOnBehalf( + address market, + address token, + address to, + uint256 amt, + uint256 getId, + uint256 setId + ) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); + + require( + market != address(0) && token != address(0), + "invalid market/token address" + ); + + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + TokenInterface tokenContract = TokenInterface(_token); + + if (isEth) { + convertEthToWeth(isEth, tokenContract, _amt); + } + + approve(tokenContract, market, _amt); + + bool success = _supply(market, _token, 0x00, to, _amt); + require(success, "supply-failed"); + + setUint(setId, _amt); + + _eventName = "LogDepositOnBehalf(address,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, to, _amt, getId, setId); + } + + /** + * @dev Deposit base asset or collateral asset supported by the market from 'from' address and update the position of 'to'. + * @notice Deposit a token to Compound for lending / collaterization from a address and update the position of 'to'. + * @param market The address of the market from where to supply. + * @param token The address of the token to be supplied. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param from The address from where amount is to be supplied. + * @param to The address on account of which the supply is made or whose positions are updated. + * @param amt The amount of the token to deposit. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens deposited. + */ + function depositFrom( + address market, + address token, + address from, + address to, + uint256 amt, + uint256 getId, + uint256 setId + ) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); + + require( + market != address(0) && token != address(0), + "invalid market/token address" + ); + + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + TokenInterface tokenContract = TokenInterface(_token); + + if (isEth) { + convertEthToWeth(isEth, tokenContract, _amt); + } + + approve(tokenContract, market, _amt); + + bool success = _supply(market, _token, from, to, _amt); + require(success, "supply-failed"); + + setUint(setId, _amt); + + _eventName = "LogDepositFrom(address,address,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, from, to, _amt, getId, setId); + } + /** * @dev Withdraw base/collateral asset or borrow base asset. * @notice Withdraw base token or deposited token from Compound. @@ -97,7 +195,7 @@ abstract contract CompoundIIIResolver is Events, Helpers { market, token ); - bool success = _withdraw(market, token, _amt); + bool success = _withdraw(market, token, 0x00, 0x00, _amt); require(success, "withdraw-failed"); uint256 finalBal = getAccountSupplyBalanceOfAsset( @@ -117,8 +215,126 @@ abstract contract CompoundIIIResolver is Events, Helpers { } /** - * @dev Withdraw base/collateral asset or borrow base asset. - * @notice Withdraw base token or deposited token from Compound. + * @dev Withdraw base/collateral asset or borrow base asset and transfer to 'to'. + * @notice Withdraw base token or deposited token from Compound on behalf of an address and transfer to 'to'. + * @param market The address of the market from where to withdraw. + * @param token The address of the token to be withdrawn. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param to The address to which the borrowed assets are to be transferred. + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function withdrawOnbehalf( + address market, + address token, + address to, + uint256 amt, + uint256 getId, + uint256 setId + ) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); + + require( + market != address(0) && token != address(0), + "invalid market/token address" + ); + + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + + TokenInterface tokenContract = TokenInterface(_token); + + uint256 initialBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + bool success = _withdraw(market, token, 0x00, to, _amt); + require(success, "withdraw-failed"); + + uint256 finalBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + + _amt = sub(finalBal, initialBal); + + convertWethToEth(isEth, tokenContract, _amt); + + setUint(setId, _amt); + + _eventName = "LogWithdrawOnBehalf(address,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, to, _amt, getId, setId); + } + + /** + * @dev Withdraw base/collateral asset or borrow base asset from an account and transfer to 'to'. + * @notice Withdraw base token or deposited token from Compound from an address and transfer to 'to'. + * @param market The address of the market from where to withdraw. + * @param token The address of the token to be withdrawn. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) + * @param from The address from where asset is to be withdrawed. + * @param to The address to which the borrowed assets are to be transferred. + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function withdrawFrom( + address market, + address token, + address from, + address to, + uint256 amt, + uint256 getId, + uint256 setId + ) + public + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); + + require( + market != address(0) && token != address(0), + "invalid market/token address" + ); + + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + + TokenInterface tokenContract = TokenInterface(_token); + + uint256 initialBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + bool success = _withdraw(market, token, from, to, _amt); + require(success, "withdraw-failed"); + + uint256 finalBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + + _amt = sub(finalBal, initialBal); + + convertWethToEth(isEth, tokenContract, _amt); + + setUint(setId, _amt); + + _eventName = "LogWithdrawFrom(address,address,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, from, to, _amt, getId, setId); + } + + /** + * @dev Borrow base asset. + * @notice Withdraw base token from Compound. * @param market The address of the market from where to withdraw. * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) * @param getId ID to retrieve amt. @@ -149,7 +365,7 @@ abstract contract CompoundIIIResolver is Events, Helpers { market, token ); - bool success = _withdraw(market, token, _amt); + bool success = _withdraw(market, token, 0x00, 0x00, _amt);; require(success, "borrow-failed"); uint256 finalBal = getAccountSupplyBalanceOfAsset( @@ -168,6 +384,124 @@ abstract contract CompoundIIIResolver is Events, Helpers { _eventParam = abi.encode(market, _amt, getId, setId); } + /** + * @dev Borrow base asset and transfer to 'to' account. + * @notice Withdraw base token from Compound on behalf of an address. + * @param market The address of the market from where to withdraw. + * @param to The address to which the borrowed asset is transferred. + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function borrowOnBehalf( + address market, + address to, + uint256 amt, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); + + require(market != address(0), "invalid market address"); + + bool token = getBaseToken(market); + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + + TokenInterface tokenContract = TokenInterface(_token); + + uint256 initialBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + bool success = _withdraw(market, token, 0x00, to, _amt); + require(success, "borrow-failed"); + + uint256 finalBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + + _amt = sub(finalBal, initialBal); + + convertWethToEth(isEth, tokenContract, _amt); + + setUint(setId, _amt); + + _eventName = "LogBorrowOnBehalf(address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, to, _amt, getId, setId); + } + + /** + * @dev Borrow base asset from 'from' and transfer to 'to'. + * @notice Withdraw base token or deposited token from Compound. + * @param market The address of the market from where to withdraw. + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param from The address from where asset is to be withdrawed. + * @param to The address to which the borrowed assets are to be transferred. + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function borrowFrom( + address market, + address from, + address to, + uint256 amt, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amt); + + require(market != address(0), "invalid market address"); + + bool token = getBaseToken(market); + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + + TokenInterface tokenContract = TokenInterface(_token); + + uint256 initialBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + bool success = _withdraw(market, token, from, to, _amt); + require(success, "borrow-failed"); + + uint256 finalBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + + _amt = sub(finalBal, initialBal); + + convertWethToEth(isEth, tokenContract, _amt); + + setUint(setId, _amt); + + _eventName = "LogBorrowFrom(address,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, from, to, _amt, getId, setId); + } + + /** + * @dev Repays entire borrow of the base asset. + * @notice Repays an entire borrow of the base asset. + * @param market The address of the market from where to withdraw. + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ function payBack( address market, uint256 getId, @@ -190,14 +524,99 @@ abstract contract CompoundIIIResolver is Events, Helpers { approve(tokenContract, market, _amt); - bool success = _supply(market, _token, _amt); + bool success = _supply(market, _token, 0x00, 0x00, _amt); require(success, "supply-failed"); setUint(setId, _amt); - _eventName = "LogDeposit(address,address,uint256,uint256,uint256)"; + _eventName = "LogPayback(address,address,uint256,uint256,uint256)"; _eventParam = abi.encode(market, token, _amt, getId, setId); } + + /** + * @dev Repays entire borrow of the base asset on behalf of 'to'. + * @notice Repays an entire borrow of the base asset on behalf of 'to'. + * @param market The address of the market from where to withdraw. + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param to The address on behalf of which the borrow is to be repaid. + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function payBackOnBehalf( + address market, + address to, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + require(market != address(0), "invalid market address"); + + address token = getBaseToken(market); + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + TokenInterface tokenContract = TokenInterface(_token); + + if (isEth) { + convertEthToWeth(isEth, tokenContract, _amt); + } + + approve(tokenContract, market, _amt); + + bool success = _supply(market, _token, 0x00, to, _amt); + require(success, "supply-failed"); + + setUint(setId, _amt); + + _eventName = "LogPaybackOnBehalf(address,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, to, _amt, getId, setId); + } + + /** + * @dev Repays entire borrow of the base asset form 'from' on behalf of 'to'. + * @notice Repays an entire borrow of the base asset on behalf of 'to'. + * @param market The address of the market from where to withdraw. + * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`) + * @param from The address from which the borrow has to be repaid on behalf of 'to'. + * @param to The address on behalf of which the borrow is to be repaid. + * @param getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function payFrom( + address market, + address from, + address to, + uint256 getId, + uint256 setId + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + require(market != address(0), "invalid market address"); + + address token = getBaseToken(market); + bool isEth = token == ethAddr; + address _token = isEth ? wethAddr : token; + TokenInterface tokenContract = TokenInterface(_token); + + if (isEth) { + convertEthToWeth(isEth, tokenContract, _amt); + } + + approve(tokenContract, market, _amt); + + bool success = _supply(market, _token, from, to, _amt); + require(success, "supply-failed"); + + setUint(setId, _amt); + + _eventName = "LogPaybackFrom(address,address,address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, from, to, _amt, getId, setId); + } + } contract ConnectV3Compound is CompoundResolver {