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",
|
"INSTAPOOL-A": "0x5806Af7AB22E2916fA582Ff05731Bf7C682387B2",
|
||||||
"MAKERDAO-CLAIM-A": "0x2f8cBE650af98602a215b6482F2aD60893C5A4E8",
|
"MAKERDAO-CLAIM-A": "0x2f8cBE650af98602a215b6482F2aD60893C5A4E8",
|
||||||
"WETH-A": "0x22075fa719eFb02Ca3cF298AFa9C974B7465E5D3",
|
"WETH-A": "0x22075fa719eFb02Ca3cF298AFa9C974B7465E5D3",
|
||||||
|
"REFINANCE-A": "0x9eA34bE6dA51aa9F6408FeA79c946FDCFA424442"
|
||||||
"INST-A": "0x52C2C4a0db049255fF345EB9D3Fb1f555b7a924A"
|
"INST-A": "0x52C2C4a0db049255fF345EB9D3Fb1f555b7a924A"
|
||||||
},
|
},
|
||||||
"137" : {
|
"137" : {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user