set external call interface

This commit is contained in:
mingda
2020-11-06 16:03:18 +08:00
parent bdc8e7f6b1
commit 52a40fec8f
7 changed files with 90 additions and 54 deletions

View File

@@ -10,9 +10,10 @@ pragma experimental ABIEncoderV2;
import {DVMStorage} from "./DVMStorage.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol";
import {IDODOCallee} from "../../intf/IDODOCallee.sol";
contract DVMFunding is DVMStorage {
function buyShares(address to) external returns (uint256) {
function buyShares(address to) external preventReentrant returns (uint256) {
uint256 baseInput = _VAULT_.getBaseInput();
uint256 quoteInput = _VAULT_.getQuoteInput();
require(baseInput > 0, "NO_BASE_INPUT");
@@ -46,17 +47,24 @@ contract DVMFunding is DVMStorage {
_VAULT_.sync();
}
function sellShares(address to, uint256 amount) external returns (uint256) {
require(_VAULT_.balanceOf(msg.sender) >= amount, "SHARES_NOT_ENOUGH");
function sellShares(
address to,
uint256 shareAmount,
bytes calldata data
) external preventReentrant returns (uint256) {
require(_VAULT_.balanceOf(msg.sender) >= shareAmount, "SHARES_NOT_ENOUGH");
(uint256 baseBalance, uint256 quoteBalance) = _VAULT_.getVaultBalance();
uint256 totalShares = _VAULT_.totalSupply();
_VAULT_.burn(msg.sender, amount);
_VAULT_.transferBaseOut(to, baseBalance.mul(amount).div(totalShares));
_VAULT_.transferQuoteOut(to, quoteBalance.mul(amount).div(totalShares));
_VAULT_.burn(msg.sender, shareAmount);
uint256 baseAmount = baseBalance.mul(shareAmount).div(totalShares);
uint256 quoteAmount = quoteBalance.mul(shareAmount).div(totalShares);
_VAULT_.transferBaseOut(to, baseAmount);
_VAULT_.transferQuoteOut(to, quoteAmount);
_VAULT_.sync();
if (data.length > 0) IDODOCallee(to, shareAmount, baseAmount, quoteAmount, data);
}
function retrieve(address to) external {
function retrieve(address to) external preventReentrant {
(uint256 baseBalance, uint256 quoteBalance) = _VAULT_.getVaultBalance();
(uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
if (baseBalance.sub(baseReserve) > 0) {

View File

@@ -12,12 +12,17 @@ import {DVMStorage} from "./DVMStorage.sol";
import {SafeMath} from "../../lib/SafeMath.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol";
import {DODOMath} from "../../lib/DODOMath.sol";
import {IExternalCall} from "../intf/IExternalCall.sol";
import {IDODOCallee} from "../../intf/IDODOCallee.sol";
contract DVMTrader is DVMStorage {
using SafeMath for uint256;
function sellBase(address to) external isSellAllow(to) returns (uint256 receiveQuoteAmount) {
function sellBase(address to)
external
preventReentrant
isSellAllow(to)
returns (uint256 receiveQuoteAmount)
{
uint256 baseInput = _VAULT_.getBaseInput();
uint256 mtFee;
(receiveQuoteAmount, mtFee) = querySellBase(to, baseInput);
@@ -29,7 +34,12 @@ contract DVMTrader is DVMStorage {
return receiveQuoteAmount;
}
function sellQuote(address to) external isBuyAllow(to) returns (uint256 receiveBaseAmount) {
function sellQuote(address to)
external
preventReentrant
isBuyAllow(to)
returns (uint256 receiveBaseAmount)
{
uint256 quoteInput = _VAULT_.getQuoteInput();
uint256 mtFee;
(receiveBaseAmount, mtFee) = querySellQuote(to, quoteInput);
@@ -45,12 +55,13 @@ contract DVMTrader is DVMStorage {
uint256 baseAmount,
uint256 quoteAmount,
address assetTo,
address call,
bytes calldata data
) external {
) external preventReentrant {
_VAULT_.transferBaseOut(assetTo, baseAmount);
_VAULT_.transferQuoteOut(assetTo, quoteAmount);
IExternalCall(call).DVMCall(data);
if (data.length > 0)
IDODOCallee(assetTo).DVMFlashLoanCall(msg.sender, baseAmount, quoteAmount, data);
(uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
(uint256 baseBalance, uint256 quoteBalance) = _VAULT_.getVaultBalance();
@@ -102,26 +113,6 @@ contract DVMTrader is DVMStorage {
return (receiveQuoteAmount, mtFee);
}
// 这是一个仅供查询的合约所有交易都是基于先给input再输出output的
// 所以想要买10ETH这个函数可以给你一个大概的成本你用这个成本输入最后能否得到10ETH是要看情况的
function queryBuyBase(address trader, uint256 receiveBaseAmount)
public
view
returns (uint256 payQuoteAmount)
{
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader);
uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader);
uint256 validReceiveBaseAmount = DecimalMath.divCeil(
receiveBaseAmount,
DecimalMath.ONE.sub(mtFeeRate).sub(lpFeeRate)
);
(uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
uint256 B0 = calculateBase0(baseReserve, quoteReserve);
uint256 B2 = baseReserve.sub(validReceiveBaseAmount);
payQuoteAmount = DODOMath._GeneralIntegrate(B0, baseReserve, B2, _I_, _K_);
return payQuoteAmount;
}
function querySellQuote(address trader, uint256 payQuoteAmount)
public
view
@@ -145,6 +136,26 @@ contract DVMTrader is DVMStorage {
return (receiveBaseAmount, mtFee);
}
// 这是一个仅供查询的合约所有交易都是基于先给input再输出output的
// 所以想要买10ETH这个函数可以给你一个大概的成本你用这个成本输入最后能否得到10ETH是要看情况的
function queryBuyBase(address trader, uint256 receiveBaseAmount)
public
view
returns (uint256 payQuoteAmount)
{
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader);
uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader);
uint256 validReceiveBaseAmount = DecimalMath.divCeil(
receiveBaseAmount,
DecimalMath.ONE.sub(mtFeeRate).sub(lpFeeRate)
);
(uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
uint256 B0 = calculateBase0(baseReserve, quoteReserve);
uint256 B2 = baseReserve.sub(validReceiveBaseAmount);
payQuoteAmount = DODOMath._GeneralIntegrate(B0, baseReserve, B2, _I_, _K_);
return payQuoteAmount;
}
function queryBuyQuote(address trader, uint256 receiveQuoteAmount)
public
view

View File

@@ -1,13 +0,0 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
interface IExternalCall {
function DVMCall(bytes calldata data) external;
}

View File

@@ -0,0 +1,26 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
interface IDODOCallee {
function DVMSellShareCall(
address sender,
uint256 burnShareAmount,
uint256 baseAmount,
uint256 quoteAmount,
bytes calldata data
) external;
function DVMFlashLoanCall(
address sender,
uint256 baseAmount,
uint256 quoteAmount,
bytes calldata data
) external;
}

View File

@@ -53,6 +53,7 @@ library DODOMath {
note: another root is negative, abondan
if deltaBSig=true, then Q2>Q1
if deltaBSig=false, then Q2<Q1
return |Q1-Q2|
*/
function _SolveQuadraticFunctionForTrade(
uint256 Q0,

View File

@@ -17,25 +17,25 @@ interface IPermissionManager {
}
contract PermissionManager is InitializableOwnable {
bool public _BLACKLIST_MODE_ON_;
bool public _WHITELIST_MODE_ON_;
mapping(address => bool) internal _whitelist_;
mapping(address => bool) internal _blacklist_;
function isAllowed(address account) external view returns (bool) {
if (_BLACKLIST_MODE_ON_) {
return !_blacklist_[account];
} else {
if (_WHITELIST_MODE_ON_) {
return _whitelist_[account];
} else {
return !_blacklist_[account];
}
}
function openBlacklist() external onlyOwner {
_BLACKLIST_MODE_ON_ = true;
function openBlacklistMode() external onlyOwner {
_WHITELIST_MODE_ON_ = false;
}
function openWhitelist() external onlyOwner {
_BLACKLIST_MODE_ON_ = true;
function openWhitelistMode() external onlyOwner {
_WHITELIST_MODE_ON_ = true;
}
function addToWhitelist(address account) external onlyOwner {

View File

@@ -51,6 +51,9 @@ describe("Trader", () => {
});
describe("trade", () => {
// it.only("gas cost", async () => {
// await logGas(ctx.DVM.methods.calculateBase0(decimalStr("200"), decimalStr("1")), ctx.sendParam(trader), "calculate base0")
// })
it("buy & sell", async () => {
console.log("BASE0 before buy", await ctx.DVM.methods.getBase0().call())