simplify dvm
This commit is contained in:
@@ -9,8 +9,6 @@ pragma solidity 0.6.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {IFeeRateModel} from "../../lib/FeeRateModel.sol";
|
||||
import {IPermissionManager} from "../../lib/PermissionManager.sol";
|
||||
import {IExternalValue} from "../../lib/ExternalValue.sol";
|
||||
import {IERC20} from "../../intf/IERC20.sol";
|
||||
import {DVMTrader} from "./DVMTrader.sol";
|
||||
import {DVMFunding} from "./DVMFunding.sol";
|
||||
@@ -18,19 +16,14 @@ import {DVMVault} from "./DVMVault.sol";
|
||||
|
||||
contract DVM is DVMTrader, DVMFunding {
|
||||
function init(
|
||||
address owner,
|
||||
address maintainer,
|
||||
address baseTokenAddress,
|
||||
address quoteTokenAddress,
|
||||
address lpFeeRateModel,
|
||||
uint256 lpFeeRate,
|
||||
address mtFeeRateModel,
|
||||
address tradePermissionManager,
|
||||
address gasPriceSource,
|
||||
uint256 i,
|
||||
uint256 k
|
||||
) external {
|
||||
initOwner(owner);
|
||||
|
||||
require(baseTokenAddress != quoteTokenAddress, "BASE_QUOTE_CAN_NOT_BE_SAME");
|
||||
_BASE_TOKEN_ = IERC20(baseTokenAddress);
|
||||
_QUOTE_TOKEN_ = IERC20(quoteTokenAddress);
|
||||
@@ -41,10 +34,8 @@ contract DVM is DVMTrader, DVMFunding {
|
||||
require(k <= 10**18);
|
||||
_K_ = k;
|
||||
|
||||
_LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel);
|
||||
_LP_FEE_RATE_ = lpFeeRate;
|
||||
_MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel);
|
||||
_TRADE_PERMISSION_ = IPermissionManager(tradePermissionManager);
|
||||
_GAS_PRICE_LIMIT_ = IExternalValue(gasPriceSource);
|
||||
_MAINTAINER_ = maintainer;
|
||||
|
||||
string memory connect = "_";
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright 2020 DODO ZOO.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity 0.6.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {IDVM} from "../intf/IDVM.sol";
|
||||
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
|
||||
import {IExternalValue} from "../../lib/ExternalValue.sol";
|
||||
|
||||
contract DVMAdmin is InitializableOwnable {
|
||||
address public _DVM_;
|
||||
|
||||
function init(address owner, address dvm) external {
|
||||
initOwner(owner);
|
||||
_DVM_ = dvm;
|
||||
}
|
||||
|
||||
// function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner {
|
||||
// IDVM(_DVM_).setLpFeeRateModel(newLpFeeRateModel);
|
||||
// }
|
||||
|
||||
function setLpFeeRateValue(uint256 newLpFeeRate) external onlyOwner {
|
||||
IDVM(_DVM_).setLpFeeRateValue(newLpFeeRate);
|
||||
}
|
||||
|
||||
// function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner {
|
||||
// IDVM(_DVM_).setMtFeeRateModel(newMtFeeRateModel);
|
||||
// }
|
||||
|
||||
function setMtFeeRateValue(uint256 newMtFeeRate) external onlyOwner {
|
||||
IDVM(_DVM_).setMtFeeRateValue(newMtFeeRate);
|
||||
}
|
||||
|
||||
// function setTradePermissionManager(address newTradePermissionManager) external onlyOwner {
|
||||
// IDVM(_DVM_).setTradePermissionManager(newTradePermissionManager);
|
||||
// }
|
||||
|
||||
function setMaintainer(address newMaintainer) external onlyOwner {
|
||||
IDVM(_DVM_).setMaintainer(newMaintainer);
|
||||
}
|
||||
|
||||
// function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner {
|
||||
// IDVM(_DVM_).setGasPriceSource(newGasPriceLimitSource);
|
||||
// }
|
||||
|
||||
function setBuy(bool open) external onlyOwner {
|
||||
IDVM(_DVM_).setBuy(open);
|
||||
}
|
||||
|
||||
function setSell(bool open) external onlyOwner {
|
||||
IDVM(_DVM_).setSell(open);
|
||||
}
|
||||
|
||||
// ============ Admin Version Control ============
|
||||
|
||||
function version() external pure returns (string memory) {
|
||||
return "DVMAdmin 1.0.0"; // 1.0.0
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ contract DVMFunding is DVMVault {
|
||||
shares = DecimalMath.mulFloor(totalSupply, mintRatio);
|
||||
}
|
||||
_mint(to, shares);
|
||||
_sync();
|
||||
_setReserve(baseBalance, quoteBalance);
|
||||
emit BuyShares(to, shares, _SHARES_[to]);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,27 +8,16 @@
|
||||
pragma solidity 0.6.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
|
||||
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
|
||||
import {SafeMath} from "../../lib/SafeMath.sol";
|
||||
import {DODOMath} from "../../lib/DODOMath.sol";
|
||||
import {DecimalMath} from "../../lib/DecimalMath.sol";
|
||||
import {IPermissionManager} from "../../lib/PermissionManager.sol";
|
||||
import {IExternalValue} from "../../lib/ExternalValue.sol";
|
||||
import {IFeeRateModel} from "../../lib/FeeRateModel.sol";
|
||||
import {IERC20} from "../../intf/IERC20.sol";
|
||||
|
||||
contract DVMStorage is InitializableOwnable, ReentrancyGuard {
|
||||
contract DVMStorage is ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
|
||||
// ============ Advanced Controls ============
|
||||
|
||||
bool public _BUYING_CLOSE_;
|
||||
bool public _SELLING_CLOSE_;
|
||||
|
||||
IPermissionManager public _TRADE_PERMISSION_;
|
||||
IExternalValue public _GAS_PRICE_LIMIT_;
|
||||
|
||||
// ============ Core Address ============
|
||||
|
||||
address public _MAINTAINER_;
|
||||
@@ -36,8 +25,8 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
|
||||
IERC20 public _BASE_TOKEN_;
|
||||
IERC20 public _QUOTE_TOKEN_;
|
||||
|
||||
uint256 public _BASE_RESERVE_;
|
||||
uint256 public _QUOTE_RESERVE_;
|
||||
uint128 public _BASE_RESERVE_;
|
||||
uint128 public _QUOTE_RESERVE_;
|
||||
|
||||
// ============ Shares (ERC20) ============
|
||||
|
||||
@@ -53,81 +42,13 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
|
||||
|
||||
bytes32 public DOMAIN_SEPARATOR;
|
||||
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
|
||||
bytes32
|
||||
public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
|
||||
bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
|
||||
mapping(address => uint256) public nonces;
|
||||
|
||||
// ============ Variables for Pricing ============
|
||||
|
||||
IFeeRateModel public _LP_FEE_RATE_MODEL_;
|
||||
uint256 public _LP_FEE_RATE_;
|
||||
IFeeRateModel public _MT_FEE_RATE_MODEL_;
|
||||
uint256 public _K_;
|
||||
uint256 public _I_;
|
||||
|
||||
// ============ Events ============
|
||||
|
||||
event SetLpFeeRateModel(address oldAddr, address newAddr);
|
||||
|
||||
event SetMtFeeRateModel(address oldAddr, address newAddr);
|
||||
|
||||
event SetTradePermissionManager(address oldAddr, address newAddr);
|
||||
|
||||
event SetMaintainer(address oldAddr, address newAddr);
|
||||
|
||||
event SetGasPriceSource(address oldAddr, address newAddr);
|
||||
|
||||
event SetBuy(bool allow);
|
||||
|
||||
event SetSell(bool allow);
|
||||
|
||||
event SetLpFeeRate(uint256 newValue);
|
||||
|
||||
event SetMtFeeRate(uint256 newValue);
|
||||
|
||||
// ============ Setting Functions ============
|
||||
|
||||
function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner {
|
||||
emit SetLpFeeRateModel(address(_LP_FEE_RATE_MODEL_), newLpFeeRateModel);
|
||||
_LP_FEE_RATE_MODEL_ = IFeeRateModel(newLpFeeRateModel);
|
||||
}
|
||||
|
||||
function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner {
|
||||
emit SetMtFeeRateModel(address(_MT_FEE_RATE_MODEL_), newMtFeeRateModel);
|
||||
_MT_FEE_RATE_MODEL_ = IFeeRateModel(newMtFeeRateModel);
|
||||
}
|
||||
|
||||
function setLpFeeRateValue(uint256 newLpFeeRate) external onlyOwner {
|
||||
_LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate);
|
||||
emit SetLpFeeRate(newLpFeeRate);
|
||||
}
|
||||
|
||||
function setMtFeeRateValue(uint256 newMtFeeRate) external onlyOwner {
|
||||
_MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate);
|
||||
emit SetMtFeeRate(newMtFeeRate);
|
||||
}
|
||||
|
||||
function setTradePermissionManager(address newTradePermissionManager) external onlyOwner {
|
||||
emit SetTradePermissionManager(address(_TRADE_PERMISSION_), newTradePermissionManager);
|
||||
_TRADE_PERMISSION_ = IPermissionManager(newTradePermissionManager);
|
||||
}
|
||||
|
||||
function setMaintainer(address newMaintainer) external onlyOwner {
|
||||
emit SetMaintainer(address(_MAINTAINER_), newMaintainer);
|
||||
_MAINTAINER_ = newMaintainer;
|
||||
}
|
||||
|
||||
function setGasPriceSource(address newGasPriceLimitSource) external onlyOwner {
|
||||
emit SetGasPriceSource(address(_GAS_PRICE_LIMIT_), newGasPriceLimitSource);
|
||||
_GAS_PRICE_LIMIT_ = IExternalValue(newGasPriceLimitSource);
|
||||
}
|
||||
|
||||
function setBuy(bool open) external onlyOwner {
|
||||
emit SetBuy(open);
|
||||
_BUYING_CLOSE_ = !open;
|
||||
}
|
||||
|
||||
function setSell(bool open) external onlyOwner {
|
||||
emit SetSell(open);
|
||||
_SELLING_CLOSE_ = !open;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,42 +35,21 @@ contract DVMTrader is DVMVault {
|
||||
uint256 quoteAmount
|
||||
);
|
||||
|
||||
// ============ Modifiers ============
|
||||
|
||||
modifier isBuyAllow(address trader) {
|
||||
require(!_BUYING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(trader), "TRADER_BUY_NOT_ALLOWED");
|
||||
_;
|
||||
}
|
||||
|
||||
modifier isSellAllow(address trader) {
|
||||
require(
|
||||
!_SELLING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(trader),
|
||||
"TRADER_SELL_NOT_ALLOWED"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier limitGasPrice() {
|
||||
require(tx.gasprice <= _GAS_PRICE_LIMIT_.get(), "GAS_PRICE_EXCEED");
|
||||
_;
|
||||
}
|
||||
|
||||
// ============ Execute ============
|
||||
|
||||
function sellBase(address to)
|
||||
external
|
||||
preventReentrant
|
||||
limitGasPrice
|
||||
isSellAllow(to) // set DVM address in trade permission
|
||||
returns (uint256 receiveQuoteAmount)
|
||||
{
|
||||
uint256 baseInput = getBaseInput();
|
||||
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
|
||||
uint256 baseInput = baseBalance.sub(uint256(_BASE_RESERVE_));
|
||||
uint256 mtFee;
|
||||
(receiveQuoteAmount, mtFee) = querySellBase(tx.origin, baseInput);
|
||||
|
||||
_transferQuoteOut(to, receiveQuoteAmount);
|
||||
_transferQuoteOut(_MAINTAINER_, mtFee);
|
||||
_sync();
|
||||
_setReserve(baseBalance, _QUOTE_TOKEN_.balanceOf(address(this)));
|
||||
|
||||
emit DODOSwap(
|
||||
address(_BASE_TOKEN_),
|
||||
@@ -84,17 +63,16 @@ contract DVMTrader is DVMVault {
|
||||
function sellQuote(address to)
|
||||
external
|
||||
preventReentrant
|
||||
limitGasPrice
|
||||
isBuyAllow(to)
|
||||
returns (uint256 receiveBaseAmount)
|
||||
{
|
||||
uint256 quoteInput = getQuoteInput();
|
||||
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
|
||||
uint256 quoteInput = quoteBalance.sub(uint256(_QUOTE_RESERVE_));
|
||||
uint256 mtFee;
|
||||
(receiveBaseAmount, mtFee) = querySellQuote(tx.origin, quoteInput);
|
||||
|
||||
_transferBaseOut(to, receiveBaseAmount);
|
||||
_transferBaseOut(_MAINTAINER_, mtFee);
|
||||
_sync();
|
||||
_setReserve(_BASE_TOKEN_.balanceOf(address(this)), quoteBalance);
|
||||
|
||||
emit DODOSwap(
|
||||
address(_QUOTE_TOKEN_),
|
||||
@@ -110,7 +88,7 @@ contract DVMTrader is DVMVault {
|
||||
uint256 quoteAmount,
|
||||
address assetTo,
|
||||
bytes calldata data
|
||||
) external preventReentrant isSellAllow(assetTo) isBuyAllow(assetTo) {
|
||||
) external preventReentrant {
|
||||
_transferBaseOut(assetTo, baseAmount);
|
||||
_transferQuoteOut(assetTo, quoteAmount);
|
||||
|
||||
@@ -128,9 +106,9 @@ contract DVMTrader is DVMVault {
|
||||
|
||||
// sell quote
|
||||
if (baseBalance < _BASE_RESERVE_) {
|
||||
uint256 quoteInput = quoteBalance.sub(_QUOTE_RESERVE_);
|
||||
uint256 quoteInput = quoteBalance.sub(uint256(_QUOTE_RESERVE_));
|
||||
(uint256 receiveBaseAmount, uint256 mtFee) = querySellQuote(tx.origin, quoteInput);
|
||||
require(_BASE_RESERVE_.sub(baseBalance) <= receiveBaseAmount, "FLASH_LOAN_FAILED");
|
||||
require(uint256(_BASE_RESERVE_).sub(baseBalance) <= receiveBaseAmount, "FLASH_LOAN_FAILED");
|
||||
|
||||
_transferBaseOut(_MAINTAINER_, mtFee);
|
||||
emit DODOSwap(
|
||||
@@ -138,15 +116,15 @@ contract DVMTrader is DVMVault {
|
||||
address(_BASE_TOKEN_),
|
||||
quoteInput,
|
||||
receiveBaseAmount,
|
||||
tx.origin
|
||||
msg.sender
|
||||
);
|
||||
}
|
||||
|
||||
// sell base
|
||||
if (quoteBalance < _QUOTE_RESERVE_) {
|
||||
uint256 baseInput = baseBalance.sub(_BASE_RESERVE_);
|
||||
uint256 baseInput = baseBalance.sub(uint256(_BASE_RESERVE_));
|
||||
(uint256 receiveQuoteAmount, uint256 mtFee) = querySellBase(tx.origin, baseInput);
|
||||
require(_QUOTE_RESERVE_.sub(quoteBalance) <= receiveQuoteAmount, "FLASH_LOAN_FAILED");
|
||||
require(uint256(_QUOTE_RESERVE_).sub(quoteBalance) <= receiveQuoteAmount, "FLASH_LOAN_FAILED");
|
||||
|
||||
_transferQuoteOut(_MAINTAINER_, mtFee);
|
||||
emit DODOSwap(
|
||||
@@ -172,11 +150,10 @@ contract DVMTrader is DVMVault {
|
||||
{
|
||||
(receiveQuoteAmount, ) = PMMPricing.sellBaseToken(getPMMState(), payBaseAmount);
|
||||
|
||||
uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader);
|
||||
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader);
|
||||
mtFee = DecimalMath.mulFloor(receiveQuoteAmount, mtFeeRate);
|
||||
receiveQuoteAmount = receiveQuoteAmount
|
||||
.sub(DecimalMath.mulFloor(receiveQuoteAmount, lpFeeRate))
|
||||
.sub(DecimalMath.mulFloor(receiveQuoteAmount, _LP_FEE_RATE_))
|
||||
.sub(mtFee);
|
||||
}
|
||||
|
||||
@@ -187,11 +164,10 @@ contract DVMTrader is DVMVault {
|
||||
{
|
||||
(receiveBaseAmount, ) = PMMPricing.sellQuoteToken(getPMMState(), payQuoteAmount);
|
||||
|
||||
uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader);
|
||||
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader);
|
||||
mtFee = DecimalMath.mulFloor(receiveBaseAmount, mtFeeRate);
|
||||
receiveBaseAmount = receiveBaseAmount
|
||||
.sub(DecimalMath.mulFloor(receiveBaseAmount, lpFeeRate))
|
||||
.sub(DecimalMath.mulFloor(receiveBaseAmount, _LP_FEE_RATE_))
|
||||
.sub(mtFee);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,15 +36,10 @@ contract DVMVault is DVMStorage {
|
||||
}
|
||||
|
||||
function getUserFeeRate(address user) external view returns (uint256 lpFeeRate, uint256 mtFeeRate) {
|
||||
lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(user);
|
||||
lpFeeRate = _LP_FEE_RATE_;
|
||||
mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(user);
|
||||
}
|
||||
|
||||
function getUserTradePermission(address user) external view returns (bool isBuyAllow, bool isSellAllow) {
|
||||
isBuyAllow = (!_BUYING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(user));
|
||||
isSellAllow = (!_SELLING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(user));
|
||||
}
|
||||
|
||||
// ============ Asset In ============
|
||||
|
||||
function getBaseInput() public view returns (uint256 input) {
|
||||
@@ -57,14 +52,21 @@ contract DVMVault is DVMStorage {
|
||||
|
||||
// ============ Set States ============
|
||||
|
||||
function _setReserve(uint256 baseReserve, uint256 quoteReserve) internal {
|
||||
require(baseReserve <= uint128(-1) && quoteReserve <= uint128(-1), "OVERFLOW");
|
||||
_BASE_RESERVE_ = uint128(baseReserve);
|
||||
_QUOTE_RESERVE_ = uint128(quoteReserve);
|
||||
}
|
||||
|
||||
function _sync() internal {
|
||||
uint256 baseBalance = _BASE_TOKEN_.balanceOf(address(this));
|
||||
uint256 quoteBalance = _QUOTE_TOKEN_.balanceOf(address(this));
|
||||
require(baseBalance <= uint128(-1) && quoteBalance <= uint128(-1), "OVERFLOW");
|
||||
if (baseBalance != _BASE_RESERVE_) {
|
||||
_BASE_RESERVE_ = baseBalance;
|
||||
_BASE_RESERVE_ = uint128(baseBalance);
|
||||
}
|
||||
if (quoteBalance != _QUOTE_RESERVE_) {
|
||||
_QUOTE_RESERVE_ = quoteBalance;
|
||||
_QUOTE_RESERVE_ = uint128(quoteBalance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user