diff --git a/contracts/DODOVendorMachine/DVMFactory.sol b/contracts/DODOVendorMachine/DVMFactory.sol deleted file mode 100644 index 4d5623a..0000000 --- a/contracts/DODOVendorMachine/DVMFactory.sol +++ /dev/null @@ -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]; - } -} diff --git a/contracts/DODOVendorMachine/impl/DVMController.sol b/contracts/DODOVendorMachine/impl/DVM.sol similarity index 61% rename from contracts/DODOVendorMachine/impl/DVMController.sol rename to contracts/DODOVendorMachine/impl/DVM.sol index 5abb225..8310d88 100644 --- a/contracts/DODOVendorMachine/impl/DVMController.sol +++ b/contracts/DODOVendorMachine/impl/DVM.sol @@ -8,32 +8,40 @@ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; +import {IFeeRateModel} from "../../intf/IFeeRateModel.sol"; +import {IPermissionManager} from "../../lib/PermissionManager.sol"; import {DVMTrader} from "./DVMTrader.sol"; import {DVMFunding} from "./DVMFunding.sol"; -import {DVMAdmin} from "./DVMAdmin.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( address owner, address maintainer, address vault, address lpFeeRateModel, address mtFeeRateModel, + address tradePermissionManager, + address fundingPermissionManager, uint256 i, - uint256 k, - uint256 gasPriceLimit + uint256 k ) external { initOwner(owner); - _MAINTAINER_ = maintainer; _VAULT_ = DVMVault(vault); _BASE_TOKEN_ = _VAULT_._BASE_TOKEN_(); _QUOTE_TOKEN_ = _VAULT_._QUOTE_TOKEN_(); _LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel); _MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel); + _TRADE_PERMISSION_ = IPermissionManager(tradePermissionManager); + _FUNDING_PERMISSION_ = IPermissionManager(fundingPermissionManager); + _MAINTAINER_ = maintainer; _I_ = i; _K_ = k; - _GAS_PRICE_LIMIT_ = gasPriceLimit; + _GAS_PRICE_LIMIT_ = uint256(-1); + } + + // ============ Version Control ============ + function version() external pure returns (uint256) { + return 100; // 1.0.0 } } diff --git a/contracts/DODOVendorMachine/impl/DVMAdmin.sol b/contracts/DODOVendorMachine/impl/DVMAdmin.sol deleted file mode 100644 index 3738c41..0000000 --- a/contracts/DODOVendorMachine/impl/DVMAdmin.sol +++ /dev/null @@ -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{} - -} \ No newline at end of file diff --git a/contracts/DODOVendorMachine/impl/DVMStorage.sol b/contracts/DODOVendorMachine/impl/DVMStorage.sol index 9061dce..0d5f314 100644 --- a/contracts/DODOVendorMachine/impl/DVMStorage.sol +++ b/contracts/DODOVendorMachine/impl/DVMStorage.sol @@ -13,7 +13,7 @@ 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 {PermissionManager} from "../../lib/PermissionManager.sol"; +import {IPermissionManager} from "../../lib/PermissionManager.sol"; import {IFeeRateModel} from "../../intf/IFeeRateModel.sol"; import {DVMVault} from "./DVMVault.sol"; @@ -30,8 +30,8 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard { bool public _BUYING_ALLOWED_; bool public _SELLING_ALLOWED_; - PermissionManager public _TRADE_PERMISSION_; - PermissionManager public _FUNDING_PERMISSION_; + IPermissionManager public _TRADE_PERMISSION_; + IPermissionManager public _FUNDING_PERMISSION_; // ============ Core Address ============ @@ -48,7 +48,6 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard { uint256 public _I_; DVMVault public _VAULT_; - DVMVault public _PROTECTION_VAULT_; // ============ Modifiers ============ @@ -58,13 +57,31 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard { } // ============ Helper Functions ============ - function getBase0() public view returns (uint256) { - uint256 fairAmount = DecimalMath.divFloor(_VAULT_._QUOTE_RESERVE_(), _I_); - return DODOMath._SolveQuadraticFunctionForTarget(_VAULT_._BASE_RESERVE_(), _K_, fairAmount); + + function getBase0(uint256 baseAmount, uint256 quoteAmount) public view returns (uint256) { + uint256 fairAmount = DecimalMath.divFloor(quoteAmount, _I_); + return DODOMath._SolveQuadraticFunctionForTarget(baseAmount, _K_, fairAmount); } - // ============ Version Control ============ - function version() external pure returns (uint256) { - return 101; // 1.0.1 + // ============ Setting Functions ============ + + 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; } } diff --git a/contracts/DODOVendorMachine/impl/DVMTrader.sol b/contracts/DODOVendorMachine/impl/DVMTrader.sol index f374d5e..c212df4 100644 --- a/contracts/DODOVendorMachine/impl/DVMTrader.sol +++ b/contracts/DODOVendorMachine/impl/DVMTrader.sol @@ -12,6 +12,7 @@ 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"; contract DVMTrader is DVMStorage { using SafeMath for uint256; @@ -19,7 +20,7 @@ contract DVMTrader is DVMStorage { function sellBase(address to) external returns (uint256 receiveQuoteAmount) { uint256 baseInput = _VAULT_.getBaseInput(); uint256 mtFee; - (receiveQuoteAmount, mtFee) = querySellBase(baseInput); + (receiveQuoteAmount, mtFee) = querySellBase(to, baseInput); _VAULT_.transferQuoteOut(to, receiveQuoteAmount); if (mtFee > 0) { _VAULT_.transferQuoteOut(_MAINTAINER_, mtFee); @@ -31,7 +32,7 @@ contract DVMTrader is DVMStorage { function sellQuote(address to) external returns (uint256 receiveBaseAmount) { uint256 quoteInput = _VAULT_.getQuoteInput(); uint256 mtFee; - (receiveBaseAmount, mtFee) = querySellQuote(quoteInput); + (receiveBaseAmount, mtFee) = querySellQuote(to, quoteInput); _VAULT_.transferBaseOut(to, receiveBaseAmount); if (mtFee > 0) { _VAULT_.transferBaseOut(_MAINTAINER_, mtFee); @@ -40,50 +41,82 @@ contract DVMTrader is DVMStorage { 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 view returns (uint256 receiveQuoteAmount, uint256 mtFee) { - uint256 B0 = getBase0(); - uint256 B2 = _VAULT_._BASE_RESERVE_(); - uint256 B1 = B2.add(payBaseAmount); + (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); + uint256 B0 = getBase0(baseReserve, quoteReserve); + + uint256 B1 = baseReserve.add(payBaseAmount); require(B0 >= B1, "DODO_BASE_BALANCE_NOT_ENOUGH"); - uint256 Q = DODOMath._GeneralIntegrate(B0, B1, B2, _I_, _K_); - uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(Q); - uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(Q); + uint256 Q = DODOMath._GeneralIntegrate(B0, B1, baseReserve, _I_, _K_); + + uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader, Q); + uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader, Q); mtFee = DecimalMath.mulCeil(Q, mtFeeRate); receiveQuoteAmount = Q.sub(mtFee).sub(DecimalMath.mulCeil(Q, lpFeeRate)); + return (receiveQuoteAmount, mtFee); } - function querySellQuote(uint256 payQuoteAmount) + function querySellQuote(address trader, uint256 payQuoteAmount) public view returns (uint256 receiveBaseAmount, uint256 mtFee) { - uint256 B0 = getBase0(); - uint256 B1 = _VAULT_._BASE_RESERVE_(); + (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); + uint256 B0 = getBase0(baseReserve, quoteReserve); + uint256 fairAmount = DecimalMath.divFloor(payQuoteAmount, _I_); uint256 newBaseReserve = DODOMath._SolveQuadraticFunctionForTrade( B0, - B1, + baseReserve, fairAmount, false, _K_ ); - uint256 deltaBase = B1.sub(newBaseReserve); - uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(payQuoteAmount); - uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(payQuoteAmount); + uint256 deltaBase = baseReserve.sub(newBaseReserve); + uint256 lpFeeRate = _LP_FEE_RATE_MODEL_.getFeeRate(trader, payQuoteAmount); + uint256 mtFeeRate = _MT_FEE_RATE_MODEL_.getFeeRate(trader, payQuoteAmount); mtFee = DecimalMath.mulCeil(deltaBase, mtFeeRate); receiveBaseAmount = deltaBase.sub(mtFee).sub(DecimalMath.mulCeil(deltaBase, lpFeeRate)); return (receiveBaseAmount, mtFee); } function getMidPrice() public view returns (uint256 midPrice) { - uint256 B0 = getBase0(); - uint256 B1 = _VAULT_._BASE_RESERVE_(); - uint256 offsetRatio = DecimalMath.ONE.mul(B0).div(B1).mul(B0).div(B1); + (uint256 baseReserve, uint256 quoteReserve) = _VAULT_.getVaultReserve(); + uint256 B0 = getBase0(baseReserve, quoteReserve); + + uint256 offsetRatio = DecimalMath.ONE.mul(B0).div(baseReserve).mul(B0).div(baseReserve); uint256 offset = DecimalMath.ONE.sub(_K_).add(DecimalMath.mulFloor(offsetRatio, _K_)); return DecimalMath.mulFloor(_I_, offset); } diff --git a/contracts/DODOVendorMachine/impl/DVMVault.sol b/contracts/DODOVendorMachine/impl/DVMVault.sol index 5e0e5d9..f68315d 100644 --- a/contracts/DODOVendorMachine/impl/DVMVault.sol +++ b/contracts/DODOVendorMachine/impl/DVMVault.sol @@ -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 { IERC20(_BASE_TOKEN_).safeTransfer(to, amount); } @@ -208,4 +200,6 @@ contract DVMVault is InitializableOwnable { emit Burn(user, value); emit Transfer(user, address(0), value); } + + // function approveAndCall() } diff --git a/contracts/DODOVendorMachine/intf/IDVM.sol b/contracts/DODOVendorMachine/intf/IDVM.sol new file mode 100644 index 0000000..8569973 --- /dev/null +++ b/contracts/DODOVendorMachine/intf/IDVM.sol @@ -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; +} diff --git a/contracts/DODOVendorMachine/intf/IDVMVault.sol b/contracts/DODOVendorMachine/intf/IDVMVault.sol new file mode 100644 index 0000000..eba49e2 --- /dev/null +++ b/contracts/DODOVendorMachine/intf/IDVMVault.sol @@ -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; +} diff --git a/contracts/DODOVendorMachine/intf/IExternalCall.sol b/contracts/DODOVendorMachine/intf/IExternalCall.sol new file mode 100644 index 0000000..fbd517e --- /dev/null +++ b/contracts/DODOVendorMachine/intf/IExternalCall.sol @@ -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; +} diff --git a/contracts/Factory/DVMFactory.sol b/contracts/Factory/DVMFactory.sol new file mode 100644 index 0000000..f67369f --- /dev/null +++ b/contracts/Factory/DVMFactory.sol @@ -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]; + } +} diff --git a/contracts/SmartRoute/SmartRoute.sol b/contracts/SmartRoute/SmartRoute.sol index f1a7712..d7949bf 100644 --- a/contracts/SmartRoute/SmartRoute.sol +++ b/contracts/SmartRoute/SmartRoute.sol @@ -8,7 +8,7 @@ pragma solidity 0.6.9; 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 {IERC20} from "../intf/IERC20.sol"; import {SafeERC20} from "../lib/SafeERC20.sol"; @@ -20,49 +20,47 @@ contract SmartRoute is Ownable { using SafeERC20 for IERC20; function sellBaseOnDVM( - address DVM, + address DVMAddress, address to, uint256 baseAmount, uint256 minReceive ) public returns (uint256 receiveAmount) { - IERC20(DVMController(DVM)._BASE_TOKEN_()).safeTransferFrom( + IERC20(DVM(DVMAddress)._BASE_TOKEN_()).safeTransferFrom( msg.sender, - address(DVMController(DVM)._VAULT_()), + address(DVM(DVMAddress)._VAULT_()), baseAmount ); - receiveAmount = DVMController(DVM).sellBase(to); + receiveAmount = DVM(DVMAddress).sellBase(to); require(receiveAmount >= minReceive, "RECEIVE_NOT_ENOUGH"); return receiveAmount; } function sellQuoteOnDVM( - address DVM, + address DVMAddress, address to, uint256 quoteAmount, uint256 minReceive ) public returns (uint256 receiveAmount) { - IERC20(DVMController(DVM)._QUOTE_TOKEN_()).safeTransferFrom( + IERC20(DVM(DVMAddress)._QUOTE_TOKEN_()).safeTransferFrom( msg.sender, - address(DVMController(DVM)._VAULT_()), + address(DVM(DVMAddress)._VAULT_()), quoteAmount ); - receiveAmount = DVMController(DVM).sellQuote(to); + receiveAmount = DVM(DVMAddress).sellQuote(to); require(receiveAmount >= minReceive, "RECEIVE_NOT_ENOUGU"); return receiveAmount; } function depositToDVM( - address DVM, + address DVMAddress, address to, uint256 baseAmount, uint256 quoteAmount ) public returns (uint256 shares) { - address vault = address(DVMController(DVM)._VAULT_()); + address vault = address(DVM(DVMAddress)._VAULT_()); uint256 adjustedBaseAmount; uint256 adjustedQuoteAmount; - (uint256 baseReserve, uint256 quoteReserve) = DVMController(DVM) - ._VAULT_() - .getVaultReserve(); + (uint256 baseReserve, uint256 quoteReserve) = DVM(DVMAddress)._VAULT_().getVaultReserve(); if (quoteReserve == 0 && baseReserve == 0) { adjustedBaseAmount = baseAmount; @@ -86,17 +84,17 @@ contract SmartRoute is Ownable { } } - IERC20(DVMController(DVM)._BASE_TOKEN_()).safeTransferFrom( + IERC20(DVM(DVMAddress)._BASE_TOKEN_()).safeTransferFrom( msg.sender, vault, adjustedBaseAmount ); - IERC20(DVMController(DVM)._QUOTE_TOKEN_()).safeTransferFrom( + IERC20(DVM(DVMAddress)._QUOTE_TOKEN_()).safeTransferFrom( msg.sender, vault, adjustedQuoteAmount ); - return DVMController(DVM).buyShares(to); + return DVM(DVMAddress).buyShares(to); } } diff --git a/contracts/helper/ConstFeeRateModel.sol b/contracts/helper/ConstFeeRateModel.sol deleted file mode 100644 index a3afd17..0000000 --- a/contracts/helper/ConstFeeRateModel.sol +++ /dev/null @@ -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_; - } -} diff --git a/contracts/helper/NaiveFeeRateModel.sol b/contracts/helper/NaiveFeeRateModel.sol deleted file mode 100644 index 7b5727d..0000000 --- a/contracts/helper/NaiveFeeRateModel.sol +++ /dev/null @@ -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_; - } -} diff --git a/contracts/intf/IFeeRateModel.sol b/contracts/intf/IFeeRateModel.sol index 81c3fdd..10e7a30 100644 --- a/contracts/intf/IFeeRateModel.sol +++ b/contracts/intf/IFeeRateModel.sol @@ -8,7 +8,6 @@ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; - interface IFeeRateModel { - function getFeeRate(uint256 amount) external view returns (uint256); + function getFeeRate(address trader, uint256 amount) external view returns (uint256); } diff --git a/contracts/lib/ConstFeeRateModel.sol b/contracts/lib/ConstFeeRateModel.sol new file mode 100644 index 0000000..4cf695c --- /dev/null +++ b/contracts/lib/ConstFeeRateModel.sol @@ -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_; + } +} diff --git a/contracts/lib/OperatorSystem.sol b/contracts/lib/OperatorSystem.sol new file mode 100644 index 0000000..c2be516 --- /dev/null +++ b/contracts/lib/OperatorSystem.sol @@ -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; + } +} diff --git a/contracts/lib/PermissionManager.sol b/contracts/lib/PermissionManager.sol index e813039..cc9d6d7 100644 --- a/contracts/lib/PermissionManager.sol +++ b/contracts/lib/PermissionManager.sol @@ -10,44 +10,47 @@ pragma experimental ABIEncoderV2; import {InitializableOwnable} from "./InitializableOwnable.sol"; +interface IPermissionManager { + function initOwner(address) external; + + function isAllowed(address) external returns (bool); +} + 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_; - mapping(address => bool) internal _blacklist_; - - function isAllowed(address account) external view returns(bool){ - if (_BLACKLIST_MODE_ON_) { - return !_blacklist_[account]; - } else { - return _whitelist_[account]; + function isAllowed(address account) external view returns (bool) { + if (_BLACKLIST_MODE_ON_) { + return !_blacklist_[account]; + } else { + return _whitelist_[account]; + } } - } - function openBlacklist() external onlyOwner { - _BLACKLIST_MODE_ON_ = true; - } + function openBlacklist() external onlyOwner { + _BLACKLIST_MODE_ON_ = true; + } - function openWhitelist() external onlyOwner { - _BLACKLIST_MODE_ON_ = true; + function openWhitelist() external onlyOwner { + _BLACKLIST_MODE_ON_ = true; + } - } + function addToWhitelist(address account) external onlyOwner { + _whitelist_[account] = true; + } - function addToWhitelist(address account) external onlyOwner{ - _whitelist_[account] = true; - } + function removeFromWhitelist(address account) external onlyOwner { + _whitelist_[account] = false; + } - function removeFromWhitelist(address account) external onlyOwner{ - _whitelist_[account] = false; - } + function addToBlacklist(address account) external onlyOwner { + _blacklist_[account] = true; + } - function addToBlacklist(address account) external onlyOwner{ - _blacklist_[account] = true; - } - - function removeFromBlacklist(address account) external onlyOwner{ - _blacklist_[account] = false; - } - -} \ No newline at end of file + function removeFromBlacklist(address account) external onlyOwner { + _blacklist_[account] = false; + } +}