mirror of
https://github.com/Instadapp/dsa-connectors-old.git
synced 2024-07-29 22:47:46 +00:00
parent
2dba6e0603
commit
e1ad68a3eb
|
@ -1,153 +1,8 @@
|
|||
pragma solidity ^0.6.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC20 standard as defined in the EIP.
|
||||
*/
|
||||
interface IERC20 {
|
||||
/**
|
||||
* @dev Returns the amount of tokens in existence.
|
||||
*/
|
||||
function totalSupply() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the amount of tokens owned by `account`.
|
||||
*/
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Moves `amount` tokens from the caller's account to `recipient`.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function transfer(address recipient, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Returns the remaining number of tokens that `spender` will be
|
||||
* allowed to spend on behalf of `owner` through {transferFrom}. This is
|
||||
* zero by default.
|
||||
*
|
||||
* This value changes when {approve} or {transferFrom} are called.
|
||||
*/
|
||||
function allowance(address owner, address spender) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* IMPORTANT: Beware that changing an allowance with this method brings the risk
|
||||
* that someone may use both the old and the new allowance by unfortunate
|
||||
* transaction ordering. One possible solution to mitigate this race
|
||||
* condition is to first reduce the spender's allowance to 0 and set the
|
||||
* desired value afterwards:
|
||||
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||
*
|
||||
* Emits an {Approval} event.
|
||||
*/
|
||||
function approve(address spender, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Moves `amount` tokens from `sender` to `recipient` using the
|
||||
* allowance mechanism. `amount` is then deducted from the caller's
|
||||
* allowance.
|
||||
*
|
||||
* Returns a boolean value indicating whether the operation succeeded.
|
||||
*
|
||||
* Emits a {Transfer} event.
|
||||
*/
|
||||
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
|
||||
|
||||
/**
|
||||
* @dev Emitted when `value` tokens are moved from one account (`from`) to
|
||||
* another (`to`).
|
||||
*
|
||||
* Note that `value` may be zero.
|
||||
*/
|
||||
event Transfer(address indexed from, address indexed to, uint256 value);
|
||||
|
||||
/**
|
||||
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
|
||||
* a call to {approve}. `value` is the new allowance.
|
||||
*/
|
||||
event Approval(address indexed owner, address indexed spender, uint256 value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Collection of functions related to the address type
|
||||
*/
|
||||
library Address {
|
||||
function isContract(address account) internal view returns (bool) {
|
||||
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
|
||||
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
|
||||
// for accounts without code, i.e. `keccak256('')`
|
||||
bytes32 codehash;
|
||||
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly { codehash := extcodehash(account) }
|
||||
return (codehash != accountHash && codehash != 0x0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
|
||||
* `errorMessage` as a fallback revert reason when `target` reverts.
|
||||
*
|
||||
* _Available since v3.1._
|
||||
*/
|
||||
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
|
||||
return _functionCallWithValue(target, data, 0, errorMessage);
|
||||
}
|
||||
|
||||
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
|
||||
require(isContract(target), "Address: call to non-contract");
|
||||
|
||||
// solhint-disable-next-line avoid-low-level-calls
|
||||
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
|
||||
if (success) {
|
||||
return returndata;
|
||||
} else {
|
||||
// Look for revert reason and bubble it up if present
|
||||
if (returndata.length > 0) {
|
||||
// The easiest way to bubble the revert reason is using memory via assembly
|
||||
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
let returndata_size := mload(returndata)
|
||||
revert(add(32, returndata), returndata_size)
|
||||
}
|
||||
} else {
|
||||
revert(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
library SafeERC20 {
|
||||
using Address for address;
|
||||
|
||||
function safeTransfer(IERC20 token, address to, uint256 value) internal {
|
||||
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
|
||||
}
|
||||
|
||||
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
|
||||
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
|
||||
}
|
||||
|
||||
function _callOptionalReturn(IERC20 token, bytes memory data) private {
|
||||
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
|
||||
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
|
||||
// the target address contains contract code and also asserts for success in the low-level call.
|
||||
|
||||
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
|
||||
if (returndata.length > 0) { // Return data is optional
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
|
||||
}
|
||||
}
|
||||
}
|
||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
interface TokenInterface {
|
||||
function approve(address, uint256) external;
|
||||
|
@ -1342,40 +1197,31 @@ contract RefinanceResolver is MakerHelpers {
|
|||
uint paybackRateMode;
|
||||
}
|
||||
|
||||
struct CommonData {
|
||||
AaveV2Interface aaveV2;
|
||||
AaveV1Interface aaveV1;
|
||||
AaveV1CoreInterface aaveCore;
|
||||
AaveV2DataProviderInterface aaveData;
|
||||
uint length;
|
||||
TokenInterface[] tokens;
|
||||
CTokenInterface[] _ctokens;
|
||||
}
|
||||
|
||||
function refinance(RefinanceData calldata data) external payable {
|
||||
CommonData memory commonData;
|
||||
|
||||
require(data.source != data.target, "source-and-target-unequal");
|
||||
|
||||
uint length = data.tokens.length; // TODO: move to common struct
|
||||
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");
|
||||
|
||||
AaveV2Interface aaveV2 = AaveV2Interface(getAaveV2Provider().getLendingPool()); // TODO: move to common struct
|
||||
AaveV1Interface aaveV1 = AaveV1Interface(getAaveProvider().getLendingPool()); // TODO: move to common struct
|
||||
AaveV1CoreInterface aaveCore = AaveV1CoreInterface(getAaveProvider().getLendingPoolCore()); // TODO: move to common struct
|
||||
AaveV2DataProviderInterface aaveData = getAaveV2DataProvider(); // TODO: move to common struct
|
||||
AaveV2Interface aaveV2 = AaveV2Interface(getAaveV2Provider().getLendingPool());
|
||||
AaveV1Interface aaveV1 = AaveV1Interface(getAaveProvider().getLendingPool());
|
||||
AaveV1CoreInterface aaveCore = AaveV1CoreInterface(getAaveProvider().getLendingPoolCore());
|
||||
AaveV2DataProviderInterface aaveData = getAaveV2DataProvider();
|
||||
|
||||
uint[] memory depositAmts; // TODO: move to common struct
|
||||
uint[] memory paybackAmts; // TODO: move to common struct
|
||||
uint[] memory depositAmts;
|
||||
uint[] memory paybackAmts;
|
||||
|
||||
TokenInterface[] memory tokens = getTokenInterfaces(length, data.tokens); // TODO: move to common struct
|
||||
CTokenInterface[] memory _ctokens = getCtokenInterfaces(length, data.tokens); // TODO: move to common struct
|
||||
TokenInterface[] memory tokens = getTokenInterfaces(length, data.tokens);
|
||||
CTokenInterface[] memory _ctokens = getCtokenInterfaces(length, data.tokens);
|
||||
|
||||
if (data.source == Protocol.Aave && data.target == Protocol.AaveV2) {
|
||||
AaveV2BorrowData memory _aaveV2BorrowData;
|
||||
|
||||
AaveV2BorrowData memory _aaveV2BorrowData;
|
||||
if (data.target == Protocol.AaveV2) {
|
||||
_aaveV2BorrowData.aave = aaveV2;
|
||||
_aaveV2BorrowData.length = length;
|
||||
_aaveV2BorrowData.fee = data.debtFee;
|
||||
|
@ -1384,10 +1230,16 @@ contract RefinanceResolver is MakerHelpers {
|
|||
_aaveV2BorrowData.ctokens = _ctokens;
|
||||
_aaveV2BorrowData.amts = data.borrowAmts;
|
||||
_aaveV2BorrowData.rateModes = data.borrowRateModes;
|
||||
}
|
||||
|
||||
CompoundBorrowData memory _compoundBorrowData;
|
||||
if (data.target == Protocol.Compound) {
|
||||
paybackAmts = _aaveV2Borrow(_aaveV2BorrowData);
|
||||
_aaveV1Payback(aaveV1, aaveCore, length, tokens, paybackAmts);
|
||||
depositAmts = _aaveV1Withdraw(aaveV1, aaveCore, length, tokens, data.withdrawAmts);
|
||||
_aaveV2Deposit(aaveV2, aaveData, length, data.collateralFee, tokens, depositAmts);
|
||||
} else if (data.source == Protocol.Aave && data.target == Protocol.Compound) {
|
||||
_compEnterMarkets(length, _ctokens);
|
||||
|
||||
CompoundBorrowData memory _compoundBorrowData;
|
||||
|
||||
_compoundBorrowData.length = length;
|
||||
_compoundBorrowData.fee = data.debtFee;
|
||||
_compoundBorrowData.target = data.source;
|
||||
|
@ -1395,12 +1247,105 @@ contract RefinanceResolver is MakerHelpers {
|
|||
_compoundBorrowData.tokens = tokens;
|
||||
_compoundBorrowData.amts = data.borrowAmts;
|
||||
_compoundBorrowData.rateModes = data.borrowRateModes;
|
||||
}
|
||||
|
||||
AaveV1BorrowData memory _aaveV1BorrowData;
|
||||
AaveV1DepositData memory _aaveV1DepositData;
|
||||
|
||||
paybackAmts = _compBorrow(_compoundBorrowData);
|
||||
|
||||
_aaveV1Payback(aaveV1, aaveCore, length, tokens, paybackAmts);
|
||||
depositAmts = _aaveV1Withdraw(aaveV1, aaveCore, length, tokens, data.withdrawAmts);
|
||||
_compDeposit(length, data.collateralFee, _ctokens, tokens, depositAmts);
|
||||
} else if (data.source == Protocol.AaveV2 && data.target == Protocol.Aave) {
|
||||
|
||||
AaveV1BorrowData memory _aaveV1BorrowData;
|
||||
AaveV2PaybackData memory _aaveV2PaybackData;
|
||||
AaveV2WithdrawData memory _aaveV2WithdrawData;
|
||||
|
||||
{
|
||||
_aaveV1BorrowData.aave = aaveV1;
|
||||
_aaveV1BorrowData.length = length;
|
||||
_aaveV1BorrowData.fee = data.debtFee;
|
||||
_aaveV1BorrowData.target = data.source;
|
||||
_aaveV1BorrowData.tokens = tokens;
|
||||
_aaveV1BorrowData.ctokens = _ctokens;
|
||||
_aaveV1BorrowData.amts = data.borrowAmts;
|
||||
_aaveV1BorrowData.borrowRateModes = data.borrowRateModes;
|
||||
_aaveV1BorrowData.paybackRateModes = data.paybackRateModes;
|
||||
|
||||
paybackAmts = _aaveV1Borrow(_aaveV1BorrowData);
|
||||
}
|
||||
|
||||
{
|
||||
_aaveV2PaybackData.aave = aaveV2;
|
||||
_aaveV2PaybackData.aaveData = aaveData;
|
||||
_aaveV2PaybackData.length = length;
|
||||
_aaveV2PaybackData.tokens = tokens;
|
||||
_aaveV2PaybackData.amts = paybackAmts;
|
||||
_aaveV2PaybackData.rateModes = data.paybackRateModes;
|
||||
_aaveV2Payback(_aaveV2PaybackData);
|
||||
}
|
||||
|
||||
{
|
||||
_aaveV2WithdrawData.aave = aaveV2;
|
||||
_aaveV2WithdrawData.aaveData = aaveData;
|
||||
_aaveV2WithdrawData.length = length;
|
||||
_aaveV2WithdrawData.tokens = tokens;
|
||||
_aaveV2WithdrawData.amts = data.withdrawAmts;
|
||||
depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData);
|
||||
}
|
||||
{
|
||||
AaveV1DepositData memory _aaveV1DepositData;
|
||||
|
||||
if (data.target == Protocol.Aave) {
|
||||
_aaveV1DepositData.aave = aaveV1;
|
||||
_aaveV1DepositData.aaveCore = aaveCore;
|
||||
_aaveV1DepositData.length = length;
|
||||
_aaveV1DepositData.fee = data.collateralFee;
|
||||
_aaveV1DepositData.tokens = tokens;
|
||||
_aaveV1DepositData.amts = depositAmts;
|
||||
|
||||
_aaveV1Deposit(_aaveV1DepositData);
|
||||
}
|
||||
} else if (data.source == Protocol.AaveV2 && data.target == Protocol.Compound) {
|
||||
_compEnterMarkets(length, _ctokens);
|
||||
|
||||
{
|
||||
CompoundBorrowData memory _compoundBorrowData;
|
||||
|
||||
_compoundBorrowData.length = length;
|
||||
_compoundBorrowData.fee = data.debtFee;
|
||||
_compoundBorrowData.target = data.source;
|
||||
_compoundBorrowData.ctokens = _ctokens;
|
||||
_compoundBorrowData.tokens = tokens;
|
||||
_compoundBorrowData.amts = data.borrowAmts;
|
||||
_compoundBorrowData.rateModes = data.borrowRateModes;
|
||||
|
||||
paybackAmts = _compBorrow(_compoundBorrowData);
|
||||
}
|
||||
|
||||
AaveV2PaybackData memory _aaveV2PaybackData;
|
||||
|
||||
_aaveV2PaybackData.aave = aaveV2;
|
||||
_aaveV2PaybackData.aaveData = aaveData;
|
||||
_aaveV2PaybackData.length = length;
|
||||
_aaveV2PaybackData.tokens = tokens;
|
||||
_aaveV2PaybackData.amts = paybackAmts;
|
||||
_aaveV2PaybackData.rateModes = data.paybackRateModes;
|
||||
|
||||
_aaveV2Payback(_aaveV2PaybackData);
|
||||
|
||||
{
|
||||
AaveV2WithdrawData memory _aaveV2WithdrawData;
|
||||
|
||||
_aaveV2WithdrawData.aave = aaveV2;
|
||||
_aaveV2WithdrawData.aaveData = aaveData;
|
||||
_aaveV2WithdrawData.length = length;
|
||||
_aaveV2WithdrawData.tokens = tokens;
|
||||
_aaveV2WithdrawData.amts = data.withdrawAmts;
|
||||
depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData);
|
||||
}
|
||||
_compDeposit(length, data.collateralFee, _ctokens, tokens, depositAmts);
|
||||
} else if (data.source == Protocol.Compound && data.target == Protocol.Aave) {
|
||||
|
||||
AaveV1BorrowData memory _aaveV1BorrowData;
|
||||
|
||||
_aaveV1BorrowData.aave = aaveV1;
|
||||
_aaveV1BorrowData.length = length;
|
||||
_aaveV1BorrowData.fee = data.debtFee;
|
||||
|
@ -1410,63 +1355,37 @@ contract RefinanceResolver is MakerHelpers {
|
|||
_aaveV1BorrowData.amts = data.borrowAmts;
|
||||
_aaveV1BorrowData.borrowRateModes = data.borrowRateModes;
|
||||
_aaveV1BorrowData.paybackRateModes = data.paybackRateModes;
|
||||
|
||||
_aaveV1DepositData.aave = aaveV1;
|
||||
_aaveV1DepositData.aaveCore = aaveCore;
|
||||
_aaveV1DepositData.length = length;
|
||||
_aaveV1DepositData.fee = data.collateralFee;
|
||||
_aaveV1DepositData.tokens = tokens;
|
||||
_aaveV1DepositData.amts = depositAmts;
|
||||
}
|
||||
|
||||
AaveV2PaybackData memory _aaveV2PaybackData;
|
||||
AaveV2WithdrawData memory _aaveV2WithdrawData;
|
||||
if (data.source == Protocol.AaveV2) {
|
||||
_aaveV2PaybackData.aave = aaveV2;
|
||||
_aaveV2PaybackData.aaveData = aaveData;
|
||||
_aaveV2PaybackData.length = length;
|
||||
_aaveV2PaybackData.tokens = tokens;
|
||||
_aaveV2PaybackData.amts = paybackAmts;
|
||||
_aaveV2PaybackData.rateModes = data.paybackRateModes;
|
||||
|
||||
_aaveV2WithdrawData.aave = aaveV2;
|
||||
_aaveV2WithdrawData.aaveData = aaveData;
|
||||
_aaveV2WithdrawData.length = length;
|
||||
_aaveV2WithdrawData.tokens = tokens;
|
||||
_aaveV2WithdrawData.amts = data.withdrawAmts;
|
||||
}
|
||||
|
||||
if (data.source == Protocol.Aave && data.target == Protocol.AaveV2) {
|
||||
paybackAmts = _aaveV2Borrow(_aaveV2BorrowData); // TODO: pass common struct + RefinanceData calldata data and refactor in the common function
|
||||
_aaveV1Payback(aaveV1, aaveCore, length, tokens, paybackAmts);
|
||||
depositAmts = _aaveV1Withdraw(aaveV1, aaveCore, length, tokens, data.withdrawAmts);
|
||||
_aaveV2Deposit(aaveV2, aaveData, length, data.collateralFee, tokens, depositAmts);
|
||||
} else if (data.source == Protocol.Aave && data.target == Protocol.Compound) {
|
||||
_compEnterMarkets(length, _ctokens);
|
||||
|
||||
paybackAmts = _compBorrow(_compoundBorrowData);
|
||||
_aaveV1Payback(aaveV1, aaveCore, length, tokens, paybackAmts);
|
||||
depositAmts = _aaveV1Withdraw(aaveV1, aaveCore, length, tokens, data.withdrawAmts);
|
||||
_compDeposit(length, data.collateralFee, _ctokens, tokens, depositAmts);
|
||||
} else if (data.source == Protocol.AaveV2 && data.target == Protocol.Aave) {
|
||||
paybackAmts = _aaveV1Borrow(_aaveV1BorrowData);
|
||||
_aaveV2Payback(_aaveV2PaybackData);
|
||||
depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData);
|
||||
|
||||
_aaveV1Deposit(_aaveV1DepositData);
|
||||
} else if (data.source == Protocol.AaveV2 && data.target == Protocol.Compound) {
|
||||
_compEnterMarkets(length, _ctokens);
|
||||
|
||||
paybackAmts = _compBorrow(_compoundBorrowData);
|
||||
_aaveV2Payback(_aaveV2PaybackData);
|
||||
depositAmts = _aaveV2Withdraw(_aaveV2WithdrawData);
|
||||
_compDeposit(length, data.collateralFee, _ctokens, tokens, depositAmts);
|
||||
} else if (data.source == Protocol.Compound && data.target == Protocol.Aave) {
|
||||
|
||||
paybackAmts = _aaveV1Borrow(_aaveV1BorrowData);
|
||||
{
|
||||
_compPayback(length, _ctokens, tokens, paybackAmts);
|
||||
depositAmts = _compWithdraw(length, _ctokens, tokens, data.withdrawAmts);
|
||||
_aaveV1Deposit(_aaveV1DepositData);
|
||||
}
|
||||
|
||||
{
|
||||
AaveV1DepositData memory _aaveV1DepositData;
|
||||
|
||||
_aaveV1DepositData.aave = aaveV1;
|
||||
_aaveV1DepositData.aaveCore = aaveCore;
|
||||
_aaveV1DepositData.length = length;
|
||||
_aaveV1DepositData.fee = data.collateralFee;
|
||||
_aaveV1DepositData.tokens = tokens;
|
||||
_aaveV1DepositData.amts = depositAmts;
|
||||
|
||||
_aaveV1Deposit(_aaveV1DepositData);
|
||||
}
|
||||
} else if (data.source == Protocol.Compound && data.target == Protocol.AaveV2) {
|
||||
AaveV2BorrowData memory _aaveV2BorrowData;
|
||||
|
||||
_aaveV2BorrowData.aave = aaveV2;
|
||||
_aaveV2BorrowData.length = length;
|
||||
_aaveV2BorrowData.fee = data.debtFee;
|
||||
_aaveV2BorrowData.target = data.source;
|
||||
_aaveV2BorrowData.tokens = tokens;
|
||||
_aaveV2BorrowData.ctokens = _ctokens;
|
||||
_aaveV2BorrowData.amts = data.borrowAmts;
|
||||
_aaveV2BorrowData.rateModes = data.borrowRateModes;
|
||||
|
||||
paybackAmts = _aaveV2Borrow(_aaveV2BorrowData);
|
||||
_compPayback(length, _ctokens, tokens, paybackAmts);
|
||||
depositAmts = _compWithdraw(length, _ctokens, tokens, data.withdrawAmts);
|
||||
|
@ -1546,5 +1465,5 @@ contract RefinanceResolver is MakerHelpers {
|
|||
}
|
||||
|
||||
contract ConnectRefinance is RefinanceResolver {
|
||||
string public name = "Refinance-v1.1";
|
||||
string public name = "Refinance-v1";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user