dsa-connectors-old/contracts/flashloan/dydx.sol

109 lines
3.7 KiB
Solidity
Raw Permalink Normal View History

2020-09-14 15:43:49 +00:00
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "@studydefi/money-legos/dydx/contracts/DydxFlashloanBase.sol";
import "@studydefi/money-legos/dydx/contracts/ICallee.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import { DSMath } from "../common/math.sol";
2020-09-14 15:43:49 +00:00
interface DSAInterface {
function cast(address[] calldata _targets, bytes[] calldata _datas, address _origin) external payable;
}
contract Helper {
2020-09-14 15:43:49 +00:00
struct CastData {
2020-09-14 16:34:51 +00:00
address dsa;
address token;
uint amount;
2020-09-14 15:43:49 +00:00
address[] targets;
bytes[] data;
}
function encodeDsaAddr(address dsa, bytes memory data) internal view returns (bytes memory _data) {
CastData memory cd;
(cd.token, cd.amount, cd.targets, cd.data) = abi.decode(data, (address, uint256, address[], bytes[]));
_data = abi.encode(dsa, cd.token, cd.amount, cd.targets, cd.data);
}
}
contract DydxFlashloaner is ICallee, DydxFlashloanBase, DSMath, Helper {
using SafeERC20 for IERC20;
// address public constant soloAddr = 0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e;
// address public constant wethAddr = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// address public constant ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public constant soloAddr = 0x4EC3570cADaAEE08Ae384779B0f3A45EF85289DE;
address public constant wethAddr = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
address public constant ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
event LogDydxFlashLoan(
address indexed sender,
address indexed token,
uint amount
);
2020-09-14 15:43:49 +00:00
function callFunction(
address sender,
Account.Info memory account,
bytes memory data
) public override {
2020-09-14 21:06:40 +00:00
require(sender == address(this), "not-same-sender");
2020-09-14 22:05:20 +00:00
CastData memory cd;
(cd.dsa, cd.token, cd.amount, cd.targets, cd.data) = abi.decode(
data,
(address, address, uint256, address[], bytes[])
);
2020-09-14 15:43:49 +00:00
2020-09-14 16:34:51 +00:00
IERC20 tokenContract;
if (cd.token == ethAddr) {
tokenContract = IERC20(wethAddr);
2020-09-14 22:05:20 +00:00
tokenContract.approve(wethAddr, cd.amount);
2020-09-14 16:34:51 +00:00
tokenContract.withdraw(cd.amount);
payable(cd.dsa).transfer(cd.amount);
} else {
tokenContract = IERC20(cd.token);
tokenContract.safeTransfer(cd.dsa, cd.amount);
2020-09-14 16:34:51 +00:00
}
DSAInterface(cd.dsa).cast(cd.targets, cd.data, 0xB7fA44c2E964B6EB24893f7082Ecc08c8d0c0F87);
if (cd.token == ethAddr) {
tokenContract.deposit.value(cd.amount)();
}
2020-09-14 15:43:49 +00:00
}
2020-09-14 16:34:51 +00:00
function initiateFlashLoan(address _token, uint256 _amount, bytes calldata data) external {
2020-09-14 15:43:49 +00:00
ISoloMargin solo = ISoloMargin(soloAddr);
uint256 marketId = _getMarketIdFromTokenAddress(soloAddr, _token);
IERC20(_token).approve(soloAddr, _amount + 2);
Actions.ActionArgs[] memory operations = new Actions.ActionArgs[](3);
operations[0] = _getWithdrawAction(marketId, _amount);
2020-09-14 22:38:28 +00:00
operations[1] = _getCallAction(encodeDsaAddr(msg.sender, data));
2020-09-14 16:34:51 +00:00
operations[2] = _getDepositAction(marketId, _amount + 2);
2020-09-14 15:43:49 +00:00
Account.Info[] memory accountInfos = new Account.Info[](1);
accountInfos[0] = _getAccountInfo();
IERC20 _tokenContract = IERC20(_token);
uint iniBal = _tokenContract.balanceOf(address(this));
solo.operate(accountInfos, operations);
uint finBal = _tokenContract.balanceOf(address(this));
2020-09-14 21:06:40 +00:00
require(sub(iniBal, finBal) < 5, "amount-paid-less");
2020-09-14 15:43:49 +00:00
}
2020-09-14 21:06:40 +00:00
2020-09-14 22:05:20 +00:00
}
contract InstaDydxFlashLoan is DydxFlashloaner {
2020-09-14 21:06:40 +00:00
receive() external payable {}
2020-09-14 15:43:49 +00:00
}