0%

SmartContract-DoDoFlashLoan测试网例子

Pre:

DoDo支持flash loan,并且手续费上比较友好

注:DODO V2 闪电贷仅当返还的base quote 数量比例产生变化时,合约会预览一笔将base quote 磨平的交易,该磨平交易手续费作为闪电贷手续费。其他情况不收取手续费用

试试在rinkby测试网上能否执行借款还款操作

DoDo闪电交换机制:

20220226162909

Code:

solidity代码:

参考文档里闪电交换,有代码例子该代码则是只实现了借款和还款的操作,具体的借款后的操作逻辑还要自己实现

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interface/IDODO.sol";
import "./interface/Withdraw.sol";

contract Flashloan is Withdraw{

function dodoFlashLoan(
address flashLoanPool, //You will make a flashloan from this DODOV2 pool
uint256 loanAmount,
address loanToken
) external {
//Note: The data can be structured with any variables required by your logic. The following code is just an example
bytes memory data = abi.encode(flashLoanPool, loanToken, loanAmount);
address flashLoanBase = IDODO(flashLoanPool)._BASE_TOKEN_();
if(flashLoanBase == loanToken) {
IDODO(flashLoanPool).flashLoan(loanAmount, 0, address(this), data);
} else {
IDODO(flashLoanPool).flashLoan(0, loanAmount, address(this), data);
}
}

//Note: CallBack function executed by DODOV2(DVM) flashLoan pool
function DVMFlashLoanCall(address sender, uint256 baseAmount, uint256 quoteAmount,bytes calldata data) external {
_flashLoanCallBack(sender,baseAmount,quoteAmount,data);
}

//Note: CallBack function executed by DODOV2(DPP) flashLoan pool
function DPPFlashLoanCall(address sender, uint256 baseAmount, uint256 quoteAmount, bytes calldata data) external {
_flashLoanCallBack(sender,baseAmount,quoteAmount,data);
}

//Note: CallBack function executed by DODOV2(DSP) flashLoan pool
function DSPFlashLoanCall(address sender, uint256 baseAmount, uint256 quoteAmount, bytes calldata data) external {
_flashLoanCallBack(sender,baseAmount,quoteAmount,data);
}

function _flashLoanCallBack(address sender, uint256, uint256, bytes calldata data) internal {
(address flashLoanPool, address loanToken, uint256 loanAmount) = abi.decode(data, (address, address, uint256));

require(sender == address(this) && msg.sender == flashLoanPool, "HANDLE_FLASH_NENIED");

//Note: Realize your own logic using the token from flashLoan pool.

//Return funds
IERC20(loanToken).transfer(flashLoanPool, loanAmount);
}
}

brownie

部署脚本:

brownie run scripts/deployment.py --network rinkeby

1
2
3
4
5
6
7
8
9
10
11
12
13
from brownie import Flashloan, accounts, config, network

def main():
"""
Deploy a `Flashloan` contract from `accounts[0]`.
"""

acct = accounts.add(
config["wallets"]["from_key"]
) # add your keystore ID as an argument to this call

flashloan = Flashloan.deploy({"from": acct})
return flashloan

执行脚本

brownie run scripts/run_flash_loan.py --network rinkeby

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from brownie import Flashloan, accounts, config, network, interface

ETHERSCAN_TX_URL = "https://rinkeby.etherscan.io/tx/{}"


def main():
"""
Executes the funcitonality of the flash loan.
"""
acct = accounts.add(config["wallets"]["from_key"])
print("Getting Flashloan contract...")
flashloan = Flashloan[len(Flashloan) - 1]
usdc = interface.IERC20(config["networks"][network.show_active()]["usdc"])

balance = usdc.balanceOf(acct)

print("Executing Flashloan...")
tx = flashloan.dodoFlashLoan("0x446Bb563EEC2E5C439f5b94C6DaAebcCF5d2F99C",10000000,"0xab0733588776B8881F7712f6AbCa98F510e6B63D", {"from": acct, "gas_limit":"5074044", "allow_revert":True})
print("You did it! View your tx here: " + ETHERSCAN_TX_URL.format(tx.txid))
return flashloan

执行效果:

tx

20220226164550

能成功借款还款

遇到的问题:

dodoFlashLoan函数有3个参数:

  • flashLoanPool 池子地址

  • loanAmount 数量

  • loanToken 要借的token地址

选择池子地址:

https://app.dodoex.io/pool/list?network=rinkeby可以看到有哪些池子信息

比如此处我要借usdc,就可以搜索一下

20220226161537

然后该池子还要支持flashloan,比如上图第一个池子就不支持,第二个池子才支持

20220226161948

借款数量

一开始我填的loanAmount为10 ether,想借10个,转换成wei则为10000000000000000000执行后报错,无法正常借款还款

查一下报错
https://dashboard.tenderly.co/tx/rinkeby/0xee7f3a6e0ef5906f8f95cbc789151e1d62da424dc80c6d93c80307ba060be646

Error Message:ERC20: transfer amount exceeds balance

20220226162947

对比一下Dodo流程,此时池子在借款的时候,要发送token给我合约时报错了,报错信息为转账数量超过余额了。

减少loanAmount10000000后,发现能成功,原来该usdc的精度为6位

20220226163700

以后要注意一下,大多数代币的精度为18位,但有些代币不是。

Refs: