From 77f3b6f33d88cf66b9af9e6d4a3b28d097bbd6c5 Mon Sep 17 00:00:00 2001 From: Richa-iitr <richa@cs.iitr.ac.in> Date: Tue, 30 Aug 2022 18:06:00 +0530 Subject: [PATCH] basic functions added --- .../connectors/compound-iii/events.sol | 54 +++++ .../connectors/compound-iii/helpers.sol | 58 +++++ .../connectors/compound-iii/interface.sol | 96 ++++++++ .../mainnet/connectors/compound-iii/main.sol | 205 ++++++++++++++++++ 4 files changed, 413 insertions(+) create mode 100644 contracts/mainnet/connectors/compound-iii/events.sol create mode 100644 contracts/mainnet/connectors/compound-iii/helpers.sol create mode 100644 contracts/mainnet/connectors/compound-iii/interface.sol create mode 100644 contracts/mainnet/connectors/compound-iii/main.sol diff --git a/contracts/mainnet/connectors/compound-iii/events.sol b/contracts/mainnet/connectors/compound-iii/events.sol new file mode 100644 index 00000000..a83641f4 --- /dev/null +++ b/contracts/mainnet/connectors/compound-iii/events.sol @@ -0,0 +1,54 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +contract Events { + event LogDeposit( + address indexed token, + address cToken, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogWithdraw( + address indexed token, + address cToken, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogBorrow( + address indexed token, + address cToken, + uint256 tokenAmt, + uint256 getId, + uint256 setId + ); + + event LogPayback( + address indexed token, + address cToken, + 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 new file mode 100644 index 00000000..d25925be --- /dev/null +++ b/contracts/mainnet/connectors/compound-iii/helpers.sol @@ -0,0 +1,58 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +import { DSMath } from "../../common/math.sol"; +import { Basic } from "../../common/basic.sol"; +import { CometInterface } from "./interface.sol"; + +abstract contract Helpers is DSMath, Basic { + function getBaseToken(address market) + internal + view + returns (address baseToken) + { + baseToken = CometInterface(market).baseToken(); + } + + function _supply( + address market, + address token, + uint256 amt + ) internal payable returns (bool success) { + bytes memory data = abi.encodeWithSignature( + "supply(address, uint256)", + token, + amt + ); + (success, ) = market.delegateCall(data); + } + + function _withdraw( + address market, + address token, + uint256 amt + ) internal payable returns (bool success) { + bytes memory data = abi.encodeWithSignature( + "withdraw(address, uint256)", + token, + amt + ); + (success, ) = market.delegateCall(data); + } + + function getAccountSupplyBalanceOfAsset( + address account, + address market, + address asset + ) internal view returns (uint256 balance) { + if (asset == getBaseToken(market)) { + //balance in base + balance = CometInterface(market).balanceOf(account); + } else { + //balance in asset denomination + balance = uint256( + CometInterface(market).userCollateral(account, asset).balance + ); + } + } +} diff --git a/contracts/mainnet/connectors/compound-iii/interface.sol b/contracts/mainnet/connectors/compound-iii/interface.sol new file mode 100644 index 00000000..a72d2bb6 --- /dev/null +++ b/contracts/mainnet/connectors/compound-iii/interface.sol @@ -0,0 +1,96 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; + +struct UserCollateral { + uint128 balance; + uint128 _reserved; +} + +interface CometInterface { + function supply(address asset, uint256 amount) external virtual; + + function supplyTo( + address dst, + address asset, + uint256 amount + ) external virtual; + + function supplyFrom( + address from, + address dst, + address asset, + uint256 amount + ) external virtual; + + function transfer(address dst, uint256 amount) + external + virtual + returns (bool); + + function transferFrom( + address src, + address dst, + uint256 amount + ) external virtual returns (bool); + + function transferAsset( + address dst, + address asset, + uint256 amount + ) external virtual; + + function transferAssetFrom( + address src, + address dst, + address asset, + uint256 amount + ) external virtual; + + function withdraw(address asset, uint256 amount) external virtual; + + function withdrawTo( + address to, + address asset, + uint256 amount + ) external virtual; + + function withdrawFrom( + address src, + address to, + address asset, + uint256 amount + ) external virtual; + + function approveThis( + address manager, + address asset, + uint256 amount + ) external virtual; + + function withdrawReserves(address to, uint256 amount) external virtual; + + function absorb(address absorber, address[] calldata accounts) + external + virtual; + + function buyCollateral( + address asset, + uint256 minAmount, + uint256 baseAmount, + address recipient + ) external virtual; + + function quoteCollateral(address asset, uint256 baseAmount) + public + view + virtual + returns (uint256); + + function userCollateral(address, address) + external + returns (UserCollateral memory); + + function baseToken() external view returns (address); + + function balanceOf(address account) external view returns (uint256); +} diff --git a/contracts/mainnet/connectors/compound-iii/main.sol b/contracts/mainnet/connectors/compound-iii/main.sol new file mode 100644 index 00000000..5bd56a14 --- /dev/null +++ b/contracts/mainnet/connectors/compound-iii/main.sol @@ -0,0 +1,205 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +/** + * @title Compound. + * @dev Lending & Borrowing. + */ + +import { TokenInterface } from "../../common/interfaces.sol"; +import { Stores } from "../../common/stores.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; +import { CometInterface } from "./interface.sol"; + +abstract contract CompoundIIIResolver is Events, Helpers { + /** + * @dev Deposit base asset or collateral asset supported by the . + * @notice Deposit a token to Compound for lending / collaterization. + * @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 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 deposit( + address market, + address token, + 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, _amt); + require(success, "supply-failed"); + + setUint(setId, _amt); + + _eventName = "LogDeposit(address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, _amt, getId, setId); + } + + /** + * @dev Withdraw base/collateral asset or borrow base asset. + * @notice Withdraw base token or deposited token from Compound. + * @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 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 withdraw( + address market, + address token, + 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, _amt); + require(success, "withdraw-failed"); + + uint256 finalBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + + _amt = sub(finalBal, initialBal); + + convertWethToEth(isEth, tokenContract, _amt); + + setUint(setId, _amt); + + _eventName = "LogWithdraw(address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, _amt, getId, setId); + } + + /** + * @dev Withdraw base/collateral asset or borrow base asset. + * @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 getId ID to retrieve amt. + * @param setId ID stores the amount of tokens withdrawn. + */ + function borrow( + address market, + 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, _amt); + require(success, "borrow-failed"); + + uint256 finalBal = getAccountSupplyBalanceOfAsset( + address(this), + market, + token + ); + + _amt = sub(finalBal, initialBal); + + convertWethToEth(isEth, tokenContract, _amt); + + setUint(setId, _amt); + + _eventName = "LogBorrow(address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, _amt, getId, setId); + } + + function payBack( + address market, + 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, _amt); + require(success, "supply-failed"); + + setUint(setId, _amt); + + _eventName = "LogDeposit(address,address,uint256,uint256,uint256)"; + _eventParam = abi.encode(market, token, _amt, getId, setId); + } +} + +contract ConnectV3Compound is CompoundResolver { + string public name = "Compound-v1.0"; +}