This commit is contained in:
mingda
2020-11-05 00:26:45 +08:00
parent dd60e1727f
commit 47a14008f4
17 changed files with 366 additions and 234 deletions

View File

@@ -1,70 +0,0 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {Ownable} from "../lib/Ownable.sol";
import {ICloneFactory} from "../lib/CloneFactory.sol";
import {DVMVault} from "./impl/DVMVault.sol";
import {DVMController} from "./impl/DVMController.sol";
contract DVMFactory is Ownable {
address public _CLONE_FACTORY_;
address public _VAULT_TEMPLATE_;
address public _CONTROLLER_TEMPLATE_;
// base -> quote -> DVM address list
mapping(address => mapping(address => address[])) _REGISTRY_;
constructor(
address cloneFactory,
address vaultTemplate,
address controllerTemplate
) public {
_CLONE_FACTORY_ = cloneFactory;
_VAULT_TEMPLATE_ = vaultTemplate;
_CONTROLLER_TEMPLATE_ = controllerTemplate;
}
function createDODOVendorMachine(
address maintainer,
address baseToken,
address quoteToken,
address lpFeeRateModel,
address mtFeeRateModel,
uint256 i,
uint256 k,
uint256 gasPriceLimit
) external returns (address newVendorMachine) {
newVendorMachine = ICloneFactory(_CLONE_FACTORY_).clone(_CONTROLLER_TEMPLATE_);
address vault = ICloneFactory(_CLONE_FACTORY_).clone(_VAULT_TEMPLATE_);
DVMVault(vault).init(newVendorMachine, baseToken, quoteToken); // vault owner is controller
DVMController(newVendorMachine).init(
msg.sender,
maintainer,
vault,
lpFeeRateModel,
mtFeeRateModel,
i,
k,
gasPriceLimit
);
_REGISTRY_[baseToken][quoteToken].push(newVendorMachine);
return newVendorMachine;
}
function getVendorMachine(address baseToken, address quoteToken)
external
view
returns (address[] memory machines)
{
return _REGISTRY_[baseToken][quoteToken];
}
}

View File

@@ -8,32 +8,40 @@
pragma solidity 0.6.9; pragma solidity 0.6.9;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import {IFeeRateModel} from "../../intf/IFeeRateModel.sol";
import {IPermissionManager} from "../../lib/PermissionManager.sol";
import {DVMTrader} from "./DVMTrader.sol"; import {DVMTrader} from "./DVMTrader.sol";
import {DVMFunding} from "./DVMFunding.sol"; import {DVMFunding} from "./DVMFunding.sol";
import {DVMAdmin} from "./DVMAdmin.sol";
import {DVMVault} from "./DVMVault.sol"; import {DVMVault} from "./DVMVault.sol";
import {IFeeRateModel} from "../../intf/IFeeRateModel.sol";
contract DVMController is DVMTrader, DVMFunding, DVMAdmin { contract DVM is DVMTrader, DVMFunding {
function init( function init(
address owner, address owner,
address maintainer, address maintainer,
address vault, address vault,
address lpFeeRateModel, address lpFeeRateModel,
address mtFeeRateModel, address mtFeeRateModel,
address tradePermissionManager,
address fundingPermissionManager,
uint256 i, uint256 i,
uint256 k, uint256 k
uint256 gasPriceLimit
) external { ) external {
initOwner(owner); initOwner(owner);
_MAINTAINER_ = maintainer;
_VAULT_ = DVMVault(vault); _VAULT_ = DVMVault(vault);
_BASE_TOKEN_ = _VAULT_._BASE_TOKEN_(); _BASE_TOKEN_ = _VAULT_._BASE_TOKEN_();
_QUOTE_TOKEN_ = _VAULT_._QUOTE_TOKEN_(); _QUOTE_TOKEN_ = _VAULT_._QUOTE_TOKEN_();
_LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel); _LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel);
_MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel); _MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel);
_TRADE_PERMISSION_ = IPermissionManager(tradePermissionManager);
_FUNDING_PERMISSION_ = IPermissionManager(fundingPermissionManager);
_MAINTAINER_ = maintainer;
_I_ = i; _I_ = i;
_K_ = k; _K_ = k;
_GAS_PRICE_LIMIT_ = gasPriceLimit; _GAS_PRICE_LIMIT_ = uint256(-1);
}
// ============ Version Control ============
function version() external pure returns (uint256) {
return 100; // 1.0.0
} }
} }

View File

@@ -1,19 +0,0 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {DVMStorage} from "./DVMStorage.sol";
contract DVMAdmin is DVMStorage{
function setI(uint256 newI) external onlyOwner{}
function setK(uint256 newK) external onlyOwner{}
}

View File

@@ -13,7 +13,7 @@ import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
import {SafeMath} from "../../lib/SafeMath.sol"; import {SafeMath} from "../../lib/SafeMath.sol";
import {DODOMath} from "../../lib/DODOMath.sol"; import {DODOMath} from "../../lib/DODOMath.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol";
import {PermissionManager} from "../../lib/PermissionManager.sol"; import {IPermissionManager} from "../../lib/PermissionManager.sol";
import {IFeeRateModel} from "../../intf/IFeeRateModel.sol"; import {IFeeRateModel} from "../../intf/IFeeRateModel.sol";
import {DVMVault} from "./DVMVault.sol"; import {DVMVault} from "./DVMVault.sol";
@@ -30,8 +30,8 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
bool public _BUYING_ALLOWED_; bool public _BUYING_ALLOWED_;
bool public _SELLING_ALLOWED_; bool public _SELLING_ALLOWED_;
PermissionManager public _TRADE_PERMISSION_; IPermissionManager public _TRADE_PERMISSION_;
PermissionManager public _FUNDING_PERMISSION_; IPermissionManager public _FUNDING_PERMISSION_;
// ============ Core Address ============ // ============ Core Address ============
@@ -48,7 +48,6 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
uint256 public _I_; uint256 public _I_;
DVMVault public _VAULT_; DVMVault public _VAULT_;
DVMVault public _PROTECTION_VAULT_;
// ============ Modifiers ============ // ============ Modifiers ============
@@ -58,13 +57,31 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard {
} }
// ============ Helper Functions ============ // ============ Helper Functions ============
function getBase0() public view returns (uint256) {
uint256 fairAmount = DecimalMath.divFloor(_VAULT_._QUOTE_RESERVE_(), _I_); function getBase0(uint256 baseAmount, uint256 quoteAmount) public view returns (uint256) {
return DODOMath._SolveQuadraticFunctionForTarget(_VAULT_._BASE_RESERVE_(), _K_, fairAmount); uint256 fairAmount = DecimalMath.divFloor(quoteAmount, _I_);
return DODOMath._SolveQuadraticFunctionForTarget(baseAmount, _K_, fairAmount);
} }
// ============ Version Control ============ // ============ Setting Functions ============
function version() external pure returns (uint256) {
return 101; // 1.0.1 function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner {
_LP_FEE_RATE_MODEL_ = IFeeRateModel(newLpFeeRateModel);
}
function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner {
_MT_FEE_RATE_MODEL_ = IFeeRateModel(newMtFeeRateModel);
}
function setTradePermissionManager(address newTradePermissionManager) external onlyOwner {
_TRADE_PERMISSION_ = IPermissionManager(newTradePermissionManager);
}
function setFundingPermissionManager(address newFundingPermissionManager) external onlyOwner {
_FUNDING_PERMISSION_ = IPermissionManager(newFundingPermissionManager);
}
function setMaintainer(address newMaintainer) external onlyOwner {
_MAINTAINER_ = newMaintainer;
} }
} }

View File

@@ -12,6 +12,7 @@ import {DVMStorage} from "./DVMStorage.sol";
import {SafeMath} from "../../lib/SafeMath.sol"; import {SafeMath} from "../../lib/SafeMath.sol";
import {DecimalMath} from "../../lib/DecimalMath.sol"; import {DecimalMath} from "../../lib/DecimalMath.sol";
import {DODOMath} from "../../lib/DODOMath.sol"; import {DODOMath} from "../../lib/DODOMath.sol";
import {IExternalCall} from "../intf/IExternalCall.sol";
contract DVMTrader is DVMStorage { contract DVMTrader is DVMStorage {
using SafeMath for uint256; using SafeMath for uint256;
@@ -19,7 +20,7 @@ contract DVMTrader is DVMStorage {
function sellBase(address to) external returns (uint256 receiveQuoteAmount) { function sellBase(address to) external returns (uint256 receiveQuoteAmount) {
uint256 baseInput = _VAULT_.getBaseInput(); uint256 baseInput = _VAULT_.getBaseInput();
uint256 mtFee; uint256 mtFee;
(receiveQuoteAmount, mtFee) = querySellBase(baseInput); (receiveQuoteAmount, mtFee) = querySellBase(to, baseInput);
_VAULT_.transferQuoteOut(to, receiveQuoteAmount); _VAULT_.transferQuoteOut(to, receiveQuoteAmount);
if (mtFee > 0) { if (mtFee > 0) {
_VAULT_.transferQuoteOut(_MAINTAINER_, mtFee); _VAULT_.transferQuoteOut(_MAINTAINER_, mtFee);
@@ -31,7 +32,7 @@ contract DVMTrader is DVMStorage {
function sellQuote(address to) external returns (uint256 receiveBaseAmount) { function sellQuote(address to) external returns (uint256 receiveBaseAmount) {
uint256 quoteInput = _VAULT_.getQuoteInput(); uint256 quoteInput = _VAULT_.getQuoteInput();
uint256 mtFee; uint256 mtFee;
(receiveBaseAmount, mtFee) = querySellQuote(quoteInput); (receiveBaseAmount, mtFee) = querySellQuote(to, quoteInput);
_VAULT_.transferBaseOut(to, receiveBaseAmount); _VAULT_.transferBaseOut(to, receiveBaseAmount);
if (mtFee > 0) { if (mtFee > 0) {
_VAULT_.transferBaseOut(_MAINTAINER_, mtFee); _VAULT_.transferBaseOut(_MAINTAINER_, mtFee);
@@ -40,50 +41,82 @@ contract DVMTrader is DVMStorage {
return receiveBaseAmount; return receiveBaseAmount;
} }
function querySellBase(uint256 payBaseAmount) function flashLoan(
uint256 baseAmount,
uint256 quoteAmount,
address assetTo,
address call,
bytes calldata data
) external {
(uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
uint256 B0 = getBase0(baseReserve, quoteReserve);
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(assetTo, quoteAmount);
uint256 baseMtFee = DecimalMath.mulCeil(baseAmount, mtFeeRate);
uint256 quoteMtFee = DecimalMath.mulCeil(quoteAmount, mtFeeRate);
_VAULT_.transferBaseOut(_MAINTAINER_, baseMtFee);
_VAULT_.transferQuoteOut(_MAINTAINER_, quoteMtFee);
_VAULT_.transferBaseOut(assetTo, baseAmount);
_VAULT_.transferQuoteOut(assetTo, quoteAmount);
IExternalCall(call).DVMCall(data);
(uint256 baseBalance, uint256 quoteBalance) = _VAULT_.getVaultBalance();
uint256 newB0 = getBase0(baseBalance, quoteBalance);
require(newB0 >= B0, "FLASH_LOAN_FAILED");
_VAULT_.sync();
}
function querySellBase(address trader, uint256 payBaseAmount)
public public
view view
returns (uint256 receiveQuoteAmount, uint256 mtFee) returns (uint256 receiveQuoteAmount, uint256 mtFee)
{ {
uint256 B0 = getBase0(); (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
uint256 B2 = _VAULT_._BASE_RESERVE_(); uint256 B0 = getBase0(baseReserve, quoteReserve);
uint256 B1 = B2.add(payBaseAmount);
uint256 B1 = baseReserve.add(payBaseAmount);
require(B0 >= B1, "DODO_BASE_BALANCE_NOT_ENOUGH"); require(B0 >= B1, "DODO_BASE_BALANCE_NOT_ENOUGH");
uint256 Q = DODOMath._GeneralIntegrate(B0, B1, B2, _I_, _K_); uint256 Q = DODOMath._GeneralIntegrate(B0, B1, baseReserve, _I_, _K_);
uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(Q);
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(Q); uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader, Q);
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader, Q);
mtFee = DecimalMath.mulCeil(Q, mtFeeRate); mtFee = DecimalMath.mulCeil(Q, mtFeeRate);
receiveQuoteAmount = Q.sub(mtFee).sub(DecimalMath.mulCeil(Q, lpFeeRate)); receiveQuoteAmount = Q.sub(mtFee).sub(DecimalMath.mulCeil(Q, lpFeeRate));
return (receiveQuoteAmount, mtFee); return (receiveQuoteAmount, mtFee);
} }
function querySellQuote(uint256 payQuoteAmount) function querySellQuote(address trader, uint256 payQuoteAmount)
public public
view view
returns (uint256 receiveBaseAmount, uint256 mtFee) returns (uint256 receiveBaseAmount, uint256 mtFee)
{ {
uint256 B0 = getBase0(); (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
uint256 B1 = _VAULT_._BASE_RESERVE_(); uint256 B0 = getBase0(baseReserve, quoteReserve);
uint256 fairAmount = DecimalMath.divFloor(payQuoteAmount, _I_); uint256 fairAmount = DecimalMath.divFloor(payQuoteAmount, _I_);
uint256 newBaseReserve = DODOMath._SolveQuadraticFunctionForTrade( uint256 newBaseReserve = DODOMath._SolveQuadraticFunctionForTrade(
B0, B0,
B1, baseReserve,
fairAmount, fairAmount,
false, false,
_K_ _K_
); );
uint256 deltaBase = B1.sub(newBaseReserve); uint256 deltaBase = baseReserve.sub(newBaseReserve);
uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(payQuoteAmount); uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader, payQuoteAmount);
uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(payQuoteAmount); uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader, payQuoteAmount);
mtFee = DecimalMath.mulCeil(deltaBase, mtFeeRate); mtFee = DecimalMath.mulCeil(deltaBase, mtFeeRate);
receiveBaseAmount = deltaBase.sub(mtFee).sub(DecimalMath.mulCeil(deltaBase, lpFeeRate)); receiveBaseAmount = deltaBase.sub(mtFee).sub(DecimalMath.mulCeil(deltaBase, lpFeeRate));
return (receiveBaseAmount, mtFee); return (receiveBaseAmount, mtFee);
} }
function getMidPrice() public view returns (uint256 midPrice) { function getMidPrice() public view returns (uint256 midPrice) {
uint256 B0 = getBase0(); (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve();
uint256 B1 = _VAULT_._BASE_RESERVE_(); uint256 B0 = getBase0(baseReserve, quoteReserve);
uint256 offsetRatio = DecimalMath.ONE.mul(B0).div(B1).mul(B0).div(B1);
uint256 offsetRatio = DecimalMath.ONE.mul(B0).div(baseReserve).mul(B0).div(baseReserve);
uint256 offset = DecimalMath.ONE.sub(_K_).add(DecimalMath.mulFloor(offsetRatio, _K_)); uint256 offset = DecimalMath.ONE.sub(_K_).add(DecimalMath.mulFloor(offsetRatio, _K_));
return DecimalMath.mulFloor(_I_, offset); return DecimalMath.mulFloor(_I_, offset);
} }

View File

@@ -109,14 +109,6 @@ contract DVMVault is InitializableOwnable {
} }
} }
function transferOut(
address token,
address to,
uint256 amount
) public onlyOwner {
IERC20(token).safeTransfer(to, amount);
}
function transferBaseOut(address to, uint256 amount) public onlyOwner { function transferBaseOut(address to, uint256 amount) public onlyOwner {
IERC20(_BASE_TOKEN_).safeTransfer(to, amount); IERC20(_BASE_TOKEN_).safeTransfer(to, amount);
} }
@@ -208,4 +200,6 @@ contract DVMVault is InitializableOwnable {
emit Burn(user, value); emit Burn(user, value);
emit Transfer(user, address(0), value); emit Transfer(user, address(0), value);
} }
// function approveAndCall()
} }

View File

@@ -0,0 +1,23 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
interface IDVM {
function init(
address owner,
address maintainer,
address vault,
address lpFeeRateModel,
address mtFeeRateModel,
address tradePermissionManager,
address fundingPermissionManager,
uint256 i,
uint256 k
) external;
}

View File

@@ -0,0 +1,17 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
interface IDVMVault {
function init(
address owner,
address _baseToken,
address _quoteToken
) external;
}

View File

@@ -0,0 +1,13 @@
/*
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,93 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {Ownable} from "../lib/Ownable.sol";
import {ICloneFactory} from "../lib/CloneFactory.sol";
import {IConstFeeRateModel} from "../lib/ConstFeeRateModel.sol";
import {IDVM} from "../DODOVendorMachine/intf/IDVM.sol";
import {IDVMVault} from "../DODOVendorMachine/intf/IDVMVault.sol";
import {IPermissionManager} from "../lib/PermissionManager.sol";
contract DVMFactory is Ownable {
address public _CLONE_FACTORY_;
address public _VAULT_TEMPLATE_;
address public _DVM_TEMPLATE_;
address public _FEE_RATE_MODEL_TEMPLATE_;
address public _PERMISSION_MANAGER_TEMPLATE_;
// base -> quote -> DVM address list
mapping(address => mapping(address => address[])) _REGISTRY_;
constructor(
address cloneFactory,
address vaultTemplate,
address dvmTemplate,
address feeRateModelTemplate,
address permissionManagerTemplate
) public {
_CLONE_FACTORY_ = cloneFactory;
_VAULT_TEMPLATE_ = vaultTemplate;
_DVM_TEMPLATE_ = dvmTemplate;
_FEE_RATE_MODEL_TEMPLATE_ = feeRateModelTemplate;
_PERMISSION_MANAGER_TEMPLATE_ = permissionManagerTemplate;
}
function createStandardDODOVendorMachine(
address baseToken,
address quoteToken,
uint256 lpFeeRate,
uint256 mtFeeRate,
uint256 i,
uint256 k
) external returns (address newVendorMachine) {
newVendorMachine = ICloneFactory(_CLONE_FACTORY_).clone(_DVM_TEMPLATE_);
address vault = ICloneFactory(_CLONE_FACTORY_).clone(_VAULT_TEMPLATE_);
IDVMVault(vault).init(newVendorMachine, baseToken, quoteToken); // vault owner is controller
IDVM(newVendorMachine).init(
msg.sender,
msg.sender,
vault,
createConstFeeRateModel(msg.sender, lpFeeRate),
createConstFeeRateModel(msg.sender, mtFeeRate),
createPermissionManager(msg.sender),
createPermissionManager(msg.sender),
i,
k
);
_REGISTRY_[baseToken][quoteToken].push(newVendorMachine);
return newVendorMachine;
}
function createConstFeeRateModel(address owner, uint256 feeRate)
public
returns (address feeRateModel)
{
feeRateModel = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_RATE_MODEL_TEMPLATE_);
IConstFeeRateModel(feeRateModel).init(owner, feeRate);
return feeRateModel;
}
function createPermissionManager(address owner) public returns (address permissionManager) {
permissionManager = ICloneFactory(_CLONE_FACTORY_).clone(_PERMISSION_MANAGER_TEMPLATE_);
IPermissionManager(permissionManager).initOwner(owner);
return permissionManager;
}
function getVendorMachine(address baseToken, address quoteToken)
external
view
returns (address[] memory machines)
{
return _REGISTRY_[baseToken][quoteToken];
}
}

View File

@@ -8,7 +8,7 @@
pragma solidity 0.6.9; pragma solidity 0.6.9;
import {Ownable} from "../lib/Ownable.sol"; import {Ownable} from "../lib/Ownable.sol";
import {DVMController} from "../DODOVendorMachine/impl/DVMController.sol"; import {DVM} from "../DODOVendorMachine/impl/DVM.sol";
import {DVMVault} from "../DODOVendorMachine/impl/DVMVault.sol"; import {DVMVault} from "../DODOVendorMachine/impl/DVMVault.sol";
import {IERC20} from "../intf/IERC20.sol"; import {IERC20} from "../intf/IERC20.sol";
import {SafeERC20} from "../lib/SafeERC20.sol"; import {SafeERC20} from "../lib/SafeERC20.sol";
@@ -20,49 +20,47 @@ contract SmartRoute is Ownable {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
function sellBaseOnDVM( function sellBaseOnDVM(
address DVM, address DVMAddress,
address to, address to,
uint256 baseAmount, uint256 baseAmount,
uint256 minReceive uint256 minReceive
) public returns (uint256 receiveAmount) { ) public returns (uint256 receiveAmount) {
IERC20(DVMController(DVM)._BASE_TOKEN_()).safeTransferFrom( IERC20(DVM(DVMAddress)._BASE_TOKEN_()).safeTransferFrom(
msg.sender, msg.sender,
address(DVMController(DVM)._VAULT_()), address(DVM(DVMAddress)._VAULT_()),
baseAmount baseAmount
); );
receiveAmount = DVMController(DVM).sellBase(to); receiveAmount = DVM(DVMAddress).sellBase(to);
require(receiveAmount >= minReceive, "RECEIVE_NOT_ENOUGH"); require(receiveAmount >= minReceive, "RECEIVE_NOT_ENOUGH");
return receiveAmount; return receiveAmount;
} }
function sellQuoteOnDVM( function sellQuoteOnDVM(
address DVM, address DVMAddress,
address to, address to,
uint256 quoteAmount, uint256 quoteAmount,
uint256 minReceive uint256 minReceive
) public returns (uint256 receiveAmount) { ) public returns (uint256 receiveAmount) {
IERC20(DVMController(DVM)._QUOTE_TOKEN_()).safeTransferFrom( IERC20(DVM(DVMAddress)._QUOTE_TOKEN_()).safeTransferFrom(
msg.sender, msg.sender,
address(DVMController(DVM)._VAULT_()), address(DVM(DVMAddress)._VAULT_()),
quoteAmount quoteAmount
); );
receiveAmount = DVMController(DVM).sellQuote(to); receiveAmount = DVM(DVMAddress).sellQuote(to);
require(receiveAmount >= minReceive, "RECEIVE_NOT_ENOUGU"); require(receiveAmount >= minReceive, "RECEIVE_NOT_ENOUGU");
return receiveAmount; return receiveAmount;
} }
function depositToDVM( function depositToDVM(
address DVM, address DVMAddress,
address to, address to,
uint256 baseAmount, uint256 baseAmount,
uint256 quoteAmount uint256 quoteAmount
) public returns (uint256 shares) { ) public returns (uint256 shares) {
address vault = address(DVMController(DVM)._VAULT_()); address vault = address(DVM(DVMAddress)._VAULT_());
uint256 adjustedBaseAmount; uint256 adjustedBaseAmount;
uint256 adjustedQuoteAmount; uint256 adjustedQuoteAmount;
(uint256 baseReserve, uint256 quoteReserve) = DVMController(DVM) (uint256 baseReserve, uint256 quoteReserve) = DVM(DVMAddress)._VAULT_().getVaultReserve();
._VAULT_()
.getVaultReserve();
if (quoteReserve == 0 && baseReserve == 0) { if (quoteReserve == 0 && baseReserve == 0) {
adjustedBaseAmount = baseAmount; adjustedBaseAmount = baseAmount;
@@ -86,17 +84,17 @@ contract SmartRoute is Ownable {
} }
} }
IERC20(DVMController(DVM)._BASE_TOKEN_()).safeTransferFrom( IERC20(DVM(DVMAddress)._BASE_TOKEN_()).safeTransferFrom(
msg.sender, msg.sender,
vault, vault,
adjustedBaseAmount adjustedBaseAmount
); );
IERC20(DVMController(DVM)._QUOTE_TOKEN_()).safeTransferFrom( IERC20(DVM(DVMAddress)._QUOTE_TOKEN_()).safeTransferFrom(
msg.sender, msg.sender,
vault, vault,
adjustedQuoteAmount adjustedQuoteAmount
); );
return DVMController(DVM).buyShares(to); return DVM(DVMAddress).buyShares(to);
} }
} }

View File

@@ -1,23 +0,0 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IFeeRateModel} from "../intf/IFeeRateModel.sol";
contract ConstFeeRateModel is IFeeRateModel {
uint256 public _FEE_RATE_;
constructor(uint256 feeRate) public {
feeRate = _FEE_RATE_;
}
function getFeeRate(uint256) external override view returns (uint256) {
return _FEE_RATE_;
}
}

View File

@@ -1,28 +0,0 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IFeeRateModel} from "../intf/IFeeRateModel.sol";
import {Ownable} from "../lib/Ownable.sol";
contract NaiveFeeRateModel is Ownable, IFeeRateModel {
uint256 public _FEE_RATE_;
constructor(uint256 feeRate) public {
_FEE_RATE_ = feeRate;
}
function setFeeRate(uint256 newFeeRate) external {
_FEE_RATE_ = newFeeRate;
}
function getFeeRate(uint256) external override view returns (uint256) {
return _FEE_RATE_;
}
}

View File

@@ -8,7 +8,6 @@
pragma solidity 0.6.9; pragma solidity 0.6.9;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
interface IFeeRateModel { interface IFeeRateModel {
function getFeeRate(uint256 amount) external view returns (uint256); function getFeeRate(address trader, uint256 amount) external view returns (uint256);
} }

View File

@@ -0,0 +1,38 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {IFeeRateModel} from "../intf/IFeeRateModel.sol";
import {Ownable} from "../lib/Ownable.sol";
import {InitializableOwnable} from "../lib/InitializableOwnable.sol";
interface IConstFeeRateModel {
function init(address owner, uint256 feeRate) external;
function setFeeRate(uint256 newFeeRate) external;
function getFeeRate(address, uint256) external view returns (uint256);
}
contract ConstFeeRateModel is InitializableOwnable, IFeeRateModel {
uint256 public _FEE_RATE_;
function init(address owner, uint256 feeRate) external {
initOwner(owner);
_FEE_RATE_ = feeRate;
}
function setFeeRate(uint256 newFeeRate) external {
_FEE_RATE_ = newFeeRate;
}
function getFeeRate(address, uint256) external override view returns (uint256) {
return _FEE_RATE_;
}
}

View File

@@ -0,0 +1,36 @@
/*
Copyright 2020 DODO ZOO.
SPDX-License-Identifier: Apache-2.0
*/
pragma solidity 0.6.9;
pragma experimental ABIEncoderV2;
import {InitializableOwnable} from "./InitializableOwnable.sol";
contract OperatorSystem is InitializableOwnable {
mapping(address => bool) internal _global_operator_;
mapping(address => mapping(address => bool)) internal _operator_; // user=>operator=>isValid
function isValidOperator(address user, address operator) external view returns (bool) {
return user == operator || _global_operator_[operator] || _operator_[user][operator];
}
function addGlobalOperator(address operator) external onlyOwner {
_global_operator_[operator] = true;
}
function removeGlobalOperator(address operator) external onlyOwner {
_global_operator_[operator] = false;
}
function addOperator(address operator) external {
_operator_[msg.sender][operator] = true;
}
function removeOperator(address operator) external {
_operator_[msg.sender][operator] = false;
}
}

View File

@@ -10,44 +10,47 @@ pragma experimental ABIEncoderV2;
import {InitializableOwnable} from "./InitializableOwnable.sol"; import {InitializableOwnable} from "./InitializableOwnable.sol";
interface IPermissionManager {
function initOwner(address) external;
function isAllowed(address) external returns (bool);
}
contract PermissionManager is InitializableOwnable { contract PermissionManager is InitializableOwnable {
bool public _BLACKLIST_MODE_ON_;
bool public _BLACKLIST_MODE_ON_; mapping(address => bool) internal _whitelist_;
mapping(address => bool) internal _blacklist_;
mapping(address => bool) internal _whitelist_; function isAllowed(address account) external view returns (bool) {
mapping(address => bool) internal _blacklist_; if (_BLACKLIST_MODE_ON_) {
return !_blacklist_[account];
function isAllowed(address account) external view returns(bool){ } else {
if (_BLACKLIST_MODE_ON_) { return _whitelist_[account];
return !_blacklist_[account]; }
} else {
return _whitelist_[account];
} }
}
function openBlacklist() external onlyOwner { function openBlacklist() external onlyOwner {
_BLACKLIST_MODE_ON_ = true; _BLACKLIST_MODE_ON_ = true;
} }
function openWhitelist() external onlyOwner { function openWhitelist() external onlyOwner {
_BLACKLIST_MODE_ON_ = true; _BLACKLIST_MODE_ON_ = true;
}
} function addToWhitelist(address account) external onlyOwner {
_whitelist_[account] = true;
}
function addToWhitelist(address account) external onlyOwner{ function removeFromWhitelist(address account) external onlyOwner {
_whitelist_[account] = true; _whitelist_[account] = false;
} }
function removeFromWhitelist(address account) external onlyOwner{ function addToBlacklist(address account) external onlyOwner {
_whitelist_[account] = false; _blacklist_[account] = true;
} }
function addToBlacklist(address account) external onlyOwner{ function removeFromBlacklist(address account) external onlyOwner {
_blacklist_[account] = true; _blacklist_[account] = false;
} }
}
function removeFromBlacklist(address account) external onlyOwner{
_blacklist_[account] = false;
}
}