开始我的第一个闪电贷
该案例最简单的闪电贷合约,不提供任何策略,只是贷款还款操作,往合约转代币即可成功完成一笔闪电贷。
第一步,添加所需要的接口
根据自己需求添加:
import { ILendingPoolAddressesProvider } from "./ILendingPoolAddressesProvider.sol"; // 通过该接口获取LendingPool地址
import { FlashLoanReceiverBase } from "./FlashLoanReceiverBase.sol"; // 接收闪电贷金额的合约必须通过IFlashLoanReceiver 接口实现的 executeOperation()
import { ILendingPool } from "./ILendingPool.sol"; // 通过该接口调用flashloan
import { IERC20 } from "./IERC20.sol"; // 涉及到ERC20代币所需
第二步,设置FlashLoanReceiverBase
abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
using SafeERC20 for IERC20;
using SafeMath for uint256;
ILendingPoolAddressesProvider public immutable override ADDRESSES_PROVIDER;
ILendingPool public immutable override LENDING_POOL;
constructor(ILendingPoolAddressesProvider provider) public {
ADDRESSES_PROVIDER = provider;
LENDING_POOL = ILendingPool(provider.getLendingPool());
}
}
另请注意,由于欠款将从你的策略同中提取,您的合同必须为 LendingPool 提供补贴以提取这些资金以偿还闪贷债务 + 保费。
第三步,完善策略合约
接收闪贷金额的合约必须通过实现相关的 executeOperation() 函数。 在下面的示例中,我们策略将继承FlashLoanReceiverBase。
contract MyfirstFlashLoan is FlashLoanReceiverBase {
/**
在你的策略合约收到闪电贷金额后将调用此函数
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{
// 该策略合约此时已获得所需资金
// 策略逻辑可以写在这里
// 在上述逻辑的最后,该合约欠闪电贷额度 + 手续费。
// 因此,请确保您的合同有足够的资金来偿还这些金额。
// 授权 LendingPool 合约提前欠款额度
for (uint i = 0; i < assets.length; i++) {
uint amountOwing = amounts[i].add(premiums[i]);
IERC20(assets[i]).approve(address(LENDING_POOL), amountOwing);
}
return true;
}
function myfirstFlashLoanCall() public {
// 接收贷款地址
address receiverAddress = address(this);
// 贷款币币种,仅贷一个币种
address[] memory assets = new address[](1);
assets[0] = address(INSERT_ASSET_ONE_ADDRESS);
// 贷款币数量
uint256[] memory amounts = new uint256[](1);
amounts[0] = INSERT_ASSET_ONE_AMOUNT;
// 贷款模式
uint256[] memory modes = new uint256[](1);
modes[0] = INSERT_ASSET_ONE_MODE;
address onBehalfOf = address(this);
bytes memory params = "";
uint16 referralCode = 0;
LENDING_POOL.flashLoan(
receiverAddress,
assets,
amounts,
modes,
onBehalfOf,
params,
referralCode
);
}
}
第四步,合约部署
部署工具可自由选择,remix,truffle,hardhat
部署参数初始值设置为LendingPoolAddressesProvider合约地址:
0xF7CeaE542b00d8CBa6D7bcb3a5AbcA7A2E19829a
MyfirstFlashLoan合约已部署在heco链上并在浏览器验证,任何人都可以调用,准备好手续费即可
第五步,调用闪电贷
调用myfirstFlashLoanCall(address asset, uint256 num, uint256 mode)函数:
参考交易:
编码和解码参数
如果您想将参数传递到您的闪电贷函数中,您首先需要对它们进行编码,然后在您的 executeOperation() 中对其进行解码。
编码
如果您要进行编码,则可以使用内置的abi.encode()
:
// Encoding an address and a uint
bytes memory params = abi.encode(address(this), 1234);
如果是链下操作,例如 web3.js
可以调用abi.encodeParameters()
:
const params = web3.eth.abi.encodeParameters(
["bytes32"],
[
web3.utils.utf8ToHex("some_value")
]
)
解码
在你的 executeOperation() 中解码时,你需要使用 abi.decode()
:
(bytes32 someValue) = abi.decode(params, (bytes32));
用法可参考闪电贷清算合约代码
预留提币接口
function rescueTokens(IERC20 token) external onlyOwner {
token.transfer(owner(), token.balanceOf(address(this)));
}
Last updated
Was this helpful?