diff --git a/contracts/DODOPrivatePool/impl/DPP.sol b/contracts/DODOPrivatePool/impl/DPP.sol new file mode 100644 index 0000000..5d2e65c --- /dev/null +++ b/contracts/DODOPrivatePool/impl/DPP.sol @@ -0,0 +1,51 @@ +/* + + Copyright 2020 DODO ZOO. + SPDX-License-Identifier: Apache-2.0 + +*/ + +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 {DPPTrader} from "./DPPTrader.sol"; +import {ISmartApprove} from "../../intf/ISmartApprove.sol"; + +contract DPP is DPPTrader { + + constructor() public { + _FACTORY_ = msg.sender; + } + + function init( + address owner, + address maintainer, + address baseTokenAddress, + address quoteTokenAddress, + address iSmartApprove, + address[] memory configAddresses + ) external { + require(msg.sender == _FACTORY_, 'INIT FORBIDDEN'); + initOwner(owner); + _MAINTAINER_ = maintainer; + _BASE_TOKEN_ = IERC20(baseTokenAddress); + _QUOTE_TOKEN_ = IERC20(quoteTokenAddress); + _DODO_SMART_APPROVE_ = ISmartApprove(iSmartApprove); + _LP_FEE_RATE_MODEL_ = IFeeRateModel(configAddresses[0]); + _MT_FEE_RATE_MODEL_ = IFeeRateModel(configAddresses[1]); + _GAS_PRICE_LIMIT_ = IExternalValue(configAddresses[2]); + _I_ = IExternalValue(configAddresses[3]); + _K_ = IExternalValue(configAddresses[4]); + _TRADE_PERMISSION_ = IPermissionManager(configAddresses[5]); + _resetTargetAndReserve(); + } + + // ============ Version Control ============ + function version() external pure returns (uint256) { + return 100; // 1.0.0 + } +} diff --git a/contracts/DODOPrivatePool/impl/DPPStorage.sol b/contracts/DODOPrivatePool/impl/DPPStorage.sol index 62408dd..7f2c4b3 100644 --- a/contracts/DODOPrivatePool/impl/DPPStorage.sol +++ b/contracts/DODOPrivatePool/impl/DPPStorage.sol @@ -14,7 +14,8 @@ import {DecimalMath} from "../../lib/DecimalMath.sol"; import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; import {IPermissionManager} from "../../lib/PermissionManager.sol"; import {IExternalValue} from "../../lib/ExternalValue.sol"; -import {IFeeRateModel} from "../../intf/IFeeRateModel.sol"; +import {IFeeRateModel} from "../../lib/FeeRateModel.sol"; +import {ISmartApprove} from "../../intf/ISmartApprove.sol"; import {IERC20} from "../../intf/IERC20.sol"; import {PMMPricing} from "../../lib/PMMPricing.sol"; @@ -27,6 +28,9 @@ import {PMMPricing} from "../../lib/PMMPricing.sol"; contract DPPStorage is InitializableOwnable, ReentrancyGuard { using SafeMath for uint256; + address public _FACTORY_; + ISmartApprove public _DODO_SMART_APPROVE_; + // ============ Variables for Control ============ IExternalValue public _GAS_PRICE_LIMIT_; @@ -80,6 +84,14 @@ contract DPPStorage is InitializableOwnable, ReentrancyGuard { _GAS_PRICE_LIMIT_ = IExternalValue(newGasPriceLimitSource); } + function setISource(address newISource) external onlyOwner { + _I_ = IExternalValue(newISource); + } + + function setKSource(address newKSource) external onlyOwner { + _K_ = IExternalValue(newKSource); + } + function setBuy(bool open) external onlyOwner { _BUYING_CLOSE_ = !open; } diff --git a/contracts/DODOPrivatePool/impl/DPPTrader.sol b/contracts/DODOPrivatePool/impl/DPPTrader.sol index b3119c5..c5050dc 100644 --- a/contracts/DODOPrivatePool/impl/DPPTrader.sol +++ b/contracts/DODOPrivatePool/impl/DPPTrader.sol @@ -25,10 +25,7 @@ contract DPPTrader is DPPVault { } modifier isSellAllow(address trader) { - require( - !_SELLING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(trader), - "TRADER_SELL_NOT_ALLOWED" - ); + require(!_SELLING_CLOSE_ && _TRADE_PERMISSION_.isAllowed(trader),"TRADER_SELL_NOT_ALLOWED"); _; } @@ -50,7 +47,8 @@ contract DPPTrader is DPPVault { uint256 mtFee; uint256 newBaseTarget; PMMPricing.RState newRState; - (receiveQuoteAmount, mtFee, newRState, newBaseTarget) = querySellBase(tx.origin, baseInput); + //TODO: confirm + (receiveQuoteAmount, mtFee, newRState, newBaseTarget) = querySellBase(to, baseInput); _transferQuoteOut(to, receiveQuoteAmount); _transferQuoteOut(_MAINTAINER_, mtFee); @@ -76,11 +74,9 @@ contract DPPTrader is DPPVault { uint256 quoteInput = getQuoteInput(); uint256 mtFee; uint256 newQuoteTarget; + PMMPricing.RState newRState; - (receiveBaseAmount, mtFee, newRState, newQuoteTarget) = querySellQuote( - tx.origin, - quoteInput - ); + (receiveBaseAmount, mtFee, newRState, newQuoteTarget) = querySellQuote(to,quoteInput); _transferBaseOut(to, receiveBaseAmount); _transferBaseOut(_MAINTAINER_, mtFee); diff --git a/contracts/DODOPrivatePool/impl/DPPVault.sol b/contracts/DODOPrivatePool/impl/DPPVault.sol index ea6ac3f..bfd802c 100644 --- a/contracts/DODOPrivatePool/impl/DPPVault.sol +++ b/contracts/DODOPrivatePool/impl/DPPVault.sol @@ -20,7 +20,7 @@ contract DPPVault is DPPStorage { using SafeMath for uint256; using SafeERC20 for IERC20; - // input + // ============ Get Input ============ function getInput() public view returns (uint256 baseInput, uint256 quoteInput) { return ( @@ -39,27 +39,41 @@ contract DPPVault is DPPStorage { // ============ Set Status ============ - function _syncReserve() internal { - _BASE_RESERVE_ = _BASE_TOKEN_.balanceOf(address(this)); - _QUOTE_RESERVE_ = _QUOTE_TOKEN_.balanceOf(address(this)); - } - + //TODO:对应前端哪个操作? function setTarget(uint256 baseTarget, uint256 quoteTarget) public onlyOwner { _BASE_TARGET_ = baseTarget; _QUOTE_TARGET_ = quoteTarget; _checkStatus(); } + + function _syncReserve() internal { + _BASE_RESERVE_ = _BASE_TOKEN_.balanceOf(address(this)); + _QUOTE_RESERVE_ = _QUOTE_TOKEN_.balanceOf(address(this)); + } - //TODO: Route queryfunc 以及 withdraw and reset - // todo 这里需要考虑,怎么一个tx同时更新k i 和 fee并reset - //TODO: 修改feerate等 - function reset() public onlyOwner { + function _resetTargetAndReserve() internal { _BASE_TARGET_ = _BASE_TOKEN_.balanceOf(address(this)); _QUOTE_TARGET_ = _QUOTE_TOKEN_.balanceOf(address(this)); _BASE_RESERVE_ = _BASE_TARGET_; _QUOTE_RESERVE_ = _QUOTE_TARGET_; } + function reset( + uint256 newLpFeeRate, + uint256 newMtFeeRate, + uint256 newI, + uint256 newK + ) public { + //TODO: 讨论 + require(msg.sender == _DODO_SMART_APPROVE_.getSmartSwap() || msg.sender == _OWNER_, "RESET FORBIDDEN!"); + require(newK > 0 && newK <= 10**18, "K OUT OF RANGE!"); + _resetTargetAndReserve(); + _LP_FEE_RATE_MODEL_.setFeeRate(newLpFeeRate); + _MT_FEE_RATE_MODEL_.setFeeRate(newMtFeeRate); + _I_.set(newI); + _K_.set(newK); + } + function _checkStatus() internal view { require( !(_BASE_RESERVE_ < _BASE_TARGET_ && _QUOTE_RESERVE_ < _QUOTE_TARGET_), @@ -69,21 +83,21 @@ contract DPPVault is DPPStorage { // ============ Assets Transfer ============ - //TODO:确定Amount后,内部调用 - function withdraw( - address to, - uint256 baseAmount, - uint256 quoteAmount, - bytes calldata data - ) public onlyOwner { - _transferBaseOut(to, baseAmount); - _transferQuoteOut(to, quoteAmount); - _BASE_TARGET_ = _BASE_TARGET_.sub(baseAmount); - _QUOTE_TARGET_ = _QUOTE_TARGET_.sub(quoteAmount); - if (data.length > 0) { - IDODOCallee(to).DPPWithdrawCall(msg.sender, baseAmount, quoteAmount, data); - } - } + // function withdraw( + // address to, + // uint256 baseAmount, + // uint256 quoteAmount, + // bytes calldata data + // ) public onlyOwner { + // _transferBaseOut(to, baseAmount); + // _transferQuoteOut(to, quoteAmount); + // _BASE_TARGET_ = _BASE_TARGET_.sub(baseAmount); + // _QUOTE_TARGET_ = _QUOTE_TARGET_.sub(quoteAmount); + // _syncReserve(); + // if (data.length > 0) { + // IDODOCallee(to).DPPWithdrawCall(msg.sender, baseAmount, quoteAmount, data); + // } + // } function _transferBaseOut(address to, uint256 amount) internal { if (amount > 0) { @@ -97,15 +111,13 @@ contract DPPVault is DPPStorage { } } - // todo 高级功能,需要讨论 - // 如果单独执行这个功能会导致状态失衡 function retrieve( address payable to, address token, uint256 amount ) external onlyOwner { require(to != address(_BASE_TOKEN_) && to != address(_QUOTE_TOKEN_), "USE_WITHDRAW"); - if (token == 0x000000000000000000000000000000000000000E) { + if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { to.transfer(amount); } else { IERC20(token).safeTransfer(msg.sender, amount); diff --git a/contracts/DODOPrivatePool/intf/IDPP.sol b/contracts/DODOPrivatePool/intf/IDPP.sol new file mode 100644 index 0000000..16761be --- /dev/null +++ b/contracts/DODOPrivatePool/intf/IDPP.sol @@ -0,0 +1,34 @@ +/* + + Copyright 2020 DODO ZOO. + SPDX-License-Identifier: Apache-2.0 + +*/ + +pragma solidity 0.6.9; +pragma experimental ABIEncoderV2; + +interface IDPP { + // function init( + // address owner, + // address maintainer, + // address baseTokenAddress, + // address quoteTokenAddress, + // address lpFeeRateModel, + // address mtFeeRateModel, + // address tradePermissionManager, + // address gasPriceSource, + // address iSource, + // address kSource, + // address iSmartApprove + // ) external; + + function init( + address owner, + address maintainer, + address baseTokenAddress, + address quoteTokenAddress, + address iSmartApprove, + address[] memory configAddresses + ) external; +} diff --git a/contracts/DODOVendingMachine/impl/DVM.sol b/contracts/DODOVendingMachine/impl/DVM.sol index fb4630f..5f95151 100644 --- a/contracts/DODOVendingMachine/impl/DVM.sol +++ b/contracts/DODOVendingMachine/impl/DVM.sol @@ -7,8 +7,8 @@ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; - -import {IFeeRateModel} from "../../intf/IFeeRateModel.sol"; +//TODO:讨论 是否应使用FeeRateModel +import {IConstFeeRateModel} from "../../lib/ConstFeeRateModel.sol"; import {IPermissionManager} from "../../lib/PermissionManager.sol"; import {IExternalValue} from "../../lib/ExternalValue.sol"; import {IERC20} from "../../intf/IERC20.sol"; @@ -32,8 +32,8 @@ contract DVM is DVMTrader, DVMFunding { initOwner(owner); _BASE_TOKEN_ = IERC20(baseTokenAddress); _QUOTE_TOKEN_ = IERC20(quoteTokenAddress); - _LP_FEE_RATE_MODEL_ = IFeeRateModel(lpFeeRateModel); - _MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel); + _LP_FEE_RATE_MODEL_ = IConstFeeRateModel(lpFeeRateModel); + _MT_FEE_RATE_MODEL_ = IConstFeeRateModel(mtFeeRateModel); _TRADE_PERMISSION_ = IPermissionManager(tradePermissionManager); _GAS_PRICE_LIMIT_ = IExternalValue(gasPriceSource); _MAINTAINER_ = maintainer; diff --git a/contracts/DODOVendingMachine/impl/DVMStorage.sol b/contracts/DODOVendingMachine/impl/DVMStorage.sol index 0eddcaf..1993db7 100644 --- a/contracts/DODOVendingMachine/impl/DVMStorage.sol +++ b/contracts/DODOVendingMachine/impl/DVMStorage.sol @@ -15,7 +15,7 @@ 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 "../../intf/IFeeRateModel.sol"; +import {IConstFeeRateModel} from "../../lib/ConstFeeRateModel.sol"; import {IERC20} from "../../intf/IERC20.sol"; contract DVMStorage is InitializableOwnable, ReentrancyGuard { @@ -54,8 +54,8 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard { // ============ Variables for Pricing ============ - IFeeRateModel public _LP_FEE_RATE_MODEL_; - IFeeRateModel public _MT_FEE_RATE_MODEL_; + IConstFeeRateModel public _LP_FEE_RATE_MODEL_; + IConstFeeRateModel public _MT_FEE_RATE_MODEL_; uint256 public _K_; uint256 public _I_; @@ -63,11 +63,11 @@ contract DVMStorage is InitializableOwnable, ReentrancyGuard { //TODO: owner权限问题论证 function setLpFeeRateModel(address newLpFeeRateModel) external onlyOwner { - _LP_FEE_RATE_MODEL_ = IFeeRateModel(newLpFeeRateModel); + _LP_FEE_RATE_MODEL_ = IConstFeeRateModel(newLpFeeRateModel); } function setMtFeeRateModel(address newMtFeeRateModel) external onlyOwner { - _MT_FEE_RATE_MODEL_ = IFeeRateModel(newMtFeeRateModel); + _MT_FEE_RATE_MODEL_ = IConstFeeRateModel(newMtFeeRateModel); } function setTradePermissionManager(address newTradePermissionManager) external onlyOwner { diff --git a/contracts/DODOZoo.sol b/contracts/DODOZoo.sol index c47cc10..d536cef 100644 --- a/contracts/DODOZoo.sol +++ b/contracts/DODOZoo.sol @@ -10,7 +10,7 @@ pragma experimental ABIEncoderV2; import {Ownable} from "./lib/Ownable.sol"; import {IDODO} from "./intf/IDODO.sol"; -import {ICloneFactory} from "./helper/CloneFactory.sol"; +import {ICloneFactory} from "./lib/CloneFactory.sol"; /** diff --git a/contracts/Factory/DPPFactory.sol b/contracts/Factory/DPPFactory.sol new file mode 100644 index 0000000..f88a4d1 --- /dev/null +++ b/contracts/Factory/DPPFactory.sol @@ -0,0 +1,122 @@ +/* + + 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 {IFeeRateModel} from "../lib/FeeRateModel.sol"; +import {IExternalValue} from "../lib/ExternalValue.sol"; +import {IDPP} from "../DODOPrivatePool/intf/IDPP.sol"; +import {IPermissionManager} from "../lib/PermissionManager.sol"; + +contract DPPFactory is Ownable { + address public _CLONE_FACTORY_; + address public _DODO_SMART_APPROVE_; + address public _DPP_TEMPLATE_; + address public _FEE_RATE_MODEL_TEMPLATE_; + address public _PERMISSION_MANAGER_TEMPLATE_; + address public _VALUE_SOURCE_; + + struct DPPInfo{ + address creator; + uint256 createTimeStamp; + //TODO:other tags + } + + // base -> quote -> DPP address list + mapping(address => mapping(address => address[])) _REGISTRY_; + // token0 -> token1 -> DPP address list + mapping(address => mapping(address => address[])) _SORT_REGISTRY_; + // creator -> DPP address list + mapping(address => address[]) _USER_REGISTRY_; + // DPP address -> info + mapping(address => DPPInfo) _DPP_INFO_; + + constructor( + address cloneFactory, + address dodoSmartApprove, + address dppTemplate, + address defautFeeRateModelTemplate, + address defaultPermissionManagerTemplate, + address defaultExternalValueTemplate + ) public { + _CLONE_FACTORY_ = cloneFactory; + _DODO_SMART_APPROVE_ = dodoSmartApprove; + _DPP_TEMPLATE_ = dppTemplate; + _FEE_RATE_MODEL_TEMPLATE_ = defautFeeRateModelTemplate; + _PERMISSION_MANAGER_TEMPLATE_ = defaultPermissionManagerTemplate; + _VALUE_SOURCE_ = defaultExternalValueTemplate; + } + + function createStandardDODOPrivatePool( + address baseToken, + address quoteToken, + address[] memory valueTemplates, //feeeRateAddr,mtRateAddr,gasPriceAddr,kAddr,iAddr + uint256[] memory values // feeRate,mtRate,gasPrice,k,i + ) external returns (address newPrivatePool) { + require(valueTemplates.length == 5 && values.length == 5, "Incorrect number of initialization parameters"); + + (address token0, address token1) = baseToken < quoteToken ? (baseToken, quoteToken) : (quoteToken, baseToken); + uint256 len = _SORT_REGISTRY_[token0][token1].length; + bytes32 salt = keccak256(abi.encodePacked(token0, token1, len)); + newPrivatePool = ICloneFactory(_CLONE_FACTORY_).clone2(_DPP_TEMPLATE_,salt); + + address[] memory configAddresses = new address[](6); + configAddresses[0] = (valueTemplates[0] == address(0) ? createFeeRateModel(newPrivatePool, values[0]) : valueTemplates[0]); + configAddresses[1] = (valueTemplates[1] == address(0) ? createFeeRateModel(newPrivatePool, values[1]) : valueTemplates[1]); + configAddresses[2] = (valueTemplates[2] == address(0) ? createExternalValueModel(newPrivatePool, values[2]) : valueTemplates[2]); + configAddresses[3] = (valueTemplates[3] == address(0) ? createExternalValueModel(newPrivatePool, values[3]) : valueTemplates[3]); + configAddresses[4] = (valueTemplates[4] == address(0) ? createExternalValueModel(newPrivatePool, values[4]) : valueTemplates[4]); + configAddresses[5] = createPermissionManager(msg.sender); + + IDPP(newPrivatePool).init( + msg.sender, + msg.sender, + baseToken, + quoteToken, + _DODO_SMART_APPROVE_, + configAddresses + ); + + _REGISTRY_[baseToken][quoteToken].push(newPrivatePool); + _SORT_REGISTRY_[token0][token1].push(newPrivatePool); + _USER_REGISTRY_[msg.sender].push(newPrivatePool); + _DPP_INFO_[newPrivatePool] = ( + DPPInfo({ + creator: msg.sender, + createTimeStamp: block.timestamp + }) + ); + return newPrivatePool; + } + + function createFeeRateModel(address owner, uint256 feeRate) + public + returns (address feeRateModel) + { + feeRateModel = ICloneFactory(_CLONE_FACTORY_).clone(_FEE_RATE_MODEL_TEMPLATE_); + IFeeRateModel(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 createExternalValueModel(address owner, uint256 value) + public + returns (address valueModel) + { + valueModel = ICloneFactory(_CLONE_FACTORY_).clone(_VALUE_SOURCE_); + IExternalValue(valueModel).init(owner, value); + return valueModel; + } +} diff --git a/contracts/Factory/DVMFactory.sol b/contracts/Factory/DVMFactory.sol index 312282e..df99dea 100644 --- a/contracts/Factory/DVMFactory.sol +++ b/contracts/Factory/DVMFactory.sol @@ -39,7 +39,6 @@ contract DVMFactory is Ownable { _DEFAULT_GAS_PRICE_SOURCE_ = defaultGasPriceSource; } - function createStandardDODOVendingMachine( address baseToken, address quoteToken, diff --git a/contracts/SmartRoute/DVMProxy.sol b/contracts/SmartRoute/DVMProxy.sol index 78ff714..4aaf56a 100644 --- a/contracts/SmartRoute/DVMProxy.sol +++ b/contracts/SmartRoute/DVMProxy.sol @@ -17,6 +17,24 @@ contract DVMProxy { using SafeMath for uint256; using SafeERC20 for IERC20; + //TODO: dodoSwap + + //TODO: externalSwap + + //TODO: createDVM + + //TODO: addLiquidityToDVM + + //TODO: removeLiquidityToDVM + + //TODO: createDPP + + //TODO: resetDPP + + //TODO: addLiquidityToClassical + + //TODO: removeLiquidityToClassical + function sellBaseOnDVM( address DVMAddress, address to, diff --git a/contracts/SmartRoute/SmartApprove.sol b/contracts/SmartRoute/SmartApprove.sol index 0fcc38b..a894b94 100644 --- a/contracts/SmartRoute/SmartApprove.sol +++ b/contracts/SmartRoute/SmartApprove.sol @@ -19,6 +19,10 @@ contract SmartApprove is Ownable { smartSwap = _smartSwap; } + function getSmartSwap() public view returns (address) { + return smartSwap; + } + function claimTokens( IERC20 token, address who, diff --git a/contracts/helper/CloneFactory.sol b/contracts/helper/CloneFactory.sol deleted file mode 100644 index fd8f755..0000000 --- a/contracts/helper/CloneFactory.sol +++ /dev/null @@ -1,33 +0,0 @@ -/* - - Copyright 2020 DODO ZOO. - SPDX-License-Identifier: Apache-2.0 - -*/ - -pragma solidity 0.6.9; -pragma experimental ABIEncoderV2; - -interface ICloneFactory { - function clone(address prototype) external returns (address proxy); -} - -// introduction of proxy mode design: https://docs.openzeppelin.com/upgrades/2.8/ -// minimum implementation of transparent proxy: https://eips.ethereum.org/EIPS/eip-1167 - -contract CloneFactory is ICloneFactory { - function clone(address prototype) external override returns (address proxy) { - bytes20 targetBytes = bytes20(prototype); - assembly { - let clone := mload(0x40) - mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) - mstore(add(clone, 0x14), targetBytes) - mstore( - add(clone, 0x28), - 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 - ) - proxy := create(0, clone, 0x37) - } - return proxy; - } -} diff --git a/contracts/intf/IFeeRateModel.sol b/contracts/intf/IFeeRateModel.sol deleted file mode 100644 index 076c316..0000000 --- a/contracts/intf/IFeeRateModel.sol +++ /dev/null @@ -1,13 +0,0 @@ -/* - - Copyright 2020 DODO ZOO. - SPDX-License-Identifier: Apache-2.0 - -*/ - -pragma solidity 0.6.9; -pragma experimental ABIEncoderV2; - -interface IFeeRateModel { - function getFeeRate(address trader) external view returns (uint256); -} diff --git a/contracts/intf/ISmartApprove.sol b/contracts/intf/ISmartApprove.sol index 6ee509f..24631d7 100644 --- a/contracts/intf/ISmartApprove.sol +++ b/contracts/intf/ISmartApprove.sol @@ -12,4 +12,5 @@ import {IERC20} from "./IERC20.sol"; interface ISmartApprove { function claimTokens(IERC20 token,address who,address dest,uint256 amount) external; + function getSmartSwap() external view returns (address); } \ No newline at end of file diff --git a/contracts/lib/CloneFactory.sol b/contracts/lib/CloneFactory.sol index fd8f755..8837a5e 100644 --- a/contracts/lib/CloneFactory.sol +++ b/contracts/lib/CloneFactory.sol @@ -10,6 +10,7 @@ pragma experimental ABIEncoderV2; interface ICloneFactory { function clone(address prototype) external returns (address proxy); + function clone2(address prototype,bytes32 salt) external returns (address proxy); } // introduction of proxy mode design: https://docs.openzeppelin.com/upgrades/2.8/ @@ -30,4 +31,20 @@ contract CloneFactory is ICloneFactory { } return proxy; } + + + function clone2(address prototype, bytes32 salt) external override returns (address proxy) { + bytes20 targetBytes = bytes20(prototype); + assembly { + let clone := mload(0x40) + mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) + mstore(add(clone, 0x14), targetBytes) + mstore( + add(clone, 0x28), + 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 + ) + proxy := create2(0, clone, 0x37, salt) + } + return proxy; + } } diff --git a/contracts/lib/ConstFeeRateModel.sol b/contracts/lib/ConstFeeRateModel.sol index 36d36ca..f5744bd 100644 --- a/contracts/lib/ConstFeeRateModel.sol +++ b/contracts/lib/ConstFeeRateModel.sol @@ -8,17 +8,15 @@ 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 is IFeeRateModel { +interface IConstFeeRateModel { function init(address owner, uint256 feeRate) external; - function setFeeRate(uint256 newFeeRate) external; + function getFeeRate(address trader) external view returns (uint256); } -contract ConstFeeRateModel is InitializableOwnable, IFeeRateModel { +contract ConstFeeRateModel is InitializableOwnable { uint256 public _FEE_RATE_; function init(address owner, uint256 feeRate) external { @@ -26,11 +24,11 @@ contract ConstFeeRateModel is InitializableOwnable, IFeeRateModel { _FEE_RATE_ = feeRate; } - function setFeeRate(uint256 newFeeRate) external { + function setFeeRate(uint256 newFeeRate) external onlyOwner { _FEE_RATE_ = newFeeRate; } - function getFeeRate(address) external override view returns (uint256) { + function getFeeRate(address trader) external view returns (uint256) { return _FEE_RATE_; } } diff --git a/contracts/lib/ExternalValue.sol b/contracts/lib/ExternalValue.sol index 641dcf4..ae381fd 100644 --- a/contracts/lib/ExternalValue.sol +++ b/contracts/lib/ExternalValue.sol @@ -8,23 +8,28 @@ pragma solidity 0.6.9; pragma experimental ABIEncoderV2; -import {Ownable} from "./Ownable.sol"; -import {InitializableOwnable} from "./InitializableOwnable.sol"; +import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; interface IExternalValue { - function set(uint256) external; - + function init(address owner, uint256 value) external; + function set(uint256 value) external; function get() external view returns (uint256); } -contract ExternalValue is IExternalValue, InitializableOwnable { + +contract ExternalValue is InitializableOwnable { uint256 public _VALUE_; - function set(uint256 value) external override onlyOwner { + function init(address owner, uint256 value) external { + initOwner(owner); _VALUE_ = value; } - function get() external override view returns (uint256) { + function set(uint256 value) external onlyOwner { + _VALUE_ = value; + } + + function get() external view returns (uint256) { return _VALUE_; } } diff --git a/contracts/lib/FeeRateModel.sol b/contracts/lib/FeeRateModel.sol new file mode 100644 index 0000000..5529b21 --- /dev/null +++ b/contracts/lib/FeeRateModel.sol @@ -0,0 +1,44 @@ +/* + + Copyright 2020 DODO ZOO. + SPDX-License-Identifier: Apache-2.0 + +*/ + +pragma solidity 0.6.9; +pragma experimental ABIEncoderV2; + +import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; + +interface IFeeRateModel { + function getFeeRate(address trader) external view returns (uint256); + function init(address owner, uint256 feeRate) external; + function setFeeRate(uint256 newFeeRate) external; +} + +contract FeeRateModel is InitializableOwnable { + //DEFAULT + uint256 public _FEE_RATE_; + mapping(address => uint256) feeMapping; + + function init(address owner, uint256 feeRate) external { + initOwner(owner); + _FEE_RATE_ = feeRate; + } + + function setSpecificFeeRate(address trader, uint256 feeRate) external onlyOwner { + require(trader != address(0), "INVALID ADDRESS!"); + feeMapping[trader] = feeRate; + } + + function setFeeRate(uint256 newFeeRate) external onlyOwner { + _FEE_RATE_ = newFeeRate; + } + + function getFeeRate(address trader) external view returns (uint256) { + uint256 feeRate = feeMapping[trader]; + if(feeRate == 0) + return _FEE_RATE_; + return feeRate; + } +}