set external call interface
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
26
contracts/intf/IDODOCallee.sol
Normal file
26
contracts/intf/IDODOCallee.sol
Normal 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;
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user