Created
September 10, 2020 06:18
-
-
Save NAKsir-melody/c5aa38f1677d050ea91c4be2250141cc to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.17+commit.d19bba13.js&optimize=false&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.17; | |
pragma experimental ABIEncoderV2; | |
import "github/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; | |
import "github/OpenZeppelin/openzeppelin-contracts/contracts/ownership/Ownable.sol"; | |
import "github/OpenZeppelin/openzeppelin-contracts/contracts/GSN/Context.sol"; | |
import "github/studydefi/money-legos/src/dydx/contracts/DydxFlashloanBase.sol"; | |
import "github/studydefi/money-legos/src/dydx/contracts/ICallee.sol"; | |
import "github/Uniswap/uniswap-v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; | |
import "github/Uniswap/uniswap-v2-periphery/contracts/interfaces/IUniswapV2Router01.sol"; | |
interface ICurveFi { | |
function exchange_underlying( | |
int128 from, int128 to, uint256 _from_amount, uint256 _min_to_amount | |
) external; | |
} | |
contract DydxFlashloaner is ICallee, DydxFlashloanBase, Ownable { | |
struct MyCustomData { | |
address fromToken; | |
address toToken; | |
uint256 borrowAmount; | |
uint256 repayAmount; | |
address curvepool; | |
int128 curveIndex1; | |
int128 curveIndex2; | |
} | |
/* | |
address _weth = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); | |
address _usdc = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48); | |
address _susd = address(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51); | |
address _solo = address(0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e); | |
//address _swap = address(0x45F783CCE6B7FF23B2ab2D70e416cdb7D6055f51); | |
address _swap = address(0xA5407eAE9Ba41422680e2e00537571bcC53efBfD); | |
//500000000000 | |
*/ | |
// This is the function that will be called postLoan | |
// i.e. Encode the logic to handle your flashloaned funds here | |
function callFunction( | |
address sender, | |
Account.Info memory account, | |
bytes memory data | |
) public { | |
MyCustomData memory mcd = abi.decode(data, (MyCustomData)); | |
// balOfLoanedToken = IERC20(mcd.token).balanceOf(address(this)); | |
// Note that you can ignore the line below | |
// if your dydx account (this contract in this case) | |
// has deposited at least ~2 Wei of assets into the account | |
// to balance out the collaterization ratio | |
//require( | |
// balOfLoanedToken >= mcd.repayAmount, | |
// "Not enough funds to repay dydx loan!" | |
//); | |
IERC20(mcd.fromToken).approve(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D,uint(-1)); | |
IUniswapV2Router02 usi = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); | |
address[] memory path = new address[](2); | |
path[0] = mcd.fromToken; | |
path[1] = mcd.toToken; | |
usi.swapExactTokensForTokens(mcd.borrowAmount,1, path, address(this), now ); | |
IERC20 susd = IERC20(mcd.toToken); | |
susd.approve(mcd.curvepool, uint(-1)); | |
ICurveFi(mcd.curvepool).exchange_underlying(mcd.curveIndex1, mcd.curveIndex2, susd.balanceOf(address(this)), 0); | |
require( | |
IERC20(mcd.fromToken).balanceOf(address(this)) >= mcd.repayAmount, | |
"Not enough funds to repay dydx loan!" | |
); | |
} | |
function initiateFlashLoan(address _solo, address _fromToken, address _toToken, uint256 _amount,address _curvepool,int128 _curveIndex1,int128 _curveIndex2) | |
external | |
{ | |
ISoloMargin solo = ISoloMargin(_solo); | |
// Get marketId from token address | |
uint256 marketId = _getMarketIdFromTokenAddress(_solo, _fromToken); | |
// Calculate repay amount (_amount + (2 wei)) | |
// Approve transfer from | |
uint256 repayAmount = _getRepaymentAmountInternal(_amount); | |
IERC20(_fromToken).approve(_solo, uint(-1)); | |
// 1. Withdraw $ | |
// 2. Call callFunction(...) | |
// 3. Deposit back $ | |
Actions.ActionArgs[] memory operations = new Actions.ActionArgs[](3); | |
operations[0] = _getWithdrawAction(marketId, _amount); | |
operations[1] = _getCallAction( | |
// Encode MyCustomData for callFunction | |
abi.encode(MyCustomData({ | |
fromToken: _fromToken, | |
toToken: _toToken, | |
borrowAmount: _amount, | |
repayAmount: repayAmount, | |
curvepool: _curvepool, | |
curveIndex1: _curveIndex1, | |
curveIndex2: _curveIndex2 | |
})) | |
); | |
operations[2] = _getDepositAction(marketId, repayAmount); | |
Account.Info[] memory accountInfos = new Account.Info[](1); | |
accountInfos[0] = _getAccountInfo(); | |
solo.operate(accountInfos, operations); | |
} | |
function withdraw( | |
address _token | |
) | |
public onlyOwner | |
{ | |
IERC20 token = IERC20(_token); | |
uint256 balance = token.balanceOf(address(this)); | |
token.transfer(0xFfdcabffB9EC425FD0B469eF626c844CB68670E8, balance); | |
} | |
function destroy() | |
public onlyOwner | |
{ | |
selfdestruct(0xFfdcabffB9EC425FD0B469eF626c844CB68670E8); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment