├── .gitignore ├── LICENSE ├── README.md ├── build └── contracts │ ├── AToken.json │ ├── Aave.json │ ├── Address.json │ ├── Compound.json │ ├── Context.json │ ├── DyDx.json │ ├── Fulcrum.json │ ├── IERC20.json │ ├── IIEarnManager.json │ ├── ILendingPoolAddressesProvider.json │ ├── IOneSplitInterface.json │ ├── IUniSwap_ETH_CDAIZap.json │ ├── Initializable.json │ ├── InvestZAP.json │ ├── IuniswapExchange.json │ ├── IuniswapFactory.json │ ├── Migrations.json │ ├── Ownable.json │ ├── SafeMath.json │ ├── Structs.json │ └── UniSwap_ETH_CDAIZap.json ├── contracts ├── IUniSwap_ETH_cDAI.sol ├── InvestZAP.sol ├── Migrations.sol └── UniSwap_ETH_cDAI.sol ├── migrations └── 1_initial_migration.js ├── package.json └── test └── Uniswap_ETH_cDAI.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 63 | 64 | # dependencies 65 | /node_modules 66 | /.pnp 67 | .pnp.js 68 | 69 | # testing 70 | /coverage 71 | 72 | # misc 73 | .DS_Store 74 | .env.local 75 | .env.development.local 76 | .env.test.local 77 | .env.production.local 78 | truffle-config.js 79 | .secret 80 | 81 | npm-debug.log* 82 | yarn-debug.log* 83 | yarn-error.log* 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 iearn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | [iearn.finance](https://docs.iearn.finance) 4 | 5 | # Smart Contract Interface 6 | 7 | | Contract | ABI | Address | 8 | | -- | -- | -- | 9 | | Uniswap_ETH_CDAIZAP | [JSON](https://github.com/iearn-finance/zap/blob/master/build/contracts/UniSwap_ETH_CDAIZap.json) | [0xB82674CfA16bb28D9b70bEC830fF24BAEC6B1337](https://etherscan.io/address/0xb82674cfa16bb28d9b70bec830ff24baec6b1337#code) | 10 | 11 | 12 | ## ZAP Interface 13 | 14 | {% tabs %} 15 | {% tab title="IUniSwap_ETH_CDAIZap.sol" %} 16 | ```javascript 17 | // Solidity Interface 18 | 19 | interface IUniSwap_ETH_CDAIZap { 20 | function getExpectedReturn(uint256 eth) external view returns (uint256); 21 | function LetsInvest(address _towhomtoissue, uint256 _minReturn) external payable returns (uint); 22 | function getUniswapExchangeContractAddress() external view returns (address); 23 | function Redeem(address payable _towhomtosend, uint256 _amount) external stopInEmergency returns (uint); 24 | function getMaxTokens(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _value) external view returns (uint); 25 | function getEthBalance(address _UniSwapExchangeContractAddress) external view returns (uint); 26 | function getTokenReserves(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress) external view returns (uint); 27 | function getTotalShares(address _UniSwapExchangeContractAddress) external view returns (uint); 28 | function getReturn(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _value) external view returns (uint, uint, uint); 29 | function calcReturnETHFromShares(uint _value) external view returns (uint, uint, uint); 30 | function uniBalanceOf(address _owner) external view returns (uint); 31 | function cBalanceOf(address _owner) external view returns (uint); 32 | function calcReturnSharesFromETH(uint _value) external view returns (uint); 33 | function getTokenToEthOutputPrice(uint _tokens) external view returns (uint); 34 | function getSharesReturn(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _ethValue) external view returns (uint); 35 | } 36 | ``` 37 | {% endtab %} 38 | {% endtabs %} 39 | -------------------------------------------------------------------------------- /build/contracts/Migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "contractName": "Migrations", 3 | "abi": [ 4 | { 5 | "inputs": [], 6 | "payable": false, 7 | "stateMutability": "nonpayable", 8 | "type": "constructor" 9 | }, 10 | { 11 | "constant": true, 12 | "inputs": [], 13 | "name": "last_completed_migration", 14 | "outputs": [ 15 | { 16 | "internalType": "uint256", 17 | "name": "", 18 | "type": "uint256" 19 | } 20 | ], 21 | "payable": false, 22 | "stateMutability": "view", 23 | "type": "function" 24 | }, 25 | { 26 | "constant": true, 27 | "inputs": [], 28 | "name": "owner", 29 | "outputs": [ 30 | { 31 | "internalType": "address", 32 | "name": "", 33 | "type": "address" 34 | } 35 | ], 36 | "payable": false, 37 | "stateMutability": "view", 38 | "type": "function" 39 | }, 40 | { 41 | "constant": false, 42 | "inputs": [ 43 | { 44 | "internalType": "uint256", 45 | "name": "completed", 46 | "type": "uint256" 47 | } 48 | ], 49 | "name": "setCompleted", 50 | "outputs": [], 51 | "payable": false, 52 | "stateMutability": "nonpayable", 53 | "type": "function" 54 | }, 55 | { 56 | "constant": false, 57 | "inputs": [ 58 | { 59 | "internalType": "address", 60 | "name": "new_address", 61 | "type": "address" 62 | } 63 | ], 64 | "name": "upgrade", 65 | "outputs": [], 66 | "payable": false, 67 | "stateMutability": "nonpayable", 68 | "type": "function" 69 | } 70 | ], 71 | "metadata": "{\"compiler\":{\"version\":\"0.5.12+commit.7709ece9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":true,\"inputs\":[],\"name\":\"last_completed_migration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"completed\",\"type\":\"uint256\"}],\"name\":\"setCompleted\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"new_address\",\"type\":\"address\"}],\"name\":\"upgrade\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"methods\":{}},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"/D/ftm/zap/contracts/Migrations.sol\":\"Migrations\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"/D/ftm/zap/contracts/Migrations.sol\":{\"keccak256\":\"0x919f575f0939571a03f4870c607e9ac4f8893eb1e8ffed3ae2e1993633d9358d\",\"urls\":[\"bzz-raw://fcaff076ff00297a792470a886fe81f0bcd08b9d5849a96f1c448f4f3beae491\",\"dweb:/ipfs/QmUUnW8xpGC2QBaimEvdNU6zjrtPKuTyaConNPSfT2Dmr4\"]}},\"version\":1}", 72 | "bytecode": "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102b7806100606000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80630900f01014610051578063445df0ac146100955780638da5cb5b146100b3578063fdacd576146100fd575b600080fd5b6100936004803603602081101561006757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061012b565b005b61009d6101f7565b6040518082815260200191505060405180910390f35b6100bb6101fd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101296004803603602081101561011357600080fd5b8101908080359060200190929190505050610222565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101f45760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156101da57600080fd5b505af11580156101ee573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561027f57806001819055505b5056fea265627a7a7231582012a1b0365285d6041900199d1648f563ada2471c4a2b7cc97ab482f3b20e104664736f6c634300050c0032", 73 | "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80630900f01014610051578063445df0ac146100955780638da5cb5b146100b3578063fdacd576146100fd575b600080fd5b6100936004803603602081101561006757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061012b565b005b61009d6101f7565b6040518082815260200191505060405180910390f35b6100bb6101fd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101296004803603602081101561011357600080fd5b8101908080359060200190929190505050610222565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101f45760008190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156101da57600080fd5b505af11580156101ee573d6000803e3d6000fd5b50505050505b50565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561027f57806001819055505b5056fea265627a7a7231582012a1b0365285d6041900199d1648f563ada2471c4a2b7cc97ab482f3b20e104664736f6c634300050c0032", 74 | "sourceMap": "34:480:0:-;;;123:50;8:9:-1;5:2;;;30:1;27;20:12;5:2;123:50:0;158:10;150:5;;:18;;;;;;;;;;;;;;;;;;34:480;;;;;;", 75 | "deployedSourceMap": "34:480:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;34:480:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;347:165;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;347:165:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;82:36;;;:::i;:::-;;;;;;;;;;;;;;;;;;;58:20;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;240:103;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;240:103:0;;;;;;;;;;;;;;;;;:::i;:::-;;347:165;223:5;;;;;;;;;;;209:19;;:10;:19;;;205:26;;;409:19;442:11;409:45;;460:8;:21;;;482:24;;460:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;460:47:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;460:47:0;;;;230:1;205:26;347:165;:::o;82:36::-;;;;:::o;58:20::-;;;;;;;;;;;;;:::o;240:103::-;223:5;;;;;;;;;;;209:19;;:10;:19;;;205:26;;;329:9;302:24;:36;;;;205:26;240:103;:::o", 76 | "source": "pragma solidity >=0.4.21 <0.7.0;\n\ncontract Migrations {\n address public owner;\n uint public last_completed_migration;\n\n constructor() public {\n owner = msg.sender;\n }\n\n modifier restricted() {\n if (msg.sender == owner) _;\n }\n\n function setCompleted(uint completed) public restricted {\n last_completed_migration = completed;\n }\n\n function upgrade(address new_address) public restricted {\n Migrations upgraded = Migrations(new_address);\n upgraded.setCompleted(last_completed_migration);\n }\n}\n", 77 | "sourcePath": "D:/ftm/zap/contracts/Migrations.sol", 78 | "ast": { 79 | "absolutePath": "/D/ftm/zap/contracts/Migrations.sol", 80 | "exportedSymbols": { 81 | "Migrations": [ 82 | 56 83 | ] 84 | }, 85 | "id": 57, 86 | "nodeType": "SourceUnit", 87 | "nodes": [ 88 | { 89 | "id": 1, 90 | "literals": [ 91 | "solidity", 92 | ">=", 93 | "0.4", 94 | ".21", 95 | "<", 96 | "0.7", 97 | ".0" 98 | ], 99 | "nodeType": "PragmaDirective", 100 | "src": "0:32:0" 101 | }, 102 | { 103 | "baseContracts": [], 104 | "contractDependencies": [], 105 | "contractKind": "contract", 106 | "documentation": null, 107 | "fullyImplemented": true, 108 | "id": 56, 109 | "linearizedBaseContracts": [ 110 | 56 111 | ], 112 | "name": "Migrations", 113 | "nodeType": "ContractDefinition", 114 | "nodes": [ 115 | { 116 | "constant": false, 117 | "id": 3, 118 | "name": "owner", 119 | "nodeType": "VariableDeclaration", 120 | "scope": 56, 121 | "src": "58:20:0", 122 | "stateVariable": true, 123 | "storageLocation": "default", 124 | "typeDescriptions": { 125 | "typeIdentifier": "t_address", 126 | "typeString": "address" 127 | }, 128 | "typeName": { 129 | "id": 2, 130 | "name": "address", 131 | "nodeType": "ElementaryTypeName", 132 | "src": "58:7:0", 133 | "stateMutability": "nonpayable", 134 | "typeDescriptions": { 135 | "typeIdentifier": "t_address", 136 | "typeString": "address" 137 | } 138 | }, 139 | "value": null, 140 | "visibility": "public" 141 | }, 142 | { 143 | "constant": false, 144 | "id": 5, 145 | "name": "last_completed_migration", 146 | "nodeType": "VariableDeclaration", 147 | "scope": 56, 148 | "src": "82:36:0", 149 | "stateVariable": true, 150 | "storageLocation": "default", 151 | "typeDescriptions": { 152 | "typeIdentifier": "t_uint256", 153 | "typeString": "uint256" 154 | }, 155 | "typeName": { 156 | "id": 4, 157 | "name": "uint", 158 | "nodeType": "ElementaryTypeName", 159 | "src": "82:4:0", 160 | "typeDescriptions": { 161 | "typeIdentifier": "t_uint256", 162 | "typeString": "uint256" 163 | } 164 | }, 165 | "value": null, 166 | "visibility": "public" 167 | }, 168 | { 169 | "body": { 170 | "id": 13, 171 | "nodeType": "Block", 172 | "src": "144:29:0", 173 | "statements": [ 174 | { 175 | "expression": { 176 | "argumentTypes": null, 177 | "id": 11, 178 | "isConstant": false, 179 | "isLValue": false, 180 | "isPure": false, 181 | "lValueRequested": false, 182 | "leftHandSide": { 183 | "argumentTypes": null, 184 | "id": 8, 185 | "name": "owner", 186 | "nodeType": "Identifier", 187 | "overloadedDeclarations": [], 188 | "referencedDeclaration": 3, 189 | "src": "150:5:0", 190 | "typeDescriptions": { 191 | "typeIdentifier": "t_address", 192 | "typeString": "address" 193 | } 194 | }, 195 | "nodeType": "Assignment", 196 | "operator": "=", 197 | "rightHandSide": { 198 | "argumentTypes": null, 199 | "expression": { 200 | "argumentTypes": null, 201 | "id": 9, 202 | "name": "msg", 203 | "nodeType": "Identifier", 204 | "overloadedDeclarations": [], 205 | "referencedDeclaration": 1102, 206 | "src": "158:3:0", 207 | "typeDescriptions": { 208 | "typeIdentifier": "t_magic_message", 209 | "typeString": "msg" 210 | } 211 | }, 212 | "id": 10, 213 | "isConstant": false, 214 | "isLValue": false, 215 | "isPure": false, 216 | "lValueRequested": false, 217 | "memberName": "sender", 218 | "nodeType": "MemberAccess", 219 | "referencedDeclaration": null, 220 | "src": "158:10:0", 221 | "typeDescriptions": { 222 | "typeIdentifier": "t_address_payable", 223 | "typeString": "address payable" 224 | } 225 | }, 226 | "src": "150:18:0", 227 | "typeDescriptions": { 228 | "typeIdentifier": "t_address", 229 | "typeString": "address" 230 | } 231 | }, 232 | "id": 12, 233 | "nodeType": "ExpressionStatement", 234 | "src": "150:18:0" 235 | } 236 | ] 237 | }, 238 | "documentation": null, 239 | "id": 14, 240 | "implemented": true, 241 | "kind": "constructor", 242 | "modifiers": [], 243 | "name": "", 244 | "nodeType": "FunctionDefinition", 245 | "parameters": { 246 | "id": 6, 247 | "nodeType": "ParameterList", 248 | "parameters": [], 249 | "src": "134:2:0" 250 | }, 251 | "returnParameters": { 252 | "id": 7, 253 | "nodeType": "ParameterList", 254 | "parameters": [], 255 | "src": "144:0:0" 256 | }, 257 | "scope": 56, 258 | "src": "123:50:0", 259 | "stateMutability": "nonpayable", 260 | "superFunction": null, 261 | "visibility": "public" 262 | }, 263 | { 264 | "body": { 265 | "id": 22, 266 | "nodeType": "Block", 267 | "src": "199:37:0", 268 | "statements": [ 269 | { 270 | "condition": { 271 | "argumentTypes": null, 272 | "commonType": { 273 | "typeIdentifier": "t_address", 274 | "typeString": "address" 275 | }, 276 | "id": 19, 277 | "isConstant": false, 278 | "isLValue": false, 279 | "isPure": false, 280 | "lValueRequested": false, 281 | "leftExpression": { 282 | "argumentTypes": null, 283 | "expression": { 284 | "argumentTypes": null, 285 | "id": 16, 286 | "name": "msg", 287 | "nodeType": "Identifier", 288 | "overloadedDeclarations": [], 289 | "referencedDeclaration": 1102, 290 | "src": "209:3:0", 291 | "typeDescriptions": { 292 | "typeIdentifier": "t_magic_message", 293 | "typeString": "msg" 294 | } 295 | }, 296 | "id": 17, 297 | "isConstant": false, 298 | "isLValue": false, 299 | "isPure": false, 300 | "lValueRequested": false, 301 | "memberName": "sender", 302 | "nodeType": "MemberAccess", 303 | "referencedDeclaration": null, 304 | "src": "209:10:0", 305 | "typeDescriptions": { 306 | "typeIdentifier": "t_address_payable", 307 | "typeString": "address payable" 308 | } 309 | }, 310 | "nodeType": "BinaryOperation", 311 | "operator": "==", 312 | "rightExpression": { 313 | "argumentTypes": null, 314 | "id": 18, 315 | "name": "owner", 316 | "nodeType": "Identifier", 317 | "overloadedDeclarations": [], 318 | "referencedDeclaration": 3, 319 | "src": "223:5:0", 320 | "typeDescriptions": { 321 | "typeIdentifier": "t_address", 322 | "typeString": "address" 323 | } 324 | }, 325 | "src": "209:19:0", 326 | "typeDescriptions": { 327 | "typeIdentifier": "t_bool", 328 | "typeString": "bool" 329 | } 330 | }, 331 | "falseBody": null, 332 | "id": 21, 333 | "nodeType": "IfStatement", 334 | "src": "205:26:0", 335 | "trueBody": { 336 | "id": 20, 337 | "nodeType": "PlaceholderStatement", 338 | "src": "230:1:0" 339 | } 340 | } 341 | ] 342 | }, 343 | "documentation": null, 344 | "id": 23, 345 | "name": "restricted", 346 | "nodeType": "ModifierDefinition", 347 | "parameters": { 348 | "id": 15, 349 | "nodeType": "ParameterList", 350 | "parameters": [], 351 | "src": "196:2:0" 352 | }, 353 | "src": "177:59:0", 354 | "visibility": "internal" 355 | }, 356 | { 357 | "body": { 358 | "id": 34, 359 | "nodeType": "Block", 360 | "src": "296:47:0", 361 | "statements": [ 362 | { 363 | "expression": { 364 | "argumentTypes": null, 365 | "id": 32, 366 | "isConstant": false, 367 | "isLValue": false, 368 | "isPure": false, 369 | "lValueRequested": false, 370 | "leftHandSide": { 371 | "argumentTypes": null, 372 | "id": 30, 373 | "name": "last_completed_migration", 374 | "nodeType": "Identifier", 375 | "overloadedDeclarations": [], 376 | "referencedDeclaration": 5, 377 | "src": "302:24:0", 378 | "typeDescriptions": { 379 | "typeIdentifier": "t_uint256", 380 | "typeString": "uint256" 381 | } 382 | }, 383 | "nodeType": "Assignment", 384 | "operator": "=", 385 | "rightHandSide": { 386 | "argumentTypes": null, 387 | "id": 31, 388 | "name": "completed", 389 | "nodeType": "Identifier", 390 | "overloadedDeclarations": [], 391 | "referencedDeclaration": 25, 392 | "src": "329:9:0", 393 | "typeDescriptions": { 394 | "typeIdentifier": "t_uint256", 395 | "typeString": "uint256" 396 | } 397 | }, 398 | "src": "302:36:0", 399 | "typeDescriptions": { 400 | "typeIdentifier": "t_uint256", 401 | "typeString": "uint256" 402 | } 403 | }, 404 | "id": 33, 405 | "nodeType": "ExpressionStatement", 406 | "src": "302:36:0" 407 | } 408 | ] 409 | }, 410 | "documentation": null, 411 | "id": 35, 412 | "implemented": true, 413 | "kind": "function", 414 | "modifiers": [ 415 | { 416 | "arguments": null, 417 | "id": 28, 418 | "modifierName": { 419 | "argumentTypes": null, 420 | "id": 27, 421 | "name": "restricted", 422 | "nodeType": "Identifier", 423 | "overloadedDeclarations": [], 424 | "referencedDeclaration": 23, 425 | "src": "285:10:0", 426 | "typeDescriptions": { 427 | "typeIdentifier": "t_modifier$__$", 428 | "typeString": "modifier ()" 429 | } 430 | }, 431 | "nodeType": "ModifierInvocation", 432 | "src": "285:10:0" 433 | } 434 | ], 435 | "name": "setCompleted", 436 | "nodeType": "FunctionDefinition", 437 | "parameters": { 438 | "id": 26, 439 | "nodeType": "ParameterList", 440 | "parameters": [ 441 | { 442 | "constant": false, 443 | "id": 25, 444 | "name": "completed", 445 | "nodeType": "VariableDeclaration", 446 | "scope": 35, 447 | "src": "262:14:0", 448 | "stateVariable": false, 449 | "storageLocation": "default", 450 | "typeDescriptions": { 451 | "typeIdentifier": "t_uint256", 452 | "typeString": "uint256" 453 | }, 454 | "typeName": { 455 | "id": 24, 456 | "name": "uint", 457 | "nodeType": "ElementaryTypeName", 458 | "src": "262:4:0", 459 | "typeDescriptions": { 460 | "typeIdentifier": "t_uint256", 461 | "typeString": "uint256" 462 | } 463 | }, 464 | "value": null, 465 | "visibility": "internal" 466 | } 467 | ], 468 | "src": "261:16:0" 469 | }, 470 | "returnParameters": { 471 | "id": 29, 472 | "nodeType": "ParameterList", 473 | "parameters": [], 474 | "src": "296:0:0" 475 | }, 476 | "scope": 56, 477 | "src": "240:103:0", 478 | "stateMutability": "nonpayable", 479 | "superFunction": null, 480 | "visibility": "public" 481 | }, 482 | { 483 | "body": { 484 | "id": 54, 485 | "nodeType": "Block", 486 | "src": "403:109:0", 487 | "statements": [ 488 | { 489 | "assignments": [ 490 | 43 491 | ], 492 | "declarations": [ 493 | { 494 | "constant": false, 495 | "id": 43, 496 | "name": "upgraded", 497 | "nodeType": "VariableDeclaration", 498 | "scope": 54, 499 | "src": "409:19:0", 500 | "stateVariable": false, 501 | "storageLocation": "default", 502 | "typeDescriptions": { 503 | "typeIdentifier": "t_contract$_Migrations_$56", 504 | "typeString": "contract Migrations" 505 | }, 506 | "typeName": { 507 | "contractScope": null, 508 | "id": 42, 509 | "name": "Migrations", 510 | "nodeType": "UserDefinedTypeName", 511 | "referencedDeclaration": 56, 512 | "src": "409:10:0", 513 | "typeDescriptions": { 514 | "typeIdentifier": "t_contract$_Migrations_$56", 515 | "typeString": "contract Migrations" 516 | } 517 | }, 518 | "value": null, 519 | "visibility": "internal" 520 | } 521 | ], 522 | "id": 47, 523 | "initialValue": { 524 | "argumentTypes": null, 525 | "arguments": [ 526 | { 527 | "argumentTypes": null, 528 | "id": 45, 529 | "name": "new_address", 530 | "nodeType": "Identifier", 531 | "overloadedDeclarations": [], 532 | "referencedDeclaration": 37, 533 | "src": "442:11:0", 534 | "typeDescriptions": { 535 | "typeIdentifier": "t_address", 536 | "typeString": "address" 537 | } 538 | } 539 | ], 540 | "expression": { 541 | "argumentTypes": [ 542 | { 543 | "typeIdentifier": "t_address", 544 | "typeString": "address" 545 | } 546 | ], 547 | "id": 44, 548 | "name": "Migrations", 549 | "nodeType": "Identifier", 550 | "overloadedDeclarations": [], 551 | "referencedDeclaration": 56, 552 | "src": "431:10:0", 553 | "typeDescriptions": { 554 | "typeIdentifier": "t_type$_t_contract$_Migrations_$56_$", 555 | "typeString": "type(contract Migrations)" 556 | } 557 | }, 558 | "id": 46, 559 | "isConstant": false, 560 | "isLValue": false, 561 | "isPure": false, 562 | "kind": "typeConversion", 563 | "lValueRequested": false, 564 | "names": [], 565 | "nodeType": "FunctionCall", 566 | "src": "431:23:0", 567 | "typeDescriptions": { 568 | "typeIdentifier": "t_contract$_Migrations_$56", 569 | "typeString": "contract Migrations" 570 | } 571 | }, 572 | "nodeType": "VariableDeclarationStatement", 573 | "src": "409:45:0" 574 | }, 575 | { 576 | "expression": { 577 | "argumentTypes": null, 578 | "arguments": [ 579 | { 580 | "argumentTypes": null, 581 | "id": 51, 582 | "name": "last_completed_migration", 583 | "nodeType": "Identifier", 584 | "overloadedDeclarations": [], 585 | "referencedDeclaration": 5, 586 | "src": "482:24:0", 587 | "typeDescriptions": { 588 | "typeIdentifier": "t_uint256", 589 | "typeString": "uint256" 590 | } 591 | } 592 | ], 593 | "expression": { 594 | "argumentTypes": [ 595 | { 596 | "typeIdentifier": "t_uint256", 597 | "typeString": "uint256" 598 | } 599 | ], 600 | "expression": { 601 | "argumentTypes": null, 602 | "id": 48, 603 | "name": "upgraded", 604 | "nodeType": "Identifier", 605 | "overloadedDeclarations": [], 606 | "referencedDeclaration": 43, 607 | "src": "460:8:0", 608 | "typeDescriptions": { 609 | "typeIdentifier": "t_contract$_Migrations_$56", 610 | "typeString": "contract Migrations" 611 | } 612 | }, 613 | "id": 50, 614 | "isConstant": false, 615 | "isLValue": false, 616 | "isPure": false, 617 | "lValueRequested": false, 618 | "memberName": "setCompleted", 619 | "nodeType": "MemberAccess", 620 | "referencedDeclaration": 35, 621 | "src": "460:21:0", 622 | "typeDescriptions": { 623 | "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$", 624 | "typeString": "function (uint256) external" 625 | } 626 | }, 627 | "id": 52, 628 | "isConstant": false, 629 | "isLValue": false, 630 | "isPure": false, 631 | "kind": "functionCall", 632 | "lValueRequested": false, 633 | "names": [], 634 | "nodeType": "FunctionCall", 635 | "src": "460:47:0", 636 | "typeDescriptions": { 637 | "typeIdentifier": "t_tuple$__$", 638 | "typeString": "tuple()" 639 | } 640 | }, 641 | "id": 53, 642 | "nodeType": "ExpressionStatement", 643 | "src": "460:47:0" 644 | } 645 | ] 646 | }, 647 | "documentation": null, 648 | "id": 55, 649 | "implemented": true, 650 | "kind": "function", 651 | "modifiers": [ 652 | { 653 | "arguments": null, 654 | "id": 40, 655 | "modifierName": { 656 | "argumentTypes": null, 657 | "id": 39, 658 | "name": "restricted", 659 | "nodeType": "Identifier", 660 | "overloadedDeclarations": [], 661 | "referencedDeclaration": 23, 662 | "src": "392:10:0", 663 | "typeDescriptions": { 664 | "typeIdentifier": "t_modifier$__$", 665 | "typeString": "modifier ()" 666 | } 667 | }, 668 | "nodeType": "ModifierInvocation", 669 | "src": "392:10:0" 670 | } 671 | ], 672 | "name": "upgrade", 673 | "nodeType": "FunctionDefinition", 674 | "parameters": { 675 | "id": 38, 676 | "nodeType": "ParameterList", 677 | "parameters": [ 678 | { 679 | "constant": false, 680 | "id": 37, 681 | "name": "new_address", 682 | "nodeType": "VariableDeclaration", 683 | "scope": 55, 684 | "src": "364:19:0", 685 | "stateVariable": false, 686 | "storageLocation": "default", 687 | "typeDescriptions": { 688 | "typeIdentifier": "t_address", 689 | "typeString": "address" 690 | }, 691 | "typeName": { 692 | "id": 36, 693 | "name": "address", 694 | "nodeType": "ElementaryTypeName", 695 | "src": "364:7:0", 696 | "stateMutability": "nonpayable", 697 | "typeDescriptions": { 698 | "typeIdentifier": "t_address", 699 | "typeString": "address" 700 | } 701 | }, 702 | "value": null, 703 | "visibility": "internal" 704 | } 705 | ], 706 | "src": "363:21:0" 707 | }, 708 | "returnParameters": { 709 | "id": 41, 710 | "nodeType": "ParameterList", 711 | "parameters": [], 712 | "src": "403:0:0" 713 | }, 714 | "scope": 56, 715 | "src": "347:165:0", 716 | "stateMutability": "nonpayable", 717 | "superFunction": null, 718 | "visibility": "public" 719 | } 720 | ], 721 | "scope": 57, 722 | "src": "34:480:0" 723 | } 724 | ], 725 | "src": "0:515:0" 726 | }, 727 | "legacyAST": { 728 | "absolutePath": "/D/ftm/zap/contracts/Migrations.sol", 729 | "exportedSymbols": { 730 | "Migrations": [ 731 | 56 732 | ] 733 | }, 734 | "id": 57, 735 | "nodeType": "SourceUnit", 736 | "nodes": [ 737 | { 738 | "id": 1, 739 | "literals": [ 740 | "solidity", 741 | ">=", 742 | "0.4", 743 | ".21", 744 | "<", 745 | "0.7", 746 | ".0" 747 | ], 748 | "nodeType": "PragmaDirective", 749 | "src": "0:32:0" 750 | }, 751 | { 752 | "baseContracts": [], 753 | "contractDependencies": [], 754 | "contractKind": "contract", 755 | "documentation": null, 756 | "fullyImplemented": true, 757 | "id": 56, 758 | "linearizedBaseContracts": [ 759 | 56 760 | ], 761 | "name": "Migrations", 762 | "nodeType": "ContractDefinition", 763 | "nodes": [ 764 | { 765 | "constant": false, 766 | "id": 3, 767 | "name": "owner", 768 | "nodeType": "VariableDeclaration", 769 | "scope": 56, 770 | "src": "58:20:0", 771 | "stateVariable": true, 772 | "storageLocation": "default", 773 | "typeDescriptions": { 774 | "typeIdentifier": "t_address", 775 | "typeString": "address" 776 | }, 777 | "typeName": { 778 | "id": 2, 779 | "name": "address", 780 | "nodeType": "ElementaryTypeName", 781 | "src": "58:7:0", 782 | "stateMutability": "nonpayable", 783 | "typeDescriptions": { 784 | "typeIdentifier": "t_address", 785 | "typeString": "address" 786 | } 787 | }, 788 | "value": null, 789 | "visibility": "public" 790 | }, 791 | { 792 | "constant": false, 793 | "id": 5, 794 | "name": "last_completed_migration", 795 | "nodeType": "VariableDeclaration", 796 | "scope": 56, 797 | "src": "82:36:0", 798 | "stateVariable": true, 799 | "storageLocation": "default", 800 | "typeDescriptions": { 801 | "typeIdentifier": "t_uint256", 802 | "typeString": "uint256" 803 | }, 804 | "typeName": { 805 | "id": 4, 806 | "name": "uint", 807 | "nodeType": "ElementaryTypeName", 808 | "src": "82:4:0", 809 | "typeDescriptions": { 810 | "typeIdentifier": "t_uint256", 811 | "typeString": "uint256" 812 | } 813 | }, 814 | "value": null, 815 | "visibility": "public" 816 | }, 817 | { 818 | "body": { 819 | "id": 13, 820 | "nodeType": "Block", 821 | "src": "144:29:0", 822 | "statements": [ 823 | { 824 | "expression": { 825 | "argumentTypes": null, 826 | "id": 11, 827 | "isConstant": false, 828 | "isLValue": false, 829 | "isPure": false, 830 | "lValueRequested": false, 831 | "leftHandSide": { 832 | "argumentTypes": null, 833 | "id": 8, 834 | "name": "owner", 835 | "nodeType": "Identifier", 836 | "overloadedDeclarations": [], 837 | "referencedDeclaration": 3, 838 | "src": "150:5:0", 839 | "typeDescriptions": { 840 | "typeIdentifier": "t_address", 841 | "typeString": "address" 842 | } 843 | }, 844 | "nodeType": "Assignment", 845 | "operator": "=", 846 | "rightHandSide": { 847 | "argumentTypes": null, 848 | "expression": { 849 | "argumentTypes": null, 850 | "id": 9, 851 | "name": "msg", 852 | "nodeType": "Identifier", 853 | "overloadedDeclarations": [], 854 | "referencedDeclaration": 1102, 855 | "src": "158:3:0", 856 | "typeDescriptions": { 857 | "typeIdentifier": "t_magic_message", 858 | "typeString": "msg" 859 | } 860 | }, 861 | "id": 10, 862 | "isConstant": false, 863 | "isLValue": false, 864 | "isPure": false, 865 | "lValueRequested": false, 866 | "memberName": "sender", 867 | "nodeType": "MemberAccess", 868 | "referencedDeclaration": null, 869 | "src": "158:10:0", 870 | "typeDescriptions": { 871 | "typeIdentifier": "t_address_payable", 872 | "typeString": "address payable" 873 | } 874 | }, 875 | "src": "150:18:0", 876 | "typeDescriptions": { 877 | "typeIdentifier": "t_address", 878 | "typeString": "address" 879 | } 880 | }, 881 | "id": 12, 882 | "nodeType": "ExpressionStatement", 883 | "src": "150:18:0" 884 | } 885 | ] 886 | }, 887 | "documentation": null, 888 | "id": 14, 889 | "implemented": true, 890 | "kind": "constructor", 891 | "modifiers": [], 892 | "name": "", 893 | "nodeType": "FunctionDefinition", 894 | "parameters": { 895 | "id": 6, 896 | "nodeType": "ParameterList", 897 | "parameters": [], 898 | "src": "134:2:0" 899 | }, 900 | "returnParameters": { 901 | "id": 7, 902 | "nodeType": "ParameterList", 903 | "parameters": [], 904 | "src": "144:0:0" 905 | }, 906 | "scope": 56, 907 | "src": "123:50:0", 908 | "stateMutability": "nonpayable", 909 | "superFunction": null, 910 | "visibility": "public" 911 | }, 912 | { 913 | "body": { 914 | "id": 22, 915 | "nodeType": "Block", 916 | "src": "199:37:0", 917 | "statements": [ 918 | { 919 | "condition": { 920 | "argumentTypes": null, 921 | "commonType": { 922 | "typeIdentifier": "t_address", 923 | "typeString": "address" 924 | }, 925 | "id": 19, 926 | "isConstant": false, 927 | "isLValue": false, 928 | "isPure": false, 929 | "lValueRequested": false, 930 | "leftExpression": { 931 | "argumentTypes": null, 932 | "expression": { 933 | "argumentTypes": null, 934 | "id": 16, 935 | "name": "msg", 936 | "nodeType": "Identifier", 937 | "overloadedDeclarations": [], 938 | "referencedDeclaration": 1102, 939 | "src": "209:3:0", 940 | "typeDescriptions": { 941 | "typeIdentifier": "t_magic_message", 942 | "typeString": "msg" 943 | } 944 | }, 945 | "id": 17, 946 | "isConstant": false, 947 | "isLValue": false, 948 | "isPure": false, 949 | "lValueRequested": false, 950 | "memberName": "sender", 951 | "nodeType": "MemberAccess", 952 | "referencedDeclaration": null, 953 | "src": "209:10:0", 954 | "typeDescriptions": { 955 | "typeIdentifier": "t_address_payable", 956 | "typeString": "address payable" 957 | } 958 | }, 959 | "nodeType": "BinaryOperation", 960 | "operator": "==", 961 | "rightExpression": { 962 | "argumentTypes": null, 963 | "id": 18, 964 | "name": "owner", 965 | "nodeType": "Identifier", 966 | "overloadedDeclarations": [], 967 | "referencedDeclaration": 3, 968 | "src": "223:5:0", 969 | "typeDescriptions": { 970 | "typeIdentifier": "t_address", 971 | "typeString": "address" 972 | } 973 | }, 974 | "src": "209:19:0", 975 | "typeDescriptions": { 976 | "typeIdentifier": "t_bool", 977 | "typeString": "bool" 978 | } 979 | }, 980 | "falseBody": null, 981 | "id": 21, 982 | "nodeType": "IfStatement", 983 | "src": "205:26:0", 984 | "trueBody": { 985 | "id": 20, 986 | "nodeType": "PlaceholderStatement", 987 | "src": "230:1:0" 988 | } 989 | } 990 | ] 991 | }, 992 | "documentation": null, 993 | "id": 23, 994 | "name": "restricted", 995 | "nodeType": "ModifierDefinition", 996 | "parameters": { 997 | "id": 15, 998 | "nodeType": "ParameterList", 999 | "parameters": [], 1000 | "src": "196:2:0" 1001 | }, 1002 | "src": "177:59:0", 1003 | "visibility": "internal" 1004 | }, 1005 | { 1006 | "body": { 1007 | "id": 34, 1008 | "nodeType": "Block", 1009 | "src": "296:47:0", 1010 | "statements": [ 1011 | { 1012 | "expression": { 1013 | "argumentTypes": null, 1014 | "id": 32, 1015 | "isConstant": false, 1016 | "isLValue": false, 1017 | "isPure": false, 1018 | "lValueRequested": false, 1019 | "leftHandSide": { 1020 | "argumentTypes": null, 1021 | "id": 30, 1022 | "name": "last_completed_migration", 1023 | "nodeType": "Identifier", 1024 | "overloadedDeclarations": [], 1025 | "referencedDeclaration": 5, 1026 | "src": "302:24:0", 1027 | "typeDescriptions": { 1028 | "typeIdentifier": "t_uint256", 1029 | "typeString": "uint256" 1030 | } 1031 | }, 1032 | "nodeType": "Assignment", 1033 | "operator": "=", 1034 | "rightHandSide": { 1035 | "argumentTypes": null, 1036 | "id": 31, 1037 | "name": "completed", 1038 | "nodeType": "Identifier", 1039 | "overloadedDeclarations": [], 1040 | "referencedDeclaration": 25, 1041 | "src": "329:9:0", 1042 | "typeDescriptions": { 1043 | "typeIdentifier": "t_uint256", 1044 | "typeString": "uint256" 1045 | } 1046 | }, 1047 | "src": "302:36:0", 1048 | "typeDescriptions": { 1049 | "typeIdentifier": "t_uint256", 1050 | "typeString": "uint256" 1051 | } 1052 | }, 1053 | "id": 33, 1054 | "nodeType": "ExpressionStatement", 1055 | "src": "302:36:0" 1056 | } 1057 | ] 1058 | }, 1059 | "documentation": null, 1060 | "id": 35, 1061 | "implemented": true, 1062 | "kind": "function", 1063 | "modifiers": [ 1064 | { 1065 | "arguments": null, 1066 | "id": 28, 1067 | "modifierName": { 1068 | "argumentTypes": null, 1069 | "id": 27, 1070 | "name": "restricted", 1071 | "nodeType": "Identifier", 1072 | "overloadedDeclarations": [], 1073 | "referencedDeclaration": 23, 1074 | "src": "285:10:0", 1075 | "typeDescriptions": { 1076 | "typeIdentifier": "t_modifier$__$", 1077 | "typeString": "modifier ()" 1078 | } 1079 | }, 1080 | "nodeType": "ModifierInvocation", 1081 | "src": "285:10:0" 1082 | } 1083 | ], 1084 | "name": "setCompleted", 1085 | "nodeType": "FunctionDefinition", 1086 | "parameters": { 1087 | "id": 26, 1088 | "nodeType": "ParameterList", 1089 | "parameters": [ 1090 | { 1091 | "constant": false, 1092 | "id": 25, 1093 | "name": "completed", 1094 | "nodeType": "VariableDeclaration", 1095 | "scope": 35, 1096 | "src": "262:14:0", 1097 | "stateVariable": false, 1098 | "storageLocation": "default", 1099 | "typeDescriptions": { 1100 | "typeIdentifier": "t_uint256", 1101 | "typeString": "uint256" 1102 | }, 1103 | "typeName": { 1104 | "id": 24, 1105 | "name": "uint", 1106 | "nodeType": "ElementaryTypeName", 1107 | "src": "262:4:0", 1108 | "typeDescriptions": { 1109 | "typeIdentifier": "t_uint256", 1110 | "typeString": "uint256" 1111 | } 1112 | }, 1113 | "value": null, 1114 | "visibility": "internal" 1115 | } 1116 | ], 1117 | "src": "261:16:0" 1118 | }, 1119 | "returnParameters": { 1120 | "id": 29, 1121 | "nodeType": "ParameterList", 1122 | "parameters": [], 1123 | "src": "296:0:0" 1124 | }, 1125 | "scope": 56, 1126 | "src": "240:103:0", 1127 | "stateMutability": "nonpayable", 1128 | "superFunction": null, 1129 | "visibility": "public" 1130 | }, 1131 | { 1132 | "body": { 1133 | "id": 54, 1134 | "nodeType": "Block", 1135 | "src": "403:109:0", 1136 | "statements": [ 1137 | { 1138 | "assignments": [ 1139 | 43 1140 | ], 1141 | "declarations": [ 1142 | { 1143 | "constant": false, 1144 | "id": 43, 1145 | "name": "upgraded", 1146 | "nodeType": "VariableDeclaration", 1147 | "scope": 54, 1148 | "src": "409:19:0", 1149 | "stateVariable": false, 1150 | "storageLocation": "default", 1151 | "typeDescriptions": { 1152 | "typeIdentifier": "t_contract$_Migrations_$56", 1153 | "typeString": "contract Migrations" 1154 | }, 1155 | "typeName": { 1156 | "contractScope": null, 1157 | "id": 42, 1158 | "name": "Migrations", 1159 | "nodeType": "UserDefinedTypeName", 1160 | "referencedDeclaration": 56, 1161 | "src": "409:10:0", 1162 | "typeDescriptions": { 1163 | "typeIdentifier": "t_contract$_Migrations_$56", 1164 | "typeString": "contract Migrations" 1165 | } 1166 | }, 1167 | "value": null, 1168 | "visibility": "internal" 1169 | } 1170 | ], 1171 | "id": 47, 1172 | "initialValue": { 1173 | "argumentTypes": null, 1174 | "arguments": [ 1175 | { 1176 | "argumentTypes": null, 1177 | "id": 45, 1178 | "name": "new_address", 1179 | "nodeType": "Identifier", 1180 | "overloadedDeclarations": [], 1181 | "referencedDeclaration": 37, 1182 | "src": "442:11:0", 1183 | "typeDescriptions": { 1184 | "typeIdentifier": "t_address", 1185 | "typeString": "address" 1186 | } 1187 | } 1188 | ], 1189 | "expression": { 1190 | "argumentTypes": [ 1191 | { 1192 | "typeIdentifier": "t_address", 1193 | "typeString": "address" 1194 | } 1195 | ], 1196 | "id": 44, 1197 | "name": "Migrations", 1198 | "nodeType": "Identifier", 1199 | "overloadedDeclarations": [], 1200 | "referencedDeclaration": 56, 1201 | "src": "431:10:0", 1202 | "typeDescriptions": { 1203 | "typeIdentifier": "t_type$_t_contract$_Migrations_$56_$", 1204 | "typeString": "type(contract Migrations)" 1205 | } 1206 | }, 1207 | "id": 46, 1208 | "isConstant": false, 1209 | "isLValue": false, 1210 | "isPure": false, 1211 | "kind": "typeConversion", 1212 | "lValueRequested": false, 1213 | "names": [], 1214 | "nodeType": "FunctionCall", 1215 | "src": "431:23:0", 1216 | "typeDescriptions": { 1217 | "typeIdentifier": "t_contract$_Migrations_$56", 1218 | "typeString": "contract Migrations" 1219 | } 1220 | }, 1221 | "nodeType": "VariableDeclarationStatement", 1222 | "src": "409:45:0" 1223 | }, 1224 | { 1225 | "expression": { 1226 | "argumentTypes": null, 1227 | "arguments": [ 1228 | { 1229 | "argumentTypes": null, 1230 | "id": 51, 1231 | "name": "last_completed_migration", 1232 | "nodeType": "Identifier", 1233 | "overloadedDeclarations": [], 1234 | "referencedDeclaration": 5, 1235 | "src": "482:24:0", 1236 | "typeDescriptions": { 1237 | "typeIdentifier": "t_uint256", 1238 | "typeString": "uint256" 1239 | } 1240 | } 1241 | ], 1242 | "expression": { 1243 | "argumentTypes": [ 1244 | { 1245 | "typeIdentifier": "t_uint256", 1246 | "typeString": "uint256" 1247 | } 1248 | ], 1249 | "expression": { 1250 | "argumentTypes": null, 1251 | "id": 48, 1252 | "name": "upgraded", 1253 | "nodeType": "Identifier", 1254 | "overloadedDeclarations": [], 1255 | "referencedDeclaration": 43, 1256 | "src": "460:8:0", 1257 | "typeDescriptions": { 1258 | "typeIdentifier": "t_contract$_Migrations_$56", 1259 | "typeString": "contract Migrations" 1260 | } 1261 | }, 1262 | "id": 50, 1263 | "isConstant": false, 1264 | "isLValue": false, 1265 | "isPure": false, 1266 | "lValueRequested": false, 1267 | "memberName": "setCompleted", 1268 | "nodeType": "MemberAccess", 1269 | "referencedDeclaration": 35, 1270 | "src": "460:21:0", 1271 | "typeDescriptions": { 1272 | "typeIdentifier": "t_function_external_nonpayable$_t_uint256_$returns$__$", 1273 | "typeString": "function (uint256) external" 1274 | } 1275 | }, 1276 | "id": 52, 1277 | "isConstant": false, 1278 | "isLValue": false, 1279 | "isPure": false, 1280 | "kind": "functionCall", 1281 | "lValueRequested": false, 1282 | "names": [], 1283 | "nodeType": "FunctionCall", 1284 | "src": "460:47:0", 1285 | "typeDescriptions": { 1286 | "typeIdentifier": "t_tuple$__$", 1287 | "typeString": "tuple()" 1288 | } 1289 | }, 1290 | "id": 53, 1291 | "nodeType": "ExpressionStatement", 1292 | "src": "460:47:0" 1293 | } 1294 | ] 1295 | }, 1296 | "documentation": null, 1297 | "id": 55, 1298 | "implemented": true, 1299 | "kind": "function", 1300 | "modifiers": [ 1301 | { 1302 | "arguments": null, 1303 | "id": 40, 1304 | "modifierName": { 1305 | "argumentTypes": null, 1306 | "id": 39, 1307 | "name": "restricted", 1308 | "nodeType": "Identifier", 1309 | "overloadedDeclarations": [], 1310 | "referencedDeclaration": 23, 1311 | "src": "392:10:0", 1312 | "typeDescriptions": { 1313 | "typeIdentifier": "t_modifier$__$", 1314 | "typeString": "modifier ()" 1315 | } 1316 | }, 1317 | "nodeType": "ModifierInvocation", 1318 | "src": "392:10:0" 1319 | } 1320 | ], 1321 | "name": "upgrade", 1322 | "nodeType": "FunctionDefinition", 1323 | "parameters": { 1324 | "id": 38, 1325 | "nodeType": "ParameterList", 1326 | "parameters": [ 1327 | { 1328 | "constant": false, 1329 | "id": 37, 1330 | "name": "new_address", 1331 | "nodeType": "VariableDeclaration", 1332 | "scope": 55, 1333 | "src": "364:19:0", 1334 | "stateVariable": false, 1335 | "storageLocation": "default", 1336 | "typeDescriptions": { 1337 | "typeIdentifier": "t_address", 1338 | "typeString": "address" 1339 | }, 1340 | "typeName": { 1341 | "id": 36, 1342 | "name": "address", 1343 | "nodeType": "ElementaryTypeName", 1344 | "src": "364:7:0", 1345 | "stateMutability": "nonpayable", 1346 | "typeDescriptions": { 1347 | "typeIdentifier": "t_address", 1348 | "typeString": "address" 1349 | } 1350 | }, 1351 | "value": null, 1352 | "visibility": "internal" 1353 | } 1354 | ], 1355 | "src": "363:21:0" 1356 | }, 1357 | "returnParameters": { 1358 | "id": 41, 1359 | "nodeType": "ParameterList", 1360 | "parameters": [], 1361 | "src": "403:0:0" 1362 | }, 1363 | "scope": 56, 1364 | "src": "347:165:0", 1365 | "stateMutability": "nonpayable", 1366 | "superFunction": null, 1367 | "visibility": "public" 1368 | } 1369 | ], 1370 | "scope": 57, 1371 | "src": "34:480:0" 1372 | } 1373 | ], 1374 | "src": "0:515:0" 1375 | }, 1376 | "compiler": { 1377 | "name": "solc", 1378 | "version": "0.5.12+commit.7709ece9.Emscripten.clang" 1379 | }, 1380 | "networks": {}, 1381 | "schemaVersion": "3.0.19", 1382 | "updatedAt": "2020-01-22T04:07:09.215Z", 1383 | "devdoc": { 1384 | "methods": {} 1385 | }, 1386 | "userdoc": { 1387 | "methods": {} 1388 | } 1389 | } -------------------------------------------------------------------------------- /contracts/IUniSwap_ETH_cDAI.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity ^0.5.0; 3 | 4 | interface IERC20 { 5 | function totalSupply() external view returns (uint256); 6 | function balanceOf(address account) external view returns (uint256); 7 | function transfer(address recipient, uint256 amount) external returns (bool); 8 | function allowance(address owner, address spender) external view returns (uint256); 9 | function approve(address spender, uint256 amount) external returns (bool); 10 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 11 | event Transfer(address indexed from, address indexed to, uint256 value); 12 | event Approval(address indexed owner, address indexed spender, uint256 value); 13 | } 14 | 15 | interface IUniSwap_ETH_CDAIZap { 16 | function getExpectedReturn(uint256 eth) external view returns (uint256); 17 | function LetsInvest(address _towhomtoissue, uint256 _minReturn) external returns (uint); 18 | function getUniswapExchangeContractAddress() external view returns (address); 19 | function Redeem(address payable _towhomtosend, uint256 _amount) external returns (uint); 20 | function getMaxTokens(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _value) external view returns (uint); 21 | function getEthBalance(address _UniSwapExchangeContractAddress) external view returns (uint); 22 | function getTokenReserves(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress) external view returns (uint); 23 | function getTotalShares(address _UniSwapExchangeContractAddress) external view returns (uint); 24 | function getReturn(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _value) external view returns (uint, uint, uint); 25 | function calcReturnETHFromShares(uint _value) external view returns (uint, uint, uint); 26 | function uniBalanceOf(address _owner) external view returns (uint); 27 | function cBalanceOf(address _owner) external view returns (uint); 28 | function calcReturnSharesFromETH(uint _value) external view returns (uint); 29 | function getTokenToEthOutputPrice(uint _tokens) external view returns (uint); 30 | function getSharesReturn(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _ethValue) external view returns (uint); 31 | } 32 | -------------------------------------------------------------------------------- /contracts/InvestZAP.sol: -------------------------------------------------------------------------------- 1 | // File: @openzeppelin\contracts\token\ERC20\IERC20.sol 2 | 3 | pragma solidity ^0.5.0; 4 | pragma experimental ABIEncoderV2; 5 | 6 | interface IERC20 { 7 | 8 | function totalSupply() external view returns (uint256); 9 | function balanceOf(address account) external view returns (uint256); 10 | function name() external view returns (string memory); 11 | function symbol() external view returns (string memory); 12 | function transfer(address recipient, uint256 amount) external returns (bool); 13 | function approve(address spender, uint256 amount) external returns (bool); 14 | } 15 | 16 | // File: @openzeppelin\contracts\GSN\Context.sol 17 | 18 | pragma solidity ^0.5.0; 19 | 20 | /* 21 | * @dev Provides information about the current execution context, including the 22 | * sender of the transaction and its data. While these are generally available 23 | * via msg.sender and msg.data, they should not be accessed in such a direct 24 | * manner, since when dealing with GSN meta-transactions the account sending and 25 | * paying for execution may not be the actual sender (as far as an application 26 | * is concerned). 27 | * 28 | * This contract is only required for intermediate, library-like contracts. 29 | */ 30 | contract Context { 31 | // Empty internal constructor, to prevent people from mistakenly deploying 32 | // an instance of this contract, which should be used via inheritance. 33 | constructor () internal { } 34 | // solhint-disable-previous-line no-empty-blocks 35 | 36 | function _msgSender() internal view returns (address payable) { 37 | return msg.sender; 38 | } 39 | 40 | function _msgData() internal view returns (bytes memory) { 41 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 42 | return msg.data; 43 | } 44 | } 45 | 46 | // File: @openzeppelin\contracts\ownership\Ownable.sol 47 | 48 | pragma solidity ^0.5.0; 49 | 50 | /** 51 | * @dev Contract module which provides a basic access control mechanism, where 52 | * there is an account (an owner) that can be granted exclusive access to 53 | * specific functions. 54 | * 55 | * This module is used through inheritance. It will make available the modifier 56 | * `onlyOwner`, which can be applied to your functions to restrict their use to 57 | * the owner. 58 | */ 59 | contract Ownable is Context { 60 | address private _owner; 61 | 62 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 63 | 64 | /** 65 | * @dev Initializes the contract setting the deployer as the initial owner. 66 | */ 67 | constructor () internal { 68 | _owner = _msgSender(); 69 | emit OwnershipTransferred(address(0), _owner); 70 | } 71 | 72 | /** 73 | * @dev Returns the address of the current owner. 74 | */ 75 | function owner() public view returns (address) { 76 | return _owner; 77 | } 78 | 79 | /** 80 | * @dev Throws if called by any account other than the owner. 81 | */ 82 | modifier onlyOwner() { 83 | require(isOwner(), "Ownable: caller is not the owner"); 84 | _; 85 | } 86 | 87 | /** 88 | * @dev Returns true if the caller is the current owner. 89 | */ 90 | function isOwner() public view returns (bool) { 91 | return _msgSender() == _owner; 92 | } 93 | 94 | /** 95 | * @dev Leaves the contract without owner. It will not be possible to call 96 | * `onlyOwner` functions anymore. Can only be called by the current owner. 97 | * 98 | * NOTE: Renouncing ownership will leave the contract without an owner, 99 | * thereby removing any functionality that is only available to the owner. 100 | */ 101 | function renounceOwnership() public onlyOwner { 102 | emit OwnershipTransferred(_owner, address(0)); 103 | _owner = address(0); 104 | } 105 | 106 | /** 107 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 108 | * Can only be called by the current owner. 109 | */ 110 | function transferOwnership(address newOwner) public onlyOwner { 111 | _transferOwnership(newOwner); 112 | } 113 | 114 | /** 115 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 116 | */ 117 | function _transferOwnership(address newOwner) internal { 118 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 119 | emit OwnershipTransferred(_owner, newOwner); 120 | _owner = newOwner; 121 | } 122 | } 123 | 124 | // File: @openzeppelin\contracts\math\SafeMath.sol 125 | 126 | pragma solidity ^0.5.0; 127 | 128 | /** 129 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 130 | * checks. 131 | * 132 | * Arithmetic operations in Solidity wrap on overflow. This can easily result 133 | * in bugs, because programmers usually assume that an overflow raises an 134 | * error, which is the standard behavior in high level programming languages. 135 | * `SafeMath` restores this intuition by reverting the transaction when an 136 | * operation overflows. 137 | * 138 | * Using this library instead of the unchecked operations eliminates an entire 139 | * class of bugs, so it's recommended to use it always. 140 | */ 141 | library SafeMath { 142 | /** 143 | * @dev Returns the addition of two unsigned integers, reverting on 144 | * overflow. 145 | * 146 | * Counterpart to Solidity's `+` operator. 147 | * 148 | * Requirements: 149 | * - Addition cannot overflow. 150 | */ 151 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 152 | uint256 c = a + b; 153 | require(c >= a, "SafeMath: addition overflow"); 154 | 155 | return c; 156 | } 157 | 158 | /** 159 | * @dev Returns the subtraction of two unsigned integers, reverting on 160 | * overflow (when the result is negative). 161 | * 162 | * Counterpart to Solidity's `-` operator. 163 | * 164 | * Requirements: 165 | * - Subtraction cannot overflow. 166 | */ 167 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 168 | return sub(a, b, "SafeMath: subtraction overflow"); 169 | } 170 | 171 | /** 172 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 173 | * overflow (when the result is negative). 174 | * 175 | * Counterpart to Solidity's `-` operator. 176 | * 177 | * Requirements: 178 | * - Subtraction cannot overflow. 179 | * 180 | * _Available since v2.4.0._ 181 | */ 182 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 183 | require(b <= a, errorMessage); 184 | uint256 c = a - b; 185 | 186 | return c; 187 | } 188 | 189 | /** 190 | * @dev Returns the multiplication of two unsigned integers, reverting on 191 | * overflow. 192 | * 193 | * Counterpart to Solidity's `*` operator. 194 | * 195 | * Requirements: 196 | * - Multiplication cannot overflow. 197 | */ 198 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 199 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 200 | // benefit is lost if 'b' is also tested. 201 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 202 | if (a == 0) { 203 | return 0; 204 | } 205 | 206 | uint256 c = a * b; 207 | require(c / a == b, "SafeMath: multiplication overflow"); 208 | 209 | return c; 210 | } 211 | 212 | /** 213 | * @dev Returns the integer division of two unsigned integers. Reverts on 214 | * division by zero. The result is rounded towards zero. 215 | * 216 | * Counterpart to Solidity's `/` operator. Note: this function uses a 217 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 218 | * uses an invalid opcode to revert (consuming all remaining gas). 219 | * 220 | * Requirements: 221 | * - The divisor cannot be zero. 222 | */ 223 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 224 | return div(a, b, "SafeMath: division by zero"); 225 | } 226 | 227 | /** 228 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 229 | * division by zero. The result is rounded towards zero. 230 | * 231 | * Counterpart to Solidity's `/` operator. Note: this function uses a 232 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 233 | * uses an invalid opcode to revert (consuming all remaining gas). 234 | * 235 | * Requirements: 236 | * - The divisor cannot be zero. 237 | * 238 | * _Available since v2.4.0._ 239 | */ 240 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 241 | // Solidity only automatically asserts when dividing by 0 242 | require(b > 0, errorMessage); 243 | uint256 c = a / b; 244 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 245 | 246 | return c; 247 | } 248 | 249 | /** 250 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 251 | * Reverts when dividing by zero. 252 | * 253 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 254 | * opcode (which leaves remaining gas untouched) while Solidity uses an 255 | * invalid opcode to revert (consuming all remaining gas). 256 | * 257 | * Requirements: 258 | * - The divisor cannot be zero. 259 | */ 260 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 261 | return mod(a, b, "SafeMath: modulo by zero"); 262 | } 263 | 264 | /** 265 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 266 | * Reverts with custom message when dividing by zero. 267 | * 268 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 269 | * opcode (which leaves remaining gas untouched) while Solidity uses an 270 | * invalid opcode to revert (consuming all remaining gas). 271 | * 272 | * Requirements: 273 | * - The divisor cannot be zero. 274 | * 275 | * _Available since v2.4.0._ 276 | */ 277 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 278 | require(b != 0, errorMessage); 279 | return a % b; 280 | } 281 | } 282 | 283 | // File: @openzeppelin\contracts\utils\Address.sol 284 | 285 | pragma solidity ^0.5.5; 286 | 287 | /** 288 | * @dev Collection of functions related to the address type 289 | */ 290 | library Address { 291 | /** 292 | * @dev Returns true if `account` is a contract. 293 | * 294 | * This test is non-exhaustive, and there may be false-negatives: during the 295 | * execution of a contract's constructor, its address will be reported as 296 | * not containing a contract. 297 | * 298 | * IMPORTANT: It is unsafe to assume that an address for which this 299 | * function returns false is an externally-owned account (EOA) and not a 300 | * contract. 301 | */ 302 | function isContract(address account) internal view returns (bool) { 303 | // This method relies in extcodesize, which returns 0 for contracts in 304 | // construction, since the code is only stored at the end of the 305 | // constructor execution. 306 | 307 | // According to EIP-1052, 0x0 is the value returned for not-yet created accounts 308 | // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned 309 | // for accounts without code, i.e. `keccak256('')` 310 | bytes32 codehash; 311 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 312 | // solhint-disable-next-line no-inline-assembly 313 | assembly { codehash := extcodehash(account) } 314 | return (codehash != 0x0 && codehash != accountHash); 315 | } 316 | 317 | /** 318 | * @dev Converts an `address` into `address payable`. Note that this is 319 | * simply a type cast: the actual underlying value is not changed. 320 | * 321 | * _Available since v2.4.0._ 322 | */ 323 | function toPayable(address account) internal pure returns (address payable) { 324 | return address(uint160(account)); 325 | } 326 | 327 | /** 328 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 329 | * `recipient`, forwarding all available gas and reverting on errors. 330 | * 331 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 332 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 333 | * imposed by `transfer`, making them unable to receive funds via 334 | * `transfer`. {sendValue} removes this limitation. 335 | * 336 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 337 | * 338 | * IMPORTANT: because control is transferred to `recipient`, care must be 339 | * taken to not create reentrancy vulnerabilities. Consider using 340 | * {ReentrancyGuard} or the 341 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 342 | * 343 | * _Available since v2.4.0._ 344 | */ 345 | function sendValue(address payable recipient, uint256 amount) internal { 346 | require(address(this).balance >= amount, "Address: insufficient balance"); 347 | 348 | // solhint-disable-next-line avoid-call-value 349 | (bool success, ) = recipient.call.value(amount)(""); 350 | require(success, "Address: unable to send value, recipient may have reverted"); 351 | } 352 | } 353 | 354 | 355 | interface Compound { 356 | function approve ( address spender, uint256 amount ) external returns ( bool ); 357 | function mint ( uint256 mintAmount ) external returns ( uint256 ); 358 | function balanceOf(address _owner) external view returns (uint256 balance); 359 | function transfer(address _to, uint _value) external returns (bool success); 360 | function redeem(uint256 redeemTokens) external returns (uint256); 361 | } 362 | 363 | interface Fulcrum { 364 | function mintWithEther(address receiver, uint256 maxPriceAllowed) external payable returns (uint256 mintAmount); 365 | function mint(address receiver, uint256 amount) external payable returns (uint256 mintAmount); 366 | function burnToEther(address receiver, uint256 burnAmount, uint256 minPriceAllowed) external returns (uint256 loanAmountPaid); 367 | function burn(address receiver, uint256 burnAmount) external returns (uint256 loanAmountPaid); 368 | function balanceOf(address _owner) external view returns (uint256 balance); 369 | } 370 | 371 | interface ILendingPoolAddressesProvider { 372 | function getLendingPool() external view returns (address); 373 | } 374 | 375 | interface Aave { 376 | function deposit(address _reserve, uint256 _amount, uint16 _referralCode) external; 377 | function redeemUnderlying(address _reserve, address payable _user, uint256 _amount, uint256 _aTokenBalanceAfterRedeem) external; 378 | function balanceOf(address _owner) external view returns (uint256 balance); 379 | } 380 | 381 | interface AToken { 382 | function redeem(uint256 amount) external; 383 | function balanceOf(address _owner) external view returns (uint256 balance); 384 | } 385 | 386 | interface IIEarnManager { 387 | function recommend(address _token) external view returns ( 388 | string memory choice, 389 | uint256 capr, 390 | uint256 iapr, 391 | uint256 aapr, 392 | uint256 dapr 393 | ); 394 | } 395 | 396 | contract Structs { 397 | struct Val { 398 | uint256 value; 399 | } 400 | 401 | struct TotalPar { 402 | uint128 borrow; 403 | uint128 supply; 404 | } 405 | 406 | enum ActionType { 407 | Deposit, // supply tokens 408 | Withdraw, // borrow tokens 409 | Transfer, // transfer balance between accounts 410 | Buy, // buy an amount of some token (externally) 411 | Sell, // sell an amount of some token (externally) 412 | Trade, // trade tokens against another account 413 | Liquidate, // liquidate an undercollateralized or expiring account 414 | Vaporize, // use excess tokens to zero-out a completely negative account 415 | Call // send arbitrary data to an address 416 | } 417 | 418 | enum AssetDenomination { 419 | Wei, // the amount is denominated in wei 420 | Par // the amount is denominated in par 421 | } 422 | 423 | enum AssetReference { 424 | Delta, // the amount is given as a delta from the current value 425 | Target // the amount is given as an exact number to end up at 426 | } 427 | 428 | struct AssetAmount { 429 | bool sign; // true if positive 430 | AssetDenomination denomination; 431 | AssetReference ref; 432 | uint256 value; 433 | } 434 | 435 | struct ActionArgs { 436 | ActionType actionType; 437 | uint256 accountId; 438 | AssetAmount amount; 439 | uint256 primaryMarketId; 440 | uint256 secondaryMarketId; 441 | address otherAddress; 442 | uint256 otherAccountId; 443 | bytes data; 444 | } 445 | 446 | struct Info { 447 | address owner; // The address that owns the account 448 | uint256 number; // A nonce that allows a single address to control many accounts 449 | } 450 | 451 | struct Wei { 452 | bool sign; // true if positive 453 | uint256 value; 454 | } 455 | } 456 | 457 | contract DyDx is Structs { 458 | function getEarningsRate() public view returns (Val memory); 459 | function getMarketInterestRate(uint256 marketId) public view returns (Val memory); 460 | function getMarketTotalPar(uint256 marketId) public view returns (TotalPar memory); 461 | function getAccountWei(Info memory account, uint256 marketId) public view returns (Wei memory); 462 | function operate(Info[] memory, ActionArgs[] memory) public; 463 | } 464 | 465 | contract InvestZAP is Ownable, Structs { 466 | using SafeMath for uint; 467 | using Address for address; 468 | 469 | mapping(address => address) public compound; 470 | mapping(address => address) public fulcrum; 471 | mapping(address => address) public aave; 472 | mapping(address => uint256) public dydx; 473 | 474 | address public APR; 475 | address public AAVE; 476 | address public DYDX; 477 | 478 | enum CurrentLender { 479 | NONE, 480 | DYDX, 481 | COMPOUND, 482 | AAVE, 483 | FULCRUM 484 | } 485 | 486 | constructor() public { 487 | APR = address(0x9CaD8AB10daA9AF1a9D2B878541f41b697268eEC); 488 | DYDX = address(0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e); 489 | AAVE = address(0x24a42fD28C976A61Df5D00D0599C34c4f90748c8); 490 | 491 | addCToken(0x6B175474E89094C44Da98b954EedeAC495271d0F, 0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643); // cDAI 492 | addCToken(0x0D8775F648430679A709E98d2b0Cb6250d2887EF, 0x6C8c6b02E7b2BE14d4fA6022Dfd6d75921D90E4E); // cBAT 493 | addCToken(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5); // cETH 494 | addCToken(0x1985365e9f78359a9B6AD760e32412f4a445E862, 0x158079Ee67Fce2f58472A96584A73C7Ab9AC95c1); // cREP 495 | addCToken(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 0x39AA39c021dfbaE8faC545936693aC917d5E7563); // cUSDC 496 | addCToken(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599, 0xC11b1268C1A384e55C48c2391d8d480264A3A7F4); // cWBTC 497 | addCToken(0xE41d2489571d322189246DaFA5ebDe1F4699F498, 0xB3319f5D18Bc0D84dD1b4825Dcde5d5f7266d407); // cZRX 498 | 499 | addAToken(0x6B175474E89094C44Da98b954EedeAC495271d0F, 0xfC1E690f61EFd961294b3e1Ce3313fBD8aa4f85d); // aDAI 500 | addAToken(0x0000000000085d4780B73119b644AE5ecd22b376, 0x4DA9b813057D04BAef4e5800E36083717b4a0341); // aTUSD 501 | addAToken(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 0x9bA00D6856a4eDF4665BcA2C2309936572473B7E); // aUSDC 502 | addAToken(0xdAC17F958D2ee523a2206206994597C13D831ec7, 0x71fc860F7D3A592A4a98740e39dB31d25db65ae8); // aUSDT 503 | addAToken(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51, 0x625aE63000f46200499120B906716420bd059240); // aSUSD 504 | addAToken(0x80fB784B7eD66730e8b1DBd9820aFD29931aab03, 0x7D2D3688Df45Ce7C552E19c27e007673da9204B8); // aLEND 505 | addAToken(0x0D8775F648430679A709E98d2b0Cb6250d2887EF, 0xE1BA0FB44CCb0D11b80F92f4f8Ed94CA3fF51D00); // aBAT 506 | addAToken(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0x3a3A65aAb0dd2A17E3F1947bA16138cd37d08c04); // aETH 507 | addAToken(0x514910771AF9Ca656af840dff83E8264EcF986CA, 0xA64BD6C70Cb9051F6A9ba1F163Fdc07E0DfB5F84); // aLINK 508 | addAToken(0xdd974D5C2e2928deA5F71b9825b8b646686BD200, 0x9D91BE44C06d373a8a226E1f3b146956083803eB); // aKNC 509 | addAToken(0x1985365e9f78359a9B6AD760e32412f4a445E862, 0x71010A9D003445aC60C4e6A7017c1E89A477B438); // aREP 510 | addAToken(0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2, 0x7deB5e830be29F91E298ba5FF1356BB7f8146998); // aMKR 511 | addAToken(0x0F5D2fB29fb7d3CFeE444a200298f468908cC942, 0x6FCE4A401B6B80ACe52baAefE4421Bd188e76F6f); // aMANA 512 | addAToken(0xE41d2489571d322189246DaFA5ebDe1F4699F498, 0x6Fb0855c404E09c47C3fBCA25f08d4E41f9F062f); // aZRX 513 | addAToken(0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F, 0x328C4c80BC7aCa0834Db37e6600A6c49E12Da4DE); // aSNX 514 | addAToken(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599, 0xFC4B8ED459e00e5400be803A9BB3954234FD50e3); // aWBTC 515 | 516 | addIToken(0xE41d2489571d322189246DaFA5ebDe1F4699F498, 0xA7Eb2bc82df18013ecC2A6C533fc29446442EDEe); // iZRX 517 | addIToken(0x1985365e9f78359a9B6AD760e32412f4a445E862, 0xBd56E9477Fc6997609Cf45F84795eFbDAC642Ff1); // iREP 518 | addIToken(0xdd974D5C2e2928deA5F71b9825b8b646686BD200, 0x1cC9567EA2eB740824a45F8026cCF8e46973234D); // iKNC 519 | addIToken(0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599, 0xBA9262578EFef8b3aFf7F60Cd629d6CC8859C8b5); // iWBTC 520 | addIToken(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 0xF013406A0B1d544238083DF0B93ad0d2cBE0f65f); // iUSDC 521 | addIToken(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0x77f973FCaF871459aa58cd81881Ce453759281bC); // iETH 522 | addIToken(0x6B175474E89094C44Da98b954EedeAC495271d0F, 0x493C57C4763932315A328269E1ADaD09653B9081); // iDAI 523 | addIToken(0x514910771AF9Ca656af840dff83E8264EcF986CA, 0x1D496da96caf6b518b133736beca85D5C4F9cBc5); // iLINK 524 | addIToken(0x57Ab1ec28D129707052df4dF418D58a2D46d5f51, 0x49f4592E641820e928F9919Ef4aBd92a719B4b49); // iSUSD 525 | 526 | addDToken(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE, 0); // dETH 527 | addDToken(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48, 2); // dUSDC 528 | addDToken(0x6B175474E89094C44Da98b954EedeAC495271d0F, 3); // dDAI 529 | } 530 | 531 | function set_new_APR(address _new_APR) public onlyOwner { 532 | APR = _new_APR; 533 | } 534 | 535 | function recommend(address _token) public view returns (CurrentLender) { 536 | (,uint256 capr,uint256 iapr,uint256 aapr,uint256 dapr) = IIEarnManager(APR).recommend(_token); 537 | uint256 max = 0; 538 | if (capr > max) { 539 | max = capr; 540 | } 541 | if (iapr > max) { 542 | max = iapr; 543 | } 544 | if (aapr > max) { 545 | max = aapr; 546 | } 547 | if (dapr > max) { 548 | max = dapr; 549 | } 550 | 551 | CurrentLender newLender = CurrentLender.NONE; 552 | if (max == dapr) { 553 | newLender = CurrentLender.DYDX; 554 | } 555 | if (max == aapr) { 556 | newLender = CurrentLender.AAVE; 557 | } 558 | if (max == iapr) { 559 | newLender = CurrentLender.FULCRUM; 560 | } 561 | if (max == capr) { 562 | newLender = CurrentLender.COMPOUND; 563 | } 564 | return newLender; 565 | } 566 | 567 | function balanceDydx(address _token) public view returns (uint256) { 568 | return balanceDydxAddress(_token, address(this)); 569 | } 570 | function balanceDydxAddress(address _token, address _owner) public view returns (uint256) { 571 | uint256 marketID = dydx[_token]; 572 | Wei memory bal = DyDx(DYDX).getAccountWei(Info(_owner, 0), marketID); 573 | return bal.value; 574 | } 575 | function balanceCompound(address _token) public view returns (uint256) { 576 | return balanceCompoundAddress(_token, address(this)); 577 | } 578 | function balanceCompoundAddress(address _token, address _owner) public view returns (uint256) { 579 | return Compound(compound[_token]).balanceOf(_owner); 580 | } 581 | function balanceFulcrum(address _token) public view returns (uint256) { 582 | return balanceFulcrumAddress(_token, address(this)); 583 | } 584 | function balanceFulcrumAddress(address _token, address _owner) public view returns (uint256) { 585 | return Fulcrum(fulcrum[_token]).balanceOf(_owner); 586 | } 587 | function balanceAave(address _token) public view returns (uint256) { 588 | return balanceAaveAddress(_token, address(this)); 589 | } 590 | function balanceAaveAddress(address _token, address _owner) public view returns (uint256) { 591 | return AToken(aave[_token]).balanceOf(_owner); 592 | } 593 | 594 | function supplyDydx(address _token, uint256 amount) public returns(uint) { 595 | uint256 marketID = dydx[_token]; 596 | 597 | Info[] memory infos = new Info[](1); 598 | infos[0] = Info(address(this), 0); 599 | 600 | AssetAmount memory amt = AssetAmount(true, AssetDenomination.Wei, AssetReference.Delta, amount); 601 | ActionArgs memory act; 602 | act.actionType = ActionType.Deposit; 603 | act.accountId = 0; 604 | act.amount = amt; 605 | act.primaryMarketId = marketID; 606 | act.otherAddress = address(this); 607 | 608 | ActionArgs[] memory args = new ActionArgs[](1); 609 | args[0] = act; 610 | 611 | DyDx(DYDX).operate(infos, args); 612 | } 613 | 614 | function withdrawDydx(address _token, uint256 amount) public { 615 | uint256 marketID = dydx[_token]; 616 | 617 | Info[] memory infos = new Info[](1); 618 | infos[0] = Info(address(this), 0); 619 | 620 | AssetAmount memory amt = AssetAmount(true, AssetDenomination.Wei, AssetReference.Delta, amount); 621 | ActionArgs memory act; 622 | act.actionType = ActionType.Withdraw; 623 | act.accountId = 0; 624 | act.amount = amt; 625 | act.primaryMarketId = marketID; 626 | act.otherAddress = address(this); 627 | 628 | ActionArgs[] memory args = new ActionArgs[](1); 629 | args[0] = act; 630 | 631 | DyDx(DYDX).operate(infos, args); 632 | } 633 | 634 | function balance(address _token) public view returns (uint256) { 635 | return IERC20(_token).balanceOf(address(this)); 636 | } 637 | 638 | function approveToken(address _token) public { 639 | IERC20(_token).approve(compound[_token], uint(-1)); //also add to constructor 640 | IERC20(_token).approve(DYDX, uint(-1)); 641 | IERC20(_token).approve(AAVE, uint(-1)); 642 | IERC20(_token).approve(fulcrum[_token], uint(-1)); 643 | } 644 | 645 | /*function transferAll(address _token) public { 646 | uint256 amount = balanceCompoundAddress(_token, msg.sender); 647 | if (amount > 0) { 648 | transferCompound(_token, amount); 649 | } 650 | amount = balanceDydxAddress(_token, msg.sender); 651 | if (amount > 0) { 652 | transferDydx(_token, amount); 653 | } 654 | amount = balanceFulcrumAddress(_token, msg.sender); 655 | if (amount > 0) { 656 | transferFulcrum(_token, amount); 657 | } 658 | amount = balanceAaveAddress(_token, msg.sender); 659 | if (amount > 0) { 660 | transferAave(_token, amount); 661 | } 662 | }*/ 663 | 664 | function withdrawAll(address _token) public { 665 | uint256 amount = balanceCompound(_token); 666 | if (amount > 0) { 667 | withdrawCompound(_token, amount); 668 | } 669 | amount = balanceDydx(_token); 670 | if (amount > 0) { 671 | withdrawDydx(_token, amount); 672 | } 673 | amount = balanceFulcrum(_token); 674 | if (amount > 0) { 675 | withdrawFulcrum(_token, amount); 676 | } 677 | amount = balanceAave(_token); 678 | if (amount > 0) { 679 | withdrawAave(_token, amount); 680 | } 681 | } 682 | 683 | function rebalance(address _token) public { 684 | CurrentLender newLender = recommend(_token); 685 | 686 | withdrawAll(_token); 687 | 688 | if (balance(_token) > 0) { 689 | if (newLender == CurrentLender.DYDX) { 690 | supplyDydx(_token, balance(_token)); 691 | } 692 | if (newLender == CurrentLender.FULCRUM) { 693 | supplyFulcrum(_token, balance(_token)); 694 | } 695 | if (newLender == CurrentLender.COMPOUND) { 696 | supplyCompound(_token, balance(_token)); 697 | } 698 | if (newLender == CurrentLender.AAVE) { 699 | supplyAave(_token, balance(_token)); 700 | } 701 | } 702 | } 703 | 704 | function supplyAave(address _token, uint amount) public { 705 | Aave(AAVE).deposit(_token, amount, 0); 706 | } 707 | function supplyFulcrum(address _token, uint amount) public { 708 | require(Fulcrum(fulcrum[_token]).mint(address(this), amount) > 0, "FULCRUM: supply failed"); 709 | } 710 | function supplyCompound(address _token, uint amount) public { 711 | require(Compound(compound[_token]).mint(amount) == 0, "COMPOUND: supply failed"); 712 | } 713 | 714 | function withdrawAave(address _token, uint amount) public { 715 | AToken(aave[_token]).redeem(amount); 716 | } 717 | function withdrawFulcrum(address _token, uint amount) public { 718 | require(Fulcrum(fulcrum[_token]).burn(address(this), amount) > 0, "FULCRUM: withdraw failed"); 719 | } 720 | function withdrawCompound(address _token, uint amount) public { 721 | require(Compound(compound[_token]).redeem(amount) == 0, "COMPOUND: withdraw failed"); 722 | } 723 | 724 | function addCToken( 725 | address token, 726 | address cToken 727 | ) public onlyOwner { 728 | compound[token] = cToken; 729 | } 730 | 731 | function addIToken( 732 | address token, 733 | address iToken 734 | ) public onlyOwner { 735 | fulcrum[token] = iToken; 736 | } 737 | 738 | function addAToken( 739 | address token, 740 | address aToken 741 | ) public onlyOwner { 742 | aave[token] = aToken; 743 | } 744 | 745 | function addDToken( 746 | address token, 747 | uint256 dToken 748 | ) public onlyOwner { 749 | dydx[token] = dToken; 750 | } 751 | 752 | 753 | function set_new_AAVE(address _new_AAVE) public onlyOwner { 754 | AAVE = _new_AAVE; 755 | } 756 | function set_new_DYDX(address _new_DYDX) public onlyOwner { 757 | DYDX = _new_DYDX; 758 | } 759 | 760 | // incase of half-way error 761 | function inCaseTokenGetsStuck(IERC20 _TokenAddress) onlyOwner public { 762 | uint qty = _TokenAddress.balanceOf(address(this)); 763 | _TokenAddress.transfer(msg.sender, qty); 764 | } 765 | // incase of half-way error 766 | function inCaseETHGetsStuck() onlyOwner public{ 767 | (bool result, ) = msg.sender.call.value(address(this).balance)(""); 768 | require(result, "transfer of ETH failed"); 769 | } 770 | 771 | } 772 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.7.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/UniSwap_ETH_cDAI.sol: -------------------------------------------------------------------------------- 1 | 2 | // File: @openzeppelin\upgrades\contracts\Initializable.sol 3 | 4 | pragma solidity >=0.4.24 <0.6.0; 5 | 6 | 7 | /** 8 | * @title Initializable 9 | * 10 | * @dev Helper contract to support initializer functions. To use it, replace 11 | * the constructor with a function that has the `initializer` modifier. 12 | * WARNING: Unlike constructors, initializer functions must be manually 13 | * invoked. This applies both to deploying an Initializable contract, as well 14 | * as extending an Initializable contract via inheritance. 15 | * WARNING: When used with inheritance, manual care must be taken to not invoke 16 | * a parent initializer twice, or ensure that all initializers are idempotent, 17 | * because this is not dealt with automatically as with constructors. 18 | */ 19 | contract Initializable { 20 | 21 | /** 22 | * @dev Indicates that the contract has been initialized. 23 | */ 24 | bool private initialized; 25 | 26 | /** 27 | * @dev Indicates that the contract is in the process of being initialized. 28 | */ 29 | bool private initializing; 30 | 31 | /** 32 | * @dev Modifier to use in the initializer function of a contract. 33 | */ 34 | modifier initializer() { 35 | require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); 36 | 37 | bool isTopLevelCall = !initializing; 38 | if (isTopLevelCall) { 39 | initializing = true; 40 | initialized = true; 41 | } 42 | 43 | _; 44 | 45 | if (isTopLevelCall) { 46 | initializing = false; 47 | } 48 | } 49 | 50 | /// @dev Returns true if and only if the function is running in the constructor 51 | function isConstructor() private view returns (bool) { 52 | // extcodesize checks the size of the code stored in an address, and 53 | // address returns the current address. Since the code is still not 54 | // deployed when running a constructor, any checks on its code size will 55 | // yield zero, making it an effective way to detect if a contract is 56 | // under construction or not. 57 | uint256 cs; 58 | assembly { cs := extcodesize(address) } 59 | return cs == 0; 60 | } 61 | 62 | // Reserved storage space to allow for layout changes in the future. 63 | uint256[50] private ______gap; 64 | } 65 | 66 | // File: @openzeppelin\contracts-ethereum-package\contracts\math\SafeMath.sol 67 | 68 | pragma solidity ^0.5.0; 69 | 70 | /** 71 | * @dev Wrappers over Solidity's arithmetic operations with added overflow 72 | * checks. 73 | * 74 | * Arithmetic operations in Solidity wrap on overflow. This can easily result 75 | * in bugs, because programmers usually assume that an overflow raises an 76 | * error, which is the standard behavior in high level programming languages. 77 | * `SafeMath` restores this intuition by reverting the transaction when an 78 | * operation overflows. 79 | * 80 | * Using this library instead of the unchecked operations eliminates an entire 81 | * class of bugs, so it's recommended to use it always. 82 | */ 83 | library SafeMath { 84 | /** 85 | * @dev Returns the addition of two unsigned integers, reverting on 86 | * overflow. 87 | * 88 | * Counterpart to Solidity's `+` operator. 89 | * 90 | * Requirements: 91 | * - Addition cannot overflow. 92 | */ 93 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 94 | uint256 c = a + b; 95 | require(c >= a, "SafeMath: addition overflow"); 96 | 97 | return c; 98 | } 99 | 100 | /** 101 | * @dev Returns the subtraction of two unsigned integers, reverting on 102 | * overflow (when the result is negative). 103 | * 104 | * Counterpart to Solidity's `-` operator. 105 | * 106 | * Requirements: 107 | * - Subtraction cannot overflow. 108 | */ 109 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 110 | return sub(a, b, "SafeMath: subtraction overflow"); 111 | } 112 | 113 | /** 114 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 115 | * overflow (when the result is negative). 116 | * 117 | * Counterpart to Solidity's `-` operator. 118 | * 119 | * Requirements: 120 | * - Subtraction cannot overflow. 121 | * 122 | * _Available since v2.4.0._ 123 | */ 124 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 125 | require(b <= a, errorMessage); 126 | uint256 c = a - b; 127 | 128 | return c; 129 | } 130 | 131 | /** 132 | * @dev Returns the multiplication of two unsigned integers, reverting on 133 | * overflow. 134 | * 135 | * Counterpart to Solidity's `*` operator. 136 | * 137 | * Requirements: 138 | * - Multiplication cannot overflow. 139 | */ 140 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 141 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 142 | // benefit is lost if 'b' is also tested. 143 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 144 | if (a == 0) { 145 | return 0; 146 | } 147 | 148 | uint256 c = a * b; 149 | require(c / a == b, "SafeMath: multiplication overflow"); 150 | 151 | return c; 152 | } 153 | 154 | /** 155 | * @dev Returns the integer division of two unsigned integers. Reverts on 156 | * division by zero. The result is rounded towards zero. 157 | * 158 | * Counterpart to Solidity's `/` operator. Note: this function uses a 159 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 160 | * uses an invalid opcode to revert (consuming all remaining gas). 161 | * 162 | * Requirements: 163 | * - The divisor cannot be zero. 164 | */ 165 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 166 | return div(a, b, "SafeMath: division by zero"); 167 | } 168 | 169 | /** 170 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 171 | * division by zero. The result is rounded towards zero. 172 | * 173 | * Counterpart to Solidity's `/` operator. Note: this function uses a 174 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 175 | * uses an invalid opcode to revert (consuming all remaining gas). 176 | * 177 | * Requirements: 178 | * - The divisor cannot be zero. 179 | * 180 | * _Available since v2.4.0._ 181 | */ 182 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 183 | // Solidity only automatically asserts when dividing by 0 184 | require(b > 0, errorMessage); 185 | uint256 c = a / b; 186 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 187 | 188 | return c; 189 | } 190 | 191 | /** 192 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 193 | * Reverts when dividing by zero. 194 | * 195 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 196 | * opcode (which leaves remaining gas untouched) while Solidity uses an 197 | * invalid opcode to revert (consuming all remaining gas). 198 | * 199 | * Requirements: 200 | * - The divisor cannot be zero. 201 | */ 202 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 203 | return mod(a, b, "SafeMath: modulo by zero"); 204 | } 205 | 206 | /** 207 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 208 | * Reverts with custom message when dividing by zero. 209 | * 210 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 211 | * opcode (which leaves remaining gas untouched) while Solidity uses an 212 | * invalid opcode to revert (consuming all remaining gas). 213 | * 214 | * Requirements: 215 | * - The divisor cannot be zero. 216 | * 217 | * _Available since v2.4.0._ 218 | */ 219 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 220 | require(b != 0, errorMessage); 221 | return a % b; 222 | } 223 | } 224 | 225 | // File: @openzeppelin\contracts-ethereum-package\contracts\token\ERC20\IERC20.sol 226 | 227 | pragma solidity ^0.5.0; 228 | 229 | /** 230 | * @dev Interface of the ERC20 standard as defined in the EIP. Does not include 231 | * the optional functions; to access them see {ERC20Detailed}. 232 | */ 233 | interface IERC20 { 234 | /** 235 | * @dev Returns the amount of tokens in existence. 236 | */ 237 | function totalSupply() external view returns (uint256); 238 | 239 | /** 240 | * @dev Returns the amount of tokens owned by `account`. 241 | */ 242 | function balanceOf(address account) external view returns (uint256); 243 | 244 | /** 245 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 246 | * 247 | * Returns a boolean value indicating whether the operation succeeded. 248 | * 249 | * Emits a {Transfer} event. 250 | */ 251 | function transfer(address recipient, uint256 amount) external returns (bool); 252 | 253 | /** 254 | * @dev Returns the remaining number of tokens that `spender` will be 255 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 256 | * zero by default. 257 | * 258 | * This value changes when {approve} or {transferFrom} are called. 259 | */ 260 | function allowance(address owner, address spender) external view returns (uint256); 261 | 262 | /** 263 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 264 | * 265 | * Returns a boolean value indicating whether the operation succeeded. 266 | * 267 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 268 | * that someone may use both the old and the new allowance by unfortunate 269 | * transaction ordering. One possible solution to mitigate this race 270 | * condition is to first reduce the spender's allowance to 0 and set the 271 | * desired value afterwards: 272 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 273 | * 274 | * Emits an {Approval} event. 275 | */ 276 | function approve(address spender, uint256 amount) external returns (bool); 277 | 278 | /** 279 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 280 | * allowance mechanism. `amount` is then deducted from the caller's 281 | * allowance. 282 | * 283 | * Returns a boolean value indicating whether the operation succeeded. 284 | * 285 | * Emits a {Transfer} event. 286 | */ 287 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 288 | 289 | /** 290 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 291 | * another (`to`). 292 | * 293 | * Note that `value` may be zero. 294 | */ 295 | event Transfer(address indexed from, address indexed to, uint256 value); 296 | 297 | /** 298 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 299 | * a call to {approve}. `value` is the new allowance. 300 | */ 301 | event Approval(address indexed owner, address indexed spender, uint256 value); 302 | } 303 | 304 | // File: contracts\UniSwap_ETH_cDAI.sol 305 | 306 | // Copyright (C) 2019, 2020 dipeshsukhani, nodarjonashi, toshsharma, suhailg 307 | 308 | // This program is free software: you can redistribute it and/or modify 309 | // it under the terms of the GNU Affero General Public License as published by 310 | // the Free Software Foundation, either version 2 of the License, or 311 | // (at your option) any later version. 312 | // 313 | // This program is distributed in the hope that it will be useful, 314 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 315 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 316 | // GNU Affero General Public License for more details. 317 | // 318 | // Visit for a copy of the GNU Affero General Public License 319 | 320 | /** 321 | * WARNING: This is an upgradable contract. Be careful not to disrupt 322 | * the existing storage layout when making upgrades to the contract. In particular, 323 | * existing fields should not be removed and should not have their types changed. 324 | * The order of field declarations must not be changed, and new fields must be added 325 | * below all existing declarations. 326 | * 327 | * The base contracts and the order in which they are declared must not be changed. 328 | * New fields must not be added to base contracts (unless the base contract has 329 | * reserved placeholder fields for this purpose). 330 | * 331 | * See https://docs.zeppelinos.org/docs/writing_contracts.html for more info. 332 | */ 333 | 334 | pragma solidity ^0.5.0; 335 | 336 | ///@author DeFiZap 337 | ///@notice this contract implements one click conversion from ETH to unipool liquidity tokens (cDAI) 338 | 339 | interface IuniswapFactory { 340 | function getExchange(address token) external view returns (address exchange); 341 | } 342 | 343 | interface IuniswapExchange { 344 | // Address of ERC20 token sold on this exchange 345 | function tokenAddress() external view returns (address token); 346 | // Address of Uniswap Factory 347 | function factoryAddress() external view returns (address factory); 348 | // Provide Liquidity 349 | function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline) external payable returns (uint256); 350 | function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) external returns (uint256, uint256); 351 | // Get Prices 352 | function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought); 353 | function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold); 354 | function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought); 355 | function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold); 356 | // Trade ETH to ERC20 357 | function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) external payable returns (uint256 tokens_bought); 358 | function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns (uint256 tokens_bought); 359 | function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) external payable returns (uint256 eth_sold); 360 | function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256 eth_sold); 361 | // Trade ERC20 to ETH 362 | function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) external returns (uint256 eth_bought); 363 | function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address recipient) external returns (uint256 eth_bought); 364 | function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) external returns (uint256 tokens_sold); 365 | function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256 tokens_sold); 366 | // Trade ERC20 to ERC20 367 | function tokenToTokenSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address token_addr) external returns (uint256 tokens_bought); 368 | function tokenToTokenTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_bought); 369 | function tokenToTokenSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address token_addr) external returns (uint256 tokens_sold); 370 | function tokenToTokenTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_sold); 371 | // Trade ERC20 to Custom Pool 372 | function tokenToExchangeSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address exchange_addr) external returns (uint256 tokens_bought); 373 | function tokenToExchangeTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_bought); 374 | function tokenToExchangeSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address exchange_addr) external returns (uint256 tokens_sold); 375 | function tokenToExchangeTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_sold); 376 | 377 | function transfer(address _to, uint256 _value) external returns (bool); 378 | function transferFrom(address _from, address _to, uint256 value) external returns (bool); 379 | function approve(address _spender, uint256 _value) external returns (bool); 380 | function allowance(address _owner, address _spender) external view returns (uint256); 381 | function balanceOf(address _owner) external view returns (uint256); 382 | function totalSupply() external view returns (uint256); 383 | } 384 | 385 | interface Compound { 386 | function approve ( address spender, uint256 amount ) external returns ( bool ); 387 | function mint ( uint256 mintAmount ) external returns ( uint256 ); 388 | function balanceOf(address _owner) external view returns (uint256 balance); 389 | function transfer(address _to, uint _value) external returns (bool success); 390 | } 391 | 392 | interface IOneSplitInterface { 393 | 394 | function getExpectedReturn( 395 | address fromToken, 396 | address toToken, 397 | uint256 amount, 398 | uint256 parts, 399 | uint256 disableFlags // 1 - Uniswap, 2 - Kyber, 4 - Bancor, 8 - Oasis, 16 - Compound, 32 - Fulcrum, 64 - Chai, 128 - Aave, 256 - SmartToken 400 | ) 401 | external 402 | view 403 | returns( 404 | uint256 returnAmount, 405 | uint256[] memory distribution // [Uniswap, Kyber, Bancor, Oasis] 406 | ); 407 | 408 | function swap( 409 | address fromToken, 410 | address toToken, 411 | uint256 amount, 412 | uint256 minReturn, 413 | uint256[] calldata distribution, // [Uniswap, Kyber, Bancor, Oasis] 414 | uint256 disableFlags // 16 - Compound, 32 - Fulcrum, 64 - Chai, 128 - Aave, 256 - SmartToken 415 | ) 416 | external 417 | payable; 418 | 419 | function goodSwap( 420 | address fromToken, 421 | address toToken, 422 | uint256 amount, 423 | uint256 minReturn, 424 | uint256 parts, 425 | uint256 disableFlags // 1 - Uniswap, 2 - Kyber, 4 - Bancor, 8 - Oasis, 16 - Compound, 32 - Fulcrum, 64 - Chai, 128 - Aave, 256 - SmartToken 426 | ) 427 | external 428 | payable; 429 | } 430 | 431 | contract UniSwap_ETH_CDAIZap is Initializable { 432 | using SafeMath for uint; 433 | // state variables 434 | 435 | // - THESE MUST ALWAYS STAY IN THE SAME LAYOUT 436 | bool private stopped; 437 | address payable public owner; 438 | IuniswapFactory public UniSwapFactoryAddress; 439 | IOneSplitInterface public OneSplitInterfaceAddress; 440 | IERC20 public NEWDAI_TOKEN_ADDRESS; 441 | Compound public COMPOUND_TOKEN_ADDRESS; 442 | address public DAI_TOKEN_ADDRESS; 443 | address public ETH_TOKEN_ADDRESS; 444 | address public ONESPLIT_ADDRESS; 445 | 446 | 447 | // events 448 | event ERC20TokenHoldingsOnConversionDaiChai(uint); 449 | event ERC20TokenHoldingsOnConversionEthDai(uint); 450 | event LiquidityTokens(uint); 451 | 452 | // circuit breaker modifiers 453 | modifier stopInEmergency {if (!stopped) _;} 454 | modifier onlyInEmergency {if (stopped) _;} 455 | modifier onlyOwner() { 456 | require(isOwner(), "you are not authorised to call this function"); 457 | _; 458 | } 459 | 460 | 461 | function initialize() initializer public { 462 | stopped = false; 463 | owner = msg.sender; 464 | UniSwapFactoryAddress = IuniswapFactory(0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95); 465 | NEWDAI_TOKEN_ADDRESS = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F); 466 | COMPOUND_TOKEN_ADDRESS = Compound(0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643); 467 | OneSplitInterfaceAddress = IOneSplitInterface(0xD010B65120E027419586216D25bF86C2c24FCC4a); 468 | ONESPLIT_ADDRESS = address(0xD010B65120E027419586216D25bF86C2c24FCC4a); 469 | DAI_TOKEN_ADDRESS = address(0x6B175474E89094C44Da98b954EedeAC495271d0F); 470 | ETH_TOKEN_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); 471 | } 472 | 473 | 474 | function set_new_UniSwapFactoryAddress(address _new_UniSwapFactoryAddress) public onlyOwner { 475 | UniSwapFactoryAddress = IuniswapFactory(_new_UniSwapFactoryAddress); 476 | } 477 | 478 | function set_new_DAI_TOKEN_ADDRESS(address _new_DAI_TOKEN_ADDRESS) public onlyOwner { 479 | NEWDAI_TOKEN_ADDRESS = IERC20(_new_DAI_TOKEN_ADDRESS); 480 | DAI_TOKEN_ADDRESS = _new_DAI_TOKEN_ADDRESS; 481 | } 482 | 483 | function set_new_cDAI_TokenContractAddress(address _new_cDAI_TokenContractAddress) public onlyOwner { 484 | COMPOUND_TOKEN_ADDRESS = Compound(_new_cDAI_TokenContractAddress); 485 | } 486 | 487 | function set_OneSplitInterfaceAddress(address _new_OneSplitInterfaceAddress) public onlyOwner { 488 | OneSplitInterfaceAddress = IOneSplitInterface(_new_OneSplitInterfaceAddress); 489 | ONESPLIT_ADDRESS = _new_OneSplitInterfaceAddress; 490 | } 491 | 492 | function getExpectedReturn(uint256 eth) public view returns (uint256) { 493 | uint256 _minReturn = 0; 494 | (_minReturn, ) = OneSplitInterfaceAddress.getExpectedReturn(ETH_TOKEN_ADDRESS, DAI_TOKEN_ADDRESS, eth, 1, 0); 495 | return _minReturn; 496 | } 497 | 498 | function LetsInvest(address _towhomtoissue, uint256 _minReturn) public payable stopInEmergency returns (uint) { 499 | IERC20 ERC20TokenAddress = IERC20(address(COMPOUND_TOKEN_ADDRESS)); 500 | IuniswapExchange UniSwapExchangeContractAddress = IuniswapExchange(UniSwapFactoryAddress.getExchange(address(COMPOUND_TOKEN_ADDRESS))); 501 | 502 | // determining the portion of the incoming ETH to be converted to the ERC20 Token 503 | uint conversionPortion = SafeMath.div(SafeMath.mul(msg.value, 505), 1000); 504 | uint non_conversionPortion = SafeMath.sub(msg.value,conversionPortion); 505 | 506 | if (_minReturn == 0) { 507 | //(_minReturn, ) = OneSplitInterfaceAddress.getExpectedReturn(ETH_TOKEN_ADDRESS, DAI_TOKEN_ADDRESS, conversionPortion, 1, 0); 508 | // Default to 1 for now to save gas costs, run getExpectedReturn first as a call instead 509 | _minReturn = 1; 510 | } 511 | 512 | OneSplitInterfaceAddress.goodSwap.value(conversionPortion)(ETH_TOKEN_ADDRESS, DAI_TOKEN_ADDRESS, conversionPortion, _minReturn, 1, 0); 513 | uint tokenBalance = NEWDAI_TOKEN_ADDRESS.balanceOf(address(this)); 514 | 515 | require(tokenBalance > 0, "the conversion did not happen as planned"); 516 | 517 | // conversion of DAI to cDAI 518 | uint qty2approve = SafeMath.mul(tokenBalance, 3); 519 | require(NEWDAI_TOKEN_ADDRESS.approve(address(ERC20TokenAddress), qty2approve)); 520 | COMPOUND_TOKEN_ADDRESS.mint(tokenBalance); 521 | uint ERC20TokenHoldings = ERC20TokenAddress.balanceOf(address(this)); 522 | require (ERC20TokenHoldings > 0, "the conversion did not happen as planned"); 523 | emit ERC20TokenHoldingsOnConversionDaiChai(ERC20TokenHoldings); 524 | NEWDAI_TOKEN_ADDRESS.approve(address(ERC20TokenAddress), 0); 525 | ERC20TokenAddress.approve(address(UniSwapExchangeContractAddress),ERC20TokenHoldings); 526 | 527 | // adding Liquidity 528 | uint max_tokens_ans = getMaxTokens(address(UniSwapExchangeContractAddress), ERC20TokenAddress, non_conversionPortion); 529 | UniSwapExchangeContractAddress.addLiquidity.value(non_conversionPortion)(1,max_tokens_ans,SafeMath.add(now,1800)); 530 | ERC20TokenAddress.approve(address(UniSwapExchangeContractAddress),0); 531 | 532 | // transferring Liquidity 533 | uint LiquityTokenHoldings = UniSwapExchangeContractAddress.balanceOf(address(this)); 534 | emit LiquidityTokens(LiquityTokenHoldings); 535 | UniSwapExchangeContractAddress.transfer(_towhomtoissue, LiquityTokenHoldings); 536 | ERC20TokenHoldings = ERC20TokenAddress.balanceOf(address(this)); 537 | ERC20TokenAddress.transfer(_towhomtoissue, ERC20TokenHoldings); 538 | return LiquityTokenHoldings; 539 | } 540 | 541 | function getUniswapExchangeContractAddress() public view returns (address) { 542 | return address(IuniswapExchange(UniSwapFactoryAddress.getExchange(address(COMPOUND_TOKEN_ADDRESS)))); 543 | } 544 | 545 | function Redeem(address payable _towhomtosend, uint256 _amount) public stopInEmergency returns (uint) { 546 | // Compound contract address 547 | IERC20 ERC20TokenAddress = IERC20(address(COMPOUND_TOKEN_ADDRESS)); 548 | 549 | // Compound uniswap exchange 550 | IuniswapExchange UniSwapExchangeContractAddress = IuniswapExchange(UniSwapFactoryAddress.getExchange(address(COMPOUND_TOKEN_ADDRESS))); 551 | 552 | uint256 balance = UniSwapExchangeContractAddress.balanceOf(msg.sender); 553 | require(balance >= _amount, "insufficient balance"); 554 | uint256 allowance = UniSwapExchangeContractAddress.allowance(msg.sender, address(this)); 555 | require(allowance >= _amount, "insufficient allowance"); 556 | 557 | // Send users uni-v1 to contract address (will fail if not approved) 558 | uint mybalance = UniSwapExchangeContractAddress.balanceOf(address(this)); 559 | bool result = UniSwapExchangeContractAddress.transferFrom(msg.sender, address(this), _amount); 560 | uint newbalance = UniSwapExchangeContractAddress.balanceOf(address(this)); 561 | require(result, "transfer of uni failed"); 562 | require(newbalance > mybalance, "insufficient uni balance"); 563 | 564 | // Get min_eth and min_token for removeLiquidity call 565 | //(, uint256 ownerSharesEth, uint256 ownerSharesToken) = getReturn(address(UniSwapExchangeContractAddress), ERC20TokenAddress, _amount); 566 | // Swap uni-v1 for eth and tokens 567 | (uint256 eth, uint256 tokens) = UniSwapExchangeContractAddress.removeLiquidity(_amount, uint(1), uint(1), SafeMath.add(now,1800)); 568 | 569 | // Approve onesplit to take the compound tokens 570 | ERC20TokenAddress.approve(ONESPLIT_ADDRESS, tokens); 571 | // Get the expected return in ETH 572 | (uint256 _minReturn, ) = OneSplitInterfaceAddress.getExpectedReturn(address(COMPOUND_TOKEN_ADDRESS), ETH_TOKEN_ADDRESS, tokens, 1, 0); 573 | // Swap for the expected ETH 574 | OneSplitInterfaceAddress.goodSwap.value(0)(address(COMPOUND_TOKEN_ADDRESS), ETH_TOKEN_ADDRESS, tokens, _minReturn, 1, 0); 575 | 576 | 577 | ERC20TokenAddress.approve(ONESPLIT_ADDRESS, 0); 578 | 579 | uint256 ethReturn = SafeMath.add(eth, _minReturn); 580 | 581 | (result, ) = _towhomtosend.call.value(ethReturn)(""); 582 | require(result, "transfer of ETH failed"); 583 | return ethReturn; 584 | } 585 | 586 | function getMaxTokens(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _value) public view returns (uint) { 587 | uint contractBalance = _UniSwapExchangeContractAddress.balance; 588 | uint eth_reserve = SafeMath.sub(contractBalance, _value); 589 | uint token_reserve = _ERC20TokenAddress.balanceOf(_UniSwapExchangeContractAddress); 590 | uint token_amount = SafeMath.div(SafeMath.mul(_value,token_reserve),eth_reserve) + 1; 591 | return token_amount; 592 | } 593 | 594 | function getEthBalance(address _UniSwapExchangeContractAddress) public view returns (uint) { 595 | uint ethBalance = _UniSwapExchangeContractAddress.balance; 596 | return ethBalance; 597 | } 598 | 599 | function getTokenReserves(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress) public view returns (uint) { 600 | uint token_reserve = _ERC20TokenAddress.balanceOf(_UniSwapExchangeContractAddress); 601 | return token_reserve; 602 | } 603 | 604 | 605 | function getTotalShares(address _UniSwapExchangeContractAddress) public view returns (uint) { 606 | uint totalShares = IuniswapExchange(_UniSwapExchangeContractAddress).totalSupply(); 607 | return totalShares; 608 | } 609 | 610 | function getReturn(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _value) public view returns (uint, uint, uint) { 611 | // Token balance in uniswap contract 612 | uint token_reserve = _ERC20TokenAddress.balanceOf(_UniSwapExchangeContractAddress); 613 | // ETH balance in uniswap contract 614 | uint ethBalance = _UniSwapExchangeContractAddress.balance; 615 | 616 | // Get total pool shares 617 | uint totalShares = IuniswapExchange(_UniSwapExchangeContractAddress).totalSupply(); 618 | 619 | // Calculate owner share pool 620 | uint ownerSharesEth = SafeMath.div(SafeMath.mul(_value, ethBalance), totalShares); 621 | uint ownerSharesToken = SafeMath.div(SafeMath.mul(_value, token_reserve), totalShares); 622 | 623 | // Calculate eth value 624 | uint ethBought = IuniswapExchange(_UniSwapExchangeContractAddress).getTokenToEthInputPrice(ownerSharesToken); 625 | uint ethValue = SafeMath.add(ethBought, ownerSharesEth); 626 | 627 | return (ethValue, ownerSharesEth, ownerSharesToken); 628 | } 629 | 630 | function calcReturnETHFromShares(uint _value) public view returns (uint, uint, uint) { 631 | IuniswapExchange UniSwapExchangeContractAddress = IuniswapExchange(UniSwapFactoryAddress.getExchange(address(COMPOUND_TOKEN_ADDRESS))); 632 | IERC20 ERC20TokenAddress = IERC20(address(COMPOUND_TOKEN_ADDRESS)); 633 | 634 | return getReturn(address(UniSwapExchangeContractAddress), ERC20TokenAddress, _value); 635 | } 636 | 637 | function uniBalanceOf(address _owner) public view returns (uint) { 638 | IuniswapExchange UniSwapExchangeContractAddress = IuniswapExchange(UniSwapFactoryAddress.getExchange(address(COMPOUND_TOKEN_ADDRESS))); 639 | return UniSwapExchangeContractAddress.balanceOf(_owner); 640 | } 641 | 642 | function cBalanceOf(address _owner) public view returns (uint) { 643 | IERC20 ERC20TokenAddress = IERC20(address(COMPOUND_TOKEN_ADDRESS)); 644 | return ERC20TokenAddress.balanceOf(_owner); 645 | } 646 | 647 | 648 | function calcReturnSharesFromETH(uint _value) public view returns (uint) { 649 | IuniswapExchange UniSwapExchangeContractAddress = IuniswapExchange(UniSwapFactoryAddress.getExchange(address(COMPOUND_TOKEN_ADDRESS))); 650 | IERC20 ERC20TokenAddress = IERC20(address(COMPOUND_TOKEN_ADDRESS)); 651 | 652 | return getSharesReturn(address(UniSwapExchangeContractAddress), ERC20TokenAddress, _value); 653 | } 654 | 655 | function getTokenToEthOutputPrice(uint _tokens) public view returns (uint) { 656 | IuniswapExchange UniSwapExchangeContractAddress = IuniswapExchange(UniSwapFactoryAddress.getExchange(address(COMPOUND_TOKEN_ADDRESS))); 657 | return UniSwapExchangeContractAddress.getTokenToEthInputPrice(_tokens); 658 | } 659 | 660 | function getSharesReturn(address _UniSwapExchangeContractAddress, IERC20 _ERC20TokenAddress, uint _ethValue) public view returns (uint) { 661 | uint tokens_sold = IuniswapExchange(_UniSwapExchangeContractAddress).getTokenToEthOutputPrice(_ethValue); 662 | 663 | // Token balance in uniswap contract 664 | uint token_reserve = _ERC20TokenAddress.balanceOf(_UniSwapExchangeContractAddress); 665 | // Get total pool shares 666 | uint totalShares = IuniswapExchange(_UniSwapExchangeContractAddress).totalSupply(); 667 | 668 | uint shares = SafeMath.div(SafeMath.mul(tokens_sold, totalShares), token_reserve); 669 | 670 | return (shares); 671 | } 672 | 673 | // incase of half-way error 674 | function inCaseTokengetsStuck(IERC20 _TokenAddress) onlyOwner public { 675 | uint qty = _TokenAddress.balanceOf(address(this)); 676 | _TokenAddress.transfer(owner, qty); 677 | } 678 | 679 | // - fallback function let you / anyone send ETH to this wallet without the need to call any function 680 | function() external payable { 681 | 682 | } 683 | 684 | // - to Pause the contract 685 | function toggleContractActive() onlyOwner public { 686 | stopped = !stopped; 687 | } 688 | // - to withdraw any ETH balance sitting in the contract 689 | function withdraw() onlyOwner public{ 690 | owner.transfer(address(this).balance); 691 | } 692 | // - to kill the contract 693 | function destruct() public onlyOwner { 694 | selfdestruct(owner); 695 | } 696 | /** 697 | * @return true if `msg.sender` is the owner of the contract. 698 | */ 699 | function isOwner() public view returns (bool) { 700 | return msg.sender == owner; 701 | } 702 | 703 | /** 704 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 705 | * Can only be called by the current owner. 706 | */ 707 | function transferOwnership(address payable newOwner) public onlyOwner { 708 | _transferOwnership(newOwner); 709 | } 710 | 711 | /** 712 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 713 | */ 714 | function _transferOwnership(address payable newOwner) internal { 715 | require(newOwner != address(0), "Ownable: new owner is the zero address"); 716 | owner = newOwner; 717 | } 718 | 719 | } 720 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "defizap", 3 | "version": "1.0.0", 4 | "description": "iearn portfolio zaps", 5 | "scripts": { 6 | "lint": "npm run eslint && npm run solium", 7 | "eslint": "eslint test/ migrations/", 8 | "solium": "solium --dir contracts", 9 | "build": "truffle build", 10 | "test": "truffle test", 11 | "truffle": "truffle", 12 | "flatten": "rm -rf contracts/Flattened.sol && truffle-flattener contracts/Staker.sol >> contracts/Flattened.sol" 13 | }, 14 | "dependencies": { 15 | "@openzeppelin/contracts": "^2.3.0" 16 | }, 17 | "devDependencies": { 18 | "@openzeppelin/contracts-ethereum-package": "^2.4.0", 19 | "@openzeppelin/upgrades": "^2.6.0", 20 | "babel-polyfill": "^6.26.0", 21 | "babel-preset-env": "^1.7.0", 22 | "babel-register": "^6.26.0", 23 | "bignumber.js": "^9.0.0", 24 | "chai": "^4.2.0", 25 | "chai-as-promised": "^7.1.1", 26 | "chai-bignumber": "^3.0.0", 27 | "eslint": "^6.2.2", 28 | "eslint-config-airbnb": "^18.0.1", 29 | "eslint-config-airbnb-base": "^14.0.0", 30 | "eslint-plugin-import": "^2.18.2", 31 | "eslint-plugin-jsx-a11y": "^6.2.3", 32 | "eslint-plugin-react": "^7.14.3", 33 | "eslint-plugin-react-hooks": "^1.7.0", 34 | "ethereumjs-testrpc-sc": "^6.5.1-sc.0", 35 | "karma": "^4.3.0", 36 | "lodash": "^4.17.15", 37 | "openzeppelin-test-helpers": "^0.4.3", 38 | "solidity-coverage": "^0.6.4", 39 | "truffle-flattener": "^1.4.0", 40 | "truffle-hdwallet-provider": "^1.0.17", 41 | "web3-utils": "^1.2.1" 42 | }, 43 | "repository": { 44 | "type": "git", 45 | "url": "" 46 | }, 47 | "author": "@andrecronje", 48 | "license": "MIT" 49 | } 50 | -------------------------------------------------------------------------------- /test/Uniswap_ETH_cDAI.js: -------------------------------------------------------------------------------- 1 | const { expect } = require('chai'); 2 | 3 | const Uniswap_ETH_cDAI = artifacts.require('UniSwap_ETH_CDAIZap'); 4 | 5 | contract('Uniswap_ETH_cDAI test', async (accounts) => { 6 | it('checking parameters', async () => { 7 | this.defizap = await Uniswap_ETH_cDAI.new(); 8 | await this.defizap.initialize({ 9 | from: accounts[0], 10 | value: 0, 11 | }); 12 | expect(await this.defizap.NEWDAI_TOKEN_ADDRESS.call()).equal('0x6B175474E89094C44Da98b954EedeAC495271d0F'); 13 | expect(await this.defizap.COMPOUND_TOKEN_ADDRESS.call()).equal('0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643'); 14 | expect(await this.defizap.DAI_TOKEN_ADDRESS.call()).equal('0x6B175474E89094C44Da98b954EedeAC495271d0F'); 15 | expect(await this.defizap.ETH_TOKEN_ADDRESS.call()).equal('0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'); 16 | expect(await this.defizap.isOwner.call()).equal(true); 17 | }); 18 | it('lets invest', async () => { 19 | this.defizap = await Uniswap_ETH_cDAI.new(); 20 | await this.defizap.initialize({ 21 | from: accounts[0], 22 | value: 0, 23 | }); 24 | var something = await this.defizap.send(1); 25 | expect(await this.defizap.send(1)); 26 | }); 27 | 28 | it('get return', async () => { 29 | this.defizap = await Uniswap_ETH_cDAI.new(); 30 | await this.defizap.initialize({ 31 | from: accounts[0], 32 | value: 0, 33 | }); 34 | const res = await this.defizap.getReturn.call('0x6B175474E89094C44Da98b954EedeAC495271d0F','0x6B175474E89094C44Da98b954EedeAC495271d0F',10) 35 | console.log(res); 36 | }); 37 | 38 | it('get max', async () => { 39 | this.defizap = await Uniswap_ETH_cDAI.new(); 40 | await this.defizap.initialize({ 41 | from: accounts[0], 42 | value: 0, 43 | }); 44 | expect(await this.defizap.getMaxTokens.call('0x6B175474E89094C44Da98b954EedeAC495271d0F','0x6B175474E89094C44Da98b954EedeAC495271d0F',10)); 45 | }); 46 | 47 | it('redeem', async () => { 48 | this.defizap = await Uniswap_ETH_cDAI.new(); 49 | await this.defizap.initialize({ 50 | from: accounts[0], 51 | value: 0, 52 | }); 53 | expect(await this.defizap.Redeem(accounts[0],10)); 54 | }); 55 | }); 56 | --------------------------------------------------------------------------------