├── .dockerignore ├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .solcover.js ├── .solhint.json ├── .solhintignore ├── .travis.yml ├── .travis ├── report.sh └── test-part.sh ├── Dockerfile ├── LICENSE ├── README.md ├── audits ├── APRAudit │ └── SmartDecAudit.pdf ├── kyberV1Audit2 │ ├── BlockchainLabs_Kyber_AuditReport.MD │ ├── Kovan_tests.MD │ ├── KyberNetwork BlockchainLabs Audit Report.pdf │ ├── test-coverage.MD │ └── work-paper.MD ├── kyberV2Audit │ └── ChainSecurity_KyberNetwork_Public.pdf └── kyberV3Audit │ └── ChainSecurity_Kyberv3.pdf ├── buidler.config.js ├── buidlerConfigSol4.js ├── buidlerConfigSol5.js ├── buidlerConfigSol6.js ├── buidlerCoverageSol4.js ├── buidlerCoverageSol5.js ├── cmp.sh ├── cmpSol6.sh ├── contractSizeReport.js ├── contracts ├── sol4 │ ├── ConversionRatesInterface.sol │ ├── ERC20Interface.sol │ ├── FeeBurnerInterface.sol │ ├── KyberNetworkInterface.sol │ ├── KyberNetworkProxyInterface.sol │ ├── KyberProxyV1.sol │ ├── KyberReserveInterface.sol │ ├── Migrations.sol │ ├── PermissionGroups.sol │ ├── SanityRates.sol │ ├── SanityRatesInterface.sol │ ├── SimpleNetworkInterface.sol │ ├── Utils.sol │ ├── Utils2.sol │ ├── Utils3.sol │ ├── Withdrawable.sol │ ├── abi │ │ ├── BurnableToken.abi │ │ ├── ConversionRates.abi │ │ ├── ERC20.abi │ │ ├── ExpectedRate.abi │ │ ├── ExpectedRateInterface.abi │ │ ├── FeeBurner.abi │ │ ├── FeeBurnerInterface.abi │ │ ├── KyberNetwork.abi │ │ ├── KyberReserve.abi │ │ ├── LiquidityConversionRates.abi │ │ ├── OasisReserve.abi │ │ ├── PermissionGroups.abi │ │ ├── SanityRates.abi │ │ ├── SanityRatesInterface.abi │ │ ├── Utils.abi │ │ ├── VolumeImbalanceRecorder.abi │ │ ├── WhiteList.abi │ │ └── Withdrawable.abi │ ├── mock │ │ ├── ConversionRatesEnhancedOpen.sol │ │ ├── MaliciousReserve.sol │ │ ├── MockCentralBank.sol │ │ ├── MockConversionRate.sol │ │ ├── MockConversionRateEnhancedSteps.sol │ │ ├── MockDepositAddress.sol │ │ ├── MockDepositAddressEther.sol │ │ ├── MockDepositAddressToken.sol │ │ ├── MockERC20.sol │ │ ├── MockEnhancedStepFunctions.sol │ │ ├── MockExchange.sol │ │ ├── MockImbalanceRecorder.sol │ │ ├── MockKyberReserveHighRate.sol │ │ ├── MockPermission.sol │ │ ├── MockUtils.sol │ │ ├── MockUtils2.sol │ │ ├── MockUtils3.sol │ │ ├── MockWithdrawable.sol │ │ ├── StrictValidatingReserve.sol │ │ ├── TempBank.sol │ │ ├── TestToken.sol │ │ ├── TestTokenFailing.sol │ │ ├── TestTokenTransferFailing.sol │ │ ├── TokenNoDecimals.sol │ │ ├── TokenReverseSend.sol │ │ ├── abi │ │ │ ├── MockCentralBank.abi │ │ │ └── Wrapper.abi │ │ └── dgx │ │ │ ├── DummyDGX.sol │ │ │ ├── DummyDGXStorage.sol │ │ │ ├── TokenReceiver.sol │ │ │ └── libs │ │ │ ├── DemurrageStructs.sol │ │ │ ├── MathUtils.sol │ │ │ ├── TransferStructs.sol │ │ │ └── Types.sol │ ├── previousVersions │ │ └── KyberReserveV1.sol │ ├── reserves │ │ ├── KyberReserve.sol │ │ ├── KyberReserveHighRate.sol │ │ ├── VolumeImbalanceRecorder.sol │ │ ├── aprConversionRate │ │ │ ├── LiquidityConversionRates.sol │ │ │ └── LiquidityFormula.sol │ │ ├── bridgeReserves │ │ │ ├── dutchX │ │ │ │ ├── KyberDutchXReserve.sol │ │ │ │ └── mock │ │ │ │ │ ├── MockDutchX.sol │ │ │ │ │ └── WETH9.sol │ │ │ └── uniswap │ │ │ │ ├── KyberUniswapReserve.sol │ │ │ │ └── forTesting │ │ │ │ ├── KyberTestingUniswapReserve.sol │ │ │ │ └── MockUniswapFactory.sol │ │ ├── fprConversionRate │ │ │ ├── ConversionRateEnhancedSteps.sol │ │ │ └── ConversionRates.sol │ │ └── orderBookReserve │ │ │ └── permissionless │ │ │ ├── OrderIdManager.sol │ │ │ ├── OrderList.sol │ │ │ ├── OrderListFactory.sol │ │ │ ├── OrderListFactoryInterface.sol │ │ │ ├── OrderListInterface.sol │ │ │ ├── OrderbookReserve.sol │ │ │ ├── OrderbookReserveInterface.sol │ │ │ ├── PermissionlessOrderbookReserveLister.sol │ │ │ └── mock │ │ │ ├── MockMedianizer.sol │ │ │ ├── MockOrderIdManager.sol │ │ │ ├── MockOrderbookReserve.sol │ │ │ └── TestBytes32.sol │ ├── weth │ │ ├── KyberWethReserve.sol │ │ └── mockContracts │ │ │ └── MockWeth.sol │ └── wrappers │ │ ├── SetStepFunctionWrapper.sol │ │ ├── WrapConversionRate.sol │ │ ├── WrapConversionRateEnhancedSteps.sol │ │ ├── WrapReadTokenData.sol │ │ ├── Wrapper.sol │ │ └── WrapperBase.sol ├── sol5 │ ├── IERC20.sol │ ├── IKyberReserve.sol │ ├── bridges │ │ ├── bancor │ │ │ ├── KyberBancorReserve.sol │ │ │ └── mock │ │ │ │ ├── IBancorNetwork.sol │ │ │ │ └── MockBancorNetwork.sol │ │ └── eth2dai │ │ │ ├── Eth2DaiReserve.sol │ │ │ └── mock │ │ │ ├── IOtc.sol │ │ │ ├── MockOtcOrderbook.sol │ │ │ └── WethToken.sol │ ├── mock │ │ ├── MockPermissionGroups2.sol │ │ ├── MockUtils4.sol │ │ ├── MockWithdrawable2.sol │ │ └── Token.sol │ └── utils │ │ ├── PermissionGroups2.sol │ │ ├── Utils4.sol │ │ └── Withdrawable2.sol └── sol6 │ ├── Dao │ ├── DaoOperator.sol │ ├── EpochUtils.sol │ ├── IEpochUtils.sol │ ├── IKyberStaking.sol │ ├── ISanityRate.sol │ ├── KyberDao.sol │ ├── KyberFeeHandler.sol │ ├── KyberStaking.sol │ ├── emergency │ │ └── EmergencyFeeHandler.sol │ └── mock │ │ ├── KyberFeeHandlerWrapper.sol │ │ ├── KyberTokenFeeHandler.sol │ │ ├── MaliciousFeeHandler.sol │ │ ├── MockChainLinkSanityRate.sol │ │ ├── MockContractCallBurnKNC.sol │ │ ├── MockEmergencyFeeHandler.sol │ │ ├── MockKyberDaoMoreGetters.sol │ │ ├── MockKyberDaoTestHandleWithdrawal.sol │ │ ├── MockKyberDaoWithdrawFailed.sol │ │ ├── MockKyberStaking.sol │ │ ├── MockKyberStakingMalicious.sol │ │ ├── MockMaliciousKyberDao.sol │ │ ├── MockMaliciousKyberDaoReentrancy.sol │ │ └── MockStakerClaimRewardReentrancy.sol │ ├── IBurnableToken.sol │ ├── IERC20.sol │ ├── IGasHelper.sol │ ├── IKyberDao.sol │ ├── IKyberFeeHandler.sol │ ├── IKyberHint.sol │ ├── IKyberHistory.sol │ ├── IKyberMatchingEngine.sol │ ├── IKyberNetwork.sol │ ├── IKyberNetworkProxy.sol │ ├── IKyberReserve.sol │ ├── IKyberSanity.sol │ ├── IKyberStorage.sol │ ├── ISimpleKyberProxy.sol │ ├── KyberHintHandler.sol │ ├── KyberHistory.sol │ ├── KyberMatchingEngine.sol │ ├── KyberNetwork.sol │ ├── KyberNetworkProxy.sol │ ├── KyberStorage.sol │ ├── SanityRatesGasPrice.sol │ ├── bridgeReserve │ └── uniswap │ │ ├── KyberUniswapV2Reserve.sol │ │ └── mock │ │ └── MockUniswapRouter.sol │ ├── mock │ ├── GasHelper.sol │ ├── GenerousKyberNetwork.sol │ ├── GenerousKyberNetwork2.sol │ ├── KyberNetworkNoMaxDest.sol │ ├── MaliciousKyberDao.sol │ ├── MaliciousKyberNetwork.sol │ ├── MaliciousKyberNetwork2.sol │ ├── MaliciousMatchingEngine.sol │ ├── MaliciousReserve2.sol │ ├── MaliciousStorage.sol │ ├── MockConversionRates.sol │ ├── MockGasHelper.sol │ ├── MockHintHandler.sol │ ├── MockKyberDao.sol │ ├── MockMatchingEngine.sol │ ├── MockNetwork.sol │ ├── MockNotPayableContract.sol │ ├── MockPermissionGroups3.sol │ ├── MockPermissionGroupsNoModifiers.sol │ ├── MockReserve.sol │ ├── MockSanityRates.sol │ ├── MockStorage.sol │ ├── MockTrader.sol │ ├── MockUtils5.sol │ ├── MockWithdrawable3.sol │ ├── MockWithdrawableNoModifiers.sol │ ├── NoPayableFallback.sol │ ├── ReentrancyAttack.sol │ ├── ReentrancyFeeClaimer.sol │ ├── ReentrancyMock.sol │ ├── ReentrantReserve.sol │ ├── ReserveNoReturnVal.sol │ ├── ReserveReturnFalse.sol │ ├── SimpleKyberProxy.sol │ ├── TestTokenNotReturn.sol │ └── Token.sol │ ├── reserves │ ├── IConversionRates.sol │ ├── IWeth.sol │ └── KyberFprReserveV2.sol │ ├── utils │ ├── PermissionGroups3.sol │ ├── PermissionGroupsNoModifiers.sol │ ├── Utils5.sol │ ├── Withdrawable3.sol │ ├── WithdrawableNoModifiers.sol │ └── zeppelin │ │ ├── Address.sol │ │ ├── ReentrancyGuard.sol │ │ ├── SafeERC20.sol │ │ └── SafeMath.sol │ └── wrappers │ ├── IKyberRateHelper.sol │ └── KyberRateHelper.sol ├── coverage.sh ├── debugScripts └── checkRatesAndBalances.js ├── gasUsedReport.js ├── migrations └── 1_initial_migration.js ├── package-lock.json ├── package.json ├── scripts ├── deployment.js ├── deployment_input.json ├── ethdistribution.js ├── feeHandler.js ├── get_liquidity_params.py ├── liquidity_input_params.json ├── orderBookSimulator.js └── txparser.js ├── solcOptimiserSettings.js ├── statistics ├── tradesPerDay.js └── volumechecker.js ├── test ├── helper.js ├── reserveSetup.js ├── sol4 │ ├── conversionRate.js │ ├── conversionRateEnhancedSteps.js │ ├── kyberDutchXReserve.js │ ├── kyberProxyV1.js │ ├── kyberReserve.js │ ├── kyberReserveHighRate.js │ ├── kyberUniswapReserve.js │ ├── kyberWethReserve.js │ ├── liquidityConversionRate.js │ ├── liquidityFormula.js │ ├── mockDepositAddressEther.js │ ├── mockDepositAddressToken.js │ ├── mockExchange.js │ ├── orderBookFuzzer │ │ ├── simulator_orderbookReserve.js │ │ └── tradeGenerator_orderbook.js │ ├── orderIdManager.js │ ├── orderList.js │ ├── orderbookReserve.js │ ├── permissionGroups.js │ ├── permissionlessOrderbookReserveLister.js │ ├── sanityRates.js │ ├── strictValidatingReserve.js │ ├── utils.js │ ├── utils2.js │ ├── utils3.js │ ├── volumeImbalanceRecorder.js │ ├── withdrawable.js │ ├── wrapConversionRate.js │ ├── wrapConversionRatesEnhanced.js │ └── wrapperBase.js ├── sol5 │ ├── eth2DaiReserve.js │ ├── kyberBancorReserve.js │ ├── permissionGroups2.js │ ├── utils4.js │ └── withdrawable2.js └── sol6 │ ├── daoFuzzTests.js │ ├── emergencyFeeHandler.js │ ├── fuzzerFiles │ ├── daoFuzzer │ │ ├── daoActionsGenerator.js │ │ └── simulator_dao.js │ ├── randomNumberGenerator.js │ ├── stakingFuzzer │ │ ├── stakingActionsGenerator.js │ │ └── stakingSimulator.js │ └── tradeFuzzer │ │ ├── multiple_trade_fuzz_test.sh │ │ ├── networkSimulator.js │ │ └── tradeParamsGenerator.js │ ├── kyberDao.js │ ├── kyberFeeHandler.js │ ├── kyberHintHandler.js │ ├── kyberHistory.js │ ├── kyberIntegration.js │ ├── kyberMatchingEngine.js │ ├── kyberNetwork.js │ ├── kyberNetworkProxy.js │ ├── kyberProxyParallel.js │ ├── kyberStaking.js │ ├── kyberStorage.js │ ├── multipleFeeHandlers.js │ ├── networkHelper.js │ ├── permissionGroups3.js │ ├── permissionGroupsNoModifiers.js │ ├── reentrancyGuard.js │ ├── reserves │ ├── kyberFprReserveV2.js │ └── kyberUniswapV2Reserve.js │ ├── sanityRatesGasPrice.js │ ├── stakingFuzzTests.js │ ├── tradeFuzzTests.js │ ├── utils5.js │ ├── withdrawable3.js │ ├── withdrawableNoModifiers.js │ └── wrapper │ └── ratehelper.js ├── truffle.js ├── tst.sh └── web3deployment ├── KatalystDeploy ├── Katalyst_deploy_production_input.json ├── Katalyst_deploy_rinkeby_input.json ├── Katalyst_deploy_staging_input.json ├── katalystNetworkDeployer.js ├── katalyst_deployer_ropsten_input.json ├── listTokens.js └── monitorAndListTokens.js ├── basicDeployer.js ├── compilers ├── soljson-v0.4.18+commit.9cf6e910.js ├── soljson-v0.5.11+commit.c082d0b4.js └── soljson-v0.6.6+commit.6c089d02.js ├── deployToken.js ├── deployer.js ├── deployerv2.js ├── deployerv3.js ├── deployment_script_input_kovan.json ├── deployment_script_input_mainnet.json ├── deployment_script_input_mainnet_stage.json ├── helperContracts └── CheckPointing.sol ├── helpers └── gasStation.js ├── kovan.json ├── kovanV2.json ├── kyberUniswapReserveDeployer.js ├── liquidityReserveDeployer.js ├── liquidityReserve_input.json ├── mainnet_production.json ├── mainnet_staging.json ├── oasisReserveDeployer.js ├── permissionlessVerify.js ├── readConversionRate.js ├── readVerifyDeployment.js ├── reserveDeployer.js ├── reserveEnhancedStepsDeployer.js ├── reserve_deployment_ropsten.json ├── retrieveArtifacts.js ├── ropsten.json ├── ropsten_reserve_input.json ├── sendTxs.js ├── utils.js ├── v2_ropsten.json ├── verifyLiquidityDeploy.js └── wethReserveDeployer.js /.dockerignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | coverage.json 17 | 18 | # nyc test coverage 19 | .nyc_output 20 | 21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 22 | .grunt 23 | 24 | # node-waf configuration 25 | .lock-wscript 26 | 27 | # Compiled binary addons (http://nodejs.org/api/addons.html) 28 | build 29 | artifacts 30 | cache 31 | 32 | # Dependency directories 33 | node_modules 34 | jspm_packages 35 | 36 | # Optional npm cache directory 37 | .npm 38 | 39 | # Optional REPL history 40 | .node_repl_history 41 | 42 | # OS file 43 | .DS_Store 44 | 45 | report 46 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # zeppelin contracts 2 | contractsSol5/utils/zeppelin 3 | contractsSol5/bridges 4 | 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": "*.sol", 5 | "options": { 6 | "printWidth": 99, 7 | "tabWidth": 4, 8 | "useTabs": false, 9 | "singleQuote": false, 10 | "bracketSpacing": false, 11 | "explicitTypes": "always" 12 | } 13 | }, 14 | { 15 | "files": "*.js", 16 | "options": { 17 | "printWidth": 119, 18 | "tabWidth": 2, 19 | "useTabs": false, 20 | "singleQuote": true, 21 | "bracketSpacing": false, 22 | "explicitTypes": "always", 23 | "semi": true 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const mv = require('mv'); 4 | 5 | const previousArtifactsPath = path.join(__dirname, '.coverageArtifacts'); 6 | const targetArtifactPath = path.join(__dirname, '.coverage_artifacts'); 7 | 8 | function moveFiles(config) { 9 | fs.readdir(previousArtifactsPath, (err, files) => { 10 | if (err) console.log(err); 11 | files.forEach(file => { 12 | mv(path.join(previousArtifactsPath, file), path.join(targetArtifactPath, file), err => { 13 | if (err) throw err; 14 | console.log(`Moving ` + file); 15 | }); 16 | }) 17 | }) 18 | } 19 | 20 | function removeArtifactsDir(config) { 21 | fs.rmdir(previousArtifactsPath, err => { 22 | if (err) console.log(err); 23 | }) 24 | } 25 | 26 | module.exports = { 27 | providerOptions: { 28 | "default_balance_ether": 100000000000000, 29 | "total_accounts": 20 30 | }, 31 | skipFiles: ['Dao/mock/', 'mock/', 'utils/zeppelin/'], 32 | istanbulReporter: ['html','json'], 33 | onCompileComplete: moveFiles, 34 | onIstanbulComplete: removeArtifactsDir 35 | } 36 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": [], 4 | "rules": { 5 | "avoid-call-value": "error", 6 | "avoid-low-level-calls": "off", 7 | "avoid-sha3": "error", 8 | "avoid-suicide": "error", 9 | "avoid-throw": "error", 10 | "avoid-tx-origin": "off", 11 | "check-send-result": "error", 12 | "compiler-version": ["off", "0.6.6"], 13 | "const-name-snakecase": "error", 14 | "func-name-mixedcase": "error", 15 | "func-order": "error", 16 | "imports-on-top": "error", 17 | "mark-callable-contracts": "off", 18 | "max-line-length": ["error", 99], 19 | "max-states-count": ["error", 20], 20 | "multiple-sends": "error", 21 | "no-complex-fallback": "error", 22 | "no-empty-blocks": "off", 23 | "no-inline-assembly": "error", 24 | "no-unused-vars": "error", 25 | "not-rely-on-block-hash": "error", 26 | "not-rely-on-time": "off", 27 | "payable-fallback": "error", 28 | "quotes": ["error","double"], 29 | "reentrancy": "error", 30 | "state-visibility": "error", 31 | "use-forbidden-name": "error", 32 | "var-name-mixedcase": "error", 33 | "visibility-modifier-order": "error" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 10 4 | 5 | before_install: 6 | - npm i -g npm 7 | - npm i -g mocha-only-detector 8 | - find test/ -name "*.js" -print0 | xargs -0 mocha-only-detector 9 | 10 | env: 11 | global: 12 | - COVERAGE_BRANCH=Katalyst 13 | 14 | jobs: 15 | include: 16 | - env: 17 | - TEST_PART: All 18 | - env: 19 | - TEST_PART: Coverage 20 | 21 | install: 22 | - npm ci 23 | 24 | before_script: 25 | - npx solhint "contracts/sol6/**/*.sol" 26 | - npx solhint "contracts/sol5/**/*.sol" 27 | - npx solhint "contracts/sol4/**/*.sol" 28 | 29 | script: 30 | - ./cmp.sh 31 | - .travis/test-part.sh 32 | - .travis/report.sh 33 | 34 | deploy: 35 | - provider: s3 36 | access_key_id: $AWS_ACCESS_KEY_ID 37 | secret_access_key: $AWS_SECRET_ACCESS_KEY 38 | bucket: katalyst-coverage.knstats.com 39 | region: ap-southeast-1 40 | acl: public_read 41 | local_dir: report 42 | upload_dir: report 43 | skip_cleanup: true 44 | on: 45 | all_branches: true 46 | condition: $TEST_PART = Sol6 47 | - provider: s3 48 | access_key_id: $AWS_ACCESS_KEY_ID 49 | secret_access_key: $AWS_SECRET_ACCESS_KEY 50 | bucket: katalyst-coverage.knstats.com 51 | region: ap-southeast-1 52 | acl: public_read 53 | local_dir: coverage 54 | skip_cleanup: true 55 | on: 56 | branch: $COVERAGE_BRANCH 57 | condition: $TEST_PART = Coverage 58 | -------------------------------------------------------------------------------- /.travis/report.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | node contractSizeReport.js $TRAVIS_PULL_REQUEST_BRANCH 4 | node gasUsedReport.js $TRAVIS_PULL_REQUEST_BRANCH 5 | -------------------------------------------------------------------------------- /.travis/test-part.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # -*- firestarter: "shfmt -i 4 -ci -w %p" -*- 3 | 4 | set -euxo pipefail 5 | 6 | readonly test_part=${TEST_PART:-} 7 | 8 | case "$test_part" in 9 | All) 10 | npx buidler test --no-compile 11 | ;; 12 | Sol6) 13 | npx buidler test --no-compile --config buidlerConfigSol6.js 14 | ;; 15 | Coverage) 16 | if [[ $TRAVIS_EVENT_TYPE != "push" ]]; then 17 | echo "Only running coverage on merge request or direct push" 18 | elif [[ $TRAVIS_BRANCH == $COVERAGE_BRANCH ]]; then 19 | ./coverage.sh || true 20 | else 21 | echo "Not running coverage on $TRAVIS_BRANCH" 22 | fi 23 | ;; 24 | *) 25 | echo "test case not define yet" 26 | ;; 27 | esac 28 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04.5 2 | 3 | RUN apt-get update && \ 4 | apt-get install -y \ 5 | software-properties-common \ 6 | g++ \ 7 | build-essential \ 8 | curl \ 9 | git \ 10 | file \ 11 | binutils \ 12 | libssl-dev \ 13 | pkg-config \ 14 | libudev-dev \ 15 | openssl 16 | 17 | RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - 18 | RUN apt-get install -y nodejs 19 | 20 | ADD . /smart-contracts 21 | 22 | WORKDIR /smart-contracts 23 | 24 | RUN npm install -g truffle@4.0.1 25 | RUN npm install bignumber.js 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 KyberNetwork 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | This repository contains kyber network smart contracts. 3 | For more details, please visit our [developer portal](https://developer.kyber.network/) 4 | 5 | ## API 6 | Public facing interfaces for kyber network (folder: contracts/sol6): 7 | 1. IKyberNetworkProxy.sol - Get rate and trade APIs. Hint handler address. 8 | 2. ISimpleKyberProxy.sol - Simple trade functions. 9 | 3. IKyberHintHandler.sol - Build hints for advanced trade functionality. 10 | 4. IKyberDao - Interact with KyberDao. 11 | 5. Dao/IKyberStaking - interact with KyberStaking. 12 | 13 | ## Setup 14 | 1. Clone this repo 15 | 2. `npm ci` 16 | 17 | ## Compilation with Buidler 18 | 1. `./cmp.sh` to compile contracts for all solidity versions. 19 | 2. `./cmpSol6.sh` to compile only sol6 contracts 20 | 21 | ## Testing with Buidler 22 | 1. If contracts have not been compiled, run `./cmp.sh`. This step can be skipped subsequently. 23 | 2. Run `./tst.sh` 24 | 3. Use `-f` for running a specific test file. 25 | 5. Use `-a` to run tests for all solidity versions. Runs only sol6 tests by default. 26 | 27 | ### Example Commands 28 | `./tst.sh` (Run only sol6 tests) 29 | `./tst.sh -f ./test/sol4/kyberReserve.js` (Test only kyberReserve.js) 30 | `./tst.sh -a` (Run sol4, sol5, sol6 tests) 31 | 32 | ### Example 33 | `npx buidler test --no-compile ./test/sol6/kyberNetwork.js` 34 | 35 | ## Coverage with `buidler-coverage` 36 | 1. Run `./coverage.sh` 37 | 2. Use `-f` for running a specific test file. 38 | 39 | ### Example Commands 40 | `./coverage.sh -f ./test/sol6/kyberNetwork.js` (Coverage for only kyberNetwork.js) 41 | -------------------------------------------------------------------------------- /audits/APRAudit/SmartDecAudit.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyberNetwork/smart-contracts/e4d3ae21e063bfd65c4621197687334527eb54dc/audits/APRAudit/SmartDecAudit.pdf -------------------------------------------------------------------------------- /audits/kyberV1Audit2/KyberNetwork BlockchainLabs Audit Report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyberNetwork/smart-contracts/e4d3ae21e063bfd65c4621197687334527eb54dc/audits/kyberV1Audit2/KyberNetwork BlockchainLabs Audit Report.pdf -------------------------------------------------------------------------------- /audits/kyberV2Audit/ChainSecurity_KyberNetwork_Public.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyberNetwork/smart-contracts/e4d3ae21e063bfd65c4621197687334527eb54dc/audits/kyberV2Audit/ChainSecurity_KyberNetwork_Public.pdf -------------------------------------------------------------------------------- /audits/kyberV3Audit/ChainSecurity_Kyberv3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KyberNetwork/smart-contracts/e4d3ae21e063bfd65c4621197687334527eb54dc/audits/kyberV3Audit/ChainSecurity_Kyberv3.pdf -------------------------------------------------------------------------------- /buidlerConfigSol4.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | solc: { 3 | version: "0.4.18", 4 | optimizer: require("./solcOptimiserSettings.js") 5 | }, 6 | 7 | paths: { 8 | sources: "./contracts/sol4" 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /buidlerConfigSol5.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | solc: { 3 | version: "0.5.11", 4 | optimizer: require("./solcOptimiserSettings.js") 5 | }, 6 | 7 | paths: { 8 | sources: "./contracts/sol5", 9 | tests: "./test/sol5" 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /buidlerCoverageSol4.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | solc: { 3 | version: "0.4.18", 4 | optimizer: require("./solcOptimiserSettings.js") 5 | }, 6 | 7 | paths: { 8 | sources: "./contracts/sol4", 9 | artifacts: ".coverageArtifacts" 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /buidlerCoverageSol5.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | solc: { 3 | version: "0.5.11", 4 | optimizer: require("./solcOptimiserSettings.js") 5 | }, 6 | 7 | paths: { 8 | sources: "./contracts/sol5", 9 | artifacts: ".coverageArtifacts" 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /cmp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export NODE_OPTIONS=--max-old-space-size=4096 3 | npx buidler compile && 4 | npx buidler compile --config buidlerConfigSol5.js && 5 | npx buidler compile --config buidlerConfigSol4.js && 6 | node contractSizeReport.js 7 | -------------------------------------------------------------------------------- /cmpSol6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npx buidler compile && 3 | node contractSizeReport.js 4 | -------------------------------------------------------------------------------- /contracts/sol4/ConversionRatesInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | 6 | 7 | interface ConversionRatesInterface { 8 | 9 | function recordImbalance( 10 | ERC20 token, 11 | int buyAmount, 12 | uint rateUpdateBlock, 13 | uint currentBlock 14 | ) 15 | public; 16 | 17 | function getRate(ERC20 token, uint currentBlockNumber, bool buy, uint qty) public view returns(uint); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/sol4/ERC20Interface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | // https://github.com/ethereum/EIPs/issues/20 5 | interface ERC20 { 6 | function totalSupply() public view returns (uint supply); 7 | function balanceOf(address _owner) public view returns (uint balance); 8 | function transfer(address _to, uint _value) public returns (bool success); 9 | function transferFrom(address _from, address _to, uint _value) public returns (bool success); 10 | function approve(address _spender, uint _value) public returns (bool success); 11 | function allowance(address _owner, address _spender) public view returns (uint remaining); 12 | function decimals() public view returns(uint digits); 13 | event Approval(address indexed _owner, address indexed _spender, uint _value); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/sol4/FeeBurnerInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | interface FeeBurnerInterface { 5 | function handleFees (uint tradeWeiAmount, address reserve, address wallet) public returns(bool); 6 | function setReserveData(address reserve, uint feesInBps, address kncWallet) public; 7 | } 8 | -------------------------------------------------------------------------------- /contracts/sol4/KyberNetworkInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | 6 | 7 | /// @title Kyber Network interface 8 | interface KyberNetworkInterface { 9 | function maxGasPrice() public view returns(uint); 10 | function getUserCapInWei(address user) public view returns(uint); 11 | function getUserCapInTokenWei(address user, ERC20 token) public view returns(uint); 12 | function enabled() public view returns(bool); 13 | function info(bytes32 id) public view returns(uint); 14 | 15 | function getExpectedRate(ERC20 src, ERC20 dest, uint srcQty) public view 16 | returns (uint expectedRate, uint slippageRate); 17 | 18 | function tradeWithHint(address trader, ERC20 src, uint srcAmount, ERC20 dest, address destAddress, 19 | uint maxDestAmount, uint minConversionRate, address walletId, bytes hint) public payable returns(uint); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/sol4/KyberNetworkProxyInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | 6 | 7 | /// @title Kyber Network interface 8 | interface KyberNetworkProxyInterface { 9 | function maxGasPrice() public view returns(uint); 10 | function getUserCapInWei(address user) public view returns(uint); 11 | function getUserCapInTokenWei(address user, ERC20 token) public view returns(uint); 12 | function enabled() public view returns(bool); 13 | function info(bytes32 id) public view returns(uint); 14 | 15 | function getExpectedRate(ERC20 src, ERC20 dest, uint srcQty) public view 16 | returns (uint expectedRate, uint slippageRate); 17 | 18 | function tradeWithHint(ERC20 src, uint srcAmount, ERC20 dest, address destAddress, uint maxDestAmount, 19 | uint minConversionRate, address walletId, bytes hint) public payable returns(uint); 20 | } 21 | -------------------------------------------------------------------------------- /contracts/sol4/KyberReserveInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | 6 | /// @title Kyber Reserve contract 7 | interface KyberReserveInterface { 8 | 9 | function trade( 10 | ERC20 srcToken, 11 | uint srcAmount, 12 | ERC20 destToken, 13 | address destAddress, 14 | uint conversionRate, 15 | bool validate 16 | ) 17 | public 18 | payable 19 | returns(bool); 20 | 21 | function getConversionRate(ERC20 src, ERC20 dest, uint srcQty, uint blockNumber) public view returns(uint); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/sol4/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | contract Migrations { 5 | address public owner; 6 | uint public lastCompletedMigration; 7 | 8 | modifier restricted() { 9 | if (msg.sender == owner) _; 10 | } 11 | 12 | function Migrations() public { 13 | owner = msg.sender; 14 | } 15 | 16 | function setCompleted(uint completed) public restricted { 17 | lastCompletedMigration = completed; 18 | } 19 | 20 | function upgrade(address newAddress) public restricted { 21 | Migrations upgraded = Migrations(newAddress); 22 | upgraded.setCompleted(lastCompletedMigration); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/sol4/SanityRates.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | import "./Withdrawable.sol"; 6 | import "./Utils.sol"; 7 | import "./SanityRatesInterface.sol"; 8 | 9 | 10 | contract SanityRates is SanityRatesInterface, Withdrawable, Utils { 11 | mapping(address=>uint) public tokenRate; 12 | mapping(address=>uint) public reasonableDiffInBps; 13 | 14 | function SanityRates(address _admin) public { 15 | require(_admin != address(0)); 16 | admin = _admin; 17 | } 18 | 19 | function setReasonableDiff(ERC20[] srcs, uint[] diff) public onlyAdmin { 20 | require(srcs.length == diff.length); 21 | for (uint i = 0; i < srcs.length; i++) { 22 | require(diff[i] <= 100 * 100); 23 | reasonableDiffInBps[srcs[i]] = diff[i]; 24 | } 25 | } 26 | 27 | function setSanityRates(ERC20[] srcs, uint[] rates) public onlyOperator { 28 | require(srcs.length == rates.length); 29 | 30 | for (uint i = 0; i < srcs.length; i++) { 31 | require(rates[i] <= MAX_RATE); 32 | tokenRate[srcs[i]] = rates[i]; 33 | } 34 | } 35 | 36 | function getSanityRate(ERC20 src, ERC20 dest) public view returns(uint) { 37 | if (src != ETH_TOKEN_ADDRESS && dest != ETH_TOKEN_ADDRESS) return 0; 38 | 39 | uint rate; 40 | address token; 41 | if (src == ETH_TOKEN_ADDRESS) { 42 | rate = (PRECISION*PRECISION)/tokenRate[dest]; 43 | token = dest; 44 | } else { 45 | rate = tokenRate[src]; 46 | token = src; 47 | } 48 | 49 | return rate * (10000 + reasonableDiffInBps[token])/10000; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/sol4/SanityRatesInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | 6 | interface SanityRatesInterface { 7 | function getSanityRate(ERC20 src, ERC20 dest) public view returns(uint); 8 | } 9 | -------------------------------------------------------------------------------- /contracts/sol4/SimpleNetworkInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | 6 | 7 | /// @title simple interface for Kyber Network 8 | interface SimpleNetworkInterface { 9 | function swapTokenToToken(ERC20 src, uint srcAmount, ERC20 dest, uint minConversionRate) public returns(uint); 10 | function swapEtherToToken(ERC20 token, uint minConversionRate) public payable returns(uint); 11 | function swapTokenToEther(ERC20 token, uint srcAmount, uint minConversionRate) public returns(uint); 12 | } 13 | -------------------------------------------------------------------------------- /contracts/sol4/Utils.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | 6 | 7 | /// @title Kyber constants contract 8 | contract Utils { 9 | 10 | ERC20 constant internal ETH_TOKEN_ADDRESS = ERC20(0x00eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee); 11 | uint constant internal PRECISION = (10**18); 12 | uint constant internal MAX_QTY = (10**28); // 10B tokens 13 | uint constant internal MAX_RATE = (PRECISION * 10**6); // up to 1M tokens per ETH 14 | uint constant internal MAX_DECIMALS = 18; 15 | uint constant internal ETH_DECIMALS = 18; 16 | mapping(address=>uint) internal decimals; 17 | 18 | function setDecimals(ERC20 token) internal { 19 | if (token == ETH_TOKEN_ADDRESS) decimals[token] = ETH_DECIMALS; 20 | else decimals[token] = token.decimals(); 21 | } 22 | 23 | function getDecimals(ERC20 token) internal view returns(uint) { 24 | if (token == ETH_TOKEN_ADDRESS) return ETH_DECIMALS; // save storage access 25 | uint tokenDecimals = decimals[token]; 26 | // technically, there might be token with decimals 0 27 | // moreover, very possible that old tokens have decimals 0 28 | // these tokens will just have higher gas fees. 29 | if(tokenDecimals == 0) return token.decimals(); 30 | 31 | return tokenDecimals; 32 | } 33 | 34 | function calcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) { 35 | require(srcQty <= MAX_QTY); 36 | require(rate <= MAX_RATE); 37 | 38 | if (dstDecimals >= srcDecimals) { 39 | require((dstDecimals - srcDecimals) <= MAX_DECIMALS); 40 | return (srcQty * rate * (10**(dstDecimals - srcDecimals))) / PRECISION; 41 | } else { 42 | require((srcDecimals - dstDecimals) <= MAX_DECIMALS); 43 | return (srcQty * rate) / (PRECISION * (10**(srcDecimals - dstDecimals))); 44 | } 45 | } 46 | 47 | function calcSrcQty(uint dstQty, uint srcDecimals, uint dstDecimals, uint rate) internal pure returns(uint) { 48 | require(dstQty <= MAX_QTY); 49 | require(rate <= MAX_RATE); 50 | 51 | //source quantity is rounded up. to avoid dest quantity being too low. 52 | uint numerator; 53 | uint denominator; 54 | if (srcDecimals >= dstDecimals) { 55 | require((srcDecimals - dstDecimals) <= MAX_DECIMALS); 56 | numerator = (PRECISION * dstQty * (10**(srcDecimals - dstDecimals))); 57 | denominator = rate; 58 | } else { 59 | require((dstDecimals - srcDecimals) <= MAX_DECIMALS); 60 | numerator = (PRECISION * dstQty); 61 | denominator = (rate * (10**(dstDecimals - srcDecimals))); 62 | } 63 | return (numerator + denominator - 1) / denominator; //avoid rounding down errors 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /contracts/sol4/Utils2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./Utils.sol"; 5 | 6 | 7 | contract Utils2 is Utils { 8 | 9 | /// @dev get the balance of a user. 10 | /// @param token The token type 11 | /// @return The balance 12 | function getBalance(ERC20 token, address user) public view returns(uint) { 13 | if (token == ETH_TOKEN_ADDRESS) 14 | return user.balance; 15 | else 16 | return token.balanceOf(user); 17 | } 18 | 19 | function getDecimalsSafe(ERC20 token) internal returns(uint) { 20 | 21 | if (decimals[token] == 0) { 22 | setDecimals(token); 23 | } 24 | 25 | return decimals[token]; 26 | } 27 | 28 | function calcDestAmount(ERC20 src, ERC20 dest, uint srcAmount, uint rate) internal view returns(uint) { 29 | return calcDstQty(srcAmount, getDecimals(src), getDecimals(dest), rate); 30 | } 31 | 32 | function calcSrcAmount(ERC20 src, ERC20 dest, uint destAmount, uint rate) internal view returns(uint) { 33 | return calcSrcQty(destAmount, getDecimals(src), getDecimals(dest), rate); 34 | } 35 | 36 | function calcRateFromQty(uint srcAmount, uint destAmount, uint srcDecimals, uint dstDecimals) 37 | internal pure returns(uint) 38 | { 39 | require(srcAmount <= MAX_QTY); 40 | require(destAmount <= MAX_QTY); 41 | 42 | if (dstDecimals >= srcDecimals) { 43 | require((dstDecimals - srcDecimals) <= MAX_DECIMALS); 44 | return (destAmount * PRECISION / ((10 ** (dstDecimals - srcDecimals)) * srcAmount)); 45 | } else { 46 | require((srcDecimals - dstDecimals) <= MAX_DECIMALS); 47 | return (destAmount * PRECISION * (10 ** (srcDecimals - dstDecimals)) / srcAmount); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /contracts/sol4/Utils3.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./Utils2.sol"; 5 | 6 | 7 | contract Utils3 is Utils2 { 8 | 9 | function calcDestAmountWithDecimals(uint srcDecimals, uint destDecimals, uint srcAmount, uint rate) internal pure returns(uint) { 10 | return calcDstQty(srcAmount, srcDecimals, destDecimals, rate); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /contracts/sol4/Withdrawable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./ERC20Interface.sol"; 5 | import "./PermissionGroups.sol"; 6 | 7 | 8 | /** 9 | * @title Contracts that should be able to recover tokens or ethers 10 | * @author Ilan Doron 11 | * @dev This allows to recover any tokens or Ethers received in a contract. 12 | * This will prevent any accidental loss of tokens. 13 | */ 14 | contract Withdrawable is PermissionGroups { 15 | 16 | event TokenWithdraw(ERC20 token, uint amount, address sendTo); 17 | 18 | /** 19 | * @dev Withdraw all ERC20 compatible tokens 20 | * @param token ERC20 The address of the token contract 21 | */ 22 | function withdrawToken(ERC20 token, uint amount, address sendTo) external onlyAdmin { 23 | require(token.transfer(sendTo, amount)); 24 | TokenWithdraw(token, amount, sendTo); 25 | } 26 | 27 | event EtherWithdraw(uint amount, address sendTo); 28 | 29 | /** 30 | * @dev Withdraw Ethers 31 | */ 32 | function withdrawEther(uint amount, address sendTo) external onlyAdmin { 33 | sendTo.transfer(amount); 34 | EtherWithdraw(amount, sendTo); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contracts/sol4/abi/BurnableToken.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_value","type":"uint256"}],"name":"burnFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /contracts/sol4/abi/ERC20.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"supply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"digits","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"}] -------------------------------------------------------------------------------- /contracts/sol4/abi/ExpectedRateInterface.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"dest","type":"address"},{"name":"srcQty","type":"uint256"}],"name":"getExpectedRate","outputs":[{"name":"expectedRate","type":"uint256"},{"name":"slippageRate","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /contracts/sol4/abi/FeeBurnerInterface.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"name":"tradeWeiAmount","type":"uint256"},{"name":"reserve","type":"address"},{"name":"wallet","type":"address"}],"name":"handleFees","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /contracts/sol4/abi/PermissionGroups.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"name":"alerter","type":"address"}],"name":"removeAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOperators","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAlerter","type":"address"}],"name":"addAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAlerters","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOperator","type":"address"}],"name":"addOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"operator","type":"address"}],"name":"removeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"pendingAdmin","type":"address"}],"name":"TransferAdminPending","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAdmin","type":"address"},{"indexed":false,"name":"previousAdmin","type":"address"}],"name":"AdminClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAlerter","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"AlerterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOperator","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"OperatorAdded","type":"event"}] -------------------------------------------------------------------------------- /contracts/sol4/abi/SanityRatesInterface.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"dest","type":"address"}],"name":"getSanityRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /contracts/sol4/abi/Utils.abi: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /contracts/sol4/abi/Withdrawable.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"name":"alerter","type":"address"}],"name":"removeAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOperators","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"},{"name":"sendTo","type":"address"}],"name":"withdrawToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newAlerter","type":"address"}],"name":"addAlerter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claimAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAlerters","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOperator","type":"address"}],"name":"addOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"operator","type":"address"}],"name":"removeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"},{"name":"sendTo","type":"address"}],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"token","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"TokenWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"sendTo","type":"address"}],"name":"EtherWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"pendingAdmin","type":"address"}],"name":"TransferAdminPending","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAdmin","type":"address"},{"indexed":false,"name":"previousAdmin","type":"address"}],"name":"AdminClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAlerter","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"AlerterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newOperator","type":"address"},{"indexed":false,"name":"isAdd","type":"bool"}],"name":"OperatorAdded","type":"event"}] -------------------------------------------------------------------------------- /contracts/sol4/mock/MockCentralBank.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "../ERC20Interface.sol"; 4 | 5 | 6 | /// @title Mock Central Bank 7 | /// @author Yaron Velner 8 | /// @dev a dummy contract that simulates a bank that holds tokens and ether. centralized exchanges can convert tokens here. 9 | 10 | 11 | contract MockCentralBank { 12 | mapping(address=>bool) public owners; 13 | 14 | function MockCentralBank() public { 15 | owners[msg.sender] = true; 16 | } 17 | 18 | function() payable public { } 19 | 20 | function withdrawEther(uint amount) public { 21 | if (! owners[tx.origin]) revert(); 22 | 23 | msg.sender.transfer(amount); 24 | } 25 | 26 | function withdrawToken(ERC20 token, uint amount) public { 27 | if (!owners[tx.origin]) revert(); 28 | 29 | token.transfer(msg.sender,amount); 30 | } 31 | 32 | function depositEther() public payable { 33 | // just to simplify interaction with testrpc 34 | } 35 | 36 | function addOwner(address newOwner) public { 37 | if ( ! owners[tx.origin] ) revert(); 38 | owners[newOwner] = true; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockConversionRate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "../reserves/fprConversionRate/ConversionRates.sol"; 4 | 5 | 6 | contract MockConversionRate is ConversionRates { 7 | function MockConversionRate(address admin) ConversionRates(admin) public { 8 | 9 | } 10 | 11 | function mockGetImbalance(ERC20 token, uint rateUpdateBlock, uint currentBlock) public view 12 | returns(int totalImbalance, int currentBlockImbalance) 13 | { 14 | (totalImbalance, currentBlockImbalance) = getImbalance(token, rateUpdateBlock, currentBlock); 15 | // return(totalImbalance, currentBlockImbalance); 16 | } 17 | 18 | function mockGetMaxTotalImbalance(ERC20 token) public view returns(uint) { 19 | return getMaxTotalImbalance(token); 20 | } 21 | 22 | function getUpdateRateBlockFromCompact (ERC20 token) public view returns(uint updateRateBlock) { 23 | // get rate update block 24 | bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex]; 25 | updateRateBlock = getLast4Bytes(compactData); 26 | } 27 | 28 | function mockAddBps(uint rate, int bps) public pure returns(uint) { 29 | return addBps(rate, bps); 30 | } 31 | 32 | function mockIsTokenTradeEnabled(address token) public view returns (bool) { 33 | return tokenData[token].enabled; 34 | } 35 | 36 | function getInitImbalance(ERC20 token) public view returns(int totalImbalance) { 37 | // check if trade is enabled 38 | if (!tokenData[token].enabled) return 0; 39 | if (tokenControlInfo[token].minimalRecordResolution == 0) return 0; // token control info not set 40 | 41 | // get rate update block 42 | bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex]; 43 | 44 | uint updateRateBlock = getLast4Bytes(compactData); 45 | // check imbalance 46 | (totalImbalance, ) = getImbalance(token, updateRateBlock, block.number); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockConversionRateEnhancedSteps.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "../reserves/fprConversionRate/ConversionRateEnhancedSteps.sol"; 4 | 5 | 6 | contract MockConversionRateEnhancedSteps is ConversionRateEnhancedSteps { 7 | function MockConversionRateEnhancedSteps(address admin) public 8 | ConversionRateEnhancedSteps(admin) 9 | { /* empty block */ } 10 | 11 | function mockGetImbalance(ERC20 token, uint rateUpdateBlock, uint currentBlock) public view 12 | returns(int totalImbalance, int currentBlockImbalance) 13 | { 14 | (totalImbalance, currentBlockImbalance) = 15 | getImbalance(token, rateUpdateBlock, currentBlock); 16 | } 17 | 18 | function mockGetMaxTotalImbalance(ERC20 token) public view returns(uint) { 19 | return getMaxTotalImbalance(token); 20 | } 21 | 22 | function getUpdateRateBlockFromCompact (ERC20 token) 23 | public view returns(uint updateRateBlock) 24 | { 25 | // get rate update block 26 | bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex]; 27 | updateRateBlock = getLast4Bytes(compactData); 28 | } 29 | 30 | function mockAddBps(uint rate, int bps) public pure returns(uint) { 31 | return addBps(rate, bps); 32 | } 33 | 34 | function mockIsTokenTradeEnabled(address token) public view returns (bool) { 35 | return tokenData[token].enabled; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockDepositAddress.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "../ERC20Interface.sol"; 4 | import "./MockCentralBank.sol"; 5 | 6 | /// @title Mock Deposit Address 7 | /// @author Ilan Doron 8 | /// @dev a dummy contract that simulates a deposit address of a token on a specific exchange. allows reserve manager to deposit and withdraw 9 | 10 | 11 | contract MockDepositAddress { 12 | 13 | MockCentralBank public bank; 14 | address public owner; 15 | 16 | /// @dev Ctor of this 17 | /// @param _bank bank address to work with for deposit and withdraw 18 | /// @param _owner owner address for this contract. 19 | function MockDepositAddress( MockCentralBank _bank, address _owner ) public { 20 | owner = _owner; 21 | bank = _bank; 22 | } 23 | 24 | modifier onlyOwner( ) 25 | { 26 | require(msg.sender == owner); 27 | _; 28 | } 29 | 30 | event Withdraw(uint amount , address destianation); 31 | 32 | function withdraw(uint tokenAmount, address destination) public; 33 | 34 | function clearBalance(uint amount) public; 35 | 36 | function getBalance() public view returns (uint); 37 | } 38 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockDepositAddressEther.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "./MockCentralBank.sol"; 4 | import "./MockDepositAddress.sol"; 5 | 6 | /// @title Mock Deposit Address for Ethers 7 | /// @author Ilan Doron 8 | /// @dev a dummy contract that simulates a deposit address of a token on a specific exchange. 9 | /// allows reserve manager to deposit and withdraw 10 | contract MockDepositAddressEther is MockDepositAddress{ 11 | 12 | function MockDepositAddressEther(MockCentralBank _bank, address _owner) 13 | MockDepositAddress(_bank, _owner) 14 | public 15 | {} 16 | 17 | function () public payable {} 18 | 19 | function withdraw(uint etherAmount, address destination) public onlyOwner { 20 | bank.withdrawEther(etherAmount); 21 | destination.transfer(etherAmount); 22 | } 23 | 24 | function clearBalance( uint amount ) public onlyOwner { 25 | if (this.balance >= amount) { 26 | bank.transfer(amount); 27 | } 28 | } 29 | 30 | function getBalance() public view returns (uint) { 31 | return this.balance; 32 | } 33 | } -------------------------------------------------------------------------------- /contracts/sol4/mock/MockDepositAddressToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "./MockCentralBank.sol"; 4 | import "./MockDepositAddress.sol"; 5 | 6 | /// @title Mock Deposit Address for token 7 | /// @author Ilan Doron 8 | /// @dev a dummy contract that simulates a deposit address of a token on a specific exchange. allows reserve manager to deposit and withdraw 9 | contract MockDepositAddressToken is MockDepositAddress{ 10 | 11 | ERC20 public token; 12 | 13 | function MockDepositAddressToken(ERC20 _token, MockCentralBank _bank, address _owner) 14 | MockDepositAddress(_bank, _owner) 15 | public 16 | { 17 | token = _token; 18 | } 19 | 20 | function withdraw(uint tokenAmount, address destination) public onlyOwner { 21 | bank.withdrawToken(token, tokenAmount); 22 | token.transfer(destination, tokenAmount); 23 | } 24 | 25 | function clearBalance(uint amount) public 26 | onlyOwner 27 | { 28 | if (token.balanceOf(this) >= amount) { 29 | token.transfer(bank, amount); 30 | } 31 | } 32 | 33 | function getBalance() public view returns (uint) { 34 | return token.balanceOf(this); 35 | } 36 | } -------------------------------------------------------------------------------- /contracts/sol4/mock/MockERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | 4 | import "../ERC20Interface.sol"; 5 | 6 | 7 | interface MockERC20 { 8 | function totalSupply() public view returns (uint supply); 9 | function balanceOf(address _owner) public view returns (uint balance); 10 | function transfer(address _to, uint _value) public returns (bool success); 11 | function transferFrom(address _from, address _to, uint _value) public returns (bool success); 12 | function approve(address _spender, uint _value) public returns (bool success); 13 | function allowance(address _owner, address _spender) public view returns (uint remaining); 14 | function decimals() public view returns(uint digits); 15 | event Approval(address indexed _owner, address indexed _spender, uint _value); 16 | function name() public view returns(string tokenName); 17 | function symbol() public view returns(string tokenSymbol); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockEnhancedStepFunctions.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "../reserves/fprConversionRate/ConversionRateEnhancedSteps.sol"; 4 | 5 | 6 | contract MockEnhancedStepFunctions is ConversionRateEnhancedSteps { 7 | 8 | function MockEnhancedStepFunctions(address admin) ConversionRateEnhancedSteps(admin) public { 9 | 10 | } 11 | 12 | function getInitImbalance(ERC20 token) public view returns(int totalImbalance) { 13 | // check if trade is enabled 14 | if (!tokenData[token].enabled) return 0; 15 | if (tokenControlInfo[token].minimalRecordResolution == 0) return 0; // token control info not set 16 | 17 | // get rate update block 18 | bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex]; 19 | 20 | uint updateRateBlock = getLast4Bytes(compactData); 21 | // check imbalance 22 | (totalImbalance, ) = getImbalance(token, updateRateBlock, block.number); 23 | } 24 | 25 | function mockGetMaxTotalImbalance(ERC20 token) public view returns(uint) { 26 | return getMaxTotalImbalance(token); 27 | } 28 | 29 | function getUpdateRateBlockFromCompact (ERC20 token) public view returns(uint updateRateBlock) { 30 | // get rate update block 31 | bytes32 compactData = tokenRatesCompactData[tokenData[token].compactDataArrayIndex]; 32 | updateRateBlock = getLast4Bytes(compactData); 33 | } 34 | 35 | function mockExecuteStepFunction(ERC20 token, int from, int to) public view returns (int) { 36 | return executeStepFunction(tokenData[token].buyRateImbalanceStepFunction, from, to); 37 | } 38 | 39 | function mockGetImbalanceMax() public pure returns (int) { 40 | return MAX_IMBALANCE; 41 | } 42 | 43 | function mockEncodeStepData(int128 x, int128 y) public pure returns (int) { 44 | return encodeStepFunctionData(x, y); 45 | } 46 | 47 | function mockDecodeStepData(int val) public pure returns (int, int) { 48 | return decodeStepFunctionData(val); 49 | } 50 | 51 | function mockCheckValueMaxImbalance(uint maxVal) public pure returns(bool) { 52 | return int(maxVal) == MAX_IMBALANCE; 53 | } 54 | 55 | function mockAddBps(uint rate, int bps) public pure returns(uint) { 56 | return addBps(rate, bps); 57 | } 58 | 59 | function mockCheckMultiOverflow(int x, int y) public pure returns (bool) { 60 | return checkMultOverflow(x, y); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockExchange.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | 4 | import "../ERC20Interface.sol"; 5 | import "./MockCentralBank.sol"; 6 | import "./MockDepositAddressEther.sol"; 7 | import "./MockDepositAddressToken.sol"; 8 | import "../Utils.sol"; 9 | 10 | 11 | /// @title Mock Exchange Deposit Address 12 | /// @author Ilan Doron 13 | /// @dev a dummy contract that simulates a deposit address of an exchange. allows user to deposit, withdraw and convert tokens. 14 | contract MockExchange is Utils { 15 | 16 | string public exchangeName; 17 | MockCentralBank public bank; 18 | mapping(address=>bool) public owners; 19 | mapping(address=>MockDepositAddress) public tokenDepositAddresses; 20 | 21 | function MockExchange(string _exchangeName, MockCentralBank _bank) public { 22 | exchangeName = _exchangeName; 23 | bank = _bank; 24 | owners[msg.sender] = true; 25 | } 26 | 27 | modifier onlyOwner() 28 | { 29 | require(owners[msg.sender]); 30 | _; 31 | } 32 | 33 | function withdraw(ERC20 token, uint tokenAmount, address destination) public onlyOwner { 34 | require(tokenDepositAddresses[token] != address(0)); 35 | // withdraw from mockDepositaddress. which withdraws from bank 36 | tokenDepositAddresses[token].withdraw(tokenAmount, destination); 37 | } 38 | 39 | function clearBalances(ERC20[] tokens, uint[] amounts) public onlyOwner { 40 | 41 | for (uint i = 0; i < tokens.length; i++) { 42 | if (tokenDepositAddresses[tokens[i]] == address(0)) continue; 43 | tokenDepositAddresses[tokens[i]].clearBalance(amounts[i]); 44 | } 45 | } 46 | 47 | function getBalance( ERC20 token ) public view returns(uint) { 48 | return tokenDepositAddresses[token].getBalance(); 49 | } 50 | 51 | function addOwner( address newOwner ) public onlyOwner { 52 | owners[newOwner] = true; 53 | } 54 | 55 | function addMockDepositAddress( ERC20 token ) public onlyOwner { 56 | 57 | if (token == ETH_TOKEN_ADDRESS) 58 | tokenDepositAddresses[token] = new MockDepositAddressEther(bank, this); 59 | else 60 | tokenDepositAddresses[token] = new MockDepositAddressToken(token, bank, this); 61 | 62 | bank.addOwner(tokenDepositAddresses[token]); 63 | } 64 | } -------------------------------------------------------------------------------- /contracts/sol4/mock/MockImbalanceRecorder.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | 4 | import "../reserves/VolumeImbalanceRecorder.sol"; 5 | 6 | 7 | contract MockImbalanceRecorder is VolumeImbalanceRecorder { 8 | function MockImbalanceRecorder(address _admin) public VolumeImbalanceRecorder(_admin) {} 9 | 10 | function addTrade(ERC20 token, int buyAmount, uint rateUpdateBlock, uint currentBlock) public { 11 | addImbalance(token, buyAmount, rateUpdateBlock, currentBlock); 12 | } 13 | 14 | function getImbalanceSinceUpdate(ERC20 token, uint rateUpdateBlock, uint currentBlock) 15 | public view 16 | returns(int buyImbalance, int currentBlockImbalance) 17 | { 18 | return getImbalanceSinceRateUpdate(token, rateUpdateBlock, currentBlock); 19 | } 20 | 21 | function getMockImbalance(ERC20 token, uint rateUpdateBlock, uint currentBlock) 22 | public view 23 | returns(int totalImbalance, int currentBlockImbalance) 24 | { 25 | return getImbalance(token, rateUpdateBlock, currentBlock); 26 | } 27 | 28 | function getMockImbalanceInRange(ERC20 token, uint startBlock, uint endBlock) public view returns(int buyImbalance) { 29 | return getImbalanceInRange(token, startBlock, endBlock); 30 | } 31 | 32 | function getMaxBlockImbalance(ERC20 token) public view returns(uint) { 33 | return getMaxPerBlockImbalance(token); 34 | } 35 | 36 | function getMaxImbalance(ERC20 token) public view returns(uint) { 37 | return getMaxTotalImbalance(token); 38 | } 39 | 40 | function callEncodeTokenImbalanceData( 41 | int lastBlockBuyUnitsImbalance, 42 | uint lastBlock, 43 | int totalBuyUnitsImbalance, 44 | uint lastRateUpdateBlock 45 | ) 46 | external pure returns(uint) 47 | { 48 | TokenImbalanceData memory data = 49 | TokenImbalanceData(lastBlockBuyUnitsImbalance, lastBlock, totalBuyUnitsImbalance, lastRateUpdateBlock); 50 | return(encodeTokenImbalanceData(data)); 51 | } 52 | 53 | function callDecodeTokenImbalanceData(uint input) external pure returns(int, uint, int, uint) { 54 | TokenImbalanceData memory data = (decodeTokenImbalanceData(input)); 55 | return ( 56 | data.lastBlockBuyUnitsImbalance, 57 | data.lastBlock , 58 | data.totalBuyUnitsImbalance, 59 | data.lastRateUpdateBlock 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockKyberReserveHighRate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import "../reserves/KyberReserveHighRate.sol"; 4 | 5 | /// @title Kyber Reserve contract 6 | /// reuses KyberReserve.sol contract while overriding a few functions / values. 7 | /// Update MAX_RATE to higher value and should have maximum code reuse 8 | contract MockKyberReserveHighRate is KyberReserveHighRate { 9 | 10 | function MockKyberReserveHighRate( 11 | address _kyberNetwork, 12 | ConversionRatesInterface _ratesContract, 13 | address _admin 14 | ) 15 | public KyberReserveHighRate(_kyberNetwork, _ratesContract, _admin) 16 | { /* empty block */ } 17 | 18 | function mockCalcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) 19 | public pure returns(uint) 20 | { 21 | return calcDstQty(srcQty, srcDecimals, dstDecimals, rate); 22 | } 23 | 24 | function mockCalcSrcQty(uint dstQty, uint srcDecimals, uint dstDecimals, uint rate) 25 | public pure returns(uint) 26 | { 27 | return calcSrcQty(dstQty, srcDecimals, dstDecimals, rate); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockPermission.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "../PermissionGroups.sol"; 4 | 5 | 6 | contract MockPermission is PermissionGroups { 7 | uint public rate; 8 | bool public tradeActive = true; 9 | 10 | function MockPermission () public 11 | PermissionGroups() 12 | { 13 | } 14 | 15 | function setRate ( uint newRate ) public 16 | onlyOperator 17 | { 18 | rate = newRate; 19 | } 20 | 21 | function stopTrade () public 22 | onlyAlerter 23 | { 24 | tradeActive = false; 25 | } 26 | 27 | function activateTrade () public 28 | onlyOperator 29 | { 30 | tradeActive = true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockUtils.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "../Utils.sol"; 5 | 6 | /// @title Kyber utils contract 7 | contract MockUtils is Utils { 8 | 9 | function getMaxRate() public pure returns(uint) { 10 | return MAX_RATE; 11 | } 12 | 13 | function getMaxQty() public pure returns(uint) { 14 | return MAX_QTY; 15 | } 16 | 17 | function mockCalcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) public pure returns(uint) { 18 | return calcDstQty(srcQty, srcDecimals, dstDecimals, rate); 19 | } 20 | 21 | function mockCalcSrcQty(uint dstQty, uint srcDecimals, uint dstDecimals, uint rate) public pure returns(uint) { 22 | return calcSrcQty(dstQty, srcDecimals, dstDecimals, rate); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockUtils2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "../Utils2.sol"; 5 | 6 | 7 | /// @title Kyber utils contract 8 | contract MockUtils2 is Utils2 { 9 | function mockGetDecimalsSafe(ERC20 token) public view returns(uint) { 10 | return decimals[token]; 11 | } 12 | 13 | function mockSetDecimalsSafe(ERC20 token) public { 14 | setDecimals(token); 15 | } 16 | 17 | function mockCalcRateFromQty(uint srcAmount, uint destAmount, uint srcDecimals, uint dstDecimals) 18 | public pure returns(uint rateResult) 19 | { 20 | rateResult = calcRateFromQty(srcAmount, destAmount, srcDecimals, dstDecimals); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockUtils3.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "../Utils3.sol"; 5 | 6 | 7 | /// @title Kyber utils contract 8 | contract MockUtils3 is Utils3 { 9 | 10 | function mockCalcDestAmountWithDecimals(uint srcDecimals, uint destDecimals, uint srcAmount, uint rate) 11 | public pure returns(uint destAmount) 12 | { 13 | destAmount = calcDestAmountWithDecimals(srcDecimals, destDecimals, srcAmount, rate); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /contracts/sol4/mock/MockWithdrawable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | 4 | import "../Withdrawable.sol"; 5 | 6 | 7 | contract MockWithdrawable is Withdrawable { 8 | function () public payable { } 9 | } 10 | -------------------------------------------------------------------------------- /contracts/sol4/mock/StrictValidatingReserve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import '../reserves/KyberReserve.sol'; 4 | 5 | import './TempBank.sol'; 6 | 7 | 8 | /* 9 | * @title KyberReserve with check conversionRate before doTrade 10 | */ 11 | contract StrictValidatingReserve is KyberReserve { 12 | TempBank bank; 13 | 14 | function StrictValidatingReserve(address _kyberNetwork, ConversionRatesInterface _ratesContract, address _admin) 15 | public 16 | KyberReserve(_kyberNetwork, _ratesContract, _admin) 17 | {} 18 | 19 | function setBank(TempBank _bank) public { 20 | bank = _bank; 21 | } 22 | 23 | function doTrade(ERC20 srcToken, uint256 srcAmount, ERC20 destToken, address destAddress, uint256 conversionRate, bool validate) 24 | internal 25 | returns (bool) 26 | { 27 | if (bank != TempBank(0)) 28 | bank.transfer(msg.value); // reduce the reserve balance before the call 29 | uint256 expecedRate = getConversionRate(srcToken, destToken, srcAmount, block.number); 30 | require(expecedRate >= conversionRate); 31 | require(KyberReserve.doTrade(srcToken, srcAmount, destToken, destAddress, conversionRate, validate)); 32 | if (bank != TempBank(0)) 33 | bank.withdraw(); // transfer ether back to reserve contract 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /contracts/sol4/mock/TempBank.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | /* 5 | * @title simple contract allow send ether in and withdraw ether out 6 | */ 7 | contract TempBank { 8 | function() public payable {} 9 | 10 | function withdraw() public { 11 | msg.sender.transfer(address(this).balance); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /contracts/sol4/mock/abi/MockCentralBank.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"owners","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"addOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"depositEther","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"}] -------------------------------------------------------------------------------- /contracts/sol4/mock/dgx/TokenReceiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | contract TokenReceiver { 5 | function tokenFallback(address from, uint256 amount, bytes32 data) 6 | public 7 | returns (bool success); 8 | } 9 | -------------------------------------------------------------------------------- /contracts/sol4/mock/dgx/libs/DemurrageStructs.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import "./Types.sol"; 4 | 5 | 6 | library DemurrageStructs { 7 | using Types for Types.MutableUint; 8 | using Types for Types.MutableTimestamp; 9 | 10 | struct User { 11 | address account; 12 | bool no_demurrage_fee; 13 | Types.MutableUint balance; 14 | Types.MutableTimestamp payment_date; 15 | } 16 | 17 | struct Config { 18 | Types.MutableUint collector_balance; 19 | uint256 base; 20 | uint256 rate; 21 | address collector; 22 | } 23 | 24 | struct Demurrage { 25 | Config config; 26 | User user; 27 | uint256 collected_fee; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/sol4/mock/dgx/libs/TransferStructs.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import "./Types.sol"; 4 | 5 | 6 | library TransferStructs { 7 | using Types for Types.MutableUint; 8 | using Types for Types.MutableTimestamp; 9 | 10 | struct User { 11 | address account; 12 | Types.MutableUint balance; 13 | bool no_transfer_fee; 14 | } 15 | 16 | struct Spender { 17 | address account; 18 | Types.MutableUint allowance; 19 | } 20 | 21 | struct Config { 22 | Types.MutableUint collector_balance; 23 | address collector; 24 | uint256 base; 25 | uint256 rate; 26 | bool global_transfer_fee_disabled; 27 | uint256 minimum_transfer_amount; 28 | } 29 | 30 | struct Transfer { 31 | User sender; 32 | User recipient; 33 | Spender spender; 34 | Config config; 35 | Types.MutableUint received_amount; 36 | uint256 sent_amount; 37 | uint256 fee; 38 | bool is_transfer_from; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/KyberReserveHighRate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import "./KyberReserve.sol"; 4 | 5 | /// @title Kyber Reserve contract 6 | /// reuses KyberReserve.sol contract while overriding a few functions / values. 7 | /// Update MAX_RATE to higher value and should have maximum code reuse 8 | contract KyberReserveHighRate is KyberReserve { 9 | 10 | uint constant internal MAX_RATE = (PRECISION * 10 ** 7); // 10M tokens per ETH 11 | 12 | function KyberReserveHighRate(address _kyberNetwork, ConversionRatesInterface _ratesContract, 13 | address _admin) public KyberReserve(_kyberNetwork, _ratesContract, _admin) 14 | { } 15 | 16 | function calcDstQty(uint srcQty, uint srcDecimals, uint dstDecimals, uint rate) 17 | internal pure returns(uint) 18 | { 19 | require(srcQty <= MAX_QTY); 20 | require(rate <= MAX_RATE); 21 | 22 | if (dstDecimals >= srcDecimals) { 23 | require((dstDecimals - srcDecimals) <= MAX_DECIMALS); 24 | return (srcQty * rate * (10**(dstDecimals - srcDecimals))) / PRECISION; 25 | } else { 26 | require((srcDecimals - dstDecimals) <= MAX_DECIMALS); 27 | return (srcQty * rate) / (PRECISION * (10**(srcDecimals - dstDecimals))); 28 | } 29 | } 30 | 31 | function calcSrcQty(uint dstQty, uint srcDecimals, uint dstDecimals, uint rate) 32 | internal pure returns(uint) 33 | { 34 | require(dstQty <= MAX_QTY); 35 | require(rate <= MAX_RATE); 36 | 37 | //source quantity is rounded up. to avoid dest quantity being too low. 38 | uint numerator; 39 | uint denominator; 40 | if (srcDecimals >= dstDecimals) { 41 | require((srcDecimals - dstDecimals) <= MAX_DECIMALS); 42 | numerator = (PRECISION * dstQty * (10**(srcDecimals - dstDecimals))); 43 | denominator = rate; 44 | } else { 45 | require((dstDecimals - srcDecimals) <= MAX_DECIMALS); 46 | numerator = (PRECISION * dstQty); 47 | denominator = (rate * (10**(dstDecimals - srcDecimals))); 48 | } 49 | return (numerator + denominator - 1) / denominator; //avoid rounding down 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/bridgeReserves/dutchX/mock/WETH9.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | contract WETH9 { 5 | string public name = "Wrapped Ether"; 6 | string public symbol = "WETH"; 7 | uint8 public decimals = 18; 8 | 9 | event Approval(address indexed src, address indexed guy, uint wad); 10 | event Transfer(address indexed src, address indexed dst, uint wad); 11 | event Deposit(address indexed dst, uint wad); 12 | event Withdrawal(address indexed src, uint wad); 13 | 14 | mapping (address => uint) public balanceOf; 15 | mapping (address => mapping (address => uint)) public allowance; 16 | 17 | function() public payable { 18 | deposit(); 19 | } 20 | 21 | function deposit() public payable { 22 | balanceOf[msg.sender] += msg.value; 23 | Deposit(msg.sender, msg.value); 24 | } 25 | 26 | function withdraw(uint wad) public { 27 | require(balanceOf[msg.sender] >= wad); 28 | balanceOf[msg.sender] -= wad; 29 | msg.sender.transfer(wad); 30 | Withdrawal(msg.sender, wad); 31 | } 32 | 33 | function totalSupply() public view returns (uint) { 34 | return this.balance; 35 | } 36 | 37 | function approve(address guy, uint wad) public returns (bool) { 38 | allowance[msg.sender][guy] = wad; 39 | Approval(msg.sender, guy, wad); 40 | return true; 41 | } 42 | 43 | function transfer(address dst, uint wad) public returns (bool) { 44 | return transferFrom(msg.sender, dst, wad); 45 | } 46 | 47 | function transferFrom(address src, address dst, uint wad) 48 | public 49 | returns (bool) 50 | { 51 | require(balanceOf[src] >= wad); 52 | 53 | if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { 54 | require(allowance[src][msg.sender] >= wad); 55 | allowance[src][msg.sender] -= wad; 56 | } 57 | 58 | balanceOf[src] -= wad; 59 | balanceOf[dst] += wad; 60 | 61 | Transfer(src, dst, wad); 62 | 63 | return true; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/bridgeReserves/uniswap/forTesting/KyberTestingUniswapReserve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import "../KyberUniswapReserve.sol"; 4 | 5 | 6 | contract TestingKyberUniswapReserve is KyberUniswapReserve { 7 | function TestingKyberUniswapReserve( 8 | UniswapFactory _uniswapFactory, 9 | address _admin, 10 | address _kyberNetwork 11 | ) 12 | public 13 | KyberUniswapReserve(_uniswapFactory, _admin, _kyberNetwork) 14 | { 15 | } 16 | 17 | function getTokenDecimals(ERC20 token) 18 | public 19 | view 20 | returns(uint) 21 | { 22 | return decimals[token]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/OrderIdManager.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | contract OrderIdManager { 5 | struct OrderIdData { 6 | uint32 firstOrderId; 7 | uint takenBitmap; 8 | } 9 | 10 | uint constant public NUM_ORDERS = 32; 11 | 12 | function fetchNewOrderId(OrderIdData storage freeOrders) 13 | internal 14 | returns(uint32) 15 | { 16 | uint orderBitmap = freeOrders.takenBitmap; 17 | uint bitPointer = 1; 18 | 19 | for (uint i = 0; i < NUM_ORDERS; ++i) { 20 | 21 | if ((orderBitmap & bitPointer) == 0) { 22 | freeOrders.takenBitmap = orderBitmap | bitPointer; 23 | return(uint32(uint(freeOrders.firstOrderId) + i)); 24 | } 25 | 26 | bitPointer *= 2; 27 | } 28 | 29 | revert(); 30 | } 31 | 32 | /// @dev mark order as free to use. 33 | function releaseOrderId(OrderIdData storage freeOrders, uint32 orderId) 34 | internal 35 | returns(bool) 36 | { 37 | require(orderId >= freeOrders.firstOrderId); 38 | require(orderId < (freeOrders.firstOrderId + NUM_ORDERS)); 39 | 40 | uint orderBitNum = uint(orderId) - uint(freeOrders.firstOrderId); 41 | uint bitPointer = uint(1) << orderBitNum; 42 | 43 | require(bitPointer & freeOrders.takenBitmap > 0); 44 | 45 | freeOrders.takenBitmap &= ~bitPointer; 46 | return true; 47 | } 48 | 49 | function allocateOrderIds( 50 | OrderIdData storage makerOrders, 51 | uint32 firstAllocatedId 52 | ) 53 | internal 54 | returns(bool) 55 | { 56 | if (makerOrders.firstOrderId > 0) { 57 | return false; 58 | } 59 | 60 | makerOrders.firstOrderId = firstAllocatedId; 61 | makerOrders.takenBitmap = 0; 62 | 63 | return true; 64 | } 65 | 66 | function orderAllocationRequired(OrderIdData storage freeOrders) internal view returns (bool) { 67 | 68 | if (freeOrders.firstOrderId == 0) return true; 69 | return false; 70 | } 71 | 72 | function getNumActiveOrderIds(OrderIdData storage makerOrders) internal view returns (uint numActiveOrders) { 73 | for (uint i = 0; i < NUM_ORDERS; ++i) { 74 | if ((makerOrders.takenBitmap & (uint(1) << i)) > 0) numActiveOrders++; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/OrderListFactory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./OrderList.sol"; 5 | 6 | 7 | contract OrderListFactory { 8 | function newOrdersContract(address admin) public returns(OrderListInterface) { 9 | OrderList orders = new OrderList(admin); 10 | return orders; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/OrderListFactoryInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./OrderListInterface.sol"; 5 | 6 | 7 | interface OrderListFactoryInterface { 8 | function newOrdersContract(address admin) public returns(OrderListInterface); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/OrderListInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | interface OrderListInterface { 5 | function getOrderDetails(uint32 orderId) public view returns (address, uint128, uint128, uint32, uint32); 6 | function add(address maker, uint32 orderId, uint128 srcAmount, uint128 dstAmount) public returns (bool); 7 | function remove(uint32 orderId) public returns (bool); 8 | function update(uint32 orderId, uint128 srcAmount, uint128 dstAmount) public returns (bool); 9 | function getFirstOrder() public view returns(uint32 orderId, bool isEmpty); 10 | function allocateIds(uint32 howMany) public returns(uint32); 11 | function findPrevOrderId(uint128 srcAmount, uint128 dstAmount) public view returns(uint32); 12 | 13 | function addAfterId(address maker, uint32 orderId, uint128 srcAmount, uint128 dstAmount, uint32 prevId) public 14 | returns (bool); 15 | 16 | function updateWithPositionHint(uint32 orderId, uint128 srcAmount, uint128 dstAmount, uint32 prevId) public 17 | returns(bool, uint); 18 | } 19 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/OrderbookReserveInterface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "./OrderListFactoryInterface.sol"; 5 | 6 | 7 | interface OrderbookReserveInterface { 8 | function init() public returns(bool); 9 | function kncRateBlocksTrade() public view returns(bool); 10 | } 11 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/mock/MockMedianizer.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | contract MockMedianizer { 5 | 6 | uint dollarPerEthPrecision; 7 | bool valid = true; 8 | 9 | function setEthPrice(uint dollarPerEth) public { 10 | dollarPerEthPrecision = dollarPerEth; 11 | } 12 | 13 | function setValid(bool isValid) public { 14 | valid = isValid; 15 | } 16 | 17 | function peek() public view returns (bytes32, bool) { 18 | return(bytes32(dollarPerEthPrecision), valid); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/mock/MockOrderIdManager.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "../OrderIdManager.sol"; 5 | 6 | 7 | contract MockOrderIdManager is OrderIdManager { 8 | 9 | OrderIdData orderIdData; 10 | 11 | function allocatOrderIds(uint firstId) public { 12 | require(allocateOrderIds(orderIdData, uint32(firstId))); 13 | } 14 | 15 | event NewOrderId(uint orderId); 16 | 17 | function fetchNewOrderId() public returns (uint orderId) { 18 | orderId = fetchNewOrderId(orderIdData); 19 | NewOrderId(orderId); 20 | return orderId; 21 | } 22 | 23 | function releaseOrderId(uint32 orderId) public { 24 | releaseOrderId(orderIdData, orderId); 25 | } 26 | 27 | function getTakenOrdersBitMap() public view returns(uint256) { 28 | return orderIdData.takenBitmap; 29 | } 30 | 31 | function getFirstOrderId() public view returns(uint32) { 32 | return orderIdData.firstOrderId; 33 | } 34 | 35 | function isOrderAllocationRequired() public view returns(bool) { 36 | return orderAllocationRequired(orderIdData); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/mock/MockOrderbookReserve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "../OrderbookReserve.sol"; 5 | 6 | 7 | contract MockOrderbookReserve is OrderbookReserve { 8 | 9 | function MockOrderbookReserve( 10 | ERC20 knc, 11 | ERC20 reserveToken, 12 | address burner, 13 | address network, 14 | MedianizerInterface medianizer, 15 | OrderListFactoryInterface factory, 16 | uint minNewOrderDollar, 17 | uint maxOrdersPerTrade, 18 | uint burnFeeBps 19 | ) 20 | public 21 | OrderbookReserve(knc, reserveToken, burner, network, medianizer, factory, minNewOrderDollar, maxOrdersPerTrade, 22 | burnFeeBps) 23 | { 24 | } 25 | 26 | function testBindStakes(address maker, int amountWei) public { 27 | bindOrderStakes(maker, amountWei); 28 | } 29 | 30 | function testHandleStakes(address maker, uint weiAmount, uint burnWeiAmount) public { 31 | releaseOrderStakes(maker, weiAmount, burnWeiAmount); 32 | } 33 | 34 | function setBaseKncPerEthRate(uint rate) public { 35 | kncPerEthBaseRatePrecision = rate; 36 | } 37 | 38 | function testTakePartialOrder( 39 | address maker, 40 | uint32 orderId, 41 | ERC20 userSrc, 42 | ERC20 userDst, 43 | uint128 userPartialSrcAmount, 44 | uint128 userTakeDstAmount, 45 | uint128 orderSrcAmount, 46 | uint128 orderDstAmount 47 | ) public { 48 | takePartialOrder(maker, orderId, userSrc, userDst, userPartialSrcAmount, userTakeDstAmount, orderSrcAmount, orderDstAmount); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /contracts/sol4/reserves/orderBookReserve/permissionless/mock/TestBytes32.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | contract testBytes32 { 4 | 5 | uint numTests; 6 | bytes public localHint; 7 | 8 | function testBytes32(bytes) public{ 9 | localHint[0] = byte(80); 10 | localHint[1] = byte(69); 11 | localHint[2] = byte(82); 12 | localHint[3] = byte(77); 13 | } 14 | 15 | event TestBytes(bytes sentHint, bytes localHint); 16 | function testBytes(bytes hint) public { 17 | ++numTests; 18 | TestBytes(hint, localHint); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /contracts/sol4/weth/mockContracts/MockWeth.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | contract WETH9 { 4 | string public name = "Wrapped Ether"; 5 | string public symbol = "WETH"; 6 | uint8 public decimals = 18; 7 | 8 | event Approval(address indexed src, address indexed guy, uint wad); 9 | event Transfer(address indexed src, address indexed dst, uint wad); 10 | event Deposit(address indexed dst, uint wad); 11 | event Withdrawal(address indexed src, uint wad); 12 | 13 | mapping (address => uint) public balanceOf; 14 | mapping (address => mapping (address => uint)) public allowance; 15 | 16 | function() public payable { 17 | deposit(); 18 | } 19 | function deposit() public payable { 20 | balanceOf[msg.sender] += msg.value; 21 | Deposit(msg.sender, msg.value); 22 | } 23 | function withdraw(uint wad) public { 24 | require(balanceOf[msg.sender] >= wad); 25 | balanceOf[msg.sender] -= wad; 26 | msg.sender.transfer(wad); 27 | Withdrawal(msg.sender, wad); 28 | } 29 | 30 | function totalSupply() public view returns (uint) { 31 | return this.balance; 32 | } 33 | 34 | function approve(address guy, uint wad) public returns (bool) { 35 | allowance[msg.sender][guy] = wad; 36 | Approval(msg.sender, guy, wad); 37 | return true; 38 | } 39 | 40 | function transfer(address dst, uint wad) public returns (bool) { 41 | return transferFrom(msg.sender, dst, wad); 42 | } 43 | 44 | function transferFrom(address src, address dst, uint wad) 45 | public 46 | returns (bool) 47 | { 48 | require(balanceOf[src] >= wad); 49 | 50 | if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { 51 | require(allowance[src][msg.sender] >= wad); 52 | allowance[src][msg.sender] -= wad; 53 | } 54 | 55 | balanceOf[src] -= wad; 56 | balanceOf[dst] += wad; 57 | 58 | Transfer(src, dst, wad); 59 | 60 | return true; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/sol4/wrappers/SetStepFunctionWrapper.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | import "../ERC20Interface.sol"; 4 | import "../Withdrawable.sol"; 5 | 6 | 7 | interface SetStepFunctionInterface { 8 | function setImbalanceStepFunction( 9 | ERC20 token, 10 | int[] xBuy, 11 | int[] yBuy, 12 | int[] xSell, 13 | int[] ySell 14 | ) public; 15 | } 16 | 17 | contract SetStepFunctionWrapper is Withdrawable { 18 | SetStepFunctionInterface public rateContract; 19 | function SetStepFunctionWrapper(address admin, address operator) public { 20 | require(admin != address(0)); 21 | require(operator != (address(0))); 22 | 23 | addOperator(operator); 24 | transferAdminQuickly(admin); 25 | } 26 | 27 | function setConversionRateAddress(SetStepFunctionInterface _contract) public onlyOperator { 28 | rateContract = _contract; 29 | } 30 | 31 | function setImbalanceStepFunction( 32 | ERC20 token, 33 | int[] xBuy, 34 | int[] yBuy, 35 | int[] xSell, 36 | int[] ySell) 37 | public onlyOperator 38 | { 39 | uint i; 40 | 41 | // check all x for buy are positive 42 | for( i = 0 ; i < xBuy.length ; i++ ) { 43 | require(xBuy[i] >= 0 ); 44 | } 45 | 46 | // check all y for buy are negative 47 | for( i = 0 ; i < yBuy.length ; i++ ) { 48 | require(yBuy[i] <= 0 ); 49 | } 50 | 51 | // check all x for sell are negative 52 | for( i = 0 ; i < xSell.length ; i++ ) { 53 | require(xSell[i] <= 0 ); 54 | } 55 | 56 | // check all y for sell are negative 57 | for( i = 0 ; i < ySell.length ; i++ ) { 58 | require(ySell[i] <= 0 ); 59 | } 60 | 61 | rateContract.setImbalanceStepFunction(token,xBuy,yBuy,xSell,ySell); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/sol4/wrappers/WrapConversionRateEnhancedSteps.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import "./WrapConversionRate.sol"; 4 | 5 | 6 | contract WrapConversionRateEnhancedSteps is WrapConversionRate { 7 | 8 | //general functions 9 | function WrapConversionRateEnhancedSteps(ConversionRates _conversionRates) public 10 | WrapConversionRate(_conversionRates) 11 | { /* empty block */ } 12 | 13 | function addToken( 14 | ERC20 token, 15 | uint minRecordResolution, 16 | uint maxPerBlockImbalance, 17 | uint maxTotalImbalance 18 | ) public onlyAdmin 19 | { 20 | require(token != address(0)); 21 | require(minRecordResolution != 0); 22 | require(maxPerBlockImbalance != 0); 23 | require(maxTotalImbalance != 0); 24 | 25 | conversionRates.addToken(token); 26 | 27 | //token control info 28 | conversionRates.setTokenControlInfo( 29 | token, 30 | minRecordResolution, 31 | maxPerBlockImbalance, 32 | maxTotalImbalance 33 | ); 34 | 35 | //step functions 36 | int[] memory emptyArr = new int[](0); 37 | int[] memory zeroArr = new int[](1); 38 | zeroArr[0] = 0; 39 | 40 | conversionRates.setImbalanceStepFunction(token, emptyArr, zeroArr, emptyArr, zeroArr); 41 | 42 | conversionRates.enableTokenTrade(token); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/sol4/wrappers/WrapReadTokenData.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | import "../reserves/fprConversionRate/ConversionRates.sol"; 5 | import "../ERC20Interface.sol"; 6 | 7 | 8 | contract WrapReadTokenData { 9 | function WrapReadTokenData() public { } 10 | 11 | function readQtyStepFunctions(ConversionRates rate, ERC20 token) public view returns( 12 | int numBuyRateQtySteps, 13 | int[] buyRateQtyStepsX, 14 | int[] buyRateQtyStepsY, 15 | int numSellRateQtySteps, 16 | int[] SellRateQtyStepsX, 17 | int[] SellRateQtyStepsY) 18 | { 19 | uint i; 20 | numBuyRateQtySteps = rate.getStepFunctionData(token, 0, 0); 21 | buyRateQtyStepsX = new int[](uint(numBuyRateQtySteps)); 22 | buyRateQtyStepsY = new int[](uint(numBuyRateQtySteps)); 23 | 24 | for (i = 0; i < uint(numBuyRateQtySteps); i++) { 25 | buyRateQtyStepsX[i] = rate.getStepFunctionData(token, 1, i); 26 | buyRateQtyStepsY[i] = rate.getStepFunctionData(token, 3, i); 27 | } 28 | 29 | numSellRateQtySteps = rate.getStepFunctionData(token, 4, 0); 30 | SellRateQtyStepsX = new int[](uint(numSellRateQtySteps)); 31 | SellRateQtyStepsY = new int[](uint(numSellRateQtySteps)); 32 | 33 | for (i = 0; i < uint(numSellRateQtySteps); i++) { 34 | SellRateQtyStepsX[i] = rate.getStepFunctionData(token, 5, i); 35 | SellRateQtyStepsY[i] = rate.getStepFunctionData(token, 7, i); 36 | } 37 | } 38 | 39 | function readImbalanceStepFunctions(ConversionRates rate, ERC20 token) public view returns( 40 | int numBuyRateImbalanceSteps, 41 | int[] buyRateImbalanceStepsX, 42 | int[] buyRateImbalanceStepsY, 43 | int numSellRateImbalanceSteps, 44 | int[] SellRateImbalanceStepsX, 45 | int[] SellRateImbalanceStepsY) 46 | { 47 | uint i; 48 | numBuyRateImbalanceSteps = rate.getStepFunctionData(token, 8, 0); 49 | buyRateImbalanceStepsX = new int[](uint(numBuyRateImbalanceSteps)); 50 | buyRateImbalanceStepsY = new int[](uint(numBuyRateImbalanceSteps)); 51 | 52 | for (i = 0; i < uint(numBuyRateImbalanceSteps); i++) { 53 | buyRateImbalanceStepsX[i] = rate.getStepFunctionData(token, 9, i); 54 | buyRateImbalanceStepsY[i] = rate.getStepFunctionData(token, 11, i); 55 | } 56 | 57 | numSellRateImbalanceSteps = rate.getStepFunctionData(token, 12, 0); 58 | SellRateImbalanceStepsX = new int[](uint(numSellRateImbalanceSteps)); 59 | SellRateImbalanceStepsY = new int[](uint(numSellRateImbalanceSteps)); 60 | 61 | for (i = 0; i < uint(numSellRateImbalanceSteps); i++) { 62 | SellRateImbalanceStepsX[i] = rate.getStepFunctionData(token, 13, i); 63 | SellRateImbalanceStepsY[i] = rate.getStepFunctionData(token, 15, i); 64 | } 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /contracts/sol4/wrappers/WrapperBase.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | import "../Withdrawable.sol"; 4 | import "../PermissionGroups.sol"; 5 | 6 | 7 | contract WrapperBase is Withdrawable { 8 | 9 | PermissionGroups public wrappedContract; 10 | 11 | function WrapperBase(PermissionGroups _wrappedContract) public { 12 | require(_wrappedContract != address(0)); 13 | wrappedContract = _wrappedContract; 14 | } 15 | 16 | function claimWrappedContractAdmin() public onlyAdmin { 17 | wrappedContract.claimAdmin(); 18 | } 19 | 20 | function transferWrappedContractAdmin (address newAdmin) public onlyAdmin { 21 | wrappedContract.transferAdmin(newAdmin); 22 | } 23 | 24 | function addAlerterWrappedContract (address _alerter) public onlyAdmin { 25 | require(_alerter != address(0)); 26 | wrappedContract.addAlerter(_alerter); 27 | } 28 | 29 | function addOperatorWrappedContract (address _operator) public onlyAdmin { 30 | require(_operator != address(0)); 31 | wrappedContract.addOperator(_operator); 32 | } 33 | 34 | function removeAlerterWrappedContract (address _alerter) public onlyAdmin { 35 | require(_alerter != address(0)); 36 | wrappedContract.removeAlerter(_alerter); 37 | } 38 | 39 | function removeOperatorWrappedContract (address _operator) public onlyAdmin { 40 | require(_operator != address(0)); 41 | wrappedContract.removeOperator(_operator); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /contracts/sol5/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | 4 | interface IERC20 { 5 | event Approval(address indexed _owner, address indexed _spender, uint256 _value); 6 | 7 | function approve(address _spender, uint256 _value) external returns (bool success); 8 | 9 | function transfer(address _to, uint256 _value) external returns (bool success); 10 | 11 | function transferFrom( 12 | address _from, 13 | address _to, 14 | uint256 _value 15 | ) external returns (bool success); 16 | 17 | function allowance(address _owner, address _spender) external view returns (uint256 remaining); 18 | 19 | function balanceOf(address _owner) external view returns (uint256 balance); 20 | 21 | function decimals() external view returns (uint256 digits); 22 | 23 | function totalSupply() external view returns (uint256 supply); 24 | } 25 | 26 | 27 | // to support backward compatible contract name -- so function signature remains same 28 | contract ERC20 is IERC20 { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /contracts/sol5/IKyberReserve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | import "./IERC20.sol"; 4 | 5 | 6 | interface IKyberReserve { 7 | function trade( 8 | IERC20 srcToken, 9 | uint256 srcAmount, 10 | IERC20 destToken, 11 | address payable destAddress, 12 | uint256 conversionRate, 13 | bool validate 14 | ) external payable returns (bool); 15 | 16 | function getConversionRate( 17 | IERC20 src, 18 | IERC20 dest, 19 | uint256 srcQty, 20 | uint256 blockNumber 21 | ) external view returns (uint256); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/sol5/bridges/bancor/mock/IBancorNetwork.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | import "../../../IERC20.sol"; 4 | 5 | contract IBancorNetwork { 6 | // to get rate, return dest amount + fee amount 7 | function getReturnByPath(IERC20[] calldata _path, uint256 _amount) external view returns (uint256, uint256); 8 | // to convert ETH to token, return dest amount 9 | function convert2( 10 | IERC20[] calldata _path, 11 | uint256 _amount, 12 | uint256 _minReturn, 13 | address _affiliateAccount, 14 | uint256 _affiliateFee 15 | ) external payable returns (uint256); 16 | 17 | // to convert token to ETH, return dest amount 18 | function claimAndConvert2( 19 | IERC20[] calldata _path, 20 | uint256 _amount, 21 | uint256 _minReturn, 22 | address _affiliateAccount, 23 | uint256 _affiliateFee 24 | ) external returns (uint256); 25 | } 26 | -------------------------------------------------------------------------------- /contracts/sol5/bridges/eth2dai/mock/IOtc.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | import "../../../IERC20.sol"; 4 | 5 | contract IOtc { 6 | function getOffer(uint id) external view returns (uint, IERC20, uint, IERC20); 7 | function getBestOffer(IERC20 sellGem, IERC20 buyGem) external view returns(uint); 8 | function getWorseOffer(uint id) external view returns(uint); 9 | function take(bytes32 id, uint128 maxTakeAmount) external; 10 | } 11 | -------------------------------------------------------------------------------- /contracts/sol5/bridges/eth2dai/mock/WethToken.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity 0.5.11; 3 | 4 | import "../../../mock/Token.sol"; 5 | 6 | contract WethToken is Token { 7 | 8 | constructor(string memory _name, string memory _symbol, uint _decimals) Token(_name, _symbol, _decimals) public {} 9 | 10 | event Deposit(address indexed dst, uint wad); 11 | 12 | function deposit() public payable { 13 | balances[msg.sender] += msg.value; 14 | emit Deposit(msg.sender, msg.value); 15 | } 16 | 17 | event Withdrawal(address indexed src, uint wad); 18 | 19 | function withdraw(uint wad) public { 20 | require(balances[msg.sender] >= wad); 21 | balances[msg.sender] -= wad; 22 | msg.sender.transfer(wad); 23 | emit Withdrawal(msg.sender, wad); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /contracts/sol5/mock/MockPermissionGroups2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | import "../utils/PermissionGroups2.sol"; 4 | 5 | 6 | contract MockPermissionGroups2 is PermissionGroups2 { 7 | uint256 public rate; 8 | bool public tradeActive = true; 9 | 10 | constructor() public PermissionGroups2(msg.sender) {} 11 | 12 | function activateTrade() public onlyOperator { 13 | tradeActive = true; 14 | } 15 | 16 | function setRate(uint256 newRate) public onlyOperator { 17 | rate = newRate; 18 | } 19 | 20 | function stopTrade() public onlyAlerter { 21 | tradeActive = false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/sol5/mock/MockUtils4.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | import "../utils/Utils4.sol"; 4 | 5 | 6 | /// @title Kyber utils contract 7 | contract MockUtils4 is Utils4 { 8 | function mockCheckGetUpdateDecimals(IERC20 token) public returns (uint256) { 9 | return getUpdateDecimals(token); 10 | } 11 | 12 | function mockSetDecimals(IERC20 token) public { 13 | return setDecimals(token); 14 | } 15 | 16 | function mockCalcDestAmount( 17 | IERC20 src, 18 | IERC20 dest, 19 | uint256 srcAmount, 20 | uint256 rate 21 | ) public view returns (uint256) { 22 | return calcDestAmount(src, dest, srcAmount, rate); 23 | } 24 | 25 | function mockCalcSrcAmount( 26 | IERC20 src, 27 | IERC20 dest, 28 | uint256 destAmount, 29 | uint256 rate 30 | ) public view returns (uint256) { 31 | return calcSrcAmount(src, dest, destAmount, rate); 32 | } 33 | 34 | function mockGetBalance(IERC20 token, address user) public view returns (uint256) { 35 | return getBalance(token, user); 36 | } 37 | 38 | function mockGetDecimals(IERC20 token) public view returns (uint256) { 39 | return getDecimals(token); 40 | } 41 | 42 | function mockGetDecimalsMap(IERC20 token) public view returns (uint256) { 43 | return decimals[address(token)]; 44 | } 45 | 46 | function mockCalcDstQty( 47 | uint256 srcQty, 48 | uint256 srcDecimals, 49 | uint256 dstDecimals, 50 | uint256 rate 51 | ) public pure returns (uint256) { 52 | return calcDstQty(srcQty, srcDecimals, dstDecimals, rate); 53 | } 54 | 55 | function mockCalcSrcQty( 56 | uint256 dstQty, 57 | uint256 srcDecimals, 58 | uint256 dstDecimals, 59 | uint256 rate 60 | ) public pure returns (uint256) { 61 | return calcSrcQty(dstQty, srcDecimals, dstDecimals, rate); 62 | } 63 | 64 | function mockCalcRateFromQty( 65 | uint256 srcAmount, 66 | uint256 destAmount, 67 | uint256 srcDecimals, 68 | uint256 dstDecimals 69 | ) public pure returns (uint256) { 70 | return calcRateFromQty(srcAmount, destAmount, srcDecimals, dstDecimals); 71 | } 72 | 73 | function mockGetEthTokenAddress() public pure returns (IERC20) { 74 | return ETH_TOKEN_ADDRESS; 75 | } 76 | 77 | function mockGetPrecision() public pure returns (uint256) { 78 | return PRECISION; 79 | } 80 | 81 | function mockGetMaxRate() public pure returns (uint256) { 82 | return MAX_RATE; 83 | } 84 | 85 | function mockGetMaxQty() public pure returns (uint256) { 86 | return MAX_QTY; 87 | } 88 | 89 | function mockGetMaxDecimals() public pure returns (uint256) { 90 | return MAX_DECIMALS; 91 | } 92 | 93 | function mockGetEthDecimals() public pure returns (uint256) { 94 | return ETH_DECIMALS; 95 | } 96 | 97 | function mockGetBPS() public pure returns (uint256) { 98 | return BPS; 99 | } 100 | 101 | function mockMinOf(uint256 x, uint256 y) public pure returns (uint256) { 102 | return minOf(x, y); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /contracts/sol5/mock/MockWithdrawable2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | import "../utils/Withdrawable2.sol"; 4 | 5 | 6 | contract MockWithdrawable2 is Withdrawable2 { 7 | constructor() public Withdrawable2(msg.sender) {} 8 | 9 | function() external payable {} 10 | } 11 | -------------------------------------------------------------------------------- /contracts/sol5/utils/Withdrawable2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.5.11; 2 | 3 | import "../IERC20.sol"; 4 | import "./PermissionGroups2.sol"; 5 | 6 | 7 | contract Withdrawable2 is PermissionGroups2 { 8 | constructor(address _admin) public PermissionGroups2(_admin) {} 9 | 10 | event TokenWithdraw(IERC20 token, uint256 amount, address sendTo); 11 | 12 | /** 13 | * @dev Withdraw all IERC20 compatible tokens 14 | * @param token IERC20 The address of the token contract 15 | */ 16 | function withdrawToken( 17 | IERC20 token, 18 | uint256 amount, 19 | address sendTo 20 | ) external onlyAdmin { 21 | token.transfer(sendTo, amount); 22 | emit TokenWithdraw(token, amount, sendTo); 23 | } 24 | 25 | event EtherWithdraw(uint256 amount, address sendTo); 26 | 27 | /** 28 | * @dev Withdraw Ethers 29 | */ 30 | function withdrawEther(uint256 amount, address payable sendTo) 31 | external 32 | onlyAdmin 33 | { 34 | (bool success, ) = sendTo.call.value(amount)(""); 35 | require(success); 36 | emit EtherWithdraw(amount, sendTo); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/DaoOperator.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | contract DaoOperator { 5 | address public daoOperator; 6 | 7 | constructor(address _daoOperator) public { 8 | require(_daoOperator != address(0), "daoOperator is 0"); 9 | daoOperator = _daoOperator; 10 | } 11 | 12 | modifier onlyDaoOperator() { 13 | require(msg.sender == daoOperator, "only daoOperator"); 14 | _; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/EpochUtils.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../utils/zeppelin/SafeMath.sol"; 4 | import "./IEpochUtils.sol"; 5 | 6 | contract EpochUtils is IEpochUtils { 7 | using SafeMath for uint256; 8 | 9 | uint256 public override epochPeriodInSeconds; 10 | uint256 public override firstEpochStartTimestamp; 11 | 12 | function getCurrentEpochNumber() public view override returns (uint256) { 13 | return getEpochNumber(now); 14 | } 15 | 16 | function getEpochNumber(uint256 timestamp) public view override returns (uint256) { 17 | if (timestamp < firstEpochStartTimestamp || epochPeriodInSeconds == 0) { 18 | return 0; 19 | } 20 | // ((timestamp - firstEpochStartTimestamp) / epochPeriodInSeconds) + 1; 21 | return ((timestamp.sub(firstEpochStartTimestamp)).div(epochPeriodInSeconds)).add(1); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/IEpochUtils.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | interface IEpochUtils { 4 | function epochPeriodInSeconds() external view returns (uint256); 5 | 6 | function firstEpochStartTimestamp() external view returns (uint256); 7 | 8 | function getCurrentEpochNumber() external view returns (uint256); 9 | 10 | function getEpochNumber(uint256 timestamp) external view returns (uint256); 11 | } 12 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/IKyberStaking.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IEpochUtils.sol"; 4 | 5 | 6 | interface IKyberStaking is IEpochUtils { 7 | event Delegated( 8 | address indexed staker, 9 | address indexed representative, 10 | uint256 indexed epoch, 11 | bool isDelegated 12 | ); 13 | event Deposited(uint256 curEpoch, address indexed staker, uint256 amount); 14 | event Withdraw(uint256 indexed curEpoch, address indexed staker, uint256 amount); 15 | 16 | function initAndReturnStakerDataForCurrentEpoch(address staker) 17 | external 18 | returns ( 19 | uint256 stake, 20 | uint256 delegatedStake, 21 | address representative 22 | ); 23 | 24 | function deposit(uint256 amount) external; 25 | 26 | function delegate(address dAddr) external; 27 | 28 | function withdraw(uint256 amount) external; 29 | 30 | /** 31 | * @notice return combine data (stake, delegatedStake, representative) of a staker 32 | * @dev allow to get staker data up to current epoch + 1 33 | */ 34 | function getStakerData(address staker, uint256 epoch) 35 | external 36 | view 37 | returns ( 38 | uint256 stake, 39 | uint256 delegatedStake, 40 | address representative 41 | ); 42 | 43 | function getLatestStakerData(address staker) 44 | external 45 | view 46 | returns ( 47 | uint256 stake, 48 | uint256 delegatedStake, 49 | address representative 50 | ); 51 | 52 | /** 53 | * @notice return raw data of a staker for an epoch 54 | * WARN: should be used only for initialized data 55 | * if data has not been initialized, it will return all 0 56 | * pool master shouldn't use this function to compute/distribute rewards of pool members 57 | */ 58 | function getStakerRawData(address staker, uint256 epoch) 59 | external 60 | view 61 | returns ( 62 | uint256 stake, 63 | uint256 delegatedStake, 64 | address representative 65 | ); 66 | } 67 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/ISanityRate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | /// @title Sanity Rate check to prevent burning knc with too expensive or cheap price 5 | /// @dev Using ChainLink as the provider for current knc/eth price 6 | interface ISanityRate { 7 | // return latest rate of knc/eth 8 | function latestAnswer() external view returns (uint256); 9 | } 10 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MaliciousFeeHandler.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberFeeHandler.sol"; 4 | 5 | 6 | contract MaliciousFeeHandler is KyberFeeHandler { 7 | constructor( 8 | address daoSetter, 9 | IKyberProxy _kyberNetworkProxy, 10 | address _kyberNetwork, 11 | IERC20 _knc, 12 | uint256 _burnBlockInterval, 13 | address _daoOperator 14 | ) 15 | public 16 | KyberFeeHandler( 17 | daoSetter, 18 | _kyberNetworkProxy, 19 | _kyberNetwork, 20 | _knc, 21 | _burnBlockInterval, 22 | _daoOperator 23 | ) 24 | {} 25 | 26 | function setTotalPayoutBalance(uint256 _amount) external { 27 | totalPayoutBalance = _amount; 28 | } 29 | 30 | function withdrawEther(uint256 amount, address payable sendTo) external { 31 | sendTo.transfer(amount); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockChainLinkSanityRate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../ISanityRate.sol"; 4 | 5 | 6 | contract MockChainLinkSanityRate is ISanityRate { 7 | uint256 latestAnswerValue; 8 | 9 | function setLatestKncToEthRate(uint256 _kncEthRate) external { 10 | latestAnswerValue = _kncEthRate; 11 | } 12 | 13 | function latestAnswer() external view override returns (uint256) { 14 | return latestAnswerValue; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockContractCallBurnKNC.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberFeeHandler.sol"; 4 | 5 | 6 | contract MockContractCallBurnKnc { 7 | KyberFeeHandler public feeHandler; 8 | 9 | constructor(KyberFeeHandler _feeHandler) public { 10 | feeHandler = _feeHandler; 11 | } 12 | 13 | function callBurnKnc() public { 14 | feeHandler.burnKnc(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockEmergencyFeeHandler.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../emergency/EmergencyFeeHandler.sol"; 4 | 5 | contract MockEmergencyFeeHandler is EmergencyKyberFeeHandler { 6 | constructor( 7 | address admin, 8 | address _kyberNetwork, 9 | uint256 _rewardBps, 10 | uint256 _rebateBps, 11 | uint256 _burnBps 12 | ) public EmergencyKyberFeeHandler(admin, _kyberNetwork, _rewardBps, _rebateBps, _burnBps) {} 13 | 14 | function calculateAndRecordFeeData( 15 | address, 16 | uint256, 17 | address[] calldata, 18 | uint256[] calldata, 19 | uint256 20 | ) external override { 21 | revert(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockKyberDaoMoreGetters.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberDao.sol"; 4 | 5 | 6 | contract MockKyberDaoMoreGetters is KyberDao { 7 | constructor( 8 | uint256 _epochPeriod, 9 | uint256 _startTimestamp, 10 | IERC20 _knc, 11 | uint256 _minCampDuration, 12 | uint256 _defaultNetworkFeeBps, 13 | uint256 _defaultRewardBps, 14 | uint256 _defaultRebateBps, 15 | address _admin 16 | ) 17 | public 18 | KyberDao( 19 | _epochPeriod, 20 | _startTimestamp, 21 | _knc, 22 | _defaultNetworkFeeBps, 23 | _defaultRewardBps, 24 | _defaultRebateBps, 25 | _admin 26 | ) 27 | { 28 | minCampaignDurationInSeconds = _minCampDuration; 29 | } 30 | 31 | function setLatestNetworkFee(uint256 _fee) public { 32 | latestNetworkFeeResult = _fee; 33 | } 34 | 35 | function setLatestBrrData(uint256 reward, uint256 rebate) public { 36 | latestBrrData.rewardInBps = reward; 37 | latestBrrData.rebateInBps = rebate; 38 | } 39 | 40 | function latestBrrResult() public view returns (uint256) { 41 | return 42 | getDataFromRewardAndRebateWithValidation( 43 | latestBrrData.rewardInBps, 44 | latestBrrData.rebateInBps 45 | ); 46 | } 47 | 48 | function getNumberVotes(address staker, uint256 epoch) public view returns (uint256) { 49 | return numberVotes[staker][epoch]; 50 | } 51 | 52 | function campaignExists(uint256 campaignID) public view returns (bool) { 53 | return campaignData[campaignID].campaignExists; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockKyberDaoTestHandleWithdrawal.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../EpochUtils.sol"; 4 | 5 | 6 | contract MockKyberDaoTestHandleWithdrawal is EpochUtils { 7 | mapping(address => uint256) public values; 8 | 9 | constructor(uint256 _epochPeriod, uint256 _startTimestamp) public { 10 | epochPeriodInSeconds = _epochPeriod; 11 | firstEpochStartTimestamp = _startTimestamp; 12 | } 13 | 14 | function handleWithdrawal(address staker, uint256 amount) public { 15 | // to test if staking has called this func or not when withdrawing 16 | values[staker] += amount; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockKyberDaoWithdrawFailed.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../EpochUtils.sol"; 4 | 5 | 6 | contract MockKyberDaoWithdrawFailed is EpochUtils { 7 | uint256 public value; 8 | 9 | constructor(uint256 _epochPeriod, uint256 _startTimestamp) public { 10 | epochPeriodInSeconds = _epochPeriod; 11 | firstEpochStartTimestamp = _startTimestamp; 12 | } 13 | 14 | function handleWithdrawal(address, uint256) public { 15 | value++; 16 | revert(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockKyberStaking.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberStaking.sol"; 4 | 5 | 6 | contract MockKyberStaking is KyberStaking { 7 | constructor( 8 | IERC20 _kncToken, 9 | uint256 _epochPeriod, 10 | uint256 _startBlock, 11 | IKyberDao _admin 12 | ) public KyberStaking(_kncToken, _epochPeriod, _startBlock, _admin) {} 13 | 14 | function getHasInitedValue(address staker, uint256 epoch) public view returns (bool) { 15 | return hasInited[epoch][staker]; 16 | } 17 | 18 | function getStakesValue(address staker, uint256 epoch) public view returns (uint256) { 19 | return stakerPerEpochData[epoch][staker].stake; 20 | } 21 | 22 | function getDelegatedStakesValue(address staker, uint256 epoch) public view returns (uint256) { 23 | return stakerPerEpochData[epoch][staker].delegatedStake; 24 | } 25 | 26 | function getRepresentativeValue(address staker, uint256 epoch) 27 | public 28 | view 29 | returns (address) 30 | { 31 | return stakerPerEpochData[epoch][staker].representative; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockKyberStakingMalicious.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberStaking.sol"; 4 | 5 | 6 | contract MockKyberStakingMalicious is KyberStaking { 7 | constructor( 8 | IERC20 _kncToken, 9 | uint256 _epochPeriod, 10 | uint256 _startBlock, 11 | IKyberDao _admin 12 | ) public KyberStaking(_kncToken, _epochPeriod, _startBlock, _admin) {} 13 | 14 | function setLatestStake(address staker, uint256 amount) public { 15 | stakerLatestData[staker].stake = amount; 16 | } 17 | 18 | function setLatestDelegatedStake(address staker, uint256 amount) public { 19 | stakerLatestData[staker].delegatedStake = amount; 20 | } 21 | 22 | function setEpochStake( 23 | address staker, 24 | uint256 epoch, 25 | uint256 amount 26 | ) public { 27 | stakerPerEpochData[epoch][staker].stake = amount; 28 | } 29 | 30 | function setEpochDelegatedStake( 31 | address staker, 32 | uint256 epoch, 33 | uint256 amount 34 | ) public { 35 | stakerPerEpochData[epoch][staker].delegatedStake = amount; 36 | } 37 | 38 | function getHasInitedValue(address staker, uint256 epoch) public view returns (bool) { 39 | return hasInited[epoch][staker]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockMaliciousKyberDao.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberDao.sol"; 4 | 5 | 6 | contract MockMaliciousKyberDao is KyberDao { 7 | constructor( 8 | uint256 _epochPeriod, 9 | uint256 _startTimestamp, 10 | IERC20 _knc, 11 | uint256 _minCampDuration, 12 | uint256 _defaultNetworkFeeBps, 13 | uint256 _defaultRewardBps, 14 | uint256 _defaultRebateBps, 15 | address _admin 16 | ) 17 | public 18 | KyberDao( 19 | _epochPeriod, 20 | _startTimestamp, 21 | _knc, 22 | _defaultNetworkFeeBps, 23 | _defaultRewardBps, 24 | _defaultRebateBps, 25 | _admin 26 | ) 27 | { 28 | minCampaignDurationInSeconds = _minCampDuration; 29 | } 30 | 31 | function setTotalEpochPoints(uint256 epoch, uint256 pts) public { 32 | totalEpochPoints[epoch] = pts; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockMaliciousKyberDaoReentrancy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../EpochUtils.sol"; 4 | import "../KyberStaking.sol"; 5 | 6 | 7 | /// @notice Mock Malicious KyberDao tries to re-enter withdraw function in Staking 8 | contract MockMaliciousKyberDaoReentrancy is EpochUtils { 9 | KyberStaking public staking; 10 | IERC20 public knc; 11 | 12 | uint256 totalDeposit = 0; 13 | 14 | constructor( 15 | uint256 _epochPeriod, 16 | uint256 _startTimestamp, 17 | KyberStaking _staking, 18 | IERC20 _knc 19 | ) public { 20 | epochPeriodInSeconds = _epochPeriod; 21 | firstEpochStartTimestamp = _startTimestamp; 22 | staking = _staking; 23 | knc = _knc; 24 | require(_knc.approve(address(_staking), 2**255)); 25 | } 26 | 27 | function deposit(uint256 amount) public { 28 | staking.deposit(amount); 29 | totalDeposit += amount; 30 | } 31 | 32 | function withdraw(uint256 amount) public { 33 | totalDeposit -= amount; 34 | staking.withdraw(amount); 35 | } 36 | 37 | function handleWithdrawal(address, uint256) public { 38 | if (totalDeposit > 0) { 39 | // reentrant one 40 | uint256 amount = totalDeposit; 41 | totalDeposit = 0; 42 | staking.withdraw(amount); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /contracts/sol6/Dao/mock/MockStakerClaimRewardReentrancy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../../IKyberFeeHandler.sol"; 4 | 5 | 6 | contract MockStakerClaimRewardReentrancy { 7 | IKyberFeeHandler public feeHandler; 8 | bool public isTestingReentrant = true; 9 | 10 | constructor( 11 | IKyberFeeHandler _feeHandler 12 | ) 13 | public 14 | { 15 | feeHandler = _feeHandler; 16 | } 17 | 18 | receive() external payable { 19 | if (isTestingReentrant) { 20 | feeHandler.claimStakerReward(address(this), 0); 21 | } 22 | } 23 | 24 | function setIsTestingReentrancy(bool isTesting) external { 25 | isTestingReentrant = isTesting; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/sol6/IBurnableToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | interface IBurnableToken { 5 | function burn(uint256 _value) external returns (bool); 6 | } 7 | -------------------------------------------------------------------------------- /contracts/sol6/IERC20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | interface IERC20 { 5 | event Approval(address indexed _owner, address indexed _spender, uint256 _value); 6 | 7 | function approve(address _spender, uint256 _value) external returns (bool success); 8 | 9 | function transfer(address _to, uint256 _value) external returns (bool success); 10 | 11 | function transferFrom( 12 | address _from, 13 | address _to, 14 | uint256 _value 15 | ) external returns (bool success); 16 | 17 | function allowance(address _owner, address _spender) external view returns (uint256 remaining); 18 | 19 | function balanceOf(address _owner) external view returns (uint256 balance); 20 | 21 | function decimals() external view returns (uint8 digits); 22 | 23 | function totalSupply() external view returns (uint256 supply); 24 | } 25 | 26 | 27 | // to support backward compatible contract name -- so function signature remains same 28 | abstract contract ERC20 is IERC20 { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /contracts/sol6/IGasHelper.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IERC20.sol"; 4 | 5 | 6 | interface IGasHelper { 7 | function freeGas( 8 | address platformWallet, 9 | IERC20 src, 10 | IERC20 dest, 11 | uint256 tradeWei, 12 | bytes32[] calldata t2eReserveIds, 13 | bytes32[] calldata e2tReserveIds 14 | ) external; 15 | } 16 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberDao.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./Dao/IEpochUtils.sol"; 4 | 5 | 6 | interface IKyberDao is IEpochUtils { 7 | event Voted(address indexed staker, uint indexed epoch, uint indexed campaignID, uint option); 8 | 9 | function getLatestNetworkFeeDataWithCache() 10 | external 11 | returns (uint256 feeInBps, uint256 expiryTimestamp); 12 | 13 | function getLatestBRRDataWithCache() 14 | external 15 | returns ( 16 | uint256 burnInBps, 17 | uint256 rewardInBps, 18 | uint256 rebateInBps, 19 | uint256 epoch, 20 | uint256 expiryTimestamp 21 | ); 22 | 23 | function handleWithdrawal(address staker, uint256 penaltyAmount) external; 24 | 25 | function vote(uint256 campaignID, uint256 option) external; 26 | 27 | function getLatestNetworkFeeData() 28 | external 29 | view 30 | returns (uint256 feeInBps, uint256 expiryTimestamp); 31 | 32 | function shouldBurnRewardForEpoch(uint256 epoch) external view returns (bool); 33 | 34 | /** 35 | * @dev return staker's reward percentage in precision for a past epoch only 36 | * fee handler should call this function when a staker wants to claim reward 37 | * return 0 if staker has no votes or stakes 38 | */ 39 | function getPastEpochRewardPercentageInPrecision(address staker, uint256 epoch) 40 | external 41 | view 42 | returns (uint256); 43 | 44 | /** 45 | * @dev return staker's reward percentage in precision for the current epoch 46 | * reward percentage is not finalized until the current epoch is ended 47 | */ 48 | function getCurrentEpochRewardPercentageInPrecision(address staker) 49 | external 50 | view 51 | returns (uint256); 52 | } 53 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberFeeHandler.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IERC20.sol"; 4 | 5 | 6 | interface IKyberFeeHandler { 7 | event RewardPaid(address indexed staker, uint256 indexed epoch, IERC20 indexed token, uint256 amount); 8 | event RebatePaid(address indexed rebateWallet, IERC20 indexed token, uint256 amount); 9 | event PlatformFeePaid(address indexed platformWallet, IERC20 indexed token, uint256 amount); 10 | event KncBurned(uint256 kncTWei, IERC20 indexed token, uint256 amount); 11 | 12 | function handleFees( 13 | IERC20 token, 14 | address[] calldata eligibleWallets, 15 | uint256[] calldata rebatePercentages, 16 | address platformWallet, 17 | uint256 platformFee, 18 | uint256 networkFee 19 | ) external payable; 20 | 21 | function claimReserveRebate(address rebateWallet) external returns (uint256); 22 | 23 | function claimPlatformFee(address platformWallet) external returns (uint256); 24 | 25 | function claimStakerReward( 26 | address staker, 27 | uint256 epoch 28 | ) external returns(uint amount); 29 | } 30 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberHint.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IKyberReserve.sol"; 4 | 5 | 6 | interface IKyberHint { 7 | enum TradeType {BestOfAll, MaskIn, MaskOut, Split} 8 | enum HintErrors { 9 | NoError, // Hint is valid 10 | NonEmptyDataError, // reserveIDs and splits must be empty for BestOfAll hint 11 | ReserveIdDupError, // duplicate reserveID found 12 | ReserveIdEmptyError, // reserveIDs array is empty for MaskIn and Split trade type 13 | ReserveIdSplitsError, // reserveIDs and splitBpsValues arrays do not have the same length 14 | ReserveIdSequenceError, // reserveID sequence in array is not in increasing order 15 | ReserveIdNotFound, // reserveID isn't registered or doesn't exist 16 | SplitsNotEmptyError, // splitBpsValues is not empty for MaskIn or MaskOut trade type 17 | TokenListedError, // reserveID not listed for the token 18 | TotalBPSError // total BPS for Split trade type is not 10000 (100%) 19 | } 20 | 21 | function buildTokenToEthHint( 22 | IERC20 tokenSrc, 23 | TradeType tokenToEthType, 24 | bytes32[] calldata tokenToEthReserveIds, 25 | uint256[] calldata tokenToEthSplits 26 | ) external view returns (bytes memory hint); 27 | 28 | function buildEthToTokenHint( 29 | IERC20 tokenDest, 30 | TradeType ethToTokenType, 31 | bytes32[] calldata ethToTokenReserveIds, 32 | uint256[] calldata ethToTokenSplits 33 | ) external view returns (bytes memory hint); 34 | 35 | function buildTokenToTokenHint( 36 | IERC20 tokenSrc, 37 | TradeType tokenToEthType, 38 | bytes32[] calldata tokenToEthReserveIds, 39 | uint256[] calldata tokenToEthSplits, 40 | IERC20 tokenDest, 41 | TradeType ethToTokenType, 42 | bytes32[] calldata ethToTokenReserveIds, 43 | uint256[] calldata ethToTokenSplits 44 | ) external view returns (bytes memory hint); 45 | 46 | function parseTokenToEthHint(IERC20 tokenSrc, bytes calldata hint) 47 | external 48 | view 49 | returns ( 50 | TradeType tokenToEthType, 51 | bytes32[] memory tokenToEthReserveIds, 52 | IKyberReserve[] memory tokenToEthAddresses, 53 | uint256[] memory tokenToEthSplits 54 | ); 55 | 56 | function parseEthToTokenHint(IERC20 tokenDest, bytes calldata hint) 57 | external 58 | view 59 | returns ( 60 | TradeType ethToTokenType, 61 | bytes32[] memory ethToTokenReserveIds, 62 | IKyberReserve[] memory ethToTokenAddresses, 63 | uint256[] memory ethToTokenSplits 64 | ); 65 | 66 | function parseTokenToTokenHint(IERC20 tokenSrc, IERC20 tokenDest, bytes calldata hint) 67 | external 68 | view 69 | returns ( 70 | TradeType tokenToEthType, 71 | bytes32[] memory tokenToEthReserveIds, 72 | IKyberReserve[] memory tokenToEthAddresses, 73 | uint256[] memory tokenToEthSplits, 74 | TradeType ethToTokenType, 75 | bytes32[] memory ethToTokenReserveIds, 76 | IKyberReserve[] memory ethToTokenAddresses, 77 | uint256[] memory ethToTokenSplits 78 | ); 79 | } 80 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberHistory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | interface IKyberHistory { 5 | function saveContract(address _contract) external; 6 | function getContracts() external view returns (address[] memory); 7 | } 8 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberMatchingEngine.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IKyberReserve.sol"; 4 | import "./IKyberNetwork.sol"; 5 | import "./IKyberStorage.sol"; 6 | 7 | 8 | interface IKyberMatchingEngine { 9 | enum ProcessWithRate {NotRequired, Required} 10 | 11 | function setNegligibleRateDiffBps(uint256 _negligibleRateDiffBps) external; 12 | 13 | function setKyberStorage(IKyberStorage _kyberStorage) external; 14 | 15 | function getNegligibleRateDiffBps() external view returns (uint256); 16 | 17 | function getTradingReserves( 18 | IERC20 src, 19 | IERC20 dest, 20 | bool isTokenToToken, 21 | bytes calldata hint 22 | ) 23 | external 24 | view 25 | returns ( 26 | bytes32[] memory reserveIds, 27 | uint256[] memory splitValuesBps, 28 | ProcessWithRate processWithRate 29 | ); 30 | 31 | function doMatch( 32 | IERC20 src, 33 | IERC20 dest, 34 | uint256[] calldata srcAmounts, 35 | uint256[] calldata feesAccountedDestBps, 36 | uint256[] calldata rates 37 | ) external view returns (uint256[] memory reserveIndexes); 38 | } 39 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberNetwork.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IERC20.sol"; 4 | 5 | 6 | interface IKyberNetwork { 7 | event KyberTrade( 8 | IERC20 indexed src, 9 | IERC20 indexed dest, 10 | uint256 ethWeiValue, 11 | uint256 networkFeeWei, 12 | uint256 customPlatformFeeWei, 13 | bytes32[] t2eIds, 14 | bytes32[] e2tIds, 15 | uint256[] t2eSrcAmounts, 16 | uint256[] e2tSrcAmounts, 17 | uint256[] t2eRates, 18 | uint256[] e2tRates 19 | ); 20 | 21 | function tradeWithHintAndFee( 22 | address payable trader, 23 | IERC20 src, 24 | uint256 srcAmount, 25 | IERC20 dest, 26 | address payable destAddress, 27 | uint256 maxDestAmount, 28 | uint256 minConversionRate, 29 | address payable platformWallet, 30 | uint256 platformFeeBps, 31 | bytes calldata hint 32 | ) external payable returns (uint256 destAmount); 33 | 34 | function listTokenForReserve( 35 | address reserve, 36 | IERC20 token, 37 | bool add 38 | ) external; 39 | 40 | function enabled() external view returns (bool); 41 | 42 | function getExpectedRateWithHintAndFee( 43 | IERC20 src, 44 | IERC20 dest, 45 | uint256 srcQty, 46 | uint256 platformFeeBps, 47 | bytes calldata hint 48 | ) 49 | external 50 | view 51 | returns ( 52 | uint256 expectedRateAfterNetworkFee, 53 | uint256 expectedRateAfterAllFees 54 | ); 55 | 56 | function getNetworkData() 57 | external 58 | view 59 | returns ( 60 | uint256 negligibleDiffBps, 61 | uint256 networkFeeBps, 62 | uint256 expiryTimestamp 63 | ); 64 | 65 | function maxGasPrice() external view returns (uint256); 66 | } 67 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberNetworkProxy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IERC20.sol"; 4 | 5 | 6 | interface IKyberNetworkProxy { 7 | 8 | event ExecuteTrade( 9 | address indexed trader, 10 | IERC20 src, 11 | IERC20 dest, 12 | address destAddress, 13 | uint256 actualSrcAmount, 14 | uint256 actualDestAmount, 15 | address platformWallet, 16 | uint256 platformFeeBps 17 | ); 18 | 19 | /// @notice backward compatible 20 | function tradeWithHint( 21 | ERC20 src, 22 | uint256 srcAmount, 23 | ERC20 dest, 24 | address payable destAddress, 25 | uint256 maxDestAmount, 26 | uint256 minConversionRate, 27 | address payable walletId, 28 | bytes calldata hint 29 | ) external payable returns (uint256); 30 | 31 | function tradeWithHintAndFee( 32 | IERC20 src, 33 | uint256 srcAmount, 34 | IERC20 dest, 35 | address payable destAddress, 36 | uint256 maxDestAmount, 37 | uint256 minConversionRate, 38 | address payable platformWallet, 39 | uint256 platformFeeBps, 40 | bytes calldata hint 41 | ) external payable returns (uint256 destAmount); 42 | 43 | function trade( 44 | IERC20 src, 45 | uint256 srcAmount, 46 | IERC20 dest, 47 | address payable destAddress, 48 | uint256 maxDestAmount, 49 | uint256 minConversionRate, 50 | address payable platformWallet 51 | ) external payable returns (uint256); 52 | 53 | /// @notice backward compatible 54 | /// @notice Rate units (10 ** 18) => destQty (twei) / srcQty (twei) * 10 ** 18 55 | function getExpectedRate( 56 | ERC20 src, 57 | ERC20 dest, 58 | uint256 srcQty 59 | ) external view returns (uint256 expectedRate, uint256 worstRate); 60 | 61 | function getExpectedRateAfterFee( 62 | IERC20 src, 63 | IERC20 dest, 64 | uint256 srcQty, 65 | uint256 platformFeeBps, 66 | bytes calldata hint 67 | ) external view returns (uint256 expectedRate); 68 | } 69 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberReserve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IERC20.sol"; 4 | 5 | 6 | interface IKyberReserve { 7 | function trade( 8 | IERC20 srcToken, 9 | uint256 srcAmount, 10 | IERC20 destToken, 11 | address payable destAddress, 12 | uint256 conversionRate, 13 | bool validate 14 | ) external payable returns (bool); 15 | 16 | function getConversionRate( 17 | IERC20 src, 18 | IERC20 dest, 19 | uint256 srcQty, 20 | uint256 blockNumber 21 | ) external view returns (uint256); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/sol6/IKyberSanity.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IERC20.sol"; 4 | 5 | interface IKyberSanity { 6 | function getSanityRate(IERC20 src, IERC20 dest) external view returns (uint256); 7 | } 8 | -------------------------------------------------------------------------------- /contracts/sol6/ISimpleKyberProxy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IERC20.sol"; 4 | 5 | 6 | /* 7 | * @title simple Kyber Network proxy interface 8 | * add convenient functions to help with kyber proxy API 9 | */ 10 | interface ISimpleKyberProxy { 11 | function swapTokenToEther( 12 | IERC20 token, 13 | uint256 srcAmount, 14 | uint256 minConversionRate 15 | ) external returns (uint256 destAmount); 16 | 17 | function swapEtherToToken(IERC20 token, uint256 minConversionRate) 18 | external 19 | payable 20 | returns (uint256 destAmount); 21 | 22 | function swapTokenToToken( 23 | IERC20 src, 24 | uint256 srcAmount, 25 | IERC20 dest, 26 | uint256 minConversionRate 27 | ) external returns (uint256 destAmount); 28 | } 29 | -------------------------------------------------------------------------------- /contracts/sol6/KyberHistory.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./IKyberHistory.sol"; 4 | import "./utils/PermissionGroupsNoModifiers.sol"; 5 | 6 | 7 | /** 8 | * @title kyberHistory contract 9 | * The contract provides the following functions for kyberStorage contract: 10 | * - Record contract changes for a set of contracts 11 | */ 12 | contract KyberHistory is IKyberHistory, PermissionGroupsNoModifiers { 13 | address public kyberStorage; 14 | address[] internal contractsHistory; 15 | 16 | constructor(address _admin) public PermissionGroupsNoModifiers(_admin) {} 17 | 18 | event KyberStorageUpdated(address newStorage); 19 | 20 | modifier onlyStorage() { 21 | require(msg.sender == kyberStorage, "only storage"); 22 | _; 23 | } 24 | 25 | function setStorageContract(address _kyberStorage) external { 26 | onlyAdmin(); 27 | require(_kyberStorage != address(0), "storage 0"); 28 | emit KyberStorageUpdated(_kyberStorage); 29 | kyberStorage = _kyberStorage; 30 | } 31 | 32 | function saveContract(address _contract) external override onlyStorage { 33 | if (contractsHistory.length > 0) { 34 | // if same address, don't do anything 35 | if (contractsHistory[0] == _contract) return; 36 | // otherwise, update history 37 | contractsHistory.push(contractsHistory[0]); 38 | contractsHistory[0] = _contract; 39 | } else { 40 | contractsHistory.push(_contract); 41 | } 42 | } 43 | 44 | /// @notice Should be called off chain 45 | /// @dev Index 0 is currently used contract address, indexes > 0 are older versions 46 | function getContracts() external override view returns (address[] memory) { 47 | return contractsHistory; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /contracts/sol6/bridgeReserve/uniswap/mock/MockUniswapRouter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "@uniswap/v2-periphery/contracts/UniswapV2Router02.sol"; 4 | import "@uniswap/v2-periphery/contracts/libraries/UniswapV2Library.sol"; 5 | 6 | contract MockUniswapRouter is UniswapV2Router02 { 7 | constructor(address _factory, address _weth) public UniswapV2Router02(_factory, _weth) {} 8 | 9 | uint256 public dstQty; 10 | 11 | function setDstQty(uint256 _dstQty) external { 12 | dstQty = _dstQty; 13 | } 14 | 15 | function swapExactETHForTokens( 16 | uint256 amountOutMin, 17 | address[] calldata path, 18 | address to, 19 | uint256 deadline 20 | ) external virtual override payable ensure(deadline) returns (uint256[] memory amounts) { 21 | require(path[0] == WETH, "UniswapV2Router: INVALID_PATH"); 22 | amounts = UniswapV2Library.getAmountsOut(factory, msg.value, path); 23 | require( 24 | amounts[amounts.length - 1] >= amountOutMin, 25 | "UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT" 26 | ); 27 | IWETH(WETH).deposit{value: amounts[0]}(); 28 | assert( 29 | IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]) 30 | ); 31 | _swap(amounts, path, to); 32 | amounts[amounts.length - 1] = dstQty; 33 | } 34 | 35 | function swapExactTokensForETH( 36 | uint256 amountIn, 37 | uint256 amountOutMin, 38 | address[] calldata path, 39 | address to, 40 | uint256 deadline 41 | ) external virtual override ensure(deadline) returns (uint256[] memory amounts) { 42 | require(path[path.length - 1] == WETH, "UniswapV2Router: INVALID_PATH"); 43 | amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); 44 | require( 45 | amounts[amounts.length - 1] >= amountOutMin, 46 | "UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT" 47 | ); 48 | TransferHelper.safeTransferFrom( 49 | path[0], 50 | msg.sender, 51 | UniswapV2Library.pairFor(factory, path[0], path[1]), 52 | amounts[0] 53 | ); 54 | _swap(amounts, path, address(this)); 55 | IWETH(WETH).withdraw(amounts[amounts.length - 1]); 56 | TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); 57 | amounts[amounts.length - 1] = dstQty; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /contracts/sol6/mock/GasHelper.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IGasHelper.sol"; 4 | import "../utils/WithdrawableNoModifiers.sol"; 5 | 6 | 7 | interface IGST2 { 8 | function freeUpTo(uint256 value) external returns (uint256 freed); 9 | 10 | function freeFromUpTo(address from, uint256 value) external returns (uint256 freed); 11 | 12 | function balanceOf(address who) external view returns (uint256); 13 | } 14 | 15 | 16 | contract GasHelper is IGasHelper, WithdrawableNoModifiers { 17 | address kyberNetwork; 18 | 19 | IGST2 constant GST2 = IGST2(0x0000000000b3F879cb30FE243b4Dfee438691c04); 20 | uint256 constant MIN_ACTIVATE_PRICE = 8 * 1000 * 1000 * 1000; // 8 gwei 21 | 22 | constructor(address _kyberNetwork, address _admin) public WithdrawableNoModifiers(_admin) { 23 | require(_kyberNetwork != address(0)); 24 | kyberNetwork = _kyberNetwork; 25 | } 26 | 27 | function freeGas( 28 | address platformWallet, 29 | IERC20 src, 30 | IERC20 dest, 31 | uint256 tradeWei, 32 | bytes32[] calldata t2eReserveIds, 33 | bytes32[] calldata e2tReserveIds 34 | ) external override { 35 | require(msg.sender == kyberNetwork); 36 | if (tx.gasprice <= MIN_ACTIVATE_PRICE) return; 37 | 38 | platformWallet; 39 | src; 40 | dest; 41 | tradeWei; 42 | t2eReserveIds; 43 | e2tReserveIds; 44 | 45 | freeGas(gasleft() / 2); 46 | } 47 | 48 | function freeGas(uint256 num_tokens) internal returns (uint256 freed) { 49 | uint256 safe_num_tokens = 0; 50 | uint256 gas = gasleft(); 51 | 52 | if (gas >= 27710) { 53 | safe_num_tokens = (gas - 27710) / (1148 + 5722 + 150); 54 | } 55 | 56 | if (num_tokens > safe_num_tokens) { 57 | num_tokens = safe_num_tokens; 58 | } 59 | 60 | if (num_tokens > 0) { 61 | return GST2.freeUpTo(num_tokens); 62 | } else { 63 | return 0; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /contracts/sol6/mock/KyberNetworkNoMaxDest.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberNetwork.sol"; 4 | 5 | 6 | /* 7 | * @title Kyber Network main contract that doesn't check max dest amount. so we can test it on proxy 8 | */ 9 | contract KyberNetworkNoMaxDest is KyberNetwork { 10 | constructor(address _admin, IKyberStorage _kyberStorage) 11 | public 12 | KyberNetwork(_admin, _kyberStorage) 13 | {} 14 | 15 | function calcTradeSrcAmountFromDest(TradeData memory tData) 16 | internal 17 | pure 18 | override 19 | returns (uint256 actualSrcAmount) 20 | { 21 | actualSrcAmount = tData.input.srcAmount; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MaliciousKyberDao.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./MockKyberDao.sol"; 4 | 5 | 6 | contract MaliciousKyberDao is MockKyberDao { 7 | uint256 public burnInBPS; 8 | 9 | constructor( 10 | uint256 _rewardInBPS, 11 | uint256 _rebateInBPS, 12 | uint256 _epoch, 13 | uint256 _expiryTimestamp 14 | ) public MockKyberDao(_rewardInBPS, _rebateInBPS, _epoch, _expiryTimestamp) {} 15 | 16 | function getLatestBRRDataWithCache() 17 | external 18 | override 19 | returns ( 20 | uint256, 21 | uint256, 22 | uint256, 23 | uint256, 24 | uint256 25 | ) 26 | { 27 | return (burnInBPS, rewardInBPS, rebateInBPS, epoch, expiryTimestamp); 28 | } 29 | 30 | function setMockBRR( 31 | uint256 _burnInBPS, 32 | uint256 _rewardInBPS, 33 | uint256 _rebateInBPS 34 | ) public { 35 | rewardInBPS = _rewardInBPS; 36 | rebateInBPS = _rebateInBPS; 37 | burnInBPS = _burnInBPS; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MaliciousKyberNetwork2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberNetwork.sol"; 4 | 5 | 6 | /* 7 | * @title Kyber Network main contract, takes some fee but returns actual dest amount 8 | * as if fee wasn't taken. 9 | */ 10 | contract MaliciousKyberNetwork2 is KyberNetwork { 11 | uint256 public myFeeWei = 10; 12 | 13 | constructor(address _admin, IKyberStorage _kyberStorage) 14 | public 15 | KyberNetwork(_admin, _kyberStorage) 16 | {} 17 | 18 | // overwrite function to reduce bytecode size 19 | function removeKyberProxy(address kyberProxy) external virtual override {} 20 | 21 | function setMyFeeWei(uint256 fee) public { 22 | myFeeWei = fee; 23 | } 24 | 25 | function doReserveTrades( 26 | IERC20 src, 27 | IERC20 dest, 28 | address payable destAddress, 29 | ReservesData memory reservesData, 30 | uint256 expectedDestAmount, 31 | uint256 srcDecimals, 32 | uint256 destDecimals 33 | ) internal override { 34 | if (src == dest) { 35 | //E2E, need not do anything except for T2E, transfer ETH to destAddress 36 | if (destAddress != (address(this))) { 37 | (bool success, ) = destAddress.call{value: expectedDestAmount - myFeeWei}(""); 38 | require(success, "send dest qty failed"); 39 | } 40 | return; 41 | } 42 | 43 | tradeAndVerifyNetworkBalance( 44 | reservesData, 45 | src, 46 | dest, 47 | srcDecimals, 48 | destDecimals 49 | ); 50 | 51 | if (destAddress != address(this)) { 52 | // for eth -> token / token -> token, transfer tokens to destAddress 53 | dest.safeTransfer(destAddress, expectedDestAmount - myFeeWei); 54 | } 55 | 56 | return; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MaliciousMatchingEngine.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberMatchingEngine.sol"; 4 | import "../utils/Utils5.sol"; 5 | 6 | contract MaliciousMatchingEngine is Utils5 { 7 | IKyberStorage public kyberStorage; 8 | uint256 splitLength; 9 | bool badValues; 10 | 11 | function setKyberStorage(IKyberStorage _kyberStorage) external { 12 | kyberStorage = _kyberStorage; 13 | } 14 | 15 | function setSplitLength(uint length) external { 16 | splitLength = length; 17 | } 18 | 19 | function setBadValues(bool shouldSetBadValues) external { 20 | badValues = shouldSetBadValues; 21 | } 22 | 23 | function getTradingReserves( 24 | IERC20 src, 25 | IERC20 dest, 26 | bool isTokenToToken, 27 | bytes calldata hint 28 | ) 29 | external 30 | view 31 | returns ( 32 | bytes32[] memory reserveIds, 33 | uint256[] memory splitValuesBps, 34 | IKyberMatchingEngine.ProcessWithRate processWithRate 35 | ) 36 | { 37 | isTokenToToken; 38 | hint; 39 | reserveIds = (dest == ETH_TOKEN_ADDRESS) 40 | ? kyberStorage.getReserveIdsPerTokenSrc(src) 41 | : kyberStorage.getReserveIdsPerTokenDest(dest); 42 | 43 | splitValuesBps = populateSplitValuesBps(); 44 | processWithRate = IKyberMatchingEngine.ProcessWithRate.Required; 45 | } 46 | 47 | function doMatch( 48 | IERC20 src, 49 | IERC20 dest, 50 | uint256[] calldata srcAmounts, 51 | uint256[] calldata feesAccountedDestBps, // 0 for no fee, networkFeeBps when has fee 52 | uint256[] calldata rates 53 | ) external view returns (uint256[] memory reserveIndexes) { 54 | src; 55 | dest; 56 | srcAmounts; 57 | feesAccountedDestBps; 58 | rates; 59 | reserveIndexes = new uint256[](splitLength + 1); 60 | } 61 | 62 | function populateSplitValuesBps() 63 | internal 64 | view 65 | returns (uint256[] memory splitValuesBps) 66 | { 67 | splitValuesBps = new uint256[](splitLength); 68 | for (uint256 i = 0; i < splitLength; i++) { 69 | if (!badValues) { 70 | splitValuesBps[i] = BPS; 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MaliciousReserve2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "./MockReserve.sol"; 4 | 5 | 6 | contract MaliciousReserve2 is MockReserve { 7 | // extraSrcAmount > 0: take more src amount from network 8 | // extraSrcAmount < 0: take less src amount from network 9 | int256 public extraSrcAmount; 10 | // extraDestAmount > 0: send more dest amount to network 11 | // extraDestAmount < 0: send less dest amount to network 12 | int256 public extraDestAmount; 13 | 14 | function setExtraSrcAndDestAmounts(int256 _extraSrcAmount, int256 _extraDestAmount) public { 15 | extraSrcAmount = _extraSrcAmount; 16 | extraDestAmount = _extraDestAmount; 17 | } 18 | 19 | function trade( 20 | IERC20 srcToken, 21 | uint256 srcAmount, 22 | IERC20 destToken, 23 | address payable destAddress, 24 | uint256 conversionRate, 25 | bool validate 26 | ) public payable override returns (bool) { 27 | validate; 28 | if (srcToken == ETH_TOKEN_ADDRESS) { 29 | require(msg.value == srcAmount, "ETH sent != srcAmount"); 30 | } else { 31 | require(msg.value == 0, "ETH was sent for token -> ETH trade"); 32 | } 33 | 34 | uint256 srcDecimals = getDecimals(srcToken); 35 | uint256 destDecimals = getDecimals(destToken); 36 | uint256 destAmount = calcDstQty(srcAmount, srcDecimals, destDecimals, conversionRate); 37 | 38 | // collect src tokens 39 | if (srcToken != ETH_TOKEN_ADDRESS) { 40 | srcToken.safeTransferFrom(msg.sender, address(this), uint256(int256(srcAmount) + extraSrcAmount)); 41 | } 42 | 43 | // send dest tokens 44 | uint256 actualDestAmount = uint256(int256(destAmount) + extraDestAmount); 45 | if (destToken == ETH_TOKEN_ADDRESS) { 46 | destAddress.transfer(actualDestAmount); 47 | } else { 48 | destToken.safeTransfer(destAddress, actualDestAmount); 49 | } 50 | 51 | return true; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MaliciousStorage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberReserve.sol"; 4 | import "../IKyberFeeHandler.sol"; 5 | 6 | // does not do anything, only return true 7 | contract MaliciousStorage { 8 | uint public feeArrayLength; 9 | uint public entitledRebateLength; 10 | uint public reserveAddressesLength; 11 | 12 | constructor() public {} 13 | 14 | function setArrayLengths(uint _fee, uint _rebate, uint _addresses) external { 15 | feeArrayLength = _fee; 16 | entitledRebateLength = _rebate; 17 | reserveAddressesLength = _addresses; 18 | } 19 | 20 | function setContracts(IKyberFeeHandler _feeHandler, address _matchingEngine) 21 | external 22 | pure 23 | { 24 | _feeHandler; 25 | _matchingEngine; 26 | } 27 | 28 | function addKyberProxy(address networkProxy, uint256 max_approved_proxies) 29 | external 30 | pure 31 | { 32 | networkProxy; 33 | max_approved_proxies; 34 | } 35 | 36 | function removeKyberProxy(address networkProxy) external pure { 37 | networkProxy; 38 | } 39 | 40 | function getReservesData(bytes32[] calldata reserveIds, IERC20 , IERC20 ) 41 | external 42 | view 43 | returns ( 44 | bool isValid, 45 | bool[] memory feeAccountedArr, 46 | bool[] memory entitledRebateArr, 47 | IKyberReserve[] memory reserveAddresses 48 | ) 49 | { 50 | isValid = true; 51 | reserveIds; 52 | feeAccountedArr = new bool[](feeArrayLength); 53 | entitledRebateArr = new bool[](entitledRebateLength); 54 | reserveAddresses = new IKyberReserve[](reserveAddressesLength); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockConversionRates.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IERC20.sol"; 4 | 5 | 6 | contract MockConversionRates { 7 | 8 | mapping (address => uint256) public buyRates; 9 | mapping (address => uint256) public sellRates; 10 | mapping (address => uint256) public imbalances; 11 | address public reserve; 12 | 13 | function setBaseRates(IERC20 token, uint256 buyRate, uint256 sellRate) external { 14 | buyRates[address(token)] = buyRate; 15 | sellRates[address(token)] = sellRate; 16 | } 17 | 18 | function recordImbalance( 19 | IERC20 token, 20 | int buyAmount, 21 | uint256 rateUpdateBlock, 22 | uint256 currentBlock 23 | ) external {} 24 | 25 | function setReserveAddress(address _reserve) external { 26 | reserve = _reserve; 27 | } 28 | 29 | function getRate( 30 | IERC20 token, 31 | uint256 currentBlockNumber, 32 | bool buy, 33 | uint256 qty 34 | ) external view returns(uint256) { 35 | currentBlockNumber; 36 | qty; 37 | if (buy) { 38 | return buyRates[address(token)]; 39 | } 40 | return sellRates[address(token)]; 41 | } 42 | 43 | function getInitImbalance(IERC20 token) external view returns(uint256) { 44 | return imbalances[address(token)]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockGasHelper.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IERC20.sol"; 4 | import "../IGasHelper.sol"; 5 | 6 | 7 | contract MockGasHelper is IGasHelper { 8 | address internal _platformWallet; 9 | 10 | constructor(address wallet) public { 11 | _platformWallet = wallet; 12 | } 13 | 14 | function freeGas( 15 | address platformWallet, 16 | IERC20 src, 17 | IERC20 dest, 18 | uint256 tradeWei, 19 | bytes32[] calldata t2eReserveIds, 20 | bytes32[] calldata e2tReserveIds 21 | ) external override { 22 | require(platformWallet == _platformWallet); 23 | src; 24 | dest; 25 | tradeWei; 26 | t2eReserveIds; 27 | e2tReserveIds; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockHintHandler.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberHintHandler.sol"; 4 | 5 | 6 | contract MockHintHandler is KyberHintHandler { 7 | mapping(bytes32 => address[]) public reserveIdToAddresses; 8 | mapping(IERC20 => mapping(bytes32 => bool)) internal isListedReserveWithTokenSrc; 9 | mapping(IERC20 => mapping(bytes32 => bool)) internal isListedReserveWithTokenDest; 10 | 11 | function callHintError(HintErrors error) external pure { 12 | return throwHintError(error); 13 | } 14 | 15 | function addReserve(address reserve, bytes32 reserveId) public { 16 | reserveIdToAddresses[reserveId].push(reserve); 17 | } 18 | 19 | function listPairForReserve(bytes32 reserveId, IERC20 token) public { 20 | mapping(bytes32 => bool) storage isListedSrc = isListedReserveWithTokenSrc[token]; 21 | mapping(bytes32 => bool) storage isListedDest = isListedReserveWithTokenDest[token]; 22 | 23 | isListedSrc[reserveId] = true; 24 | isListedDest[reserveId] = true; 25 | } 26 | 27 | function getReserveAddress(bytes32 reserveId) internal view override returns (address reserveAddress) { 28 | address[] memory reserveAddresses = reserveIdToAddresses[reserveId]; 29 | 30 | if (reserveAddresses.length != 0) { 31 | reserveAddress = reserveIdToAddresses[reserveId][0]; 32 | } 33 | } 34 | 35 | function areAllReservesListed( 36 | bytes32[] memory reserveIds, 37 | IERC20 src, 38 | IERC20 dest 39 | ) internal override view returns (bool) { 40 | bool result = true; 41 | 42 | mapping(bytes32 => bool) storage isListedReserveWithToken = (dest == ETH_TOKEN_ADDRESS) 43 | ? isListedReserveWithTokenSrc[src] 44 | : isListedReserveWithTokenDest[dest]; 45 | 46 | for (uint256 i = 0; i < reserveIds.length; i++) { 47 | if (!isListedReserveWithToken[reserveIds[i]]){ 48 | result = false; 49 | break; 50 | } 51 | } 52 | 53 | return result; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockMatchingEngine.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberMatchingEngine.sol"; 4 | 5 | 6 | /** 7 | * @dev MockMatchEngine is a mock for testing overflow 8 | */ 9 | 10 | contract MockMatchEngine is KyberMatchingEngine { 11 | constructor(address _admin) public KyberMatchingEngine(_admin) {} 12 | 13 | function reserveIdToAddress(bytes32 reserveId) public view returns (address) { 14 | return getReserveAddress(reserveId); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockNetwork.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberNetwork.sol"; 4 | 5 | 6 | // override some of original KyberNetwork contract 7 | contract MockNetwork is KyberNetwork { 8 | constructor(address _admin, IKyberStorage _kyberStorage) 9 | public 10 | KyberNetwork(_admin, _kyberStorage) 11 | {} 12 | 13 | // allow set zero contract 14 | function setContracts( 15 | IKyberFeeHandler _kyberFeeHandler, 16 | IKyberMatchingEngine _kyberMatchingEngine, 17 | IGasHelper _gasHelper 18 | ) external override { 19 | if (kyberFeeHandler != _kyberFeeHandler) { 20 | kyberFeeHandler = _kyberFeeHandler; 21 | emit KyberFeeHandlerUpdated(_kyberFeeHandler); 22 | } 23 | 24 | if (kyberMatchingEngine != _kyberMatchingEngine) { 25 | kyberMatchingEngine = _kyberMatchingEngine; 26 | emit KyberMatchingEngineUpdated(_kyberMatchingEngine); 27 | } 28 | 29 | if ((_gasHelper != IGasHelper(0)) && (_gasHelper != gasHelper)) { 30 | gasHelper = _gasHelper; 31 | emit GasHelperUpdated(_gasHelper); 32 | } 33 | } 34 | 35 | function mockHandleChange( 36 | IERC20 src, 37 | uint256 srcAmount, 38 | uint256 requiredSrcAmount, 39 | address payable trader 40 | ) public { 41 | return handleChange(src, srcAmount, requiredSrcAmount, trader); 42 | } 43 | 44 | function setNetworkFeeData(uint256 _networkFeeBps, uint256 _expiryTimestamp) public { 45 | updateNetworkFee(_expiryTimestamp, _networkFeeBps); 46 | } 47 | 48 | function getNetworkFeeData() 49 | public 50 | view 51 | returns (uint256 _networkFeeBps, uint256 _expiryTimestamp) 52 | { 53 | (_networkFeeBps, _expiryTimestamp) = readNetworkFeeData(); 54 | } 55 | 56 | function mockGetNetworkFee() public view returns (uint256 networkFeeBps) { 57 | return getNetworkFee(); 58 | } 59 | 60 | //over ride some functions to reduce contract size. 61 | function doReserveTrades( 62 | IERC20 src, 63 | IERC20 dest, 64 | address payable destAddress, 65 | ReservesData memory reservesData, 66 | uint256 expectedDestAmount, 67 | uint256 srcDecimals, 68 | uint256 destDecimals 69 | ) internal override { 70 | src; 71 | dest; 72 | destAddress; 73 | reservesData; 74 | expectedDestAmount; 75 | srcDecimals; 76 | destDecimals; 77 | 78 | revert("must use real network"); 79 | // return true; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockNotPayableContract.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | contract MockNotPayableContract { 5 | constructor() public {} 6 | } 7 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockPermissionGroups3.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../utils/PermissionGroups3.sol"; 4 | 5 | 6 | contract MockPermissionGroups3 is PermissionGroups3 { 7 | uint256 public rate; 8 | bool public tradeActive = true; 9 | 10 | constructor() public PermissionGroups3(msg.sender) {} 11 | 12 | function activateTrade() public onlyOperator { 13 | tradeActive = true; 14 | } 15 | 16 | function setRate(uint256 newRate) public onlyOperator { 17 | rate = newRate; 18 | } 19 | 20 | function stopTrade() public onlyAlerter { 21 | tradeActive = false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockPermissionGroupsNoModifiers.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../utils/PermissionGroupsNoModifiers.sol"; 4 | 5 | 6 | contract MockPermissionGroupsNoModifiers is PermissionGroupsNoModifiers { 7 | uint256 public rate; 8 | bool public tradeActive = true; 9 | 10 | constructor() public PermissionGroupsNoModifiers(msg.sender) {} 11 | 12 | function activateTrade() public { 13 | onlyOperator(); 14 | tradeActive = true; 15 | } 16 | 17 | function setRate(uint256 newRate) public { 18 | onlyOperator(); 19 | rate = newRate; 20 | } 21 | 22 | function stopTrade() public { 23 | onlyAlerter(); 24 | tradeActive = false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockSanityRates.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberSanity.sol"; 4 | 5 | 6 | contract MockSanityRates is IKyberSanity { 7 | uint256 public sanityRateValue; 8 | 9 | function setSanityRateValue(uint256 _value) external { 10 | sanityRateValue = _value; 11 | } 12 | 13 | function getSanityRate(IERC20 src, IERC20 dest) external override view returns (uint256 rate) { 14 | src; 15 | dest; 16 | rate = sanityRateValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockStorage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../KyberStorage.sol"; 4 | 5 | 6 | contract MockStorage is KyberStorage { 7 | constructor( 8 | address _admin, 9 | IKyberHistory _networkHistory, 10 | IKyberHistory _feeHandlerHistory, 11 | IKyberHistory _kyberDaoHistory, 12 | IKyberHistory _matchingEngineHistory 13 | ) 14 | public 15 | KyberStorage( 16 | _admin, 17 | _networkHistory, 18 | _feeHandlerHistory, 19 | _kyberDaoHistory, 20 | _matchingEngineHistory 21 | ) 22 | {} 23 | 24 | function setReserveId(address reserve, bytes32 reserveId) public { 25 | reserveAddressToId[reserve] = reserveId; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockTrader.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberNetworkProxy.sol"; 4 | 5 | 6 | contract MockTrader { 7 | IERC20 internal constant ETH_TOKEN_ADDRESS = IERC20( 8 | 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE 9 | ); 10 | IKyberNetworkProxy public kyberNetworkProxy; 11 | 12 | constructor(IKyberNetworkProxy _kyberNetworkProxy) public { 13 | kyberNetworkProxy = _kyberNetworkProxy; 14 | } 15 | 16 | function tradeWithHintAndFee( 17 | IERC20 src, 18 | uint256 srcAmount, 19 | IERC20 dest, 20 | address payable destAddress, 21 | address payable platformWallet, 22 | uint256 platformFeeBps, 23 | bytes calldata hint 24 | ) external payable returns (uint256 destAmount) { 25 | if (src != ETH_TOKEN_ADDRESS) { 26 | require(src.transferFrom(msg.sender, address(this), srcAmount)); 27 | require(src.approve(address(kyberNetworkProxy), srcAmount)); 28 | } 29 | 30 | uint256 rate = kyberNetworkProxy.getExpectedRateAfterFee( 31 | src, 32 | dest, 33 | srcAmount, 34 | platformFeeBps, 35 | hint 36 | ); 37 | 38 | return 39 | kyberNetworkProxy.tradeWithHintAndFee{value: msg.value}( 40 | src, 41 | srcAmount, 42 | dest, 43 | destAddress, 44 | 2**255, 45 | rate, 46 | platformWallet, 47 | platformFeeBps, 48 | hint 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockUtils5.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../utils/Utils5.sol"; 4 | 5 | 6 | /// @title Kyber utils contract 7 | contract MockUtils5 is Utils5 { 8 | function mockCheckGetUpdateDecimals(IERC20 token) public returns (uint256) { 9 | return getUpdateDecimals(token); 10 | } 11 | 12 | function mockSetDecimals(IERC20 token) public { 13 | return setDecimals(token); 14 | } 15 | 16 | function mockCalcDestAmount( 17 | IERC20 src, 18 | IERC20 dest, 19 | uint256 srcAmount, 20 | uint256 rate 21 | ) public view returns (uint256) { 22 | return calcDestAmount(src, dest, srcAmount, rate); 23 | } 24 | 25 | function mockCalcSrcAmount( 26 | IERC20 src, 27 | IERC20 dest, 28 | uint256 destAmount, 29 | uint256 rate 30 | ) public view returns (uint256) { 31 | return calcSrcAmount(src, dest, destAmount, rate); 32 | } 33 | 34 | function mockGetBalance(IERC20 token, address user) public view returns (uint256) { 35 | return getBalance(token, user); 36 | } 37 | 38 | function mockGetDecimals(IERC20 token) public view returns (uint256) { 39 | return getDecimals(token); 40 | } 41 | 42 | function mockGetDecimalsMap(IERC20 token) public view returns (uint256) { 43 | return decimals[token]; 44 | } 45 | 46 | function mockCalcDstQty( 47 | uint256 srcQty, 48 | uint256 srcDecimals, 49 | uint256 dstDecimals, 50 | uint256 rate 51 | ) public pure returns (uint256) { 52 | return calcDstQty(srcQty, srcDecimals, dstDecimals, rate); 53 | } 54 | 55 | function mockCalcSrcQty( 56 | uint256 dstQty, 57 | uint256 srcDecimals, 58 | uint256 dstDecimals, 59 | uint256 rate 60 | ) public pure returns (uint256) { 61 | return calcSrcQty(dstQty, srcDecimals, dstDecimals, rate); 62 | } 63 | 64 | function mockCalcRateFromQty( 65 | uint256 srcAmount, 66 | uint256 destAmount, 67 | uint256 srcDecimals, 68 | uint256 dstDecimals 69 | ) public pure returns (uint256) { 70 | return calcRateFromQty(srcAmount, destAmount, srcDecimals, dstDecimals); 71 | } 72 | 73 | function mockGetEthTokenAddress() public pure returns (IERC20) { 74 | return ETH_TOKEN_ADDRESS; 75 | } 76 | 77 | function mockGetPrecision() public pure returns (uint256) { 78 | return PRECISION; 79 | } 80 | 81 | function mockGetMaxRate() public pure returns (uint256) { 82 | return MAX_RATE; 83 | } 84 | 85 | function mockGetMaxQty() public pure returns (uint256) { 86 | return MAX_QTY; 87 | } 88 | 89 | function mockGetMaxDecimals() public pure returns (uint256) { 90 | return MAX_DECIMALS; 91 | } 92 | 93 | function mockGetEthDecimals() public pure returns (uint256) { 94 | return ETH_DECIMALS; 95 | } 96 | 97 | function mockGetBPS() public pure returns (uint256) { 98 | return BPS; 99 | } 100 | 101 | function mockMinOf(uint256 x, uint256 y) public pure returns (uint256) { 102 | return minOf(x, y); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockWithdrawable3.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../utils/Withdrawable3.sol"; 4 | 5 | 6 | contract MockWithdrawable3 is Withdrawable3 { 7 | constructor() public Withdrawable3(msg.sender) {} 8 | 9 | receive() external payable {} 10 | } 11 | -------------------------------------------------------------------------------- /contracts/sol6/mock/MockWithdrawableNoModifiers.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../utils/WithdrawableNoModifiers.sol"; 4 | 5 | 6 | contract MockWithdrawableNoModifiers is WithdrawableNoModifiers { 7 | constructor() public WithdrawableNoModifiers(msg.sender) {} 8 | 9 | receive() external payable {} 10 | } 11 | -------------------------------------------------------------------------------- /contracts/sol6/mock/NoPayableFallback.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | contract NoPayableFallback {} 5 | -------------------------------------------------------------------------------- /contracts/sol6/mock/ReentrancyAttack.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | contract ReentrancyAttack { 5 | function callSender(bytes4 data) public { 6 | (bool success, ) = msg.sender.call(abi.encodeWithSelector(data)); 7 | require(success, "ReentrancyAttack: failed call"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /contracts/sol6/mock/ReentrancyFeeClaimer.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberNetworkProxy.sol"; 4 | import "../utils/Utils5.sol"; 5 | import "../IKyberFeeHandler.sol"; 6 | 7 | /// @dev contract to call trade when claimPlatformFee 8 | contract ReentrancyFeeClaimer is Utils5 { 9 | IKyberNetworkProxy kyberProxy; 10 | IKyberFeeHandler feeHandler; 11 | IERC20 token; 12 | uint256 amount; 13 | 14 | bool isReentrancy = true; 15 | 16 | constructor( 17 | IKyberNetworkProxy _kyberProxy, 18 | IKyberFeeHandler _feeHandler, 19 | IERC20 _token, 20 | uint256 _amount 21 | ) public { 22 | kyberProxy = _kyberProxy; 23 | feeHandler = _feeHandler; 24 | token = _token; 25 | amount = _amount; 26 | require(_token.approve(address(_kyberProxy), _amount)); 27 | } 28 | 29 | function setReentrancy(bool _isReentrancy) external { 30 | isReentrancy = _isReentrancy; 31 | } 32 | 33 | receive() external payable { 34 | if (!isReentrancy) { 35 | return; 36 | } 37 | 38 | bytes memory hint; 39 | kyberProxy.tradeWithHintAndFee( 40 | token, 41 | amount, 42 | ETH_TOKEN_ADDRESS, 43 | msg.sender, 44 | MAX_QTY, 45 | 0, 46 | address(this), 47 | 100, 48 | hint 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /contracts/sol6/mock/ReentrancyMock.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../utils/zeppelin/ReentrancyGuard.sol"; 4 | import "./ReentrancyAttack.sol"; 5 | 6 | 7 | contract ReentrancyMock is ReentrancyGuard { 8 | uint256 public counter; 9 | 10 | constructor() public { 11 | counter = 0; 12 | } 13 | 14 | function callback() external nonReentrant { 15 | count(); 16 | } 17 | 18 | function countLocalRecursive(uint256 n) public nonReentrant { 19 | if (n > 0) { 20 | count(); 21 | countLocalRecursive(n - 1); 22 | } 23 | } 24 | 25 | function countThisRecursive(uint256 n) public nonReentrant { 26 | if (n > 0) { 27 | count(); 28 | (bool success, ) = address(this).call( 29 | abi.encodeWithSignature("countThisRecursive(uint256)", n - 1) 30 | ); 31 | require(success, "ReentrancyMock: failed call"); 32 | } 33 | } 34 | 35 | function countAndCall(ReentrancyAttack attacker) public nonReentrant { 36 | count(); 37 | bytes4 func = bytes4(keccak256("callback()")); 38 | attacker.callSender(func); 39 | } 40 | 41 | function count() private { 42 | counter += 1; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/sol6/mock/ReentrantReserve.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberReserve.sol"; 4 | import "../utils/Utils5.sol"; 5 | import "../utils/zeppelin/SafeERC20.sol"; 6 | import "../IKyberNetwork.sol"; 7 | 8 | 9 | contract ReentrantReserve is IKyberReserve, Utils5 { 10 | using SafeERC20 for IERC20; 11 | 12 | mapping(address => uint256) public buyTokenRates; 13 | IKyberNetwork network; 14 | address payable scammer; 15 | IERC20 public scamToken; 16 | 17 | uint256 public numRecursive = 1; 18 | 19 | receive() external payable {} 20 | 21 | function trade( 22 | IERC20 srcToken, 23 | uint256 srcAmount, 24 | IERC20 destToken, 25 | address payable destAddress, 26 | uint256 conversionRate, 27 | bool validate 28 | ) public payable override returns (bool) { 29 | require(srcToken == ETH_TOKEN_ADDRESS, "not buy token"); 30 | 31 | if (numRecursive > 0) { 32 | --numRecursive; 33 | 34 | doTrade(); 35 | } 36 | 37 | validate; 38 | require(msg.value == srcAmount, "ETH sent != srcAmount"); 39 | 40 | uint256 srcDecimals = getDecimals(srcToken); 41 | uint256 destDecimals = getDecimals(destToken); 42 | uint256 destAmount = calcDstQty(srcAmount, srcDecimals, destDecimals, conversionRate); 43 | 44 | // send dest tokens 45 | destToken.safeTransfer(destAddress, destAmount); 46 | 47 | return true; 48 | } 49 | 50 | function doTrade() public { 51 | uint256 callValue = 960; 52 | 53 | network.tradeWithHintAndFee{value: callValue}( 54 | address(this), 55 | ETH_TOKEN_ADDRESS, 56 | callValue, 57 | scamToken, 58 | scammer, 59 | (2**255), 60 | 0, 61 | address(0), 62 | 0, 63 | "0x" 64 | ); 65 | } 66 | 67 | function setDestAddress(address payable _scammer) public { 68 | scammer = _scammer; 69 | } 70 | 71 | function setDestToken(ERC20 _token) public { 72 | scamToken = _token; 73 | } 74 | 75 | function setNetwork(IKyberNetwork _network) public { 76 | network = _network; 77 | } 78 | 79 | function setNumRecursive(uint256 num) public { 80 | numRecursive = num; 81 | } 82 | 83 | function setRate(IERC20 token, uint256 buyRate) public { 84 | buyTokenRates[address(token)] = buyRate; 85 | } 86 | 87 | function getConversionRate( 88 | IERC20 src, 89 | IERC20 dest, 90 | uint256 srcQty, 91 | uint256 blockNumber 92 | ) public view override returns (uint256) { 93 | blockNumber; 94 | srcQty; 95 | 96 | if (src == ETH_TOKEN_ADDRESS) { 97 | return buyTokenRates[address(dest)]; 98 | } 99 | return 0; 100 | } 101 | 102 | function getTokenDecimals(IERC20 token) public view returns (uint256) { 103 | return getDecimals(token); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /contracts/sol6/mock/ReserveNoReturnVal.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberReserve.sol"; 4 | import "../utils/Utils5.sol"; 5 | import "../utils/zeppelin/SafeERC20.sol"; 6 | import "../IKyberNetwork.sol"; 7 | 8 | 9 | contract ReserveNoReturnVal is IKyberReserve, Utils5 { 10 | using SafeERC20 for IERC20; 11 | 12 | mapping(address => uint256) public buyTokenRates; 13 | 14 | uint256 public numRecursive = 1; 15 | 16 | receive() external payable {} 17 | 18 | function trade( 19 | IERC20 srcToken, 20 | uint256 srcAmount, 21 | IERC20 destToken, 22 | address payable destAddress, 23 | uint256 conversionRate, 24 | bool validate 25 | ) public payable override returns (bool) { 26 | require(srcToken == ETH_TOKEN_ADDRESS, "not buy token"); 27 | 28 | validate; 29 | require(msg.value == srcAmount, "ETH sent != srcAmount"); 30 | 31 | uint256 srcDecimals = getDecimals(srcToken); 32 | uint256 destDecimals = getDecimals(destToken); 33 | uint256 destAmount = calcDstQty(srcAmount, srcDecimals, destDecimals, conversionRate); 34 | 35 | // send dest tokens 36 | destToken.safeTransfer(destAddress, destAmount); 37 | } 38 | 39 | function setRate(IERC20 token, uint256 buyRate) public { 40 | buyTokenRates[address(token)] = buyRate; 41 | } 42 | 43 | function getConversionRate( 44 | IERC20 src, 45 | IERC20 dest, 46 | uint256 srcQty, 47 | uint256 blockNumber 48 | ) public view override returns (uint256) { 49 | blockNumber; 50 | srcQty; 51 | 52 | if (src == ETH_TOKEN_ADDRESS) { 53 | return buyTokenRates[address(dest)]; 54 | } 55 | return 0; 56 | } 57 | 58 | function getTokenDecimals(IERC20 token) public view returns (uint256) { 59 | return getDecimals(token); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /contracts/sol6/mock/ReserveReturnFalse.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberReserve.sol"; 4 | import "../utils/Utils5.sol"; 5 | import "../utils/zeppelin/SafeERC20.sol"; 6 | import "../IKyberNetwork.sol"; 7 | 8 | 9 | contract ReserveReturnFalse is IKyberReserve, Utils5 { 10 | using SafeERC20 for IERC20; 11 | 12 | mapping(address => uint256) public buyTokenRates; 13 | 14 | uint256 public numRecursive = 1; 15 | 16 | receive() external payable {} 17 | 18 | function trade( 19 | IERC20 srcToken, 20 | uint256 srcAmount, 21 | IERC20 destToken, 22 | address payable destAddress, 23 | uint256 conversionRate, 24 | bool validate 25 | ) public payable override returns (bool) { 26 | require(srcToken == ETH_TOKEN_ADDRESS, "not buy token"); 27 | 28 | validate; 29 | require(msg.value == srcAmount, "ETH sent != srcAmount"); 30 | 31 | uint256 srcDecimals = getDecimals(srcToken); 32 | uint256 destDecimals = getDecimals(destToken); 33 | uint256 destAmount = calcDstQty(srcAmount, srcDecimals, destDecimals, conversionRate); 34 | 35 | // send dest tokens 36 | destToken.safeTransfer(destAddress, destAmount); 37 | return false; 38 | } 39 | 40 | function setRate(IERC20 token, uint256 buyRate) public { 41 | buyTokenRates[address(token)] = buyRate; 42 | } 43 | 44 | function getConversionRate( 45 | IERC20 src, 46 | IERC20 dest, 47 | uint256 srcQty, 48 | uint256 blockNumber 49 | ) public view override returns (uint256) { 50 | blockNumber; 51 | srcQty; 52 | 53 | if (src == ETH_TOKEN_ADDRESS) { 54 | return buyTokenRates[address(dest)]; 55 | } 56 | return 0; 57 | } 58 | 59 | function getTokenDecimals(IERC20 token) public view returns (uint256) { 60 | return getDecimals(token); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /contracts/sol6/reserves/IConversionRates.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | 4 | import "../IERC20.sol"; 5 | 6 | 7 | interface IConversionRates { 8 | 9 | function recordImbalance( 10 | IERC20 token, 11 | int buyAmount, 12 | uint256 rateUpdateBlock, 13 | uint256 currentBlock 14 | ) external; 15 | 16 | function getRate( 17 | IERC20 token, 18 | uint256 currentBlockNumber, 19 | bool buy, 20 | uint256 qty 21 | ) external view returns(uint256); 22 | } 23 | -------------------------------------------------------------------------------- /contracts/sol6/reserves/IWeth.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IERC20.sol"; 4 | 5 | 6 | interface IWeth is IERC20 { 7 | function deposit() external payable; 8 | function withdraw(uint256 wad) external; 9 | } 10 | -------------------------------------------------------------------------------- /contracts/sol6/utils/Withdrawable3.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IERC20.sol"; 4 | import "./PermissionGroups3.sol"; 5 | 6 | contract Withdrawable3 is PermissionGroups3 { 7 | constructor(address _admin) public PermissionGroups3(_admin) {} 8 | 9 | event TokenWithdraw(IERC20 token, uint256 amount, address sendTo); 10 | 11 | event EtherWithdraw(uint256 amount, address sendTo); 12 | 13 | /** 14 | * @dev Withdraw all IERC20 compatible tokens 15 | * @param token IERC20 The address of the token contract 16 | */ 17 | function withdrawToken( 18 | IERC20 token, 19 | uint256 amount, 20 | address sendTo 21 | ) external onlyAdmin { 22 | token.transfer(sendTo, amount); 23 | emit TokenWithdraw(token, amount, sendTo); 24 | } 25 | 26 | /** 27 | * @dev Withdraw Ethers 28 | */ 29 | function withdrawEther(uint256 amount, address payable sendTo) external onlyAdmin { 30 | (bool success, ) = sendTo.call{value: amount}(""); 31 | require(success); 32 | emit EtherWithdraw(amount, sendTo); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /contracts/sol6/utils/WithdrawableNoModifiers.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IERC20.sol"; 4 | import "./PermissionGroupsNoModifiers.sol"; 5 | 6 | 7 | contract WithdrawableNoModifiers is PermissionGroupsNoModifiers { 8 | constructor(address _admin) public PermissionGroupsNoModifiers(_admin) {} 9 | 10 | event EtherWithdraw(uint256 amount, address sendTo); 11 | event TokenWithdraw(IERC20 token, uint256 amount, address sendTo); 12 | 13 | /// @dev Withdraw Ethers 14 | function withdrawEther(uint256 amount, address payable sendTo) external { 15 | onlyAdmin(); 16 | (bool success, ) = sendTo.call{value: amount}(""); 17 | require(success); 18 | emit EtherWithdraw(amount, sendTo); 19 | } 20 | 21 | /// @dev Withdraw all IERC20 compatible tokens 22 | /// @param token IERC20 The address of the token contract 23 | function withdrawToken( 24 | IERC20 token, 25 | uint256 amount, 26 | address sendTo 27 | ) external { 28 | onlyAdmin(); 29 | token.transfer(sendTo, amount); 30 | emit TokenWithdraw(token, amount, sendTo); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contracts/sol6/utils/zeppelin/Address.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | /** 4 | * @dev Collection of functions related to the address type 5 | */ 6 | library Address { 7 | /** 8 | * @dev Returns true if `account` is a contract. 9 | * 10 | * [IMPORTANT] 11 | * ==== 12 | * It is unsafe to assume that an address for which this function returns 13 | * false is an externally-owned account (EOA) and not a contract. 14 | * 15 | * Among others, `isContract` will return false for the following 16 | * types of addresses: 17 | * 18 | * - an externally-owned account 19 | * - a contract in construction 20 | * - an address where a contract will be created 21 | * - an address where a contract lived, but was destroyed 22 | * ==== 23 | */ 24 | function isContract(address account) internal view returns (bool) { 25 | // According to EIP-1052, 0x0 is the value returned for not-yet created accounts 26 | // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned 27 | // for accounts without code, i.e. `keccak256('')` 28 | bytes32 codehash; 29 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 30 | // solhint-disable-next-line no-inline-assembly 31 | assembly { codehash := extcodehash(account) } 32 | return (codehash != accountHash && codehash != 0x0); 33 | } 34 | 35 | /** 36 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 37 | * `recipient`, forwarding all available gas and reverting on errors. 38 | * 39 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 40 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 41 | * imposed by `transfer`, making them unable to receive funds via 42 | * `transfer`. {sendValue} removes this limitation. 43 | * 44 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 45 | * 46 | * IMPORTANT: because control is transferred to `recipient`, care must be 47 | * taken to not create reentrancy vulnerabilities. Consider using 48 | * {ReentrancyGuard} or the 49 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 50 | */ 51 | function sendValue(address payable recipient, uint256 amount) internal { 52 | require(address(this).balance >= amount, "Address: insufficient balance"); 53 | 54 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 55 | (bool success, ) = recipient.call{ value: amount }(""); 56 | require(success, "Address: unable to send value, recipient may have reverted"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /contracts/sol6/utils/zeppelin/ReentrancyGuard.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | /** 4 | * @dev Contract module that helps prevent reentrant calls to a function. 5 | * 6 | * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 7 | * available, which can be applied to functions to make sure there are no nested 8 | * (reentrant) calls to them. 9 | * 10 | * Note that because there is a single `nonReentrant` guard, functions marked as 11 | * `nonReentrant` may not call one another. This can be worked around by making 12 | * those functions `private`, and then adding `external` `nonReentrant` entry 13 | * points to them. 14 | * 15 | * TIP: If you would like to learn more about reentrancy and alternative ways 16 | * to protect against it, check out our blog post 17 | * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. 18 | */ 19 | contract ReentrancyGuard { 20 | bool private _notEntered; 21 | 22 | constructor () internal { 23 | // Storing an initial non-zero value makes deployment a bit more 24 | // expensive, but in exchange the refund on every call to nonReentrant 25 | // will be lower in amount. Since refunds are capped to a percetange of 26 | // the total transaction's gas, it is best to keep them low in cases 27 | // like this one, to increase the likelihood of the full refund coming 28 | // into effect. 29 | _notEntered = true; 30 | } 31 | 32 | /** 33 | * @dev Prevents a contract from calling itself, directly or indirectly. 34 | * Calling a `nonReentrant` function from another `nonReentrant` 35 | * function is not supported. It is possible to prevent this from happening 36 | * by making the `nonReentrant` function external, and make it call a 37 | * `private` function that does the actual work. 38 | */ 39 | modifier nonReentrant() { 40 | // On the first call to nonReentrant, _notEntered will be true 41 | require(_notEntered, "ReentrancyGuard: reentrant call"); 42 | 43 | // Any calls to nonReentrant after this point will fail 44 | _notEntered = false; 45 | 46 | _; 47 | 48 | // By storing the original value once again, a refund is triggered (see 49 | // https://eips.ethereum.org/EIPS/eip-2200) 50 | _notEntered = true; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /contracts/sol6/wrappers/IKyberRateHelper.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.6.6; 2 | 3 | import "../IKyberReserve.sol"; 4 | 5 | 6 | interface IKyberRateHelper { 7 | function getRatesForToken( 8 | IERC20 token, 9 | uint256 optionalBuyAmountWei, 10 | uint256 optionalSellAmountTwei 11 | ) 12 | external 13 | view 14 | returns ( 15 | bytes32[] memory buyReserves, 16 | uint256[] memory buyRates, 17 | bytes32[] memory sellReserves, 18 | uint256[] memory sellRates 19 | ); 20 | 21 | function getPricesForToken( 22 | IERC20 token, 23 | uint256 optionalBuyAmountWei, 24 | uint256 optionalSellAmountTwei 25 | ) 26 | external 27 | view 28 | returns ( 29 | bytes32[] memory buyReserves, 30 | uint256[] memory buyRates, 31 | bytes32[] memory sellReserves, 32 | uint256[] memory sellRates 33 | ); 34 | 35 | function getRatesForTokenWithCustomFee( 36 | IERC20 token, 37 | uint256 optionalBuyAmountWei, 38 | uint256 optionalSellAmountTwei, 39 | uint256 networkFeeBps 40 | ) 41 | external 42 | view 43 | returns ( 44 | bytes32[] memory buyReserves, 45 | uint256[] memory buyRates, 46 | bytes32[] memory sellReserves, 47 | uint256[] memory sellRates 48 | ); 49 | 50 | function getReservesRates(IERC20 token, uint256 optionalAmountWei) 51 | external 52 | view 53 | returns ( 54 | bytes32[] memory buyReserves, 55 | uint256[] memory buyRates, 56 | bytes32[] memory sellReserves, 57 | uint256[] memory sellRates 58 | ); 59 | 60 | function getSpreadInfo(IERC20 token, uint256 optionalAmountWei) 61 | external 62 | view 63 | returns (bytes32[] memory reserves, int256[] memory spreads); 64 | 65 | function getSlippageRateInfo( 66 | IERC20 token, 67 | uint256 optionalAmountWei, 68 | uint256 optionalSlippageAmountWei 69 | ) 70 | external 71 | view 72 | returns ( 73 | bytes32[] memory buyReserves, 74 | int256[] memory buySlippageRateBps, 75 | bytes32[] memory sellReserves, 76 | int256[] memory sellSlippageRateBps 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | while getopts "f:" arg; do 3 | case $arg in 4 | f) FILE=$OPTARG;; 5 | esac 6 | done 7 | 8 | export NODE_OPTIONS=--max-old-space-size=4096 9 | 10 | npx buidler clean 11 | npx buidler compile --config ./buidlerCoverageSol4.js 12 | 13 | if [ -n "$FILE" ] 14 | then 15 | npx buidler coverage --config ./buidlerConfigSol6.js --testfiles $FILE --solcoverjs ".solcover.js" --temp "" 16 | else 17 | npx buidler coverage --config ./buidlerConfigSol6.js --testfiles "" --solcoverjs ".solcover.js" --temp "" 18 | fi 19 | -------------------------------------------------------------------------------- /gasUsedReport.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const fs = require('fs'); 3 | const util = require('util'); 4 | const got = require('got'); 5 | const yargs = require('yargs'); 6 | 7 | let argv = yargs.default('branch', 'Katalyst').alias('b', 'branch').argv; 8 | 9 | async function getRemoteReport() { 10 | try { 11 | const url = `http://katalyst-coverage.knstats.com/report/${argv.branch}/gasUsed.json`; 12 | return await got(url).json(); 13 | } catch (error) { 14 | // console.log(error); 15 | return false; 16 | } 17 | } 18 | 19 | async function getLocalReport() { 20 | let reportFile = `report/gasUsed.json`; 21 | if (process.env.TRAVIS_BRANCH !== undefined) { 22 | reportFile = `report/${process.env.TRAVIS_BRANCH}/gasUsed.json`; 23 | } 24 | let report = JSON.parse(fs.readFileSync(reportFile, 'utf8')); 25 | return report 26 | } 27 | 28 | async function compareGasConsumtion() { 29 | let localReport = await getLocalReport(); 30 | let remoteReport = await getRemoteReport(); 31 | if (!remoteReport) { 32 | console.log(`Could not get report for ${argv.branch}. Current report`); 33 | console.table(localReport); 34 | return false; 35 | } 36 | let diffDict = {}; 37 | for (let testCase in localReport) { 38 | if (testCase in remoteReport) { 39 | let baseBranchSize = remoteReport[testCase]; 40 | let currentSize = localReport[testCase]; 41 | let diff = currentSize - baseBranchSize; 42 | if (diff != 0) { 43 | diffDict[testCase] = { 44 | [argv.branch]: baseBranchSize, 45 | current: currentSize, 46 | diff: diff, 47 | }; 48 | } 49 | } 50 | } 51 | for (let testCase in remoteReport) { 52 | if (testCase in remoteReport && !(testCase in diffDict)) { 53 | let baseBranchSize = remoteReport[testCase]; 54 | let currentSize = localReport[testCase]; 55 | let diff = currentSize - baseBranchSize; 56 | if (diff != 0) { 57 | diffDict[testCase] = { 58 | [argv.branch]: baseBranchSize, 59 | current: currentSize, 60 | diff: diff, 61 | }; 62 | } 63 | } 64 | } 65 | if (Object.keys(diffDict).length > 0) { 66 | console.log(`There is change in following gas report with ${argv.branch}`); 67 | console.table(diffDict); 68 | } else { 69 | console.log("Gas report didn't change"); 70 | console.table(localReport); 71 | } 72 | } 73 | 74 | compareGasConsumtion(); 75 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | // deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "smart-contracts", 3 | "version": "1.0.0", 4 | "description": "This repository has the main contracts for KyberNetwork protocol.", 5 | "main": "truffle.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/KyberNetwork/smart-contracts.git" 15 | }, 16 | "author": "", 17 | "license": "ISC", 18 | "bugs": { 19 | "url": "https://github.com/KyberNetwork/smart-contracts/issues" 20 | }, 21 | "homepage": "https://github.com/KyberNetwork/smart-contracts#readme", 22 | "dependencies": { 23 | "chai-as-promised": "7.1.1", 24 | "compare-versions": "3.5.1", 25 | "ethers": "5.0.4", 26 | "ganache-cli": "6.8.2", 27 | "mathjs": "4.4.2", 28 | "rlp": "2.2.4", 29 | "secp256k1": "3.8.0", 30 | "sha3": "2.1.1", 31 | "solc": "0.6.6", 32 | "solhint": "3.0.0-rc.8", 33 | "truffle-assertions": "0.7.2", 34 | "truffle-flattener": "1.4.2", 35 | "web3": "1.2.4", 36 | "web3-utils": "1.2.4", 37 | "winston": "^3.3.3", 38 | "yargs": "11.1.1" 39 | }, 40 | "devDependencies": { 41 | "@nomiclabs/buidler": "1.3.0", 42 | "@nomiclabs/buidler-truffle5": "1.3.0", 43 | "@nomiclabs/buidler-web3": "1.3.0", 44 | "@openzeppelin/test-helpers": "0.5.6", 45 | "@uniswap/v2-periphery": "1.1.0-beta.0", 46 | "chai": "4.2.0", 47 | "chai-bn": "0.2.0", 48 | "mv": "2.1.1", 49 | "got": "^11.1.0", 50 | "prettier": "2.0.4", 51 | "prettier-plugin-solidity": "1.0.0-alpha.54", 52 | "solidity-coverage": "0.7.5" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /scripts/ethdistribution.js: -------------------------------------------------------------------------------- 1 | 2 | var sendEtherWithPromise = function( sender, recv, amount ) { 3 | return new Promise(function(fulfill, reject){ 4 | web3.eth.sendTransaction({to: recv, from: sender, value: amount}, function(error, result){ 5 | if( error ) { 6 | return reject(error); 7 | } 8 | else { 9 | return fulfill(true); 10 | } 11 | }); 12 | }); 13 | }; 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | 17 | var sendEtherToNam = function( sender, namAddresses, amount ){ 18 | return new Promise(function (fulfill, reject){ 19 | 20 | var inputs = []; 21 | 22 | for (var i = 0 ; i < namAddresses.length ; i++ ) { 23 | inputs.push(namAddresses[i]); 24 | } 25 | 26 | return inputs.reduce(function (promise, item) { 27 | return promise.then(function () { 28 | return sendEtherWithPromise(sender, item, amount); 29 | }); 30 | 31 | }, Promise.resolve()).then(function(){ 32 | fulfill(true); 33 | }).catch(function(err){ 34 | reject(err); 35 | }); 36 | }); 37 | }; 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | 41 | var nam; 42 | var victor_1; 43 | var victor_2; 44 | var victor_3; 45 | var duc; 46 | var spyrus; 47 | var andrew; 48 | 49 | var amount = 10**10 * 10 **18; 50 | 51 | var parseInput = function( jsonInput ) { 52 | 53 | // special addresses 54 | var specialAddresses = jsonInput["special addresses"]; 55 | victor_1 = specialAddresses["victor_1"]; 56 | victor_2 = specialAddresses["victor_2"]; 57 | victor_3 = specialAddresses["victor_3"]; 58 | nam = specialAddresses["nam"]; 59 | duc = specialAddresses["duc"]; 60 | spyrus = specialAddresses["spyrus"]; 61 | andrew = specialAddresses["andrew"]; 62 | }; 63 | 64 | 65 | contract('Scenario One', function(accounts) { 66 | 67 | beforeEach(function(done){ 68 | done(); 69 | }); 70 | afterEach(function(done){ 71 | done(); 72 | }); 73 | 74 | it("read parameters from file", function() { 75 | var fs = require("fs"); 76 | try{ 77 | var content = JSON.parse(fs.readFileSync("deployment_input.json", 'utf8')); 78 | parseInput(content); 79 | } 80 | catch(err) { 81 | console.log(err); 82 | assert.fail(err.toString()); 83 | } 84 | 85 | }); 86 | 87 | it("send to victor_1", function() { 88 | return sendEtherWithPromise(accounts[0],victor_1,amount); 89 | }); 90 | it("send to victor_2", function() { 91 | return sendEtherWithPromise(accounts[0],victor_2,amount); 92 | }); 93 | it("send to victor_3", function() { 94 | return sendEtherWithPromise(accounts[0],victor_3,amount); 95 | }); 96 | it("send to duc", function() { 97 | return sendEtherWithPromise(accounts[0],duc,amount); 98 | }); 99 | it("send to nam", function() { 100 | return sendEtherToNam(accounts[0],nam,amount); 101 | }); 102 | it("send to spyrus", function() { 103 | return sendEtherWithPromise(accounts[0],spyrus, amount); 104 | }); 105 | it("send to andrew", function() { 106 | return sendEtherWithPromise(accounts[0],andrew, amount); 107 | }); 108 | 109 | 110 | 111 | }); 112 | -------------------------------------------------------------------------------- /scripts/liquidity_input_params.json: -------------------------------------------------------------------------------- 1 | { 2 | "liquidity_rate": 0.01, 3 | "initial_ether_amount": 70.0, 4 | "initial_token_amount": 724638, 5 | "initial_price": 0.000069, 6 | "min_supported_price_factor": 0.5, 7 | "max_supported_price_factor" : 2.0, 8 | "max_tx_buy_amount_eth": 10.0, 9 | "max_tx_sell_amount_eth": 10.0, 10 | "fee_percent": 0.25, 11 | "formula_precision_bits": 40 12 | } 13 | -------------------------------------------------------------------------------- /solcOptimiserSettings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | enabled: true, 3 | runs: 430 4 | } 5 | -------------------------------------------------------------------------------- /test/sol4/utils3.js: -------------------------------------------------------------------------------- 1 | const MockUtils3 = artifacts.require("./mockContracts/MockUtils3.sol"); 2 | 3 | const Helper = require("../helper.js"); 4 | const BN = web3.utils.BN; 5 | 6 | const PRECISION = new BN(10).pow(new BN(18)); 7 | const MAX_QTY = new BN(10).pow(new BN(28)); 8 | const MAX_RATE = new BN(10).pow(new BN(24)); 9 | const MAX_DECIMAL_DIFF = 18; 10 | 11 | let utils3; 12 | 13 | contract('utils3', function(accounts) { 14 | before("one time init", async() => { 15 | user = accounts[7]; 16 | utils3 = await MockUtils3.new(); 17 | }); 18 | 19 | it("test calc dest amount correctly.", async function () { 20 | let srcDecimal = 15; 21 | let dstDecimal = 17; 22 | let srcQty = (new BN(10)).pow(new BN(srcDecimal)).mul(new BN(531)); 23 | let rate = (new BN(10)).pow(new BN(dstDecimal)).mul(new BN(3423)); 24 | 25 | let expectedDest = Helper.calcDstQty(srcQty, srcDecimal, dstDecimal, rate); 26 | let destAmount = await utils3.mockCalcDestAmountWithDecimals(srcDecimal, dstDecimal, srcQty, rate); 27 | 28 | Helper.assertEqual(destAmount, expectedDest); 29 | 30 | srcDecimal = 18; 31 | dstDecimal = 15; 32 | srcQty = (new BN(10)).pow(new BN(srcDecimal)).mul(new BN(531)); 33 | rate = (new BN(10)).pow(new BN(dstDecimal)).mul(new BN(3423)); 34 | 35 | expectedDest = Helper.calcDstQty(srcQty, srcDecimal, dstDecimal, rate); 36 | destAmount = await utils3.mockCalcDestAmountWithDecimals(srcDecimal, dstDecimal, srcQty, rate); 37 | 38 | Helper.assertEqual(destAmount, expectedDest); 39 | 40 | srcDecimal = 18; 41 | dstDecimal = 18; 42 | srcQty = (new BN(10)).pow(new BN(srcDecimal)).mul(new BN(531)); 43 | rate = (new BN(10)).pow(new BN(dstDecimal)).mul(new BN(3423)); 44 | 45 | expectedDest = Helper.calcDstQty(srcQty, srcDecimal, dstDecimal, rate); 46 | destAmount = await utils3.mockCalcDestAmountWithDecimals(srcDecimal, dstDecimal, srcQty, rate); 47 | 48 | Helper.assertEqual(destAmount, expectedDest); 49 | }); 50 | 51 | it("test calc functionality with high decimal diff is reverted.", async function () { 52 | let dstDecimal = 9; 53 | let srcDecimal = dstDecimal + MAX_DECIMAL_DIFF * 1; 54 | let srcQty = 795; 55 | let rate = 9853; 56 | 57 | //should work with max decimal diff. 58 | let expectedDestAmount = Helper.calcDstQty(srcQty, srcDecimal, dstDecimal, rate); 59 | let destAmount = await utils3.mockCalcDestAmountWithDecimals(srcDecimal, dstDecimal, srcQty, rate); 60 | 61 | Helper.assertEqual(destAmount, expectedDestAmount); 62 | 63 | //should revert when qty above max 64 | srcDecimal += 1 * 1; 65 | try { 66 | let destAmount = await utils3.mockCalcDestAmountWithDecimals(srcDecimal, dstDecimal, srcQty, rate); 67 | assert(false, "throw was expected in line above.") 68 | } catch(e){ 69 | assert(Helper.isRevertErrorMessage(e), "expected throw but got: " + e); 70 | } 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /test/sol6/fuzzerFiles/randomNumberGenerator.js: -------------------------------------------------------------------------------- 1 | const BN = web3.utils.BN; 2 | module.exports.genRandomSeed = genRandomSeed; 3 | function genRandomSeed(base) { 4 | return Math.floor(Math.random() * base) % base; 5 | } 6 | 7 | module.exports.genRandomBN = function(minBN, maxBN) { 8 | let seed = new BN(genRandomSeed(1000000000000000)); 9 | // normalise seed 10 | return (maxBN.sub(minBN).mul(seed).div(new BN(1000000000000000))).add(minBN); 11 | } 12 | -------------------------------------------------------------------------------- /test/sol6/fuzzerFiles/tradeFuzzer/multiple_trade_fuzz_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for _ in {1..100} 4 | do 5 | npx buidler test --no-compile test/sol6/tradeFuzzTests.js 6 | done 7 | -------------------------------------------------------------------------------- /test/sol6/reentrancyGuard.js: -------------------------------------------------------------------------------- 1 | const ReentrancyMock = artifacts.require('./mockContracts/ReentrancyMock.sol'); 2 | const ReentrancyAttack = artifacts.require('./mockContracts/ReentrancyAttack.sol'); 3 | 4 | const { expectRevert } = require('@openzeppelin/test-helpers'); 5 | const { expect } = require('chai'); 6 | 7 | 8 | contract('ReentrancyGuard', function(accounts) { 9 | beforeEach(async function () { 10 | this.reentrancyMock = await ReentrancyMock.new(); 11 | expect(await this.reentrancyMock.counter()).to.be.bignumber.equal('0'); 12 | }); 13 | 14 | it('should not allow remote callback', async function () { 15 | const attacker = await ReentrancyAttack.new(); 16 | await expectRevert( 17 | this.reentrancyMock.countAndCall(attacker.address), 'ReentrancyAttack: failed call'); 18 | }); 19 | 20 | // The following are more side-effects than intended behavior: 21 | // I put them here as documentation, and to monitor any changes 22 | // in the side-effects. 23 | 24 | it('should not allow local recursion', async function () { 25 | await expectRevert( 26 | this.reentrancyMock.countLocalRecursive(10), 'ReentrancyGuard: reentrant call' 27 | ); 28 | }); 29 | 30 | it('should not allow indirect local recursion', async function () { 31 | await expectRevert( 32 | this.reentrancyMock.countThisRecursive(10), 'ReentrancyMock: failed call' 33 | ); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/sol6/stakingFuzzTests.js: -------------------------------------------------------------------------------- 1 | const TestToken = artifacts.require("TestToken.sol"); 2 | // using mock contract here, as we need to read the hasInited value 3 | const MockKyberStaking = artifacts.require("MockKyberStaking.sol"); 4 | 5 | const Helper = require("../helper.js"); 6 | const BN = web3.utils.BN; 7 | const StakeSimulator = require("./fuzzerFiles/stakingFuzzer/stakingSimulator.js"); 8 | const { precisionUnits } = require("../helper.js"); 9 | 10 | //global variables 11 | ////////////////// 12 | const NUM_RUNS = 100; 13 | 14 | // accounts 15 | let admin; 16 | let daoOperator; 17 | let stakers; 18 | 19 | // token 20 | let kncToken; 21 | const tokenDecimals = 18; 22 | 23 | // staking and its params 24 | let kyberStaking; 25 | let epochPeriod = new BN(1000); 26 | let firstBlockTimestamp; 27 | 28 | contract('KyberStaking simulator', async (accounts) => { 29 | before('one time init: Stakers, KyberStaking, KNC token', async() => { 30 | admin = accounts[1]; 31 | daoOperator = accounts[2]; 32 | stakers = accounts.slice(5,); // 5 stakers 33 | kncToken = await TestToken.new("kyber Crystals", "KNC", tokenDecimals); 34 | 35 | // prepare kyber staking 36 | firstBlockTimestamp = await Helper.getCurrentBlockTime(); 37 | 38 | kyberStaking = await MockKyberStaking.new( 39 | kncToken.address, 40 | epochPeriod, 41 | firstBlockTimestamp + 1000, 42 | daoOperator 43 | ); 44 | }); 45 | 46 | beforeEach("deposits some KNC tokens to each account, gives allowance to staking contract", async() => { 47 | // 1M KNC token 48 | let kncTweiDepositAmount = new BN(1000000).mul(precisionUnits); 49 | let maxAllowance = (new BN(2)).pow(new BN(255)); 50 | // transfer tokens, approve staking contract 51 | for(let i = 0; i < stakers.length; i++) { 52 | await kncToken.transfer(stakers[i], kncTweiDepositAmount); 53 | let expectedResult = await kncToken.balanceOf(stakers[i]); 54 | Helper.assertEqual(expectedResult, kncTweiDepositAmount, "staker did not receive tokens"); 55 | await kncToken.approve(kyberStaking.address, maxAllowance, {from: stakers[i]}); 56 | expectedResult = await kncToken.allowance(stakers[i], kyberStaking.address); 57 | Helper.assertEqual(expectedResult, maxAllowance, "staker did not give sufficient allowance"); 58 | } 59 | }); 60 | 61 | it(`fuzz tests kyberStaking contract with ${NUM_RUNS} loops`, async() => { 62 | await StakeSimulator.doFuzzStakeTests( 63 | kyberStaking, NUM_RUNS, kncToken, stakers, epochPeriod 64 | ); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | solc: { 3 | optimizer: require("./solcOptimiserSettings.js") 4 | }, 5 | networks: { 6 | development: { 7 | host: "localhost", 8 | port: 8545, 9 | gas: 6000000, 10 | gasPrice: 40000000000, 11 | network_id: "*" // Match any network id 12 | }, 13 | rinkeby: { 14 | host: "localhost", // Connect to geth on the specified 15 | port: 8545, 16 | gasPrice: 4000000000, 17 | network_id: 4, 18 | gas: 4612388 // Gas limit used for deploys 19 | }, 20 | simulation: { 21 | host: "blockchain", // Connect to geth on the specified 22 | port: 8545, 23 | gasPrice: 4000000000, 24 | network_id: 4, 25 | gas: 4612388 // Gas limit used for deploys 26 | } 27 | }, 28 | mocha: { 29 | enableTimeouts: false 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /tst.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ALL=false 3 | 4 | while getopts "f:a" arg; do 5 | case $arg in 6 | a) ALL=true;; 7 | f) FILE=$OPTARG;; 8 | esac 9 | done 10 | 11 | if [ -n "$FILE" ]; then 12 | npx buidler test --no-compile $FILE 13 | elif [ "$ALL" = true ]; then 14 | echo "Running all tests..." 15 | npx buidler test --no-compile 16 | else 17 | echo "Running sol6 tests..." 18 | npx buidler test --config ./buidlerConfigSol6.js --no-compile 19 | fi 20 | -------------------------------------------------------------------------------- /web3deployment/helperContracts/CheckPointing.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.18; 2 | 3 | 4 | contract KyberReserveIf { 5 | address public kyberNetwork; 6 | } 7 | 8 | 9 | interface KyberReserveInterface { 10 | 11 | function trade(address srcToken, uint srcAmount, address destToken, address destAddress, uint conversionRate, 12 | bool validate) public payable returns(bool); 13 | function getConversionRate(address src, address dest, uint srcQty, uint blockNumber) public view returns(uint); 14 | } 15 | 16 | 17 | contract KyberNetworkIf { 18 | KyberReserveInterface[] public reserves; 19 | function getNumReserves() public view returns(uint); 20 | } 21 | 22 | 23 | contract CheckReservePoint { 24 | 25 | KyberNetworkIf constant kyber = KyberNetworkIf(0x65bF64Ff5f51272f729BDcD7AcFB00677ced86Cd); 26 | KyberNetworkIf constant oldKyber = KyberNetworkIf(0x9ae49C0d7F8F9EF4B864e004FE86Ac8294E20950); 27 | 28 | function checkPointing() public view returns(address[] goodPoint, address[] oldKybers, address[] badPoint, uint numReserves, uint oldIndex, uint goodIndex) { 29 | numReserves = kyber.getNumReserves(); 30 | 31 | goodPoint = new address[](numReserves); 32 | oldKybers = new address[](numReserves); 33 | badPoint = new address[](10); 34 | 35 | uint badIndex; 36 | 37 | KyberReserveIf reserve; 38 | 39 | for (uint i = 0; i < numReserves; i ++) { 40 | reserve = KyberReserveIf(kyber.reserves(i)); 41 | 42 | if (reserve.kyberNetwork() == address(oldKyber)) { 43 | oldKybers[oldIndex++] = address(reserve); 44 | } else if (reserve.kyberNetwork() == address(kyber)){ 45 | goodPoint[goodIndex++] = address(reserve); 46 | } else { 47 | badPoint[badIndex++] = address(reserve); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /web3deployment/helpers/gasStation.js: -------------------------------------------------------------------------------- 1 | const request = require('xhr-request-promise'); 2 | const ethers = require('ethers'); 3 | const BN = ethers.utils.BigNumber; 4 | 5 | const MAX_RETRIES = 3; 6 | const GASSTATION_URL = 'https://ethgasstation.info/api/ethgasAPI.json'; 7 | const SLEEP_TIME = 3000; // sleep between retries 8 | const EXPIRE_TIME = 60000; // expire time for gas data 9 | 10 | let lastUpdate =0; 11 | let gasData; 12 | 13 | async function getGasData () { 14 | if (Date.now() - lastUpdate <= EXPIRE_TIME) { 15 | return gasData; 16 | } 17 | let err; 18 | for (let attempt = 0; attempt < MAX_RETRIES; attempt++) { 19 | try { 20 | let result = await request(GASSTATION_URL, {responseType: 'json'}); 21 | gasData = result; 22 | lastUpdate = Date.now(); 23 | return result; 24 | } catch (e) { 25 | err = e; 26 | console.log(e); 27 | await setTimeout(() => {}, SLEEP_TIME); 28 | } 29 | } 30 | throw err; 31 | } 32 | 33 | module.exports = { getGasData }; 34 | 35 | -------------------------------------------------------------------------------- /web3deployment/kovan.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": { 3 | "OMG": { 4 | "name": "OmiseGO", 5 | "decimals": 18, 6 | "address": "0x7606bd550f467546212649a9c25623dfca88dcd7", 7 | "minimalRecordResolution": "1000000000000000", 8 | "maxPerBlockImbalance": "120000000000000000000", 9 | "maxTotalImbalance": "180000000000000000000" 10 | }, 11 | "KNC": { 12 | "name": "KyberNetwork", 13 | "decimals": 18, 14 | "address": "0x8dc114d77e857558aefbe8e1a50b460ff9578f1a", 15 | "minimalRecordResolution": "1000000000000000", 16 | "maxPerBlockImbalance": "550000000000000000000", 17 | "maxTotalImbalance": "820000000000000000000" 18 | }, 19 | "EOS": { 20 | "name": "Eos", 21 | "decimals": 18, 22 | "address": "0x15fb2a9d7dadbb88f260f78dcbb574b3b76a8e06", 23 | "minimalRecordResolution": "1000000000000000", 24 | "maxPerBlockImbalance": "150000000000000000000", 25 | "maxTotalImbalance": "230000000000000000000" 26 | }, 27 | "SALT": { 28 | "name": "SALT", 29 | "decimals": 8, 30 | "address": "0xcc112cd38362bf3c07d226768fd5869e65296083", 31 | "minimalRecordResolution": "100000", 32 | "maxPerBlockImbalance": "25000000000", 33 | "maxTotalImbalance": "37000000000" 34 | }, 35 | "SNT": { 36 | "name": "STATUS", 37 | "decimals": 18, 38 | "address": "0x676f650000f420485b99ef0377a2e1c96eb3e821", 39 | "minimalRecordResolution": "10000000000000000", 40 | "maxPerBlockImbalance": "6850000000000000000000", 41 | "maxTotalImbalance": "10300000000000000000000" 42 | }, 43 | "ETH": { 44 | "name": "Ethereum", 45 | "decimals": 18, 46 | "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 47 | } 48 | }, 49 | "exchanges": { 50 | "binance": { 51 | "ETH": "0x1ae659f93ba2fc0a1f379545cf9335adb75fa547", 52 | "OMG": "0x1ae659f93ba2fc0a1f379545cf9335adb75fa547", 53 | "KNC": "0x1ae659f93ba2fc0a1f379545cf9335adb75fa547", 54 | "SNT": "0x1ae659f93ba2fc0a1f379545cf9335adb75fa547", 55 | "SALT": "0x1ae659f93ba2fc0a1f379545cf9335adb75fa547" 56 | } 57 | }, 58 | "reserve": "0xc1400758cC253750516eCd0dAc4C4B0E469a90fF", 59 | "pricing": "0x54409D8cB061379C97521c3b23a36E9b098c37d7", 60 | "network": "0x1F2e33BEc486480a954E0Bab1D6d2E02831e7449", 61 | "wrapper": "0x8E7D25b4c9093e01699aDB23B6fD232452f34981", 62 | "feeburner": "0x1DF07Ef28347f79D1D32fee0247D9D8390D0B71D" 63 | } -------------------------------------------------------------------------------- /web3deployment/liquidityReserve_input.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": { 3 | "name": "KyberNetwork", 4 | "symbol": "KNC", 5 | "decimals": 18, 6 | "address": "0x4E470dc7321E84CA96FcAEDD0C8aBCebbAEB68C6" 7 | }, 8 | 9 | "whitelistedAddresses": { 10 | "ETH": ["0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90"], 11 | "KNC": ["0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90"] 12 | }, 13 | 14 | "permission" : { 15 | "reserve": { 16 | "admin": "0xBC33a1F908612640F2849b56b67a4De4d179C151", 17 | "operators": ["0x5bab5ef16cfac98e216a229db17913454b0f9365"], 18 | "alerters": ["0x5bab5ef16cfac98e216a229db17913454b0f9365"] 19 | }, 20 | 21 | "pricing": { 22 | "admin": "0xBC33a1F908612640F2849b56b67a4De4d179C151", 23 | "operators": [], 24 | "alerters": [] 25 | } 26 | }, 27 | 28 | "output filename" : "liquidityReserve_deployment.json" 29 | } 30 | -------------------------------------------------------------------------------- /web3deployment/reserve_deployment_ropsten.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": { 3 | "OMG": { 4 | "name": "OmiseGO", 5 | "decimals": 18, 6 | "address": "0x4BFBa4a8F28755Cb2061c413459EE562c6B9c51b", 7 | "minimalRecordResolution": "1000000000000000", 8 | "maxPerBlockImbalance": "775091297865175138304", 9 | "maxTotalImbalance": "1096640332676811325440" 10 | }, 11 | "KNC": { 12 | "name": "KyberNetwork", 13 | "decimals": 18, 14 | "address": "0x4E470dc7321E84CA96FcAEDD0C8aBCebbAEB68C6", 15 | "minimalRecordResolution": "1000000000000000", 16 | "maxPerBlockImbalance": "2711997842670896021504", 17 | "maxTotalImbalance": "3833713935933528080384" 18 | }, 19 | "ETH": { 20 | "name": "Ethereum", 21 | "decimals": 18, 22 | "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" 23 | } 24 | }, 25 | "exchanges": { 26 | "binance": { 27 | "ETH": "0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90", 28 | "OMG": "0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90", 29 | "KNC": "0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90" 30 | } 31 | }, 32 | "permission": { 33 | "KyberReserve": { 34 | "admin": "0xBC33a1F908612640F2849b56b67a4De4d179C151", 35 | "operator": [ 36 | "0x5bab5ef16cfac98e216a229db17913454b0f9365" 37 | ], 38 | "alerter": [] 39 | }, 40 | "ConversionRates": { 41 | "admin": "0xBC33a1F908612640F2849b56b67a4De4d179C151", 42 | "operator": [ 43 | "0x8bc3da587def887b5c822105729ee1d6af05a5ca", 44 | "0x9224016462B204C57Eb70e1D69652f60bcAF53A8" 45 | ], 46 | "alerter": [] 47 | } 48 | }, 49 | "valid duration block": 60, 50 | "reserve": "0x65e37074Af5B132954E265f6265d45809731cd1f", 51 | "pricing": "0x3e91D0825e443A2E33281dc8Ed1fbBcd616FBD7C", 52 | "network": "0xD19559B3121c1b071481d8813d5dBcDC5869e2e8" 53 | } -------------------------------------------------------------------------------- /web3deployment/retrieveArtifacts.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const util = require('util'); 3 | const readdir = util.promisify(fs.readdir); 4 | const path = require("path"); 5 | const artifactsPath = path.join(__dirname, "../artifacts/"); 6 | const buidlerConfigSol5 = path.join(__dirname, "../buidlerConfigSol5.js"); 7 | const buidlerConfigSol4 = path.join(__dirname, "../buidlerConfigSol4.js"); 8 | const execSync = require('child_process').execSync; 9 | 10 | module.exports.retrieveArtifacts = main; 11 | async function main(skipCompilation) { 12 | if (!skipCompilation) { 13 | compileContracts(); 14 | } 15 | let output = await packageArtifacts(); 16 | return output; 17 | } 18 | 19 | async function packageArtifacts() { 20 | let result = {}; 21 | files = await readdir(artifactsPath); 22 | files.forEach(file => { 23 | content = JSON.parse(fs.readFileSync(path.join(artifactsPath, file))); 24 | result[content.contractName] = content; 25 | }) 26 | return result; 27 | } 28 | 29 | 30 | function compileContracts() { 31 | console.log("Compiling contracts..."); 32 | execSync(`npx buidler compile`, { encoding: 'utf-8' }); 33 | execSync(`npx buidler compile --config ${buidlerConfigSol5}`, { encoding: 'utf-8'}); 34 | execSync(`npx buidler compile --config ${buidlerConfigSol4}`, { encoding: 'utf-8'}); 35 | } 36 | 37 | main(); 38 | -------------------------------------------------------------------------------- /web3deployment/ropsten_reserve_input.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": { 3 | "OMG": { 4 | "name": "OmiseGO", 5 | "decimals": 18, 6 | "address": "0x4BFBa4a8F28755Cb2061c413459EE562c6B9c51b", 7 | "minimalRecordResolution" : "1000000000000000", 8 | "maxPerBlockImbalance" : "775091297865175138304", 9 | "maxTotalImbalance" : "1096640332676811325440" 10 | }, 11 | "KNC": { 12 | "name": "KyberNetwork", 13 | "decimals": 18, 14 | "address": "0x4E470dc7321E84CA96FcAEDD0C8aBCebbAEB68C6", 15 | "minimalRecordResolution" : "1000000000000000", 16 | "maxPerBlockImbalance" : "2711997842670896021504", 17 | "maxTotalImbalance" : "3833713935933528080384" 18 | } 19 | }, 20 | "exchanges": { 21 | "binance" : {"ETH" : "0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90", 22 | "OMG" : "0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90", 23 | "KNC" : "0x44d34a119ba21a42167ff8b77a88f0fc7bb2db90" } 24 | }, 25 | 26 | "permission" : { 27 | "KyberReserve" : { "admin" : "0xBC33a1F908612640F2849b56b67a4De4d179C151", 28 | "operator" : ["0x5bab5ef16cfac98e216a229db17913454b0f9365"], 29 | "alerter" : []}, 30 | "ConversionRates" : { "admin" : "0xBC33a1F908612640F2849b56b67a4De4d179C151", 31 | "operator" : ["0x8bc3da587def887b5c822105729ee1d6af05a5ca", 32 | "0x9224016462B204C57Eb70e1D69652f60bcAF53A8"], 33 | "alerter" : []} 34 | }, 35 | 36 | "valid duration block" : 60, 37 | 38 | "output filename" : "reserve_deployment_ropsten.json" 39 | } 40 | -------------------------------------------------------------------------------- /web3deployment/sendTxs.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const Web3 = require("web3"); 4 | const fs = require("fs"); 5 | 6 | process.on('unhandledRejection', console.error.bind(console)) 7 | 8 | const { rpcUrl, signedTxsInput } = require('yargs') 9 | .usage('Usage: $0 --rpc-url [url] --signed-tx-input [path]') 10 | .demandOption(['rpcUrl', 'signedTxsInput']) 11 | .argv; 12 | 13 | const { from, txs } = JSON.parse(fs.readFileSync(signedTxsInput)) 14 | 15 | const provider = new Web3.providers.HttpProvider(rpcUrl) 16 | const web3 = new Web3(provider) 17 | 18 | async function main () { 19 | console.log('from', from, 'number of txs', txs.length); 20 | await waitForEth(from) 21 | 22 | const res = await Promise.all(txs.map((tx, i) => { 23 | const payload = { 24 | jsonrpc: '2.0', 25 | method: 'eth_sendRawTransaction', 26 | id: i, 27 | params: [ tx ] 28 | } 29 | return new Promise((resolve, reject) => { 30 | return provider.send(payload, function (err, result) { 31 | return err ? reject(err) : resolve({ transactionHash: result.result }) 32 | }) 33 | }) 34 | })) 35 | console.log(JSON.stringify(res, null, 2)); 36 | } 37 | 38 | async function waitForEth(sender) { 39 | while(true) { 40 | const balance = await web3.eth.getBalance(sender); 41 | console.log("waiting for balance to account " + sender); 42 | if(balance.toString() !== "0") { 43 | console.log("received " + balance.toString() + " wei"); 44 | return; 45 | } 46 | else await sleep(10000) 47 | } 48 | } 49 | function sleep(ms){ 50 | return new Promise(resolve=>{ 51 | setTimeout(resolve,ms) 52 | }) 53 | } 54 | 55 | main(); 56 | -------------------------------------------------------------------------------- /web3deployment/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | 3 | let ouputLogString = ""; 4 | let ouputErrString = ""; 5 | let addressesToNames = {}; 6 | 7 | 8 | module.exports.myLog = function myLog(error, highlight, string) { 9 | if (error) { 10 | // console.error(string); 11 | console.log('\x1b[31m%s\x1b[0m', string); 12 | ouputErrString += "\nerror: " + string; 13 | ouputLogString += "\nerror: " + string; 14 | } else if (highlight) { 15 | console.log('\x1b[33m%s\x1b[0m', string); 16 | ouputErrString += "\nwarning: " + string; 17 | ouputLogString += "\nwarning: " + string; 18 | } else { 19 | console.log('\x1b[32m%s\x1b[0m', string); 20 | ouputLogString += "\n " + string; 21 | } 22 | }; 23 | 24 | //write log ouputs 25 | module.exports.writeLogs = function writeLogs(deployInputJsonPath) { 26 | 27 | let fileName = deployInputJsonPath + ".log"; 28 | module.exports.myLog(0, 1, "write output log to: " + fileName); 29 | 30 | fs.writeFileSync(fileName, ouputLogString, function(err) { 31 | if(err) { 32 | console.log(err); 33 | } else { 34 | module.exports.myLog(0, 1, "saved log to: " + fileName); 35 | } 36 | }); 37 | 38 | 39 | 40 | fileName = deployInputJsonPath + ".err"; 41 | module.exports.myLog(0, 1, "write error log to: " + fileName); 42 | 43 | fs.writeFileSync(fileName, ouputErrString, function(err) { 44 | if(err) { 45 | console.log(err); 46 | } else { 47 | module.exports.myLog(0, 1, "saved error file to: " + fileName); 48 | } 49 | }); 50 | } 51 | 52 | //address to name 53 | module.exports.a2n = async function a2n(address, showAddWithName, isToken, solcOutput) { 54 | let name; 55 | try { 56 | name = addressesToNames[address.toLowerCase()]; 57 | if (name == undefined) { 58 | if (isToken == true) { 59 | let abi = solcOutput.contracts["MockERC20.sol:MockERC20"].interface; 60 | let ERC20 = await new web3.eth.Contract(JSON.parse(abi), address); 61 | try { 62 | name = await ERC20.methods.symbol().call(); 63 | if (name != undefined) { 64 | addressesToNames[address.toLowerCase()] = name; 65 | if (showAddWithName) name += " " + address.toLowerCase(); 66 | } 67 | } catch(e) {} 68 | } 69 | if (name == undefined) { 70 | name = address; 71 | } 72 | } else if (showAddWithName) { 73 | name += " " + address.toLowerCase(); 74 | } 75 | } catch(e) { 76 | name = address; 77 | } 78 | 79 | return name; 80 | } 81 | 82 | //address to name 83 | module.exports.addName2Add = function setName(address, name) { 84 | addressesToNames[address] = name; 85 | } 86 | 87 | module.exports.getNameFromAdd = function getName(address) { 88 | return addressesToNames[address]; 89 | } 90 | --------------------------------------------------------------------------------