mirror of
				https://github.com/Instadapp/dsa-connectors.git
				synced 2024-07-29 22:37:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			347 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
			
		
		
	
	
			347 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			Solidity
		
	
	
	
	
	
| //SPDX-License-Identifier: MIT
 | |
| pragma solidity ^0.7.0;
 | |
| import { DSMath } from "../../../common/math.sol";
 | |
| import { Basic } from "../../../common/basic.sol";
 | |
| import { TokenInterface, AccountInterface } from "../../../common/interfaces.sol";
 | |
| import { AaveInterface, AavePoolProviderInterface, AaveDataProviderInterface } from "./interface.sol";
 | |
| import "./events.sol";
 | |
| import "./interface.sol";
 | |
| 
 | |
| abstract contract Helper is DSMath, Basic {
 | |
| 	/**
 | |
| 	 * @dev Aave referal code
 | |
| 	 */
 | |
| 	uint16 internal constant referalCode = 3228;
 | |
| 
 | |
| 	/**
 | |
| 	 * @dev Aave Pool Provider
 | |
| 	 */
 | |
| 	AavePoolProviderInterface internal constant aaveProvider =
 | |
| 		AavePoolProviderInterface(0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb);
 | |
| 
 | |
| 	/**
 | |
| 	 * @dev Aave Protocol Data Provider
 | |
| 	 */
 | |
| 	AaveDataProviderInterface internal constant aaveData =
 | |
| 		AaveDataProviderInterface(0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654);
 | |
| 
 | |
| 	function getIsColl(address token, address user)
 | |
| 		internal
 | |
| 		view
 | |
| 		returns (bool isCol)
 | |
| 	{
 | |
| 		(, , , , , , , , isCol) = aaveData.getUserReserveData(token, user);
 | |
| 	}
 | |
| 
 | |
| 	struct ImportData {
 | |
| 		address[] _supplyTokens;
 | |
| 		address[] _borrowTokens;
 | |
| 		ATokenInterface[] aTokens;
 | |
| 		uint256[] supplyAmts;
 | |
| 		uint256[] variableBorrowAmts;
 | |
| 		uint256[] variableBorrowAmtsWithFee;
 | |
| 		uint256[] stableBorrowAmts;
 | |
| 		uint256[] stableBorrowAmtsWithFee;
 | |
| 		uint256[] totalBorrowAmts;
 | |
| 		uint256[] totalBorrowAmtsWithFee;
 | |
| 		bool convertStable;
 | |
| 	}
 | |
| 
 | |
| 	struct ImportInputData {
 | |
| 		address[] supplyTokens;
 | |
| 		address[] borrowTokens;
 | |
| 		bool convertStable;
 | |
| 		uint256[] flashLoanFees;
 | |
| 	}
 | |
| 
 | |
| 	struct SignedPermits {
 | |
| 		uint8[] v;
 | |
| 		bytes32[] r;
 | |
| 		bytes32[] s;
 | |
| 		uint256[] expiry;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| contract AaveHelpers is Helper {
 | |
| 	function getBorrowAmount(address _token, address userAccount)
 | |
| 		internal
 | |
| 		view
 | |
| 		returns (uint256 stableBorrow, uint256 variableBorrow)
 | |
| 	{
 | |
| 		(
 | |
| 			,
 | |
| 			address stableDebtTokenAddress,
 | |
| 			address variableDebtTokenAddress
 | |
| 		) = aaveData.getReserveTokensAddresses(_token);
 | |
| 
 | |
| 		stableBorrow = ATokenInterface(stableDebtTokenAddress).balanceOf(
 | |
| 			userAccount
 | |
| 		);
 | |
| 		variableBorrow = ATokenInterface(variableDebtTokenAddress).balanceOf(
 | |
| 			userAccount
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	function getBorrowAmounts(
 | |
| 		address userAccount,
 | |
| 		AaveInterface aave,
 | |
| 		ImportInputData memory inputData,
 | |
| 		ImportData memory data
 | |
| 	) internal returns (ImportData memory) {
 | |
| 		if (inputData.borrowTokens.length > 0) {
 | |
| 			data._borrowTokens = new address[](inputData.borrowTokens.length);
 | |
| 			data.variableBorrowAmts = new uint256[](
 | |
| 				inputData.borrowTokens.length
 | |
| 			);
 | |
| 			data.variableBorrowAmtsWithFee = new uint256[](
 | |
| 				inputData.borrowTokens.length
 | |
| 			);
 | |
| 			data.stableBorrowAmts = new uint256[](
 | |
| 				inputData.borrowTokens.length
 | |
| 			);
 | |
| 			data.stableBorrowAmtsWithFee = new uint256[](
 | |
| 				inputData.borrowTokens.length
 | |
| 			);
 | |
| 			data.totalBorrowAmts = new uint256[](inputData.borrowTokens.length);
 | |
| 			data.totalBorrowAmtsWithFee = new uint256[](
 | |
| 				inputData.borrowTokens.length
 | |
| 			);
 | |
| 			for (uint256 i = 0; i < inputData.borrowTokens.length; i++) {
 | |
| 				for (uint256 j = i; j < inputData.borrowTokens.length; j++) {
 | |
| 					if (j != i) {
 | |
| 						require(
 | |
| 							inputData.borrowTokens[i] !=
 | |
| 								inputData.borrowTokens[j],
 | |
| 							"token-repeated"
 | |
| 						);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			for (uint256 i = 0; i < inputData.borrowTokens.length; i++) {
 | |
| 				address _token = inputData.borrowTokens[i] == avaxAddr
 | |
| 					? wavaxAddr
 | |
| 					: inputData.borrowTokens[i];
 | |
| 				data._borrowTokens[i] = _token;
 | |
| 
 | |
| 				(
 | |
| 					data.stableBorrowAmts[i],
 | |
| 					data.variableBorrowAmts[i]
 | |
| 				) = getBorrowAmount(_token, userAccount);
 | |
| 
 | |
| 				if (data.variableBorrowAmts[i] != 0) {
 | |
| 					data.variableBorrowAmtsWithFee[i] = add(
 | |
| 						data.variableBorrowAmts[i],
 | |
| 						inputData.flashLoanFees[i]
 | |
| 					);
 | |
| 					data.stableBorrowAmtsWithFee[i] = data.stableBorrowAmts[i];
 | |
| 				} else {
 | |
| 					data.stableBorrowAmtsWithFee[i] = add(
 | |
| 						data.stableBorrowAmts[i],
 | |
| 						inputData.flashLoanFees[i]
 | |
| 					);
 | |
| 					data.variableBorrowAmtsWithFee[i] = data.variableBorrowAmts[
 | |
| 						i
 | |
| 					];
 | |
| 				}
 | |
| 
 | |
| 				data.totalBorrowAmts[i] = add(
 | |
| 					data.stableBorrowAmts[i],
 | |
| 					data.variableBorrowAmts[i]
 | |
| 				);
 | |
| 				data.totalBorrowAmtsWithFee[i] = add(
 | |
| 					data.stableBorrowAmtsWithFee[i],
 | |
| 					data.variableBorrowAmtsWithFee[i]
 | |
| 				);
 | |
| 
 | |
| 				if (data.totalBorrowAmts[i] > 0) {
 | |
| 					uint256 _amt = data.totalBorrowAmts[i];
 | |
| 					TokenInterface(_token).approve(address(aave), _amt);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return data;
 | |
| 	}
 | |
| 
 | |
| 	function getSupplyAmounts(
 | |
| 		address userAccount,
 | |
| 		ImportInputData memory inputData,
 | |
| 		ImportData memory data
 | |
| 	) internal view returns (ImportData memory) {
 | |
| 		data.supplyAmts = new uint256[](inputData.supplyTokens.length);
 | |
| 		data._supplyTokens = new address[](inputData.supplyTokens.length);
 | |
| 		data.aTokens = new ATokenInterface[](inputData.supplyTokens.length);
 | |
| 
 | |
| 		for (uint256 i = 0; i < inputData.supplyTokens.length; i++) {
 | |
| 			for (uint256 j = i; j < inputData.supplyTokens.length; j++) {
 | |
| 				if (j != i) {
 | |
| 					require(
 | |
| 						inputData.supplyTokens[i] != inputData.supplyTokens[j],
 | |
| 						"token-repeated"
 | |
| 					);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		for (uint256 i = 0; i < inputData.supplyTokens.length; i++) {
 | |
| 			address _token = inputData.supplyTokens[i] == avaxAddr
 | |
| 				? wavaxAddr
 | |
| 				: inputData.supplyTokens[i];
 | |
| 			(address _aToken, , ) = aaveData.getReserveTokensAddresses(_token);
 | |
| 			data._supplyTokens[i] = _token;
 | |
| 			data.aTokens[i] = ATokenInterface(_aToken);
 | |
| 			data.supplyAmts[i] = data.aTokens[i].balanceOf(userAccount);
 | |
| 		}
 | |
| 
 | |
| 		return data;
 | |
| 	}
 | |
| 
 | |
| 	function _paybackBehalfOne(
 | |
| 		AaveInterface aave,
 | |
| 		address token,
 | |
| 		uint256 amt,
 | |
| 		uint256 rateMode,
 | |
| 		address user
 | |
| 	) private {
 | |
| 		aave.repay(token, amt, rateMode, user);
 | |
| 	}
 | |
| 
 | |
| 	function _PaybackStable(
 | |
| 		uint256 _length,
 | |
| 		AaveInterface aave,
 | |
| 		address[] memory tokens,
 | |
| 		uint256[] memory amts,
 | |
| 		address user
 | |
| 	) internal {
 | |
| 		for (uint256 i = 0; i < _length; i++) {
 | |
| 			if (amts[i] > 0) {
 | |
| 				_paybackBehalfOne(aave, tokens[i], amts[i], 1, user);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function _PaybackVariable(
 | |
| 		uint256 _length,
 | |
| 		AaveInterface aave,
 | |
| 		address[] memory tokens,
 | |
| 		uint256[] memory amts,
 | |
| 		address user
 | |
| 	) internal {
 | |
| 		for (uint256 i = 0; i < _length; i++) {
 | |
| 			if (amts[i] > 0) {
 | |
| 				_paybackBehalfOne(aave, tokens[i], amts[i], 2, user);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function _PermitATokens(
 | |
| 		address userAccount,
 | |
| 		ATokenInterface[] memory aTokenContracts,
 | |
| 		address[] memory tokens,
 | |
| 		uint8[] memory v,
 | |
| 		bytes32[] memory r,
 | |
| 		bytes32[] memory s,
 | |
| 		uint256[] memory expiry
 | |
| 	) internal {
 | |
| 		for (uint256 i = 0; i < tokens.length; i++) {
 | |
| 			aTokenContracts[i].permit(
 | |
| 				userAccount,
 | |
| 				address(this),
 | |
| 				uint256(-1),
 | |
| 				expiry[i],
 | |
| 				v[i],
 | |
| 				r[i],
 | |
| 				s[i]
 | |
| 			);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function _TransferAtokens(
 | |
| 		uint256 _length,
 | |
| 		AaveInterface aave,
 | |
| 		ATokenInterface[] memory atokenContracts,
 | |
| 		uint256[] memory amts,
 | |
| 		address[] memory tokens,
 | |
| 		address userAccount
 | |
| 	) internal {
 | |
| 		for (uint256 i = 0; i < _length; i++) {
 | |
| 			if (amts[i] > 0) {
 | |
| 				uint256 _amt = amts[i];
 | |
| 				require(
 | |
| 					atokenContracts[i].transferFrom(
 | |
| 						userAccount,
 | |
| 						address(this),
 | |
| 						_amt
 | |
| 					),
 | |
| 					"allowance?"
 | |
| 				);
 | |
| 
 | |
| 				if (!getIsColl(tokens[i], address(this))) {
 | |
| 					aave.setUserUseReserveAsCollateral(tokens[i], true);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function _TransferAtokensWithCollateral(
 | |
| 		uint256 _length,
 | |
| 		AaveInterface aave,
 | |
| 		ATokenInterface[] memory atokenContracts,
 | |
| 		uint256[] memory amts,
 | |
| 		address[] memory tokens,
 | |
| 		bool[] memory colEnable,
 | |
| 		address userAccount
 | |
| 	) internal {
 | |
| 		for (uint256 i = 0; i < _length; i++) {
 | |
| 			if (amts[i] > 0) {
 | |
| 				uint256 _amt = amts[i];
 | |
| 				require(
 | |
| 					atokenContracts[i].transferFrom(
 | |
| 						userAccount,
 | |
| 						address(this),
 | |
| 						_amt
 | |
| 					),
 | |
| 					"allowance?"
 | |
| 				);
 | |
| 
 | |
| 				if (!getIsColl(tokens[i], address(this))) {
 | |
| 					aave.setUserUseReserveAsCollateral(tokens[i], colEnable[i]);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function _BorrowVariable(
 | |
| 		uint256 _length,
 | |
| 		AaveInterface aave,
 | |
| 		address[] memory tokens,
 | |
| 		uint256[] memory amts
 | |
| 	) internal {
 | |
| 		for (uint256 i = 0; i < _length; i++) {
 | |
| 			if (amts[i] > 0) {
 | |
| 				_borrowOne(aave, tokens[i], amts[i], 2);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function _BorrowStable(
 | |
| 		uint256 _length,
 | |
| 		AaveInterface aave,
 | |
| 		address[] memory tokens,
 | |
| 		uint256[] memory amts
 | |
| 	) internal {
 | |
| 		for (uint256 i = 0; i < _length; i++) {
 | |
| 			if (amts[i] > 0) {
 | |
| 				_borrowOne(aave, tokens[i], amts[i], 1);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	function _borrowOne(
 | |
| 		AaveInterface aave,
 | |
| 		address token,
 | |
| 		uint256 amt,
 | |
| 		uint256 rateMode
 | |
| 	) private {
 | |
| 		aave.borrow(token, amt, rateMode, referalCode, address(this));
 | |
| 	}
 | |
| }
 | 
