mirror of
				https://github.com/Instadapp/dsa-connectors.git
				synced 2024-07-29 22:37:00 +00:00 
			
		
		
		
	Merge pull request #45 from Instadapp/feat/refinance-connector
Add Refinance connector
This commit is contained in:
		
						commit
						4848a8170e
					
				
							
								
								
									
										0
									
								
								contracts/mainnet/connectors/refinance/events.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								contracts/mainnet/connectors/refinance/events.sol
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										155
									
								
								contracts/mainnet/connectors/refinance/helpers.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								contracts/mainnet/connectors/refinance/helpers.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,155 @@ | |||
| pragma solidity ^0.7.0; | ||||
| pragma experimental ABIEncoderV2; | ||||
| 
 | ||||
| import { Basic } from "../../common/basic.sol"; | ||||
| 
 | ||||
| 
 | ||||
| import { | ||||
|     AaveV1ProviderInterface, | ||||
|     AaveV1Interface, | ||||
|     AaveV2LendingPoolProviderInterface,  | ||||
|     AaveV2DataProviderInterface, | ||||
|     AaveV2Interface, | ||||
|     ComptrollerInterface, | ||||
|     CTokenInterface, | ||||
|     CompoundMappingInterface | ||||
| } from "./interfaces.sol"; | ||||
| 
 | ||||
| 
 | ||||
| import { TokenInterface } from "../../common/interfaces.sol"; | ||||
| 
 | ||||
| import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; | ||||
| import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||||
| 
 | ||||
| contract Helpers is Basic { | ||||
|     using SafeERC20 for IERC20; | ||||
| 
 | ||||
|     enum Protocol { | ||||
|         Aave, | ||||
|         AaveV2, | ||||
|         Compound | ||||
|     } | ||||
| 
 | ||||
|     address payable constant feeCollector = 0xb1DC62EC38E6E3857a887210C38418E4A17Da5B2; | ||||
| 
 | ||||
|     /** | ||||
|      * @dev Return InstaDApp Mapping Address | ||||
|      */ | ||||
|     address constant internal getMappingAddr = 0xA8F9D4aA7319C54C04404765117ddBf9448E2082; // CompoundMapping Address | ||||
| 
 | ||||
|     /** | ||||
|      * @dev Return Compound Comptroller Address | ||||
|      */ | ||||
|     address constant internal getComptrollerAddress = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; // CompoundMapping Address | ||||
| 
 | ||||
|     /** | ||||
|      * @dev get Aave Provider | ||||
|     */ | ||||
|     AaveV1ProviderInterface constant internal getAaveProvider = | ||||
|                     AaveV1ProviderInterface(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8); | ||||
| 
 | ||||
|     /** | ||||
|      * @dev get Aave Lending Pool Provider | ||||
|     */ | ||||
|     AaveV2LendingPoolProviderInterface constant internal getAaveV2Provider = | ||||
|                     AaveV2LendingPoolProviderInterface(0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5); | ||||
| 
 | ||||
|     /** | ||||
|      * @dev get Aave Protocol Data Provider | ||||
|     */ | ||||
|     AaveV2DataProviderInterface constant internal getAaveV2DataProvider = | ||||
|                     AaveV2DataProviderInterface(0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d); | ||||
| 
 | ||||
|     /** | ||||
|      * @dev get Referral Code | ||||
|     */ | ||||
|     uint16 constant internal getReferralCode =  3228; | ||||
| } | ||||
| 
 | ||||
| contract protocolHelpers is Helpers { | ||||
|     using SafeERC20 for IERC20; | ||||
| 
 | ||||
|     function getWithdrawBalance(AaveV1Interface aave, address token) internal view returns (uint bal) { | ||||
|         (bal, , , , , , , , , ) = aave.getUserReserveData(token, address(this)); | ||||
|     } | ||||
| 
 | ||||
|     function getPaybackBalance(AaveV1Interface aave, address token) internal view returns (uint bal, uint fee) { | ||||
|         (, bal, , , , , fee, , , ) = aave.getUserReserveData(token, address(this)); | ||||
|     } | ||||
| 
 | ||||
|     function getTotalBorrowBalance(AaveV1Interface aave, address token) internal view returns (uint amt) { | ||||
|         (, uint bal, , , , , uint fee, , , ) = aave.getUserReserveData(token, address(this)); | ||||
|         amt = add(bal, fee); | ||||
|     } | ||||
| 
 | ||||
|     function getWithdrawBalanceV2(AaveV2DataProviderInterface aaveData, address token) internal view returns (uint bal) { | ||||
|         (bal, , , , , , , , ) = aaveData.getUserReserveData(token, address(this)); | ||||
|     } | ||||
| 
 | ||||
|     function getPaybackBalanceV2(AaveV2DataProviderInterface aaveData, address token, uint rateMode) internal view returns (uint bal) { | ||||
|         if (rateMode == 1) { | ||||
|             (, bal, , , , , , , ) = aaveData.getUserReserveData(token, address(this)); | ||||
|         } else { | ||||
|             (, , bal, , , , , , ) = aaveData.getUserReserveData(token, address(this)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function getIsColl(AaveV1Interface aave, address token) internal view returns (bool isCol) { | ||||
|         (, , , , , , , , , isCol) = aave.getUserReserveData(token, address(this)); | ||||
|     } | ||||
| 
 | ||||
|     function getIsCollV2(AaveV2DataProviderInterface aaveData, address token) internal view returns (bool isCol) { | ||||
|         (, , , , , , , , isCol) = aaveData.getUserReserveData(token, address(this)); | ||||
|     } | ||||
| 
 | ||||
|     function getMaxBorrow(Protocol target, address token, CTokenInterface ctoken, uint rateMode) internal returns (uint amt) { | ||||
|         AaveV1Interface aaveV1 = AaveV1Interface(getAaveProvider.getLendingPool()); | ||||
|         AaveV2DataProviderInterface aaveData = getAaveV2DataProvider; | ||||
| 
 | ||||
|         if (target == Protocol.Aave) { | ||||
|             (uint _amt, uint _fee) = getPaybackBalance(aaveV1, token); | ||||
|             amt = _amt + _fee; | ||||
|         } else if (target == Protocol.AaveV2) { | ||||
|             amt = getPaybackBalanceV2(aaveData, token, rateMode); | ||||
|         } else if (target == Protocol.Compound) { | ||||
|             amt = ctoken.borrowBalanceCurrent(address(this)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function transferFees(address token, uint feeAmt) internal { | ||||
|         if (feeAmt > 0) { | ||||
|             if (token == ethAddr) { | ||||
|                 feeCollector.transfer(feeAmt); | ||||
|             } else { | ||||
|                 IERC20(token).safeTransfer(feeCollector, feeAmt); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function calculateFee(uint256 amount, uint256 fee, bool toAdd) internal pure returns(uint feeAmount, uint _amount){ | ||||
|         feeAmount = wmul(amount, fee); | ||||
|         _amount = toAdd ? add(amount, feeAmount) : sub(amount, feeAmount); | ||||
|     } | ||||
| 
 | ||||
|     function getTokenInterfaces(uint length, address[] memory tokens) internal pure returns (TokenInterface[] memory) { | ||||
|         TokenInterface[] memory _tokens = new TokenInterface[](length); | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             if (tokens[i] ==  ethAddr) { | ||||
|                 _tokens[i] = TokenInterface(wethAddr); | ||||
|             } else { | ||||
|                 _tokens[i] = TokenInterface(tokens[i]); | ||||
|             } | ||||
|         } | ||||
|         return _tokens; | ||||
|     } | ||||
| 
 | ||||
|     function getCtokenInterfaces(uint length, string[] memory tokenIds) internal view returns (CTokenInterface[] memory) { | ||||
|         CTokenInterface[] memory _ctokens = new CTokenInterface[](length); | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             (address token, address cToken) = CompoundMappingInterface(getMappingAddr).getMapping(tokenIds[i]); | ||||
|             require(token != address(0) && cToken != address(0), "invalid token/ctoken address"); | ||||
|             _ctokens[i] = CTokenInterface(cToken); | ||||
|         } | ||||
|         return _ctokens; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										202
									
								
								contracts/mainnet/connectors/refinance/helpers/aaveV1.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								contracts/mainnet/connectors/refinance/helpers/aaveV1.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,202 @@ | |||
| pragma solidity ^0.7.0; | ||||
| pragma experimental ABIEncoderV2; | ||||
| 
 | ||||
| import { protocolHelpers } from "../helpers.sol"; | ||||
| 
 | ||||
| import { | ||||
|     AaveV1ProviderInterface, | ||||
|     AaveV1Interface, | ||||
|     AaveV1CoreInterface, | ||||
|     ATokenV1Interface, | ||||
|     CTokenInterface | ||||
|     // AaveV2LendingPoolProviderInterface,  | ||||
|     // AaveV2DataProviderInterface, | ||||
|     // AaveV2Interface, | ||||
| } from "../interfaces.sol"; | ||||
| 
 | ||||
| import { TokenInterface } from "../../../common/interfaces.sol"; | ||||
| 
 | ||||
| contract AaveV1Helpers is protocolHelpers { | ||||
| 
 | ||||
|     struct AaveV1BorrowData { | ||||
|         AaveV1Interface aave; | ||||
|         uint length; | ||||
|         uint fee; | ||||
|         Protocol target; | ||||
|         TokenInterface[] tokens; | ||||
|         CTokenInterface[] ctokens; | ||||
|         uint[] amts; | ||||
|         uint[] borrowRateModes; | ||||
|         uint[] paybackRateModes; | ||||
|     } | ||||
| 
 | ||||
|     struct AaveV1DepositData { | ||||
|         AaveV1Interface aave; | ||||
|         AaveV1CoreInterface aaveCore; | ||||
|         uint length; | ||||
|         uint fee; | ||||
|         TokenInterface[] tokens; | ||||
|         uint[] amts; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1BorrowOne( | ||||
|         AaveV1Interface aave, | ||||
|         uint fee, | ||||
|         Protocol target, | ||||
|         TokenInterface token, | ||||
|         CTokenInterface ctoken, | ||||
|         uint amt, | ||||
|         uint borrowRateMode, | ||||
|         uint paybackRateMode | ||||
|     ) internal returns (uint) { | ||||
|         if (amt > 0) { | ||||
| 
 | ||||
|             address _token = address(token) == wethAddr ? ethAddr : address(token); | ||||
| 
 | ||||
|             if (amt == uint(-1)) { | ||||
|                 amt = getMaxBorrow(target, address(token), ctoken, paybackRateMode); | ||||
|             } | ||||
| 
 | ||||
|             (uint feeAmt, uint _amt) = calculateFee(amt, fee, true); | ||||
| 
 | ||||
|             aave.borrow(_token, _amt, borrowRateMode, getReferralCode); | ||||
|             transferFees(_token, feeAmt); | ||||
|         } | ||||
|         return amt; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1Borrow( | ||||
|         AaveV1BorrowData memory data | ||||
|     ) internal returns (uint[] memory) { | ||||
|         uint[] memory finalAmts = new uint[](data.length); | ||||
|         for (uint i = 0; i < data.length; i++) { | ||||
|             finalAmts[i] = _aaveV1BorrowOne( | ||||
|                 data.aave, | ||||
|                 data.fee, | ||||
|                 data.target, | ||||
|                 data.tokens[i], | ||||
|                 data.ctokens[i], | ||||
|                 data.amts[i], | ||||
|                 data.borrowRateModes[i], | ||||
|                 data.paybackRateModes[i] | ||||
|             ); | ||||
|         } | ||||
|         return finalAmts; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1DepositOne( | ||||
|         AaveV1Interface aave, | ||||
|         AaveV1CoreInterface aaveCore, | ||||
|         uint fee, | ||||
|         TokenInterface token, | ||||
|         uint amt | ||||
|     ) internal { | ||||
|         if (amt > 0) { | ||||
|             uint ethAmt; | ||||
|             (uint feeAmt, uint _amt) = calculateFee(amt, fee, false); | ||||
| 
 | ||||
|             bool isEth = address(token) == wethAddr; | ||||
| 
 | ||||
|             address _token = isEth ? ethAddr : address(token); | ||||
| 
 | ||||
|             if (isEth) { | ||||
|                 ethAmt = _amt; | ||||
|             } else { | ||||
|                 token.approve(address(aaveCore), _amt); | ||||
|             } | ||||
| 
 | ||||
|             transferFees(_token, feeAmt); | ||||
| 
 | ||||
|             aave.deposit{value:ethAmt}(_token, _amt, getReferralCode); | ||||
| 
 | ||||
|             if (!getIsColl(aave, _token)) | ||||
|                 aave.setUserUseReserveAsCollateral(_token, true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1Deposit( | ||||
|         AaveV1DepositData memory data | ||||
|     ) internal { | ||||
|         for (uint i = 0; i < data.length; i++) { | ||||
|             _aaveV1DepositOne( | ||||
|                 data.aave, | ||||
|                 data.aaveCore, | ||||
|                 data.fee, | ||||
|                 data.tokens[i], | ||||
|                 data.amts[i] | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1WithdrawOne( | ||||
|         AaveV1Interface aave, | ||||
|         AaveV1CoreInterface aaveCore, | ||||
|         TokenInterface token, | ||||
|         uint amt | ||||
|     ) internal returns (uint) { | ||||
|         if (amt > 0) { | ||||
|             address _token = address(token) == wethAddr ? ethAddr : address(token); | ||||
|             ATokenV1Interface atoken = ATokenV1Interface(aaveCore.getReserveATokenAddress(_token)); | ||||
|             if (amt == uint(-1)) { | ||||
|                 amt = getWithdrawBalance(aave, _token); | ||||
|             } | ||||
|             atoken.redeem(amt); | ||||
|         } | ||||
|         return amt; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1Withdraw( | ||||
|         AaveV1Interface aave, | ||||
|         AaveV1CoreInterface aaveCore, | ||||
|         uint length, | ||||
|         TokenInterface[] memory tokens, | ||||
|         uint[] memory amts | ||||
|     ) internal returns (uint[] memory) { | ||||
|         uint[] memory finalAmts = new uint[](length); | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             finalAmts[i] = _aaveV1WithdrawOne(aave, aaveCore, tokens[i], amts[i]); | ||||
|         } | ||||
|         return finalAmts; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1PaybackOne( | ||||
|         AaveV1Interface aave, | ||||
|         AaveV1CoreInterface aaveCore, | ||||
|         TokenInterface token, | ||||
|         uint amt | ||||
|     ) internal returns (uint) { | ||||
|         if (amt > 0) { | ||||
|             uint ethAmt; | ||||
| 
 | ||||
|             bool isEth = address(token) == wethAddr; | ||||
| 
 | ||||
|             address _token = isEth ? ethAddr : address(token); | ||||
| 
 | ||||
|             if (amt == uint(-1)) { | ||||
|                 (uint _amt, uint _fee) = getPaybackBalance(aave, _token); | ||||
|                 amt = _amt + _fee; | ||||
|             } | ||||
| 
 | ||||
|             if (isEth) { | ||||
|                 ethAmt = amt; | ||||
|             } else { | ||||
|                 token.approve(address(aaveCore), amt); | ||||
|             } | ||||
| 
 | ||||
|             aave.repay{value:ethAmt}(_token, amt, payable(address(this))); | ||||
|         } | ||||
|         return amt; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV1Payback( | ||||
|         AaveV1Interface aave, | ||||
|         AaveV1CoreInterface aaveCore, | ||||
|         uint length, | ||||
|         TokenInterface[] memory tokens, | ||||
|         uint[] memory amts | ||||
|     ) internal { | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             _aaveV1PaybackOne(aave, aaveCore, tokens[i], amts[i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										200
									
								
								contracts/mainnet/connectors/refinance/helpers/aaveV2.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								contracts/mainnet/connectors/refinance/helpers/aaveV2.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,200 @@ | |||
| pragma solidity ^0.7.0; | ||||
| pragma experimental ABIEncoderV2; | ||||
| 
 | ||||
| import { protocolHelpers } from "../helpers.sol"; | ||||
| 
 | ||||
| import { | ||||
|     // AaveV1ProviderInterface, | ||||
|     // AaveV1Interface, | ||||
|     // AaveV1CoreInterface, | ||||
|     AaveV2LendingPoolProviderInterface,  | ||||
|     AaveV2DataProviderInterface, | ||||
|     AaveV2Interface, | ||||
|     ATokenV1Interface, | ||||
|     CTokenInterface | ||||
| } from "../interfaces.sol"; | ||||
| 
 | ||||
| import { TokenInterface } from "../../../common/interfaces.sol"; | ||||
| 
 | ||||
| contract AaveV2Helpers is protocolHelpers { | ||||
| 
 | ||||
|     struct AaveV2BorrowData { | ||||
|         AaveV2Interface aave; | ||||
|         uint length; | ||||
|         uint fee; | ||||
|         Protocol target; | ||||
|         TokenInterface[] tokens; | ||||
|         CTokenInterface[] ctokens; | ||||
|         uint[] amts; | ||||
|         uint[] rateModes; | ||||
|     } | ||||
| 
 | ||||
|     struct AaveV2PaybackData { | ||||
|         AaveV2Interface aave; | ||||
|         AaveV2DataProviderInterface aaveData; | ||||
|         uint length; | ||||
|         TokenInterface[] tokens; | ||||
|         uint[] amts; | ||||
|         uint[] rateModes; | ||||
|     } | ||||
| 
 | ||||
|     struct AaveV2WithdrawData { | ||||
|         AaveV2Interface aave; | ||||
|         AaveV2DataProviderInterface aaveData; | ||||
|         uint length; | ||||
|         TokenInterface[] tokens; | ||||
|         uint[] amts; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2BorrowOne( | ||||
|         AaveV2Interface aave, | ||||
|         uint fee, | ||||
|         Protocol target, | ||||
|         TokenInterface token, | ||||
|         CTokenInterface ctoken, | ||||
|         uint amt, | ||||
|         uint rateMode | ||||
|     ) internal returns (uint) { | ||||
|         if (amt > 0) { | ||||
|             bool isEth = address(token) == wethAddr; | ||||
|              | ||||
|             address _token = isEth ? ethAddr : address(token); | ||||
| 
 | ||||
|             if (amt == uint(-1)) { | ||||
|                 amt = getMaxBorrow(target, _token, ctoken, rateMode); | ||||
|             } | ||||
| 
 | ||||
|             (uint feeAmt, uint _amt) = calculateFee(amt, fee, true); | ||||
| 
 | ||||
|             aave.borrow(address(token), _amt, rateMode, getReferralCode, address(this)); | ||||
|             convertWethToEth(isEth, token, amt); | ||||
| 
 | ||||
|             transferFees(_token, feeAmt); | ||||
|         } | ||||
|         return amt; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2Borrow( | ||||
|         AaveV2BorrowData memory data | ||||
|     ) internal returns (uint[] memory) { | ||||
|         uint[] memory finalAmts = new uint[](data.length); | ||||
|         for (uint i = 0; i < data.length; i++) { | ||||
|             finalAmts[i] = _aaveV2BorrowOne( | ||||
|                 data.aave, | ||||
|                 data.fee, | ||||
|                 data.target, | ||||
|                 data.tokens[i], | ||||
|                 data.ctokens[i], | ||||
|                 data.amts[i], | ||||
|                 data.rateModes[i] | ||||
|             ); | ||||
|         } | ||||
|         return finalAmts; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2DepositOne( | ||||
|         AaveV2Interface aave, | ||||
|         AaveV2DataProviderInterface aaveData, | ||||
|         uint fee, | ||||
|         TokenInterface token, | ||||
|         uint amt | ||||
|     ) internal { | ||||
|         if (amt > 0) { | ||||
|             (uint feeAmt, uint _amt) = calculateFee(amt, fee, false); | ||||
| 
 | ||||
|             bool isEth = address(token) == wethAddr; | ||||
|             address _token = isEth ? ethAddr : address(token); | ||||
| 
 | ||||
|             transferFees(_token, feeAmt); | ||||
| 
 | ||||
|             convertEthToWeth(isEth, token, _amt); | ||||
| 
 | ||||
|             token.approve(address(aave), _amt); | ||||
| 
 | ||||
|             aave.deposit(address(token), _amt, address(this), getReferralCode); | ||||
| 
 | ||||
|             if (!getIsCollV2(aaveData, address(token))) { | ||||
|                 aave.setUserUseReserveAsCollateral(address(token), true); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2Deposit( | ||||
|         AaveV2Interface aave, | ||||
|         AaveV2DataProviderInterface aaveData, | ||||
|         uint length, | ||||
|         uint fee, | ||||
|         TokenInterface[] memory tokens, | ||||
|         uint[] memory amts | ||||
|     ) internal { | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             _aaveV2DepositOne(aave, aaveData, fee, tokens[i], amts[i]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2WithdrawOne( | ||||
|         AaveV2Interface aave, | ||||
|         AaveV2DataProviderInterface aaveData, | ||||
|         TokenInterface token, | ||||
|         uint amt | ||||
|     ) internal returns (uint _amt) { | ||||
|         if (amt > 0) { | ||||
|             bool isEth = address(token) == wethAddr; | ||||
| 
 | ||||
|             aave.withdraw(address(token), amt, address(this)); | ||||
| 
 | ||||
|             _amt = amt == uint(-1) ? getWithdrawBalanceV2(aaveData, address(token)) : amt; | ||||
| 
 | ||||
|             convertWethToEth(isEth, token, _amt); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2Withdraw( | ||||
|         AaveV2WithdrawData memory data | ||||
|     ) internal returns (uint[] memory) { | ||||
|         uint[] memory finalAmts = new uint[](data.length); | ||||
|         for (uint i = 0; i < data.length; i++) { | ||||
|             finalAmts[i] = _aaveV2WithdrawOne( | ||||
|                 data.aave, | ||||
|                 data.aaveData, | ||||
|                 data.tokens[i], | ||||
|                 data.amts[i] | ||||
|             ); | ||||
|         } | ||||
|         return finalAmts; | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2PaybackOne( | ||||
|         AaveV2Interface aave, | ||||
|         AaveV2DataProviderInterface aaveData, | ||||
|         TokenInterface token, | ||||
|         uint amt, | ||||
|         uint rateMode | ||||
|     ) internal returns (uint _amt) { | ||||
|         if (amt > 0) { | ||||
|             bool isEth = address(token) == wethAddr; | ||||
| 
 | ||||
|             _amt = amt == uint(-1) ? getPaybackBalanceV2(aaveData, address(token), rateMode) : amt; | ||||
| 
 | ||||
|             convertEthToWeth(isEth, token, _amt); | ||||
| 
 | ||||
|             token.approve(address(aave), _amt); | ||||
| 
 | ||||
|             aave.repay(address(token), _amt, rateMode, address(this)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _aaveV2Payback( | ||||
|         AaveV2PaybackData memory data | ||||
|     ) internal { | ||||
|         for (uint i = 0; i < data.length; i++) { | ||||
|             _aaveV2PaybackOne( | ||||
|                 data.aave, | ||||
|                 data.aaveData, | ||||
|                 data.tokens[i], | ||||
|                 data.amts[i], | ||||
|                 data.rateModes[i] | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										160
									
								
								contracts/mainnet/connectors/refinance/helpers/compound.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								contracts/mainnet/connectors/refinance/helpers/compound.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,160 @@ | |||
| pragma solidity ^0.7.0; | ||||
| pragma experimental ABIEncoderV2; | ||||
| 
 | ||||
| import { protocolHelpers } from "../helpers.sol"; | ||||
| 
 | ||||
| import { | ||||
|     ComptrollerInterface, | ||||
|     CTokenInterface, | ||||
|     CompoundMappingInterface, | ||||
|     CETHInterface | ||||
| } from "../interfaces.sol"; | ||||
| 
 | ||||
| import { TokenInterface } from "../../../common/interfaces.sol"; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| contract CompoundHelpers is protocolHelpers { | ||||
| 
 | ||||
|     struct CompoundBorrowData { | ||||
|         uint length; | ||||
|         uint fee; | ||||
|         Protocol target; | ||||
|         CTokenInterface[] ctokens; | ||||
|         TokenInterface[] tokens; | ||||
|         uint[] amts; | ||||
|         uint[] rateModes; | ||||
|     } | ||||
| 
 | ||||
|     function _compEnterMarkets(uint length, CTokenInterface[] memory ctokens) internal { | ||||
|         ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress); | ||||
|         address[] memory _cTokens = new address[](length); | ||||
| 
 | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             _cTokens[i] = address(ctokens[i]); | ||||
|         } | ||||
|         troller.enterMarkets(_cTokens); | ||||
|     } | ||||
| 
 | ||||
|     function _compBorrowOne( | ||||
|         uint fee, | ||||
|         CTokenInterface ctoken, | ||||
|         TokenInterface token, | ||||
|         uint amt, | ||||
|         Protocol target, | ||||
|         uint rateMode | ||||
|     ) internal returns (uint) { | ||||
|         if (amt > 0) { | ||||
|             address _token = address(token) == wethAddr ? ethAddr : address(token); | ||||
| 
 | ||||
|             if (amt == uint(-1)) { | ||||
|                 amt = getMaxBorrow(target, address(token), ctoken, rateMode); | ||||
|             } | ||||
| 
 | ||||
|             (uint feeAmt, uint _amt) = calculateFee(amt, fee, true); | ||||
| 
 | ||||
|             require(ctoken.borrow(_amt) == 0, "borrow-failed-collateral?"); | ||||
|             transferFees(_token, feeAmt); | ||||
|         } | ||||
|         return amt; | ||||
|     } | ||||
| 
 | ||||
|     function _compBorrow( | ||||
|         CompoundBorrowData memory data | ||||
|     ) internal returns (uint[] memory) { | ||||
|         uint[] memory finalAmts = new uint[](data.length); | ||||
|         for (uint i = 0; i < data.length; i++) { | ||||
|             finalAmts[i] = _compBorrowOne( | ||||
|                 data.fee,  | ||||
|                 data.ctokens[i],  | ||||
|                 data.tokens[i],  | ||||
|                 data.amts[i],  | ||||
|                 data.target,  | ||||
|                 data.rateModes[i] | ||||
|             ); | ||||
|         } | ||||
|         return finalAmts; | ||||
|     } | ||||
| 
 | ||||
|     function _compDepositOne(uint fee, CTokenInterface ctoken, TokenInterface token, uint amt) internal { | ||||
|         if (amt > 0) { | ||||
|             address _token = address(token) == wethAddr ? ethAddr : address(token); | ||||
| 
 | ||||
|             (uint feeAmt, uint _amt) = calculateFee(amt, fee, false); | ||||
| 
 | ||||
|             if (_token != ethAddr) { | ||||
|                 token.approve(address(ctoken), _amt); | ||||
|                 require(ctoken.mint(_amt) == 0, "deposit-failed"); | ||||
|             } else { | ||||
|                 CETHInterface(address(ctoken)).mint{value:_amt}(); | ||||
|             } | ||||
|             transferFees(_token, feeAmt); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _compDeposit( | ||||
|         uint length, | ||||
|         uint fee, | ||||
|         CTokenInterface[] memory ctokens, | ||||
|         TokenInterface[] memory tokens, | ||||
|         uint[] memory amts | ||||
|     ) internal { | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             _compDepositOne(fee, ctokens[i], tokens[i], amts[i]); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function _compWithdrawOne(CTokenInterface ctoken, TokenInterface token, uint amt) internal returns (uint) { | ||||
|         if (amt > 0) { | ||||
|             if (amt == uint(-1)) { | ||||
|                 bool isEth = address(token) == wethAddr; | ||||
|                 uint initalBal = isEth ? address(this).balance : token.balanceOf(address(this)); | ||||
|                 require(ctoken.redeem(ctoken.balanceOf(address(this))) == 0, "withdraw-failed"); | ||||
|                 uint finalBal = isEth ? address(this).balance : token.balanceOf(address(this)); | ||||
|                 amt = sub(finalBal, initalBal); | ||||
|             } else { | ||||
|                 require(ctoken.redeemUnderlying(amt) == 0, "withdraw-failed"); | ||||
|             } | ||||
|         } | ||||
|         return amt; | ||||
|     } | ||||
| 
 | ||||
|     function _compWithdraw( | ||||
|         uint length, | ||||
|         CTokenInterface[] memory ctokens, | ||||
|         TokenInterface[] memory tokens, | ||||
|         uint[] memory amts | ||||
|     ) internal returns(uint[] memory) { | ||||
|         uint[] memory finalAmts = new uint[](length); | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             finalAmts[i] = _compWithdrawOne(ctokens[i], tokens[i], amts[i]); | ||||
|         } | ||||
|         return finalAmts; | ||||
|     } | ||||
| 
 | ||||
|     function _compPaybackOne(CTokenInterface ctoken, TokenInterface token, uint amt) internal returns (uint) { | ||||
|         if (amt > 0) { | ||||
|             if (amt == uint(-1)) { | ||||
|                 amt = ctoken.borrowBalanceCurrent(address(this)); | ||||
|             } | ||||
|             if (address(token) != wethAddr) { | ||||
|                 token.approve(address(ctoken), amt); | ||||
|                 require(ctoken.repayBorrow(amt) == 0, "repay-failed."); | ||||
|             } else { | ||||
|                 CETHInterface(address(ctoken)).repayBorrow{value:amt}(); | ||||
|             } | ||||
|         } | ||||
|         return amt; | ||||
|     } | ||||
| 
 | ||||
|     function _compPayback( | ||||
|         uint length, | ||||
|         CTokenInterface[] memory ctokens, | ||||
|         TokenInterface[] memory tokens, | ||||
|         uint[] memory amts | ||||
|     ) internal { | ||||
|         for (uint i = 0; i < length; i++) { | ||||
|             _compPaybackOne(ctokens[i], tokens[i], amts[i]); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										113
									
								
								contracts/mainnet/connectors/refinance/interfaces.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								contracts/mainnet/connectors/refinance/interfaces.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,113 @@ | |||
| pragma solidity ^0.7.0; | ||||
| pragma experimental ABIEncoderV2; | ||||
| 
 | ||||
| // Compound Helpers | ||||
| interface CTokenInterface { | ||||
|     function mint(uint mintAmount) external returns (uint); | ||||
|     function redeem(uint redeemTokens) external returns (uint); | ||||
|     function borrow(uint borrowAmount) external returns (uint); | ||||
|     function repayBorrow(uint repayAmount) external returns (uint); | ||||
| 
 | ||||
|     function borrowBalanceCurrent(address account) external returns (uint); | ||||
|     function redeemUnderlying(uint redeemAmount) external returns (uint); | ||||
| 
 | ||||
|     function balanceOf(address owner) external view returns (uint256 balance); | ||||
| } | ||||
| 
 | ||||
| interface CETHInterface { | ||||
|     function mint() external payable; | ||||
|     function repayBorrow() external payable; | ||||
| } | ||||
| 
 | ||||
| interface CompoundMappingInterface { | ||||
|     function cTokenMapping(string calldata tokenId) external view returns (address); | ||||
|     function getMapping(string calldata tokenId) external view returns (address, address); | ||||
| } | ||||
| 
 | ||||
| interface ComptrollerInterface { | ||||
|     function enterMarkets(address[] calldata cTokens) external returns (uint[] memory); | ||||
| } | ||||
| // End Compound Helpers | ||||
| 
 | ||||
| // Aave v1 Helpers | ||||
| interface AaveV1Interface { | ||||
|     function deposit(address _reserve, uint256 _amount, uint16 _referralCode) external payable; | ||||
|     function redeemUnderlying( | ||||
|         address _reserve, | ||||
|         address payable _user, | ||||
|         uint256 _amount, | ||||
|         uint256 _aTokenBalanceAfterRedeem | ||||
|     ) external; | ||||
|      | ||||
|     function setUserUseReserveAsCollateral(address _reserve, bool _useAsCollateral) external; | ||||
|     function getUserReserveData(address _reserve, address _user) external view returns ( | ||||
|         uint256 currentATokenBalance, | ||||
|         uint256 currentBorrowBalance, | ||||
|         uint256 principalBorrowBalance, | ||||
|         uint256 borrowRateMode, | ||||
|         uint256 borrowRate, | ||||
|         uint256 liquidityRate, | ||||
|         uint256 originationFee, | ||||
|         uint256 variableBorrowIndex, | ||||
|         uint256 lastUpdateTimestamp, | ||||
|         bool usageAsCollateralEnabled | ||||
|     ); | ||||
|     function borrow(address _reserve, uint256 _amount, uint256 _interestRateMode, uint16 _referralCode) external; | ||||
|     function repay(address _reserve, uint256 _amount, address payable _onBehalfOf) external payable; | ||||
| } | ||||
| 
 | ||||
| interface AaveV1ProviderInterface { | ||||
|     function getLendingPool() external view returns (address); | ||||
|     function getLendingPoolCore() external view returns (address); | ||||
| } | ||||
| 
 | ||||
| interface AaveV1CoreInterface { | ||||
|     function getReserveATokenAddress(address _reserve) external view returns (address); | ||||
| } | ||||
| 
 | ||||
| interface ATokenV1Interface { | ||||
|     function redeem(uint256 _amount) external; | ||||
|     function balanceOf(address _user) external view returns(uint256); | ||||
|     function principalBalanceOf(address _user) external view returns(uint256); | ||||
| 
 | ||||
|     function allowance(address, address) external view returns (uint); | ||||
|     function approve(address, uint) external; | ||||
|     function transfer(address, uint) external returns (bool); | ||||
|     function transferFrom(address, address, uint) external returns (bool); | ||||
| } | ||||
| // End Aave v1 Helpers | ||||
| 
 | ||||
| // Aave v2 Helpers | ||||
| interface AaveV2Interface { | ||||
|     function deposit(address _asset, uint256 _amount, address _onBehalfOf, uint16 _referralCode) external; | ||||
|     function withdraw(address _asset, uint256 _amount, address _to) external; | ||||
|     function borrow( | ||||
|         address _asset, | ||||
|         uint256 _amount, | ||||
|         uint256 _interestRateMode, | ||||
|         uint16 _referralCode, | ||||
|         address _onBehalfOf | ||||
|     ) external; | ||||
|     function repay(address _asset, uint256 _amount, uint256 _rateMode, address _onBehalfOf) external; | ||||
|     function setUserUseReserveAsCollateral(address _asset, bool _useAsCollateral) external; | ||||
| } | ||||
| 
 | ||||
| interface AaveV2LendingPoolProviderInterface { | ||||
|     function getLendingPool() external view returns (address); | ||||
| } | ||||
| 
 | ||||
| // Aave Protocol Data Provider | ||||
| interface AaveV2DataProviderInterface { | ||||
|     function getUserReserveData(address _asset, address _user) external view returns ( | ||||
|         uint256 currentATokenBalance, | ||||
|         uint256 currentStableDebt, | ||||
|         uint256 currentVariableDebt, | ||||
|         uint256 principalStableDebt, | ||||
|         uint256 scaledVariableDebt, | ||||
|         uint256 stableBorrowRate, | ||||
|         uint256 liquidityRate, | ||||
|         uint40 stableRateLastUpdated, | ||||
|         bool usageAsCollateralEnabled | ||||
|     ); | ||||
| } | ||||
| // End Aave v2 Helpers | ||||
							
								
								
									
										339
									
								
								contracts/mainnet/connectors/refinance/main.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								contracts/mainnet/connectors/refinance/main.sol
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,339 @@ | |||
| pragma solidity ^0.7.0; | ||||
| pragma experimental ABIEncoderV2; | ||||
| 
 | ||||
| /** | ||||
|  * @title Refinance. | ||||
|  * @dev Refinancing. | ||||
|  */ | ||||
| 
 | ||||
| import { TokenInterface } from "../../common/interfaces.sol"; | ||||
| 
 | ||||
| import { | ||||
|     AaveV1ProviderInterface, | ||||
|     AaveV1Interface, | ||||
|     AaveV1CoreInterface, | ||||
|     AaveV2LendingPoolProviderInterface,  | ||||
|     AaveV2DataProviderInterface, | ||||
|     AaveV2Interface, | ||||
|     ComptrollerInterface, | ||||
|     CTokenInterface, | ||||
|     CompoundMappingInterface | ||||
| } from "./interfaces.sol"; | ||||
| 
 | ||||
| 
 | ||||
| import { AaveV1Helpers } from "./helpers/aaveV1.sol"; | ||||
| import { AaveV2Helpers } from "./helpers/aaveV2.sol"; | ||||
| import { CompoundHelpers } from "./helpers/compound.sol"; | ||||
| 
 | ||||
| 
 | ||||
| contract RefinanceResolver is CompoundHelpers, AaveV1Helpers, AaveV2Helpers { | ||||
| 
 | ||||
|     struct RefinanceData { | ||||
|         Protocol source; | ||||
|         Protocol target; | ||||
|         uint collateralFee; | ||||
|         uint debtFee; | ||||
|         address[] tokens; | ||||
|         string[] ctokenIds; | ||||
|         uint[] borrowAmts; | ||||
|         uint[] withdrawAmts; | ||||
|         uint[] borrowRateModes; | ||||
|         uint[] paybackRateModes; | ||||
|     } | ||||
| 
 | ||||
|     struct RefinanceInternalData { | ||||
|         AaveV2Interface aaveV2; | ||||
|         AaveV1Interface aaveV1; | ||||
|         AaveV1CoreInterface aaveCore; | ||||
|         AaveV2DataProviderInterface aaveData; | ||||
|         uint[] depositAmts; | ||||
|         uint[] paybackAmts; | ||||
|         TokenInterface[] tokens; | ||||
|         CTokenInterface[] _ctokens; | ||||
|     } | ||||
| 
 | ||||
|     function _refinance(RefinanceData calldata data)  | ||||
|         internal returns (string memory _eventName, bytes memory _eventParam) | ||||
|     { | ||||
| 
 | ||||
|         require(data.source != data.target, "source-and-target-unequal"); | ||||
| 
 | ||||
|         uint length = data.tokens.length; | ||||
| 
 | ||||
|         require(data.borrowAmts.length == length, "length-mismatch"); | ||||
|         require(data.withdrawAmts.length == length, "length-mismatch"); | ||||
|         require(data.borrowRateModes.length == length, "length-mismatch"); | ||||
|         require(data.paybackRateModes.length == length, "length-mismatch"); | ||||
|         require(data.ctokenIds.length == length, "length-mismatch"); | ||||
| 
 | ||||
|         RefinanceInternalData memory refinanceInternalData; | ||||
| 
 | ||||
|         refinanceInternalData.aaveV2 = AaveV2Interface(getAaveV2Provider.getLendingPool()); | ||||
|         refinanceInternalData.aaveV1 = AaveV1Interface(getAaveProvider.getLendingPool()); | ||||
|         refinanceInternalData.aaveCore = AaveV1CoreInterface(getAaveProvider.getLendingPoolCore()); | ||||
|         refinanceInternalData.aaveData = getAaveV2DataProvider; | ||||
| 
 | ||||
|         refinanceInternalData.depositAmts; | ||||
|         refinanceInternalData.paybackAmts; | ||||
| 
 | ||||
|         refinanceInternalData.tokens = getTokenInterfaces(length, data.tokens); | ||||
|         refinanceInternalData._ctokens = getCtokenInterfaces(length, data.ctokenIds); | ||||
| 
 | ||||
|         if (data.source == Protocol.Aave && data.target == Protocol.AaveV2) { | ||||
|             AaveV2BorrowData memory _aaveV2BorrowData; | ||||
| 
 | ||||
|             _aaveV2BorrowData.aave = refinanceInternalData.aaveV2; | ||||
|             _aaveV2BorrowData.length = length; | ||||
|             _aaveV2BorrowData.fee = data.debtFee; | ||||
|             _aaveV2BorrowData.target = data.source; | ||||
|             _aaveV2BorrowData.tokens = refinanceInternalData.tokens; | ||||
|             _aaveV2BorrowData.ctokens = refinanceInternalData._ctokens; | ||||
|             _aaveV2BorrowData.amts = data.borrowAmts; | ||||
|             _aaveV2BorrowData.rateModes = data.borrowRateModes; | ||||
|             { | ||||
|             refinanceInternalData.paybackAmts = _aaveV2Borrow(_aaveV2BorrowData); | ||||
|             _aaveV1Payback( | ||||
|                 refinanceInternalData.aaveV1, | ||||
|                 refinanceInternalData.aaveCore, | ||||
|                 length, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 refinanceInternalData.paybackAmts | ||||
|             ); | ||||
|             refinanceInternalData.depositAmts = _aaveV1Withdraw( | ||||
|                 refinanceInternalData.aaveV1, | ||||
|                 refinanceInternalData.aaveCore, | ||||
|                 length, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 data.withdrawAmts | ||||
|             ); | ||||
|             _aaveV2Deposit( | ||||
|                 refinanceInternalData.aaveV2, | ||||
|                 refinanceInternalData.aaveData, | ||||
|                 length, | ||||
|                 data.collateralFee, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 refinanceInternalData.depositAmts | ||||
|             ); | ||||
|             } | ||||
|         } else if (data.source == Protocol.Aave && data.target == Protocol.Compound) { | ||||
|             _compEnterMarkets(length, refinanceInternalData._ctokens); | ||||
| 
 | ||||
|             CompoundBorrowData memory _compoundBorrowData; | ||||
| 
 | ||||
|             _compoundBorrowData.length = length; | ||||
|             _compoundBorrowData.fee = data.debtFee; | ||||
|             _compoundBorrowData.target = data.source; | ||||
|             _compoundBorrowData.ctokens = refinanceInternalData._ctokens; | ||||
|             _compoundBorrowData.tokens = refinanceInternalData.tokens; | ||||
|             _compoundBorrowData.amts = data.borrowAmts; | ||||
|             _compoundBorrowData.rateModes = data.borrowRateModes; | ||||
| 
 | ||||
|             refinanceInternalData.paybackAmts = _compBorrow(_compoundBorrowData); | ||||
|              | ||||
|             _aaveV1Payback( | ||||
|                 refinanceInternalData.aaveV1, | ||||
|                 refinanceInternalData.aaveCore, | ||||
|                 length, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 refinanceInternalData.paybackAmts | ||||
|             ); | ||||
|             refinanceInternalData.depositAmts = _aaveV1Withdraw( | ||||
|                 refinanceInternalData.aaveV1, | ||||
|                 refinanceInternalData.aaveCore, | ||||
|                 length, | ||||
|                 refinanceInternalData.tokens,  | ||||
|                 data.withdrawAmts | ||||
|             ); | ||||
|             _compDeposit( | ||||
|                 length, | ||||
|                 data.collateralFee, | ||||
|                 refinanceInternalData._ctokens, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 refinanceInternalData.depositAmts | ||||
|             ); | ||||
|         } else if (data.source == Protocol.AaveV2 && data.target == Protocol.Aave) { | ||||
| 
 | ||||
|             AaveV1BorrowData memory _aaveV1BorrowData; | ||||
|             AaveV2PaybackData memory _aaveV2PaybackData; | ||||
|             AaveV2WithdrawData memory _aaveV2WithdrawData; | ||||
| 
 | ||||
|             { | ||||
|                 _aaveV1BorrowData.aave = refinanceInternalData.aaveV1; | ||||
|                 _aaveV1BorrowData.length = length; | ||||
|                 _aaveV1BorrowData.fee = data.debtFee; | ||||
|                 _aaveV1BorrowData.target = data.source; | ||||
|                 _aaveV1BorrowData.tokens = refinanceInternalData.tokens; | ||||
|                 _aaveV1BorrowData.ctokens = refinanceInternalData._ctokens; | ||||
|                 _aaveV1BorrowData.amts = data.borrowAmts; | ||||
|                 _aaveV1BorrowData.borrowRateModes = data.borrowRateModes; | ||||
|                 _aaveV1BorrowData.paybackRateModes = data.paybackRateModes; | ||||
| 
 | ||||
|                 refinanceInternalData.paybackAmts = _aaveV1Borrow(_aaveV1BorrowData); | ||||
|             } | ||||
|              | ||||
|             { | ||||
|                 _aaveV2PaybackData.aave = refinanceInternalData.aaveV2; | ||||
|                 _aaveV2PaybackData.aaveData = refinanceInternalData.aaveData; | ||||
|                 _aaveV2PaybackData.length = length; | ||||
|                 _aaveV2PaybackData.tokens = refinanceInternalData.tokens; | ||||
|                 _aaveV2PaybackData.amts = refinanceInternalData.paybackAmts; | ||||
|                 _aaveV2PaybackData.rateModes = data.paybackRateModes; | ||||
|                 _aaveV2Payback(_aaveV2PaybackData); | ||||
|             } | ||||
| 
 | ||||
|             { | ||||
|                 _aaveV2WithdrawData.aave = refinanceInternalData.aaveV2; | ||||
|                 _aaveV2WithdrawData.aaveData = refinanceInternalData.aaveData; | ||||
|                 _aaveV2WithdrawData.length = length; | ||||
|                 _aaveV2WithdrawData.tokens = refinanceInternalData.tokens; | ||||
|                 _aaveV2WithdrawData.amts = data.withdrawAmts; | ||||
|                 refinanceInternalData.depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData); | ||||
|             } | ||||
|             { | ||||
|                 AaveV1DepositData memory _aaveV1DepositData; | ||||
|                  | ||||
|                 _aaveV1DepositData.aave = refinanceInternalData.aaveV1; | ||||
|                 _aaveV1DepositData.aaveCore = refinanceInternalData.aaveCore; | ||||
|                 _aaveV1DepositData.length = length; | ||||
|                 _aaveV1DepositData.fee = data.collateralFee; | ||||
|                 _aaveV1DepositData.tokens = refinanceInternalData.tokens; | ||||
|                 _aaveV1DepositData.amts = refinanceInternalData.depositAmts; | ||||
| 
 | ||||
|                 _aaveV1Deposit(_aaveV1DepositData); | ||||
|             } | ||||
|         } else if (data.source == Protocol.AaveV2 && data.target == Protocol.Compound) { | ||||
|             _compEnterMarkets(length, refinanceInternalData._ctokens); | ||||
| 
 | ||||
|             { | ||||
|                 CompoundBorrowData memory _compoundBorrowData; | ||||
| 
 | ||||
|                 _compoundBorrowData.length = length; | ||||
|                 _compoundBorrowData.fee = data.debtFee; | ||||
|                 _compoundBorrowData.target = data.source; | ||||
|                 _compoundBorrowData.ctokens = refinanceInternalData._ctokens; | ||||
|                 _compoundBorrowData.tokens = refinanceInternalData.tokens; | ||||
|                 _compoundBorrowData.amts = data.borrowAmts; | ||||
|                 _compoundBorrowData.rateModes = data.borrowRateModes; | ||||
| 
 | ||||
|                 refinanceInternalData.paybackAmts = _compBorrow(_compoundBorrowData); | ||||
|             } | ||||
| 
 | ||||
|             AaveV2PaybackData memory _aaveV2PaybackData; | ||||
| 
 | ||||
|             _aaveV2PaybackData.aave = refinanceInternalData.aaveV2; | ||||
|             _aaveV2PaybackData.aaveData = refinanceInternalData.aaveData; | ||||
|             _aaveV2PaybackData.length = length; | ||||
|             _aaveV2PaybackData.tokens = refinanceInternalData.tokens; | ||||
|             _aaveV2PaybackData.amts = refinanceInternalData.paybackAmts; | ||||
|             _aaveV2PaybackData.rateModes = data.paybackRateModes; | ||||
|              | ||||
|             _aaveV2Payback(_aaveV2PaybackData); | ||||
| 
 | ||||
|             { | ||||
|                 AaveV2WithdrawData memory _aaveV2WithdrawData; | ||||
| 
 | ||||
|                 _aaveV2WithdrawData.aave = refinanceInternalData.aaveV2; | ||||
|                 _aaveV2WithdrawData.aaveData = refinanceInternalData.aaveData; | ||||
|                 _aaveV2WithdrawData.length = length; | ||||
|                 _aaveV2WithdrawData.tokens = refinanceInternalData.tokens; | ||||
|                 _aaveV2WithdrawData.amts = data.withdrawAmts; | ||||
|                 refinanceInternalData.depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData); | ||||
|             } | ||||
|             _compDeposit( | ||||
|                 length, | ||||
|                 data.collateralFee, | ||||
|                 refinanceInternalData._ctokens, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 refinanceInternalData.depositAmts | ||||
|             ); | ||||
|         } else if (data.source == Protocol.Compound && data.target == Protocol.Aave) { | ||||
| 
 | ||||
|             AaveV1BorrowData memory _aaveV1BorrowData; | ||||
| 
 | ||||
|             _aaveV1BorrowData.aave = refinanceInternalData.aaveV1; | ||||
|             _aaveV1BorrowData.length = length; | ||||
|             _aaveV1BorrowData.fee = data.debtFee; | ||||
|             _aaveV1BorrowData.target = data.source; | ||||
|             _aaveV1BorrowData.tokens = refinanceInternalData.tokens; | ||||
|             _aaveV1BorrowData.ctokens = refinanceInternalData._ctokens; | ||||
|             _aaveV1BorrowData.amts = data.borrowAmts; | ||||
|             _aaveV1BorrowData.borrowRateModes = data.borrowRateModes; | ||||
|             _aaveV1BorrowData.paybackRateModes = data.paybackRateModes; | ||||
|              | ||||
|             refinanceInternalData.paybackAmts = _aaveV1Borrow(_aaveV1BorrowData); | ||||
|             { | ||||
|             _compPayback( | ||||
|                 length, | ||||
|                 refinanceInternalData._ctokens, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 refinanceInternalData.paybackAmts | ||||
|             ); | ||||
|             refinanceInternalData.depositAmts = _compWithdraw( | ||||
|                 length, | ||||
|                 refinanceInternalData._ctokens, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 data.withdrawAmts | ||||
|             ); | ||||
|             } | ||||
| 
 | ||||
|             { | ||||
|                 AaveV1DepositData memory _aaveV1DepositData; | ||||
|                  | ||||
|                 _aaveV1DepositData.aave = refinanceInternalData.aaveV1; | ||||
|                 _aaveV1DepositData.aaveCore = refinanceInternalData.aaveCore; | ||||
|                 _aaveV1DepositData.length = length; | ||||
|                 _aaveV1DepositData.fee = data.collateralFee; | ||||
|                 _aaveV1DepositData.tokens = refinanceInternalData.tokens; | ||||
|                 _aaveV1DepositData.amts = refinanceInternalData.depositAmts; | ||||
| 
 | ||||
|                 _aaveV1Deposit(_aaveV1DepositData); | ||||
|             } | ||||
|         } else if (data.source == Protocol.Compound && data.target == Protocol.AaveV2) { | ||||
|             AaveV2BorrowData memory _aaveV2BorrowData; | ||||
| 
 | ||||
|             _aaveV2BorrowData.aave = refinanceInternalData.aaveV2; | ||||
|             _aaveV2BorrowData.length = length; | ||||
|             _aaveV2BorrowData.fee = data.debtFee; | ||||
|             _aaveV2BorrowData.target = data.source; | ||||
|             _aaveV2BorrowData.tokens = refinanceInternalData.tokens; | ||||
|             _aaveV2BorrowData.ctokens = refinanceInternalData._ctokens; | ||||
|             _aaveV2BorrowData.amts = data.borrowAmts; | ||||
|             _aaveV2BorrowData.rateModes = data.borrowRateModes; | ||||
|              | ||||
|             refinanceInternalData.paybackAmts = _aaveV2Borrow(_aaveV2BorrowData); | ||||
|             _compPayback(length, refinanceInternalData._ctokens, refinanceInternalData.tokens, refinanceInternalData.paybackAmts); | ||||
|             refinanceInternalData.depositAmts = _compWithdraw( | ||||
|                 length, | ||||
|                 refinanceInternalData._ctokens, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 data.withdrawAmts | ||||
|             ); | ||||
|             _aaveV2Deposit( | ||||
|                 refinanceInternalData.aaveV2, | ||||
|                 refinanceInternalData.aaveData, | ||||
|                 length, | ||||
|                 data.collateralFee, | ||||
|                 refinanceInternalData.tokens, | ||||
|                 refinanceInternalData.depositAmts | ||||
|             ); | ||||
|         } else { | ||||
|             revert("invalid-options"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * @dev Refinance | ||||
|      * @notice Refinancing between AaveV1, AaveV2 and Compound | ||||
|      * @param data refinance data. | ||||
|     */ | ||||
|     function refinance(RefinanceData calldata data)  | ||||
|         external payable returns (string memory _eventName, bytes memory _eventParam) { | ||||
|         (_eventName, _eventParam) = _refinance(data); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| contract ConnectV2Refinance is RefinanceResolver { | ||||
|     string public name = "Refinance-v1.0"; | ||||
| } | ||||
|  | @ -20,6 +20,7 @@ | |||
|     "INSTAPOOL-A": "0x5806Af7AB22E2916fA582Ff05731Bf7C682387B2", | ||||
|     "MAKERDAO-CLAIM-A": "0x2f8cBE650af98602a215b6482F2aD60893C5A4E8", | ||||
|     "WETH-A": "0x22075fa719eFb02Ca3cF298AFa9C974B7465E5D3", | ||||
|     "REFINANCE-A": "0x9eA34bE6dA51aa9F6408FeA79c946FDCFA424442" | ||||
|     "INST-A": "0x52C2C4a0db049255fF345EB9D3Fb1f555b7a924A" | ||||
|   }, | ||||
|   "137" : { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Thrilok kumar
						Thrilok kumar