套利准备
本次使用流程
第一步我们要借款,根据dydx规则,我们需要先完成一个 initiateFlashLoan 函数(闪电贷开始函数), 其amount即为需要借的数量
1 | function initiateFlashLoan(uint256 _amount) |
具体动作结构体为:
1 | Actions.ActionArgs({ |
本合约就算借款了,在operate发出的交易中,dydx将回调我们合约的callFunction函数
dydx地址0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e,可见operate结构
1 | function operate( |
当_runActions发出指导动作,本次闪电贷即正式开始。
在运行到_getCallAction动作,构造的Action结构体指示 actionType: Actions.ActionType.Call
,此时_runActions将进入
1 | else { |
callFunction操作-还款实现
操作第一步是将dydx给我们的WETH在池中回撤换回ETH,因为我们想要的是ETH
WETHAddress == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
WETH兑换成ETH–(weth合约)
1 | WETH9(WETHAddress).withdraw(tokenBalanceBefore);//调weth取出ETH,数额为借来的weth量 |
1 | function withdraw(uint wad) public { |
套利操作
我们有了tokenBalanceBefore个ETH,接下来撰写套利逻辑
ETH换USDT–(Cofix交易所)
1 | uint256 loopTimes = address(this).balance.div(cofixETHSapn); |
USDT 在Uniswap中兑换成ETH–(uniswap交易所)
1 | uint256 usdtBalance = IERC20(USDTAddress).balanceOf(address(this)); |
套利逻辑至此结束,由于当然此步不仅可以利用差价,还可能利用一些预言机漏洞认为创造差价等价格模型漏洞进行闪电贷套利操作。
还款操作
ETH兑换成WETH–(weth合约)
1 | WETH9(WETHAddress).deposit{value:tokenBalanceBefore.add(2)}; |
一种未成功的实例。
同一时间在cofi一个ETH换来 71.187个UMA
于此同时
在第五步骤换回一个ETH需要 71.679 个UMA ,这时该交易就是不划算的,将无法进行套利
而如果在cofi 1个eth换出的uma
大于在其他交易所 换回1个eth消耗的uma
我们就可以赚到他们之间的差价的uma。而此间当然存在滑点和手续费
部署
完整合约项目在:https://github.com/MLY0813/FlashSwapForCofixAndUni
1 | pragma solidity 0.7.4; |
测试网这样的汇率便是可以的:
一个ETH换出1289个USDT
然后1289个USDT全部换出19.7个weth:
这样归还后就能净赚18.7个wETH + 0.66594938个USDT - 2weiETH(手续费)
remix部署,传递1000000000000000000, 也就是1ether, uint256默认和wei单位相同:
但是测试网未很好的部署dydx则无法进行完整贷款操作0xdbf0497b是initiateFlashLoan(uint)的abi编码,由于目标地址不是一个合约地址,因此未能成功调用
调用的是initiateFlashLoan(uint256)
其值为1*10^18 ,也就是1ether