├── .editorconfig ├── .env.example ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── .solhint.json ├── .solhintignore ├── .travis.yml ├── LICENSE ├── README.md ├── artifacts └── kovan │ ├── abi │ ├── ERC20Detailed.json │ ├── FaucetInterface.json │ ├── MarginFlowProtocol.json │ ├── MarginFlowProtocolConfig.json │ ├── MarginFlowProtocolSafety.json │ ├── MarginLiquidityPoolInterface.json │ ├── MarginLiquidityPoolRegistry.json │ ├── MoneyMarket.json │ ├── PriceOracleInterface.json │ ├── SimplePriceOracle.json │ ├── SyntheticFlowProtocol.json │ ├── SyntheticFlowToken.json │ └── SyntheticLiquidityPoolInterface.json │ └── deployment.json ├── buidler.config.js ├── codechecks.yml ├── contracts ├── Migrations.sol ├── impls │ ├── FlowProtocolBase.sol │ ├── LiquidityPool.sol │ ├── MintableToken.sol │ ├── MoneyMarket.sol │ ├── margin │ │ ├── MarginFlowProtocol.sol │ │ ├── MarginFlowProtocolAccPositions.sol │ │ ├── MarginFlowProtocolConfig.sol │ │ ├── MarginFlowProtocolLiquidated.sol │ │ ├── MarginFlowProtocolSafety.sol │ │ ├── MarginLiquidityPool.sol │ │ ├── MarginLiquidityPoolRegistry.sol │ │ └── MarginMarketLib.sol │ ├── oracles │ │ ├── ChainLinkOracle.sol │ │ ├── PriceOracleConfig.sol │ │ └── SimplePriceOracle.sol │ └── synthetic │ │ ├── SyntheticFlowProtocol.sol │ │ ├── SyntheticFlowToken.sol │ │ └── SyntheticLiquidityPool.sol ├── interfaces │ ├── CErc20Interface.sol │ ├── LiquidityPoolInterface.sol │ ├── MarginLiquidityPoolInterface.sol │ ├── MoneyMarketInterface.sol │ ├── PriceOracleInterface.sol │ └── SyntheticLiquidityPoolInterface.sol ├── libs │ ├── Arrays.sol │ ├── Percentage.sol │ └── upgrades │ │ └── Proxy.sol ├── mocks │ ├── ArraysImpl.sol │ ├── FaucetInterface.sol │ ├── TestCToken.sol │ ├── TestToken.sol │ ├── margin │ │ ├── MockIsPoolSafeMarginProtocol.sol │ │ └── TestMarginFlowProtocol.sol │ └── upgrades │ │ ├── MarginFlowProtocolNewVersion.sol │ │ ├── MarginFlowProtocolSafetyNewVersion.sol │ │ ├── MarginLiquidityPoolNewVersion.sol │ │ ├── MarginLiquidityPoolRegistryNewVersion.sol │ │ ├── MoneyMarketNewVersion copy.sol │ │ ├── SimplePriceOracleNewVersion.sol │ │ ├── SyntheticFlowProtocolNewVersion.sol │ │ ├── SyntheticFlowTokenNewVersion.sol │ │ └── SyntheticLiquidityPoolNewVersion.sol └── roles │ ├── PriceFeederRole.sol │ └── ProtocolOwnable.sol ├── cucumber.js ├── cucumber ├── features │ └── margin.feature └── step-definitions │ └── margin.steps.ts ├── dev-scripts ├── changeOwners.js ├── changeSpread.js ├── debug.js ├── dummy-oracle-server.js ├── getKovanDaiFaucet.js ├── margin-PoC.js └── upgradeContract.js ├── docker-compose.yml ├── generated-docs ├── SUMMARY.md ├── contract.hbs ├── docs │ ├── Migrations.md │ ├── impls │ │ ├── FlowProtocolBase.md │ │ ├── LiquidityPool.md │ │ ├── MintableToken.md │ │ ├── MoneyMarket.md │ │ ├── PriceOracleConfig.md │ │ ├── SimplePriceOracle.md │ │ ├── margin │ │ │ ├── MarginFlowProtocol.md │ │ │ ├── MarginFlowProtocolAccPositions.md │ │ │ ├── MarginFlowProtocolConfig.md │ │ │ ├── MarginFlowProtocolLiquidated.md │ │ │ ├── MarginFlowProtocolSafety.md │ │ │ ├── MarginLiquidityPool.md │ │ │ ├── MarginLiquidityPoolRegistry.md │ │ │ └── MarginMarketLib.md │ │ ├── oracles │ │ │ ├── ChainLinkOracle.md │ │ │ ├── PriceOracleConfig.md │ │ │ └── SimplePriceOracle.md │ │ └── synthetic │ │ │ ├── SyntheticFlowProtocol.md │ │ │ ├── SyntheticFlowToken.md │ │ │ └── SyntheticLiquidityPool.md │ ├── interfaces │ │ ├── CErc20Interface.md │ │ ├── LiquidityPoolInterface.md │ │ ├── MarginLiquidityPoolInterface.md │ │ ├── MoneyMarketInterface.md │ │ ├── PriceOracleInterface.md │ │ └── SyntheticLiquidityPoolInterface.md │ ├── libs │ │ ├── Arrays.md │ │ ├── Percentage.md │ │ └── upgrades │ │ │ ├── ERC20DetailedUpgradable.md │ │ │ ├── Proxy.md │ │ │ ├── UpgradeAccessControl.md │ │ │ ├── UpgradeContext.md │ │ │ ├── UpgradeOwnable.md │ │ │ └── UpgradeReentrancyGuard.md │ ├── mocks │ │ ├── ArraysImpl.md │ │ ├── FaucetInterface.md │ │ ├── TestCToken.md │ │ ├── TestToken.md │ │ ├── margin │ │ │ ├── MockIsPoolSafeMarginProtocol.md │ │ │ └── TestMarginFlowProtocol.md │ │ └── upgrades │ │ │ ├── MarginFlowProtocolNewVersion.md │ │ │ ├── MarginFlowProtocolSafetyNewVersion.md │ │ │ ├── MarginLiquidityPoolNewVersion.md │ │ │ ├── MarginLiquidityPoolRegistryNewVersion.md │ │ │ ├── MoneyMarketNewVersion copy.md │ │ │ ├── SimplePriceOracleNewVersion.md │ │ │ ├── SyntheticFlowProtocolNewVersion.md │ │ │ ├── SyntheticFlowTokenNewVersion.md │ │ │ └── SyntheticLiquidityPoolNewVersion.md │ └── roles │ │ ├── PriceFeederRole.md │ │ └── ProtocolOwnable.md └── exclude.txt ├── migrations ├── 1_initial_migration.js ├── 2_deploy_contracts.js ├── config │ ├── development │ │ ├── margin │ │ │ ├── margin_config.json │ │ │ └── margin_pools │ │ │ │ └── general_margin_pool.json │ │ ├── oracles.json │ │ └── synthetic │ │ │ ├── synthetic_config.json │ │ │ └── synthetic_pools │ │ │ └── general_synthetic_pool.json │ └── kovan │ │ ├── margin │ │ ├── margin_config.json │ │ └── margin_pools │ │ │ ├── ACME_margin_pool.json │ │ │ └── general_margin_pool.json │ │ ├── oracles.json │ │ └── synthetic │ │ ├── synthetic_config.json │ │ └── synthetic_pools │ │ ├── XYZ_synthetic_pool.json │ │ └── general_synthetic_pool.json └── deploy_contracts.ts ├── package.json ├── scripts ├── debug.sh ├── deploy-local.sh ├── docify.js ├── run_cucumber_tests.sh └── run_tests.sh ├── subgraph ├── package.json ├── schema.graphql ├── scripts │ └── codegen.js ├── src │ └── mapping.ts ├── subgraph.template.yaml └── yarn.lock ├── test ├── arrays.ts ├── helpers.ts ├── margin │ ├── marginFlowProtocol.ts │ ├── marginFlowProtocolConfig.ts │ ├── marginFlowProtocolSafety.ts │ ├── marginFlowProtocolSimulation.ts │ ├── marginLiquidityPool.ts │ └── marginLiquidityPoolRegistry.ts ├── moneyMarket.ts ├── simplePriceOracle.ts ├── synthetic │ ├── syntheticFlowProtocol.ts │ ├── syntheticFlowToken.ts │ └── syntheticLiquidityPool.ts └── truffle-fixture.js ├── truffle-config.js ├── tsconfig.eslint.json ├── tsconfig.json ├── typings.d.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | end_of_line = lf 8 | insert_final_newline = true 9 | 10 | [package.json] 11 | indent_size = 2 12 | 13 | [*.{js,ts}] 14 | indent_style = space 15 | indent_size = 2 16 | 17 | [*.sol] 18 | indent_style = space 19 | indent_size = 4 20 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | INFURA_API_KEY='' 2 | MNEMONIC='' 3 | ETHERSCAN_API_KEY='' 4 | COINMARKETCAP_API_KEY='' -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/build/* 2 | **/coverage/* 3 | **/node_modules/* 4 | types/* 5 | subgraph/generated/* 6 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | es6: true, 4 | node: true, 5 | mocha: true, 6 | }, 7 | extends: [ 8 | 'airbnb-base', 9 | 'plugin:@typescript-eslint/eslint-recommended', 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:@typescript-eslint/recommended-requiring-type-checking', 12 | 'plugin:import/typescript', 13 | 'plugin:prettier/recommended', 14 | 'prettier/@typescript-eslint', 15 | ], 16 | globals: { 17 | artifacts: 'readonly', 18 | contract: 'readonly', 19 | assert: 'readonly', 20 | web3: 'readonly', 21 | }, 22 | parser: '@typescript-eslint/parser', 23 | parserOptions: { 24 | warnOnUnsupportedTypeScriptVersion: false, 25 | project: ['./tsconfig.json', './tsconfig.eslint.json'], 26 | }, 27 | plugins: ['@typescript-eslint', 'import', 'prettier'], 28 | rules: { 29 | '@typescript-eslint/no-unsafe-assignment': ['off'], 30 | '@typescript-eslint/no-unsafe-member-access': ['off'], 31 | '@typescript-eslint/no-unsafe-call': ['off'], 32 | '@typescript-eslint/no-unsafe-return': ['off'], 33 | '@typescript-eslint/restrict-template-expressions': ['off'], 34 | '@typescript-eslint/indent': ['error', 2], 35 | indent: 'off', // required as 'off' by @typescript-eslint/indent 36 | 'no-console': 'off', 37 | 'no-restricted-syntax': 'off', 38 | 'max-len': ['error', {code: 150}], 39 | 'comma-dangle': ['error', 'always-multiline'], 40 | 'no-mixed-operators': 'off', 41 | 'object-curly-newline': 'off', 42 | '@typescript-eslint/explicit-function-return-type': 'off', 43 | '@typescript-eslint/await-thenable': 'off', // not accurate for many web3 types 44 | 'no-await-in-loop': 'off', 45 | 'implicit-arrow-linebreak': 'off', 46 | '@typescript-eslint/no-explicit-any': 'off', 47 | 'no-loop-func': 'off', 48 | 'no-underscore-dangle': 'off', 49 | 'no-unused-expressions': 'off', 50 | 'no-empty-character-class': 'off', // causing linter to crash 51 | 'no-regex-spaces': 'off', // causing linter to crash 52 | 'prettier/prettier': ['error', {endOfLine: 'auto'}], 53 | 'import/extensions': [ 54 | 'error', 55 | 'ignorePackages', 56 | { 57 | js: 'never', 58 | jsx: 'never', 59 | ts: 'never', 60 | tsx: 'never', 61 | }, 62 | ], 63 | }, 64 | settings: { 65 | 'import/resolver': { 66 | typescript: { 67 | directory: './tsconfig.json', 68 | }, 69 | }, 70 | }, 71 | overrides: [ 72 | { 73 | files: ['subgraph/**/*.ts'], 74 | rules: { 75 | 'prefer-const': 'off', 76 | '@typescript-eslint/no-unnecessary-type-assertion': 'off', 77 | 'no-param-reassign': 'off', 78 | }, 79 | }, 80 | ], 81 | }; 82 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/soliditytruffle 3 | # Edit at https://www.gitignore.io/?templates=soliditytruffle 4 | 5 | ### SolidityTruffle ### 6 | # depedencies 7 | node_modules 8 | 9 | # testing 10 | coverage 11 | 12 | # production 13 | build 14 | build_webpack 15 | 16 | # misc 17 | .DS_Store 18 | .env 19 | npm-debug.log 20 | .truffle-solidity-loader 21 | .vagrant/** 22 | blockchain/geth/** 23 | blockchain/keystore/** 24 | blockchain/history 25 | 26 | #truffle 27 | .tern-port 28 | package-lock.json 29 | 30 | # buidler 31 | artifacts 32 | cache 33 | 34 | # End of https://www.gitignore.io/api/soliditytruffle 35 | 36 | .vscode/ 37 | .idea/ 38 | types/truffle-contracts 39 | types/web3-v1-contracts 40 | 41 | generated 42 | subgraph.yaml 43 | 44 | artifacts/development 45 | 46 | # Docker data 47 | data -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "overrides": [ 6 | { 7 | "files": "*.sol", 8 | "options": { 9 | "endOfLine": "auto", 10 | "printWidth": 150, 11 | "tabWidth": 4, 12 | "useTabs": false, 13 | "singleQuote": false, 14 | "bracketSpacing": false, 15 | "explicitTypes": "always" 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "plugins": ["prettier"], 4 | "rules": { 5 | "prettier/prettier": "error", 6 | "compiler-version": ["error", "^0.6.10"], 7 | "not-rely-on-time": "off", 8 | "max-line-length": ["error", 150], 9 | "quotes": ["error", "double"], 10 | "reason-string": ["error", {"maxLength": 50}], 11 | "max-states-count": ["warn", 16] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 10 4 | 5 | cache: yarn 6 | 7 | before_script: 8 | - echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p 9 | 10 | script: 11 | - yarn test 12 | - yarn deploy:development 13 | - yarn lint 14 | - yarn codechecks 15 | - cd subgraph 16 | - yarn build 17 | 18 | branches: 19 | only: 20 | - master 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Table of Contents 2 | 3 | 4 | - [1. Introduction](#1-introduction) 5 | - [2. Implementation](#2-implementation) 6 | - [2.1. Flow Protocol Smart Contracts on Ethereum](#21-flow-protocol-smart-contracts-on-ethereum) 7 | - [2.2. Substrate implementation - LaminarChain as parachain on Polkadot](#22-substrate-implementation---laminarchain-as-parachain-on-polkadot) 8 | 9 | 10 | 11 | # 1. Introduction 12 | Laminar aims to create an open finance platform along with financial assets to serve traders from both the crypto and mainstream finance worlds. Please find details of Laminar and its Flow Protocols for synthetic asset and margin trading [here](https://github.com/laminar-protocol/laminar-chain). 13 | 14 | # 2. Implementation 15 | We have been R&D our protocol on Ethereum, where the network is highly secure with valuable assets as basis for trading. There are also existing DeFi community and DeFi building blocks such as stablecoin. The Ethereum implementation will be the value gateway, and our Substrate implementation - the LaminarChain which will later connect to Polkadot will be the specialized high performance financial service chain. We can best serve both mainstream finance and crypto traders and service providers by leveraging the best of both worlds. 16 | 17 | ### 2.1. Flow Protocol Smart Contracts on Ethereum 18 | A reference implementation of the Flow Margin Trading Protocol, Synthetic Asset Protocol and Money Market Protocol smart contracts are deployed on Ethereum Kovan test net. 19 | 20 | [The Flow Exchange Web App](https://flow.laminar.one/) gives people a friendly and easy way to test the functionalities of the protocols. It is still work in progress, so please kindly excuse bugs and provide feedback to help us improve. 21 | 22 | [The Laminar Flow Protocol Subgraph](https://thegraph.com/explorer/subgraph/laminar-protocol/flow-protocol-subgraph) provides an easy way to query the synthetic assets, margin positions, liquidity pools, and other useful information off the blockchain. 23 | 24 | We will continue to develop and improve the protocols, and new contracts would be deployed as we progress. Find the latest deployed contracts [here](https://github.com/laminar-protocol/flow-protocol-ethereum/blob/master/artifacts/deployment.json). 25 | 26 | Please refer to [the Wiki Guide](https://github.com/laminar-protocol/flow-protocol-ethereum/wiki) for using and developing on top of these contracts. 27 | 28 | Please refer to [Testing Laminar Flow Synthetic Assets & Margin Trading Protocols](https://medium.com/laminar/testing-laminar-flow-synthetic-assets-margin-trading-protocols-130c5826cf4d?source=collection_home---6------1-----------------------) for exploring our contracts and dApp. 29 | 30 | ### 2.2. Substrate implementation - LaminarChain as parachain on Polkadot 31 | See more details [here](https://github.com/laminar-protocol/laminar-chain) -------------------------------------------------------------------------------- /artifacts/kovan/abi/ERC20Detailed.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "string", 6 | "name": "name", 7 | "type": "string" 8 | }, 9 | { 10 | "internalType": "string", 11 | "name": "symbol", 12 | "type": "string" 13 | }, 14 | { 15 | "internalType": "uint8", 16 | "name": "decimals", 17 | "type": "uint8" 18 | } 19 | ], 20 | "stateMutability": "nonpayable", 21 | "type": "constructor" 22 | }, 23 | { 24 | "anonymous": false, 25 | "inputs": [ 26 | { 27 | "indexed": true, 28 | "internalType": "address", 29 | "name": "owner", 30 | "type": "address" 31 | }, 32 | { 33 | "indexed": true, 34 | "internalType": "address", 35 | "name": "spender", 36 | "type": "address" 37 | }, 38 | { 39 | "indexed": false, 40 | "internalType": "uint256", 41 | "name": "value", 42 | "type": "uint256" 43 | } 44 | ], 45 | "name": "Approval", 46 | "type": "event" 47 | }, 48 | { 49 | "anonymous": false, 50 | "inputs": [ 51 | { 52 | "indexed": true, 53 | "internalType": "address", 54 | "name": "from", 55 | "type": "address" 56 | }, 57 | { 58 | "indexed": true, 59 | "internalType": "address", 60 | "name": "to", 61 | "type": "address" 62 | }, 63 | { 64 | "indexed": false, 65 | "internalType": "uint256", 66 | "name": "value", 67 | "type": "uint256" 68 | } 69 | ], 70 | "name": "Transfer", 71 | "type": "event" 72 | }, 73 | { 74 | "inputs": [ 75 | { 76 | "internalType": "address", 77 | "name": "owner", 78 | "type": "address" 79 | }, 80 | { 81 | "internalType": "address", 82 | "name": "spender", 83 | "type": "address" 84 | } 85 | ], 86 | "name": "allowance", 87 | "outputs": [ 88 | { 89 | "internalType": "uint256", 90 | "name": "", 91 | "type": "uint256" 92 | } 93 | ], 94 | "stateMutability": "view", 95 | "type": "function" 96 | }, 97 | { 98 | "inputs": [ 99 | { 100 | "internalType": "address", 101 | "name": "spender", 102 | "type": "address" 103 | }, 104 | { 105 | "internalType": "uint256", 106 | "name": "amount", 107 | "type": "uint256" 108 | } 109 | ], 110 | "name": "approve", 111 | "outputs": [ 112 | { 113 | "internalType": "bool", 114 | "name": "", 115 | "type": "bool" 116 | } 117 | ], 118 | "stateMutability": "nonpayable", 119 | "type": "function" 120 | }, 121 | { 122 | "inputs": [ 123 | { 124 | "internalType": "address", 125 | "name": "account", 126 | "type": "address" 127 | } 128 | ], 129 | "name": "balanceOf", 130 | "outputs": [ 131 | { 132 | "internalType": "uint256", 133 | "name": "", 134 | "type": "uint256" 135 | } 136 | ], 137 | "stateMutability": "view", 138 | "type": "function" 139 | }, 140 | { 141 | "inputs": [], 142 | "name": "totalSupply", 143 | "outputs": [ 144 | { 145 | "internalType": "uint256", 146 | "name": "", 147 | "type": "uint256" 148 | } 149 | ], 150 | "stateMutability": "view", 151 | "type": "function" 152 | }, 153 | { 154 | "inputs": [ 155 | { 156 | "internalType": "address", 157 | "name": "recipient", 158 | "type": "address" 159 | }, 160 | { 161 | "internalType": "uint256", 162 | "name": "amount", 163 | "type": "uint256" 164 | } 165 | ], 166 | "name": "transfer", 167 | "outputs": [ 168 | { 169 | "internalType": "bool", 170 | "name": "", 171 | "type": "bool" 172 | } 173 | ], 174 | "stateMutability": "nonpayable", 175 | "type": "function" 176 | }, 177 | { 178 | "inputs": [ 179 | { 180 | "internalType": "address", 181 | "name": "sender", 182 | "type": "address" 183 | }, 184 | { 185 | "internalType": "address", 186 | "name": "recipient", 187 | "type": "address" 188 | }, 189 | { 190 | "internalType": "uint256", 191 | "name": "amount", 192 | "type": "uint256" 193 | } 194 | ], 195 | "name": "transferFrom", 196 | "outputs": [ 197 | { 198 | "internalType": "bool", 199 | "name": "", 200 | "type": "bool" 201 | } 202 | ], 203 | "stateMutability": "nonpayable", 204 | "type": "function" 205 | }, 206 | { 207 | "inputs": [], 208 | "name": "name", 209 | "outputs": [ 210 | { 211 | "internalType": "string", 212 | "name": "", 213 | "type": "string" 214 | } 215 | ], 216 | "stateMutability": "view", 217 | "type": "function" 218 | }, 219 | { 220 | "inputs": [], 221 | "name": "symbol", 222 | "outputs": [ 223 | { 224 | "internalType": "string", 225 | "name": "", 226 | "type": "string" 227 | } 228 | ], 229 | "stateMutability": "view", 230 | "type": "function" 231 | }, 232 | { 233 | "inputs": [], 234 | "name": "decimals", 235 | "outputs": [ 236 | { 237 | "internalType": "uint8", 238 | "name": "", 239 | "type": "uint8" 240 | } 241 | ], 242 | "stateMutability": "view", 243 | "type": "function" 244 | } 245 | ] -------------------------------------------------------------------------------- /artifacts/kovan/abi/FaucetInterface.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "address", 6 | "name": "_owner", 7 | "type": "address" 8 | }, 9 | { 10 | "internalType": "uint256", 11 | "name": "value", 12 | "type": "uint256" 13 | } 14 | ], 15 | "name": "allocateTo", 16 | "outputs": [], 17 | "stateMutability": "nonpayable", 18 | "type": "function" 19 | } 20 | ] -------------------------------------------------------------------------------- /artifacts/kovan/abi/PriceOracleInterface.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "addr", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "sender", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "uint256", 20 | "name": "price", 21 | "type": "uint256" 22 | } 23 | ], 24 | "name": "PriceFeeded", 25 | "type": "event", 26 | "signature": "0x3105faf42de9614e0ddc10fabac5d5aaf57cc1632093d5e3e42e89a505edb7c8" 27 | }, 28 | { 29 | "anonymous": false, 30 | "inputs": [ 31 | { 32 | "indexed": true, 33 | "internalType": "address", 34 | "name": "addr", 35 | "type": "address" 36 | }, 37 | { 38 | "indexed": false, 39 | "internalType": "uint256", 40 | "name": "price", 41 | "type": "uint256" 42 | } 43 | ], 44 | "name": "PriceUpdated", 45 | "type": "event", 46 | "signature": "0x0d86730737b142fc160892fa8a0f2db687a92a0e294d1ad70624cf5acef03b84" 47 | }, 48 | { 49 | "inputs": [], 50 | "name": "isPriceOracle", 51 | "outputs": [ 52 | { 53 | "internalType": "bool", 54 | "name": "", 55 | "type": "bool" 56 | } 57 | ], 58 | "stateMutability": "pure", 59 | "type": "function", 60 | "constant": true, 61 | "signature": "0x66331bba" 62 | }, 63 | { 64 | "inputs": [ 65 | { 66 | "internalType": "address", 67 | "name": "addr", 68 | "type": "address" 69 | } 70 | ], 71 | "name": "getPrice", 72 | "outputs": [ 73 | { 74 | "internalType": "uint256", 75 | "name": "", 76 | "type": "uint256" 77 | } 78 | ], 79 | "stateMutability": "nonpayable", 80 | "type": "function", 81 | "signature": "0x41976e09" 82 | }, 83 | { 84 | "inputs": [ 85 | { 86 | "internalType": "address", 87 | "name": "addr", 88 | "type": "address" 89 | } 90 | ], 91 | "name": "readPrice", 92 | "outputs": [ 93 | { 94 | "internalType": "uint256", 95 | "name": "", 96 | "type": "uint256" 97 | } 98 | ], 99 | "stateMutability": "view", 100 | "type": "function", 101 | "constant": true, 102 | "signature": "0x033d497a" 103 | } 104 | ] -------------------------------------------------------------------------------- /artifacts/kovan/deployment.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseToken": "0xbF7A7169562078c96f0eC1A8aFD6aE50f12e5A99", 3 | "cToken": "0x0A1e4D0B5c71B955c0a5993023fc48bA6E380496", 4 | "moneyMarket": "0x034Cbe2206675328d62042007d673aD15D1F6473", 5 | "iToken": "0x8104D8353A78071a3fe8a4bbB4F779481D0BDe16", 6 | "oracle": "0xA6A675e87Daf880e57ECe0c9178fafF13b7290b0", 7 | "syntheticProtocol": "0x29a042b9D50101B921958cE5A24aaB6CB37b1957", 8 | "fEUR": "0x38F0e0e4749e1bb578C435114C94497DE641BC29", 9 | "fJPY": "0xC45820FdB7B811bE0641A390A9E486e996B3Adeb", 10 | "fCAD": "0xDDe97588cc64e997e9FEF888D8BEa990e1dDF953", 11 | "fCHF": "0x21cBc7cFD050f5c01528EE8cCC30E1Ccf3C2DA12", 12 | "fGBP": "0xe76268950c0F346a0BBc4F11A371D1d6AB600Fd9", 13 | "fAUD": "0x78429eaF37E6B217850aCf996A79c52D275eD315", 14 | "fUSOIL": "0x8d5Da0866Dd37528509A2F7e0B5eB1Dbb0ff5160", 15 | "fXAU": "0xDfF7C8cB5304d28Fb7a62F299a923852d281b3ad", 16 | "fBTC": "0x0a2934E52e15329Af178598EAb40ca7Fac1f86B9", 17 | "fETH": "0xA021c275A105FdB4e7fdc705B5D1E1a34217d221", 18 | "marginProtocol": "0x92b0C6E37cd631D02EB35e08FA592f5c3c64bE53", 19 | "marginProtocolSafety": "0x269C39494767cbEd2913658600b9dBE1194Cc16d", 20 | "marginProtocolLiquidated": "0xE87304b80A71403e1f825634c7Cc963172541BD6", 21 | "marginProtocolAccPositions": "0x94B7443f03C1f3156de93DFD6E8041C7877690bd", 22 | "marginProtocolConfig": "0xCe86D8c4A6A39DDAAcBB67Ea6862590bA6b9Fd9d", 23 | "marginPoolRegistry": "0xd0766762298a569D872C8804f30281baAeC19160", 24 | "marginPoolACME": "0xA06159257aC5fc922F05915439e12665d19b82f5", 25 | "marginPoolGeneral": "0x8eC93Aad548204a3939661CE3a561605730Eb2d7", 26 | "syntheticPoolGeneral": "0x6182A475Eb130c1E7c78E161421db2Ee7bceFdbb", 27 | "syntheticPoolXYZ": "0xc006F6cAA51D2c998093F6eD03c6bF7cAc546b2e" 28 | } -------------------------------------------------------------------------------- /buidler.config.js: -------------------------------------------------------------------------------- 1 | usePlugin('@nomiclabs/buidler-truffle5'); // eslint-disable-line 2 | 3 | module.exports = { 4 | defaultNetwork: 'buidlerevm', 5 | networks: { 6 | buidlerevm: { 7 | gas: 9500000, 8 | allowUnlimitedContractSize: true, 9 | }, 10 | }, 11 | solc: { 12 | version: '0.6.10', 13 | optimizer: {enabled: true, runs: 200}, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /codechecks.yml: -------------------------------------------------------------------------------- 1 | checks: 2 | - name: eth-gas-reporter/codechecks -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | contract Migrations { 5 | address public owner; 6 | uint256 public lastCompletedMigration; 7 | 8 | modifier restricted() { 9 | if (msg.sender == owner) _; 10 | } 11 | 12 | constructor() public { 13 | owner = msg.sender; 14 | } 15 | 16 | function setCompleted(uint256 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/impls/FlowProtocolBase.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 5 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol"; 6 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol"; 7 | import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol"; 8 | import "@openzeppelin/contracts-ethereum-package/contracts/math/Math.sol"; 9 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 10 | import "@openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol"; 11 | 12 | import "../libs/Percentage.sol"; 13 | 14 | import "../interfaces/PriceOracleInterface.sol"; 15 | import "../interfaces/MoneyMarketInterface.sol"; 16 | 17 | contract FlowProtocolBase is Initializable, OwnableUpgradeSafe, ReentrancyGuardUpgradeSafe { 18 | using SafeMath for uint256; 19 | using SafeERC20 for IERC20; 20 | 21 | PriceOracleInterface public oracle; 22 | MoneyMarketInterface public moneyMarket; 23 | 24 | int256 private constant MAX_INT = type(int256).max; 25 | uint256 private constant MAX_UINT = type(uint256).max; 26 | 27 | uint256 public maxSpread; 28 | 29 | function initialize(PriceOracleInterface _oracle, MoneyMarketInterface _moneyMarket) public initializer { 30 | OwnableUpgradeSafe.__Ownable_init(); 31 | ReentrancyGuardUpgradeSafe.__ReentrancyGuard_init(); 32 | 33 | oracle = _oracle; 34 | moneyMarket = _moneyMarket; 35 | 36 | moneyMarket.baseToken().safeApprove(address(moneyMarket), MAX_UINT); 37 | 38 | maxSpread = 1 ether / 10; // 10% TODO: pick a justified value 39 | } 40 | 41 | function setMaxSpread(uint256 _maxSpread) external onlyOwner { 42 | maxSpread = _maxSpread; 43 | } 44 | 45 | function getPrice(address _token) internal returns (uint256) { 46 | uint256 price = oracle.getPrice(_token); 47 | require(price > 0, "no oracle price"); 48 | 49 | return price; 50 | } 51 | 52 | function _getSpread(uint256 _spread) internal view returns (uint256) { 53 | require(_spread > 0, "Token disabled for this pool"); 54 | return Math.min(_spread, maxSpread); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /contracts/impls/LiquidityPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 5 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol"; 6 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol"; 7 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 8 | 9 | import "../interfaces/LiquidityPoolInterface.sol"; 10 | import "../interfaces/MoneyMarketInterface.sol"; 11 | 12 | abstract contract LiquidityPool is Initializable, OwnableUpgradeSafe, LiquidityPoolInterface { 13 | using SafeERC20 for IERC20; 14 | 15 | MoneyMarketInterface public override moneyMarket; 16 | address public override protocol; 17 | 18 | function initialize(MoneyMarketInterface _moneyMarket, address _protocol) public virtual initializer { 19 | OwnableUpgradeSafe.__Ownable_init(); 20 | 21 | moneyMarket = _moneyMarket; 22 | protocol = _protocol; 23 | } 24 | 25 | function approveToProtocol(uint256 _amount) external override onlyOwner { 26 | moneyMarket.iToken().safeApprove(protocol, _amount); 27 | } 28 | 29 | function getOwner() public override view returns (address) { 30 | return OwnableUpgradeSafe.owner(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /contracts/impls/MintableToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 4 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract MintableToken is OwnableUpgradeSafe, ERC20UpgradeSafe { 7 | function initialize(string memory name, string memory symbol) public initializer { 8 | OwnableUpgradeSafe.__Ownable_init(); 9 | ERC20UpgradeSafe.__ERC20_init(name, symbol); 10 | } 11 | 12 | function mint(address account, uint256 amount) public onlyOwner { 13 | _mint(account, amount); 14 | } 15 | 16 | function burn(address account, uint256 amount) public onlyOwner { 17 | _burn(account, amount); 18 | } 19 | 20 | function ownerTransferFrom( 21 | address sender, 22 | address recipient, 23 | uint256 amount 24 | ) public onlyOwner { 25 | _transfer(sender, recipient, amount); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /contracts/impls/margin/MarginLiquidityPoolRegistry.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | pragma experimental ABIEncoderV2; // not experimental anymore 4 | 5 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 6 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol"; 7 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol"; 8 | import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol"; 9 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 10 | import "@openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol"; 11 | 12 | import "../../interfaces/MarginLiquidityPoolInterface.sol"; 13 | 14 | import "./MarginMarketLib.sol"; 15 | 16 | contract MarginLiquidityPoolRegistry is Initializable, OwnableUpgradeSafe, ReentrancyGuardUpgradeSafe { 17 | using SafeMath for uint256; 18 | using SafeERC20 for IERC20; 19 | 20 | MarginMarketLib.MarketData private market; 21 | 22 | mapping(MarginLiquidityPoolInterface => bool) public isVerifiedPool; 23 | mapping(MarginLiquidityPoolInterface => bool) public poolHasPaidDeposits; 24 | mapping(MarginLiquidityPoolInterface => bool) public isMarginCalled; 25 | mapping(MarginLiquidityPoolInterface => uint256) public poolMarginCallITokens; 26 | mapping(MarginLiquidityPoolInterface => uint256) public poolLiquidationITokens; 27 | 28 | function initialize(MarginMarketLib.MarketData memory _market) public initializer { 29 | OwnableUpgradeSafe.__Ownable_init(); 30 | ReentrancyGuardUpgradeSafe.__ReentrancyGuard_init(); 31 | 32 | market = _market; 33 | } 34 | 35 | /** 36 | * @dev Register a new pool by sending the combined margin and liquidation fees. 37 | * @param _pool The MarginLiquidityPool. 38 | */ 39 | function registerPool(MarginLiquidityPoolInterface _pool) public nonReentrant { 40 | require(address(_pool) != address(0), "0"); 41 | require(!poolHasPaidDeposits[_pool], "PR1"); 42 | 43 | uint256 poolMarginCallDeposit = market.config.poolMarginCallDeposit(); 44 | uint256 poolLiquidationDeposit = market.config.poolLiquidationDeposit(); 45 | uint256 feeSum = poolMarginCallDeposit.add(poolLiquidationDeposit); 46 | market.moneyMarket.baseToken().safeTransferFrom(msg.sender, address(this), feeSum); 47 | market.moneyMarket.baseToken().safeApprove(address(market.moneyMarket), feeSum); 48 | 49 | poolMarginCallITokens[_pool] = market.moneyMarket.mintTo(address(market.protocolSafety), poolMarginCallDeposit); 50 | poolLiquidationITokens[_pool] = market.moneyMarket.mintTo(address(market.protocolSafety), poolLiquidationDeposit); 51 | poolHasPaidDeposits[_pool] = true; 52 | } 53 | 54 | /** 55 | * @dev Verify a new pool, only for the owner. 56 | * @param _pool The MarginLiquidityPool. 57 | */ 58 | function verifyPool(MarginLiquidityPoolInterface _pool) public onlyOwner { 59 | require(poolHasPaidDeposits[_pool], "PF1"); 60 | require(!isVerifiedPool[_pool], "PF2"); 61 | isVerifiedPool[_pool] = true; 62 | } 63 | 64 | /** 65 | * @dev Unverify a pool, only for the owner. 66 | * @param _pool The MarginLiquidityPool. 67 | */ 68 | function unverifyPool(MarginLiquidityPoolInterface _pool) public onlyOwner { 69 | require(isVerifiedPool[_pool], "PV1"); 70 | isVerifiedPool[_pool] = false; 71 | } 72 | 73 | /** 74 | * @dev Margin call a pool, only used by the address(market.protocolSafety). 75 | * @param _pool The MarginLiquidityPool. 76 | */ 77 | function marginCallPool(MarginLiquidityPoolInterface _pool) external returns (uint256) { 78 | require(msg.sender == address(market.protocolSafety), "Only safety protocol can call this function"); 79 | require(!isMarginCalled[_pool], "PM1"); 80 | 81 | uint256 marginCallITokens = poolMarginCallITokens[_pool]; 82 | 83 | isMarginCalled[_pool] = true; 84 | poolMarginCallITokens[_pool] = 0; 85 | 86 | return marginCallITokens; 87 | } 88 | 89 | /** 90 | * @dev Margin call a pool, only used by the address(market.protocolSafety). 91 | * @param _pool The MarginLiquidityPool. 92 | */ 93 | function liquidatePool(MarginLiquidityPoolInterface _pool) external returns (uint256) { 94 | require(msg.sender == address(market.protocolSafety), "Only safety protocol can call this function"); 95 | require(isMarginCalled[_pool], "PM1"); 96 | 97 | uint256 liquidationCallITokens = poolLiquidationITokens[_pool]; 98 | 99 | isMarginCalled[_pool] = false; 100 | poolLiquidationITokens[_pool] = 0; 101 | 102 | return liquidationCallITokens; 103 | } 104 | 105 | /** 106 | * @dev Make pool safe, only used by address(market.protocolSafety). 107 | * @param _pool The MarginLiquidityPool. 108 | */ 109 | function makePoolSafe(MarginLiquidityPoolInterface _pool) external { 110 | require(msg.sender == address(market.protocolSafety), "Only safety protocol can call this function"); 111 | require(isMarginCalled[_pool], "PS1"); 112 | 113 | uint256 poolMarginCallDeposit = market.config.poolMarginCallDeposit(); 114 | market.moneyMarket.baseToken().safeTransferFrom(msg.sender, address(this), poolMarginCallDeposit); 115 | market.moneyMarket.baseToken().safeApprove(address(market.moneyMarket), poolMarginCallDeposit); 116 | 117 | poolMarginCallITokens[_pool] = market.moneyMarket.mintTo(address(market.protocolSafety), poolMarginCallDeposit); 118 | isMarginCalled[_pool] = false; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /contracts/impls/oracles/ChainLinkOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@chainlink/contracts/src/v0.6/interfaces/AggregatorInterface.sol"; 5 | import "@chainlink/contracts/src/v0.6/ChainlinkClient.sol"; 6 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 7 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 8 | 9 | import "../../interfaces/PriceOracleInterface.sol"; 10 | 11 | contract ChainLinkOracle is ChainlinkClient, PriceOracleInterface, Initializable, OwnableUpgradeSafe { 12 | mapping(address => AggregatorInterface) public aggregators; 13 | address public usdToken; 14 | 15 | function initialize( 16 | address _link, 17 | address _usdToken, 18 | address[] memory _currencyReferences, 19 | address[] memory _tokenReferences 20 | ) public initializer { 21 | OwnableUpgradeSafe.__Ownable_init(); 22 | 23 | require(_currencyReferences.length == _tokenReferences.length, "Token count must match oracle count"); 24 | 25 | if (_link == address(0)) { 26 | setPublicChainlinkToken(); 27 | } else { 28 | setChainlinkToken(_link); 29 | } 30 | 31 | usdToken = _usdToken; 32 | 33 | for (uint256 i = 0; i < _currencyReferences.length; i++) { 34 | aggregators[_tokenReferences[i]] = AggregatorInterface(_currencyReferences[i]); 35 | } 36 | } 37 | 38 | function setOracleAddress(address _token, address _aggregator) public onlyOwner { 39 | aggregators[_token] = AggregatorInterface(_aggregator); 40 | } 41 | 42 | function getPrice(address _key) public override returns (uint256) { 43 | return _getPrice(_key); 44 | } 45 | 46 | function readPrice(address _key) public override view returns (uint256) { 47 | return _getPrice(_key); 48 | } 49 | 50 | function isPriceOracle() external override pure returns (bool) { 51 | return true; 52 | } 53 | 54 | function _getPrice(address _key) private view returns (uint256) { 55 | if (_key == usdToken) { 56 | return 1e18; 57 | } 58 | 59 | require(address(aggregators[_key]) != address(0), "Invalid token address for oracle"); 60 | 61 | int256 price = aggregators[_key].latestAnswer(); 62 | require(price > 0, "no price available"); 63 | 64 | return uint256(price).mul(1e10); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /contracts/impls/oracles/PriceOracleConfig.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 5 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 6 | 7 | import "../../libs/Percentage.sol"; 8 | 9 | contract PriceOracleConfig is Initializable, OwnableUpgradeSafe { 10 | // max price diff since last input 11 | Percentage.Percent public oracleDeltaLastLimit; 12 | // max price diff since last snapshot 13 | Percentage.Percent public oracleDeltaSnapshotLimit; 14 | // min time between snapshots 15 | uint256 public oracleDeltaSnapshotTime; 16 | // price record is considered expired after this amount of time 17 | uint256 public expireIn; 18 | 19 | function initialize() public virtual initializer { 20 | OwnableUpgradeSafe.__Ownable_init(); 21 | 22 | // TODO: all those values should be from constructor parameter 23 | oracleDeltaLastLimit = Percentage.fromFraction(10, 100); 24 | oracleDeltaSnapshotLimit = Percentage.fromFraction(15, 100); 25 | oracleDeltaSnapshotTime = 1 hours; 26 | expireIn = 10 minutes; 27 | } 28 | 29 | function setOracleDeltaLastLimit(uint256 limit) public onlyOwner { 30 | oracleDeltaLastLimit.value = limit; 31 | } 32 | 33 | function setOracleDeltaSnapshotLimit(uint256 limit) public onlyOwner { 34 | oracleDeltaSnapshotLimit.value = limit; 35 | } 36 | 37 | function setOracleDeltaSnapshotTime(uint256 time) public onlyOwner { 38 | oracleDeltaSnapshotTime = time; 39 | } 40 | 41 | function setExpireIn(uint256 time) public onlyOwner { 42 | expireIn = time; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/impls/oracles/SimplePriceOracle.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../../interfaces/PriceOracleInterface.sol"; 5 | import "../../roles/PriceFeederRole.sol"; 6 | import "../../libs/Arrays.sol"; 7 | import "../../libs/Percentage.sol"; 8 | 9 | import "./PriceOracleConfig.sol"; 10 | 11 | library PriceOracleStructs { 12 | struct PriceRecord { 13 | uint256 price; 14 | uint256 timestamp; 15 | } 16 | } 17 | 18 | /// Price oracle data source. Only for inheritance. 19 | contract PriceOracleDataSource { 20 | // key => feeder => price record 21 | mapping(address => mapping(address => PriceOracleStructs.PriceRecord)) private priceRecords; 22 | // key => hasUpdate 23 | mapping(address => bool) internal hasUpdate; 24 | 25 | function _feedPrice(address key, uint256 price) internal { 26 | priceRecords[key][msg.sender] = PriceOracleStructs.PriceRecord(price, now); 27 | hasUpdate[key] = true; 28 | } 29 | 30 | function findMedianPrice( 31 | address key, 32 | uint256 expireIn, 33 | address[] storage priceFeeders 34 | ) internal view returns (uint256) { 35 | uint256 expireAt = now - expireIn; 36 | 37 | // filter active price records, put them in an array with max possible length 38 | uint256[] memory validPricesWithMaxCapacity = new uint256[](priceFeeders.length); 39 | uint256 validPricesLength = 0; 40 | for (uint256 i = 0; i < priceFeeders.length; i++) { 41 | PriceOracleStructs.PriceRecord storage record = priceRecords[key][priceFeeders[i]]; 42 | if (record.timestamp > expireAt) { 43 | validPricesWithMaxCapacity[validPricesLength] = record.price; 44 | validPricesLength += 1; 45 | } 46 | } 47 | 48 | if (validPricesLength == 0) { 49 | return 0; 50 | } 51 | 52 | // move active price records into an array just long enough to hold all records 53 | uint256[] memory validPrices = new uint256[](validPricesLength); 54 | for (uint256 i = 0; i < validPricesLength; i++) { 55 | validPrices[i] = validPricesWithMaxCapacity[i]; 56 | } 57 | 58 | return Arrays.findMedian(validPrices); 59 | } 60 | } 61 | 62 | contract SimplePriceOracle is PriceOracleConfig, PriceOracleInterface, PriceFeederRole, PriceOracleDataSource { 63 | mapping(address => uint256) private cachedPrices; 64 | mapping(address => PriceOracleStructs.PriceRecord) private priceSnapshots; 65 | 66 | function initialize() public override(PriceOracleConfig, PriceFeederRole) initializer { 67 | PriceOracleConfig.initialize(); 68 | PriceFeederRole.initialize(); 69 | } 70 | 71 | function isPriceOracle() external override pure returns (bool) { 72 | return true; 73 | } 74 | 75 | event PriceUpdated(address indexed addr, uint256 price); 76 | 77 | function feedPrice(address key, uint256 price) external onlyPriceFeeder { 78 | _feedPrice(key, price); 79 | 80 | emit PriceFeeded(key, msg.sender, price); 81 | } 82 | 83 | function getPrice(address key) external override returns (uint256) { 84 | if (hasUpdate[key]) { 85 | uint256 price = findMedianPrice(key, expireIn, priceFeeders); 86 | if (price > 0) { 87 | _setPrice(key, price); 88 | } 89 | hasUpdate[key] = false; 90 | } 91 | return cachedPrices[key]; 92 | } 93 | 94 | function readPrice(address key) external override view returns (uint256) { 95 | if (hasUpdate[key]) { 96 | uint256 price = findMedianPrice(key, expireIn, priceFeeders); 97 | if (price > 0) { 98 | return _calculateCapPrice(key, price); 99 | } 100 | } 101 | return cachedPrices[key]; 102 | } 103 | 104 | function _calculateCapPrice(address addr, uint256 price) private view returns (uint256) { 105 | require(price != 0, "Invalid price"); 106 | 107 | PriceOracleStructs.PriceRecord storage snapshotPrice = priceSnapshots[addr]; 108 | uint256 lastPrice = cachedPrices[addr]; 109 | uint256 price2 = _capPrice(price, lastPrice, oracleDeltaLastLimit); 110 | uint256 price3 = _capPrice(price2, snapshotPrice.price, oracleDeltaSnapshotLimit); 111 | 112 | return price3; 113 | } 114 | 115 | function _setPrice(address addr, uint256 price) private { 116 | uint256 finalPrice = _calculateCapPrice(addr, price); 117 | 118 | PriceOracleStructs.PriceRecord storage snapshotPrice = priceSnapshots[addr]; 119 | if (snapshotPrice.timestamp + oracleDeltaSnapshotTime < now) { 120 | snapshotPrice.price = finalPrice; 121 | snapshotPrice.timestamp = now; 122 | } 123 | 124 | cachedPrices[addr] = finalPrice; 125 | 126 | emit PriceUpdated(addr, finalPrice); 127 | } 128 | 129 | function _capPrice( 130 | uint256 current, 131 | uint256 last, 132 | Percentage.Percent storage limit 133 | ) private pure returns (uint256) { 134 | if (last == 0) { 135 | return current; 136 | } 137 | uint256 price = current; 138 | uint256 cap = Percentage.mulPercent(last, limit); 139 | if (current > last) { 140 | uint256 diff = current - last; 141 | if (diff > cap) { 142 | price = last + cap; 143 | } 144 | } else if (current < last) { 145 | uint256 diff = last - current; 146 | if (diff > cap) { 147 | price = last - cap; 148 | } 149 | } 150 | return price; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /contracts/impls/synthetic/SyntheticLiquidityPool.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 5 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol"; 6 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/SafeERC20.sol"; 7 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 8 | 9 | import "../../interfaces/SyntheticLiquidityPoolInterface.sol"; 10 | 11 | import "../LiquidityPool.sol"; 12 | import "./SyntheticFlowProtocol.sol"; 13 | import "./SyntheticFlowToken.sol"; 14 | 15 | contract SyntheticLiquidityPool is Initializable, OwnableUpgradeSafe, LiquidityPool, SyntheticLiquidityPoolInterface { 16 | mapping(address => uint256) public override spreadsPerToken; 17 | mapping(address => bool) public override allowedTokens; 18 | 19 | uint256 public override collateralRatio; 20 | 21 | function initialize(MoneyMarketInterface _moneyMarket, address _protocol) public override initializer { 22 | LiquidityPool.initialize(_moneyMarket, _protocol); 23 | collateralRatio = 0; // use fToken default 24 | } 25 | 26 | function getBidSpread(address _fToken) external override view returns (uint256) { 27 | if (allowedTokens[_fToken] && spreadsPerToken[_fToken] > 0) { 28 | return spreadsPerToken[_fToken]; 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | function getAskSpread(address _fToken) external override view returns (uint256) { 35 | if (allowedTokens[_fToken] && spreadsPerToken[_fToken] > 0) { 36 | return spreadsPerToken[_fToken]; 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | function getAdditionalCollateralRatio(address fToken) external override view returns (uint256) { 43 | if (allowedTokens[fToken]) { 44 | return collateralRatio; 45 | } 46 | return 0; 47 | } 48 | 49 | function setSpreadForToken(address _token, uint256 _value) external override onlyOwner { 50 | require(_value > 0, "Spread is 0"); 51 | spreadsPerToken[_token] = _value; 52 | 53 | emit SpreadUpdated(_token, _value); 54 | } 55 | 56 | function setCollateralRatio(uint256 _value) external override onlyOwner { 57 | collateralRatio = _value; 58 | 59 | emit AdditionalCollateralRatioUpdated(); 60 | } 61 | 62 | function enableToken(address _token, uint256 _spread) external override onlyOwner { 63 | require(_spread > 0, "Spread is 0"); 64 | 65 | allowedTokens[_token] = true; 66 | spreadsPerToken[_token] = _spread; 67 | } 68 | 69 | function disableToken(address _token) external override onlyOwner { 70 | allowedTokens[_token] = false; 71 | spreadsPerToken[_token] = 0; 72 | } 73 | 74 | function addCollateral(SyntheticFlowToken _token, uint256 _baseTokenAmount) external override onlyOwner { 75 | SyntheticFlowProtocol(protocol).addCollateral(_token, address(this), _baseTokenAmount); 76 | } 77 | 78 | function withdrawCollateral(SyntheticFlowToken _token) external override onlyOwner { 79 | SyntheticFlowProtocol(protocol).withdrawCollateral(_token); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /contracts/interfaces/CErc20Interface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity >=0.4.21 <0.7.0; 3 | 4 | interface CErc20Interface { 5 | function totalSupply() external view returns (uint256); 6 | 7 | function exchangeRateStored() external view returns (uint256); 8 | 9 | function getCash() external view returns (uint256); 10 | 11 | function totalBorrows() external view returns (uint256); 12 | 13 | function underlying() external view returns (address); 14 | 15 | function balanceOf(address owner) external view returns (uint256); 16 | 17 | function redeemUnderlying(uint256 redeemAmount) external returns (uint256); 18 | 19 | function mint(uint256 mintAmount) external returns (uint256); 20 | 21 | function transfer(address dst, uint256 amount) external returns (bool); 22 | 23 | function redeem(uint256 redeemTokens) external returns (uint256); 24 | 25 | function approve(address spender, uint256 amount) external returns (bool); 26 | 27 | function transferFrom( 28 | address src, 29 | address dst, 30 | uint256 amount 31 | ) external returns (bool); 32 | } 33 | -------------------------------------------------------------------------------- /contracts/interfaces/LiquidityPoolInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "./MoneyMarketInterface.sol"; 5 | 6 | interface LiquidityPoolInterface { 7 | function protocol() external returns (address); 8 | 9 | function moneyMarket() external returns (MoneyMarketInterface); 10 | 11 | function approveToProtocol(uint256 amount) external; 12 | 13 | function getOwner() external view returns (address); 14 | } 15 | -------------------------------------------------------------------------------- /contracts/interfaces/MarginLiquidityPoolInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | pragma experimental ABIEncoderV2; // not experimental anymore 4 | 5 | import "../impls/margin/MarginFlowProtocol.sol"; 6 | import "../impls/margin/MarginFlowProtocolConfig.sol"; 7 | import "./LiquidityPoolInterface.sol"; 8 | 9 | interface MarginLiquidityPoolInterface is LiquidityPoolInterface { 10 | function depositLiquidity(uint256 _realized) external returns (uint256); 11 | 12 | function increaseAllowanceForProtocol(uint256 _realized) external; 13 | 14 | function increaseAllowanceForProtocolSafety(uint256 _realized) external; 15 | 16 | function withdrawLiquidityOwner(uint256 _realized) external returns (uint256); 17 | 18 | function getLiquidity() external view returns (uint256); 19 | 20 | function getBidSpread(address baseToken, address quoteToken) external view returns (uint256); 21 | 22 | function getAskSpread(address baseToken, address quoteToken) external view returns (uint256); 23 | 24 | function spreadsPerTokenPair(address baseToken, address quoteToken) external view returns (uint256); 25 | 26 | function setSpreadForPair( 27 | address baseToken, 28 | address quoteToken, 29 | uint256 spread 30 | ) external; 31 | 32 | function enableToken( 33 | address baseToken, 34 | address quoteToken, 35 | uint256 spread, 36 | int256 _newSwapRateMarkup 37 | ) external; 38 | 39 | function disableToken(address baseToken, address quoteToken) external; 40 | 41 | function allowedTokens(address baseToken, address quoteToken) external returns (bool); 42 | 43 | function minLeverage() external returns (uint256); 44 | 45 | function maxLeverage() external returns (uint256); 46 | 47 | function minLeverageAmount() external returns (uint256); 48 | 49 | function getSwapRateMarkupForPair(address baseToken, address quoteToken) external view returns (int256); 50 | 51 | function setMinLeverage(uint256 _minLeverage) external; 52 | 53 | function setMaxLeverage(uint256 _maxLeverage) external; 54 | 55 | function setMinLeverageAmount(uint256 _newMinLeverageAmount) external; 56 | 57 | function setCurrentSwapRateMarkupForPair( 58 | address base, 59 | address quote, 60 | int256 newSwapRateMarkup 61 | ) external; 62 | 63 | event SpreadUpdated(address indexed baseToken, address indexed quoteToken, uint256 newSpread); 64 | } 65 | -------------------------------------------------------------------------------- /contracts/interfaces/MoneyMarketInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol"; 5 | 6 | interface MoneyMarketInterface { 7 | function baseToken() external view returns (IERC20); 8 | 9 | function iToken() external view returns (IERC20); 10 | 11 | function exchangeRate() external view returns (uint256); 12 | 13 | function mint(uint256 baseTokenAmount) external returns (uint256); 14 | 15 | function mintTo(address recipient, uint256 baseTokenAmount) external returns (uint256); 16 | 17 | function redeem(uint256 iTokenAmount) external returns (uint256); 18 | 19 | function redeemTo(address recipient, uint256 iTokenAmount) external returns (uint256); 20 | 21 | function redeemBaseToken(uint256 baseTokenAmount) external returns (uint256); 22 | 23 | function redeemBaseTokenTo(address recipient, uint256 baseTokenAmount) external returns (uint256); 24 | 25 | function convertAmountFromBase(uint256 _baseTokenAmount) external view returns (uint256); 26 | 27 | function convertAmountFromBase(uint256 rate, uint256 baseTokenAmount) external pure returns (uint256); 28 | 29 | function convertAmountToBase(uint256 iTokenAmount) external view returns (uint256); 30 | 31 | function convertAmountToBase(uint256 rate, uint256 iTokenAmount) external pure returns (uint256); 32 | 33 | function convertAmountFromBase(int256 _baseTokenAmount) external view returns (int256); 34 | 35 | function convertAmountFromBase(int256 rate, int256 baseTokenAmount) external pure returns (int256); 36 | 37 | function convertAmountToBase(int256 iTokenAmount) external view returns (int256); 38 | 39 | function convertAmountToBase(int256 rate, int256 iTokenAmount) external pure returns (int256); 40 | 41 | function totalHoldings() external view returns (uint256); 42 | 43 | event Minted(address indexed recipient, uint256 baseTokenAmount, uint256 iTokenAmount); 44 | event Redeemed(address indexed recipient, uint256 baseTokenAmount, uint256 iTokenAmount); 45 | } 46 | -------------------------------------------------------------------------------- /contracts/interfaces/PriceOracleInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | interface PriceOracleInterface { 5 | function isPriceOracle() external pure returns (bool); 6 | 7 | function getPrice(address addr) external returns (uint256); 8 | 9 | function readPrice(address addr) external view returns (uint256); 10 | 11 | event PriceFeeded(address indexed addr, address indexed sender, uint256 price); 12 | event PriceUpdated(address indexed addr, uint256 price); 13 | } 14 | -------------------------------------------------------------------------------- /contracts/interfaces/SyntheticLiquidityPoolInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../impls/synthetic/SyntheticFlowProtocol.sol"; 5 | import "../impls/synthetic/SyntheticFlowToken.sol"; 6 | 7 | import "./LiquidityPoolInterface.sol"; 8 | 9 | interface SyntheticLiquidityPoolInterface is LiquidityPoolInterface { 10 | function addCollateral(SyntheticFlowToken token, uint256 baseTokenAmount) external; 11 | 12 | function withdrawCollateral(SyntheticFlowToken token) external; 13 | 14 | function getBidSpread(address fToken) external view returns (uint256); 15 | 16 | function getAskSpread(address fToken) external view returns (uint256); 17 | 18 | function setSpreadForToken(address fToken, uint256 value) external; 19 | 20 | function spreadsPerToken(address fToken) external returns (uint256); 21 | 22 | function collateralRatio() external view returns (uint256); 23 | 24 | function getAdditionalCollateralRatio(address fToken) external view returns (uint256); 25 | 26 | function setCollateralRatio(uint256 value) external; 27 | 28 | function enableToken(address token, uint256 spread) external; 29 | 30 | function disableToken(address token) external; 31 | 32 | function allowedTokens(address token) external returns (bool); 33 | 34 | event SpreadUpdated(address indexed token, uint256 newSpread); 35 | event AdditionalCollateralRatioUpdated(); 36 | } 37 | -------------------------------------------------------------------------------- /contracts/libs/Arrays.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | library Arrays { 5 | /// Find median of an unsorted uint array. Median: item at index `length/2`(floor) of sorted array. 6 | /// Note that items in the input array might be swapped. 7 | function findMedian(uint256[] memory unsorted) internal pure returns (uint256) { 8 | require(unsorted.length > 0, "empty array has no median"); 9 | 10 | uint256 medianIndex = unsorted.length / 2; 11 | return Quick.select(unsorted, medianIndex); 12 | } 13 | } 14 | 15 | /// Quick select/sort. 16 | library Quick { 17 | /// Select kth smallest item, where k starts from 0. 18 | function select(uint256[] memory arr, uint256 k) internal pure returns (uint256) { 19 | require((0 <= k) && (k < arr.length), "k out of bound"); 20 | 21 | uint256 low = 0; 22 | uint256 high = arr.length - 1; 23 | while (high > low) { 24 | uint256 i = partition(arr, low, high); 25 | if (i > k) high = i - 1; 26 | else if (i < k) low = i + 1; 27 | else return arr[i]; 28 | } 29 | return arr[low]; 30 | } 31 | 32 | /// Partition the subarray a[low..high] so that a[low..j-1] <= a[j] <= a[j+1..high] and return j. 33 | function partition( 34 | uint256[] memory arr, 35 | uint256 low, 36 | uint256 high 37 | ) internal pure returns (uint256) { 38 | uint256 i = low; 39 | uint256 j = high + 1; 40 | uint256 v = arr[low]; 41 | 42 | while (true) { 43 | // find item on low to swap 44 | while (arr[++i] < v) { 45 | if (i == high) break; 46 | } 47 | // find item on high to swap 48 | while (v < arr[--j]) { 49 | if (j == low) break; 50 | } 51 | 52 | // check if pointer cross 53 | if (i >= j) break; 54 | 55 | (arr[i], arr[j]) = (arr[j], arr[i]); 56 | } 57 | 58 | // put partitioning item v at arr[j] 59 | (arr[low], arr[j]) = (arr[j], arr[low]); 60 | 61 | return j; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/libs/Percentage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol"; 4 | import "@openzeppelin/contracts-ethereum-package/contracts/math/SignedSafeMath.sol"; 5 | 6 | library Percentage { 7 | using SafeMath for uint256; 8 | using SignedSafeMath for int256; 9 | 10 | uint256 public constant ONE = 1e18; 11 | uint256 public constant ONE_BY_ONE = 1e36; 12 | 13 | int256 public constant SIGNED_ONE = 1e18; 14 | int256 public constant SIGNED_ONE_BY_ONE = 1e36; 15 | 16 | struct Percent { 17 | uint256 value; 18 | } 19 | 20 | struct SignedPercent { 21 | int256 value; 22 | } 23 | 24 | function fromFraction(uint256 numerator, uint256 denominator) internal pure returns (Percent memory) { 25 | if (numerator == 0) { 26 | // it is fine if denominator is 0 in this case 27 | return Percent(0); 28 | } 29 | return Percent(numerator.mul(ONE).div(denominator)); 30 | } 31 | 32 | function signedFromFraction(int256 numerator, int256 denominator) internal pure returns (SignedPercent memory) { 33 | if (numerator == 0) { 34 | // it is fine if denominator is 0 in this case 35 | return SignedPercent(0); 36 | } 37 | return SignedPercent(numerator.mul(SIGNED_ONE).div(denominator)); 38 | } 39 | 40 | function mulPercent(uint256 val, Percent memory percent) internal pure returns (uint256) { 41 | return val.mul(percent.value).div(ONE); 42 | } 43 | 44 | function signedMulPercent(int256 val, SignedPercent memory percent) internal pure returns (int256) { 45 | return val.mul(percent.value).div(SIGNED_ONE); 46 | } 47 | 48 | function divPercent(uint256 val, Percent memory percent) internal pure returns (uint256) { 49 | return val.mul(ONE).div(percent.value); 50 | } 51 | 52 | function oneOver(Percent memory percent) internal pure returns (Percent memory) { 53 | return Percent(ONE_BY_ONE.div(percent.value)); 54 | } 55 | 56 | function addPercent(Percent memory a, Percent memory b) internal pure returns (Percent memory) { 57 | return Percent(a.value.add(b.value)); 58 | } 59 | 60 | function signedAddPercent(SignedPercent memory a, SignedPercent memory b) internal pure returns (SignedPercent memory) { 61 | return SignedPercent(a.value.add(b.value)); 62 | } 63 | 64 | function subPercent(Percent memory a, Percent memory b) internal pure returns (Percent memory) { 65 | return Percent(a.value.sub(b.value)); 66 | } 67 | 68 | function signedSubPercent(SignedPercent memory a, SignedPercent memory b) internal pure returns (SignedPercent memory) { 69 | return SignedPercent(a.value.sub(b.value)); 70 | } 71 | 72 | function signedMulPercent(SignedPercent memory a, SignedPercent memory b) internal pure returns (SignedPercent memory) { 73 | return SignedPercent(a.value.mul(b.value).div(SIGNED_ONE)); 74 | } 75 | 76 | function oneHundredPercent() internal pure returns (Percent memory) { 77 | return Percent(ONE); 78 | } 79 | 80 | function one() internal pure returns (uint256) { 81 | return ONE; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /contracts/libs/upgrades/Proxy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | contract Proxy { 5 | bytes32 private constant IMPLEMENTATION_POSITION = keccak256("implementation.address"); 6 | bytes32 private constant PROXY_OWNER_POSITION = keccak256("proxy.owner"); 7 | 8 | modifier onlyProxyOwner() { 9 | require(msg.sender == proxyOwner(), "Only for proxy owner"); 10 | _; 11 | } 12 | 13 | constructor() public { 14 | _setUpgradeabilityOwner(msg.sender); 15 | } 16 | 17 | function transferProxyOwnership(address _newOwner) public onlyProxyOwner { 18 | require(_newOwner != address(0), "Only for proxy owner"); 19 | _setUpgradeabilityOwner(_newOwner); 20 | } 21 | 22 | function upgradeTo(address _implementation) public onlyProxyOwner { 23 | _upgradeTo(_implementation); 24 | } 25 | 26 | function implementation() public view returns (address impl) { 27 | bytes32 position = IMPLEMENTATION_POSITION; 28 | 29 | // solhint-disable no-inline-assembly 30 | assembly { 31 | impl := sload(position) 32 | } 33 | } 34 | 35 | function proxyOwner() public view returns (address owner) { 36 | bytes32 position = PROXY_OWNER_POSITION; 37 | 38 | // solhint-disable no-inline-assembly 39 | assembly { 40 | owner := sload(position) 41 | } 42 | } 43 | 44 | // solhint-disable no-complex-fallback 45 | fallback() external payable { 46 | address impl = implementation(); 47 | require(impl != address(0), "Impl is 0"); 48 | 49 | // solhint-disable no-inline-assembly 50 | assembly { 51 | let ptr := mload(0x40) 52 | calldatacopy(ptr, 0, calldatasize()) 53 | let result := delegatecall(gas(), impl, ptr, calldatasize(), 0, 0) 54 | let size := returndatasize() 55 | returndatacopy(ptr, 0, size) 56 | 57 | switch result 58 | case 0 { 59 | revert(ptr, size) 60 | } 61 | default { 62 | return(ptr, size) 63 | } 64 | } 65 | } 66 | 67 | receive() external payable { 68 | revert("Contract cannot receive ETH!"); 69 | } 70 | 71 | function _setImplementation(address _newImplementation) internal { 72 | bytes32 position = IMPLEMENTATION_POSITION; 73 | // solhint-disable no-inline-assembly 74 | assembly { 75 | sstore(position, _newImplementation) 76 | } 77 | } 78 | 79 | function _upgradeTo(address _newImplementation) internal { 80 | address currentImplementation = implementation(); 81 | require(currentImplementation != _newImplementation, "New impl must be different"); 82 | _setImplementation(_newImplementation); 83 | } 84 | 85 | function _setUpgradeabilityOwner(address _newProxyOwner) internal { 86 | bytes32 position = PROXY_OWNER_POSITION; 87 | // solhint-disable no-inline-assembly 88 | assembly { 89 | sstore(position, _newProxyOwner) 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /contracts/mocks/ArraysImpl.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | import "../libs/Arrays.sol"; 4 | 5 | contract ArraysImpl { 6 | function findMedian(uint256[] memory unsorted) public pure returns (uint256) { 7 | return Arrays.findMedian(unsorted); 8 | } 9 | } 10 | 11 | contract QuickImpl { 12 | function select(uint256[] memory arr, uint256 k) public pure returns (uint256) { 13 | return Quick.select(arr, k); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /contracts/mocks/FaucetInterface.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | interface FaucetInterface { 5 | function allocateTo(address _owner, uint256 value) external; 6 | } 7 | -------------------------------------------------------------------------------- /contracts/mocks/TestCToken.sol: -------------------------------------------------------------------------------- 1 | /* solium-disable error-reason */ 2 | 3 | // SPDX-License-Identifier: Apache-2.0 4 | pragma solidity ^0.6.10; 5 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 6 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 7 | 8 | contract TestCToken is ERC20 { 9 | IERC20 public baseToken; 10 | uint256 public totalBorrows; 11 | 12 | constructor(IERC20 baseToken_) public ERC20("Test cToken", "cTEST") { 13 | baseToken = baseToken_; 14 | } 15 | 16 | function mint(uint256 baseTokenAmount) public returns (uint256) { 17 | uint256 cTokenAmount = (baseTokenAmount * 1 ether) / getPrice(); 18 | 19 | require(baseToken.transferFrom(msg.sender, address(this), baseTokenAmount), "TransferFrom failed"); 20 | _mint(msg.sender, cTokenAmount); 21 | 22 | return 0; 23 | } 24 | 25 | function redeem(uint256 cTokenAmount) public returns (uint256) { 26 | uint256 baseTokenAmount = (cTokenAmount * getPrice()) / 1 ether; 27 | 28 | _burn(msg.sender, cTokenAmount); 29 | require(baseToken.transfer(msg.sender, baseTokenAmount), "Transfer failed"); 30 | 31 | return 0; 32 | } 33 | 34 | function getPrice() public view returns (uint256) { 35 | uint256 poolSize = baseToken.balanceOf(address(this)); 36 | uint256 issued = totalSupply(); 37 | 38 | if (poolSize == 0 || issued == 0) { 39 | return 1 ether; 40 | } 41 | 42 | return (poolSize * 1 ether) / issued; 43 | } 44 | 45 | function borrow(address recipient, uint256 amount) public { 46 | totalBorrows += amount; 47 | require(baseToken.transfer(recipient, amount), "Transfer failed"); 48 | } 49 | 50 | function repay(uint256 amount) public { 51 | totalBorrows -= amount; 52 | require(baseToken.transferFrom(msg.sender, address(this), amount), "TransferFrom failed"); 53 | } 54 | 55 | function exchangeRateStored() public view returns (uint256) { 56 | return getPrice(); 57 | } 58 | 59 | function getCash() public view returns (uint256) { 60 | return baseToken.balanceOf(address(this)); 61 | } 62 | 63 | function underlying() public view returns (address) { 64 | return address(baseToken); 65 | } 66 | 67 | function redeemUnderlying(uint256 baseTokenAmount) public returns (uint256) { 68 | uint256 cTokenAmount = (baseTokenAmount * 1 ether) / getPrice(); 69 | 70 | _burn(msg.sender, cTokenAmount); 71 | require(baseToken.transfer(msg.sender, baseTokenAmount), "Transfer failed"); 72 | 73 | return 0; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /contracts/mocks/TestToken.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 4 | 5 | contract TestToken is ERC20 { 6 | constructor() public ERC20("Test Token", "TEST") { 7 | _mint(msg.sender, 1000000000 ether); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /contracts/mocks/margin/MockIsPoolSafeMarginProtocol.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | pragma experimental ABIEncoderV2; // not experimental anymore 4 | 5 | import "../../impls/margin/MarginFlowProtocolSafety.sol"; 6 | 7 | contract MockPoolIsSafeMarginProtocol { 8 | event FakeWithdrew(address sender, uint256 amount); 9 | 10 | function market() 11 | public 12 | view 13 | returns ( 14 | uint256, 15 | uint256, 16 | uint256, 17 | uint256, 18 | MarginFlowProtocolSafety, 19 | uint256, 20 | uint256, 21 | uint256, 22 | uint256 23 | ) 24 | { 25 | return (0, 0, 0, 0, MarginFlowProtocolSafety(address(this)), 0, 0, 0, 0); 26 | } 27 | 28 | function isPoolSafe(MarginLiquidityPoolInterface _pool) public pure returns (bool) { 29 | return address(_pool) != address(0); 30 | } 31 | 32 | function withdrawForPool(uint256 _iTokenAmount) public { 33 | emit FakeWithdrew(msg.sender, _iTokenAmount); 34 | } 35 | 36 | function balances(MarginLiquidityPoolInterface _pool, address _trader) public pure returns (uint256) { 37 | if (address(_pool) != address(0) && _trader != address(0)) { 38 | return 0; 39 | } 40 | } 41 | } 42 | 43 | contract MockPoolIsNotSafeMarginProtocol { 44 | event FakeWithdrew(address sender, uint256 amount); 45 | 46 | function market() 47 | public 48 | view 49 | returns ( 50 | uint256, 51 | uint256, 52 | uint256, 53 | uint256, 54 | MarginFlowProtocolSafety, 55 | uint256, 56 | uint256, 57 | uint256, 58 | uint256 59 | ) 60 | { 61 | return (0, 0, 0, 0, MarginFlowProtocolSafety(address(this)), 0, 0, 0, 0); 62 | } 63 | 64 | function isPoolSafe(MarginLiquidityPoolInterface _pool) public pure returns (bool) { 65 | return address(_pool) == address(0); 66 | } 67 | 68 | function withdrawForPool(uint256 _iTokenAmount) public { 69 | emit FakeWithdrew(msg.sender, _iTokenAmount); 70 | } 71 | 72 | function balances(MarginLiquidityPoolInterface _pool, address _trader) public pure returns (uint256) { 73 | if (address(_pool) != address(0) && _trader != address(0)) { 74 | return 0; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/MarginFlowProtocolNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | pragma experimental ABIEncoderV2; // not experimental anymore 4 | 5 | import "../../impls/margin/MarginFlowProtocol.sol"; 6 | 7 | contract MarginFlowProtocolNewVersion is MarginFlowProtocol { 8 | bytes32[] public newStorageBytes32; 9 | uint256 public newStorageUint; 10 | 11 | function addNewStorageBytes32(bytes32 _newBytes32) public { 12 | newStorageBytes32.push(_newBytes32); 13 | } 14 | 15 | function setNewStorageUint(uint256 _newStorageUint) public { 16 | newStorageUint = _newStorageUint; 17 | } 18 | 19 | function getNewValuePlusNextPositionId() public view returns (uint256) { 20 | return nextPositionId.add(newStorageUint); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/MarginFlowProtocolSafetyNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | pragma experimental ABIEncoderV2; // not experimental anymore 4 | 5 | import "../../impls/margin/MarginFlowProtocolSafety.sol"; 6 | 7 | contract MarginFlowProtocolSafetyNewVersion is MarginFlowProtocolSafety { 8 | bytes32[] public newStorageBytes32; 9 | uint256 public newStorageUint; 10 | 11 | function addNewStorageBytes32(bytes32 _newBytes32) public { 12 | newStorageBytes32.push(_newBytes32); 13 | } 14 | 15 | function setNewStorageUint(uint256 _newStorageUint) public { 16 | newStorageUint = _newStorageUint; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/MarginLiquidityPoolNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../../impls/margin/MarginLiquidityPool.sol"; 5 | 6 | contract MarginLiquidityPoolNewVersion is MarginLiquidityPool { 7 | bytes32[] public newStorageBytes32; 8 | uint256 public newStorageUint; 9 | 10 | function addNewStorageBytes32(bytes32 _newBytes32) public { 11 | newStorageBytes32.push(_newBytes32); 12 | } 13 | 14 | function setNewStorageUint(uint256 _newStorageUint) public { 15 | newStorageUint = _newStorageUint; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/MarginLiquidityPoolRegistryNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | pragma experimental ABIEncoderV2; // not experimental anymore 4 | 5 | import "../../impls/margin/MarginLiquidityPoolRegistry.sol"; 6 | 7 | contract MarginLiquidityPoolRegistryNewVersion is MarginLiquidityPoolRegistry { 8 | bytes32[] public newStorageBytes32; 9 | uint256 public newStorageUint; 10 | 11 | function addNewStorageBytes32(bytes32 _newBytes32) public { 12 | newStorageBytes32.push(_newBytes32); 13 | } 14 | 15 | function setNewStorageUint(uint256 _newStorageUint) public { 16 | newStorageUint = _newStorageUint; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/MoneyMarketNewVersion copy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../../impls/MoneyMarket.sol"; 5 | 6 | contract MoneyMarketNewVersion is MoneyMarket { 7 | bytes32[] public newStorageBytes32; 8 | uint256 public newStorageUint; 9 | 10 | function addNewStorageBytes32(bytes32 _newBytes32) public { 11 | newStorageBytes32.push(_newBytes32); 12 | } 13 | 14 | function setNewStorageUint(uint256 _newStorageUint) public { 15 | newStorageUint = _newStorageUint; 16 | } 17 | 18 | function getNewValuePlusMinLiquidity() public view returns (uint256) { 19 | return minLiquidity.value.add(newStorageUint); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/SimplePriceOracleNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../../impls/oracles/SimplePriceOracle.sol"; 5 | 6 | contract SimplePriceOracleNewVersion is SimplePriceOracle { 7 | bytes32[] public newStorageBytes32; 8 | uint256 public newStorageUint; 9 | 10 | function addNewStorageBytes32(bytes32 _newBytes32) public { 11 | newStorageBytes32.push(_newBytes32); 12 | } 13 | 14 | function setNewStorageUint(uint256 _newStorageUint) public { 15 | newStorageUint = _newStorageUint; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/SyntheticFlowProtocolNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../../impls/synthetic/SyntheticFlowProtocol.sol"; 5 | 6 | contract SyntheticFlowProtocolNewVersion is SyntheticFlowProtocol { 7 | bytes32[] public newStorageBytes32; 8 | uint256 public newStorageUint; 9 | 10 | function addNewStorageBytes32(bytes32 _newBytes32) public { 11 | newStorageBytes32.push(_newBytes32); 12 | } 13 | 14 | function setNewStorageUint(uint256 _newStorageUint) public { 15 | newStorageUint = _newStorageUint; 16 | } 17 | 18 | function getNewValuePlusMaxSpread() public view returns (uint256) { 19 | return maxSpread.add(newStorageUint); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/SyntheticFlowTokenNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../../impls/synthetic/SyntheticFlowToken.sol"; 5 | 6 | contract SyntheticFlowTokenNewVersion is SyntheticFlowToken { 7 | bytes32[] public newStorageBytes32; 8 | uint256 public newStorageUint; 9 | 10 | function addNewStorageBytes32(bytes32 _newBytes32) public { 11 | newStorageBytes32.push(_newBytes32); 12 | } 13 | 14 | function setNewStorageUint(uint256 _newStorageUint) public { 15 | newStorageUint = _newStorageUint; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/mocks/upgrades/SyntheticLiquidityPoolNewVersion.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "../../impls/synthetic/SyntheticLiquidityPool.sol"; 5 | 6 | contract SyntheticLiquidityPoolNewVersion is SyntheticLiquidityPool { 7 | bytes32[] public newStorageBytes32; 8 | uint256 public newStorageUint; 9 | 10 | function addNewStorageBytes32(bytes32 _newBytes32) public { 11 | newStorageBytes32.push(_newBytes32); 12 | } 13 | 14 | function setNewStorageUint(uint256 _newStorageUint) public { 15 | newStorageUint = _newStorageUint; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /contracts/roles/PriceFeederRole.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 5 | import "@openzeppelin/contracts-ethereum-package/contracts/access/AccessControl.sol"; 6 | import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol"; 7 | 8 | contract AccessControlUpgradable is AccessControlUpgradeSafe { 9 | function initialize() public virtual initializer { 10 | _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); 11 | super.__AccessControl_init(); 12 | } 13 | } 14 | 15 | // TODO: change Ownable to Admin to ensure always must be a valid admin 16 | contract PriceFeederRole is Initializable, OwnableUpgradeSafe, AccessControlUpgradable { 17 | event PriceFeederAdded(address indexed _account); 18 | event PriceFeederRemoved(address indexed _account); 19 | 20 | bytes32 public constant PRICE_FEEDER_ROLE = keccak256("PRICE_FEEDER_ROLE"); 21 | 22 | // store all price feeders to support traverse etc 23 | address[] internal priceFeeders; 24 | // addr => index in `priceFeeders` 25 | mapping(address => uint256) internal priceFeederIndices; 26 | 27 | modifier onlyPriceFeeder() { 28 | require(isPriceFeeder(msg.sender), "Caller doesnt have the PriceFeeder role"); 29 | _; 30 | } 31 | 32 | function initialize() public virtual override initializer { 33 | OwnableUpgradeSafe.__Ownable_init(); 34 | AccessControlUpgradable.initialize(); 35 | } 36 | 37 | function isPriceFeeder(address _account) public view returns (bool) { 38 | return hasRole(PRICE_FEEDER_ROLE, _account); 39 | } 40 | 41 | function addPriceFeeder(address _account) public onlyOwner { 42 | _addPriceFeeder(_account); 43 | } 44 | 45 | function removePriceFeeder(address _account) public onlyOwner { 46 | revokeRole(PRICE_FEEDER_ROLE, _account); 47 | _removePriceFeeder(_account); 48 | } 49 | 50 | function renouncePriceFeeder() public { 51 | renounceRole(PRICE_FEEDER_ROLE, msg.sender); 52 | _removePriceFeeder(msg.sender); 53 | } 54 | 55 | function _addPriceFeeder(address _account) internal { 56 | // role 57 | grantRole(PRICE_FEEDER_ROLE, _account); 58 | 59 | // push and record index 60 | priceFeeders.push(_account); 61 | priceFeederIndices[_account] = priceFeeders.length - 1; 62 | 63 | emit PriceFeederAdded(_account); 64 | } 65 | 66 | function _removePriceFeeder(address _account) internal { 67 | // if not last index, swap with last element 68 | uint256 index = priceFeederIndices[_account]; 69 | uint256 lastIndex = priceFeeders.length - 1; 70 | if (index != lastIndex) { 71 | priceFeeders[index] = priceFeeders[lastIndex]; 72 | } 73 | // delete last element and its index 74 | priceFeeders.pop(); 75 | delete priceFeederIndices[_account]; 76 | 77 | emit PriceFeederRemoved(_account); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /contracts/roles/ProtocolOwnable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: Apache-2.0 2 | pragma solidity ^0.6.10; 3 | 4 | import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol"; 5 | 6 | contract ProtocolOwnable is Initializable { 7 | address private _protocol; 8 | 9 | function initialize(address protocol) public initializer { 10 | _protocol = protocol; 11 | } 12 | 13 | function protocol() public view returns (address) { 14 | return _protocol; 15 | } 16 | 17 | modifier onlyProtocol() { 18 | require(isProtocol(), "Ownable: caller is not the protocol"); 19 | _; 20 | } 21 | 22 | function isProtocol() public view returns (bool) { 23 | return msg.sender == address(_protocol); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /cucumber.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | default: [ 3 | 'cucumber/features/**/*.feature', // Specify our feature files 4 | '--require-module ts-node/register', // Load TypeScript module 5 | '--require cucumber/step-definitions/**/*.ts', // Load step definitions 6 | '--format progress-bar', // Load custom formatter 7 | '--format node_modules/cucumber-pretty', // Load custom formatter 8 | ].join(' '), 9 | }; 10 | -------------------------------------------------------------------------------- /dev-scripts/changeOwners.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); /* eslint-disable-line */ 2 | const path = require('path'); /* eslint-disable-line */ 3 | 4 | const readFile = filePath => { 5 | const finalPath = path.join(...filePath); 6 | 7 | const obj = fs.readFileSync(finalPath); 8 | return JSON.parse(obj); 9 | }; 10 | 11 | module.exports = callback => { 12 | async function changeOwners() { 13 | const network = process.env.NETWORK; 14 | 15 | const MarginFlowProtocol = artifacts.require('MarginFlowProtocol'); 16 | const MarginFlowProtocolSafety = artifacts.require( 17 | 'MarginFlowProtocolSafety', 18 | ); 19 | const SyntheticFlowProtocol = artifacts.require('SyntheticFlowProtocol'); 20 | const SyntheticLiquidityPool = artifacts.require('SyntheticLiquidityPool'); 21 | const MarginLiquidityPoolRegistry = artifacts.require( 22 | 'MarginLiquidityPoolRegistry', 23 | ); 24 | const MarginLiquidityPool = artifacts.require('MarginLiquidityPool'); 25 | const MoneyMarket = artifacts.require('MoneyMarket'); 26 | const Proxy = artifacts.require('Proxy'); 27 | const SimplePriceOracle = artifacts.require('SimplePriceOracle'); 28 | 29 | const currentOwner = (await web3.eth.getAccounts())[0]; 30 | const newOwner = '0x16C27eC21eA6478ACA452f7683db9dB94E75f936'; // deployed MultiSig 31 | 32 | console.log(`Changing owner from ${currentOwner} to ${newOwner}...`); 33 | 34 | const deployedContracts = readFile([ 35 | 'artifacts', 36 | network, 37 | 'deployment.json', 38 | ]); 39 | 40 | const changeOwnerContracts = [ 41 | { address: deployedContracts.moneyMarket, contract: MoneyMarket }, 42 | { address: deployedContracts.oracle, contract: SimplePriceOracle }, 43 | { 44 | address: deployedContracts.syntheticProtocol, 45 | contract: SyntheticFlowProtocol, 46 | }, 47 | { 48 | address: deployedContracts.marginProtocol, 49 | contract: MarginFlowProtocol, 50 | }, 51 | { 52 | address: deployedContracts.marginProtocolSafety, 53 | contract: MarginFlowProtocolSafety, 54 | }, 55 | { 56 | address: deployedContracts.marginPoolRegistry, 57 | contract: MarginLiquidityPoolRegistry, 58 | }, 59 | { address: deployedContracts.marginPool, contract: MarginLiquidityPool }, 60 | { address: deployedContracts.marginPool2, contract: MarginLiquidityPool }, 61 | { 62 | address: deployedContracts.syntheticPool, 63 | contract: SyntheticLiquidityPool, 64 | }, 65 | { 66 | address: deployedContracts.syntheticPool2, 67 | contract: SyntheticLiquidityPool, 68 | }, 69 | ]; 70 | 71 | for (const { address, contract } of changeOwnerContracts) { 72 | const Contract = await contract.at(address); 73 | await Contract.transferOwnership(newOwner); 74 | 75 | const ProxyContract = await Proxy.at(address); 76 | await ProxyContract.transferProxyOwnership(newOwner); 77 | } 78 | } 79 | 80 | changeOwners() 81 | .then(() => { 82 | console.log('Successfully finished!'); 83 | callback(); 84 | }) 85 | .catch(error => console.log({ error })); 86 | }; 87 | -------------------------------------------------------------------------------- /dev-scripts/changeSpread.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); /* eslint-disable-line */ 2 | const path = require('path'); /* eslint-disable-line */ 3 | 4 | const readFile = filePath => { 5 | const finalPath = path.join(...filePath); 6 | 7 | const obj = fs.readFileSync(finalPath); 8 | return JSON.parse(obj); 9 | }; 10 | 11 | module.exports = callback => { 12 | async function changeData() { 13 | const network = process.env.NETWORK; 14 | const spread = '28152000000000'; 15 | const SyntheticLiquidityPool = artifacts.require('SyntheticLiquidityPool'); 16 | 17 | const { 18 | syntheticPool, 19 | syntheticPool2, 20 | baseToken, 21 | fEUR, 22 | fJPY, 23 | fXAU, 24 | fAAPL, 25 | } = readFile(['artifacts', network, 'deployment.json']); 26 | 27 | const SyntheticLiquidityPoolContract1 = await SyntheticLiquidityPool.at( 28 | syntheticPool, 29 | ); 30 | const SyntheticLiquidityPoolContract2 = await SyntheticLiquidityPool.at( 31 | syntheticPool2, 32 | ); 33 | 34 | for (const token of [baseToken, fEUR, fJPY, fXAU, fAAPL]) { 35 | await SyntheticLiquidityPoolContract1.setSpreadForToken(token, spread); 36 | await SyntheticLiquidityPoolContract2.setSpreadForToken(token, spread); 37 | } 38 | } 39 | 40 | changeData() 41 | .then(() => { 42 | console.log('Successfully changed!'); 43 | callback(); 44 | }) 45 | .catch(error => console.log({ error })); 46 | }; 47 | -------------------------------------------------------------------------------- /dev-scripts/debug.js: -------------------------------------------------------------------------------- 1 | module.exports = callback => { 2 | web3.eth.getBlock('latest').then(b => { 3 | console.log(b.transactions[0]); 4 | callback(); 5 | }); 6 | }; 7 | -------------------------------------------------------------------------------- /dev-scripts/dummy-oracle-server.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-param-reassign */ 2 | 3 | const main = async time => { 4 | const SimplePriceOracle = artifacts.require('SimplePriceOracle'); 5 | const SyntheticFlowToken = artifacts.require('SyntheticFlowToken'); 6 | 7 | const oracle = await SimplePriceOracle.deployed(); 8 | const fEUR = await SyntheticFlowToken.deployed(); 9 | 10 | const cycles = [50, 30, 10]; 11 | const step = 0.001; 12 | 13 | async function loop({ price, movements }) { 14 | const priceStr = price.toFixed(8); 15 | console.log(`${new Date().toISOString()}: Set Price - ${priceStr}`); 16 | await oracle.setPrice(fEUR.address, web3.utils.toWei(priceStr)); 17 | 18 | let delta = Math.random() - 0.5; 19 | movements = movements.map(([val, count], idx) => { 20 | delta += val; 21 | count -= 1; 22 | if (count === 0) { 23 | count = Math.floor((Math.random() + 0.2) * cycles[idx] + 1); 24 | val = (Math.random() - 0.5) / Math.max(Math.floor(count / 5), 1); 25 | } 26 | return [val, count]; 27 | }); 28 | 29 | price *= 1 + delta * step; 30 | 31 | return new Promise(resolve => { 32 | setTimeout(() => { 33 | resolve(loop({ price, movements })); 34 | }, time); 35 | }); 36 | } 37 | 38 | loop({ 39 | time, 40 | price: 1.2, 41 | movements: cycles.map(() => [Math.random(), 1]), 42 | }); 43 | }; 44 | 45 | module.exports = async callback => { 46 | try { 47 | const newtworkType = await web3.eth.net.getNetworkType(); 48 | const time = 49 | { 50 | private: 1000, 51 | }[newtworkType] || 20000; 52 | await main(time); 53 | } catch (err) { 54 | console.error(err); 55 | callback(err); 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /dev-scripts/getKovanDaiFaucet.js: -------------------------------------------------------------------------------- 1 | module.exports = callback => { 2 | async function getFaucetDai() { 3 | const FaucetInterface = artifacts.require('FaucetInterface'); 4 | const FaucetInterfaceContract = await FaucetInterface.at( 5 | '0xbf7a7169562078c96f0ec1a8afd6ae50f12e5a99', 6 | ); 7 | 8 | await FaucetInterfaceContract.allocateTo( 9 | '0x15ae150d7dC03d3B635EE90b85219dBFe071ED35', 10 | '100000000000000000000000000', 11 | ); 12 | } 13 | 14 | getFaucetDai() 15 | .then(() => { 16 | console.log('Successfully finished!'); 17 | callback(); 18 | }) 19 | .catch(error => console.log({ error })); 20 | }; 21 | -------------------------------------------------------------------------------- /dev-scripts/upgradeContract.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); /* eslint-disable-line */ 2 | const path = require('path'); /* eslint-disable-line */ 3 | 4 | const readFile = filePath => { 5 | const finalPath = path.join(...filePath); 6 | 7 | const obj = fs.readFileSync(finalPath); 8 | return JSON.parse(obj); 9 | }; 10 | 11 | const contractMapping = { 12 | MoneyMarket: ['moneyMarket'], 13 | SimplePriceOracle: ['oracle'], 14 | SyntheticFlowProtocol: ['syntheticProtocol'], 15 | SyntheticFlowToken: ['fEUR', 'fJPY', 'fXAU', 'fAAPL'], 16 | SyntheticLiquidityPool: ['syntheticPool', 'syntheticPool2'], 17 | MarginFlowProtocol: ['marginProtocol'], 18 | MarginFlowProtocolSafety: ['marginProtocolSafety'], 19 | MarginLiquidityPoolRegistry: ['marginPoolRegistry'], 20 | MarginLiquidityPool: ['marginPool', 'marginPool2'], 21 | }; 22 | 23 | module.exports = callback => { 24 | async function upgradeContract() { 25 | const contractName = process.env.CONTRACT_NAME; 26 | const network = process.env.NETWORK; 27 | 28 | const Contract = artifacts.require(contractName); 29 | const Proxy = artifacts.require('Proxy'); 30 | const contractsToUpdate = contractMapping[contractName]; 31 | 32 | fs.writeFileSync( 33 | `artifacts/${network}/abi/${contractName}.json`, 34 | JSON.stringify(Contract.abi, null, 2), 35 | ); 36 | 37 | console.log('Deploying new contract implementation...'); 38 | const contractImpl = await Contract.new(); 39 | 40 | const deployedContracts = readFile([ 41 | 'artifacts', 42 | network, 43 | 'deployment.json', 44 | ]); 45 | 46 | for (const contractKey of contractsToUpdate) { 47 | const contractAddress = deployedContracts[contractKey]; 48 | const contractInstance = await Proxy.at(contractAddress); 49 | 50 | console.log(`Upgrading ${contractKey} contract...`); 51 | await contractInstance.upgradeTo(contractImpl.address); 52 | } 53 | } 54 | 55 | upgradeContract() 56 | .then(() => { 57 | console.log('Successfully finished!'); 58 | callback(); 59 | }) 60 | .catch(error => console.log({ error })); 61 | }; 62 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | graph-node: 4 | image: graphprotocol/graph-node 5 | ports: 6 | - '8000:8000' 7 | - '8001:8001' 8 | - '8020:8020' 9 | - '8030:8030' 10 | - '8040:8040' 11 | depends_on: 12 | # - ganache 13 | - ipfs 14 | - postgres 15 | environment: 16 | postgres_host: postgres:5432 17 | postgres_user: graph-node 18 | postgres_pass: let-me-in 19 | postgres_db: graph-node 20 | ipfs: 'ipfs:5001' 21 | ethereum: 'development:http://host.docker.internal:8545' 22 | ipfs: 23 | image: ipfs/go-ipfs 24 | ports: 25 | - '5001:5001' 26 | volumes: 27 | - ./data/ipfs:/data/ipfs 28 | postgres: 29 | image: postgres 30 | ports: 31 | - '5432:5432' 32 | command: ['postgres', '-cshared_preload_libraries=pg_stat_statements'] 33 | environment: 34 | POSTGRES_USER: graph-node 35 | POSTGRES_PASSWORD: let-me-in 36 | POSTGRES_DB: graph-node 37 | volumes: 38 | - ./data/postgres:/var/lib/postgresql/data 39 | # ganache: 40 | # image: trufflesuite/ganache-cli:latest 41 | # ports: 42 | # - '8545:8545' 43 | # command: 44 | # [ 45 | # '-d', 46 | # '--db=/tmp', 47 | # '-m "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat"', 48 | # '-q', 49 | # ] 50 | # volumes: 51 | # - ./data/ganache:/tmp 52 | -------------------------------------------------------------------------------- /generated-docs/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | * contracts 3 | * impls 4 | * [FlowProtocolBase](docs/impls/FlowProtocolBase.md) 5 | * [LiquidityPool](docs/impls/LiquidityPool.md) 6 | * margin 7 | * [MarginFlowProtocol](docs/impls/margin/MarginFlowProtocol.md) 8 | * [MarginFlowProtocolAccPositions](docs/impls/margin/MarginFlowProtocolAccPositions.md) 9 | * [MarginFlowProtocolConfig](docs/impls/margin/MarginFlowProtocolConfig.md) 10 | * [MarginFlowProtocolLiquidated](docs/impls/margin/MarginFlowProtocolLiquidated.md) 11 | * [MarginFlowProtocolSafety](docs/impls/margin/MarginFlowProtocolSafety.md) 12 | * [MarginLiquidityPool](docs/impls/margin/MarginLiquidityPool.md) 13 | * [MarginLiquidityPoolRegistry](docs/impls/margin/MarginLiquidityPoolRegistry.md) 14 | * [MarginMarketLib](docs/impls/margin/MarginMarketLib.md) 15 | * [MintableToken](docs/impls/MintableToken.md) 16 | * [MoneyMarket](docs/impls/MoneyMarket.md) 17 | * oracles 18 | * [ChainLinkOracle](docs/impls/oracles/ChainLinkOracle.md) 19 | * [PriceOracleConfig](docs/impls/oracles/PriceOracleConfig.md) 20 | * [SimplePriceOracle](docs/impls/oracles/SimplePriceOracle.md) 21 | * synthetic 22 | * [SyntheticFlowProtocol](docs/impls/synthetic/SyntheticFlowProtocol.md) 23 | * [SyntheticFlowToken](docs/impls/synthetic/SyntheticFlowToken.md) 24 | * [SyntheticLiquidityPool](docs/impls/synthetic/SyntheticLiquidityPool.md) 25 | * interfaces 26 | * [CErc20Interface](docs/interfaces/CErc20Interface.md) 27 | * [LiquidityPoolInterface](docs/interfaces/LiquidityPoolInterface.md) 28 | * [MarginLiquidityPoolInterface](docs/interfaces/MarginLiquidityPoolInterface.md) 29 | * [MoneyMarketInterface](docs/interfaces/MoneyMarketInterface.md) 30 | * [PriceOracleInterface](docs/interfaces/PriceOracleInterface.md) 31 | * [SyntheticLiquidityPoolInterface](docs/interfaces/SyntheticLiquidityPoolInterface.md) 32 | * libs 33 | * [Arrays](docs/libs/Arrays.md) 34 | * [Percentage](docs/libs/Percentage.md) 35 | * upgrades 36 | * [Proxy](docs/libs/upgrades/Proxy.md) 37 | * [Migrations](docs/Migrations.md) 38 | * mocks 39 | * [ArraysImpl](docs/mocks/ArraysImpl.md) 40 | * [FaucetInterface](docs/mocks/FaucetInterface.md) 41 | * margin 42 | * [MockIsPoolSafeMarginProtocol](docs/mocks/margin/MockIsPoolSafeMarginProtocol.md) 43 | * [TestMarginFlowProtocol](docs/mocks/margin/TestMarginFlowProtocol.md) 44 | * [TestCToken](docs/mocks/TestCToken.md) 45 | * [TestToken](docs/mocks/TestToken.md) 46 | * upgrades 47 | * [MarginFlowProtocolNewVersion](docs/mocks/upgrades/MarginFlowProtocolNewVersion.md) 48 | * [MarginFlowProtocolSafetyNewVersion](docs/mocks/upgrades/MarginFlowProtocolSafetyNewVersion.md) 49 | * [MarginLiquidityPoolNewVersion](docs/mocks/upgrades/MarginLiquidityPoolNewVersion.md) 50 | * [MarginLiquidityPoolRegistryNewVersion](docs/mocks/upgrades/MarginLiquidityPoolRegistryNewVersion.md) 51 | * [MoneyMarketNewVersion copy](docs/mocks/upgrades/MoneyMarketNewVersion copy.md) 52 | * [SimplePriceOracleNewVersion](docs/mocks/upgrades/SimplePriceOracleNewVersion.md) 53 | * [SyntheticFlowProtocolNewVersion](docs/mocks/upgrades/SyntheticFlowProtocolNewVersion.md) 54 | * [SyntheticFlowTokenNewVersion](docs/mocks/upgrades/SyntheticFlowTokenNewVersion.md) 55 | * [SyntheticLiquidityPoolNewVersion](docs/mocks/upgrades/SyntheticLiquidityPoolNewVersion.md) 56 | * roles 57 | * [PriceFeederRole](docs/roles/PriceFeederRole.md) 58 | * [ProtocolOwnable](docs/roles/ProtocolOwnable.md) 59 | -------------------------------------------------------------------------------- /generated-docs/contract.hbs: -------------------------------------------------------------------------------- 1 | {{{natspec.devdoc}}} 2 | 3 | {{#if ownFunctions}} 4 | ## Functions: 5 | {{#ownFunctions}} 6 | {{#if (or (eq visibility "public") (eq visibility "external"))}} 7 | - [`{{name}}({{args}})`](#{{anchor}}) 8 | {{/if}} 9 | {{/ownFunctions}} 10 | {{/if}} 11 | 12 | {{#if ownEvents}} 13 | ## Events: 14 | {{#ownEvents}} 15 | - [`{{name}}({{args}})`](#{{anchor}}) 16 | {{/ownEvents}} 17 | {{/if}} 18 | 19 | {{#ownFunctions}} 20 | {{#if (or (eq visibility "public") (eq visibility "external"))}} 21 | ### [Function `{{name}}({{args}}){{#if outputs}} → {{outputs}}{{/if}}`](#{{anchor~}}) 22 | {{#if natspec.devdoc}}{{natspec.devdoc}}{{else}}No description{{/if}} 23 | {{#if natspec.params}} 24 | #### Parameters: 25 | {{#natspec.params}} 26 | - `{{param}}`: {{description}} 27 | {{/natspec.params}} 28 | {{/if}} 29 | {{#if natspec.returns}} 30 | #### Return Values: 31 | {{#natspec.returns}} 32 | - {{param}} {{description}} 33 | {{/natspec.returns}} 34 | {{/if}} 35 | {{/if}} 36 | {{/ownFunctions}} 37 | 38 | {{#ownEvents}} 39 | ### Event `{{name}}({{args}})` {#{{anchor~}} } 40 | {{#if natspec.devdoc}}{{natspec.devdoc}}{{else}}No description{{/if}} 41 | {{#if natspec.params}} 42 | #### Parameters: 43 | {{#natspec.params}} 44 | - `{{param}}`: {{description}} 45 | {{/natspec.params}} 46 | {{/if}} 47 | {{/ownEvents}} -------------------------------------------------------------------------------- /generated-docs/docs/Migrations.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`setCompleted(uint256 completed)`](#Migrations-setCompleted-uint256-) 4 | 5 | - [`upgrade(address newAddress)`](#Migrations-upgrade-address-) 6 | 7 | ### [Function `setCompleted(uint256 completed)`](#Migrations-setCompleted-uint256-) 8 | 9 | No description 10 | 11 | ### [Function `upgrade(address newAddress)`](#Migrations-upgrade-address-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/FlowProtocolBase.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(contract PriceOracleInterface _oracle, contract MoneyMarketInterface _moneyMarket)`](#FlowProtocolBase-initialize-contract-PriceOracleInterface-contract-MoneyMarketInterface-) 4 | 5 | - [`setMaxSpread(uint256 _maxSpread)`](#FlowProtocolBase-setMaxSpread-uint256-) 6 | 7 | ### [Function `initialize(contract PriceOracleInterface _oracle, contract MoneyMarketInterface _moneyMarket)`](#FlowProtocolBase-initialize-contract-PriceOracleInterface-contract-MoneyMarketInterface-) 8 | 9 | No description 10 | 11 | ### [Function `setMaxSpread(uint256 _maxSpread)`](#FlowProtocolBase-setMaxSpread-uint256-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/LiquidityPool.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(contract MoneyMarketInterface _moneyMarket, address _protocol)`](#LiquidityPool-initialize-contract-MoneyMarketInterface-address-) 4 | 5 | - [`approveToProtocol(uint256 _amount)`](#LiquidityPool-approveToProtocol-uint256-) 6 | 7 | - [`getOwner()`](#LiquidityPool-getOwner--) 8 | 9 | ### [Function `initialize(contract MoneyMarketInterface _moneyMarket, address _protocol)`](#LiquidityPool-initialize-contract-MoneyMarketInterface-address-) 10 | 11 | No description 12 | 13 | ### [Function `approveToProtocol(uint256 _amount)`](#LiquidityPool-approveToProtocol-uint256-) 14 | 15 | No description 16 | 17 | ### [Function `getOwner() → address`](#LiquidityPool-getOwner--) 18 | 19 | No description 20 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/MintableToken.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(string name, string symbol)`](#MintableToken-initialize-string-string-) 4 | 5 | - [`mint(address account, uint256 amount)`](#MintableToken-mint-address-uint256-) 6 | 7 | - [`burn(address account, uint256 amount)`](#MintableToken-burn-address-uint256-) 8 | 9 | - [`ownerTransferFrom(address sender, address recipient, uint256 amount)`](#MintableToken-ownerTransferFrom-address-address-uint256-) 10 | 11 | ### [Function `initialize(string name, string symbol)`](#MintableToken-initialize-string-string-) 12 | 13 | No description 14 | 15 | ### [Function `mint(address account, uint256 amount)`](#MintableToken-mint-address-uint256-) 16 | 17 | No description 18 | 19 | ### [Function `burn(address account, uint256 amount)`](#MintableToken-burn-address-uint256-) 20 | 21 | No description 22 | 23 | ### [Function `ownerTransferFrom(address sender, address recipient, uint256 amount)`](#MintableToken-ownerTransferFrom-address-address-uint256-) 24 | 25 | No description 26 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/MoneyMarket.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(contract CErc20Interface _cToken, string _iTokenName, string _iTokenSymbol, uint256 _minLiquidity)`](#MoneyMarket-initialize-contract-CErc20Interface-string-string-uint256-) 4 | 5 | - [`baseToken()`](#MoneyMarket-baseToken--) 6 | 7 | - [`iToken()`](#MoneyMarket-iToken--) 8 | 9 | - [`mint(uint256 _baseTokenAmount)`](#MoneyMarket-mint-uint256-) 10 | 11 | - [`mintTo(address recipient, uint256 _baseTokenAmount)`](#MoneyMarket-mintTo-address-uint256-) 12 | 13 | - [`redeem(uint256 iTokenAmount)`](#MoneyMarket-redeem-uint256-) 14 | 15 | - [`redeemTo(address recipient, uint256 iTokenAmount)`](#MoneyMarket-redeemTo-address-uint256-) 16 | 17 | - [`redeemBaseToken(uint256 _baseTokenAmount)`](#MoneyMarket-redeemBaseToken-uint256-) 18 | 19 | - [`redeemBaseTokenTo(address recipient, uint256 _baseTokenAmount)`](#MoneyMarket-redeemBaseTokenTo-address-uint256-) 20 | 21 | - [`rebalance()`](#MoneyMarket-rebalance--) 22 | 23 | - [`setMinLiquidity(uint256 _newMinLiquidity)`](#MoneyMarket-setMinLiquidity-uint256-) 24 | 25 | - [`calculateInvestAmount(uint256 cTokenCash, uint256 cTokenBorrow, uint256 totalValue)`](#MoneyMarket-calculateInvestAmount-uint256-uint256-uint256-) 26 | 27 | - [`exchangeRate()`](#MoneyMarket-exchangeRate--) 28 | 29 | - [`totalHoldings()`](#MoneyMarket-totalHoldings--) 30 | 31 | - [`convertAmountFromBase(uint256 _baseTokenAmount)`](#MoneyMarket-convertAmountFromBase-uint256-) 32 | 33 | - [`convertAmountFromBase(int256 _baseTokenAmount)`](#MoneyMarket-convertAmountFromBase-int256-) 34 | 35 | - [`convertAmountFromBase(uint256 rate, uint256 _baseTokenAmount)`](#MoneyMarket-convertAmountFromBase-uint256-uint256-) 36 | 37 | - [`convertAmountFromBase(int256 rate, int256 _baseTokenAmount)`](#MoneyMarket-convertAmountFromBase-int256-int256-) 38 | 39 | - [`convertAmountToBase(uint256 iTokenAmount)`](#MoneyMarket-convertAmountToBase-uint256-) 40 | 41 | - [`convertAmountToBase(int256 iTokenAmount)`](#MoneyMarket-convertAmountToBase-int256-) 42 | 43 | - [`convertAmountToBase(uint256 rate, uint256 iTokenAmount)`](#MoneyMarket-convertAmountToBase-uint256-uint256-) 44 | 45 | - [`convertAmountToBase(int256 rate, int256 iTokenAmount)`](#MoneyMarket-convertAmountToBase-int256-int256-) 46 | 47 | ### [Function `initialize(contract CErc20Interface _cToken, string _iTokenName, string _iTokenSymbol, uint256 _minLiquidity)`](#MoneyMarket-initialize-contract-CErc20Interface-string-string-uint256-) 48 | 49 | No description 50 | 51 | ### [Function `baseToken() → contract IERC20`](#MoneyMarket-baseToken--) 52 | 53 | No description 54 | 55 | ### [Function `iToken() → contract IERC20`](#MoneyMarket-iToken--) 56 | 57 | No description 58 | 59 | ### [Function `mint(uint256 _baseTokenAmount) → uint256`](#MoneyMarket-mint-uint256-) 60 | 61 | No description 62 | 63 | ### [Function `mintTo(address recipient, uint256 _baseTokenAmount) → uint256`](#MoneyMarket-mintTo-address-uint256-) 64 | 65 | No description 66 | 67 | ### [Function `redeem(uint256 iTokenAmount) → uint256`](#MoneyMarket-redeem-uint256-) 68 | 69 | No description 70 | 71 | ### [Function `redeemTo(address recipient, uint256 iTokenAmount) → uint256`](#MoneyMarket-redeemTo-address-uint256-) 72 | 73 | No description 74 | 75 | ### [Function `redeemBaseToken(uint256 _baseTokenAmount) → uint256`](#MoneyMarket-redeemBaseToken-uint256-) 76 | 77 | No description 78 | 79 | ### [Function `redeemBaseTokenTo(address recipient, uint256 _baseTokenAmount) → uint256`](#MoneyMarket-redeemBaseTokenTo-address-uint256-) 80 | 81 | No description 82 | 83 | ### [Function `rebalance()`](#MoneyMarket-rebalance--) 84 | 85 | No description 86 | 87 | ### [Function `setMinLiquidity(uint256 _newMinLiquidity)`](#MoneyMarket-setMinLiquidity-uint256-) 88 | 89 | No description 90 | 91 | ### [Function `calculateInvestAmount(uint256 cTokenCash, uint256 cTokenBorrow, uint256 totalValue) → uint256`](#MoneyMarket-calculateInvestAmount-uint256-uint256-uint256-) 92 | 93 | No description 94 | 95 | ### [Function `exchangeRate() → uint256`](#MoneyMarket-exchangeRate--) 96 | 97 | No description 98 | 99 | ### [Function `totalHoldings() → uint256`](#MoneyMarket-totalHoldings--) 100 | 101 | No description 102 | 103 | ### [Function `convertAmountFromBase(uint256 _baseTokenAmount) → uint256`](#MoneyMarket-convertAmountFromBase-uint256-) 104 | 105 | No description 106 | 107 | ### [Function `convertAmountFromBase(int256 _baseTokenAmount) → int256`](#MoneyMarket-convertAmountFromBase-int256-) 108 | 109 | No description 110 | 111 | ### [Function `convertAmountFromBase(uint256 rate, uint256 _baseTokenAmount) → uint256`](#MoneyMarket-convertAmountFromBase-uint256-uint256-) 112 | 113 | No description 114 | 115 | ### [Function `convertAmountFromBase(int256 rate, int256 _baseTokenAmount) → int256`](#MoneyMarket-convertAmountFromBase-int256-int256-) 116 | 117 | No description 118 | 119 | ### [Function `convertAmountToBase(uint256 iTokenAmount) → uint256`](#MoneyMarket-convertAmountToBase-uint256-) 120 | 121 | No description 122 | 123 | ### [Function `convertAmountToBase(int256 iTokenAmount) → int256`](#MoneyMarket-convertAmountToBase-int256-) 124 | 125 | No description 126 | 127 | ### [Function `convertAmountToBase(uint256 rate, uint256 iTokenAmount) → uint256`](#MoneyMarket-convertAmountToBase-uint256-uint256-) 128 | 129 | No description 130 | 131 | ### [Function `convertAmountToBase(int256 rate, int256 iTokenAmount) → int256`](#MoneyMarket-convertAmountToBase-int256-int256-) 132 | 133 | No description 134 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/PriceOracleConfig.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize()`](#PriceOracleConfig-initialize--) 4 | 5 | - [`setOracleDeltaLastLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaLastLimit-uint256-) 6 | 7 | - [`setOracleDeltaSnapshotLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaSnapshotLimit-uint256-) 8 | 9 | - [`setOracleDeltaSnapshotTime(uint256 time)`](#PriceOracleConfig-setOracleDeltaSnapshotTime-uint256-) 10 | 11 | - [`setExpireIn(uint256 time)`](#PriceOracleConfig-setExpireIn-uint256-) 12 | 13 | ### [Function `initialize()`](#PriceOracleConfig-initialize--) 14 | 15 | No description 16 | 17 | ### [Function `setOracleDeltaLastLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaLastLimit-uint256-) 18 | 19 | No description 20 | 21 | ### [Function `setOracleDeltaSnapshotLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaSnapshotLimit-uint256-) 22 | 23 | No description 24 | 25 | ### [Function `setOracleDeltaSnapshotTime(uint256 time)`](#PriceOracleConfig-setOracleDeltaSnapshotTime-uint256-) 26 | 27 | No description 28 | 29 | ### [Function `setExpireIn(uint256 time)`](#PriceOracleConfig-setExpireIn-uint256-) 30 | 31 | No description 32 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/SimplePriceOracle.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize()`](#SimplePriceOracle-initialize--) 4 | 5 | - [`isPriceOracle()`](#SimplePriceOracle-isPriceOracle--) 6 | 7 | - [`feedPrice(address key, uint256 price)`](#SimplePriceOracle-feedPrice-address-uint256-) 8 | 9 | - [`getPrice(address key)`](#SimplePriceOracle-getPrice-address-) 10 | 11 | - [`readPrice(address key)`](#SimplePriceOracle-readPrice-address-) 12 | 13 | ## Events: 14 | 15 | - [`PriceUpdated(address addr, uint256 price)`](#SimplePriceOracle-PriceUpdated-address-uint256-) 16 | 17 | ### [Function `initialize()`](#SimplePriceOracle-initialize--) 18 | 19 | No description 20 | 21 | ### [Function `isPriceOracle() → bool`](#SimplePriceOracle-isPriceOracle--) 22 | 23 | No description 24 | 25 | ### [Function `feedPrice(address key, uint256 price)`](#SimplePriceOracle-feedPrice-address-uint256-) 26 | 27 | No description 28 | 29 | ### [Function `getPrice(address key) → uint256`](#SimplePriceOracle-getPrice-address-) 30 | 31 | No description 32 | 33 | ### [Function `readPrice(address key) → uint256`](#SimplePriceOracle-readPrice-address-) 34 | 35 | No description 36 | 37 | ### Event `PriceUpdated(address addr, uint256 price)` {#SimplePriceOracle-PriceUpdated-address-uint256-} 38 | 39 | No description 40 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/margin/MarginFlowProtocolAccPositions.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(struct MarginMarketLib.MarketData _market)`](#MarginFlowProtocolAccPositions-initialize-struct-MarginMarketLib-MarketData-) 4 | 5 | - [`getPairPoolSafetyInfo(contract MarginLiquidityPoolInterface _pool, struct MarginFlowProtocol.TradingPair _pair)`](#MarginFlowProtocolAccPositions-getPairPoolSafetyInfo-contract-MarginLiquidityPoolInterface-struct-MarginFlowProtocol-TradingPair-) 6 | 7 | - [`getPairTraderUnrealized(contract MarginLiquidityPoolInterface _pool, address _trader, struct MarginFlowProtocol.TradingPair _pair)`](#MarginFlowProtocolAccPositions-getPairTraderUnrealized-contract-MarginLiquidityPoolInterface-address-struct-MarginFlowProtocol-TradingPair-) 8 | 9 | - [`getPairTraderNet(contract MarginLiquidityPoolInterface _pool, address _trader, struct MarginFlowProtocol.TradingPair _pair)`](#MarginFlowProtocolAccPositions-getPairTraderNet-contract-MarginLiquidityPoolInterface-address-struct-MarginFlowProtocol-TradingPair-) 10 | 11 | - [`__updateAccumulatedPositions(struct MarginFlowProtocol.Position _position, bool _isAddition)`](#MarginFlowProtocolAccPositions-__updateAccumulatedPositions-struct-MarginFlowProtocol-Position-bool-) 12 | 13 | ### [Function `initialize(struct MarginMarketLib.MarketData _market)`](#MarginFlowProtocolAccPositions-initialize-struct-MarginMarketLib-MarketData-) 14 | 15 | Initialize the MarginFlowProtocolLiquidated. 16 | 17 | #### Parameters: 18 | 19 | - `_market`: The market data. 20 | 21 | ### [Function `getPairPoolSafetyInfo(contract MarginLiquidityPoolInterface _pool, struct MarginFlowProtocol.TradingPair _pair) → uint256, uint256, int256`](#MarginFlowProtocolAccPositions-getPairPoolSafetyInfo-contract-MarginLiquidityPoolInterface-struct-MarginFlowProtocol-TradingPair-) 22 | 23 | Receive current pair safety values for pool. 24 | 25 | #### Parameters: 26 | 27 | - `_pool`: The MarginLiquidityPool. 28 | 29 | - `_pair`: The trading pair. 30 | 31 | ### [Function `getPairTraderUnrealized(contract MarginLiquidityPoolInterface _pool, address _trader, struct MarginFlowProtocol.TradingPair _pair) → int256`](#MarginFlowProtocolAccPositions-getPairTraderUnrealized-contract-MarginLiquidityPoolInterface-address-struct-MarginFlowProtocol-TradingPair-) 32 | 33 | Receive current unrealized for trader for trading pair. 34 | 35 | #### Parameters: 36 | 37 | - `_pool`: The MarginLiquidityPool. 38 | 39 | - `_trader`: The trader. 40 | 41 | - `_pair`: The trading pair. 42 | 43 | ### [Function `getPairTraderNet(contract MarginLiquidityPoolInterface _pool, address _trader, struct MarginFlowProtocol.TradingPair _pair) → uint256`](#MarginFlowProtocolAccPositions-getPairTraderNet-contract-MarginLiquidityPoolInterface-address-struct-MarginFlowProtocol-TradingPair-) 44 | 45 | Receive current net for trader for trading pair. 46 | 47 | #### Parameters: 48 | 49 | - `_pool`: The MarginLiquidityPool. 50 | 51 | - `_trader`: The trader. 52 | 53 | - `_pair`: The trading pair. 54 | 55 | ### [Function `__updateAccumulatedPositions(struct MarginFlowProtocol.Position _position, bool _isAddition)`](#MarginFlowProtocolAccPositions-__updateAccumulatedPositions-struct-MarginFlowProtocol-Position-bool-) 56 | 57 | No description 58 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/margin/MarginFlowProtocolLiquidated.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(struct MarginMarketLib.MarketData _market)`](#MarginFlowProtocolLiquidated-initialize-struct-MarginMarketLib-MarketData-) 4 | 5 | - [`closePositionForLiquidatedPool(uint256 _positionId, uint256 _estimatedPoolIndex, uint256 _estimatedTraderIndex)`](#MarginFlowProtocolLiquidated-closePositionForLiquidatedPool-uint256-uint256-uint256-) 6 | 7 | - [`closePositionForLiquidatedTrader(uint256 _positionId, uint256 _estimatedPoolIndex, uint256 _estimatedTraderIndex)`](#MarginFlowProtocolLiquidated-closePositionForLiquidatedTrader-uint256-uint256-uint256-) 8 | 9 | - [`restoreTraderInPool(contract MarginLiquidityPoolInterface _pool, address _trader)`](#MarginFlowProtocolLiquidated-restoreTraderInPool-contract-MarginLiquidityPoolInterface-address-) 10 | 11 | - [`restoreLiquidatedPool(contract MarginLiquidityPoolInterface _pool)`](#MarginFlowProtocolLiquidated-restoreLiquidatedPool-contract-MarginLiquidityPoolInterface-) 12 | 13 | - [`__stopPool(contract MarginLiquidityPoolInterface _pool)`](#MarginFlowProtocolLiquidated-__stopPool-contract-MarginLiquidityPoolInterface-) 14 | 15 | - [`__stopTraderInPool(contract MarginLiquidityPoolInterface _pool, address _trader)`](#MarginFlowProtocolLiquidated-__stopTraderInPool-contract-MarginLiquidityPoolInterface-address-) 16 | 17 | - [`getEstimatedEquityOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader, struct Percentage.Percent _usdPairPrice, struct Percentage.Percent _closePrice)`](#MarginFlowProtocolLiquidated-getEstimatedEquityOfTrader-contract-MarginLiquidityPoolInterface-address-struct-Percentage-Percent-struct-Percentage-Percent-) 18 | 19 | ### [Function `initialize(struct MarginMarketLib.MarketData _market)`](#MarginFlowProtocolLiquidated-initialize-struct-MarginMarketLib-MarketData-) 20 | 21 | Initialize the MarginFlowProtocolLiquidated. 22 | 23 | #### Parameters: 24 | 25 | - `_market`: The market data. 26 | 27 | ### [Function `closePositionForLiquidatedPool(uint256 _positionId, uint256 _estimatedPoolIndex, uint256 _estimatedTraderIndex)`](#MarginFlowProtocolLiquidated-closePositionForLiquidatedPool-uint256-uint256-uint256-) 28 | 29 | Force close position for trader for liquidated pool. 30 | 31 | #### Parameters: 32 | 33 | - `_positionId`: The id of the position to close. 34 | 35 | - `_estimatedPoolIndex`: The index inside the pool positions array. 36 | 37 | - `_estimatedTraderIndex`: The index inside the trader positions array. 38 | 39 | ### [Function `closePositionForLiquidatedTrader(uint256 _positionId, uint256 _estimatedPoolIndex, uint256 _estimatedTraderIndex) → int256`](#MarginFlowProtocolLiquidated-closePositionForLiquidatedTrader-uint256-uint256-uint256-) 40 | 41 | Force close position for trader for liquidated trader. 42 | 43 | #### Parameters: 44 | 45 | - `_positionId`: The id of the position to close. 46 | 47 | - `_estimatedPoolIndex`: The index inside the pool positions array. 48 | 49 | - `_estimatedTraderIndex`: The index inside the trader positions array. 50 | 51 | ### [Function `restoreTraderInPool(contract MarginLiquidityPoolInterface _pool, address _trader)`](#MarginFlowProtocolLiquidated-restoreTraderInPool-contract-MarginLiquidityPoolInterface-address-) 52 | 53 | Restore a trader in a pool after being liquidated. 54 | 55 | #### Parameters: 56 | 57 | - `_pool`: The margin liquidity pool. 58 | 59 | - `_trader`: The trader. 60 | 61 | ### [Function `restoreLiquidatedPool(contract MarginLiquidityPoolInterface _pool)`](#MarginFlowProtocolLiquidated-restoreLiquidatedPool-contract-MarginLiquidityPoolInterface-) 62 | 63 | Restore a pool after being liquidated. 64 | 65 | #### Parameters: 66 | 67 | - `_pool`: The margin liquidity pool. 68 | 69 | ### [Function `__stopPool(contract MarginLiquidityPoolInterface _pool)`](#MarginFlowProtocolLiquidated-__stopPool-contract-MarginLiquidityPoolInterface-) 70 | 71 | No description 72 | 73 | ### [Function `__stopTraderInPool(contract MarginLiquidityPoolInterface _pool, address _trader)`](#MarginFlowProtocolLiquidated-__stopTraderInPool-contract-MarginLiquidityPoolInterface-address-) 74 | 75 | No description 76 | 77 | ### [Function `getEstimatedEquityOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader, struct Percentage.Percent _usdPairPrice, struct Percentage.Percent _closePrice) → int256`](#MarginFlowProtocolLiquidated-getEstimatedEquityOfTrader-contract-MarginLiquidityPoolInterface-address-struct-Percentage-Percent-struct-Percentage-Percent-) 78 | 79 | No description 80 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/margin/MarginLiquidityPoolRegistry.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(struct MarginMarketLib.MarketData _market)`](#MarginLiquidityPoolRegistry-initialize-struct-MarginMarketLib-MarketData-) 4 | 5 | - [`registerPool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-registerPool-contract-MarginLiquidityPoolInterface-) 6 | 7 | - [`verifyPool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-verifyPool-contract-MarginLiquidityPoolInterface-) 8 | 9 | - [`unverifyPool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-unverifyPool-contract-MarginLiquidityPoolInterface-) 10 | 11 | - [`marginCallPool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-marginCallPool-contract-MarginLiquidityPoolInterface-) 12 | 13 | - [`liquidatePool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-liquidatePool-contract-MarginLiquidityPoolInterface-) 14 | 15 | - [`makePoolSafe(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-makePoolSafe-contract-MarginLiquidityPoolInterface-) 16 | 17 | ### [Function `initialize(struct MarginMarketLib.MarketData _market)`](#MarginLiquidityPoolRegistry-initialize-struct-MarginMarketLib-MarketData-) 18 | 19 | No description 20 | 21 | ### [Function `registerPool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-registerPool-contract-MarginLiquidityPoolInterface-) 22 | 23 | Register a new pool by sending the combined margin and liquidation fees. 24 | 25 | #### Parameters: 26 | 27 | - `_pool`: The MarginLiquidityPool. 28 | 29 | ### [Function `verifyPool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-verifyPool-contract-MarginLiquidityPoolInterface-) 30 | 31 | Verify a new pool, only for the owner. 32 | 33 | #### Parameters: 34 | 35 | - `_pool`: The MarginLiquidityPool. 36 | 37 | ### [Function `unverifyPool(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-unverifyPool-contract-MarginLiquidityPoolInterface-) 38 | 39 | Unverify a pool, only for the owner. 40 | 41 | #### Parameters: 42 | 43 | - `_pool`: The MarginLiquidityPool. 44 | 45 | ### [Function `marginCallPool(contract MarginLiquidityPoolInterface _pool) → uint256`](#MarginLiquidityPoolRegistry-marginCallPool-contract-MarginLiquidityPoolInterface-) 46 | 47 | Margin call a pool, only used by the address(market.protocolSafety). 48 | 49 | #### Parameters: 50 | 51 | - `_pool`: The MarginLiquidityPool. 52 | 53 | ### [Function `liquidatePool(contract MarginLiquidityPoolInterface _pool) → uint256`](#MarginLiquidityPoolRegistry-liquidatePool-contract-MarginLiquidityPoolInterface-) 54 | 55 | Margin call a pool, only used by the address(market.protocolSafety). 56 | 57 | #### Parameters: 58 | 59 | - `_pool`: The MarginLiquidityPool. 60 | 61 | ### [Function `makePoolSafe(contract MarginLiquidityPoolInterface _pool)`](#MarginLiquidityPoolRegistry-makePoolSafe-contract-MarginLiquidityPoolInterface-) 62 | 63 | Make pool safe, only used by address(market.protocolSafety). 64 | 65 | #### Parameters: 66 | 67 | - `_pool`: The MarginLiquidityPool. 68 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/oracles/ChainLinkOracle.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(address _link, address _usdToken, address[] _currencyReferences, address[] _tokenReferences)`](#ChainLinkOracle-initialize-address-address-address---address---) 4 | 5 | - [`setOracleAddress(address _token, address _aggregator)`](#ChainLinkOracle-setOracleAddress-address-address-) 6 | 7 | - [`getPrice(address _key)`](#ChainLinkOracle-getPrice-address-) 8 | 9 | - [`readPrice(address _key)`](#ChainLinkOracle-readPrice-address-) 10 | 11 | - [`isPriceOracle()`](#ChainLinkOracle-isPriceOracle--) 12 | 13 | ### [Function `initialize(address _link, address _usdToken, address[] _currencyReferences, address[] _tokenReferences)`](#ChainLinkOracle-initialize-address-address-address---address---) 14 | 15 | No description 16 | 17 | ### [Function `setOracleAddress(address _token, address _aggregator)`](#ChainLinkOracle-setOracleAddress-address-address-) 18 | 19 | No description 20 | 21 | ### [Function `getPrice(address _key) → uint256`](#ChainLinkOracle-getPrice-address-) 22 | 23 | No description 24 | 25 | ### [Function `readPrice(address _key) → uint256`](#ChainLinkOracle-readPrice-address-) 26 | 27 | No description 28 | 29 | ### [Function `isPriceOracle() → bool`](#ChainLinkOracle-isPriceOracle--) 30 | 31 | No description 32 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/oracles/PriceOracleConfig.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize()`](#PriceOracleConfig-initialize--) 4 | 5 | - [`setOracleDeltaLastLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaLastLimit-uint256-) 6 | 7 | - [`setOracleDeltaSnapshotLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaSnapshotLimit-uint256-) 8 | 9 | - [`setOracleDeltaSnapshotTime(uint256 time)`](#PriceOracleConfig-setOracleDeltaSnapshotTime-uint256-) 10 | 11 | - [`setExpireIn(uint256 time)`](#PriceOracleConfig-setExpireIn-uint256-) 12 | 13 | ### [Function `initialize()`](#PriceOracleConfig-initialize--) 14 | 15 | No description 16 | 17 | ### [Function `setOracleDeltaLastLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaLastLimit-uint256-) 18 | 19 | No description 20 | 21 | ### [Function `setOracleDeltaSnapshotLimit(uint256 limit)`](#PriceOracleConfig-setOracleDeltaSnapshotLimit-uint256-) 22 | 23 | No description 24 | 25 | ### [Function `setOracleDeltaSnapshotTime(uint256 time)`](#PriceOracleConfig-setOracleDeltaSnapshotTime-uint256-) 26 | 27 | No description 28 | 29 | ### [Function `setExpireIn(uint256 time)`](#PriceOracleConfig-setExpireIn-uint256-) 30 | 31 | No description 32 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/oracles/SimplePriceOracle.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize()`](#SimplePriceOracle-initialize--) 4 | 5 | - [`isPriceOracle()`](#SimplePriceOracle-isPriceOracle--) 6 | 7 | - [`feedPrice(address key, uint256 price)`](#SimplePriceOracle-feedPrice-address-uint256-) 8 | 9 | - [`getPrice(address key)`](#SimplePriceOracle-getPrice-address-) 10 | 11 | - [`readPrice(address key)`](#SimplePriceOracle-readPrice-address-) 12 | 13 | ## Events: 14 | 15 | - [`PriceUpdated(address addr, uint256 price)`](#SimplePriceOracle-PriceUpdated-address-uint256-) 16 | 17 | ### [Function `initialize()`](#SimplePriceOracle-initialize--) 18 | 19 | No description 20 | 21 | ### [Function `isPriceOracle() → bool`](#SimplePriceOracle-isPriceOracle--) 22 | 23 | No description 24 | 25 | ### [Function `feedPrice(address key, uint256 price)`](#SimplePriceOracle-feedPrice-address-uint256-) 26 | 27 | No description 28 | 29 | ### [Function `getPrice(address key) → uint256`](#SimplePriceOracle-getPrice-address-) 30 | 31 | No description 32 | 33 | ### [Function `readPrice(address key) → uint256`](#SimplePriceOracle-readPrice-address-) 34 | 35 | No description 36 | 37 | ### Event `PriceUpdated(address addr, uint256 price)` {#SimplePriceOracle-PriceUpdated-address-uint256-} 38 | 39 | No description 40 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/synthetic/SyntheticFlowToken.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(string _name, string _symbol, contract MoneyMarketInterface _moneyMarket, address _protocol, uint256 _extremeCollateralRatio, uint256 _liquidationCollateralRatio, uint256 _defaultCollateralRatio)`](#SyntheticFlowToken-initialize-string-string-contract-MoneyMarketInterface-address-uint256-uint256-uint256-) 4 | 5 | - [`setLiquidationCollateralRatio(uint256 percent)`](#SyntheticFlowToken-setLiquidationCollateralRatio-uint256-) 6 | 7 | - [`setExtremeCollateralRatio(uint256 percent)`](#SyntheticFlowToken-setExtremeCollateralRatio-uint256-) 8 | 9 | - [`setDefaultCollateralRatio(uint256 percent)`](#SyntheticFlowToken-setDefaultCollateralRatio-uint256-) 10 | 11 | - [`incentiveRatio(uint256 currentRatio)`](#SyntheticFlowToken-incentiveRatio-uint256-) 12 | 13 | - [`mint(address account, uint256 amount)`](#SyntheticFlowToken-mint-address-uint256-) 14 | 15 | - [`burn(address account, uint256 amount)`](#SyntheticFlowToken-burn-address-uint256-) 16 | 17 | - [`getPosition(address poolAddr)`](#SyntheticFlowToken-getPosition-address-) 18 | 19 | - [`addPosition(address poolAddr, uint256 additonalCollaterals, uint256 additionalMinted, uint256 liquidityPoolShares)`](#SyntheticFlowToken-addPosition-address-uint256-uint256-uint256-) 20 | 21 | - [`removePosition(address poolAddr, uint256 collateralsToRemove, uint256 mintedToRemove)`](#SyntheticFlowToken-removePosition-address-uint256-uint256-) 22 | 23 | - [`interestShareExchangeRate()`](#SyntheticFlowToken-interestShareExchangeRate--) 24 | 25 | - [`withdrawTo(address recipient, uint256 baseTokenAmount)`](#SyntheticFlowToken-withdrawTo-address-uint256-) 26 | 27 | - [`deposit(address sender, uint256 amount, uint256 price)`](#SyntheticFlowToken-deposit-address-uint256-uint256-) 28 | 29 | - [`withdraw(address sender, uint256 amount)`](#SyntheticFlowToken-withdraw-address-uint256-) 30 | 31 | ### [Function `initialize(string _name, string _symbol, contract MoneyMarketInterface _moneyMarket, address _protocol, uint256 _extremeCollateralRatio, uint256 _liquidationCollateralRatio, uint256 _defaultCollateralRatio)`](#SyntheticFlowToken-initialize-string-string-contract-MoneyMarketInterface-address-uint256-uint256-uint256-) 32 | 33 | No description 34 | 35 | ### [Function `setLiquidationCollateralRatio(uint256 percent)`](#SyntheticFlowToken-setLiquidationCollateralRatio-uint256-) 36 | 37 | No description 38 | 39 | ### [Function `setExtremeCollateralRatio(uint256 percent)`](#SyntheticFlowToken-setExtremeCollateralRatio-uint256-) 40 | 41 | No description 42 | 43 | ### [Function `setDefaultCollateralRatio(uint256 percent)`](#SyntheticFlowToken-setDefaultCollateralRatio-uint256-) 44 | 45 | No description 46 | 47 | ### [Function `incentiveRatio(uint256 currentRatio) → uint256`](#SyntheticFlowToken-incentiveRatio-uint256-) 48 | 49 | No description 50 | 51 | ### [Function `mint(address account, uint256 amount)`](#SyntheticFlowToken-mint-address-uint256-) 52 | 53 | No description 54 | 55 | ### [Function `burn(address account, uint256 amount)`](#SyntheticFlowToken-burn-address-uint256-) 56 | 57 | No description 58 | 59 | ### [Function `getPosition(address poolAddr) → uint256 collaterals, uint256 minted`](#SyntheticFlowToken-getPosition-address-) 60 | 61 | No description 62 | 63 | ### [Function `addPosition(address poolAddr, uint256 additonalCollaterals, uint256 additionalMinted, uint256 liquidityPoolShares)`](#SyntheticFlowToken-addPosition-address-uint256-uint256-uint256-) 64 | 65 | No description 66 | 67 | ### [Function `removePosition(address poolAddr, uint256 collateralsToRemove, uint256 mintedToRemove) → uint256`](#SyntheticFlowToken-removePosition-address-uint256-uint256-) 68 | 69 | No description 70 | 71 | ### [Function `interestShareExchangeRate() → uint256`](#SyntheticFlowToken-interestShareExchangeRate--) 72 | 73 | No description 74 | 75 | ### [Function `withdrawTo(address recipient, uint256 baseTokenAmount)`](#SyntheticFlowToken-withdrawTo-address-uint256-) 76 | 77 | No description 78 | 79 | ### [Function `deposit(address sender, uint256 amount, uint256 price) → uint256`](#SyntheticFlowToken-deposit-address-uint256-uint256-) 80 | 81 | No description 82 | 83 | ### [Function `withdraw(address sender, uint256 amount) → uint256`](#SyntheticFlowToken-withdraw-address-uint256-) 84 | 85 | No description 86 | -------------------------------------------------------------------------------- /generated-docs/docs/impls/synthetic/SyntheticLiquidityPool.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(contract MoneyMarketInterface _moneyMarket, address _protocol)`](#SyntheticLiquidityPool-initialize-contract-MoneyMarketInterface-address-) 4 | 5 | - [`getBidSpread(address _fToken)`](#SyntheticLiquidityPool-getBidSpread-address-) 6 | 7 | - [`getAskSpread(address _fToken)`](#SyntheticLiquidityPool-getAskSpread-address-) 8 | 9 | - [`getAdditionalCollateralRatio(address fToken)`](#SyntheticLiquidityPool-getAdditionalCollateralRatio-address-) 10 | 11 | - [`setSpreadForToken(address _token, uint256 _value)`](#SyntheticLiquidityPool-setSpreadForToken-address-uint256-) 12 | 13 | - [`setCollateralRatio(uint256 _value)`](#SyntheticLiquidityPool-setCollateralRatio-uint256-) 14 | 15 | - [`enableToken(address _token, uint256 _spread)`](#SyntheticLiquidityPool-enableToken-address-uint256-) 16 | 17 | - [`disableToken(address _token)`](#SyntheticLiquidityPool-disableToken-address-) 18 | 19 | - [`addCollateral(contract SyntheticFlowToken _token, uint256 _baseTokenAmount)`](#SyntheticLiquidityPool-addCollateral-contract-SyntheticFlowToken-uint256-) 20 | 21 | - [`withdrawCollateral(contract SyntheticFlowToken _token)`](#SyntheticLiquidityPool-withdrawCollateral-contract-SyntheticFlowToken-) 22 | 23 | ### [Function `initialize(contract MoneyMarketInterface _moneyMarket, address _protocol)`](#SyntheticLiquidityPool-initialize-contract-MoneyMarketInterface-address-) 24 | 25 | No description 26 | 27 | ### [Function `getBidSpread(address _fToken) → uint256`](#SyntheticLiquidityPool-getBidSpread-address-) 28 | 29 | No description 30 | 31 | ### [Function `getAskSpread(address _fToken) → uint256`](#SyntheticLiquidityPool-getAskSpread-address-) 32 | 33 | No description 34 | 35 | ### [Function `getAdditionalCollateralRatio(address fToken) → uint256`](#SyntheticLiquidityPool-getAdditionalCollateralRatio-address-) 36 | 37 | No description 38 | 39 | ### [Function `setSpreadForToken(address _token, uint256 _value)`](#SyntheticLiquidityPool-setSpreadForToken-address-uint256-) 40 | 41 | No description 42 | 43 | ### [Function `setCollateralRatio(uint256 _value)`](#SyntheticLiquidityPool-setCollateralRatio-uint256-) 44 | 45 | No description 46 | 47 | ### [Function `enableToken(address _token, uint256 _spread)`](#SyntheticLiquidityPool-enableToken-address-uint256-) 48 | 49 | No description 50 | 51 | ### [Function `disableToken(address _token)`](#SyntheticLiquidityPool-disableToken-address-) 52 | 53 | No description 54 | 55 | ### [Function `addCollateral(contract SyntheticFlowToken _token, uint256 _baseTokenAmount)`](#SyntheticLiquidityPool-addCollateral-contract-SyntheticFlowToken-uint256-) 56 | 57 | No description 58 | 59 | ### [Function `withdrawCollateral(contract SyntheticFlowToken _token)`](#SyntheticLiquidityPool-withdrawCollateral-contract-SyntheticFlowToken-) 60 | 61 | No description 62 | -------------------------------------------------------------------------------- /generated-docs/docs/interfaces/CErc20Interface.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`totalSupply()`](#CErc20Interface-totalSupply--) 4 | 5 | - [`exchangeRateStored()`](#CErc20Interface-exchangeRateStored--) 6 | 7 | - [`getCash()`](#CErc20Interface-getCash--) 8 | 9 | - [`totalBorrows()`](#CErc20Interface-totalBorrows--) 10 | 11 | - [`underlying()`](#CErc20Interface-underlying--) 12 | 13 | - [`balanceOf(address owner)`](#CErc20Interface-balanceOf-address-) 14 | 15 | - [`redeemUnderlying(uint256 redeemAmount)`](#CErc20Interface-redeemUnderlying-uint256-) 16 | 17 | - [`mint(uint256 mintAmount)`](#CErc20Interface-mint-uint256-) 18 | 19 | - [`transfer(address dst, uint256 amount)`](#CErc20Interface-transfer-address-uint256-) 20 | 21 | - [`redeem(uint256 redeemTokens)`](#CErc20Interface-redeem-uint256-) 22 | 23 | - [`approve(address spender, uint256 amount)`](#CErc20Interface-approve-address-uint256-) 24 | 25 | - [`transferFrom(address src, address dst, uint256 amount)`](#CErc20Interface-transferFrom-address-address-uint256-) 26 | 27 | ### [Function `totalSupply() → uint256`](#CErc20Interface-totalSupply--) 28 | 29 | No description 30 | 31 | ### [Function `exchangeRateStored() → uint256`](#CErc20Interface-exchangeRateStored--) 32 | 33 | No description 34 | 35 | ### [Function `getCash() → uint256`](#CErc20Interface-getCash--) 36 | 37 | No description 38 | 39 | ### [Function `totalBorrows() → uint256`](#CErc20Interface-totalBorrows--) 40 | 41 | No description 42 | 43 | ### [Function `underlying() → address`](#CErc20Interface-underlying--) 44 | 45 | No description 46 | 47 | ### [Function `balanceOf(address owner) → uint256`](#CErc20Interface-balanceOf-address-) 48 | 49 | No description 50 | 51 | ### [Function `redeemUnderlying(uint256 redeemAmount) → uint256`](#CErc20Interface-redeemUnderlying-uint256-) 52 | 53 | No description 54 | 55 | ### [Function `mint(uint256 mintAmount) → uint256`](#CErc20Interface-mint-uint256-) 56 | 57 | No description 58 | 59 | ### [Function `transfer(address dst, uint256 amount) → bool`](#CErc20Interface-transfer-address-uint256-) 60 | 61 | No description 62 | 63 | ### [Function `redeem(uint256 redeemTokens) → uint256`](#CErc20Interface-redeem-uint256-) 64 | 65 | No description 66 | 67 | ### [Function `approve(address spender, uint256 amount) → bool`](#CErc20Interface-approve-address-uint256-) 68 | 69 | No description 70 | 71 | ### [Function `transferFrom(address src, address dst, uint256 amount) → bool`](#CErc20Interface-transferFrom-address-address-uint256-) 72 | 73 | No description 74 | -------------------------------------------------------------------------------- /generated-docs/docs/interfaces/LiquidityPoolInterface.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`protocol()`](#LiquidityPoolInterface-protocol--) 4 | 5 | - [`moneyMarket()`](#LiquidityPoolInterface-moneyMarket--) 6 | 7 | - [`approveToProtocol(uint256 amount)`](#LiquidityPoolInterface-approveToProtocol-uint256-) 8 | 9 | - [`getOwner()`](#LiquidityPoolInterface-getOwner--) 10 | 11 | ### [Function `protocol() → address`](#LiquidityPoolInterface-protocol--) 12 | 13 | No description 14 | 15 | ### [Function `moneyMarket() → contract MoneyMarketInterface`](#LiquidityPoolInterface-moneyMarket--) 16 | 17 | No description 18 | 19 | ### [Function `approveToProtocol(uint256 amount)`](#LiquidityPoolInterface-approveToProtocol-uint256-) 20 | 21 | No description 22 | 23 | ### [Function `getOwner() → address`](#LiquidityPoolInterface-getOwner--) 24 | 25 | No description 26 | -------------------------------------------------------------------------------- /generated-docs/docs/interfaces/MoneyMarketInterface.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`baseToken()`](#MoneyMarketInterface-baseToken--) 4 | 5 | - [`iToken()`](#MoneyMarketInterface-iToken--) 6 | 7 | - [`exchangeRate()`](#MoneyMarketInterface-exchangeRate--) 8 | 9 | - [`mint(uint256 baseTokenAmount)`](#MoneyMarketInterface-mint-uint256-) 10 | 11 | - [`mintTo(address recipient, uint256 baseTokenAmount)`](#MoneyMarketInterface-mintTo-address-uint256-) 12 | 13 | - [`redeem(uint256 iTokenAmount)`](#MoneyMarketInterface-redeem-uint256-) 14 | 15 | - [`redeemTo(address recipient, uint256 iTokenAmount)`](#MoneyMarketInterface-redeemTo-address-uint256-) 16 | 17 | - [`redeemBaseToken(uint256 baseTokenAmount)`](#MoneyMarketInterface-redeemBaseToken-uint256-) 18 | 19 | - [`redeemBaseTokenTo(address recipient, uint256 baseTokenAmount)`](#MoneyMarketInterface-redeemBaseTokenTo-address-uint256-) 20 | 21 | - [`convertAmountFromBase(uint256 _baseTokenAmount)`](#MoneyMarketInterface-convertAmountFromBase-uint256-) 22 | 23 | - [`convertAmountFromBase(uint256 rate, uint256 baseTokenAmount)`](#MoneyMarketInterface-convertAmountFromBase-uint256-uint256-) 24 | 25 | - [`convertAmountToBase(uint256 iTokenAmount)`](#MoneyMarketInterface-convertAmountToBase-uint256-) 26 | 27 | - [`convertAmountToBase(uint256 rate, uint256 iTokenAmount)`](#MoneyMarketInterface-convertAmountToBase-uint256-uint256-) 28 | 29 | - [`convertAmountFromBase(int256 _baseTokenAmount)`](#MoneyMarketInterface-convertAmountFromBase-int256-) 30 | 31 | - [`convertAmountFromBase(int256 rate, int256 baseTokenAmount)`](#MoneyMarketInterface-convertAmountFromBase-int256-int256-) 32 | 33 | - [`convertAmountToBase(int256 iTokenAmount)`](#MoneyMarketInterface-convertAmountToBase-int256-) 34 | 35 | - [`convertAmountToBase(int256 rate, int256 iTokenAmount)`](#MoneyMarketInterface-convertAmountToBase-int256-int256-) 36 | 37 | - [`totalHoldings()`](#MoneyMarketInterface-totalHoldings--) 38 | 39 | ## Events: 40 | 41 | - [`Minted(address recipient, uint256 baseTokenAmount, uint256 iTokenAmount)`](#MoneyMarketInterface-Minted-address-uint256-uint256-) 42 | 43 | - [`Redeemed(address recipient, uint256 baseTokenAmount, uint256 iTokenAmount)`](#MoneyMarketInterface-Redeemed-address-uint256-uint256-) 44 | 45 | ### [Function `baseToken() → contract IERC20`](#MoneyMarketInterface-baseToken--) 46 | 47 | No description 48 | 49 | ### [Function `iToken() → contract IERC20`](#MoneyMarketInterface-iToken--) 50 | 51 | No description 52 | 53 | ### [Function `exchangeRate() → uint256`](#MoneyMarketInterface-exchangeRate--) 54 | 55 | No description 56 | 57 | ### [Function `mint(uint256 baseTokenAmount) → uint256`](#MoneyMarketInterface-mint-uint256-) 58 | 59 | No description 60 | 61 | ### [Function `mintTo(address recipient, uint256 baseTokenAmount) → uint256`](#MoneyMarketInterface-mintTo-address-uint256-) 62 | 63 | No description 64 | 65 | ### [Function `redeem(uint256 iTokenAmount) → uint256`](#MoneyMarketInterface-redeem-uint256-) 66 | 67 | No description 68 | 69 | ### [Function `redeemTo(address recipient, uint256 iTokenAmount) → uint256`](#MoneyMarketInterface-redeemTo-address-uint256-) 70 | 71 | No description 72 | 73 | ### [Function `redeemBaseToken(uint256 baseTokenAmount) → uint256`](#MoneyMarketInterface-redeemBaseToken-uint256-) 74 | 75 | No description 76 | 77 | ### [Function `redeemBaseTokenTo(address recipient, uint256 baseTokenAmount) → uint256`](#MoneyMarketInterface-redeemBaseTokenTo-address-uint256-) 78 | 79 | No description 80 | 81 | ### [Function `convertAmountFromBase(uint256 _baseTokenAmount) → uint256`](#MoneyMarketInterface-convertAmountFromBase-uint256-) 82 | 83 | No description 84 | 85 | ### [Function `convertAmountFromBase(uint256 rate, uint256 baseTokenAmount) → uint256`](#MoneyMarketInterface-convertAmountFromBase-uint256-uint256-) 86 | 87 | No description 88 | 89 | ### [Function `convertAmountToBase(uint256 iTokenAmount) → uint256`](#MoneyMarketInterface-convertAmountToBase-uint256-) 90 | 91 | No description 92 | 93 | ### [Function `convertAmountToBase(uint256 rate, uint256 iTokenAmount) → uint256`](#MoneyMarketInterface-convertAmountToBase-uint256-uint256-) 94 | 95 | No description 96 | 97 | ### [Function `convertAmountFromBase(int256 _baseTokenAmount) → int256`](#MoneyMarketInterface-convertAmountFromBase-int256-) 98 | 99 | No description 100 | 101 | ### [Function `convertAmountFromBase(int256 rate, int256 baseTokenAmount) → int256`](#MoneyMarketInterface-convertAmountFromBase-int256-int256-) 102 | 103 | No description 104 | 105 | ### [Function `convertAmountToBase(int256 iTokenAmount) → int256`](#MoneyMarketInterface-convertAmountToBase-int256-) 106 | 107 | No description 108 | 109 | ### [Function `convertAmountToBase(int256 rate, int256 iTokenAmount) → int256`](#MoneyMarketInterface-convertAmountToBase-int256-int256-) 110 | 111 | No description 112 | 113 | ### [Function `totalHoldings() → uint256`](#MoneyMarketInterface-totalHoldings--) 114 | 115 | No description 116 | 117 | ### Event `Minted(address recipient, uint256 baseTokenAmount, uint256 iTokenAmount)` {#MoneyMarketInterface-Minted-address-uint256-uint256-} 118 | 119 | No description 120 | 121 | ### Event `Redeemed(address recipient, uint256 baseTokenAmount, uint256 iTokenAmount)` {#MoneyMarketInterface-Redeemed-address-uint256-uint256-} 122 | 123 | No description 124 | -------------------------------------------------------------------------------- /generated-docs/docs/interfaces/PriceOracleInterface.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`isPriceOracle()`](#PriceOracleInterface-isPriceOracle--) 4 | 5 | - [`getPrice(address addr)`](#PriceOracleInterface-getPrice-address-) 6 | 7 | - [`readPrice(address addr)`](#PriceOracleInterface-readPrice-address-) 8 | 9 | ## Events: 10 | 11 | - [`PriceFeeded(address addr, address sender, uint256 price)`](#PriceOracleInterface-PriceFeeded-address-address-uint256-) 12 | 13 | - [`PriceUpdated(address addr, uint256 price)`](#PriceOracleInterface-PriceUpdated-address-uint256-) 14 | 15 | ### [Function `isPriceOracle() → bool`](#PriceOracleInterface-isPriceOracle--) 16 | 17 | No description 18 | 19 | ### [Function `getPrice(address addr) → uint256`](#PriceOracleInterface-getPrice-address-) 20 | 21 | No description 22 | 23 | ### [Function `readPrice(address addr) → uint256`](#PriceOracleInterface-readPrice-address-) 24 | 25 | No description 26 | 27 | ### Event `PriceFeeded(address addr, address sender, uint256 price)` {#PriceOracleInterface-PriceFeeded-address-address-uint256-} 28 | 29 | No description 30 | 31 | ### Event `PriceUpdated(address addr, uint256 price)` {#PriceOracleInterface-PriceUpdated-address-uint256-} 32 | 33 | No description 34 | -------------------------------------------------------------------------------- /generated-docs/docs/interfaces/SyntheticLiquidityPoolInterface.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addCollateral(contract SyntheticFlowToken token, uint256 baseTokenAmount)`](#SyntheticLiquidityPoolInterface-addCollateral-contract-SyntheticFlowToken-uint256-) 4 | 5 | - [`withdrawCollateral(contract SyntheticFlowToken token)`](#SyntheticLiquidityPoolInterface-withdrawCollateral-contract-SyntheticFlowToken-) 6 | 7 | - [`getBidSpread(address fToken)`](#SyntheticLiquidityPoolInterface-getBidSpread-address-) 8 | 9 | - [`getAskSpread(address fToken)`](#SyntheticLiquidityPoolInterface-getAskSpread-address-) 10 | 11 | - [`setSpreadForToken(address fToken, uint256 value)`](#SyntheticLiquidityPoolInterface-setSpreadForToken-address-uint256-) 12 | 13 | - [`spreadsPerToken(address fToken)`](#SyntheticLiquidityPoolInterface-spreadsPerToken-address-) 14 | 15 | - [`collateralRatio()`](#SyntheticLiquidityPoolInterface-collateralRatio--) 16 | 17 | - [`getAdditionalCollateralRatio(address fToken)`](#SyntheticLiquidityPoolInterface-getAdditionalCollateralRatio-address-) 18 | 19 | - [`setCollateralRatio(uint256 value)`](#SyntheticLiquidityPoolInterface-setCollateralRatio-uint256-) 20 | 21 | - [`enableToken(address token, uint256 spread)`](#SyntheticLiquidityPoolInterface-enableToken-address-uint256-) 22 | 23 | - [`disableToken(address token)`](#SyntheticLiquidityPoolInterface-disableToken-address-) 24 | 25 | - [`allowedTokens(address token)`](#SyntheticLiquidityPoolInterface-allowedTokens-address-) 26 | 27 | ## Events: 28 | 29 | - [`SpreadUpdated(address token, uint256 newSpread)`](#SyntheticLiquidityPoolInterface-SpreadUpdated-address-uint256-) 30 | 31 | - [`AdditionalCollateralRatioUpdated()`](#SyntheticLiquidityPoolInterface-AdditionalCollateralRatioUpdated--) 32 | 33 | ### [Function `addCollateral(contract SyntheticFlowToken token, uint256 baseTokenAmount)`](#SyntheticLiquidityPoolInterface-addCollateral-contract-SyntheticFlowToken-uint256-) 34 | 35 | No description 36 | 37 | ### [Function `withdrawCollateral(contract SyntheticFlowToken token)`](#SyntheticLiquidityPoolInterface-withdrawCollateral-contract-SyntheticFlowToken-) 38 | 39 | No description 40 | 41 | ### [Function `getBidSpread(address fToken) → uint256`](#SyntheticLiquidityPoolInterface-getBidSpread-address-) 42 | 43 | No description 44 | 45 | ### [Function `getAskSpread(address fToken) → uint256`](#SyntheticLiquidityPoolInterface-getAskSpread-address-) 46 | 47 | No description 48 | 49 | ### [Function `setSpreadForToken(address fToken, uint256 value)`](#SyntheticLiquidityPoolInterface-setSpreadForToken-address-uint256-) 50 | 51 | No description 52 | 53 | ### [Function `spreadsPerToken(address fToken) → uint256`](#SyntheticLiquidityPoolInterface-spreadsPerToken-address-) 54 | 55 | No description 56 | 57 | ### [Function `collateralRatio() → uint256`](#SyntheticLiquidityPoolInterface-collateralRatio--) 58 | 59 | No description 60 | 61 | ### [Function `getAdditionalCollateralRatio(address fToken) → uint256`](#SyntheticLiquidityPoolInterface-getAdditionalCollateralRatio-address-) 62 | 63 | No description 64 | 65 | ### [Function `setCollateralRatio(uint256 value)`](#SyntheticLiquidityPoolInterface-setCollateralRatio-uint256-) 66 | 67 | No description 68 | 69 | ### [Function `enableToken(address token, uint256 spread)`](#SyntheticLiquidityPoolInterface-enableToken-address-uint256-) 70 | 71 | No description 72 | 73 | ### [Function `disableToken(address token)`](#SyntheticLiquidityPoolInterface-disableToken-address-) 74 | 75 | No description 76 | 77 | ### [Function `allowedTokens(address token) → bool`](#SyntheticLiquidityPoolInterface-allowedTokens-address-) 78 | 79 | No description 80 | 81 | ### Event `SpreadUpdated(address token, uint256 newSpread)` {#SyntheticLiquidityPoolInterface-SpreadUpdated-address-uint256-} 82 | 83 | No description 84 | 85 | ### Event `AdditionalCollateralRatioUpdated()` {#SyntheticLiquidityPoolInterface-AdditionalCollateralRatioUpdated--} 86 | 87 | No description 88 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/Arrays.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/Percentage.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/upgrades/ERC20DetailedUpgradable.md: -------------------------------------------------------------------------------- 1 | Optional functions from the ERC20 standard. 2 | 3 | ## Functions: 4 | 5 | - [`initialize(string name, string symbol, uint8 decimals)`](#ERC20DetailedUpgradable-initialize-string-string-uint8-) 6 | 7 | - [`name()`](#ERC20DetailedUpgradable-name--) 8 | 9 | - [`symbol()`](#ERC20DetailedUpgradable-symbol--) 10 | 11 | - [`decimals()`](#ERC20DetailedUpgradable-decimals--) 12 | 13 | ### [Function `initialize(string name, string symbol, uint8 decimals)`](#ERC20DetailedUpgradable-initialize-string-string-uint8-) 14 | 15 | Sets the values for `name`, `symbol`, and `decimals`. All three of 16 | 17 | these values are immutable: they can only be set once during 18 | 19 | construction. 20 | 21 | ### [Function `name() → string`](#ERC20DetailedUpgradable-name--) 22 | 23 | Returns the name of the token. 24 | 25 | ### [Function `symbol() → string`](#ERC20DetailedUpgradable-symbol--) 26 | 27 | Returns the symbol of the token, usually a shorter version of the 28 | 29 | name. 30 | 31 | ### [Function `decimals() → uint8`](#ERC20DetailedUpgradable-decimals--) 32 | 33 | Returns the number of decimals used to get its user representation. 34 | 35 | For example, if `decimals` equals `2`, a balance of `505` tokens should 36 | 37 | be displayed to a user as `5,05` (`505 / 10 ** 2`). 38 | 39 | Tokens usually opt for a value of 18, imitating the relationship between 40 | 41 | Ether and Wei. 42 | 43 | NOTE: This information is only used for _display_ purposes: it in 44 | 45 | no way affects any of the arithmetic of the contract, including 46 | 47 | {IERC20-balanceOf} and {IERC20-transfer}. 48 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/upgrades/Proxy.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`transferProxyOwnership(address _newOwner)`](#Proxy-transferProxyOwnership-address-) 4 | 5 | - [`upgradeTo(address _implementation)`](#Proxy-upgradeTo-address-) 6 | 7 | - [`implementation()`](#Proxy-implementation--) 8 | 9 | - [`proxyOwner()`](#Proxy-proxyOwner--) 10 | 11 | - [`fallback()`](#Proxy-fallback--) 12 | 13 | - [`receive()`](#Proxy-receive--) 14 | 15 | ### [Function `transferProxyOwnership(address _newOwner)`](#Proxy-transferProxyOwnership-address-) 16 | 17 | No description 18 | 19 | ### [Function `upgradeTo(address _implementation)`](#Proxy-upgradeTo-address-) 20 | 21 | No description 22 | 23 | ### [Function `implementation() → address impl`](#Proxy-implementation--) 24 | 25 | No description 26 | 27 | ### [Function `proxyOwner() → address owner`](#Proxy-proxyOwner--) 28 | 29 | No description 30 | 31 | ### [Function `fallback()`](#Proxy-fallback--) 32 | 33 | No description 34 | 35 | ### [Function `receive()`](#Proxy-receive--) 36 | 37 | No description 38 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/upgrades/UpgradeAccessControl.md: -------------------------------------------------------------------------------- 1 | Contract module that allows children to implement role-based access 2 | 3 | control mechanisms. 4 | 5 | Roles are referred to by their `bytes32` identifier. These should be exposed 6 | 7 | in the external API and be unique. The best way to achieve this is by 8 | 9 | using `public constant` hash digests: 10 | 11 | ``` 12 | 13 | bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); 14 | 15 | ``` 16 | 17 | Roles can be used to represent a set of permissions. To restrict access to a 18 | 19 | function call, use {hasRole}: 20 | 21 | ``` 22 | 23 | function foo() public { 24 | 25 | require(hasRole(MY_ROLE, _msgSender())); 26 | 27 | ... 28 | 29 | } 30 | 31 | ``` 32 | 33 | Roles can be granted and revoked programatically by calling the `internal` 34 | 35 | {_grantRole} and {_revokeRole} functions. 36 | 37 | This can also be achieved dynamically via the `external` {grantRole} and 38 | 39 | {revokeRole} functions. Each role has an associated admin role, and only 40 | 41 | accounts that have a role's admin role can call {grantRole} and {revokeRoke}. 42 | 43 | By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means 44 | 45 | that only accounts with this role will be able to grant or revoke other 46 | 47 | roles. More complex role relationships can be created by using 48 | 49 | {_setRoleAdmin}. 50 | 51 | ## Functions: 52 | 53 | - [`hasRole(bytes32 role, address account)`](#AccessControl-hasRole-bytes32-address-) 54 | 55 | - [`getRoleMemberCount(bytes32 role)`](#AccessControl-getRoleMemberCount-bytes32-) 56 | 57 | - [`getRoleMember(bytes32 role, uint256 index)`](#AccessControl-getRoleMember-bytes32-uint256-) 58 | 59 | - [`getRoleAdmin(bytes32 role)`](#AccessControl-getRoleAdmin-bytes32-) 60 | 61 | - [`grantRole(bytes32 role, address account)`](#AccessControl-grantRole-bytes32-address-) 62 | 63 | - [`revokeRole(bytes32 role, address account)`](#AccessControl-revokeRole-bytes32-address-) 64 | 65 | - [`renounceRole(bytes32 role, address account)`](#AccessControl-renounceRole-bytes32-address-) 66 | 67 | ## Events: 68 | 69 | - [`RoleGranted(bytes32 role, address account, address sender)`](#AccessControl-RoleGranted-bytes32-address-address-) 70 | 71 | - [`RoleRevoked(bytes32 role, address account, address sender)`](#AccessControl-RoleRevoked-bytes32-address-address-) 72 | 73 | ### [Function `hasRole(bytes32 role, address account) → bool`](#AccessControl-hasRole-bytes32-address-) 74 | 75 | Returns `true` if `account` has been granted `role`. 76 | 77 | ### [Function `getRoleMemberCount(bytes32 role) → uint256`](#AccessControl-getRoleMemberCount-bytes32-) 78 | 79 | Returns the number of accounts that have `role`. Can be used 80 | 81 | together with {getRoleMember} to enumerate all bearers of a role. 82 | 83 | ### [Function `getRoleMember(bytes32 role, uint256 index) → address`](#AccessControl-getRoleMember-bytes32-uint256-) 84 | 85 | Returns one of the accounts that have `role`. `index` must be a 86 | 87 | value between 0 and {getRoleMemberCount}, non-inclusive. 88 | 89 | Role bearers are not sorted in any particular way, and their ordering may 90 | 91 | change at any point. 92 | 93 | WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure 94 | 95 | you perform all queries on the same block. See the following 96 | 97 | https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] 98 | 99 | for more information. 100 | 101 | ### [Function `getRoleAdmin(bytes32 role) → bytes32`](#AccessControl-getRoleAdmin-bytes32-) 102 | 103 | Returns the admin role that controls `role`. See {grantRole} and 104 | 105 | {revokeRole}. 106 | 107 | To change a role's admin, use {_setRoleAdmin}. 108 | 109 | ### [Function `grantRole(bytes32 role, address account)`](#AccessControl-grantRole-bytes32-address-) 110 | 111 | Grants `role` to `account`. 112 | 113 | Calls {_grantRole} internally. 114 | 115 | Requirements: 116 | 117 | - the caller must have `role`'s admin role. 118 | 119 | ### [Function `revokeRole(bytes32 role, address account)`](#AccessControl-revokeRole-bytes32-address-) 120 | 121 | Revokes `role` from `account`. 122 | 123 | Calls {_revokeRole} internally. 124 | 125 | Requirements: 126 | 127 | - the caller must have `role`'s admin role. 128 | 129 | ### [Function `renounceRole(bytes32 role, address account)`](#AccessControl-renounceRole-bytes32-address-) 130 | 131 | Revokes `role` from the calling account. 132 | 133 | Roles are often managed via {grantRole} and {revokeRole}: this function's 134 | 135 | purpose is to provide a mechanism for accounts to lose their privileges 136 | 137 | if they are compromised (such as when a trusted device is misplaced). 138 | 139 | Requirements: 140 | 141 | - the caller must be `account`. 142 | 143 | ### Event `RoleGranted(bytes32 role, address account, address sender)` {#AccessControl-RoleGranted-bytes32-address-address-} 144 | 145 | Emitted when `account` is granted `role`. 146 | 147 | `sender` is the account that originated the contract call: 148 | 149 | - if using `grantRole`, it is the admin role bearer 150 | 151 | - if using `_grantRole`, its meaning is system-dependent 152 | 153 | ### Event `RoleRevoked(bytes32 role, address account, address sender)` {#AccessControl-RoleRevoked-bytes32-address-address-} 154 | 155 | Emitted when `account` is revoked `role`. 156 | 157 | `sender` is the account that originated the contract call: 158 | 159 | - if using `revokeRole`, it is the admin role bearer 160 | 161 | - if using `renounceRole`, it is the role bearer (i.e. `account`) 162 | 163 | - if using `_renounceRole`, its meaning is system-dependent 164 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/upgrades/UpgradeContext.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/upgrades/UpgradeOwnable.md: -------------------------------------------------------------------------------- 1 | Contract module which provides a basic access control mechanism, where 2 | 3 | there is an account (an owner) that can be granted exclusive access to 4 | 5 | specific functions. 6 | 7 | This module is used through inheritance. It will make available the modifier 8 | 9 | `onlyOwner`, which can be aplied to your functions to restrict their use to 10 | 11 | the owner. 12 | 13 | ## Functions: 14 | 15 | - [`initialize(address sender)`](#UpgradeOwnable-initialize-address-) 16 | 17 | - [`owner()`](#UpgradeOwnable-owner--) 18 | 19 | - [`isOwner()`](#UpgradeOwnable-isOwner--) 20 | 21 | - [`renounceOwnership()`](#UpgradeOwnable-renounceOwnership--) 22 | 23 | - [`transferOwnership(address newOwner)`](#UpgradeOwnable-transferOwnership-address-) 24 | 25 | ## Events: 26 | 27 | - [`OwnershipTransferred(address previousOwner, address newOwner)`](#UpgradeOwnable-OwnershipTransferred-address-address-) 28 | 29 | ### [Function `initialize(address sender)`](#UpgradeOwnable-initialize-address-) 30 | 31 | Initializes the contract setting the deployer as the initial owner. 32 | 33 | ### [Function `owner() → address`](#UpgradeOwnable-owner--) 34 | 35 | Returns the address of the current owner. 36 | 37 | ### [Function `isOwner() → bool`](#UpgradeOwnable-isOwner--) 38 | 39 | Returns true if the caller is the current owner. 40 | 41 | ### [Function `renounceOwnership()`](#UpgradeOwnable-renounceOwnership--) 42 | 43 | Leaves the contract without owner. It will not be possible to call 44 | 45 | `onlyOwner` functions anymore. Can only be called by the current owner. 46 | 47 | > Note: Renouncing ownership will leave the contract without an owner, 48 | 49 | thereby removing any functionality that is only available to the owner. 50 | 51 | ### [Function `transferOwnership(address newOwner)`](#UpgradeOwnable-transferOwnership-address-) 52 | 53 | Transfers ownership of the contract to a new account (`newOwner`). 54 | 55 | Can only be called by the current owner. 56 | 57 | ### Event `OwnershipTransferred(address previousOwner, address newOwner)` {#UpgradeOwnable-OwnershipTransferred-address-address-} 58 | 59 | No description 60 | -------------------------------------------------------------------------------- /generated-docs/docs/libs/upgrades/UpgradeReentrancyGuard.md: -------------------------------------------------------------------------------- 1 | Contract module that helps prevent reentrant calls to a function. 2 | 3 | Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier 4 | 5 | available, which can be applied to functions to make sure there are no nested 6 | 7 | (reentrant) calls to them. 8 | 9 | Note that because there is a single `nonReentrant` guard, functions marked as 10 | 11 | `nonReentrant` may not call one another. This can be worked around by making 12 | 13 | those functions `private`, and then adding `external` `nonReentrant` entry 14 | 15 | points to them. 16 | 17 | ## Functions: 18 | 19 | - [`initialize()`](#UpgradeReentrancyGuard-initialize--) 20 | 21 | ### [Function `initialize()`](#UpgradeReentrancyGuard-initialize--) 22 | 23 | No description 24 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/ArraysImpl.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`select(uint256[] arr, uint256 k)`](#QuickImpl-select-uint256---uint256-) 4 | 5 | ### [Function `select(uint256[] arr, uint256 k) → uint256`](#QuickImpl-select-uint256---uint256-) 6 | 7 | No description 8 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/FaucetInterface.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`allocateTo(address _owner, uint256 value)`](#FaucetInterface-allocateTo-address-uint256-) 4 | 5 | ### [Function `allocateTo(address _owner, uint256 value)`](#FaucetInterface-allocateTo-address-uint256-) 6 | 7 | No description 8 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/TestCToken.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`constructor(contract IERC20 baseToken_)`](#TestCToken-constructor-contract-IERC20-) 4 | 5 | - [`mint(uint256 baseTokenAmount)`](#TestCToken-mint-uint256-) 6 | 7 | - [`redeem(uint256 cTokenAmount)`](#TestCToken-redeem-uint256-) 8 | 9 | - [`getPrice()`](#TestCToken-getPrice--) 10 | 11 | - [`borrow(address recipient, uint256 amount)`](#TestCToken-borrow-address-uint256-) 12 | 13 | - [`repay(uint256 amount)`](#TestCToken-repay-uint256-) 14 | 15 | - [`exchangeRateStored()`](#TestCToken-exchangeRateStored--) 16 | 17 | - [`getCash()`](#TestCToken-getCash--) 18 | 19 | - [`underlying()`](#TestCToken-underlying--) 20 | 21 | - [`redeemUnderlying(uint256 baseTokenAmount)`](#TestCToken-redeemUnderlying-uint256-) 22 | 23 | ### [Function `constructor(contract IERC20 baseToken_)`](#TestCToken-constructor-contract-IERC20-) 24 | 25 | No description 26 | 27 | ### [Function `mint(uint256 baseTokenAmount) → uint256`](#TestCToken-mint-uint256-) 28 | 29 | No description 30 | 31 | ### [Function `redeem(uint256 cTokenAmount) → uint256`](#TestCToken-redeem-uint256-) 32 | 33 | No description 34 | 35 | ### [Function `getPrice() → uint256`](#TestCToken-getPrice--) 36 | 37 | No description 38 | 39 | ### [Function `borrow(address recipient, uint256 amount)`](#TestCToken-borrow-address-uint256-) 40 | 41 | No description 42 | 43 | ### [Function `repay(uint256 amount)`](#TestCToken-repay-uint256-) 44 | 45 | No description 46 | 47 | ### [Function `exchangeRateStored() → uint256`](#TestCToken-exchangeRateStored--) 48 | 49 | No description 50 | 51 | ### [Function `getCash() → uint256`](#TestCToken-getCash--) 52 | 53 | No description 54 | 55 | ### [Function `underlying() → address`](#TestCToken-underlying--) 56 | 57 | No description 58 | 59 | ### [Function `redeemUnderlying(uint256 baseTokenAmount) → uint256`](#TestCToken-redeemUnderlying-uint256-) 60 | 61 | No description 62 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/TestToken.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/margin/MockIsPoolSafeMarginProtocol.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`market()`](#MockPoolIsNotSafeMarginProtocol-market--) 4 | 5 | - [`isPoolSafe(contract MarginLiquidityPoolInterface _pool)`](#MockPoolIsNotSafeMarginProtocol-isPoolSafe-contract-MarginLiquidityPoolInterface-) 6 | 7 | - [`withdrawForPool(uint256 _iTokenAmount)`](#MockPoolIsNotSafeMarginProtocol-withdrawForPool-uint256-) 8 | 9 | - [`balances(contract MarginLiquidityPoolInterface _pool, address _trader)`](#MockPoolIsNotSafeMarginProtocol-balances-contract-MarginLiquidityPoolInterface-address-) 10 | 11 | ## Events: 12 | 13 | - [`FakeWithdrew(address sender, uint256 amount)`](#MockPoolIsNotSafeMarginProtocol-FakeWithdrew-address-uint256-) 14 | 15 | ### [Function `market() → uint256, uint256, uint256, uint256, contract MarginFlowProtocolSafety, uint256, uint256, uint256, uint256`](#MockPoolIsNotSafeMarginProtocol-market--) 16 | 17 | No description 18 | 19 | ### [Function `isPoolSafe(contract MarginLiquidityPoolInterface _pool) → bool`](#MockPoolIsNotSafeMarginProtocol-isPoolSafe-contract-MarginLiquidityPoolInterface-) 20 | 21 | No description 22 | 23 | ### [Function `withdrawForPool(uint256 _iTokenAmount)`](#MockPoolIsNotSafeMarginProtocol-withdrawForPool-uint256-) 24 | 25 | No description 26 | 27 | ### [Function `balances(contract MarginLiquidityPoolInterface _pool, address _trader) → uint256`](#MockPoolIsNotSafeMarginProtocol-balances-contract-MarginLiquidityPoolInterface-address-) 28 | 29 | No description 30 | 31 | ### Event `FakeWithdrew(address sender, uint256 amount)` {#MockPoolIsNotSafeMarginProtocol-FakeWithdrew-address-uint256-} 32 | 33 | No description 34 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/margin/TestMarginFlowProtocol.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`getUnrealizedPlAndMarketPriceOfPosition(contract MarginLiquidityPoolInterface _pool, address _base, address _quote, int256 _leverage, int256 _leveragedHeld, int256 _leveragedDebits, uint256 _maxPrice)`](#TestMarginFlowProtocol-getUnrealizedPlAndMarketPriceOfPosition-contract-MarginLiquidityPoolInterface-address-address-int256-int256-int256-uint256-) 4 | 5 | - [`getPrice(address _base, address _quote)`](#TestMarginFlowProtocol-getPrice-address-address-) 6 | 7 | - [`getUsdValue(address _base, int256 _amount)`](#TestMarginFlowProtocol-getUsdValue-address-int256-) 8 | 9 | - [`getAskPrice(contract MarginLiquidityPoolInterface _pool, address _base, address _quote, uint256 _max)`](#TestMarginFlowProtocol-getAskPrice-contract-MarginLiquidityPoolInterface-address-address-uint256-) 10 | 11 | - [`getBidPrice(contract MarginLiquidityPoolInterface _pool, address _base, address _quote, uint256 _min)`](#TestMarginFlowProtocol-getBidPrice-contract-MarginLiquidityPoolInterface-address-address-uint256-) 12 | 13 | - [`removePositionFromPoolList(contract MarginLiquidityPoolInterface _pool, uint256 _positionId)`](#TestMarginFlowProtocol-removePositionFromPoolList-contract-MarginLiquidityPoolInterface-uint256-) 14 | 15 | - [`getPositionIdsByPool(contract MarginLiquidityPoolInterface _pool, address _trader)`](#TestMarginFlowProtocol-getPositionIdsByPool-contract-MarginLiquidityPoolInterface-address-) 16 | 17 | - [`getSwapRatesOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader)`](#TestMarginFlowProtocol-getSwapRatesOfTrader-contract-MarginLiquidityPoolInterface-address-) 18 | 19 | - [`getUnrealizedPlOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader)`](#TestMarginFlowProtocol-getUnrealizedPlOfTrader-contract-MarginLiquidityPoolInterface-address-) 20 | 21 | - [`getEstimatedFreeMargin(contract MarginLiquidityPoolInterface _pool, address _trader)`](#TestMarginFlowProtocol-getEstimatedFreeMargin-contract-MarginLiquidityPoolInterface-address-) 22 | 23 | - [`getEstimatedEquityOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader)`](#TestMarginFlowProtocol-getEstimatedEquityOfTrader-contract-MarginLiquidityPoolInterface-address-) 24 | 25 | - [`getAccumulatedSwapRateFromParameters(contract MarginLiquidityPoolInterface _pool, address base, address quote, int256 _leveragedHeld, int256 _swapRate, uint256 _timeWhenOpened)`](#TestMarginFlowProtocol-getAccumulatedSwapRateFromParameters-contract-MarginLiquidityPoolInterface-address-address-int256-int256-uint256-) 26 | 27 | ### [Function `getUnrealizedPlAndMarketPriceOfPosition(contract MarginLiquidityPoolInterface _pool, address _base, address _quote, int256 _leverage, int256 _leveragedHeld, int256 _leveragedDebits, uint256 _maxPrice) → int256, uint256`](#TestMarginFlowProtocol-getUnrealizedPlAndMarketPriceOfPosition-contract-MarginLiquidityPoolInterface-address-address-int256-int256-int256-uint256-) 28 | 29 | No description 30 | 31 | ### [Function `getPrice(address _base, address _quote) → struct Percentage.Percent`](#TestMarginFlowProtocol-getPrice-address-address-) 32 | 33 | No description 34 | 35 | ### [Function `getUsdValue(address _base, int256 _amount) → int256`](#TestMarginFlowProtocol-getUsdValue-address-int256-) 36 | 37 | No description 38 | 39 | ### [Function `getAskPrice(contract MarginLiquidityPoolInterface _pool, address _base, address _quote, uint256 _max) → uint256`](#TestMarginFlowProtocol-getAskPrice-contract-MarginLiquidityPoolInterface-address-address-uint256-) 40 | 41 | No description 42 | 43 | ### [Function `getBidPrice(contract MarginLiquidityPoolInterface _pool, address _base, address _quote, uint256 _min) → uint256`](#TestMarginFlowProtocol-getBidPrice-contract-MarginLiquidityPoolInterface-address-address-uint256-) 44 | 45 | No description 46 | 47 | ### [Function `removePositionFromPoolList(contract MarginLiquidityPoolInterface _pool, uint256 _positionId)`](#TestMarginFlowProtocol-removePositionFromPoolList-contract-MarginLiquidityPoolInterface-uint256-) 48 | 49 | No description 50 | 51 | ### [Function `getPositionIdsByPool(contract MarginLiquidityPoolInterface _pool, address _trader) → uint256[]`](#TestMarginFlowProtocol-getPositionIdsByPool-contract-MarginLiquidityPoolInterface-address-) 52 | 53 | No description 54 | 55 | ### [Function `getSwapRatesOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader) → int256`](#TestMarginFlowProtocol-getSwapRatesOfTrader-contract-MarginLiquidityPoolInterface-address-) 56 | 57 | No description 58 | 59 | ### [Function `getUnrealizedPlOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader) → int256`](#TestMarginFlowProtocol-getUnrealizedPlOfTrader-contract-MarginLiquidityPoolInterface-address-) 60 | 61 | No description 62 | 63 | ### [Function `getEstimatedFreeMargin(contract MarginLiquidityPoolInterface _pool, address _trader) → uint256`](#TestMarginFlowProtocol-getEstimatedFreeMargin-contract-MarginLiquidityPoolInterface-address-) 64 | 65 | No description 66 | 67 | ### [Function `getEstimatedEquityOfTrader(contract MarginLiquidityPoolInterface _pool, address _trader) → int256`](#TestMarginFlowProtocol-getEstimatedEquityOfTrader-contract-MarginLiquidityPoolInterface-address-) 68 | 69 | No description 70 | 71 | ### [Function `getAccumulatedSwapRateFromParameters(contract MarginLiquidityPoolInterface _pool, address base, address quote, int256 _leveragedHeld, int256 _swapRate, uint256 _timeWhenOpened) → int256`](#TestMarginFlowProtocol-getAccumulatedSwapRateFromParameters-contract-MarginLiquidityPoolInterface-address-address-int256-int256-uint256-) 72 | 73 | No description 74 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/MarginFlowProtocolNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#MarginFlowProtocolNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#MarginFlowProtocolNewVersion-setNewStorageUint-uint256-) 6 | 7 | - [`getNewValuePlusNextPositionId()`](#MarginFlowProtocolNewVersion-getNewValuePlusNextPositionId--) 8 | 9 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#MarginFlowProtocolNewVersion-addNewStorageBytes32-bytes32-) 10 | 11 | No description 12 | 13 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#MarginFlowProtocolNewVersion-setNewStorageUint-uint256-) 14 | 15 | No description 16 | 17 | ### [Function `getNewValuePlusNextPositionId() → uint256`](#MarginFlowProtocolNewVersion-getNewValuePlusNextPositionId--) 18 | 19 | No description 20 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/MarginFlowProtocolSafetyNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#MarginFlowProtocolSafetyNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#MarginFlowProtocolSafetyNewVersion-setNewStorageUint-uint256-) 6 | 7 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#MarginFlowProtocolSafetyNewVersion-addNewStorageBytes32-bytes32-) 8 | 9 | No description 10 | 11 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#MarginFlowProtocolSafetyNewVersion-setNewStorageUint-uint256-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/MarginLiquidityPoolNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#MarginLiquidityPoolNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#MarginLiquidityPoolNewVersion-setNewStorageUint-uint256-) 6 | 7 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#MarginLiquidityPoolNewVersion-addNewStorageBytes32-bytes32-) 8 | 9 | No description 10 | 11 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#MarginLiquidityPoolNewVersion-setNewStorageUint-uint256-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/MarginLiquidityPoolRegistryNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#MarginLiquidityPoolRegistryNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#MarginLiquidityPoolRegistryNewVersion-setNewStorageUint-uint256-) 6 | 7 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#MarginLiquidityPoolRegistryNewVersion-addNewStorageBytes32-bytes32-) 8 | 9 | No description 10 | 11 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#MarginLiquidityPoolRegistryNewVersion-setNewStorageUint-uint256-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/MoneyMarketNewVersion copy.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#MoneyMarketNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#MoneyMarketNewVersion-setNewStorageUint-uint256-) 6 | 7 | - [`getNewValuePlusMinLiquidity()`](#MoneyMarketNewVersion-getNewValuePlusMinLiquidity--) 8 | 9 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#MoneyMarketNewVersion-addNewStorageBytes32-bytes32-) 10 | 11 | No description 12 | 13 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#MoneyMarketNewVersion-setNewStorageUint-uint256-) 14 | 15 | No description 16 | 17 | ### [Function `getNewValuePlusMinLiquidity() → uint256`](#MoneyMarketNewVersion-getNewValuePlusMinLiquidity--) 18 | 19 | No description 20 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/SimplePriceOracleNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#SimplePriceOracleNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#SimplePriceOracleNewVersion-setNewStorageUint-uint256-) 6 | 7 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#SimplePriceOracleNewVersion-addNewStorageBytes32-bytes32-) 8 | 9 | No description 10 | 11 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#SimplePriceOracleNewVersion-setNewStorageUint-uint256-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/SyntheticFlowProtocolNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#SyntheticFlowProtocolNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#SyntheticFlowProtocolNewVersion-setNewStorageUint-uint256-) 6 | 7 | - [`getNewValuePlusMaxSpread()`](#SyntheticFlowProtocolNewVersion-getNewValuePlusMaxSpread--) 8 | 9 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#SyntheticFlowProtocolNewVersion-addNewStorageBytes32-bytes32-) 10 | 11 | No description 12 | 13 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#SyntheticFlowProtocolNewVersion-setNewStorageUint-uint256-) 14 | 15 | No description 16 | 17 | ### [Function `getNewValuePlusMaxSpread() → uint256`](#SyntheticFlowProtocolNewVersion-getNewValuePlusMaxSpread--) 18 | 19 | No description 20 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/SyntheticFlowTokenNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#SyntheticFlowTokenNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#SyntheticFlowTokenNewVersion-setNewStorageUint-uint256-) 6 | 7 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#SyntheticFlowTokenNewVersion-addNewStorageBytes32-bytes32-) 8 | 9 | No description 10 | 11 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#SyntheticFlowTokenNewVersion-setNewStorageUint-uint256-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/mocks/upgrades/SyntheticLiquidityPoolNewVersion.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`addNewStorageBytes32(bytes32 _newBytes32)`](#SyntheticLiquidityPoolNewVersion-addNewStorageBytes32-bytes32-) 4 | 5 | - [`setNewStorageUint(uint256 _newStorageUint)`](#SyntheticLiquidityPoolNewVersion-setNewStorageUint-uint256-) 6 | 7 | ### [Function `addNewStorageBytes32(bytes32 _newBytes32)`](#SyntheticLiquidityPoolNewVersion-addNewStorageBytes32-bytes32-) 8 | 9 | No description 10 | 11 | ### [Function `setNewStorageUint(uint256 _newStorageUint)`](#SyntheticLiquidityPoolNewVersion-setNewStorageUint-uint256-) 12 | 13 | No description 14 | -------------------------------------------------------------------------------- /generated-docs/docs/roles/PriceFeederRole.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize()`](#PriceFeederRole-initialize--) 4 | 5 | - [`isPriceFeeder(address _account)`](#PriceFeederRole-isPriceFeeder-address-) 6 | 7 | - [`addPriceFeeder(address _account)`](#PriceFeederRole-addPriceFeeder-address-) 8 | 9 | - [`removePriceFeeder(address _account)`](#PriceFeederRole-removePriceFeeder-address-) 10 | 11 | - [`renouncePriceFeeder()`](#PriceFeederRole-renouncePriceFeeder--) 12 | 13 | ## Events: 14 | 15 | - [`PriceFeederAdded(address _account)`](#PriceFeederRole-PriceFeederAdded-address-) 16 | 17 | - [`PriceFeederRemoved(address _account)`](#PriceFeederRole-PriceFeederRemoved-address-) 18 | 19 | ### [Function `initialize()`](#PriceFeederRole-initialize--) 20 | 21 | No description 22 | 23 | ### [Function `isPriceFeeder(address _account) → bool`](#PriceFeederRole-isPriceFeeder-address-) 24 | 25 | No description 26 | 27 | ### [Function `addPriceFeeder(address _account)`](#PriceFeederRole-addPriceFeeder-address-) 28 | 29 | No description 30 | 31 | ### [Function `removePriceFeeder(address _account)`](#PriceFeederRole-removePriceFeeder-address-) 32 | 33 | No description 34 | 35 | ### [Function `renouncePriceFeeder()`](#PriceFeederRole-renouncePriceFeeder--) 36 | 37 | No description 38 | 39 | ### Event `PriceFeederAdded(address _account)` {#PriceFeederRole-PriceFeederAdded-address-} 40 | 41 | No description 42 | 43 | ### Event `PriceFeederRemoved(address _account)` {#PriceFeederRole-PriceFeederRemoved-address-} 44 | 45 | No description 46 | -------------------------------------------------------------------------------- /generated-docs/docs/roles/ProtocolOwnable.md: -------------------------------------------------------------------------------- 1 | ## Functions: 2 | 3 | - [`initialize(address protocol)`](#ProtocolOwnable-initialize-address-) 4 | 5 | - [`protocol()`](#ProtocolOwnable-protocol--) 6 | 7 | - [`isProtocol()`](#ProtocolOwnable-isProtocol--) 8 | 9 | ### [Function `initialize(address protocol)`](#ProtocolOwnable-initialize-address-) 10 | 11 | No description 12 | 13 | ### [Function `protocol() → address`](#ProtocolOwnable-protocol--) 14 | 15 | No description 16 | 17 | ### [Function `isProtocol() → bool`](#ProtocolOwnable-isProtocol--) 18 | 19 | No description 20 | -------------------------------------------------------------------------------- /generated-docs/exclude.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laminar-protocol/flow-protocol-ethereum/a2393e9212580c87b1e66005ae5489d4d37023a7/generated-docs/exclude.txt -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require('Migrations'); 2 | 3 | module.exports = deployer => { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | module.exports = require('./deploy_contracts')(artifacts, web3); 3 | -------------------------------------------------------------------------------- /migrations/config/development/margin/margin_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "maxSpread": "0.1$", 3 | "maxTradingPairCount": "25", 4 | "traderMarginCall": "3%", 5 | "traderStopOut": "1%", 6 | "enpMarginCall": "30%", 7 | "enpStopOut": "30%", 8 | "ellMarginCall": "30%", 9 | "ellStopOut": "10%", 10 | "traderMarginCallDeposit": "100$", 11 | "traderStopOutDeposit": "100$", 12 | "poolMarginCallDeposit": "300$", 13 | "poolStopOutDeposit": "1000$", 14 | "treasuryAddress": "0x15ae150d7dC03d3B635EE90b85219dBFe071ED35", 15 | "tradingPairs": [ 16 | { 17 | "swapRateUnit": "3153600", 18 | "swapRateLong": "0.0001", 19 | "swapRateShort": "-0.0001", 20 | "names": ["USD/EUR"] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /migrations/config/development/margin/margin_pools/general_margin_pool.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "General", 3 | "initialDeposit": "20000$", 4 | "minLeveragedAmount": "1$", 5 | "minLeverage": "1x", 6 | "maxLeverage": "50x", 7 | "tradingPairs": [ 8 | { 9 | "name": "EUR/USD", 10 | "spread": "0.000028152", 11 | "additionalSwap": "0%" 12 | }, 13 | { 14 | "name": "USD/EUR", 15 | "spread": "0.000028152", 16 | "additionalSwap": "0%" 17 | }, 18 | { 19 | "name": "JPY/USD", 20 | "spread": "0.000028152", 21 | "additionalSwap": "0%" 22 | }, 23 | { 24 | "name": "USD/JPY", 25 | "spread": "0.000028152", 26 | "additionalSwap": "0%" 27 | }, 28 | { 29 | "name": "JPY/EUR", 30 | "spread": "0.000028152", 31 | "additionalSwap": "0%" 32 | }, 33 | { 34 | "name": "EUR/JPY", 35 | "spread": "0.000028152", 36 | "additionalSwap": "0%" 37 | }, 38 | { 39 | "name": "XAU/USD", 40 | "spread": "0.000028152", 41 | "additionalSwap": "0%" 42 | }, 43 | { 44 | "name": "USD/XAU", 45 | "spread": "0.000028152", 46 | "additionalSwap": "0%" 47 | } 48 | ] 49 | } -------------------------------------------------------------------------------- /migrations/config/development/oracles.json: -------------------------------------------------------------------------------- 1 | { 2 | "EUR": "0xf23CCdA8333f658c43E7fC19aa00f6F5722eB225", 3 | "JPY": "0xcd93a652e731Bb38eA9Efc5fEbCf977EDa2a01f7", 4 | "XAU": "0xF1302340da93EdEF6DA03C66bc52F75A956e482C", 5 | "AUD": "0xFD4767F2136F277ddd36b563504797C46a2eFF3B", 6 | "GBP": "0xbcf04560239e5A0D8e497E8215288fF8D25C026e", 7 | "CHF": "0x3a982Ed122bF8e2bee035fCc6CAec894823E0129", 8 | "BTC": "0x2445F2466898565374167859Ae5e3a231e48BB41", 9 | "ETH": "0xD21912D8762078598283B14cbA40Cb4bFCb87581", 10 | 11 | "__comment0__": "// actually ZRX/ETH", 12 | "CAD": "0x2636cfdDB457a6C7A7D60A439F1E5a5a0C3d9c65", 13 | 14 | "__comment1__": "// actually LINK/USD", 15 | "USOIL": "0x326C977E6efc84E512bB9C30f76E30c160eD06FB" 16 | } -------------------------------------------------------------------------------- /migrations/config/development/synthetic/synthetic_config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "additionalCollateral": "10%", 4 | "liquidationRatio": "5%", 5 | "extremeRatio": "1%", 6 | "tokens": [ 7 | { "symbol": "fEUR", "name": "Euro" }, 8 | { "symbol": "fJPY", "name": "Yen" }, 9 | { "symbol": "fXAU", "name": "Gold" } 10 | ] 11 | } 12 | ] -------------------------------------------------------------------------------- /migrations/config/development/synthetic/synthetic_pools/general_synthetic_pool.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "General", 3 | "initialDeposit": "500000$", 4 | "tradingPairs": [ 5 | { 6 | "name": "EUR", 7 | "spread": "0.0008" 8 | }, 9 | { 10 | "name": "JPY", 11 | "spread": "0.006" 12 | }, 13 | { 14 | "name": "XAU", 15 | "spread": "0.006" 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /migrations/config/kovan/margin/margin_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "maxSpread": "0.01$", 3 | "maxTradingPairCount": "25", 4 | "traderMarginCall": "7%", 5 | "traderStopOut": "4%", 6 | "enpMarginCall": "60%", 7 | "enpStopOut": "30%", 8 | "ellMarginCall": "20%", 9 | "ellStopOut": "5%", 10 | "traderMarginCallDeposit": "100$", 11 | "traderStopOutDeposit": "100$", 12 | "poolMarginCallDeposit": "300$", 13 | "poolStopOutDeposit": "1000$", 14 | "treasuryAddress": "0x15ae150d7dC03d3B635EE90b85219dBFe071ED35", 15 | "tradingPairs": [ 16 | { 17 | "type": "fiat", 18 | "swapRateUnit": "86400", 19 | "swapRateLong": "0.0001", 20 | "swapRateShort": "-0.0001", 21 | "names": [ 22 | "EUR/USD", 23 | "USD/JPY", 24 | "USD/EUR", 25 | "USD/XAU", 26 | "USD/AUD", 27 | "USD/GBP", 28 | "USD/CAD", 29 | "USD/USOIL" 30 | ] 31 | }, 32 | { 33 | "type": "crypto", 34 | "swapRateUnit": "28800", 35 | "swapRateLong": "0.0001", 36 | "swapRateShort": "-0.0001", 37 | "names": ["USD/BTC", "USD/ETH"] 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /migrations/config/kovan/margin/margin_pools/ACME_margin_pool.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ACME", 3 | "initialDeposit": "1000000$", 4 | "minLeveragedAmount": "500$", 5 | "minLeverage": "5x", 6 | "maxLeverage": "20x", 7 | "tradingPairs": [ 8 | { 9 | "name": "EUR/USD", 10 | "spread": "0.001", 11 | "additionalSwap": "10%" 12 | }, 13 | { 14 | "name": "AUD/USD", 15 | "spread": "0.001", 16 | "additionalSwap": "10%" 17 | }, 18 | { 19 | "name": "USD/CAD", 20 | "spread": "0.001", 21 | "additionalSwap": "10%" 22 | }, 23 | { 24 | "name": "USD/CHF", 25 | "spread": "0.001", 26 | "additionalSwap": "10%" 27 | }, 28 | { 29 | "name": "USD/JPY", 30 | "spread": "0.004", 31 | "additionalSwap": "10%" 32 | }, 33 | { 34 | "name": "XAU/USD", 35 | "spread": "0.6", 36 | "additionalSwap": "10%" 37 | }, 38 | { 39 | "name": "USOIL/USD", 40 | "minLeveragedAmount": "500$", 41 | "minLeverage": "5x", 42 | "maxLeverage": "20x", 43 | "spread": "1.0", 44 | "additionalSwap": "10%" 45 | } 46 | ] 47 | } -------------------------------------------------------------------------------- /migrations/config/kovan/margin/margin_pools/general_margin_pool.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "General", 3 | "initialDeposit": "1000000$", 4 | "minLeveragedAmount": "500$", 5 | "minLeverage": "5x", 6 | "maxLeverage": "20x", 7 | "tradingPairs": [ 8 | { 9 | "name": "EUR/USD", 10 | "spread": "0.0008", 11 | "additionalSwap": "10%" 12 | }, 13 | { 14 | "name": "AUD/USD", 15 | "spread": "0.0008", 16 | "additionalSwap": "10%" 17 | }, 18 | { 19 | "name": "USD/CAD", 20 | "spread": "0.0008", 21 | "additionalSwap": "10%" 22 | }, 23 | { 24 | "name": "USD/CHF", 25 | "spread": "0.0008", 26 | "additionalSwap": "10%" 27 | }, 28 | { 29 | "name": "USD/JPY", 30 | "spread": "0.006", 31 | "additionalSwap": "10%" 32 | }, 33 | { 34 | "name": "XAU/USD", 35 | "spread": "0.006", 36 | "additionalSwap": "10%" 37 | }, 38 | { 39 | "name": "USOIL/USD", 40 | "spread": "0.8", 41 | "additionalSwap": "10%" 42 | }, 43 | { 44 | "name": "BTC/USD", 45 | "spread": "6", 46 | "additionalSwap": "10%" 47 | }, 48 | { 49 | "name": "ETH/USD", 50 | "spread": "0.08", 51 | "additionalSwap": "10%" 52 | } 53 | ] 54 | } -------------------------------------------------------------------------------- /migrations/config/kovan/oracles.json: -------------------------------------------------------------------------------- 1 | { 2 | "EUR": "0xf23CCdA8333f658c43E7fC19aa00f6F5722eB225", 3 | "JPY": "0xcd93a652e731Bb38eA9Efc5fEbCf977EDa2a01f7", 4 | "XAU": "0xF1302340da93EdEF6DA03C66bc52F75A956e482C", 5 | "AUD": "0xFD4767F2136F277ddd36b563504797C46a2eFF3B", 6 | "GBP": "0xbcf04560239e5A0D8e497E8215288fF8D25C026e", 7 | "CHF": "0x3a982Ed122bF8e2bee035fCc6CAec894823E0129", 8 | "BTC": "0x2445F2466898565374167859Ae5e3a231e48BB41", 9 | "ETH": "0xD21912D8762078598283B14cbA40Cb4bFCb87581", 10 | 11 | "__comment0__": "// actually ZRX/ETH", 12 | "CAD": "0x2636cfdDB457a6C7A7D60A439F1E5a5a0C3d9c65", 13 | 14 | "__comment1__": "// actually LINK/USD", 15 | "USOIL": "0x326C977E6efc84E512bB9C30f76E30c160eD06FB" 16 | } -------------------------------------------------------------------------------- /migrations/config/kovan/synthetic/synthetic_config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "additionalCollateral": "10%", 4 | "liquidationRatio": "5%", 5 | "extremeRatio": "1%", 6 | "tokens": [ 7 | { "symbol": "fEUR", "name": "Euro" }, 8 | { "symbol": "fJPY", "name": "Yen" }, 9 | { "symbol": "fAUD", "name": "Australian Dollar" }, 10 | { "symbol": "fCAD", "name": "Canadian Dollar" }, 11 | { "symbol": "fCHF", "name": "Swiss Franc" }, 12 | { "symbol": "fXAU", "name": "Gold" }, 13 | { "symbol": "fGBP", "name": "British Pound" } 14 | ] 15 | }, 16 | { 17 | "additionalCollateral": "50%", 18 | "liquidationRatio": "10%", 19 | "extremeRatio": "5%", 20 | "tokens": [ 21 | { "symbol": "fUSOIL", "name": "US Oil" }, 22 | { "symbol": "fBTC", "name": "Bitcoin" }, 23 | { "symbol": "fETH", "name": "Ether" } 24 | ] 25 | } 26 | ] -------------------------------------------------------------------------------- /migrations/config/kovan/synthetic/synthetic_pools/XYZ_synthetic_pool.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "XYZ", 3 | "initialDeposit": "500000$", 4 | "tradingPairs": [ 5 | { 6 | "name": "BTC", 7 | "spread": "6" 8 | }, 9 | { 10 | "name": "ETH", 11 | "spread": "0.08" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /migrations/config/kovan/synthetic/synthetic_pools/general_synthetic_pool.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "General", 3 | "initialDeposit": "500000$", 4 | "tradingPairs": [ 5 | { 6 | "name": "EUR", 7 | "spread": "0.0008" 8 | }, 9 | { 10 | "name": "AUD", 11 | "spread": "0.0008" 12 | }, 13 | { 14 | "name": "CAD", 15 | "spread": "0.0008" 16 | }, 17 | { 18 | "name": "CHF", 19 | "spread": "0.0008" 20 | }, 21 | { 22 | "name": "JPY", 23 | "spread": "0.006" 24 | }, 25 | { 26 | "name": "XAU", 27 | "spread": "0.006" 28 | }, 29 | { 30 | "name": "USOIL", 31 | "spread": "0.8" 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@laminar/flow-protocol-ethereum", 3 | "files": [ 4 | "artifacts" 5 | ], 6 | "version": "0.0.11", 7 | "author": "Bryan Chen ", 8 | "private": false, 9 | "scripts": { 10 | "generate": "yarn truffle compile && yarn typechain --target truffle-v5 \"./build/**/*.json\" && yarn typechain --target web3-v1 \"./build/**/*.json\"", 11 | "prepare": "yarn generate && cd subgraph && yarn && cross-env NETWORK=kovan yarn codegen", 12 | "verify": "cross-env-shell truffle run verify Proxy MoneyMarket SyntheticFlowProtocol SyntheticFlowToken SyntheticLiquidityPool MarginLiquidityPool SimplePriceOracle MarginFlowProtocol --network $NETWORK", 13 | "lint": "yarn solhint 'contracts/**/*.sol' && yarn eslint --ext .js,.ts subgraph && yarn tsc --noEmit --pretty", 14 | "test": "bash ./scripts/run_tests.sh", 15 | "test:debug": "yarn buidler test", 16 | "test:cucumber": "bash ./scripts/run_cucumber_tests.sh", 17 | "docify": "node ./scripts/docify.js", 18 | "graph-node": "docker-compose up", 19 | "deploy-local": "sh deploy-local.sh", 20 | "deploy": "cross-env-shell yarn truffle migrate --reset --network $NETWORK --skip-dry-run", 21 | "deploy:development": "cross-env NETWORK=development yarn deploy", 22 | "deploy:kovan": "cross-env NETWORK=kovan yarn deploy", 23 | "deploy:mainnet": "cross-env NETWORK=mainnet yarn deploy", 24 | "change-owner": "cross-env-shell NETWORK=$NETWORK yarn truffle exec dev-scripts/changeOwners.js --network $NETWORK", 25 | "change-owner:development": "cross-env NETWORK=development yarn change-owner", 26 | "change-owner:kovan": "cross-env NETWORK=kovan change-owner", 27 | "change-owner:mainnet": "cross-env NETWORK=mainnet change-owner", 28 | "upgrade-contracts:kovan": "cross-env-shell CONTRACT_NAME=$CONTRACT_NAME NETWORK=kovan yarn truffle exec dev-scripts/upgradeContract.js --network kovan" 29 | }, 30 | "devDependencies": { 31 | "@chainlink/contracts": "0.0.5", 32 | "@codechecks/client": "^0.1.10", 33 | "@nomiclabs/buidler": "1.3.6", 34 | "@nomiclabs/buidler-truffle5": "1.3.4", 35 | "@nomiclabs/buidler-web3": "1.3.4", 36 | "@openzeppelin/contracts": "3.0.2", 37 | "@openzeppelin/contracts-ethereum-package": "^3.0.0", 38 | "@openzeppelin/upgrades": "2.8.0", 39 | "@typechain/truffle-v5": "^2.0.2", 40 | "@typechain/web3-v1": "^1.0.0", 41 | "@types/chai": "4.2.11", 42 | "@types/cucumber": "^6.0.1", 43 | "@types/mocha": "^7.0.2", 44 | "@types/node": "14.0.13", 45 | "@typescript-eslint/eslint-plugin": "3.3.0", 46 | "@typescript-eslint/parser": "3.3.0", 47 | "bn.js": "^5.1.2", 48 | "chai": "^4.2.0", 49 | "chai-bn": "0.2.1", 50 | "cross-env": "^7.0.2", 51 | "cucumber": "^6.0.5", 52 | "cucumber-pretty": "^6.0.0", 53 | "dotenv": "^8.2.0", 54 | "eslint": "7.2.0", 55 | "eslint-config-airbnb-base": "14.2.0", 56 | "eslint-config-prettier": "6.11.0", 57 | "eslint-import-resolver-typescript": "^2.0.0", 58 | "eslint-plugin-import": "2.21.2", 59 | "eslint-plugin-prettier": "3.1.4", 60 | "eth-gas-reporter": "0.2.17", 61 | "ethlint": "^1.2.5", 62 | "ganache-cli": "^6.9.1", 63 | "openzeppelin-test-helpers": "^0.5.1", 64 | "prettier": "2.0.5", 65 | "prettier-plugin-solidity": "^1.0.0-alpha.54", 66 | "solc": "0.6.10", 67 | "solhint": "^3.0.0", 68 | "solhint-plugin-prettier": "^0.0.4", 69 | "solidity-docgen": "0.5.3", 70 | "truffle": "5.1.30", 71 | "truffle-contract-size": "^1.0.1", 72 | "truffle-hdwallet-provider": "^1.0.17", 73 | "truffle-plugin-verify": "0.3.11", 74 | "ts-node": "8.10.2", 75 | "typechain": "2.0.0", 76 | "typescript": "3.9.5", 77 | "web3": "1.2.6", 78 | "web3-core": "1.2.6", 79 | "web3-eth-contract": "1.2.6" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /scripts/debug.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OUTPUT=$(truffle exec dev-scripts/debug.js | tail -n1) 4 | truffle debug $OUTPUT -------------------------------------------------------------------------------- /scripts/deploy-local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | yarn deploy:development 4 | 5 | cd subgraph 6 | yarn build 7 | yarn create-local 8 | yarn deploy-local -------------------------------------------------------------------------------- /scripts/docify.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); // eslint-disable-line 2 | const path = require('path'); // eslint-disable-line 3 | const {spawnSync} = require('child_process'); // eslint-disable-line 4 | 5 | const NODE_DIR = 'node_modules'; 6 | const INPUT_DIR = 'contracts'; 7 | const CONFIG_DIR = 'generated-docs'; 8 | const OUTPUT_DIR = 'generated-docs/docs'; 9 | // const README_FILE = 'generated-docs/README.md'; 10 | const SUMMARY_FILE = 'generated-docs/SUMMARY.md'; 11 | const EXCLUDE_FILE = 'generated-docs/exclude.txt'; 12 | 13 | function lines(pathName) { 14 | return fs 15 | .readFileSync(pathName, {encoding: 'utf8'}) 16 | .split('\r') 17 | .join('') 18 | .split('\n'); 19 | } 20 | 21 | const excludeList = lines(EXCLUDE_FILE).map((line) => `${INPUT_DIR}/${line}`); 22 | const relativePath = path.relative(path.dirname(SUMMARY_FILE), OUTPUT_DIR); 23 | 24 | function scan(pathName, indentation) { 25 | if (!excludeList.includes(pathName)) { 26 | if (fs.lstatSync(pathName).isDirectory()) { 27 | fs.appendFileSync( 28 | SUMMARY_FILE, 29 | `${indentation}* ${path.basename(pathName)}\n`, 30 | ); 31 | for (const fileName of fs.readdirSync(pathName)) 32 | scan(`${pathName}/${fileName}`, `${indentation} `); 33 | } else if (pathName.endsWith('.sol')) { 34 | const text = path.basename(pathName).slice(0, -4); 35 | const link = pathName.slice(INPUT_DIR.length, -4); 36 | fs.appendFileSync( 37 | SUMMARY_FILE, 38 | `${indentation}* [${text}](${relativePath}${link}.md)\n`, 39 | ); 40 | } 41 | } 42 | } 43 | 44 | function fix(pathName) { 45 | if (fs.lstatSync(pathName).isDirectory()) { 46 | for (const fileName of fs.readdirSync(pathName)) 47 | fix(`${pathName}/${fileName}`); 48 | } else if (pathName.endsWith('.md')) { 49 | fs.writeFileSync( 50 | pathName, 51 | `${lines(pathName) 52 | .filter((line) => line.trim().length > 0) 53 | .join('\n\n')}\n`, 54 | ); 55 | } 56 | } 57 | 58 | fs.writeFileSync(SUMMARY_FILE, '# Summary\n'); 59 | /* 60 | fs.writeFileSync('.gitbook.yaml', 'root: ./\n'); 61 | fs.appendFileSync('.gitbook.yaml', 'structure:\n'); 62 | fs.appendFileSync('.gitbook.yaml', ` readme: ${README_FILE}\n`); 63 | fs.appendFileSync('.gitbook.yaml', ` summary: ${SUMMARY_FILE}\n`); 64 | */ 65 | 66 | scan(INPUT_DIR, ''); 67 | 68 | const args = [ 69 | `${NODE_DIR}/solidity-docgen/dist/cli.js`, 70 | `--input=${INPUT_DIR}`, 71 | `--output=${OUTPUT_DIR}`, 72 | `--templates=${CONFIG_DIR}`, 73 | `--solc-settings=${JSON.stringify({ 74 | optimizer: {enabled: true, runs: 200}, 75 | })}`, 76 | ]; 77 | 78 | const result = spawnSync('node', args, { 79 | stdio: ['inherit', 'inherit', 'pipe'], 80 | }); 81 | if (result.stderr.length > 0) throw new Error(result.stderr); 82 | 83 | fix(OUTPUT_DIR); 84 | -------------------------------------------------------------------------------- /scripts/run_cucumber_tests.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/env bash 3 | 4 | # Exit script as soon as a command fails. 5 | set -o errexit 6 | 7 | # Executes cleanup function at script exit. 8 | trap cleanup EXIT 9 | 10 | cleanup() { 11 | # Kill the ganache instance that we started (if we started one and if it's still running). 12 | if [ -n "$ganache_pid" ] && ps -p $ganache_pid > /dev/null; then 13 | kill -9 $ganache_pid 14 | fi 15 | } 16 | 17 | ganache_port=8545 18 | 19 | ganache_running() { 20 | nc -z localhost "$ganache_port" 21 | } 22 | 23 | start_ganache() { 24 | # We define 10 accounts with balance 1M ether, needed for high-value tests. 25 | local accounts=( 26 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200,100000000000000000000000000000" 27 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201,1000000000000000000000000" 28 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501202,1000000000000000000000000" 29 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501203,1000000000000000000000000" 30 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501204,1000000000000000000000000" 31 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501205,1000000000000000000000000" 32 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501206,1000000000000000000000000" 33 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501207,1000000000000000000000000" 34 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501208,1000000000000000000000000" 35 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501209,1000000000000000000000000" 36 | ) 37 | 38 | yarn ganache-cli --gasLimit 0x1fffffffffffff --gasPrice 0x1 --port "$ganache_port" --accounts 70 --allowUnlimitedContractSize > /dev/null & 39 | 40 | ganache_pid=$! 41 | 42 | echo "Waiting for ganache to launch on port "$ganache_port"..." 43 | 44 | while ! ganache_running; do 45 | sleep 0.1 # wait for 1/10 of the second before check again 46 | done 47 | 48 | echo "Ganache launched!" 49 | } 50 | 51 | if ganache_running; then 52 | echo "Using existing ganache instance" 53 | else 54 | echo "Starting our own ganache instance" 55 | start_ganache 56 | fi 57 | 58 | yarn deploy:development 59 | 60 | yarn cucumber-js -p default 61 | -------------------------------------------------------------------------------- /scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Exit script as soon as a command fails. 4 | set -o errexit 5 | 6 | # Executes cleanup function at script exit. 7 | trap cleanup EXIT 8 | 9 | cleanup() { 10 | # Kill the ganache instance that we started (if we started one and if it's still running). 11 | if [ -n "$ganache_pid" ] && ps -p $ganache_pid > /dev/null; then 12 | kill -9 $ganache_pid 13 | fi 14 | } 15 | 16 | ganache_port=8545 17 | 18 | ganache_running() { 19 | nc -z localhost "$ganache_port" 20 | } 21 | 22 | start_ganache() { 23 | # We define 10 accounts with balance 1M ether, needed for high-value tests. 24 | local accounts=( 25 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501200,1000000000000000000000000" 26 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501201,1000000000000000000000000" 27 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501202,1000000000000000000000000" 28 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501203,1000000000000000000000000" 29 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501204,1000000000000000000000000" 30 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501205,1000000000000000000000000" 31 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501206,1000000000000000000000000" 32 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501207,1000000000000000000000000" 33 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501208,1000000000000000000000000" 34 | --account="0x2bdd21761a483f71054e14f5b827213567971c676928d9a1808cbfa4b7501209,1000000000000000000000000" 35 | ) 36 | 37 | yarn ganache-cli --gasLimit 0x1fffffffffffff --gasPrice 0x1 --port "$ganache_port" --accounts 70 --allowUnlimitedContractSize > /dev/null & 38 | 39 | ganache_pid=$! 40 | 41 | echo "Waiting for ganache to launch on port "$ganache_port"..." 42 | 43 | while ! ganache_running; do 44 | sleep 0.1 # wait for 1/10 of the second before check again 45 | done 46 | 47 | echo "Ganache launched!" 48 | } 49 | 50 | if ganache_running; then 51 | echo "Using existing ganache instance" 52 | else 53 | echo "Starting our own ganache instance" 54 | start_ganache 55 | fi 56 | 57 | yarn truffle version 58 | 59 | if [ "$BUIDLER_DEBUG" = true ]; then 60 | yarn buidler test "$@" 61 | else 62 | yarn truffle test "$@" 63 | fi -------------------------------------------------------------------------------- /subgraph/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flow-protocol-subgraph", 3 | "author": "Bryan Chen ", 4 | "private": true, 5 | "scripts": { 6 | "codegen": "node ./scripts/codegen.js && graph codegen", 7 | "codegen:development": "cross-env NETWORK=development yarn codegen", 8 | "codegen:kovan": "cross-env NETWORK=kovan yarn codegen", 9 | "codegen:mainnet": "cross-env NETWORK=mainnet yarn codegen", 10 | "build": "yarn graph build", 11 | "deploy": "yarn graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ laminar-protocol/flow-protocol-kovan", 12 | "create-local": "yarn graph create --node http://localhost:8020/ laminar-protocol/flow-protocol-subgraph", 13 | "remove-local": "yarn graph remove --node http://localhost:8020/ laminar-protocol/flow-protocol-subgraph", 14 | "deploy-local": "yarn graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 laminar-protocol/flow-protocol-subgraph" 15 | }, 16 | "dependencies": { 17 | "@graphprotocol/graph-cli": "^0.18.0", 18 | "@graphprotocol/graph-ts": "^0.18.1" 19 | }, 20 | "devDependencies": { 21 | "cross-env": "^7.0.2", 22 | "lodash.template": "^4.5.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /subgraph/schema.graphql: -------------------------------------------------------------------------------- 1 | type SyntheticFlowProtocolEntity @entity { 2 | id: ID! # 0, singleton 3 | 4 | totalEvents: BigInt! 5 | } 6 | 7 | type SyntheticTokenEntity @entity { 8 | id: ID! # Token contract address 9 | name: String! # Name of the token 10 | symbol: String! # Symbol of the token 11 | } 12 | 13 | type MarginTokenPairEntity @entity { 14 | id: ID! # Token Pair Id 15 | base: Bytes! # Base token contract address 16 | quote: Bytes! # Quote token contract address 17 | } 18 | 19 | enum EventKind { 20 | Minted 21 | Redeemed 22 | Liquidated 23 | Deposited 24 | Withdrew 25 | CollateralAdded 26 | CollateralWithdrew 27 | } 28 | 29 | type EventEntity @entity { 30 | id: ID! # Sequence ID since a tx can have multiple events 31 | kind: EventKind! # EventKind enum: Minted, Redeemed, Liquidated, Deposited, Withdrew 32 | # CollateralAdded, CollateralWithdrew 33 | 34 | timestamp: Int! # Timestamp in seconds 35 | txhash: Bytes! # Transaction hash 36 | block: Int! # Block number that the transaction is recorded 37 | 38 | user: Bytes! # Address of sender 39 | token: SyntheticTokenEntity! # Synthetic Token Entity 40 | liquidityPool: Bytes # Address of liquidity pool 41 | 42 | baseTokenAmount: BigDecimal! # Base token amount, e.g. 10 DAI 43 | flowTokenAmount: BigDecimal! # Flow Token amount, e.g. 9 fEUR 44 | } 45 | 46 | type PriceEntity @entity { 47 | id: ID! # Synthetic Asset (Token) Address 48 | value: BigDecimal! # Market Price from Price Oracle 49 | updatedAt: Int! # Timestamp in seconds 50 | } 51 | 52 | type MarginPositionEntity @entity { 53 | id: ID! # Margin Trading Pair Contract Address + Position ID 54 | 55 | base: Bytes! # The Trading Pair Base Token 56 | quote: Bytes! # The Trading Pair Quote Token 57 | positionId: Int! # Position ID is returned upon opening a position 58 | 59 | owner: Bytes! # Address of the position owner, who opens this position 60 | liquidityPool: Bytes! # Address of the liquidity pool 61 | leverage: Int! # Leverage number e.g. 50x 62 | amount: BigDecimal! # Amount in DAI for opening the position 63 | openPrice: BigDecimal! # Price when opening this position, accounted for spread 64 | 65 | openTime: Int! # Position open timestamp in seconds 66 | openTxhash: Bytes! # Position open transaction hash 67 | openBlock: Int! # Position open block number 68 | 69 | closePrice: BigDecimal # Price when closing this position, accounted for spread 70 | liquidator: Bytes # Address of the liquidator who closes this position 71 | realizedPl: BigDecimal # Amount in DAI returns to owner when closing position 72 | 73 | closeTime: Int # Position close timestamp in seconds 74 | closeTxhash: Bytes # Position close transaction hash 75 | closeBlock: Int # Position close block number 76 | } 77 | -------------------------------------------------------------------------------- /subgraph/scripts/codegen.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* eslint-disable import/no-extraneous-dependencies, @typescript-eslint/no-var-requires */ 4 | 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | const template = require('lodash.template'); 8 | 9 | const subgraphTemplate = fs 10 | .readFileSync(path.join(__dirname, '../subgraph.template.yaml')) 11 | .toString(); 12 | 13 | const network = process.env.NETWORK; 14 | console.log(`Network: ${network}`); 15 | 16 | const deployment = JSON.parse( 17 | fs 18 | .readFileSync( 19 | path.join(__dirname, `../../artifacts/${network}/deployment.json`), 20 | ) 21 | .toString(), 22 | ); 23 | 24 | const subgraph = template(subgraphTemplate)({ 25 | deployment, 26 | network, 27 | }); 28 | 29 | fs.writeFileSync(path.join(__dirname, '../subgraph.yaml'), subgraph); 30 | 31 | console.log('subgraph.yaml updated'); 32 | 33 | const generatedDeploy = Object.entries(deployment) 34 | .map(([key, value]) => `export const ${key} = '${value}';`) 35 | .join('\n'); 36 | 37 | try { 38 | fs.mkdirSync(path.join(__dirname, '../generated'), {rescursive: true}); 39 | } catch { 40 | // ignore mkdir error 41 | } 42 | 43 | fs.writeFileSync( 44 | path.join(__dirname, '../generated/deployment.ts'), 45 | generatedDeploy, 46 | ); 47 | 48 | console.log('generated/deployment.ts updated'); 49 | -------------------------------------------------------------------------------- /subgraph/subgraph.template.yaml: -------------------------------------------------------------------------------- 1 | specVersion: 0.0.2 2 | description: Flow Protocols powering synthetic asset and margin trading. 3 | repository: https://github.com/laminar-protocol/flow-protocol-ethereum 4 | schema: 5 | file: ./schema.graphql 6 | dataSources: 7 | - kind: ethereum/contract 8 | name: PriceOracle 9 | network: ${ network } 10 | source: 11 | address: '${ deployment.oracle }' 12 | abi: PriceOracleInterface 13 | startBlock: 18264484 14 | mapping: 15 | kind: ethereum/events 16 | apiVersion: 0.0.3 17 | language: wasm/assemblyscript 18 | entities: 19 | - Price 20 | abis: 21 | - name: PriceOracleInterface 22 | file: ../build/contracts/PriceOracleInterface.json 23 | file: ./src/mapping.ts 24 | eventHandlers: 25 | - event: PriceFeeded(indexed address,indexed address,uint256) 26 | handler: handlePriceFeeded 27 | - kind: ethereum/contract 28 | name: SyntheticFlowProtocol 29 | network: ${ network } 30 | source: 31 | address: '${ deployment.syntheticProtocol }' 32 | abi: SyntheticFlowProtocol 33 | startBlock: 18264484 34 | mapping: 35 | kind: ethereum/events 36 | apiVersion: 0.0.3 37 | language: wasm/assemblyscript 38 | entities: 39 | - SyntheticFlowToken 40 | abis: 41 | - name: SyntheticFlowProtocol 42 | file: ../build/contracts/SyntheticFlowProtocol.json 43 | - name: SyntheticFlowToken 44 | file: ../build/contracts/SyntheticFlowToken.json 45 | file: ./src/mapping.ts 46 | eventHandlers: 47 | - event: NewFlowToken(indexed address) 48 | handler: handleNewFlowToken 49 | - event: Minted(indexed address,indexed address,indexed address,uint256,uint256) 50 | handler: handleMinted 51 | - event: Redeemed(indexed address,indexed address,indexed address,uint256,uint256) 52 | handler: handleRedeemed 53 | - event: Liquidated(indexed address,indexed address,indexed address,uint256,uint256) 54 | handler: handleLiquidated 55 | - event: CollateralAdded(indexed address,indexed address,uint256,uint256) 56 | handler: handleCollateralAdded 57 | - event: CollateralWithdrew(indexed address,indexed address,uint256,uint256) 58 | handler: handleCollateralWithdrew 59 | - event: FlowTokenDeposited(indexed address,indexed address,uint256,uint256) 60 | handler: handleFlowTokenDeposited 61 | - event: FlowTokenWithdrew(indexed address,indexed address,uint256,uint256) 62 | handler: handleFlowTokenWithdrew 63 | - kind: ethereum/contract 64 | name: MarginFlowProtocol 65 | network: ${ network } 66 | source: 67 | address: '${ deployment.marginProtocol }' 68 | abi: MarginFlowProtocol 69 | startBlock: 18264484 70 | mapping: 71 | kind: ethereum/events 72 | apiVersion: 0.0.3 73 | language: wasm/assemblyscript 74 | entities: 75 | - MarginFlowProtocol 76 | abis: 77 | - name: MarginFlowProtocol 78 | file: ../build/contracts/MarginFlowProtocol.json 79 | - name: MoneyMarket 80 | file: ../build/contracts/MoneyMarket.json 81 | file: ./src/mapping.ts 82 | eventHandlers: 83 | - event: PositionOpened(uint256,indexed address,indexed address,indexed address,address,int256,int256,uint256) 84 | handler: handleOpenPosition 85 | - event: PositionClosed(uint256,indexed address,indexed address,indexed address,address,int256,uint256) 86 | handler: handleClosePosition 87 | - kind: ethereum/contract 88 | name: MarginFlowProtocolConfig 89 | network: ${ network } 90 | source: 91 | address: '${ deployment.marginProtocolConfig }' 92 | abi: MarginFlowProtocolConfig 93 | startBlock: 18264484 94 | mapping: 95 | kind: ethereum/events 96 | apiVersion: 0.0.3 97 | language: wasm/assemblyscript 98 | entities: 99 | - MarginFlowProtocol 100 | abis: 101 | - name: MarginFlowProtocolConfig 102 | file: ../build/contracts/MarginFlowProtocolConfig.json 103 | - name: MoneyMarket 104 | file: ../build/contracts/MoneyMarket.json 105 | file: ./src/mapping.ts 106 | eventHandlers: 107 | - event: NewTradingPair(indexed address,indexed address) 108 | handler: handleNewTradingPair -------------------------------------------------------------------------------- /test/arrays.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import {expectRevert} from 'openzeppelin-test-helpers'; 3 | import {QuickImplInstance, ArraysImplInstance} from 'types/truffle-contracts'; 4 | 5 | import {bn} from './helpers'; 6 | 7 | const QuickImpl = artifacts.require('QuickImpl'); 8 | 9 | contract('QuickImpl', () => { 10 | let quick: QuickImplInstance; 11 | 12 | beforeEach(async () => { 13 | quick = await QuickImpl.new(); 14 | }); 15 | 16 | describe('Kth smallest quick select', () => { 17 | it('should fail if k out of bound', async () => { 18 | await expectRevert(quick.select([], 0), 'k out of bound'); 19 | await expectRevert(quick.select([1], 1), 'k out of bound'); 20 | }); 21 | 22 | it('distinct items', async () => { 23 | expect(await quick.select([1], 0)).bignumber.equal(bn(1)); 24 | expect(await quick.select([1, 2], 1)).bignumber.equal(bn(2)); 25 | expect(await quick.select([2, 1, 3], 1)).bignumber.equal(bn(2)); 26 | expect(await quick.select([3, 2, 1, 5, 6, 4], 4)).bignumber.equal(bn(5)); 27 | }); 28 | 29 | it('with some repeat items', async () => { 30 | expect(await quick.select([2, 2, 3], 1)).bignumber.equal(bn(2)); 31 | expect( 32 | await quick.select([3, 2, 3, 1, 2, 4, 5, 5, 6], 5), 33 | ).bignumber.equal(bn(4)); 34 | }); 35 | }); 36 | }); 37 | 38 | const ArraysImpl = artifacts.require('ArraysImpl'); 39 | 40 | contract('ArrayImpl', () => { 41 | let arrays: ArraysImplInstance; 42 | 43 | beforeEach(async () => { 44 | arrays = await ArraysImpl.new(); 45 | }); 46 | 47 | describe('Find median', () => { 48 | it('empty array fails', async () => { 49 | await expectRevert(arrays.findMedian([]), 'empty array has no median'); 50 | }); 51 | 52 | it('odd length', async () => { 53 | expect(await arrays.findMedian([1])).bignumber.equal(bn(1)); 54 | expect(await arrays.findMedian([2, 1, 3])).bignumber.equal(bn(2)); 55 | expect(await arrays.findMedian([4, 5, 2, 1, 6, 3, 7])).bignumber.equal( 56 | bn(4), 57 | ); 58 | expect(await arrays.findMedian([7, 5, 2, 6, 1, 3, 4])).bignumber.equal( 59 | bn(4), 60 | ); 61 | expect(await arrays.findMedian([7, 5, 4, 6, 1, 3, 2])).bignumber.equal( 62 | bn(4), 63 | ); 64 | }); 65 | 66 | it('even length', async () => { 67 | expect(await arrays.findMedian([2, 1])).bignumber.equal(bn(2)); 68 | expect(await arrays.findMedian([4, 1, 2, 3])).bignumber.equal(bn(3)); 69 | expect(await arrays.findMedian([3, 2, 4, 1])).bignumber.equal(bn(3)); 70 | expect(await arrays.findMedian([2, 4, 3, 1])).bignumber.equal(bn(3)); 71 | }); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /test/truffle-fixture.js: -------------------------------------------------------------------------------- 1 | const MoneyMarket = artifacts.require('MoneyMarket'); 2 | const Proxy = artifacts.require('Proxy'); 3 | const SyntheticFlowProtocol = artifacts.require('SyntheticFlowProtocol'); 4 | const SyntheticFlowToken = artifacts.require('SyntheticFlowToken'); 5 | const SyntheticLiquidityPool = artifacts.require('SyntheticLiquidityPool'); 6 | const MarginLiquidityPool = artifacts.require('MarginLiquidityPool'); 7 | const MarginLiquidityPoolRegistry = artifacts.require( 8 | 'MarginLiquidityPoolRegistry', 9 | ); 10 | const SimplePriceOracle = artifacts.require('SimplePriceOracle'); 11 | const MarginFlowProtocol = artifacts.require('MarginFlowProtocol'); 12 | const MarginFlowProtocolSafety = artifacts.require('MarginFlowProtocolSafety'); 13 | const MarginFlowProtocolLiquidated = artifacts.require( 14 | 'MarginFlowProtocolLiquidated', 15 | ); 16 | const MarginFlowProtocolConfig = artifacts.require('MarginFlowProtocolConfig'); 17 | const MarginMarketLib = artifacts.require('MarginMarketLib'); 18 | 19 | module.exports = async () => { 20 | const moneyMarket = await MoneyMarket.new(); 21 | MoneyMarket.setAsDeployed(moneyMarket); 22 | const proxy = await Proxy.new(); 23 | Proxy.setAsDeployed(proxy); 24 | const flowProtocol = await SyntheticFlowProtocol.new(); 25 | SyntheticFlowProtocol.setAsDeployed(flowProtocol); 26 | const flowToken = await SyntheticFlowToken.new(); 27 | SyntheticFlowToken.setAsDeployed(flowToken); 28 | const syntheticLiquidityPool = await SyntheticLiquidityPool.new(); 29 | SyntheticLiquidityPool.setAsDeployed(syntheticLiquidityPool); 30 | const marginLiquidityPool = await MarginLiquidityPool.new(); 31 | MarginLiquidityPool.setAsDeployed(marginLiquidityPool); 32 | const marginLiquidityPoolRegistry = await MarginLiquidityPoolRegistry.new(); 33 | MarginLiquidityPoolRegistry.setAsDeployed(marginLiquidityPoolRegistry); 34 | const simplePriceOracle = await SimplePriceOracle.new(); 35 | SimplePriceOracle.setAsDeployed(simplePriceOracle); 36 | 37 | const marginMarketLib = await MarginMarketLib.new(); 38 | MarginMarketLib.setAsDeployed(marginMarketLib); 39 | 40 | try { 41 | MarginFlowProtocol.link(marginMarketLib); 42 | MarginFlowProtocolLiquidated.link(marginMarketLib); 43 | MarginFlowProtocolSafety.link(marginMarketLib); 44 | } catch (e) { 45 | // ignore 46 | } 47 | 48 | const marginFlowProtocol = await MarginFlowProtocol.new(); 49 | MarginFlowProtocol.setAsDeployed(marginFlowProtocol); 50 | const marginFlowProtocolSafety = await MarginFlowProtocolSafety.new(); 51 | MarginFlowProtocolSafety.setAsDeployed(marginFlowProtocolSafety); 52 | const marginFlowProtocolLiquidated = await MarginFlowProtocolLiquidated.new(); 53 | MarginFlowProtocolLiquidated.setAsDeployed(marginFlowProtocolLiquidated); 54 | const marginFlowProtocolConfig = await MarginFlowProtocolConfig.new(); 55 | MarginFlowProtocolConfig.setAsDeployed(marginFlowProtocolConfig); 56 | }; 57 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | require('ts-node').register({ 4 | files: true 5 | }); 6 | 7 | const HDWalletProvider = require('truffle-hdwallet-provider'); 8 | 9 | require('dotenv').config(); 10 | 11 | module.exports = { 12 | networks: { 13 | mainnet: { 14 | provider: () => 15 | new HDWalletProvider( 16 | process.env.MNEMONIC, 17 | `https://mainnet.infura.io/v3/${process.env.INFURA_API_KEY}` 18 | ), 19 | network_id: 1 20 | }, 21 | ropsten: { 22 | provider: () => 23 | new HDWalletProvider( 24 | process.env.MNEMONIC, 25 | `https://ropsten.infura.io/v3/${process.env.INFURA_API_KEY}` 26 | ), 27 | network_id: 3 28 | }, 29 | kovan: { 30 | provider: () => 31 | new HDWalletProvider( 32 | process.env.MNEMONIC, 33 | `https://kovan.infura.io/v3/${process.env.INFURA_API_KEY}` 34 | ), 35 | network_id: 42, 36 | gasPrice: '1000000000', 37 | gas: 9500000, 38 | networkCheckTimeout: 1000000000, 39 | }, 40 | development: { 41 | host: 'localhost', 42 | port: 8545, 43 | network_id: '*', // Match any network id, 44 | gas: 9500000 45 | } 46 | }, 47 | compilers: { 48 | solc: { 49 | version: '0.6.10', 50 | settings: { 51 | optimizer: { 52 | enabled: true, 53 | runs: 200 54 | } 55 | } 56 | } 57 | }, 58 | plugins: ['truffle-contract-size', 'truffle-plugin-verify', 'truffle-contract-size'], 59 | api_keys: { 60 | etherscan: process.env.ETHERSCAN_API_KEY 61 | }, 62 | mocha: { 63 | reporter: 'eth-gas-reporter', 64 | reporterOptions : { 65 | currency: 'USD', 66 | coinmarketcap: process.env.COINMARKETCAP_API_KEY, 67 | excludeContracts: [ 68 | 'Migrations', 69 | 'Proxy', 70 | 'ArraysImpl', 71 | 'MarginFlowProtocolNewVersion', 72 | 'SyntheticFlowProtocolNewVersion', 73 | 'SyntheticFlowTokenNewVersion', 74 | 'MarginFlowProtocolSafetyNewVersion', 75 | 'MarginLiquidityPoolNewVersion', 76 | 'MarginLiquidityPoolRegistryNewVersion', 77 | 'SyntheticLiquidityPoolNewVersion', 78 | 'MockPoolIsSafeMarginProtocol', 79 | 'MockPoolIsNotSafeMarginProtocol', 80 | 'MoneyMarketNewVersion', 81 | 'QuickImpl', 82 | 'SimplePriceOracleNewVersion', 83 | 'TestCToken', 84 | 'TestToken', 85 | 'TestMarginFlowProtocol' 86 | ] 87 | } 88 | } 89 | }; 90 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true 6 | }, 7 | "include": ["**/*.ts", "**/*.js"] 8 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "module": "commonjs", 6 | "strict": true, 7 | "moduleResolution": "node", 8 | "noImplicitThis": true, 9 | "alwaysStrict": true, 10 | "experimentalDecorators": true, 11 | "emitDecoratorMetadata": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "lib": ["es2015", "esnext.asynciterable"], 14 | "sourceMap": true, 15 | "typeRoots": ["./node_modules/@types", "./types"], 16 | "types": ["node", "truffle-contracts"], 17 | "baseUrl": "./", 18 | "esModuleInterop": true, 19 | "resolveJsonModule": true 20 | }, 21 | "include": ["**/*.ts", "typings.d.ts"], 22 | "files": ["./typings.d.ts"], 23 | "exclude": ["node_modules", "build", "subgraph"] 24 | } 25 | -------------------------------------------------------------------------------- /typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'openzeppelin-test-helpers' { 2 | export interface ExpectRevert { 3 | (promise: Promise, msg: string): Promise; 4 | assertion: (promise: Promise) => Promise; 5 | unspecified: (promise: Promise) => Promise; 6 | } 7 | export const expectRevert: ExpectRevert; 8 | export const time: { 9 | increase: (n: number) => Promise; 10 | latest: () => Promise; 11 | duration: { 12 | seconds: (n: number) => any; 13 | minutes: (n: number) => any; 14 | hours: (n: number) => any; 15 | days: (n: number) => any; 16 | weeks: (n: number) => any; 17 | years: (n: number) => any; 18 | }; 19 | }; 20 | export const constants: any; 21 | export const expectEvent: ( 22 | receipt: Truffle.TransactionResponse, 23 | eventName: string, 24 | eventArgs: {}, 25 | ) => Promise; 26 | } 27 | 28 | declare namespace Chai { 29 | interface Assertion { 30 | bignumber: Assertion; 31 | } 32 | } 33 | 34 | declare module 'chai-bn' { 35 | const f: (bn: any) => (chai: any, utils: any) => null; 36 | export = f; 37 | } 38 | --------------------------------------------------------------------------------