正文
基于DYDX闪电贷在Cofix和Uniswap之间套利
由于在以太坊中的交易属性,在一笔交易中可以借出大量资金进行操作(不能超过gaslimit限制)。所以当各个交易平台有利差的时候可以进行套利(无风险套利),避免了准备大量资金。
相关项目
Cofix
github:
https://github.com/Computable-Finance
coifx中调用了NEST预言机的价格,完成做市、交易的操作并且去中心化。
Uniswap
github:
https://github.com/Uniswap/uniswap-v2-core
Uniswap根据交易拟合算法来完成交易,目前锁仓量最大的去中心化交易平台。
NEST
github:
https://github.com/NEST-Protocol
使用双向报价机制,可以在以太坊上生成去中心化的价格。
这几个项目之后会单独细说,本篇只讲述如何组合各个合约进行套利
流程
1.闪电贷WETH
2.WETH换ETH
3.ETH换USDT
4.USDT换ETH
5.ETH换WETH
6.WETH还款
DYDX
套利合约
WETH
Cofix
Uniswap
还款后剩余资金为所的利润
套利合约
github:
https://github.com/MLY0813/FlashSwapForCofixAndUni/blob/main/Contract/Flash_Swap.sol
核心方法
function callFunction (
address sender,
Account. Info memory account,
bytes memory data
) public {
MyCustomData memory mcd = abi. decode ( data, ( MyCustomData) ) ;
uint256 tokenBalanceBefore = IERC20 ( mcd. token) . balanceOf ( address ( this) ) ;
WETH9 ( WETHAddress) . withdraw ( tokenBalanceBefore) ;
uint256 loopTimes = address ( this) . balance. div ( cofixETHSapn) ;
for ( uint256 i = 0 ; i < loopTimes; i++ ) {
CoFiXRouter ( cofixRouter) . swapExactETHForTokens{ value: cofixETHSapn} ( USDTAddress, cofixETHSapn. sub ( nestPrice) , 1 , address ( this) , address ( this) , uint256 ( block. timestamp) . add ( 100 ) ) ;
}
uint256 usdtBalance = IERC20 ( USDTAddress) . balanceOf ( address ( this) ) ;
address[ ] memory uniData = new address[ ] ( 2 ) ;
uniData[ 0 ] = address ( 0xdAC17F958D2ee523a2206206994597C13D831ec7 ) ;
uniData[ 1 ] = address ( 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ) ;
UniswapV2Router ( uniRouter) . swapExactTokensForETH ( usdtBalance, 1 , uniData, address ( this) , uint256 ( block. timestamp) . add ( 100 ) ) ;
WETH9 ( WETHAddress) . deposit{ value: tokenBalanceBefore. add ( 2 ) } ;
uint256 balOfLoanedToken = IERC20 ( mcd. token) . balanceOf ( address ( this) ) ;
require (
balOfLoanedToken >= mcd. repayAmount,
"Not enough funds to repay dydx loan!"
) ;
}
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
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
callFunction方法会在调用DYDX闪电贷过程中被回调,在方法中实现收到贷款资金后需要的进行的操作。
1.WETH兑换成ETH
WETH9 ( WETHAddress) . withdraw ( tokenBalanceBefore) ;
2.ETH 在Cofix中兑换成USDT
uint256 loopTimes = address ( this) . balance. div ( cofixETHSapn) ;
for ( uint256 i = 0 ; i < loopTimes; i++ ) {
CoFiXRouter ( cofixRouter) . swapExactETHForTokens{ value: cofixETHSapn} ( USDTAddress, cofixETHSapn. sub ( nestPrice) , 1 , address ( this) , address ( this) , uint256 ( block. timestamp) . add ( 100 ) ) ;
}
这里使用了循环操作,因为cofix中有冲击成本的限制。单笔大额资金是亏钱的,所以要分成小部分资金进行兑换。
3.USDT 在Uniswap中兑换成ETH
uint256 usdtBalance = IERC20 ( USDTAddress) . balanceOf ( address ( this) ) ;
address[ ] memory uniData = new address[ ] ( 2 ) ;
uniData[ 0 ] = address ( 0xdAC17F958D2ee523a2206206994597C13D831ec7 ) ;
uniData[ 1 ] = address ( 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ) ;
UniswapV2Router ( uniRouter) . swapExactTokensForETH ( usdtBalance, 1 , uniData, address ( this) , uint256 ( block. timestamp) . add ( 100 ) ) ;
4.ETH兑换成WETH
WETH9 ( WETHAddress) . deposit{ value: tokenBalanceBefore. add ( 2 ) } ;
注意dydx还款的时候需要加2wei的资金
整个操作完成后剩余的ETH就是自己的了
function initiateFlashLoan ( uint256 _amount)
external
{
ISoloMargin solo = ISoloMargin ( dydxAddress) ;
uint256 marketId = _getMarketIdFromTokenAddress ( dydxAddress, WETHAddress) ;
uint256 repayAmount = _getRepaymentAmountInternal ( _amount) ;
IERC20 ( WETHAddress) . approve ( dydxAddress, repayAmount) ;
Actions. ActionArgs[ ] memory operations = new Actions. ActionArgs[ ] ( 3 ) ;
operations[ 0 ] = _getWithdrawAction ( marketId, _amount) ;
operations[ 1 ] = _getCallAction (
abi. encode ( MyCustomData ( { token: WETHAddress, repayAmount: repayAmount} ) )
) ;
operations[ 2 ] = _getDepositAction ( marketId, repayAmount) ;
Account. Info[ ] memory accountInfos = new Account. Info[ ] ( 1 ) ;
accountInfos[ 0 ] = _getAccountInfo ( ) ;
solo. operate ( accountInfos, operations) ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
使用dydx闪电贷的代码,传入参数就是想借多少WETH。大部分代码都是按照dydx固定的参数拼接数据。
注意事项
只有出现利差的时候闪电贷套利才有效,这种机会很少,但是也没什么成本。
cofix交易会挖出cofi,合约中需要有取出cofi的接口,否则就锁里面拿不出来了。
最好有脚本程序配合,发现套利机会直接发起交易套利。