{"content":{"title":"Aave v3实现第一笔闪电交易","body":"### 闪电贷(Flash Loan)\r\n\r\n闪电贷是一种在区块链上借入资产的新方式。最初由aave实现完成，后续其他流行的DeFi协议迅速跟进，添加了这个功能。原理很简单，也很实用。与传统的担保贷款不同，闪电贷不需要任何抵押品、信用评分或管理来处理无担保贷款。<br>Flash Loan 利用原子性允许用户在不提供抵押品的情况下借款。有两个注意事项需要提及。 首先，无论何时你在闪电贷中借入资产，你都必须支付借出金额的 0.09% 的费用。 其次，必须在借款的同一笔交易中偿还贷款.<br>\r\n\r\n### Aave\r\nAave 是一种去中心化的非托管流动性市场协议，用户可以作为存款人或借款人参与其中。 储户向市场提供流动性以赚取被动收入，而借款人能够以超额抵押（永久）或抵押不足（单块流动性）的方式借款。<br>可以将 Aave 视为去中心化的伪银行。 Aave 没有验证所有交易的中央银行，而是拥有以自动化方式完成所有这些工作的智能合约。 储户将他们的代币存入 Aave，并开始从他们的存款中赚取利息。 另一方面，借款人会做相反的事情。 他们将从 Aave 取钱，并开始对借入的金额产生利息。 为了做到这一点，他们必须超额抵押。对于那些不想将钱存入 Aave 而只想借钱的人来说，还有另一种方法。 这就是我们前面提到的闪电贷（Flash Loan）\r\n\r\n### 实战\r\n基于上面的概念，下面将一步一步按照步骤完成第一笔闪电贷。<br>本教程是结合自身理解以及 **[quicknode英文教程](https://www.quicknode.com/guides/defi/lending-protocols/how-to-make-a-flash-loan-using-aave/#remix-setup)** 翻译完成，没有虎头蛇尾，按照步骤均可实战成功！\r\n\r\n#### 准备工具\r\n这次我们用到的是AaveV3版本，网络rpc是Polygon Mumbai Testnet RPC \r\n1. remix在线编译\r\n2. MetaMask钱包\r\n#### 预先配置环境\r\n1. 将Polygon Mumbai Testnet 配置到MetaMask钱包。<br>\r\n   首先在 **[QuickNode.com](https://www.quicknode.com/?utm_source=internal&utm_campaign=guides)** 注册账户，注册成功在选择Polygon链，创建QuickNode，成功之后如下<br>\r\n   **![QuickNode 截图](https://i.ibb.co/C9bbsQZ/Wechat-IMG32.png)** <br>\r\n   然后在图中点击红框，在弹出的MetaMask授权框中点击批准，然后该网络就会添加到钱包中。<br>\r\n   ![QuickNode 截图](https://i.ibb.co/tDW58qM/Wechat-IMG33.png)\r\n2. 从 **[QuickNode Multi-chain Faucet](https://faucet.quicknode.com/polygon/mumbai)** 发送matic代币到你的钱包地址。稍等几分钟就会到你的钱包中。目前每次接水大概是1个 matic. <br>\r\n   ![QuickNode 水龙头](https://i.ibb.co/HxbWjSt/WX20230409-111450-2x.png)<br>\r\n以上的准备环境已经准备完毕。下面开始实战。\r\n#### 实战教程\r\n实战的目的是在Polygon Mumbai Testnet上通过AaveV3的loanPool借出来10usdc，然后再把10个usdc+本次的手续费fee一起还给AaveV3的LoanPool\r\n1. 下面将闪电贷合约代码以及注释贴到remix上。<br>\r\n``` javascript\r\n// SPDX-License-Identifier: MIT\r\n/*\r\n 合约是针对AaveV3版本\r\n*/\r\npragma solidity 0.8.10;\r\n// 引入Aave V3的基础合约、借贷池管理合约、以及openzeppeln erc20合约\r\nimport \"https://github.com/aave/aave-v3-core/blob/master/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol\";\r\nimport \"https://github.com/aave/aave-v3-core/blob/master/contracts/interfaces/IPoolAddressesProvider.sol\";\r\nimport \"https://github.com/aave/aave-v3-core/blob/master/contracts/dependencies/openzeppelin/contracts/IERC20.sol\";\r\n\r\n// 继承Aave's FlashLoanSimpleReceiverBase 合约\r\ncontract SimpleFlashLoan is FlashLoanSimpleReceiverBase {\r\n    address payable owner;\r\n// 初始化合约，在构造器中填入Aave's lending pool的地址，后面会演示到\r\n    constructor(address _addressProvider)\r\n        FlashLoanSimpleReceiverBase(IPoolAddressesProvider(_addressProvider))\r\n    {\r\n    }\r\n// 请求借款的函数，\r\n    function fn_RequestFlashLoan(address _token, uint256 _amount) public {\r\n        address receiverAddress = address(this); // 用来接收闪电贷资金的合约地址，在这个合约中是部署合约的地址\r\n        address asset = _token; // 闪电贷的贷款资产代币地址，这次是usdc\r\n        uint256 amount = _amount; // 闪电贷的额度，本次是10个usdc\r\n        bytes memory params = \"\"; // 额外信息作为可变参数打包传递给receiver，暂时用不到\r\n        uint16 referralCode = 0; // 邀请码，暂时用不到\r\n        // 调用aave 的资金池进行交互\r\n        POOL.flashLoanSimple(\r\n            receiverAddress, \r\n            asset, \r\n            amount, \r\n            params, \r\n            referralCode \r\n        );\r\n    }\r\n    \r\n    /*\r\n        闪电贷策略合约必须实现的函数，一般用于授权还款额度给LendPool合约地址，\r\n        该函数是在上面的函数执行完毕之后，回调执行该函数，操作approve一定量的币(贷款+手续费)给Lending Pool地址\r\n        手续费：借款总额的0.09%.\r\n    */\r\n    \r\n    function  executeOperation(\r\n        address asset,\r\n        uint256 amount,\r\n        uint256 premium,\r\n        address initiator,\r\n        bytes calldata params\r\n    )  external override returns (bool) {\r\n        \r\n        //具体业务逻辑可以写在这里，当逻辑走完，接下来就是要偿还\r\n        // 该合约闪电贷额度+手续费，请确保由足够的资金偿还金额\r\n        \r\n        uint256 totalAmount = amount + premium;\r\n        IERC20(asset).approve(address(POOL), totalAmount);\r\n\r\n        return true;\r\n    }\r\n\r\n    receive() external payable {}\r\n}\r\n```\r\n选择编译环境进行编译，如图<br>\r\n**![remix编译](https://i.ibb.co/0YQs6KR/WX20230409-114921-2x.png)**   \r\n2. 部署之前，需要查询 **[Aave's pool provider](https://docs.aave.com/developers/deployed-contracts/v3-testnet-addresses)** 的地址如图 <br> \r\n**![Aave pool provider address](https://i.ibb.co/cxL9Jrx/WX20230409-115708-2x.png)** \r\n将该地址复制，粘贴到合约中的构造函数中，如图 <br>\r\n**![remix部署Pool address](https://i.ibb.co/ncQG01f/WX20230409-120002-2x.png)**\r\n然后点击transact进行合约部署。完成之后，将**该合约地址复制**下来<br>\r\n**![合约地址](https://i.ibb.co/FmS7kF2/WX20230409-120323-2x.png)** <br>\r\n3. 下面需要 Polygon Mumbai Testnet 的一些usdc来作为部署合约的手续费，打开 **[usdc faucet](https://staging.aave.com/faucet/)** 如图进行获取![usdc faucet](https://i.ibb.co/DQxmNTX/WX20230409-120725-2x.png),获取成功之后，在钱包中会显示usdc的余额\r\n4. 接着通过钱包的usdc,给刚才部署合约的地址发送一部分usdca代币作为手续费 <br> ![发送usdc给部署合约](https://i.ibb.co/61NbGJX/WX20230409-121315-2x.png)  <br>\r\n5. 开始执行闪电贷交易，交易之前，获取必要的参数，usdc在  [Aave V3的地址](https://docs.aave.com/developers/deployed-contracts/v3-testnet-addresses) <br>\r\n **![usdc地址](https://i.ibb.co/qML7q0b/WX20230409-121739-2x.png)** 将该地址粘贴到合约函数中，同时将本次打算借款的数量10填进去，如图<br>\r\n ![合约函数参数](https://i.ibb.co/dLDYpVJ/WX20230409-122011-2x.png) <br>\r\n 这里注意的是数量，本次是借10个usdc,通过区块链浏览器查看，usdc的精度是6，因此本次填入的数值应该是10000000。点击方法进行执行，完成交易如图 <br>  \r\n ![usdc精度](https://i.ibb.co/3TL79zv/WX20230409-122157-2x.png)\r\n **![交易明细](https://i.ibb.co/F7h5XFy/WX20230409-122620-2x.png)** <br>\r\n上面的是借的10usdc,下面是借款额度+手续费，都是在一个区块中完成。<br>\r\n\r\n\r\n### 总结\r\n以上就完成了一个最简单的闪电贷合约，不提供任何策略，仅仅是贷款换款操作，往合约转代币即可完成一笔闪电贷。闪电贷应用场景很多，比如资产清算，差价套利，抵押品更换，换币还款等，其风险也不可小觑，甚至有些项目被盗了两次，比如Cream,说的就是你！"},"author":{"user":"https://learnblockchain.cn/people/3290","address":null},"history":"QmTRKMX2T7FdA6bNWVgHnTxhRt883PCoEEaWoAay4P6rWx","timestamp":1681020133,"version":1}