diff --git a/config/cfx-config.js b/config/cfx-config.js new file mode 100644 index 0000000..08bf9b8 --- /dev/null +++ b/config/cfx-config.js @@ -0,0 +1,101 @@ +module.exports = { + CFX_CONFIG: { + //TOKEN + WETH: "0x14b2d3bc65e74dae1030eafd8ac30c533c976a9b", + CHI: "", + DODO: "", + + //Helper + DODOSellHelper: "0x87cC76c08eF625d46eeC9183bA2977B34E16CDfe", + DODOCalleeHelper: "0x5B2fd46E6E3Ff1E479d651ec0b210882Aa9871dF", + DODOV1PmmHelper: "0xAC716E87b0853C0712674e8E3a8435a489F276b4", + DODOV2RouteHelper: "0x7E9c460d0A10bd0605B15F0d0388e307d34a62E6", + ERC20Helper: "0x24549FC74B3076A962624A26370ed556c467F74C", + DODOSwapCalcHelper: "0x6433407a29706Bbdd43b36cd402a53A174f066a1", + MultiCall: "0x696E25A5e2AEd1C55E6d6Cfa0532Bbda9020165d", + CurveSample: "", + + //Template + CloneFactory: "0x64842A3EbC09bB69429c1a34ae181375fea5f17F", + FeeRateModel: "0x41bb458c5FEEB114a977E59D5E153A2112e4e293", + //FeeRateImpl: "0x5381382257C761DAc6F1509B1BA1B70dDaa6862a", + FeeRateDIP3Impl: "0x6D208e3dD3ba8dc7b0D23D6Bf15fef9324643984", + UserQuota: "0xfcA520C94078b65F8237d4F566c438a9468917A1", + PermissionManager: "0xB89CCC740c9E3BE8712a2174b648a95C6978B836", + DVM: "0x4553E5CF08E8E5229caB9b092e76cB92cde672BA", + DPP: "0x1C6578Db75A269c9dD7baAAD3B252b74EA03E741", + DSP: "0xB8C29329FD2d295C73Aa6AcFBD3cAff7f93FA28D", //"0xc6D718Fa2bb39CCDf29a640361E42656DB1EBBD9", + DPPAdmin: "0x2144BF2003bFd9Aa0950716333fBb5B7A1Caeda4", + DPPAdvanced: "0x7E49058F16b8754b0af9B03A39777b1Ca5285f67", + DPPAdvancedAdmin: "0x942a23d3Be9C83D267B1B862F2ea397906Af8f3a", + CP: "0x716fcc67dcA500A91B4a28c9255262c398D8f971", + ERC20MineV2: "0x18586f053329CB477E171377BD5Ba1f26FeB2589", + ERC20MineV3: "0x4c52f61212F9e36922ab78AAb250F1a2f000D93C",//"0xe33421899CbF22E762407f02c34622519518986a", + ERC20: "0xe7d0B30e06b85Adfe01276f187603Bea20244f1D", + CustomERC20: "0x12e599006a5F19819cde6FABceBbd8586688C8ac", + CustomMintableERC20: "0xC9143e54021f4a6d33b9b89DBB9F458AaEdd56FB", + + //Factory + DVMFactory: "0xC77392396Be1FB5143f1f66A3Ae67dD03fbaBA27", + DPPFactory: "0xaC9a7053bC23D22ecC50F82cc9143d16bbC0E621", + DSPFactory: "0x9244EAa27266128610bad748625f512275A41a96", + //UpCpFactory: "0x0218E24dd47f9a1D05418eAa5B9cEDB13Ca48492", + CrowdPoolingFactory: "0xe05dd51e4eB5636f4f0E8e7Fbe82eA31a2ecef16", + ERC20Factory: "", + ERC20V2Factory: "0xA37164a08b830Ca164a4E417aCDaCCFdf5d80100", + ERC20V3Factory: "0x585adbB35d0eE28B0d2AdC7213284D37bab7EA4B", + DODOMineV2Factory: "0xc7d7CC1e9f5E823887980c9C51F9c418ee3A3e28", + DODOMineV3Registry: "0x4632e6EBd4a01eBF54739A9D71a62CEdb29E9183", + + //Approve + DODOApprove: "0x5BaF16d57620Cb361F622232F3cb4090e35F3da2", + DODOApproveProxy: "0xEfD2eC5F9fFe9899515C7032d86F925715eD9D05", + + //Periphery + DODOIncentive: "", + + //Adpater + DODOV1Adapter: "0x49d5c0908d12B272b0b5A3443a54FEd6e4a044FB", + DODOV2Adapter: "0xAE1E7e4c5743321d2a8ceeD179264998a56CF1d9", + UniAdapter: "0xD63c8Bf9ACaFfE6da2a4043F1C94CC3a55F28117", + CurveAdapter: "", + + //Proxy + DODOV2Proxy: "0xbce44767af0a53A108b3B7ba4F740E03D228Ec0A", + DSPProxy: "0x8d9ccc26CbF3D49bbA76E9920C3E6ed29e06b5cc", + CpProxy: "0x7Dd8c909E1F48a68FfEF03492761AF17B1496EDc", + DPPProxy: "0x99d69565EdA438E3ebAA0627A407968ABD0f755b", + RouteProxy: "0x3037e79fce8817a6f21196d8d93c80f53abb9267", + DODOMineV3Proxy: "0x14F7B8Fb0c1447DdE7bcf92a8d9BB058c8A5FE64", + + //vDODO + DODOCirculationHelper: "", + Governance: "", + dodoTeam: "", + vDODOToken: "", + + //Account + multiSigAddress: "0x1Dc662D3D7De14a57CD369e3a9E774f8F80d4214", + defaultMaintainer: "0x1Dc662D3D7De14a57CD369e3a9E774f8F80d4214", + + //================== NFT ==================== + BuyoutModel: "", + Fragment: "", + NFTCollateralVault: "", + DODONFTRouteHelper: "", + + DodoNftErc721: "", + DodoNftErc1155: "", + + DODONFTRegistry: "", + DODONFTProxy: "", + + //=================== NFTPool ================== + DODONFTApprove: "", + DODONFTPoolProxy: "", + FilterAdmin: "", + FilterERC721V1: "", + FilterERC1155V1: "", + NFTPoolController: "" + } +} \ No newline at end of file diff --git a/configAdapter.js b/configAdapter.js index 01f8bd5..de44cbf 100755 --- a/configAdapter.js +++ b/configAdapter.js @@ -11,6 +11,7 @@ const { MOONRIVER_CONFIG } = require("./config/moonriver-config"); const { BOBA_CONFIG } = require("./config/boba-config"); const { AVAX_CONFIG } = require("./config/avax-config"); const { DASHBOARD_CONFIG } = require("./config/dashboard-config"); +const {CFX_CONFIG} = require("./config/cfx-config.js"); exports.GetConfig = function (network, accounts) { var CONFIG = {} @@ -46,7 +47,7 @@ exports.GetConfig = function (network, accounts) { CONFIG = AVAX_CONFIG break; case "dashboard": - CONFIG = DASHBOARD_CONFIG + CONFIG = CFX_CONFIG break; //testnet case "kovan": @@ -59,6 +60,9 @@ exports.GetConfig = function (network, accounts) { CONFIG.multiSigAddress = accounts[0] CONFIG.defaultMaintainer = accounts[0] break; + case "cfx": + CONFIG = CFX_CONFIG + break; } return CONFIG } diff --git a/contracts/SmartRoute/adapter/UniAdapter.sol b/contracts/SmartRoute/adapter/UniAdapter.sol index 9da470a..1e6b171 100644 --- a/contracts/SmartRoute/adapter/UniAdapter.sol +++ b/contracts/SmartRoute/adapter/UniAdapter.sol @@ -16,34 +16,42 @@ contract UniAdapter is IDODOAdapter { using SafeMath for uint; //fromToken == token0 - function sellBase(address to, address pool, bytes memory) external override { + function sellBase(address to, address pool, bytes memory data) external override { address baseToken = IUni(pool).token0(); (uint reserveIn, uint reserveOut,) = IUni(pool).getReserves(); + uint receiveQuoteAmount; + { + (uint256 fee, uint256 denFee) = abi.decode(data, (uint256, uint256)); require(reserveIn > 0 && reserveOut > 0, 'UniAdapter: INSUFFICIENT_LIQUIDITY'); uint balance0 = IERC20(baseToken).balanceOf(pool); uint sellBaseAmount = balance0 - reserveIn; - uint sellBaseAmountWithFee = sellBaseAmount.mul(997); + uint sellBaseAmountWithFee = sellBaseAmount.mul(denFee - fee); uint numerator = sellBaseAmountWithFee.mul(reserveOut); - uint denominator = reserveIn.mul(1000).add(sellBaseAmountWithFee); - uint receiveQuoteAmount = numerator / denominator; + uint denominator = reserveIn.mul(denFee).add(sellBaseAmountWithFee); + receiveQuoteAmount = numerator / denominator; + } IUni(pool).swap(0, receiveQuoteAmount, to, new bytes(0)); } //fromToken == token1 - function sellQuote(address to, address pool, bytes memory) external override { + function sellQuote(address to, address pool, bytes memory data) external override { address quoteToken = IUni(pool).token1(); (uint reserveOut, uint reserveIn,) = IUni(pool).getReserves(); + uint receiveBaseAmount; + { + (uint256 fee, uint256 denFee) = abi.decode(data, (uint256, uint256)); require(reserveIn > 0 && reserveOut > 0, 'UniAdapter: INSUFFICIENT_LIQUIDITY'); uint balance1 = IERC20(quoteToken).balanceOf(pool); uint sellQuoteAmount = balance1 - reserveIn; - uint sellQuoteAmountWithFee = sellQuoteAmount.mul(997); + uint sellQuoteAmountWithFee = sellQuoteAmount.mul(denFee - fee); uint numerator = sellQuoteAmountWithFee.mul(reserveOut); - uint denominator = reserveIn.mul(1000).add(sellQuoteAmountWithFee); - uint receiveBaseAmount = numerator / denominator; + uint denominator = reserveIn.mul(denFee).add(sellQuoteAmountWithFee); + receiveBaseAmount = numerator / denominator; + } IUni(pool).swap(receiveBaseAmount, 0, to, new bytes(0)); } } \ No newline at end of file diff --git a/contracts/SmartRoute/helper/DODOV2CuttingRouteHelper.sol b/contracts/SmartRoute/helper/DODOV2CuttingRouteHelper.sol index d179c93..f9e2c68 100644 --- a/contracts/SmartRoute/helper/DODOV2CuttingRouteHelper.sol +++ b/contracts/SmartRoute/helper/DODOV2CuttingRouteHelper.sol @@ -94,17 +94,23 @@ contract DODOV2CuttingRouteHelper is InitializableOwnable { curRes.quoteToken = token0; } - ( - curRes.i, - curRes.K, - curRes.B, - curRes.Q, - curRes.B0, - curRes.Q0, - curRes.R - ) = IDODOV2(cur).getPMMStateForCall(); - - (curRes.lpFeeRate, curRes.mtFeeRate) = IDODOV2(cur).getUserFeeRate(userAddr); + try IDODOV2(cur).getPMMStateForCall() returns (uint256 _i, uint256 _K, uint256 _B, uint256 _Q, uint256 _B0, uint256 _Q0, uint256 _R){ + curRes.i = _i; + curRes.K = _K; + curRes.B = _B; + curRes.Q = _Q; + curRes.B0 = _B0; + curRes.Q0 = _Q0; + curRes.R = _R; + } catch { + continue; + } + + try IDODOV2(cur).getUserFeeRate(userAddr) returns (uint256 lpFeeRate, uint256 mtFeeRate) { + (curRes.lpFeeRate, curRes.mtFeeRate) = (lpFeeRate, mtFeeRate); + } catch { + (curRes.lpFeeRate, curRes.mtFeeRate) = (0, 1e18); + } curRes.curPair = cur; res[i] = curRes; } diff --git a/contracts/SmartRoute/helper/DODOV2RouteHelper.sol b/contracts/SmartRoute/helper/DODOV2RouteHelper.sol index 5ead267..df9209f 100644 --- a/contracts/SmartRoute/helper/DODOV2RouteHelper.sol +++ b/contracts/SmartRoute/helper/DODOV2RouteHelper.sol @@ -73,17 +73,23 @@ contract DODOV2RouteHelper { curRes.quoteToken = token0; } - ( - curRes.i, - curRes.K, - curRes.B, - curRes.Q, - curRes.B0, - curRes.Q0, - curRes.R - ) = IDODOV2(cur).getPMMStateForCall(); - - (curRes.lpFeeRate, curRes.mtFeeRate) = IDODOV2(cur).getUserFeeRate(userAddr); + try IDODOV2(cur).getPMMStateForCall() returns (uint256 _i, uint256 _K, uint256 _B, uint256 _Q, uint256 _B0, uint256 _Q0, uint256 _R){ + curRes.i = _i; + curRes.K = _K; + curRes.B = _B; + curRes.Q = _Q; + curRes.B0 = _B0; + curRes.Q0 = _Q0; + curRes.R = _R; + } catch { + continue; + } + + try IDODOV2(cur).getUserFeeRate(userAddr) returns (uint256 lpFeeRate, uint256 mtFeeRate) { + (curRes.lpFeeRate, curRes.mtFeeRate) = (lpFeeRate, mtFeeRate); + } catch { + (curRes.lpFeeRate, curRes.mtFeeRate) = (0, 1e18); + } curRes.curPair = cur; res[i] = curRes; } diff --git a/contracts/SmartRoute/intf/IUniswapV3SwapCallBack.sol b/contracts/SmartRoute/intf/IUniswapV3SwapCallBack.sol index a76ebda..f72ec96 100644 --- a/contracts/SmartRoute/intf/IUniswapV3SwapCallBack.sol +++ b/contracts/SmartRoute/intf/IUniswapV3SwapCallBack.sol @@ -1,4 +1,5 @@ -pragma solidity 0.6.9; +// SPDX-License-Identifier: GPL-2.0-or-later +pragma solidity >=0.5.0; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface diff --git a/migrations/3_deploy_v2.js b/migrations/3_deploy_v2.js index 561825c..7ca105b 100644 --- a/migrations/3_deploy_v2.js +++ b/migrations/3_deploy_v2.js @@ -191,6 +191,8 @@ module.exports = async (deployer, network, accounts) => { logger.log("UserQuotaAddress: ", UserQuotaAddress); } + + /* if (FeeRateImplAddress == "") { await deployer.deploy(FeeRateImpl); FeeRateImplAddress = FeeRateImpl.address; @@ -199,11 +201,15 @@ module.exports = async (deployer, network, accounts) => { var tx = await feeRateImplInstance.init(multiSigAddress,CloneFactoryAddress,UserQuotaAddress); logger.log("Init FeeRateImpl Tx:", tx.tx); } + */ if (FeeRateDIP3ImplAddress == "") { await deployer.deploy(FeeRateDIP3); FeeRateDIP3ImplAddress = FeeRateDIP3.address; logger.log("FeeRateDIP3Impl Address: ", FeeRateDIP3ImplAddress); + const feeRateImplInstance = await FeeRateDIP3.at(FeeRateDIP3ImplAddress); + var tx = await feeRateImplInstance.initOwner(multiSigAddress); + logger.log("Init FeeRateDIP3Impl Tx:", tx.tx); } if (DefaultPermissionAddress == "") { @@ -227,6 +233,7 @@ module.exports = async (deployer, network, accounts) => { logger.log("DspTemplateAddress: ", DspTemplateAddress); } + /* if (DppTemplateAddress == "") { await deployer.deploy(DppTemplate); DppTemplateAddress = DppTemplate.address; @@ -238,9 +245,10 @@ module.exports = async (deployer, network, accounts) => { DppAdminTemplateAddress = DppAdminTemplate.address; logger.log("DppAdminTemplateAddress: ", DppAdminTemplateAddress); } + */ if (DppAdvancedTemplateAddress == "") { - await deployer.deploy(DppAdvanedTemplate); + await deployer.deploy(DppAdvancedTemplate); DppAdvancedTemplateAddress = DppAdvancedTemplate.address; logger.log("DppAdvancedTemplateAddress: ", DppAdvancedTemplateAddress); } @@ -303,6 +311,8 @@ module.exports = async (deployer, network, accounts) => { //Factory + /* + 疑似废弃 if (ERC20V2FactoryAddress == "") { await deployer.deploy( ERC20V2Factory, @@ -316,6 +326,7 @@ module.exports = async (deployer, network, accounts) => { var tx = await ERC20V2FactoryInstance.initOwner(multiSigAddress); logger.log("Init ERC20V2Factory Tx:", tx.tx); } + */ if (ERC20V3FactoryAddress == "") { await deployer.deploy( @@ -365,6 +376,7 @@ module.exports = async (deployer, network, accounts) => { logger.log("Init DppFactory Tx:", tx.tx); } + /* if (UpCpFactoryAddress == "") { await deployer.deploy( UpCpFactory, @@ -381,6 +393,7 @@ module.exports = async (deployer, network, accounts) => { var tx = await UpCpFactoryInstance.initOwner(multiSigAddress); logger.log("Init UpCpFactory Tx:", tx.tx); } + if (CpFactoryAddress == "") { await deployer.deploy( @@ -398,6 +411,7 @@ module.exports = async (deployer, network, accounts) => { var tx = await CpFactoryInstance.initOwner(multiSigAddress); logger.log("Init CpFactory Tx:", tx.tx); } + */ if (CpV2FactoryAddress == "") { await deployer.deploy( @@ -539,6 +553,8 @@ module.exports = async (deployer, network, accounts) => { logger.log("Init DODOMineV3Proxy Tx:", tx.tx); } + // need deploy dodoRouteProxy in dodo-route-contract repo + /* if (DODORouteProxyAddress == "") { await deployer.deploy( DODORouteProxy, @@ -548,10 +564,11 @@ module.exports = async (deployer, network, accounts) => { DODOApproveProxyAddress = DODORouteProxy.address; logger.log("DODORouteProxy Address: ", DODORouteProxy.address); } + */ - - if (network == 'kovan' || network == 'rinkeby' ||network == "boba_test") { + if (network == 'kovan' || network == 'rinkeby' ||network == "boba_test" || network == "dashboard") { var tx; + //ApproveProxy init以及添加ProxyList const DODOApproveProxyInstance = await DODOApproveProxy.at(DODOApproveProxyAddress); tx = await DODOApproveProxyInstance.init(multiSigAddress, [DODOV2ProxyAddress, DODODspProxyAddress, DODOCpProxyAddress, DODODppProxyAddress, DODOMineV3ProxyAddress, DODORouteProxyAddress]); @@ -561,16 +578,17 @@ module.exports = async (deployer, network, accounts) => { const DODOApproveInstance = await DODOApprove.at(DODOApproveAddress); tx = await DODOApproveInstance.init(multiSigAddress, DODOApproveProxy.address); logger.log("DODOApprove Init tx: ", tx.tx); + //Set FeeRateImpl const FeeRateModelInstance = await FeeRateModelTemplate.at(DefaultMtFeeRateAddress); - tx = await FeeRateModelInstance.setFeeProxy(FeeRateImplAddress); + tx = await FeeRateModelInstance.setFeeProxy(FeeRateDIP3ImplAddress); logger.log("Set FeeRateImpl tx: ", tx.tx); - //ERC20V2Factory 设置fee - const ERC20V2FactoryInstance = await ERC20V2Factory.at(ERC20V2FactoryAddress); - tx = await ERC20V2FactoryInstance.changeCreateFee("100000000000000000"); - logger.log("Set ERC20V2 fee tx: ", tx.tx); + //ERC20V3Factory 设置fee + const ERC20V3FactoryInstance = await ERC20V3Factory.at(ERC20V3FactoryAddress); + tx = await ERC20V3FactoryInstance.changeCreateFee("100000000000000000"); + logger.log("Set ERC20V3 fee tx: ", tx.tx); //DODOMineV2Factory 设置个人账户为owner const dodoMineV2FactoryInstance = await DODOMineV2Factory.at(DODOMineV2FactoryAddress); diff --git a/truffle-config.js b/truffle-config.js index 1a796ac..e933d8e 100755 --- a/truffle-config.js +++ b/truffle-config.js @@ -70,6 +70,7 @@ module.exports = { }, dashboard: { + //host: "localhost", port: 24012, }, @@ -231,6 +232,18 @@ module.exports = { // timeoutBlocks: 200, skipDryRun: true }, + base: { + networkCheckTimeout: 1000000, + provider: () => { + return new HDWalletProvider(privKey, 'https://goerli.base.org') + }, + network_id: 84531, + gas: 6000000, + gasPrice: 35000000000, + // confirmations: 2, + // timeoutBlocks: 200, + skipDryRun: true + }, optimism: { provider: () => {