-
Notifications
You must be signed in to change notification settings - Fork 83
/
DyDxFlashLoan.sol
100 lines (80 loc) 路 3.08 KB
/
DyDxFlashLoan.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.0;
import "./DyDx.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract DyDxFlashLoan is Structs {
using SafeERC20 for IERC20;
DyDxPool constant pool = DyDxPool(0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e);
// DyDx tokens
address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address constant SAI = 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359;
// Both DyDx and mUSD tokens
address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
address constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
// mUSD tokens
address constant sUSD = 0x57Ab1ec28D129707052df4dF418D58a2D46d5f51;
address constant TUSD = 0x0000000000085d4780B73119b644AE5ecd22b376;
address constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
mapping(address => uint256) public currencies;
constructor() public {
currencies[WETH] = 1;
currencies[SAI] = 2;
currencies[USDC] = 3;
currencies[DAI] = 4;
}
modifier onlyPool() {
require(
msg.sender == address(pool),
"FlashLoan: only called by DyDx pool"
);
_;
}
function tokenToMarketId(address token) public view returns (uint256) {
uint256 marketId = currencies[token];
require(marketId != 0, "FlashLoan: Unsupported token");
return marketId - 1;
}
// the DyDx will call `callFunction(address sender, Info memory accountInfo, bytes memory data) public` after during `operate` call
function flashloan(address token, uint256 amount, bytes memory data)
internal virtual
{
IERC20(token).approve(address(pool), amount + 1);
Info[] memory infos = new Info[](1);
ActionArgs[] memory args = new ActionArgs[](3);
infos[0] = Info(address(this), 0);
AssetAmount memory wamt = AssetAmount(
false,
AssetDenomination.Wei,
AssetReference.Delta,
amount
);
ActionArgs memory withdraw;
withdraw.actionType = ActionType.Withdraw;
withdraw.accountId = 0;
withdraw.amount = wamt;
withdraw.primaryMarketId = tokenToMarketId(token);
withdraw.otherAddress = address(this);
args[0] = withdraw;
ActionArgs memory call;
call.actionType = ActionType.Call;
call.accountId = 0;
call.otherAddress = address(this);
call.data = data;
args[1] = call;
ActionArgs memory deposit;
AssetAmount memory damt = AssetAmount(
true,
AssetDenomination.Wei,
AssetReference.Delta,
amount + 1
);
deposit.actionType = ActionType.Deposit;
deposit.accountId = 0;
deposit.amount = damt;
deposit.primaryMarketId = tokenToMarketId(token);
deposit.otherAddress = address(this);
args[2] = deposit;
pool.operate(infos, args);
}
}