├── .babelrc ├── .eslintrc.yaml ├── .gitattributes ├── .gitignore ├── .prettierrc ├── .solcover.js ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── abi └── dodoAbi.json ├── archive ├── CustomERC20.sol ├── DODOV1Proxy01.sol ├── DODOV1Proxy02.sol ├── DODOV1Proxy03.sol ├── DODOV1Proxy04.sol ├── DODOV2Proxy01.sol ├── FeeRateImpl.sol └── UpCrowdPoolingFactory.sol ├── audit ├── PeckShield-Audit-DODOV2-v1.0.pdf ├── SlowMist_Smart Contract_Security_Audit_Report_DODOV2.pdf ├── Smart contract security audit report-DODO.pdf ├── [Certik] MiningV2.pdf ├── [Certik] NFT.pdf ├── [PeckShield] DODO-NFTPool-v1.0.pdf ├── [PeckShiled] MiningV2.pdf ├── [PeckShiled] MiningV3.pdf ├── [Peckshield] dodo_audit_report_2020_16_en_1.0.pdf ├── [SlowMist] DODO-NFTPool.pdf ├── [SlowMist] MiningV3 and NFT.pdf ├── [Trail of Bits] DODO Summary Report.pdf ├── dodo_audit_report_2020_16_en_1.0.pdf └── vDODO-final-report.pdf ├── config ├── arb-config.js ├── aurora-config.js ├── avax-config.js ├── base-config.js ├── boba-config.js ├── bsc-config.js ├── cfx-config.js ├── dashboard-config.js ├── dodo-testnet-config.js ├── eth-config.js ├── heco-config.js ├── kovan-config.js ├── linea-config.js ├── manta-config.js ├── manta-testnet-config.js ├── mantle-config.js ├── matic-config.js ├── moonriver-config.js ├── ok-config.js ├── optimism-config.js ├── rinkeby-config.js ├── scroll-config.js ├── scroll-sepolia-config.js └── sepolia-config.js ├── configAdapter.js ├── contracts ├── CollateralVault │ ├── impl │ │ └── NFTCollateralVault.sol │ └── intf │ │ └── ICollateralVault.sol ├── CrowdPooling │ ├── impl │ │ ├── CP.sol │ │ ├── CPFunding.sol │ │ ├── CPStorage.sol │ │ └── CPVesting.sol │ └── intf │ │ └── ICP.sol ├── DODODrops │ ├── DODODropsV1.sol │ └── DODODropsV2 │ │ ├── DODODrops.sol │ │ ├── DropsERC1155.sol │ │ ├── DropsERC721.sol │ │ └── DropsFeeModel.sol ├── DODOFee │ ├── FeeRateDIP3Impl.sol │ ├── PoolHeartBeat.sol │ ├── UserQuota.sol │ ├── UserQuotaFactory.sol │ └── vDODOQuota.sol ├── DODOPrivatePool │ ├── impl │ │ ├── DPP.sol │ │ ├── DPPAdmin.sol │ │ ├── DPPAdvanced │ │ │ ├── DPPAdvanced.sol │ │ │ └── DPPAdvancedAmin.sol │ │ ├── DPPOracle │ │ │ ├── DPPOracle.sol │ │ │ ├── DPPOracleAdmin.sol │ │ │ ├── DPPStorage.sol │ │ │ ├── DPPTrader.sol │ │ │ ├── DPPVault.sol │ │ │ └── WooOracleAdapter.sol │ │ ├── DPPStorage.sol │ │ ├── DPPTrader.sol │ │ └── DPPVault.sol │ └── intf │ │ ├── IDPP.sol │ │ ├── IDPPAdmin.sol │ │ ├── IDPPOracle.sol │ │ └── IOracle.sol ├── DODOStablePool │ ├── impl │ │ ├── DSP.sol │ │ ├── DSPFunding.sol │ │ ├── DSPStorage.sol │ │ ├── DSPTrader.sol │ │ └── DSPVault.sol │ └── intf │ │ └── IDSP.sol ├── DODOStarter │ ├── impl │ │ ├── FairFunding.sol │ │ ├── FairFundingV2.sol │ │ ├── InstantFunding.sol │ │ ├── InstantFundingV2.sol │ │ ├── Storage.sol │ │ └── Vesting.sol │ └── intf │ │ └── IDODOStarter.sol ├── DODOToken │ ├── DODOBscToken.sol │ ├── DODOCirculationHelper.sol │ ├── DODOIncentive.sol │ ├── DODOMigrationBSC.sol │ ├── DODOMine.sol │ ├── DODOMineV2 │ │ ├── BaseMine.sol │ │ ├── ERC20Mine.sol │ │ ├── RewardVault.sol │ │ └── vDODOMine.sol │ ├── DODOMineV3 │ │ ├── BaseMine.sol │ │ ├── ERC20MineV3.sol │ │ └── RewardVault.sol │ ├── DODORecharge.sol │ ├── DODORewardVault.sol │ ├── DODOToken.sol │ ├── Governance.sol │ ├── LockedTokenVault.sol │ └── vDODOToken.sol ├── DODOVendingMachine │ ├── impl │ │ ├── DVM.sol │ │ ├── DVMFunding.sol │ │ ├── DVMStorage.sol │ │ ├── DVMTrader.sol │ │ └── DVMVault.sol │ └── intf │ │ └── IDVM.sol ├── Factory │ ├── CrowdPoolingFactory.sol │ ├── DODOMineV2Factory.sol │ ├── DODONFT.sol │ ├── DODONFT1155.sol │ ├── DODOStarterFactory.sol │ ├── DODOStarterFactoryV2.sol │ ├── DPPFactory.sol │ ├── DSPFactory.sol │ ├── DVMFactory.sol │ ├── ERC20Factory.sol │ ├── ERC20V2Factory.sol │ ├── ERC20V3Factory.sol │ ├── NFTTokenFactory.sol │ └── Registries │ │ ├── DODOMineV3Registry.sol │ │ └── DODONFTRegistry.sol ├── GeneralizedFragment │ ├── impl │ │ ├── BuyoutModel.sol │ │ └── Fragment.sol │ └── intf │ │ └── IFragment.sol ├── NFTPool │ ├── impl │ │ ├── BaseFilterV1.sol │ │ ├── Controller.sol │ │ ├── FilterAdmin.sol │ │ ├── FilterERC1155V1.sol │ │ └── FilterERC721V1.sol │ └── intf │ │ ├── IController.sol │ │ ├── IFilter.sol │ │ └── IFilterAdmin.sol ├── SmartRoute │ ├── DODOApprove.sol │ ├── DODOApproveProxy.sol │ ├── DODONFTApprove.sol │ ├── DODOV2Proxy02.sol │ ├── adapter │ │ ├── CurveAdapter.sol │ │ ├── DODOV1Adapter.sol │ │ ├── DODOV2Adapter.sol │ │ ├── GambitAdapter.sol │ │ ├── UniAdapter.sol │ │ └── UniV3Adapter.sol │ ├── helper │ │ ├── DODOCalleeHelper.sol │ │ ├── DODONFTRouteHelper.sol │ │ ├── DODOSellHelper.sol │ │ ├── DODOSwapCalcHelper.sol │ │ ├── DODOV1PmmHelper.sol │ │ ├── DODOV2CuttingRouteHelper.sol │ │ └── DODOV2RouteHelper.sol │ ├── intf │ │ ├── IChi.sol │ │ ├── ICurve.sol │ │ ├── IDODOAdapter.sol │ │ ├── IDODOV1.sol │ │ ├── IDODOV1Proxy01.sol │ │ ├── IDODOV1Proxy02.sol │ │ ├── IDODOV2.sol │ │ ├── IDODOV2Proxy01.sol │ │ ├── IGambit.sol │ │ ├── IUni.sol │ │ ├── IUniV3.sol │ │ └── IUniswapV3SwapCallBack.sol │ ├── lib │ │ └── UniversalERC20.sol │ ├── proxies │ │ ├── DODOCpProxy.sol │ │ ├── DODODppProxy.sol │ │ ├── DODODropsProxy.sol │ │ ├── DODODspProxy.sol │ │ ├── DODOFeeRouteProxy.sol │ │ ├── DODOMineV3Proxy.sol │ │ ├── DODONFTPoolProxy.sol │ │ ├── DODONFTProxy.sol │ │ ├── DODORouteProxy.sol │ │ └── DODOStarterProxy.sol │ └── sampler │ │ └── CurveSample.sol ├── external │ ├── ERC1155 │ │ ├── ERC1155.sol │ │ └── InitializableERC1155.sol │ ├── ERC20 │ │ ├── ChiToken.sol │ │ ├── CustomERC20.sol │ │ ├── CustomMintableERC20.sol │ │ ├── InitializableERC20.sol │ │ ├── InitializableFragERC20.sol │ │ ├── InitializableInternalMintableERC20.sol │ │ ├── InitializableMintableERC20.sol │ │ ├── MintableERC20.sol │ │ ├── TestERC20.sol │ │ └── TestWETH.sol │ ├── ERC721 │ │ ├── ERC721.sol │ │ ├── ERC721Enumerable.sol │ │ ├── ERC721URIStorage.sol │ │ └── InitializableERC721.sol │ ├── Multicall.sol │ ├── MulticallWithValid.sol │ ├── uniswap │ │ ├── PoolAddress.sol │ │ ├── TickMath.sol │ │ └── UniswapV2.sol │ └── utils │ │ ├── Address.sol │ │ ├── Context.sol │ │ ├── ERC165.sol │ │ └── Strings.sol ├── helper │ ├── ERC20Helper.sol │ ├── Migrations.sol │ └── NaiveOracle.sol ├── intf │ ├── IDODOApprove.sol │ ├── IDODOApproveProxy.sol │ ├── IDODOCallee.sol │ ├── IDODONFTApprove.sol │ ├── IERC1155.sol │ ├── IERC1155MetadataURI.sol │ ├── IERC1155Receiver.sol │ ├── IERC165.sol │ ├── IERC20.sol │ ├── IERC721.sol │ ├── IERC721Enumerable.sol │ ├── IERC721Metadata.sol │ ├── IERC721Receiver.sol │ ├── IFeeDistributor.sol │ ├── IOracle.sol │ └── IWETH.sol └── lib │ ├── CloneFactory.sol │ ├── ConstFeeRateModel.sol │ ├── DODOMath.sol │ ├── DecimalMath.sol │ ├── ExternalValue.sol │ ├── FeeRateModel.sol │ ├── InitializableOwnable.sol │ ├── Ownable.sol │ ├── PMMPricing.sol │ ├── PermissionManager.sol │ ├── RandomGenerator.sol │ ├── ReentrancyGuard.sol │ ├── SafeERC20.sol │ └── SafeMath.sol ├── coverage.json ├── cpV2&&cpV1-diff.html ├── deploy-starter.txt ├── immunefibugbounty.md ├── migrations ├── 1_initial_migration.js ├── 2_deploy_erc20V3.js ├── 2_deploy_starter.js ├── 3_deploy_v2.js ├── 4_deploy_nftPool.js ├── 5_deploy_nft.js ├── 6_deploy_periphery.js ├── 7_deploy_dropsV2.js └── 8_deploy_v2_mock.js ├── package-lock.json ├── package.json ├── test ├── CrowdPooling │ ├── CPBid.test.ts │ ├── CPCancelEthBid.test.ts │ ├── CPSettle.test.ts │ ├── CPSettleReversePool.test.ts │ └── CPVesting.test.ts ├── DODODrops │ └── dropsV2.test.ts ├── DODOMineV2 │ ├── erc20Mine.test.ts │ └── vDODOMine.test.ts ├── DODONFT │ ├── mysteryBoxV1.test.ts │ └── nftMainFlow.test.ts ├── DODOStarter │ ├── FairFunding.test.ts │ └── InstantFunding.test.ts ├── DPP │ ├── owner.test.ts │ ├── reset.test.ts │ └── trader.test.ts ├── DSP │ ├── funding.test.ts │ └── trader.test.ts ├── DVM │ ├── AMMLikeCase.test.ts │ ├── ConstPriceCase.test.ts │ ├── funding.test.ts │ └── trader.test.ts ├── NFTPool │ ├── erc1155NftPool.test.ts │ └── erc721NftPool.test.ts ├── V1Proxy │ └── Route.test.ts ├── V2Proxy │ ├── proxy.classical.test.ts │ ├── proxy.cp.test.ts │ ├── proxy.dpp.test.ts │ ├── proxy.dvm.test.ts │ ├── proxy.incentive.test.ts │ ├── proxy.mix.test.ts │ └── proxy.twap.test.ts ├── utils-v1 │ ├── Contracts.ts │ ├── Converter.ts │ ├── EVM.ts │ ├── Log.ts │ └── ProxyContextV1.ts ├── utils │ ├── Contracts.ts │ ├── Converter.ts │ ├── CrowdPoolingContext.ts │ ├── DODOMineV2Context.ts │ ├── DODOStarterContext.ts │ ├── DPPContext.ts │ ├── DSPContext.ts │ ├── DVMContext.ts │ ├── DropsContext.ts │ ├── EVM.ts │ ├── Log.ts │ ├── NFTContext.ts │ ├── NFTPoolContext.ts │ ├── ProxyContextV2.ts │ ├── SignHelper.ts │ ├── SlippageFormula.ts │ └── VDODOContext.ts └── vDODO │ ├── erc20.test.ts │ ├── global.test.ts │ └── mintRedeem.test.ts ├── truffle-config.js ├── truffle-test.sh ├── tsconfig.json ├── tslint.json └── yarn-error.log /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2", "stage-3"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | extends: airbnb-base 2 | parser: babel-eslint 3 | 4 | env: 5 | node: true 6 | es6: true 7 | 8 | globals: 9 | artifacts: true 10 | 11 | rules: 12 | no-use-before-define: 0 13 | class-methods-use-this: 0 14 | no-underscore-dangle: 0 15 | max-len: 16 | - error 17 | - 100 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .coverage* 2 | .DS_Store 3 | .env.local 4 | .env 5 | .idea 6 | 7 | build/ 8 | build-v1/ 9 | dist/ 10 | node_modules/ 11 | coverage/ 12 | lint/ 13 | script/ 14 | flattered/ 15 | 16 | deploy-detail-v2.0.txt 17 | deploy-detail-periphery.txt 18 | deploy-drops.txt 19 | deploy-nft.txt 20 | deploy-starter.txt 21 | kovan-mock-v2.0.txt 22 | deploy-detail-erc20V3.txt 23 | 24 | # VIM 25 | *.swo 26 | *.swp 27 | 28 | 29 | node_modules 30 | 31 | #Hardhat files 32 | cache 33 | artifacts 34 | 35 | error-v1.5-stat.txt -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": "*.sol", 5 | "options": { 6 | "printWidth": 100, 7 | "tabWidth": 4, 8 | "useTabs": false, 9 | "singleQuote": false, 10 | "bracketSpacing": false, 11 | "explicitTypes": "always" 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: require("ganache-cli"), 3 | port: 6545, 4 | testrpcOptions: 5 | "--port 6545 -l 0x1fffffffffffff -i 1002 -g 1 --allowUnlimitedContractSize", 6 | skipFiles: [ 7 | "lib/SafeMath.sol", 8 | "lib/DecimalMath.sol", 9 | "lib/Types.sol", 10 | "lib/ReentrancyGuard.sol", 11 | "lib/Ownable.sol", 12 | "impl/DODOLpToken.sol", 13 | "intf", 14 | "helper", 15 | ], 16 | }; 17 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "solidity.compileUsingRemoteVersion": "v0.6.9+commit.3e3065ac", 3 | "solidity.defaultCompiler": "remote" 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DODO V2: Help 1 Trillion People Issue Token 2 | 3 | ## Audit Report 4 | 5 | [Audited by Peckshield](https://github.com/DODOEX/contractV2/blob/main/audit/PeckShield-Audit-DODOV2-v1.0.pdf) 6 | 7 | ## Bug Bounty 💰 8 | 9 | ### Rewards 10 | 11 | Severity of bugs will be assessed under the [CVSS Risk Rating](https://www.first.org/cvss/calculator/3.0) scale, as follows: 12 | 13 | - Critical (9.0-10.0): Up to $100,000 14 | - High (7.0-8.9): Up to $10,000 15 | - Medium (4.0-6.9): Up to $5,000 16 | - Low (0.1-3.9): Up to $1,000 17 | 18 | In addition to assessing severity, rewards will be considered based on the impact of the discovered vulnerability as well as the level of difficulty in discovering such vulnerability. 19 | 20 | ### Disclosure 21 | 22 | Any vulnerability or bug discovered must be reported only to the following email: contact@dodoex.io; must not be disclosed publicly; must not be disclosed to any other person, entity or email address prior to disclosure to the contact@dodoex.io email; and must not be disclosed in any way other than to the contact@dodoex.io email. In addition, disclosure to contact@dodoex.io must be made promptly following discovery of the vulnerability. Please include as much information about the vulnerability as possible, including: 23 | 24 | - The conditions on which reproducing the bug is contingent. 25 | - The steps needed to reproduce the bug or, preferably, a proof of concept. 26 | - The potential implications of the vulnerability being abused. 27 | 28 | A detailed report of a vulnerability increases the likelihood of a reward and may increase the reward amount. 29 | 30 | Anyone who reports a unique, previously-unreported vulnerability that results in a change to the code or a configuration change and who keeps such vulnerability confidential until it has been resolved by our engineers will be recognized publicly for their contribution, if agreed. 31 | 32 | ## Contact Us 33 | 34 | Send E-mail to contact@dodoex.io -------------------------------------------------------------------------------- /audit/PeckShield-Audit-DODOV2-v1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/PeckShield-Audit-DODOV2-v1.0.pdf -------------------------------------------------------------------------------- /audit/SlowMist_Smart Contract_Security_Audit_Report_DODOV2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/SlowMist_Smart Contract_Security_Audit_Report_DODOV2.pdf -------------------------------------------------------------------------------- /audit/Smart contract security audit report-DODO.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/Smart contract security audit report-DODO.pdf -------------------------------------------------------------------------------- /audit/[Certik] MiningV2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[Certik] MiningV2.pdf -------------------------------------------------------------------------------- /audit/[Certik] NFT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[Certik] NFT.pdf -------------------------------------------------------------------------------- /audit/[PeckShield] DODO-NFTPool-v1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[PeckShield] DODO-NFTPool-v1.0.pdf -------------------------------------------------------------------------------- /audit/[PeckShiled] MiningV2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[PeckShiled] MiningV2.pdf -------------------------------------------------------------------------------- /audit/[PeckShiled] MiningV3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[PeckShiled] MiningV3.pdf -------------------------------------------------------------------------------- /audit/[Peckshield] dodo_audit_report_2020_16_en_1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[Peckshield] dodo_audit_report_2020_16_en_1.0.pdf -------------------------------------------------------------------------------- /audit/[SlowMist] DODO-NFTPool.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[SlowMist] DODO-NFTPool.pdf -------------------------------------------------------------------------------- /audit/[SlowMist] MiningV3 and NFT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[SlowMist] MiningV3 and NFT.pdf -------------------------------------------------------------------------------- /audit/[Trail of Bits] DODO Summary Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/[Trail of Bits] DODO Summary Report.pdf -------------------------------------------------------------------------------- /audit/dodo_audit_report_2020_16_en_1.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/dodo_audit_report_2020_16_en_1.0.pdf -------------------------------------------------------------------------------- /audit/vDODO-final-report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DODOEX/contractV2/82733a61f329c22e5e31b755c8a30c51884a5afd/audit/vDODO-final-report.pdf -------------------------------------------------------------------------------- /config/manta-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | MANTA_CONFIG: { 3 | //TOKEN 4 | WETH: "0x0Dc808adcE2099A9F62AA87D9670745AbA741746", 5 | 6 | //Helper 7 | DODOSellHelper: "0x8eA40e8Da3ae64Bad5E77a5f7DB346499F543baC", 8 | DODOCalleeHelper: "0x44023441f2Bad375b6b5C6354B03c3E9AD01E269", 9 | DODOV1PmmHelper: "0x17644d3B366273faC75A07996E2F90A99A2946a7", 10 | DODOV2RouteHelper: "0x4CAD0052524648A7Fa2cfE279997b00239295F33", 11 | ERC20Helper: "0xB5c7BA1EAde74800cD6cf5F56b1c4562De373780", 12 | DODOSwapCalcHelper: "0xbcd2FDC3B884Cf0dfD932f55Ec2Fe1fB7e8c62Da", 13 | MultiCall: "0xf5Ec1a19e1570bDf0A3AaA6585274f27027270b1", 14 | 15 | //Template 16 | CloneFactory: "0x628E5081bA93b1c4F58E54e7175088B1ACe58852", 17 | FeeRateModel: "0x7B07164ecFaF0F0D85DFC062Bc205a4674c75Aa0", 18 | FeeRateDIP3Impl: "0x4aAe1d041C01078725dB016BA4D4F72455CaF931", 19 | PermissionManager: "0x5fe43C0EbfE66b83C10A9A37AD1E4aC640AAAA65", 20 | DVM: "0x1fC8EC204549C865a17b4059A57decA66A4Bd4cC", 21 | DSP: "0x6a9De0C6235bDD14B52eeA53F5a08Ff7D4183b3e", 22 | DPPAdvanced: "0xCb3dC90E800C961d4a206BeAAFd92A6d2E06495e", 23 | DPPAdvancedAdmin: "0xCD536b4DECFD2fa0443666B6becD145F8aDe2E48", 24 | CP: "0x3dD629473A2eD7f3C6299FFD9F3e0C283d073f11", 25 | ERC20MineV2: "0x89872650fA1A391f58B4E144222bB02e44db7e3B", 26 | ERC20MineV3: "0x6de4d882a84A98f4CCD5D33ea6b3C99A07BAbeB1", 27 | ERC20: "0x8414560d69650bC0c915d5d4385e1714a23cbe81", 28 | CustomERC20: "0xEAC4BFef7D1c872Ed705B01856af7f9802adC596", 29 | CustomMintableERC20: "0x04f7BaE2A4c05cd567F762E33450deBCebdC89EA", 30 | 31 | //Factory 32 | DVMFactory: "0x97bBF5BB1dcfC93A8c67e97E50Bea19DB3416A83", 33 | DPPFactory: "0xa71415675F68f29259ddD63215E5518d2735bf0a", 34 | DSPFactory: "0x29C7718e8B606cEF1c44Fe6e43e07aF9D0875DE1", 35 | CrowdPoolingFactory: "0xFD2b7994f91c08aAa5e013E899334A2DBb500DF1", 36 | ERC20V3Factory: "0xc0F9553Df63De5a97Fe64422c8578D0657C360f7", 37 | DODOMineV2Factory: "0x46AF6b152F2cb02a3cFcc74014C2617BC4F6cD5C", 38 | DODOMineV3Registry: "0x66c45FF040e86DC613F239123A5E21FFdC3A3fEC", 39 | 40 | //Approve 41 | DODOApprove: "0x0226fCE8c969604C3A0AD19c37d1FAFac73e13c2", 42 | DODOApproveProxy: "0xa23137871C4A4ce8514f581EE82262CD1A49EEAE", 43 | 44 | //Adpater 45 | DODOV2Adapter: "0x7dB214f2D46d94846936a0f8Bd9044c5C5Bd2b93", 46 | 47 | //Proxy 48 | DODOV2Proxy: "0x2F86652dAEF5f1728c54191C955F065Ec3C188c7", 49 | DSPProxy: "0x0B1467f71c082D8d410aF4376C685D9A6893cF36", 50 | CpProxy: "0x2F66C5aAF006Bd9c51615D617589C16c0ed35fD3", 51 | DPPProxy: "0xCDA4a6cc5997002B87f28D46852F9F0aA0f3c897", 52 | FeeRouteProxy1: "0x2933c0374089D7D98BA0C71c5E02E1A0e09deBEE", // for front-end 53 | FeeRouteProxy2: "0x200D866Edf41070DE251Ef92715a6Ea825A5Eb80", // for widget 54 | DODOMineV3Proxy: "0xA6d0066328Edbcf3220cf8F61e8527e589DD9719", 55 | 56 | //Account 57 | multiSigAddress: "0xa7b9C3a116b20bEDDdBE4d90ff97157f67F0bD97", 58 | defaultMaintainer: "0xa7b9C3a116b20bEDDdBE4d90ff97157f67F0bD97", 59 | } 60 | } -------------------------------------------------------------------------------- /config/sepolia-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | SEPOLIA_CONFIG: { 3 | //TOKEN 4 | WETH: "0x7B07164ecFaF0F0D85DFC062Bc205a4674c75Aa0", 5 | 6 | //Helper 7 | DODOSellHelper: "0xa1609A1fa7DC16c025feA194c02b2822441b8c10", 8 | DODOCalleeHelper: "0xCD536b4DECFD2fa0443666B6becD145F8aDe2E48", 9 | DODOV1PmmHelper: "0x3dD629473A2eD7f3C6299FFD9F3e0C283d073f11", 10 | DODOV2RouteHelper: "0x03e89fC55A5ad0531576E5a502c4CA52c8bf391B", 11 | ERC20Helper: "0x297da061D1dE0132D241Fafed224288B34d81005", 12 | DODOSwapCalcHelper: "0x6a9De0C6235bDD14B52eeA53F5a08Ff7D4183b3e", 13 | MultiCall: "0x0fcB5237A1997C4700Ffa2BB4522EA38d4F851Fc", 14 | MultiCallWithValid: "0x1fC8EC204549C865a17b4059A57decA66A4Bd4cC", 15 | 16 | //Template 17 | CloneFactory: "0x8414560d69650bC0c915d5d4385e1714a23cbe81", 18 | FeeRateModel: "0xEAC4BFef7D1c872Ed705B01856af7f9802adC596", 19 | FeeRateDIP3Impl: "0x89872650fA1A391f58B4E144222bB02e44db7e3B", 20 | PermissionManager: "0xCb3dC90E800C961d4a206BeAAFd92A6d2E06495e", 21 | DVM: "0xa23137871C4A4ce8514f581EE82262CD1A49EEAE", 22 | DSP: "0xF3e3c6065C83b1E2F8B6701f07dF3a55aAA249BB", 23 | DPPAdvanced: "0x14DD1cb49e08b53DE3bD67Ee2815Ba5b2e9f269d", 24 | DPPAdvancedAdmin: "0xFaFC924BF0F70BdF4a722231622f559b94e53902", 25 | CP: "0xa71415675F68f29259ddD63215E5518d2735bf0a", 26 | ERC20MineV2: "0x1506b54A1c0eA1B2F4a84866Ec5776F7F6e7f0B1", 27 | ERC20MineV3: "0x46AF6b152F2cb02a3cFcc74014C2617BC4F6cD5C", 28 | ERC20: "0xFD2b7994f91c08aAa5e013E899334A2DBb500DF1", 29 | CustomERC20: "0x8dD0Fea5FA2f7df535F87f312641Cc15d8B151BA", 30 | CustomMintableERC20: "0x29C7718e8B606cEF1c44Fe6e43e07aF9D0875DE1", 31 | 32 | //Factory 33 | DVMFactory: "0x2F86652dAEF5f1728c54191C955F065Ec3C188c7", 34 | DPPFactory: "0x0B1467f71c082D8d410aF4376C685D9A6893cF36", 35 | DSPFactory: "0xe7979E2F3e77196Bb2AB206eaa67Ea278A3E33A2", 36 | CrowdPoolingFactory: "0xCDA4a6cc5997002B87f28D46852F9F0aA0f3c897", 37 | ERC20V3Factory: "0x4CAD0052524648A7Fa2cfE279997b00239295F33", 38 | DODOMineV2Factory: "0x49186E32fEd50fd6B5604A2618c7B0b03Cd41414", 39 | DODOMineV3Registry: "0xa5fc92Ca57a21C87AA0477b1c8fE8B9Bbf69d6C2", 40 | 41 | //Approve 42 | DODOApprove: "0x66c45FF040e86DC613F239123A5E21FFdC3A3fEC", 43 | DODOApproveProxy: "0xE2004eE21f88a7D8e1A5EDc3c9617a0460CC7b99", 44 | 45 | //Adpater 46 | DODOV2Adapter: "0x70B9C57E1fF24761C1C3ced57Ddae9A3F3570698", 47 | 48 | //Proxy 49 | DODOV2Proxy: "0x6292e8f7647b3b9dDf5795b1Fb77D0187e30E0F9", 50 | DSPProxy: "0x987bFBE33c9cF18cAA665B792Db66339a9c16D32", 51 | CpProxy: "0xA376762070F7fCE8f3646AAe90e6e375e6daF128", 52 | DPPProxy: "0x5e1251f4873248a030e1c92FFEB133AF1513277f", 53 | FeeRouteProxy1: "0x5fa9e06111814840398ceF6E9563d400F6ed3a8d", // for front-end 54 | FeeRouteProxy2: "0xb38D394D52A15910b8acc173b816624dc90066cd", // for widget 55 | DODOMineV3Proxy: "0xBbD59b9316eE65526DbBdEc2A748Cc05A285d54C", 56 | 57 | //Account 58 | multiSigAddress: "0xb37136B338C6cC0E459A35fe9Aa036f6b5A147c0", 59 | defaultMaintainer: "0xb37136B338C6cC0E459A35fe9Aa036f6b5A147c0", 60 | } 61 | } -------------------------------------------------------------------------------- /contracts/CollateralVault/intf/ICollateralVault.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | 11 | interface ICollateralVault { 12 | function _OWNER_() external returns (address); 13 | 14 | function init(address owner, string memory name, string memory baseURI) external; 15 | 16 | function directTransferOwnership(address newOwner) external; 17 | } 18 | -------------------------------------------------------------------------------- /contracts/CrowdPooling/intf/ICP.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface ICP { 12 | function init( 13 | address[] calldata addressList, 14 | uint256[] calldata timeLine, 15 | uint256[] calldata valueList, 16 | bool[] calldata switches 17 | ) external; 18 | 19 | function bid(address to) external; 20 | 21 | function cancel(address assetTo, uint256 amount) external; 22 | 23 | function settle() external; 24 | 25 | function emergencySettle() external; 26 | 27 | function claimLPToken() external; 28 | } 29 | -------------------------------------------------------------------------------- /contracts/DODODrops/DODODropsV2/DropsERC1155.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {ERC1155} from "../../external/ERC1155/ERC1155.sol"; 12 | import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; 13 | import {Strings} from "../../external/utils/Strings.sol"; 14 | 15 | contract DropsERC1155 is ERC1155, InitializableOwnable { 16 | using Strings for uint256; 17 | 18 | mapping (address => bool) public _IS_ALLOWED_MINT_; 19 | string internal _baseUri = ""; 20 | 21 | // ============ Event ============= 22 | event addMinter(address account); 23 | event removeMinter(address account); 24 | 25 | function addMintAccount(address account) public onlyOwner { 26 | _IS_ALLOWED_MINT_[account] = true; 27 | emit addMinter(account); 28 | } 29 | 30 | function removeMintAccount(address account) public onlyOwner { 31 | _IS_ALLOWED_MINT_[account] = false; 32 | emit removeMinter(account); 33 | } 34 | 35 | function init( 36 | address owner, 37 | string memory uri 38 | ) public { 39 | initOwner(owner); 40 | _baseUri = uri; 41 | } 42 | 43 | function mint(address account, uint256 id, uint256 amount, bytes memory data) external { 44 | require(_IS_ALLOWED_MINT_[msg.sender], "Mint restricted"); 45 | _mint(account, id, amount, data); 46 | } 47 | 48 | function uri(uint256 tokenId) public view override returns (string memory) { 49 | string memory baseURI = _baseUri; 50 | 51 | return bytes(baseURI).length > 0 52 | ? string(abi.encodePacked(baseURI, tokenId.toString())) 53 | : ''; 54 | } 55 | } -------------------------------------------------------------------------------- /contracts/DODODrops/DODODropsV2/DropsERC721.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {ERC721Enumerable} from "../../external/ERC721/ERC721Enumerable.sol"; 12 | import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; 13 | 14 | contract DropsERC721 is ERC721Enumerable, InitializableOwnable { 15 | mapping (address => bool) public _IS_ALLOWED_MINT_; 16 | 17 | // ============ Event ============= 18 | event addMinter(address account); 19 | event removeMinter(address account); 20 | 21 | function addMintAccount(address account) public onlyOwner { 22 | _IS_ALLOWED_MINT_[account] = true; 23 | emit addMinter(account); 24 | } 25 | 26 | function removeMintAccount(address account) public onlyOwner { 27 | _IS_ALLOWED_MINT_[account] = false; 28 | emit removeMinter(account); 29 | } 30 | 31 | function init( 32 | address owner, 33 | string memory name, 34 | string memory symbol, 35 | string memory uri 36 | ) public { 37 | initOwner(owner); 38 | _name = name; 39 | _symbol = symbol; 40 | _baseUri = uri; 41 | } 42 | 43 | function mint(address to, uint256 tokenId) external { 44 | require(_IS_ALLOWED_MINT_[msg.sender], "restricted"); 45 | _mint(to, tokenId); 46 | } 47 | } -------------------------------------------------------------------------------- /contracts/DODODrops/DODODropsV2/DropsFeeModel.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; 11 | import {SafeMath} from "../../lib/SafeMath.sol"; 12 | import {DecimalMath} from "../../lib/DecimalMath.sol"; 13 | 14 | interface IFee { 15 | function getUserFee(address user,uint256 ticketAmount) external view returns (uint256); 16 | } 17 | 18 | interface IPrice { 19 | function getUserPrice(address user, uint256 originalPrice, uint256 ticketAmount) external view returns (uint256); 20 | } 21 | 22 | contract DropsFeeModel is InitializableOwnable { 23 | using SafeMath for uint256; 24 | 25 | struct DropBoxInfo { 26 | bool isSet; 27 | uint256 globalFee; 28 | address feeAddr; 29 | address priceAddr; 30 | } 31 | 32 | mapping(address => DropBoxInfo) dropBoxes; 33 | 34 | // ============ Event ============= 35 | event AddDropBoxInfo(address dropBox, uint256 globalFee, address feeAddr, address priceAddr); 36 | event SetDropBoxInfo(address dropBox, uint256 globalFee, address feeAddr, address priceAddr); 37 | 38 | 39 | function addDropBoxInfo(address dropBox, uint256 globalFee, address feeAddr, address priceAddr) external onlyOwner { 40 | DropBoxInfo memory dropBoxInfo = DropBoxInfo({ 41 | isSet: true, 42 | globalFee: globalFee, 43 | feeAddr: feeAddr, 44 | priceAddr: priceAddr 45 | }); 46 | dropBoxes[dropBox] = dropBoxInfo; 47 | emit AddDropBoxInfo(dropBox, globalFee, feeAddr, priceAddr); 48 | } 49 | 50 | function setDropBoxInfo(address dropBox, uint256 globalFee, address feeAddr, address priceAddr) external onlyOwner { 51 | require(dropBoxes[dropBox].isSet, "NOT_FOUND_BOX"); 52 | dropBoxes[dropBox].globalFee = globalFee; 53 | dropBoxes[dropBox].feeAddr = feeAddr; 54 | dropBoxes[dropBox].priceAddr = priceAddr; 55 | emit SetDropBoxInfo(dropBox, globalFee, feeAddr, priceAddr); 56 | } 57 | 58 | function getPayAmount(address dropBox, address user, uint256 originalPrice, uint256 ticketAmount) external view returns (uint256 payAmount, uint256 feeAmount) { 59 | DropBoxInfo memory dropBoxInfo = dropBoxes[dropBox]; 60 | if(!dropBoxInfo.isSet) { 61 | payAmount = originalPrice.mul(ticketAmount); 62 | feeAmount = 0; 63 | } else { 64 | uint256 feeRate = dropBoxInfo.globalFee; 65 | address feeAddr = dropBoxInfo.feeAddr; 66 | if(feeAddr != address(0)) 67 | feeRate = IFee(feeAddr).getUserFee(user, ticketAmount); 68 | 69 | uint256 price = originalPrice; 70 | address priceAddr = dropBoxInfo.priceAddr; 71 | if(priceAddr != address(0)) 72 | price = IPrice(priceAddr).getUserPrice(user, originalPrice, ticketAmount); 73 | 74 | payAmount = price.mul(ticketAmount); 75 | feeAmount = DecimalMath.mulFloor(payAmount, feeRate); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /contracts/DODOFee/PoolHeartBeat.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2022 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 11 | 12 | 13 | contract PoolHeartBeat is InitializableOwnable { 14 | 15 | struct heartBeat { 16 | uint256 lastHeartBeat; 17 | uint256 maxInterval; 18 | } 19 | 20 | mapping(address => address) public poolHeartBeatManager; // pool => heartbeat manager 21 | mapping(address => heartBeat) public beats; // heartbeat manager => heartbeat 22 | 23 | function isPoolHeartBeatLive(address pool) external view returns(bool) { 24 | if(poolHeartBeatManager[pool]==address(0)) { 25 | return true; 26 | } 27 | heartBeat memory beat = beats[poolHeartBeatManager[pool]]; 28 | return block.timestamp - beat.lastHeartBeat < beat.maxInterval; 29 | } 30 | 31 | function triggerBeat() external { 32 | heartBeat storage beat = beats[msg.sender]; 33 | beat.lastHeartBeat = block.timestamp; 34 | } 35 | 36 | function setBeatInterval(uint256 interval) external { 37 | heartBeat storage beat = beats[msg.sender]; 38 | beat.maxInterval = interval; 39 | } 40 | 41 | function bindPoolHeartBeat(address[] memory pools, address manager) external onlyOwner { 42 | for(uint256 i=0; i uint256) public userQuota; 19 | 20 | event SetQuota(address user, uint256 amount); 21 | 22 | function setUserQuota(address[] memory users, uint256[] memory quotas) external onlyOwner { 23 | require(users.length == quotas.length, "PARAMS_LENGTH_NOT_MATCH"); 24 | for(uint256 i = 0; i< users.length; i++) { 25 | require(users[i] != address(0), "USER_INVALID"); 26 | userQuota[users[i]] = quotas[i]; 27 | emit SetQuota(users[i],quotas[i]); 28 | } 29 | } 30 | 31 | function getUserQuota(address user) override external view returns (int) { 32 | return int(userQuota[user]); 33 | } 34 | } -------------------------------------------------------------------------------- /contracts/DODOFee/UserQuotaFactory.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2022 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {ICloneFactory} from "../lib/CloneFactory.sol"; 12 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 13 | 14 | 15 | interface IQuota { 16 | function initOwner(address newOwner) external; 17 | function getUserQuota(address user) external view returns (int); 18 | } 19 | 20 | 21 | /** 22 | * @title DODO UserQuotaFactory 23 | * @author DODO Breeder 24 | * 25 | */ 26 | contract UserQuotaFactory is InitializableOwnable{ 27 | // ============ Templates ============ 28 | 29 | address public immutable _CLONE_FACTORY_; 30 | address public immutable _USER_QUOTA_TEMPLATE_; 31 | 32 | // ============ Events ============ 33 | 34 | event NewQuota(address quota); 35 | 36 | // ============ Functions ============ 37 | 38 | constructor( 39 | address cloneFactory, 40 | address quotaTemplate 41 | ) public { 42 | _CLONE_FACTORY_ = cloneFactory; 43 | _USER_QUOTA_TEMPLATE_ = quotaTemplate; 44 | } 45 | 46 | function createQuota( 47 | address quotaOwner 48 | ) external onlyOwner returns(address newQuota){ 49 | newQuota = ICloneFactory(_CLONE_FACTORY_).clone(_USER_QUOTA_TEMPLATE_); 50 | IQuota(newQuota).initOwner(quotaOwner); 51 | emit NewQuota(newQuota); 52 | } 53 | } -------------------------------------------------------------------------------- /contracts/DODOFee/vDODOQuota.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 11 | import {IERC20} from "../intf/IERC20.sol"; 12 | import {SafeMath} from "../lib/SafeMath.sol"; 13 | 14 | 15 | contract vDODOQuota is InitializableOwnable { 16 | using SafeMath for uint256; 17 | address public immutable _VDODO_TOKEN_; 18 | uint256 public _QUOTA_RATIO_; 19 | uint256 public _BASE_QUOTA_; 20 | 21 | constructor(address vdodoToken) public { 22 | _VDODO_TOKEN_ = vdodoToken; 23 | } 24 | 25 | function setParams(uint256 quotaRatio, uint256 baseQuota) external onlyOwner { 26 | _QUOTA_RATIO_ = quotaRatio; 27 | _BASE_QUOTA_ = baseQuota; 28 | } 29 | 30 | function getUserQuota(address user) external view returns (int) { 31 | uint256 vDODOAmount = IERC20(_VDODO_TOKEN_).balanceOf(user); 32 | return int(vDODOAmount.div(_QUOTA_RATIO_).add(_BASE_QUOTA_)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/impl/DPP.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {IFeeRateModel} from "../../lib/FeeRateModel.sol"; 12 | import {IERC20} from "../../intf/IERC20.sol"; 13 | import {DPPTrader} from "./DPPTrader.sol"; 14 | 15 | /** 16 | * @title DODO PrivatePool 17 | * @author DODO Breeder 18 | * 19 | * @notice DODOPrivatePool initialization 20 | */ 21 | contract DPP is DPPTrader { 22 | function init( 23 | address owner, 24 | address maintainer, 25 | address baseTokenAddress, 26 | address quoteTokenAddress, 27 | uint256 lpFeeRate, 28 | address mtFeeRateModel, 29 | uint256 k, 30 | uint256 i, 31 | bool isOpenTWAP 32 | ) external { 33 | initOwner(owner); 34 | 35 | require(baseTokenAddress != quoteTokenAddress, "BASE_QUOTE_CAN_NOT_BE_SAME"); 36 | _BASE_TOKEN_ = IERC20(baseTokenAddress); 37 | _QUOTE_TOKEN_ = IERC20(quoteTokenAddress); 38 | 39 | _MAINTAINER_ = maintainer; 40 | _MT_FEE_RATE_MODEL_ = IFeeRateModel(mtFeeRateModel); 41 | 42 | require(lpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE"); 43 | require(k <= 1e18, "K_OUT_OF_RANGE"); 44 | require(i > 0 && i <= 1e36, "I_OUT_OF_RANGE"); 45 | _LP_FEE_RATE_ = uint64(lpFeeRate); 46 | _K_ = uint64(k); 47 | _I_ = uint128(i); 48 | 49 | _IS_OPEN_TWAP_ = isOpenTWAP; 50 | if(isOpenTWAP) _BLOCK_TIMESTAMP_LAST_ = uint32(block.timestamp % 2**32); 51 | 52 | _resetTargetAndReserve(); 53 | } 54 | 55 | // ============ Version Control ============ 56 | 57 | function version() virtual external pure returns (string memory) { 58 | return "DPP 1.0.0"; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/impl/DPPAdmin.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {IDPP} from "../intf/IDPP.sol"; 12 | import {IDODOApproveProxy} from "../../SmartRoute/DODOApproveProxy.sol"; 13 | import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; 14 | 15 | /** 16 | * @title DPPAdmin 17 | * @author DODO Breeder 18 | * 19 | * @notice Admin of DODOPrivatePool 20 | */ 21 | contract DPPAdmin is InitializableOwnable { 22 | address public _DPP_; 23 | address public _OPERATOR_; 24 | address public _DODO_APPROVE_PROXY_; 25 | uint256 public _FREEZE_TIMESTAMP_; 26 | 27 | 28 | modifier notFreezed() { 29 | require(block.timestamp >= _FREEZE_TIMESTAMP_, "ADMIN_FREEZED"); 30 | _; 31 | } 32 | 33 | function init( 34 | address owner, 35 | address dpp, 36 | address operator, 37 | address dodoApproveProxy 38 | ) external { 39 | initOwner(owner); 40 | _DPP_ = dpp; 41 | _OPERATOR_ = operator; 42 | _DODO_APPROVE_PROXY_ = dodoApproveProxy; 43 | } 44 | 45 | function sync() external notFreezed onlyOwner { 46 | IDPP(_DPP_).ratioSync(); 47 | } 48 | 49 | function setFreezeTimestamp(uint256 timestamp) external notFreezed onlyOwner { 50 | _FREEZE_TIMESTAMP_ = timestamp; 51 | } 52 | 53 | function setOperator(address newOperator) external notFreezed onlyOwner { 54 | _OPERATOR_ = newOperator; 55 | } 56 | 57 | function retrieve( 58 | address payable to, 59 | address token, 60 | uint256 amount 61 | ) external notFreezed onlyOwner { 62 | IDPP(_DPP_).retrieve(to, token, amount); 63 | } 64 | 65 | function reset( 66 | address operator, 67 | uint256 newLpFeeRate, 68 | uint256 newI, 69 | uint256 newK, 70 | uint256 baseOutAmount, 71 | uint256 quoteOutAmount, 72 | uint256 minBaseReserve, 73 | uint256 minQuoteReserve 74 | ) external notFreezed returns (bool) { 75 | require( 76 | msg.sender == _OWNER_ || 77 | (IDODOApproveProxy(_DODO_APPROVE_PROXY_).isAllowedProxy(msg.sender) && 78 | operator == _OPERATOR_), 79 | "RESET FORBIDDEN!" 80 | ); 81 | return 82 | IDPP(_DPP_).reset( 83 | msg.sender, 84 | newLpFeeRate, 85 | newI, 86 | newK, 87 | baseOutAmount, 88 | quoteOutAmount, 89 | minBaseReserve, 90 | minQuoteReserve 91 | ); 92 | } 93 | 94 | // ============ Admin Version Control ============ 95 | 96 | function version() external pure returns (string memory) { 97 | return "DPPAdmin 1.0.0"; // 1.0.0 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/impl/DPPAdvanced/DPPAdvanced.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {DPP} from "../DPP.sol"; 12 | 13 | /** 14 | * @title DODO PrivatePool 15 | * @author DODO Breeder 16 | * 17 | * @notice Advanced DODOPrivatePool 18 | */ 19 | contract DPPAdvanced is DPP { 20 | 21 | function tuneParameters( 22 | uint256 newLpFeeRate, 23 | uint256 newI, 24 | uint256 newK, 25 | uint256 minBaseReserve, 26 | uint256 minQuoteReserve 27 | ) public preventReentrant onlyOwner returns (bool) { 28 | require( 29 | _BASE_RESERVE_ >= minBaseReserve && _QUOTE_RESERVE_ >= minQuoteReserve, 30 | "RESERVE_AMOUNT_IS_NOT_ENOUGH" 31 | ); 32 | require(newLpFeeRate <= 1e18, "LP_FEE_RATE_OUT_OF_RANGE"); 33 | require(newK <= 1e18, "K_OUT_OF_RANGE"); 34 | require(newI > 0 && newI <= 1e36, "I_OUT_OF_RANGE"); 35 | _LP_FEE_RATE_ = uint64(newLpFeeRate); 36 | _K_ = uint64(newK); 37 | _I_ = uint128(newI); 38 | emit LpFeeRateChange(newLpFeeRate); 39 | return true; 40 | } 41 | 42 | 43 | function tunePrice( 44 | uint256 newI, 45 | uint256 minBaseReserve, 46 | uint256 minQuoteReserve 47 | ) public preventReentrant onlyOwner returns (bool) { 48 | require( 49 | _BASE_RESERVE_ >= minBaseReserve && _QUOTE_RESERVE_ >= minQuoteReserve, 50 | "RESERVE_AMOUNT_IS_NOT_ENOUGH" 51 | ); 52 | require(newI > 0 && newI <= 1e36, "I_OUT_OF_RANGE"); 53 | _I_ = uint128(newI); 54 | return true; 55 | } 56 | 57 | 58 | // ============ Version Control ============ 59 | 60 | function version() override external pure returns (string memory) { 61 | return "DPP Advanced 1.0.0"; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/impl/DPPOracle/DPPStorage.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {InitializableOwnable} from "../../../lib/InitializableOwnable.sol"; 12 | import {SafeMath} from "../../../lib/SafeMath.sol"; 13 | import {DecimalMath} from "../../../lib/DecimalMath.sol"; 14 | import {ReentrancyGuard} from "../../../lib/ReentrancyGuard.sol"; 15 | import {IFeeRateModel} from "../../../lib/FeeRateModel.sol"; 16 | import {IERC20} from "../../../intf/IERC20.sol"; 17 | import {PMMPricing} from "../../../lib/PMMPricing.sol"; 18 | import {IOracle} from "../../intf/IOracle.sol"; 19 | 20 | contract DPPStorage is InitializableOwnable, ReentrancyGuard { 21 | using SafeMath for uint256; 22 | 23 | bool public _IS_OPEN_TWAP_ = false; 24 | bool public _IS_ORACLE_ENABLED = true; 25 | 26 | // ============ Core Address ============ 27 | 28 | address public _MAINTAINER_; 29 | 30 | IERC20 public _BASE_TOKEN_; 31 | IERC20 public _QUOTE_TOKEN_; 32 | 33 | uint112 public _BASE_RESERVE_; 34 | uint112 public _QUOTE_RESERVE_; 35 | uint32 public _BLOCK_TIMESTAMP_LAST_; 36 | 37 | uint112 public _BASE_TARGET_; 38 | uint112 public _QUOTE_TARGET_; 39 | uint32 public _RState_; 40 | 41 | uint256 public _BASE_PRICE_CUMULATIVE_LAST_; 42 | 43 | // ============ Variables for Pricing ============ 44 | 45 | IFeeRateModel public _MT_FEE_RATE_MODEL_; 46 | 47 | uint64 public _LP_FEE_RATE_; 48 | uint64 public _K_; 49 | uint128 public _I_; 50 | address public _O_; 51 | 52 | // ============ Helper Functions ============ 53 | 54 | function getPMMState() public view returns (PMMPricing.PMMState memory state) { 55 | if (_IS_ORACLE_ENABLED) { 56 | state.i = IOracle(_O_).prices(address(_BASE_TOKEN_)); 57 | } else { 58 | state.i = _I_; 59 | } 60 | state.K = _K_; 61 | state.B = _BASE_RESERVE_; 62 | state.Q = _QUOTE_RESERVE_; 63 | state.B0 = _BASE_TARGET_; 64 | state.Q0 = _QUOTE_TARGET_; 65 | state.R = PMMPricing.RState(_RState_); 66 | PMMPricing.adjustedTarget(state); 67 | } 68 | 69 | function getPMMStateForCall() 70 | external 71 | view 72 | returns ( 73 | uint256 i, 74 | uint256 K, 75 | uint256 B, 76 | uint256 Q, 77 | uint256 B0, 78 | uint256 Q0, 79 | uint256 R 80 | ) 81 | { 82 | PMMPricing.PMMState memory state = getPMMState(); 83 | i = state.i; 84 | K = state.K; 85 | B = state.B; 86 | Q = state.Q; 87 | B0 = state.B0; 88 | Q0 = state.Q0; 89 | R = uint256(state.R); 90 | } 91 | 92 | function getMidPrice() public view returns (uint256 midPrice) { 93 | return PMMPricing.getMidPrice(getPMMState()); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/impl/DPPOracle/WooOracleAdapter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {IOracle} from "../../intf/IOracle.sol"; 12 | 13 | interface IWooracle { 14 | function timestamp() external view returns (uint256); 15 | function isFeasible(address base) external view returns (bool); 16 | function getPrice(address base) external view returns (uint256); 17 | function price(address base) external view returns (uint256 priceNow, bool feasible); 18 | } 19 | 20 | contract WooOracleAdapter is IOracle { 21 | IWooracle public oracle; 22 | 23 | constructor(address oracleAddress) public { 24 | oracle = IWooracle(oracleAddress); 25 | } 26 | 27 | function getPrice(address base) external override view returns (uint256 latestPrice,bool isValid,bool isStale,uint256 timestamp) { 28 | latestPrice = oracle.getPrice(base); 29 | isValid = oracle.isFeasible(base); 30 | isStale = !isValid; 31 | timestamp = oracle.timestamp(); 32 | return (latestPrice, isValid, isStale, timestamp); 33 | } 34 | 35 | function prices(address base) external override view returns (uint256) { 36 | require(oracle.isFeasible(base), "ORACLE NOT FEASIBLE"); 37 | return oracle.getPrice(base); 38 | } 39 | 40 | function isFeasible(address base) external override view returns (bool) { 41 | return oracle.isFeasible(base); 42 | } 43 | } -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/impl/DPPStorage.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; 12 | import {SafeMath} from "../../lib/SafeMath.sol"; 13 | import {DecimalMath} from "../../lib/DecimalMath.sol"; 14 | import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; 15 | import {IFeeRateModel} from "../../lib/FeeRateModel.sol"; 16 | import {IERC20} from "../../intf/IERC20.sol"; 17 | import {PMMPricing} from "../../lib/PMMPricing.sol"; 18 | 19 | contract DPPStorage is InitializableOwnable, ReentrancyGuard { 20 | using SafeMath for uint256; 21 | 22 | bool public _IS_OPEN_TWAP_ = false; 23 | 24 | // ============ Core Address ============ 25 | 26 | address public _MAINTAINER_; 27 | 28 | IERC20 public _BASE_TOKEN_; 29 | IERC20 public _QUOTE_TOKEN_; 30 | 31 | uint112 public _BASE_RESERVE_; 32 | uint112 public _QUOTE_RESERVE_; 33 | uint32 public _BLOCK_TIMESTAMP_LAST_; 34 | 35 | uint112 public _BASE_TARGET_; 36 | uint112 public _QUOTE_TARGET_; 37 | uint32 public _RState_; 38 | 39 | uint256 public _BASE_PRICE_CUMULATIVE_LAST_; 40 | 41 | // ============ Variables for Pricing ============ 42 | 43 | IFeeRateModel public _MT_FEE_RATE_MODEL_; 44 | 45 | uint64 public _LP_FEE_RATE_; 46 | uint64 public _K_; 47 | uint128 public _I_; 48 | 49 | // ============ Helper Functions ============ 50 | 51 | function getPMMState() public view returns (PMMPricing.PMMState memory state) { 52 | state.i = _I_; 53 | state.K = _K_; 54 | state.B = _BASE_RESERVE_; 55 | state.Q = _QUOTE_RESERVE_; 56 | state.B0 = _BASE_TARGET_; 57 | state.Q0 = _QUOTE_TARGET_; 58 | state.R = PMMPricing.RState(_RState_); 59 | PMMPricing.adjustedTarget(state); 60 | } 61 | 62 | function getPMMStateForCall() 63 | external 64 | view 65 | returns ( 66 | uint256 i, 67 | uint256 K, 68 | uint256 B, 69 | uint256 Q, 70 | uint256 B0, 71 | uint256 Q0, 72 | uint256 R 73 | ) 74 | { 75 | PMMPricing.PMMState memory state = getPMMState(); 76 | i = state.i; 77 | K = state.K; 78 | B = state.B; 79 | Q = state.Q; 80 | B0 = state.B0; 81 | Q0 = state.Q0; 82 | R = uint256(state.R); 83 | } 84 | 85 | function getMidPrice() public view returns (uint256 midPrice) { 86 | return PMMPricing.getMidPrice(getPMMState()); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/intf/IDPP.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDPP { 12 | function init( 13 | address owner, 14 | address maintainer, 15 | address baseTokenAddress, 16 | address quoteTokenAddress, 17 | uint256 lpFeeRate, 18 | address mtFeeRateModel, 19 | uint256 k, 20 | uint256 i, 21 | bool isOpenTWAP 22 | ) external; 23 | 24 | function _MT_FEE_RATE_MODEL_() external returns (address); 25 | 26 | //=========== admin ========== 27 | function ratioSync() external; 28 | 29 | function retrieve( 30 | address payable to, 31 | address token, 32 | uint256 amount 33 | ) external; 34 | 35 | function reset( 36 | address assetTo, 37 | uint256 newLpFeeRate, 38 | uint256 newI, 39 | uint256 newK, 40 | uint256 baseOutAmount, 41 | uint256 quoteOutAmount, 42 | uint256 minBaseReserve, 43 | uint256 minQuoteReserve 44 | ) external returns (bool); 45 | 46 | //========== advanced ======== 47 | function tuneParameters( 48 | uint256 newLpFeeRate, 49 | uint256 newI, 50 | uint256 newK, 51 | uint256 minBaseReserve, 52 | uint256 minQuoteReserve 53 | ) external returns (bool); 54 | 55 | function tunePrice( 56 | uint256 newI, 57 | uint256 minBaseReserve, 58 | uint256 minQuoteReserve 59 | ) external returns (bool); 60 | } 61 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/intf/IDPPAdmin.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDPPAdmin { 12 | function init(address owner, address dpp,address operator, address dodoSmartApprove) external; 13 | } -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/intf/IDPPOracle.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDPPOracle { 12 | function init( 13 | address owner, 14 | address maintainer, 15 | address baseTokenAddress, 16 | address quoteTokenAddress, 17 | uint256 lpFeeRate, 18 | address mtFeeRateModel, 19 | uint256 k, 20 | uint256 i, 21 | address o, 22 | bool isOpenTWAP, 23 | bool isOracleEnabled 24 | ) external; 25 | 26 | function _MT_FEE_RATE_MODEL_() external returns (address); 27 | 28 | //=========== admin ========== 29 | function ratioSync() external; 30 | 31 | function retrieve( 32 | address payable to, 33 | address token, 34 | uint256 amount 35 | ) external; 36 | 37 | function reset( 38 | address assetTo, 39 | uint256 newLpFeeRate, 40 | uint256 newI, 41 | uint256 newK, 42 | uint256 baseOutAmount, 43 | uint256 quoteOutAmount, 44 | uint256 minBaseReserve, 45 | uint256 minQuoteReserve 46 | ) external returns (bool); 47 | 48 | 49 | function tuneParameters( 50 | uint256 newLpFeeRate, 51 | uint256 newI, 52 | uint256 newK, 53 | uint256 minBaseReserve, 54 | uint256 minQuoteReserve 55 | ) external returns (bool); 56 | 57 | function tunePrice( 58 | uint256 newI, 59 | uint256 minBaseReserve, 60 | uint256 minQuoteReserve 61 | ) external returns (bool); 62 | 63 | function changeOracle(address newOracle) external; 64 | 65 | function enableOracle() external; 66 | 67 | function disableOracle(uint256 newI) external; 68 | } 69 | -------------------------------------------------------------------------------- /contracts/DODOPrivatePool/intf/IOracle.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IOracle { 11 | function getPrice(address base) external view returns (uint256 latestPrice,bool isValid,bool isStale,uint256 timestamp); 12 | 13 | function prices(address base) external view returns (uint256); 14 | 15 | function isFeasible(address base) external view returns (bool); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/DODOStablePool/intf/IDSP.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDSP { 12 | function init( 13 | address maintainer, 14 | address baseTokenAddress, 15 | address quoteTokenAddress, 16 | uint256 lpFeeRate, 17 | address mtFeeRateModel, 18 | uint256 i, 19 | uint256 k, 20 | bool isOpenTWAP 21 | ) external; 22 | 23 | function _BASE_TOKEN_() external view returns (address); 24 | 25 | function _QUOTE_TOKEN_() external view returns (address); 26 | 27 | function _I_() external view returns (uint256); 28 | 29 | function _MT_FEE_RATE_MODEL_() external view returns (address); 30 | 31 | function getVaultReserve() external view returns (uint256 baseReserve, uint256 quoteReserve); 32 | 33 | function sellBase(address to) external returns (uint256); 34 | 35 | function sellQuote(address to) external returns (uint256); 36 | 37 | function buyShares(address to) external returns (uint256,uint256,uint256); 38 | } 39 | -------------------------------------------------------------------------------- /contracts/DODOStarter/impl/Storage.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2022 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; 12 | import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; 13 | import {SafeMath} from "../../lib/SafeMath.sol"; 14 | import {IERC20} from "../../intf/IERC20.sol"; 15 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 16 | 17 | contract Storage is InitializableOwnable, ReentrancyGuard { 18 | using SafeMath for uint256; 19 | using SafeERC20 for IERC20; 20 | 21 | bool public _FORCE_STOP_ = false; 22 | address public _QUOTA_; 23 | 24 | // ============ Events ============ 25 | event ForceStop(); 26 | 27 | // ============ Token & Balance ============ 28 | 29 | uint256 public _FUNDS_RESERVE_; 30 | address public _FUNDS_ADDRESS_; 31 | address public _TOKEN_ADDRESS_; 32 | uint256 public _TOTAL_TOKEN_AMOUNT_; 33 | 34 | uint256 public _TOTAL_RAISED_FUNDS_; 35 | 36 | // ============ Vesting Timeline ============ 37 | 38 | uint256 public _TOKEN_VESTING_START_; 39 | uint256 public _TOKEN_VESTING_DURATION_; 40 | uint256 public _TOKEN_CLIFF_RATE_; 41 | mapping(address => uint256) _CLAIMED_TOKEN_; 42 | 43 | uint256 public _FUNDS_VESTING_START_; 44 | uint256 public _FUNDS_VESTING_DURATION_; 45 | uint256 public _FUNDS_CLIFF_RATE_; 46 | uint256 _CLAIMED_FUNDS_; 47 | 48 | uint256 public _LP_VESTING_START_; 49 | uint256 public _LP_VESTING_DURATION_; 50 | uint256 public _LP_CLIFF_RATE_; 51 | uint256 _CLAIMED_LP_; 52 | 53 | // ============ Liquidity Params ============ 54 | 55 | address public _POOL_FACTORY_; 56 | address public _INITIAL_POOL_; 57 | uint256 public _INITIAL_FUND_LIQUIDITY_; 58 | uint256 public _TOTAL_LP_; 59 | 60 | // ============ Timeline ============== 61 | uint256 public _START_TIME_; 62 | uint256 public _BIDDING_DURATION_; 63 | 64 | 65 | // ============ Events ============ 66 | event SetQuota(address quota); 67 | 68 | // ============ Modifiers ============ 69 | modifier isNotForceStop() { 70 | require(!_FORCE_STOP_, "FORCE_STOP"); 71 | _; 72 | } 73 | 74 | // ============ Ownable Control ============ 75 | function forceStop() external onlyOwner { 76 | require(block.timestamp < _START_TIME_, "FUNDING_ALREADY_STARTED"); 77 | _FORCE_STOP_ = true; 78 | _TOTAL_TOKEN_AMOUNT_ = 0; 79 | uint256 tokenAmount = IERC20(_TOKEN_ADDRESS_).balanceOf(address(this)); 80 | IERC20(_TOKEN_ADDRESS_).safeTransfer(_OWNER_, tokenAmount); 81 | 82 | emit ForceStop(); 83 | } 84 | 85 | function setQuota(address quota) external onlyOwner { 86 | _QUOTA_ = quota; 87 | emit SetQuota(quota); 88 | } 89 | } -------------------------------------------------------------------------------- /contracts/DODOStarter/intf/IDODOStarter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2022 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDODOStarter { 12 | //Instant mode 13 | function init( 14 | address[] calldata addressList, 15 | uint256[] calldata timeLine, 16 | uint256[] calldata valueList 17 | ) external; 18 | 19 | //Fair mode 20 | function init( 21 | address[] calldata addressList, 22 | uint256[] calldata timeLine, 23 | uint256[] calldata valueList, 24 | bool isOverCapStop 25 | ) external; 26 | 27 | function _FUNDS_ADDRESS_() external view returns (address); 28 | 29 | function depositFunds(address to) external returns (uint256); 30 | } 31 | -------------------------------------------------------------------------------- /contracts/DODOToken/DODOCirculationHelper.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | pragma solidity 0.6.9; 8 | pragma experimental ABIEncoderV2; 9 | 10 | import {IERC20} from "../intf/IERC20.sol"; 11 | import {SafeMath} from "../lib/SafeMath.sol"; 12 | import {DecimalMath} from "../lib/DecimalMath.sol"; 13 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 14 | 15 | 16 | contract DODOCirculationHelper is InitializableOwnable { 17 | using SafeMath for uint256; 18 | 19 | // ============ Storage ============ 20 | 21 | address immutable _VDODO_TOKEN_; 22 | address immutable _DODO_TOKEN_; 23 | address[] _LOCKED_CONTRACT_ADDRESS_; 24 | 25 | uint256 public _MIN_PENALTY_RATIO_ = 5 * 10**16; // 5% 26 | uint256 public _MAX_PENALTY_RATIO_ = 15 * 10**16; // 15% 27 | 28 | constructor(address vDodoToken,address dodoToken) public { 29 | _VDODO_TOKEN_ = vDodoToken; 30 | _DODO_TOKEN_ = dodoToken; 31 | } 32 | 33 | function addLockedContractAddress(address lockedContract) external onlyOwner { 34 | require(lockedContract != address(0)); 35 | _LOCKED_CONTRACT_ADDRESS_.push(lockedContract); 36 | } 37 | 38 | function removeLockedContractAddress(address lockedContract) external onlyOwner { 39 | require(lockedContract != address(0)); 40 | address[] memory lockedContractAddress = _LOCKED_CONTRACT_ADDRESS_; 41 | for (uint256 i = 0; i < lockedContractAddress.length; i++) { 42 | if (lockedContractAddress[i] == lockedContract) { 43 | lockedContractAddress[i] = lockedContractAddress[lockedContractAddress.length - 1]; 44 | break; 45 | } 46 | } 47 | _LOCKED_CONTRACT_ADDRESS_ = lockedContractAddress; 48 | _LOCKED_CONTRACT_ADDRESS_.pop(); 49 | } 50 | 51 | function getCirculation() public view returns (uint256 circulation) { 52 | circulation = 10**9 * 10**18; 53 | for (uint256 i = 0; i < _LOCKED_CONTRACT_ADDRESS_.length; i++) { 54 | circulation -= IERC20(_DODO_TOKEN_).balanceOf(_LOCKED_CONTRACT_ADDRESS_[i]); 55 | } 56 | } 57 | 58 | function getDodoWithdrawFeeRatio() external view returns (uint256 ratio) { 59 | uint256 dodoCirculationAmout = getCirculation(); 60 | uint256 x = 61 | DecimalMath.divCeil( 62 | IERC20(_VDODO_TOKEN_).totalSupply() * 100, 63 | dodoCirculationAmout 64 | ); 65 | 66 | ratio = geRatioValue(x); 67 | } 68 | 69 | function geRatioValue(uint256 input) public view returns (uint256) { 70 | 71 | // y = 15% (x < 0.1) 72 | // y = 5% (x > 0.5) 73 | // y = 0.175 - 0.25 * x 74 | 75 | if (input < 10**17) { 76 | return _MAX_PENALTY_RATIO_; 77 | } else if (input > 5 * 10**17) { 78 | return _MIN_PENALTY_RATIO_; 79 | } else { 80 | return 175 * 10**15 - DecimalMath.mulFloor(input, 25 * 10**16); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /contracts/DODOToken/DODOMigrationBSC.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | pragma solidity 0.6.9; 8 | pragma experimental ABIEncoderV2; 9 | 10 | import {IERC20} from "../intf/IERC20.sol"; 11 | import {SafeMath} from "../lib/SafeMath.sol"; 12 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 13 | import {IDODOApproveProxy} from "../SmartRoute/DODOApproveProxy.sol"; 14 | 15 | /** 16 | * @title DODOMigration between Ethereum and BSC 17 | * @author DODO Breeder 18 | */ 19 | contract DODOMigrationBSC is InitializableOwnable { 20 | using SafeMath for uint256; 21 | 22 | // ============ Storage ============ 23 | 24 | address public immutable _ETH_DODO_TOKEN_; 25 | address public immutable _DODO_APPROVE_PROXY_; 26 | mapping(address => uint256) public balances; 27 | 28 | constructor(address ethDodoToken, address dodoApproveProxy) public { 29 | _ETH_DODO_TOKEN_ = ethDodoToken; 30 | _DODO_APPROVE_PROXY_ = dodoApproveProxy; 31 | } 32 | 33 | // ============ Events ============ 34 | 35 | event Lock(address indexed sender, address indexed mintToBscAccount, uint256 amount); 36 | event Unlock(address indexed to, uint256 amount); 37 | 38 | // ============ Functions ============ 39 | 40 | function lock(uint256 amount, address mintToBscAccount) external { 41 | IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens( 42 | _ETH_DODO_TOKEN_, 43 | msg.sender, 44 | address(this), 45 | amount 46 | ); 47 | balances[msg.sender] = balances[msg.sender].add(amount); 48 | emit Lock(msg.sender, mintToBscAccount, amount); 49 | } 50 | 51 | function unlock(address unlockTo, uint256 amount) external onlyOwner { 52 | require(balances[unlockTo] >= amount); 53 | balances[unlockTo] = balances[unlockTo].sub(amount); 54 | IERC20(_ETH_DODO_TOKEN_).transfer(unlockTo, amount); 55 | emit Unlock(unlockTo, amount); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /contracts/DODOToken/DODOMineV2/ERC20Mine.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | pragma solidity 0.6.9; 8 | pragma experimental ABIEncoderV2; 9 | 10 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 11 | import {IERC20} from "../../intf/IERC20.sol"; 12 | import {SafeMath} from "../../lib/SafeMath.sol"; 13 | import {BaseMine} from "./BaseMine.sol"; 14 | 15 | contract ERC20Mine is BaseMine { 16 | using SafeERC20 for IERC20; 17 | using SafeMath for uint256; 18 | 19 | // ============ Storage ============ 20 | 21 | address public _TOKEN_; 22 | 23 | function init(address owner, address token) external { 24 | super.initOwner(owner); 25 | _TOKEN_ = token; 26 | } 27 | 28 | // ============ Event ============ 29 | 30 | event Deposit(address indexed user, uint256 amount); 31 | event Withdraw(address indexed user, uint256 amount); 32 | 33 | // ============ Deposit && Withdraw && Exit ============ 34 | 35 | function deposit(uint256 amount) external { 36 | require(amount > 0, "DODOMineV2: CANNOT_DEPOSIT_ZERO"); 37 | 38 | _updateAllReward(msg.sender); 39 | 40 | uint256 erc20OriginBalance = IERC20(_TOKEN_).balanceOf(address(this)); 41 | IERC20(_TOKEN_).safeTransferFrom(msg.sender, address(this), amount); 42 | uint256 actualStakeAmount = IERC20(_TOKEN_).balanceOf(address(this)).sub(erc20OriginBalance); 43 | 44 | _totalSupply = _totalSupply.add(actualStakeAmount); 45 | _balances[msg.sender] = _balances[msg.sender].add(actualStakeAmount); 46 | 47 | emit Deposit(msg.sender, actualStakeAmount); 48 | } 49 | 50 | function withdraw(uint256 amount) external { 51 | require(amount > 0, "DODOMineV2: CANNOT_WITHDRAW_ZERO"); 52 | 53 | _updateAllReward(msg.sender); 54 | _totalSupply = _totalSupply.sub(amount); 55 | _balances[msg.sender] = _balances[msg.sender].sub(amount); 56 | IERC20(_TOKEN_).safeTransfer(msg.sender, amount); 57 | 58 | emit Withdraw(msg.sender, amount); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /contracts/DODOToken/DODOMineV2/RewardVault.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {Ownable} from "../../lib/Ownable.sol"; 11 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 12 | import {IERC20} from "../../intf/IERC20.sol"; 13 | 14 | 15 | interface IRewardVault { 16 | function reward(address to, uint256 amount) external; 17 | function withdrawLeftOver(address to, uint256 amount) external; 18 | } 19 | 20 | contract RewardVault is Ownable { 21 | using SafeERC20 for IERC20; 22 | 23 | address public rewardToken; 24 | 25 | constructor(address _rewardToken) public { 26 | rewardToken = _rewardToken; 27 | } 28 | 29 | function reward(address to, uint256 amount) external onlyOwner { 30 | IERC20(rewardToken).safeTransfer(to, amount); 31 | } 32 | 33 | function withdrawLeftOver(address to,uint256 amount) external onlyOwner { 34 | uint256 leftover = IERC20(rewardToken).balanceOf(address(this)); 35 | require(amount <= leftover, "VAULT_NOT_ENOUGH"); 36 | IERC20(rewardToken).safeTransfer(to, amount); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/DODOToken/DODOMineV2/vDODOMine.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 11 | import {IERC20} from "../../intf/IERC20.sol"; 12 | import {SafeMath} from "../../lib/SafeMath.sol"; 13 | import {BaseMine} from "./BaseMine.sol"; 14 | 15 | interface IVDODOToken { 16 | function availableBalanceOf(address account) external view returns (uint256); 17 | } 18 | 19 | contract vDODOMine is BaseMine { 20 | using SafeERC20 for IERC20; 21 | using SafeMath for uint256; 22 | 23 | // ============ Storage ============ 24 | address public _vDODO_TOKEN_; 25 | 26 | function init(address owner, address vDODOToken) external { 27 | super.initOwner(owner); 28 | _vDODO_TOKEN_ = vDODOToken; 29 | } 30 | 31 | // ============ Event ============= 32 | 33 | event Deposit(address indexed user, uint256 amount); 34 | event Withdraw(address indexed user, uint256 amount); 35 | event SyncBalance(); 36 | 37 | // ============ Deposit && Withdraw && Exit ============ 38 | 39 | function deposit(uint256 amount) external { 40 | require(amount > 0, "DODOMineV2: CANNOT_DEPOSIT_ZERO"); 41 | require( 42 | amount <= IVDODOToken(_vDODO_TOKEN_).availableBalanceOf(msg.sender), 43 | "DODOMineV2: vDODO_NOT_ENOUGH" 44 | ); 45 | _updateAllReward(msg.sender); 46 | _totalSupply = _totalSupply.add(amount); 47 | _balances[msg.sender] = _balances[msg.sender].add(amount); 48 | emit Deposit(msg.sender, amount); 49 | } 50 | 51 | function withdraw(uint256 amount) external { 52 | require(amount > 0, "DODOMineV2: CANNOT_WITHDRAW_ZERO"); 53 | require(amount <= _balances[msg.sender], "DODOMineV2: WITHDRAW_BALANCE_NOT_ENOUGH"); 54 | _updateAllReward(msg.sender); 55 | _totalSupply = _totalSupply.sub(amount); 56 | _balances[msg.sender] = _balances[msg.sender].sub(amount); 57 | emit Withdraw(msg.sender, amount); 58 | } 59 | 60 | function syncBalance(address[] calldata userList) external { 61 | for (uint256 i = 0; i < userList.length; ++i) { 62 | address user = userList[i]; 63 | uint256 curBalance = balanceOf(user); 64 | uint256 vDODOBalance = IERC20(_vDODO_TOKEN_).balanceOf(user); 65 | if (curBalance > vDODOBalance) { 66 | _updateAllReward(user); 67 | _totalSupply = _totalSupply.add(vDODOBalance).sub(curBalance); 68 | _balances[user] = vDODOBalance; 69 | } 70 | } 71 | emit SyncBalance(); 72 | } 73 | 74 | // ============ View ============ 75 | 76 | function getLockedvDODO(address account) external view returns (uint256) { 77 | return balanceOf(account); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /contracts/DODOToken/DODOMineV3/ERC20MineV3.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | pragma solidity 0.6.9; 8 | pragma experimental ABIEncoderV2; 9 | 10 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 11 | import {IERC20} from "../../intf/IERC20.sol"; 12 | import {SafeMath} from "../../lib/SafeMath.sol"; 13 | import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; 14 | import {BaseMine} from "./BaseMine.sol"; 15 | 16 | contract ERC20MineV3 is ReentrancyGuard, BaseMine { 17 | using SafeERC20 for IERC20; 18 | using SafeMath for uint256; 19 | 20 | // ============ Storage ============ 21 | 22 | address public _TOKEN_; 23 | 24 | function init(address owner, address token) external { 25 | super.initOwner(owner); 26 | _TOKEN_ = token; 27 | } 28 | 29 | // ============ Event ============ 30 | 31 | event Deposit(address indexed user, uint256 amount); 32 | event Withdraw(address indexed user, uint256 amount); 33 | 34 | // ============ Deposit && Withdraw && Exit ============ 35 | 36 | function deposit(uint256 amount) external preventReentrant { 37 | require(amount > 0, "DODOMineV3: CANNOT_DEPOSIT_ZERO"); 38 | 39 | _updateAllReward(msg.sender); 40 | 41 | uint256 erc20OriginBalance = IERC20(_TOKEN_).balanceOf(address(this)); 42 | IERC20(_TOKEN_).safeTransferFrom(msg.sender, address(this), amount); 43 | uint256 actualStakeAmount = IERC20(_TOKEN_).balanceOf(address(this)).sub(erc20OriginBalance); 44 | 45 | _totalSupply = _totalSupply.add(actualStakeAmount); 46 | _balances[msg.sender] = _balances[msg.sender].add(actualStakeAmount); 47 | 48 | emit Deposit(msg.sender, actualStakeAmount); 49 | } 50 | 51 | function withdraw(uint256 amount) external preventReentrant { 52 | require(amount > 0, "DODOMineV3: CANNOT_WITHDRAW_ZERO"); 53 | 54 | _updateAllReward(msg.sender); 55 | _totalSupply = _totalSupply.sub(amount); 56 | _balances[msg.sender] = _balances[msg.sender].sub(amount); 57 | IERC20(_TOKEN_).safeTransfer(msg.sender, amount); 58 | 59 | emit Withdraw(msg.sender, amount); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/DODOToken/DODOMineV3/RewardVault.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {Ownable} from "../../lib/Ownable.sol"; 11 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 12 | import {SafeMath} from "../../lib/SafeMath.sol"; 13 | import {IERC20} from "../../intf/IERC20.sol"; 14 | 15 | 16 | interface IRewardVault { 17 | function reward(address to, uint256 amount) external; 18 | function withdrawLeftOver(address to, uint256 amount) external; 19 | function syncValue() external; 20 | function _TOTAL_REWARD_() external view returns(uint256); 21 | } 22 | 23 | contract RewardVault is Ownable { 24 | using SafeERC20 for IERC20; 25 | using SafeMath for uint256; 26 | 27 | uint256 public _REWARD_RESERVE_; 28 | uint256 public _TOTAL_REWARD_; 29 | address public _REWARD_TOKEN_; 30 | 31 | // ============ Event ============= 32 | event DepositReward(uint256 totalReward, uint256 inputReward, uint256 rewardReserve); 33 | 34 | constructor(address _rewardToken) public { 35 | _REWARD_TOKEN_ = _rewardToken; 36 | } 37 | 38 | function reward(address to, uint256 amount) external onlyOwner { 39 | require(_REWARD_RESERVE_ >= amount, "VAULT_NOT_ENOUGH"); 40 | _REWARD_RESERVE_ = _REWARD_RESERVE_.sub(amount); 41 | IERC20(_REWARD_TOKEN_).safeTransfer(to, amount); 42 | } 43 | 44 | function withdrawLeftOver(address to,uint256 amount) external onlyOwner { 45 | require(_REWARD_RESERVE_ >= amount, "VAULT_NOT_ENOUGH"); 46 | _REWARD_RESERVE_ = _REWARD_RESERVE_.sub(amount); 47 | IERC20(_REWARD_TOKEN_).safeTransfer(to, amount); 48 | } 49 | 50 | function syncValue() external { 51 | uint256 rewardBalance = IERC20(_REWARD_TOKEN_).balanceOf(address(this)); 52 | uint256 rewardInput = rewardBalance.sub(_REWARD_RESERVE_); 53 | 54 | _TOTAL_REWARD_ = _TOTAL_REWARD_.add(rewardInput); 55 | _REWARD_RESERVE_ = rewardBalance; 56 | 57 | emit DepositReward(_TOTAL_REWARD_, rewardInput, _REWARD_RESERVE_); 58 | } 59 | } -------------------------------------------------------------------------------- /contracts/DODOToken/DODORecharge.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity ^0.6.9; 9 | 10 | import {SafeERC20} from "../lib/SafeERC20.sol"; 11 | import {IERC20} from "../intf/IERC20.sol"; 12 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 13 | import {IDODOApproveProxy} from "../SmartRoute/DODOApproveProxy.sol"; 14 | 15 | 16 | contract DODORecharge is InitializableOwnable { 17 | using SafeERC20 for IERC20; 18 | 19 | address public immutable _DODO_TOKEN_; 20 | address public immutable _DODO_APPROVE_PROXY_; 21 | 22 | event DeductDODO(address user,uint256 _amount); 23 | 24 | constructor(address dodoAddress, address dodoApproveProxy) public { 25 | _DODO_TOKEN_ = dodoAddress; 26 | _DODO_APPROVE_PROXY_ = dodoApproveProxy; 27 | } 28 | 29 | function deductionDODO(uint256 amount) external { 30 | IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(_DODO_TOKEN_, msg.sender, address(this), amount); 31 | emit DeductDODO(msg.sender, amount); 32 | } 33 | 34 | // ============ Owner Functions ============ 35 | function claimToken(address token) public onlyOwner { 36 | uint256 balance = IERC20(token).balanceOf(address(this)); 37 | require(balance>0,"no enough token can claim"); 38 | IERC20(token).safeTransfer(_OWNER_, balance); 39 | } 40 | } -------------------------------------------------------------------------------- /contracts/DODOToken/DODORewardVault.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {Ownable} from "../lib/Ownable.sol"; 12 | import {SafeERC20} from "../lib/SafeERC20.sol"; 13 | import {IERC20} from "../intf/IERC20.sol"; 14 | 15 | 16 | interface IDODORewardVault { 17 | function reward(address to, uint256 amount) external; 18 | } 19 | 20 | 21 | contract DODORewardVault is Ownable { 22 | using SafeERC20 for IERC20; 23 | 24 | address public dodoToken; 25 | 26 | constructor(address _dodoToken) public { 27 | dodoToken = _dodoToken; 28 | } 29 | 30 | function reward(address to, uint256 amount) external onlyOwner { 31 | IERC20(dodoToken).safeTransfer(to, amount); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/DODOToken/Governance.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | pragma solidity 0.6.9; 8 | 9 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 10 | import {SafeMath} from "../lib/SafeMath.sol"; 11 | 12 | interface IVDODOMine { 13 | function balanceOf(address account) external view returns (uint256); 14 | } 15 | 16 | contract Governance is InitializableOwnable { 17 | using SafeMath for uint256; 18 | 19 | // ============ Storage ============ 20 | address[] public _VDODO_MINE_LIST_; 21 | 22 | 23 | // ============ Event ============= 24 | event AddMineContract(address mineContract); 25 | event RemoveMineContract(address mineContract); 26 | 27 | 28 | function getLockedvDODO(address account) external view returns (uint256 lockedvDODO) { 29 | uint256 len = _VDODO_MINE_LIST_.length; 30 | for(uint i = 0; i < len; i++){ 31 | uint256 curLocked = IVDODOMine(_VDODO_MINE_LIST_[i]).balanceOf(account); 32 | lockedvDODO = lockedvDODO.add(curLocked); 33 | } 34 | } 35 | 36 | // =============== Ownable ================ 37 | 38 | function addMineContract(address[] memory mineContracts) external onlyOwner { 39 | for(uint i = 0; i < mineContracts.length; i++){ 40 | require(mineContracts[i] != address(0),"ADDRESS_INVALID"); 41 | _VDODO_MINE_LIST_.push(mineContracts[i]); 42 | emit AddMineContract(mineContracts[i]); 43 | } 44 | } 45 | 46 | function removeMineContract(address mineContract) external onlyOwner { 47 | uint256 len = _VDODO_MINE_LIST_.length; 48 | for (uint256 i = 0; i < len; i++) { 49 | if (mineContract == _VDODO_MINE_LIST_[i]) { 50 | _VDODO_MINE_LIST_[i] = _VDODO_MINE_LIST_[len - 1]; 51 | _VDODO_MINE_LIST_.pop(); 52 | emit RemoveMineContract(mineContract); 53 | break; 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /contracts/DODOVendingMachine/intf/IDVM.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDVM { 12 | function init( 13 | address maintainer, 14 | address baseTokenAddress, 15 | address quoteTokenAddress, 16 | uint256 lpFeeRate, 17 | address mtFeeRateModel, 18 | uint256 i, 19 | uint256 k, 20 | bool isOpenTWAP 21 | ) external; 22 | 23 | function _BASE_TOKEN_() external returns (address); 24 | 25 | function _QUOTE_TOKEN_() external returns (address); 26 | 27 | function _MT_FEE_RATE_MODEL_() external returns (address); 28 | 29 | function getVaultReserve() external returns (uint256 baseReserve, uint256 quoteReserve); 30 | 31 | function sellBase(address to) external returns (uint256); 32 | 33 | function sellQuote(address to) external returns (uint256); 34 | 35 | function buyShares(address to) external returns (uint256,uint256,uint256); 36 | 37 | function addressToShortString(address _addr) external pure returns (string memory); 38 | 39 | function getMidPrice() external view returns (uint256 midPrice); 40 | 41 | function sellShares( 42 | uint256 shareAmount, 43 | address to, 44 | uint256 baseMinAmount, 45 | uint256 quoteMinAmount, 46 | bytes calldata data, 47 | uint256 deadline 48 | ) external returns (uint256 baseAmount, uint256 quoteAmount); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /contracts/Factory/DODONFT.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {ERC721URIStorage} from "../external/ERC721/ERC721URIStorage.sol"; 11 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 12 | 13 | contract DODONFT is ERC721URIStorage, InitializableOwnable { 14 | 15 | uint256 public _CUR_TOKENID_; 16 | 17 | // ============ Event ============= 18 | event DODONFTMint(address creator, uint256 tokenId); 19 | event DODONFTBurn(uint256 tokenId); 20 | 21 | function init( 22 | address owner, 23 | string memory name, 24 | string memory symbol 25 | ) public { 26 | initOwner(owner); 27 | _name = name; 28 | _symbol = symbol; 29 | } 30 | 31 | function mint(string calldata uri) external { 32 | _safeMint(msg.sender, _CUR_TOKENID_); 33 | _setTokenURI(_CUR_TOKENID_, uri); 34 | emit DODONFTMint(msg.sender, _CUR_TOKENID_); 35 | _CUR_TOKENID_ = _CUR_TOKENID_ + 1; 36 | } 37 | 38 | function burn(uint256 tokenId) external onlyOwner { 39 | require(tokenId < _CUR_TOKENID_, "TOKENID_INVALID"); 40 | _burn(tokenId); 41 | emit DODONFTBurn(tokenId); 42 | } 43 | } -------------------------------------------------------------------------------- /contracts/Factory/DODONFT1155.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {ERC1155} from "../external/ERC1155/ERC1155.sol"; 11 | import {Strings} from "../external/utils/Strings.sol"; 12 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 13 | 14 | contract DODONFT1155 is ERC1155, InitializableOwnable { 15 | using Strings for uint256; 16 | 17 | uint256 public _CUR_TOKENID_; 18 | string internal _baseUri = ""; 19 | mapping (uint256 => string) private _tokenURIs; 20 | 21 | // ============ Event ============= 22 | event DODONFTMint(address creator, uint256 tokenId, uint256 amount); 23 | event DODONFTBurn(address account, uint256 tokenId, uint256 amount); 24 | 25 | 26 | function mint(string calldata uri, uint256 amount) external { 27 | _mint(msg.sender, _CUR_TOKENID_, amount, ""); 28 | _setTokenURI(_CUR_TOKENID_, uri); 29 | emit DODONFTMint(msg.sender, _CUR_TOKENID_, amount); 30 | _CUR_TOKENID_ = _CUR_TOKENID_ + 1; 31 | } 32 | 33 | function burn(address account, uint256 tokenId, uint256 amount) external onlyOwner { 34 | require(tokenId < _CUR_TOKENID_, "TOKENID_INVALID"); 35 | _burn(account, tokenId, amount); 36 | emit DODONFTBurn(account, tokenId, amount); 37 | } 38 | 39 | function uri(uint256 tokenId) public view override returns (string memory) { 40 | string memory _tokenURI = _tokenURIs[tokenId]; 41 | string memory base = _baseUri; 42 | 43 | if (bytes(base).length == 0) { 44 | return _tokenURI; 45 | } 46 | 47 | if (bytes(_tokenURI).length > 0) { 48 | return string(abi.encodePacked(base, _tokenURI)); 49 | } 50 | 51 | return super.uri(tokenId); 52 | } 53 | 54 | function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal { 55 | _tokenURIs[tokenId] = _tokenURI; 56 | } 57 | } -------------------------------------------------------------------------------- /contracts/Factory/ERC20Factory.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {ICloneFactory} from "../lib/CloneFactory.sol"; 12 | import {InitializableERC20} from "../external/ERC20/InitializableERC20.sol"; 13 | import {InitializableMintableERC20} from "../external/ERC20/InitializableMintableERC20.sol"; 14 | 15 | 16 | /** 17 | * @title DODO ERC20Factory 18 | * @author DODO Breeder 19 | * 20 | * @notice Help user to create erc20 token 21 | */ 22 | contract ERC20Factory { 23 | // ============ Templates ============ 24 | 25 | address public immutable _CLONE_FACTORY_; 26 | address public immutable _ERC20_TEMPLATE_; 27 | address public immutable _MINTABLE_ERC20_TEMPLATE_; 28 | 29 | // ============ Events ============ 30 | 31 | event NewERC20(address erc20, address creator, bool isMintable); 32 | 33 | // ============ Registry ============ 34 | // creator -> token address list 35 | mapping(address => address[]) public _USER_STD_REGISTRY_; 36 | 37 | // ============ Functions ============ 38 | 39 | constructor( 40 | address cloneFactory, 41 | address erc20Template, 42 | address mintableErc20Template 43 | ) public { 44 | _CLONE_FACTORY_ = cloneFactory; 45 | _ERC20_TEMPLATE_ = erc20Template; 46 | _MINTABLE_ERC20_TEMPLATE_ = mintableErc20Template; 47 | } 48 | 49 | function createStdERC20( 50 | uint256 totalSupply, 51 | string memory name, 52 | string memory symbol, 53 | uint8 decimals 54 | ) external returns (address newERC20) { 55 | newERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC20_TEMPLATE_); 56 | InitializableERC20(newERC20).init(msg.sender, totalSupply, name, symbol, decimals); 57 | _USER_STD_REGISTRY_[msg.sender].push(newERC20); 58 | emit NewERC20(newERC20, msg.sender, false); 59 | } 60 | 61 | function createMintableERC20( 62 | uint256 initSupply, 63 | string memory name, 64 | string memory symbol, 65 | uint8 decimals 66 | ) external returns (address newMintableERC20) { 67 | newMintableERC20 = ICloneFactory(_CLONE_FACTORY_).clone(_MINTABLE_ERC20_TEMPLATE_); 68 | InitializableMintableERC20(newMintableERC20).init( 69 | msg.sender, 70 | initSupply, 71 | name, 72 | symbol, 73 | decimals 74 | ); 75 | emit NewERC20(newMintableERC20, msg.sender, true); 76 | } 77 | 78 | 79 | function getTokenByUser(address user) 80 | external 81 | view 82 | returns (address[] memory tokens) 83 | { 84 | return _USER_STD_REGISTRY_[user]; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /contracts/Factory/NFTTokenFactory.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | pragma solidity 0.6.9; 8 | pragma experimental ABIEncoderV2; 9 | 10 | import {ICloneFactory} from "../lib/CloneFactory.sol"; 11 | import {InitializableERC721} from "../external/ERC721/InitializableERC721.sol"; 12 | import {InitializableERC1155} from "../external/ERC1155/InitializableERC1155.sol"; 13 | 14 | /** 15 | * @title DODO NFTTokenFactory 16 | * @author DODO Breeder 17 | * 18 | * @notice Help user to create erc721 && erc1155 token 19 | */ 20 | contract NFTTokenFactory { 21 | // ============ Templates ============ 22 | 23 | address public immutable _CLONE_FACTORY_; 24 | address public immutable _ERC721_TEMPLATE_; 25 | address public immutable _ERC1155_TEMPLATE_; 26 | 27 | // ============ Events ============ 28 | 29 | event NewERC721(address erc721, address creator); 30 | event NewERC1155(address erc1155, address creator); 31 | 32 | // ============ Registry ============ 33 | mapping(address => address[]) public _USER_ERC721_REGISTRY_; 34 | mapping(address => address[]) public _USER_ERC1155_REGISTRY_; 35 | 36 | // ============ Functions ============ 37 | 38 | constructor( 39 | address cloneFactory, 40 | address erc721Template, 41 | address erc1155Tempalte 42 | ) public { 43 | _CLONE_FACTORY_ = cloneFactory; 44 | _ERC721_TEMPLATE_ = erc721Template; 45 | _ERC1155_TEMPLATE_ = erc1155Tempalte; 46 | } 47 | 48 | function createERC721( 49 | string memory uri 50 | ) external returns (address newERC721) { 51 | newERC721 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC721_TEMPLATE_); 52 | InitializableERC721(newERC721).init(msg.sender, "DODONFT", "DODONFT", uri); 53 | _USER_ERC721_REGISTRY_[msg.sender].push(newERC721); 54 | emit NewERC721(newERC721, msg.sender); 55 | } 56 | 57 | function createERC1155( 58 | uint256 amount, 59 | string memory uri 60 | ) external returns (address newERC1155) { 61 | newERC1155 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC1155_TEMPLATE_); 62 | InitializableERC1155(newERC1155).init(msg.sender, amount, uri); 63 | _USER_ERC1155_REGISTRY_[msg.sender].push(newERC1155); 64 | emit NewERC1155(newERC1155, msg.sender); 65 | } 66 | 67 | 68 | function getERC721TokenByUser(address user) 69 | external 70 | view 71 | returns (address[] memory tokens) 72 | { 73 | return _USER_ERC721_REGISTRY_[user]; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /contracts/GeneralizedFragment/impl/BuyoutModel.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {InitializableOwnable} from "../../lib/InitializableOwnable.sol"; 12 | import {IERC20} from "../../intf/IERC20.sol"; 13 | import {SafeMath} from "../../lib/SafeMath.sol"; 14 | 15 | interface IBuyout { 16 | function getBuyoutQualification(address user) external view returns (bool); 17 | } 18 | 19 | contract BuyoutModel is InitializableOwnable { 20 | using SafeMath for uint256; 21 | 22 | uint256 public _MIN_FRAG_ = 100; //0.1 23 | uint256 public _MAX_FRAG_ = 1000; //1 24 | int public _BUYOUT_FEE_ = 0; 25 | 26 | struct FragInfo { 27 | uint256 minFrag; 28 | uint256 maxFrag; 29 | address buyoutAddr; 30 | bool isSet; 31 | } 32 | 33 | mapping(address => FragInfo) frags; 34 | 35 | function addFragInfo(address fragAddr, uint256 minFrag, uint256 maxFrag, address buyoutAddr) external onlyOwner { 36 | FragInfo memory fragInfo = FragInfo({ 37 | minFrag: minFrag, 38 | maxFrag: maxFrag, 39 | buyoutAddr: buyoutAddr, 40 | isSet: true 41 | }); 42 | frags[fragAddr] = fragInfo; 43 | } 44 | 45 | function setFragInfo(address fragAddr, uint256 minFrag, uint256 maxFrag, address buyoutAddr) external onlyOwner { 46 | frags[fragAddr].minFrag = minFrag; 47 | frags[fragAddr].maxFrag = maxFrag; 48 | frags[fragAddr].buyoutAddr = buyoutAddr; 49 | } 50 | 51 | function setGlobalParam(uint256 minFrag, uint256 maxFrag, uint256 buyoutFee) external onlyOwner { 52 | require(minFrag <= 1000 && maxFrag <= 1000, "PARAM_INVALID"); 53 | _MIN_FRAG_ = minFrag; 54 | _MAX_FRAG_ = maxFrag; 55 | _BUYOUT_FEE_ = int(buyoutFee); 56 | } 57 | 58 | function getBuyoutStatus(address fragAddr, address user) external view returns (int) { 59 | FragInfo memory fragInfo = frags[fragAddr]; 60 | 61 | uint256 userBalance = IERC20(fragAddr).balanceOf(user); 62 | uint256 totalSupply = IERC20(fragAddr).totalSupply(); 63 | uint256 minFrag = _MIN_FRAG_; 64 | uint256 maxFrag = _MAX_FRAG_; 65 | 66 | if(fragInfo.isSet) { 67 | address buyoutAddr = fragInfo.buyoutAddr; 68 | if(buyoutAddr != address(0)) { 69 | bool isQualified = IBuyout(buyoutAddr).getBuyoutQualification(user); 70 | if(isQualified) { 71 | return _BUYOUT_FEE_; 72 | }else { 73 | return -1; 74 | } 75 | } 76 | 77 | minFrag = fragInfo.minFrag; 78 | maxFrag = fragInfo.maxFrag; 79 | } 80 | 81 | if(userBalance >= totalSupply.mul(minFrag).div(1000) && userBalance <= totalSupply.mul(maxFrag).div(1000)) { 82 | return _BUYOUT_FEE_; 83 | }else { 84 | return -1; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /contracts/GeneralizedFragment/intf/IFragment.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | 11 | interface IFragment { 12 | 13 | function init( 14 | address dvm, 15 | address vaultPreOwner, 16 | address collateralVault, 17 | uint256 totalSupply, 18 | uint256 ownerRatio, 19 | uint256 buyoutTimestamp, 20 | address defaultMaintainer, 21 | address buyoutModel, 22 | uint256 distributionRatio, 23 | string memory fragSymbol 24 | ) external; 25 | 26 | function buyout(address newVaultOwner) external; 27 | 28 | function redeem(address to) external; 29 | 30 | function _QUOTE_() external view returns (address); 31 | 32 | function _COLLATERAL_VAULT_() external view returns (address); 33 | 34 | function _DVM_() external view returns (address); 35 | 36 | function totalSupply() external view returns (uint256); 37 | } 38 | -------------------------------------------------------------------------------- /contracts/NFTPool/intf/IController.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IController { 11 | function getMintFeeRate(address filterAdminAddr) external view returns (uint256); 12 | 13 | function getBurnFeeRate(address filterAdminAddr) external view returns (uint256); 14 | 15 | function isEmergencyWithdrawOpen(address filter) external view returns (bool); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/NFTPool/intf/IFilter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IFilter { 11 | function init( 12 | address filterAdmin, 13 | address nftCollection, 14 | bool[] memory toggles, 15 | string memory filterName, 16 | uint256[] memory numParams, 17 | uint256[] memory priceRules, 18 | uint256[] memory spreadIds 19 | ) external; 20 | 21 | function isNFTValid(address nftCollectionAddress, uint256 nftId) external view returns (bool); 22 | 23 | function _NFT_COLLECTION_() external view returns (address); 24 | 25 | function queryNFTIn(uint256 NFTInAmount) 26 | external 27 | view 28 | returns (uint256 rawReceive, uint256 received); 29 | 30 | function queryNFTTargetOut(uint256 NFTOutAmount) 31 | external 32 | view 33 | returns (uint256 rawPay, uint256 pay); 34 | 35 | function queryNFTRandomOut(uint256 NFTOutAmount) 36 | external 37 | view 38 | returns (uint256 rawPay, uint256 pay); 39 | 40 | function ERC721In(uint256[] memory tokenIds, address to) external returns (uint256 received); 41 | 42 | function ERC721TargetOut(uint256[] memory tokenIds, address to) external returns (uint256 paid); 43 | 44 | function ERC721RandomOut(uint256 amount, address to) external returns (uint256 paid); 45 | 46 | function ERC1155In(uint256[] memory tokenIds, address to) external returns (uint256 received); 47 | 48 | function ERC1155TargetOut( 49 | uint256[] memory tokenIds, 50 | uint256[] memory amounts, 51 | address to 52 | ) external returns (uint256 paid); 53 | 54 | function ERC1155RandomOut(uint256 amount, address to) external returns (uint256 paid); 55 | } 56 | -------------------------------------------------------------------------------- /contracts/NFTPool/intf/IFilterAdmin.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IFilterAdmin { 11 | function _OWNER_() external view returns (address); 12 | 13 | function _CONTROLLER_() external view returns (address); 14 | 15 | function init( 16 | address owner, 17 | uint256 initSupply, 18 | string memory name, 19 | string memory symbol, 20 | uint256 feeRate, 21 | address controller, 22 | address maintainer, 23 | address[] memory filters 24 | ) external; 25 | 26 | function mintFragTo(address to, uint256 rawAmount) external returns (uint256 received); 27 | 28 | function burnFragFrom(address from, uint256 rawAmount) external returns (uint256 paid); 29 | 30 | function queryMintFee(uint256 rawAmount) 31 | external 32 | view 33 | returns ( 34 | uint256 poolFee, 35 | uint256 mtFee, 36 | uint256 afterChargedAmount 37 | ); 38 | 39 | function queryBurnFee(uint256 rawAmount) 40 | external 41 | view 42 | returns ( 43 | uint256 poolFee, 44 | uint256 mtFee, 45 | uint256 afterChargedAmount 46 | ); 47 | } 48 | -------------------------------------------------------------------------------- /contracts/SmartRoute/DODOApprove.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {IERC20} from "../intf/IERC20.sol"; 11 | import {SafeERC20} from "../lib/SafeERC20.sol"; 12 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 13 | 14 | 15 | /** 16 | * @title DODOApprove 17 | * @author DODO Breeder 18 | * 19 | * @notice Handle authorizations in DODO platform 20 | */ 21 | contract DODOApprove is InitializableOwnable { 22 | using SafeERC20 for IERC20; 23 | 24 | // ============ Storage ============ 25 | uint256 private constant _TIMELOCK_DURATION_ = 3 days; 26 | uint256 private constant _TIMELOCK_EMERGENCY_DURATION_ = 24 hours; 27 | uint256 public _TIMELOCK_; 28 | address public _PENDING_DODO_PROXY_; 29 | address public _DODO_PROXY_; 30 | 31 | // ============ Events ============ 32 | 33 | event SetDODOProxy(address indexed oldProxy, address indexed newProxy); 34 | 35 | 36 | // ============ Modifiers ============ 37 | modifier notLocked() { 38 | require( 39 | _TIMELOCK_ <= block.timestamp, 40 | "SetProxy is timelocked" 41 | ); 42 | _; 43 | } 44 | 45 | function init(address owner, address initProxyAddress) external { 46 | initOwner(owner); 47 | _DODO_PROXY_ = initProxyAddress; 48 | } 49 | 50 | function unlockSetProxy(address newDodoProxy) public onlyOwner { 51 | if(_DODO_PROXY_ == address(0)) 52 | _TIMELOCK_ = block.timestamp + _TIMELOCK_EMERGENCY_DURATION_; 53 | else 54 | _TIMELOCK_ = block.timestamp + _TIMELOCK_DURATION_; 55 | _PENDING_DODO_PROXY_ = newDodoProxy; 56 | } 57 | 58 | 59 | function lockSetProxy() public onlyOwner { 60 | _PENDING_DODO_PROXY_ = address(0); 61 | _TIMELOCK_ = 0; 62 | } 63 | 64 | 65 | function setDODOProxy() external onlyOwner notLocked() { 66 | emit SetDODOProxy(_DODO_PROXY_, _PENDING_DODO_PROXY_); 67 | _DODO_PROXY_ = _PENDING_DODO_PROXY_; 68 | lockSetProxy(); 69 | } 70 | 71 | 72 | function claimTokens( 73 | address token, 74 | address who, 75 | address dest, 76 | uint256 amount 77 | ) external { 78 | require(msg.sender == _DODO_PROXY_, "DODOApprove:Access restricted"); 79 | if (amount > 0) { 80 | IERC20(token).safeTransferFrom(who, dest, amount); 81 | } 82 | } 83 | 84 | function getDODOProxy() public view returns (address) { 85 | return _DODO_PROXY_; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /contracts/SmartRoute/DODOApproveProxy.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {IDODOApprove} from "../intf/IDODOApprove.sol"; 12 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 13 | 14 | interface IDODOApproveProxy { 15 | function isAllowedProxy(address _proxy) external view returns (bool); 16 | function claimTokens(address token,address who,address dest,uint256 amount) external; 17 | } 18 | 19 | /** 20 | * @title DODOApproveProxy 21 | * @author DODO Breeder 22 | * 23 | * @notice Allow different version dodoproxy to claim from DODOApprove 24 | */ 25 | contract DODOApproveProxy is InitializableOwnable { 26 | 27 | // ============ Storage ============ 28 | uint256 private constant _TIMELOCK_DURATION_ = 3 days; 29 | mapping (address => bool) public _IS_ALLOWED_PROXY_; 30 | uint256 public _TIMELOCK_; 31 | address public _PENDING_ADD_DODO_PROXY_; 32 | address public immutable _DODO_APPROVE_; 33 | 34 | // ============ Modifiers ============ 35 | modifier notLocked() { 36 | require( 37 | _TIMELOCK_ <= block.timestamp, 38 | "SetProxy is timelocked" 39 | ); 40 | _; 41 | } 42 | 43 | constructor(address dodoApporve) public { 44 | _DODO_APPROVE_ = dodoApporve; 45 | } 46 | 47 | function init(address owner, address[] memory proxies) external { 48 | initOwner(owner); 49 | for(uint i = 0; i < proxies.length; i++) 50 | _IS_ALLOWED_PROXY_[proxies[i]] = true; 51 | } 52 | 53 | function unlockAddProxy(address newDodoProxy) public onlyOwner { 54 | _TIMELOCK_ = block.timestamp + _TIMELOCK_DURATION_; 55 | _PENDING_ADD_DODO_PROXY_ = newDodoProxy; 56 | } 57 | 58 | function lockAddProxy() public onlyOwner { 59 | _PENDING_ADD_DODO_PROXY_ = address(0); 60 | _TIMELOCK_ = 0; 61 | } 62 | 63 | 64 | function addDODOProxy() external onlyOwner notLocked() { 65 | _IS_ALLOWED_PROXY_[_PENDING_ADD_DODO_PROXY_] = true; 66 | lockAddProxy(); 67 | } 68 | 69 | function removeDODOProxy (address oldDodoProxy) public onlyOwner { 70 | _IS_ALLOWED_PROXY_[oldDodoProxy] = false; 71 | } 72 | 73 | function claimTokens( 74 | address token, 75 | address who, 76 | address dest, 77 | uint256 amount 78 | ) external { 79 | require(_IS_ALLOWED_PROXY_[msg.sender], "DODOApproveProxy:Access restricted"); 80 | IDODOApprove(_DODO_APPROVE_).claimTokens( 81 | token, 82 | who, 83 | dest, 84 | amount 85 | ); 86 | } 87 | 88 | function isAllowedProxy(address _proxy) external view returns (bool) { 89 | return _IS_ALLOWED_PROXY_[_proxy]; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /contracts/SmartRoute/adapter/CurveAdapter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 DODO ZOO. 3 | SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | pragma solidity 0.6.9; 7 | 8 | import {IDODOAdapter} from "../intf/IDODOAdapter.sol"; 9 | import {ICurve} from "../intf/ICurve.sol"; 10 | import {IERC20} from "../../intf/IERC20.sol"; 11 | import {SafeMath} from "../../lib/SafeMath.sol"; 12 | import {UniversalERC20} from "../lib/UniversalERC20.sol"; 13 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 14 | 15 | // for two tokens; to adapter like dodo V1 16 | contract CurveAdapter is IDODOAdapter { 17 | using SafeMath for uint; 18 | using UniversalERC20 for IERC20; 19 | 20 | function _curveSwap(address to, address pool, bytes memory moreInfo) internal { 21 | (bool noLending, address fromToken, address toToken, int128 i, int128 j) = abi.decode(moreInfo, (bool, address, address, int128, int128)); 22 | uint256 sellAmount = IERC20(fromToken).balanceOf(address(this)); 23 | 24 | // approve 25 | IERC20(fromToken).universalApproveMax(pool, sellAmount); 26 | // swap 27 | if(noLending) { 28 | ICurve(pool).exchange(i, j, sellAmount, 0); 29 | } else { 30 | ICurve(pool).exchange_underlying(i, j, sellAmount, 0); 31 | } 32 | 33 | if(to != address(this)) { 34 | SafeERC20.safeTransfer(IERC20(toToken), to, IERC20(toToken).balanceOf(address(this))); 35 | } 36 | } 37 | 38 | function sellBase(address to, address pool, bytes memory moreInfo) external override { 39 | _curveSwap(to, pool, moreInfo); 40 | } 41 | 42 | function sellQuote(address to, address pool, bytes memory moreInfo) external override { 43 | _curveSwap(to, pool, moreInfo); 44 | } 45 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/adapter/DODOV1Adapter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {IERC20} from "../../intf/IERC20.sol"; 11 | import {IDODOV1} from "../intf/IDODOV1.sol"; 12 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 13 | import {IDODOSellHelper} from "../helper/DODOSellHelper.sol"; 14 | import {UniversalERC20} from "../lib/UniversalERC20.sol"; 15 | import {SafeMath} from "../../lib/SafeMath.sol"; 16 | import {IDODOAdapter} from "../intf/IDODOAdapter.sol"; 17 | 18 | contract DODOV1Adapter is IDODOAdapter { 19 | using SafeMath for uint256; 20 | using UniversalERC20 for IERC20; 21 | 22 | address public immutable _DODO_SELL_HELPER_; 23 | 24 | constructor(address dodoSellHelper) public { 25 | _DODO_SELL_HELPER_ = dodoSellHelper; 26 | } 27 | 28 | function sellBase(address to, address pool, bytes memory) external override { 29 | address curBase = IDODOV1(pool)._BASE_TOKEN_(); 30 | uint256 curAmountIn = IERC20(curBase).tokenBalanceOf(address(this)); 31 | IERC20(curBase).universalApproveMax(pool, curAmountIn); 32 | IDODOV1(pool).sellBaseToken(curAmountIn, 0, ""); 33 | if(to != address(this)) { 34 | address curQuote = IDODOV1(pool)._QUOTE_TOKEN_(); 35 | SafeERC20.safeTransfer(IERC20(curQuote), to, IERC20(curQuote).tokenBalanceOf(address(this))); 36 | } 37 | } 38 | 39 | function sellQuote(address to, address pool, bytes memory) external override { 40 | address curQuote = IDODOV1(pool)._QUOTE_TOKEN_(); 41 | uint256 curAmountIn = IERC20(curQuote).tokenBalanceOf(address(this)); 42 | IERC20(curQuote).universalApproveMax(pool, curAmountIn); 43 | uint256 canBuyBaseAmount = IDODOSellHelper(_DODO_SELL_HELPER_).querySellQuoteToken( 44 | pool, 45 | curAmountIn 46 | ); 47 | IDODOV1(pool).buyBaseToken(canBuyBaseAmount, curAmountIn, ""); 48 | if(to != address(this)) { 49 | address curBase = IDODOV1(pool)._BASE_TOKEN_(); 50 | SafeERC20.safeTransfer(IERC20(curBase), to, canBuyBaseAmount); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/adapter/DODOV2Adapter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {IDODOV2} from "../intf/IDODOV2.sol"; 11 | import {IDODOAdapter} from "../intf/IDODOAdapter.sol"; 12 | 13 | contract DODOV2Adapter is IDODOAdapter { 14 | function sellBase(address to, address pool, bytes memory) external override { 15 | IDODOV2(pool).sellBase(to); 16 | } 17 | 18 | function sellQuote(address to, address pool, bytes memory) external override { 19 | IDODOV2(pool).sellQuote(to); 20 | } 21 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/adapter/GambitAdapter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {IGambit} from "../intf/IGambit.sol"; 11 | import {IDODOAdapter} from "../intf/IDODOAdapter.sol"; 12 | 13 | contract GambitAdapter is IDODOAdapter { 14 | 15 | function _gambitSwap(address to, address pool, bytes memory moreInfo) internal { 16 | (address tokenIn, address tokenOut) = abi.decode(moreInfo, (address, address)); 17 | 18 | IGambit(pool).swap(tokenIn, tokenOut, to); 19 | } 20 | 21 | function sellBase(address to, address pool, bytes memory moreInfo) external override { 22 | _gambitSwap(to, pool, moreInfo); 23 | } 24 | 25 | function sellQuote(address to, address pool, bytes memory moreInfo) external override { 26 | _gambitSwap(to, pool, moreInfo); 27 | } 28 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/adapter/UniAdapter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {IDODOAdapter} from "../intf/IDODOAdapter.sol"; 11 | import {IUni} from "../intf/IUni.sol"; 12 | import {IERC20} from "../../intf/IERC20.sol"; 13 | import {SafeMath} from "../../lib/SafeMath.sol"; 14 | 15 | contract UniAdapter is IDODOAdapter { 16 | using SafeMath for uint; 17 | 18 | //fromToken == token0 19 | function sellBase(address to, address pool, bytes memory data) external override { 20 | address baseToken = IUni(pool).token0(); 21 | (uint reserveIn, uint reserveOut,) = IUni(pool).getReserves(); 22 | uint receiveQuoteAmount; 23 | { 24 | (uint256 fee, uint256 denFee) = abi.decode(data, (uint256, uint256)); 25 | require(reserveIn > 0 && reserveOut > 0, 'UniAdapter: INSUFFICIENT_LIQUIDITY'); 26 | 27 | uint balance0 = IERC20(baseToken).balanceOf(pool); 28 | uint sellBaseAmount = balance0 - reserveIn; 29 | 30 | uint sellBaseAmountWithFee = sellBaseAmount.mul(denFee - fee); 31 | uint numerator = sellBaseAmountWithFee.mul(reserveOut); 32 | uint denominator = reserveIn.mul(denFee).add(sellBaseAmountWithFee); 33 | receiveQuoteAmount = numerator / denominator; 34 | } 35 | IUni(pool).swap(0, receiveQuoteAmount, to, new bytes(0)); 36 | } 37 | 38 | //fromToken == token1 39 | function sellQuote(address to, address pool, bytes memory data) external override { 40 | address quoteToken = IUni(pool).token1(); 41 | (uint reserveOut, uint reserveIn,) = IUni(pool).getReserves(); 42 | uint receiveBaseAmount; 43 | { 44 | (uint256 fee, uint256 denFee) = abi.decode(data, (uint256, uint256)); 45 | require(reserveIn > 0 && reserveOut > 0, 'UniAdapter: INSUFFICIENT_LIQUIDITY'); 46 | 47 | uint balance1 = IERC20(quoteToken).balanceOf(pool); 48 | uint sellQuoteAmount = balance1 - reserveIn; 49 | 50 | uint sellQuoteAmountWithFee = sellQuoteAmount.mul(denFee - fee); 51 | uint numerator = sellQuoteAmountWithFee.mul(reserveOut); 52 | uint denominator = reserveIn.mul(denFee).add(sellQuoteAmountWithFee); 53 | receiveBaseAmount = numerator / denominator; 54 | } 55 | IUni(pool).swap(receiveBaseAmount, 0, to, new bytes(0)); 56 | } 57 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/helper/DODOCalleeHelper.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {IDODOV2} from "../intf/IDODOV2.sol"; 12 | import {IFragment} from "../../GeneralizedFragment/intf/IFragment.sol"; 13 | import {IERC20} from "../../intf/IERC20.sol"; 14 | import {IWETH} from "../../intf/IWETH.sol"; 15 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 16 | import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; 17 | 18 | contract DODOCalleeHelper is ReentrancyGuard { 19 | using SafeERC20 for IERC20; 20 | address payable public immutable _WETH_; 21 | 22 | fallback() external payable { 23 | require(msg.sender == _WETH_, "WE_SAVED_YOUR_ETH"); 24 | } 25 | 26 | receive() external payable { 27 | require(msg.sender == _WETH_, "WE_SAVED_YOUR_ETH"); 28 | } 29 | 30 | constructor(address payable weth) public { 31 | _WETH_ = weth; 32 | } 33 | 34 | function DVMSellShareCall( 35 | address payable assetTo, 36 | uint256, 37 | uint256 baseAmount, 38 | uint256 quoteAmount, 39 | bytes calldata 40 | ) external preventReentrant { 41 | address _baseToken = IDODOV2(msg.sender)._BASE_TOKEN_(); 42 | address _quoteToken = IDODOV2(msg.sender)._QUOTE_TOKEN_(); 43 | _withdraw(assetTo, _baseToken, baseAmount, _baseToken == _WETH_); 44 | _withdraw(assetTo, _quoteToken, quoteAmount, _quoteToken == _WETH_); 45 | } 46 | 47 | function CPCancelCall( 48 | address payable assetTo, 49 | uint256 amount, 50 | bytes calldata 51 | )external preventReentrant{ 52 | address _quoteToken = IDODOV2(msg.sender)._QUOTE_TOKEN_(); 53 | _withdraw(assetTo, _quoteToken, amount, _quoteToken == _WETH_); 54 | } 55 | 56 | function CPClaimBidCall( 57 | address payable assetTo, 58 | uint256 baseAmount, 59 | uint256 quoteAmount, 60 | bytes calldata 61 | ) external preventReentrant { 62 | address _baseToken = IDODOV2(msg.sender)._BASE_TOKEN_(); 63 | address _quoteToken = IDODOV2(msg.sender)._QUOTE_TOKEN_(); 64 | _withdraw(assetTo, _baseToken, baseAmount, _baseToken == _WETH_); 65 | _withdraw(assetTo, _quoteToken, quoteAmount, _quoteToken == _WETH_); 66 | } 67 | 68 | function NFTRedeemCall( 69 | address payable assetTo, 70 | uint256 quoteAmount, 71 | bytes calldata 72 | ) external preventReentrant { 73 | address _quoteToken = IFragment(msg.sender)._QUOTE_(); 74 | _withdraw(assetTo, _quoteToken, quoteAmount, _quoteToken == _WETH_); 75 | } 76 | 77 | function _withdraw( 78 | address payable to, 79 | address token, 80 | uint256 amount, 81 | bool isETH 82 | ) internal { 83 | if (isETH) { 84 | if (amount > 0) { 85 | IWETH(_WETH_).withdraw(amount); 86 | to.transfer(amount); 87 | } 88 | } else { 89 | if (amount > 0) { 90 | SafeERC20.safeTransfer(IERC20(token), to, amount); 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /contracts/SmartRoute/helper/DODONFTRouteHelper.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {IDODOV2} from "../intf/IDODOV2.sol"; 12 | 13 | contract DODONFTRouteHelper { 14 | address public immutable _NFT_REGISTER_; 15 | 16 | struct PairDetail { 17 | uint256 i; 18 | uint256 K; 19 | uint256 B; 20 | uint256 Q; 21 | uint256 B0; 22 | uint256 Q0; 23 | uint256 R; 24 | uint256 lpFeeRate; 25 | uint256 mtFeeRate; 26 | address baseToken; 27 | address quoteToken; 28 | address curPair; 29 | uint256 pairVersion; 30 | } 31 | 32 | constructor(address nftRegistry) public { 33 | _NFT_REGISTER_ = nftRegistry; 34 | } 35 | 36 | function getPairDetail(address token0,address token1,address userAddr) external view returns (PairDetail[] memory res) { 37 | (address[] memory baseToken0DVM, address[] memory baseToken1DVM) = IDODOV2(_NFT_REGISTER_).getDODOPoolBidirection(token0,token1); 38 | uint256 len = baseToken0DVM.length + baseToken1DVM.length; 39 | res = new PairDetail[](len); 40 | for(uint8 i = 0; i < len; i++) { 41 | PairDetail memory curRes = PairDetail(0,0,0,0,0,0,0,0,0,address(0),address(0),address(0),2); 42 | address cur; 43 | if(i < baseToken0DVM.length) { 44 | cur = baseToken0DVM[i]; 45 | curRes.baseToken = token0; 46 | curRes.quoteToken = token1; 47 | } else { 48 | cur = baseToken1DVM[i - baseToken0DVM.length]; 49 | curRes.baseToken = token1; 50 | curRes.quoteToken = token0; 51 | } 52 | 53 | ( 54 | curRes.i, 55 | curRes.K, 56 | curRes.B, 57 | curRes.Q, 58 | curRes.B0, 59 | curRes.Q0, 60 | curRes.R 61 | ) = IDODOV2(cur).getPMMStateForCall(); 62 | 63 | (curRes.lpFeeRate, curRes.mtFeeRate) = IDODOV2(cur).getUserFeeRate(userAddr); 64 | curRes.curPair = cur; 65 | res[i] = curRes; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/helper/DODOSwapCalcHelper.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {IDODOV1} from "../intf/IDODOV1.sol"; 11 | import {IDODOSellHelper} from "./DODOSellHelper.sol"; 12 | 13 | contract DODOSwapCalcHelper { 14 | address public immutable _DODO_SELL_HELPER_; 15 | 16 | constructor(address dodoSellHelper) public { 17 | _DODO_SELL_HELPER_ = dodoSellHelper; 18 | } 19 | 20 | function calcReturnAmountV1( 21 | uint256 fromTokenAmount, 22 | address[] memory dodoPairs, 23 | uint8[] memory directions 24 | ) external view returns (uint256 returnAmount,uint256[] memory midPrices,uint256[] memory feeRates) { 25 | returnAmount = fromTokenAmount; 26 | midPrices = new uint256[](dodoPairs.length); 27 | feeRates = new uint256[](dodoPairs.length); 28 | for (uint256 i = 0; i < dodoPairs.length; i++) { 29 | address curDodoPair = dodoPairs[i]; 30 | if (directions[i] == 0) { 31 | returnAmount = IDODOV1(curDodoPair).querySellBaseToken(returnAmount); 32 | } else { 33 | returnAmount = IDODOSellHelper(_DODO_SELL_HELPER_).querySellQuoteToken( 34 | curDodoPair, 35 | returnAmount 36 | ); 37 | } 38 | midPrices[i] = IDODOV1(curDodoPair).getMidPrice(); 39 | feeRates[i] = IDODOV1(curDodoPair)._MT_FEE_RATE_() + IDODOV1(curDodoPair)._LP_FEE_RATE_(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/helper/DODOV1PmmHelper.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {IDODOV1} from "../intf/IDODOV1.sol"; 12 | 13 | contract DODOV1PmmHelper { 14 | 15 | struct PairDetail { 16 | uint256 i; 17 | uint256 K; 18 | uint256 B; 19 | uint256 Q; 20 | uint256 B0; 21 | uint256 Q0; 22 | uint256 R; 23 | uint256 lpFeeRate; 24 | uint256 mtFeeRate; 25 | address baseToken; 26 | address quoteToken; 27 | address curPair; 28 | uint256 pairVersion; 29 | } 30 | 31 | function getPairDetail(address pool) external view returns (PairDetail[] memory res) { 32 | res = new PairDetail[](1); 33 | PairDetail memory curRes = PairDetail(0,0,0,0,0,0,0,0,0,address(0),address(0),pool,1); 34 | curRes.i = IDODOV1(pool).getOraclePrice(); 35 | curRes.K = IDODOV1(pool)._K_(); 36 | curRes.B = IDODOV1(pool)._BASE_BALANCE_(); 37 | curRes.Q = IDODOV1(pool)._QUOTE_BALANCE_(); 38 | (curRes.B0,curRes.Q0) = IDODOV1(pool).getExpectedTarget(); 39 | curRes.R = IDODOV1(pool)._R_STATUS_(); 40 | curRes.lpFeeRate = IDODOV1(pool)._LP_FEE_RATE_(); 41 | curRes.mtFeeRate = IDODOV1(pool)._MT_FEE_RATE_(); 42 | curRes.baseToken = IDODOV1(pool)._BASE_TOKEN_(); 43 | curRes.quoteToken = IDODOV1(pool)._QUOTE_TOKEN_(); 44 | res[0] = curRes; 45 | } 46 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IChi.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.9; 2 | pragma experimental ABIEncoderV2; 3 | 4 | interface IChi { 5 | function freeUpTo(uint256 value) external returns (uint256); 6 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/ICurve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.9; 2 | pragma experimental ABIEncoderV2; 3 | 4 | interface ICurve { 5 | // solium-disable-next-line mixedcase 6 | function get_dy_underlying(int128 i, int128 j, uint256 dx) external view returns(uint256 dy); 7 | 8 | // solium-disable-next-line mixedcase 9 | function get_dy(int128 i, int128 j, uint256 dx) external view returns(uint256 dy); 10 | 11 | // solium-disable-next-line mixedcase 12 | function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 minDy) external; 13 | 14 | // solium-disable-next-line mixedcase 15 | function exchange(int128 i, int128 j, uint256 dx, uint256 minDy) external; 16 | 17 | // view coins address 18 | function underlying_coins(int128 arg0) external view returns(address out); 19 | function coins(int128 arg0) external view returns(address out); 20 | 21 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IDODOAdapter.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDODOAdapter { 12 | 13 | function sellBase(address to, address pool, bytes memory data) external; 14 | 15 | function sellQuote(address to, address pool, bytes memory data) external; 16 | } 17 | -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IDODOV1.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDODOV1 { 12 | function init( 13 | address owner, 14 | address supervisor, 15 | address maintainer, 16 | address baseToken, 17 | address quoteToken, 18 | address oracle, 19 | uint256 lpFeeRate, 20 | uint256 mtFeeRate, 21 | uint256 k, 22 | uint256 gasPriceLimit 23 | ) external; 24 | 25 | function transferOwnership(address newOwner) external; 26 | 27 | function claimOwnership() external; 28 | 29 | function sellBaseToken( 30 | uint256 amount, 31 | uint256 minReceiveQuote, 32 | bytes calldata data 33 | ) external returns (uint256); 34 | 35 | function buyBaseToken( 36 | uint256 amount, 37 | uint256 maxPayQuote, 38 | bytes calldata data 39 | ) external returns (uint256); 40 | 41 | function querySellBaseToken(uint256 amount) external view returns (uint256 receiveQuote); 42 | 43 | function queryBuyBaseToken(uint256 amount) external view returns (uint256 payQuote); 44 | 45 | function depositBaseTo(address to, uint256 amount) external returns (uint256); 46 | 47 | function withdrawBase(uint256 amount) external returns (uint256); 48 | 49 | function withdrawAllBase() external returns (uint256); 50 | 51 | function depositQuoteTo(address to, uint256 amount) external returns (uint256); 52 | 53 | function withdrawQuote(uint256 amount) external returns (uint256); 54 | 55 | function withdrawAllQuote() external returns (uint256); 56 | 57 | function _BASE_CAPITAL_TOKEN_() external returns (address); 58 | 59 | function _QUOTE_CAPITAL_TOKEN_() external returns (address); 60 | 61 | function _BASE_TOKEN_() external view returns (address); 62 | 63 | function _QUOTE_TOKEN_() external view returns (address); 64 | 65 | function _R_STATUS_() external view returns (uint8); 66 | 67 | function _QUOTE_BALANCE_() external view returns (uint256); 68 | 69 | function _BASE_BALANCE_() external view returns (uint256); 70 | 71 | function _K_() external view returns (uint256); 72 | 73 | function _MT_FEE_RATE_() external view returns (uint256); 74 | 75 | function _LP_FEE_RATE_() external view returns (uint256); 76 | 77 | function getExpectedTarget() external view returns (uint256 baseTarget, uint256 quoteTarget); 78 | 79 | function getOraclePrice() external view returns (uint256); 80 | 81 | function getMidPrice() external view returns (uint256 midPrice); 82 | } 83 | -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IDODOV1Proxy01.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDODOV1Proxy01 { 12 | function dodoSwapV1( 13 | address fromToken, 14 | address toToken, 15 | uint256 fromTokenAmount, 16 | uint256 minReturnAmount, 17 | address[] memory dodoPairs, 18 | uint8[] memory directions, 19 | uint256 deadLine 20 | ) external payable returns (uint256 returnAmount); 21 | 22 | function externalSwap( 23 | address fromToken, 24 | address toToken, 25 | address approveTarget, 26 | address to, 27 | uint256 fromTokenAmount, 28 | uint256 minReturnAmount, 29 | bytes memory callDataConcat, 30 | uint256 deadLine 31 | ) external payable returns (uint256 returnAmount); 32 | 33 | function mixSwapV1( 34 | address fromToken, 35 | address toToken, 36 | uint256 fromTokenAmount, 37 | uint256 minReturnAmount, 38 | address[] memory mixPairs, 39 | uint8[] memory directions, 40 | address[] memory portionPath, 41 | uint256 deadLine 42 | ) external payable returns (uint256 returnAmount); 43 | } 44 | -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IDODOV1Proxy02.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDODOV1Proxy02 { 12 | function dodoSwapV1( 13 | address fromToken, 14 | address toToken, 15 | uint256 fromTokenAmount, 16 | uint256 minReturnAmount, 17 | address[] memory dodoPairs, 18 | uint256 directions, 19 | uint256 deadLine 20 | ) external payable returns (uint256 returnAmount); 21 | 22 | function externalSwap( 23 | address fromToken, 24 | address toToken, 25 | address approveTarget, 26 | address to, 27 | uint256 fromTokenAmount, 28 | uint256 minReturnAmount, 29 | bytes memory callDataConcat, 30 | uint256 deadLine 31 | ) external payable returns (uint256 returnAmount); 32 | 33 | function mixSwapV1( 34 | address fromToken, 35 | address toToken, 36 | uint256 fromTokenAmount, 37 | uint256 minReturnAmount, 38 | address[] memory mixPairs, 39 | uint256[] memory directions, 40 | address[] memory portionPath, 41 | uint256 deadLine 42 | ) external payable returns (uint256 returnAmount); 43 | } 44 | -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IDODOV2.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDODOV2 { 12 | 13 | //========== Common ================== 14 | 15 | function sellBase(address to) external returns (uint256 receiveQuoteAmount); 16 | 17 | function sellQuote(address to) external returns (uint256 receiveBaseAmount); 18 | 19 | function getVaultReserve() external view returns (uint256 baseReserve, uint256 quoteReserve); 20 | 21 | function _BASE_TOKEN_() external view returns (address); 22 | 23 | function _QUOTE_TOKEN_() external view returns (address); 24 | 25 | function getPMMStateForCall() external view returns ( 26 | uint256 i, 27 | uint256 K, 28 | uint256 B, 29 | uint256 Q, 30 | uint256 B0, 31 | uint256 Q0, 32 | uint256 R 33 | ); 34 | 35 | function getUserFeeRate(address user) external view returns (uint256 lpFeeRate, uint256 mtFeeRate); 36 | 37 | 38 | function getDODOPoolBidirection(address token0, address token1) external view returns (address[] memory, address[] memory); 39 | 40 | //========== DODOVendingMachine ======== 41 | 42 | function createDODOVendingMachine( 43 | address baseToken, 44 | address quoteToken, 45 | uint256 lpFeeRate, 46 | uint256 i, 47 | uint256 k, 48 | bool isOpenTWAP 49 | ) external returns (address newVendingMachine); 50 | 51 | function buyShares(address to) external returns (uint256,uint256,uint256); 52 | 53 | 54 | //========== DODOPrivatePool =========== 55 | 56 | function createDODOPrivatePool() external returns (address newPrivatePool); 57 | 58 | function initDODOPrivatePool( 59 | address dppAddress, 60 | address creator, 61 | address baseToken, 62 | address quoteToken, 63 | uint256 lpFeeRate, 64 | uint256 k, 65 | uint256 i, 66 | bool isOpenTwap 67 | ) external; 68 | 69 | function reset( 70 | address operator, 71 | uint256 newLpFeeRate, 72 | uint256 newI, 73 | uint256 newK, 74 | uint256 baseOutAmount, 75 | uint256 quoteOutAmount, 76 | uint256 minBaseReserve, 77 | uint256 minQuoteReserve 78 | ) external returns (bool); 79 | 80 | 81 | function _OWNER_() external returns (address); 82 | 83 | //========== CrowdPooling =========== 84 | 85 | function createCrowdPooling() external returns (address payable newCrowdPooling); 86 | 87 | function initCrowdPooling( 88 | address cpAddress, 89 | address creator, 90 | address[] memory tokens, 91 | uint256[] memory timeLine, 92 | uint256[] memory valueList, 93 | bool[] memory switches, 94 | int globalQuota 95 | ) external; 96 | 97 | function bid(address to) external; 98 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IGambit.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.9; 2 | pragma experimental ABIEncoderV2; 3 | 4 | interface IGambit { 5 | function swap(address _tokenIn, address _tokenOut, address _receiver) external returns (uint256); 6 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IUni.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.9; 2 | pragma experimental ABIEncoderV2; 3 | 4 | interface IUni { 5 | function swapExactTokensForTokens( 6 | uint amountIn, 7 | uint amountOutMin, 8 | address[] calldata path, 9 | address to, 10 | uint deadline 11 | ) external returns (uint[] memory amounts); 12 | 13 | function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; 14 | 15 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 16 | 17 | function token0() external view returns (address); 18 | 19 | function token1() external view returns (address); 20 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IUniV3.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.9; 2 | pragma experimental ABIEncoderV2; 3 | 4 | interface IUniV3 { 5 | function swap( 6 | address recipient, 7 | bool zeroForOne, 8 | int256 amountSpecified, 9 | uint160 sqrtPriceLimitX96, 10 | bytes calldata data 11 | ) external returns (int256 amount0, int256 amount1); 12 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/intf/IUniswapV3SwapCallBack.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Callback for IUniswapV3PoolActions#swap 5 | /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface 6 | interface IUniswapV3SwapCallback { 7 | /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. 8 | /// @dev In the implementation you must pay the pool tokens owed for the swap. 9 | /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. 10 | /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. 11 | /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by 12 | /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. 13 | /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by 14 | /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. 15 | /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call 16 | function uniswapV3SwapCallback( 17 | int256 amount0Delta, 18 | int256 amount1Delta, 19 | bytes calldata data 20 | ) external; 21 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/lib/UniversalERC20.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {SafeMath} from "../../lib/SafeMath.sol"; 11 | import {IERC20} from "../../intf/IERC20.sol"; 12 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 13 | 14 | library UniversalERC20 { 15 | using SafeMath for uint256; 16 | using SafeERC20 for IERC20; 17 | 18 | IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); 19 | 20 | function universalTransfer( 21 | IERC20 token, 22 | address payable to, 23 | uint256 amount 24 | ) internal { 25 | if (amount > 0) { 26 | if (isETH(token)) { 27 | to.transfer(amount); 28 | } else { 29 | token.safeTransfer(to, amount); 30 | } 31 | } 32 | } 33 | 34 | function universalApproveMax( 35 | IERC20 token, 36 | address to, 37 | uint256 amount 38 | ) internal { 39 | uint256 allowance = token.allowance(address(this), to); 40 | if (allowance < amount) { 41 | if (allowance > 0) { 42 | token.safeApprove(to, 0); 43 | } 44 | token.safeApprove(to, uint256(-1)); 45 | } 46 | } 47 | 48 | function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) { 49 | if (isETH(token)) { 50 | return who.balance; 51 | } else { 52 | return token.balanceOf(who); 53 | } 54 | } 55 | 56 | function tokenBalanceOf(IERC20 token, address who) internal view returns (uint256) { 57 | return token.balanceOf(who); 58 | } 59 | 60 | function isETH(IERC20 token) internal pure returns (bool) { 61 | return token == ETH_ADDRESS; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/SmartRoute/proxies/DODODropsProxy.sol: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | pragma solidity 0.6.9; 8 | 9 | import {IDODOApproveProxy} from "../DODOApproveProxy.sol"; 10 | import {IERC20} from "../../intf/IERC20.sol"; 11 | import {SafeMath} from "../../lib/SafeMath.sol"; 12 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 13 | import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; 14 | 15 | interface IDODODrops { 16 | function _BUY_TOKEN_() external view returns (address); 17 | function _FEE_MODEL_() external view returns (address); 18 | function getSellingInfo() external view returns (uint256, uint256, uint256); 19 | function buyTickets(address assetTo, uint256 ticketAmount) external; 20 | } 21 | 22 | interface IDropsFeeModel { 23 | function getPayAmount(address mysteryBox, address user, uint256 originalPrice, uint256 ticketAmount) external view returns (uint256, uint256); 24 | } 25 | 26 | /** 27 | * @title DODO DropsProxy 28 | * @author DODO Breeder 29 | * 30 | * @notice Entrance of Drops in DODO platform 31 | */ 32 | contract DODODropsProxy is ReentrancyGuard { 33 | using SafeMath for uint256; 34 | 35 | // ============ Storage ============ 36 | 37 | address constant _BASE_COIN_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 38 | address public immutable _DODO_APPROVE_PROXY_; 39 | 40 | // ============ Events ============ 41 | event BuyTicket(address indexed account, address indexed mysteryBox, uint256 ticketAmount); 42 | 43 | fallback() external payable {} 44 | 45 | receive() external payable {} 46 | 47 | constructor(address dodoApproveProxy) public { 48 | _DODO_APPROVE_PROXY_ = dodoApproveProxy; 49 | } 50 | 51 | function buyTickets(address payable dodoDrops, uint256 ticketAmount) external payable preventReentrant { 52 | (uint256 curPrice, uint256 sellAmount,) = IDODODrops(dodoDrops).getSellingInfo(); 53 | require(curPrice > 0 && sellAmount > 0, "CAN_NOT_BUY"); 54 | require(ticketAmount <= sellAmount, "TICKETS_NOT_ENOUGH"); 55 | 56 | address feeModel = IDODODrops(dodoDrops)._FEE_MODEL_(); 57 | (uint256 payAmount,) = IDropsFeeModel(feeModel).getPayAmount(dodoDrops, msg.sender, curPrice, ticketAmount); 58 | require(payAmount > 0, "UnQualified"); 59 | address buyToken = IDODODrops(dodoDrops)._BUY_TOKEN_(); 60 | 61 | if(buyToken == _BASE_COIN_) { 62 | require(msg.value == payAmount, "PAYAMOUNT_NOT_ENOUGH"); 63 | dodoDrops.transfer(payAmount); 64 | }else { 65 | IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(buyToken, msg.sender, dodoDrops, payAmount); 66 | } 67 | 68 | IDODODrops(dodoDrops).buyTickets(msg.sender, ticketAmount); 69 | 70 | emit BuyTicket(msg.sender, dodoDrops, ticketAmount); 71 | } 72 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/proxies/DODOStarterProxy.sol: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 DODO ZOO. 3 | SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | pragma solidity 0.6.9; 7 | 8 | import {IDODOApproveProxy} from "../DODOApproveProxy.sol"; 9 | import {IERC20} from "../../intf/IERC20.sol"; 10 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 11 | import {IWETH} from "../../intf/IWETH.sol"; 12 | import {SafeMath} from "../../lib/SafeMath.sol"; 13 | import {SafeERC20} from "../../lib/SafeERC20.sol"; 14 | import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol"; 15 | import {IDODOStarter} from "../../DODOStarter/intf/IDODOStarter.sol"; 16 | 17 | /** 18 | * @title DODOStarterProxy 19 | * @author DODO Breeder 20 | * 21 | * @notice FairFund && InstantFund Proxy 22 | */ 23 | contract DODOStarterProxy is ReentrancyGuard { 24 | using SafeMath for uint256; 25 | using SafeERC20 for IERC20; 26 | 27 | // ============ Storage ============ 28 | 29 | address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; 30 | address public immutable _WETH_; 31 | address public immutable _DODO_APPROVE_PROXY_; 32 | 33 | // ============ Modifiers ============ 34 | 35 | modifier judgeExpired(uint256 deadLine) { 36 | require(deadLine >= block.timestamp, "DODOStarterProxy: EXPIRED"); 37 | _; 38 | } 39 | 40 | fallback() external payable {} 41 | 42 | receive() external payable {} 43 | 44 | constructor( 45 | address payable weth, 46 | address dodoApproveProxy 47 | ) public { 48 | _WETH_ = weth; 49 | _DODO_APPROVE_PROXY_ = dodoApproveProxy; 50 | } 51 | 52 | //============ Functions (bid) ============ 53 | function bid( 54 | address pool, 55 | uint256 fundAmount, 56 | uint8 flag, // 0 - ERC20, 1 - fundInETH 57 | uint256 deadLine 58 | ) external payable preventReentrant judgeExpired(deadLine) returns(uint256) { 59 | _deposit(msg.sender, pool, IDODOStarter(pool)._FUNDS_ADDRESS_(), fundAmount, flag == 1); 60 | return IDODOStarter(pool).depositFunds(msg.sender); 61 | } 62 | 63 | //====================== internal ======================= 64 | 65 | function _deposit( 66 | address from, 67 | address to, 68 | address token, 69 | uint256 amount, 70 | bool isETH 71 | ) internal { 72 | if (isETH) { 73 | if (amount > 0) { 74 | require(msg.value == amount, "ETH_VALUE_WRONG"); 75 | IWETH(_WETH_).deposit{value: amount}(); 76 | if (to != address(this)) SafeERC20.safeTransfer(IERC20(_WETH_), to, amount); 77 | } 78 | } else { 79 | IDODOApproveProxy(_DODO_APPROVE_PROXY_).claimTokens(token, from, to, amount); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /contracts/SmartRoute/sampler/CurveSample.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import "../intf/ICurve.sol"; 12 | 13 | contract CurveSampler { 14 | 15 | function sampleFromCurve( 16 | address curveAddress, 17 | int128 fromTokenIdx, 18 | int128 toTokenIdx, 19 | uint256[] memory takerTokenAmounts 20 | ) 21 | public 22 | view 23 | returns (uint256[] memory makerTokenAmounts) 24 | { 25 | uint256 numSamples = takerTokenAmounts.length; 26 | makerTokenAmounts = new uint256[](numSamples); 27 | for (uint256 i = 0; i < numSamples; i++) { 28 | uint256 buyAmount = ICurve(curveAddress).get_dy_underlying(fromTokenIdx, toTokenIdx, takerTokenAmounts[i]); 29 | makerTokenAmounts[i] = buyAmount; 30 | // Break early if there are 0 amounts 31 | if (makerTokenAmounts[i] == 0) { 32 | break; 33 | } 34 | } 35 | return makerTokenAmounts; 36 | } 37 | } -------------------------------------------------------------------------------- /contracts/external/ERC1155/InitializableERC1155.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {ERC1155} from "./ERC1155.sol"; 11 | import {Strings} from "../utils/Strings.sol"; 12 | 13 | contract InitializableERC1155 is ERC1155 { 14 | using Strings for uint256; 15 | 16 | mapping (uint256 => string) private _tokenURIs; 17 | string internal _baseUri = ""; 18 | bool internal _INITIALIZED_; 19 | 20 | function init( 21 | address creator, 22 | uint256 amount, 23 | string memory uri 24 | ) public { 25 | require(!_INITIALIZED_, "INITIALIZED"); 26 | _INITIALIZED_ = true; 27 | _mint(creator, 0, amount ,""); 28 | _setTokenURI(0, uri); 29 | } 30 | 31 | function uri(uint256 tokenId) public view override returns (string memory) { 32 | string memory _tokenURI = _tokenURIs[tokenId]; 33 | string memory base = _baseUri; 34 | 35 | if (bytes(base).length == 0) { 36 | return _tokenURI; 37 | } 38 | 39 | if (bytes(_tokenURI).length > 0) { 40 | return string(abi.encodePacked(base, _tokenURI)); 41 | } 42 | 43 | return super.uri(tokenId); 44 | } 45 | 46 | function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal { 47 | _tokenURIs[tokenId] = _tokenURI; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /contracts/external/ERC20/InitializableERC20.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {SafeMath} from "../../lib/SafeMath.sol"; 11 | 12 | contract InitializableERC20 { 13 | using SafeMath for uint256; 14 | 15 | string public name; 16 | uint8 public decimals; 17 | string public symbol; 18 | uint256 public totalSupply; 19 | 20 | bool public initialized; 21 | 22 | mapping(address => uint256) internal balances; 23 | mapping(address => mapping(address => uint256)) internal allowed; 24 | 25 | event Transfer(address indexed from, address indexed to, uint256 amount); 26 | event Approval(address indexed owner, address indexed spender, uint256 amount); 27 | 28 | function init( 29 | address _creator, 30 | uint256 _totalSupply, 31 | string memory _name, 32 | string memory _symbol, 33 | uint8 _decimals 34 | ) public { 35 | require(!initialized, "TOKEN_INITIALIZED"); 36 | initialized = true; 37 | totalSupply = _totalSupply; 38 | balances[_creator] = _totalSupply; 39 | name = _name; 40 | symbol = _symbol; 41 | decimals = _decimals; 42 | emit Transfer(address(0), _creator, _totalSupply); 43 | } 44 | 45 | function transfer(address to, uint256 amount) public returns (bool) { 46 | _transfer(msg.sender, to, amount); 47 | return true; 48 | } 49 | 50 | function balanceOf(address owner) public view returns (uint256 balance) { 51 | return balances[owner]; 52 | } 53 | 54 | function transferFrom( 55 | address from, 56 | address to, 57 | uint256 amount 58 | ) public returns (bool) { 59 | require(to != address(0), "TO_ADDRESS_IS_EMPTY"); 60 | require(amount <= balances[from], "BALANCE_NOT_ENOUGH"); 61 | require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH"); 62 | 63 | balances[from] = balances[from].sub(amount); 64 | balances[to] = balances[to].add(amount); 65 | allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount); 66 | emit Transfer(from, to, amount); 67 | return true; 68 | } 69 | 70 | function approve(address spender, uint256 amount) public returns (bool) { 71 | allowed[msg.sender][spender] = amount; 72 | emit Approval(msg.sender, spender, amount); 73 | return true; 74 | } 75 | 76 | function allowance(address owner, address spender) public view returns (uint256) { 77 | return allowed[owner][spender]; 78 | } 79 | 80 | function _transfer(address sender, address recipient, uint256 amount) internal { 81 | require(sender != address(0), "FROM_ADDRESS_IS_EMPTY"); 82 | require(recipient != address(0), "TO_ADDRESS_IS_EMPTY"); 83 | require(amount <= balances[sender], "BALANCE_NOT_ENOUGH"); 84 | 85 | balances[sender] = balances[sender].sub(amount); 86 | balances[recipient] = balances[recipient].add(amount); 87 | 88 | emit Transfer(sender, recipient, amount); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /contracts/external/ERC20/InitializableFragERC20.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {SafeMath} from "../../lib/SafeMath.sol"; 11 | 12 | contract InitializableFragERC20 { 13 | using SafeMath for uint256; 14 | 15 | string public name; 16 | string public symbol; 17 | uint256 public totalSupply; 18 | 19 | bool public initialized; 20 | 21 | mapping(address => uint256) internal balances; 22 | mapping(address => mapping(address => uint256)) internal allowed; 23 | 24 | event Transfer(address indexed from, address indexed to, uint256 amount); 25 | event Approval(address indexed owner, address indexed spender, uint256 amount); 26 | 27 | function init( 28 | address _creator, 29 | uint256 _totalSupply, 30 | string memory _name, 31 | string memory _symbol 32 | ) public { 33 | require(!initialized, "TOKEN_INITIALIZED"); 34 | initialized = true; 35 | totalSupply = _totalSupply; 36 | balances[_creator] = _totalSupply; 37 | name = _name; 38 | symbol = _symbol; 39 | emit Transfer(address(0), _creator, _totalSupply); 40 | } 41 | 42 | function decimals() public pure returns (uint8) { 43 | return 18; 44 | } 45 | 46 | function transfer(address to, uint256 amount) public returns (bool) { 47 | _transfer(msg.sender, to, amount); 48 | return true; 49 | } 50 | 51 | function balanceOf(address owner) public view returns (uint256 balance) { 52 | return balances[owner]; 53 | } 54 | 55 | function transferFrom( 56 | address from, 57 | address to, 58 | uint256 amount 59 | ) public returns (bool) { 60 | require(to != address(0), "TO_ADDRESS_IS_EMPTY"); 61 | require(amount <= balances[from], "BALANCE_NOT_ENOUGH"); 62 | require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH"); 63 | 64 | balances[from] = balances[from].sub(amount); 65 | balances[to] = balances[to].add(amount); 66 | allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount); 67 | emit Transfer(from, to, amount); 68 | return true; 69 | } 70 | 71 | function approve(address spender, uint256 amount) public returns (bool) { 72 | allowed[msg.sender][spender] = amount; 73 | emit Approval(msg.sender, spender, amount); 74 | return true; 75 | } 76 | 77 | function allowance(address owner, address spender) public view returns (uint256) { 78 | return allowed[owner][spender]; 79 | } 80 | 81 | function _transfer(address sender, address recipient, uint256 amount) internal { 82 | require(sender != address(0), "FROM_ADDRESS_IS_EMPTY"); 83 | require(recipient != address(0), "TO_ADDRESS_IS_EMPTY"); 84 | require(amount <= balances[sender], "BALANCE_NOT_ENOUGH"); 85 | 86 | balances[sender] = balances[sender].sub(amount); 87 | balances[recipient] = balances[recipient].add(amount); 88 | 89 | emit Transfer(sender, recipient, amount); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /contracts/external/ERC20/MintableERC20.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {SafeMath} from "../../lib/SafeMath.sol"; 11 | 12 | contract MintableERC20 { 13 | using SafeMath for uint256; 14 | 15 | string public name; 16 | string public symbol; 17 | uint8 public decimals; 18 | 19 | mapping(address => uint256) balances; 20 | mapping(address => mapping(address => uint256)) internal allowed; 21 | 22 | event Transfer(address indexed from, address indexed to, uint256 amount); 23 | event Approval(address indexed owner, address indexed spender, uint256 amount); 24 | 25 | constructor( 26 | string memory _name, 27 | string memory _symbol, 28 | uint8 _decimals 29 | ) public { 30 | name = _name; 31 | symbol = _symbol; 32 | decimals = _decimals; 33 | } 34 | 35 | function transfer(address to, uint256 amount) public returns (bool) { 36 | require(to != address(0), "TO_ADDRESS_IS_EMPTY"); 37 | require(amount <= balances[msg.sender], "BALANCE_NOT_ENOUGH"); 38 | 39 | balances[msg.sender] = balances[msg.sender].sub(amount); 40 | balances[to] = balances[to].add(amount); 41 | emit Transfer(msg.sender, to, amount); 42 | return true; 43 | } 44 | 45 | function balanceOf(address owner) public view returns (uint256 balance) { 46 | return balances[owner]; 47 | } 48 | 49 | function transferFrom( 50 | address from, 51 | address to, 52 | uint256 amount 53 | ) public returns (bool) { 54 | require(to != address(0), "TO_ADDRESS_IS_EMPTY"); 55 | require(amount <= balances[from], "BALANCE_NOT_ENOUGH"); 56 | require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH"); 57 | 58 | balances[from] = balances[from].sub(amount); 59 | balances[to] = balances[to].add(amount); 60 | allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount); 61 | emit Transfer(from, to, amount); 62 | return true; 63 | } 64 | 65 | function approve(address spender, uint256 amount) public returns (bool) { 66 | allowed[msg.sender][spender] = amount; 67 | emit Approval(msg.sender, spender, amount); 68 | return true; 69 | } 70 | 71 | function allowance(address owner, address spender) public view returns (uint256) { 72 | return allowed[owner][spender]; 73 | } 74 | 75 | function mint(address account, uint256 amount) external { 76 | balances[account] = balances[account].add(amount); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /contracts/external/ERC20/TestERC20.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {SafeMath} from "../../lib/SafeMath.sol"; 11 | 12 | contract TestERC20 { 13 | using SafeMath for uint256; 14 | 15 | string public name; 16 | uint8 public decimals; 17 | string public symbol; 18 | 19 | mapping(address => uint256) balances; 20 | mapping(address => mapping(address => uint256)) internal allowed; 21 | 22 | event Transfer(address indexed from, address indexed to, uint256 amount); 23 | event Approval(address indexed owner, address indexed spender, uint256 amount); 24 | 25 | constructor( 26 | string memory _name, 27 | uint8 _decimals, 28 | string memory _symbol 29 | ) public { 30 | name = _name; 31 | decimals = _decimals; 32 | symbol = _symbol; 33 | } 34 | 35 | function transfer(address to, uint256 amount) public returns (bool) { 36 | require(to != address(0), "TO_ADDRESS_IS_EMPTY"); 37 | require(amount <= balances[msg.sender], "BALANCE_NOT_ENOUGH"); 38 | 39 | balances[msg.sender] = balances[msg.sender].sub(amount); 40 | balances[to] = balances[to].add(amount); 41 | emit Transfer(msg.sender, to, amount); 42 | return true; 43 | } 44 | 45 | function balanceOf(address owner) public view returns (uint256 balance) { 46 | return balances[owner]; 47 | } 48 | 49 | function transferFrom( 50 | address from, 51 | address to, 52 | uint256 amount 53 | ) public returns (bool) { 54 | require(to != address(0), "TO_ADDRESS_IS_EMPTY"); 55 | require(amount <= balances[from], "BALANCE_NOT_ENOUGH"); 56 | require(amount <= allowed[from][msg.sender], "ALLOWANCE_NOT_ENOUGH"); 57 | 58 | balances[from] = balances[from].sub(amount); 59 | balances[to] = balances[to].add(amount); 60 | allowed[from][msg.sender] = allowed[from][msg.sender].sub(amount); 61 | emit Transfer(from, to, amount); 62 | return true; 63 | } 64 | 65 | function approve(address spender, uint256 amount) public returns (bool) { 66 | allowed[msg.sender][spender] = amount; 67 | emit Approval(msg.sender, spender, amount); 68 | return true; 69 | } 70 | 71 | function allowance(address owner, address spender) public view returns (uint256) { 72 | return allowed[owner][spender]; 73 | } 74 | 75 | function mint(address account, uint256 amount) external { 76 | balances[account] = balances[account].add(amount); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /contracts/external/ERC20/TestWETH.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | 11 | contract WETH9 { 12 | string public name = "Wrapped Ether"; 13 | string public symbol = "WETH"; 14 | uint8 public decimals = 18; 15 | 16 | event Approval(address indexed src, address indexed guy, uint256 wad); 17 | event Transfer(address indexed src, address indexed dst, uint256 wad); 18 | event Deposit(address indexed dst, uint256 wad); 19 | event Withdrawal(address indexed src, uint256 wad); 20 | 21 | mapping(address => uint256) public balanceOf; 22 | mapping(address => mapping(address => uint256)) public allowance; 23 | 24 | fallback() external payable { 25 | deposit(); 26 | } 27 | 28 | receive() external payable { 29 | deposit(); 30 | } 31 | 32 | function deposit() public payable { 33 | balanceOf[msg.sender] += msg.value; 34 | emit Deposit(msg.sender, msg.value); 35 | } 36 | 37 | function withdraw(uint256 wad) public { 38 | require(balanceOf[msg.sender] >= wad); 39 | balanceOf[msg.sender] -= wad; 40 | msg.sender.transfer(wad); 41 | emit Withdrawal(msg.sender, wad); 42 | } 43 | 44 | function totalSupply() public view returns (uint256) { 45 | return address(this).balance; 46 | } 47 | 48 | function approve(address guy, uint256 wad) public returns (bool) { 49 | allowance[msg.sender][guy] = wad; 50 | emit Approval(msg.sender, guy, wad); 51 | return true; 52 | } 53 | 54 | function transfer(address dst, uint256 wad) public returns (bool) { 55 | return transferFrom(msg.sender, dst, wad); 56 | } 57 | 58 | function transferFrom( 59 | address src, 60 | address dst, 61 | uint256 wad 62 | ) public returns (bool) { 63 | require(balanceOf[src] >= wad); 64 | 65 | if (src != msg.sender && allowance[src][msg.sender] != uint256(-1)) { 66 | require(allowance[src][msg.sender] >= wad); 67 | allowance[src][msg.sender] -= wad; 68 | } 69 | 70 | balanceOf[src] -= wad; 71 | balanceOf[dst] += wad; 72 | 73 | Transfer(src, dst, wad); 74 | 75 | return true; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /contracts/external/ERC721/ERC721URIStorage.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/ERC721URIStorage.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | import "./ERC721Enumerable.sol"; 7 | 8 | /** 9 | * @dev ERC721 token with storage based token URI management. 10 | */ 11 | abstract contract ERC721URIStorage is ERC721Enumerable { 12 | using Strings for uint256; 13 | 14 | // Optional mapping for token URIs 15 | mapping (uint256 => string) private _tokenURIs; 16 | 17 | /** 18 | * @dev See {IERC721Metadata-tokenURI}. 19 | */ 20 | function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { 21 | require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token"); 22 | 23 | string memory _tokenURI = _tokenURIs[tokenId]; 24 | string memory base = _baseURI(); 25 | 26 | // If there is no base URI, return the token URI. 27 | if (bytes(base).length == 0) { 28 | return _tokenURI; 29 | } 30 | // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). 31 | if (bytes(_tokenURI).length > 0) { 32 | return string(abi.encodePacked(base, _tokenURI)); 33 | } 34 | 35 | return super.tokenURI(tokenId); 36 | } 37 | 38 | /** 39 | * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. 40 | * 41 | * Requirements: 42 | * 43 | * - `tokenId` must exist. 44 | */ 45 | function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { 46 | require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); 47 | _tokenURIs[tokenId] = _tokenURI; 48 | } 49 | 50 | /** 51 | * @dev Destroys `tokenId`. 52 | * The approval is cleared when the token is burned. 53 | * 54 | * Requirements: 55 | * 56 | * - `tokenId` must exist. 57 | * 58 | * Emits a {Transfer} event. 59 | */ 60 | function _burn(uint256 tokenId) internal virtual override { 61 | super._burn(tokenId); 62 | 63 | if (bytes(_tokenURIs[tokenId]).length != 0) { 64 | delete _tokenURIs[tokenId]; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /contracts/external/ERC721/InitializableERC721.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | import {ERC721URIStorage} from "./ERC721URIStorage.sol"; 11 | 12 | contract InitializableERC721 is ERC721URIStorage { 13 | function init( 14 | address creator, 15 | string memory name, 16 | string memory symbol, 17 | string memory uri 18 | ) public { 19 | _name = name; 20 | _symbol = symbol; 21 | _mint(creator, 0); 22 | _setTokenURI(0, uri); 23 | } 24 | } -------------------------------------------------------------------------------- /contracts/external/Multicall.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.9; 2 | pragma experimental ABIEncoderV2; 3 | 4 | /// @title Multicall - Aggregate results from multiple read-only function calls 5 | /// @author Michael Elliot 6 | /// @author Joshua Levine 7 | /// @author Nick Johnson 8 | 9 | // WithValid 10 | contract Multicall { 11 | struct Call { 12 | address target; 13 | bytes callData; 14 | } 15 | 16 | function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) { 17 | blockNumber = block.number; 18 | returnData = new bytes[](calls.length); 19 | for(uint256 i = 0; i < calls.length; i++) { 20 | (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData); 21 | require(success); 22 | returnData[i] = ret; 23 | } 24 | } 25 | // Helper functions 26 | function getEthBalance(address addr) public view returns (uint256 balance) { 27 | balance = addr.balance; 28 | } 29 | function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { 30 | blockHash = blockhash(blockNumber); 31 | } 32 | function getLastBlockHash() public view returns (bytes32 blockHash) { 33 | blockHash = blockhash(block.number - 1); 34 | } 35 | function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { 36 | timestamp = block.timestamp; 37 | } 38 | function getCurrentBlockDifficulty() public view returns (uint256 difficulty) { 39 | difficulty = block.difficulty; 40 | } 41 | function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) { 42 | gaslimit = block.gaslimit; 43 | } 44 | function getCurrentBlockCoinbase() public view returns (address coinbase) { 45 | coinbase = block.coinbase; 46 | } 47 | } -------------------------------------------------------------------------------- /contracts/external/MulticallWithValid.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.9; 2 | pragma experimental ABIEncoderV2; 3 | 4 | /// @title Multicall - Aggregate results from multiple read-only function calls 5 | /// @author Michael Elliot 6 | /// @author Joshua Levine 7 | /// @author Nick Johnson 8 | 9 | // WithValid 10 | contract MulticallWithValid { 11 | struct Call { 12 | address target; 13 | bytes callData; 14 | } 15 | function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData, bool[] memory dataValid) { 16 | blockNumber = block.number; 17 | returnData = new bytes[](calls.length); 18 | dataValid = new bool[](calls.length); 19 | for(uint256 i = 0; i < calls.length; i++) { 20 | (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData); 21 | dataValid[i] = success; 22 | returnData[i] = ret; 23 | } 24 | } 25 | // Helper functions 26 | function getEthBalance(address addr) public view returns (uint256 balance) { 27 | balance = addr.balance; 28 | } 29 | function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { 30 | blockHash = blockhash(blockNumber); 31 | } 32 | function getLastBlockHash() public view returns (bytes32 blockHash) { 33 | blockHash = blockhash(block.number - 1); 34 | } 35 | function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { 36 | timestamp = block.timestamp; 37 | } 38 | function getCurrentBlockDifficulty() public view returns (uint256 difficulty) { 39 | difficulty = block.difficulty; 40 | } 41 | function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) { 42 | gaslimit = block.gaslimit; 43 | } 44 | function getCurrentBlockCoinbase() public view returns (address coinbase) { 45 | coinbase = block.coinbase; 46 | } 47 | } -------------------------------------------------------------------------------- /contracts/external/uniswap/PoolAddress.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | pragma solidity >=0.5.0; 3 | 4 | /// @title Provides functions for deriving a pool address from the factory, tokens, and the fee 5 | library PoolAddress { 6 | bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54; 7 | 8 | /// @notice The identifying key of the pool 9 | struct PoolKey { 10 | address token0; 11 | address token1; 12 | uint24 fee; 13 | } 14 | 15 | /// @notice Returns PoolKey: the ordered tokens with the matched fee levels 16 | /// @param tokenA The first token of a pool, unsorted 17 | /// @param tokenB The second token of a pool, unsorted 18 | /// @param fee The fee level of the pool 19 | /// @return Poolkey The pool details with ordered token0 and token1 assignments 20 | function getPoolKey( 21 | address tokenA, 22 | address tokenB, 23 | uint24 fee 24 | ) internal pure returns (PoolKey memory) { 25 | if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); 26 | return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); 27 | } 28 | 29 | /// @notice Deterministically computes the pool address given the factory and PoolKey 30 | /// @param factory The Uniswap V3 factory contract address 31 | /// @param key The PoolKey 32 | /// @return pool The contract address of the V3 pool 33 | function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { 34 | require(key.token0 < key.token1); 35 | pool = address( 36 | uint256( 37 | keccak256( 38 | abi.encodePacked( 39 | hex'ff', 40 | factory, 41 | keccak256(abi.encode(key.token0, key.token1, key.fee)), 42 | POOL_INIT_CODE_HASH 43 | ) 44 | ) 45 | ) 46 | ); 47 | } 48 | } -------------------------------------------------------------------------------- /contracts/external/utils/Context.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | /* 7 | * @dev Provides information about the current execution context, including the 8 | * sender of the transaction and its data. While these are generally available 9 | * via msg.sender and msg.data, they should not be accessed in such a direct 10 | * manner, since when dealing with meta-transactions the account sending and 11 | * paying for execution may not be the actual sender (as far as an application 12 | * is concerned). 13 | * 14 | * This contract is only required for intermediate, library-like contracts. 15 | */ 16 | abstract contract Context { 17 | function _msgSender() internal view virtual returns (address) { 18 | return msg.sender; 19 | } 20 | 21 | function _msgData() internal view virtual returns (bytes calldata) { 22 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 23 | return msg.data; 24 | } 25 | } -------------------------------------------------------------------------------- /contracts/external/utils/ERC165.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | import "../../intf/IERC165.sol"; 7 | 8 | /** 9 | * @dev Implementation of the {IERC165} interface. 10 | * 11 | * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check 12 | * for the additional interface id that will be supported. For example: 13 | * 14 | * ```solidity 15 | * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 16 | * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); 17 | * } 18 | * ``` 19 | * 20 | * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. 21 | */ 22 | abstract contract ERC165 is IERC165 { 23 | /** 24 | * @dev See {IERC165-supportsInterface}. 25 | */ 26 | function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { 27 | return interfaceId == type(IERC165).interfaceId; 28 | } 29 | } -------------------------------------------------------------------------------- /contracts/external/utils/Strings.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | /** 7 | * @dev String operations. 8 | */ 9 | library Strings { 10 | bytes16 private constant alphabet = "0123456789abcdef"; 11 | 12 | /** 13 | * @dev Converts a `uint256` to its ASCII `string` decimal representation. 14 | */ 15 | function toString(uint256 value) internal pure returns (string memory) { 16 | // Inspired by OraclizeAPI's implementation - MIT licence 17 | // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol 18 | 19 | if (value == 0) { 20 | return "0"; 21 | } 22 | uint256 temp = value; 23 | uint256 digits; 24 | while (temp != 0) { 25 | digits++; 26 | temp /= 10; 27 | } 28 | bytes memory buffer = new bytes(digits); 29 | while (value != 0) { 30 | digits -= 1; 31 | buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); 32 | value /= 10; 33 | } 34 | return string(buffer); 35 | } 36 | 37 | /** 38 | * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. 39 | */ 40 | function toHexString(uint256 value) internal pure returns (string memory) { 41 | if (value == 0) { 42 | return "0x00"; 43 | } 44 | uint256 temp = value; 45 | uint256 length = 0; 46 | while (temp != 0) { 47 | length++; 48 | temp >>= 8; 49 | } 50 | return toHexString(value, length); 51 | } 52 | 53 | /** 54 | * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. 55 | */ 56 | function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { 57 | bytes memory buffer = new bytes(2 * length + 2); 58 | buffer[0] = "0"; 59 | buffer[1] = "x"; 60 | for (uint256 i = 2 * length + 1; i > 1; --i) { 61 | buffer[i] = alphabet[value & 0xf]; 62 | value >>= 4; 63 | } 64 | require(value == 0, "Strings: hex length insufficient"); 65 | return string(buffer); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /contracts/helper/ERC20Helper.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IERC20ForCheck { 11 | function decimals() external view returns (uint); 12 | function name() external view returns (string memory); 13 | function symbol() external view returns (string memory); 14 | 15 | function balanceOf(address account) external view returns (uint256); 16 | function allowance(address owner, address spender) external view returns (uint256); 17 | } 18 | 19 | interface IOldERC20ForCheck { 20 | function decimals() external view returns (uint); 21 | function name() external view returns (bytes32); 22 | function symbol() external view returns (bytes32); 23 | 24 | function balanceOf(address account) external view returns (uint256); 25 | function allowance(address owner, address spender) external view returns (uint256); 26 | } 27 | 28 | 29 | contract ERC20Helper { 30 | function isERC20(address token, address user, address spender) external view returns(bool isOk, string memory symbol, string memory name, uint decimals, uint256 balance, uint256 allownance) { 31 | try this.judgeERC20(token, user, spender) returns (string memory _symbol, string memory _name, uint _decimals, uint256 _balance, uint256 _allownance) { 32 | symbol = _symbol; 33 | name = _name; 34 | decimals = _decimals; 35 | balance = _balance; 36 | allownance = _allownance; 37 | isOk = true; 38 | } catch { 39 | try this.judgeOldERC20(token, user, spender) returns (bytes32 _symbol, bytes32 _name, uint _decimals, uint256 _balance, uint256 _allownance) { 40 | symbol = bytes32ToString(_symbol); 41 | name = bytes32ToString(_name); 42 | decimals = _decimals; 43 | balance = _balance; 44 | allownance = _allownance; 45 | isOk = true; 46 | } catch { 47 | isOk = false; 48 | } 49 | } 50 | } 51 | 52 | function judgeERC20(address token, address user, address spender) external view returns(string memory symbol, string memory name, uint decimals, uint256 balance, uint256 allownance) { 53 | name = IERC20ForCheck(token).name(); 54 | symbol = IERC20ForCheck(token).symbol(); 55 | decimals = IERC20ForCheck(token).decimals(); 56 | 57 | balance = IERC20ForCheck(token).balanceOf(user); 58 | allownance = IERC20ForCheck(token).allowance(user,spender); 59 | } 60 | 61 | function judgeOldERC20(address token, address user, address spender) external view returns(bytes32 symbol, bytes32 name, uint decimals, uint256 balance, uint256 allownance) { 62 | name = IOldERC20ForCheck(token).name(); 63 | symbol = IOldERC20ForCheck(token).symbol(); 64 | decimals = IOldERC20ForCheck(token).decimals(); 65 | 66 | balance = IOldERC20ForCheck(token).balanceOf(user); 67 | allownance = IOldERC20ForCheck(token).allowance(user,spender); 68 | } 69 | 70 | function bytes32ToString(bytes32 _bytes) public pure returns (string memory _string) { 71 | _string = string(abi.encodePacked(_bytes)); 72 | } 73 | } -------------------------------------------------------------------------------- /contracts/helper/Migrations.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | 12 | contract Migrations { 13 | address public owner; 14 | uint256 public last_completed_migration; 15 | 16 | modifier restricted() { 17 | if (msg.sender == owner) { 18 | _; 19 | } 20 | } 21 | 22 | constructor() public { 23 | owner = msg.sender; 24 | } 25 | 26 | function setCompleted(uint256 completed) public restricted { 27 | last_completed_migration = completed; 28 | } 29 | 30 | function upgrade(address newAddress) public restricted { 31 | Migrations upgraded = Migrations(newAddress); 32 | upgraded.setCompleted(last_completed_migration); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/helper/NaiveOracle.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {Ownable} from "../lib/Ownable.sol"; 12 | 13 | 14 | // Oracle only for test 15 | contract NaiveOracle is Ownable { 16 | uint256 public tokenPrice; 17 | 18 | function setPrice(uint256 newPrice) external onlyOwner { 19 | tokenPrice = newPrice; 20 | } 21 | 22 | function getPrice() external view returns (uint256) { 23 | return tokenPrice; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/intf/IDODOApprove.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IDODOApprove { 11 | function claimTokens(address token,address who,address dest,uint256 amount) external; 12 | function getDODOProxy() external view returns (address); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/intf/IDODOApproveProxy.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IDODOApproveProxy { 11 | function isAllowedProxy(address _proxy) external view returns (bool); 12 | function claimTokens(address token,address who,address dest,uint256 amount) external; 13 | } 14 | -------------------------------------------------------------------------------- /contracts/intf/IDODOCallee.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface IDODOCallee { 12 | function DVMSellShareCall( 13 | address sender, 14 | uint256 burnShareAmount, 15 | uint256 baseAmount, 16 | uint256 quoteAmount, 17 | bytes calldata data 18 | ) external; 19 | 20 | function DVMFlashLoanCall( 21 | address sender, 22 | uint256 baseAmount, 23 | uint256 quoteAmount, 24 | bytes calldata data 25 | ) external; 26 | 27 | function DPPFlashLoanCall( 28 | address sender, 29 | uint256 baseAmount, 30 | uint256 quoteAmount, 31 | bytes calldata data 32 | ) external; 33 | 34 | function DSPFlashLoanCall( 35 | address sender, 36 | uint256 baseAmount, 37 | uint256 quoteAmount, 38 | bytes calldata data 39 | ) external; 40 | 41 | function CPCancelCall( 42 | address sender, 43 | uint256 amount, 44 | bytes calldata data 45 | ) external; 46 | 47 | function CPClaimBidCall( 48 | address sender, 49 | uint256 baseAmount, 50 | uint256 quoteAmount, 51 | bytes calldata data 52 | ) external; 53 | 54 | function NFTRedeemCall( 55 | address payable assetTo, 56 | uint256 quoteAmount, 57 | bytes calldata 58 | ) external; 59 | } 60 | -------------------------------------------------------------------------------- /contracts/intf/IDODONFTApprove.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2021 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IDODONFTApprove { 11 | function isAllowedProxy(address _proxy) external view returns (bool); 12 | 13 | function claimERC721(address nftContract, address who, address dest, uint256 tokenId) external; 14 | 15 | function claimERC1155(address nftContract, address who, address dest, uint256 tokenId, uint256 amount) external; 16 | 17 | function claimERC1155Batch(address nftContract, address who, address dest, uint256[] memory tokenIds, uint256[] memory amounts) external; 18 | } 19 | -------------------------------------------------------------------------------- /contracts/intf/IERC1155MetadataURI.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | import "./IERC1155.sol"; 7 | 8 | /** 9 | * @dev Interface of the optional ERC1155MetadataExtension interface, as defined 10 | * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. 11 | * 12 | * _Available since v3.1._ 13 | */ 14 | interface IERC1155MetadataURI is IERC1155 { 15 | /** 16 | * @dev Returns the URI for token type `id`. 17 | * 18 | * If the `\{id\}` substring is present in the URI, it must be replaced by 19 | * clients with the actual token type ID. 20 | */ 21 | function uri(uint256 id) external view returns (string memory); 22 | } -------------------------------------------------------------------------------- /contracts/intf/IERC1155Receiver.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC1155/IERC1155Receiver.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | import "./IERC165.sol"; 7 | 8 | /** 9 | * _Available since v3.1._ 10 | */ 11 | interface IERC1155Receiver is IERC165 { 12 | /** 13 | @dev Handles the receipt of a single ERC1155 token type. This function is 14 | called at the end of a `safeTransferFrom` after the balance has been updated. 15 | To accept the transfer, this must return 16 | `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` 17 | (i.e. 0xf23a6e61, or its own function selector). 18 | @param operator The address which initiated the transfer (i.e. msg.sender) 19 | @param from The address which previously owned the token 20 | @param id The ID of the token being transferred 21 | @param value The amount of tokens being transferred 22 | @param data Additional data with no specified format 23 | @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed 24 | */ 25 | function onERC1155Received( 26 | address operator, 27 | address from, 28 | uint256 id, 29 | uint256 value, 30 | bytes calldata data 31 | ) external returns (bytes4); 32 | 33 | /** 34 | @dev Handles the receipt of a multiple ERC1155 token types. This function 35 | is called at the end of a `safeBatchTransferFrom` after the balances have 36 | been updated. To accept the transfer(s), this must return 37 | `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` 38 | (i.e. 0xbc197c81, or its own function selector). 39 | @param operator The address which initiated the batch transfer (i.e. msg.sender) 40 | @param from The address which previously owned the token 41 | @param ids An array containing ids of each token being transferred (order and length must match values array) 42 | @param values An array containing amounts of each token being transferred (order and length must match ids array) 43 | @param data Additional data with no specified format 44 | @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed 45 | */ 46 | function onERC1155BatchReceived( 47 | address operator, 48 | address from, 49 | uint256[] calldata ids, 50 | uint256[] calldata values, 51 | bytes calldata data 52 | ) external returns (bytes4); 53 | } 54 | -------------------------------------------------------------------------------- /contracts/intf/IERC165.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/introspection/IERC165.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | /** 7 | * @dev Interface of the ERC165 standard, as defined in the 8 | * https://eips.ethereum.org/EIPS/eip-165[EIP]. 9 | * 10 | * Implementers can declare support of contract interfaces, which can then be 11 | * queried by others ({ERC165Checker}). 12 | * 13 | * For an implementation, see {ERC165}. 14 | */ 15 | interface IERC165 { 16 | /** 17 | * @dev Returns true if this contract implements the interface defined by 18 | * `interfaceId`. See the corresponding 19 | * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] 20 | * to learn more about how these ids are created. 21 | * 22 | * This function call must use less than 30 000 gas. 23 | */ 24 | function supportsInterface(bytes4 interfaceId) external view returns (bool); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/intf/IERC20.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | pragma experimental ABIEncoderV2; 6 | 7 | /** 8 | * @dev Interface of the ERC20 standard as defined in the EIP. 9 | */ 10 | interface IERC20 { 11 | /** 12 | * @dev Returns the amount of tokens in existence. 13 | */ 14 | function totalSupply() external view returns (uint256); 15 | 16 | function decimals() external view returns (uint8); 17 | 18 | function name() external view returns (string memory); 19 | 20 | function symbol() external view returns (string memory); 21 | 22 | /** 23 | * @dev Returns the amount of tokens owned by `account`. 24 | */ 25 | function balanceOf(address account) external view returns (uint256); 26 | 27 | /** 28 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 29 | * 30 | * Returns a boolean value indicating whether the operation succeeded. 31 | * 32 | * Emits a {Transfer} event. 33 | */ 34 | function transfer(address recipient, uint256 amount) external returns (bool); 35 | 36 | /** 37 | * @dev Returns the remaining number of tokens that `spender` will be 38 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 39 | * zero by default. 40 | * 41 | * This value changes when {approve} or {transferFrom} are called. 42 | */ 43 | function allowance(address owner, address spender) external view returns (uint256); 44 | 45 | /** 46 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 47 | * 48 | * Returns a boolean value indicating whether the operation succeeded. 49 | * 50 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 51 | * that someone may use both the old and the new allowance by unfortunate 52 | * transaction ordering. One possible solution to mitigate this race 53 | * condition is to first reduce the spender's allowance to 0 and set the 54 | * desired value afterwards: 55 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 56 | * 57 | * Emits an {Approval} event. 58 | */ 59 | function approve(address spender, uint256 amount) external returns (bool); 60 | 61 | /** 62 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 63 | * allowance mechanism. `amount` is then deducted from the caller's 64 | * allowance. 65 | * 66 | * Returns a boolean value indicating whether the operation succeeded. 67 | * 68 | * Emits a {Transfer} event. 69 | */ 70 | function transferFrom( 71 | address sender, 72 | address recipient, 73 | uint256 amount 74 | ) external returns (bool); 75 | } -------------------------------------------------------------------------------- /contracts/intf/IERC721Enumerable.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Enumerable.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | import "./IERC165.sol"; 7 | import "./IERC721.sol"; 8 | 9 | 10 | /** 11 | * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension 12 | * @dev See https://eips.ethereum.org/EIPS/eip-721 13 | */ 14 | interface IERC721Enumerable is IERC721 { 15 | 16 | /** 17 | * @dev Returns the total amount of tokens stored by the contract. 18 | */ 19 | function totalSupply() external view returns (uint256); 20 | 21 | /** 22 | * @dev Returns a token ID owned by `owner` at a given `index` of its token list. 23 | * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. 24 | */ 25 | function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); 26 | 27 | /** 28 | * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. 29 | * Use along with {totalSupply} to enumerate all tokens. 30 | */ 31 | function tokenByIndex(uint256 index) external view returns (uint256); 32 | } -------------------------------------------------------------------------------- /contracts/intf/IERC721Metadata.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | import "./IERC721.sol"; 7 | 8 | /** 9 | * @title ERC-721 Non-Fungible Token Standard, optional metadata extension 10 | * @dev See https://eips.ethereum.org/EIPS/eip-721 11 | */ 12 | interface IERC721Metadata is IERC721 { 13 | 14 | /** 15 | * @dev Returns the token collection name. 16 | */ 17 | function name() external view returns (string memory); 18 | 19 | /** 20 | * @dev Returns the token collection symbol. 21 | */ 22 | function symbol() external view returns (string memory); 23 | 24 | /** 25 | * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. 26 | */ 27 | function tokenURI(uint256 tokenId) external view returns (string memory); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/intf/IERC721Receiver.sol: -------------------------------------------------------------------------------- 1 | // This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/solc-0.6/contracts/token/ERC721/IERC721Receiver.sol 2 | // SPDX-License-Identifier: MIT 3 | 4 | pragma solidity 0.6.9; 5 | 6 | /** 7 | * @title ERC721 token receiver interface 8 | * @dev Interface for any contract that wants to support safeTransfers 9 | * from ERC721 asset contracts. 10 | */ 11 | interface IERC721Receiver { 12 | /** 13 | * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} 14 | * by `operator` from `from`, this function is called. 15 | * 16 | * It must return its Solidity selector to confirm the token transfer. 17 | * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. 18 | * 19 | * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. 20 | */ 21 | function onERC721Received( 22 | address operator, 23 | address from, 24 | uint256 tokenId, 25 | bytes calldata data 26 | ) external returns (bytes4); 27 | } 28 | -------------------------------------------------------------------------------- /contracts/intf/IFeeDistributor.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IFeeDistributor { 11 | function init( 12 | address baseToken, 13 | address quoteToken, 14 | address stakeToken 15 | ) external; 16 | 17 | function stake(address to) external; 18 | 19 | function _STAKE_TOKEN_() external view returns(address); 20 | 21 | function _STAKE_VAULT_() external view returns(address); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /contracts/intf/IOracle.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | 12 | interface IOracle { 13 | function getPrice() external view returns (uint256); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/intf/IWETH.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | 12 | interface IWETH { 13 | function totalSupply() external view returns (uint256); 14 | 15 | function balanceOf(address account) external view returns (uint256); 16 | 17 | function transfer(address recipient, uint256 amount) external returns (bool); 18 | 19 | function allowance(address owner, address spender) external view returns (uint256); 20 | 21 | function approve(address spender, uint256 amount) external returns (bool); 22 | 23 | function transferFrom( 24 | address src, 25 | address dst, 26 | uint256 wad 27 | ) external returns (bool); 28 | 29 | function deposit() external payable; 30 | 31 | function withdraw(uint256 wad) external; 32 | } 33 | -------------------------------------------------------------------------------- /contracts/lib/CloneFactory.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | interface ICloneFactory { 12 | function clone(address prototype) external returns (address proxy); 13 | } 14 | 15 | // introduction of proxy mode design: https://docs.openzeppelin.com/upgrades/2.8/ 16 | // minimum implementation of transparent proxy: https://eips.ethereum.org/EIPS/eip-1167 17 | 18 | contract CloneFactory is ICloneFactory { 19 | function clone(address prototype) external override returns (address proxy) { 20 | bytes20 targetBytes = bytes20(prototype); 21 | assembly { 22 | let clone := mload(0x40) 23 | mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000) 24 | mstore(add(clone, 0x14), targetBytes) 25 | mstore( 26 | add(clone, 0x28), 27 | 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000 28 | ) 29 | proxy := create(0, clone, 0x37) 30 | } 31 | return proxy; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/lib/ConstFeeRateModel.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IConstFeeRateModel { 11 | function init(uint256 feeRate) external; 12 | 13 | function getFeeRate(address) external view returns (uint256); 14 | } 15 | 16 | contract ConstFeeRateModel { 17 | uint256 public _FEE_RATE_; 18 | 19 | function init(uint256 feeRate) external { 20 | _FEE_RATE_ = feeRate; 21 | } 22 | 23 | function getFeeRate(address) external view returns (uint256) { 24 | return _FEE_RATE_; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /contracts/lib/DecimalMath.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {SafeMath} from "./SafeMath.sol"; 12 | 13 | /** 14 | * @title DecimalMath 15 | * @author DODO Breeder 16 | * 17 | * @notice Functions for fixed point number with 18 decimals 18 | */ 19 | library DecimalMath { 20 | using SafeMath for uint256; 21 | 22 | uint256 internal constant ONE = 10**18; 23 | uint256 internal constant ONE2 = 10**36; 24 | 25 | function mulFloor(uint256 target, uint256 d) internal pure returns (uint256) { 26 | return target.mul(d) / (10**18); 27 | } 28 | 29 | function mulCeil(uint256 target, uint256 d) internal pure returns (uint256) { 30 | return target.mul(d).divCeil(10**18); 31 | } 32 | 33 | function divFloor(uint256 target, uint256 d) internal pure returns (uint256) { 34 | return target.mul(10**18).div(d); 35 | } 36 | 37 | function divCeil(uint256 target, uint256 d) internal pure returns (uint256) { 38 | return target.mul(10**18).divCeil(d); 39 | } 40 | 41 | function reciprocalFloor(uint256 target) internal pure returns (uint256) { 42 | return uint256(10**36).div(target); 43 | } 44 | 45 | function reciprocalCeil(uint256 target) internal pure returns (uint256) { 46 | return uint256(10**36).divCeil(target); 47 | } 48 | 49 | function powFloor(uint256 target, uint256 e) internal pure returns (uint256) { 50 | if (e == 0) { 51 | return 10 ** 18; 52 | } else if (e == 1) { 53 | return target; 54 | } else { 55 | uint p = powFloor(target, e.div(2)); 56 | p = p.mul(p) / (10**18); 57 | if (e % 2 == 1) { 58 | p = p.mul(target) / (10**18); 59 | } 60 | return p; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/lib/ExternalValue.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 12 | 13 | interface IExternalValue { 14 | function init(address owner, uint256 value) external; 15 | function set(uint256 value) external; 16 | function get() external view returns (uint256); 17 | } 18 | 19 | 20 | contract ExternalValue is InitializableOwnable { 21 | uint256 public _VALUE_; 22 | 23 | function init(address owner, uint256 value) external { 24 | initOwner(owner); 25 | _VALUE_ = value; 26 | } 27 | 28 | function set(uint256 value) external onlyOwner { 29 | _VALUE_ = value; 30 | } 31 | 32 | function get() external view returns (uint256) { 33 | return _VALUE_; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/lib/FeeRateModel.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {InitializableOwnable} from "../lib/InitializableOwnable.sol"; 12 | 13 | interface IFeeRateImpl { 14 | function getFeeRate(address pool, address trader) external view returns (uint256); 15 | } 16 | 17 | interface IFeeRateModel { 18 | function getFeeRate(address trader) external view returns (uint256); 19 | } 20 | 21 | contract FeeRateModel is InitializableOwnable { 22 | address public feeRateImpl; 23 | 24 | function setFeeProxy(address _feeRateImpl) public onlyOwner { 25 | feeRateImpl = _feeRateImpl; 26 | } 27 | 28 | function getFeeRate(address trader) external view returns (uint256) { 29 | if(feeRateImpl == address(0)) 30 | return 0; 31 | return IFeeRateImpl(feeRateImpl).getFeeRate(msg.sender,trader); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/lib/InitializableOwnable.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | /** 12 | * @title Ownable 13 | * @author DODO Breeder 14 | * 15 | * @notice Ownership related functions 16 | */ 17 | contract InitializableOwnable { 18 | address public _OWNER_; 19 | address public _NEW_OWNER_; 20 | bool internal _INITIALIZED_; 21 | 22 | // ============ Events ============ 23 | 24 | event OwnershipTransferPrepared(address indexed previousOwner, address indexed newOwner); 25 | 26 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 27 | 28 | // ============ Modifiers ============ 29 | 30 | modifier notInitialized() { 31 | require(!_INITIALIZED_, "DODO_INITIALIZED"); 32 | _; 33 | } 34 | 35 | modifier onlyOwner() { 36 | require(msg.sender == _OWNER_, "NOT_OWNER"); 37 | _; 38 | } 39 | 40 | // ============ Functions ============ 41 | 42 | function initOwner(address newOwner) public notInitialized { 43 | _INITIALIZED_ = true; 44 | _OWNER_ = newOwner; 45 | } 46 | 47 | function transferOwnership(address newOwner) public onlyOwner { 48 | emit OwnershipTransferPrepared(_OWNER_, newOwner); 49 | _NEW_OWNER_ = newOwner; 50 | } 51 | 52 | function claimOwnership() public { 53 | require(msg.sender == _NEW_OWNER_, "INVALID_CLAIM"); 54 | emit OwnershipTransferred(_OWNER_, _NEW_OWNER_); 55 | _OWNER_ = _NEW_OWNER_; 56 | _NEW_OWNER_ = address(0); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /contracts/lib/Ownable.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | /** 12 | * @title Ownable 13 | * @author DODO Breeder 14 | * 15 | * @notice Ownership related functions 16 | */ 17 | contract Ownable { 18 | address public _OWNER_; 19 | address public _NEW_OWNER_; 20 | 21 | // ============ Events ============ 22 | 23 | event OwnershipTransferPrepared(address indexed previousOwner, address indexed newOwner); 24 | 25 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 26 | 27 | // ============ Modifiers ============ 28 | 29 | modifier onlyOwner() { 30 | require(msg.sender == _OWNER_, "NOT_OWNER"); 31 | _; 32 | } 33 | 34 | // ============ Functions ============ 35 | 36 | constructor() internal { 37 | _OWNER_ = msg.sender; 38 | emit OwnershipTransferred(address(0), _OWNER_); 39 | } 40 | 41 | function transferOwnership(address newOwner) external virtual onlyOwner { 42 | emit OwnershipTransferPrepared(_OWNER_, newOwner); 43 | _NEW_OWNER_ = newOwner; 44 | } 45 | 46 | function claimOwnership() external { 47 | require(msg.sender == _NEW_OWNER_, "INVALID_CLAIM"); 48 | emit OwnershipTransferred(_OWNER_, _NEW_OWNER_); 49 | _OWNER_ = _NEW_OWNER_; 50 | _NEW_OWNER_ = address(0); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /contracts/lib/PermissionManager.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | import {InitializableOwnable} from "./InitializableOwnable.sol"; 12 | 13 | interface IPermissionManager { 14 | function initOwner(address) external; 15 | 16 | function isAllowed(address) external view returns (bool); 17 | } 18 | 19 | contract PermissionManager is InitializableOwnable { 20 | bool public _WHITELIST_MODE_ON_; 21 | 22 | mapping(address => bool) internal _whitelist_; 23 | mapping(address => bool) internal _blacklist_; 24 | 25 | function isAllowed(address account) external view returns (bool) { 26 | if (_WHITELIST_MODE_ON_) { 27 | return _whitelist_[account]; 28 | } else { 29 | return !_blacklist_[account]; 30 | } 31 | } 32 | 33 | function openBlacklistMode() external onlyOwner { 34 | _WHITELIST_MODE_ON_ = false; 35 | } 36 | 37 | function openWhitelistMode() external onlyOwner { 38 | _WHITELIST_MODE_ON_ = true; 39 | } 40 | 41 | function addToWhitelist(address account) external onlyOwner { 42 | _whitelist_[account] = true; 43 | } 44 | 45 | function removeFromWhitelist(address account) external onlyOwner { 46 | _whitelist_[account] = false; 47 | } 48 | 49 | function addToBlacklist(address account) external onlyOwner { 50 | _blacklist_[account] = true; 51 | } 52 | 53 | function removeFromBlacklist(address account) external onlyOwner { 54 | _blacklist_[account] = false; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/lib/RandomGenerator.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | 10 | interface IRandomGenerator { 11 | function random(uint256 seed) external view returns (uint256); 12 | } 13 | 14 | interface IDODOMidPrice { 15 | function getMidPrice() external view returns (uint256 midPrice); 16 | } 17 | 18 | contract RandomGenerator is IRandomGenerator{ 19 | address[] public pools; 20 | 21 | constructor(address[] memory _pools) public { 22 | for (uint256 i = 0; i < _pools.length; i++) { 23 | pools.push(_pools[i]); 24 | } 25 | } 26 | 27 | function random(uint256 seed) external override view returns (uint256) { 28 | uint256 priceSum; 29 | for (uint256 i = 0; i < pools.length; i++) { 30 | priceSum += IDODOMidPrice(pools[i]).getMidPrice(); 31 | } 32 | return uint256(keccak256(abi.encodePacked(blockhash(block.number-1), priceSum, seed))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/lib/ReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | /** 12 | * @title ReentrancyGuard 13 | * @author DODO Breeder 14 | * 15 | * @notice Protect functions from Reentrancy Attack 16 | */ 17 | contract ReentrancyGuard { 18 | // https://solidity.readthedocs.io/en/latest/control-structures.html?highlight=zero-state#scoping-and-declarations 19 | // zero-state of _ENTERED_ is false 20 | bool private _ENTERED_; 21 | 22 | modifier preventReentrant() { 23 | require(!_ENTERED_, "REENTRANT"); 24 | _ENTERED_ = true; 25 | _; 26 | _ENTERED_ = false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /contracts/lib/SafeMath.sol: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | pragma solidity 0.6.9; 9 | pragma experimental ABIEncoderV2; 10 | 11 | 12 | /** 13 | * @title SafeMath 14 | * @author DODO Breeder 15 | * 16 | * @notice Math operations with safety checks that revert on error 17 | */ 18 | library SafeMath { 19 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 20 | if (a == 0) { 21 | return 0; 22 | } 23 | 24 | uint256 c = a * b; 25 | require(c / a == b, "MUL_ERROR"); 26 | 27 | return c; 28 | } 29 | 30 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 31 | require(b > 0, "DIVIDING_ERROR"); 32 | return a / b; 33 | } 34 | 35 | function divCeil(uint256 a, uint256 b) internal pure returns (uint256) { 36 | uint256 quotient = div(a, b); 37 | uint256 remainder = a - quotient * b; 38 | if (remainder > 0) { 39 | return quotient + 1; 40 | } else { 41 | return quotient; 42 | } 43 | } 44 | 45 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 46 | require(b <= a, "SUB_ERROR"); 47 | return a - b; 48 | } 49 | 50 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 51 | uint256 c = a + b; 52 | require(c >= a, "ADD_ERROR"); 53 | return c; 54 | } 55 | 56 | function sqrt(uint256 x) internal pure returns (uint256 y) { 57 | uint256 z = x / 2 + 1; 58 | y = x; 59 | while (z < y) { 60 | y = z; 61 | z = (x / z + z) / 2; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /immunefibugbounty.md: -------------------------------------------------------------------------------- 1 | ## Immunefi Bug Bounty for DODO 2 | 3 | This bug bounty document is to verify that [DODO] hosts a bug bounty on Immunefi at the address https://immunefi.com/bounty/dodo/ 4 | 5 | If you have found a vulnerability in our project, it must be submitted through Immunefi's platform. Immunefi will handle bug bounty communications. 6 | 7 | See the bounty page at Immunefi for more details on accepted vulnerabilities, payout amounts, and rules of participation. 8 | 9 | Users who violate the rules of participation will not receive bug bounty payouts and may be temporarily suspended or banned from the bug bounty program. 10 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations"); 2 | 3 | module.exports = function (deployer) { 4 | // deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /migrations/2_deploy_erc20V3.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const { deploySwitch } = require('../truffle-config.js') 3 | const file = fs.createWriteStream("../deploy-detail-erc20V3.txt", { 'flags': 'a' }); 4 | let logger = new console.Console(file, file); 5 | const { GetConfig } = require("../configAdapter.js") 6 | 7 | const ERC20V3Factory = artifacts.require("ERC20V3Factory"); 8 | const CustomERC20 = artifacts.require("CustomERC20"); 9 | const CustomMintableERC20 = artifacts.require("CustomMintableERC20"); 10 | 11 | 12 | module.exports = async (deployer, network, accounts) => { 13 | let CONFIG = GetConfig(network, accounts) 14 | let CloneFactoryAddress = CONFIG.CloneFactory; 15 | let ERC20Address = CONFIG.ERC20; 16 | if (CONFIG == null || ERC20Address == "") return; 17 | 18 | let ERC20V3FactoryAddress = CONFIG.ERC20V3Factory; 19 | let CustomERC20Address = CONFIG.CustomERC20; 20 | let CustomMintableERC20Address = CONFIG.CustomMintableERC20; 21 | 22 | let multiSigAddress = CONFIG.multiSigAddress; 23 | 24 | if (deploySwitch.ERC20V3Factory) { 25 | logger.log("===================================================="); 26 | logger.log("network type: " + network); 27 | logger.log("Deploy time: " + new Date().toLocaleString()); 28 | logger.log("Deploy type: ERC20V3Factory"); 29 | 30 | 31 | if (CustomERC20Address == "") { 32 | await deployer.deploy(CustomERC20); 33 | CustomERC20Address = CustomERC20.address; 34 | logger.log("CustomERC20Address: ", CustomERC20Address); 35 | } 36 | 37 | if (CustomMintableERC20Address == "") { 38 | await deployer.deploy(CustomMintableERC20); 39 | CustomMintableERC20Address = CustomMintableERC20.address; 40 | logger.log("CustomMintableERC20Address: ", CustomMintableERC20Address); 41 | } 42 | 43 | 44 | if (ERC20V3FactoryAddress == "") { 45 | await deployer.deploy( 46 | ERC20V3Factory, 47 | CloneFactoryAddress, 48 | ERC20Address, 49 | CustomERC20Address, 50 | CustomMintableERC20Address, 51 | "2000000000000000" //0.002 52 | ); 53 | ERC20V3FactoryAddress = ERC20V3Factory.address; 54 | logger.log("ERC20V3FactoryAddress: ", ERC20V3FactoryAddress); 55 | 56 | const erc20V3FactoryInstance = await ERC20V3Factory.at(ERC20V3FactoryAddress); 57 | var tx = await erc20V3FactoryInstance.initOwner(multiSigAddress); 58 | logger.log("Init ERC20V3Factory Tx:", tx.tx); 59 | } 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dodo", 3 | "version": "1.0.0", 4 | "description": "a kind of bird", 5 | "main": "index.js", 6 | "author": "dodo breeder", 7 | "license": "Apache-2.0", 8 | "keywords": [ 9 | "dodo", 10 | "ethereum", 11 | "pmm" 12 | ], 13 | "scripts": { 14 | "prettier": "prettier --write **/*.sol", 15 | "migrate": "truffle migrate", 16 | "compile": "rm -r build && truffle compile", 17 | "coverage": "NETWORK_ID=1002 RPC_NODE_URI=http://127.0.0.1:6545 COVERAGE=true truffle run coverage", 18 | "test": "truffle compile && truffle test", 19 | "test_only": "truffle test", 20 | "deploy": "truffle migrate --network=$NETWORK --reset", 21 | "deploy_kovan": "NETWORK=kovan npm run deploy", 22 | "deploy_mainnet": "NETWORK=mainnet npm run deploy", 23 | "deploy_test": "NETWORK=development npm run deploy", 24 | "node": "ganache-cli --port 8545 -l 0x1fffffffffffff -i 5777 -g 1 --allowUnlimitedContractSize" 25 | }, 26 | "dependencies": { 27 | "@truffle/hdwallet-provider": "^1.7.0", 28 | "@types/chai": "^4.2.11", 29 | "@types/es6-promisify": "^6.0.0", 30 | "@types/ethereumjs-abi": "^0.6.3", 31 | "@types/mocha": "^7.0.2", 32 | "assert": "^2.0.0", 33 | "axios": "^0.24.0", 34 | "babel-cli": "^6.26.0", 35 | "babel-eslint": "^10.1.0", 36 | "bignumber.js": "^9.0.0", 37 | "chai-bignumber": "^3.0.0", 38 | "debug": "^4.1.1", 39 | "dotenv": "^16.4.5", 40 | "dotenv-flow": "^3.3.0", 41 | "es6-promisify": "^6.1.1", 42 | "ethereumjs-util": "^7.0.7", 43 | "ethjs": "^0.4.0", 44 | "lodash": "^4.17.20", 45 | "mocha": "^7.2.0", 46 | "solc": "^0.6.9", 47 | "truffle-hdwallet-provider": "^1.0.17", 48 | "ts-node": "^8.10.2", 49 | "typescript": "^3.9.5", 50 | "web3": "^1.2.8", 51 | "web3-core-helpers": "^1.2.8", 52 | "web3-eth-contract": "^1.2.8" 53 | }, 54 | "devDependencies": { 55 | "chai": "^4.2.0", 56 | "ganache-cli": "^6.9.1", 57 | "hardhat": "^2.22.2", 58 | "prettier": "^2.0.5", 59 | "prettier-plugin-solidity": "^1.0.0-alpha.52", 60 | "solidity-coverage": "^0.7.7", 61 | "truffle-assertions": "^0.9.2", 62 | "truffle-plugin-verify": "^0.5.33" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /test/CrowdPooling/CPBid.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | // import * as assert from 'assert'; 9 | 10 | import { decimalStr } from '../utils/Converter'; 11 | import { logGas } from '../utils/Log'; 12 | import { CPContext, CPContextInitConfig } from '../utils/CrowdPoolingContext'; 13 | import BigNumber from 'bignumber.js'; 14 | import { assert } from 'chai'; 15 | const truffleAssert = require('truffle-assertions'); 16 | 17 | let bidder1: string; 18 | let bidder2: string; 19 | let config: CPContextInitConfig 20 | 21 | async function init(ctx: CPContext): Promise { 22 | bidder1 = ctx.SpareAccounts[1] 23 | bidder2 = ctx.SpareAccounts[2] 24 | await ctx.QUOTE.methods.mint(bidder1, decimalStr("1000")).send(ctx.sendParam(ctx.Deployer)) 25 | await ctx.QUOTE.methods.mint(bidder2, decimalStr("1000")).send(ctx.sendParam(ctx.Deployer)) 26 | } 27 | 28 | describe("Funding", () => { 29 | let snapshotId: string; 30 | let ctx: CPContext; 31 | 32 | before(async () => { 33 | config = { 34 | totalBase: decimalStr("10000"), 35 | poolQuoteCap: decimalStr("50000"), 36 | k: decimalStr("0"), 37 | i: decimalStr("10"), 38 | lpFeeRate: decimalStr("0.002"), 39 | bidDuration: new BigNumber(86400), 40 | calmDuration: new BigNumber(86400), 41 | freezeDuration: new BigNumber(86400), 42 | vestingDuration: new BigNumber(86400), 43 | cliffRate: decimalStr("1"), 44 | quoteTokenContract:"", 45 | isOpenTWAP:true 46 | } 47 | ctx = new CPContext(); 48 | await ctx.init(config); 49 | await init(ctx); 50 | }); 51 | 52 | beforeEach(async () => { 53 | snapshotId = await ctx.EVM.snapshot(); 54 | }); 55 | 56 | afterEach(async () => { 57 | await ctx.EVM.reset(snapshotId); 58 | }); 59 | 60 | describe("bid & cancel", () => { 61 | 62 | it("bid and cancel", async () => { 63 | await ctx.QUOTE.methods.transfer(ctx.CP.options.address, decimalStr("100")).send(ctx.sendParam(bidder1)) 64 | await logGas(ctx.CP.methods.bid(bidder1), ctx.sendParam(bidder1), "bid") 65 | assert.equal(await ctx.CP.methods.getShares(bidder1).call(), decimalStr("100")) 66 | assert.equal(await ctx.CP.methods._TOTAL_SHARES_().call(), decimalStr("100")) 67 | assert.equal(await ctx.QUOTE.methods.balanceOf(ctx.Maintainer).call(), decimalStr("0")) 68 | 69 | await ctx.QUOTE.methods.transfer(ctx.CP.options.address, decimalStr("50")).send(ctx.sendParam(bidder2)) 70 | await ctx.CP.methods.bid(bidder2).send(ctx.sendParam(bidder2)) 71 | assert.equal(await ctx.CP.methods.getShares(bidder2).call(), decimalStr("50")) 72 | assert.equal(await ctx.CP.methods._TOTAL_SHARES_().call(), decimalStr("150")) 73 | assert.equal(await ctx.QUOTE.methods.balanceOf(ctx.Maintainer).call(), decimalStr("0")) 74 | 75 | await ctx.EVM.increaseTime(86400) 76 | await logGas(ctx.CP.methods.cancel(bidder1, decimalStr("20"),"0x"), ctx.sendParam(bidder1), "cancel") 77 | assert.equal(await ctx.CP.methods.getShares(bidder1).call(), decimalStr("80")) 78 | assert.equal(await ctx.CP.methods._TOTAL_SHARES_().call(), decimalStr("130")) 79 | assert.equal(await ctx.QUOTE.methods.balanceOf(bidder1).call(), decimalStr("920")) 80 | 81 | }) 82 | 83 | }) 84 | }) 85 | -------------------------------------------------------------------------------- /test/DPP/owner.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | // import * as assert from 'assert'; 9 | 10 | import { DPPContext, getDPPContext } from '../utils/DPPContext'; 11 | import { assert } from 'chai'; 12 | const truffleAssert = require('truffle-assertions'); 13 | 14 | async function init(ctx: DPPContext): Promise { } 15 | 16 | describe("Admin Set", () => { 17 | let snapshotId: string; 18 | let ctx: DPPContext; 19 | 20 | before(async () => { 21 | ctx = await getDPPContext(); 22 | await init(ctx); 23 | }); 24 | 25 | beforeEach(async () => { 26 | snapshotId = await ctx.EVM.snapshot(); 27 | }); 28 | 29 | afterEach(async () => { 30 | await ctx.EVM.reset(snapshotId); 31 | }); 32 | 33 | describe("setting", () => { 34 | 35 | it("get addresses", async () => { 36 | 37 | var tempAddress = ctx.SpareAccounts[0] 38 | 39 | assert.equal(await ctx.DPP.methods._MAINTAINER_().call(), tempAddress) 40 | 41 | }); 42 | 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /test/utils-v1/Converter.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import { getDefaultWeb3 } from './EVM'; 3 | 4 | export const MAX_UINT256 = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 5 | 6 | export function decimalStr(value: string): string { 7 | return new BigNumber(value).multipliedBy(10 ** 18).toFixed(0, BigNumber.ROUND_DOWN) 8 | } 9 | 10 | export function mweiStr(value: string): string { 11 | return new BigNumber(value).multipliedBy(10 ** 6).toFixed(0, BigNumber.ROUND_DOWN) 12 | } 13 | 14 | export function gweiStr(gwei: string): string { 15 | return new BigNumber(gwei).multipliedBy(10 ** 9).toFixed(0, BigNumber.ROUND_DOWN) 16 | } 17 | 18 | export function fromWei(value:string,unit:any): string { 19 | var web3 = getDefaultWeb3(); 20 | return web3.utils.fromWei(value,unit); 21 | } -------------------------------------------------------------------------------- /test/utils-v1/EVM.ts: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | // require('dotenv-flow').config(); 9 | 10 | import { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers'; 11 | import Web3 from 'web3'; 12 | 13 | export function getDefaultWeb3() { 14 | return new Web3(process.env.RPC_NODE_URI) 15 | } 16 | 17 | export class EVM { 18 | private provider = new Web3.providers.HttpProvider(process.env.RPC_NODE_URI); 19 | 20 | public async reset(id: string): Promise { 21 | if (!id) { 22 | throw new Error('id must be set'); 23 | } 24 | 25 | await this.callJsonrpcMethod('evm_revert', [id]); 26 | 27 | return this.snapshot(); 28 | } 29 | 30 | 31 | public async snapshot(): Promise { 32 | return this.callJsonrpcMethod('evm_snapshot'); 33 | } 34 | 35 | public async evmRevert(id: string): Promise { 36 | return this.callJsonrpcMethod('evm_revert', [id]); 37 | } 38 | 39 | public async stopMining(): Promise { 40 | return this.callJsonrpcMethod('miner_stop'); 41 | } 42 | 43 | public async startMining(): Promise { 44 | return this.callJsonrpcMethod('miner_start'); 45 | } 46 | 47 | public async mineBlock(): Promise { 48 | return this.callJsonrpcMethod('evm_mine'); 49 | } 50 | 51 | public async fastMove(moveBlockNum: number): Promise { 52 | var res: string 53 | for (let i = 0; i < moveBlockNum; i++) { 54 | res = await this.callJsonrpcMethod('evm_mine'); 55 | } 56 | return res 57 | } 58 | 59 | public async increaseTime(duration: number): Promise { 60 | await this.callJsonrpcMethod('evm_increaseTime', [duration]); 61 | return this.callJsonrpcMethod('evm_mine'); 62 | } 63 | 64 | public async callJsonrpcMethod(method: string, params?: (any[])): Promise { 65 | const args: JsonRpcPayload = { 66 | method, 67 | params, 68 | jsonrpc: '2.0', 69 | id: new Date().getTime(), 70 | }; 71 | 72 | const response = await this.send(args); 73 | 74 | return response.result; 75 | } 76 | 77 | private async send(args: JsonRpcPayload): Promise { 78 | return new Promise((resolve, reject) => { 79 | const callback: any = (error: Error, val: JsonRpcResponse): void => { 80 | if (error) { 81 | reject(error); 82 | } else { 83 | resolve(val); 84 | } 85 | }; 86 | 87 | this.provider.send( 88 | args, 89 | callback, 90 | ); 91 | }); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /test/utils-v1/Log.ts: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | export const blueText = x => `\x1b[36m${x}\x1b[0m`; 9 | export const yellowText = x => `\x1b[33m${x}\x1b[0m`; 10 | export const greenText = x => `\x1b[32m${x}\x1b[0m`; 11 | export const redText = x => `\x1b[31m${x}\x1b[0m`; 12 | export const numberWithCommas = x => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); 13 | 14 | export async function logGas(funcCall: any, params: any, desc: string) { 15 | const estimatedGas = await funcCall.estimateGas(params) 16 | const receipt = await funcCall.send(params) 17 | const gasUsed = receipt.gasUsed; 18 | let colorFn; 19 | 20 | if (gasUsed < 80000) { 21 | colorFn = greenText; 22 | } else if (gasUsed < 200000) { 23 | colorFn = yellowText; 24 | } else { 25 | colorFn = redText; 26 | } 27 | 28 | console.log(("Gas estimated:" + numberWithCommas(estimatedGas)).padEnd(60, '.'), blueText(desc) + " ", colorFn(numberWithCommas(gasUsed).padStart(5))); 29 | return receipt 30 | } -------------------------------------------------------------------------------- /test/utils/Converter.ts: -------------------------------------------------------------------------------- 1 | import BigNumber from "bignumber.js"; 2 | import { getDefaultWeb3 } from './EVM'; 3 | 4 | 5 | export const MAX_UINT256 = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 6 | 7 | export function decimalStr(value: string): string { 8 | return new BigNumber(value).multipliedBy(10 ** 18).toFixed(0, BigNumber.ROUND_DOWN) 9 | } 10 | 11 | export function gweiStr(gwei: string): string { 12 | return new BigNumber(gwei).multipliedBy(10 ** 9).toFixed(0, BigNumber.ROUND_DOWN) 13 | } 14 | 15 | export function mweiStr(gwei: string): string { 16 | return new BigNumber(gwei).multipliedBy(10 ** 6).toFixed(0, BigNumber.ROUND_DOWN) 17 | } 18 | 19 | export function fromWei(value: string, unit: any): string { 20 | var web3 = getDefaultWeb3(); 21 | return web3.utils.fromWei(value, unit); 22 | } -------------------------------------------------------------------------------- /test/utils/EVM.ts: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | // require('dotenv-flow').config(); 9 | 10 | import { JsonRpcPayload, JsonRpcResponse } from 'web3-core-helpers'; 11 | import Web3 from 'web3'; 12 | 13 | export function getDefaultWeb3() { 14 | return new Web3(process.env.RPC_NODE_URI) 15 | } 16 | 17 | export class EVM { 18 | private provider = new Web3.providers.HttpProvider(process.env.RPC_NODE_URI); 19 | 20 | public async reset(id: string): Promise { 21 | if (!id) { 22 | throw new Error('id must be set'); 23 | } 24 | 25 | await this.callJsonrpcMethod('evm_revert', [id]); 26 | 27 | return this.snapshot(); 28 | } 29 | 30 | public async snapshot(): Promise { 31 | return this.callJsonrpcMethod('evm_snapshot'); 32 | } 33 | 34 | public async evmRevert(id: string): Promise { 35 | return this.callJsonrpcMethod('evm_revert', [id]); 36 | } 37 | 38 | public async stopMining(): Promise { 39 | return this.callJsonrpcMethod('miner_stop'); 40 | } 41 | 42 | public async startMining(): Promise { 43 | return this.callJsonrpcMethod('miner_start'); 44 | } 45 | 46 | public async mineBlock(): Promise { 47 | return this.callJsonrpcMethod('evm_mine'); 48 | } 49 | 50 | public async fastMove(moveBlockNum: number): Promise { 51 | var res: string 52 | for (let i = 0; i < moveBlockNum; i++) { 53 | res = await this.callJsonrpcMethod('evm_mine'); 54 | } 55 | return res 56 | } 57 | 58 | public async increaseTime(duration: number): Promise { 59 | await this.callJsonrpcMethod('evm_increaseTime', [duration]); 60 | return this.callJsonrpcMethod('evm_mine'); 61 | } 62 | 63 | public async callJsonrpcMethod(method: string, params?: (any[])): Promise { 64 | const args: JsonRpcPayload = { 65 | method, 66 | params, 67 | jsonrpc: '2.0', 68 | id: new Date().getTime(), 69 | }; 70 | 71 | const response = await this.send(args); 72 | 73 | return response.result; 74 | } 75 | 76 | private async send(args: JsonRpcPayload): Promise { 77 | return new Promise((resolve, reject) => { 78 | const callback: any = (error: Error, val: JsonRpcResponse): void => { 79 | if (error) { 80 | reject(error); 81 | } else { 82 | resolve(val); 83 | } 84 | }; 85 | 86 | this.provider.send( 87 | args, 88 | callback, 89 | ); 90 | }); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /test/utils/Log.ts: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright 2020 DODO ZOO. 4 | SPDX-License-Identifier: Apache-2.0 5 | 6 | */ 7 | 8 | export const blueText = x => `\x1b[36m${x}\x1b[0m`; 9 | export const yellowText = x => `\x1b[33m${x}\x1b[0m`; 10 | export const greenText = x => `\x1b[32m${x}\x1b[0m`; 11 | export const redText = x => `\x1b[31m${x}\x1b[0m`; 12 | export const numberWithCommas = x => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); 13 | 14 | export async function logGas(funcCall: any, params: any, desc: string) { 15 | const estimatedGas = await funcCall.estimateGas(params) 16 | 17 | const receipt = await funcCall.send(params) 18 | const gasUsed = receipt.gasUsed; 19 | let colorFn; 20 | 21 | if (gasUsed < 80000) { 22 | colorFn = greenText; 23 | } else if (gasUsed < 200000) { 24 | colorFn = yellowText; 25 | } else { 26 | colorFn = redText; 27 | } 28 | 29 | console.log(("Gas estimated:" + numberWithCommas(estimatedGas)).padEnd(60, '.'), blueText(desc) + " ", colorFn(numberWithCommas(gasUsed).padStart(5))); 30 | return receipt 31 | } 32 | -------------------------------------------------------------------------------- /test/utils/SlippageFormula.ts: -------------------------------------------------------------------------------- 1 | function calculateSlippage(buyPercentage: number) { 2 | const k = 0.1 3 | console.log(buyPercentage, ":", ((1 / (1 - buyPercentage)) * k - k) * 100, "%") 4 | } 5 | 6 | function calculateLoss(priceGap: number) { 7 | const feeRate = 0.0025 8 | const k = 0.1 9 | let amountPartial = Math.sqrt(priceGap / k + 1) - 1 10 | let loss = amountPartial * (priceGap - feeRate * 2) 11 | console.log(priceGap, ":", loss * 100, "%") 12 | } 13 | 14 | // calculateSlippage(0.01) 15 | // calculateSlippage(0.05) 16 | // calculateSlippage(0.1) 17 | // calculateSlippage(0.2) 18 | // calculateSlippage(0.5) 19 | // calculateSlippage(0.7) 20 | 21 | // calculateLoss(0.006) 22 | // calculateLoss(0.007) 23 | // calculateLoss(0.008) 24 | // calculateLoss(0.009) 25 | // calculateLoss(0.01) 26 | // calculateLoss(0.02) 27 | // calculateLoss(0.03) -------------------------------------------------------------------------------- /truffle-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | truffle compile --all 3 | 4 | if [ "$1"x = "proxy-dpp"x ] 5 | then 6 | truffle test ./test/V2Proxy/proxy.dpp.test.ts 7 | fi 8 | 9 | if [ "$1"x = "proxy-dvm"x ] 10 | then 11 | truffle test ./test/V2Proxy/proxy.dvm.test.ts 12 | fi 13 | 14 | if [ "$1"x = "proxy-mix"x ] 15 | then 16 | truffle test ./test/V2Proxy/proxy.mix.test.ts 17 | fi 18 | 19 | if [ "$1"x = "proxy-classical"x ] 20 | then 21 | truffle test ./test/V2Proxy/proxy.classical.test.ts 22 | fi 23 | 24 | if [ "$1"x = "proxy-cp"x ] 25 | then 26 | truffle test ./test/V2Proxy/proxy.cp.test.ts 27 | fi 28 | 29 | if [ "$1"x = "proxy-incentive"x ] 30 | then 31 | truffle test ./test/V2Proxy/proxy.incentive.test.ts 32 | fi 33 | 34 | if [ "$1"x = "proxy-incentive-bsc"x ] 35 | then 36 | truffle test ./test/V2Proxy/proxy.incentive.bsc.test.ts 37 | fi 38 | 39 | if [ "$1"x = "proxy-twap"x ] 40 | then 41 | truffle test ./test/V2Proxy/proxy.twap.test.ts 42 | fi 43 | 44 | if [ "$1"x = "vdodo-mintRedeem"x ] 45 | then 46 | truffle test ./test/vDODO/mintRedeem.test.ts 47 | fi 48 | 49 | if [ "$1"x = "erc20-mine"x ] 50 | then 51 | truffle test ./test/DODOMineV2/erc20Mine.test.ts 52 | fi 53 | 54 | if [ "$1"x = "vdodo-mine"x ] 55 | then 56 | truffle test ./test/DODOMineV2/vDODOMine.test.ts 57 | fi 58 | 59 | if [ "$1"x = "nft"x ] 60 | then 61 | truffle test ./test/DODONFT/nftMainFlow.test.ts 62 | fi 63 | 64 | if [ "$1"x = "boxV1"x ] 65 | then 66 | truffle test ./test/DODONFT/mysteryBoxV1.test.ts 67 | fi 68 | 69 | if [ "$1"x = "boxV2"x ] 70 | then 71 | truffle test ./test/DODODrops/dropsV2.test.ts 72 | fi 73 | 74 | if [ "$1"x = "erc721NFTPool"x ] 75 | then 76 | truffle test ./test/NFTPool/erc721NftPool.test.ts 77 | fi 78 | 79 | if [ "$1"x = "erc1155NFTPool"x ] 80 | then 81 | truffle test ./test/NFTPool/erc1155NftPool.test.ts 82 | fi -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "lib": ["es2015", "es2016", "es2017", "dom"], 6 | "strict": false, 7 | "sourceMap": true, 8 | "declaration": true, 9 | "downlevelIteration": true, 10 | // "noUnusedLocals": true, 11 | "esModuleInterop": true, 12 | "outDir": "dist", 13 | "resolveJsonModule": true, 14 | "allowSyntheticDefaultImports": true, 15 | "typeRoots": ["node_modules/@types"], 16 | "types": ["node", "mocha", "chai"] 17 | }, 18 | "include": ["src", "test", "script"], 19 | "exclude": ["scripts/**/*", "build/**/*", "migrations/**/*"], 20 | "compileOnSave": true 21 | } 22 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["tslint-config-airbnb", "tslint-no-focused-test"], 3 | "rules": { 4 | "import-name": false, 5 | "no-floating-promises": true, 6 | "no-focused-test": true, 7 | "variable-name": [ 8 | true, 9 | "allow-pascal-case", 10 | "ban-keywords" 11 | ] 12 | } 13 | } 14 | --------------------------------------------------------------------------------