dsa-connectors/contracts/mainnet/connectors/refinance/main.sol
2022-03-22 20:54:40 +05:30

340 lines
14 KiB
Solidity

//SPDX-License-Identifier: MIT
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.1";
}