Compare commits
	
		
			43 Commits
		
	
	
		
			@0x/contra
			...
			feat/PTP
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | d52d882b14 | ||
|  | 4c8629840b | ||
|  | feede28293 | ||
|  | 08cf51b101 | ||
|  | 4ba6918e06 | ||
|  | 52a3ffa77c | ||
|  | afe77a432c | ||
|  | 64c090c4b4 | ||
|  | e24474f152 | ||
|  | 29fa408256 | ||
|  | 1b94cc68af | ||
|  | f5b4bb3035 | ||
|  | afd880f28c | ||
|  | cd14cdd168 | ||
|  | c8ff53a75f | ||
|  | 6d08add20b | ||
|  | 29f9c725e3 | ||
|  | a83453f07f | ||
|  | ae365ce92c | ||
|  | 77a592e891 | ||
|  | 9a1df67d6b | ||
|  | 4b91411faf | ||
|  | 622a542d57 | ||
|  | cba53a9a50 | ||
|  | e186f27f63 | ||
|  | 4cd767ecb8 | ||
|  | f6e85aedf1 | ||
|  | b3ee294ba5 | ||
|  | 1c242def93 | ||
|  | f0fe6f2f69 | ||
|  | f86d555e49 | ||
|  | b0f2c40463 | ||
|  | 87be6fbb8a | ||
|  | 9141a9d2c8 | ||
|  | 7f75de347e | ||
|  | 329f7761c3 | ||
|  | 0d8e83cd75 | ||
|  | e5d60b8077 | ||
|  | ae2fe55efa | ||
|  | 6073607d3e | ||
|  | 389ebb5df8 | ||
|  | fd9655e9d4 | ||
|  | 6480aaa189 | 
| @@ -4,7 +4,7 @@ jobs: | ||||
|     build: | ||||
|         resource_class: xlarge | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         environment: | ||||
|             NODE_OPTIONS: '--max-old-space-size=16384' | ||||
|         working_directory: ~/repo | ||||
| @@ -31,7 +31,7 @@ jobs: | ||||
|     test-exchange-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -41,7 +41,7 @@ jobs: | ||||
|     test-integrations-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -51,7 +51,7 @@ jobs: | ||||
|     test-contracts-staking-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -61,7 +61,7 @@ jobs: | ||||
|     test-contracts-extra-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -71,7 +71,7 @@ jobs: | ||||
|     test-contracts-rest-ganache: | ||||
|         resource_class: medium+ | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -83,7 +83,7 @@ jobs: | ||||
|         environment: | ||||
|             NODE_OPTIONS: '--max-old-space-size=6442' | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|             - image: 0xorg/verdaccio | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
| @@ -97,7 +97,7 @@ jobs: | ||||
|                   path: ~/.npm/_logs | ||||
|     test-doc-generation: | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -108,7 +108,7 @@ jobs: | ||||
|                   no_output_timeout: 1200 | ||||
|     test-rest: | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
| @@ -136,7 +136,7 @@ jobs: | ||||
|         resource_class: large | ||||
|         working_directory: ~/repo | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|                   keys: | ||||
| @@ -147,7 +147,7 @@ jobs: | ||||
|             - run: yarn diff_md_docs:ci | ||||
|     submit-coverage: | ||||
|         docker: | ||||
|             - image: node:12 | ||||
|             - image: node:16 | ||||
|         working_directory: ~/repo | ||||
|         steps: | ||||
|             - restore_cache: | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "3.3.27", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1645569128, | ||||
|         "version": "3.3.26", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v3.3.27 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v3.3.26 - _February 22, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-erc20", | ||||
|     "version": "3.3.26", | ||||
|     "version": "3.3.27", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -53,8 +53,8 @@ | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.7.2", | ||||
|         "@0x/contracts-gen": "^2.0.43", | ||||
|         "@0x/contracts-test-utils": "^5.4.17", | ||||
|         "@0x/contracts-utils": "^4.8.7", | ||||
|         "@0x/contracts-test-utils": "^5.4.18", | ||||
|         "@0x/contracts-utils": "^4.8.8", | ||||
|         "@0x/dev-utils": "^4.2.11", | ||||
|         "@0x/sol-compiler": "^4.7.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "5.4.18", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1645569128, | ||||
|         "version": "5.4.17", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v5.4.18 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v5.4.17 - _February 22, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-test-utils", | ||||
|     "version": "5.4.17", | ||||
|     "version": "5.4.18", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -44,7 +44,7 @@ | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.31", | ||||
|         "@0x/base-contract": "^6.4.5", | ||||
|         "@0x/contract-addresses": "^6.11.0", | ||||
|         "@0x/contract-addresses": "^6.12.0", | ||||
|         "@0x/dev-utils": "^4.2.11", | ||||
|         "@0x/json-schemas": "^6.4.1", | ||||
|         "@0x/order-utils": "^10.4.28", | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "1.4.10", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1645569128, | ||||
|         "version": "1.4.9", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.4.10 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.4.9 - _February 22, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-treasury", | ||||
|     "version": "1.4.9", | ||||
|     "version": "1.4.10", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -47,12 +47,12 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.7.2", | ||||
|         "@0x/contract-addresses": "^6.11.0", | ||||
|         "@0x/contract-addresses": "^6.12.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.19", | ||||
|         "@0x/contracts-erc20": "^3.3.26", | ||||
|         "@0x/contracts-erc20": "^3.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.43", | ||||
|         "@0x/contracts-staking": "^2.0.45", | ||||
|         "@0x/contracts-test-utils": "^5.4.17", | ||||
|         "@0x/contracts-test-utils": "^5.4.18", | ||||
|         "@0x/sol-compiler": "^4.7.8", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
|         "@0x/tslint-config": "^4.1.4", | ||||
| @@ -73,7 +73,7 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.5", | ||||
|         "@0x/protocol-utils": "^1.11.0", | ||||
|         "@0x/protocol-utils": "^1.11.1", | ||||
|         "@0x/subproviders": "^6.6.2", | ||||
|         "@0x/types": "^3.3.4", | ||||
|         "@0x/typescript-typings": "^5.2.1", | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "4.8.8", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1645569128, | ||||
|         "version": "4.8.7", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v4.8.8 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v4.8.7 - _February 22, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-utils", | ||||
|     "version": "4.8.7", | ||||
|     "version": "4.8.8", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -52,7 +52,7 @@ | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.7.2", | ||||
|         "@0x/contracts-gen": "^2.0.43", | ||||
|         "@0x/contracts-test-utils": "^5.4.17", | ||||
|         "@0x/contracts-test-utils": "^5.4.18", | ||||
|         "@0x/dev-utils": "^4.2.11", | ||||
|         "@0x/order-utils": "^10.4.28", | ||||
|         "@0x/sol-compiler": "^4.7.8", | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "0.31.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "0.31.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v0.31.1 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v0.31.0 - _February 22, 2022_ | ||||
|  | ||||
|     * Add ERC721OrdersFeature, ERC1155OrdersFeature, and ERC165Feature (#429) | ||||
|   | ||||
| @@ -33,6 +33,7 @@ import "./mixins/MixinCurveV2.sol"; | ||||
| import "./mixins/MixinCryptoCom.sol"; | ||||
| import "./mixins/MixinDodo.sol"; | ||||
| import "./mixins/MixinDodoV2.sol"; | ||||
| import "./mixins/MixinGMX.sol"; | ||||
| import "./mixins/MixinKyber.sol"; | ||||
| import "./mixins/MixinKyberDmm.sol"; | ||||
| import "./mixins/MixinLido.sol"; | ||||
| @@ -60,6 +61,7 @@ contract BridgeAdapter is | ||||
|     MixinCryptoCom, | ||||
|     MixinDodo, | ||||
|     MixinDodoV2, | ||||
|     MixinGMX, | ||||
|     MixinKyber, | ||||
|     MixinKyberDmm, | ||||
|     MixinLido, | ||||
| @@ -87,6 +89,7 @@ contract BridgeAdapter is | ||||
|         MixinCryptoCom() | ||||
|         MixinDodo() | ||||
|         MixinDodoV2() | ||||
|         MixinGMX() | ||||
|         MixinKyber(weth) | ||||
|         MixinLido(weth) | ||||
|         MixinMakerPSM() | ||||
| @@ -265,6 +268,12 @@ contract BridgeAdapter is | ||||
|                 sellAmount, | ||||
|                 order.bridgeData | ||||
|             ); | ||||
|         } else if (protocolId == BridgeProtocols.GMX) { | ||||
|             boughtAmount = _tradeGMX( | ||||
|                 buyToken, | ||||
|                 sellAmount, | ||||
|                 order.bridgeData | ||||
|             ); | ||||
|         } else { | ||||
|             boughtAmount = _tradeZeroExBridge( | ||||
|                 sellToken, | ||||
|   | ||||
| @@ -52,4 +52,5 @@ library BridgeProtocols { | ||||
|     uint128 internal constant CLIPPER     = 22; // Not used: Clipper is now using PLP interface | ||||
|     uint128 internal constant AAVEV2      = 23; | ||||
|     uint128 internal constant COMPOUND    = 24; | ||||
|     uint128 internal constant GMX         = 25; | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,104 @@ | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
|  | ||||
| /* | ||||
|  | ||||
|   Copyright 2020 ZeroEx Intl. | ||||
|  | ||||
|   Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|   you may not use this file except in compliance with the License. | ||||
|   You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
|   Unless required by applicable law or agreed to in writing, software | ||||
|   distributed under the License is distributed on an "AS IS" BASIS, | ||||
|   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|   See the License for the specific language governing permissions and | ||||
|   limitations under the License. | ||||
|  | ||||
| */ | ||||
|  | ||||
| pragma solidity ^0.6.5; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol"; | ||||
| import "../IBridgeAdapter.sol"; | ||||
|  | ||||
| /* | ||||
|     UniswapV2 | ||||
| */ | ||||
| interface IGmxRouter { | ||||
|  | ||||
|     // /// @dev Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path. | ||||
|     // ///      The first element of path is the input token, the last is the output token, and any intermediate elements represent | ||||
|     // ///      intermediate pairs to trade through (if, for example, a direct pair does not exist). | ||||
|     // /// @param _path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. | ||||
|     // /// @param _amountIn The amount of input tokens to send. | ||||
|     // /// @param _minOut The minimum amount of output tokens that must be received for the transaction not to revert. | ||||
|     // /// @param _reciever Recipient of the output tokens. | ||||
|     function swap( | ||||
|        address[] calldata _path, uint256 _amountIn, uint256 _minOut, address _receiver | ||||
|     ) external; | ||||
| } | ||||
|  | ||||
| contract MixinGMX { | ||||
|  | ||||
|     using LibERC20TokenV06 for IERC20TokenV06; | ||||
|     using LibSafeMathV06 for uint256; | ||||
|  | ||||
|     function _tradeGMX( | ||||
|         IERC20TokenV06 buyToken, | ||||
|         uint256 sellAmount, | ||||
|         bytes memory bridgeData | ||||
|     ) | ||||
|         public | ||||
|         returns (uint256 boughtAmount) | ||||
|     { | ||||
|         address _router; | ||||
|         address reader; | ||||
|         address vault; | ||||
|         address[] memory _path; | ||||
|         IGmxRouter router; | ||||
|         IERC20TokenV06[] memory path; | ||||
|          | ||||
|         { | ||||
|             //decode the bridge data | ||||
|             (_router, reader, vault, _path) = abi.decode(bridgeData, (address, address, address, address[])); | ||||
|             // To get around `abi.decode()` not supporting interface array types. | ||||
|             assembly { path := _path } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         require(path.length >= 2, "MixinGMX/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||||
|         require( | ||||
|             path[path.length - 1] == buyToken, | ||||
|             "MixinGMX/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN" | ||||
|         ); | ||||
|  | ||||
|         //connect to the GMX router | ||||
|         router = IGmxRouter(_router); | ||||
|  | ||||
|         // Grant the GMX router an allowance to sell the first token. | ||||
|         path[0].approveIfBelow(address(router), sellAmount); | ||||
|  | ||||
|         //track the balance to know how much we bought | ||||
|         uint256 beforeBalance = buyToken.balanceOf(address(this)); | ||||
|         router.swap( | ||||
|             // Convert to `buyToken` along this path. | ||||
|             _path, | ||||
|              // Sell all tokens we hold. | ||||
|             sellAmount, | ||||
|              // Minimum buy amount. | ||||
|             0, | ||||
|             // Recipient is `this`. | ||||
|             address(this) | ||||
|         ); | ||||
|  | ||||
|         //calculate the difference in balance from preswap->postswap to find how many tokens out | ||||
|         boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance); | ||||
|  | ||||
|         return boughtAmount; | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contracts-zero-ex", | ||||
|     "version": "0.31.0", | ||||
|     "version": "0.31.1", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -43,7 +43,7 @@ | ||||
|     "config": { | ||||
|         "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature", | ||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", | ||||
|         "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json" | ||||
|         "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json" | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
| @@ -56,10 +56,10 @@ | ||||
|     "homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex", | ||||
|     "devDependencies": { | ||||
|         "@0x/abi-gen": "^5.7.2", | ||||
|         "@0x/contract-addresses": "^6.11.0", | ||||
|         "@0x/contracts-erc20": "^3.3.26", | ||||
|         "@0x/contract-addresses": "^6.12.0", | ||||
|         "@0x/contracts-erc20": "^3.3.27", | ||||
|         "@0x/contracts-gen": "^2.0.43", | ||||
|         "@0x/contracts-test-utils": "^5.4.17", | ||||
|         "@0x/contracts-test-utils": "^5.4.18", | ||||
|         "@0x/dev-utils": "^4.2.11", | ||||
|         "@0x/order-utils": "^10.4.28", | ||||
|         "@0x/sol-compiler": "^4.7.8", | ||||
| @@ -83,7 +83,7 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.5", | ||||
|         "@0x/protocol-utils": "^1.11.0", | ||||
|         "@0x/protocol-utils": "^1.11.1", | ||||
|         "@0x/subproviders": "^6.6.2", | ||||
|         "@0x/types": "^3.3.4", | ||||
|         "@0x/typescript-typings": "^5.2.1", | ||||
|   | ||||
| @@ -109,6 +109,7 @@ import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json'; | ||||
| import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json'; | ||||
| import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json'; | ||||
| import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json'; | ||||
| import * as MixinGMX from '../test/generated-artifacts/MixinGMX.json'; | ||||
| import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json'; | ||||
| import * as MixinKyberDmm from '../test/generated-artifacts/MixinKyberDmm.json'; | ||||
| import * as MixinLido from '../test/generated-artifacts/MixinLido.json'; | ||||
| @@ -321,6 +322,7 @@ export const artifacts = { | ||||
|     MixinCurveV2: MixinCurveV2 as ContractArtifact, | ||||
|     MixinDodo: MixinDodo as ContractArtifact, | ||||
|     MixinDodoV2: MixinDodoV2 as ContractArtifact, | ||||
|     MixinGMX: MixinGMX as ContractArtifact, | ||||
|     MixinKyber: MixinKyber as ContractArtifact, | ||||
|     MixinKyberDmm: MixinKyberDmm as ContractArtifact, | ||||
|     MixinLido: MixinLido as ContractArtifact, | ||||
|   | ||||
| @@ -107,6 +107,7 @@ export * from '../test/generated-wrappers/mixin_curve'; | ||||
| export * from '../test/generated-wrappers/mixin_curve_v2'; | ||||
| export * from '../test/generated-wrappers/mixin_dodo'; | ||||
| export * from '../test/generated-wrappers/mixin_dodo_v2'; | ||||
| export * from '../test/generated-wrappers/mixin_g_m_x'; | ||||
| export * from '../test/generated-wrappers/mixin_kyber'; | ||||
| export * from '../test/generated-wrappers/mixin_kyber_dmm'; | ||||
| export * from '../test/generated-wrappers/mixin_lido'; | ||||
|   | ||||
| @@ -140,6 +140,7 @@ | ||||
|         "test/generated-artifacts/MixinCurveV2.json", | ||||
|         "test/generated-artifacts/MixinDodo.json", | ||||
|         "test/generated-artifacts/MixinDodoV2.json", | ||||
|         "test/generated-artifacts/MixinGMX.json", | ||||
|         "test/generated-artifacts/MixinKyber.json", | ||||
|         "test/generated-artifacts/MixinKyberDmm.json", | ||||
|         "test/generated-artifacts/MixinLido.json", | ||||
|   | ||||
| @@ -4,23 +4,28 @@ Audits | ||||
|  | ||||
| Below are links to our third-party audit reports. | ||||
|  | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | **Release**      | **Reports**                                                                                                   | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | Exchange V4      | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__    | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | Exchange V3      | * `Trail of Bits <http://zeips.0x.org.s3-website.us-east-2.amazonaws.com/audits/56/trail-of-bits/audit.pdf>`_ | | ||||
| |                  | * `Consensys Diligence (Exchange) <https://diligence.consensys.net/audits/2019/09/0x-v3-exchange/>`__         | | ||||
| |                  | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__           | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | Exchange V2.1    | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_             | | ||||
| |                  | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_                            | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | MultiAssetProxy  | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__                              | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | ERC1155Proxy     | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__                              | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | StaticCallProxy  | * No third-party audit.                                                                                       | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| | ERC20BridgeProxy | * No third-party audit.                                                                                       | | ||||
| +------------------+---------------------------------------------------------------------------------------------------------------+ | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | **Release**          | **Reports**                                                                                                               | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | ERC721OrdersFeature  | * `ABDK Consulting <https://s3.us-east-2.amazonaws.com/zeips.0x.org/audits/abdk-consulting/ABDK_0x_Solidity_v_1_0.pdf>`__ | | ||||
| |                      |                                                                                                                           | | ||||
| |                      |                                                                                                                           | | ||||
| | ERC1155OrdersFeature |                                                                                                                           | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | Exchange V4          | * `Consensys Diligence (December 2020) <https://consensys.net/diligence/audits/2020/12/0x-exchange-v4/>`__                | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | Exchange V3          | * `Trail of Bits <http://zeips.0x.org.s3-website.us-east-2.amazonaws.com/audits/56/trail-of-bits/audit.pdf>`__            | | ||||
| |                      | * `Consensys Diligence (Exchange) <https://diligence.consensys.net/audits/2019/09/0x-v3-exchange/>`__                     | | ||||
| |                      | * `Consensys Diligence (Staking) <https://diligence.consensys.net/audits/2019/10/0x-v3-staking/>`__                       | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | Exchange V2.1        | * `First <https://docs.google.com/document/d/1jYv6V21MfCSwCS5fxD6ZyaLWGzkpRSUO0lZpST94XsA/edit>`_                         | | ||||
| |                      | * `Consensys Diligence <https://github.com/ConsenSys/0x_audit_report_2018-07-23>`_                                        | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | MultiAssetProxy      | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2018-12>`__                                          | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | ERC1155Proxy         | * `Consensys Diligence <https://github.com/ConsenSys/0x-audit-report-2019-05>`__                                          | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | StaticCallProxy      | * No third-party audit.                                                                                                   | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
| | ERC20BridgeProxy     | * No third-party audit.                                                                                                   | | ||||
| +----------------------+---------------------------------------------------------------------------------------------------------------------------+ | ||||
|   | ||||
| @@ -65,7 +65,7 @@ | ||||
|         "@0xproject/npm-cli-login": "^0.0.11", | ||||
|         "async-child-process": "^1.1.1", | ||||
|         "coveralls": "^3.0.0", | ||||
|         "ganache-cli": "6.8.0-istanbul.0", | ||||
|         "ganache-cli": "6.12.2", | ||||
|         "lcov-result-merger": "^3.0.0", | ||||
|         "lerna": "^3.0.0-beta.25", | ||||
|         "npm-run-all": "^4.1.2", | ||||
| @@ -75,6 +75,7 @@ | ||||
|         "wsrun": "^5.2.4" | ||||
|     }, | ||||
|     "resolutions": { | ||||
|         "merkle-patricia-tree": "^2.3.2" | ||||
|         "merkle-patricia-tree": "3.0.0", | ||||
|         "bignumber.js": "9.0.2" | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,85 @@ | ||||
| [ | ||||
|     { | ||||
|         "version": "16.52.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Adds support for mobius money on celo", | ||||
|                 "pr": 423 | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "16.51.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Added `Curve` `YFI-ETH` pool", | ||||
|                 "pr": 444 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1646888282 | ||||
|     }, | ||||
|     { | ||||
|         "version": "16.50.3", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Routing glue optimization", | ||||
|                 "pr": 439 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Move VIP source routing into neon-router & disable fallback orders for native/plp", | ||||
|                 "pr": 440 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1646837959 | ||||
|     }, | ||||
|     { | ||||
|         "version": "16.50.2", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Update `Uniswap_V3` address on `Ropsten`", | ||||
|                 "pr": 441 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1646617024 | ||||
|     }, | ||||
|     { | ||||
|         "version": "16.50.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Add BTRFLY/WETH Curve pool on mainnet", | ||||
|                 "pr": 437 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Lower Uniswap V3 Sampler gas allowance", | ||||
|                 "pr": 438 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1646312638 | ||||
|     }, | ||||
|     { | ||||
|         "version": "16.50.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Adding support for Geist on `Fantom`", | ||||
|                 "pr": 398 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Improve Uniswap V3 gas schedule", | ||||
|                 "pr": 424 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1646225739 | ||||
|     }, | ||||
|     { | ||||
|         "version": "16.49.9", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Fix native order scaling & filter out 1 wei quotes", | ||||
|                 "pr": "430" | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1645696356 | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1645569128, | ||||
|         "version": "16.49.8", | ||||
|   | ||||
| @@ -5,6 +5,33 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v16.51.0 - _March 10, 2022_ | ||||
|  | ||||
|     * Added `Curve` `YFI-ETH` pool (#444) | ||||
|  | ||||
| ## v16.50.3 - _March 9, 2022_ | ||||
|  | ||||
|     * Routing glue optimization (#439) | ||||
|     * Move VIP source routing into neon-router & disable fallback orders for native/plp (#440) | ||||
|  | ||||
| ## v16.50.2 - _March 7, 2022_ | ||||
|  | ||||
|     * Update `Uniswap_V3` address on `Ropsten` (#441) | ||||
|  | ||||
| ## v16.50.1 - _March 3, 2022_ | ||||
|  | ||||
|     * Add BTRFLY/WETH Curve pool on mainnet (#437) | ||||
|     * Lower Uniswap V3 Sampler gas allowance (#438) | ||||
|  | ||||
| ## v16.50.0 - _March 2, 2022_ | ||||
|  | ||||
|     * Adding support for Geist on `Fantom` (#398) | ||||
|     * Improve Uniswap V3 gas schedule (#424) | ||||
|  | ||||
| ## v16.49.9 - _February 24, 2022_ | ||||
|  | ||||
|     * Fix native order scaling & filter out 1 wei quotes (#430) | ||||
|  | ||||
| ## v16.49.8 - _February 22, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -22,9 +22,9 @@ pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./interfaces/IBancor.sol"; | ||||
|  | ||||
| contract CompilerHack {} | ||||
|  | ||||
| contract BancorSampler is CompilerHack { | ||||
|  | ||||
| contract BancorSampler { | ||||
|  | ||||
|     /// @dev Base gas limit for Bancor calls. | ||||
|     uint256 constant private BANCOR_CALL_GAS = 300e3; // 300k | ||||
|   | ||||
| @@ -27,6 +27,7 @@ import "./CompoundSampler.sol"; | ||||
| import "./CurveSampler.sol"; | ||||
| import "./DODOSampler.sol"; | ||||
| import "./DODOV2Sampler.sol"; | ||||
| import "./GMXSampler.sol"; | ||||
| import "./KyberSampler.sol"; | ||||
| import "./KyberDmmSampler.sol"; | ||||
| import "./LidoSampler.sol"; | ||||
| @@ -36,6 +37,7 @@ import "./MultiBridgeSampler.sol"; | ||||
| import "./MStableSampler.sol"; | ||||
| import "./MooniswapSampler.sol"; | ||||
| import "./NativeOrderSampler.sol"; | ||||
| import "./PlatypusSampler.sol"; | ||||
| import "./ShellSampler.sol"; | ||||
| import "./SmoothySampler.sol"; | ||||
| import "./TwoHopSampler.sol"; | ||||
| @@ -53,6 +55,7 @@ contract ERC20BridgeSampler is | ||||
|     CurveSampler, | ||||
|     DODOSampler, | ||||
|     DODOV2Sampler, | ||||
|     GMXSampler, | ||||
|     KyberSampler, | ||||
|     KyberDmmSampler, | ||||
|     LidoSampler, | ||||
| @@ -62,6 +65,7 @@ contract ERC20BridgeSampler is | ||||
|     MooniswapSampler, | ||||
|     MultiBridgeSampler, | ||||
|     NativeOrderSampler, | ||||
|     PlatypusSampler, | ||||
|     ShellSampler, | ||||
|     SmoothySampler, | ||||
|     TwoHopSampler, | ||||
|   | ||||
							
								
								
									
										99
									
								
								packages/asset-swapper/contracts/src/GMXSampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								packages/asset-swapper/contracts/src/GMXSampler.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| pragma solidity ^0.6; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./interfaces/IGMX.sol"; | ||||
| import "./ApproximateBuys.sol"; | ||||
| import "./SamplerUtils.sol"; | ||||
|  | ||||
| contract GMXSampler is | ||||
|     SamplerUtils, | ||||
|     ApproximateBuys | ||||
| { | ||||
|     struct GMXInfo { | ||||
|         address reader; | ||||
|         address vault; | ||||
|         address[] path; | ||||
|     } | ||||
|     // address immutable WAVAX = 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7; | ||||
|     // address immutable AVAX = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; | ||||
|  | ||||
|     function sampleSellsFromGMX( | ||||
|         address reader, | ||||
|         address vault, | ||||
|         address[] memory path, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts) | ||||
|     { | ||||
|         uint256 numSamples = takerTokenAmounts.length; | ||||
|         makerTokenAmounts = new uint256[](numSamples); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             try | ||||
|                 IGMX(reader).getAmountOut(IVault(vault), path[0], path[1], takerTokenAmounts[i]) | ||||
|                 returns (uint256 amountAfterFees, uint256 feeAmount) | ||||
|             { | ||||
|                 makerTokenAmounts[i] = amountAfterFees; | ||||
|                 // Break early if there are 0 amounts | ||||
|                 if (makerTokenAmounts[i] == 0) { | ||||
|                     break; | ||||
|                 } | ||||
|             } catch (bytes memory) { | ||||
|                 // Swallow failures, leaving all results as zero. | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function sampleBuysFromGMX( | ||||
|         address reader, | ||||
|         address vault, | ||||
|         address[] memory path, | ||||
|         uint256[] memory makerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts) | ||||
|     { | ||||
|         address[] memory invertBuyPath = new address[](2); | ||||
|         invertBuyPath[0] = path[1]; | ||||
|         invertBuyPath[1] = path[0]; | ||||
|         return _sampleApproximateBuys( | ||||
|                 ApproximateBuyQuoteOpts({ | ||||
|                     makerTokenData: abi.encode(reader, vault, invertBuyPath), | ||||
|                     takerTokenData: abi.encode(reader, vault, path), | ||||
|                     getSellQuoteCallback: _sampleSellForApproximateBuyFromGMX | ||||
|                 }), | ||||
|                 makerTokenAmounts | ||||
|             ); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function _sampleSellForApproximateBuyFromGMX( | ||||
|         bytes memory takerTokenData, | ||||
|         bytes memory makerTokenData, | ||||
|         uint256 sellAmount | ||||
|     ) | ||||
|         private | ||||
|         view | ||||
|         returns (uint256 buyAmount) | ||||
|     { | ||||
|         (address _reader, address _vault, address[] memory _path ) = abi.decode(takerTokenData, (address, address, address[])); | ||||
|  | ||||
|         (bool success, bytes memory resultData) = address(this).staticcall(abi.encodeWithSelector( | ||||
|             this.sampleSellsFromGMX.selector, | ||||
|             _reader, | ||||
|             _vault, | ||||
|             _path, | ||||
|             _toSingleValueArray(sellAmount) | ||||
|         )); | ||||
|         if(!success) { | ||||
|             return 0; | ||||
|         } | ||||
|         // solhint-disable-next-line indent | ||||
|         return abi.decode(resultData, (uint256[]))[0]; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
							
								
								
									
										118
									
								
								packages/asset-swapper/contracts/src/PlatypusSampler.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								packages/asset-swapper/contracts/src/PlatypusSampler.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| pragma solidity ^0.6; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "./interfaces/IPlatypus.sol"; | ||||
| import "./ApproximateBuys.sol"; | ||||
| import "./SamplerUtils.sol"; | ||||
|  | ||||
| contract PlatypusSampler is | ||||
|     SamplerUtils, | ||||
|     ApproximateBuys | ||||
| { | ||||
|  | ||||
|     function sampleSellsFromPlatypus( | ||||
|         address router, | ||||
|         address[] memory path, | ||||
|         address[] memory pool, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory makerTokenAmounts) | ||||
|     { | ||||
|  | ||||
|         uint256 numSamples = takerTokenAmounts.length; | ||||
|         makerTokenAmounts = new uint256[](numSamples); | ||||
|         for (uint256 i = 0; i < numSamples; i++) { | ||||
|             try | ||||
|                 IPlatypus(router).quotePotentialSwaps(path, pool, takerTokenAmounts[i]) | ||||
|                 returns (uint256 amountAfterFees, uint256 feeAmount) | ||||
|             { | ||||
|                 makerTokenAmounts[i] = amountAfterFees; | ||||
|                 // Break early if there are 0 amounts | ||||
|                 if (makerTokenAmounts[i] == 0) { | ||||
|                     break; | ||||
|                 } | ||||
|             } catch (bytes memory) { | ||||
|                 // Swallow failures, leaving all results as zero. | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function sampleBuysFromPlatypus( | ||||
|         address router, | ||||
|         address[] memory path, | ||||
|         address[] memory pool, | ||||
|         uint256[] memory makerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         view | ||||
|         returns (uint256[] memory takerTokenAmounts) | ||||
|     { | ||||
|         address[] memory invertBuyPath; | ||||
|         address[] memory invertPoolPath; | ||||
|  | ||||
|         if(path.length > 2){ | ||||
|  | ||||
|             invertBuyPath = new address[](3); | ||||
|             invertPoolPath = new address[](2); | ||||
|  | ||||
|             invertBuyPath[0] = path[2]; | ||||
|             invertBuyPath[2] = path[0]; | ||||
|             invertBuyPath[1] = path[1]; | ||||
|  | ||||
|             invertPoolPath[0] = pool[1]; | ||||
|             invertPoolPath[1] = pool[0]; | ||||
|         } | ||||
|         else { | ||||
|  | ||||
|             invertBuyPath = new address[](2); | ||||
|             invertPoolPath = new address[](1); | ||||
|  | ||||
|             invertBuyPath[0] = path[1]; | ||||
|             invertBuyPath[1] = path[0]; | ||||
|             invertPoolPath[0] = pool[0]; | ||||
|         } | ||||
|  | ||||
|         uint256[] memory result = _sampleApproximateBuys( | ||||
|                 ApproximateBuyQuoteOpts({ | ||||
|                     makerTokenData: abi.encode(router, invertBuyPath, invertPoolPath), | ||||
|                     takerTokenData: abi.encode(router, path, pool), | ||||
|                     getSellQuoteCallback: _sampleSellForApproximateBuyFromPlatypus | ||||
|                 }), | ||||
|                 makerTokenAmounts | ||||
|         ); | ||||
|  | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function _sampleSellForApproximateBuyFromPlatypus( | ||||
|         bytes memory makerTokenData, | ||||
|         bytes memory takerTokenData, | ||||
|         uint256 sellAmount | ||||
|     ) | ||||
|         private | ||||
|         view | ||||
|         returns (uint256 buyAmount) | ||||
|     { | ||||
|         (address router,  address[] memory _path, address[] memory _pool ) = abi.decode(makerTokenData, (address, address[], address[])); | ||||
|  | ||||
|         (bool success, bytes memory resultData) = address(this).staticcall(abi.encodeWithSelector( | ||||
|             this.sampleSellsFromPlatypus.selector, | ||||
|             router, | ||||
|             _path, | ||||
|             _pool, | ||||
|             _toSingleValueArray(sellAmount) | ||||
|         )); | ||||
|  | ||||
|         if(!success) { | ||||
|             return 0; | ||||
|         } | ||||
|         // solhint-disable-next-line indent | ||||
|         return abi.decode(resultData, (uint256[]))[0]; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @@ -22,17 +22,43 @@ pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol"; | ||||
|  | ||||
| interface IUniswapV3Quoter { | ||||
| interface IUniswapV3QuoterV2 { | ||||
|     function factory() | ||||
|         external | ||||
|         view | ||||
|         returns (IUniswapV3Factory factory); | ||||
|  | ||||
|     // @notice Returns the amount out received for a given exact input swap without executing the swap | ||||
|     // @param path The path of the swap, i.e. each token pair and the pool fee | ||||
|     // @param amountIn The amount of the first token to swap | ||||
|     // @return amountOut The amount of the last token that would be received | ||||
|     // @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path | ||||
|     // @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path | ||||
|     // @return gasEstimate The estimate of the gas that the swap consumes | ||||
|     function quoteExactInput(bytes memory path, uint256 amountIn) | ||||
|         external | ||||
|         returns (uint256 amountOut); | ||||
|         returns ( | ||||
|             uint256 amountOut, | ||||
|             uint160[] memory sqrtPriceX96AfterList, | ||||
|             uint32[] memory initializedTicksCrossedList, | ||||
|             uint256 gasEstimate | ||||
|         ); | ||||
|  | ||||
|     // @notice Returns the amount in required for a given exact output swap without executing the swap | ||||
|     // @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order | ||||
|     // @param amountOut The amount of the last token to receive | ||||
|     // @return amountIn The amount of first token required to be paid | ||||
|     // @return sqrtPriceX96AfterList List of the sqrt price after the swap for each pool in the path | ||||
|     // @return initializedTicksCrossedList List of the initialized ticks that the swap crossed for each pool in the path | ||||
|     // @return gasEstimate The estimate of the gas that the swap consumes | ||||
|     function quoteExactOutput(bytes memory path, uint256 amountOut) | ||||
|         external | ||||
|         returns (uint256 amountIn); | ||||
|         returns ( | ||||
|             uint256 amountIn, | ||||
|             uint160[] memory sqrtPriceX96AfterList, | ||||
|             uint32[] memory initializedTicksCrossedList, | ||||
|             uint256 gasEstimate | ||||
|         ); | ||||
| } | ||||
|  | ||||
| interface IUniswapV3Factory { | ||||
| @@ -51,23 +77,25 @@ interface IUniswapV3Pool { | ||||
| contract UniswapV3Sampler | ||||
| { | ||||
|     /// @dev Gas limit for UniswapV3 calls. This is 100% a guess. | ||||
|     uint256 constant private QUOTE_GAS = 600e3; | ||||
|     uint256 constant private QUOTE_GAS = 700e3; | ||||
|  | ||||
|     /// @dev Sample sell quotes from UniswapV3. | ||||
|     /// @param quoter UniswapV3 Quoter contract. | ||||
|     /// @param path Token route. Should be takerToken -> makerToken | ||||
|     /// @param takerTokenAmounts Taker token sell amount for each sample. | ||||
|     /// @return uniswapPaths The encoded uniswap path for each sample. | ||||
|     /// @return uniswapGasUsed Estimated amount of gas used | ||||
|     /// @return makerTokenAmounts Maker amounts bought at each taker token | ||||
|     ///         amount. | ||||
|     function sampleSellsFromUniswapV3( | ||||
|         IUniswapV3Quoter quoter, | ||||
|         IUniswapV3QuoterV2 quoter, | ||||
|         IERC20TokenV06[] memory path, | ||||
|         uint256[] memory takerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         returns ( | ||||
|             bytes[] memory uniswapPaths, | ||||
|             uint256[] memory uniswapGasUsed, | ||||
|             uint256[] memory makerTokenAmounts | ||||
|         ) | ||||
|     { | ||||
| @@ -76,31 +104,39 @@ contract UniswapV3Sampler | ||||
|  | ||||
|         makerTokenAmounts = new uint256[](takerTokenAmounts.length); | ||||
|         uniswapPaths = new bytes[](takerTokenAmounts.length); | ||||
|         uniswapGasUsed = new uint256[](takerTokenAmounts.length); | ||||
|  | ||||
|         for (uint256 i = 0; i < takerTokenAmounts.length; ++i) { | ||||
|             // Pick the best result from all the paths. | ||||
|             bytes memory topUniswapPath; | ||||
|             uint256 topBuyAmount = 0; | ||||
|             for (uint256 j = 0; j < poolPaths.length; ++j) { | ||||
|                 bytes memory uniswapPath = _toUniswapPath(path, poolPaths[j]); | ||||
|                 try | ||||
|                     quoter.quoteExactInput | ||||
|                         { gas: QUOTE_GAS } | ||||
|                         (uniswapPath, takerTokenAmounts[i]) | ||||
|                         returns (uint256 buyAmount) | ||||
|                 try quoter.quoteExactInput | ||||
|                     { gas: QUOTE_GAS } | ||||
|                     (uniswapPath, takerTokenAmounts[i]) | ||||
|                     returns ( | ||||
|                         uint256 buyAmount, | ||||
|                         uint160[] memory, /* sqrtPriceX96AfterList */ | ||||
|                         uint32[] memory, /* initializedTicksCrossedList */ | ||||
|                         uint256 gasUsed | ||||
|                     ) | ||||
|                 { | ||||
|                     if (topBuyAmount <= buyAmount) { | ||||
|                         topBuyAmount = buyAmount; | ||||
|                         topUniswapPath = uniswapPath; | ||||
|                         uniswapPaths[i] = uniswapPath; | ||||
|                         uniswapGasUsed[i] = gasUsed; | ||||
|                     } | ||||
|                 } catch { } | ||||
|                 } catch {} | ||||
|             } | ||||
|             // Break early if we can't complete the buys. | ||||
|             // Break early if we can't complete the sells. | ||||
|             if (topBuyAmount == 0) { | ||||
|                 // HACK(kimpers): To avoid too many local variables, paths and gas used is set directly in the loop | ||||
|                 // then reset if no valid valid quote was found | ||||
|                 uniswapPaths[i] = ""; | ||||
|                 uniswapGasUsed[i] = 0; | ||||
|                 break; | ||||
|             } | ||||
|             makerTokenAmounts[i] = topBuyAmount; | ||||
|             uniswapPaths[i] = topUniswapPath; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -109,16 +145,18 @@ contract UniswapV3Sampler | ||||
|     /// @param path Token route. Should be takerToken -> makerToken. | ||||
|     /// @param makerTokenAmounts Maker token buy amount for each sample. | ||||
|     /// @return uniswapPaths The encoded uniswap path for each sample. | ||||
|     /// @return uniswapGasUsed Estimated amount of gas used | ||||
|     /// @return takerTokenAmounts Taker amounts sold at each maker token | ||||
|     ///         amount. | ||||
|     function sampleBuysFromUniswapV3( | ||||
|         IUniswapV3Quoter quoter, | ||||
|         IUniswapV3QuoterV2 quoter, | ||||
|         IERC20TokenV06[] memory path, | ||||
|         uint256[] memory makerTokenAmounts | ||||
|     ) | ||||
|         public | ||||
|         returns ( | ||||
|             bytes[] memory uniswapPaths, | ||||
|             uint256[] memory uniswapGasUsed, | ||||
|             uint256[] memory takerTokenAmounts | ||||
|         ) | ||||
|     { | ||||
| @@ -128,10 +166,10 @@ contract UniswapV3Sampler | ||||
|  | ||||
|         takerTokenAmounts = new uint256[](makerTokenAmounts.length); | ||||
|         uniswapPaths = new bytes[](makerTokenAmounts.length); | ||||
|         uniswapGasUsed = new uint256[](makerTokenAmounts.length); | ||||
|  | ||||
|         for (uint256 i = 0; i < makerTokenAmounts.length; ++i) { | ||||
|             // Pick the best result from all the paths. | ||||
|             bytes memory topUniswapPath; | ||||
|             uint256 topSellAmount = 0; | ||||
|             for (uint256 j = 0; j < poolPaths.length; ++j) { | ||||
|                 // quoter requires path to be reversed for buys. | ||||
| @@ -143,21 +181,30 @@ contract UniswapV3Sampler | ||||
|                     quoter.quoteExactOutput | ||||
|                         { gas: QUOTE_GAS } | ||||
|                         (uniswapPath, makerTokenAmounts[i]) | ||||
|                         returns (uint256 sellAmount) | ||||
|                         returns ( | ||||
|                             uint256 sellAmount, | ||||
|                             uint160[] memory, /* sqrtPriceX96AfterList */ | ||||
|                             uint32[] memory, /* initializedTicksCrossedList */ | ||||
|                             uint256 gasUsed | ||||
|                         ) | ||||
|                 { | ||||
|                     if (topSellAmount == 0 || topSellAmount >= sellAmount) { | ||||
|                         topSellAmount = sellAmount; | ||||
|                         // But the output path should still be encoded for sells. | ||||
|                         topUniswapPath = _toUniswapPath(path, poolPaths[j]); | ||||
|                         uniswapPaths[i] = _toUniswapPath(path, poolPaths[j]); | ||||
|                         uniswapGasUsed[i] = gasUsed; | ||||
|                     } | ||||
|                 } catch {} | ||||
|             } | ||||
|             // Break early if we can't complete the buys. | ||||
|             if (topSellAmount == 0) { | ||||
|                 // HACK(kimpers): To avoid too many local variables, paths and gas used is set directly in the loop | ||||
|                 // then reset if no valid valid quote was found | ||||
|                 uniswapPaths[i] = ""; | ||||
|                 uniswapGasUsed[i] = 0; | ||||
|                 break; | ||||
|             } | ||||
|             takerTokenAmounts[i] = topSellAmount; | ||||
|             uniswapPaths[i] = topUniswapPath; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -236,6 +283,7 @@ contract UniswapV3Sampler | ||||
|  | ||||
|     function _reverseTokenPath(IERC20TokenV06[] memory tokenPath) | ||||
|         private | ||||
|         pure | ||||
|         returns (IERC20TokenV06[] memory reversed) | ||||
|     { | ||||
|         reversed = new IERC20TokenV06[](tokenPath.length); | ||||
| @@ -246,6 +294,7 @@ contract UniswapV3Sampler | ||||
|  | ||||
|     function _reversePoolPath(IUniswapV3Pool[] memory poolPath) | ||||
|         private | ||||
|         pure | ||||
|         returns (IUniswapV3Pool[] memory reversed) | ||||
|     { | ||||
|         reversed = new IUniswapV3Pool[](poolPath.length); | ||||
|   | ||||
							
								
								
									
										23
									
								
								packages/asset-swapper/contracts/src/interfaces/IGMX.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/asset-swapper/contracts/src/interfaces/IGMX.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| pragma solidity ^0.6; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| interface IGMX { | ||||
|     function getMaxAmountIn(IVault _vault, address _tokenIn, address _tokenOut) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256); | ||||
|  | ||||
|     function getAmountOut(IVault _vault, address _tokenIn, address _tokenOut, uint256 _amountIn) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256, uint256); | ||||
| } | ||||
|  | ||||
| interface IVault { | ||||
|     function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256); | ||||
|     function stableSwapFeeBasisPoints() external view returns (uint256); | ||||
|     function stableTokens(address _token) external view returns (bool); | ||||
|     function tokenDecimals(address _token) external view returns (uint256); | ||||
|     function getMaxPrice(address _token) external view returns (uint256); | ||||
|     function getMinPrice(address _token) external view returns (uint256); | ||||
| } | ||||
| @@ -0,0 +1,10 @@ | ||||
|  | ||||
| pragma solidity ^0.6; | ||||
|  | ||||
| interface IPlatypus { | ||||
|     function quotePotentialSwaps( | ||||
|         address[] memory tokenPath, | ||||
|         address[] memory poolPath, | ||||
|         uint256 fromAmount | ||||
|     ) external view returns (uint256 potentialOutcome, uint256 haircut); | ||||
| } | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/asset-swapper", | ||||
|     "version": "16.49.8", | ||||
|     "version": "16.51.0", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -39,7 +39,7 @@ | ||||
|     "config": { | ||||
|         "publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker", | ||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", | ||||
|         "abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|IBalancer|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json", | ||||
|         "abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBancor|ICurve|IGMX|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json", | ||||
|         "postpublish": { | ||||
|             "assets": [] | ||||
|         } | ||||
| @@ -60,14 +60,14 @@ | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.31", | ||||
|         "@0x/base-contract": "^6.4.5", | ||||
|         "@0x/contract-addresses": "^6.11.0", | ||||
|         "@0x/contract-wrappers": "^13.19.0", | ||||
|         "@0x/contracts-erc20": "^3.3.26", | ||||
|         "@0x/contracts-zero-ex": "^0.31.0", | ||||
|         "@0x/contract-addresses": "^6.12.0", | ||||
|         "@0x/contract-wrappers": "^13.19.1", | ||||
|         "@0x/contracts-erc20": "^3.3.27", | ||||
|         "@0x/contracts-zero-ex": "^0.31.1", | ||||
|         "@0x/dev-utils": "^4.2.11", | ||||
|         "@0x/json-schemas": "^6.4.1", | ||||
|         "@0x/neon-router": "^0.3.2", | ||||
|         "@0x/protocol-utils": "^1.11.0", | ||||
|         "@0x/neon-router": "^0.3.5", | ||||
|         "@0x/protocol-utils": "^1.11.1", | ||||
|         "@0x/quote-server": "^6.0.6", | ||||
|         "@0x/types": "^3.3.4", | ||||
|         "@0x/typescript-typings": "^5.2.1", | ||||
| @@ -98,10 +98,10 @@ | ||||
|         "@0x/contracts-exchange": "^3.2.38", | ||||
|         "@0x/contracts-exchange-libs": "^4.3.37", | ||||
|         "@0x/contracts-gen": "^2.0.43", | ||||
|         "@0x/contracts-test-utils": "^5.4.17", | ||||
|         "@0x/contracts-utils": "^4.8.7", | ||||
|         "@0x/contracts-test-utils": "^5.4.18", | ||||
|         "@0x/contracts-utils": "^4.8.8", | ||||
|         "@0x/mesh-rpc-client": "^9.4.2", | ||||
|         "@0x/migrations": "^8.1.15", | ||||
|         "@0x/migrations": "^8.1.16", | ||||
|         "@0x/sol-compiler": "^4.7.8", | ||||
|         "@0x/subproviders": "^6.6.2", | ||||
|         "@0x/ts-doc-gen": "^0.0.28", | ||||
| @@ -128,5 +128,6 @@ | ||||
|     "publishConfig": { | ||||
|         "access": "public" | ||||
|     }, | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56" | ||||
|     "gitHead": "4f91bfd907996b2f4dd383778b50c479c2602b56", | ||||
|     "resolutions": {} | ||||
| } | ||||
|   | ||||
							
								
								
									
										57
									
								
								packages/asset-swapper/src/noop_samplers/GeistSampler.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								packages/asset-swapper/src/noop_samplers/GeistSampler.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| import { BigNumber } from '@0x/utils'; | ||||
|  | ||||
| import { ZERO_AMOUNT } from '../constants'; | ||||
| export interface GeistInfo { | ||||
|     lendingPool: string; | ||||
|     gToken: string; | ||||
|     underlyingToken: string; | ||||
| } | ||||
| // tslint:disable-next-line:no-unnecessary-class | ||||
| export class GeistSampler { | ||||
|     public static sampleSellsFromGeist( | ||||
|         geistInfo: GeistInfo, | ||||
|         takerToken: string, | ||||
|         makerToken: string, | ||||
|         takerTokenAmounts: BigNumber[], | ||||
|     ): BigNumber[] { | ||||
|         // Deposit/Withdrawal underlying <-> gToken is always 1:1 | ||||
|         if ( | ||||
|             (takerToken.toLowerCase() === geistInfo.gToken.toLowerCase() && | ||||
|                 makerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase()) || | ||||
|             (takerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase() && | ||||
|                 makerToken.toLowerCase() === geistInfo.gToken.toLowerCase()) | ||||
|         ) { | ||||
|             return takerTokenAmounts; | ||||
|         } | ||||
|  | ||||
|         // Not matching the reserve return 0 results | ||||
|         const numSamples = takerTokenAmounts.length; | ||||
|  | ||||
|         const makerTokenAmounts = new Array(numSamples); | ||||
|         makerTokenAmounts.fill(ZERO_AMOUNT); | ||||
|         return makerTokenAmounts; | ||||
|     } | ||||
|  | ||||
|     public static sampleBuysFromGeist( | ||||
|         geistInfo: GeistInfo, | ||||
|         takerToken: string, | ||||
|         makerToken: string, | ||||
|         makerTokenAmounts: BigNumber[], | ||||
|     ): BigNumber[] { | ||||
|         // Deposit/Withdrawal underlying <-> gToken is always 1:1 | ||||
|         if ( | ||||
|             (takerToken.toLowerCase() === geistInfo.gToken.toLowerCase() && | ||||
|                 makerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase()) || | ||||
|             (takerToken.toLowerCase() === geistInfo.underlyingToken.toLowerCase() && | ||||
|                 makerToken.toLowerCase() === geistInfo.gToken.toLowerCase()) | ||||
|         ) { | ||||
|             return makerTokenAmounts; | ||||
|         } | ||||
|  | ||||
|         // Not matching the reserve return 0 results | ||||
|         const numSamples = makerTokenAmounts.length; | ||||
|         const takerTokenAmounts = new Array(numSamples); | ||||
|         takerTokenAmounts.fill(ZERO_AMOUNT); | ||||
|         return takerTokenAmounts; | ||||
|     } | ||||
| } | ||||
| @@ -357,7 +357,7 @@ export class SwapQuoter { | ||||
|         if (nativeOrders.length === 0) { | ||||
|             nativeOrders.push(createDummyOrder(makerToken, takerToken)); | ||||
|         } | ||||
|  | ||||
|          | ||||
|         //  ** Prepare options for fetching market side liquidity ** | ||||
|         // Scale fees by gas price. | ||||
|         const cloneOpts = _.omit(opts, 'gasPrice') as GetMarketOrdersOpts; | ||||
|   | ||||
| @@ -31,6 +31,7 @@ import { | ||||
|     KYBER_BRIDGED_LIQUIDITY_PREFIX, | ||||
|     MAX_DODOV2_POOLS_QUERIED, | ||||
|     MAX_KYBER_RESERVES_QUERIED, | ||||
|     MOBIUSMONEY_CELO_INFOS, | ||||
|     MORPHEUSSWAP_ROUTER_BY_CHAIN_ID, | ||||
|     MSTABLE_POOLS_BY_CHAIN_ID, | ||||
|     NERVE_BSC_INFOS, | ||||
| @@ -61,8 +62,9 @@ import { | ||||
|     UNISWAPV2_ROUTER_BY_CHAIN_ID, | ||||
|     WAULTSWAP_ROUTER_BY_CHAIN_ID, | ||||
|     XSIGMA_MAINNET_INFOS, | ||||
|     PLATYPUS_AVALANCHE_INFOS, | ||||
| } from './constants'; | ||||
| import { CurveInfo, ERC20BridgeSource } from './types'; | ||||
| import { CurveInfo, ERC20BridgeSource, PlatypusInfo } from './types'; | ||||
|  | ||||
| /** | ||||
|  * Filter Kyber reserves which should not be used (0xbb bridged reserves) | ||||
| @@ -449,6 +451,60 @@ export function getAcryptosInfosForPair(chainId: ChainId, takerToken: string, ma | ||||
|         ), | ||||
|     ); | ||||
| } | ||||
| export function getMobiusMoneyInfoForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] { | ||||
|     if (chainId !== ChainId.Celo) { | ||||
|         return []; | ||||
|     } | ||||
|     return Object.values(MOBIUSMONEY_CELO_INFOS).filter(c => | ||||
|         [makerToken, takerToken].every( | ||||
|             t => | ||||
|                 (c.tokens.includes(t) && c.metaTokens === undefined) || | ||||
|                 (c.tokens.includes(t) && [makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0), | ||||
|         ), | ||||
|     ); | ||||
| } | ||||
|  | ||||
| export function getPlatypusInfoForPair(chainId: ChainId, takerToken: string, makerToken: string): PlatypusInfo[] { | ||||
|     if (chainId !== ChainId.Avalanche) { | ||||
|         return []; | ||||
|     } | ||||
|     let ptpPools: PlatypusInfo[] = []; | ||||
|     const makerTokenPool = Object.values(PLATYPUS_AVALANCHE_INFOS).filter(c => | ||||
|         [makerToken].every( | ||||
|             t => | ||||
|                 c.tokens.includes(t), | ||||
|         ), | ||||
|     ); | ||||
|     const takerTokenPool = Object.values(PLATYPUS_AVALANCHE_INFOS).filter(c => | ||||
|         [takerToken].every( | ||||
|             t => | ||||
|                 c.tokens.includes(t), | ||||
|         ), | ||||
|     ); | ||||
|  | ||||
|  | ||||
|     if( makerTokenPool[0].tokens.includes(takerToken)){ | ||||
|         let pool: PlatypusInfo = { | ||||
|             gasSchedule: makerTokenPool[0].gasSchedule, | ||||
|             poolAddress: [makerTokenPool[0].poolAddress[0]], | ||||
|             tokens: [makerToken,takerToken], | ||||
|         }; | ||||
|         ptpPools.push(pool); | ||||
|     } | ||||
|     else{ | ||||
|         const intermediateToken = makerTokenPool[0].tokens.filter(element => takerTokenPool[0].tokens.includes(element)); | ||||
|         //return similar values from two arrays | ||||
|  | ||||
|         let pool: PlatypusInfo = { | ||||
|             gasSchedule: makerTokenPool[0].gasSchedule + makerTokenPool[0].gasSchedule, | ||||
|             poolAddress: [makerTokenPool[0].poolAddress[0], takerTokenPool[0].poolAddress[0]], | ||||
|             tokens: [makerToken,intermediateToken[0],takerToken], | ||||
|         }; | ||||
|         ptpPools.push(pool); | ||||
|     } | ||||
|  | ||||
|     return ptpPools; | ||||
| } | ||||
|  | ||||
| export function getShellLikeInfosForPair( | ||||
|     chainId: ChainId, | ||||
| @@ -491,7 +547,8 @@ export function getCurveLikeInfosForPair( | ||||
|         | ERC20BridgeSource.IronSwap | ||||
|         | ERC20BridgeSource.XSigma | ||||
|         | ERC20BridgeSource.FirebirdOneSwap | ||||
|         | ERC20BridgeSource.ACryptos, | ||||
|         | ERC20BridgeSource.ACryptos | ||||
|         | ERC20BridgeSource.MobiusMoney, | ||||
| ): CurveDetailedInfo[] { | ||||
|     let pools: CurveInfo[] = []; | ||||
|     switch (source) { | ||||
| @@ -537,6 +594,9 @@ export function getCurveLikeInfosForPair( | ||||
|         case ERC20BridgeSource.ACryptos: | ||||
|             pools = getAcryptosInfosForPair(chainId, takerToken, makerToken); | ||||
|             break; | ||||
|         case ERC20BridgeSource.MobiusMoney: | ||||
|             pools = getMobiusMoneyInfoForPair(chainId, takerToken, makerToken); | ||||
|             break; | ||||
|         default: | ||||
|             throw new Error(`Unknown Curve like source ${source}`); | ||||
|     } | ||||
|   | ||||
| @@ -17,13 +17,18 @@ import { | ||||
|     ERC20BridgeSource, | ||||
|     FeeSchedule, | ||||
|     FillData, | ||||
|     FinalUniswapV3FillData, | ||||
|     GeistFillData, | ||||
|     GetMarketOrdersOpts, | ||||
|     isFinalUniswapV3FillData, | ||||
|     KyberSamplerOpts, | ||||
|     LidoInfo, | ||||
|     LiquidityProviderFillData, | ||||
|     LiquidityProviderRegistry, | ||||
|     MakerPsmFillData, | ||||
|     MultiHopFillData, | ||||
|     PlatypusFillData, | ||||
|     PlatypusInfo, | ||||
|     PsmInfo, | ||||
|     TokenAdjacencyGraph, | ||||
|     UniswapV2FillData, | ||||
| @@ -181,12 +186,15 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.KyberDmm, | ||||
|             ERC20BridgeSource.AaveV2, | ||||
|             ERC20BridgeSource.Synapse, | ||||
|             ERC20BridgeSource.GMX, | ||||
|             ERC20BridgeSource.Platypus, | ||||
|         ]), | ||||
|         [ChainId.Fantom]: new SourceFilters([ | ||||
|             ERC20BridgeSource.MultiHop, | ||||
|             ERC20BridgeSource.Beethovenx, | ||||
|             ERC20BridgeSource.Curve, | ||||
|             ERC20BridgeSource.CurveV2, | ||||
|             ERC20BridgeSource.Geist, | ||||
|             ERC20BridgeSource.JetSwap, | ||||
|             ERC20BridgeSource.MorpheusSwap, | ||||
|             ERC20BridgeSource.SpiritSwap, | ||||
| @@ -198,6 +206,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.UbeSwap, | ||||
|             ERC20BridgeSource.SushiSwap, | ||||
|             ERC20BridgeSource.MultiHop, | ||||
|             ERC20BridgeSource.MobiusMoney, | ||||
|         ]), | ||||
|         [ChainId.Optimism]: new SourceFilters([ | ||||
|             ERC20BridgeSource.UniswapV3, | ||||
| @@ -275,6 +284,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.Mooniswap, | ||||
|             ERC20BridgeSource.MultiHop, | ||||
|             ERC20BridgeSource.Nerve, | ||||
|             ERC20BridgeSource.Synapse, | ||||
|             ERC20BridgeSource.PancakeSwap, | ||||
|             ERC20BridgeSource.PancakeSwapV2, | ||||
|             ERC20BridgeSource.SushiSwap, | ||||
| @@ -325,12 +335,15 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.KyberDmm, | ||||
|             ERC20BridgeSource.AaveV2, | ||||
|             ERC20BridgeSource.Synapse, | ||||
|             ERC20BridgeSource.GMX, | ||||
|             ERC20BridgeSource.Platypus, | ||||
|         ]), | ||||
|         [ChainId.Fantom]: new SourceFilters([ | ||||
|             ERC20BridgeSource.MultiHop, | ||||
|             ERC20BridgeSource.Beethovenx, | ||||
|             ERC20BridgeSource.Curve, | ||||
|             ERC20BridgeSource.CurveV2, | ||||
|             ERC20BridgeSource.Geist, | ||||
|             ERC20BridgeSource.JetSwap, | ||||
|             ERC20BridgeSource.MorpheusSwap, | ||||
|             ERC20BridgeSource.SpiritSwap, | ||||
| @@ -342,6 +355,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>( | ||||
|             ERC20BridgeSource.UbeSwap, | ||||
|             ERC20BridgeSource.SushiSwap, | ||||
|             ERC20BridgeSource.MultiHop, | ||||
|             ERC20BridgeSource.MobiusMoney, | ||||
|         ]), | ||||
|         [ChainId.Optimism]: new SourceFilters([ | ||||
|             ERC20BridgeSource.UniswapV3, | ||||
| @@ -495,6 +509,7 @@ export const MAINNET_TOKENS = { | ||||
|     OUSD: '0x2a8e1e676ec238d8a992307b495b45b3feaa5e86', | ||||
|     agEUR: '0x1a7e4e63778b4f12a199c062f3efdd288afcbce8', | ||||
|     ibEUR: '0x96e61422b6a9ba0e068b6c5add4ffabc6a4aae27', | ||||
|     YFI: '0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e', | ||||
| }; | ||||
|  | ||||
| export const BSC_TOKENS = { | ||||
| @@ -542,6 +557,7 @@ export const AVALANCHE_TOKENS = { | ||||
|     // native USDC on Avalanche | ||||
|     nUSDC: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e', | ||||
|     USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118', | ||||
|     USDt: '0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7', | ||||
|     aDAI: '0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a', | ||||
|     aUSDC: '0x46a51127c3ce23fb7ab1de06226147f446e4a857', | ||||
|     aUSDT: '0x532e6537fea298397212f09a61e03311686f548e', | ||||
| @@ -549,6 +565,10 @@ export const AVALANCHE_TOKENS = { | ||||
|     nUSD: '0xcfc37a6ab183dd4aed08c204d1c2773c0b1bdf46', | ||||
|     aWETH: '0x53f7c5869a859f0aec3d334ee8b4cf01e3492f21', | ||||
|     MIM: '0x130966628846bfd36ff31a822705796e8cb8c18d', | ||||
|     sAVAX: '0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be', | ||||
|     UST: '0xb599c3590f42f8f995ecfa0f85d2980b76862fc1', | ||||
|     FRAX: '0xd24c2ad096400b6fbcd2ad8b24e7acbc21a1da64', | ||||
|  | ||||
| }; | ||||
|  | ||||
| export const CELO_TOKENS = { | ||||
| @@ -556,11 +576,11 @@ export const CELO_TOKENS = { | ||||
|     // Some of these tokens are Optics bridge? tokens which | ||||
|     // had an issue and migrated from v1 to v2 | ||||
|     WETHv1: '0xe919f65739c26a42616b7b8eedc6b5524d1e3ac4', | ||||
|     WETH: '0x122013fd7df1c6f636a5bb8f03108e876548b455', | ||||
|     oWETH: '0x122013fd7df1c6f636a5bb8f03108e876548b455', | ||||
|     WBTC: '0xbaab46e28388d2779e6e31fd00cf0e5ad95e327b', | ||||
|     cUSD: '0x765de816845861e75a25fca122bb6898b8b1282a', | ||||
|     // ?? | ||||
|     WBTCv1: '0xd629eb00deced2a080b7ec630ef6ac117e614f1b', | ||||
|     cBTC: '0xd629eb00deced2a080b7ec630ef6ac117e614f1b', | ||||
|     cETH: '0x2def4285787d58a2f811af24755a8150622f4361', | ||||
|     UBE: '0x00be915b9dcf56a3cbe739d9b9c202ca692409ec', | ||||
|     // Moolah | ||||
| @@ -569,6 +589,22 @@ export const CELO_TOKENS = { | ||||
|     mCEUR: '0xe273ad7ee11dcfaa87383ad5977ee1504ac07568', | ||||
|     amCUSD: '0x64defa3544c695db8c535d289d843a189aa26b98', | ||||
|     MOO: '0x17700282592d6917f6a73d0bf8accf4d578c131e', | ||||
|  | ||||
|     // | ||||
|     wBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', | ||||
|     wETH: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', | ||||
|     wBTCO: '0xbe50a3013a1c94768a1abb78c3cb79ab28fc1ace', | ||||
|     pUSDC: '0xcc82628f6a8defa1e2b0ad7ed448bef3647f7941', | ||||
|     cUSDC: '0x2a3684e9dc20b857375ea04235f2f7edbe818fa7', | ||||
|     cUSDC_V2: '0xef4229c8c3250c675f21bcefa42f58efbff6002a', | ||||
|     pUSDC_V2: '0x1bfc26ce035c368503fae319cc2596716428ca44', | ||||
|     pUSD: '0xeadf4a7168a82d30ba0619e64d5bcf5b30b45226', | ||||
|     pCELO: '0x301a61d01a63c8d670c2b8a43f37d12ef181f997', | ||||
|     aaUSDC: '0xb70e0a782b058bfdb0d109a3599bec1f19328e36', | ||||
|     asUSDC: '0xcd7d7ff64746c1909e44db8e95331f9316478817', | ||||
|     mcUSDT: '0xcfffe0c89a779c09df3df5624f54cdf7ef5fdd5d', | ||||
|     mcUSDC: '0x93db49be12b864019da9cb147ba75cdc0506190e', | ||||
|     DAI: '0x90ca507a5d4458a4c6c6249d186b6dcb02a5bccd', | ||||
| }; | ||||
|  | ||||
| export const FANTOM_TOKENS = { | ||||
| @@ -578,6 +614,7 @@ export const FANTOM_TOKENS = { | ||||
|     DAI: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', | ||||
|     fUSDT: '0x049d68029688eabf473097a2fc38ef61633a3c7a', | ||||
|     WBTC: '0x321162cd933e2be498cd2267a90534a804051b11', | ||||
|     WCRV: '0x1e4f97b9f9f913c46f1632781732927b9019c68b', | ||||
|     renBTC: '0xdbf31df14b66535af65aac99c32e9ea844e14501', | ||||
|     MIM: '0x82f0b8b456c1a451378467398982d4834b6829c1', | ||||
|     nUSD: '0xed2a7edd7413021d440b09d654f3b87712abab66', | ||||
| @@ -586,6 +623,15 @@ export const FANTOM_TOKENS = { | ||||
|     gUSDC: '0xe578c856933d8e1082740bf7661e379aa2a30b26', | ||||
|     gDAI: '0x07e6332dd090d287d3489245038daf987955dcfb', | ||||
|     FRAX: '0xdc301622e621166bd8e82f2ca0a26c13ad0be355', | ||||
|     gFTM: '0x39b3bd37208cbade74d0fcbdbb12d606295b430a', | ||||
|     gETH: '0x25c130b2624cf12a4ea30143ef50c5d68cefa22f', | ||||
|     gWBTC: '0x38aca5484b8603373acc6961ecd57a6a594510a3', | ||||
|     gCRV: '0x690754a168b022331caa2467207c61919b3f8a98', | ||||
|     gMIM: '0xc664fc7b8487a3e10824cda768c1d239f2403bbe', | ||||
| }; | ||||
|  | ||||
| export const GEIST_FANTOM_POOLS = { | ||||
|     lendingPool: '0x9fad24f572045c7869117160a571b2e50b10d068', | ||||
| }; | ||||
|  | ||||
| export const OPTIMISM_TOKENS = { | ||||
| @@ -631,6 +677,7 @@ export const CURVE_POOLS = { | ||||
|     USDP: '0x42d7025938bec20b69cbae5a77421082407f053a', // usdp | ||||
|     ib: '0x2dded6da1bf5dbdf597c45fcfaa3194e53ecfeaf', // iron bank | ||||
|     link: '0xf178c0b5bb7e7abf4e12a4838c7b7c5ba2c623c0', // link | ||||
|     btrflyweth: '0xf43b15ab692fde1f9c24a9fce700adcc809d5391', // redacted cartel | ||||
|     // StableSwap "open pools" (crv.finance) | ||||
|     TUSD: '0xecd5e75afb02efa118af914515d6521aabd189f1', | ||||
|     STABLEx: '0x3252efd4ea2d6c78091a1f43982ee2c3659cc3d1', | ||||
| @@ -653,6 +700,7 @@ export const CURVE_POOLS = { | ||||
|     d3pool: '0xbaaa1f5dba42c3389bdbc2c9d2de134f5cd0dc89', | ||||
|     triEURpool: '0xb9446c4ef5ebe66268da6700d26f96273de3d571', | ||||
|     ibEURsEUR: '0x19b080fe1ffa0553469d20ca36219f17fcf03859', | ||||
|     wethyfi: '0xc26b89a667578ec7b3f11b2f98d6fd15c07c54ba', | ||||
| }; | ||||
|  | ||||
| export const CURVE_V2_POOLS = { | ||||
| @@ -780,6 +828,14 @@ export const FIREBIRDONESWAP_BSC_POOLS = { | ||||
| export const FIREBIRDONESWAP_POLYGON_POOLS = { | ||||
|     oneswap: '0x01c9475dbd36e46d1961572c8de24b74616bae9e', | ||||
| }; | ||||
| export const MOBIUSMONEY_CELO_POOLS = { | ||||
|     usdc_optics_v2: '0x9906589ea8fd27504974b7e8201df5bbde986b03', | ||||
|     dai_optics_v2: '0xf3f65dfe0c8c8f2986da0fec159abe6fd4e700b4', | ||||
|     weth_optics_v2: '0x74ef28d635c6c5800dd3cd62d4c4f8752daacb09', | ||||
|     pusdc_optics_v2: '0xcce0d62ce14fb3e4363eb92db37ff3630836c252', | ||||
|     usdc_allbridge_solana: '0x63c1914bf00a9b395a2bf89aada55a5615a3656e', | ||||
|     usdc_poly_optics: '0xa2f0e57d4ceacf025e81c76f28b9ad6e9fbe8735', | ||||
| }; | ||||
|  | ||||
| export const ACRYPTOS_POOLS = { | ||||
|     acs4usd: '0xb3f0c9ea1f05e312093fdb031e789a756659b0ac', | ||||
| @@ -788,6 +844,14 @@ export const ACRYPTOS_POOLS = { | ||||
|     acs3btc: '0xbe7caa236544d1b9a0e7f91e94b9f5bfd3b5ca81', | ||||
| }; | ||||
|  | ||||
| export const PLATYPUS_AVALANCHE_POOLS = { | ||||
|     usd: '0x66357dcace80431aee0a7507e2e361b7e2402370', | ||||
|     ust: '0xe0d166de15665bc4b7185b2e35e847e51316e126', | ||||
|     frax: '0xb8e567fc23c39c94a1f6359509d7b43d1fbed824', | ||||
|     mim: '0x30c30d826be87cd0a4b90855c2f38f7fcfe4eaa7', | ||||
|     sAVAX: '0x4658ea7e9960d6158a261104aaa160cc953bb6ba', | ||||
| }; | ||||
|  | ||||
| export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>( | ||||
|     { | ||||
|         [ChainId.Mainnet]: [ | ||||
| @@ -839,7 +903,13 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>( | ||||
|             FANTOM_TOKENS.nETH, | ||||
|             FANTOM_TOKENS.MIM, | ||||
|         ], | ||||
|         [ChainId.Celo]: [CELO_TOKENS.WCELO, CELO_TOKENS.mCUSD, CELO_TOKENS.WETH, CELO_TOKENS.amCUSD, CELO_TOKENS.WBTC], | ||||
|         [ChainId.Celo]: [ | ||||
|             CELO_TOKENS.WCELO, | ||||
|             CELO_TOKENS.mCUSD, | ||||
|             CELO_TOKENS.WETHv1, | ||||
|             CELO_TOKENS.amCUSD, | ||||
|             CELO_TOKENS.WBTC, | ||||
|         ], | ||||
|         [ChainId.Optimism]: [ | ||||
|             OPTIMISM_TOKENS.WETH, | ||||
|             OPTIMISM_TOKENS.DAI, | ||||
| @@ -1004,6 +1074,25 @@ const createCurveV2MetaTriPool = (info: { tokens: string[]; pool: string; gasSch | ||||
|     gasSchedule: info.gasSchedule, | ||||
| }); | ||||
|  | ||||
| const createCurveFactoryCryptoExchangePool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({ | ||||
|     exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_uint256, | ||||
|     sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_uint256, | ||||
|     buyQuoteFunctionSelector: CurveFunctionSelectors.None, | ||||
|     tokens: info.tokens, | ||||
|     metaTokens: undefined, | ||||
|     poolAddress: info.pool, | ||||
|     gasSchedule: info.gasSchedule, | ||||
| }); | ||||
| const MOBIUSMONEY_CELO_SHARED: CurveInfo = { | ||||
|     exchangeFunctionSelector: CurveFunctionSelectors.swap, | ||||
|     sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap, | ||||
|     buyQuoteFunctionSelector: CurveFunctionSelectors.None, | ||||
|     metaTokens: undefined, | ||||
|     gasSchedule: 150e3, | ||||
|     poolAddress: NULL_ADDRESS, | ||||
|     tokens: [], | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Mainnet Curve configuration | ||||
|  * The tokens are in order of their index, which each curve defines | ||||
| @@ -1270,6 +1359,16 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
|         pool: CURVE_POOLS.ibEURsEUR, | ||||
|         gasSchedule: 176e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.btrflyweth]: createCurveFactoryCryptoExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.BTRFLY], | ||||
|         pool: CURVE_POOLS.btrflyweth, | ||||
|         gasSchedule: 250e3, | ||||
|     }), | ||||
|     [CURVE_POOLS.wethyfi]: createCurveFactoryCryptoExchangePool({ | ||||
|         tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.YFI], | ||||
|         pool: CURVE_POOLS.wethyfi, | ||||
|         gasSchedule: 250e3, | ||||
|     }), | ||||
| }; | ||||
|  | ||||
| export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = { | ||||
| @@ -1665,6 +1764,39 @@ export const FIREBIRDONESWAP_POLYGON_INFOS: { [name: string]: CurveInfo } = { | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| export const MOBIUSMONEY_CELO_INFOS: { [name: string]: CurveInfo } = { | ||||
|     [MOBIUSMONEY_CELO_POOLS.usdc_optics_v2]: { | ||||
|         ...MOBIUSMONEY_CELO_SHARED, | ||||
|         poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_optics_v2, | ||||
|         tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.cUSDC_V2], | ||||
|     }, | ||||
|     [MOBIUSMONEY_CELO_POOLS.weth_optics_v2]: { | ||||
|         ...MOBIUSMONEY_CELO_SHARED, | ||||
|         poolAddress: MOBIUSMONEY_CELO_POOLS.weth_optics_v2, | ||||
|         tokens: [CELO_TOKENS.cETH, CELO_TOKENS.oWETH], | ||||
|     }, | ||||
|     [MOBIUSMONEY_CELO_POOLS.pusdc_optics_v2]: { | ||||
|         ...MOBIUSMONEY_CELO_SHARED, | ||||
|         poolAddress: MOBIUSMONEY_CELO_POOLS.pusdc_optics_v2, | ||||
|         tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.pUSDC_V2], | ||||
|     }, | ||||
|     [MOBIUSMONEY_CELO_POOLS.usdc_allbridge_solana]: { | ||||
|         ...MOBIUSMONEY_CELO_SHARED, | ||||
|         poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_allbridge_solana, | ||||
|         tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.asUSDC], | ||||
|     }, | ||||
|     [MOBIUSMONEY_CELO_POOLS.usdc_poly_optics]: { | ||||
|         ...MOBIUSMONEY_CELO_SHARED, | ||||
|         poolAddress: MOBIUSMONEY_CELO_POOLS.usdc_poly_optics, | ||||
|         tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.pUSD], | ||||
|     }, | ||||
|     [MOBIUSMONEY_CELO_POOLS.dai_optics_v2]: { | ||||
|         ...MOBIUSMONEY_CELO_SHARED, | ||||
|         poolAddress: MOBIUSMONEY_CELO_POOLS.dai_optics_v2, | ||||
|         tokens: [CELO_TOKENS.cUSD, CELO_TOKENS.DAI], | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| const ACRYPTOS_ACS4USD_POOL_BSC_TOKENS = [BSC_TOKENS.BUSD, BSC_TOKENS.USDT, BSC_TOKENS.DAI, BSC_TOKENS.USDC]; | ||||
|  | ||||
| const createAcryptosMetaUsdPool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({ | ||||
| @@ -1703,6 +1835,34 @@ export const ACRYPTOS_BSC_INFOS: { [name: string]: CurveInfo } = { | ||||
|     }), | ||||
| }; | ||||
|  | ||||
| export const PLATYPUS_AVALANCHE_INFOS: { [name: string]: PlatypusInfo } = { | ||||
|     [PLATYPUS_AVALANCHE_POOLS.usd]: { | ||||
|         poolAddress: [PLATYPUS_AVALANCHE_POOLS.usd], | ||||
|         tokens: [AVALANCHE_TOKENS.USDT, AVALANCHE_TOKENS.USDC, AVALANCHE_TOKENS.DAI, AVALANCHE_TOKENS.nUSDC, AVALANCHE_TOKENS.USDt], | ||||
|         gasSchedule: 350e3, | ||||
|     }, | ||||
|     [PLATYPUS_AVALANCHE_POOLS.ust]: { | ||||
|         poolAddress: [PLATYPUS_AVALANCHE_POOLS.ust], | ||||
|         tokens: [AVALANCHE_TOKENS.nUSDC, AVALANCHE_TOKENS.UST], | ||||
|         gasSchedule: 350e3, | ||||
|     }, | ||||
|     [PLATYPUS_AVALANCHE_POOLS.frax]: { | ||||
|         poolAddress: [PLATYPUS_AVALANCHE_POOLS.frax], | ||||
|         tokens: [AVALANCHE_TOKENS.nUSDC, AVALANCHE_TOKENS.FRAX], //liq issues | ||||
|         gasSchedule: 350e3, | ||||
|     }, | ||||
|     [PLATYPUS_AVALANCHE_POOLS.mim]: { | ||||
|         poolAddress: [PLATYPUS_AVALANCHE_POOLS.mim], | ||||
|         tokens: [AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.nUSDC], | ||||
|         gasSchedule: 350e3, | ||||
|     }, | ||||
|     [PLATYPUS_AVALANCHE_POOLS.sAVAX]: { | ||||
|         poolAddress: [PLATYPUS_AVALANCHE_POOLS.sAVAX], | ||||
|         tokens: [AVALANCHE_TOKENS.WAVAX, AVALANCHE_TOKENS.sAVAX], //add unwrapping | ||||
|         gasSchedule: 350e3, | ||||
|     }, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Kyber reserve prefixes | ||||
|  * 0xff Fed price reserve | ||||
| @@ -1996,6 +2156,13 @@ export const COMPONENT_POOLS_BY_CHAIN_ID = valueByChainId( | ||||
|     }, | ||||
| ); | ||||
|  | ||||
| export const GEIST_INFO_ADDRESS_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Fantom]: '0xd8321aa83fb0a4ecd6348d4577431310a6e0814d', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const BALANCER_V2_VAULT_ADDRESS_BY_CHAIN = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Mainnet]: '0xba12222222228d8ba445958a75a0704d566bf2c8', | ||||
| @@ -2045,19 +2212,19 @@ export const BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>( | ||||
| export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId( | ||||
|     { | ||||
|         [ChainId.Mainnet]: { | ||||
|             quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6', | ||||
|             quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e', | ||||
|             router: '0xe592427a0aece92de3edee1f18e0157c05861564', | ||||
|         }, | ||||
|         [ChainId.Ropsten]: { | ||||
|             quoter: '0x2f9e608fd881861b8916257b76613cb22ee0652c', | ||||
|             router: '0x03782388516e94fcd4c18666303601a12aa729ea', | ||||
|             quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e', | ||||
|             router: '0xe592427a0aece92de3edee1f18e0157c05861564', | ||||
|         }, | ||||
|         [ChainId.Polygon]: { | ||||
|             quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6', | ||||
|             quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e', | ||||
|             router: '0xe592427a0aece92de3edee1f18e0157c05861564', | ||||
|         }, | ||||
|         [ChainId.Optimism]: { | ||||
|             quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6', | ||||
|             quoter: '0x61ffe014ba17989e743c5f6cb21bf9697530b21e', | ||||
|             router: '0xe592427a0aece92de3edee1f18e0157c05861564', | ||||
|         }, | ||||
|     }, | ||||
| @@ -2224,6 +2391,33 @@ export const SPOOKYSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
| export const GMX_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Avalanche]: '0x5f719c2f1095f7b9fc68a68e35b51194f4b6abe8', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const GMX_READER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Avalanche]: '0x67b789d48c926006f5132bfce4e976f0a7a63d5d', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const GMX_VAULT_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Avalanche]: '0x9ab2de34a33fb459b538c43f251eb825645e8595', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const PLATYPUS_ROUTER_BY_CHAIN_ID = valueByChainId<string>( | ||||
|     { | ||||
|         [ChainId.Avalanche]: '0x73256ec7575d999c360c1eec118ecbefd8da7d12', | ||||
|     }, | ||||
|     NULL_ADDRESS, | ||||
| ); | ||||
|  | ||||
| export const VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>( | ||||
|     { | ||||
| @@ -2297,6 +2491,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = { | ||||
|     [ERC20BridgeSource.IronSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule, | ||||
|     [ERC20BridgeSource.XSigma]: fillData => (fillData as CurveFillData).pool.gasSchedule, | ||||
|     [ERC20BridgeSource.FirebirdOneSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule, | ||||
|     [ERC20BridgeSource.MobiusMoney]: fillData => (fillData as CurveFillData).pool.gasSchedule, | ||||
|     [ERC20BridgeSource.MultiBridge]: () => 350e3, | ||||
|     [ERC20BridgeSource.UniswapV2]: uniswapV2CloneGasSchedule, | ||||
|     [ERC20BridgeSource.SushiSwap]: uniswapV2CloneGasSchedule, | ||||
| @@ -2349,11 +2544,34 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = { | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.UniswapV3]: (fillData?: FillData) => { | ||||
|         let gas = 100e3; | ||||
|         const path = (fillData as UniswapV3FillData).tokenAddressPath; | ||||
|         if (path.length > 2) { | ||||
|             gas += (path.length - 2) * 32e3; // +32k for each hop. | ||||
|         const uniFillData = fillData as UniswapV3FillData | FinalUniswapV3FillData; | ||||
|         // NOTE: This base value was heuristically chosen by looking at how much it generally | ||||
|         // underestimated gas usage | ||||
|         const base = 34e3; // 34k base | ||||
|         let gas = base; | ||||
|         if (isFinalUniswapV3FillData(uniFillData)) { | ||||
|             gas += uniFillData.gasUsed; | ||||
|         } else { | ||||
|             // NOTE: We don't actually know which of the paths would be used in the router | ||||
|             // therefore we estimate using the median of gas usage returned from UniswapV3 | ||||
|             // For the best case scenario (least amount of hops & ticks) this will | ||||
|             // overestimate the gas usage | ||||
|             const pathAmountsWithGasUsed = uniFillData.pathAmounts.filter(p => p.gasUsed > 0); | ||||
|             const medianGasUsedForPath = | ||||
|                 pathAmountsWithGasUsed[Math.floor(pathAmountsWithGasUsed.length / 2)]?.gasUsed ?? 0; | ||||
|             gas += medianGasUsedForPath; | ||||
|         } | ||||
|  | ||||
|         // If we for some reason could not read `gasUsed` when sampling | ||||
|         // fall back to legacy gas estimation | ||||
|         if (gas === base) { | ||||
|             gas = 100e3; | ||||
|             const path = uniFillData.tokenAddressPath; | ||||
|             if (path.length > 2) { | ||||
|                 gas += (path.length - 2) * 32e3; // +32k for each hop. | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return gas; | ||||
|     }, | ||||
|     [ERC20BridgeSource.Lido]: () => 226e3, | ||||
| @@ -2362,6 +2580,10 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = { | ||||
|         // NOTE: The Aave deposit method is more expensive than the withdraw | ||||
|         return aaveFillData.takerToken === aaveFillData.underlyingToken ? 400e3 : 300e3; | ||||
|     }, | ||||
|     [ERC20BridgeSource.Geist]: (fillData?: FillData) => { | ||||
|         const geistFillData = fillData as GeistFillData; | ||||
|         return geistFillData.takerToken === geistFillData.underlyingToken ? 400e3 : 300e3; | ||||
|     }, | ||||
|     [ERC20BridgeSource.Compound]: (fillData?: FillData) => { | ||||
|         // NOTE: cETH is handled differently than other cTokens | ||||
|         const wethAddress = NATIVE_FEE_TOKEN_BY_CHAIN_ID[ChainId.Mainnet]; | ||||
| @@ -2400,6 +2622,8 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = { | ||||
|     // | ||||
|     [ERC20BridgeSource.Pangolin]: uniswapV2CloneGasSchedule, | ||||
|     [ERC20BridgeSource.TraderJoe]: uniswapV2CloneGasSchedule, | ||||
|     [ERC20BridgeSource.GMX]: () => 450e3, | ||||
|     [ERC20BridgeSource.Platypus]: () => 450e3, | ||||
|  | ||||
|     // | ||||
|     // Celo | ||||
|   | ||||
| @@ -175,9 +175,9 @@ export function dexSamplesToFills( | ||||
|         const { source, fillData } = sample; | ||||
|         const input = sample.input.minus(prevSample ? prevSample.input : 0); | ||||
|         const output = sample.output.minus(prevSample ? prevSample.output : 0); | ||||
|         const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData) || 0; | ||||
|         let penalty = ZERO_AMOUNT; | ||||
|         if (i === 0) { | ||||
|             const fee = fees[source] === undefined ? 0 : fees[source]!(sample.fillData) || 0; | ||||
|             // Only the first fill in a DEX path incurs a penalty. | ||||
|             penalty = ethToOutputAmount({ | ||||
|                 input, | ||||
|   | ||||
| @@ -0,0 +1,36 @@ | ||||
| import { FANTOM_TOKENS, GEIST_FANTOM_POOLS } from './constants'; | ||||
| import { GeistInfo } from './types'; | ||||
|  | ||||
| const gTokenToUnderlyingToken = new Map<string, string>([ | ||||
|     [FANTOM_TOKENS.gFTM, FANTOM_TOKENS.WFTM], | ||||
|     [FANTOM_TOKENS.gfUSDT, FANTOM_TOKENS.fUSDT], | ||||
|     [FANTOM_TOKENS.gDAI, FANTOM_TOKENS.DAI], | ||||
|     [FANTOM_TOKENS.gUSDC, FANTOM_TOKENS.USDC], | ||||
|     [FANTOM_TOKENS.gETH, FANTOM_TOKENS.WETH], | ||||
|     [FANTOM_TOKENS.gWBTC, FANTOM_TOKENS.WBTC], | ||||
|     [FANTOM_TOKENS.gCRV, FANTOM_TOKENS.WCRV], | ||||
|     [FANTOM_TOKENS.gMIM, FANTOM_TOKENS.MIM], | ||||
| ]); | ||||
|  | ||||
| /** | ||||
|  * Returns GeistInfo for a certain pair if that pair exists on Geist | ||||
|  */ | ||||
| export function getGeistInfoForPair(takerToken: string, makerToken: string): GeistInfo | undefined { | ||||
|     let gToken; | ||||
|     let underlyingToken; | ||||
|     if (gTokenToUnderlyingToken.get(takerToken) === makerToken) { | ||||
|         gToken = takerToken; | ||||
|         underlyingToken = makerToken; | ||||
|     } else if (gTokenToUnderlyingToken.get(makerToken) === takerToken) { | ||||
|         gToken = makerToken; | ||||
|         underlyingToken = takerToken; | ||||
|     } else { | ||||
|         return undefined; | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         lendingPool: GEIST_FANTOM_POOLS.lendingPool, | ||||
|         gToken, | ||||
|         underlyingToken, | ||||
|     }; | ||||
| } | ||||
| @@ -42,7 +42,7 @@ import { createFills } from './fills'; | ||||
| import { getBestTwoHopQuote } from './multihop_utils'; | ||||
| import { createOrdersFromTwoHopSample } from './orders'; | ||||
| import { Path, PathPenaltyOpts } from './path'; | ||||
| import { fillsToSortedPaths, findOptimalPathJSAsync, findOptimalRustPathFromSamples } from './path_optimizer'; | ||||
| import { findOptimalPathJSAsync, findOptimalRustPathFromSamples } from './path_optimizer'; | ||||
| import { DexOrderSampler, getSampleAmounts } from './sampler'; | ||||
| import { SourceFilters } from './source_filters'; | ||||
| import { | ||||
| @@ -493,18 +493,6 @@ export class MarketOperationUtils { | ||||
|                 } as NativeOrderWithFillableAmounts), | ||||
|         ); | ||||
|  | ||||
|         // Convert native orders and dex quotes into `Fill` objects. | ||||
|         const fills = createFills({ | ||||
|             side, | ||||
|             orders: [...nativeOrders, ...augmentedRfqtIndicativeQuotes], | ||||
|             dexQuotes, | ||||
|             targetInput: inputAmount, | ||||
|             outputAmountPerEth, | ||||
|             inputAmountPerEth, | ||||
|             excludedSources: opts.excludedSources, | ||||
|             feeSchedule: opts.feeSchedule, | ||||
|         }); | ||||
|  | ||||
|         // Find the optimal path. | ||||
|         const penaltyOpts: PathPenaltyOpts = { | ||||
|             outputAmountPerEth, | ||||
| @@ -517,13 +505,11 @@ export class MarketOperationUtils { | ||||
|         const takerAmountPerEth = side === MarketOperation.Sell ? inputAmountPerEth : outputAmountPerEth; | ||||
|         const makerAmountPerEth = side === MarketOperation.Sell ? outputAmountPerEth : inputAmountPerEth; | ||||
|  | ||||
|         // Find the unoptimized best rate to calculate savings from optimizer | ||||
|         const _unoptimizedPath = fillsToSortedPaths(fills, side, inputAmount, penaltyOpts)[0]; | ||||
|         const unoptimizedPath = _unoptimizedPath ? _unoptimizedPath.collapse(orderOpts) : undefined; | ||||
|  | ||||
|         let fills: Fill[][]; | ||||
|         // Find the optimal path using Rust router if enabled, otherwise fallback to JS Router | ||||
|         let optimalPath: Path | undefined; | ||||
|         if (SHOULD_USE_RUST_ROUTER) { | ||||
|             fills = [[]]; | ||||
|             optimalPath = findOptimalRustPathFromSamples( | ||||
|                 side, | ||||
|                 dexQuotes, | ||||
| @@ -536,6 +522,18 @@ export class MarketOperationUtils { | ||||
|                 opts.samplerMetrics, | ||||
|             ); | ||||
|         } else { | ||||
|             // Convert native orders and dex quotes into `Fill` objects. | ||||
|             fills = createFills({ | ||||
|                 side, | ||||
|                 orders: [...nativeOrders, ...augmentedRfqtIndicativeQuotes], | ||||
|                 dexQuotes, | ||||
|                 targetInput: inputAmount, | ||||
|                 outputAmountPerEth, | ||||
|                 inputAmountPerEth, | ||||
|                 excludedSources: opts.excludedSources, | ||||
|                 feeSchedule: opts.feeSchedule, | ||||
|             }); | ||||
|  | ||||
|             optimalPath = await findOptimalPathJSAsync( | ||||
|                 side, | ||||
|                 fills, | ||||
| @@ -561,7 +559,6 @@ export class MarketOperationUtils { | ||||
|                 sourceFlags: SOURCE_FLAGS[ERC20BridgeSource.MultiHop], | ||||
|                 marketSideLiquidity, | ||||
|                 adjustedRate: bestTwoHopRate, | ||||
|                 unoptimizedPath, | ||||
|                 takerAmountPerEth, | ||||
|                 makerAmountPerEth, | ||||
|             }; | ||||
| @@ -573,7 +570,10 @@ export class MarketOperationUtils { | ||||
|         } | ||||
|  | ||||
|         // Generate a fallback path if required | ||||
|         await this._addOptionalFallbackAsync(side, inputAmount, optimalPath, dexQuotes, fills, opts, penaltyOpts); | ||||
|         // TODO(kimpers): Will experiment with disabling this and see how it affects revert rate | ||||
|         // to avoid yet another router roundtrip | ||||
|         // TODO: clean this up if we don't need it | ||||
|         // await this._addOptionalFallbackAsync(side, inputAmount, optimalPath, dexQuotes, fills, opts, penaltyOpts); | ||||
|         const collapsedPath = optimalPath.collapse(orderOpts); | ||||
|  | ||||
|         return { | ||||
| @@ -582,7 +582,6 @@ export class MarketOperationUtils { | ||||
|             sourceFlags: collapsedPath.sourceFlags, | ||||
|             marketSideLiquidity, | ||||
|             adjustedRate: optimalPathRate, | ||||
|             unoptimizedPath, | ||||
|             takerAmountPerEth, | ||||
|             makerAmountPerEth, | ||||
|         }; | ||||
| @@ -778,6 +777,8 @@ export class MarketOperationUtils { | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * TODO(kimpers): Remove this when we know that it's safe to drop the fallbacks on native orders | ||||
|     // tslint:disable-next-line: prefer-function-over-method | ||||
|     private async _addOptionalFallbackAsync( | ||||
|         side: MarketOperation, | ||||
| @@ -843,6 +844,7 @@ export class MarketOperationUtils { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     */ | ||||
| } | ||||
|  | ||||
| // tslint:disable: max-file-line-count | ||||
|   | ||||
| @@ -18,7 +18,9 @@ import { | ||||
|     ERC20BridgeSource, | ||||
|     FillData, | ||||
|     FinalUniswapV3FillData, | ||||
|     GeistFillData, | ||||
|     GenericRouterFillData, | ||||
|     GMXFillData, | ||||
|     KyberDmmFillData, | ||||
|     KyberFillData, | ||||
|     LidoFillData, | ||||
| @@ -33,9 +35,11 @@ import { | ||||
|     OptimizedMarketOrder, | ||||
|     OptimizedMarketOrderBase, | ||||
|     OrderDomain, | ||||
|     PlatypusFillData, | ||||
|     ShellFillData, | ||||
|     UniswapV2FillData, | ||||
|     UniswapV3FillData, | ||||
|     UniswapV3PathAmount, | ||||
| } from './types'; | ||||
|  | ||||
| // tslint:disable completed-docs | ||||
| @@ -202,6 +206,14 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s | ||||
|             return encodeBridgeSourceId(BridgeProtocol.AaveV2, 'AaveV2'); | ||||
|         case ERC20BridgeSource.Compound: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.Compound, 'Compound'); | ||||
|         case ERC20BridgeSource.Geist: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.AaveV2, 'Geist'); | ||||
|         case ERC20BridgeSource.MobiusMoney: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.Nerve, 'MobiusMoney'); | ||||
|         case ERC20BridgeSource.GMX: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.GMX, 'GMX'); | ||||
|         case ERC20BridgeSource.Platypus: | ||||
|             return encodeBridgeSourceId(BridgeProtocol.Platypus, 'Platypus'); | ||||
|         default: | ||||
|             throw new Error(AggregationError.NoBridgeForSource); | ||||
|     } | ||||
| @@ -237,6 +249,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder | ||||
|         case ERC20BridgeSource.FirebirdOneSwap: | ||||
|         case ERC20BridgeSource.IronSwap: | ||||
|         case ERC20BridgeSource.ACryptos: | ||||
|         case ERC20BridgeSource.MobiusMoney: | ||||
|             const curveFillData = (order as OptimizedMarketBridgeOrder<CurveFillData>).fillData; | ||||
|             bridgeData = encoder.encode([ | ||||
|                 curveFillData.pool.poolAddress, | ||||
| @@ -356,6 +369,27 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder | ||||
|             const compoundFillData = (order as OptimizedMarketBridgeOrder<CompoundFillData>).fillData; | ||||
|             bridgeData = encoder.encode([compoundFillData.cToken]); | ||||
|             break; | ||||
|         case ERC20BridgeSource.Geist: | ||||
|             const geistFillData = (order as OptimizedMarketBridgeOrder<GeistFillData>).fillData; | ||||
|             bridgeData = encoder.encode([geistFillData.lendingPool, geistFillData.gToken]); | ||||
|             break; | ||||
|         case ERC20BridgeSource.GMX: | ||||
|             const gmxFillData = (order as OptimizedMarketBridgeOrder<GMXFillData>).fillData; | ||||
|             bridgeData = encoder.encode([ | ||||
|                 gmxFillData.router, | ||||
|                 gmxFillData.reader, | ||||
|                 gmxFillData.vault, | ||||
|                 gmxFillData.tokenAddressPath, | ||||
|             ]); | ||||
|             break; | ||||
|         case ERC20BridgeSource.Platypus: | ||||
|             const platypusFillData = (order as OptimizedMarketBridgeOrder<PlatypusFillData>).fillData; | ||||
|             bridgeData = encoder.encode([ | ||||
|                 platypusFillData.router, | ||||
|                 platypusFillData.pool, | ||||
|                 platypusFillData.tokenAddressPath, | ||||
|             ]); | ||||
|             break; | ||||
|  | ||||
|         default: | ||||
|             throw new Error(AggregationError.NoBridgeForSource); | ||||
| @@ -387,11 +421,14 @@ function createFinalBridgeOrderFillDataFromCollapsedFill(fill: CollapsedFill): F | ||||
|     switch (fill.source) { | ||||
|         case ERC20BridgeSource.UniswapV3: { | ||||
|             const fd = fill.fillData as UniswapV3FillData; | ||||
|             return { | ||||
|             const { uniswapPath, gasUsed } = getBestUniswapV3PathAmountForInputAmount(fd, fill.input); | ||||
|             const finalFillData: FinalUniswapV3FillData = { | ||||
|                 router: fd.router, | ||||
|                 tokenAddressPath: fd.tokenAddressPath, | ||||
|                 uniswapPath: getBestUniswapV3PathForInputAmount(fd, fill.input), | ||||
|                 uniswapPath, | ||||
|                 gasUsed, | ||||
|             }; | ||||
|             return finalFillData; | ||||
|         } | ||||
|         default: | ||||
|             break; | ||||
| @@ -399,18 +436,21 @@ function createFinalBridgeOrderFillDataFromCollapsedFill(fill: CollapsedFill): F | ||||
|     return fill.fillData; | ||||
| } | ||||
|  | ||||
| function getBestUniswapV3PathForInputAmount(fillData: UniswapV3FillData, inputAmount: BigNumber): string { | ||||
| function getBestUniswapV3PathAmountForInputAmount( | ||||
|     fillData: UniswapV3FillData, | ||||
|     inputAmount: BigNumber, | ||||
| ): UniswapV3PathAmount { | ||||
|     if (fillData.pathAmounts.length === 0) { | ||||
|         throw new Error(`No Uniswap V3 paths`); | ||||
|     } | ||||
|     // Find the best path that can satisfy `inputAmount`. | ||||
|     // Assumes `fillData.pathAmounts` is sorted ascending. | ||||
|     for (const { inputAmount: pathInputAmount, uniswapPath } of fillData.pathAmounts) { | ||||
|         if (pathInputAmount.gte(inputAmount)) { | ||||
|             return uniswapPath; | ||||
|     for (const pathAmount of fillData.pathAmounts) { | ||||
|         if (pathAmount.inputAmount.gte(inputAmount)) { | ||||
|             return pathAmount; | ||||
|         } | ||||
|     } | ||||
|     return fillData.pathAmounts[fillData.pathAmounts.length - 1].uniswapPath; | ||||
|     return fillData.pathAmounts[fillData.pathAmounts.length - 1]; | ||||
| } | ||||
|  | ||||
| export function getMakerTakerTokens(opts: CreateOrderFromPathOpts): [string, string] { | ||||
| @@ -435,6 +475,8 @@ const balancerV2Encoder = AbiEncoder.create([ | ||||
|     { name: 'poolId', type: 'bytes32' }, | ||||
| ]); | ||||
| const routerAddressPathEncoder = AbiEncoder.create('(address,address[])'); | ||||
| const gmxAddressPathEncoder = AbiEncoder.create('(address,address,address,address[])'); | ||||
| const platypusAddressPathEncoder = AbiEncoder.create('(address,address[],address[])'); | ||||
| const tokenAddressEncoder = AbiEncoder.create([{ name: 'tokenAddress', type: 'address' }]); | ||||
|  | ||||
| export const BRIDGE_ENCODERS: { | ||||
| @@ -475,6 +517,7 @@ export const BRIDGE_ENCODERS: { | ||||
|     [ERC20BridgeSource.FirebirdOneSwap]: curveEncoder, | ||||
|     [ERC20BridgeSource.IronSwap]: curveEncoder, | ||||
|     [ERC20BridgeSource.ACryptos]: curveEncoder, | ||||
|     [ERC20BridgeSource.MobiusMoney]: curveEncoder, | ||||
|     // UniswapV2 like, (router, address[]) | ||||
|     [ERC20BridgeSource.Bancor]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.UniswapV2]: routerAddressPathEncoder, | ||||
| @@ -487,6 +530,9 @@ export const BRIDGE_ENCODERS: { | ||||
|     [ERC20BridgeSource.SpiritSwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.SpookySwap]: routerAddressPathEncoder, | ||||
|     [ERC20BridgeSource.MorpheusSwap]: routerAddressPathEncoder, | ||||
|     // Avalanche | ||||
|     [ERC20BridgeSource.GMX]: gmxAddressPathEncoder, | ||||
|     [ERC20BridgeSource.Platypus]: platypusAddressPathEncoder, | ||||
|     // Celo | ||||
|     [ERC20BridgeSource.UbeSwap]: routerAddressPathEncoder, | ||||
|     // BSC | ||||
| @@ -525,6 +571,7 @@ export const BRIDGE_ENCODERS: { | ||||
|     [ERC20BridgeSource.Lido]: AbiEncoder.create('(address)'), | ||||
|     [ERC20BridgeSource.AaveV2]: AbiEncoder.create('(address,address)'), | ||||
|     [ERC20BridgeSource.Compound]: AbiEncoder.create('(address)'), | ||||
|     [ERC20BridgeSource.Geist]: AbiEncoder.create('(address,address)'), | ||||
| }; | ||||
|  | ||||
| function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] { | ||||
|   | ||||
| @@ -122,17 +122,8 @@ export class Path { | ||||
|                 ++i; | ||||
|                 continue; | ||||
|             } | ||||
|             // If there are contiguous bridge orders, we can batch them together. | ||||
|             // TODO jacob pretty sure this is from DFB and we can remove | ||||
|             const contiguousBridgeFills = [collapsedFills[i]]; | ||||
|             for (let j = i + 1; j < collapsedFills.length; ++j) { | ||||
|                 if (collapsedFills[j].source === ERC20BridgeSource.Native) { | ||||
|                     break; | ||||
|                 } | ||||
|                 contiguousBridgeFills.push(collapsedFills[j]); | ||||
|             } | ||||
|  | ||||
|             this.orders.push(createBridgeOrder(contiguousBridgeFills[0], makerToken, takerToken, opts.side)); | ||||
|             this.orders.push(createBridgeOrder(collapsedFills[i], makerToken, takerToken, opts.side)); | ||||
|             i += 1; | ||||
|         } | ||||
|         return this as CollapsedPath; | ||||
|   | ||||
| @@ -21,6 +21,8 @@ const MIN_NUM_SAMPLE_INPUTS = 3; | ||||
|  | ||||
| const isDexSample = (obj: DexSample | NativeOrderWithFillableAmounts): obj is DexSample => !!(obj as DexSample).source; | ||||
|  | ||||
| const ONE_BASE_UNIT = new BigNumber(1); | ||||
|  | ||||
| function nativeOrderToNormalizedAmounts( | ||||
|     side: MarketOperation, | ||||
|     nativeOrder: NativeOrderWithFillableAmounts, | ||||
| @@ -74,7 +76,15 @@ function findRoutesAndCreateOptimalPath( | ||||
|     opts: PathPenaltyOpts, | ||||
|     fees: FeeSchedule, | ||||
|     neonRouterNumSamples: number, | ||||
| ): Path | undefined { | ||||
|     vipSourcesSet: Set<ERC20BridgeSource>, | ||||
| ): { allSourcesPath: Path | undefined; vipSourcesPath: Path | undefined } | undefined { | ||||
|     // Currently the rust router is unable to handle 1 base unit sized quotes and will error out | ||||
|     // To avoid flooding the logs with these errors we just return an insufficient liquidity error | ||||
|     // which is how the JS router handles these quotes today | ||||
|     if (input.isLessThanOrEqualTo(ONE_BASE_UNIT)) { | ||||
|         return undefined; | ||||
|     } | ||||
|  | ||||
|     const createFill = (sample: DexSample): Fill | undefined => { | ||||
|         const fills = dexSamplesToFills(side, [sample], opts.outputAmountPerEth, opts.inputAmountPerEth, fees); | ||||
|         // NOTE: If the sample has 0 output dexSamplesToFills will return [] because no fill can be created | ||||
| @@ -85,6 +95,127 @@ function findRoutesAndCreateOptimalPath( | ||||
|         return fills[0]; | ||||
|     }; | ||||
|  | ||||
|     const createPathFromStrategy = (sourcesRustRoute: Float64Array, sourcesOutputAmounts: Float64Array) => { | ||||
|         const routesAndSamplesAndOutputs = _.zip( | ||||
|             sourcesRustRoute, | ||||
|             samplesAndNativeOrdersWithResults, | ||||
|             sourcesOutputAmounts, | ||||
|             sampleSourcePathIds, | ||||
|         ); | ||||
|         const adjustedFills: Fill[] = []; | ||||
|         const totalRoutedAmount = BigNumber.sum(...sourcesRustRoute); | ||||
|  | ||||
|         const scale = input.dividedBy(totalRoutedAmount); | ||||
|         for (const [ | ||||
|             routeInput, | ||||
|             routeSamplesAndNativeOrders, | ||||
|             outputAmount, | ||||
|             sourcePathId, | ||||
|         ] of routesAndSamplesAndOutputs) { | ||||
|             if (!Number.isFinite(outputAmount)) { | ||||
|                 DEFAULT_WARNING_LOGGER(rustArgs, `neon-router: invalid route outputAmount ${outputAmount}`); | ||||
|                 return undefined; | ||||
|             } | ||||
|             if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount) { | ||||
|                 continue; | ||||
|             } | ||||
|             // TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64 | ||||
|             // we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much | ||||
|             const rustInputAdjusted = BigNumber.min( | ||||
|                 new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL), | ||||
|                 input, | ||||
|             ); | ||||
|  | ||||
|             const current = routeSamplesAndNativeOrders[routeSamplesAndNativeOrders.length - 1]; | ||||
|             if (!isDexSample(current)) { | ||||
|                 const nativeFill = nativeOrdersToFills( | ||||
|                     side, | ||||
|                     [current], | ||||
|                     rustInputAdjusted, | ||||
|                     opts.outputAmountPerEth, | ||||
|                     opts.inputAmountPerEth, | ||||
|                     fees, | ||||
|                     false, | ||||
|                 )[0] as Fill | undefined; | ||||
|                 // Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped | ||||
|                 // and nativeFill will be `undefined` | ||||
|                 if (nativeFill) { | ||||
|                     // NOTE: For Limit/RFQ orders we are done here. No need to scale output | ||||
|                     adjustedFills.push({ ...nativeFill, sourcePathId: sourcePathId ?? hexUtils.random() }); | ||||
|                 } | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             // NOTE: For DexSamples only | ||||
|             let fill = createFill(current); | ||||
|             if (!fill) { | ||||
|                 continue; | ||||
|             } | ||||
|             const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>; | ||||
|             // Descend to approach a closer fill for fillData which may not be consistent | ||||
|             // throughout the path (UniswapV3) and for a closer guesstimate at | ||||
|             // gas used | ||||
|  | ||||
|             assert.assert(routeSamples.length >= 1, 'Found no sample to use for source'); | ||||
|             for (let k = routeSamples.length - 1; k >= 0; k--) { | ||||
|                 if (k === 0) { | ||||
|                     fill = createFill(routeSamples[0]) ?? fill; | ||||
|                 } | ||||
|                 if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) { | ||||
|                     const left = routeSamples[k]; | ||||
|                     const right = routeSamples[k + 1]; | ||||
|                     if (left && right) { | ||||
|                         fill = | ||||
|                             createFill({ | ||||
|                                 ...right, // default to the greater (for gas used) | ||||
|                                 input: rustInputAdjusted, | ||||
|                                 output: new BigNumber(outputAmount), | ||||
|                             }) ?? fill; | ||||
|                     } else { | ||||
|                         assert.assert(Boolean(left || right), 'No valid sample to use'); | ||||
|                         fill = createFill(left || right) ?? fill; | ||||
|                     } | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // TODO(kimpers): remove once we have solved the rounding/precision loss issues in the Rust router | ||||
|             const maxSampledOutput = BigNumber.max(...routeSamples.map(s => s.output)); | ||||
|             // Scale output by scale factor but never go above the largest sample in sell quotes (unknown liquidity)  or below 1 base unit (unfillable) | ||||
|             const scaleOutput = (output: BigNumber) => { | ||||
|                 // Don't try to scale 0 output as it will be clamped to 1 | ||||
|                 if (output.eq(ZERO_AMOUNT)) { | ||||
|                     return output; | ||||
|                 } | ||||
|  | ||||
|                 const scaled = output | ||||
|                     .times(scale) | ||||
|                     .decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL); | ||||
|                 const capped = MarketOperation.Sell ? BigNumber.min(scaled, maxSampledOutput) : scaled; | ||||
|  | ||||
|                 return BigNumber.max(capped, 1); | ||||
|             }; | ||||
|  | ||||
|             adjustedFills.push({ | ||||
|                 ...fill, | ||||
|                 input: rustInputAdjusted, | ||||
|                 output: scaleOutput(fill.output), | ||||
|                 adjustedOutput: scaleOutput(fill.adjustedOutput), | ||||
|                 index: 0, | ||||
|                 parent: undefined, | ||||
|                 sourcePathId: sourcePathId ?? hexUtils.random(), | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         if (adjustedFills.length === 0) { | ||||
|             return undefined; | ||||
|         } | ||||
|  | ||||
|         const pathFromRustInputs = Path.create(side, adjustedFills, input, opts); | ||||
|  | ||||
|         return pathFromRustInputs; | ||||
|     }; | ||||
|  | ||||
|     const samplesAndNativeOrdersWithResults: Array<DexSample[] | NativeOrderWithFillableAmounts[]> = []; | ||||
|     const serializedPaths: SerializedPath[] = []; | ||||
|     const sampleSourcePathIds: string[] = []; | ||||
| @@ -127,6 +258,7 @@ function findRoutesAndCreateOptimalPath( | ||||
|                 inputs: [], | ||||
|                 outputs: [], | ||||
|                 outputFees: [], | ||||
|                 isVip: vipSourcesSet.has(singleSourceSamplesWithOutput[0]?.source), | ||||
|             }, | ||||
|         ); | ||||
|  | ||||
| @@ -155,12 +287,24 @@ function findRoutesAndCreateOptimalPath( | ||||
|         const inputs = []; | ||||
|         const outputs = []; | ||||
|         const outputFees = []; | ||||
|         // NOTE: We start at 0 here because the native order might be much larger than the amount | ||||
|         // By starting at 0 we make sure we can always use a portion of the native order to fill/partial fill | ||||
|         for (let i = 0; i <= 12; i++) { | ||||
|             const fraction = i / 12; | ||||
|             const currentInput = BigNumber.min(normalizedOrderInput.times(fraction), normalizedOrderInput); | ||||
|             const currentOutput = BigNumber.min(normalizedOrderOutput.times(fraction), normalizedOrderOutput); | ||||
|  | ||||
|         // NOTE: Limit orders can be both larger or smaller than the input amount | ||||
|         // If the order is larger than the input we can scale the order to the size of | ||||
|         // the quote input (order pricing is constant) and then create 13 "samples" up to | ||||
|         // and including the full quote input amount. | ||||
|         // If the order is smaller we don't need to scale anything, we will just end up | ||||
|         // with trailing duplicate samples for the order input as we cannot go higher | ||||
|         const scaleToInput = BigNumber.min(input.dividedBy(normalizedOrderInput), 1); | ||||
|         for (let i = 1; i <= 13; i++) { | ||||
|             const fraction = i / 13; | ||||
|             const currentInput = BigNumber.min( | ||||
|                 normalizedOrderInput.times(scaleToInput).times(fraction), | ||||
|                 normalizedOrderInput, | ||||
|             ); | ||||
|             const currentOutput = BigNumber.min( | ||||
|                 normalizedOrderOutput.times(scaleToInput).times(fraction), | ||||
|                 normalizedOrderOutput, | ||||
|             ); | ||||
|             const id = `${ERC20BridgeSource.Native}-${serializedPaths.length}-${idx}-${i}`; | ||||
|             inputs.push(currentInput.integerValue().toNumber()); | ||||
|             outputs.push(currentOutput.integerValue().toNumber()); | ||||
| @@ -173,6 +317,7 @@ function findRoutesAndCreateOptimalPath( | ||||
|             inputs, | ||||
|             outputs, | ||||
|             outputFees, | ||||
|             isVip: true, | ||||
|         }; | ||||
|  | ||||
|         samplesAndNativeOrdersWithResults.push([nativeOrder]); | ||||
| @@ -191,129 +336,42 @@ function findRoutesAndCreateOptimalPath( | ||||
|     }; | ||||
|  | ||||
|     const allSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length); | ||||
|     const strategySourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length); | ||||
|     route(rustArgs, allSourcesRustRoute, strategySourcesOutputAmounts, neonRouterNumSamples); | ||||
|     const allSourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length); | ||||
|     const vipSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length); | ||||
|     const vipSourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length); | ||||
|  | ||||
|     route( | ||||
|         rustArgs, | ||||
|         allSourcesRustRoute, | ||||
|         allSourcesOutputAmounts, | ||||
|         vipSourcesRustRoute, | ||||
|         vipSourcesOutputAmounts, | ||||
|         neonRouterNumSamples, | ||||
|     ); | ||||
|     assert.assert( | ||||
|         rustArgs.pathsIn.length === allSourcesRustRoute.length, | ||||
|         'different number of sources in the Router output than the input', | ||||
|     ); | ||||
|     assert.assert( | ||||
|         rustArgs.pathsIn.length === strategySourcesOutputAmounts.length, | ||||
|         rustArgs.pathsIn.length === allSourcesOutputAmounts.length, | ||||
|         'different number of sources in the Router output amounts results than the input', | ||||
|     ); | ||||
|     assert.assert( | ||||
|         rustArgs.pathsIn.length === vipSourcesRustRoute.length, | ||||
|         'different number of sources in the Router output than the input', | ||||
|     ); | ||||
|     assert.assert( | ||||
|         rustArgs.pathsIn.length === vipSourcesOutputAmounts.length, | ||||
|         'different number of sources in the Router output amounts results than the input', | ||||
|     ); | ||||
|  | ||||
|     const routesAndSamplesAndOutputs = _.zip( | ||||
|         allSourcesRustRoute, | ||||
|         samplesAndNativeOrdersWithResults, | ||||
|         strategySourcesOutputAmounts, | ||||
|         sampleSourcePathIds, | ||||
|     ); | ||||
|     const adjustedFills: Fill[] = []; | ||||
|     const totalRoutedAmount = BigNumber.sum(...allSourcesRustRoute); | ||||
|     const allSourcesPath = createPathFromStrategy(allSourcesRustRoute, allSourcesOutputAmounts); | ||||
|     const vipSourcesPath = createPathFromStrategy(vipSourcesRustRoute, vipSourcesOutputAmounts); | ||||
|  | ||||
|     const scale = input.dividedBy(totalRoutedAmount); | ||||
|     for (const [routeInput, routeSamplesAndNativeOrders, outputAmount, sourcePathId] of routesAndSamplesAndOutputs) { | ||||
|         if (!Number.isFinite(outputAmount)) { | ||||
|             DEFAULT_WARNING_LOGGER(rustArgs, `neon-router: invalid route outputAmount ${outputAmount}`); | ||||
|             return undefined; | ||||
|         } | ||||
|         if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount) { | ||||
|             continue; | ||||
|         } | ||||
|         // TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64 | ||||
|         // we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much | ||||
|         const rustInputAdjusted = BigNumber.min( | ||||
|             new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL), | ||||
|             input, | ||||
|         ); | ||||
|  | ||||
|         const current = routeSamplesAndNativeOrders[routeSamplesAndNativeOrders.length - 1]; | ||||
|         if (!isDexSample(current)) { | ||||
|             const nativeFill = nativeOrdersToFills( | ||||
|                 side, | ||||
|                 [current], | ||||
|                 rustInputAdjusted, | ||||
|                 opts.outputAmountPerEth, | ||||
|                 opts.inputAmountPerEth, | ||||
|                 fees, | ||||
|                 false, | ||||
|             )[0] as Fill | undefined; | ||||
|             // Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped | ||||
|             // and nativeFill will be `undefined` | ||||
|             if (nativeFill) { | ||||
|                 // NOTE: For Limit/RFQ orders we are done here. No need to scale output | ||||
|                 adjustedFills.push({ ...nativeFill, sourcePathId: sourcePathId ?? hexUtils.random() }); | ||||
|             } | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         // NOTE: For DexSamples only | ||||
|         let fill = createFill(current); | ||||
|         if (!fill) { | ||||
|             continue; | ||||
|         } | ||||
|         const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>; | ||||
|         // Descend to approach a closer fill for fillData which may not be consistent | ||||
|         // throughout the path (UniswapV3) and for a closer guesstimate at | ||||
|         // gas used | ||||
|  | ||||
|         assert.assert(routeSamples.length >= 1, 'Found no sample to use for source'); | ||||
|         for (let k = routeSamples.length - 1; k >= 0; k--) { | ||||
|             if (k === 0) { | ||||
|                 fill = createFill(routeSamples[0]) ?? fill; | ||||
|             } | ||||
|             if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) { | ||||
|                 const left = routeSamples[k]; | ||||
|                 const right = routeSamples[k + 1]; | ||||
|                 if (left && right) { | ||||
|                     fill = | ||||
|                         createFill({ | ||||
|                             ...right, // default to the greater (for gas used) | ||||
|                             input: rustInputAdjusted, | ||||
|                             output: new BigNumber(outputAmount), | ||||
|                         }) ?? fill; | ||||
|                 } else { | ||||
|                     assert.assert(Boolean(left || right), 'No valid sample to use'); | ||||
|                     fill = createFill(left || right) ?? fill; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // TODO(kimpers): remove once we have solved the rounding/precision loss issues in the Rust router | ||||
|         const maxSampledOutput = BigNumber.max(...routeSamples.map(s => s.output)); | ||||
|         // Scale output by scale factor but never go above the largest sample (unknown liquidity) or below 1 base unit (unfillable) | ||||
|         const scaleOutput = (output: BigNumber) => { | ||||
|             // Don't try to scale 0 output as it will be clamped to 1 | ||||
|             if (output.eq(ZERO_AMOUNT)) { | ||||
|                 return output; | ||||
|             } | ||||
|  | ||||
|             const scaled = output | ||||
|                 .times(scale) | ||||
|                 .decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL); | ||||
|  | ||||
|             return BigNumber.max(BigNumber.min(scaled, maxSampledOutput), 1); | ||||
|         }; | ||||
|  | ||||
|         adjustedFills.push({ | ||||
|             ...fill, | ||||
|             input: rustInputAdjusted, | ||||
|             output: scaleOutput(fill.output), | ||||
|             adjustedOutput: scaleOutput(fill.adjustedOutput), | ||||
|             index: 0, | ||||
|             parent: undefined, | ||||
|             sourcePathId: sourcePathId ?? hexUtils.random(), | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     if (adjustedFills.length === 0) { | ||||
|         return undefined; | ||||
|     } | ||||
|  | ||||
|     const pathFromRustInputs = Path.create(side, adjustedFills, input, opts); | ||||
|  | ||||
|     return pathFromRustInputs; | ||||
|     return { | ||||
|         allSourcesPath, | ||||
|         vipSourcesPath, | ||||
|     }; | ||||
| } | ||||
|  | ||||
| export function findOptimalRustPathFromSamples( | ||||
| @@ -327,9 +385,18 @@ export function findOptimalRustPathFromSamples( | ||||
|     neonRouterNumSamples: number, | ||||
|     samplerMetrics?: SamplerMetrics, | ||||
| ): Path | undefined { | ||||
|     const beforeAllTimeMs = performance.now(); | ||||
|     let beforeTimeMs = performance.now(); | ||||
|     const allSourcesPath = findRoutesAndCreateOptimalPath( | ||||
|     const beforeTimeMs = performance.now(); | ||||
|     const sendMetrics = () => { | ||||
|         // tslint:disable-next-line: no-unused-expression | ||||
|         samplerMetrics && | ||||
|             samplerMetrics.logRouterDetails({ | ||||
|                 router: 'neon-router', | ||||
|                 type: 'total', | ||||
|                 timingMs: performance.now() - beforeTimeMs, | ||||
|             }); | ||||
|     }; | ||||
|     const vipSourcesSet = new Set(VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID[chainId]); | ||||
|     const paths = findRoutesAndCreateOptimalPath( | ||||
|         side, | ||||
|         samples, | ||||
|         nativeOrders, | ||||
| @@ -337,58 +404,22 @@ export function findOptimalRustPathFromSamples( | ||||
|         opts, | ||||
|         fees, | ||||
|         neonRouterNumSamples, | ||||
|         vipSourcesSet, | ||||
|     ); | ||||
|     // tslint:disable-next-line: no-unused-expression | ||||
|     samplerMetrics && | ||||
|         samplerMetrics.logRouterDetails({ | ||||
|             router: 'neon-router', | ||||
|             type: 'all', | ||||
|             timingMs: performance.now() - beforeTimeMs, | ||||
|         }); | ||||
|     if (!allSourcesPath) { | ||||
|  | ||||
|     if (!paths) { | ||||
|         sendMetrics(); | ||||
|         return undefined; | ||||
|     } | ||||
|  | ||||
|     const vipSources = VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID[chainId]; | ||||
|     const { allSourcesPath, vipSourcesPath } = paths; | ||||
|  | ||||
|     // HACK(kimpers): The Rust router currently doesn't account for VIP sources correctly | ||||
|     // we need to try to route them in isolation and compare with the results all sources | ||||
|     if (vipSources.length > 0) { | ||||
|         beforeTimeMs = performance.now(); | ||||
|         const vipSourcesSet = new Set(vipSources); | ||||
|         const vipSourcesSamples = samples.filter(s => s[0] && vipSourcesSet.has(s[0].source)); | ||||
|  | ||||
|         if (vipSourcesSamples.length > 0) { | ||||
|             const vipSourcesPath = findRoutesAndCreateOptimalPath( | ||||
|                 side, | ||||
|                 vipSourcesSamples, | ||||
|                 [], | ||||
|                 input, | ||||
|                 opts, | ||||
|                 fees, | ||||
|                 neonRouterNumSamples, | ||||
|             ); | ||||
|             // tslint:disable-next-line: no-unused-expression | ||||
|             samplerMetrics && | ||||
|                 samplerMetrics.logRouterDetails({ | ||||
|                     router: 'neon-router', | ||||
|                     type: 'vip', | ||||
|                     timingMs: performance.now() - beforeTimeMs, | ||||
|                 }); | ||||
|  | ||||
|             if (vipSourcesPath?.isBetterThan(allSourcesPath)) { | ||||
|                 return vipSourcesPath; | ||||
|             } | ||||
|         } | ||||
|     if (!allSourcesPath || vipSourcesPath?.isBetterThan(allSourcesPath)) { | ||||
|         sendMetrics(); | ||||
|         return vipSourcesPath; | ||||
|     } | ||||
|     // tslint:disable-next-line: no-unused-expression | ||||
|     samplerMetrics && | ||||
|         samplerMetrics.logRouterDetails({ | ||||
|             router: 'neon-router', | ||||
|             type: 'total', | ||||
|             timingMs: performance.now() - beforeAllTimeMs, | ||||
|         }); | ||||
|  | ||||
|     sendMetrics(); | ||||
|     return allSourcesPath; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { BigNumber, logUtils } from '@0x/utils'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { AaveV2Sampler } from '../../noop_samplers/AaveV2Sampler'; | ||||
| import { GeistSampler } from '../../noop_samplers/GeistSampler'; | ||||
| import { SamplerCallResult, SignedNativeOrder } from '../../types'; | ||||
| import { ERC20BridgeSamplerContract } from '../../wrappers'; | ||||
|  | ||||
| @@ -13,6 +14,7 @@ import { | ||||
|     getCurveLikeInfosForPair, | ||||
|     getDodoV2Offsets, | ||||
|     getKyberOffsets, | ||||
|     getPlatypusInfoForPair, | ||||
|     getShellLikeInfosForPair, | ||||
|     isAllowedKyberReserveId, | ||||
|     isBadTokenForSource, | ||||
| @@ -29,6 +31,9 @@ import { | ||||
|     COMPOUND_API_URL_BY_CHAIN_ID, | ||||
|     DODOV1_CONFIG_BY_CHAIN_ID, | ||||
|     DODOV2_FACTORIES_BY_CHAIN_ID, | ||||
|     GMX_READER_BY_CHAIN_ID, | ||||
|     GMX_ROUTER_BY_CHAIN_ID, | ||||
|     GMX_VAULT_BY_CHAIN_ID, | ||||
|     KYBER_CONFIG_BY_CHAIN_ID, | ||||
|     KYBER_DMM_ROUTER_BY_CHAIN_ID, | ||||
|     LIDO_INFO_BY_CHAIN, | ||||
| @@ -41,11 +46,13 @@ import { | ||||
|     NATIVE_FEE_TOKEN_BY_CHAIN_ID, | ||||
|     NULL_ADDRESS, | ||||
|     NULL_BYTES, | ||||
|     PLATYPUS_ROUTER_BY_CHAIN_ID, | ||||
|     SELL_SOURCE_FILTER_BY_CHAIN_ID, | ||||
|     UNISWAPV1_ROUTER_BY_CHAIN_ID, | ||||
|     UNISWAPV3_CONFIG_BY_CHAIN_ID, | ||||
|     ZERO_AMOUNT, | ||||
| } from './constants'; | ||||
| import { getGeistInfoForPair } from './geist_utils'; | ||||
| import { getLiquidityProvidersForPair } from './liquidity_provider_utils'; | ||||
| import { getIntermediateTokens } from './multihop_utils'; | ||||
| import { BalancerPoolsCache, BalancerV2PoolsCache, CreamPoolsCache, PoolsCache } from './pools_cache'; | ||||
| @@ -66,7 +73,10 @@ import { | ||||
|     DexSample, | ||||
|     DODOFillData, | ||||
|     ERC20BridgeSource, | ||||
|     GeistFillData, | ||||
|     GeistInfo, | ||||
|     GenericRouterFillData, | ||||
|     GMXFillData, | ||||
|     HopInfo, | ||||
|     KyberDmmFillData, | ||||
|     KyberFillData, | ||||
| @@ -78,6 +88,7 @@ import { | ||||
|     MakerPsmFillData, | ||||
|     MooniswapFillData, | ||||
|     MultiHopFillData, | ||||
|     PlatypusFillData, | ||||
|     PsmInfo, | ||||
|     ShellFillData, | ||||
|     SourceQuoteOperation, | ||||
| @@ -767,16 +778,17 @@ export class SamplerOperations { | ||||
|             function: this._samplerContract.sampleSellsFromUniswapV3, | ||||
|             params: [quoter, tokenAddressPath, takerFillAmounts], | ||||
|             callback: (callResults: string, fillData: UniswapV3FillData): BigNumber[] => { | ||||
|                 const [paths, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>( | ||||
|                     'sampleSellsFromUniswapV3', | ||||
|                     callResults, | ||||
|                 ); | ||||
|                 const [paths, gasUsed, samples] = this._samplerContract.getABIDecodedReturnData< | ||||
|                     [string[], BigNumber[], BigNumber[]] | ||||
|                 >('sampleSellsFromUniswapV3', callResults); | ||||
|                 fillData.router = router; | ||||
|                 fillData.tokenAddressPath = tokenAddressPath; | ||||
|                 fillData.pathAmounts = paths.map((uniswapPath, i) => ({ | ||||
|                     uniswapPath, | ||||
|                     inputAmount: takerFillAmounts[i], | ||||
|                     gasUsed: gasUsed[i].toNumber(), | ||||
|                 })); | ||||
|  | ||||
|                 return samples; | ||||
|             }, | ||||
|         }); | ||||
| @@ -795,15 +807,15 @@ export class SamplerOperations { | ||||
|             function: this._samplerContract.sampleBuysFromUniswapV3, | ||||
|             params: [quoter, tokenAddressPath, makerFillAmounts], | ||||
|             callback: (callResults: string, fillData: UniswapV3FillData): BigNumber[] => { | ||||
|                 const [paths, samples] = this._samplerContract.getABIDecodedReturnData<[string[], BigNumber[]]>( | ||||
|                     'sampleBuysFromUniswapV3', | ||||
|                     callResults, | ||||
|                 ); | ||||
|                 const [paths, gasUsed, samples] = this._samplerContract.getABIDecodedReturnData< | ||||
|                     [string[], BigNumber[], BigNumber[]] | ||||
|                 >('sampleBuysFromUniswapV3', callResults); | ||||
|                 fillData.router = router; | ||||
|                 fillData.tokenAddressPath = tokenAddressPath; | ||||
|                 fillData.pathAmounts = paths.map((uniswapPath, i) => ({ | ||||
|                     uniswapPath, | ||||
|                     inputAmount: makerFillAmounts[i], | ||||
|                     gasUsed: gasUsed[i].toNumber(), | ||||
|                 })); | ||||
|                 return samples; | ||||
|             }, | ||||
| @@ -1151,6 +1163,34 @@ export class SamplerOperations { | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     // tslint:disable-next-line:prefer-function-over-method | ||||
|     public getGeistSellQuotes( | ||||
|         geistInfo: GeistInfo, | ||||
|         makerToken: string, | ||||
|         takerToken: string, | ||||
|         takerFillAmounts: BigNumber[], | ||||
|     ): SourceQuoteOperation<GeistFillData> { | ||||
|         return new SamplerNoOperation({ | ||||
|             source: ERC20BridgeSource.Geist, | ||||
|             fillData: { ...geistInfo, takerToken }, | ||||
|             callback: () => GeistSampler.sampleSellsFromGeist(geistInfo, takerToken, makerToken, takerFillAmounts), | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     // tslint:disable-next-line:prefer-function-over-method | ||||
|     public getGeistBuyQuotes( | ||||
|         geistInfo: GeistInfo, | ||||
|         makerToken: string, | ||||
|         takerToken: string, | ||||
|         makerFillAmounts: BigNumber[], | ||||
|     ): SourceQuoteOperation<GeistFillData> { | ||||
|         return new SamplerNoOperation({ | ||||
|             source: ERC20BridgeSource.Geist, | ||||
|             fillData: { ...geistInfo, takerToken }, | ||||
|             callback: () => GeistSampler.sampleBuysFromGeist(geistInfo, takerToken, makerToken, makerFillAmounts), | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public getCompoundSellQuotes( | ||||
|         cToken: string, | ||||
|         makerToken: string, | ||||
| @@ -1180,6 +1220,65 @@ export class SamplerOperations { | ||||
|             params: [cToken, takerToken, makerToken, makerFillAmounts], | ||||
|         }); | ||||
|     } | ||||
|     public getGMXSellQuotes( | ||||
|         router: string, | ||||
|         reader: string, | ||||
|         vault: string, | ||||
|         tokenAddressPath: string[], | ||||
|         takerFillAmounts: BigNumber[], | ||||
|     ): SourceQuoteOperation<GMXFillData> { | ||||
|         return new SamplerContractOperation({ | ||||
|             source: ERC20BridgeSource.GMX, | ||||
|             fillData: { router, reader, vault, tokenAddressPath }, | ||||
|             contract: this._samplerContract, | ||||
|             function: this._samplerContract.sampleSellsFromGMX, | ||||
|             params: [reader, vault, tokenAddressPath, takerFillAmounts], | ||||
|         }); | ||||
|     } | ||||
|     public getGMXBuyQuotes( | ||||
|         router: string, | ||||
|         reader: string, | ||||
|         vault: string, | ||||
|         tokenAddressPath: string[], | ||||
|         makerFillAmounts: BigNumber[], | ||||
|     ): SourceQuoteOperation<GMXFillData> { | ||||
|         return new SamplerContractOperation({ | ||||
|             source: ERC20BridgeSource.GMX, | ||||
|             fillData: { router, reader, vault, tokenAddressPath }, | ||||
|             contract: this._samplerContract, | ||||
|             function: this._samplerContract.sampleBuysFromGMX, | ||||
|             params: [reader, vault, tokenAddressPath, makerFillAmounts], | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public getPlatypusSellQuotes( | ||||
|         router: string, | ||||
|         pool: string[], | ||||
|         tokenAddressPath: string[], | ||||
|         takerFillAmounts: BigNumber[], | ||||
|     ): SourceQuoteOperation<PlatypusFillData> { | ||||
|         return new SamplerContractOperation({ | ||||
|             source: ERC20BridgeSource.Platypus, | ||||
|             fillData: { router, pool, tokenAddressPath }, | ||||
|             contract: this._samplerContract, | ||||
|             function: this._samplerContract.sampleSellsFromPlatypus, | ||||
|             params: [router, tokenAddressPath, pool, takerFillAmounts], | ||||
|         }); | ||||
|     } | ||||
|     public getPlatypusBuyQuotes( | ||||
|         router: string, | ||||
|         pool: string[], | ||||
|         tokenAddressPath: string[], | ||||
|         makerFillAmounts: BigNumber[], | ||||
|     ): SourceQuoteOperation<PlatypusFillData> { | ||||
|         return new SamplerContractOperation({ | ||||
|             source: ERC20BridgeSource.Platypus, | ||||
|             fillData: { router, tokenAddressPath, pool }, | ||||
|             contract: this._samplerContract, | ||||
|             function: this._samplerContract.sampleBuysFromPlatypus, | ||||
|             params: [router, tokenAddressPath, pool, makerFillAmounts], | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     public getMedianSellRate( | ||||
|         sources: ERC20BridgeSource[], | ||||
| @@ -1350,6 +1449,7 @@ export class SamplerOperations { | ||||
|                     case ERC20BridgeSource.FirebirdOneSwap: | ||||
|                     case ERC20BridgeSource.IronSwap: | ||||
|                     case ERC20BridgeSource.ACryptos: | ||||
|                     case ERC20BridgeSource.MobiusMoney: | ||||
|                         return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool => | ||||
|                             this.getCurveSellQuotes( | ||||
|                                 pool, | ||||
| @@ -1548,6 +1648,13 @@ export class SamplerOperations { | ||||
|                         }; | ||||
|                         return this.getAaveV2SellQuotes(info, makerToken, takerToken, takerFillAmounts); | ||||
|                     } | ||||
|                     case ERC20BridgeSource.Geist: { | ||||
|                         const info: GeistInfo | undefined = getGeistInfoForPair(takerToken, makerToken); | ||||
|                         if (!info) { | ||||
|                             return []; | ||||
|                         } | ||||
|                         return this.getGeistSellQuotes(info, makerToken, takerToken, takerFillAmounts); | ||||
|                     } | ||||
|                     case ERC20BridgeSource.Compound: { | ||||
|                         if (!this.compoundCTokenCache) { | ||||
|                             return []; | ||||
| @@ -1564,8 +1671,28 @@ export class SamplerOperations { | ||||
|                             takerFillAmounts, | ||||
|                         ); | ||||
|                     } | ||||
|                     default: | ||||
|                         throw new Error(`Unsupported sell sample source: ${source}`); | ||||
|                     case ERC20BridgeSource.GMX: { | ||||
|                         return this.getGMXSellQuotes( | ||||
|                             GMX_ROUTER_BY_CHAIN_ID[this.chainId], | ||||
|                             GMX_READER_BY_CHAIN_ID[this.chainId], | ||||
|                             GMX_VAULT_BY_CHAIN_ID[this.chainId], | ||||
|                             [takerToken, makerToken], | ||||
|                             takerFillAmounts, | ||||
|                         ); | ||||
|                     } | ||||
|                     case ERC20BridgeSource.Platypus: { | ||||
|                         return getPlatypusInfoForPair(this.chainId, takerToken, makerToken).map(pool => | ||||
|                             this.getPlatypusSellQuotes( | ||||
|                             PLATYPUS_ROUTER_BY_CHAIN_ID[this.chainId], | ||||
|                             pool.poolAddress, | ||||
|                             pool.tokens, | ||||
|                             takerFillAmounts, | ||||
|                             ), | ||||
|                         ); | ||||
|                     } | ||||
|                 default: | ||||
|                     throw new Error(`Unsupported sell sample source: ${source}`); | ||||
|  | ||||
|                 } | ||||
|             }), | ||||
|         ); | ||||
| @@ -1578,7 +1705,7 @@ export class SamplerOperations { | ||||
|         takerToken: string, | ||||
|         makerFillAmounts: BigNumber[], | ||||
|     ): SourceQuoteOperation[] { | ||||
|         // Find the adjacent tokens in the provided tooken adjacency graph, | ||||
|         // Find the adjacent tokens in the provided token adjacency graph, | ||||
|         // e.g if this is DAI->USDC we may check for DAI->WETH->USDC | ||||
|         const intermediateTokens = getIntermediateTokens(makerToken, takerToken, this.tokenAdjacencyGraph); | ||||
|         const _sources = BATCH_SOURCE_FILTERS.getAllowed(sources); | ||||
| @@ -1656,6 +1783,7 @@ export class SamplerOperations { | ||||
|                     case ERC20BridgeSource.FirebirdOneSwap: | ||||
|                     case ERC20BridgeSource.IronSwap: | ||||
|                     case ERC20BridgeSource.ACryptos: | ||||
|                     case ERC20BridgeSource.MobiusMoney: | ||||
|                         return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool => | ||||
|                             this.getCurveBuyQuotes( | ||||
|                                 pool, | ||||
| @@ -1849,6 +1977,13 @@ export class SamplerOperations { | ||||
|                         }; | ||||
|                         return this.getAaveV2BuyQuotes(info, makerToken, takerToken, makerFillAmounts); | ||||
|                     } | ||||
|                     case ERC20BridgeSource.Geist: { | ||||
|                         const info: GeistInfo | undefined = getGeistInfoForPair(takerToken, makerToken); | ||||
|                         if (!info) { | ||||
|                             return []; | ||||
|                         } | ||||
|                         return this.getGeistBuyQuotes(info, makerToken, takerToken, makerFillAmounts); | ||||
|                     } | ||||
|                     case ERC20BridgeSource.Compound: { | ||||
|                         if (!this.compoundCTokenCache) { | ||||
|                             return []; | ||||
| @@ -1860,6 +1995,25 @@ export class SamplerOperations { | ||||
|                         } | ||||
|                         return this.getCompoundBuyQuotes(cToken.tokenAddress, makerToken, takerToken, makerFillAmounts); | ||||
|                     } | ||||
|                     case ERC20BridgeSource.GMX: { | ||||
|                         return this.getGMXBuyQuotes( | ||||
|                             GMX_ROUTER_BY_CHAIN_ID[this.chainId], | ||||
|                             GMX_READER_BY_CHAIN_ID[this.chainId], | ||||
|                             GMX_VAULT_BY_CHAIN_ID[this.chainId], | ||||
|                             [takerToken, makerToken], | ||||
|                             makerFillAmounts, | ||||
|                         ); | ||||
|                     } | ||||
|                     case ERC20BridgeSource.Platypus: { | ||||
|                         return getPlatypusInfoForPair(this.chainId, takerToken, makerToken).map(pool => | ||||
|                             this.getPlatypusBuyQuotes( | ||||
|                             PLATYPUS_ROUTER_BY_CHAIN_ID[this.chainId], | ||||
|                             pool.poolAddress, | ||||
|                             pool.tokens, | ||||
|                             makerFillAmounts, | ||||
|                             ), | ||||
|                         ); | ||||
|                     } | ||||
|                     default: | ||||
|                         throw new Error(`Unsupported buy sample source: ${source}`); | ||||
|                 } | ||||
|   | ||||
| @@ -10,7 +10,6 @@ import { NativeOrderWithFillableAmounts, RfqFirmQuoteValidator, RfqRequestOpts } | ||||
| import { QuoteRequestor, V4RFQIndicativeQuoteMM } from '../../utils/quote_requestor'; | ||||
| import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from '../quote_report_generator'; | ||||
|  | ||||
| import { CollapsedPath } from './path'; | ||||
| import { SourceFilters } from './source_filters'; | ||||
|  | ||||
| /** | ||||
| @@ -95,13 +94,18 @@ export enum ERC20BridgeSource { | ||||
|     // Avalanche | ||||
|     Pangolin = 'Pangolin', | ||||
|     TraderJoe = 'TraderJoe', | ||||
|     // tslint:disable-next-line: enum-naming | ||||
|     GMX = 'GMX', | ||||
|     Platypus = 'Platypus', | ||||
|     // Celo only | ||||
|     UbeSwap = 'UbeSwap', | ||||
|     MobiusMoney = 'MobiusMoney', | ||||
|     // Fantom | ||||
|     SpiritSwap = 'SpiritSwap', | ||||
|     SpookySwap = 'SpookySwap', | ||||
|     Beethovenx = 'Beethovenx', | ||||
|     MorpheusSwap = 'MorpheusSwap', | ||||
|     Geist = 'Geist', | ||||
| } | ||||
| export type SourcesWithPoolsCache = | ||||
|     | ERC20BridgeSource.Balancer | ||||
| @@ -181,6 +185,17 @@ export interface AaveV2Info { | ||||
|     underlyingToken: string; | ||||
| } | ||||
|  | ||||
| export interface GeistInfo { | ||||
|     lendingPool: string; | ||||
|     gToken: string; | ||||
|     underlyingToken: string; | ||||
| } | ||||
|  | ||||
| export interface PlatypusInfo { | ||||
|     poolAddress: string[]; | ||||
|     tokens: string[]; | ||||
|     gasSchedule: number; | ||||
| } | ||||
| // Internal `fillData` field for `Fill` objects. | ||||
| export interface FillData {} | ||||
|  | ||||
| @@ -216,6 +231,19 @@ export interface UniswapV2FillData extends FillData { | ||||
|     router: string; | ||||
| } | ||||
|  | ||||
| export interface GMXFillData extends FillData { | ||||
|     router: string; | ||||
|     reader: string; | ||||
|     vault: string; | ||||
|     tokenAddressPath: string[]; | ||||
| } | ||||
|  | ||||
| export interface PlatypusFillData extends FillData { | ||||
|     router: string; | ||||
|     pool: string[]; | ||||
|     tokenAddressPath: string[]; | ||||
| } | ||||
|  | ||||
| export interface ShellFillData extends FillData { | ||||
|     poolAddress: string; | ||||
| } | ||||
| @@ -268,19 +296,34 @@ export interface HopInfo { | ||||
|     returnData: string; | ||||
| } | ||||
|  | ||||
| export interface UniswapV3PathAmount { | ||||
|     uniswapPath: string; | ||||
|     inputAmount: BigNumber; | ||||
|     gasUsed: number; | ||||
| } | ||||
| export interface UniswapV3FillData extends FillData { | ||||
|     tokenAddressPath: string[]; | ||||
|     router: string; | ||||
|     pathAmounts: Array<{ uniswapPath: string; inputAmount: BigNumber }>; | ||||
|     pathAmounts: UniswapV3PathAmount[]; | ||||
| } | ||||
|  | ||||
| export interface KyberDmmFillData extends UniswapV2FillData { | ||||
|     poolsPath: string[]; | ||||
| } | ||||
|  | ||||
| export interface FinalUniswapV3FillData extends Omit<UniswapV3FillData, 'uniswapPaths'> { | ||||
| /** | ||||
|  * Determines whether FillData is UniswapV3FillData or FinalUniswapV3FillData | ||||
|  */ | ||||
| export function isFinalUniswapV3FillData( | ||||
|     data: UniswapV3FillData | FinalUniswapV3FillData, | ||||
| ): data is FinalUniswapV3FillData { | ||||
|     return !!(data as FinalUniswapV3FillData).uniswapPath; | ||||
| } | ||||
|  | ||||
| export interface FinalUniswapV3FillData extends Omit<UniswapV3FillData, 'pathAmounts'> { | ||||
|     // The uniswap-encoded path that can fll the maximum input amount. | ||||
|     uniswapPath: string; | ||||
|     gasUsed: number; | ||||
| } | ||||
|  | ||||
| export interface LidoFillData extends FillData { | ||||
| @@ -301,6 +344,13 @@ export interface CompoundFillData extends FillData { | ||||
|     makerToken: string; | ||||
| } | ||||
|  | ||||
| export interface GeistFillData extends FillData { | ||||
|     lendingPool: string; | ||||
|     gToken: string; | ||||
|     underlyingToken: string; | ||||
|     takerToken: string; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Represents a node on a fill path. | ||||
|  */ | ||||
| @@ -550,7 +600,6 @@ export interface OptimizerResult { | ||||
|     liquidityDelivered: CollapsedFill[] | DexSample<MultiHopFillData>; | ||||
|     marketSideLiquidity: MarketSideLiquidity; | ||||
|     adjustedRate: BigNumber; | ||||
|     unoptimizedPath?: CollapsedPath; | ||||
|     takerAmountPerEth: BigNumber; | ||||
|     makerAmountPerEth: BigNumber; | ||||
| } | ||||
|   | ||||
| @@ -17,13 +17,16 @@ import * as DODOV2Sampler from '../test/generated-artifacts/DODOV2Sampler.json'; | ||||
| import * as DummyLiquidityProvider from '../test/generated-artifacts/DummyLiquidityProvider.json'; | ||||
| import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json'; | ||||
| import * as FakeTaker from '../test/generated-artifacts/FakeTaker.json'; | ||||
| import * as GMXSampler from '../test/generated-artifacts/GMXSampler.json'; | ||||
| import * as IBalancer from '../test/generated-artifacts/IBalancer.json'; | ||||
| import * as IBancor from '../test/generated-artifacts/IBancor.json'; | ||||
| import * as ICurve from '../test/generated-artifacts/ICurve.json'; | ||||
| import * as IGMX from '../test/generated-artifacts/IGMX.json'; | ||||
| import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json'; | ||||
| import * as IMooniswap from '../test/generated-artifacts/IMooniswap.json'; | ||||
| import * as IMStable from '../test/generated-artifacts/IMStable.json'; | ||||
| import * as IMultiBridge from '../test/generated-artifacts/IMultiBridge.json'; | ||||
| import * as IPlatypus from '../test/generated-artifacts/IPlatypus.json'; | ||||
| import * as IShell from '../test/generated-artifacts/IShell.json'; | ||||
| import * as ISmoothy from '../test/generated-artifacts/ISmoothy.json'; | ||||
| import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json'; | ||||
| @@ -37,6 +40,7 @@ import * as MooniswapSampler from '../test/generated-artifacts/MooniswapSampler. | ||||
| import * as MStableSampler from '../test/generated-artifacts/MStableSampler.json'; | ||||
| import * as MultiBridgeSampler from '../test/generated-artifacts/MultiBridgeSampler.json'; | ||||
| import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSampler.json'; | ||||
| import * as PlatypusSampler from '../test/generated-artifacts/PlatypusSampler.json'; | ||||
| import * as SamplerUtils from '../test/generated-artifacts/SamplerUtils.json'; | ||||
| import * as ShellSampler from '../test/generated-artifacts/ShellSampler.json'; | ||||
| import * as SmoothySampler from '../test/generated-artifacts/SmoothySampler.json'; | ||||
| @@ -59,6 +63,7 @@ export const artifacts = { | ||||
|     DODOV2Sampler: DODOV2Sampler as ContractArtifact, | ||||
|     ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact, | ||||
|     FakeTaker: FakeTaker as ContractArtifact, | ||||
|     GMXSampler: GMXSampler as ContractArtifact, | ||||
|     KyberDmmSampler: KyberDmmSampler as ContractArtifact, | ||||
|     KyberSampler: KyberSampler as ContractArtifact, | ||||
|     LidoSampler: LidoSampler as ContractArtifact, | ||||
| @@ -68,6 +73,7 @@ export const artifacts = { | ||||
|     MooniswapSampler: MooniswapSampler as ContractArtifact, | ||||
|     MultiBridgeSampler: MultiBridgeSampler as ContractArtifact, | ||||
|     NativeOrderSampler: NativeOrderSampler as ContractArtifact, | ||||
|     PlatypusSampler: PlatypusSampler as ContractArtifact, | ||||
|     SamplerUtils: SamplerUtils as ContractArtifact, | ||||
|     ShellSampler: ShellSampler as ContractArtifact, | ||||
|     SmoothySampler: SmoothySampler as ContractArtifact, | ||||
| @@ -79,10 +85,12 @@ export const artifacts = { | ||||
|     IBalancer: IBalancer as ContractArtifact, | ||||
|     IBancor: IBancor as ContractArtifact, | ||||
|     ICurve: ICurve as ContractArtifact, | ||||
|     IGMX: IGMX as ContractArtifact, | ||||
|     IKyberNetwork: IKyberNetwork as ContractArtifact, | ||||
|     IMStable: IMStable as ContractArtifact, | ||||
|     IMooniswap: IMooniswap as ContractArtifact, | ||||
|     IMultiBridge: IMultiBridge as ContractArtifact, | ||||
|     IPlatypus: IPlatypus as ContractArtifact, | ||||
|     IShell: IShell as ContractArtifact, | ||||
|     ISmoothy: ISmoothy as ContractArtifact, | ||||
|     IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact, | ||||
|   | ||||
| @@ -15,6 +15,7 @@ export * from '../test/generated-wrappers/d_o_d_o_v2_sampler'; | ||||
| export * from '../test/generated-wrappers/dummy_liquidity_provider'; | ||||
| export * from '../test/generated-wrappers/erc20_bridge_sampler'; | ||||
| export * from '../test/generated-wrappers/fake_taker'; | ||||
| export * from '../test/generated-wrappers/g_m_x_sampler'; | ||||
| export * from '../test/generated-wrappers/i_balancer'; | ||||
| export * from '../test/generated-wrappers/i_bancor'; | ||||
| export * from '../test/generated-wrappers/i_curve'; | ||||
| @@ -22,10 +23,12 @@ export * from '../test/generated-wrappers/i_kyber_network'; | ||||
| export * from '../test/generated-wrappers/i_m_stable'; | ||||
| export * from '../test/generated-wrappers/i_mooniswap'; | ||||
| export * from '../test/generated-wrappers/i_multi_bridge'; | ||||
| export * from '../test/generated-wrappers/i_platypus'; | ||||
| export * from '../test/generated-wrappers/i_shell'; | ||||
| export * from '../test/generated-wrappers/i_smoothy'; | ||||
| export * from '../test/generated-wrappers/i_uniswap_exchange_quotes'; | ||||
| export * from '../test/generated-wrappers/i_uniswap_v2_router01'; | ||||
| export * from '../test/generated-wrappers/igmx'; | ||||
| export * from '../test/generated-wrappers/kyber_dmm_sampler'; | ||||
| export * from '../test/generated-wrappers/kyber_sampler'; | ||||
| export * from '../test/generated-wrappers/lido_sampler'; | ||||
| @@ -35,6 +38,7 @@ export * from '../test/generated-wrappers/maker_p_s_m_sampler'; | ||||
| export * from '../test/generated-wrappers/mooniswap_sampler'; | ||||
| export * from '../test/generated-wrappers/multi_bridge_sampler'; | ||||
| export * from '../test/generated-wrappers/native_order_sampler'; | ||||
| export * from '../test/generated-wrappers/platypus_sampler'; | ||||
| export * from '../test/generated-wrappers/sampler_utils'; | ||||
| export * from '../test/generated-wrappers/shell_sampler'; | ||||
| export * from '../test/generated-wrappers/smoothy_sampler'; | ||||
|   | ||||
| @@ -18,13 +18,16 @@ | ||||
|         "test/generated-artifacts/DummyLiquidityProvider.json", | ||||
|         "test/generated-artifacts/ERC20BridgeSampler.json", | ||||
|         "test/generated-artifacts/FakeTaker.json", | ||||
|         "test/generated-artifacts/GMXSampler.json", | ||||
|         "test/generated-artifacts/IBalancer.json", | ||||
|         "test/generated-artifacts/IBancor.json", | ||||
|         "test/generated-artifacts/ICurve.json", | ||||
|         "test/generated-artifacts/IGMX.json", | ||||
|         "test/generated-artifacts/IKyberNetwork.json", | ||||
|         "test/generated-artifacts/IMStable.json", | ||||
|         "test/generated-artifacts/IMooniswap.json", | ||||
|         "test/generated-artifacts/IMultiBridge.json", | ||||
|         "test/generated-artifacts/IPlatypus.json", | ||||
|         "test/generated-artifacts/IShell.json", | ||||
|         "test/generated-artifacts/ISmoothy.json", | ||||
|         "test/generated-artifacts/IUniswapExchangeQuotes.json", | ||||
| @@ -38,6 +41,7 @@ | ||||
|         "test/generated-artifacts/MooniswapSampler.json", | ||||
|         "test/generated-artifacts/MultiBridgeSampler.json", | ||||
|         "test/generated-artifacts/NativeOrderSampler.json", | ||||
|         "test/generated-artifacts/PlatypusSampler.json", | ||||
|         "test/generated-artifacts/SamplerUtils.json", | ||||
|         "test/generated-artifacts/ShellSampler.json", | ||||
|         "test/generated-artifacts/SmoothySampler.json", | ||||
|   | ||||
| @@ -1,4 +1,14 @@ | ||||
| [ | ||||
|     { | ||||
|         "version": "6.12.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Update fantom fillQuoteTransformer addresses", | ||||
|                 "pr": 398 | ||||
|             } | ||||
|         ], | ||||
|         "timestamp": 1646225739 | ||||
|     }, | ||||
|     { | ||||
|         "version": "6.11.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v6.12.0 - _March 2, 2022_ | ||||
|  | ||||
|     * Update fantom fillQuoteTransformer addresses (#398) | ||||
|  | ||||
| ## v6.11.0 - _December 24, 2021_ | ||||
|  | ||||
|     * Add Optimism addresses (#385) | ||||
|   | ||||
| @@ -415,7 +415,7 @@ | ||||
|             "wethTransformer": "0x9b6aa8f26a92108e7d1f66373d757bb955112703", | ||||
|             "payTakerTransformer": "0x32df54951d33d7460e15fa59b1fcc262183ce4c2", | ||||
|             "affiliateFeeTransformer": "0x67efa679a4b56c38713d478e649c88247f4f8e88", | ||||
|             "fillQuoteTransformer": "0x71de60a1b160094a3f6c7e1b883ff9337d639131", | ||||
|             "fillQuoteTransformer": "0x641efe8a57ad39353fe22f77d211ef6b17b0590b", | ||||
|             "positiveSlippageFeeTransformer": "0xe87d69b285005cc82b53b844322652c49ed64600" | ||||
|         } | ||||
|     }, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contract-addresses", | ||||
|     "version": "6.11.0", | ||||
|     "version": "6.12.0", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "13.19.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "13.19.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v13.19.1 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v13.19.0 - _February 22, 2022_ | ||||
|  | ||||
|     * Regenerate wrappers to add ContractTxFunctionObj.selector (#429) | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/contract-wrappers", | ||||
|     "version": "13.19.0", | ||||
|     "version": "13.19.1", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -57,7 +57,7 @@ | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.31", | ||||
|         "@0x/base-contract": "^6.4.5", | ||||
|         "@0x/contract-addresses": "^6.11.0", | ||||
|         "@0x/contract-addresses": "^6.12.0", | ||||
|         "@0x/json-schemas": "^6.4.1", | ||||
|         "@0x/types": "^3.3.4", | ||||
|         "@0x/utils": "^6.5.0", | ||||
|   | ||||
| @@ -1,4 +1,13 @@ | ||||
| [ | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "8.1.16", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1645569128, | ||||
|         "version": "8.1.15", | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v8.1.16 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v8.1.15 - _February 22, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/migrations", | ||||
|     "version": "8.1.15", | ||||
|     "version": "8.1.16", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -68,20 +68,20 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/base-contract": "^6.4.5", | ||||
|         "@0x/contract-addresses": "^6.11.0", | ||||
|         "@0x/contract-addresses": "^6.12.0", | ||||
|         "@0x/contracts-asset-proxy": "^3.7.19", | ||||
|         "@0x/contracts-coordinator": "^3.1.38", | ||||
|         "@0x/contracts-dev-utils": "^1.3.36", | ||||
|         "@0x/contracts-erc1155": "^2.1.37", | ||||
|         "@0x/contracts-erc20": "^3.3.26", | ||||
|         "@0x/contracts-erc20": "^3.3.27", | ||||
|         "@0x/contracts-erc721": "^3.1.37", | ||||
|         "@0x/contracts-exchange": "^3.2.38", | ||||
|         "@0x/contracts-exchange-forwarder": "^4.2.38", | ||||
|         "@0x/contracts-extensions": "^6.2.32", | ||||
|         "@0x/contracts-multisig": "^4.1.38", | ||||
|         "@0x/contracts-staking": "^2.0.45", | ||||
|         "@0x/contracts-utils": "^4.8.7", | ||||
|         "@0x/contracts-zero-ex": "^0.31.0", | ||||
|         "@0x/contracts-utils": "^4.8.8", | ||||
|         "@0x/contracts-zero-ex": "^0.31.1", | ||||
|         "@0x/sol-compiler": "^4.7.8", | ||||
|         "@0x/subproviders": "^6.6.2", | ||||
|         "@0x/typescript-typings": "^5.2.1", | ||||
|   | ||||
| @@ -1,4 +1,21 @@ | ||||
| [ | ||||
|     { | ||||
|         "version": "1.12.0", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Added Support for GMX liquidity source on Avalanche" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "timestamp": 1646225739, | ||||
|         "version": "1.11.1", | ||||
|         "changes": [ | ||||
|             { | ||||
|                 "note": "Dependencies updated" | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|     { | ||||
|         "version": "1.11.0", | ||||
|         "changes": [ | ||||
|   | ||||
| @@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only. | ||||
|  | ||||
| CHANGELOG | ||||
|  | ||||
| ## v1.11.1 - _March 2, 2022_ | ||||
|  | ||||
|     * Dependencies updated | ||||
|  | ||||
| ## v1.11.0 - _February 22, 2022_ | ||||
|  | ||||
|     * Add utils and errors for NFT orders (#429) | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@0x/protocol-utils", | ||||
|     "version": "1.11.0", | ||||
|     "version": "1.11.1", | ||||
|     "engines": { | ||||
|         "node": ">=6.12" | ||||
|     }, | ||||
| @@ -63,8 +63,8 @@ | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@0x/assert": "^3.0.31", | ||||
|         "@0x/contract-addresses": "^6.11.0", | ||||
|         "@0x/contract-wrappers": "^13.19.0", | ||||
|         "@0x/contract-addresses": "^6.12.0", | ||||
|         "@0x/contract-wrappers": "^13.19.1", | ||||
|         "@0x/json-schemas": "^6.4.1", | ||||
|         "@0x/subproviders": "^6.6.2", | ||||
|         "@0x/utils": "^6.5.0", | ||||
|   | ||||
| @@ -134,6 +134,8 @@ export enum BridgeProtocol { | ||||
|     Clipper, // Not used: Clipper is now using PLP interface | ||||
|     AaveV2, | ||||
|     Compound, | ||||
|     GMX, | ||||
|     Platypus, | ||||
| } | ||||
| // tslint:enable: enum-naming | ||||
|  | ||||
|   | ||||
							
								
								
									
										189
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										189
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -646,7 +646,6 @@ | ||||
| "@0x/abi-gen@^5.7.2": | ||||
|   version "5.7.2" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/abi-gen/-/abi-gen-5.7.2.tgz#c40eb225aab9ee04d331e72af887237dd1967fc0" | ||||
|   integrity sha512-jaFpJqb9hu0kY0yocjmQ0S5suDOBPJYIU3ZuSTZKwnmeOQj4Jl4LzzOTrNWjyqX6+wylW1o4K2/c3e4ZDF+2EA== | ||||
|   dependencies: | ||||
|     "@0x/types" "^3.3.4" | ||||
|     "@0x/typescript-typings" "^5.2.1" | ||||
| @@ -680,7 +679,6 @@ | ||||
| "@0x/assert@^3.0.31": | ||||
|   version "3.0.31" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/assert/-/assert-3.0.31.tgz#2c9e7e0ff9cc7bae8cd0380022e1723ee505a82e" | ||||
|   integrity sha512-ZzlnldKNvhA78IOcH6KCH3kb65XB7fI3wyuocjL72Es3eGTmyVg1KNK7eJnmV+RHSGDTYLwhvmb5hfIvFHMArg== | ||||
|   dependencies: | ||||
|     "@0x/json-schemas" "^6.4.1" | ||||
|     "@0x/typescript-typings" "^5.2.1" | ||||
| @@ -720,7 +718,6 @@ | ||||
| "@0x/base-contract@^6.4.5": | ||||
|   version "6.4.5" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/base-contract/-/base-contract-6.4.5.tgz#f241f5b2c17b3e90e7ead8dec19840ee54ab29bf" | ||||
|   integrity sha512-eYSDhXJxiRrCGWiU6z0P5fPzao4FX1+mujsviXK4a1wp7YvNIYDJ1pEa6C3vCSPJrCHf3EBJT9pwOsNphlyyTg== | ||||
|   dependencies: | ||||
|     "@0x/assert" "^3.0.31" | ||||
|     "@0x/json-schemas" "^6.4.1" | ||||
| @@ -838,7 +835,6 @@ | ||||
| "@0x/contracts-gen@^2.0.43": | ||||
|   version "2.0.43" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/contracts-gen/-/contracts-gen-2.0.43.tgz#42abf96961d3afa70112ca4f4dc3f129328f1993" | ||||
|   integrity sha512-yVdvx4ihxOZ4fZVE01xxFTylC4cZ+O781cg1A0bWwgAL6GzjzjbDXULfsl0FKfN/4rh+rnwdGrN9Ns5QvB7+xQ== | ||||
|   dependencies: | ||||
|     "@0x/sol-compiler" "^4.7.8" | ||||
|     "@0x/sol-resolver" "^3.1.9" | ||||
| @@ -874,7 +870,6 @@ | ||||
| "@0x/dev-utils@^4.2.11": | ||||
|   version "4.2.11" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/dev-utils/-/dev-utils-4.2.11.tgz#017dcc50a91eb75c6ac3d6fe77021e4f4330bbe7" | ||||
|   integrity sha512-8T6803s1GCEdKegjoktMkhp3SVFsKA/m8nDwXy3DiijPGbQejLHxsD0CsR8Uhf/RUP84MMqA0bHYaonb8H4Mag== | ||||
|   dependencies: | ||||
|     "@0x/subproviders" "^6.6.2" | ||||
|     "@0x/types" "^3.3.4" | ||||
| @@ -912,7 +907,6 @@ | ||||
| "@0x/json-schemas@^6.4.1": | ||||
|   version "6.4.1" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/json-schemas/-/json-schemas-6.4.1.tgz#2db8f6056af7a4d198ae9f56b568473447908d6e" | ||||
|   integrity sha512-4LGe7/QNKAdfxBNu5e5w24JKUqEHGg08TgKhyotStW5m0TJNBGoyGavip1FJeI3KRqNilRN22lgo9HsCBnF5Qg== | ||||
|   dependencies: | ||||
|     "@0x/typescript-typings" "^5.2.1" | ||||
|     "@types/node" "12.12.54" | ||||
| @@ -934,7 +928,6 @@ | ||||
| "@0x/monorepo-scripts@^3.2.1": | ||||
|   version "3.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/monorepo-scripts/-/monorepo-scripts-3.2.1.tgz#24e90e835427b199474cc70458d1b3fd52349541" | ||||
|   integrity sha512-PMCKWK/y6aC+HxWk7jbchcAuJ7eMERfH6Ox8op7833MsxNArSp6Fv3XJKU58PWjLVQHpVf51/Cz7E238QAibDg== | ||||
|   dependencies: | ||||
|     "@0x/types" "^3.3.4" | ||||
|     "@0x/utils" "^6.5.0" | ||||
| @@ -959,10 +952,10 @@ | ||||
|     typedoc "~0.16.11" | ||||
|     yargs "^10.0.3" | ||||
|  | ||||
| "@0x/neon-router@^0.3.2": | ||||
|   version "0.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.2.tgz#dc68d0a108060d607b48e3d32ce0ff46f8dc0cc2" | ||||
|   integrity sha512-AdSPeCxRcjdpmWDkJI1wg+X4q14tmLE21vM0AixtMQQI5+f22sIeUCrPqU9FFKqMQTOW0/3d8tVXzxdollahbA== | ||||
| "@0x/neon-router@^0.3.5": | ||||
|   version "0.3.5" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.5.tgz#895e7a2dc65d492a413daaea283cbc0ca6df83fa" | ||||
|   integrity sha512-8wizP3smc5o4jVg1smZzCCFo4ohOrgDhO4JFjF+/oNHbFImlGHOvmH9HQ2FJXAXiLEOTxrbp3T5XxP5GNATq3w== | ||||
|   dependencies: | ||||
|     "@mapbox/node-pre-gyp" "^1.0.5" | ||||
|  | ||||
| @@ -983,7 +976,6 @@ | ||||
| "@0x/quote-server@^6.0.6": | ||||
|   version "6.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/quote-server/-/quote-server-6.0.6.tgz#0f0bf50647efc4bff039a491689974af7e8c5776" | ||||
|   integrity sha512-ubugDwCFDhOv8R8LWO4Z9BmWfm/KjbB92bg1nEHw2HzosOk1rLkQWnPCJGqbMzxHlt3EtLxXPrrZE2IxWBKgwQ== | ||||
|   dependencies: | ||||
|     "@0x/json-schemas" "^6.0.1" | ||||
|     "@0x/order-utils" "^10.2.4" | ||||
| @@ -997,7 +989,6 @@ | ||||
| "@0x/sol-compiler@^4.7.8": | ||||
|   version "4.7.8" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/sol-compiler/-/sol-compiler-4.7.8.tgz#31bd4f21bbb045d19e2e500282258d6526b5a837" | ||||
|   integrity sha512-0lHaoSDRlPzWCf4o8aEaMoQUnZmeiUreWSNNyPbCO/nF+siPqMPQw6W7ATei/XhVb3UKHZto1ScsyAar/8pIWQ== | ||||
|   dependencies: | ||||
|     "@0x/assert" "^3.0.31" | ||||
|     "@0x/json-schemas" "^6.4.1" | ||||
| @@ -1026,7 +1017,6 @@ | ||||
| "@0x/sol-coverage@^4.0.42": | ||||
|   version "4.0.42" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/sol-coverage/-/sol-coverage-4.0.42.tgz#632c504ec060534d83d19bf9b3f812f271d47a61" | ||||
|   integrity sha512-6R53Kpn1If4D3BI3Pz4qa7AoVLaF7jg6cNNLvqHROW1+chwMGmtPKj2t/R1mKiljTU1lUL1bebfhIJUfYA7IAQ== | ||||
|   dependencies: | ||||
|     "@0x/sol-tracing-utils" "^7.2.8" | ||||
|     "@0x/subproviders" "^6.6.2" | ||||
| @@ -1041,7 +1031,6 @@ | ||||
| "@0x/sol-profiler@^4.1.32": | ||||
|   version "4.1.32" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/sol-profiler/-/sol-profiler-4.1.32.tgz#93f09264ab414f8e83324d8369a3e6cb2dc8b531" | ||||
|   integrity sha512-FqrP/lAgQCvj5qcr/77leTqgGa2xwYSEIq6/FN5NAE6YYb0JrjJmkwTpxd1fB6xo+T11ESH4+7l5UxjPseuo9w== | ||||
|   dependencies: | ||||
|     "@0x/sol-tracing-utils" "^7.2.8" | ||||
|     "@0x/subproviders" "^6.6.2" | ||||
| @@ -1056,7 +1045,6 @@ | ||||
| "@0x/sol-resolver@^3.1.9": | ||||
|   version "3.1.9" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/sol-resolver/-/sol-resolver-3.1.9.tgz#525c545c4ff4d0ff2ff99e433b2405778abe0693" | ||||
|   integrity sha512-N+GxAqtHzEgVsnj9k4yeE7xRqE2ymR+yo98j0s2VC8icjecVqm6LtqQpEpdPULEg20vA0aPdU/XY2q0xiCDpLg== | ||||
|   dependencies: | ||||
|     "@0x/types" "^3.3.4" | ||||
|     "@0x/typescript-typings" "^5.2.1" | ||||
| @@ -1066,7 +1054,6 @@ | ||||
| "@0x/sol-trace@^3.0.42": | ||||
|   version "3.0.42" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/sol-trace/-/sol-trace-3.0.42.tgz#5a1cb6d4213bbf6746bf393858019fb7b3586916" | ||||
|   integrity sha512-8Elq5aFgMvmUNi3rvDTSA84VMtiyCBNFDaIiKQZ9YtZbgOJnyfxBbelV0sXggnmoochpQ72yX0Cxe3WEdR+5JQ== | ||||
|   dependencies: | ||||
|     "@0x/sol-tracing-utils" "^7.2.8" | ||||
|     "@0x/subproviders" "^6.6.2" | ||||
| @@ -1082,7 +1069,6 @@ | ||||
| "@0x/sol-tracing-utils@^7.2.8": | ||||
|   version "7.2.8" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/sol-tracing-utils/-/sol-tracing-utils-7.2.8.tgz#c365931d9f290738fa67d29ae5443d26acf3122c" | ||||
|   integrity sha512-OP9v3bilfvx7JtDQmp4iIE0dZ7Zq0/S9xWP+WLhx2KMKQ1jF9fK3WnsMHea7KtmQnmEBv0naFnEOqedxmus66g== | ||||
|   dependencies: | ||||
|     "@0x/dev-utils" "^4.2.11" | ||||
|     "@0x/sol-compiler" "^4.7.8" | ||||
| @@ -1110,7 +1096,6 @@ | ||||
| "@0x/subproviders@^6.6.2": | ||||
|   version "6.6.2" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/subproviders/-/subproviders-6.6.2.tgz#c51b3167fcd3b58f5522305864bd4896455ee697" | ||||
|   integrity sha512-/SB6BurdYbGXvIa3rmQdaUYPk7D+BFiAAkvQbsA4s//51eVLLQG+QdgDT1RUKGJbhX11ff31jc7dEu/wh6nQhg== | ||||
|   dependencies: | ||||
|     "@0x/assert" "^3.0.31" | ||||
|     "@0x/types" "^3.3.4" | ||||
| @@ -1188,7 +1173,6 @@ | ||||
| "@0x/types@^3.3.4": | ||||
|   version "3.3.4" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/types/-/types-3.3.4.tgz#184946b1674f7f5b4cfb73105952b499a67fc23e" | ||||
|   integrity sha512-lB6maU/D1TEBrJXQcbwzGilmugX9qrfhxbyPr8r89TinSHe2SS694tTKIyI+ijnTbhyVjWzEnA95iuWxhPmP5g== | ||||
|   dependencies: | ||||
|     "@types/node" "12.12.54" | ||||
|     bignumber.js "~9.0.0" | ||||
| @@ -1230,7 +1214,6 @@ | ||||
| "@0x/typescript-typings@^5.2.1": | ||||
|   version "5.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/typescript-typings/-/typescript-typings-5.2.1.tgz#bc82d0f39688b174142ebb5b2fd6a01c1d2f0163" | ||||
|   integrity sha512-2yswstFMy/cpF+MrJclEZc8BNceBAVovwzRYdz1CyGPfzMT1Kh8jVGeexx0KvVw58KrhxMgcRD4mzCSHNqzjPA== | ||||
|   dependencies: | ||||
|     "@types/bn.js" "^4.11.0" | ||||
|     "@types/node" "12.12.54" | ||||
| @@ -1297,7 +1280,6 @@ | ||||
| "@0x/utils@^6.5.0": | ||||
|   version "6.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/utils/-/utils-6.5.0.tgz#a75eda9a1cdc7cd2520056dbaec678f20f7f16c4" | ||||
|   integrity sha512-1+9nIagW9OQG0rcUaBvIOMolWgZHqSjNADQIJk+GmEMYnt7wUpokSkHPHxmw+/xVQs/da5dh1U0/nWsW+A1Nuw== | ||||
|   dependencies: | ||||
|     "@0x/types" "^3.3.4" | ||||
|     "@0x/typescript-typings" "^5.2.1" | ||||
| @@ -1331,7 +1313,6 @@ | ||||
| "@0x/web3-wrapper@^7.6.2": | ||||
|   version "7.6.2" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/web3-wrapper/-/web3-wrapper-7.6.2.tgz#fd6c50f67ce21191feabea1f59e1467ea5d89dae" | ||||
|   integrity sha512-o3TjgpJWAInFqkFVaeaGlRDXF53NNgO/M3CfUbC+X8p4ReQm4J81BxEf6yxeDzsPt5qLKzrRzhkRiIWeDIlNQw== | ||||
|   dependencies: | ||||
|     "@0x/assert" "^3.0.31" | ||||
|     "@0x/json-schemas" "^6.4.1" | ||||
| @@ -1408,7 +1389,6 @@ | ||||
| "@ethereumjs/common@^2.4.0": | ||||
|   version "2.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.4.0.tgz#2d67f6e6ba22246c5c89104e6b9a119fb3039766" | ||||
|   integrity sha512-UdkhFWzWcJCZVsj1O/H8/oqj/0RVYjLc1OhPjBrQdALAkQHpCp8xXI4WLnuGTADqTdJZww0NtgwG+TRPkXt27w== | ||||
|   dependencies: | ||||
|     crc-32 "^1.2.0" | ||||
|     ethereumjs-util "^7.1.0" | ||||
| @@ -1416,7 +1396,6 @@ | ||||
| "@ethereumjs/tx@^3.3.0": | ||||
|   version "3.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.0.tgz#14ed1b7fa0f28e1cd61e3ecbdab824205f6a4378" | ||||
|   integrity sha512-yTwEj2lVzSMgE6Hjw9Oa1DZks/nKTWM8Wn4ykDNapBPua2f4nXO3qKnni86O6lgDj5fVNRqbDsD0yy7/XNGDEA== | ||||
|   dependencies: | ||||
|     "@ethereumjs/common" "^2.4.0" | ||||
|     ethereumjs-util "^7.1.0" | ||||
| @@ -2483,7 +2462,6 @@ | ||||
| "@mapbox/node-pre-gyp@^1.0.5": | ||||
|   version "1.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz#2a0b32fcb416fb3f2250fd24cb2a81421a4f5950" | ||||
|   integrity sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA== | ||||
|   dependencies: | ||||
|     detect-libc "^1.0.3" | ||||
|     https-proxy-agent "^5.0.0" | ||||
| @@ -2903,7 +2881,7 @@ abstract-leveldown@3.0.0: | ||||
|   dependencies: | ||||
|     xtend "~4.0.0" | ||||
|  | ||||
| abstract-leveldown@^2.4.1, abstract-leveldown@~2.7.1: | ||||
| abstract-leveldown@^2.4.1: | ||||
|   version "2.7.2" | ||||
|   resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz#87a44d7ebebc341d59665204834c8b7e0932cc93" | ||||
|   dependencies: | ||||
| @@ -2915,12 +2893,6 @@ abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0: | ||||
|   dependencies: | ||||
|     xtend "~4.0.0" | ||||
|  | ||||
| abstract-leveldown@~2.6.0: | ||||
|   version "2.6.3" | ||||
|   resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" | ||||
|   dependencies: | ||||
|     xtend "~4.0.0" | ||||
|  | ||||
| accepts@~1.3.7: | ||||
|   version "1.3.7" | ||||
|   resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" | ||||
| @@ -3205,7 +3177,7 @@ async-limiter@~1.0.0: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" | ||||
|  | ||||
| async@1.x, async@^1.4.2: | ||||
| async@1.x: | ||||
|   version "1.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" | ||||
|  | ||||
| @@ -3783,23 +3755,16 @@ bigi@1.4.2, bigi@^1.1.0: | ||||
|   version "1.4.2" | ||||
|   resolved "https://registry.yarnpkg.com/bigi/-/bigi-1.4.2.tgz#9c665a95f88b8b08fc05cfd731f561859d725825" | ||||
|  | ||||
| bignumber.js@7.2.1: | ||||
|   version "7.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" | ||||
|  | ||||
| bignumber.js@^9.0.0, bignumber.js@~9.0.0: | ||||
|   version "9.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" | ||||
|  | ||||
| bignumber.js@~4.1.0: | ||||
|   version "4.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" | ||||
| bignumber.js@7.2.1, bignumber.js@9.0.2, bignumber.js@^9.0.0, bignumber.js@~4.1.0, bignumber.js@~9.0.0: | ||||
|   version "9.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" | ||||
|   integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== | ||||
|  | ||||
| binary-extensions@^2.0.0: | ||||
|   version "2.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" | ||||
|  | ||||
| bindings@^1.2.1, bindings@^1.4.0, bindings@^1.5.0: | ||||
| bindings@^1.4.0, bindings@^1.5.0: | ||||
|   version "1.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" | ||||
|   dependencies: | ||||
| @@ -4250,7 +4215,6 @@ caniuse-lite@^1.0.30000844: | ||||
| cargo-cp-artifact@^0.1.6: | ||||
|   version "0.1.6" | ||||
|   resolved "https://registry.yarnpkg.com/cargo-cp-artifact/-/cargo-cp-artifact-0.1.6.tgz#df1bc9dad036ae0f4230639a869182e1d5850f89" | ||||
|   integrity sha512-CQw0doK/aaF7j041666XzuilHxqMxaKkn+I5vmBsd8SAwS0cO5CqVEVp0xJwOKstyqWZ6WK4Ww3O6p26x/Goyg== | ||||
|  | ||||
| caseless@~0.12.0: | ||||
|   version "0.12.0" | ||||
| @@ -5126,12 +5090,6 @@ defer-to-connect@^1.0.1: | ||||
|   version "1.1.3" | ||||
|   resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" | ||||
|  | ||||
| deferred-leveldown@~1.2.1: | ||||
|   version "1.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz#3acd2e0b75d1669924bc0a4b642851131173e1eb" | ||||
|   dependencies: | ||||
|     abstract-leveldown "~2.6.0" | ||||
|  | ||||
| deferred-leveldown@~4.0.0: | ||||
|   version "4.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz#0b0570087827bf480a23494b398f04c128c19a20" | ||||
| @@ -5876,7 +5834,6 @@ ethereum-types@^3.5.0: | ||||
| ethereum-types@^3.6.0: | ||||
|   version "3.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/ethereum-types/-/ethereum-types-3.6.0.tgz#7cf0a7258537b1f8d113dd51d050189a742a9a6e" | ||||
|   integrity sha512-iJX96C9W1elWhCZKUiSQfWn9fC+EO+xU2TvAE/p7QhMwcGibihKsxcG27B/4WZAudd8jNoeIhY4PH2qQPLuUfw== | ||||
|   dependencies: | ||||
|     "@types/node" "12.12.54" | ||||
|     bignumber.js "~9.0.0" | ||||
| @@ -5976,18 +5933,6 @@ ethereumjs-tx@^1.1.1, ethereumjs-tx@^1.2.0, ethereumjs-tx@^1.2.2, ethereumjs-tx@ | ||||
|     ethereum-common "^0.0.18" | ||||
|     ethereumjs-util "^5.0.0" | ||||
|  | ||||
| ethereumjs-util@6.1.0: | ||||
|   version "6.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" | ||||
|   dependencies: | ||||
|     bn.js "^4.11.0" | ||||
|     create-hash "^1.1.2" | ||||
|     ethjs-util "0.1.6" | ||||
|     keccak "^1.0.2" | ||||
|     rlp "^2.0.0" | ||||
|     safe-buffer "^5.1.1" | ||||
|     secp256k1 "^3.0.1" | ||||
|  | ||||
| ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0: | ||||
|   version "6.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" | ||||
| @@ -6010,7 +5955,7 @@ ethereumjs-util@^4.3.0: | ||||
|     ethereum-cryptography "^0.1.3" | ||||
|     rlp "^2.0.0" | ||||
|  | ||||
| ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5: | ||||
| ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereumjs-util@^5.1.2, ethereumjs-util@^5.1.3, ethereumjs-util@^5.1.5, ethereumjs-util@^5.2.0: | ||||
|   version "5.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" | ||||
|   dependencies: | ||||
| @@ -6352,7 +6297,6 @@ fake-merkle-patricia-tree@^1.0.1: | ||||
| fast-abi@^0.0.4: | ||||
|   version "0.0.4" | ||||
|   resolved "https://registry.yarnpkg.com/fast-abi/-/fast-abi-0.0.4.tgz#c6a547d0fe75862a9eea6fe5aa7ab135e6ab62a0" | ||||
|   integrity sha512-BM/x54z6i5L+VnHk1c1xt4sSlx4SCIZNQJ3tNBrM88ytOSd/JY/2pRVkx/RxY3sdF6X5exgB6YVemCqVLzQzUA== | ||||
|   dependencies: | ||||
|     "@mapbox/node-pre-gyp" "^1.0.4" | ||||
|     cargo-cp-artifact "^0.1.6" | ||||
| @@ -6697,11 +6641,11 @@ functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" | ||||
|  | ||||
| ganache-cli@6.8.0-istanbul.0: | ||||
|   version "6.8.0-istanbul.0" | ||||
|   resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.8.0-istanbul.0.tgz#ec19bc08ff30d250ae13c6f57c16069ecf583fa6" | ||||
| ganache-cli@6.12.2: | ||||
|   version "6.12.2" | ||||
|   resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.2.tgz#c0920f7db0d4ac062ffe2375cb004089806f627a" | ||||
|   dependencies: | ||||
|     ethereumjs-util "6.1.0" | ||||
|     ethereumjs-util "6.2.1" | ||||
|     source-map-support "0.5.12" | ||||
|     yargs "13.2.4" | ||||
|  | ||||
| @@ -7364,10 +7308,6 @@ ignore@^4.0.3, ignore@^4.0.6: | ||||
|   version "4.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" | ||||
|  | ||||
| immediate@^3.2.3: | ||||
|   version "3.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.3.0.tgz#1aef225517836bcdf7f2a2de2600c79ff0269266" | ||||
|  | ||||
| immediate@~3.2.3: | ||||
|   version "3.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c" | ||||
| @@ -8133,15 +8073,6 @@ keccak@3.0.1, keccak@^3.0.0: | ||||
|     node-addon-api "^2.0.0" | ||||
|     node-gyp-build "^4.2.0" | ||||
|  | ||||
| keccak@^1.0.2: | ||||
|   version "1.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80" | ||||
|   dependencies: | ||||
|     bindings "^1.2.1" | ||||
|     inherits "^2.0.3" | ||||
|     nan "^2.2.1" | ||||
|     safe-buffer "^5.1.0" | ||||
|  | ||||
| keyv@^3.0.0: | ||||
|   version "3.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" | ||||
| @@ -8249,28 +8180,12 @@ level-codec@^9.0.0: | ||||
|   dependencies: | ||||
|     buffer "^5.6.0" | ||||
|  | ||||
| level-codec@~7.0.0: | ||||
|   version "7.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7" | ||||
|  | ||||
| level-errors@^1.0.3: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d" | ||||
|   dependencies: | ||||
|     errno "~0.1.1" | ||||
|  | ||||
| level-errors@^2.0.0, level-errors@~2.0.0: | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-2.0.1.tgz#2132a677bf4e679ce029f517c2f17432800c05c8" | ||||
|   dependencies: | ||||
|     errno "~0.1.1" | ||||
|  | ||||
| level-errors@~1.0.3: | ||||
|   version "1.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.0.5.tgz#83dbfb12f0b8a2516bdc9a31c4876038e227b859" | ||||
|   dependencies: | ||||
|     errno "~0.1.1" | ||||
|  | ||||
| level-iterator-stream@^2.0.3: | ||||
|   version "2.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz#ccfff7c046dcf47955ae9a86f46dfa06a31688b4" | ||||
| @@ -8279,15 +8194,6 @@ level-iterator-stream@^2.0.3: | ||||
|     readable-stream "^2.0.5" | ||||
|     xtend "^4.0.0" | ||||
|  | ||||
| level-iterator-stream@~1.3.0: | ||||
|   version "1.3.1" | ||||
|   resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz#e43b78b1a8143e6fa97a4f485eb8ea530352f2ed" | ||||
|   dependencies: | ||||
|     inherits "^2.0.1" | ||||
|     level-errors "^1.0.3" | ||||
|     readable-stream "^1.0.33" | ||||
|     xtend "^4.0.0" | ||||
|  | ||||
| level-iterator-stream@~3.0.0: | ||||
|   version "3.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz#2c98a4f8820d87cdacab3132506815419077c730" | ||||
| @@ -8331,12 +8237,13 @@ level-sublevel@6.6.4: | ||||
|     typewiselite "~1.0.0" | ||||
|     xtend "~4.0.0" | ||||
|  | ||||
| level-ws@0.0.0: | ||||
|   version "0.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b" | ||||
| level-ws@^1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-1.0.0.tgz#19a22d2d4ac57b18cc7c6ecc4bd23d899d8f603b" | ||||
|   dependencies: | ||||
|     readable-stream "~1.0.15" | ||||
|     xtend "~2.1.1" | ||||
|     inherits "^2.0.3" | ||||
|     readable-stream "^2.2.8" | ||||
|     xtend "^4.0.1" | ||||
|  | ||||
| levelup@3.1.1, levelup@^3.0.0: | ||||
|   version "3.1.1" | ||||
| @@ -8347,18 +8254,6 @@ levelup@3.1.1, levelup@^3.0.0: | ||||
|     level-iterator-stream "~3.0.0" | ||||
|     xtend "~4.0.0" | ||||
|  | ||||
| levelup@^1.2.1: | ||||
|   version "1.3.9" | ||||
|   resolved "https://registry.yarnpkg.com/levelup/-/levelup-1.3.9.tgz#2dbcae845b2bb2b6bea84df334c475533bbd82ab" | ||||
|   dependencies: | ||||
|     deferred-leveldown "~1.2.1" | ||||
|     level-codec "~7.0.0" | ||||
|     level-errors "~1.0.3" | ||||
|     level-iterator-stream "~1.3.0" | ||||
|     prr "~1.0.1" | ||||
|     semver "~5.4.1" | ||||
|     xtend "~4.0.0" | ||||
|  | ||||
| levn@^0.3.0, levn@~0.3.0: | ||||
|   version "0.3.0" | ||||
|   resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" | ||||
| @@ -8720,17 +8615,6 @@ mem@^4.0.0: | ||||
|     mimic-fn "^2.0.0" | ||||
|     p-is-promise "^2.0.0" | ||||
|  | ||||
| memdown@^1.0.0: | ||||
|   version "1.4.1" | ||||
|   resolved "https://registry.yarnpkg.com/memdown/-/memdown-1.4.1.tgz#b4e4e192174664ffbae41361aa500f3119efe215" | ||||
|   dependencies: | ||||
|     abstract-leveldown "~2.7.1" | ||||
|     functional-red-black-tree "^1.0.1" | ||||
|     immediate "^3.2.3" | ||||
|     inherits "~2.0.1" | ||||
|     ltgt "~2.2.0" | ||||
|     safe-buffer "~5.1.1" | ||||
|  | ||||
| memdown@~3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309" | ||||
| @@ -8806,15 +8690,14 @@ merge2@^1.2.3: | ||||
|   resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" | ||||
|  | ||||
| merkle-patricia-tree@3.0.0, merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: | ||||
|   version "2.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" | ||||
|   dependencies: | ||||
|     async "^1.4.2" | ||||
|     ethereumjs-util "^5.0.0" | ||||
|     level-ws "0.0.0" | ||||
|     levelup "^1.2.1" | ||||
|     memdown "^1.0.0" | ||||
|     readable-stream "^2.0.0" | ||||
|     async "^2.6.1" | ||||
|     ethereumjs-util "^5.2.0" | ||||
|     level-mem "^3.0.1" | ||||
|     level-ws "^1.0.0" | ||||
|     readable-stream "^3.0.6" | ||||
|     rlp "^2.0.0" | ||||
|     semaphore ">=1.0.1" | ||||
|  | ||||
| @@ -9169,7 +9052,7 @@ nan@2.13.2: | ||||
|   version "2.13.2" | ||||
|   resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" | ||||
|  | ||||
| nan@^2.13.2, nan@^2.14.0, nan@^2.2.1: | ||||
| nan@^2.13.2, nan@^2.14.0: | ||||
|   version "2.14.2" | ||||
|   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" | ||||
|  | ||||
| @@ -10566,7 +10449,7 @@ read@1, read@1.0.x, read@~1.0.1, read@~1.0.5: | ||||
|   dependencies: | ||||
|     mute-stream "~0.0.4" | ||||
|  | ||||
| "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: | ||||
| "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.8, readable-stream@^2.2.9, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: | ||||
|   version "2.3.7" | ||||
|   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" | ||||
|   dependencies: | ||||
| @@ -10578,7 +10461,7 @@ read@1, read@1.0.x, read@~1.0.1, read@~1.0.5: | ||||
|     string_decoder "~1.1.1" | ||||
|     util-deprecate "~1.0.1" | ||||
|  | ||||
| "readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: | ||||
| "readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: | ||||
|   version "3.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" | ||||
|   dependencies: | ||||
| @@ -10586,7 +10469,7 @@ read@1, read@1.0.x, read@~1.0.1, read@~1.0.5: | ||||
|     string_decoder "^1.1.1" | ||||
|     util-deprecate "^1.0.1" | ||||
|  | ||||
| "readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.15, readable-stream@~1.0.26: | ||||
| "readable-stream@>=1.0.33-1 <1.1.0-0", readable-stream@~1.0.26: | ||||
|   version "1.0.34" | ||||
|   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" | ||||
|   dependencies: | ||||
| @@ -10595,7 +10478,7 @@ read@1, read@1.0.x, read@~1.0.1, read@~1.0.5: | ||||
|     isarray "0.0.1" | ||||
|     string_decoder "~0.10.x" | ||||
|  | ||||
| readable-stream@^1.0.33, readable-stream@~1.1.9: | ||||
| readable-stream@~1.1.9: | ||||
|   version "1.1.14" | ||||
|   resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" | ||||
|   dependencies: | ||||
| @@ -11059,10 +10942,6 @@ semver@^7.3.4: | ||||
|   dependencies: | ||||
|     lru-cache "^6.0.0" | ||||
|  | ||||
| semver@~5.4.1: | ||||
|   version "5.4.1" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" | ||||
|  | ||||
| send@0.17.1: | ||||
|   version "0.17.1" | ||||
|   resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user