Solidity Uniswap V2 Flash loans

2024-03-28 12:04
文章标签 v2 solidity flash uniswap loans

本文主要是介绍Solidity Uniswap V2 Flash loans,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        Flash loans是一种非常强大的金融工具,在传统金融中没有类似的工具。它是一种无限制、无抵押的贷款,必须在接受贷款的同一交易中偿还。Uniswap 就是能提供闪电贷款的平台之一。让我们把它们添加到合同中,看看它们是如何工作的。

GitHub - XuHugo/solidityproject: DApp go go go !!!

        关于闪电贷款的实现,你需要知道的第一件事就是它们只能由智能合约使用。下面是闪贷的借款和还款方式:

        1一个智能合约从另一个合约借入闪贷。

        2出借合约向借款合约发送代币,并调用该合约中的一个特殊函数。

        3在特殊函数中,借款合约对贷款执行一些操作,然后将贷款转回。

        4贷方合约确保全额还款。如果有费用,它也会确保费用已支付。

        5控制流返回借款合同。

        要在 Zuniswap 中添加闪贷,我们需要做一些改动。首先,更新 swap,增加一个参数:

function swap(uint256 amount0Out,uint256 amount1Out,address to,bytes calldata data) public {

        新参数是一个字节数组数据。它可以包含任何文学内容。

        下一步是实际发放贷款。请记住,我们在交换函数中进行了乐观的转账:

...if (amount0Out > 0) _safeTransfer(token0, to, amount0Out);if (amount1Out > 0) _safeTransfer(token1, to, amount1Out);...

        这意味着我们已经在不要求抵押的情况下提供了任意数量(输出量由用户指定)的代币!我们唯一需要做的就是让调用者偿还贷款。为此,我们需要调用调用者合约中的一个特殊函数:

...if (amount0Out > 0) _safeTransfer(token0, to, amount0Out);if (amount1Out > 0) _safeTransfer(token1, to, amount1Out);if (data.length > 0) IZuniswapV2Callee(to).zuniswapV2Call(msg.sender, amount0Out, amount1Out, data);...

        根据我们定义的约定,我们希望调用者合约实现 zuniswapV2Call 函数,该函数接收:发送者地址、第一输出量、第二输出量和新数据参数。合同中的其他内容保持不变!同样,这也是一个非常优雅和简单的解决方案。

        基本上就是这样!事实证明,我们已经实现了检查贷款是否偿还的逻辑--这与检查新 K 是否有效的逻辑相同!

        现在,让我们来测试一下 Flash 贷款!我希望在添加测试后,整个流程会更加清晰。

        如上所述,要使用闪电贷款,我们需要一个智能合约。为了测试闪电贷款,我们需要一个单独的合约--让我们称它为 Flashloaner:

contract Flashloaner {error InsufficientFlashLoanAmount();uint256 expectedLoanAmount;...}

        合同将实现两个功能:

        第一个函数将从 Zuniswap 借入闪存贷款。

        第二个函数 zuniswapV2Call 将处理贷款并偿还贷款。

        获取闪贷和swap一样简单:

function flashloan(address pairAddress,uint256 amount0Out,uint256 amount1Out,address tokenAddress) public {if (amount0Out > 0) {expectedLoanAmount = amount0Out;}if (amount1Out > 0) {expectedLoanAmount = amount1Out;}ZuniswapV2Pair(pairAddress).swap(amount0Out,amount1Out,address(this),abi.encode(tokenAddress));}

        在进行swap之前,我们要设置预期贷款额,以便日后检查所请求的token数额是否确实已发放给我们。

        在swap函数中,请注意我们传递了 tokenAddress 作为数据参数--我们稍后将使用它来偿还贷款。或者,我们也可以将该地址存储在状态变量中。由于数据是字节数组,我们需要一种将地址转换为字节的方法,而 abi.encode 是一种常用的解决方案。

        现在是闪存贷款处理程序:

function zuniswapV2Call(address sender,uint256 amount0Out,uint256 amount1Out,bytes calldata data) public {address tokenAddress = abi.decode(data, (address));uint256 balance = ERC20(tokenAddress).balanceOf(address(this));if (balance < expectedLoanAmount) revert InsufficientFlashLoanAmount();ERC20(tokenAddress).transfer(msg.sender, balance);}

        这是我们在 flashloan 中调用的交换函数中的配对合约将调用的函数。pair合约还会把我们输入的任何数据传给swap。

        在处理函数中,我们要确保我们确实获得了所请求的贷款,而且我们只是在还贷。与其偿还贷款,我们还可以将其用于杠杆、套利或利用智能合约中的漏洞等用途。Flash 贷款是一个非常强大的工具,可以用来做好事,也可以用来做坏事。

        最后,让我们添加一个测试,获取贷款并确保偿还正确的金额:

function testFlashloan() public {token0.transfer(address(pair), 1 ether);token1.transfer(address(pair), 2 ether);pair.mint(address(this));uint256 flashloanAmount = 0.1 ether;uint256 flashloanFee = (flashloanAmount * 1000) / 997 - flashloanAmount + 1;Flashloaner fl = new Flashloaner();token1.transfer(address(fl), flashloanFee);fl.flashloan(address(pair), 0, flashloanAmount, address(token1));assertEq(token1.balanceOf(address(fl)), 0);assertEq(token1.balanceOf(address(pair)), 2 ether + flashloanFee);}

        问题是,Uniswap V2 对闪贷收取了费用:我们必须支付闪贷的交换费。回想一下,我们并没有对闪贷是否偿还进行额外检查,我们只是使用了新的 k 计算方法。这种计算方法会从余额中减去掉期费用!因此,在归还闪贷时,我们必须支付所借金额 + 0.3%(实际略高于 0.3009027%)。

        为了让 Flashloaner 全额还款,我们要计算 flashloanFee 并将其发送到合同中。闪贷还清后,Flashloaner 的余额为 0,而pair合约将获得手续费。

这篇关于Solidity Uniswap V2 Flash loans的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/855561

相关文章

什么是 Flash Attention

Flash Attention 是 由 Tri Dao 和 Dan Fu 等人在2022年的论文 FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness 中 提出的, 论文可以从 https://arxiv.org/abs/2205.14135 页面下载,点击 View PDF 就可以下载。 下面我

STM32内部闪存FLASH(内部ROM)、IAP

1 FLASH简介  1 利用程序存储器的剩余空间来保存掉电不丢失的用户数据 2 通过在程序中编程(IAP)实现程序的自我更新 (OTA) 3在线编程(ICP把整个程序都更新掉) 1 系统的Bootloader写死了,只能用串口下载到指定的位置,启动方式也不方便需要配置BOOT引脚触发启动  4 IAP(自己写的Bootloader,实现程序升级) 1 比如蓝牙转串口,

STM32 ADC+DMA导致写FLASH失败

最近用STM32G070系列的ADC+DMA采样时,遇到了一些小坑记录一下; 一、ADC+DMA采样时进入死循环; 解决方法:ADC-dma死循环问题_stm32 adc dma死机-CSDN博客 将ADC的DMA中断调整为最高,且增大ADCHAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_Buffer_Size); 的ADC_Bu

野火霸天虎V2学习记录

文章目录 嵌入式开发常识汇总1、嵌入式Linux和stm32之间的区别和联系2、stm32程序下载方式3、Keil5安装芯片包4、芯片封装种类5、STM32命名6、数据手册和参考手册7、什么是寄存器、寄存器映射和内存映射8、芯片引脚顺序9、stm32芯片里有什么10、存储器空间的划分11、如何理解寄存器说明12、如何操作寄存器的某一位 STM32F407芯片学习1、stm32单片机启动流程s

翻译Houdini官方对UE4新版插件的介绍:Houdini Engine for Unreal - V2

原视频:Houdini For Unreal - YouTube 目录 介绍0. 总览1. 简介HoudiniEngine2. UE4的HoudiniEngine - 第二版为什么要做“第二版” ?What's new? - 核心What's new? - 输出(1)What's new? - 输出(2)What's new? - 输入What's new? - 参数What's new?

通过 Flash 让所有浏览器支持 WebP 格式图像解码

http://www.guao.hk/tag/webp#userconsent# http://www.etherdream.com/WebP/

提高Flash builder编译速度 (转)

提高Flash builder编译速度   2013-04-08 03:14:42|  分类: flash |  标签: |举报 |字号大中小 订阅 我们在开发过程中随着项目的不断壮大,经常会碰到编译速度过慢,IDE崩溃等令人头痛的问题,这里我总结了一下网上别人的经验,对FB进行了3点优化,效果明显  1、把 Build Auto 改成 手动 Build  2

Jaxb - com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExcepti

一、异常 com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExceptions类的两个属性具有相同名称 "orderName"his problem is related to the following location:at public java.lang.Stri

MapReduce V2---Yarn的架构及其执行原理

1. MRv1的局限性    1):扩展性差            MRv1中,Jobracker同事兼备了资源管理和作业控制(job的生命周期管理(task调度,跟踪task过程状态,task处理容错)两个功能。     单个的jobtracker无论在内存还是其他资源方面总存在瓶颈,在伸缩性、资源利用率、运行除mapreduce的其他任务等方面都会有限制。 MRv2 Y

DM8168 关于nand flash的折腾之路

主机平台:ubuntu 12.04  目标平台:TI DM8168 开发套件:*****北京某公司开发板 拿到板子,看了看资源,看了看平台的组成,上网看了看这写博客的评价,之后就开始了折腾之路,还是老方法;首先用厂商给的东西,原封不动的启动,摸索认识一番,TI给的是带开发套件的SD卡,按照 【快速开始QSG】;拨马开关-连线上电,启动。一切ok. 接着安装交叉编译工具,配置host主