这是一个非常有意思的概念。
参考资料
- 图解 DeFi 闪电贷原理与常见用例
- 智能合约 + 闪电贷 初体验
- 闪电贷套利机器人开发教程(一)
- 闪电贷套利机器人开发教程(二)
- 如何使用Aave进行闪电贷
- 崔棉大师教你玩转闪电贷(上集)
- 崔棉大师教你玩转闪电贷(下集)
- flashloan
- pancake-bakery-arbitrage
讲解
其实上面的参考资料已经讲的非常好了,我在这里再讲一下,并且说一下上面那些资料中没说的细节。
本闪电贷主要是针对通过 swap
进行借贷。
关于借贷方式请参考
这里我们以 pancakeswap
作为例子。
首先参考 pair
中的一段代码。
PancakePair.sol
1 | // this low-level function should be called from a contract which performs important safety checks |
第 12
和 第 13
行
if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
如果 amount0Out
、amount1Out
大于 0
,就会先把币打到账户上。
注意,这里用的方法是
_safeTransfer
即,假设池子中只有 500 BNB
,你不能借 600 BNB
。
所以,在借的时候,一定要区分好,你借的币是 token0
还是 token1
。
接着,第 14
行
if (data.length > 0) IPancakeCallee(to).pancakeCall(msg.sender, amount0Out, amount1Out, data);
如果 data
的长度大于 0
,就会执行
IPancakeCallee(to).pancakeCall(msg.sender, amount0Out, amount1Out, data);
这个方法。data
是一个 bytes
,无所谓是什么,只需要让它的长度大于 0
就好了。
这里要注意 IPancakeCallee(to)
这个 to
是你的合约地址,所以,如果你要是有 pancakeCall
这个方法,这个时候会调用该方法。
所以说,假设你实现了这个方法,那么,进入到你账户执行的时候,由于你之前已经借出了 token
,所以,可以在 pancakeCall
这个方法中继续使用。
其他的 dex
平台原理差不多都是这样子,但是,方法名可能不一样,比如 biswap
叫 bisCall
。
执行 swap
我们借出币是通过 pair
借出的。
我们拿着借出的币,进行 dex
的 swapToken
方法。
可以参考
OK,这里假设你已经兑换了。并且
AB
你借出了B
BC
你兑换了C
CA
你兑换了A
那么,如何归还呢?
归还
对于 AB
来说,如果你借出 B
,你是归还 A
还是 B
呢?
答案是,两个都可以。
如果你借出 B
,归还 B
,那么,你只是拿着这个 B
执行了执行了一圈然后还回去而已,你借出 50
个 B
还回 50
个 B
就好了。
如果你借出 B
,归还的是 A
,那么,相当于你执行了 swapTokenForToken
,用 A
去购买 B
。只不过,B
是先打给你,然后你后付的 A
而已。但是,这个时候你就要付手续费了。因为,你本质上就是执行了 swapTokenForToken
的操作,所以要收取手续费。
那么,如何归还,归还给谁?
只需要对 AB
的 pair
转对应数量的 A
即可。
参考
1 | uint[] memory backamounts = functionContract(backRouter).getAmountsIn(receiveAmountIn, backPaths); |
其中
receiveAmountIn
- 借出
B
的数量
- 借出
backPaths
A
兑换B
的路径
backToken
A
的合约地址
functionContract
- 接口合约,放置了一些接口函数
其中 getAmountsIn
的方法,就可以知道你借出多少的 B
,需要归还多少的 A
。
上面的就是归还了。
具体细节可以参考一下 pancakeswap
的公开的方法。
下面说一下整体的手续费的计算,以
AB
你借出了B
BC
你兑换了C
CA
你兑换了A
来说,实际上,上面相当于执行了 3
次 swapTokenForToken
方法。也就是会收 3
次手续费。
盈利
后面就把归还后剩余的 A
发送到相应账户就好了。
我将所有的代码放在了
相对于公开的代码,我写的代码可以适应于大部分的场景。