mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
remove uni-v2, compound-import
This commit is contained in:
parent
e31b77e0b2
commit
5e09509137
|
@ -1,14 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.6;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
contract Events {
|
|
||||||
event LogCompoundImport(
|
|
||||||
address indexed user,
|
|
||||||
address[] ctokens,
|
|
||||||
string[] supplyIds,
|
|
||||||
string[] borrowIds,
|
|
||||||
uint256[] supplyAmts,
|
|
||||||
uint256[] borrowAmts
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,222 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.6;
|
|
||||||
|
|
||||||
import { DSMath } from "../../common/math.sol";
|
|
||||||
import { Basic } from "../../common/basic.sol";
|
|
||||||
import { TokenInterface, AccountInterface } from "../../common/interfaces.sol";
|
|
||||||
import { ComptrollerInterface, CompoundMappingInterface, CETHInterface, CTokenInterface } from "./interface.sol";
|
|
||||||
|
|
||||||
abstract contract Helpers is DSMath, Basic {
|
|
||||||
/**
|
|
||||||
* @dev Compound CEth
|
|
||||||
*/
|
|
||||||
CETHInterface internal constant cEth =
|
|
||||||
CETHInterface(0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Compound Comptroller
|
|
||||||
*/
|
|
||||||
ComptrollerInterface internal constant troller =
|
|
||||||
ComptrollerInterface(0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Compound Mapping
|
|
||||||
*/
|
|
||||||
CompoundMappingInterface internal constant compMapping =
|
|
||||||
CompoundMappingInterface(0xe7a85d0adDB972A4f0A4e57B698B37f171519e88);
|
|
||||||
|
|
||||||
struct ImportData {
|
|
||||||
address[] cTokens; // is the list of all tokens the user has interacted with (supply/borrow) -> used to enter markets
|
|
||||||
uint256[] borrowAmts;
|
|
||||||
uint256[] supplyAmts;
|
|
||||||
address[] borrowTokens;
|
|
||||||
address[] supplyTokens;
|
|
||||||
CTokenInterface[] borrowCtokens;
|
|
||||||
CTokenInterface[] supplyCtokens;
|
|
||||||
address[] supplyCtokensAddr;
|
|
||||||
address[] borrowCtokensAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ImportInputData {
|
|
||||||
address userAccount;
|
|
||||||
string[] supplyIds;
|
|
||||||
string[] borrowIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev enter compound market
|
|
||||||
* @param _cotkens array of ctoken addresses to enter compound market
|
|
||||||
*/
|
|
||||||
function _enterMarkets(address[] memory _cotkens) internal {
|
|
||||||
troller.enterMarkets(_cotkens);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contract CompoundHelper is Helpers {
|
|
||||||
/**
|
|
||||||
* @notice fetch the borrow details of the user
|
|
||||||
* @dev approve the cToken to spend (borrowed amount of) tokens to allow for repaying later
|
|
||||||
* @param _importInputData the struct containing borrowIds of the users borrowed tokens
|
|
||||||
* @param data struct used to store the final data on which the CompoundHelper contract functions operate
|
|
||||||
* @return ImportData the final value of param data
|
|
||||||
*/
|
|
||||||
function getBorrowAmounts(
|
|
||||||
ImportInputData memory _importInputData,
|
|
||||||
ImportData memory data
|
|
||||||
) internal returns (ImportData memory) {
|
|
||||||
if (_importInputData.borrowIds.length > 0) {
|
|
||||||
// initialize arrays for borrow data
|
|
||||||
uint256 _length = _importInputData.borrowIds.length;
|
|
||||||
data.borrowTokens = new address[](_length);
|
|
||||||
data.borrowCtokens = new CTokenInterface[](_length);
|
|
||||||
data.borrowCtokensAddr = new address[](_length);
|
|
||||||
data.borrowAmts = new uint256[](_length);
|
|
||||||
|
|
||||||
// populate the arrays with borrow tokens, cToken addresses and instances, and borrow amounts
|
|
||||||
for (uint256 i; i < _length; i++) {
|
|
||||||
(address _token, address _cToken) = compMapping.getMapping(
|
|
||||||
_importInputData.borrowIds[i]
|
|
||||||
);
|
|
||||||
|
|
||||||
require(
|
|
||||||
_token != address(0) && _cToken != address(0),
|
|
||||||
"ctoken mapping not found"
|
|
||||||
);
|
|
||||||
|
|
||||||
data.cTokens[i] = _cToken;
|
|
||||||
|
|
||||||
data.borrowTokens[i] = _token;
|
|
||||||
data.borrowCtokens[i] = CTokenInterface(_cToken);
|
|
||||||
data.borrowCtokensAddr[i] = _cToken;
|
|
||||||
data.borrowAmts[i] = data.borrowCtokens[i].borrowBalanceCurrent(
|
|
||||||
_importInputData.userAccount
|
|
||||||
);
|
|
||||||
|
|
||||||
// give the resp. cToken address approval to spend tokens
|
|
||||||
if (_token != ethAddr && data.borrowAmts[i] > 0) {
|
|
||||||
// will be required when repaying the borrow amount on behalf of the user
|
|
||||||
TokenInterface(_token).approve(_cToken, data.borrowAmts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice fetch the supply details of the user
|
|
||||||
* @dev only reads data from blockchain hence view
|
|
||||||
* @param _importInputData the struct containing supplyIds of the users supplied tokens
|
|
||||||
* @param data struct used to store the final data on which the CompoundHelper contract functions operate
|
|
||||||
* @return ImportData the final value of param data
|
|
||||||
*/
|
|
||||||
function getSupplyAmounts(
|
|
||||||
ImportInputData memory _importInputData,
|
|
||||||
ImportData memory data
|
|
||||||
) internal view returns (ImportData memory) {
|
|
||||||
// initialize arrays for supply data
|
|
||||||
uint256 _length = _importInputData.supplyIds.length;
|
|
||||||
data.supplyTokens = new address[](_length);
|
|
||||||
data.supplyCtokens = new CTokenInterface[](_length);
|
|
||||||
data.supplyCtokensAddr = new address[](_length);
|
|
||||||
data.supplyAmts = new uint256[](_length);
|
|
||||||
|
|
||||||
// populate arrays with supply data (supply tokens address, cToken addresses, cToken instances and supply amounts)
|
|
||||||
for (uint256 i; i < _length; i++) {
|
|
||||||
(address _token, address _cToken) = compMapping.getMapping(
|
|
||||||
_importInputData.supplyIds[i]
|
|
||||||
);
|
|
||||||
|
|
||||||
require(
|
|
||||||
_token != address(0) && _cToken != address(0),
|
|
||||||
"ctoken mapping not found"
|
|
||||||
);
|
|
||||||
|
|
||||||
uint256 _supplyIndex = add(i, _importInputData.borrowIds.length);
|
|
||||||
data.cTokens[_supplyIndex] = _cToken;
|
|
||||||
|
|
||||||
data.supplyTokens[i] = _token;
|
|
||||||
data.supplyCtokens[i] = CTokenInterface(_cToken);
|
|
||||||
data.supplyCtokensAddr[i] = (_cToken);
|
|
||||||
data.supplyAmts[i] = data.supplyCtokens[i].balanceOf(
|
|
||||||
_importInputData.userAccount
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice repays the debt taken by user on Compound on its behalf to free its collateral for transfer
|
|
||||||
* @dev uses the cEth contract for ETH repays, otherwise the general cToken interface
|
|
||||||
* @param _userAccount the user address for which debt is to be repayed
|
|
||||||
* @param _cTokenContracts array containing all interfaces to the cToken contracts in which the user has debt positions
|
|
||||||
* @param _borrowAmts array containing the amount borrowed for each token
|
|
||||||
*/
|
|
||||||
function _repayUserDebt(
|
|
||||||
address _userAccount,
|
|
||||||
CTokenInterface[] memory _cTokenContracts,
|
|
||||||
uint256[] memory _borrowAmts
|
|
||||||
) internal {
|
|
||||||
for (uint256 i; i < _cTokenContracts.length; i++) {
|
|
||||||
if (_borrowAmts[i] > 0) {
|
|
||||||
if (address(_cTokenContracts[i]) == address(cEth))
|
|
||||||
cEth.repayBorrowBehalf{ value: _borrowAmts[i] }(
|
|
||||||
_userAccount
|
|
||||||
);
|
|
||||||
else
|
|
||||||
require(
|
|
||||||
_cTokenContracts[i].repayBorrowBehalf(
|
|
||||||
_userAccount,
|
|
||||||
_borrowAmts[i]
|
|
||||||
) == 0,
|
|
||||||
"repayOnBehalf-failed"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice used to transfer user's supply position on Compound to DSA
|
|
||||||
* @dev uses the transferFrom token in cToken contracts to transfer positions, requires approval from user first
|
|
||||||
* @param _userAccount address of the user account whose position is to be transferred
|
|
||||||
* @param _cTokenContracts array containing all interfaces to the cToken contracts in which the user has supply positions
|
|
||||||
* @param _amts array containing the amount supplied for each token
|
|
||||||
*/
|
|
||||||
function _transferTokensToDsa(
|
|
||||||
address _userAccount,
|
|
||||||
CTokenInterface[] memory _cTokenContracts,
|
|
||||||
uint256[] memory _amts
|
|
||||||
) internal {
|
|
||||||
for (uint256 i; i < _cTokenContracts.length; i++)
|
|
||||||
if (_amts[i] > 0)
|
|
||||||
require(
|
|
||||||
_cTokenContracts[i].transferFrom(
|
|
||||||
_userAccount,
|
|
||||||
address(this),
|
|
||||||
_amts[i]
|
|
||||||
),
|
|
||||||
"ctoken-transfer-failed-allowance?"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice borrows the user's debt positions from Compound via DSA, so that its debt positions get imported to DSA
|
|
||||||
* @dev actually borrow some extra amount than the original position to cover the flash loan fee
|
|
||||||
* @param _cTokenContracts array containing all interfaces to the cToken contracts in which the user has debt positions
|
|
||||||
* @param _amts array containing the amounts the user had borrowed originally from Compound plus the flash loan fee
|
|
||||||
* @param _flashLoanFees flash loan fee (in percentage and scaled up to 10**2)
|
|
||||||
*/
|
|
||||||
function _borrowDebtPosition(
|
|
||||||
CTokenInterface[] memory _cTokenContracts,
|
|
||||||
uint256[] memory _amts,
|
|
||||||
uint256[] memory _flashLoanFees
|
|
||||||
) internal {
|
|
||||||
for (uint256 i; i < _cTokenContracts.length; i++)
|
|
||||||
if (_amts[i] > 0)
|
|
||||||
require(
|
|
||||||
_cTokenContracts[i].borrow(
|
|
||||||
add(_amts[i], _flashLoanFees[i])
|
|
||||||
) == 0,
|
|
||||||
"borrow-failed-collateral?"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,100 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.6;
|
|
||||||
|
|
||||||
interface TokenInterface {
|
|
||||||
function balanceOf(address) external view returns (uint256);
|
|
||||||
|
|
||||||
function allowance(address, address) external view returns (uint256);
|
|
||||||
|
|
||||||
function approve(address, uint256) external;
|
|
||||||
|
|
||||||
function transfer(address, uint256) external returns (bool);
|
|
||||||
|
|
||||||
function transferFrom(
|
|
||||||
address,
|
|
||||||
address,
|
|
||||||
uint256
|
|
||||||
) external returns (bool);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CTokenInterface {
|
|
||||||
function mint(uint256 mintAmount) external returns (uint256);
|
|
||||||
|
|
||||||
function redeem(uint256 redeemTokens) external returns (uint256);
|
|
||||||
|
|
||||||
function borrow(uint256 borrowAmount) external returns (uint256);
|
|
||||||
|
|
||||||
function repayBorrow(uint256 repayAmount) external returns (uint256);
|
|
||||||
|
|
||||||
function repayBorrowBehalf(address borrower, uint256 repayAmount)
|
|
||||||
external
|
|
||||||
returns (uint256); // For ERC20
|
|
||||||
|
|
||||||
function liquidateBorrow(
|
|
||||||
address borrower,
|
|
||||||
uint256 repayAmount,
|
|
||||||
address cTokenCollateral
|
|
||||||
) external returns (uint256);
|
|
||||||
|
|
||||||
function borrowBalanceCurrent(address account) external returns (uint256);
|
|
||||||
|
|
||||||
function redeemUnderlying(uint256 redeemAmount) external returns (uint256);
|
|
||||||
|
|
||||||
function exchangeRateCurrent() external returns (uint256);
|
|
||||||
|
|
||||||
function balanceOf(address owner) external view returns (uint256 balance);
|
|
||||||
|
|
||||||
function transferFrom(
|
|
||||||
address,
|
|
||||||
address,
|
|
||||||
uint256
|
|
||||||
) external returns (bool);
|
|
||||||
|
|
||||||
function allowance(address, address) external view returns (uint256);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CETHInterface {
|
|
||||||
function mint() external payable;
|
|
||||||
|
|
||||||
function repayBorrow() external payable;
|
|
||||||
|
|
||||||
function repayBorrowBehalf(address borrower) external payable;
|
|
||||||
|
|
||||||
function liquidateBorrow(address borrower, address cTokenCollateral)
|
|
||||||
external
|
|
||||||
payable;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ComptrollerInterface {
|
|
||||||
function enterMarkets(address[] calldata cTokens)
|
|
||||||
external
|
|
||||||
returns (uint256[] memory);
|
|
||||||
|
|
||||||
function exitMarket(address cTokenAddress) external returns (uint256);
|
|
||||||
|
|
||||||
function getAssetsIn(address account)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (address[] memory);
|
|
||||||
|
|
||||||
function getAccountLiquidity(address account)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (
|
|
||||||
uint256,
|
|
||||||
uint256,
|
|
||||||
uint256
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CompoundMappingInterface {
|
|
||||||
function cTokenMapping(string calldata tokenId)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (address);
|
|
||||||
|
|
||||||
function getMapping(string calldata tokenId)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (address, address);
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.6;
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @title Compound-Import.
|
|
||||||
* @dev Lending & Borrowing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { TokenInterface, AccountInterface } from "../../common/interfaces.sol";
|
|
||||||
import { CompoundHelper } from "./helpers.sol";
|
|
||||||
import { Events } from "./events.sol";
|
|
||||||
|
|
||||||
contract CompoundImportResolver is CompoundHelper {
|
|
||||||
/**
|
|
||||||
* @notice this function performs the import of user's Compound positions into its DSA
|
|
||||||
* @dev called internally by the importCompound and migrateCompound functions
|
|
||||||
* @param _importInputData the struct containing borrowIds of the users borrowed tokens
|
|
||||||
* @param _flashLoanFees list of flash loan fees
|
|
||||||
*/
|
|
||||||
function _importCompound(
|
|
||||||
ImportInputData memory _importInputData,
|
|
||||||
uint256[] memory _flashLoanFees
|
|
||||||
) internal returns (string memory _eventName, bytes memory _eventParam) {
|
|
||||||
require(
|
|
||||||
AccountInterface(address(this)).isAuth(
|
|
||||||
_importInputData.userAccount
|
|
||||||
),
|
|
||||||
"user-account-not-auth"
|
|
||||||
);
|
|
||||||
|
|
||||||
require(_importInputData.supplyIds.length > 0, "0-length-not-allowed");
|
|
||||||
|
|
||||||
ImportData memory data;
|
|
||||||
|
|
||||||
uint256 _length = add(
|
|
||||||
_importInputData.supplyIds.length,
|
|
||||||
_importInputData.borrowIds.length
|
|
||||||
);
|
|
||||||
data.cTokens = new address[](_length);
|
|
||||||
|
|
||||||
// get info about all borrowings and lendings by the user on Compound
|
|
||||||
data = getBorrowAmounts(_importInputData, data);
|
|
||||||
data = getSupplyAmounts(_importInputData, data);
|
|
||||||
|
|
||||||
_enterMarkets(data.cTokens);
|
|
||||||
|
|
||||||
// pay back user's debt using flash loan funds
|
|
||||||
_repayUserDebt(
|
|
||||||
_importInputData.userAccount,
|
|
||||||
data.borrowCtokens,
|
|
||||||
data.borrowAmts
|
|
||||||
);
|
|
||||||
|
|
||||||
// transfer user's tokens to DSA
|
|
||||||
_transferTokensToDsa(
|
|
||||||
_importInputData.userAccount,
|
|
||||||
data.supplyCtokens,
|
|
||||||
data.supplyAmts
|
|
||||||
);
|
|
||||||
|
|
||||||
// borrow the earlier position from Compound with flash loan fee added
|
|
||||||
_borrowDebtPosition(
|
|
||||||
data.borrowCtokens,
|
|
||||||
data.borrowAmts,
|
|
||||||
_flashLoanFees
|
|
||||||
);
|
|
||||||
|
|
||||||
_eventName = "LogCompoundImport(address,address[],string[],string[],uint256[],uint256[])";
|
|
||||||
_eventParam = abi.encode(
|
|
||||||
_importInputData.userAccount,
|
|
||||||
data.cTokens,
|
|
||||||
_importInputData.supplyIds,
|
|
||||||
_importInputData.borrowIds,
|
|
||||||
data.supplyAmts,
|
|
||||||
data.borrowAmts
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @notice import Compound position of the address passed in as userAccount
|
|
||||||
* @dev internally calls _importContract to perform the actual import
|
|
||||||
* @param _userAccount address of user whose position is to be imported to DSA
|
|
||||||
* @param _supplyIds Ids of all tokens the user has supplied to Compound
|
|
||||||
* @param _borrowIds Ids of all token borrowed by the user
|
|
||||||
* @param _flashLoanFees list of flash loan fees
|
|
||||||
*/
|
|
||||||
function importCompound(
|
|
||||||
address _userAccount,
|
|
||||||
string[] memory _supplyIds,
|
|
||||||
string[] memory _borrowIds,
|
|
||||||
uint256[] memory _flashLoanFees
|
|
||||||
)
|
|
||||||
external
|
|
||||||
payable
|
|
||||||
returns (string memory _eventName, bytes memory _eventParam)
|
|
||||||
{
|
|
||||||
ImportInputData memory inputData = ImportInputData({
|
|
||||||
userAccount: _userAccount,
|
|
||||||
supplyIds: _supplyIds,
|
|
||||||
borrowIds: _borrowIds
|
|
||||||
});
|
|
||||||
|
|
||||||
(_eventName, _eventParam) = _importCompound(inputData, _flashLoanFees);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contract ConnectV2CompoundImport is CompoundImportResolver {
|
|
||||||
string public constant name = "Compound-Import-v2";
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
//SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.0;
|
|
||||||
|
|
||||||
contract Events {
|
|
||||||
event LogDepositLiquidity(
|
|
||||||
address indexed tokenA,
|
|
||||||
address indexed tokenB,
|
|
||||||
uint256 amtA,
|
|
||||||
uint256 amtB,
|
|
||||||
uint256 uniAmount,
|
|
||||||
uint256 getId,
|
|
||||||
uint256 setId
|
|
||||||
);
|
|
||||||
|
|
||||||
event LogWithdrawLiquidity(
|
|
||||||
address indexed tokenA,
|
|
||||||
address indexed tokenB,
|
|
||||||
uint256 amountA,
|
|
||||||
uint256 amountB,
|
|
||||||
uint256 uniAmount,
|
|
||||||
uint256 getId,
|
|
||||||
uint256[] setId
|
|
||||||
);
|
|
||||||
|
|
||||||
event LogBuy(
|
|
||||||
address indexed buyToken,
|
|
||||||
address indexed sellToken,
|
|
||||||
uint256 buyAmt,
|
|
||||||
uint256 sellAmt,
|
|
||||||
uint256 getId,
|
|
||||||
uint256 setId
|
|
||||||
);
|
|
||||||
|
|
||||||
event LogSell(
|
|
||||||
address indexed buyToken,
|
|
||||||
address indexed sellToken,
|
|
||||||
uint256 buyAmt,
|
|
||||||
uint256 sellAmt,
|
|
||||||
uint256 getId,
|
|
||||||
uint256 setId
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
//SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.0;
|
|
||||||
|
|
||||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
|
||||||
import { DSMath } from "../../../common/math.sol";
|
|
||||||
import { Basic } from "../../../common/basic.sol";
|
|
||||||
import { IUniswapV2Router02, IUniswapV2Factory } from "./interface.sol";
|
|
||||||
|
|
||||||
abstract contract Helpers is DSMath, Basic {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev uniswap v2 router02
|
|
||||||
*/
|
|
||||||
IUniswapV2Router02 internal constant router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
|
|
||||||
|
|
||||||
function getExpectedBuyAmt(
|
|
||||||
address[] memory paths,
|
|
||||||
uint sellAmt
|
|
||||||
) internal view returns(uint buyAmt) {
|
|
||||||
uint[] memory amts = router.getAmountsOut(
|
|
||||||
sellAmt,
|
|
||||||
paths
|
|
||||||
);
|
|
||||||
buyAmt = amts[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getExpectedSellAmt(
|
|
||||||
address[] memory paths,
|
|
||||||
uint buyAmt
|
|
||||||
) internal view returns(uint sellAmt) {
|
|
||||||
uint[] memory amts = router.getAmountsIn(
|
|
||||||
buyAmt,
|
|
||||||
paths
|
|
||||||
);
|
|
||||||
sellAmt = amts[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkPair(
|
|
||||||
address[] memory paths
|
|
||||||
) internal view {
|
|
||||||
address pair = IUniswapV2Factory(router.factory()).getPair(paths[0], paths[1]);
|
|
||||||
require(pair != address(0), "No-exchange-address");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPaths(
|
|
||||||
address buyAddr,
|
|
||||||
address sellAddr
|
|
||||||
) internal pure returns(address[] memory paths) {
|
|
||||||
paths = new address[](2);
|
|
||||||
paths[0] = address(sellAddr);
|
|
||||||
paths[1] = address(buyAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMinAmount(
|
|
||||||
TokenInterface token,
|
|
||||||
uint amt,
|
|
||||||
uint slippage
|
|
||||||
) internal view returns(uint minAmt) {
|
|
||||||
uint _amt18 = convertTo18(token.decimals(), amt);
|
|
||||||
minAmt = wmul(_amt18, sub(WAD, slippage));
|
|
||||||
minAmt = convert18ToDec(token.decimals(), minAmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _addLiquidity(
|
|
||||||
address tokenA,
|
|
||||||
address tokenB,
|
|
||||||
uint _amt,
|
|
||||||
uint unitAmt,
|
|
||||||
uint slippage
|
|
||||||
) internal returns (uint _amtA, uint _amtB, uint _liquidity) {
|
|
||||||
(TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(tokenA, tokenB);
|
|
||||||
|
|
||||||
_amtA = _amt == uint(-1) ? getTokenBal(TokenInterface(tokenA)) : _amt;
|
|
||||||
_amtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA)));
|
|
||||||
|
|
||||||
bool isEth = address(_tokenA) == wethAddr;
|
|
||||||
convertEthToWeth(isEth, _tokenA, _amtA);
|
|
||||||
|
|
||||||
isEth = address(_tokenB) == wethAddr;
|
|
||||||
convertEthToWeth(isEth, _tokenB, _amtB);
|
|
||||||
|
|
||||||
approve(_tokenA, address(router), _amtA);
|
|
||||||
approve(_tokenB, address(router), _amtB);
|
|
||||||
|
|
||||||
uint minAmtA = getMinAmount(_tokenA, _amtA, slippage);
|
|
||||||
uint minAmtB = getMinAmount(_tokenB, _amtB, slippage);
|
|
||||||
(_amtA, _amtB, _liquidity) = router.addLiquidity(
|
|
||||||
address(_tokenA),
|
|
||||||
address(_tokenB),
|
|
||||||
_amtA,
|
|
||||||
_amtB,
|
|
||||||
minAmtA,
|
|
||||||
minAmtB,
|
|
||||||
address(this),
|
|
||||||
block.timestamp + 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _removeLiquidity(
|
|
||||||
address tokenA,
|
|
||||||
address tokenB,
|
|
||||||
uint _amt,
|
|
||||||
uint unitAmtA,
|
|
||||||
uint unitAmtB
|
|
||||||
) internal returns (uint _amtA, uint _amtB, uint _uniAmt) {
|
|
||||||
TokenInterface _tokenA;
|
|
||||||
TokenInterface _tokenB;
|
|
||||||
(_tokenA, _tokenB, _uniAmt) = _getRemoveLiquidityData(
|
|
||||||
tokenA,
|
|
||||||
tokenB,
|
|
||||||
_amt
|
|
||||||
);
|
|
||||||
{
|
|
||||||
uint minAmtA = convert18ToDec(_tokenA.decimals(), wmul(unitAmtA, _uniAmt));
|
|
||||||
uint minAmtB = convert18ToDec(_tokenB.decimals(), wmul(unitAmtB, _uniAmt));
|
|
||||||
(_amtA, _amtB) = router.removeLiquidity(
|
|
||||||
address(_tokenA),
|
|
||||||
address(_tokenB),
|
|
||||||
_uniAmt,
|
|
||||||
minAmtA,
|
|
||||||
minAmtB,
|
|
||||||
address(this),
|
|
||||||
block.timestamp + 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isEth = address(_tokenA) == wethAddr;
|
|
||||||
convertWethToEth(isEth, _tokenA, _amtA);
|
|
||||||
|
|
||||||
isEth = address(_tokenB) == wethAddr;
|
|
||||||
convertWethToEth(isEth, _tokenB, _amtB);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _getRemoveLiquidityData(
|
|
||||||
address tokenA,
|
|
||||||
address tokenB,
|
|
||||||
uint _amt
|
|
||||||
) internal returns (TokenInterface _tokenA, TokenInterface _tokenB, uint _uniAmt) {
|
|
||||||
(_tokenA, _tokenB) = changeEthAddress(tokenA, tokenB);
|
|
||||||
address exchangeAddr = IUniswapV2Factory(router.factory()).getPair(address(_tokenA), address(_tokenB));
|
|
||||||
require(exchangeAddr != address(0), "pair-not-found.");
|
|
||||||
|
|
||||||
TokenInterface uniToken = TokenInterface(exchangeAddr);
|
|
||||||
_uniAmt = _amt == uint(-1) ? uniToken.balanceOf(address(this)) : _amt;
|
|
||||||
approve(uniToken, address(router), _uniAmt);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
//SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.0;
|
|
||||||
|
|
||||||
interface IUniswapV2Router02 {
|
|
||||||
function factory() external pure returns (address);
|
|
||||||
function WETH() external pure returns (address);
|
|
||||||
|
|
||||||
function addLiquidity(
|
|
||||||
address tokenA,
|
|
||||||
address tokenB,
|
|
||||||
uint amountADesired,
|
|
||||||
uint amountBDesired,
|
|
||||||
uint amountAMin,
|
|
||||||
uint amountBMin,
|
|
||||||
address to,
|
|
||||||
uint deadline
|
|
||||||
) external returns (uint amountA, uint amountB, uint liquidity);
|
|
||||||
function removeLiquidity(
|
|
||||||
address tokenA,
|
|
||||||
address tokenB,
|
|
||||||
uint liquidity,
|
|
||||||
uint amountAMin,
|
|
||||||
uint amountBMin,
|
|
||||||
address to,
|
|
||||||
uint deadline
|
|
||||||
) external returns (uint amountA, uint amountB);
|
|
||||||
function swapExactTokensForTokens(
|
|
||||||
uint amountIn,
|
|
||||||
uint amountOutMin,
|
|
||||||
address[] calldata path,
|
|
||||||
address to,
|
|
||||||
uint deadline
|
|
||||||
) external returns (uint[] memory amounts);
|
|
||||||
function swapTokensForExactTokens(
|
|
||||||
uint amountOut,
|
|
||||||
uint amountInMax,
|
|
||||||
address[] calldata path,
|
|
||||||
address to,
|
|
||||||
uint deadline
|
|
||||||
) external returns (uint[] memory amounts);
|
|
||||||
|
|
||||||
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
|
|
||||||
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
|
|
||||||
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
|
|
||||||
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
|
|
||||||
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IUniswapV2Factory {
|
|
||||||
function getPair(address tokenA, address tokenB) external view returns (address pair);
|
|
||||||
function allPairs(uint) external view returns (address pair);
|
|
||||||
function allPairsLength() external view returns (uint);
|
|
||||||
|
|
||||||
function feeTo() external view returns (address);
|
|
||||||
function feeToSetter() external view returns (address);
|
|
||||||
|
|
||||||
function createPair(address tokenA, address tokenB) external returns (address pair);
|
|
||||||
}
|
|
|
@ -1,197 +0,0 @@
|
||||||
//SPDX-License-Identifier: MIT
|
|
||||||
pragma solidity ^0.7.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @title Uniswap v2.
|
|
||||||
* @dev Decentralized Exchange.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { TokenInterface } from "../../../common/interfaces.sol";
|
|
||||||
import { Helpers } from "./helpers.sol";
|
|
||||||
import { Events } from "./events.sol";
|
|
||||||
|
|
||||||
abstract contract UniswapResolver is Helpers, Events {
|
|
||||||
/**
|
|
||||||
* @dev Deposit Liquidity.
|
|
||||||
* @notice Deposit Liquidity to a Uniswap v2 pool.
|
|
||||||
* @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param amtA The amount of A tokens to deposit.
|
|
||||||
* @param unitAmt The unit amount of of amtB/amtA with slippage.
|
|
||||||
* @param slippage Slippage amount.
|
|
||||||
* @param getId ID to retrieve amtA.
|
|
||||||
* @param setId ID stores the amount of pools tokens received.
|
|
||||||
*/
|
|
||||||
function deposit(
|
|
||||||
address tokenA,
|
|
||||||
address tokenB,
|
|
||||||
uint256 amtA,
|
|
||||||
uint256 unitAmt,
|
|
||||||
uint256 slippage,
|
|
||||||
uint256 getId,
|
|
||||||
uint256 setId
|
|
||||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
|
||||||
uint _amt = getUint(getId, amtA);
|
|
||||||
|
|
||||||
(uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity(
|
|
||||||
tokenA,
|
|
||||||
tokenB,
|
|
||||||
_amt,
|
|
||||||
unitAmt,
|
|
||||||
slippage
|
|
||||||
);
|
|
||||||
setUint(setId, _uniAmt);
|
|
||||||
|
|
||||||
_eventName = "LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256,uint256)";
|
|
||||||
_eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Withdraw Liquidity.
|
|
||||||
* @notice Withdraw Liquidity from a Uniswap v2 pool.
|
|
||||||
* @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param uniAmt The amount of pool tokens to withdraw.
|
|
||||||
* @param unitAmtA The unit amount of amtA/uniAmt with slippage.
|
|
||||||
* @param unitAmtB The unit amount of amtB/uniAmt with slippage.
|
|
||||||
* @param getId ID to retrieve uniAmt.
|
|
||||||
* @param setIds Array of IDs to store the amount tokens received.
|
|
||||||
*/
|
|
||||||
function withdraw(
|
|
||||||
address tokenA,
|
|
||||||
address tokenB,
|
|
||||||
uint256 uniAmt,
|
|
||||||
uint256 unitAmtA,
|
|
||||||
uint256 unitAmtB,
|
|
||||||
uint256 getId,
|
|
||||||
uint256[] calldata setIds
|
|
||||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
|
||||||
uint _amt = getUint(getId, uniAmt);
|
|
||||||
|
|
||||||
(uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity(
|
|
||||||
tokenA,
|
|
||||||
tokenB,
|
|
||||||
_amt,
|
|
||||||
unitAmtA,
|
|
||||||
unitAmtB
|
|
||||||
);
|
|
||||||
|
|
||||||
setUint(setIds[0], _amtA);
|
|
||||||
setUint(setIds[1], _amtB);
|
|
||||||
|
|
||||||
_eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])";
|
|
||||||
_eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Buy ETH/ERC20_Token.
|
|
||||||
* @notice Buy a token using a Uniswap v2
|
|
||||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param buyAmt The amount of tokens to buy.
|
|
||||||
* @param unitAmt The unit amount of sellAmt/buyAmt with slippage.
|
|
||||||
* @param getId ID to retrieve buyAmt.
|
|
||||||
* @param setId ID to store the amount of tokens sold.
|
|
||||||
*/
|
|
||||||
function buy(
|
|
||||||
address buyAddr,
|
|
||||||
address sellAddr,
|
|
||||||
uint256 buyAmt,
|
|
||||||
uint256 unitAmt,
|
|
||||||
uint256 getId,
|
|
||||||
uint256 setId
|
|
||||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
|
||||||
uint _buyAmt = getUint(getId, buyAmt);
|
|
||||||
(TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
|
|
||||||
address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
|
|
||||||
|
|
||||||
uint _slippageAmt = convert18ToDec(_sellAddr.decimals(),
|
|
||||||
wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))
|
|
||||||
);
|
|
||||||
|
|
||||||
checkPair(paths);
|
|
||||||
uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt);
|
|
||||||
require(_slippageAmt >= _expectedAmt, "Too much slippage");
|
|
||||||
|
|
||||||
bool isEth = address(_sellAddr) == wethAddr;
|
|
||||||
convertEthToWeth(isEth, _sellAddr, _expectedAmt);
|
|
||||||
approve(_sellAddr, address(router), _expectedAmt);
|
|
||||||
|
|
||||||
uint _sellAmt = router.swapTokensForExactTokens(
|
|
||||||
_buyAmt,
|
|
||||||
_expectedAmt,
|
|
||||||
paths,
|
|
||||||
address(this),
|
|
||||||
block.timestamp + 1
|
|
||||||
)[0];
|
|
||||||
|
|
||||||
isEth = address(_buyAddr) == wethAddr;
|
|
||||||
convertWethToEth(isEth, _buyAddr, _buyAmt);
|
|
||||||
|
|
||||||
setUint(setId, _sellAmt);
|
|
||||||
|
|
||||||
_eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)";
|
|
||||||
_eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Sell ETH/ERC20_Token.
|
|
||||||
* @notice Sell a token using a Uniswap v2
|
|
||||||
* @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
|
||||||
* @param sellAmt The amount of the token to sell.
|
|
||||||
* @param unitAmt The unit amount of buyAmt/sellAmt with slippage.
|
|
||||||
* @param getId ID to retrieve sellAmt.
|
|
||||||
* @param setId ID stores the amount of token brought.
|
|
||||||
*/
|
|
||||||
function sell(
|
|
||||||
address buyAddr,
|
|
||||||
address sellAddr,
|
|
||||||
uint256 sellAmt,
|
|
||||||
uint256 unitAmt,
|
|
||||||
uint256 getId,
|
|
||||||
uint256 setId
|
|
||||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
|
||||||
uint _sellAmt = getUint(getId, sellAmt);
|
|
||||||
(TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
|
|
||||||
address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
|
|
||||||
|
|
||||||
if (_sellAmt == uint(-1)) {
|
|
||||||
_sellAmt = sellAddr == ethAddr ?
|
|
||||||
address(this).balance :
|
|
||||||
_sellAddr.balanceOf(address(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint _slippageAmt = convert18ToDec(_buyAddr.decimals(),
|
|
||||||
wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))
|
|
||||||
);
|
|
||||||
|
|
||||||
checkPair(paths);
|
|
||||||
uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt);
|
|
||||||
require(_slippageAmt <= _expectedAmt, "Too much slippage");
|
|
||||||
|
|
||||||
bool isEth = address(_sellAddr) == wethAddr;
|
|
||||||
convertEthToWeth(isEth, _sellAddr, _sellAmt);
|
|
||||||
approve(_sellAddr, address(router), _sellAmt);
|
|
||||||
|
|
||||||
uint _buyAmt = router.swapExactTokensForTokens(
|
|
||||||
_sellAmt,
|
|
||||||
_expectedAmt,
|
|
||||||
paths,
|
|
||||||
address(this),
|
|
||||||
block.timestamp + 1
|
|
||||||
)[1];
|
|
||||||
|
|
||||||
isEth = address(_buyAddr) == wethAddr;
|
|
||||||
convertWethToEth(isEth, _buyAddr, _buyAmt);
|
|
||||||
|
|
||||||
setUint(setId, _buyAmt);
|
|
||||||
|
|
||||||
_eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
|
|
||||||
_eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contract ConnectV2UniswapV2 is UniswapResolver {
|
|
||||||
string public constant name = "UniswapV2-v1.1";
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user