├── .gitignore ├── .waffle.json ├── LICENSE ├── README.md ├── buidler.config.ts ├── cache └── compilers │ └── list.json ├── contracts ├── BurgerMainToken.sol ├── DemaxDelegate.sol ├── DemaxFactory.sol ├── DemaxGovernance.sol ├── DemaxLP.sol ├── DemaxPair.sol ├── DemaxPool.sol ├── DemaxProjectConfig.sol ├── DemaxProjectDeploy.sol ├── DemaxProjectFactory.sol ├── DemaxProjectPool.sol ├── DemaxProjectQuery.sol ├── DemaxQuery.sol ├── DemaxQuery2.sol ├── DemaxQueryPair.sol ├── DemaxQueryPairWeigth.sol ├── DemaxTransferListener.sol ├── DemaxTrigger.sol ├── Dgas.sol ├── DgasHub.sol ├── backup.zip ├── ballots │ ├── DemaxBallot.sol │ └── DemaxBallotFactory.sol ├── demaxConfig.sol ├── demaxPlatform.sol ├── interfaces │ ├── ERC2917-Interface.sol │ ├── IDemaxBallot.sol │ ├── IDemaxBallotFactory.sol │ ├── IDemaxCallee.sol │ ├── IDemaxConfig.sol │ ├── IDemaxDelegate.sol │ ├── IDemaxFactory.sol │ ├── IDemaxGovernance.sol │ ├── IDemaxLP.sol │ ├── IDemaxPair.sol │ ├── IDemaxPool.sol │ ├── IDemaxTransferListener.sol │ ├── IDgas.sol │ ├── IERC20.sol │ ├── IERC2917.sol │ ├── ITokenRegistry.sol │ └── IWETH.sol ├── libraries │ ├── AddressStringUtil.sol │ ├── Babylonian.sol │ ├── ConfigNames.sol │ ├── DemaxSwapLibrary.sol │ ├── FixedPoint.sol │ ├── Math.sol │ ├── PairNamer.sol │ ├── SafeERC20Namer.sol │ ├── SafeMath.sol │ ├── TransferHelper.sol │ └── UQ112x112.sol ├── modules │ ├── BaseMintField.sol │ ├── BaseShareField.sol │ ├── BaseToken.sol │ ├── Configable.sol │ ├── Controller.sol │ ├── DgasStaking.sol │ ├── ERC20Token.sol │ ├── ERC2917Impl.sol │ ├── Governable.sol │ ├── Initializable.sol │ ├── Lock.sol │ ├── Ownable.sol │ ├── ProjectConfigable.sol │ ├── ReentrancyGuard.sol │ ├── SwitchFeature.sol │ ├── TokenRegistry.sol │ └── Upgradable.sol └── test │ ├── DeflatingERC20.sol │ ├── DemaxBallotTestToken.sol │ ├── DemaxConfigTest.sol │ ├── DemaxGovernanceTest.sol │ ├── DgasTest.sol │ ├── ERC20.sol │ ├── ERC20Factory.sol │ ├── ERC20ForFactory.sol │ ├── TERC20.sol │ ├── TokenQuery.sol │ ├── USDT.sol │ └── WETH9.sol ├── deploy ├── address.json ├── config.example.js ├── deploy.js ├── test.js └── upgrade.plateform.js ├── hardhat.config.ts ├── package-lock.json ├── package.json ├── scripts └── sample-script.js ├── test.sol ├── test ├── ConfigNames.spec.ts ├── DemaxBallot.spec.ts ├── DemaxBallotFactory.spec.ts ├── DemaxConfig.spec.ts ├── DemaxGovernance.spec.ts ├── DemaxTransferListener.spec.ts ├── Dgas.spec.ts ├── demaxPlatform.spec.ts ├── demaxPlatform.spec2.ts ├── shared │ ├── fixtures.ts │ ├── logconsol.ts │ ├── peripheryFixtures.ts │ └── utilities.ts └── util.spec.ts ├── tsconfig.json └── yarn-error.log /.gitignore: -------------------------------------------------------------------------------- 1 | yarn.lock 2 | node_modules/ 3 | build/ 4 | flatten/ 5 | 6 | node_modules 7 | .DS_Store 8 | .config* 9 | report.*.json 10 | yarn-error.log 11 | .idea/ 12 | 13 | node_modules 14 | .env 15 | coverage 16 | coverage.json 17 | typechain 18 | typechain-types 19 | 20 | # Hardhat files 21 | cache 22 | artifacts 23 | 24 | -------------------------------------------------------------------------------- /.waffle.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerVersion": "./node_modules/solc", 3 | "outputType": "all", 4 | "outputHumanReadableAbi": true, 5 | "compilerOptions": { 6 | "outputSelection": { 7 | "*": { 8 | "*": [ 9 | "evm.bytecode.object", 10 | "evm.deployedBytecode.object", 11 | "abi", 12 | "evm.bytecode.sourceMap", 13 | "evm.deployedBytecode.sourceMap", 14 | "metadata" 15 | ], 16 | "": ["ast"] 17 | } 18 | }, 19 | 20 | "evmVersion": "istanbul", 21 | "optimizer": { 22 | "enabled": true, 23 | "runs": 200 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Local Development 2 | 3 | The following assumes the use of `node@>=10`. 4 | 5 | ## Install Dependencies 6 | 7 | `yarn` 8 | 9 | ## Compile Contracts 10 | 11 | `yarn compile` 12 | 13 | ## Run Tests 14 | 15 | `yarn test` 16 | 17 | ## Contract addresses 18 | ### Main Chain 19 | ``` 20 | BurgerMainToken 0x2a4A071BCe925D210797c6FB0BC7bd08a80Cb9c2 21 | Dgas 0x5ffe4d18863441181B95cf57799cbeee01b1c14d 22 | DemaxConfig 0x1a9bf813c3D03B8f591DD4658c42C321a074a731 23 | DemaxPlatform 0x07c484abd8f885252C80510aAa1d4807733CFD17 24 | DemaxTransferListener 0x7dF3FBE4488B4f6F12E22858D8D9444B200759fF 25 | DemaxGovernance 0xa81241A89EB5c14bAcFf21C65f38DB08CC05ca93 26 | DemaxBallotFactory 0xC66EEeAAb12b12012Ea59BaE0f88bf6eb6005eB7 27 | DemaxFactory 0xb3d9B9C8B30a73Cb602513278b7369E1919C531d 28 | DemaxQuery 0x09E67978A9F404a95c2773Cf955e8dE14436bc9c 29 | 30 | TokenQuery 0xd91dDB1818232eB9230A59B394dc3f5e4D0d0BAd 31 | 32 | WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 33 | USDT 0xdAC17F958D2ee523a2206206994597C13D831ec7 34 | ``` 35 | 36 | ### BSC Chain v1 37 | ``` 38 | Dgas 0xAe9269f27437f0fcBC232d39Ec814844a51d6b8f 39 | DemaxConfig 0xE7F6824706aEee33542088eb2fdd2D69e37455B6 40 | DemaxPlatform 0x75Ca8F6c82df5FdFd09049f46AD5d072b0a53BF6 41 | DemaxTransferListener 0xF45DdD55FDe8db85B5000cfF94cD912F61138D70 42 | DemaxGovernance 0x9154c2684aeF8d106babcB19Aa81d4FabF7581ec 43 | DemaxBallotFactory 0xA7545C64D65a6E329e0ED3c9c9CfB99B5DeA07FF 44 | DemaxFactory 0xa4790135Ba4439cdb2eFB35fe191dC83d3D627F6 45 | DemaxQuery 0xa6F21AaAdA32CA46c876D915FDEb98d9c35A122a 46 | 47 | 48 | WETH9 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c 49 | USDT 0x55d398326f99059fF775485246999027B3197955 50 | BBTC 0x0C177Bccab0454aF11c6C02E08A6bebE9cd07710 51 | 52 | ``` 53 | 54 | ### BSC Chain v2 55 | ``` 56 | DgasHub 0x54a1Ca2ED74F0ac04E21E2154022b330104F2E7A 57 | Dgas 0xAe9269f27437f0fcBC232d39Ec814844a51d6b8f 58 | DemaxConfig 0xE7F6824706aEee33542088eb2fdd2D69e37455B6 59 | DemaxPlatform 0xBf6527834dBB89cdC97A79FCD62E6c08B19F8ec0, 0x42591f57f707739b95C5C486c014B525f19d70ca,0x789c11212EaCA5312d4aa6d63148613e658CcFAd, 0xB099D7dbC415bf5491B0ca6fdCcFddF8b7EDCE12 60 | DemaxTransferListener 0x93435503fdeBC171f05e60C882FFba5F332cF05E, 0x3BecD05231bBBa6F7AdDa92F3c79fb3AA96d943b 61 | DemaxGovernance 0x9154c2684aeF8d106babcB19Aa81d4FabF7581ec 62 | DemaxBallotFactory 0xA7545C64D65a6E329e0ED3c9c9CfB99B5DeA07FF, 0x29d5aC18A4C315aF2E8c8325a2748e590Ab00a68 63 | DemaxFactory 0x8a1E9d3aEbBBd5bA2A64d3355A48dD5E9b511256 64 | DemaxQuery 0x4D584e02E135A9145a1e1b3a50F487B59cCcF045, 0xc2969239da155C96047D276A2D0e28Cc55892BBe 65 | DemaxPool 0x86A327715d707BCa24983b1145D1F6c40C5d4A74 66 | DemaxDelegateBeta 0xd1c39d8ed2E2E0fd52A7FaBfCD6b560153D49651 67 | DemaxDelegateAlpha 0xd0dd735851C1Ca61d0324291cCD3959d2153A88d 68 | DemaxQuery2Beta 0xE5c13951F51e8C616fF3e7c815042533D527D255 69 | DemaxQuery2Alpha 0x29863F5af663bbdF6732A5DF3d58dA002Ea43272 70 | DemaxDelegate 0x3dE79b6fF181AA60bd1Cd7d2C6ea8a6099A35E60 71 | DemaxQuery2 0x2c7fC9cCF3D03d99007DB5977dD5926e8E32e022, 0x59138b0B399edF74B8d296B8A52FE0cC18623fDD 72 | 73 | DemaxProjectConfig 0xCB519729D866eb3D4142169985Fde407EA757057 74 | DemaxProjectDeploy 0x5Bb57735352165cEaBCB50dc9b11DB5341E5C7b5 75 | DemaxProjectQuery 0x1a64489D69FB4C6638eae6Cb5D898296F8Db19cE 76 | 77 | DemaxQueryPairWeigth 0x19A8cb7498c40dc36FD65e600ad4a67c1F9BF920 78 | DemaxQueryPair 0x5bd05ffBcdCa245aD7A26327Dae7D12455F63093 79 | 80 | 81 | XBurger 0xAFE24E29Da7E9b3e8a25c9478376B6AD6AD788dD 82 | DemaxShackChef 0x03253A7b8B5e868542ddbDdC86bb068C62A8faB7 83 | 84 | IFOQuery 0x136Efc39B6ba21143E408fe318efe0F872Ffbae4 85 | 86 | DemaxTrigger 0xEF72ebbA2602De655Ad05aE67F7E15CcdD119031 87 | 88 | WETH9 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c 89 | USDT 0x55d398326f99059fF775485246999027B3197955 90 | BBTC 0x0C177Bccab0454aF11c6C02E08A6bebE9cd07710 91 | Fake USDT 0xA9a6c929A2b6E538FE1d2151AD76f751DCB312Ae, 0xBbECa1d3DE03Da93C4e028A770772495d289945f 92 | 93 | TokenQuery 0xe85ED3322373F1dC720B7dCCDBECFcEb871364e0 94 | TokenQuery(other) 0xb78D2b02dC344120eF7e1f0517aCe259125C8031 95 | 96 | 97 | DemaxTransferListener History 98 | 0x43BfE4438dC0EbfdE7aF5dAF51a62c6ADE30256A 99 | 0x675E283077b6686fc1d0D1fC28ff5Fde16688152 100 | 0xF45DdD55FDe8db85B5000cfF94cD912F61138D70 101 | 0x93435503fdeBC171f05e60C882FFba5F332cF05E 102 | 0x3BecD05231bBBa6F7AdDa92F3c79fb3AA96d943b 103 | 104 | ERC20Factory 0x6292c755Af42512c5901524E42c8666ef60A4a08 105 | 106 | ``` 107 | 108 | 109 | ### Ropsten Chain 110 | ``` 111 | Dgas 0x33cEA1E091De4483feBF6e7d6beF097a66EFfcdA 112 | DemaxConfig 0x82AA6A57f83180d8b086E804663A8667259eaC40 113 | DemaxPlatform 0x197AD5aD546086267A2D7304B6Ee5C82Ef249636 114 | DemaxTransferListener 0xE52E6E526d36c1fB0443b1F5C46a0Cb9F5e6796B 115 | DemaxGovernance 0x8D3E38A5976255E064525A68834d7621D767De90 116 | DemaxBallotFactory 0x328352FAd15a2E7CB7bf3fc20d9A304B62AeDfd1 117 | DemaxFactory 0xa4790135Ba4439cdb2eFB35fe191dC83d3D627F6 118 | DemaxQuery 0x212a432e34C0C867c526905690a5Af778fe5c211 119 | 120 | WETH9 0xb603cea165119701b58d56d10d2060fbfb3efad8 121 | USDT 0x719cDcB5F81b06a6c8ED87e64eF0BDa257c922f7 122 | ``` 123 | ### Kovan Chain 124 | ``` 125 | Dgas 0x2828De56f364f460627485B4D1b0B0cEcF55fa74 126 | DemaxConfig 0xB4191C5b2815D907fd748c652446C34EC8998909 127 | DemaxPlatform 0x062BA20eD36833aB549E238bA538de3e32C7fDA8 128 | DemaxTransferListener 0xB472FddD75Ce35ee457D7Bbf88020647387A727b 129 | DemaxGovernance 0x0411c04987de2dCE385b1bDA5555412cDDCf0723 130 | DemaxBallotFactory 0xC24d8feaa20F083d3A6b680244561AbEb3231366 131 | DemaxFactory 0xBce7D74859D73f9F9b40851cEf29f7AB82658dd9 132 | DemaxQuery 0x2bBdd25389eA566D3b0916A2C104C941d72F6D72 133 | 134 | TokenQuery 0x0aAE6E28Fab4A923f19C015517EAcEd0966CaF61 135 | ERC20Factory 0xE815639DF607bb567b2f36FDf561A0455bd8ee3B 136 | 137 | WETH9 0x67fe5bE3f16c01fd5C5eb3DdCC08f1dAefac40a5 138 | USDT 0x01904b5ee633b15F252879c9C0756416aDee7F03, 0xD5FAdFe4b86E06b57f93D57dB5933B90b07648AF 139 | 140 | BNB 0x97cF17393390ae8c9B99D1e2e7543f6c16d77690, 0xc0D2c91e0B6A46235A0649C2314164Ec848Da704 141 | T1 0x975d0028f23F44ECEDd75C34Deb7371599A2D734 142 | T2 0x055b5A8dBce4af0d39a2C50DD55992E5A51fDaB1 143 | T3 0xD39e9e2e4D95C39Bd03F413B82BD7D4248f6406C 144 | ``` 145 | ["0x2828De56f364f460627485B4D1b0B0cEcF55fa74","0x67fe5bE3f16c01fd5C5eb3DdCC08f1dAefac40a5","0x01904b5ee633b15F252879c9C0756416aDee7F03"] 146 | ### BSC-Test Chain 147 | ``` 148 | DgasHub 0xC2eBD377D36Ef35E83A2528486A45A40Dc65acE0 149 | weth address 0x7FcCaDD3e6A3F80e194CaDf13FeDF36B9BBbe98F 150 | platform address 0xc0E19d4f981a3cE78428b395052Ab09EEC063481, 0x075ECEA56A9C5313E8b78D8115Df1C8943A549b7, 0x75Be6D27d1007E26Ee8696eDF6f83C96b500D0aC 151 | dgas address 0x06bF890dfF5b422c35c9683f47d2d7663f6E1c24 152 | usdt address 0x8FB6a96E1A3CB6ABFd3714d49d4040cEC9bb34fC 153 | governance address 0xeD2eA4283a673252A7cd3A3a8C88702140947909 154 | config address 0xa09f3f6aD50A6069cfBda310520353132a128031 155 | ballotFactory address 0x3e4a0DED01912C42D22f8eCf0634ca479cd8F221 156 | transfer listener address 0x6Cb0205BeD6133bcb9531c475D6E01f6CF0e2cd4 157 | 158 | demax factory address 0xb43Bf0457563f54d104fc2711094DFF7AAC1Abe4 159 | demax query address 0x2940a00E5a56271aB0c2898eC41362DE3ebB2b0A, 0x9C0931EFe04740DF65dDC75bc5e2e08b8e1d60B9 160 | pool address 0xB913E531A255091edcc1c454D0f141B553918158 161 | 162 | TokenQuery 0x4821d7846FE9b1b13BF4969C20b6188F9B3B30a3 163 | DemaxQueryPairWeigth 0xbc34DEC637a1b0585d0c089041De592EbbF1072E 164 | DemaxQueryPair 0xd6a22DC441bC6F1242C9a48dA0F2334980a36871 165 | 166 | DemaxDelegate_beta 0x3854d78b47B487Fd5b3867739aD38F093EEa5720 167 | query2_beta 0xf6F4e404e5cE9FaB416dB93A3f93453732849951 168 | query2_alpha 0x841844c83D612f7F3aAA9bB07eB1Fce6582965E2 169 | DemaxDelegate_alpha 0x3637Ef96D13b6fbA4fa097e7C491206eBA5E7187 170 | DemaxDelegate 0xc73Ad485bF29EC7dC36A60A1980BE4C946167D97 171 | query2 0x12b0821ec33898B0b4D6A4D656a751c689d0E240, 0x8a1E9d3aEbBBd5bA2A64d3355A48dD5E9b511256 172 | 173 | DemaxProjectConfig 0x780Ee65a425b1C79f18D0a8728f4C6687cd47230 174 | DemaxProjectDeploy 0xB2632a763d7E32FC895f1852D5B039199071ED60 175 | DemaxProjectQuery 0xF63cF3523c03617Dffa993c2b9d5422e1c0042d9 176 | 177 | DemaxTrigger 0x20D63c8699f9B63AE952D0b2f804f95149db740E 178 | 179 | ERC20Factory 0xcA23d4b682618aC2374d6818F30ae4515FB5FF76 180 | 181 | tokenA address 0x2B67896f2dEB913Ec10c0bdDBE662bc2D1D3f6d2 182 | 183 | USDT18 0xF2ED382e6A3439Be124813842200cf6702fD6ecA 184 | BUSD 0x83B379Ecb67A527cBdA54876077DF70D8c084900 185 | 186 | TT 0xd6e09B5DE6eceDFACD9Be91A70270C65A8f69CB1 187 | 188 | 189 | ETH 0x0000000000000000000000000000000000000000 190 | ``` 191 | 192 | ["0x1ABb64B03cc760158e624C003B505B73700F70ad","0x9597E38a57c244094780548d9ef17b3953d8d653","0x2BeD5CdE64EF8F98c60B13896754705171c4A6Ca"] 193 | 194 | [400,100,200] 195 | 196 | ["0x9C65AB58d8d978DB963e63f2bfB7121627e3a739","0xAEE4164c1ee46ed0bbC34790f1a3d1Fc87796668","0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c","0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c","0x2170Ed0880ac9A755fd29B2688956BD959F933F8","0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56","0x55d398326f99059fF775485246999027B3197955"] 197 | ["0x9C65AB58d8d978DB963e63f2bfB7121627e3a739","0x9C65AB58d8d978DB963e63f2bfB7121627e3a739","0x9C65AB58d8d978DB963e63f2bfB7121627e3a739","0x9C65AB58d8d978DB963e63f2bfB7121627e3a739","0x9C65AB58d8d978DB963e63f2bfB7121627e3a739","0x9C65AB58d8d978DB963e63f2bfB7121627e3a739"] 198 | 199 | * 0 => MDX (0x9C65AB58d8d978DB963e63f2bfB7121627e3a739) 200 | * 1 => HMDX (0xAEE4164c1ee46ed0bbC34790f1a3d1Fc87796668) 201 | * 2 => WBNB (0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c) 202 | * 3 => BTCB (0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c) 203 | * 4 => ETH (0x2170Ed0880ac9A755fd29B2688956BD959F933F8) 204 | * 5 => DOT (0x7083609fCE4d1d8Dc0C979AAb8c869Ea2C873402), Closed 205 | * 6 => BUSD (0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56) 206 | * 7 => USDT (0x55d398326f99059fF775485246999027B3197955) 207 | 208 | [ getProductivity method Response ] 209 | uint256 : 32284104047802774796500 210 | uint256 : 43988126499188765765700 211 | 212 | ### Heco-Test Chain 213 | ``` 214 | weth address 0x8F8da91c632be57C62D60A27f4ed07025Dfb9580 215 | platform address 0x0D1a690D07B6Ac6764506815268bF5971634fc16 216 | dgas address 0x5bf0967dC4121E41F77e852d918C3BFc1e8A3C1b 217 | usdt address 0x93A35F691BbC07165063B9179FfB68812F43407B 218 | governance address 0xd330e040894b2D5e0Be76286C55c7B9BbDC2e57b 219 | config address 0x8060BC08Dc4EB1d8DB2b14CE71B0663Ace8C43cc 220 | ballotFactory address 0x5182A186AB8af04c864A57e336A1F8a0e21081d0 221 | transfer listener address 0x022bcB66F1168ca9FFcecCb96292dEc5ac46Cc73 222 | demax factory address 0x0586d313075a69228DA2e19C8090F9f362e220e8 223 | demax pool address 0x7EFab8A082E5D8a3445ba6a787EeFa34549CF6Aa 224 | demax query address0x4a2B1025bc55c6139C510e06BED87fE78312A37E 225 | tokenA address 0xE1ac960C40cA95dD955dba0c15e13FC5ecF4A968 226 | ``` 227 | 228 | ### Kovan3 L2 229 | ``` 230 | current endpoint https://kovan3.arbitrum.io/rpc 231 | wallet 0xEcF600B841D0734F301B8Cc7e6e3c93772638851 232 | weth address 0xc56F17386B2c8EF0D58c64A39BAd24001e2D35B9 233 | platform address 0x7F120Dd7EFFbD8E43472F9d5c0EBDecdE36E7AAF 234 | dgas address 0xA0511959FC004BBCC62b193126393ddED1564AaA 235 | usdt address 0x8B96AF41622236251Ba7eB514e8519f3509928E6 236 | governance address 0x6642cb586814E4eE1cfc04119679e4d942bc6779 237 | config address 0x813415eb22bBc4b6eC0EA765B4d347733727D074 238 | ballotFactory address 0x656C16651A257E964fC6eBb7068950993039F5C5 239 | transfer listener address 0xa697a52B14b6f76236576DD5Cba40b7B61606417 240 | demax factory address 0x33886386dB7bC74f32FF126ABf42549E3b04873e 241 | demax pool address 0xefd655255C8fDA2aCfa07b95cC2d9289aD3f10E8 242 | demax query address 0x63646aAB174FdC63C95D93AcE0959d6685868A0c 243 | tokenA address 0xcA15CdcBA25207434Ba40dDE70F430EEa055568C 244 | ``` -------------------------------------------------------------------------------- /buidler.config.ts: -------------------------------------------------------------------------------- 1 | import { BuidlerConfig, usePlugin } from "@nomiclabs/buidler/config"; 2 | 3 | usePlugin("@nomiclabs/buidler-waffle"); 4 | 5 | const config: BuidlerConfig = { 6 | solc: { 7 | version: "0.6.6" 8 | } 9 | }; -------------------------------------------------------------------------------- /contracts/BurgerMainToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | import './modules/ERC20Token.sol'; 3 | import './modules/Ownable.sol'; 4 | 5 | contract BurgerMainToken is ERC20Token, Ownable { 6 | uint public maxSupply = 21000000 * 10 ** 18; 7 | 8 | event Minted(address indexed user, uint amount); 9 | 10 | constructor() public { 11 | name = 'Burger Token'; 12 | symbol = 'BURGER'; 13 | totalSupply = 10000000 * 10 ** 18; 14 | balanceOf[msg.sender] = totalSupply; 15 | } 16 | 17 | function mint(uint amount) external onlyOwner returns (uint) { 18 | require(amount > 0, 'Invalid amount'); 19 | if(amount.add(totalSupply) > maxSupply) { 20 | amount = maxSupply.sub(totalSupply); 21 | } 22 | balanceOf[msg.sender] += amount; 23 | totalSupply += amount; 24 | emit Minted(msg.sender, amount); 25 | return amount; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /contracts/DemaxFactory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | pragma solidity >=0.6.6; 3 | 4 | import './DemaxPair.sol'; 5 | import './interfaces/IDemaxConfig.sol'; 6 | 7 | contract DemaxFactory { 8 | uint256 public version = 1; 9 | address public DGAS; 10 | address public CONFIG; 11 | address public owner; 12 | mapping(address => mapping(address => address)) public getPair; 13 | mapping(address => bool) public isPair; 14 | address[] public allPairs; 15 | 16 | mapping(address => address[]) public playerPairs; 17 | mapping(address => mapping(address => bool)) isAddPlayerPair; 18 | 19 | bytes32 public contractCodeHash; 20 | event PairCreated(address indexed token0, address indexed token1, address pair, uint256); 21 | 22 | constructor(address _DGAS, address _CONFIG) public { 23 | DGAS = _DGAS; 24 | CONFIG = _CONFIG; 25 | owner = msg.sender; 26 | } 27 | 28 | function updateConfig(address _CONFIG) external { 29 | require(msg.sender == owner, 'DEMAX FACTORY: PERMISSION'); 30 | CONFIG = _CONFIG; 31 | for(uint i = 0; i < allPairs.length; i ++) { 32 | DemaxPair(allPairs[i]).initialize(DemaxPair(allPairs[i]).token0(), DemaxPair(allPairs[i]).token1(), _CONFIG, DGAS); 33 | } 34 | } 35 | 36 | function getPlayerPairCount(address player) external view returns (uint256) { 37 | address[] storage existAddress = playerPairs[player]; 38 | return existAddress.length; 39 | } 40 | 41 | function addPlayerPair(address _player, address _pair) external returns (bool) { 42 | require(msg.sender == IDemaxConfig(CONFIG).platform(), 'DEMAX FACTORY: PERMISSION'); 43 | if (isAddPlayerPair[_player][_pair] == false) { 44 | isAddPlayerPair[_player][_pair] = true; 45 | playerPairs[_player].push(_pair); 46 | } 47 | return true; 48 | } 49 | 50 | function allPairsLength() external view returns (uint256) { 51 | return allPairs.length; 52 | } 53 | 54 | function createPair(address tokenA, address tokenB) external returns (address pair) { 55 | require(msg.sender == IDemaxConfig(CONFIG).platform(), 'DEMAX FACTORY: PERMISSION'); 56 | require(tokenA != tokenB, 'DEMAX FACTORY: IDENTICAL_ADDRESSES'); 57 | require( 58 | IDemaxConfig(CONFIG).checkToken(tokenA) && IDemaxConfig(CONFIG).checkToken(tokenB), 59 | 'DEMAX FACTORY: NOT LIST' 60 | ); 61 | (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); 62 | require(token0 != address(0), 'DEMAX FACTORY: ZERO_ADDRESS'); 63 | require(getPair[token0][token1] == address(0), 'DEMAX FACTORY: PAIR_EXISTS'); // single check is sufficient 64 | bytes memory bytecode = type(DemaxPair).creationCode; 65 | if (uint256(contractCodeHash) == 0) { 66 | contractCodeHash = keccak256(bytecode); 67 | } 68 | bytes32 salt = keccak256(abi.encodePacked(token0, token1)); 69 | assembly { 70 | pair := create2(0, add(bytecode, 32), mload(bytecode), salt) 71 | } 72 | isPair[pair] = true; 73 | DemaxPair(pair).initialize(token0, token1, CONFIG, DGAS); 74 | getPair[token0][token1] = pair; 75 | getPair[token1][token0] = pair; // populate mapping in the reverse direction 76 | allPairs.push(pair); 77 | emit PairCreated(token0, token1, pair, allPairs.length); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /contracts/DemaxPool.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >= 0.5.1; 2 | import './modules/Ownable.sol'; 3 | import './libraries/TransferHelper.sol'; 4 | import './interfaces/IDgas.sol'; 5 | import './interfaces/IDemaxPair.sol'; 6 | import './interfaces/IDemaxFactory.sol'; 7 | import './interfaces/IDemaxGovernance.sol'; 8 | import './libraries/SafeMath.sol'; 9 | import './libraries/ConfigNames.sol'; 10 | import './interfaces/IDemaxConfig.sol'; 11 | 12 | interface IDemaxPlatform { 13 | function swapExactTokensForETH( 14 | uint256 amountIn, 15 | uint256 amountOutMin, 16 | address[] calldata path, 17 | address to, 18 | uint256 deadline 19 | ) external returns (uint256[] memory amounts) ; 20 | function swapExactTokensForTokens( 21 | uint256 amountIn, 22 | uint256 amountOutMin, 23 | address[] calldata path, 24 | address to, 25 | uint256 deadline 26 | ) external returns (uint256[] memory amounts); 27 | } 28 | 29 | contract DemaxPool is Ownable { 30 | using SafeMath for uint; 31 | address public DGAS; 32 | address public FACTORY; 33 | address public PLATFORM; 34 | address public WETH; 35 | address public CONFIG; 36 | address public GOVERNANCE; 37 | uint public totalReward; 38 | 39 | struct UserInfo { 40 | uint rewardDebt; // Reward debt. 41 | uint rewardEarn; // Reward earn and not minted 42 | } 43 | 44 | event ClaimReward(address indexed user, address indexed pair, address indexed rewardToken, uint amountDGAS); 45 | event AddReward(address indexed pair, uint amount); 46 | 47 | mapping(address => mapping (address => UserInfo)) public users; 48 | 49 | mapping (address => uint) public pairAmountPerShare; 50 | mapping (address => uint) public pairReward; 51 | 52 | function initialize(address _DGAS, address _WETH, address _FACTORY, address _PLATFORM, address _CONFIG, address _GOVERNANCE) external onlyOwner { 53 | DGAS = _DGAS; 54 | WETH = _WETH; 55 | FACTORY = _FACTORY; 56 | PLATFORM = _PLATFORM; 57 | CONFIG = _CONFIG; 58 | GOVERNANCE = _GOVERNANCE; 59 | } 60 | 61 | function upgrade(address _newPool, address[] calldata _pairs) external onlyOwner { 62 | IDgas(DGAS).approve(_newPool, totalReward); 63 | for(uint i = 0;i < _pairs.length;i++) { 64 | if(pairReward[_pairs[i]] > 0) { 65 | DemaxPool(_newPool).addReward(_pairs[i], pairReward[_pairs[i]]); 66 | totalReward = totalReward.sub(pairReward[_pairs[i]]); 67 | pairReward[_pairs[i]] = 0; 68 | } 69 | } 70 | } 71 | 72 | function addRewardFromPlatform(address _pair, uint _amount) external { 73 | require(msg.sender == PLATFORM, "DEMAX POOL: FORBIDDEN"); 74 | uint balanceOf = IDgas(DGAS).balanceOf(address(this)); 75 | require(balanceOf.sub(totalReward) >= _amount, 'DEMAX POOL: ADD_REWARD_EXCEED'); 76 | 77 | uint rewardAmount = IDemaxConfig(CONFIG).getConfigValue(ConfigNames.FEE_LP_REWARD_PERCENT).mul(_amount).div(10000); 78 | _addReward(_pair, rewardAmount); 79 | 80 | uint remainAmount = _amount.sub(rewardAmount); 81 | uint governanceAmount = IDemaxConfig(CONFIG).getConfigValue(ConfigNames.FEE_GOVERNANCE_REWARD_PERCENT).mul(remainAmount).div(10000); 82 | if(governanceAmount > 0) { 83 | TransferHelper.safeTransfer(DGAS, GOVERNANCE, governanceAmount); 84 | IDemaxGovernance(GOVERNANCE).addReward(governanceAmount); 85 | } 86 | if(remainAmount.sub(governanceAmount) > 0) { 87 | TransferHelper.safeTransfer(DGAS, address(0), remainAmount.sub(governanceAmount)); 88 | } 89 | emit AddReward(_pair, rewardAmount); 90 | } 91 | 92 | function addReward(address _pair, uint _amount) external { 93 | TransferHelper.safeTransferFrom(DGAS, msg.sender, address(this), _amount); 94 | 95 | require(IDemaxFactory(FACTORY).isPair(_pair), "DEMAX POOL: INVALID PAIR"); 96 | _addReward(_pair, _amount); 97 | 98 | emit AddReward(_pair, _amount); 99 | } 100 | 101 | function preProductivityChanged(address _pair, address _user) external { 102 | require(msg.sender == PLATFORM, "DEMAX POOL: FORBIDDEN"); 103 | _auditUser(_pair, _user); 104 | } 105 | 106 | function postProductivityChanged(address _pair, address _user) external { 107 | require(msg.sender == PLATFORM, "DEMAX POOL: FORBIDDEN"); 108 | require(IDemaxFactory(FACTORY).isPair(_pair), "DEMAX POOL: INVALID PAIR"); 109 | 110 | _updateDebt(_pair, _user); 111 | } 112 | 113 | function _addReward(address _pair, uint _amount) internal { 114 | pairReward[_pair] = pairReward[_pair].add(_amount); 115 | uint totalProdutivity = IDemaxPair(_pair).totalSupply(); 116 | if(totalProdutivity > 0) { 117 | pairAmountPerShare[_pair] = pairAmountPerShare[_pair].add(_amount.mul(1e12).div(totalProdutivity)); 118 | totalReward = totalReward.add(_amount); 119 | } 120 | } 121 | 122 | function _auditUser(address _pair, address _user) internal { 123 | require(IDemaxFactory(FACTORY).isPair(_pair), "DEMAX POOL: INVALID PAIR"); 124 | 125 | uint balance = IDemaxPair(_pair).balanceOf(_user); 126 | uint accAmountPerShare = pairAmountPerShare[_pair]; 127 | UserInfo storage userInfo = users[_user][_pair]; 128 | uint pending = balance.mul(accAmountPerShare).div(1e12).sub(userInfo.rewardDebt); 129 | userInfo.rewardEarn = userInfo.rewardEarn.add(pending); 130 | userInfo.rewardDebt = balance.mul(accAmountPerShare).div(1e12); 131 | } 132 | 133 | function _updateDebt(address _pair, address _user) internal { 134 | uint balance = IDemaxPair(_pair).balanceOf(_user); 135 | uint accAmountPerShare = pairAmountPerShare[_pair]; 136 | users[_user][_pair].rewardDebt = balance.mul(accAmountPerShare).div(1e12); 137 | } 138 | 139 | function claimReward(address _pair, address _rewardToken) external { 140 | _auditUser(_pair, msg.sender); 141 | UserInfo storage userInfo = users[msg.sender][_pair]; 142 | 143 | uint amount = userInfo.rewardEarn; 144 | pairReward[_pair] = pairReward[_pair].sub(amount); 145 | totalReward = totalReward.sub(amount); 146 | require(amount > 0, "NOTHING TO MINT"); 147 | 148 | userInfo.rewardEarn = 0; 149 | 150 | if(_rewardToken == DGAS) { 151 | TransferHelper.safeTransfer(DGAS, msg.sender, amount); 152 | } else if(_rewardToken == WETH) { 153 | require(IDemaxFactory(FACTORY).getPair(WETH, DGAS) != address(0), "DEMAX POOL: INVALID PAIR"); 154 | IDgas(DGAS).approve(PLATFORM, amount); 155 | address[] memory path = new address[](2); 156 | path[0] = DGAS; 157 | path[1] = WETH; 158 | IDemaxPlatform(PLATFORM).swapExactTokensForETH(amount, 0, path, msg.sender, block.timestamp + 1); 159 | } else { 160 | require(IDemaxFactory(FACTORY).getPair(_rewardToken, DGAS) != address(0), "DEMAX POOL: INVALID PAIR"); 161 | IDgas(DGAS).approve(PLATFORM, amount); 162 | address[] memory path = new address[](2); 163 | path[0] = DGAS; 164 | path[1] = _rewardToken; 165 | IDemaxPlatform(PLATFORM).swapExactTokensForTokens(amount, 0, path, msg.sender, block.timestamp + 1); 166 | } 167 | 168 | emit ClaimReward(msg.sender, _pair, _rewardToken, amount); 169 | } 170 | 171 | function queryReward(address _pair, address _user) external view returns(uint) { 172 | require(IDemaxFactory(FACTORY).isPair(_pair), "DEMAX POOL: INVALID PAIR"); 173 | 174 | UserInfo memory userInfo = users[_user][_pair]; 175 | uint balance = IDemaxPair(_pair).balanceOf(_user); 176 | return balance.mul(pairAmountPerShare[_pair]).div(1e12).add(userInfo.rewardEarn).sub(userInfo.rewardDebt); 177 | } 178 | } -------------------------------------------------------------------------------- /contracts/DemaxProjectConfig.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | contract DemaxProjectConfig { 4 | address public owner; 5 | address public dev; 6 | address public admin; 7 | 8 | constructor() public { 9 | owner = msg.sender; 10 | dev = msg.sender; 11 | admin = msg.sender; 12 | } 13 | 14 | modifier onlyOwner() { 15 | require(msg.sender == owner, 'IFOConfig: Only Owner'); 16 | _; 17 | } 18 | 19 | modifier onlyAdmin() { 20 | require(msg.sender == admin || msg.sender == owner, "IFOConfig: FORBIDDEN"); 21 | _; 22 | } 23 | 24 | modifier onlyDev() { 25 | require(msg.sender == dev || msg.sender == owner, "IFOConfig: FORBIDDEN"); 26 | _; 27 | } 28 | 29 | function changeOwner(address _user) external onlyOwner { 30 | require(owner != _user, 'IFOConfig: NO CHANGE'); 31 | owner = _user; 32 | } 33 | 34 | function changeDev(address _user) external onlyDev { 35 | require(dev != _user, 'IFOConfig: NO CHANGE'); 36 | dev = _user; 37 | } 38 | 39 | function changeAdmin(address _user) external onlyAdmin { 40 | require(admin != _user, 'IFOConfig: NO CHANGE'); 41 | admin = _user; 42 | } 43 | } -------------------------------------------------------------------------------- /contracts/DemaxProjectDeploy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import './libraries/SafeMath.sol'; 4 | import './libraries/TransferHelper.sol'; 5 | import './modules/ProjectConfigable.sol'; 6 | 7 | interface IDemaxProjectFactory { 8 | function initialize (address _mintToken, address _admin, string calldata _intro) external; 9 | function mintToken() external view returns (address); 10 | } 11 | 12 | interface IDemaxProjectPool { 13 | function initialize (address _mintToken, address _burgerToken, address _lpToken, address _factory) external; 14 | } 15 | 16 | contract DemaxProjectDeploy is ProjectConfigable { 17 | uint public version = 1; 18 | mapping(address => address) public factoryList; 19 | mapping(address => mapping(address => address)) public poolList; 20 | address[] public factories; 21 | uint public factoryListLength; 22 | mapping(address => uint) public factoryPoolListLength; 23 | mapping(address => address[]) public factoryPools; 24 | bytes32 public factoryByteCodeHash; 25 | bytes32 public poolByteCodeHash; 26 | address public burgerToken; 27 | mapping(address => bool) public disabledFactory; 28 | mapping(address => bool) public disabledPool; 29 | 30 | event FactoryCreated(address indexed token, address indexed factory); 31 | event PoolCreated(address indexed factory, address indexed lpToken, address pool); 32 | 33 | function initialize (address _burgerToken, bytes32 _factoryByteCodeHash, bytes32 _poolByteCodeHash) external onlyOwner { 34 | burgerToken = _burgerToken; 35 | factoryByteCodeHash = _factoryByteCodeHash; 36 | poolByteCodeHash = _poolByteCodeHash; 37 | } 38 | 39 | function createFactory( 40 | address _mintToken, 41 | string calldata _intro, 42 | bytes calldata _bytecode 43 | ) external onlyDev returns (address factory) { 44 | require(factoryList[_mintToken] == address(0), 'DemaxProjectDeploy: FACTORY_EXISTS'); // single check is sufficient 45 | bytes32 salt = keccak256(abi.encodePacked(_mintToken)); 46 | bytes memory bytecode = _bytecode; 47 | require(keccak256(bytecode) == factoryByteCodeHash, "INVALID BYTECODE."); 48 | 49 | assembly { 50 | factory := create2(0, add(bytecode, 32), mload(bytecode), salt) 51 | } 52 | 53 | factoryListLength ++; 54 | factoryList[_mintToken] = factory; 55 | factories.push(factory); 56 | ProjectConfigable(factory).setupConfig(config); 57 | IDemaxProjectFactory(factory).initialize(_mintToken, ProjectConfigable(config).admin(), _intro); 58 | emit FactoryCreated(_mintToken, factory); 59 | return factory; 60 | } 61 | 62 | function createPool( 63 | address _factory, 64 | address _lpToken, 65 | bytes calldata _bytecode 66 | ) external onlyDev returns (address pool) { 67 | require(poolList[_factory][_lpToken]== address(0), 'DemaxProjectDeploy: POOL_EXISTS'); // single check is sufficient 68 | bytes32 salt = keccak256(abi.encodePacked(_factory, _lpToken)); 69 | bytes memory bytecode = _bytecode; 70 | require(keccak256(bytecode) == poolByteCodeHash, "INVALID BYTECODE."); 71 | 72 | assembly { 73 | pool := create2(0, add(bytecode, 32), mload(bytecode), salt) 74 | } 75 | 76 | factoryPoolListLength[_factory] ++; 77 | poolList[_factory][_lpToken] = pool; 78 | factoryPools[_factory].push(pool); 79 | IDemaxProjectPool(pool).initialize( 80 | IDemaxProjectFactory(_factory).mintToken(), 81 | burgerToken, 82 | _lpToken, 83 | _factory 84 | ); 85 | emit PoolCreated(_factory, _lpToken, pool); 86 | return pool; 87 | } 88 | 89 | function getPoolByIndex(address _factory, uint _index) external view returns (address) { 90 | return factoryPools[_factory][_index]; 91 | } 92 | 93 | function getFactoryList() external view returns (address[] memory) { 94 | return factories; 95 | } 96 | 97 | function getPoolList(address _factory) external view returns (address[] memory) { 98 | return factoryPools[_factory]; 99 | } 100 | 101 | function setFactory(address _factory, bool _value) external onlyDev returns (bool) { 102 | disabledFactory[_factory] = _value; 103 | return _value; 104 | } 105 | 106 | function setPool(address _pool, bool _value) external onlyDev returns (bool) { 107 | disabledPool[_pool] = _value; 108 | return _value; 109 | } 110 | } -------------------------------------------------------------------------------- /contracts/DemaxProjectFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import './libraries/SafeMath.sol'; 4 | import './libraries/TransferHelper.sol'; 5 | import './modules/ProjectConfigable.sol'; 6 | 7 | contract DemaxProjectFactory is ProjectConfigable { 8 | using SafeMath for uint; 9 | uint public version = 1; 10 | bool initialized; 11 | uint public totalWeight; 12 | 13 | struct MintStruct { 14 | uint weight; 15 | uint amountToMint; 16 | uint aPerBMinted; 17 | } 18 | 19 | mapping(address => MintStruct) public pools; 20 | 21 | address public mintToken; 22 | uint public mintRate; 23 | uint public mintTotal; 24 | uint public amountPerWeight; 25 | uint public startBlock; 26 | uint public finishBlock; 27 | uint public lastUpdateBlock; 28 | string public intro; 29 | 30 | modifier _updateBlock() { 31 | uint applicableBlock = block.number > finishBlock ? finishBlock: block.number; 32 | if(totalWeight > 0) { 33 | amountPerWeight = amountPerWeight.add(applicableBlock.sub(lastUpdateBlock).mul(mintRate).mul(1e18).div(totalWeight)); 34 | } 35 | lastUpdateBlock = applicableBlock; 36 | _; 37 | } 38 | 39 | function initialize (address _mintToken, address _admin, string memory _intro) public { 40 | require(!initialized, 'initialized'); 41 | initialized = true; 42 | mintToken = _mintToken; 43 | owner = _admin; 44 | intro = _intro; 45 | } 46 | 47 | function setWeights(address[] calldata _pools, uint[] calldata _weights) onlyAdmin external _updateBlock { 48 | require(_pools.length == _weights.length); 49 | uint cnt = _pools.length; 50 | for(uint i = 0; i < cnt;i++) { 51 | _updatePool(_pools[i]); 52 | totalWeight = totalWeight.sub(pools[_pools[i]].weight); 53 | pools[_pools[i]].weight = _weights[i]; 54 | totalWeight = totalWeight.add(_weights[i]); 55 | } 56 | } 57 | 58 | function _updatePool(address pool) internal { 59 | MintStruct storage record = pools[pool]; 60 | record.amountToMint = record.amountToMint.add(amountPerWeight.sub(record.aPerBMinted).mul(record.weight).div(1e18)); 61 | record.aPerBMinted = amountPerWeight; 62 | } 63 | 64 | function queryPool() external view returns (uint amount) { 65 | uint applicableBlock = block.number > finishBlock ? finishBlock: block.number; 66 | uint _amountPerWeight = amountPerWeight; 67 | if(totalWeight > 0) { 68 | _amountPerWeight = amountPerWeight.add(applicableBlock.sub(lastUpdateBlock).mul(mintRate).mul(1e18).div(totalWeight)); 69 | } 70 | 71 | return pools[msg.sender].amountToMint.add(_amountPerWeight.sub(pools[msg.sender].aPerBMinted).mul(pools[msg.sender].weight).div(1e18)); 72 | } 73 | 74 | function mintToPool() external _updateBlock returns (uint amount) { 75 | _updatePool(msg.sender); 76 | amount = pools[msg.sender].amountToMint; 77 | if(amount > 0) { 78 | TransferHelper.safeTransfer(mintToken, msg.sender, amount); 79 | } 80 | pools[msg.sender].amountToMint = 0; 81 | } 82 | 83 | function addReward(uint amount, uint duration) external _updateBlock { 84 | require(block.number.add(duration) >= finishBlock, "CAN NOT DECREASE DURATION"); 85 | TransferHelper.safeTransferFrom(mintToken, msg.sender, address(this), amount); 86 | if(block.number > finishBlock) { 87 | mintRate = amount.div(duration); 88 | } else { 89 | uint remain = finishBlock.sub(block.number).mul(mintRate); 90 | mintRate = remain.add(amount).div(duration); 91 | } 92 | lastUpdateBlock = block.number; 93 | finishBlock = block.number.add(duration); 94 | if(startBlock == 0) { 95 | startBlock = block.number; 96 | } 97 | mintTotal = mintTotal.add(amount); 98 | } 99 | } -------------------------------------------------------------------------------- /contracts/DemaxProjectPool.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import './libraries/SafeMath.sol'; 4 | import './libraries/TransferHelper.sol'; 5 | 6 | interface IDemaxProjectFactory { 7 | function mintToPool() external returns (uint amount); 8 | function queryPool() external view returns (uint amount); 9 | } 10 | 11 | interface IDemaxLP { 12 | function mintReward() external returns (uint amount); 13 | function queryReward() external view returns (uint); 14 | } 15 | 16 | contract DemaxProjectPool { 17 | using SafeMath for uint; 18 | uint public version = 1; 19 | bool initialized; 20 | uint public totalWeight; 21 | 22 | event MintBurger(address indexed user, uint amount); 23 | event MintReward(address indexed user, uint amount); 24 | 25 | struct MintStruct { 26 | uint amountToMint; 27 | uint aPerBMinted; 28 | } 29 | 30 | mapping(address => MintStruct) public rewardInfo; 31 | mapping(address => MintStruct) public burgerInfo; 32 | 33 | mapping(address => uint) public balance; 34 | 35 | uint public amountPerBurger; 36 | uint public amountPerReward; 37 | 38 | uint public totalStake; 39 | 40 | address public mintToken; 41 | address public burgerToken; 42 | address public lpToken; 43 | 44 | address public factory; 45 | 46 | function initialize (address _mintToken, address _burgerToken, address _lpToken, address _factory) public { 47 | require(!initialized, 'initialized'); 48 | initialized = true; 49 | mintToken = _mintToken; 50 | burgerToken = _burgerToken; 51 | lpToken = _lpToken; 52 | factory = _factory; 53 | } 54 | 55 | modifier _update(address user) { 56 | if(IDemaxLP(lpToken).queryReward() > 0 && totalStake > 0) { 57 | amountPerBurger = amountPerBurger.add(IDemaxLP(lpToken).mintReward().mul(1e18).div(totalStake)); 58 | } 59 | 60 | if(IDemaxProjectFactory(factory).queryPool() > 0 && totalStake > 0) { 61 | amountPerReward = amountPerReward.add(IDemaxProjectFactory(factory).mintToPool().mul(1e18).div(totalStake)); 62 | } 63 | 64 | burgerInfo[user].amountToMint = burgerInfo[user].amountToMint.add(amountPerBurger.sub(burgerInfo[user].aPerBMinted).mul(balance[user]).div(1e18)); 65 | burgerInfo[user].aPerBMinted = amountPerBurger; 66 | 67 | rewardInfo[user].amountToMint = rewardInfo[user].amountToMint.add(amountPerReward.sub(rewardInfo[user].aPerBMinted).mul(balance[user]).div(1e18)); 68 | rewardInfo[user].aPerBMinted = amountPerReward; 69 | _; 70 | } 71 | 72 | function stake(uint amount) external _update(msg.sender) { 73 | balance[msg.sender] = balance[msg.sender].add(amount); 74 | totalStake = totalStake.add(amount); 75 | TransferHelper.safeTransferFrom(lpToken, msg.sender, address(this), amount); 76 | } 77 | 78 | function withdraw(uint amount) public _update(msg.sender) { 79 | require(balance[msg.sender] >= amount, "NOT ENOUGH BANLANCE"); 80 | balance[msg.sender] = balance[msg.sender].sub(amount); 81 | totalStake = totalStake.sub(amount); 82 | TransferHelper.safeTransfer(lpToken, msg.sender, amount); 83 | } 84 | 85 | function queryBurger(address _user) external view returns(uint) { 86 | if(totalStake == 0) { 87 | return 0; 88 | } else { 89 | uint _amountPerBurger = amountPerBurger.add(IDemaxLP(lpToken).queryReward().mul(1e18).div(totalStake)); 90 | return burgerInfo[_user].amountToMint.add(_amountPerBurger.sub(burgerInfo[_user].aPerBMinted).mul(balance[_user]).div(1e18)); 91 | } 92 | } 93 | 94 | function queryReward(address _user) external view returns(uint) { 95 | if(totalStake == 0) { 96 | return 0; 97 | } else { 98 | uint _amountPerReward = amountPerReward.add(IDemaxProjectFactory(factory).queryPool().mul(1e18).div(totalStake)); 99 | return rewardInfo[_user].amountToMint.add(_amountPerReward.sub(rewardInfo[_user].aPerBMinted).mul(balance[_user]).div(1e18)); 100 | } 101 | } 102 | 103 | function _mintBurger() internal returns(uint amount) { 104 | amount = burgerInfo[msg.sender].amountToMint; 105 | if(amount > 0) { 106 | TransferHelper.safeTransfer(burgerToken, msg.sender, amount); 107 | burgerInfo[msg.sender].amountToMint = 0; 108 | emit MintBurger(msg.sender, amount); 109 | } 110 | return amount; 111 | } 112 | 113 | function _mintReward() internal returns(uint amount) { 114 | amount = rewardInfo[msg.sender].amountToMint; 115 | if(amount > 0) { 116 | TransferHelper.safeTransfer(mintToken, msg.sender, amount); 117 | rewardInfo[msg.sender].amountToMint = 0; 118 | emit MintReward(msg.sender, amount); 119 | } 120 | return amount; 121 | } 122 | 123 | function mintBurger() external _update(msg.sender) returns(uint amount) { 124 | return _mintBurger(); 125 | } 126 | 127 | function mintReward() external _update(msg.sender) returns(uint amount) { 128 | return _mintReward(); 129 | } 130 | 131 | function mintAll() public _update(msg.sender) returns(uint, uint) { 132 | return (_mintBurger(), _mintReward()); 133 | } 134 | 135 | function exit() external _update(msg.sender) { 136 | _mintBurger(); 137 | _mintReward(); 138 | withdraw(balance[msg.sender]); 139 | } 140 | } -------------------------------------------------------------------------------- /contracts/DemaxQueryPair.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | pragma solidity >= 0.6.6; 3 | import './modules/Ownable.sol'; 4 | 5 | interface IERC20 { 6 | function name() external view returns (string memory); 7 | function symbol() external view returns (string memory); 8 | function decimals() external view returns (uint); 9 | function totalSupply() external view returns (uint); 10 | function balanceOf(address owner) external view returns (uint); 11 | function allowance(address owner, address spender) external view returns (uint); 12 | } 13 | 14 | 15 | interface IDemaxFactory { 16 | function getPair(address _token0, address _token1) external view returns (address); 17 | function allPairsLength() external view returns(uint); 18 | function isPair(address _pair) external view returns(bool); 19 | function allPairs(uint _index) external view returns(address); 20 | } 21 | 22 | interface IDemaxPair { 23 | function totalSupply() external view returns(uint256); 24 | function token0() external view returns (address); 25 | function token1() external view returns (address); 26 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 27 | } 28 | 29 | interface IDemaxTransferListener { 30 | function pairWeights(address pair) external view returns(uint); 31 | } 32 | 33 | pragma experimental ABIEncoderV2; 34 | 35 | contract DemaxQueryPair is Ownable { 36 | address public factory; 37 | address public transferListener; 38 | address public baseToken; 39 | address[] public routerTokens; 40 | 41 | struct PairInfo { 42 | address pair; 43 | uint weight; 44 | uint tvl; 45 | uint totalSupply; 46 | address token0; 47 | address token1; 48 | string token0Symbol; 49 | string token1Symbol; 50 | } 51 | 52 | constructor() public { 53 | } 54 | 55 | function initialize(address _factory, address _transferListener, address _baseToken) public onlyOwner { 56 | factory = _factory; 57 | transferListener = _transferListener; 58 | baseToken = _baseToken; 59 | } 60 | 61 | 62 | function addRouterTokens(address[] memory tokens) public onlyOwner { 63 | for(uint i; i< tokens.length; i++) { 64 | addRouterToken(tokens[i]); 65 | } 66 | } 67 | 68 | function addRouterToken(address token) public onlyOwner { 69 | if(isRouterToken(token) == false) { 70 | routerTokens.push(token); 71 | } 72 | } 73 | 74 | function removeRouterTokens(address[] memory tokens) public onlyOwner { 75 | for(uint i; i< tokens.length; i++) { 76 | removeRouterToken(tokens[i]); 77 | } 78 | } 79 | 80 | function removeRouterToken(address token) public onlyOwner { 81 | uint index = indexRouterToken(token); 82 | if(index == routerTokens.length) { 83 | return; 84 | } 85 | if(index < routerTokens.length -1) { 86 | routerTokens[index] = routerTokens[routerTokens.length-1]; 87 | } 88 | routerTokens.pop(); 89 | } 90 | 91 | function isRouterToken(address token) public view returns (bool) { 92 | for(uint i = 0;i < routerTokens.length;i++) { 93 | if(token == routerTokens[i]) { 94 | return true; 95 | } 96 | } 97 | return false; 98 | } 99 | 100 | function indexRouterToken(address token) public view returns (uint) { 101 | for(uint i; i< routerTokens.length; i++) { 102 | if(routerTokens[i] == token) { 103 | return i; 104 | } 105 | } 106 | return routerTokens.length; 107 | } 108 | 109 | function countRouterToken() public view returns (uint) { 110 | return routerTokens.length; 111 | } 112 | 113 | 114 | function getPair(address _token0, address _token1) public view returns (address) { 115 | return IDemaxFactory(factory).getPair(_token0, _token1); 116 | } 117 | 118 | function getSwapPairReserve(address _pair) public view returns (address token0, address token1, uint decimals0, uint decimals1, uint reserve0, uint reserve1, uint totalSupply) { 119 | totalSupply = IDemaxPair(_pair).totalSupply(); 120 | token0 = IDemaxPair(_pair).token0(); 121 | token1 = IDemaxPair(_pair).token1(); 122 | decimals0 = IERC20(token0).decimals(); 123 | decimals1 = IERC20(token1).decimals(); 124 | (reserve0, reserve1, ) = IDemaxPair(_pair).getReserves(); 125 | } 126 | 127 | function getSwapPairReserveByTokens(address _token0, address _token1) public view returns (address token0, address token1, uint decimals0, uint decimals1, uint reserve0, uint reserve1, uint totalSupply) { 128 | address _pair = getPair(_token0, _token1); 129 | totalSupply = IDemaxPair(_pair).totalSupply(); 130 | token0 = IDemaxPair(_pair).token0(); 131 | token1 = IDemaxPair(_pair).token1(); 132 | decimals0 = IERC20(token0).decimals(); 133 | decimals1 = IERC20(token1).decimals(); 134 | (reserve0, reserve1, ) = IDemaxPair(_pair).getReserves(); 135 | } 136 | 137 | // _tokenB is base token 138 | function getLpValueByFactory(address _factory, address _tokenA, address _tokenB, uint _amount) public view returns (uint, uint) { 139 | address pair = IDemaxFactory(_factory).getPair(_tokenA, _tokenB); 140 | if(pair == address(0)) { 141 | return (0, 0); 142 | } 143 | (, address token1, uint decimals0, uint decimals1, uint reserve0, uint reserve1, uint totalSupply) = getSwapPairReserve(pair); 144 | if(_amount == 0 || totalSupply == 0) { 145 | return (0, 0); 146 | } 147 | uint decimals = decimals0; 148 | uint total = reserve0 * 2; 149 | if(_tokenB == token1) { 150 | total = reserve1 * 2; 151 | decimals = decimals1; 152 | } 153 | return (_amount*total/totalSupply, decimals); 154 | } 155 | 156 | function getCurrentRate(address _tokenIn, uint256 _amount) public view returns (uint256) { 157 | address pair = IDemaxFactory(factory).getPair(_tokenIn, baseToken); 158 | if(pair == address(0)) { 159 | return 0; 160 | } 161 | (uint112 reserve0, uint112 reserve1, ) = IDemaxPair(pair).getReserves(); 162 | if(reserve0 == 0 || reserve1 ==0) { 163 | return 0; 164 | } 165 | uint256 tokenInReserve = uint256(reserve0); 166 | uint256 tokenOutReserve = uint256(reserve1); 167 | uint256 tokenInDecimals = uint256(IERC20(_tokenIn).decimals()); 168 | uint256 tokenOutDecimals = uint256(IERC20(baseToken).decimals()); 169 | if(IDemaxPair(pair).token0() != _tokenIn) { 170 | tokenInDecimals = IERC20(baseToken).decimals(); 171 | tokenOutDecimals = IERC20(_tokenIn).decimals(); 172 | tokenInReserve = uint256(reserve1); 173 | tokenOutReserve = uint256(reserve0); 174 | } 175 | if(tokenInDecimals > tokenOutDecimals) { 176 | tokenOutReserve = tokenOutReserve * 10** (tokenInDecimals - tokenOutDecimals); 177 | } else if(tokenInDecimals < tokenOutDecimals) { 178 | tokenInReserve = tokenInReserve * 10** (tokenOutDecimals - tokenInDecimals); 179 | } 180 | 181 | return _amount * tokenOutReserve / tokenInReserve; 182 | } 183 | 184 | function getLpBaseTokenValue(address _pair) public view returns (address token0, address token1, uint decimals0, uint decimals1, uint reserve0, uint reserve1, uint totalSupply, uint tvl) { 185 | (token0, token1, decimals0, decimals1, reserve0, reserve1, totalSupply) = getSwapPairReserve(_pair); 186 | if(token0 == baseToken) { 187 | tvl = reserve0 * 2; 188 | } else if(token1 == baseToken) { 189 | tvl = reserve1 * 2; 190 | } else if (isRouterToken(token0)) { 191 | tvl = getCurrentRate(token0, reserve0*2); 192 | } else if (isRouterToken(token1)) { 193 | tvl = getCurrentRate(token1, reserve1*2); 194 | } 195 | } 196 | 197 | 198 | function getPairInfo(address _pair) public view returns (PairInfo memory info) { 199 | if(!IDemaxFactory(factory).isPair(_pair)) return info; 200 | info.pair = _pair; 201 | info.weight = IDemaxTransferListener(transferListener).pairWeights(_pair); 202 | info.token0 = IDemaxPair(_pair).token0(); 203 | info.token1 = IDemaxPair(_pair).token1(); 204 | (, , , , , , uint totalSupply, uint tvl) = getLpBaseTokenValue(_pair); 205 | info.token0Symbol = IERC20(info.token0).symbol(); 206 | info.token1Symbol = IERC20(info.token1).symbol(); 207 | info.totalSupply = totalSupply; 208 | info.tvl = tvl; 209 | return info; 210 | } 211 | 212 | function iteratePairInfoList(uint _start, uint _end) public view returns (PairInfo[] memory result){ 213 | require(_start <= _end && _start >= 0 && _end >= 0, "INVAID_PARAMTERS"); 214 | uint count = IDemaxFactory(factory).allPairsLength(); 215 | if (_end > count) _end = count; 216 | count = _end - _start; 217 | result = new PairInfo[](count); 218 | if (count == 0) return result; 219 | uint index = 0; 220 | for(uint i = _start;i < _end;i++) { 221 | address _pool = IDemaxFactory(factory).allPairs(i); 222 | result[index] = getPairInfo(_pool); 223 | index++; 224 | } 225 | return result; 226 | } 227 | 228 | } -------------------------------------------------------------------------------- /contracts/DemaxQueryPairWeigth.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | pragma solidity >= 0.5.1; 3 | import './modules/Ownable.sol'; 4 | 5 | interface IERC20 { 6 | function name() external view returns (string memory); 7 | function symbol() external view returns (string memory); 8 | function decimals() external view returns (uint); 9 | function totalSupply() external view returns (uint); 10 | function balanceOf(address owner) external view returns (uint); 11 | function allowance(address owner, address spender) external view returns (uint); 12 | } 13 | 14 | 15 | interface IDemaxFactory { 16 | function allPairsLength() external view returns(uint); 17 | function isPair(address _pair) external view returns(bool); 18 | function allPairs(uint _index) external view returns(address); 19 | } 20 | 21 | interface IDemaxPair { 22 | function token0() external view returns(address); 23 | function token1() external view returns(address); 24 | } 25 | 26 | 27 | interface IDemaxTransferListener { 28 | function pairWeights(address pair) external view returns(uint); 29 | } 30 | 31 | pragma experimental ABIEncoderV2; 32 | 33 | contract DemaxQueryPairWeigth is Ownable { 34 | address public factory; 35 | address public transferListener; 36 | 37 | struct PairWeight { 38 | address pair; 39 | uint weight; 40 | address token0; 41 | address token1; 42 | string token0Symbol; 43 | string token1Symbol; 44 | } 45 | 46 | constructor() public { 47 | } 48 | 49 | function initialize(address _factory, address _transferListener) public onlyOwner { 50 | factory = _factory; 51 | transferListener = _transferListener; 52 | } 53 | 54 | 55 | function getPairWeight(address _pair) public view returns (PairWeight memory info) { 56 | if(!IDemaxFactory(factory).isPair(_pair)) return info; 57 | info.pair = _pair; 58 | info.weight = IDemaxTransferListener(transferListener).pairWeights(_pair); 59 | info.token0 = IDemaxPair(_pair).token0(); 60 | info.token1 = IDemaxPair(_pair).token1(); 61 | info.token0Symbol = IERC20(info.token0).symbol(); 62 | info.token1Symbol = IERC20(info.token1).symbol(); 63 | return info; 64 | } 65 | 66 | function iteratePairWeightList(uint _start, uint _end) public view returns (PairWeight[] memory result){ 67 | require(_start <= _end && _start >= 0 && _end >= 0, "INVAID_PARAMTERS"); 68 | uint count = IDemaxFactory(factory).allPairsLength(); 69 | if (_end > count) _end = count; 70 | count = _end - _start; 71 | result = new PairWeight[](count); 72 | if (count == 0) return result; 73 | uint index = 0; 74 | for(uint i = _start;i < _end;i++) { 75 | address _pool = IDemaxFactory(factory).allPairs(i); 76 | result[index] = getPairWeight(_pool); 77 | index++; 78 | } 79 | return result; 80 | } 81 | 82 | 83 | } -------------------------------------------------------------------------------- /contracts/DemaxTransferListener.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | pragma solidity >=0.6.6; 3 | import './modules/Ownable.sol'; 4 | import './interfaces/IDgas.sol'; 5 | import './interfaces/IDemaxFactory.sol'; 6 | import './interfaces/IERC20.sol'; 7 | import './interfaces/IDemaxPair.sol'; 8 | import './libraries/DemaxSwapLibrary.sol'; 9 | import './libraries/SafeMath.sol'; 10 | 11 | contract DemaxTransferListener is Ownable { 12 | using SafeMath for uint; 13 | uint256 public version = 2; 14 | address public DGAS; 15 | address public PLATFORM; 16 | address public WETH; 17 | address public FACTORY; 18 | address public admin; 19 | 20 | mapping(address => uint) public pairWeights; 21 | 22 | event Transfer(address indexed from, address indexed to, address indexed token, uint256 amount); 23 | event WeightChanged(address indexed pair, uint weight); 24 | 25 | function initialize( 26 | address _DGAS, 27 | address _FACTORY, 28 | address _WETH, 29 | address _PLATFORM, 30 | address _admin 31 | ) external onlyOwner { 32 | require( 33 | _DGAS != address(0) && _FACTORY != address(0) && _WETH != address(0) && _PLATFORM != address(0), 34 | 'DEMAX TRANSFER LISTENER : INPUT ADDRESS IS ZERO' 35 | ); 36 | DGAS = _DGAS; 37 | FACTORY = _FACTORY; 38 | WETH = _WETH; 39 | PLATFORM = _PLATFORM; 40 | admin = _admin; 41 | } 42 | 43 | function changeAdmin(address _admin) external onlyOwner { 44 | admin = _admin; 45 | } 46 | 47 | function updateDGASImpl(address _newImpl) external onlyOwner { 48 | IDgas(DGAS).upgradeImpl(_newImpl); 49 | } 50 | 51 | function updatePairPowers(address[] calldata _pairs, uint[] calldata _weights) external { 52 | require(msg.sender == admin, 'DEMAX TRANSFER LISTENER: ADMIN PERMISSION'); 53 | require(_pairs.length == _weights.length, "DEMAX TRANSFER LISTENER: INVALID PARAMS"); 54 | 55 | for(uint i = 0;i < _weights.length;i++) { 56 | pairWeights[_pairs[i]] = _weights[i]; 57 | _setProdutivity(_pairs[i]); 58 | emit WeightChanged(_pairs[i], _weights[i]); 59 | } 60 | } 61 | 62 | function upgradeProdutivity(address fromPair, address toPair) external { 63 | require(msg.sender == PLATFORM, 'DEMAX TRANSFER LISTENER: PERMISSION'); 64 | (uint256 fromPairPower, ) = IDgas(DGAS).getProductivity(fromPair); 65 | (uint256 toPairPower, ) = IDgas(DGAS).getProductivity(toPair); 66 | if(fromPairPower > 0 && toPairPower == 0) { 67 | IDgas(DGAS).decreaseProductivity(fromPair, fromPairPower); 68 | IDgas(DGAS).increaseProductivity(toPair, fromPairPower); 69 | } 70 | } 71 | 72 | function _setProdutivity(address _pair) internal { 73 | (uint256 lastProdutivity, ) = IDgas(DGAS).getProductivity(_pair); 74 | address token0 = IDemaxPair(_pair).token0(); 75 | address token1 = IDemaxPair(_pair).token1(); 76 | (uint reserve0, uint reserve1, ) = IDemaxPair(_pair).getReserves(); 77 | uint currentProdutivity = 0; 78 | if(token0 == DGAS) { 79 | currentProdutivity = reserve0.mul(pairWeights[_pair]); 80 | } else if(token1 == DGAS) { 81 | currentProdutivity = reserve1.mul(pairWeights[_pair]); 82 | } 83 | 84 | if(lastProdutivity != currentProdutivity) { 85 | if(lastProdutivity > 0) { 86 | IDgas(DGAS).decreaseProductivity(_pair, lastProdutivity); 87 | } 88 | 89 | if(currentProdutivity > 0) { 90 | IDgas(DGAS).increaseProductivity(_pair, currentProdutivity); 91 | } 92 | } 93 | } 94 | 95 | function transferNotify( 96 | address from, 97 | address to, 98 | address token, 99 | uint256 amount 100 | ) external returns (bool) { 101 | require(msg.sender == PLATFORM, 'DEMAX TRANSFER LISTENER: PERMISSION'); 102 | if(IDemaxFactory(FACTORY).isPair(from) && token == DGAS) { 103 | _setProdutivity(from); 104 | } 105 | 106 | if(IDemaxFactory(FACTORY).isPair(to) && token == DGAS) { 107 | _setProdutivity(to); 108 | } 109 | 110 | emit Transfer(from, to, token, amount); 111 | return true; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /contracts/DemaxTrigger.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | pragma solidity >= 0.5.1; 3 | 4 | import './modules/Ownable.sol'; 5 | 6 | contract DemaxTrigger is Ownable { 7 | 8 | mapping(address => bool) whiteList; 9 | event Trigger(address indexed user, uint indexed signal); 10 | 11 | constructor() public { 12 | whiteList[msg.sender] = true; 13 | } 14 | 15 | function setWhite(address _user, bool _value) public onlyOwner { 16 | whiteList[_user] = _value; 17 | } 18 | 19 | function trigger(uint _signal) public { 20 | require(whiteList[msg.sender], "FORBIDDEN"); 21 | emit Trigger(msg.sender, _signal); 22 | } 23 | } -------------------------------------------------------------------------------- /contracts/Dgas.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import './modules/ERC2917Impl.sol'; 4 | 5 | contract Dgas is ERC2917Impl("Burger Swap", "BURGER", 18, 40 * (10 ** 18)) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /contracts/DgasHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.0; 3 | 4 | import './modules/Initializable.sol'; 5 | import './libraries/SafeMath.sol'; 6 | import "./interfaces/IERC2917.sol"; 7 | import './modules/Configable.sol'; 8 | 9 | contract DgasHub is Configable, Initializable { 10 | using SafeMath for uint; 11 | address public team; 12 | IERC2917 public dgas; 13 | uint public teamRate; 14 | mapping (address => uint) public funds; 15 | 16 | event TeamChanged(address indexed _user, address indexed _old, address indexed _new); 17 | event TeamRateChanged(address indexed _user, uint indexed _old, uint indexed _new); 18 | event FundChanged(address indexed _user, uint indexed _old, uint indexed _new); 19 | 20 | modifier onlyTeam() { 21 | require(msg.sender == team || msg.sender == owner, "forbidden"); 22 | _; 23 | } 24 | 25 | modifier onlyOwnerAndAdmin() { 26 | require(msg.sender == admin() || msg.sender == owner, "forbidden"); 27 | _; 28 | } 29 | 30 | function initialize(address _dgas) external initializer { 31 | owner = msg.sender; 32 | team = msg.sender; 33 | dgas = IERC2917(_dgas); 34 | } 35 | 36 | function changeDgas(address _dgas) external onlyDev { 37 | dgas = IERC2917(_dgas); 38 | } 39 | 40 | function changeTeam(address _user) external onlyTeam { 41 | require(team != _user, 'no change'); 42 | emit TeamChanged(msg.sender, team, _user); 43 | team = _user; 44 | } 45 | 46 | function changeTeamRate(uint _teamRate) external onlyOwnerAndAdmin { 47 | require(teamRate != _teamRate, 'no change'); 48 | emit TeamRateChanged(msg.sender, teamRate, _teamRate); 49 | teamRate = _teamRate; 50 | } 51 | 52 | function increaseFund (address _user, uint _value) public onlyOwnerAndAdmin { 53 | require(_value > 0, 'zero'); 54 | uint _old = funds[_user]; 55 | funds[_user] = _old.add(_value); 56 | emit FundChanged(msg.sender, _old, funds[_user]); 57 | } 58 | 59 | function decreaseFund (address _user, uint _value) public onlyOwnerAndAdmin { 60 | uint _old = funds[_user]; 61 | require(_value > 0, 'zero'); 62 | require(_old >= _value, 'insufficient'); 63 | funds[_user] = _old.sub(_value); 64 | emit FundChanged(msg.sender, _old, funds[_user]); 65 | } 66 | 67 | function increaseFunds (address[] calldata _users, uint[] calldata _values) external onlyOwnerAndAdmin { 68 | require(_users.length == _values.length, 'invalid parameters'); 69 | for (uint i=0; i<_users.length; i++){ 70 | increaseFund(_users[i], _values[i]); 71 | } 72 | } 73 | 74 | function decreaseFunds (address[] calldata _users, uint[] calldata _values) external onlyOwnerAndAdmin { 75 | require(_users.length == _values.length, 'invalid parameters'); 76 | for (uint i=0; i<_users.length; i++){ 77 | decreaseFund(_users[i], _values[i]); 78 | } 79 | } 80 | 81 | function upgradeImpl(address _newImpl) external onlyDev { 82 | dgas.upgradeImpl(_newImpl); 83 | } 84 | 85 | function upgradeGovernance(address _newGovernor) external onlyDev { 86 | dgas.upgradeGovernance(_newGovernor); 87 | } 88 | 89 | function changeInterestRatePerBlock(uint value) external onlyOwnerAndAdmin returns (bool) { 90 | return dgas.changeInterestRatePerBlock(value); 91 | } 92 | 93 | function increaseProductivity(address user, uint value) public returns (bool) { 94 | if(msg.sender == dev() || msg.sender == owner) { 95 | return dgas.increaseProductivity(user, value); 96 | } 97 | return false; 98 | } 99 | 100 | function decreaseProductivity(address user, uint value) public returns (bool) { 101 | if(msg.sender == dev() || msg.sender == owner) { 102 | return dgas.decreaseProductivity(user, value); 103 | } 104 | return false; 105 | } 106 | 107 | function increaseProductivities(address[] calldata _users, uint[] calldata _values) external onlyDev { 108 | require(_users.length == _values.length, 'invalid parameters'); 109 | for (uint i=0; i<_users.length; i++){ 110 | increaseProductivity(_users[i], _values[i]); 111 | } 112 | } 113 | 114 | function decreaseProductivities(address[] calldata _users, uint[] calldata _values) external onlyDev { 115 | require(_users.length == _values.length, 'invalid parameters'); 116 | for (uint i=0; i<_users.length; i++){ 117 | decreaseProductivity(_users[i], _values[i]); 118 | } 119 | } 120 | 121 | function getProductivity(address user) external view returns (uint, uint) { 122 | return dgas.getProductivity(user); 123 | } 124 | 125 | function mintDgas() external onlyManager returns (uint) { 126 | if(dgas.takeWithAddress(address(this)) > 0) { 127 | return dgas.mint(); 128 | } 129 | return 0; 130 | } 131 | 132 | function take() public view returns (uint) { 133 | uint amount = funds[msg.sender]; 134 | uint balance = dgas.balanceOf(address(this)); 135 | if(amount > balance) { 136 | amount = balance; 137 | } 138 | return amount; 139 | } 140 | 141 | function _mint(address to, uint value) internal returns (bool) { 142 | if(value > dgas.balanceOf(address(this))) { 143 | dgas.mint(); 144 | } 145 | require(dgas.balanceOf(address(this)) >= value, "mint insufficient"); 146 | return dgas.transfer(to, value); 147 | } 148 | 149 | function mint(address to, uint value) external returns (bool) { 150 | require(take() >= value && funds[msg.sender] >= value, "fund insufficient"); 151 | funds[msg.sender] = funds[msg.sender].sub(value); 152 | _mint(to, value); 153 | 154 | if(value > 0 && teamRate > 0 && team != to) { 155 | uint reward = value.div(teamRate); 156 | _mint(team, reward); 157 | } 158 | return true; 159 | } 160 | 161 | function name() external view returns (string memory) { 162 | return dgas.name(); 163 | } 164 | 165 | function symbol() external view returns (string memory) { 166 | return dgas.symbol(); 167 | } 168 | 169 | function decimals() external view returns (uint8) { 170 | return dgas.decimals(); 171 | } 172 | 173 | function totalSupply() external view returns (uint) { 174 | return dgas.totalSupply(); 175 | } 176 | 177 | function balanceOf(address user) external view returns (uint) { 178 | return dgas.balanceOf(user); 179 | } 180 | 181 | function allowance(address owner, address spender) external view returns (uint) { 182 | return dgas.allowance(owner, spender); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /contracts/backup.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/burgerswap-org/burgerswap-core/f00a7d58380f9895eb441e92baa64e95614b448f/contracts/backup.zip -------------------------------------------------------------------------------- /contracts/ballots/DemaxBallot.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | pragma solidity >=0.6.6; 3 | 4 | import '../interfaces/IERC20.sol'; 5 | 6 | /** 7 | * @title DemaxBallot 8 | * @dev Implements voting process along with vote delegation 9 | */ 10 | contract DemaxBallot { 11 | 12 | struct Voter { 13 | uint weight; // weight is accumulated by delegation 14 | bool voted; // if true, that person already voted 15 | address delegate; // person delegated to 16 | uint vote; // index of the voted proposal 17 | } 18 | 19 | mapping(address => Voter) public voters; 20 | mapping(uint => uint) public proposals; 21 | 22 | address public governor; 23 | address public proposer; 24 | uint public value; 25 | uint public endBlockNumber; 26 | bool public ended; 27 | string public subject; 28 | string public content; 29 | 30 | uint private constant NONE = 0; 31 | uint private constant YES = 1; 32 | uint private constant NO = 2; 33 | 34 | uint public total; 35 | uint public createTime; 36 | address public factory; 37 | 38 | modifier onlyGovernor() { 39 | require(msg.sender == governor, 'DemaxBallot: FORBIDDEN'); 40 | _; 41 | } 42 | 43 | /** 44 | * @dev Create a new ballot. 45 | */ 46 | constructor() public { 47 | factory = msg.sender; 48 | proposals[YES] = 0; 49 | proposals[NO] = 0; 50 | createTime = block.timestamp; 51 | } 52 | 53 | function initialize(address _proposer, uint _value, uint _endBlockNumber, address _governor, string memory _subject, string memory _content) public { 54 | require(msg.sender == factory, 'DemaxBallot: FORBIDDEN'); 55 | proposer = _proposer; 56 | value = _value; 57 | endBlockNumber = _endBlockNumber; 58 | governor = _governor; 59 | subject = _subject; 60 | content = _content; 61 | } 62 | 63 | /** 64 | * @dev Give 'voter' the right to vote on this ballot. 65 | * @param voter address of voter 66 | */ 67 | function _giveRightToVote(address voter) private returns (Voter storage) { 68 | require(block.number < endBlockNumber, "Ballot is ended"); 69 | Voter storage sender = voters[voter]; 70 | require(!sender.voted, "You already voted"); 71 | sender.weight += IERC20(governor).balanceOf(voter); 72 | require(sender.weight != 0, "Has no right to vote"); 73 | return sender; 74 | } 75 | 76 | /** 77 | * @dev Delegate your vote to the voter 'to'. 78 | * @param to address to which vote is delegated 79 | */ 80 | function delegate(address to) public { 81 | Voter storage sender = _giveRightToVote(msg.sender); 82 | require(to != msg.sender, "Self-delegation is disallowed"); 83 | 84 | while (voters[to].delegate != address(0)) { 85 | to = voters[to].delegate; 86 | 87 | // We found a loop in the delegation, not allowed. 88 | require(to != msg.sender, "Found loop in delegation"); 89 | } 90 | sender.voted = true; 91 | sender.delegate = to; 92 | Voter storage delegate_ = voters[to]; 93 | if (delegate_.voted) { 94 | // If the delegate already voted, 95 | // directly add to the number of votes 96 | proposals[delegate_.vote] += sender.weight; 97 | total += sender.weight; 98 | } else { 99 | // If the delegate did not vote yet, 100 | // add to her weight. 101 | delegate_.weight += sender.weight; 102 | } 103 | sender.weight = 0; 104 | } 105 | 106 | /** 107 | * @dev Give your vote (including votes delegated to you) to proposal 'proposals[proposal].name'. 108 | * @param proposal index of proposal in the proposals array 109 | */ 110 | function vote(uint proposal) public { 111 | Voter storage sender = _giveRightToVote(msg.sender); 112 | require(proposal==YES || proposal==NO, 'Only vote 1 or 2'); 113 | sender.voted = true; 114 | sender.vote = proposal; 115 | proposals[proposal] += sender.weight; 116 | total += sender.weight; 117 | } 118 | 119 | /** 120 | * @dev Computes the winning proposal taking all previous votes into account. 121 | * @return winningProposal_ index of winning proposal in the proposals array 122 | */ 123 | function winningProposal() public view returns (uint) { 124 | if (proposals[YES] > proposals[NO]) { 125 | return YES; 126 | } else if (proposals[YES] < proposals[NO]) { 127 | return NO; 128 | } else { 129 | return NONE; 130 | } 131 | } 132 | 133 | function result() public view returns (bool) { 134 | uint winner = winningProposal(); 135 | if (winner == YES) { 136 | return true; 137 | } 138 | return false; 139 | } 140 | 141 | function end() public onlyGovernor returns (bool) { 142 | require(block.number >= endBlockNumber, "ballot not yet ended"); 143 | require(!ended, "end has already been called"); 144 | ended = true; 145 | return result(); 146 | } 147 | 148 | function weight(address user) external view returns (uint) { 149 | Voter memory voter = voters[user]; 150 | return voter.weight; 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /contracts/ballots/DemaxBallotFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import "./DemaxBallot.sol"; 4 | 5 | contract DemaxBallotFactory { 6 | 7 | event Created(address indexed proposer, address indexed ballotAddr, uint createTime); 8 | 9 | constructor () public { 10 | } 11 | 12 | function create(address _proposer, uint _value, uint _endBlockNumber, string calldata _subject, string calldata _content) external returns (address) { 13 | require(_value >= 0, 'DemaxBallotFactory: INVALID_PARAMTERS'); 14 | address ballotAddr = address( 15 | new DemaxBallot() 16 | ); 17 | DemaxBallot(ballotAddr).initialize(_proposer, _value, _endBlockNumber, msg.sender, _subject, _content); 18 | emit Created(_proposer, ballotAddr, block.timestamp); 19 | return ballotAddr; 20 | } 21 | } -------------------------------------------------------------------------------- /contracts/demaxConfig.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import './libraries/ConfigNames.sol'; 4 | import './libraries/TransferHelper.sol'; 5 | import './modules/TokenRegistry.sol'; 6 | import './modules/Ownable.sol'; 7 | 8 | contract DemaxConfig is TokenRegistry, Ownable { 9 | uint public version = 1; 10 | event ConfigValueChanged(bytes32 _name, uint _old, uint _value); 11 | 12 | struct Config { 13 | uint minValue; 14 | uint maxValue; 15 | uint maxSpan; 16 | uint value; 17 | uint enable; // 0:disable, 1: enable 18 | } 19 | 20 | mapping(bytes32 => Config) public configs; 21 | address public dgas; // DGAS contract address 22 | address public platform; 23 | address public dev; 24 | uint public constant PERCENT_DENOMINATOR = 10000; 25 | uint public constant DGAS_DECIMAL = 10 ** 18; 26 | address[] public defaultListTokens; 27 | 28 | modifier onlyPlatform() { 29 | require(msg.sender == platform, 'DemaxConfig: ONLY_PLATFORM'); 30 | _; 31 | } 32 | 33 | constructor() public { 34 | _initConfig(ConfigNames.PRODUCE_DGAS_RATE, 1 * DGAS_DECIMAL, 120 * DGAS_DECIMAL, 10 * DGAS_DECIMAL, 40 * DGAS_DECIMAL); 35 | _initConfig(ConfigNames.SWAP_FEE_PERCENT, 5,30,5,30); 36 | _initConfig(ConfigNames.LIST_DGAS_AMOUNT, 0, 100000 * DGAS_DECIMAL, 1000 * DGAS_DECIMAL, 0); 37 | _initConfig(ConfigNames.UNSTAKE_DURATION, 17280, 17280*7, 17280, 17280); 38 | _initConfig(ConfigNames.REMOVE_LIQUIDITY_DURATION, 0, 17280*7, 17280, 0); 39 | _initConfig(ConfigNames.TOKEN_TO_DGAS_PAIR_MIN_PERCENT, 20, 500, 10, 100); 40 | _initConfig(ConfigNames.LIST_TOKEN_FAILURE_BURN_PRECENT, 100, 5000, 500, 1000); 41 | _initConfig(ConfigNames.LIST_TOKEN_SUCCESS_BURN_PRECENT, 1000, 5000, 500, 5000); 42 | _initConfig(ConfigNames.PROPOSAL_DGAS_AMOUNT, 100 * DGAS_DECIMAL, 10000 * DGAS_DECIMAL, 100 * DGAS_DECIMAL, 100 * DGAS_DECIMAL); 43 | _initConfig(ConfigNames.VOTE_DURATION, 17280, 17280*7, 17280, 17280); 44 | _initConfig(ConfigNames.VOTE_REWARD_PERCENT, 0, 1000, 100, 500); 45 | _initConfig(ConfigNames.TOKEN_PENGDING_SWITCH, 0, 1, 1, 1); // 0:off, 1:on 46 | _initConfig(ConfigNames.TOKEN_PENGDING_TIME, 0, 100*17280, 10*17280, 100*17280); 47 | _initConfig(ConfigNames.LIST_TOKEN_SWITCH, 0, 1, 1, 0); // 0:off, 1:on 48 | _initConfig(ConfigNames.DEV_PRECENT, 1000, 1000, 1000, 1000); 49 | } 50 | 51 | function _initConfig(bytes32 _name, uint _minValue, uint _maxValue, uint _maxSpan, uint _value) internal { 52 | Config storage config = configs[_name]; 53 | config.minValue = _minValue; 54 | config.maxValue = _maxValue; 55 | config.maxSpan = _maxSpan; 56 | config.value = _value; 57 | config.enable = 1; 58 | } 59 | 60 | function initialize( 61 | address _dgas, 62 | address _governor, 63 | address _platform, 64 | address _dev, 65 | address[] memory _listTokens) public onlyOwner { 66 | require(_dgas != address(0), "DemaxConfig: ZERO ADDRESS"); 67 | dgas = _dgas; 68 | platform = _platform; 69 | dev = _dev; 70 | for(uint i = 0 ; i < _listTokens.length; i++){ 71 | _updateToken(_listTokens[i], OPENED); 72 | defaultListTokens.push(_listTokens[i]); 73 | } 74 | initGovernorAddress(_governor); 75 | } 76 | 77 | function modifyGovernor(address _new) public onlyOwner { 78 | _changeGovernor(_new); 79 | } 80 | 81 | function modifyDev(address _new) public { 82 | require(msg.sender == dev, 'DemaxConfig: FORBIDDEN'); 83 | dev = _new; 84 | } 85 | 86 | function changeConfig(bytes32 _name, uint _minValue, uint _maxValue, uint _maxSpan, uint _value) external onlyOwner returns (bool) { 87 | _initConfig(_name, _minValue, _maxValue, _maxSpan, _value); 88 | return true; 89 | } 90 | 91 | function getConfig(bytes32 _name) external view returns (uint minValue, uint maxValue, uint maxSpan, uint value, uint enable) { 92 | Config memory config = configs[_name]; 93 | minValue = config.minValue; 94 | maxValue = config.maxValue; 95 | maxSpan = config.maxSpan; 96 | value = config.value; 97 | enable = config.enable; 98 | } 99 | 100 | function getConfigValue(bytes32 _name) public view returns (uint) { 101 | return configs[_name].value; 102 | } 103 | 104 | function changeConfigValue(bytes32 _name, uint _value) external onlyGovernor returns (bool) { 105 | Config storage config = configs[_name]; 106 | require(config.enable == 1, "DemaxConfig: DISABLE"); 107 | require(_value <= config.maxValue && _value >= config.minValue, "DemaxConfig: OVERFLOW"); 108 | uint old = config.value; 109 | uint span = _value >= old ? (_value - old) : (old - _value); 110 | require(span <= config.maxSpan, "DemaxConfig: EXCEED MAX ADJUST SPAN"); 111 | config.value = _value; 112 | emit ConfigValueChanged(_name, old, _value); 113 | return true; 114 | } 115 | 116 | function checkToken(address _token) public view returns(bool) { 117 | if (getConfigValue(ConfigNames.LIST_TOKEN_SWITCH) == 0) { 118 | return true; 119 | } 120 | if (tokenStatus[_token] == OPENED) { 121 | return true; 122 | } else if (tokenStatus[_token] == PENDING ) { 123 | if (getConfigValue(ConfigNames.TOKEN_PENGDING_SWITCH) == 1 && block.number > publishTime[_token] + getConfigValue(ConfigNames.TOKEN_PENGDING_TIME)) { 124 | return false; 125 | } else { 126 | return true; 127 | } 128 | } 129 | return false; 130 | } 131 | 132 | function checkPair(address tokenA, address tokenB) external view returns (bool) { 133 | if (checkToken(tokenA) && checkToken(tokenB)) { 134 | return true; 135 | } 136 | return false; 137 | } 138 | 139 | function getDefaultListTokens() external view returns (address[] memory) { 140 | address[] memory res = new address[](defaultListTokens.length); 141 | for (uint i; i < defaultListTokens.length; i++) { 142 | res[i] = defaultListTokens[i]; 143 | } 144 | return res; 145 | } 146 | 147 | function addToken(address _token) external onlyPlatform returns (bool) { 148 | if(getConfigValue(ConfigNames.LIST_TOKEN_SWITCH) == 0) { 149 | if(tokenStatus[_token] != OPENED) { 150 | _updateToken(_token, OPENED); 151 | } 152 | } 153 | return true; 154 | } 155 | 156 | } 157 | 158 | -------------------------------------------------------------------------------- /contracts/interfaces/ERC2917-Interface.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.6; 3 | import '../interfaces/IERC20.sol'; 4 | 5 | interface IERC2917 is IERC20 { 6 | 7 | /// @dev This emit when interests amount per block is changed by the owner of the contract. 8 | /// It emits with the old interests amount and the new interests amount. 9 | event InterestRatePerBlockChanged (uint oldValue, uint newValue); 10 | 11 | /// @dev This emit when a users' productivity has changed 12 | /// It emits with the user's address and the the value after the change. 13 | event ProductivityIncreased (address indexed user, uint value); 14 | 15 | /// @dev This emit when a users' productivity has changed 16 | /// It emits with the user's address and the the value after the change. 17 | event ProductivityDecreased (address indexed user, uint value); 18 | 19 | /// @dev Return the current contract's interests rate per block. 20 | /// @return The amount of interests currently producing per each block. 21 | function interestsPerBlock() external view returns (uint); 22 | 23 | /// @notice Change the current contract's interests rate. 24 | /// @dev Note the best practice will be restrict the gross product provider's contract address to call this. 25 | /// @return The true/fase to notice that the value has successfully changed or not, when it succeed, it will emite the InterestRatePerBlockChanged event. 26 | function changeInterestRatePerBlock(uint value) external returns (bool); 27 | 28 | /// @notice It will get the productivity of given user. 29 | /// @dev it will return 0 if user has no productivity proved in the contract. 30 | /// @return user's productivity and overall productivity. 31 | function getProductivity(address user) external view returns (uint, uint); 32 | 33 | /// @notice increase a user's productivity. 34 | /// @dev Note the best practice will be restrict the callee to prove of productivity's contract address. 35 | /// @return true to confirm that the productivity added success. 36 | function increaseProductivity(address user, uint value) external returns (bool); 37 | 38 | /// @notice decrease a user's productivity. 39 | /// @dev Note the best practice will be restrict the callee to prove of productivity's contract address. 40 | /// @return true to confirm that the productivity removed success. 41 | function decreaseProductivity(address user, uint value) external returns (bool); 42 | 43 | /// @notice take() will return the interests that callee will get at current block height. 44 | /// @dev it will always calculated by block.number, so it will change when block height changes. 45 | /// @return amount of the interests that user are able to mint() at current block height. 46 | function take() external view returns (uint); 47 | 48 | /// @notice similar to take(), but with the block height joined to calculate return. 49 | /// @dev for instance, it returns (_amount, _block), which means at block height _block, the callee has accumulated _amount of interests. 50 | /// @return amount of interests and the block height. 51 | function takeWithBlock() external view returns (uint, uint); 52 | 53 | /// @notice mint the avaiable interests to callee. 54 | /// @dev once it mint, the amount of interests will transfer to callee's address. 55 | /// @return the amount of interests minted. 56 | function mint() external returns (uint); 57 | } -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxBallot.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.1; 2 | 3 | interface IDemaxBallot { 4 | function proposer() external view returns(address); 5 | function endBlockNumber() external view returns(uint); 6 | function value() external view returns(uint); 7 | function result() external view returns(bool); 8 | function end() external returns (bool); 9 | function total() external view returns(uint); 10 | function weight(address user) external view returns (uint); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxBallotFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDemaxBallotFactory { 4 | function create( 5 | address _proposer, 6 | uint _value, 7 | uint _endBlockNumber, 8 | string calldata _subject, 9 | string calldata _content 10 | ) external returns (address); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxCallee.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDemaxCallee { 4 | function demaxCall(address sender, uint amount0, uint amount1, bytes calldata data) external; 5 | } 6 | -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxConfig.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDemaxConfig { 4 | function governor() external view returns (address); 5 | function dev() external view returns (address); 6 | function PERCENT_DENOMINATOR() external view returns (uint); 7 | function getConfig(bytes32 _name) external view returns (uint minValue, uint maxValue, uint maxSpan, uint value, uint enable); 8 | function getConfigValue(bytes32 _name) external view returns (uint); 9 | function changeConfigValue(bytes32 _name, uint _value) external returns (bool); 10 | function checkToken(address _token) external view returns(bool); 11 | function checkPair(address tokenA, address tokenB) external view returns (bool); 12 | function listToken(address _token) external returns (bool); 13 | function getDefaultListTokens() external returns (address[] memory); 14 | function platform() external view returns (address); 15 | function addToken(address _token) external returns (bool); 16 | } -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxDelegate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | interface IDemaxDelegate { 4 | function getPair(address tokenA, address tokenB) external view returns(address); 5 | function allPairs(uint index) external view returns(address); 6 | function allPairsLength() external view returns (uint256); 7 | 8 | function getPlayerPairCount(address player) external view returns(uint); 9 | function playerPairs(address user, uint index) external view returns(address); 10 | 11 | function addLiquidityETH( 12 | address token, 13 | uint256 amountTokenDesired, 14 | uint256 amountTokenMin, 15 | uint256 amountETHMin, 16 | uint256 deadline 17 | ) payable external returns ( 18 | uint256 _amountToken, 19 | uint256 _amountETH, 20 | uint256 _liquidity 21 | ); 22 | 23 | 24 | function addLiquidity( 25 | address tokenA, 26 | address tokenB, 27 | uint256 amountA, 28 | uint256 amountB, 29 | uint256 amountAMin, 30 | uint256 amountBMin, 31 | uint256 deadline) external returns ( 32 | uint256 _amountA, 33 | uint256 _amountB, 34 | uint256 _liquidity 35 | ); 36 | 37 | function removeLiquidityETH( 38 | address token, 39 | uint liquidity, 40 | uint amountTokenMin, 41 | uint amountETHMin, 42 | uint deadline 43 | ) external returns (uint _amountToken, uint _amountETH); 44 | 45 | function removeLiquidity( 46 | address tokenA, 47 | address tokenB, 48 | uint256 liquidity, 49 | uint256 amountAMin, 50 | uint256 amountBMin, 51 | uint256 deadline) external returns ( 52 | uint256 _amountA, 53 | uint256 _amountB 54 | ); 55 | } -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDemaxFactory { 4 | event PairCreated(address indexed token0, address indexed token1, address pair, uint); 5 | 6 | function contractCodeHash() external view returns (bytes32); 7 | function getPair(address tokenA, address tokenB) external view returns (address pair); 8 | function isPair(address pair) external view returns (bool); 9 | function allPairs(uint) external view returns (address pair); 10 | function allPairsLength() external view returns (uint); 11 | function playerPairs(address player, uint index) external view returns (address pair); 12 | function getPlayerPairCount(address player) external view returns (uint); 13 | 14 | function createPair(address tokenA, address tokenB) external returns (address pair); 15 | function addPlayerPair(address player, address _pair) external returns (bool); 16 | } 17 | -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxGovernance.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDemaxGovernance { 4 | function addPair(address _tokenA, address _tokenB) external returns (bool); 5 | function addReward(uint _value) external returns (bool); 6 | } 7 | 8 | -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxLP.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | interface IDemaxLP { 4 | function name() external view returns (string memory); 5 | function symbol() external view returns (string memory); 6 | function decimals() external view returns (uint8); 7 | function totalSupply() external view returns (uint); 8 | function balanceOf(address owner) external view returns (uint); 9 | function allowance(address owner, address spender) external view returns (uint); 10 | 11 | function approve(address spender, uint value) external returns (bool); 12 | function transfer(address to, uint value) external returns (bool); 13 | function transferFrom(address from, address to, uint value) external returns (bool); 14 | 15 | function tokenA() external view returns (address); 16 | function tokenB() external view returns (address); 17 | function queryReward() external view returns (uint); 18 | function mintReward() external returns (uint amount); 19 | } -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxPair.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDemaxPair { 4 | 5 | event Mint(address indexed sender, uint amount0, uint amount1); 6 | event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); 7 | event Swap( 8 | address indexed sender, 9 | uint amount0In, 10 | uint amount1In, 11 | uint amount0Out, 12 | uint amount1Out, 13 | address indexed to 14 | ); 15 | event Sync(uint112 reserve0, uint112 reserve1); 16 | 17 | function MINIMUM_LIQUIDITY() external pure returns (uint); 18 | function factory() external view returns (address); 19 | function token0() external view returns (address); 20 | function token1() external view returns (address); 21 | function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); 22 | function price0CumulativeLast() external view returns (uint); 23 | function price1CumulativeLast() external view returns (uint); 24 | function kLast() external view returns (uint); 25 | function totalSupply() external view returns (uint); 26 | function balanceOf(address) external view returns (uint); 27 | 28 | function mint(address to) external returns (uint liquidity); 29 | function burn(address from, address to, uint amount) external returns (uint amount0, uint amount1); 30 | function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; 31 | function skim(address to) external; 32 | function sync() external; 33 | 34 | function initialize(address tokenA, address tokenB, address platform, address dgas) external; 35 | function swapFee(uint amount, address token, address to) external ; 36 | function queryReward() external view returns (uint rewardAmount, uint blockNumber); 37 | function mintReward() external returns (uint rewardAmount); 38 | function getDGASReserve() external view returns (uint); 39 | } 40 | -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxPool.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDemaxPool { 4 | function addRewardFromPlatform(address _pair, uint _amount) external; 5 | function preProductivityChanged(address _pair, address _user) external; 6 | function postProductivityChanged(address _pair, address _user) external; 7 | } -------------------------------------------------------------------------------- /contracts/interfaces/IDemaxTransferListener.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | interface IDemaxTransferListener { 4 | function transferNotify(address from, address to, address token, uint amount) external returns (bool); 5 | function upgradeProdutivity(address fromPair, address toPair) external; 6 | } -------------------------------------------------------------------------------- /contracts/interfaces/IDgas.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IDgas { 4 | function amountPerBlock() external view returns (uint); 5 | function changeInterestRatePerBlock(uint value) external returns (bool); 6 | function getProductivity(address user) external view returns (uint, uint); 7 | function increaseProductivity(address user, uint value) external returns (bool); 8 | function decreaseProductivity(address user, uint value) external returns (bool); 9 | function take() external view returns (uint); 10 | function takeWithBlock() external view returns (uint, uint); 11 | function mint() external returns (uint); 12 | function balanceOf(address owner) external view returns (uint); 13 | function upgradeImpl(address _newImpl) external; 14 | function upgradeGovernance(address _newGovernor) external; 15 | function transfer(address to, uint value) external returns (bool); 16 | function approve(address spender, uint value) external returns (bool); 17 | } -------------------------------------------------------------------------------- /contracts/interfaces/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IERC20 { 4 | event Approval(address indexed owner, address indexed spender, uint value); 5 | event Transfer(address indexed from, address indexed to, uint value); 6 | 7 | function name() external view returns (string memory); 8 | function symbol() external view returns (string memory); 9 | function decimals() external view returns (uint8); 10 | function totalSupply() external view returns (uint); 11 | function balanceOf(address owner) external view returns (uint); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | 14 | function approve(address spender, uint value) external returns (bool); 15 | function transfer(address to, uint value) external returns (bool); 16 | function transferFrom(address from, address to, uint value) external returns (bool); 17 | } 18 | -------------------------------------------------------------------------------- /contracts/interfaces/IERC2917.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.6; 3 | import './IERC20.sol'; 4 | 5 | interface IERC2917 is IERC20 { 6 | 7 | function upgradeGovernance(address _newGovernor) external; 8 | function upgradeImpl(address _newImpl) external; 9 | 10 | /// @dev Return the current contract's interests rate per block. 11 | /// @return The amount of interests currently producing per each block. 12 | function interestsPerBlock() external view returns (uint); 13 | 14 | /// @notice Change the current contract's interests rate. 15 | /// @dev Note the best practice will be restrict the gross product provider's contract address to call this. 16 | /// @return The true/fase to notice that the value has successfully changed or not, when it succeed, it will emite the InterestRatePerBlockChanged event. 17 | function changeInterestRatePerBlock(uint value) external returns (bool); 18 | 19 | /// @notice It will get the productivity of given user. 20 | /// @dev it will return 0 if user has no productivity proved in the contract. 21 | /// @return user's productivity and overall productivity. 22 | function getProductivity(address user) external view returns (uint, uint); 23 | 24 | /// @notice increase a user's productivity. 25 | /// @dev Note the best practice will be restrict the callee to prove of productivity's contract address. 26 | /// @return true to confirm that the productivity added success. 27 | function increaseProductivity(address user, uint value) external returns (bool); 28 | 29 | /// @notice decrease a user's productivity. 30 | /// @dev Note the best practice will be restrict the callee to prove of productivity's contract address. 31 | /// @return true to confirm that the productivity removed success. 32 | function decreaseProductivity(address user, uint value) external returns (bool); 33 | 34 | /// @notice take() will return the interests that callee will get at current block height. 35 | /// @dev it will always calculated by block.number, so it will change when block height changes. 36 | /// @return amount of the interests that user are able to mint() at current block height. 37 | function take() external view returns (uint); 38 | 39 | /// @notice similar to take(), but with the block height joined to calculate return. 40 | /// @dev for instance, it returns (_amount, _block), which means at block height _block, the callee has accumulated _amount of interests. 41 | /// @return amount of interests and the block height. 42 | function takeWithBlock() external view returns (uint, uint); 43 | function takeWithAddress(address user) external view returns (uint); 44 | 45 | /// @notice mint the avaiable interests to callee. 46 | /// @dev once it mint, the amount of interests will transfer to callee's address. 47 | /// @return the amount of interests minted. 48 | function mint() external returns (uint); 49 | } -------------------------------------------------------------------------------- /contracts/interfaces/ITokenRegistry.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | interface ITokenRegistry { 4 | function tokenStatus(address _token) external view returns(uint); 5 | function pairStatus(address tokenA, address tokenB) external view returns (uint); 6 | function NONE() external view returns(uint); 7 | function REGISTERED() external view returns(uint); 8 | function PENDING() external view returns(uint); 9 | function OPENED() external view returns(uint); 10 | function CLOSED() external view returns(uint); 11 | function registryToken(address _token) external returns (bool); 12 | function publishToken(address _token) external returns (bool); 13 | function updateToken(address _token, uint _status) external returns (bool); 14 | function updatePair(address tokenA, address tokenB, uint _status) external returns (bool); 15 | function tokenCount() external view returns(uint); 16 | function validTokens() external view returns(address[] memory); 17 | function iterateValidTokens(uint32 _start, uint32 _end) external view returns (address[] memory); 18 | } -------------------------------------------------------------------------------- /contracts/interfaces/IWETH.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | interface IWETH { 4 | function deposit() external payable; 5 | function transfer(address to, uint value) external returns (bool); 6 | function withdraw(uint) external; 7 | } 8 | -------------------------------------------------------------------------------- /contracts/libraries/AddressStringUtil.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | library AddressStringUtil { 6 | // converts an address to the uppercase hex string, extracting only len bytes (up to 20, multiple of 2) 7 | function toAsciiString(address addr, uint len) pure internal returns (string memory) { 8 | require(len % 2 == 0 && len > 0 && len <= 40, "AddressStringUtil: INVALID_LEN"); 9 | 10 | bytes memory s = new bytes(len); 11 | uint addrNum = uint(addr); 12 | for (uint i = 0; i < len / 2; i++) { 13 | // shift right and truncate all but the least significant byte to extract the byte at position 19-i 14 | uint8 b = uint8(addrNum >> (8 * (19 - i))); 15 | // first hex character is the most significant 4 bits 16 | uint8 hi = b >> 4; 17 | // second hex character is the least significant 4 bits 18 | uint8 lo = b - (hi << 4); 19 | s[2 * i] = char(hi); 20 | s[2 * i + 1] = char(lo); 21 | } 22 | return string(s); 23 | } 24 | 25 | // hi and lo are only 4 bits and between 0 and 16 26 | // this method converts those values to the unicode/ascii code point for the hex representation 27 | // uses upper case for the characters 28 | function char(uint8 b) pure private returns (byte c) { 29 | if (b < 10) { 30 | return byte(b + 0x30); 31 | } else { 32 | return byte(b + 0x37); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contracts/libraries/Babylonian.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.4.0; 4 | 5 | // computes square roots using the babylonian method 6 | // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method 7 | library Babylonian { 8 | function sqrt(uint y) internal pure returns (uint z) { 9 | if (y > 3) { 10 | z = y; 11 | uint x = y / 2 + 1; 12 | while (x < z) { 13 | z = x; 14 | x = (y / x + x) / 2; 15 | } 16 | } else if (y != 0) { 17 | z = 1; 18 | } 19 | // else z = 0 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/libraries/ConfigNames.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | library ConfigNames { 4 | bytes32 public constant PRODUCE_DGAS_RATE = bytes32('PRODUCE_DGAS_RATE'); 5 | bytes32 public constant SWAP_FEE_PERCENT = bytes32('SWAP_FEE_PERCENT'); 6 | bytes32 public constant LIST_DGAS_AMOUNT = bytes32('LIST_DGAS_AMOUNT'); 7 | bytes32 public constant UNSTAKE_DURATION = bytes32('UNSTAKE_DURATION'); 8 | bytes32 public constant REMOVE_LIQUIDITY_DURATION = bytes32('REMOVE_LIQUIDITY_DURATION'); 9 | bytes32 public constant TOKEN_TO_DGAS_PAIR_MIN_PERCENT = bytes32('TOKEN_TO_DGAS_PAIR_MIN_PERCENT'); 10 | bytes32 public constant LIST_TOKEN_FAILURE_BURN_PRECENT = bytes32('LIST_TOKEN_FAILURE_BURN_PRECENT'); 11 | bytes32 public constant LIST_TOKEN_SUCCESS_BURN_PRECENT = bytes32('LIST_TOKEN_SUCCESS_BURN_PRECENT'); 12 | bytes32 public constant PROPOSAL_DGAS_AMOUNT = bytes32('PROPOSAL_DGAS_AMOUNT'); 13 | bytes32 public constant VOTE_DURATION = bytes32('VOTE_DURATION'); 14 | bytes32 public constant VOTE_REWARD_PERCENT = bytes32('VOTE_REWARD_PERCENT'); 15 | bytes32 public constant TOKEN_PENGDING_SWITCH = bytes32('TOKEN_PENGDING_SWITCH'); 16 | bytes32 public constant TOKEN_PENGDING_TIME = bytes32('TOKEN_PENGDING_TIME'); 17 | bytes32 public constant LIST_TOKEN_SWITCH = bytes32('LIST_TOKEN_SWITCH'); 18 | bytes32 public constant DEV_PRECENT = bytes32('DEV_PRECENT'); 19 | bytes32 public constant FEE_GOVERNANCE_REWARD_PERCENT = bytes32('FEE_GOVERNANCE_REWARD_PERCENT'); 20 | bytes32 public constant FEE_LP_REWARD_PERCENT = bytes32('FEE_LP_REWARD_PERCENT'); 21 | } -------------------------------------------------------------------------------- /contracts/libraries/DemaxSwapLibrary.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | import '../interfaces/IDemaxPair.sol'; 4 | import '../interfaces/IDemaxFactory.sol'; 5 | import "./SafeMath.sol"; 6 | 7 | library DemaxSwapLibrary { 8 | using SafeMath for uint; 9 | 10 | function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { 11 | require(tokenA != tokenB, 'DemaxSwapLibrary: IDENTICAL_ADDRESSES'); 12 | (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); 13 | require(token0 != address(0), 'DemaxSwapLibrary: ZERO_ADDRESS'); 14 | } 15 | 16 | function pairFor(address factory, address tokenA, address tokenB) internal view returns (address pair) { 17 | (address token0, address token1) = sortTokens(tokenA, tokenB); 18 | bytes32 salt = keccak256(abi.encodePacked(token0, token1)); 19 | bytes32 rawAddress = keccak256( 20 | abi.encodePacked( 21 | bytes1(0xff), 22 | factory, 23 | salt, 24 | IDemaxFactory(factory).contractCodeHash() 25 | ) 26 | ); 27 | return address(bytes20(rawAddress << 96)); 28 | } 29 | 30 | function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { 31 | (address token0,) = sortTokens(tokenA, tokenB); 32 | (uint reserve0, uint reserve1,) = IDemaxPair(pairFor(factory, tokenA, tokenB)).getReserves(); 33 | (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); 34 | } 35 | 36 | function quoteEnhance(address factory, address tokenA, address tokenB, uint amountA) internal view returns(uint amountB) { 37 | (uint reserveA, uint reserveB) = getReserves(factory, tokenA, tokenB); 38 | return quote(amountA, reserveA, reserveB); 39 | } 40 | 41 | function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { 42 | require(amountA > 0, 'DemaxSwapLibrary: INSUFFICIENT_AMOUNT'); 43 | require(reserveA > 0 && reserveB > 0, 'DemaxSwapLibrary: INSUFFICIENT_LIQUIDITY'); 44 | amountB = amountA.mul(reserveB) / reserveA; 45 | } 46 | 47 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { 48 | require(amountIn > 0, 'DemaxSwapLibrary: INSUFFICIENT_INPUT_AMOUNT'); 49 | require(reserveIn > 0 && reserveOut > 0, 'DemaxSwapLibrary: INSUFFICIENT_LIQUIDITY'); 50 | uint numerator = amountIn.mul(reserveOut); 51 | uint denominator = reserveIn.add(amountIn); 52 | amountOut = numerator / denominator; 53 | } 54 | 55 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { 56 | require(amountOut > 0, 'DemaxSwapLibrary: INSUFFICIENT_OUTPUT_AMOUNT'); 57 | require(reserveIn > 0 && reserveOut > 0, 'DemaxSwapLibrary: INSUFFICIENT_LIQUIDITY'); 58 | uint numerator = reserveIn.mul(amountOut); 59 | uint denominator = reserveOut.sub(amountOut); 60 | amountIn = (numerator / denominator).add(1); 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /contracts/libraries/FixedPoint.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.4.0; 4 | 5 | import './Babylonian.sol'; 6 | 7 | // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) 8 | library FixedPoint { 9 | // range: [0, 2**112 - 1] 10 | // resolution: 1 / 2**112 11 | struct uq112x112 { 12 | uint224 _x; 13 | } 14 | 15 | // range: [0, 2**144 - 1] 16 | // resolution: 1 / 2**112 17 | struct uq144x112 { 18 | uint _x; 19 | } 20 | 21 | uint8 private constant RESOLUTION = 112; 22 | uint private constant Q112 = uint(1) << RESOLUTION; 23 | uint private constant Q224 = Q112 << RESOLUTION; 24 | 25 | // encode a uint112 as a UQ112x112 26 | function encode(uint112 x) internal pure returns (uq112x112 memory) { 27 | return uq112x112(uint224(x) << RESOLUTION); 28 | } 29 | 30 | // encodes a uint144 as a UQ144x112 31 | function encode144(uint144 x) internal pure returns (uq144x112 memory) { 32 | return uq144x112(uint256(x) << RESOLUTION); 33 | } 34 | 35 | // divide a UQ112x112 by a uint112, returning a UQ112x112 36 | function div(uq112x112 memory self, uint112 x) internal pure returns (uq112x112 memory) { 37 | require(x != 0, 'FixedPoint: DIV_BY_ZERO'); 38 | return uq112x112(self._x / uint224(x)); 39 | } 40 | 41 | // multiply a UQ112x112 by a uint, returning a UQ144x112 42 | // reverts on overflow 43 | function mul(uq112x112 memory self, uint y) internal pure returns (uq144x112 memory) { 44 | uint z; 45 | require(y == 0 || (z = uint(self._x) * y) / y == uint(self._x), "FixedPoint: MULTIPLICATION_OVERFLOW"); 46 | return uq144x112(z); 47 | } 48 | 49 | // returns a UQ112x112 which represents the ratio of the numerator to the denominator 50 | // equivalent to encode(numerator).div(denominator) 51 | function fraction(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) { 52 | require(denominator > 0, "FixedPoint: DIV_BY_ZERO"); 53 | return uq112x112((uint224(numerator) << RESOLUTION) / denominator); 54 | } 55 | 56 | // decode a UQ112x112 into a uint112 by truncating after the radix point 57 | function decode(uq112x112 memory self) internal pure returns (uint112) { 58 | return uint112(self._x >> RESOLUTION); 59 | } 60 | 61 | // decode a UQ144x112 into a uint144 by truncating after the radix point 62 | function decode144(uq144x112 memory self) internal pure returns (uint144) { 63 | return uint144(self._x >> RESOLUTION); 64 | } 65 | 66 | // take the reciprocal of a UQ112x112 67 | function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) { 68 | require(self._x != 0, 'FixedPoint: ZERO_RECIPROCAL'); 69 | return uq112x112(uint224(Q224 / self._x)); 70 | } 71 | 72 | // square root of a UQ112x112 73 | function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) { 74 | return uq112x112(uint224(Babylonian.sqrt(uint256(self._x)) << 56)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /contracts/libraries/Math.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | // a library for performing various math operations 4 | 5 | library Math { 6 | function min(uint x, uint y) internal pure returns (uint z) { 7 | z = x < y ? x : y; 8 | } 9 | 10 | // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) 11 | function sqrt(uint y) internal pure returns (uint z) { 12 | if (y > 3) { 13 | z = y; 14 | uint x = y / 2 + 1; 15 | while (x < z) { 16 | z = x; 17 | x = (y / x + x) / 2; 18 | } 19 | } else if (y != 0) { 20 | z = 1; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/libraries/PairNamer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | import './SafeERC20Namer.sol'; 6 | 7 | // produces names for pairs of tokens using Uniswap's naming scheme 8 | library PairNamer { 9 | string private constant TOKEN_SYMBOL_PREFIX = '🦄'; 10 | string private constant TOKEN_SEPARATOR = ':'; 11 | 12 | // produces a pair descriptor in the format of `${prefix}${name0}:${name1}${suffix}` 13 | function pairName(address token0, address token1, string memory prefix, string memory suffix) internal view returns (string memory) { 14 | return string( 15 | abi.encodePacked( 16 | prefix, 17 | SafeERC20Namer.tokenName(token0), 18 | TOKEN_SEPARATOR, 19 | SafeERC20Namer.tokenName(token1), 20 | suffix 21 | ) 22 | ); 23 | } 24 | 25 | // produces a pair symbol in the format of `🦄${symbol0}:${symbol1}${suffix}` 26 | function pairSymbol(address token0, address token1, string memory suffix) internal view returns (string memory) { 27 | return string( 28 | abi.encodePacked( 29 | TOKEN_SYMBOL_PREFIX, 30 | SafeERC20Namer.tokenSymbol(token0), 31 | TOKEN_SEPARATOR, 32 | SafeERC20Namer.tokenSymbol(token1), 33 | suffix 34 | ) 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /contracts/libraries/SafeERC20Namer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.5.0; 4 | 5 | import './AddressStringUtil.sol'; 6 | 7 | // produces token descriptors from inconsistent or absent ERC20 symbol implementations that can return string or bytes32 8 | // this library will always produce a string symbol to represent the token 9 | library SafeERC20Namer { 10 | function bytes32ToString(bytes32 x) pure private returns (string memory) { 11 | bytes memory bytesString = new bytes(32); 12 | uint charCount = 0; 13 | for (uint j = 0; j < 32; j++) { 14 | byte char = x[j]; 15 | if (char != 0) { 16 | bytesString[charCount] = char; 17 | charCount++; 18 | } 19 | } 20 | bytes memory bytesStringTrimmed = new bytes(charCount); 21 | for (uint j = 0; j < charCount; j++) { 22 | bytesStringTrimmed[j] = bytesString[j]; 23 | } 24 | return string(bytesStringTrimmed); 25 | } 26 | 27 | // assumes the data is in position 2 28 | function parseStringData(bytes memory b) pure private returns (string memory) { 29 | uint charCount = 0; 30 | // first parse the charCount out of the data 31 | for (uint i = 32; i < 64; i++) { 32 | charCount <<= 8; 33 | charCount += uint8(b[i]); 34 | } 35 | 36 | bytes memory bytesStringTrimmed = new bytes(charCount); 37 | for (uint i = 0; i < charCount; i++) { 38 | bytesStringTrimmed[i] = b[i + 64]; 39 | } 40 | 41 | return string(bytesStringTrimmed); 42 | } 43 | 44 | // uses a heuristic to produce a token name from the address 45 | // the heuristic returns the full hex of the address string in upper case 46 | function addressToName(address token) pure private returns (string memory) { 47 | return AddressStringUtil.toAsciiString(token, 40); 48 | } 49 | 50 | // uses a heuristic to produce a token symbol from the address 51 | // the heuristic returns the first 6 hex of the address string in upper case 52 | function addressToSymbol(address token) pure private returns (string memory) { 53 | return AddressStringUtil.toAsciiString(token, 6); 54 | } 55 | 56 | // calls an external view token contract method that returns a symbol or name, and parses the output into a string 57 | function callAndParseStringReturn(address token, bytes4 selector) view private returns (string memory) { 58 | (bool success, bytes memory data) = token.staticcall(abi.encodeWithSelector(selector)); 59 | // if not implemented, or returns empty data, return empty string 60 | if (!success || data.length == 0) { 61 | return ""; 62 | } 63 | // bytes32 data always has length 32 64 | if (data.length == 32) { 65 | bytes32 decoded = abi.decode(data, (bytes32)); 66 | return bytes32ToString(decoded); 67 | } else if (data.length > 64) { 68 | return abi.decode(data, (string)); 69 | } 70 | return ""; 71 | } 72 | 73 | // attempts to extract the token symbol. if it does not implement symbol, returns a symbol derived from the address 74 | function tokenSymbol(address token) internal view returns (string memory) { 75 | // 0x95d89b41 = bytes4(keccak256("symbol()")) 76 | string memory symbol = callAndParseStringReturn(token, 0x95d89b41); 77 | if (bytes(symbol).length == 0) { 78 | // fallback to 6 uppercase hex of address 79 | return addressToSymbol(token); 80 | } 81 | return symbol; 82 | } 83 | 84 | // attempts to extract the token name. if it does not implement name, returns a name derived from the address 85 | function tokenName(address token) internal view returns (string memory) { 86 | // 0x06fdde03 = bytes4(keccak256("name()")) 87 | string memory name = callAndParseStringReturn(token, 0x06fdde03); 88 | if (bytes(name).length == 0) { 89 | // fallback to full hex of address 90 | return addressToName(token); 91 | } 92 | return name; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /contracts/libraries/SafeMath.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | /** 6 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 7 | * checks. 8 | * 9 | * Arithmetic operations in Solidity wrap on overflow. This can easily result 10 | * in bugs, because programmers usually assume that an overflow raises an 11 | * error, which is the standard behavior in high level programming languages. 12 | * `SafeMath` restores this intuition by reverting the transaction when an 13 | * operation overflows. 14 | * 15 | * Using this library instead of the unchecked operations eliminates an entire 16 | * class of bugs, so it's recommended to use it always. 17 | */ 18 | library SafeMath { 19 | /** 20 | * @dev Returns the addition of two unsigned integers, reverting on 21 | * overflow. 22 | * 23 | * Counterpart to Solidity's `+` operator. 24 | * 25 | * Requirements: 26 | * 27 | * - Addition cannot overflow. 28 | */ 29 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 30 | uint256 c = a + b; 31 | require(c >= a, "SafeMath: addition overflow"); 32 | 33 | return c; 34 | } 35 | 36 | /** 37 | * @dev Returns the subtraction of two unsigned integers, reverting on 38 | * overflow (when the result is negative). 39 | * 40 | * Counterpart to Solidity's `-` operator. 41 | * 42 | * Requirements: 43 | * 44 | * - Subtraction cannot overflow. 45 | */ 46 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 47 | return sub(a, b, "SafeMath: subtraction overflow"); 48 | } 49 | 50 | /** 51 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 52 | * overflow (when the result is negative). 53 | * 54 | * Counterpart to Solidity's `-` operator. 55 | * 56 | * Requirements: 57 | * 58 | * - Subtraction cannot overflow. 59 | */ 60 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 61 | require(b <= a, errorMessage); 62 | uint256 c = a - b; 63 | 64 | return c; 65 | } 66 | 67 | /** 68 | * @dev Returns the multiplication of two unsigned integers, reverting on 69 | * overflow. 70 | * 71 | * Counterpart to Solidity's `*` operator. 72 | * 73 | * Requirements: 74 | * 75 | * - Multiplication cannot overflow. 76 | */ 77 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 78 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 79 | // benefit is lost if 'b' is also tested. 80 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 81 | if (a == 0) { 82 | return 0; 83 | } 84 | 85 | uint256 c = a * b; 86 | require(c / a == b, "SafeMath: multiplication overflow"); 87 | 88 | return c; 89 | } 90 | 91 | /** 92 | * @dev Returns the integer division of two unsigned integers. Reverts on 93 | * division by zero. The result is rounded towards zero. 94 | * 95 | * Counterpart to Solidity's `/` operator. Note: this function uses a 96 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 97 | * uses an invalid opcode to revert (consuming all remaining gas). 98 | * 99 | * Requirements: 100 | * 101 | * - The divisor cannot be zero. 102 | */ 103 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 104 | return div(a, b, "SafeMath: division by zero"); 105 | } 106 | 107 | /** 108 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 109 | * division by zero. The result is rounded towards zero. 110 | * 111 | * Counterpart to Solidity's `/` operator. Note: this function uses a 112 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 113 | * uses an invalid opcode to revert (consuming all remaining gas). 114 | * 115 | * Requirements: 116 | * 117 | * - The divisor cannot be zero. 118 | */ 119 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 120 | require(b > 0, errorMessage); 121 | uint256 c = a / b; 122 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 123 | 124 | return c; 125 | } 126 | 127 | /** 128 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 129 | * Reverts when dividing by zero. 130 | * 131 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 132 | * opcode (which leaves remaining gas untouched) while Solidity uses an 133 | * invalid opcode to revert (consuming all remaining gas). 134 | * 135 | * Requirements: 136 | * 137 | * - The divisor cannot be zero. 138 | */ 139 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 140 | return mod(a, b, "SafeMath: modulo by zero"); 141 | } 142 | 143 | /** 144 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 145 | * Reverts with custom message when dividing by zero. 146 | * 147 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 148 | * opcode (which leaves remaining gas untouched) while Solidity uses an 149 | * invalid opcode to revert (consuming all remaining gas). 150 | * 151 | * Requirements: 152 | * 153 | * - The divisor cannot be zero. 154 | */ 155 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 156 | require(b != 0, errorMessage); 157 | return a % b; 158 | } 159 | } -------------------------------------------------------------------------------- /contracts/libraries/TransferHelper.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-or-later 2 | 3 | pragma solidity >=0.6.0; 4 | 5 | // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false 6 | library TransferHelper { 7 | function safeApprove(address token, address to, uint value) internal { 8 | // bytes4(keccak256(bytes('approve(address,uint256)'))); 9 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); 10 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); 11 | } 12 | 13 | function safeTransfer(address token, address to, uint value) internal { 14 | // bytes4(keccak256(bytes('transfer(address,uint256)'))); 15 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); 16 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); 17 | } 18 | 19 | function safeTransferFrom(address token, address from, address to, uint value) internal { 20 | // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); 21 | (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); 22 | require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); 23 | } 24 | 25 | function safeTransferETH(address to, uint value) internal { 26 | (bool success,) = to.call{value:value}(new bytes(0)); 27 | require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/libraries/UQ112x112.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0; 2 | 3 | // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) 4 | 5 | // range: [0, 2**112 - 1] 6 | // resolution: 1 / 2**112 7 | 8 | library UQ112x112 { 9 | uint224 constant Q112 = 2**112; 10 | 11 | // encode a uint112 as a UQ112x112 12 | function encode(uint112 y) internal pure returns (uint224 z) { 13 | z = uint224(y) * Q112; // never overflows 14 | } 15 | 16 | // divide a UQ112x112 by a uint112, returning a UQ112x112 17 | function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { 18 | z = x / uint224(y); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/modules/BaseMintField.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | import '../libraries/SafeMath.sol'; 3 | 4 | contract BaseMintField { 5 | using SafeMath for uint; 6 | struct Productivity { 7 | uint product; // user's productivity 8 | uint total; // total productivity 9 | uint block; // record's block number 10 | uint user; // accumulated products 11 | uint global; // global accumulated products 12 | } 13 | 14 | Productivity private global; 15 | mapping(address => Productivity) public users; 16 | 17 | event AmountPerBlockChanged (uint oldValue, uint newValue); 18 | event ProductivityIncreased (address indexed user, uint value); 19 | event ProductivityDecreased (address indexed user, uint value); 20 | 21 | uint private unlocked = 1; 22 | 23 | modifier lock() { 24 | require(unlocked == 1, 'Locked'); 25 | unlocked = 0; 26 | _; 27 | unlocked = 1; 28 | } 29 | 30 | 31 | // compute productivity returns total productivity of a user. 32 | function _computeProductivity(Productivity memory user) private view returns (uint) { 33 | uint blocks = block.number.sub(user.block); 34 | return user.product.add(user.total.mul(blocks)); 35 | } 36 | 37 | // update users' productivity by value with boolean value indicating increase or decrease. 38 | function _updateProductivity(Productivity storage user, uint value, bool increase) private { 39 | user.product = _computeProductivity(user); 40 | global.product = _computeProductivity(global); 41 | 42 | require(global.product <= uint(-1), 'BaseMintField: GLOBAL_PRODUCT_OVERFLOW'); 43 | 44 | user.block = block.number; 45 | global.block = block.number; 46 | if(increase) { 47 | user.total = user.total.add(value); 48 | global.total = global.total.add(value); 49 | } 50 | else { 51 | require(user.total >= value, 'BaseMintField: INVALID_DECREASE_USER_POWER'); 52 | require(global.total >= value, 'BaseMintField: INVALID_DECREASE_GLOBAL_POWER'); 53 | user.total = user.total.sub(value); 54 | global.total = global.total.sub(value); 55 | } 56 | } 57 | 58 | function _increaseProductivity(address user, uint value) internal returns (bool) { 59 | require(value > 0, 'BaseMintField: PRODUCTIVITY_VALUE_MUST_BE_GREATER_THAN_ZERO'); 60 | Productivity storage product = users[user]; 61 | _updateProductivity(product, value, true); 62 | emit ProductivityIncreased(user, value); 63 | return true; 64 | } 65 | 66 | 67 | function _decreaseProductivity(address user, uint value) internal returns (bool) { 68 | Productivity storage product = users[user]; 69 | require(value > 0 && product.total >= value, 'BaseMintField: INSUFFICIENT_PRODUCTIVITY'); 70 | _updateProductivity(product, value, false); 71 | emit ProductivityDecreased(user, value); 72 | return true; 73 | } 74 | 75 | function _updateProductValue() internal returns (bool) { 76 | Productivity storage product = users[msg.sender]; 77 | 78 | product.user = _computeProductivity(product); 79 | product.global = _computeProductivity(global); 80 | 81 | return true; 82 | } 83 | 84 | function _computeUserPercentage() internal view returns (uint numerator, uint denominator) { 85 | Productivity memory product = users[msg.sender]; 86 | 87 | uint userProduct = _computeProductivity(product); 88 | uint globalProduct = _computeProductivity(global); 89 | 90 | numerator = userProduct.sub(product.user); 91 | denominator = globalProduct.sub(product.global); 92 | } 93 | 94 | } -------------------------------------------------------------------------------- /contracts/modules/BaseShareField.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | import '../interfaces/ERC2917-Interface.sol'; 3 | import '../libraries/SafeMath.sol'; 4 | import '../libraries/TransferHelper.sol'; 5 | 6 | contract BaseShareField { 7 | using SafeMath for uint; 8 | 9 | uint totalProductivity; 10 | uint accAmountPerShare; 11 | 12 | uint public totalShare; 13 | uint public mintedShare; 14 | uint public mintCumulation; 15 | 16 | address public shareToken; 17 | 18 | struct UserInfo { 19 | uint amount; // How many tokens the user has provided. 20 | uint rewardDebt; // Reward debt. 21 | uint rewardEarn; // Reward earn and not minted 22 | } 23 | 24 | mapping(address => UserInfo) public users; 25 | 26 | function _setShareToken(address _shareToken) internal { 27 | shareToken = _shareToken; 28 | } 29 | 30 | // Update reward variables of the given pool to be up-to-date. 31 | function _update() internal virtual { 32 | if (totalProductivity == 0) { 33 | totalShare = totalShare.add(_currentReward()); 34 | return; 35 | } 36 | 37 | uint256 reward = _currentReward(); 38 | accAmountPerShare = accAmountPerShare.add(reward.mul(1e12).div(totalProductivity)); 39 | totalShare = totalShare.add(reward); 40 | } 41 | 42 | function _currentReward() internal virtual view returns (uint) { 43 | return mintedShare.add(IERC20(shareToken).balanceOf(address(this))).sub(totalShare); 44 | } 45 | 46 | // Audit user's reward to be up-to-date 47 | function _audit(address user) internal virtual { 48 | UserInfo storage userInfo = users[user]; 49 | if (userInfo.amount > 0) { 50 | uint pending = userInfo.amount.mul(accAmountPerShare).div(1e12).sub(userInfo.rewardDebt); 51 | userInfo.rewardEarn = userInfo.rewardEarn.add(pending); 52 | mintCumulation = mintCumulation.add(pending); 53 | userInfo.rewardDebt = userInfo.amount.mul(accAmountPerShare).div(1e12); 54 | } 55 | } 56 | 57 | // External function call 58 | // This function increase user's productivity and updates the global productivity. 59 | // the users' actual share percentage will calculated by: 60 | // Formula: user_productivity / global_productivity 61 | function _increaseProductivity(address user, uint value) internal virtual returns (bool) { 62 | require(value > 0, 'PRODUCTIVITY_VALUE_MUST_BE_GREATER_THAN_ZERO'); 63 | 64 | UserInfo storage userInfo = users[user]; 65 | _update(); 66 | _audit(user); 67 | 68 | totalProductivity = totalProductivity.add(value); 69 | 70 | userInfo.amount = userInfo.amount.add(value); 71 | userInfo.rewardDebt = userInfo.amount.mul(accAmountPerShare).div(1e12); 72 | return true; 73 | } 74 | 75 | // External function call 76 | // This function will decreases user's productivity by value, and updates the global productivity 77 | // it will record which block this is happenning and accumulates the area of (productivity * time) 78 | function _decreaseProductivity(address user, uint value) internal virtual returns (bool) { 79 | UserInfo storage userInfo = users[user]; 80 | require(value > 0 && userInfo.amount >= value, 'INSUFFICIENT_PRODUCTIVITY'); 81 | 82 | _update(); 83 | _audit(user); 84 | 85 | userInfo.amount = userInfo.amount.sub(value); 86 | userInfo.rewardDebt = userInfo.amount.mul(accAmountPerShare).div(1e12); 87 | totalProductivity = totalProductivity.sub(value); 88 | 89 | return true; 90 | } 91 | 92 | function _takeWithAddress(address user) internal view returns (uint) { 93 | UserInfo storage userInfo = users[user]; 94 | uint _accAmountPerShare = accAmountPerShare; 95 | // uint256 lpSupply = totalProductivity; 96 | if (totalProductivity != 0) { 97 | uint reward = _currentReward(); 98 | _accAmountPerShare = _accAmountPerShare.add(reward.mul(1e12).div(totalProductivity)); 99 | } 100 | return userInfo.amount.mul(_accAmountPerShare).div(1e12).add(userInfo.rewardEarn).sub(userInfo.rewardDebt); 101 | } 102 | 103 | // External function call 104 | // When user calls this function, it will calculate how many token will mint to user from his productivity * time 105 | // Also it calculates global token supply from last time the user mint to this time. 106 | function _mint(address user) internal virtual returns (uint) { 107 | _update(); 108 | _audit(user); 109 | require(users[user].rewardEarn > 0, "NOTHING TO MINT"); 110 | uint amount = users[user].rewardEarn; 111 | users[user].rewardEarn = 0; 112 | mintedShare = mintedShare.add(amount); 113 | TransferHelper.safeTransfer(shareToken, msg.sender, amount); 114 | return amount; 115 | } 116 | 117 | // Returns how many productivity a user has and global has. 118 | function getProductivity(address user) public virtual view returns (uint, uint) { 119 | return (users[user].amount, totalProductivity); 120 | } 121 | 122 | // Returns the current gorss product rate. 123 | function interestsPerBlock() public virtual view returns (uint) { 124 | return accAmountPerShare; 125 | } 126 | 127 | } -------------------------------------------------------------------------------- /contracts/modules/BaseToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | contract BaseToken { 4 | address public baseToken; 5 | 6 | // called after deployment 7 | function initBaseToken(address _baseToken) internal { 8 | require(baseToken == address(0), 'INITIALIZED'); 9 | require(_baseToken != address(0), 'ADDRESS_IS_ZERO'); 10 | baseToken = _baseToken; // it should be dgas token address 11 | } 12 | } -------------------------------------------------------------------------------- /contracts/modules/Configable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.6; 3 | 4 | interface IConfig { 5 | function dev() external view returns (address); 6 | function admin() external view returns (address); 7 | } 8 | 9 | contract Configable { 10 | address public config; 11 | address public owner; 12 | 13 | event ConfigChanged(address indexed _user, address indexed _old, address indexed _new); 14 | event OwnerChanged(address indexed _user, address indexed _old, address indexed _new); 15 | 16 | function setupConfig(address _config) external onlyOwner { 17 | emit ConfigChanged(msg.sender, config, _config); 18 | config = _config; 19 | } 20 | 21 | modifier onlyOwner() { 22 | require(msg.sender == owner, 'OWNER FORBIDDEN'); 23 | _; 24 | } 25 | 26 | function admin() public view returns(address) { 27 | if(config != address(0)) { 28 | return IConfig(config).admin(); 29 | } 30 | return owner; 31 | } 32 | 33 | function dev() public view returns(address) { 34 | if(config != address(0)) { 35 | return IConfig(config).dev(); 36 | } 37 | return owner; 38 | } 39 | 40 | function changeOwner(address _user) external onlyOwner { 41 | require(owner != _user, 'Owner: NO CHANGE'); 42 | emit OwnerChanged(msg.sender, owner, _user); 43 | owner = _user; 44 | } 45 | 46 | modifier onlyDev() { 47 | require(msg.sender == dev() || msg.sender == owner, 'dev FORBIDDEN'); 48 | _; 49 | } 50 | 51 | modifier onlyAdmin() { 52 | require(msg.sender == admin() || msg.sender == owner, 'admin FORBIDDEN'); 53 | _; 54 | } 55 | 56 | modifier onlyManager() { 57 | require(msg.sender == dev() || msg.sender == admin() || msg.sender == owner, 'manager FORBIDDEN'); 58 | _; 59 | } 60 | } -------------------------------------------------------------------------------- /contracts/modules/Controller.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | import './Ownable.sol'; 3 | contract Controller is Ownable{ 4 | address public controller; 5 | 6 | event ControllerChanged(address indexed _oldController, address indexed _newController); 7 | 8 | modifier onlyController { 9 | require(msg.sender == controller, "controller : no permission"); 10 | _; 11 | } 12 | 13 | function setController (address _controller) onlyOwner public { 14 | require(_controller != address(0), 'controller : INVALID_ADDRESS'); 15 | emit ControllerChanged(controller, _controller); 16 | controller = _controller; 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/modules/DgasStaking.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../libraries/TransferHelper.sol'; 4 | import '../libraries/SafeMath.sol'; 5 | import '../interfaces/IERC20.sol'; 6 | import '../interfaces/IDemaxConfig.sol'; 7 | import '../modules/BaseToken.sol'; 8 | 9 | 10 | contract DgasStaking is BaseToken { 11 | using SafeMath for uint; 12 | 13 | uint public lockTime; 14 | uint public totalSupply; 15 | uint public stakingSupply; 16 | mapping(address => uint) public balanceOf; 17 | mapping(address => uint) public allowance; 18 | 19 | 20 | constructor (address _baseToken) public { 21 | initBaseToken(_baseToken); 22 | } 23 | 24 | function _add(address user, uint value) internal { 25 | require(value > 0, 'ZERO'); 26 | balanceOf[user] = balanceOf[user].add(value); 27 | stakingSupply = stakingSupply.add(value); 28 | allowance[user] = block.number; 29 | } 30 | 31 | function _reduce(address user, uint value) internal { 32 | require(balanceOf[user] >= value && value > 0, 'DgasStaking: INSUFFICIENT_BALANCE'); 33 | balanceOf[user] = balanceOf[user].sub(value); 34 | stakingSupply = stakingSupply.sub(value); 35 | } 36 | 37 | function _reset(address user) internal { 38 | allowance[user] = block.number; 39 | } 40 | 41 | function deposit(uint _amount) external returns (bool) { 42 | TransferHelper.safeTransferFrom(baseToken, msg.sender, address(this), _amount); 43 | _add(msg.sender, _amount); 44 | totalSupply = IERC20(baseToken).balanceOf(address(this)); 45 | return true; 46 | } 47 | 48 | function withdraw(uint _amount) external returns (bool) { 49 | require(block.number > allowance[msg.sender] + lockTime, 'DgasStaking: NOT_DUE'); 50 | TransferHelper.safeTransfer(baseToken, msg.sender, _amount); 51 | _reduce(msg.sender, _amount); 52 | totalSupply = IERC20(baseToken).balanceOf(address(this)); 53 | return true; 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /contracts/modules/ERC20Token.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../libraries/SafeMath.sol'; 4 | 5 | contract ERC20Token { 6 | using SafeMath for uint; 7 | 8 | string public name; 9 | string public symbol; 10 | uint8 public decimals = 18; 11 | uint public totalSupply; 12 | mapping(address => uint) public balanceOf; 13 | mapping(address => mapping(address => uint)) public allowance; 14 | 15 | event Transfer(address indexed from, address indexed to, uint value); 16 | event Approval(address indexed owner, address indexed spender, uint value); 17 | 18 | function _transfer(address from, address to, uint value) internal { 19 | require(balanceOf[from] >= value, 'ERC20Token: INSUFFICIENT_BALANCE'); 20 | balanceOf[from] = balanceOf[from].sub(value); 21 | balanceOf[to] = balanceOf[to].add(value); 22 | if (to == address(0)) { // burn 23 | totalSupply = totalSupply.sub(value); 24 | } 25 | emit Transfer(from, to, value); 26 | } 27 | 28 | function approve(address spender, uint value) external returns (bool) { 29 | allowance[msg.sender][spender] = value; 30 | emit Approval(msg.sender, spender, value); 31 | return true; 32 | } 33 | 34 | function transfer(address to, uint value) external returns (bool) { 35 | _transfer(msg.sender, to, value); 36 | return true; 37 | } 38 | 39 | function transferFrom(address from, address to, uint value) external returns (bool) { 40 | require(allowance[from][msg.sender] >= value, 'ERC20Token: INSUFFICIENT_ALLOWANCE'); 41 | allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); 42 | _transfer(from, to, value); 43 | return true; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /contracts/modules/ERC2917Impl.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: MIT 2 | pragma solidity >=0.6.6; 3 | 4 | import '../interfaces/ERC2917-Interface.sol'; 5 | import '../modules/Upgradable.sol'; 6 | import '../libraries/SafeMath.sol'; 7 | 8 | /* 9 | The Objective of ERC2917 Demo is to implement a decentralized staking mechanism, which calculates users' share 10 | by accumulating productiviy * time. And calculates users revenue from anytime t0 to t1 by the formula below: 11 | 12 | user_accumulated_productivity(time1) - user_accumulated_productivity(time0) 13 | _____________________________________________________________________________ * (gross_product(t1) - gross_product(t0)) 14 | total_accumulated_productivity(time1) - total_accumulated_productivity(time0) 15 | 16 | */ 17 | contract ERC2917Impl is IERC2917, UpgradableProduct, UpgradableGovernance { 18 | using SafeMath for uint; 19 | 20 | uint public mintCumulation; 21 | uint public amountPerBlock; 22 | 23 | // implementation of ERC20 interfaces. 24 | string override public name; 25 | string override public symbol; 26 | uint8 override public decimals = 18; 27 | uint override public totalSupply; 28 | 29 | mapping(address => uint) override public balanceOf; 30 | mapping(address => mapping(address => uint)) override public allowance; 31 | 32 | function _transfer(address from, address to, uint value) internal virtual { 33 | require(balanceOf[from] >= value, 'ERC20Token: INSUFFICIENT_BALANCE'); 34 | balanceOf[from] = balanceOf[from].sub(value); 35 | balanceOf[to] = balanceOf[to].add(value); 36 | if (to == address(0)) { // burn 37 | totalSupply = totalSupply.sub(value); 38 | } 39 | emit Transfer(from, to, value); 40 | } 41 | 42 | function approve(address spender, uint value) external virtual override returns (bool) { 43 | allowance[msg.sender][spender] = value; 44 | emit Approval(msg.sender, spender, value); 45 | return true; 46 | } 47 | 48 | function transfer(address to, uint value) external virtual override returns (bool) { 49 | _transfer(msg.sender, to, value); 50 | return true; 51 | } 52 | 53 | function transferFrom(address from, address to, uint value) external virtual override returns (bool) { 54 | require(allowance[from][msg.sender] >= value, 'ERC20Token: INSUFFICIENT_ALLOWANCE'); 55 | allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); 56 | _transfer(from, to, value); 57 | return true; 58 | } 59 | 60 | // end of implementation of ERC20 61 | 62 | uint lastRewardBlock; 63 | uint totalProductivity; 64 | uint accAmountPerShare; 65 | struct UserInfo { 66 | uint amount; // How many LP tokens the user has provided. 67 | uint rewardDebt; // Reward debt. 68 | uint rewardEarn; // Reward earn and not minted 69 | } 70 | 71 | mapping(address => UserInfo) public users; 72 | 73 | // creation of the interests token. 74 | constructor(string memory _name, string memory _symbol, uint8 _decimals, uint _interestsRate) UpgradableProduct() UpgradableGovernance() public { 75 | name = _name; 76 | symbol = _symbol; 77 | decimals = _decimals; 78 | 79 | amountPerBlock = _interestsRate; 80 | } 81 | 82 | // External function call 83 | // This function adjust how many token will be produced by each block, eg: 84 | // changeAmountPerBlock(100) 85 | // will set the produce rate to 100/block. 86 | function changeInterestRatePerBlock(uint value) external virtual override requireGovernor returns (bool) { 87 | uint old = amountPerBlock; 88 | require(value != old, 'AMOUNT_PER_BLOCK_NO_CHANGE'); 89 | 90 | _update(); 91 | amountPerBlock = value; 92 | 93 | emit InterestRatePerBlockChanged(old, value); 94 | return true; 95 | } 96 | 97 | // Update reward variables of the given pool to be up-to-date. 98 | function _update() internal virtual { 99 | if (block.number <= lastRewardBlock) { 100 | return; 101 | } 102 | 103 | if (totalProductivity == 0) { 104 | lastRewardBlock = block.number; 105 | return; 106 | } 107 | 108 | uint256 reward = _currentReward(); 109 | balanceOf[address(this)] = balanceOf[address(this)].add(reward); 110 | totalSupply = totalSupply.add(reward); 111 | 112 | accAmountPerShare = accAmountPerShare.add(reward.mul(1e12).div(totalProductivity)); 113 | lastRewardBlock = block.number; 114 | } 115 | 116 | function _currentReward() internal virtual view returns (uint){ 117 | uint256 multiplier = block.number.sub(lastRewardBlock); 118 | return multiplier.mul(amountPerBlock); 119 | } 120 | 121 | // Audit user's reward to be up-to-date 122 | function _audit(address user) internal virtual { 123 | UserInfo storage userInfo = users[user]; 124 | if (userInfo.amount > 0) { 125 | uint pending = userInfo.amount.mul(accAmountPerShare).div(1e12).sub(userInfo.rewardDebt); 126 | userInfo.rewardEarn = userInfo.rewardEarn.add(pending); 127 | mintCumulation = mintCumulation.add(pending); 128 | userInfo.rewardDebt = userInfo.amount.mul(accAmountPerShare).div(1e12); 129 | } 130 | } 131 | 132 | // External function call 133 | // This function increase user's productivity and updates the global productivity. 134 | // the users' actual share percentage will calculated by: 135 | // Formula: user_productivity / global_productivity 136 | function increaseProductivity(address user, uint value) external virtual override requireImpl returns (bool) { 137 | require(value > 0, 'PRODUCTIVITY_VALUE_MUST_BE_GREATER_THAN_ZERO'); 138 | 139 | UserInfo storage userInfo = users[user]; 140 | _update(); 141 | _audit(user); 142 | 143 | totalProductivity = totalProductivity.add(value); 144 | 145 | userInfo.amount = userInfo.amount.add(value); 146 | userInfo.rewardDebt = userInfo.amount.mul(accAmountPerShare).div(1e12); 147 | emit ProductivityIncreased(user, value); 148 | return true; 149 | } 150 | 151 | // External function call 152 | // This function will decreases user's productivity by value, and updates the global productivity 153 | // it will record which block this is happenning and accumulates the area of (productivity * time) 154 | function decreaseProductivity(address user, uint value) external virtual override requireImpl returns (bool) { 155 | UserInfo storage userInfo = users[user]; 156 | require(value > 0 && userInfo.amount >= value, "INSUFFICIENT_PRODUCTIVITY"); 157 | _update(); 158 | _audit(user); 159 | 160 | userInfo.amount = userInfo.amount.sub(value); 161 | userInfo.rewardDebt = userInfo.amount.mul(accAmountPerShare).div(1e12); 162 | totalProductivity = totalProductivity.sub(value); 163 | 164 | emit ProductivityDecreased(user, value); 165 | return true; 166 | } 167 | 168 | function takeWithAddress(address user) public view returns (uint) { 169 | UserInfo storage userInfo = users[user]; 170 | uint _accAmountPerShare = accAmountPerShare; 171 | // uint256 lpSupply = totalProductivity; 172 | if (block.number > lastRewardBlock && totalProductivity != 0) { 173 | uint reward = _currentReward(); 174 | _accAmountPerShare = _accAmountPerShare.add(reward.mul(1e12).div(totalProductivity)); 175 | } 176 | return userInfo.amount.mul(_accAmountPerShare).div(1e12).sub(userInfo.rewardDebt).add(userInfo.rewardEarn); 177 | } 178 | 179 | function take() external override virtual view returns (uint) { 180 | return takeWithAddress(msg.sender); 181 | } 182 | 183 | // Returns how much a user could earn plus the giving block number. 184 | function takeWithBlock() external override virtual view returns (uint, uint) { 185 | uint earn = takeWithAddress(msg.sender); 186 | return (earn, block.number); 187 | } 188 | 189 | 190 | // External function call 191 | // When user calls this function, it will calculate how many token will mint to user from his productivity * time 192 | // Also it calculates global token supply from last time the user mint to this time. 193 | function mint() external override virtual returns (uint) { 194 | _update(); 195 | _audit(msg.sender); 196 | require(users[msg.sender].rewardEarn > 0, "NO_PRODUCTIVITY"); 197 | uint amount = users[msg.sender].rewardEarn; 198 | _transfer(address(this), msg.sender, users[msg.sender].rewardEarn); 199 | users[msg.sender].rewardEarn = 0; 200 | return amount; 201 | } 202 | 203 | // Returns how many productivity a user has and global has. 204 | function getProductivity(address user) external override virtual view returns (uint, uint) { 205 | return (users[user].amount, totalProductivity); 206 | } 207 | 208 | // Returns the current gorss product rate. 209 | function interestsPerBlock() external override virtual view returns (uint) { 210 | return accAmountPerShare; 211 | } 212 | } 213 | -------------------------------------------------------------------------------- /contracts/modules/Governable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | contract Governable { 4 | address public governor; 5 | 6 | event ChangeGovernor(address indexed _old, address indexed _new); 7 | 8 | modifier onlyGovernor() { 9 | require(msg.sender == governor, 'Governable: FORBIDDEN'); 10 | _; 11 | } 12 | 13 | // called after deployment 14 | function initGovernorAddress(address _governor) internal { 15 | require(_governor != address(0), 'Governable: INPUT_ADDRESS_IS_ZERO'); 16 | governor = _governor; 17 | } 18 | 19 | function changeGovernor(address _new) public onlyGovernor { 20 | _changeGovernor(_new); 21 | } 22 | 23 | function _changeGovernor(address _new) internal { 24 | require(_new != address(0), 'Governable: INVALID_ADDRESS'); 25 | require(_new != governor, 'Governable: NO_CHANGE'); 26 | address old = governor; 27 | governor = _new; 28 | emit ChangeGovernor(old, _new); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /contracts/modules/Initializable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0; 4 | 5 | 6 | /** 7 | * @title Initializable 8 | * 9 | * @dev Helper contract to support initializer functions. To use it, replace 10 | * the constructor with a function that has the `initializer` modifier. 11 | * WARNING: Unlike constructors, initializer functions must be manually 12 | * invoked. This applies both to deploying an Initializable contract, as well 13 | * as extending an Initializable contract via inheritance. 14 | * WARNING: When used with inheritance, manual care must be taken to not invoke 15 | * a parent initializer twice, or ensure that all initializers are idempotent, 16 | * because this is not dealt with automatically as with constructors. 17 | */ 18 | contract Initializable { 19 | 20 | /** 21 | * @dev Indicates that the contract has been initialized. 22 | */ 23 | bool private initialized; 24 | 25 | /** 26 | * @dev Indicates that the contract is in the process of being initialized. 27 | */ 28 | bool private initializing; 29 | 30 | /** 31 | * @dev Modifier to use in the initializer function of a contract. 32 | */ 33 | modifier initializer() { 34 | require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); 35 | 36 | bool isTopLevelCall = !initializing; 37 | if (isTopLevelCall) { 38 | initializing = true; 39 | initialized = true; 40 | } 41 | 42 | _; 43 | 44 | if (isTopLevelCall) { 45 | initializing = false; 46 | } 47 | } 48 | 49 | /// @dev Returns true if and only if the function is running in the constructor 50 | function isConstructor() private view returns (bool) { 51 | // extcodesize checks the size of the code stored in an address, and 52 | // address returns the current address. Since the code is still not 53 | // deployed when running a constructor, any checks on its code size will 54 | // yield zero, making it an effective way to detect if a contract is 55 | // under construction or not. 56 | address self = address(this); 57 | uint256 cs; 58 | assembly { cs := extcodesize(self) } 59 | return cs == 0; 60 | } 61 | 62 | // Reserved storage space to allow for layout changes in the future. 63 | uint256[50] private ______gap; 64 | } 65 | -------------------------------------------------------------------------------- /contracts/modules/Lock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | contract Lock { 4 | uint private unlocked = 1; 5 | modifier lock() { 6 | require(unlocked == 1, 'LOCKED'); 7 | unlocked = 0; 8 | _; 9 | unlocked = 1; 10 | } 11 | } -------------------------------------------------------------------------------- /contracts/modules/Ownable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | contract Ownable { 4 | address public owner; 5 | 6 | event OwnerChanged(address indexed _oldOwner, address indexed _newOwner); 7 | 8 | constructor() public { 9 | owner = msg.sender; 10 | } 11 | 12 | modifier onlyOwner() { 13 | require(msg.sender == owner, 'Ownable: FORBIDDEN'); 14 | _; 15 | } 16 | 17 | function changeOwner(address _newOwner) public onlyOwner { 18 | require(_newOwner != address(0), 'Ownable: INVALID_ADDRESS'); 19 | emit OwnerChanged(owner, _newOwner); 20 | owner = _newOwner; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /contracts/modules/ProjectConfigable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | interface IConfig { 4 | function dev() external view returns (address); 5 | function admin() external view returns (address); 6 | } 7 | 8 | contract ProjectConfigable { 9 | address public config; 10 | address public owner; 11 | 12 | constructor() public { 13 | owner = msg.sender; 14 | } 15 | 16 | function setupConfig(address _config) external onlyOwner { 17 | config = _config; 18 | } 19 | 20 | modifier onlyOwner() { 21 | require(msg.sender == owner, 'OWNER FORBIDDEN'); 22 | _; 23 | } 24 | 25 | function admin() public view returns(address) { 26 | if(config != address(0)) { 27 | return IConfig(config).admin(); 28 | } 29 | return owner; 30 | } 31 | 32 | function dev() public view returns(address) { 33 | if(config != address(0)) { 34 | return IConfig(config).dev(); 35 | } 36 | return owner; 37 | } 38 | 39 | function changeOwner(address _user) external onlyOwner { 40 | require(owner != _user, 'IFOConfig: NO CHANGE'); 41 | owner = _user; 42 | } 43 | 44 | modifier onlyDev() { 45 | require(msg.sender == dev() || msg.sender == owner, 'dev FORBIDDEN'); 46 | _; 47 | } 48 | 49 | modifier onlyAdmin() { 50 | require(msg.sender == admin() || msg.sender == owner, 'admin FORBIDDEN'); 51 | _; 52 | } 53 | } -------------------------------------------------------------------------------- /contracts/modules/ReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity >=0.6.0 <0.8.0; 4 | 5 | /** 6 | * @dev Contract module that helps prevent reentrant calls to a function. 7 | * 8 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 9 | * available, which can be applied to functions to make sure there are no nested 10 | * (reentrant) calls to them. 11 | * 12 | * Note that because there is a single `nonReentrant` guard, functions marked as 13 | * `nonReentrant` may not call one another. This can be worked around by making 14 | * those functions `private`, and then adding `external` `nonReentrant` entry 15 | * points to them. 16 | * 17 | * TIP: If you would like to learn more about reentrancy and alternative ways 18 | * to protect against it, check out our blog post 19 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 20 | */ 21 | abstract contract ReentrancyGuard { 22 | // Booleans are more expensive than uint256 or any type that takes up a full 23 | // word because each write operation emits an extra SLOAD to first read the 24 | // slot's contents, replace the bits taken up by the boolean, and then write 25 | // back. This is the compiler's defense against contract upgrades and 26 | // pointer aliasing, and it cannot be disabled. 27 | 28 | // The values being non-zero value makes deployment a bit more expensive, 29 | // but in exchange the refund on every call to nonReentrant will be lower in 30 | // amount. Since refunds are capped to a percentage of the total 31 | // transaction's gas, it is best to keep them low in cases like this one, to 32 | // increase the likelihood of the full refund coming into effect. 33 | uint256 private constant _NOT_ENTERED = 1; 34 | uint256 private constant _ENTERED = 2; 35 | 36 | uint256 private _status; 37 | 38 | constructor () internal { 39 | _status = _NOT_ENTERED; 40 | } 41 | 42 | /** 43 | * @dev Prevents a contract from calling itself, directly or indirectly. 44 | * Calling a `nonReentrant` function from another `nonReentrant` 45 | * function is not supported. It is possible to prevent this from happening 46 | * by making the `nonReentrant` function external, and make it call a 47 | * `private` function that does the actual work. 48 | */ 49 | modifier nonReentrant() { 50 | // On the first call to nonReentrant, _notEntered will be true 51 | require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); 52 | 53 | // Any calls to nonReentrant after this point will fail 54 | _status = _ENTERED; 55 | 56 | _; 57 | 58 | // By storing the original value once again, a refund is triggered (see 59 | // https://eips.ethereum.org/EIPS/eip-2200) 60 | _status = _NOT_ENTERED; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/modules/SwitchFeature.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import './Governable.sol'; 4 | 5 | 6 | contract SwitchFeature is Governable { 7 | bool public enable = true; 8 | 9 | event Switched(bool _value); 10 | 11 | constructor() public { 12 | } 13 | 14 | function switchOn() external onlyGovernor returns (bool) { 15 | require(!enable, 'SWITCH_NOCHANGE'); 16 | enable = true; 17 | emit Switched(enable); 18 | return true; 19 | } 20 | 21 | function switchOff() external onlyGovernor returns (bool) { 22 | require(enable, 'SWITCH_NOCHANGE'); 23 | enable = false; 24 | emit Switched(enable); 25 | return true; 26 | } 27 | } -------------------------------------------------------------------------------- /contracts/modules/TokenRegistry.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import './Governable.sol'; 4 | 5 | /** 6 | Business Process 7 | step 1. publishToken 8 | step 2. addToken or removeToken 9 | */ 10 | 11 | contract TokenRegistry is Governable { 12 | mapping (address => uint) public tokenStatus; 13 | mapping (address => uint) public publishTime; 14 | uint public tokenCount; 15 | address[] public tokenList; 16 | uint public constant NONE = 0; 17 | uint public constant REGISTERED = 1; 18 | uint public constant PENDING = 2; 19 | uint public constant OPENED = 3; 20 | uint public constant CLOSED = 4; 21 | 22 | event TokenStatusChanged(address indexed _token, uint _status, uint _block); 23 | 24 | function registryToken(address _token) external onlyGovernor returns (bool) { 25 | return _updateToken(_token, REGISTERED); 26 | } 27 | 28 | function publishToken(address _token) external onlyGovernor returns (bool) { 29 | publishTime[_token] = block.number; 30 | return _updateToken(_token, PENDING); 31 | } 32 | 33 | function updateToken(address _token, uint _status) external onlyGovernor returns (bool) { 34 | return _updateToken(_token, _status); 35 | } 36 | 37 | function validTokens() external view returns (address[] memory) { 38 | uint count; 39 | for (uint i; i < tokenList.length; i++) { 40 | if (tokenStatus[tokenList[i]] == PENDING || tokenStatus[tokenList[i]] == OPENED) { 41 | count++; 42 | } 43 | } 44 | address[] memory res = new address[](count); 45 | uint index = 0; 46 | for (uint i; i < tokenList.length; i++) { 47 | if (tokenStatus[tokenList[i]] == PENDING || tokenStatus[tokenList[i]] == OPENED) { 48 | res[index] = tokenList[i]; 49 | index++; 50 | } 51 | } 52 | return res; 53 | } 54 | 55 | function iterateValidTokens(uint _start, uint _end) external view returns (address[] memory) { 56 | require(_end <= tokenList.length, "TokenRegistry: OVERFLOW"); 57 | require(_start <= _end && _start >= 0 && _end >= 0, "TokenRegistry: INVAID_PARAMTERS"); 58 | uint count; 59 | for (uint i = _start; i < _end; i++) { 60 | if (tokenStatus[tokenList[i]] == PENDING || tokenStatus[tokenList[i]] == OPENED) { 61 | count++; 62 | } 63 | } 64 | address[] memory res = new address[](count); 65 | uint index = 0; 66 | for (uint i = _start; i < _end; i++) { 67 | if (tokenStatus[tokenList[i]] == PENDING || tokenStatus[tokenList[i]] == OPENED) { 68 | res[index] = tokenList[i]; 69 | index++; 70 | } 71 | } 72 | return res; 73 | } 74 | 75 | function _updateToken(address _token, uint _status) internal returns (bool) { 76 | require(_token != address(0), 'TokenRegistry: INVALID_TOKEN'); 77 | require(tokenStatus[_token] != _status, 'TokenRegistry: TOKEN_STATUS_NO_CHANGE'); 78 | if (tokenStatus[_token] == NONE) { 79 | tokenCount++; 80 | tokenList.push(_token); 81 | } 82 | tokenStatus[_token] = _status; 83 | emit TokenStatusChanged(_token, _status, block.number); 84 | return true; 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /contracts/modules/Upgradable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | contract UpgradableProduct { 4 | address public impl; 5 | 6 | event ImplChanged(address indexed _oldImpl, address indexed _newImpl); 7 | 8 | constructor() public { 9 | impl = msg.sender; 10 | } 11 | 12 | modifier requireImpl() { 13 | require(msg.sender == impl, 'FORBIDDEN'); 14 | _; 15 | } 16 | 17 | function upgradeImpl(address _newImpl) public requireImpl { 18 | require(_newImpl != address(0), 'INVALID_ADDRESS'); 19 | require(_newImpl != impl, 'NO_CHANGE'); 20 | address lastImpl = impl; 21 | impl = _newImpl; 22 | emit ImplChanged(lastImpl, _newImpl); 23 | } 24 | } 25 | 26 | contract UpgradableGovernance { 27 | address public governor; 28 | 29 | event GovernorChanged(address indexed _oldGovernor, address indexed _newGovernor); 30 | 31 | constructor() public { 32 | governor = msg.sender; 33 | } 34 | 35 | modifier requireGovernor() { 36 | require(msg.sender == governor, 'FORBIDDEN'); 37 | _; 38 | } 39 | 40 | function upgradeGovernance(address _newGovernor) public requireGovernor { 41 | require(_newGovernor != address(0), 'INVALID_ADDRESS'); 42 | require(_newGovernor != governor, 'NO_CHANGE'); 43 | address lastGovernor = governor; 44 | governor = _newGovernor; 45 | emit GovernorChanged(lastGovernor, _newGovernor); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /contracts/test/DeflatingERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import '../libraries/SafeMath.sol'; 4 | 5 | contract DeflatingERC20 { 6 | using SafeMath for uint; 7 | 8 | string public constant name = 'Deflating Test Token'; 9 | string public constant symbol = 'DTT'; 10 | uint8 public constant decimals = 18; 11 | uint public totalSupply; 12 | mapping(address => uint) public balanceOf; 13 | mapping(address => mapping(address => uint)) public allowance; 14 | 15 | bytes32 public DOMAIN_SEPARATOR; 16 | // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); 17 | bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; 18 | mapping(address => uint) public nonces; 19 | 20 | event Approval(address indexed owner, address indexed spender, uint value); 21 | event Transfer(address indexed from, address indexed to, uint value); 22 | 23 | constructor(uint _totalSupply) public { 24 | uint chainId; 25 | assembly { 26 | chainId := chainid() 27 | } 28 | DOMAIN_SEPARATOR = keccak256( 29 | abi.encode( 30 | keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), 31 | keccak256(bytes(name)), 32 | keccak256(bytes('1')), 33 | chainId, 34 | address(this) 35 | ) 36 | ); 37 | _mint(msg.sender, _totalSupply); 38 | } 39 | 40 | function _mint(address to, uint value) internal { 41 | totalSupply = totalSupply.add(value); 42 | balanceOf[to] = balanceOf[to].add(value); 43 | emit Transfer(address(0), to, value); 44 | } 45 | 46 | function _burn(address from, uint value) internal { 47 | balanceOf[from] = balanceOf[from].sub(value); 48 | totalSupply = totalSupply.sub(value); 49 | emit Transfer(from, address(0), value); 50 | } 51 | 52 | function _approve(address owner, address spender, uint value) private { 53 | allowance[owner][spender] = value; 54 | emit Approval(owner, spender, value); 55 | } 56 | 57 | function _transfer(address from, address to, uint value) private { 58 | uint burnAmount = value / 100; 59 | _burn(from, burnAmount); 60 | uint transferAmount = value.sub(burnAmount); 61 | balanceOf[from] = balanceOf[from].sub(transferAmount); 62 | balanceOf[to] = balanceOf[to].add(transferAmount); 63 | emit Transfer(from, to, transferAmount); 64 | } 65 | 66 | function approve(address spender, uint value) external returns (bool) { 67 | _approve(msg.sender, spender, value); 68 | return true; 69 | } 70 | 71 | function transfer(address to, uint value) external returns (bool) { 72 | _transfer(msg.sender, to, value); 73 | return true; 74 | } 75 | 76 | function transferFrom(address from, address to, uint value) external returns (bool) { 77 | if (allowance[from][msg.sender] != uint(-1)) { 78 | allowance[from][msg.sender] = allowance[from][msg.sender].sub(value); 79 | } 80 | _transfer(from, to, value); 81 | return true; 82 | } 83 | 84 | function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { 85 | require(deadline >= block.timestamp, 'EXPIRED'); 86 | bytes32 digest = keccak256( 87 | abi.encodePacked( 88 | '\x19\x01', 89 | DOMAIN_SEPARATOR, 90 | keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) 91 | ) 92 | ); 93 | address recoveredAddress = ecrecover(digest, v, r, s); 94 | require(recoveredAddress != address(0) && recoveredAddress == owner, 'INVALID_SIGNATURE'); 95 | _approve(owner, spender, value); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /contracts/test/DemaxBallotTestToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../modules/ERC20Token.sol'; 4 | import '../interfaces/IDemaxBallot.sol'; 5 | 6 | contract DemaxBallotTestToken is ERC20Token { 7 | constructor(uint _totalSupply, string memory _name, string memory _symbol) public { 8 | name = _name; 9 | symbol = _symbol; 10 | totalSupply = _totalSupply; 11 | balanceOf[msg.sender] = totalSupply; 12 | } 13 | 14 | function end(address _ballot) external { 15 | IDemaxBallot(_ballot).end(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/test/DemaxConfigTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import '../DemaxConfig.sol'; 4 | 5 | contract DemaxConfigTest is DemaxConfig { 6 | 7 | function changeConfigValueNoCheck(bytes32 _name, uint _value) external returns (bool) { 8 | Config storage config = configs[_name]; 9 | require(config.enable == 1, "demax config: disable"); 10 | uint old = config.value; 11 | config.value = _value; 12 | emit ConfigValueChanged(_name, old, _value); 13 | return true; 14 | } 15 | 16 | function changeTokenStatus(address _token, uint _status) external returns (bool) { 17 | return _updateToken(_token, _status); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /contracts/test/DemaxGovernanceTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.6; 2 | 3 | import '../DemaxGovernance.sol'; 4 | 5 | contract DemaxGovernanceTest is DemaxGovernance { 6 | 7 | constructor (address _dgas) DemaxGovernance(_dgas) public { 8 | } 9 | 10 | function changeLockTime(uint _value) external returns (bool) { 11 | lockTime = _value; 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /contracts/test/DgasTest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../modules/ERC2917Impl.sol'; 4 | 5 | contract DgasTest is ERC2917Impl("Demax Gas", "DGAS", 18, 1000 * (10 ** 18)) { 6 | 7 | constructor() public { 8 | totalSupply += 1000000000* 10 ** 18; 9 | balanceOf[msg.sender] = 1000000000* 10 ** 18; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /contracts/test/ERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../modules/ERC20Token.sol'; 4 | 5 | contract ERC20 is ERC20Token { 6 | constructor(uint _totalSupply, string memory _name, string memory _symbol) public { 7 | name = _name; 8 | symbol = _symbol; 9 | totalSupply = _totalSupply; 10 | balanceOf[msg.sender] = totalSupply; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/test/ERC20Factory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import './ERC20ForFactory.sol'; 4 | 5 | contract ERC20Factory { 6 | address public owner; 7 | address[] public allTokens; 8 | 9 | event TokenCreated(address indexed token); 10 | 11 | constructor() public { 12 | owner = msg.sender; 13 | } 14 | 15 | modifier onlyOwner() { 16 | require(msg.sender == owner, 'ERC20Factory: Only Owner'); 17 | _; 18 | } 19 | 20 | function changeOwner(address _user) external onlyOwner { 21 | require(owner != _user, 'ERC20Factory: NO CHANGE'); 22 | owner = _user; 23 | } 24 | 25 | function createToken(address _to, uint _totalSupply, uint8 _decimals, string memory _name, string memory _symbol) public returns (address token) { 26 | bytes memory bytecode = type(ERC20ForFactory).creationCode; 27 | bytes32 salt = keccak256(abi.encodePacked(_symbol, block.number)); 28 | assembly { 29 | token := create2(0, add(bytecode, 32), mload(bytecode), salt) 30 | } 31 | 32 | ERC20ForFactory(token).initialize(_to, _totalSupply, _decimals, _name, _symbol); 33 | allTokens.push(token); 34 | emit TokenCreated(token); 35 | } 36 | 37 | function allTokensLength() external view returns (uint) { 38 | return allTokens.length; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/test/ERC20ForFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../modules/ERC20Token.sol'; 4 | 5 | contract ERC20ForFactory is ERC20Token { 6 | address public owner; 7 | bool private initialized; 8 | constructor() public { 9 | owner = msg.sender; 10 | } 11 | 12 | function initialize(address _to, uint _totalSupply, uint8 _decimals, string memory _name, string memory _symbol) public { 13 | require(!initialized, 'initialized'); 14 | owner = _to; 15 | initialized = true; 16 | name = _name; 17 | symbol = _symbol; 18 | totalSupply = _totalSupply; 19 | decimals = _decimals; 20 | balanceOf[_to] = totalSupply; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/test/TERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../modules/ERC20Token.sol'; 4 | 5 | contract TERC20 is ERC20Token { 6 | constructor(uint _totalSupply, uint8 _decimals, string memory _name, string memory _symbol) public { 7 | name = _name; 8 | symbol = _symbol; 9 | totalSupply = _totalSupply; 10 | decimals = _decimals; 11 | balanceOf[msg.sender] = totalSupply; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /contracts/test/TokenQuery.sol: -------------------------------------------------------------------------------- 1 | // Root file: contracts/TokenQuery.sol 2 | 3 | // SPDX-License-Identifier: GPL-3.0-or-later 4 | pragma solidity >= 0.5.1; 5 | interface IERC20 { 6 | event Approval(address indexed owner, address indexed spender, uint value); 7 | event Transfer(address indexed from, address indexed to, uint value); 8 | 9 | function name() external view returns (string memory); 10 | function symbol() external view returns (string memory); 11 | function decimals() external view returns (uint8); 12 | function totalSupply() external view returns (uint); 13 | function balanceOf(address owner) external view returns (uint); 14 | function allowance(address owner, address spender) external view returns (uint); 15 | 16 | function approve(address spender, uint value) external returns (bool); 17 | function transfer(address to, uint value) external returns (bool); 18 | function transferFrom(address from, address to, uint value) external returns (bool); 19 | } 20 | 21 | pragma experimental ABIEncoderV2; 22 | 23 | contract TokenQuery { 24 | 25 | struct Token { 26 | string name; 27 | string symbol; 28 | uint8 decimals; 29 | uint balanceOf; 30 | } 31 | 32 | function queryInfo(address user, address[] memory tokens) public view returns(Token[] memory info_list){ 33 | info_list = new Token[](tokens.length); 34 | for(uint i = 0;i < tokens.length;i++) { 35 | info_list[i] = Token(IERC20(tokens[i]).name(), IERC20(tokens[i]).symbol(), IERC20(tokens[i]).decimals() 36 | , IERC20(tokens[i]).balanceOf(user)); 37 | } 38 | } 39 | 40 | function queryTokenList(address[] memory tokens) public view returns (Token[] memory token_list) { 41 | uint count = tokens.length; 42 | if(count > 0) { 43 | token_list = new Token[](count); 44 | for(uint i = 0;i < count;i++) { 45 | Token memory tk; 46 | tk.name = IERC20(tokens[i]).name(); 47 | tk.symbol = IERC20(tokens[i]).symbol(); 48 | tk.decimals = IERC20(tokens[i]).decimals(); 49 | tk.balanceOf = IERC20(tokens[i]).balanceOf(msg.sender); 50 | token_list[i] = tk; 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /contracts/test/USDT.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.16; 2 | 3 | import '../modules/ERC20Token.sol'; 4 | 5 | contract USDT is ERC20Token { 6 | address owner; 7 | 8 | constructor() public { 9 | name = "USDT"; 10 | symbol = "USDT"; 11 | totalSupply = 1000000000000 * 10 ** 6; 12 | balanceOf[msg.sender] = totalSupply; 13 | decimals = 6; 14 | owner = msg.sender; 15 | } 16 | 17 | function swap() payable external returns (uint) { 18 | balanceOf[msg.sender] += msg.value * 1000 * 10**6 / 10**18; 19 | totalSupply += balanceOf[msg.sender]; 20 | return balanceOf[msg.sender]; 21 | } 22 | 23 | function withdraw() external returns (uint) { 24 | (bool success,) = owner.call{value:address(this).balance}(new bytes(0)); 25 | require(success, 'ETH_TRANSFER_FAILED'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /deploy/address.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "weth": "0x6DB985312069742DF3F4ebbA2d133A1d541eC882", 4 | "block": 1481 5 | }, 6 | { 7 | "factory": "0x286e3aEB5254fc7a61f00e83b66CE7Fa3B9Cac58", 8 | "block": 1482 9 | }, 10 | { 11 | "platform": "0xed3d24c3D9aaC0BaB7a9082E23f9722FE51a02D6", 12 | "block": 1483 13 | }, 14 | { 15 | "dgas": "0xeeC73049119B41b905acE184D638725B39Ca796D", 16 | "block": 1484 17 | }, 18 | { 19 | "governance": "0xBf1fc7257Dbd825a1937132FC6e9Baeb356cf681", 20 | "block": 1485 21 | }, 22 | { 23 | "config": "0x4262De85216adF95450c3DAa9C226761d555a085", 24 | "block": 1486 25 | }, 26 | { 27 | "ballotFactory": "0x9e55F2B5Fc769D29E01B34292d8fEE601518C8a3", 28 | "block": 1487 29 | } 30 | ] -------------------------------------------------------------------------------- /deploy/config.example.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | wethAddr: "", 3 | usdtAddr: "", 4 | privateKey: "0xc694e5ba2c125177601db89cc45ad3eff988613715016a74f9940ec59f671e43", 5 | httpProvider: 'http://localhost:8545' 6 | } 7 | -------------------------------------------------------------------------------- /deploy/test.js: -------------------------------------------------------------------------------- 1 | let fs = require("fs"); 2 | let path = require("path"); 3 | const ethers = require("ethers") 4 | 5 | const DemaxProjectFactory = require("../build/DemaxProjectFactory.json"); 6 | const DemaxProjectPool = require("../build/DemaxProjectPool.json"); 7 | 8 | async function run() { 9 | let res = ethers.utils.keccak256('0x'+ DemaxProjectFactory.bytecode) 10 | console.log('DemaxProjectFactory:',res) 11 | 12 | res = ethers.utils.keccak256('0x'+ DemaxProjectPool.bytecode) 13 | console.log('DemaxProjectPool:',res) 14 | } 15 | run() 16 | -------------------------------------------------------------------------------- /deploy/upgrade.plateform.js: -------------------------------------------------------------------------------- 1 | let fs = require("fs"); 2 | let path = require("path"); 3 | const ethers = require("ethers") 4 | const erc20 = require("../build/ERC20.json") 5 | const platform = require("../build/DemaxPlatform.json") 6 | const demaxConfig = require("../build/DemaxConfig.json") 7 | const dgas = require("../build/DgasTest.json") 8 | const usdt = require("../build/usdt.json") 9 | const demaxPair = require("../build/DemaxPair.json") 10 | const weth = require("../build/WETH9.json") 11 | const demaxPool = require("../build/DemaxPool.json") 12 | const demaxFactory = require("../build/DemaxFactory.json") 13 | const demaxGovernance = require("../build/DemaxGovernance.json") 14 | const ballotFactory = require("../build/DemaxBallotFactory.json") 15 | const transferListener = require("../build/DemaxTransferListener.json") 16 | const demaxQuery = require("../build/DemaxQuery.json") 17 | const demaxQuery2 = require("../build/DemaxQuery2.json") 18 | const demaxDelegate = require("../build/demaxDelegate.json") 19 | const {bigNumberify} = require("ethers/utils") 20 | const Web3 = require("web3") 21 | const web3 = new Web3() 22 | const USER_HOME = process.env.HOME || process.env.USERPROFILE 23 | 24 | let config = { 25 | "gasPrice": "10", 26 | "url": "", 27 | "pk": "", 28 | "devWallet": "", 29 | "adminWallet": "", 30 | "WETH": "", 31 | "DGAS": "", 32 | "DemaxPlatform": "", 33 | "DemaxConfig": "", 34 | "DemaxFactory": "", 35 | "DemaxDelegate": "", 36 | "DemaxPool": "", 37 | "DemaxGovernance": "", 38 | "DemaxQuery": "", 39 | "DemaxQuery2": "", 40 | "DemaxTransferListener": "", 41 | "DemaxBallotFactory": "" 42 | } 43 | 44 | if(fs.existsSync(path.join(USER_HOME+'/.config.upgrade.plateform.json'))) { 45 | config = JSON.parse(fs.readFileSync(path.join(USER_HOME+'/.config.upgrade.plateform.json')).toString()); 46 | } 47 | if(fs.existsSync(path.join(__dirname, ".config.upgrade.plateform.json"))) { 48 | config = JSON.parse(fs.readFileSync(path.join(__dirname, ".config.upgrade.plateform.json")).toString()); 49 | } 50 | 51 | 52 | 53 | let ETHER_SEND_CONFIG = { 54 | gasPrice: ethers.utils.parseUnits(config.gasPrice, "gwei") 55 | } 56 | 57 | console.log("config url", config.url) 58 | 59 | let provider = new ethers.providers.JsonRpcProvider(config.url) 60 | 61 | const privateKey = config.pk 62 | const ownerAddress = web3.eth.accounts.privateKeyToAccount(privateKey).address 63 | console.log('wallet ', ownerAddress) 64 | 65 | function expandTo18Decimals(n, p = 18) { 66 | return bigNumberify(n).mul(bigNumberify(10).pow(p)) 67 | } 68 | 69 | function getWallet(key = privateKey) { 70 | return new ethers.Wallet(key, provider) 71 | } 72 | 73 | const sleep = ms => 74 | new Promise(resolve => 75 | setTimeout(() => { 76 | resolve() 77 | }, ms) 78 | ) 79 | 80 | async function waitForMint(tx) { 81 | let result = null 82 | do { 83 | result = await provider.getTransactionReceipt(tx) 84 | await sleep(100) 85 | } while (result === null) 86 | await sleep(200) 87 | console.log('tx: ', tx) 88 | } 89 | 90 | async function getBlockNumber() { 91 | return await provider.getBlockNumber() 92 | } 93 | 94 | async function upgrade() { 95 | console.log("start upgrade...") 96 | 97 | console.log('DemaxPlatform initialize...') 98 | let ins = new ethers.Contract( 99 | config.DemaxPlatform, 100 | platform.abi, 101 | getWallet() 102 | ) 103 | let tx = await ins.pause( 104 | ETHER_SEND_CONFIG 105 | ) 106 | await waitForMint(tx.hash) 107 | tx = await ins.initialize( 108 | config.DGAS, 109 | config.DemaxConfig, 110 | config.DemaxFactory, 111 | config.WETH, 112 | config.DemaxGovernance, 113 | config.DemaxTransferListener, 114 | config.DemaxPool, 115 | ETHER_SEND_CONFIG 116 | ) 117 | await waitForMint(tx.hash) 118 | 119 | console.log('DemaxTransferListener initialize...') 120 | ins = new ethers.Contract( 121 | config.DemaxTransferListener, 122 | transferListener.abi, 123 | getWallet() 124 | ) 125 | tx = await ins.initialize( 126 | config.DGAS, 127 | config.DemaxFactory, 128 | config.WETH, 129 | config.DemaxPlatform, 130 | config.adminWallet, 131 | ETHER_SEND_CONFIG 132 | ) 133 | await waitForMint(tx.hash) 134 | 135 | // console.log('DemaxGovernance initialize...') 136 | // ins = new ethers.Contract( 137 | // config.DemaxGovernance, 138 | // demaxGovernance.abi, 139 | // getWallet() 140 | // ) 141 | // tx = await ins.initialize( 142 | // config.DemaxPool, 143 | // config.DemaxConfig, 144 | // config.DemaxBallotFactory, 145 | // ETHER_SEND_CONFIG 146 | // ) 147 | // await waitForMint(tx.hash) 148 | 149 | console.log('DemaxPool initialize...') 150 | ins = new ethers.Contract(config.DemaxPool, demaxPool.abi, getWallet()) 151 | tx = await ins.initialize( 152 | config.DGAS, 153 | config.WETH, 154 | config.DemaxFactory, 155 | config.DemaxPlatform, 156 | config.DemaxConfig, 157 | config.DemaxGovernance, 158 | ETHER_SEND_CONFIG 159 | ) 160 | await waitForMint(tx.hash) 161 | 162 | console.log('DemaxConfig initialize...') 163 | ins = new ethers.Contract(config.DemaxConfig, demaxConfig.abi, getWallet()) 164 | tx = await ins.initialize( 165 | config.DGAS, 166 | config.DemaxGovernance, 167 | config.DemaxPlatform, 168 | config.devWallet, 169 | [], 170 | ETHER_SEND_CONFIG 171 | ) 172 | await waitForMint(tx.hash) 173 | 174 | // DEMAX QUERY 175 | console.log("DemaxQuery upgrade...") 176 | ins = new ethers.Contract(config.DemaxQuery, demaxQuery.abi, getWallet()) 177 | tx = await ins.upgrade(config.DemaxConfig, config.DemaxPlatform, config.DemaxFactory, config.DemaxGovernance, config.DemaxTransferListener, ETHER_SEND_CONFIG) 178 | await waitForMint(tx.hash) 179 | 180 | // DEMAX QUERY2 181 | console.log("DemaxQuery2 upgrade...") 182 | ins = new ethers.Contract(config.DemaxQuery2, demaxQuery2.abi, getWallet()) 183 | tx = await ins.upgrade(config.DemaxConfig, config.DemaxPlatform, config.DemaxFactory, config.DemaxGovernance, config.DemaxTransferListener, config.DemaxDelegate, ETHER_SEND_CONFIG) 184 | await waitForMint(tx.hash) 185 | 186 | console.log("DemaxDelegate DemaxDelegate...") 187 | ins = new ethers.Contract(config.DemaxDelegate, demaxDelegate.abi, getWallet()) 188 | tx = await ins.initialize( 189 | config.DemaxPlatform, 190 | config.DemaxPool, 191 | config.DGAS, 192 | config.WETH, 193 | { 194 | ...ETHER_SEND_CONFIG 195 | }) 196 | await waitForMint(tx.hash) 197 | 198 | console.log("DemaxDelegate upgradePlatform...") 199 | ins = new ethers.Contract(config.DemaxDelegate, demaxDelegate.abi, getWallet()) 200 | tx = await ins.upgradePlatform(config.DemaxPlatform, { 201 | ...ETHER_SEND_CONFIG 202 | }) 203 | await waitForMint(tx.hash) 204 | 205 | await upgradeOldDelegatePlatform() 206 | 207 | console.log("DemaxPlatform resume...") 208 | ins = new ethers.Contract( 209 | config.DemaxPlatform, 210 | platform.abi, 211 | getWallet() 212 | ) 213 | tx = await ins.resume( 214 | ETHER_SEND_CONFIG 215 | ) 216 | } 217 | 218 | async function upgradeOldDelegatePlatform() { 219 | console.log("DemaxDelegate upgradeOldDelegatePlatform...", config.OldDemaxDelegate) 220 | let ins = new ethers.Contract(config.OldDemaxDelegate, demaxDelegate.abi, getWallet()) 221 | let tx = await ins.upgradePlatform(config.DemaxPlatform, { 222 | ...ETHER_SEND_CONFIG 223 | }) 224 | await waitForMint(tx.hash) 225 | } 226 | 227 | upgrade(); 228 | 229 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @type import('hardhat/config').HardhatUserConfig 3 | */ 4 | import { HardhatUserConfig } from "hardhat/types"; 5 | import '@openzeppelin/hardhat-upgrades'; 6 | 7 | import "@nomiclabs/hardhat-waffle"; 8 | import "@nomiclabs/hardhat-etherscan"; 9 | import "hardhat-typechain"; 10 | import fs from "fs"; 11 | import path from "path"; 12 | const USER_HOME = process.env.HOME || process.env.USERPROFILE 13 | let data = { 14 | "PrivateKey": "", 15 | "InfuraApiKey": "", 16 | "EtherscanApiKey": "", 17 | }; 18 | 19 | let filePath = path.join(USER_HOME+'/.hardhat.data.json'); 20 | if (fs.existsSync(filePath)) { 21 | let rawdata = fs.readFileSync(filePath); 22 | data = JSON.parse(rawdata.toString()); 23 | } 24 | filePath = path.join(__dirname, `.hardhat.data.json`); 25 | if (fs.existsSync(filePath)) { 26 | let rawdata = fs.readFileSync(filePath); 27 | data = JSON.parse(rawdata.toString()); 28 | } 29 | 30 | const LOWEST_OPTIMIZER_COMPILER_SETTINGS = { 31 | version: "0.6.6", 32 | settings: { 33 | optimizer: { 34 | enabled: true, 35 | runs: 200, 36 | }, 37 | metadata: { 38 | bytecodeHash: 'none', 39 | }, 40 | }, 41 | } 42 | 43 | const LOWER_OPTIMIZER_COMPILER_SETTINGS = { 44 | version: "0.6.6", 45 | settings: { 46 | optimizer: { 47 | enabled: true, 48 | runs: 10_000, 49 | }, 50 | metadata: { 51 | bytecodeHash: 'none', 52 | }, 53 | }, 54 | } 55 | 56 | const DEFAULT_COMPILER_SETTINGS = { 57 | version: "0.6.6", 58 | settings: { 59 | optimizer: { 60 | enabled: true, 61 | runs: 1_000_000, 62 | }, 63 | metadata: { 64 | bytecodeHash: 'none', 65 | }, 66 | }, 67 | } 68 | 69 | const config: HardhatUserConfig = { 70 | defaultNetwork: "hardhat", 71 | solidity: { 72 | compilers: [DEFAULT_COMPILER_SETTINGS], 73 | overrides: { 74 | }, 75 | }, 76 | networks: { 77 | hardhat: {}, 78 | mainnet: { 79 | url: `https://mainnet.infura.io/v3/${data.InfuraApiKey}`, 80 | accounts: [data.PrivateKey] 81 | }, 82 | ropsten: { 83 | url: `https://ropsten.infura.io/v3/${data.InfuraApiKey}`, 84 | accounts: [data.PrivateKey] 85 | }, 86 | rinkeby: { 87 | url: `https://rinkeby.infura.io/v3/${data.InfuraApiKey}`, 88 | accounts: [data.PrivateKey] 89 | }, 90 | bsctestnet: { 91 | url: `https://rpc.ankr.com/bsc_testnet_chapel`, 92 | accounts: [data.PrivateKey] 93 | }, 94 | bscmainnet: { 95 | url: `https://rpc.ankr.com/bsc`, 96 | accounts: [data.PrivateKey] 97 | }, 98 | hecotestnet: { 99 | url: `https://http-testnet.hecochain.com`, 100 | accounts: [data.PrivateKey] 101 | }, 102 | hecomainnet: { 103 | url: `https://http-mainnet.hecochain.com`, 104 | accounts: [data.PrivateKey] 105 | }, 106 | matictestnet: { 107 | url: `https://matic-mumbai.chainstacklabs.com`, 108 | accounts: [data.PrivateKey], 109 | gas: "auto", 110 | gasPrice: 1000000000 111 | }, 112 | maticmainnet: { 113 | url: `https://polygon-mainnet.infura.io/v3/${data.InfuraApiKey}`, 114 | accounts: [data.PrivateKey], 115 | gas: 3000000, 116 | gasPrice: 5000000000 117 | }, 118 | arbitrumtestnet: { 119 | url: `https://rinkeby.arbitrum.io/rpc`, 120 | accounts: [data.PrivateKey], 121 | gas: "auto", 122 | gasPrice: 100000000 123 | }, 124 | arbitrummainnet: { 125 | url: `https://arb1.arbitrum.io/rpc`, 126 | accounts: [data.PrivateKey], 127 | }, 128 | }, 129 | etherscan: { 130 | apiKey: data.EtherscanApiKey, 131 | }, 132 | paths: { 133 | sources: "./contracts", 134 | tests: "./test", 135 | cache: "./cache", 136 | artifacts: "./artifacts" 137 | }, 138 | mocha: { 139 | timeout: 100000 140 | } 141 | }; 142 | 143 | export default config; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@demax/demax-core", 3 | "description": "Core contracts for the Demax protocol", 4 | "version": "1.0.1", 5 | "homepage": "", 6 | "repository": { 7 | "type": "git", 8 | "url": "" 9 | }, 10 | "keywords": [ 11 | "demax", 12 | "ethereum", 13 | "v2", 14 | "core" 15 | ], 16 | "files": [ 17 | "contracts", 18 | "build" 19 | ], 20 | "engines": { 21 | "node": ">=10" 22 | }, 23 | "devDependencies": { 24 | "@nomiclabs/hardhat-ethers": "^2.0.2", 25 | "@nomiclabs/hardhat-etherscan": "^2.1.1", 26 | "@nomiclabs/hardhat-waffle": "^2.0.1", 27 | "@openzeppelin/hardhat-upgrades": "^1.6.0", 28 | "@typechain/ethers-v5": "^6.0.5", 29 | "@types/chai": "^4.2.6", 30 | "@types/mocha": "^5.2.7", 31 | "chai": "^4.2.0", 32 | "ethereum-waffle": "2.5.1", 33 | "ethereumjs-util": "^7.0.3", 34 | "ethers": "^5.1.0", 35 | "fs": "0.0.1-security", 36 | "hardhat": "^2.1.2", 37 | "hardhat-typechain": "^0.3.5", 38 | "mocha": "^8.1.0", 39 | "prettier": "^1.19.1", 40 | "rimraf": "^3.0.0", 41 | "solc": "0.6.6", 42 | "ts-generator": "^0.1.1", 43 | "ts-node": "^8.10.2", 44 | "typechain": "^4.0.1", 45 | "typescript": "^3.9.7" 46 | }, 47 | "scripts": { 48 | "lint": "yarn prettier ./test/*.ts --check", 49 | "lint:fix": "yarn prettier ./test/*.ts --write", 50 | "clean": "rimraf ./build/", 51 | "precompile": "yarn clean", 52 | "compile": "waffle .waffle.json", 53 | "hcompile": "npx hardhat compile", 54 | "pretest": "yarn compile", 55 | "test": "mocha --timeout 600000", 56 | "flatten": "waffle flatten .waffle.json", 57 | "deploy": "waffle .waffle.json && node ./deploy/deploy.js", 58 | "test1": "mocha --timeout 600000 --no-config --require ts-node/register", 59 | "prepublishOnly": "yarn test" 60 | }, 61 | "license": "GPL-3.0-or-later", 62 | "dependencies": { 63 | "@nomiclabs/buidler": "^1.4.3", 64 | "@nomiclabs/buidler-ethers": "^2.0.0", 65 | "@nomiclabs/buidler-waffle": "^2.0.0" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /scripts/sample-script.js: -------------------------------------------------------------------------------- 1 | // We require the Buidler Runtime Environment explicitly here. This is optional 2 | // but useful for running the script in a standalone fashion through `node