Feat/bancor v2 (#2650)
* Bancor Bridge contract * refactor Quote and FillData types * BancorService (wrapper for the Bancor SDK) * disable bancor while waiting for bancor SDK update * add bancor to test
This commit is contained in:
		| @@ -10,6 +10,10 @@ | ||||
|                 "note": "Export DexForwarderBridgeContract", | ||||
|                 "pr": 2656 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add BancorBridge and IBancorNetwork, ", | ||||
|                 "pr": 2650 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `MStableBridge`", | ||||
|                 "pr": 2662 | ||||
|   | ||||
							
								
								
									
										122
									
								
								contracts/asset-proxy/contracts/src/bridges/BancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								contracts/asset-proxy/contracts/src/bridges/BancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
|  | ||||
| /* | ||||
|  | ||||
|   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.5.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol"; | ||||
| import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol"; | ||||
| import "../interfaces/IERC20Bridge.sol"; | ||||
| import "../interfaces/IBancorNetwork.sol"; | ||||
|  | ||||
|  | ||||
| contract BancorBridge is | ||||
|     IERC20Bridge, | ||||
|     IWallet, | ||||
|     DeploymentConstants | ||||
| { | ||||
|     struct TransferState { | ||||
|         address bancorNetworkAddress; | ||||
|         address[] path; | ||||
|     } | ||||
|  | ||||
|     /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of | ||||
|     ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress` | ||||
|     ///      token encoded in the bridge data, then transfers the bought | ||||
|     ///      tokens to `to`. | ||||
|     /// @param toTokenAddress The token to buy and transfer to `to`. | ||||
|     /// @param from The maker (this contract). | ||||
|     /// @param to The recipient of the bought tokens. | ||||
|     /// @param amount Minimum amount of `toTokenAddress` tokens to buy. | ||||
|     /// @param bridgeData The abi-encoded conversion path addresses and Bancor network address | ||||
|     /// @return success The magic bytes if successful. | ||||
|     function bridgeTransferFrom( | ||||
|         address toTokenAddress, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount, | ||||
|         bytes calldata bridgeData | ||||
|     ) | ||||
|         external | ||||
|         returns (bytes4 success) | ||||
|     { | ||||
|         // hold variables to get around stack depth limitations | ||||
|         TransferState memory state; | ||||
|  | ||||
|         // Decode the bridge data. | ||||
|         ( | ||||
|             state.path, | ||||
|             state.bancorNetworkAddress | ||||
|         // solhint-disable indent | ||||
|         ) = abi.decode(bridgeData, (address[], address)); | ||||
|         // solhint-enable indent | ||||
|  | ||||
|         require(state.path.length > 0, "BancorBridge/PATH_MUST_EXIST"); | ||||
|         // Just transfer the tokens if they're the same. | ||||
|         if (state.path[0] == toTokenAddress) { | ||||
|             LibERC20Token.transfer(state.path[0], to, amount); | ||||
|             return BRIDGE_SUCCESS; | ||||
|         } | ||||
|  | ||||
|         // Otherwise use Bancor to convert | ||||
|         require(state.path.length > 2, "BancorBridge/PATH_LENGTH_MUST_BE_GREATER_THAN_TWO"); | ||||
|         require(state.path[state.path.length - 1] == toTokenAddress, "BancorBridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"); | ||||
|          | ||||
|         // // Grant an allowance to the Bancor Network to spend `fromTokenAddress` token. | ||||
|         uint256 fromTokenBalance = IERC20Token(state.path[0]).balanceOf(address(this)); | ||||
|         LibERC20Token.approveIfBelow(state.path[0], state.bancorNetworkAddress, fromTokenBalance); | ||||
|  | ||||
|         // Convert the tokens | ||||
|         uint256 boughtAmount = IBancorNetwork(state.bancorNetworkAddress).convertByPath( | ||||
|             state.path, // path originating with source token and terminating in destination token | ||||
|             fromTokenBalance, // amount of source token to trade | ||||
|             amount, // minimum amount of destination token expected to receive | ||||
|             to, // beneficiary | ||||
|             address(0), // affiliateAccount; no fee paid | ||||
|             0 // affiliateFee; no fee paid | ||||
|         ); | ||||
|  | ||||
|         emit ERC20BridgeTransfer( | ||||
|             state.path[0], // fromTokenAddress | ||||
|             toTokenAddress, | ||||
|             fromTokenBalance, | ||||
|             boughtAmount, | ||||
|             from, | ||||
|             to | ||||
|         ); | ||||
|         return BRIDGE_SUCCESS; | ||||
|     } | ||||
|  | ||||
|     /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker | ||||
|     ///      and sign for itself in orders. Always succeeds. | ||||
|     /// @return magicValue Magic success bytes, always. | ||||
|     function isValidSignature( | ||||
|         bytes32, | ||||
|         bytes calldata | ||||
|     ) | ||||
|         external | ||||
|         view | ||||
|         returns (bytes4 magicValue) | ||||
|     { | ||||
|         return LEGACY_WALLET_MAGIC_VALUE; | ||||
|     } | ||||
|      | ||||
| } | ||||
| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|  | ||||
|   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.5.9; | ||||
|  | ||||
|  | ||||
| contract IContractRegistry { | ||||
|     function addressOf( | ||||
|         bytes32 contractName | ||||
|     ) external returns(address); | ||||
| } | ||||
|  | ||||
|  | ||||
| contract IBancorNetwork { | ||||
|     function convertByPath( | ||||
|         address[] calldata _path, | ||||
|         uint256 _amount, | ||||
|         uint256 _minReturn, | ||||
|         address _beneficiary, | ||||
|         address _affiliateAccount, | ||||
|         uint256 _affiliateFee | ||||
|     ) external payable returns (uint256); | ||||
| } | ||||
							
								
								
									
										247
									
								
								contracts/asset-proxy/contracts/test/TestBancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								contracts/asset-proxy/contracts/test/TestBancorBridge.sol
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,247 @@ | ||||
| /* | ||||
|  | ||||
|   Copyright 2019 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.5.9; | ||||
| pragma experimental ABIEncoderV2; | ||||
|  | ||||
| import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; | ||||
| import "@0x/contracts-utils/contracts/src/LibAddressArray.sol"; | ||||
| import "../src/bridges/BancorBridge.sol"; | ||||
| import "../src/interfaces/IBancorNetwork.sol"; | ||||
|  | ||||
|  | ||||
| contract TestEventsRaiser { | ||||
|  | ||||
|     event TokenTransfer( | ||||
|         address token, | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ); | ||||
|  | ||||
|     event TokenApprove( | ||||
|         address spender, | ||||
|         uint256 allowance | ||||
|     ); | ||||
|  | ||||
|     event ConvertByPathInput( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address toTokenAddress, | ||||
|         address to, | ||||
|         address feeRecipient, | ||||
|         uint256 feeAmount | ||||
|     ); | ||||
|  | ||||
|     function raiseTokenTransfer( | ||||
|         address from, | ||||
|         address to, | ||||
|         uint256 amount | ||||
|     ) | ||||
|         external | ||||
|     { | ||||
|         emit TokenTransfer( | ||||
|             msg.sender, | ||||
|             from, | ||||
|             to, | ||||
|             amount | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function raiseTokenApprove(address spender, uint256 allowance) external { | ||||
|         emit TokenApprove(spender, allowance); | ||||
|     } | ||||
|  | ||||
|     function raiseConvertByPathInput( | ||||
|         uint amountIn, | ||||
|         uint amountOutMin, | ||||
|         address toTokenAddress, | ||||
|         address to, | ||||
|         address feeRecipient, | ||||
|         uint256 feeAmount | ||||
|     ) external | ||||
|     { | ||||
|         emit ConvertByPathInput( | ||||
|             amountIn, | ||||
|             amountOutMin, | ||||
|             toTokenAddress, | ||||
|             to, | ||||
|             feeRecipient, | ||||
|             feeAmount | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev A minimalist ERC20 token. | ||||
| contract TestToken { | ||||
|  | ||||
|     using LibSafeMath for uint256; | ||||
|  | ||||
|     mapping (address => uint256) public balances; | ||||
|     string private _nextRevertReason; | ||||
|  | ||||
|     /// @dev Set the balance for `owner`. | ||||
|     function setBalance(address owner, uint256 balance) | ||||
|         external | ||||
|         payable | ||||
|     { | ||||
|         balances[owner] = balance; | ||||
|     } | ||||
|  | ||||
|     /// @dev Just emits a TokenTransfer event on the caller | ||||
|     function transfer(address to, uint256 amount) | ||||
|         external | ||||
|         returns (bool) | ||||
|     { | ||||
|         TestEventsRaiser(msg.sender).raiseTokenTransfer(msg.sender, to, amount); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /// @dev Just emits a TokenApprove event on the caller | ||||
|     function approve(address spender, uint256 allowance) | ||||
|         external | ||||
|         returns (bool) | ||||
|     { | ||||
|         TestEventsRaiser(msg.sender).raiseTokenApprove(spender, allowance); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     function allowance(address, address) external view returns (uint256) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /// @dev Retrieve the balance for `owner`. | ||||
|     function balanceOf(address owner) | ||||
|         external | ||||
|         view | ||||
|         returns (uint256) | ||||
|     { | ||||
|         return balances[owner]; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev Mock the BancorNetwork contract | ||||
| contract TestBancorNetwork is | ||||
|     IBancorNetwork | ||||
| { | ||||
|     string private _nextRevertReason; | ||||
|  | ||||
|     /// @dev Set the revert reason for `swapExactTokensForTokens`. | ||||
|     function setRevertReason(string calldata reason) | ||||
|         external | ||||
|     { | ||||
|         _nextRevertReason = reason; | ||||
|     } | ||||
|  | ||||
|     function convertByPath( | ||||
|         address[] calldata _path, | ||||
|         uint256 _amount, | ||||
|         uint256 _minReturn, | ||||
|         address _beneficiary, | ||||
|         address _affiliateAccount, | ||||
|         uint256 _affiliateFee | ||||
|     ) external payable returns (uint256) | ||||
|     { | ||||
|         _revertIfReasonExists(); | ||||
|  | ||||
|         TestEventsRaiser(msg.sender).raiseConvertByPathInput( | ||||
|             // tokens sold | ||||
|             _amount, | ||||
|             // tokens bought | ||||
|             _minReturn, | ||||
|             // output token | ||||
|             _path[_path.length - 1], | ||||
|             // recipient | ||||
|             _beneficiary, | ||||
|             // fee recipient | ||||
|             _affiliateAccount, | ||||
|             // fee amount | ||||
|             _affiliateFee | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     function _revertIfReasonExists() | ||||
|         private | ||||
|         view | ||||
|     { | ||||
|         if (bytes(_nextRevertReason).length != 0) { | ||||
|             revert(_nextRevertReason); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| /// @dev BancorBridge overridden to mock tokens and BancorNetwork | ||||
| contract TestBancorBridge is | ||||
|     BancorBridge, | ||||
|     TestEventsRaiser | ||||
| { | ||||
|  | ||||
|     // Token address to TestToken instance. | ||||
|     mapping (address => TestToken) private _testTokens; | ||||
|     // TestRouter instance. | ||||
|     TestBancorNetwork private _testNetwork; | ||||
|  | ||||
|     constructor() public { | ||||
|         _testNetwork = new TestBancorNetwork(); | ||||
|     } | ||||
|  | ||||
|     function setNetworkRevertReason(string calldata revertReason) | ||||
|         external | ||||
|     { | ||||
|         _testNetwork.setRevertReason(revertReason); | ||||
|     } | ||||
|  | ||||
|     /// @dev Sets the balance of this contract for an existing token. | ||||
|     function setTokenBalance(address tokenAddress, uint256 balance) | ||||
|         external | ||||
|     { | ||||
|         TestToken token = _testTokens[tokenAddress]; | ||||
|         token.setBalance(address(this), balance); | ||||
|     } | ||||
|  | ||||
|     /// @dev Create a new token | ||||
|     /// @param tokenAddress The token address. If zero, one will be created. | ||||
|     function createToken( | ||||
|         address tokenAddress | ||||
|     ) | ||||
|         external | ||||
|         returns (TestToken token) | ||||
|     { | ||||
|         token = TestToken(tokenAddress); | ||||
|         if (tokenAddress == address(0)) { | ||||
|             token = new TestToken(); | ||||
|         } | ||||
|         _testTokens[address(token)] = token; | ||||
|  | ||||
|         return token; | ||||
|     } | ||||
|  | ||||
|     function getNetworkAddress() | ||||
|         external | ||||
|         view | ||||
|         returns (address) | ||||
|     { | ||||
|         return address(_testNetwork); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -38,7 +38,7 @@ | ||||
|         "docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES" | ||||
|     }, | ||||
|     "config": { | ||||
|         "abis": "./test/generated-artifacts/@(BalancerBridge|ChaiBridge|CurveBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MultiAssetProxy|Ownable|StaticCallProxy|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json", | ||||
|         "abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CurveBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MultiAssetProxy|Ownable|StaticCallProxy|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json", | ||||
|         "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." | ||||
|     }, | ||||
|     "repository": { | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| import { ContractArtifact } from 'ethereum-types'; | ||||
|  | ||||
| import * as BalancerBridge from '../generated-artifacts/BalancerBridge.json'; | ||||
| import * as BancorBridge from '../generated-artifacts/BancorBridge.json'; | ||||
| import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json'; | ||||
| import * as CurveBridge from '../generated-artifacts/CurveBridge.json'; | ||||
| import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json'; | ||||
| @@ -20,6 +21,7 @@ import * as IAssetProxy from '../generated-artifacts/IAssetProxy.json'; | ||||
| import * as IAssetProxyDispatcher from '../generated-artifacts/IAssetProxyDispatcher.json'; | ||||
| import * as IAuthorizable from '../generated-artifacts/IAuthorizable.json'; | ||||
| import * as IBalancerPool from '../generated-artifacts/IBalancerPool.json'; | ||||
| import * as IBancorNetwork from '../generated-artifacts/IBancorNetwork.json'; | ||||
| import * as IChai from '../generated-artifacts/IChai.json'; | ||||
| import * as ICurve from '../generated-artifacts/ICurve.json'; | ||||
| import * as IDydx from '../generated-artifacts/IDydx.json'; | ||||
| @@ -40,6 +42,7 @@ import * as MStableBridge from '../generated-artifacts/MStableBridge.json'; | ||||
| import * as MultiAssetProxy from '../generated-artifacts/MultiAssetProxy.json'; | ||||
| import * as Ownable from '../generated-artifacts/Ownable.json'; | ||||
| import * as StaticCallProxy from '../generated-artifacts/StaticCallProxy.json'; | ||||
| import * as TestBancorBridge from '../generated-artifacts/TestBancorBridge.json'; | ||||
| import * as TestChaiBridge from '../generated-artifacts/TestChaiBridge.json'; | ||||
| import * as TestDexForwarderBridge from '../generated-artifacts/TestDexForwarderBridge.json'; | ||||
| import * as TestDydxBridge from '../generated-artifacts/TestDydxBridge.json'; | ||||
| @@ -62,6 +65,7 @@ export const artifacts = { | ||||
|     MultiAssetProxy: MultiAssetProxy as ContractArtifact, | ||||
|     StaticCallProxy: StaticCallProxy as ContractArtifact, | ||||
|     BalancerBridge: BalancerBridge as ContractArtifact, | ||||
|     BancorBridge: BancorBridge as ContractArtifact, | ||||
|     ChaiBridge: ChaiBridge as ContractArtifact, | ||||
|     CurveBridge: CurveBridge as ContractArtifact, | ||||
|     DexForwarderBridge: DexForwarderBridge as ContractArtifact, | ||||
| @@ -77,6 +81,7 @@ export const artifacts = { | ||||
|     IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact, | ||||
|     IAuthorizable: IAuthorizable as ContractArtifact, | ||||
|     IBalancerPool: IBalancerPool as ContractArtifact, | ||||
|     IBancorNetwork: IBancorNetwork as ContractArtifact, | ||||
|     IChai: IChai as ContractArtifact, | ||||
|     ICurve: ICurve as ContractArtifact, | ||||
|     IDydx: IDydx as ContractArtifact, | ||||
| @@ -89,6 +94,7 @@ export const artifacts = { | ||||
|     IUniswapExchange: IUniswapExchange as ContractArtifact, | ||||
|     IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact, | ||||
|     IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact, | ||||
|     TestBancorBridge: TestBancorBridge as ContractArtifact, | ||||
|     TestChaiBridge: TestChaiBridge as ContractArtifact, | ||||
|     TestDexForwarderBridge: TestDexForwarderBridge as ContractArtifact, | ||||
|     TestDydxBridge: TestDydxBridge as ContractArtifact, | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| export * from '../generated-wrappers/balancer_bridge'; | ||||
| export * from '../generated-wrappers/bancor_bridge'; | ||||
| export * from '../generated-wrappers/chai_bridge'; | ||||
| export * from '../generated-wrappers/curve_bridge'; | ||||
| export * from '../generated-wrappers/dex_forwarder_bridge'; | ||||
| @@ -18,6 +19,7 @@ export * from '../generated-wrappers/i_asset_proxy'; | ||||
| export * from '../generated-wrappers/i_asset_proxy_dispatcher'; | ||||
| export * from '../generated-wrappers/i_authorizable'; | ||||
| export * from '../generated-wrappers/i_balancer_pool'; | ||||
| export * from '../generated-wrappers/i_bancor_network'; | ||||
| export * from '../generated-wrappers/i_chai'; | ||||
| export * from '../generated-wrappers/i_curve'; | ||||
| export * from '../generated-wrappers/i_dydx'; | ||||
| @@ -38,6 +40,7 @@ export * from '../generated-wrappers/mixin_gas_token'; | ||||
| export * from '../generated-wrappers/multi_asset_proxy'; | ||||
| export * from '../generated-wrappers/ownable'; | ||||
| export * from '../generated-wrappers/static_call_proxy'; | ||||
| export * from '../generated-wrappers/test_bancor_bridge'; | ||||
| export * from '../generated-wrappers/test_chai_bridge'; | ||||
| export * from '../generated-wrappers/test_dex_forwarder_bridge'; | ||||
| export * from '../generated-wrappers/test_dydx_bridge'; | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| import { ContractArtifact } from 'ethereum-types'; | ||||
|  | ||||
| import * as BalancerBridge from '../test/generated-artifacts/BalancerBridge.json'; | ||||
| import * as BancorBridge from '../test/generated-artifacts/BancorBridge.json'; | ||||
| import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json'; | ||||
| import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json'; | ||||
| import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json'; | ||||
| @@ -20,6 +21,7 @@ import * as IAssetProxy from '../test/generated-artifacts/IAssetProxy.json'; | ||||
| import * as IAssetProxyDispatcher from '../test/generated-artifacts/IAssetProxyDispatcher.json'; | ||||
| import * as IAuthorizable from '../test/generated-artifacts/IAuthorizable.json'; | ||||
| import * as IBalancerPool from '../test/generated-artifacts/IBalancerPool.json'; | ||||
| import * as IBancorNetwork from '../test/generated-artifacts/IBancorNetwork.json'; | ||||
| import * as IChai from '../test/generated-artifacts/IChai.json'; | ||||
| import * as ICurve from '../test/generated-artifacts/ICurve.json'; | ||||
| import * as IDydx from '../test/generated-artifacts/IDydx.json'; | ||||
| @@ -40,6 +42,7 @@ import * as MStableBridge from '../test/generated-artifacts/MStableBridge.json'; | ||||
| import * as MultiAssetProxy from '../test/generated-artifacts/MultiAssetProxy.json'; | ||||
| import * as Ownable from '../test/generated-artifacts/Ownable.json'; | ||||
| import * as StaticCallProxy from '../test/generated-artifacts/StaticCallProxy.json'; | ||||
| import * as TestBancorBridge from '../test/generated-artifacts/TestBancorBridge.json'; | ||||
| import * as TestChaiBridge from '../test/generated-artifacts/TestChaiBridge.json'; | ||||
| import * as TestDexForwarderBridge from '../test/generated-artifacts/TestDexForwarderBridge.json'; | ||||
| import * as TestDydxBridge from '../test/generated-artifacts/TestDydxBridge.json'; | ||||
| @@ -62,6 +65,7 @@ export const artifacts = { | ||||
|     MultiAssetProxy: MultiAssetProxy as ContractArtifact, | ||||
|     StaticCallProxy: StaticCallProxy as ContractArtifact, | ||||
|     BalancerBridge: BalancerBridge as ContractArtifact, | ||||
|     BancorBridge: BancorBridge as ContractArtifact, | ||||
|     ChaiBridge: ChaiBridge as ContractArtifact, | ||||
|     CurveBridge: CurveBridge as ContractArtifact, | ||||
|     DexForwarderBridge: DexForwarderBridge as ContractArtifact, | ||||
| @@ -77,6 +81,7 @@ export const artifacts = { | ||||
|     IAssetProxyDispatcher: IAssetProxyDispatcher as ContractArtifact, | ||||
|     IAuthorizable: IAuthorizable as ContractArtifact, | ||||
|     IBalancerPool: IBalancerPool as ContractArtifact, | ||||
|     IBancorNetwork: IBancorNetwork as ContractArtifact, | ||||
|     IChai: IChai as ContractArtifact, | ||||
|     ICurve: ICurve as ContractArtifact, | ||||
|     IDydx: IDydx as ContractArtifact, | ||||
| @@ -89,6 +94,7 @@ export const artifacts = { | ||||
|     IUniswapExchange: IUniswapExchange as ContractArtifact, | ||||
|     IUniswapExchangeFactory: IUniswapExchangeFactory as ContractArtifact, | ||||
|     IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact, | ||||
|     TestBancorBridge: TestBancorBridge as ContractArtifact, | ||||
|     TestChaiBridge: TestChaiBridge as ContractArtifact, | ||||
|     TestDexForwarderBridge: TestDexForwarderBridge as ContractArtifact, | ||||
|     TestDydxBridge: TestDydxBridge as ContractArtifact, | ||||
|   | ||||
							
								
								
									
										205
									
								
								contracts/asset-proxy/test/bancor_bridge.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								contracts/asset-proxy/test/bancor_bridge.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,205 @@ | ||||
| import { | ||||
|     blockchainTests, | ||||
|     constants, | ||||
|     expect, | ||||
|     filterLogsToArguments, | ||||
|     getRandomInteger, | ||||
|     randomAddress, | ||||
| } from '@0x/contracts-test-utils'; | ||||
| import { AssetProxyId } from '@0x/types'; | ||||
| import { AbiEncoder, BigNumber, hexUtils } from '@0x/utils'; | ||||
| import { DecodedLogs } from 'ethereum-types'; | ||||
| import * as _ from 'lodash'; | ||||
|  | ||||
| import { artifacts } from './artifacts'; | ||||
|  | ||||
| import { TestBancorBridgeContract } from './generated-wrappers/test_bancor_bridge'; | ||||
| import { | ||||
|     TestBancorBridgeConvertByPathInputEventArgs as ConvertByPathArgs, | ||||
|     TestBancorBridgeEvents as ContractEvents, | ||||
|     TestBancorBridgeTokenApproveEventArgs as TokenApproveArgs, | ||||
|     TestBancorBridgeTokenTransferEventArgs as TokenTransferArgs, | ||||
| } from './wrappers'; | ||||
|  | ||||
| blockchainTests.resets('Bancor unit tests', env => { | ||||
|     const FROM_TOKEN_DECIMALS = 6; | ||||
|     const TO_TOKEN_DECIMALS = 18; | ||||
|     const FROM_TOKEN_BASE = new BigNumber(10).pow(FROM_TOKEN_DECIMALS); | ||||
|     const TO_TOKEN_BASE = new BigNumber(10).pow(TO_TOKEN_DECIMALS); | ||||
|     let testContract: TestBancorBridgeContract; | ||||
|  | ||||
|     before(async () => { | ||||
|         testContract = await TestBancorBridgeContract.deployFrom0xArtifactAsync( | ||||
|             artifacts.TestBancorBridge, | ||||
|             env.provider, | ||||
|             env.txDefaults, | ||||
|             artifacts, | ||||
|         ); | ||||
|     }); | ||||
|  | ||||
|     describe('isValidSignature()', () => { | ||||
|         it('returns success bytes', async () => { | ||||
|             const LEGACY_WALLET_MAGIC_VALUE = '0xb0671381'; | ||||
|             const result = await testContract | ||||
|                 .isValidSignature(hexUtils.random(), hexUtils.random(_.random(0, 32))) | ||||
|                 .callAsync(); | ||||
|             expect(result).to.eq(LEGACY_WALLET_MAGIC_VALUE); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     describe('bridgeTransferFrom()', () => { | ||||
|         interface TransferFromOpts { | ||||
|             tokenAddressesPath: string[]; | ||||
|             toAddress: string; | ||||
|             // Amount to pass into `bridgeTransferFrom()` | ||||
|             amount: BigNumber; | ||||
|             // Token balance of the bridge. | ||||
|             fromTokenBalance: BigNumber; | ||||
|             // Router reverts with this reason | ||||
|             routerRevertReason: string; | ||||
|         } | ||||
|  | ||||
|         interface TransferFromResult { | ||||
|             opts: TransferFromOpts; | ||||
|             result: string; | ||||
|             logs: DecodedLogs; | ||||
|             blocktime: number; | ||||
|         } | ||||
|  | ||||
|         function createTransferFromOpts(opts?: Partial<TransferFromOpts>): TransferFromOpts { | ||||
|             const amount = getRandomInteger(1, TO_TOKEN_BASE.times(100)); | ||||
|             return { | ||||
|                 tokenAddressesPath: Array(3).fill(constants.NULL_ADDRESS), | ||||
|                 amount, | ||||
|                 toAddress: randomAddress(), | ||||
|                 fromTokenBalance: getRandomInteger(1, FROM_TOKEN_BASE.times(100)), | ||||
|                 routerRevertReason: '', | ||||
|                 ...opts, | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         const bridgeDataEncoder = AbiEncoder.create('(address[], address)'); | ||||
|  | ||||
|         async function transferFromAsync(opts?: Partial<TransferFromOpts>): Promise<TransferFromResult> { | ||||
|             const _opts = createTransferFromOpts(opts); | ||||
|  | ||||
|             for (let i = 0; i < _opts.tokenAddressesPath.length; i++) { | ||||
|                 const createFromTokenFn = testContract.createToken(_opts.tokenAddressesPath[i]); | ||||
|                 _opts.tokenAddressesPath[i] = await createFromTokenFn.callAsync(); | ||||
|                 await createFromTokenFn.awaitTransactionSuccessAsync(); | ||||
|             } | ||||
|  | ||||
|             // Set the token balance for the token we're converting from. | ||||
|             await testContract | ||||
|                 .setTokenBalance(_opts.tokenAddressesPath[0], _opts.fromTokenBalance) | ||||
|                 .awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             // Set revert reason for the router. | ||||
|             await testContract.setNetworkRevertReason(_opts.routerRevertReason).awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             // Call bridgeTransferFrom(). | ||||
|             const bridgeTransferFromFn = testContract.bridgeTransferFrom( | ||||
|                 // Output token | ||||
|                 _opts.tokenAddressesPath[_opts.tokenAddressesPath.length - 1], | ||||
|                 // Random maker address. | ||||
|                 randomAddress(), | ||||
|                 // Recipient address. | ||||
|                 _opts.toAddress, | ||||
|                 // Transfer amount. | ||||
|                 _opts.amount, | ||||
|                 // ABI-encode the input token address as the bridge data. | ||||
|                 bridgeDataEncoder.encode([ | ||||
|                     _opts.tokenAddressesPath, | ||||
|                     await testContract.getNetworkAddress().callAsync(), | ||||
|                 ]), | ||||
|             ); | ||||
|             const result = await bridgeTransferFromFn.callAsync(); | ||||
|             const receipt = await bridgeTransferFromFn.awaitTransactionSuccessAsync(); | ||||
|             return { | ||||
|                 opts: _opts, | ||||
|                 result, | ||||
|                 logs: (receipt.logs as any) as DecodedLogs, | ||||
|                 blocktime: await env.web3Wrapper.getBlockTimestampAsync(receipt.blockNumber), | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         it('returns magic bytes on success', async () => { | ||||
|             const { result } = await transferFromAsync(); | ||||
|             expect(result).to.eq(AssetProxyId.ERC20Bridge); | ||||
|         }); | ||||
|  | ||||
|         it('performs transfer when both tokens are the same', async () => { | ||||
|             const createTokenFn = testContract.createToken(constants.NULL_ADDRESS); | ||||
|             const tokenAddress = await createTokenFn.callAsync(); | ||||
|             await createTokenFn.awaitTransactionSuccessAsync(); | ||||
|  | ||||
|             const { opts, result, logs } = await transferFromAsync({ | ||||
|                 tokenAddressesPath: [tokenAddress, tokenAddress], | ||||
|             }); | ||||
|             expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|             const transfers = filterLogsToArguments<TokenTransferArgs>(logs, ContractEvents.TokenTransfer); | ||||
|  | ||||
|             expect(transfers.length).to.eq(1); | ||||
|             expect(transfers[0].token).to.eq(tokenAddress, 'input token address'); | ||||
|             expect(transfers[0].from).to.eq(testContract.address); | ||||
|             expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|             expect(transfers[0].amount).to.bignumber.eq(opts.amount, 'amount'); | ||||
|         }); | ||||
|  | ||||
|         describe('token -> token', async () => { | ||||
|             it('calls BancorNetwork.convertByPath()', async () => { | ||||
|                 const { opts, result, logs } = await transferFromAsync(); | ||||
|                 expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|                 const transfers = filterLogsToArguments<ConvertByPathArgs>(logs, ContractEvents.ConvertByPathInput); | ||||
|  | ||||
|                 expect(transfers.length).to.eq(1); | ||||
|                 expect(transfers[0].toTokenAddress).to.eq( | ||||
|                     opts.tokenAddressesPath[opts.tokenAddressesPath.length - 1], | ||||
|                     'output token address', | ||||
|                 ); | ||||
|                 expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|                 expect(transfers[0].amountIn).to.bignumber.eq(opts.fromTokenBalance, 'input token amount'); | ||||
|                 expect(transfers[0].amountOutMin).to.bignumber.eq(opts.amount, 'output token amount'); | ||||
|                 expect(transfers[0].feeRecipient).to.eq(constants.NULL_ADDRESS); | ||||
|                 expect(transfers[0].feeAmount).to.bignumber.eq(new BigNumber(0)); | ||||
|             }); | ||||
|  | ||||
|             it('sets allowance for "from" token', async () => { | ||||
|                 const { logs } = await transferFromAsync(); | ||||
|                 const approvals = filterLogsToArguments<TokenApproveArgs>(logs, ContractEvents.TokenApprove); | ||||
|                 const networkAddress = await testContract.getNetworkAddress().callAsync(); | ||||
|                 expect(approvals.length).to.eq(1); | ||||
|                 expect(approvals[0].spender).to.eq(networkAddress); | ||||
|                 expect(approvals[0].allowance).to.bignumber.eq(constants.MAX_UINT256); | ||||
|             }); | ||||
|  | ||||
|             it('fails if the router fails', async () => { | ||||
|                 const revertReason = 'FOOBAR'; | ||||
|                 const tx = transferFromAsync({ | ||||
|                     routerRevertReason: revertReason, | ||||
|                 }); | ||||
|                 return expect(tx).to.eventually.be.rejectedWith(revertReason); | ||||
|             }); | ||||
|         }); | ||||
|         describe('token -> token -> token', async () => { | ||||
|             it('calls BancorNetwork.convertByPath()', async () => { | ||||
|                 const { opts, result, logs } = await transferFromAsync({ | ||||
|                     tokenAddressesPath: Array(5).fill(constants.NULL_ADDRESS), | ||||
|                 }); | ||||
|                 expect(result).to.eq(AssetProxyId.ERC20Bridge, 'asset proxy id'); | ||||
|                 const transfers = filterLogsToArguments<ConvertByPathArgs>(logs, ContractEvents.ConvertByPathInput); | ||||
|  | ||||
|                 expect(transfers.length).to.eq(1); | ||||
|                 expect(transfers[0].toTokenAddress).to.eq( | ||||
|                     opts.tokenAddressesPath[opts.tokenAddressesPath.length - 1], | ||||
|                     'output token address', | ||||
|                 ); | ||||
|                 expect(transfers[0].to).to.eq(opts.toAddress, 'recipient address'); | ||||
|                 expect(transfers[0].amountIn).to.bignumber.eq(opts.fromTokenBalance, 'input token amount'); | ||||
|                 expect(transfers[0].amountOutMin).to.bignumber.eq(opts.amount, 'output token amount'); | ||||
|                 expect(transfers[0].feeRecipient).to.eq(constants.NULL_ADDRESS); | ||||
|                 expect(transfers[0].feeAmount).to.bignumber.eq(new BigNumber(0)); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -4,6 +4,7 @@ | ||||
|  * ----------------------------------------------------------------------------- | ||||
|  */ | ||||
| export * from '../test/generated-wrappers/balancer_bridge'; | ||||
| export * from '../test/generated-wrappers/bancor_bridge'; | ||||
| export * from '../test/generated-wrappers/chai_bridge'; | ||||
| export * from '../test/generated-wrappers/curve_bridge'; | ||||
| export * from '../test/generated-wrappers/dex_forwarder_bridge'; | ||||
| @@ -18,6 +19,7 @@ export * from '../test/generated-wrappers/i_asset_proxy'; | ||||
| export * from '../test/generated-wrappers/i_asset_proxy_dispatcher'; | ||||
| export * from '../test/generated-wrappers/i_authorizable'; | ||||
| export * from '../test/generated-wrappers/i_balancer_pool'; | ||||
| export * from '../test/generated-wrappers/i_bancor_network'; | ||||
| export * from '../test/generated-wrappers/i_chai'; | ||||
| export * from '../test/generated-wrappers/i_curve'; | ||||
| export * from '../test/generated-wrappers/i_dydx'; | ||||
| @@ -38,6 +40,7 @@ export * from '../test/generated-wrappers/mixin_gas_token'; | ||||
| export * from '../test/generated-wrappers/multi_asset_proxy'; | ||||
| export * from '../test/generated-wrappers/ownable'; | ||||
| export * from '../test/generated-wrappers/static_call_proxy'; | ||||
| export * from '../test/generated-wrappers/test_bancor_bridge'; | ||||
| export * from '../test/generated-wrappers/test_chai_bridge'; | ||||
| export * from '../test/generated-wrappers/test_dex_forwarder_bridge'; | ||||
| export * from '../test/generated-wrappers/test_dydx_bridge'; | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|     "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"], | ||||
|     "files": [ | ||||
|         "generated-artifacts/BalancerBridge.json", | ||||
|         "generated-artifacts/BancorBridge.json", | ||||
|         "generated-artifacts/ChaiBridge.json", | ||||
|         "generated-artifacts/CurveBridge.json", | ||||
|         "generated-artifacts/DexForwarderBridge.json", | ||||
| @@ -18,6 +19,7 @@ | ||||
|         "generated-artifacts/IAssetProxyDispatcher.json", | ||||
|         "generated-artifacts/IAuthorizable.json", | ||||
|         "generated-artifacts/IBalancerPool.json", | ||||
|         "generated-artifacts/IBancorNetwork.json", | ||||
|         "generated-artifacts/IChai.json", | ||||
|         "generated-artifacts/ICurve.json", | ||||
|         "generated-artifacts/IDydx.json", | ||||
| @@ -38,6 +40,7 @@ | ||||
|         "generated-artifacts/MultiAssetProxy.json", | ||||
|         "generated-artifacts/Ownable.json", | ||||
|         "generated-artifacts/StaticCallProxy.json", | ||||
|         "generated-artifacts/TestBancorBridge.json", | ||||
|         "generated-artifacts/TestChaiBridge.json", | ||||
|         "generated-artifacts/TestDexForwarderBridge.json", | ||||
|         "generated-artifacts/TestDydxBridge.json", | ||||
| @@ -50,6 +53,7 @@ | ||||
|         "generated-artifacts/UniswapBridge.json", | ||||
|         "generated-artifacts/UniswapV2Bridge.json", | ||||
|         "test/generated-artifacts/BalancerBridge.json", | ||||
|         "test/generated-artifacts/BancorBridge.json", | ||||
|         "test/generated-artifacts/ChaiBridge.json", | ||||
|         "test/generated-artifacts/CurveBridge.json", | ||||
|         "test/generated-artifacts/DexForwarderBridge.json", | ||||
| @@ -64,6 +68,7 @@ | ||||
|         "test/generated-artifacts/IAssetProxyDispatcher.json", | ||||
|         "test/generated-artifacts/IAuthorizable.json", | ||||
|         "test/generated-artifacts/IBalancerPool.json", | ||||
|         "test/generated-artifacts/IBancorNetwork.json", | ||||
|         "test/generated-artifacts/IChai.json", | ||||
|         "test/generated-artifacts/ICurve.json", | ||||
|         "test/generated-artifacts/IDydx.json", | ||||
| @@ -84,6 +89,7 @@ | ||||
|         "test/generated-artifacts/MultiAssetProxy.json", | ||||
|         "test/generated-artifacts/Ownable.json", | ||||
|         "test/generated-artifacts/StaticCallProxy.json", | ||||
|         "test/generated-artifacts/TestBancorBridge.json", | ||||
|         "test/generated-artifacts/TestChaiBridge.json", | ||||
|         "test/generated-artifacts/TestDexForwarderBridge.json", | ||||
|         "test/generated-artifacts/TestDydxBridge.json", | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
|         "wsrun": "wsrun", | ||||
|         "lerna": "lerna", | ||||
|         "build": "lerna link && wsrun build $PKG -r --stages --fast-exit --exclude-missing", | ||||
|         "build:ci": "lerna link && wsrun build:ci $PKG --fast-exit -r --stages --exclude-missing", | ||||
|         "build:ci": "lerna link && wsrun build:ci $PKG --fast-exit -r --stages --exclude-missing --exclude @0x/instant", | ||||
|         "build:contracts": "lerna link && wsrun build -p ${npm_package_config_contractsPackages} -c --fast-exit -r --stages --exclude-missing", | ||||
|         "build:monorepo_scripts": "PKG=@0x/monorepo-scripts yarn build", | ||||
|         "build:ts": "tsc -b", | ||||
| @@ -39,7 +39,7 @@ | ||||
|         "contracts:watch": "wsrun watch $PKG --parallel --exclude-missing", | ||||
|         "remove_node_modules": "lerna clean --yes; rm -rf node_modules", | ||||
|         "rebuild": "run-s clean build", | ||||
|         "test": "wsrun test $PKG --fast-exit --serial --exclude-missing --exclude @0x/asset-swapper --exclude @0x/orderbook", | ||||
|         "test": "wsrun test $PKG --fast-exit --serial --exclude-missing --exclude @0x/orderbook", | ||||
|         "test:contracts": "wsrun test -p ${npm_package_config_contractsPackages} -c --fast-exit --exclude-missing", | ||||
|         "generate_doc": "node ./packages/monorepo-scripts/lib/doc_generate.js", | ||||
|         "upload_md_docs": "aws s3 rm --recursive s3://docs-markdown; wsrun s3:sync_md_docs --exclude-missing", | ||||
| @@ -62,10 +62,6 @@ | ||||
|             { | ||||
|                 "path": "packages/0x.js/_bundles/index.min.js", | ||||
|                 "maxSize": "1300kB" | ||||
|             }, | ||||
|             { | ||||
|                 "path": "packages/instant/umd/v3/instant.js", | ||||
|                 "maxSize": "2100kB" | ||||
|             } | ||||
|         ], | ||||
|         "ci": { | ||||
|   | ||||
| @@ -46,6 +46,10 @@ | ||||
|                 "note": "Adjust fill by ethToInputRate when ethToOutputRate is 0", | ||||
|                 "pr": 2660 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add Bancor as liquidity source", | ||||
|                 "pr": 2650 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Added `mStable`", | ||||
|                 "pr": 2662 | ||||
|   | ||||
| @@ -68,6 +68,7 @@ | ||||
|         "@0x/utils": "^5.5.1", | ||||
|         "@0x/web3-wrapper": "^7.2.0", | ||||
|         "@balancer-labs/sor": "0.3.2", | ||||
|         "@bancor/sdk": "^0.2.5", | ||||
|         "axios": "^0.19.2", | ||||
|         "axios-mock-adapter": "^1.18.1", | ||||
|         "decimal.js": "^10.2.0", | ||||
|   | ||||
| @@ -108,6 +108,7 @@ export { | ||||
| } from './types'; | ||||
| export { affiliateFeeUtils } from './utils/affiliate_fee_utils'; | ||||
| export { | ||||
|     BancorFillData, | ||||
|     BalancerFillData, | ||||
|     CollapsedFill, | ||||
|     CurveFillData, | ||||
|   | ||||
| @@ -25,6 +25,7 @@ import { | ||||
| import { assert } from './utils/assert'; | ||||
| import { calculateLiquidity } from './utils/calculate_liquidity'; | ||||
| import { MarketOperationUtils } from './utils/market_operation_utils'; | ||||
| import { BancorService } from './utils/market_operation_utils/bancor_service'; | ||||
| import { createDummyOrderForSampler } from './utils/market_operation_utils/orders'; | ||||
| import { DexOrderSampler } from './utils/market_operation_utils/sampler'; | ||||
| import { | ||||
| @@ -202,7 +203,7 @@ export class SwapQuoter { | ||||
|             }, | ||||
|         ); | ||||
|         this._marketOperationUtils = new MarketOperationUtils( | ||||
|             new DexOrderSampler(samplerContract, samplerOverrides), | ||||
|             new DexOrderSampler(samplerContract, samplerOverrides, new BancorService(provider)), | ||||
|             this._contractAddresses, | ||||
|             { | ||||
|                 chainId, | ||||
|   | ||||
| @@ -264,6 +264,7 @@ export interface SwapQuoterOpts extends OrderPrunerOpts { | ||||
|     chainId: number; | ||||
|     orderRefreshIntervalMs: number; | ||||
|     expiryBufferMs: number; | ||||
|     ethereumRpcUrl?: string; | ||||
|     contractAddresses?: ContractAddresses; | ||||
|     samplerGasLimit?: number; | ||||
|     liquidityProviderRegistryAddress?: string; | ||||
|   | ||||
| @@ -0,0 +1,63 @@ | ||||
| import { SupportedProvider } from '@0x/dev-utils'; | ||||
| import { BigNumber } from '@0x/utils'; | ||||
| import { SDK } from '@bancor/sdk'; | ||||
| import { Ethereum, getDecimals } from '@bancor/sdk/dist/blockchains/ethereum'; | ||||
| import { fromWei, toWei } from '@bancor/sdk/dist/helpers'; | ||||
| import { BlockchainType, Token } from '@bancor/sdk/dist/types'; | ||||
|  | ||||
| import { BancorFillData, Quote } from './types'; | ||||
|  | ||||
| /** | ||||
|  * Converts an address to a Bancor Token type | ||||
|  */ | ||||
| export function token(address: string, blockchainType: BlockchainType = BlockchainType.Ethereum): Token { | ||||
|     return { | ||||
|         blockchainType, | ||||
|         blockchainId: address, | ||||
|     }; | ||||
| } | ||||
|  | ||||
| export class BancorService { | ||||
|     // Bancor recommends setting this value to 2% under the expected return amount | ||||
|     public minReturnAmountBufferPercentage = 0.99; | ||||
|     private _sdk?: SDK; | ||||
|  | ||||
|     constructor(public provider: SupportedProvider) {} | ||||
|  | ||||
|     public async getSDKAsync(): Promise<SDK> { | ||||
|         if (!this._sdk) { | ||||
|             this._sdk = await SDK.create({ ethereumNodeEndpoint: this.provider }); | ||||
|         } | ||||
|         return this._sdk; | ||||
|     } | ||||
|  | ||||
|     public async getQuoteAsync( | ||||
|         fromToken: string, | ||||
|         toToken: string, | ||||
|         amount: BigNumber = new BigNumber(1), | ||||
|     ): Promise<Quote<BancorFillData>> { | ||||
|         const sdk = await this.getSDKAsync(); | ||||
|         const blockchain = sdk._core.blockchains[BlockchainType.Ethereum] as Ethereum; | ||||
|         const sourceDecimals = await getDecimals(blockchain, fromToken); | ||||
|         const { path, rate } = await sdk.pricing.getPathAndRate( | ||||
|             token(fromToken), | ||||
|             token(toToken), | ||||
|             fromWei(amount.toString(), sourceDecimals), | ||||
|         ); | ||||
|         const targetDecimals = await getDecimals(blockchain, toToken); | ||||
|         const output = toWei(rate, targetDecimals); | ||||
|         return { | ||||
|             amount: new BigNumber(output).multipliedBy(this.minReturnAmountBufferPercentage).dp(0), | ||||
|             fillData: { | ||||
|                 path: path.map(p => p.blockchainId), | ||||
|                 networkAddress: await this.getBancorNetworkAddressAsync(), | ||||
|             }, | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     public async getBancorNetworkAddressAsync(): Promise<string> { | ||||
|         const sdk = await this.getSDKAsync(); | ||||
|         const blockchain = sdk._core.blockchains[BlockchainType.Ethereum] as Ethereum; | ||||
|         return blockchain.bancorNetwork._address; | ||||
|     } | ||||
| } | ||||
| @@ -14,6 +14,7 @@ export const SELL_SOURCES = [ | ||||
|     ERC20BridgeSource.Kyber, | ||||
|     ERC20BridgeSource.Curve, | ||||
|     ERC20BridgeSource.Balancer, | ||||
|     // ERC20BridgeSource.Bancor, // FIXME: Disabled until Bancor SDK supports batch requests | ||||
|     ERC20BridgeSource.MStable, | ||||
| ]; | ||||
|  | ||||
| @@ -27,6 +28,7 @@ export const BUY_SOURCES = [ | ||||
|     ERC20BridgeSource.Kyber, | ||||
|     ERC20BridgeSource.Curve, | ||||
|     ERC20BridgeSource.Balancer, | ||||
|     // ERC20BridgeSource.Bancor, // FIXME: Disabled until Bancor SDK supports buy quotes | ||||
|     ERC20BridgeSource.MStable, | ||||
| ]; | ||||
|  | ||||
|   | ||||
| @@ -256,6 +256,7 @@ export function collapsePath(path: Fill[]): CollapsedFill[] { | ||||
|             if (prevFill.sourcePathId === fill.sourcePathId) { | ||||
|                 prevFill.input = prevFill.input.plus(fill.input); | ||||
|                 prevFill.output = prevFill.output.plus(fill.output); | ||||
|                 prevFill.fillData = fill.fillData; | ||||
|                 prevFill.subFills.push(fill); | ||||
|                 continue; | ||||
|             } | ||||
|   | ||||
| @@ -114,6 +114,7 @@ export class MarketOperationUtils { | ||||
|                 this._sampler.balancerPoolsCache, | ||||
|                 this._liquidityProviderRegistry, | ||||
|                 this._multiBridge, | ||||
|                 this._sampler.bancorService, | ||||
|             ), | ||||
|             // Get ETH -> taker token price. | ||||
|             await DexOrderSampler.ops.getMedianSellRateAsync( | ||||
| @@ -139,6 +140,7 @@ export class MarketOperationUtils { | ||||
|                 this._sampler.balancerPoolsCache, | ||||
|                 this._liquidityProviderRegistry, | ||||
|                 this._multiBridge, | ||||
|                 this._sampler.bancorService, | ||||
|             ), | ||||
|         ); | ||||
|  | ||||
| @@ -160,6 +162,7 @@ export class MarketOperationUtils { | ||||
|                 this._sampler.balancerPoolsCache, | ||||
|                 this._liquidityProviderRegistry, | ||||
|                 this._multiBridge, | ||||
|                 this._sampler.bancorService, | ||||
|             ) | ||||
|             .then(async r => this._sampler.executeAsync(r)); | ||||
|  | ||||
| @@ -241,6 +244,7 @@ export class MarketOperationUtils { | ||||
|                 this._sampler.balancerPoolsCache, | ||||
|                 this._liquidityProviderRegistry, | ||||
|                 this._multiBridge, | ||||
|                 this._sampler.bancorService, | ||||
|             ), | ||||
|             // Get buy quotes for taker -> maker. | ||||
|             await DexOrderSampler.ops.getBuyQuotesAsync( | ||||
| @@ -248,7 +252,7 @@ export class MarketOperationUtils { | ||||
|                     BUY_SOURCES.concat( | ||||
|                         this._liquidityProviderRegistry !== NULL_ADDRESS ? [ERC20BridgeSource.LiquidityProvider] : [], | ||||
|                     ), | ||||
|                     _opts.excludedSources.concat(ERC20BridgeSource.Balancer), | ||||
|                     _opts.excludedSources.concat([ERC20BridgeSource.Balancer]), | ||||
|                 ), | ||||
|                 makerToken, | ||||
|                 takerToken, | ||||
| @@ -256,6 +260,7 @@ export class MarketOperationUtils { | ||||
|                 this._wethAddress, | ||||
|                 this._sampler.balancerPoolsCache, | ||||
|                 this._liquidityProviderRegistry, | ||||
|                 this._sampler.bancorService, | ||||
|             ), | ||||
|         ); | ||||
|  | ||||
| @@ -268,6 +273,7 @@ export class MarketOperationUtils { | ||||
|                 this._wethAddress, | ||||
|                 this._sampler.balancerPoolsCache, | ||||
|                 this._liquidityProviderRegistry, | ||||
|                 this._sampler.bancorService, | ||||
|             ), | ||||
|         ); | ||||
|  | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import { getMultiBridgeIntermediateToken } from './multibridge_utils'; | ||||
| import { | ||||
|     AggregationError, | ||||
|     BalancerFillData, | ||||
|     BancorFillData, | ||||
|     CollapsedFill, | ||||
|     CurveFillData, | ||||
|     ERC20BridgeSource, | ||||
| @@ -190,6 +191,8 @@ function getBridgeAddressFromFill(fill: CollapsedFill, opts: CreateOrderFromPath | ||||
|             return opts.contractAddresses.uniswapV2Bridge; | ||||
|         case ERC20BridgeSource.Curve: | ||||
|             return opts.contractAddresses.curveBridge; | ||||
|         case ERC20BridgeSource.Bancor: | ||||
|             return opts.contractAddresses.bancorBridge; | ||||
|         case ERC20BridgeSource.Balancer: | ||||
|             return opts.contractAddresses.balancerBridge; | ||||
|         case ERC20BridgeSource.LiquidityProvider: | ||||
| @@ -232,6 +235,14 @@ function createBridgeOrder(fill: CollapsedFill, opts: CreateOrderFromPathOpts): | ||||
|                 createBalancerBridgeData(takerToken, balancerFillData.poolAddress), | ||||
|             ); | ||||
|             break; | ||||
|         case ERC20BridgeSource.Bancor: | ||||
|             const bancorFillData = (fill as CollapsedFill<BancorFillData>).fillData!; // tslint:disable-line:no-non-null-assertion | ||||
|             makerAssetData = assetDataUtils.encodeERC20BridgeAssetData( | ||||
|                 makerToken, | ||||
|                 bridgeAddress, | ||||
|                 createBancorBridgeData(bancorFillData.path, bancorFillData.networkAddress), | ||||
|             ); | ||||
|             break; | ||||
|         case ERC20BridgeSource.UniswapV2: | ||||
|             const uniswapV2FillData = (fill as CollapsedFill<UniswapV2FillData>).fillData!; // tslint:disable-line:no-non-null-assertion | ||||
|             makerAssetData = assetDataUtils.encodeERC20BridgeAssetData( | ||||
| @@ -337,6 +348,14 @@ function createBalancerBridgeData(takerToken: string, poolAddress: string): stri | ||||
|     return encoder.encode({ takerToken, poolAddress }); | ||||
| } | ||||
|  | ||||
| function createBancorBridgeData(path: string[], networkAddress: string): string { | ||||
|     const encoder = AbiEncoder.create([ | ||||
|         { name: 'path', type: 'address[]' }, | ||||
|         { name: 'networkAddress', type: 'address' }, | ||||
|     ]); | ||||
|     return encoder.encode({ path, networkAddress }); | ||||
| } | ||||
|  | ||||
| function createCurveBridgeData( | ||||
|     curveAddress: string, | ||||
|     exchangeFunctionSelector: string, | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { SamplerOverrides } from '../../types'; | ||||
| import { ERC20BridgeSamplerContract } from '../../wrappers'; | ||||
|  | ||||
| import { BalancerPoolsCache } from './balancer_utils'; | ||||
| import { BancorService } from './bancor_service'; | ||||
| import { samplerOperations } from './sampler_operations'; | ||||
| import { BatchedOperation } from './types'; | ||||
|  | ||||
| @@ -39,6 +40,7 @@ export class DexOrderSampler { | ||||
|     constructor( | ||||
|         private readonly _samplerContract: ERC20BridgeSamplerContract, | ||||
|         private readonly _samplerOverrides?: SamplerOverrides, | ||||
|         public bancorService?: BancorService, | ||||
|         public balancerPoolsCache: BalancerPoolsCache = new BalancerPoolsCache(), | ||||
|     ) {} | ||||
|  | ||||
|   | ||||
| @@ -3,15 +3,19 @@ import * as _ from 'lodash'; | ||||
| import { BigNumber, ERC20BridgeSource, SignedOrder } from '../..'; | ||||
|  | ||||
| import { BalancerPool, BalancerPoolsCache, computeBalancerBuyQuote, computeBalancerSellQuote } from './balancer_utils'; | ||||
| import { BancorService } from './bancor_service'; | ||||
| import { NULL_BYTES, ZERO_AMOUNT } from './constants'; | ||||
| import { getCurveInfosForPair } from './curve_utils'; | ||||
| import { getMultiBridgeIntermediateToken } from './multibridge_utils'; | ||||
| import { | ||||
|     BalancerFillData, | ||||
|     BancorFillData, | ||||
|     BatchedOperation, | ||||
|     CurveFillData, | ||||
|     CurveInfo, | ||||
|     DexSample, | ||||
|     FillData, | ||||
|     Quote, | ||||
|     SourceQuoteOperation, | ||||
|     UniswapV2FillData, | ||||
| } from './types'; | ||||
| @@ -54,7 +58,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromKyberNetwork', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromKyberNetwork', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -67,7 +73,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromKyberNetwork', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleBuysFromKyberNetwork', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -80,7 +88,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromUniswap', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromUniswap', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -93,7 +103,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromUniswap', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleBuysFromUniswap', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -103,14 +115,18 @@ export const samplerOperations = { | ||||
|     ): SourceQuoteOperation<UniswapV2FillData> { | ||||
|         return { | ||||
|             source: ERC20BridgeSource.UniswapV2, | ||||
|             fillData: { tokenAddressPath }, | ||||
|             encodeCall: contract => { | ||||
|                 return contract | ||||
|                     .sampleSellsFromUniswapV2(tokenAddressPath, takerFillAmounts) | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromUniswapV2', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromUniswapV2', callResults) | ||||
|                     .map(amount => ({ | ||||
|                         amount, | ||||
|                         fillData: { tokenAddressPath }, | ||||
|                     })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -120,14 +136,18 @@ export const samplerOperations = { | ||||
|     ): SourceQuoteOperation<UniswapV2FillData> { | ||||
|         return { | ||||
|             source: ERC20BridgeSource.UniswapV2, | ||||
|             fillData: { tokenAddressPath }, | ||||
|             encodeCall: contract => { | ||||
|                 return contract | ||||
|                     .sampleBuysFromUniswapV2(tokenAddressPath, makerFillAmounts) | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromUniswapV2', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleBuysFromUniswapV2', callResults) | ||||
|                     .map(amount => ({ | ||||
|                         amount, | ||||
|                         fillData: { tokenAddressPath }, | ||||
|                     })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -145,10 +165,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>( | ||||
|                     'sampleSellsFromLiquidityProviderRegistry', | ||||
|                     callResults, | ||||
|                 ); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromLiquidityProviderRegistry', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -166,10 +185,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>( | ||||
|                     'sampleBuysFromLiquidityProviderRegistry', | ||||
|                     callResults, | ||||
|                 ); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleBuysFromLiquidityProviderRegistry', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -194,7 +212,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromMultiBridge', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromMultiBridge', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -207,7 +227,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromEth2Dai', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromEth2Dai', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -220,7 +242,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromEth2Dai', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleBuysFromEth2Dai', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -232,11 +256,6 @@ export const samplerOperations = { | ||||
|     ): SourceQuoteOperation<CurveFillData> { | ||||
|         return { | ||||
|             source: ERC20BridgeSource.Curve, | ||||
|             fillData: { | ||||
|                 curve, | ||||
|                 fromTokenIdx, | ||||
|                 toTokenIdx, | ||||
|             }, | ||||
|             encodeCall: contract => { | ||||
|                 return contract | ||||
|                     .sampleSellsFromCurve( | ||||
| @@ -252,7 +271,16 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromCurve', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromCurve', callResults) | ||||
|                     .map(amount => ({ | ||||
|                         amount, | ||||
|                         fillData: { | ||||
|                             curve, | ||||
|                             fromTokenIdx, | ||||
|                             toTokenIdx, | ||||
|                         }, | ||||
|                     })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -264,11 +292,6 @@ export const samplerOperations = { | ||||
|     ): SourceQuoteOperation<CurveFillData> { | ||||
|         return { | ||||
|             source: ERC20BridgeSource.Curve, | ||||
|             fillData: { | ||||
|                 curve, | ||||
|                 fromTokenIdx, | ||||
|                 toTokenIdx, | ||||
|             }, | ||||
|             encodeCall: contract => { | ||||
|                 return contract | ||||
|                     .sampleBuysFromCurve( | ||||
| @@ -284,22 +307,57 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromCurve', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleBuysFromCurve', callResults) | ||||
|                     .map(amount => ({ | ||||
|                         amount, | ||||
|                         fillData: { | ||||
|                             curve, | ||||
|                             fromTokenIdx, | ||||
|                             toTokenIdx, | ||||
|                         }, | ||||
|                     })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
|     getBancorSellQuotes( | ||||
|         makerToken: string, | ||||
|         takerToken: string, | ||||
|         takerFillAmounts: BigNumber[], | ||||
|         bancorService: BancorService, | ||||
|     ): SourceQuoteOperation<BancorFillData> { | ||||
|         return { | ||||
|             source: ERC20BridgeSource.Bancor, | ||||
|             encodeCall: _contract => { | ||||
|                 return '0x'; | ||||
|             }, | ||||
|             handleCallResultsAsync: async (_contract, _callResults) => { | ||||
|                 return Promise.all( | ||||
|                     takerFillAmounts.map(async amt => bancorService.getQuoteAsync(takerToken, makerToken, amt)), | ||||
|                 ); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
|     getBalancerSellQuotes(pool: BalancerPool, takerFillAmounts: BigNumber[]): SourceQuoteOperation<BalancerFillData> { | ||||
|         return { | ||||
|             source: ERC20BridgeSource.Balancer, | ||||
|             ...samplerOperations.constant( | ||||
|                 takerFillAmounts.map(amount => ({ | ||||
|                     amount: computeBalancerSellQuote(pool, amount), | ||||
|                     fillData: { poolAddress: pool.id }, | ||||
|             ...samplerOperations.constant(takerFillAmounts.map(amount => computeBalancerSellQuote(pool, amount))), | ||||
|                 })), | ||||
|             ), | ||||
|         }; | ||||
|     }, | ||||
|     getBalancerBuyQuotes(pool: BalancerPool, makerFillAmounts: BigNumber[]): SourceQuoteOperation<BalancerFillData> { | ||||
|         return { | ||||
|             source: ERC20BridgeSource.Balancer, | ||||
|             ...samplerOperations.constant( | ||||
|                 makerFillAmounts.map(amount => ({ | ||||
|                     amount: computeBalancerBuyQuote(pool, amount), | ||||
|                     fillData: { poolAddress: pool.id }, | ||||
|             ...samplerOperations.constant(makerFillAmounts.map(amount => computeBalancerBuyQuote(pool, amount))), | ||||
|                 })), | ||||
|             ), | ||||
|         }; | ||||
|     }, | ||||
|     getMStableSellQuotes(makerToken: string, takerToken: string, takerFillAmounts: BigNumber[]): SourceQuoteOperation { | ||||
| @@ -311,7 +369,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleSellsFromMStable', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleSellsFromMStable', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -324,7 +384,9 @@ export const samplerOperations = { | ||||
|                     .getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 return contract.getABIDecodedReturnData<BigNumber[]>('sampleBuysFromMStable', callResults); | ||||
|                 return contract | ||||
|                     .getABIDecodedReturnData<BigNumber[]>('sampleBuysFromMStable', callResults) | ||||
|                     .map(amount => ({ amount })); | ||||
|             }, | ||||
|         }; | ||||
|     }, | ||||
| @@ -337,6 +399,7 @@ export const samplerOperations = { | ||||
|         balancerPoolsCache?: BalancerPoolsCache, | ||||
|         liquidityProviderRegistryAddress?: string, | ||||
|         multiBridgeAddress?: string, | ||||
|         bancorService?: BancorService, | ||||
|     ): Promise<BatchedOperation<BigNumber>> => { | ||||
|         if (makerToken.toLowerCase() === takerToken.toLowerCase()) { | ||||
|             return samplerOperations.constant(new BigNumber(1)); | ||||
| @@ -350,6 +413,7 @@ export const samplerOperations = { | ||||
|             balancerPoolsCache, | ||||
|             liquidityProviderRegistryAddress, | ||||
|             multiBridgeAddress, | ||||
|             bancorService, | ||||
|         ); | ||||
|         return { | ||||
|             encodeCall: contract => { | ||||
| @@ -417,11 +481,12 @@ export const samplerOperations = { | ||||
|         balancerPoolsCache?: BalancerPoolsCache, | ||||
|         liquidityProviderRegistryAddress?: string, | ||||
|         multiBridgeAddress?: string, | ||||
|         bancorService?: BancorService, | ||||
|     ): Promise<BatchedOperation<DexSample[][]>> => { | ||||
|         const subOps = _.flatten( | ||||
|             await Promise.all( | ||||
|                 sources.map( | ||||
|                     async (source): Promise<SourceQuoteOperation | SourceQuoteOperation[]> => { | ||||
|                     async (source): Promise<SourceQuoteOperation<FillData> | Array<SourceQuoteOperation<FillData>>> => { | ||||
|                         switch (source) { | ||||
|                             case ERC20BridgeSource.Eth2Dai: | ||||
|                                 return samplerOperations.getEth2DaiSellQuotes(makerToken, takerToken, takerFillAmounts); | ||||
| @@ -491,6 +556,18 @@ export const samplerOperations = { | ||||
|                                 return pools.map(pool => | ||||
|                                     samplerOperations.getBalancerSellQuotes(pool, takerFillAmounts), | ||||
|                                 ); | ||||
|                             case ERC20BridgeSource.Bancor: | ||||
|                                 if (bancorService === undefined) { | ||||
|                                     throw new Error( | ||||
|                                         'Cannot sample liquidity from Bancor; no Bancor service instantiated.', | ||||
|                                     ); | ||||
|                                 } | ||||
|                                 return samplerOperations.getBancorSellQuotes( | ||||
|                                     makerToken, | ||||
|                                     takerToken, | ||||
|                                     takerFillAmounts, | ||||
|                                     bancorService, | ||||
|                                 ); | ||||
|                             case ERC20BridgeSource.MStable: | ||||
|                                 return samplerOperations.getMStableSellQuotes(makerToken, takerToken, takerFillAmounts); | ||||
|                             default: | ||||
| @@ -500,8 +577,16 @@ export const samplerOperations = { | ||||
|                 ), | ||||
|             ), | ||||
|         ); | ||||
|         const samplerOps = subOps.filter(op => op.source !== ERC20BridgeSource.Balancer); | ||||
|         const nonSamplerOps = subOps.filter(op => op.source === ERC20BridgeSource.Balancer); | ||||
|         const nonSamplerSources = [ERC20BridgeSource.Balancer, ERC20BridgeSource.Bancor]; | ||||
|         const samplerOps: Array<SourceQuoteOperation<FillData>> = []; | ||||
|         const nonSamplerOps: Array<SourceQuoteOperation<FillData>> = []; | ||||
|         subOps.forEach(op => { | ||||
|             if (nonSamplerSources.includes(op.source)) { | ||||
|                 nonSamplerOps.push(op); | ||||
|             } else { | ||||
|                 samplerOps.push(op); | ||||
|             } | ||||
|         }); | ||||
|         return { | ||||
|             encodeCall: contract => { | ||||
|                 // All operations are NOOPs | ||||
| @@ -512,7 +597,7 @@ export const samplerOperations = { | ||||
|                 return contract.batchCall(subCalls).getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 let samples: BigNumber[][]; | ||||
|                 let samples: Array<Array<Quote<FillData>>>; | ||||
|                 // If all operations were NOOPs then just call the handle result callback | ||||
|                 if (callResults === NULL_BYTES && samplerOps.length === 0) { | ||||
|                     samples = await Promise.all(nonSamplerOps.map(async op => op.handleCallResultsAsync(contract, ''))); | ||||
| @@ -528,9 +613,9 @@ export const samplerOperations = { | ||||
|                 return [...samplerOps, ...nonSamplerOps].map((op, i) => { | ||||
|                     return samples[i].map((output, j) => ({ | ||||
|                         source: op.source, | ||||
|                         output, | ||||
|                         output: output.amount, | ||||
|                         input: takerFillAmounts[j], | ||||
|                         fillData: op.fillData, | ||||
|                         fillData: output.fillData, | ||||
|                     })); | ||||
|                 }); | ||||
|             }, | ||||
| @@ -544,11 +629,12 @@ export const samplerOperations = { | ||||
|         wethAddress: string, | ||||
|         balancerPoolsCache?: BalancerPoolsCache, | ||||
|         liquidityProviderRegistryAddress?: string, | ||||
|         bancorService?: BancorService, | ||||
|     ): Promise<BatchedOperation<DexSample[][]>> => { | ||||
|         const subOps = _.flatten( | ||||
|             await Promise.all( | ||||
|                 sources.map( | ||||
|                     async (source): Promise<SourceQuoteOperation | SourceQuoteOperation[]> => { | ||||
|                     async (source): Promise<SourceQuoteOperation<FillData> | Array<SourceQuoteOperation<FillData>>> => { | ||||
|                         switch (source) { | ||||
|                             case ERC20BridgeSource.Eth2Dai: | ||||
|                                 return samplerOperations.getEth2DaiBuyQuotes(makerToken, takerToken, makerFillAmounts); | ||||
| @@ -600,6 +686,8 @@ export const samplerOperations = { | ||||
|                                 return pools.map(pool => | ||||
|                                     samplerOperations.getBalancerBuyQuotes(pool, makerFillAmounts), | ||||
|                                 ); | ||||
|                             case ERC20BridgeSource.Bancor: | ||||
|                                 return []; //  FIXME: Waiting for Bancor SDK to support buy quotes, but don't throw an error here | ||||
|                             case ERC20BridgeSource.MStable: | ||||
|                                 return samplerOperations.getMStableBuyQuotes(makerToken, takerToken, makerFillAmounts); | ||||
|                             default: | ||||
| @@ -609,8 +697,16 @@ export const samplerOperations = { | ||||
|                 ), | ||||
|             ), | ||||
|         ); | ||||
|         const samplerOps = subOps.filter(op => op.source !== ERC20BridgeSource.Balancer); | ||||
|         const nonSamplerOps = subOps.filter(op => op.source === ERC20BridgeSource.Balancer); | ||||
|         const nonSamplerSources = [ERC20BridgeSource.Balancer, ERC20BridgeSource.Bancor]; | ||||
|         const samplerOps: Array<SourceQuoteOperation<FillData>> = []; | ||||
|         const nonSamplerOps: Array<SourceQuoteOperation<FillData>> = []; | ||||
|         subOps.forEach(op => { | ||||
|             if (nonSamplerSources.find(s => s === op.source) !== undefined) { | ||||
|                 nonSamplerOps.push(op); | ||||
|             } else { | ||||
|                 samplerOps.push(op); | ||||
|             } | ||||
|         }); | ||||
|         return { | ||||
|             encodeCall: contract => { | ||||
|                 // All operations are NOOPs | ||||
| @@ -621,7 +717,7 @@ export const samplerOperations = { | ||||
|                 return contract.batchCall(subCalls).getABIEncodedTransactionData(); | ||||
|             }, | ||||
|             handleCallResultsAsync: async (contract, callResults) => { | ||||
|                 let samples: BigNumber[][]; | ||||
|                 let samples: Array<Array<Quote<FillData>>>; | ||||
|                 if (callResults === NULL_BYTES && samplerOps.length === 0) { | ||||
|                     samples = await Promise.all(nonSamplerOps.map(async op => op.handleCallResultsAsync(contract, ''))); | ||||
|                 } else { | ||||
| @@ -636,9 +732,9 @@ export const samplerOperations = { | ||||
|                 return [...samplerOps, ...nonSamplerOps].map((op, i) => { | ||||
|                     return samples[i].map((output, j) => ({ | ||||
|                         source: op.source, | ||||
|                         output, | ||||
|                         output: output.amount, | ||||
|                         input: makerFillAmounts[j], | ||||
|                         fillData: op.fillData, | ||||
|                         fillData: output.fillData, | ||||
|                     })); | ||||
|                 }); | ||||
|             }, | ||||
|   | ||||
| @@ -38,6 +38,7 @@ export enum ERC20BridgeSource { | ||||
|     LiquidityProvider = 'LiquidityProvider', | ||||
|     MultiBridge = 'MultiBridge', | ||||
|     Balancer = 'Balancer', | ||||
|     Bancor = 'Bancor', | ||||
|     MStable = 'mStable', | ||||
| } | ||||
|  | ||||
| @@ -96,6 +97,15 @@ export interface LiquidityProviderFillData extends FillData { | ||||
| export interface MultiBridgeFillData extends FillData { | ||||
|     poolAddress: string; | ||||
| } | ||||
| export interface BancorFillData extends FillData { | ||||
|     path: string[]; | ||||
|     networkAddress: string; | ||||
| } | ||||
|  | ||||
| export interface Quote<TFillData = FillData> { | ||||
|     amount: BigNumber; | ||||
|     fillData?: TFillData; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Represents an individual DEX sample from the sampler contract. | ||||
| @@ -266,9 +276,9 @@ export interface BatchedOperation<TResult> { | ||||
|     handleCallResultsAsync(contract: ERC20BridgeSamplerContract, callResults: string): Promise<TResult>; | ||||
| } | ||||
|  | ||||
| export interface SourceQuoteOperation<TFillData extends FillData = FillData> extends BatchedOperation<BigNumber[]> { | ||||
| export interface SourceQuoteOperation<TFillData extends FillData = FillData> | ||||
|     extends BatchedOperation<Array<Quote<TFillData>>> { | ||||
|     source: ERC20BridgeSource; | ||||
|     fillData?: TFillData; | ||||
| } | ||||
|  | ||||
| export interface OptimizedOrdersAndQuoteReport { | ||||
|   | ||||
							
								
								
									
										61
									
								
								packages/asset-swapper/test/bancor_service_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								packages/asset-swapper/test/bancor_service_test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| import { web3Factory, Web3ProviderEngine } from '@0x/dev-utils'; | ||||
| import * as chai from 'chai'; | ||||
| import * as _ from 'lodash'; | ||||
| import 'mocha'; | ||||
|  | ||||
| import { BancorFillData, BigNumber } from '../src'; | ||||
| import { BancorService, token } from '../src/utils/market_operation_utils/bancor_service'; | ||||
|  | ||||
| import { chaiSetup } from './utils/chai_setup'; | ||||
|  | ||||
| chaiSetup.configure(); | ||||
| const expect = chai.expect; | ||||
|  | ||||
| const ADDRESS_REGEX = /^(0x)?[0-9a-f]{40}$/i; | ||||
| const RPC_URL = `https://mainnet.infura.io/v3/${process.env.INFURA_PROJECT_ID}`; | ||||
|  | ||||
| const provider: Web3ProviderEngine = web3Factory.getRpcProvider({ rpcUrl: RPC_URL }); | ||||
| // tslint:disable:custom-no-magic-numbers | ||||
|  | ||||
| // These tests test the bancor SDK against mainnet | ||||
| // TODO (xianny): After we move asset-swapper out of the monorepo, we should add an env variable to circle CI to run this test | ||||
| describe.skip('Bancor Service', () => { | ||||
|     const bancorService = new BancorService(provider); | ||||
|     const eth = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'; | ||||
|     const bnt = '0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c'; | ||||
|     it('should retrieve the bancor network address', async () => { | ||||
|         const networkAddress = await bancorService.getBancorNetworkAddressAsync(); | ||||
|         expect(networkAddress).to.match(ADDRESS_REGEX); | ||||
|     }); | ||||
|     it('should retrieve a quote', async () => { | ||||
|         const amt = new BigNumber(2); | ||||
|         const quote = await bancorService.getQuoteAsync(eth, bnt, amt); | ||||
|         const fillData = quote.fillData as BancorFillData; | ||||
|  | ||||
|         // get rate from the bancor sdk | ||||
|         const sdk = await bancorService.getSDKAsync(); | ||||
|         const expectedAmt = await sdk.pricing.getRateByPath(fillData.path.map(s => token(s)), amt.toString()); | ||||
|  | ||||
|         expect(fillData.networkAddress).to.match(ADDRESS_REGEX); | ||||
|         expect(fillData.path).to.be.an.instanceOf(Array); | ||||
|         expect(fillData.path).to.have.lengthOf(3); | ||||
|         expect(quote.amount.dp(0)).to.bignumber.eq( | ||||
|             new BigNumber(expectedAmt).multipliedBy(bancorService.minReturnAmountBufferPercentage).dp(0), | ||||
|         ); | ||||
|     }); | ||||
|     // HACK (xianny): for exploring SDK results | ||||
|     it('should retrieve multiple quotes', async () => { | ||||
|         const amts = [1, 10, 100, 1000].map(a => new BigNumber(a).multipliedBy(10e18)); | ||||
|         const quotes = await Promise.all(amts.map(async amount => bancorService.getQuoteAsync(eth, bnt, amount))); | ||||
|         quotes.map((q, i) => { | ||||
|             // tslint:disable:no-console | ||||
|             const fillData = q.fillData as BancorFillData; | ||||
|             console.log( | ||||
|                 `Input ${amts[i].toExponential()}; Output: ${q.amount}; Path: ${ | ||||
|                     fillData.path.length | ||||
|                 }\nPath: ${JSON.stringify(fillData.path)}`, | ||||
|             ); | ||||
|             // tslint:enable:no-console | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -21,7 +21,9 @@ import { DexOrderSampler, getSampleAmounts } from '../src/utils/market_operation | ||||
| import { ERC20BridgeSource, FillData } from '../src/utils/market_operation_utils/types'; | ||||
|  | ||||
| import { MockBalancerPoolsCache } from './utils/mock_balancer_pools_cache'; | ||||
| import { MockBancorService } from './utils/mock_bancor_service'; | ||||
| import { MockSamplerContract } from './utils/mock_sampler_contract'; | ||||
| import { provider } from './utils/web3_wrapper'; | ||||
|  | ||||
| const CHAIN_ID = 1; | ||||
| // tslint:disable: custom-no-magic-numbers | ||||
| @@ -148,7 +150,7 @@ describe('DexSampler tests', () => { | ||||
|                     expectedTakerFillAmounts, | ||||
|                 ), | ||||
|             ); | ||||
|             expect(fillableAmounts).to.deep.eq(expectedMakerFillAmounts); | ||||
|             expect(fillableAmounts.map(q => q.amount)).to.deep.eq(expectedMakerFillAmounts); | ||||
|         }); | ||||
|  | ||||
|         it('getLiquidityProviderSellQuotes()', async () => { | ||||
| @@ -288,7 +290,7 @@ describe('DexSampler tests', () => { | ||||
|                     expectedTakerFillAmounts, | ||||
|                 ), | ||||
|             ); | ||||
|             expect(fillableAmounts).to.deep.eq(expectedMakerFillAmounts); | ||||
|             expect(fillableAmounts.map(q => q.amount)).to.deep.eq(expectedMakerFillAmounts); | ||||
|         }); | ||||
|  | ||||
|         it('getUniswapSellQuotes()', async () => { | ||||
| @@ -312,7 +314,7 @@ describe('DexSampler tests', () => { | ||||
|                     expectedTakerFillAmounts, | ||||
|                 ), | ||||
|             ); | ||||
|             expect(fillableAmounts).to.deep.eq(expectedMakerFillAmounts); | ||||
|             expect(fillableAmounts.map(q => q.amount)).to.deep.eq(expectedMakerFillAmounts); | ||||
|         }); | ||||
|  | ||||
|         it('getUniswapV2SellQuotes()', async () => { | ||||
| @@ -334,7 +336,7 @@ describe('DexSampler tests', () => { | ||||
|                     expectedTakerFillAmounts, | ||||
|                 ), | ||||
|             ); | ||||
|             expect(fillableAmounts).to.deep.eq(expectedMakerFillAmounts); | ||||
|             expect(fillableAmounts.map(q => q.amount)).to.deep.eq(expectedMakerFillAmounts); | ||||
|         }); | ||||
|  | ||||
|         it('getEth2DaiBuyQuotes()', async () => { | ||||
| @@ -358,7 +360,7 @@ describe('DexSampler tests', () => { | ||||
|                     expectedMakerFillAmounts, | ||||
|                 ), | ||||
|             ); | ||||
|             expect(fillableAmounts).to.deep.eq(expectedTakerFillAmounts); | ||||
|             expect(fillableAmounts.map(q => q.amount)).to.deep.eq(expectedTakerFillAmounts); | ||||
|         }); | ||||
|  | ||||
|         it('getUniswapBuyQuotes()', async () => { | ||||
| @@ -382,7 +384,7 @@ describe('DexSampler tests', () => { | ||||
|                     expectedMakerFillAmounts, | ||||
|                 ), | ||||
|             ); | ||||
|             expect(fillableAmounts).to.deep.eq(expectedTakerFillAmounts); | ||||
|             expect(fillableAmounts.map(q => q.amount)).to.deep.eq(expectedTakerFillAmounts); | ||||
|         }); | ||||
|  | ||||
|         interface RatesBySource { | ||||
| @@ -484,7 +486,12 @@ describe('DexSampler tests', () => { | ||||
|                     return Promise.resolve(pools); | ||||
|                 }, | ||||
|             }); | ||||
|             const dexOrderSampler = new DexOrderSampler(new MockSamplerContract({}), undefined, balancerPoolsCache); | ||||
|             const dexOrderSampler = new DexOrderSampler( | ||||
|                 new MockSamplerContract({}), | ||||
|                 undefined, // sampler overrides | ||||
|                 undefined, // bancor service | ||||
|                 balancerPoolsCache, | ||||
|             ); | ||||
|             const [quotes] = await dexOrderSampler.executeAsync( | ||||
|                 await DexOrderSampler.ops.getSellQuotesAsync( | ||||
|                     [ERC20BridgeSource.Balancer], | ||||
| @@ -506,7 +513,52 @@ describe('DexSampler tests', () => { | ||||
|             expect(quotes).to.have.lengthOf(2); // one array per pool | ||||
|             expect(quotes).to.deep.eq(expectedQuotes); | ||||
|         }); | ||||
|  | ||||
|         it('getSellQuotes() uses samples from Bancor', async () => { | ||||
|             const expectedTakerToken = randomAddress(); | ||||
|             const expectedMakerToken = randomAddress(); | ||||
|             const networkAddress = randomAddress(); | ||||
|             const expectedTakerFillAmounts = getSampleAmounts(new BigNumber(100e18), 3); | ||||
|             const rate = getRandomFloat(0, 100); | ||||
|             const bancorService = new MockBancorService(provider, { | ||||
|                 getQuoteAsync: async (fromToken: string, toToken: string, amount: BigNumber) => { | ||||
|                     expect(fromToken).equal(expectedTakerToken); | ||||
|                     expect(toToken).equal(expectedMakerToken); | ||||
|                     return Promise.resolve({ | ||||
|                         fillData: { path: [fromToken, toToken], networkAddress }, | ||||
|                         amount: amount.multipliedBy(rate), | ||||
|                     }); | ||||
|                 }, | ||||
|             }); | ||||
|             const dexOrderSampler = new DexOrderSampler( | ||||
|                 new MockSamplerContract({}), | ||||
|                 undefined, // sampler overrides | ||||
|                 bancorService, | ||||
|                 undefined, // balancer cache | ||||
|             ); | ||||
|             const [quotes] = await dexOrderSampler.executeAsync( | ||||
|                 await DexOrderSampler.ops.getSellQuotesAsync( | ||||
|                     [ERC20BridgeSource.Bancor], | ||||
|                     expectedMakerToken, | ||||
|                     expectedTakerToken, | ||||
|                     expectedTakerFillAmounts, | ||||
|                     wethAddress, | ||||
|                     undefined, // balancer pools cache | ||||
|                     undefined, // liquidity provider registry address | ||||
|                     undefined, // multibridge address | ||||
|                     bancorService, | ||||
|                 ), | ||||
|             ); | ||||
|             const expectedQuotes = [ | ||||
|                 expectedTakerFillAmounts.map(a => ({ | ||||
|                     source: ERC20BridgeSource.Bancor, | ||||
|                     input: a, | ||||
|                     output: a.multipliedBy(rate), | ||||
|                     fillData: { path: [expectedTakerToken, expectedMakerToken], networkAddress }, | ||||
|                 })), | ||||
|             ]; | ||||
|             expect(quotes).to.have.lengthOf(1); //  one set per pool | ||||
|             expect(quotes).to.deep.eq(expectedQuotes); | ||||
|         }); | ||||
|         it('getBuyQuotes()', async () => { | ||||
|             const expectedTakerToken = randomAddress(); | ||||
|             const expectedMakerToken = randomAddress(); | ||||
| @@ -590,7 +642,12 @@ describe('DexSampler tests', () => { | ||||
|                     return Promise.resolve(pools); | ||||
|                 }, | ||||
|             }); | ||||
|             const dexOrderSampler = new DexOrderSampler(new MockSamplerContract({}), undefined, balancerPoolsCache); | ||||
|             const dexOrderSampler = new DexOrderSampler( | ||||
|                 new MockSamplerContract({}), | ||||
|                 undefined, // sampler overrides | ||||
|                 undefined, // bancor service | ||||
|                 balancerPoolsCache, | ||||
|             ); | ||||
|             const [quotes] = await dexOrderSampler.executeAsync( | ||||
|                 await DexOrderSampler.ops.getBuyQuotesAsync( | ||||
|                     [ERC20BridgeSource.Balancer], | ||||
|   | ||||
| @@ -288,6 +288,7 @@ describe('MarketOperationUtils tests', () => { | ||||
|         [ERC20BridgeSource.Uniswap]: createDecreasingRates(NUM_SAMPLES), | ||||
|         [ERC20BridgeSource.UniswapV2]: _.times(NUM_SAMPLES, () => 0), | ||||
|         [ERC20BridgeSource.Balancer]: _.times(NUM_SAMPLES, () => 0), | ||||
|         [ERC20BridgeSource.Bancor]: _.times(NUM_SAMPLES, () => 0), | ||||
|         [ERC20BridgeSource.Curve]: _.times(NUM_SAMPLES, () => 0), | ||||
|         [ERC20BridgeSource.LiquidityProvider]: _.times(NUM_SAMPLES, () => 0), | ||||
|         [ERC20BridgeSource.MultiBridge]: _.times(NUM_SAMPLES, () => 0), | ||||
| @@ -301,6 +302,7 @@ describe('MarketOperationUtils tests', () => { | ||||
|     const DEFAULT_FILL_DATA: FillDataBySource = { | ||||
|         [ERC20BridgeSource.UniswapV2]: { tokenAddressPath: [] }, | ||||
|         [ERC20BridgeSource.Balancer]: { poolAddress: randomAddress() }, | ||||
|         [ERC20BridgeSource.Bancor]: { path: [], networkAddress: randomAddress() }, | ||||
|         [ERC20BridgeSource.Curve]: { | ||||
|             curve: { | ||||
|                 poolAddress: randomAddress(), | ||||
|   | ||||
							
								
								
									
										24
									
								
								packages/asset-swapper/test/utils/mock_bancor_service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								packages/asset-swapper/test/utils/mock_bancor_service.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| import { BigNumber } from '@0x/utils'; | ||||
|  | ||||
| import { SupportedProvider } from '../../src'; | ||||
| import { BancorService } from '../../src/utils/market_operation_utils/bancor_service'; | ||||
| import { BancorFillData, Quote } from '../../src/utils/market_operation_utils/types'; | ||||
|  | ||||
| export interface Handlers { | ||||
|     getQuoteAsync: (fromToken: string, toToken: string, amount: BigNumber) => Promise<Quote<BancorFillData>>; | ||||
| } | ||||
|  | ||||
| export class MockBancorService extends BancorService { | ||||
|     // Bancor recommends setting this value to 2% under the expected return amount | ||||
|     public minReturnAmountBufferPercentage = 0.98; | ||||
|  | ||||
|     constructor(provider: SupportedProvider, public handlers: Partial<Handlers>) { | ||||
|         super(provider); | ||||
|     } | ||||
|  | ||||
|     public async getQuoteAsync(fromToken: string, toToken: string, amount: BigNumber): Promise<Quote<BancorFillData>> { | ||||
|         return this.handlers.getQuoteAsync | ||||
|             ? this.handlers.getQuoteAsync(fromToken, toToken, amount) | ||||
|             : super.getQuoteAsync(fromToken, toToken, amount); | ||||
|     } | ||||
| } | ||||
| @@ -18,6 +18,10 @@ | ||||
|                 "note": "Redeploy previously unverified contracts on testnets", | ||||
|                 "pr": 2656 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Deploy `BancorBridge` on Mainnet", | ||||
|                 "pr": 2650 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Deploy FQT", | ||||
|                 "pr": 2667 | ||||
|   | ||||
| @@ -34,6 +34,7 @@ | ||||
|         "dexForwarderBridge": "0xc47b7094f378e54347e281aab170e8cca69d880a", | ||||
|         "multiBridge": "0xc03117a8c9bde203f70aa911cb64a7a0df5ba1e1", | ||||
|         "balancerBridge": "0xfe01821ca163844203220cd08e4f2b2fb43ae4e4", | ||||
|         "bancorBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e", | ||||
|         "exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff", | ||||
|         "exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb", | ||||
| @@ -82,6 +83,7 @@ | ||||
|         "dexForwarderBridge": "0x3261ea1411a1a840aed708896f779e1b837c917e", | ||||
|         "multiBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "balancerBridge": "0x47697b44bd89051e93b4d5857ba8e024800a74ac", | ||||
|         "bancorBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e", | ||||
|         "exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff", | ||||
|         "exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb", | ||||
| @@ -130,6 +132,7 @@ | ||||
|         "dexForwarderBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "multiBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "balancerBridge": "0x5d8c9ba74607d2cbc4176882a42d4ace891c1c00", | ||||
|         "bancorBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e", | ||||
|         "exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff", | ||||
|         "exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb", | ||||
| @@ -178,6 +181,7 @@ | ||||
|         "dexForwarderBridge": "0x985d1a95c6a86a3bf85c4d425af984abceaf01de", | ||||
|         "multiBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "balancerBridge": "0x407b4128e9ecad8769b2332312a9f655cb9f5f3a", | ||||
|         "bancorBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "exchangeProxyGovernor": "0x618f9c67ce7bf1a50afa1e7e0238422601b0ff6e", | ||||
|         "exchangeProxy": "0xdef1c0ded9bec7f1a1670819833240f027b25eff", | ||||
|         "exchangeProxyAllowanceTarget": "0xf740b67da229f2f10bcbd38a7979992fcc71b8eb", | ||||
| @@ -226,6 +230,7 @@ | ||||
|         "dexForwarderBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "multiBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "balancerBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "bancorBridge": "0x0000000000000000000000000000000000000000", | ||||
|         "exchangeProxyGovernor": "0x0000000000000000000000000000000000000000", | ||||
|         "exchangeProxy": "0x5315e44798395d4a952530d131249fe00f554565", | ||||
|         "exchangeProxyAllowanceTarget": "0x8362c3ebd90041b30ec45908332e592721642637", | ||||
|   | ||||
| @@ -35,6 +35,7 @@ export interface ContractAddresses { | ||||
|     dexForwarderBridge: string; | ||||
|     multiBridge: string; | ||||
|     balancerBridge: string; | ||||
|     bancorBridge: string; | ||||
|     exchangeProxyGovernor: string; | ||||
|     exchangeProxy: string; | ||||
|     exchangeProxyAllowanceTarget: string; | ||||
|   | ||||
| @@ -9,6 +9,10 @@ | ||||
|             { | ||||
|                 "note": "Refactor `migration.ts` a little", | ||||
|                 "pr": 2656 | ||||
|             }, | ||||
|             { | ||||
|                 "note": "Add bancorBridge to addresses", | ||||
|                 "pr": 2650 | ||||
|             } | ||||
|         ] | ||||
|     }, | ||||
|   | ||||
| @@ -405,6 +405,7 @@ export async function runMigrationsAsync( | ||||
|         dexForwarderBridge: NULL_ADDRESS, | ||||
|         multiBridge: NULL_ADDRESS, | ||||
|         balancerBridge: NULL_ADDRESS, | ||||
|         bancorBridge: NULL_ADDRESS, | ||||
|         exchangeProxyGovernor: NULL_ADDRESS, | ||||
|         mStableBridge: NULL_ADDRESS, | ||||
|         exchangeProxy: exchangeProxy.address, | ||||
|   | ||||
							
								
								
									
										415
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										415
									
								
								yarn.lock
									
									
									
									
									
								
							| @@ -751,7 +751,6 @@ | ||||
| "@0x/quote-server@^2.0.2": | ||||
|   version "2.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/@0x/quote-server/-/quote-server-2.0.2.tgz#60d0665c1cad378c9abb89b5491bdc55b4c8412c" | ||||
|   integrity sha512-ScK8lHj2AN0RaEjSYplnxsABGy30j6bATG3GjmGMWOx5Bmj2X6UGHpD2ZJ0UH+oJqyDHyZ31vgpMbCSlBLFlzQ== | ||||
|   dependencies: | ||||
|     "@0x/json-schemas" "^5.0.7" | ||||
|     "@0x/order-utils" "^10.2.4" | ||||
| @@ -1003,6 +1002,12 @@ | ||||
|   dependencies: | ||||
|     regenerator-runtime "^0.12.0" | ||||
|  | ||||
| "@babel/runtime@7.6.0": | ||||
|   version "7.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" | ||||
|   dependencies: | ||||
|     regenerator-runtime "^0.13.2" | ||||
|  | ||||
| "@babel/runtime@^7.1.5", "@babel/runtime@^7.3.1": | ||||
|   version "7.5.5" | ||||
|   resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" | ||||
| @@ -1050,13 +1055,23 @@ | ||||
| "@balancer-labs/sor@0.3.2": | ||||
|   version "0.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/@balancer-labs/sor/-/sor-0.3.2.tgz#b05c63a07031c2ea13ed0d2670f5105cfaa40523" | ||||
|   integrity sha512-wmYmTm/zhnRPd/OaqzJJGo9mRIp4PvNNS/AG0EVWJmLmZvYkm2sl6/dBL3KC88rub9duVQr2M8BHCosseFuGLw== | ||||
|   dependencies: | ||||
|     bignumber.js "^9.0.0" | ||||
|     ethers "^4.0.39" | ||||
|     isomorphic-fetch "^2.2.1" | ||||
|     typescript "^3.8.3" | ||||
|  | ||||
| "@bancor/sdk@^0.2.5": | ||||
|   version "0.2.5" | ||||
|   resolved "https://registry.yarnpkg.com/@bancor/sdk/-/sdk-0.2.5.tgz#dda2d6a91bc130684d83e5d395c00677cd0fdd71" | ||||
|   dependencies: | ||||
|     "@types/text-encoding" "0.0.35" | ||||
|     decimal.js "^10.2.0" | ||||
|     eosjs "^20.0.3" | ||||
|     node-fetch "^2.6.0" | ||||
|     web3 "1.2.1" | ||||
|     web3-typescript-typings "^0.10.2" | ||||
|  | ||||
| "@cnakazawa/watch@^1.0.3": | ||||
|   version "1.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" | ||||
| @@ -1997,7 +2012,6 @@ | ||||
| "@types/bignumber.js@^5.0.0": | ||||
|   version "5.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969" | ||||
|   integrity sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA== | ||||
|   dependencies: | ||||
|     bignumber.js "*" | ||||
|  | ||||
| @@ -2022,7 +2036,6 @@ | ||||
| "@types/body-parser@*": | ||||
|   version "1.19.0" | ||||
|   resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" | ||||
|   integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== | ||||
|   dependencies: | ||||
|     "@types/connect" "*" | ||||
|     "@types/node" "*" | ||||
| @@ -2034,7 +2047,6 @@ | ||||
| "@types/connect@*": | ||||
|   version "3.4.33" | ||||
|   resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" | ||||
|   integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== | ||||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
|  | ||||
| @@ -2079,7 +2091,6 @@ | ||||
| "@types/express-serve-static-core@*": | ||||
|   version "4.17.7" | ||||
|   resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.7.tgz#dfe61f870eb549dc6d7e12050901847c7d7e915b" | ||||
|   integrity sha512-EMgTj/DF9qpgLXyc+Btimg+XoH7A2liE8uKul8qSmMTHCeNYzydDKFdsJskDvw42UsesCnhO63dO0Grbj8J4Dw== | ||||
|   dependencies: | ||||
|     "@types/node" "*" | ||||
|     "@types/qs" "*" | ||||
| @@ -2088,7 +2099,6 @@ | ||||
| "@types/express@^4.17.3": | ||||
|   version "4.17.6" | ||||
|   resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e" | ||||
|   integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w== | ||||
|   dependencies: | ||||
|     "@types/body-parser" "*" | ||||
|     "@types/express-serve-static-core" "*" | ||||
| @@ -2187,7 +2197,6 @@ | ||||
| "@types/mime@*": | ||||
|   version "2.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.2.tgz#857a118d8634c84bba7ae14088e4508490cd5da5" | ||||
|   integrity sha512-4kPlzbljFcsttWEq6aBW0OZe6BDajAmyvr2xknBG92tejQnvdGtT9+kXSZ580DqpxY9qG2xeQVF9Dq0ymUTo5Q== | ||||
|  | ||||
| "@types/minimatch@*", "@types/minimatch@3.0.3", "@types/minimatch@^3.0.3": | ||||
|   version "3.0.3" | ||||
| @@ -2238,7 +2247,6 @@ | ||||
| "@types/qs@*": | ||||
|   version "6.9.3" | ||||
|   resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.3.tgz#b755a0934564a200d3efdf88546ec93c369abd03" | ||||
|   integrity sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA== | ||||
|  | ||||
| "@types/query-string@^5.1.0": | ||||
|   version "5.1.0" | ||||
| @@ -2247,7 +2255,6 @@ | ||||
| "@types/range-parser@*": | ||||
|   version "1.2.3" | ||||
|   resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" | ||||
|   integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== | ||||
|  | ||||
| "@types/react-dom@16.0.6": | ||||
|   version "16.0.6" | ||||
| @@ -2298,7 +2305,6 @@ | ||||
| "@types/serve-static@*": | ||||
|   version "1.13.4" | ||||
|   resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.4.tgz#6662a93583e5a6cabca1b23592eb91e12fa80e7c" | ||||
|   integrity sha512-jTDt0o/YbpNwZbQmE/+2e+lfjJEJJR0I3OFaKQKPWkASkCoW3i6fsUnqudSMcNAfbtmADGu8f4MV4q+GqULmug== | ||||
|   dependencies: | ||||
|     "@types/express-serve-static-core" "*" | ||||
|     "@types/mime" "*" | ||||
| @@ -2323,6 +2329,10 @@ | ||||
|     "@types/react" "*" | ||||
|     csstype "^2.2.0" | ||||
|  | ||||
| "@types/text-encoding@0.0.35": | ||||
|   version "0.0.35" | ||||
|   resolved "https://registry.yarnpkg.com/@types/text-encoding/-/text-encoding-0.0.35.tgz#6f14474e0b232bc70c59677aadc65dcc5a99c3a9" | ||||
|  | ||||
| "@types/tmp@^0.0.33": | ||||
|   version "0.0.33" | ||||
|   resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.0.33.tgz#1073c4bc824754ae3d10cfab88ab0237ba964e4d" | ||||
| @@ -2375,7 +2385,6 @@ | ||||
| "@web3-js/scrypt-shim@^0.1.0": | ||||
|   version "0.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz#0bf7529ab6788311d3e07586f7d89107c3bea2cc" | ||||
|   integrity sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw== | ||||
|   dependencies: | ||||
|     scryptsy "^2.1.0" | ||||
|     semver "^6.3.0" | ||||
| @@ -2383,7 +2392,6 @@ | ||||
| "@web3-js/websocket@^1.0.29": | ||||
|   version "1.0.30" | ||||
|   resolved "https://registry.yarnpkg.com/@web3-js/websocket/-/websocket-1.0.30.tgz#9ea15b7b582cf3bf3e8bc1f4d3d54c0731a87f87" | ||||
|   integrity sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA== | ||||
|   dependencies: | ||||
|     debug "^2.2.0" | ||||
|     es5-ext "^0.10.50" | ||||
| @@ -2588,7 +2596,6 @@ accepts@~1.3.4, accepts@~1.3.5: | ||||
| accepts@~1.3.7: | ||||
|   version "1.3.7" | ||||
|   resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" | ||||
|   integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== | ||||
|   dependencies: | ||||
|     mime-types "~2.1.24" | ||||
|     negotiator "0.6.2" | ||||
| @@ -3787,7 +3794,7 @@ babel-register@^6.26.0: | ||||
|     mkdirp "^0.5.1" | ||||
|     source-map-support "^0.4.15" | ||||
|  | ||||
| babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: | ||||
| babel-runtime@6.26.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: | ||||
|   version "6.26.0" | ||||
|   resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" | ||||
|   dependencies: | ||||
| @@ -3916,6 +3923,10 @@ big.js@^5.2.2: | ||||
|   version "5.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" | ||||
|  | ||||
| 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@*, bignumber.js@^9.0.0, bignumber.js@~9.0.0: | ||||
|   version "9.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" | ||||
| @@ -4171,6 +4182,16 @@ browser-stdout@1.3.1: | ||||
|   version "1.3.1" | ||||
|   resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" | ||||
|  | ||||
| browserify-aes@1.0.6: | ||||
|   version "1.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a" | ||||
|   dependencies: | ||||
|     buffer-xor "^1.0.2" | ||||
|     cipher-base "^1.0.0" | ||||
|     create-hash "^1.1.0" | ||||
|     evp_bytestokey "^1.0.0" | ||||
|     inherits "^2.0.1" | ||||
|  | ||||
| browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6: | ||||
|   version "1.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" | ||||
| @@ -4249,16 +4270,16 @@ bs-logger@0.x: | ||||
|   dependencies: | ||||
|     fast-json-stable-stringify "^2.0.0" | ||||
|  | ||||
| bs58@^2.0.1: | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" | ||||
|  | ||||
| bs58@^4.0.0: | ||||
| bs58@4.0.1, bs58@^4.0.0: | ||||
|   version "4.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" | ||||
|   dependencies: | ||||
|     base-x "^3.0.2" | ||||
|  | ||||
| bs58@^2.0.1: | ||||
|   version "2.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" | ||||
|  | ||||
| bs58check@^2.1.2: | ||||
|   version "2.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" | ||||
| @@ -4301,7 +4322,7 @@ buffer-to-arraybuffer@^0.0.5: | ||||
|   version "0.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" | ||||
|  | ||||
| buffer-xor@^1.0.3: | ||||
| buffer-xor@^1.0.2, buffer-xor@^1.0.3: | ||||
|   version "1.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" | ||||
|  | ||||
| @@ -4373,6 +4394,12 @@ byte-size@^5.0.1: | ||||
|   version "5.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191" | ||||
|  | ||||
| bytebuffer@5.0.1: | ||||
|   version "5.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" | ||||
|   dependencies: | ||||
|     long "~3" | ||||
|  | ||||
| bytes@3.0.0, bytes@^3.0.0: | ||||
|   version "3.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" | ||||
| @@ -5198,7 +5225,6 @@ content-disposition@0.5.2: | ||||
| content-disposition@0.5.3: | ||||
|   version "0.5.3" | ||||
|   resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" | ||||
|   integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== | ||||
|   dependencies: | ||||
|     safe-buffer "5.1.2" | ||||
|  | ||||
| @@ -5379,7 +5405,6 @@ cookie@0.3.1: | ||||
| cookie@0.4.0: | ||||
|   version "0.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" | ||||
|   integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== | ||||
|  | ||||
| cookiejar@^2.1.1: | ||||
|   version "2.1.2" | ||||
| @@ -5498,6 +5523,15 @@ create-error-class@^3.0.0: | ||||
|   dependencies: | ||||
|     capture-stack-trace "^1.0.0" | ||||
|  | ||||
| create-hash@1.1.3: | ||||
|   version "1.1.3" | ||||
|   resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" | ||||
|   dependencies: | ||||
|     cipher-base "^1.0.1" | ||||
|     inherits "^2.0.1" | ||||
|     ripemd160 "^2.0.0" | ||||
|     sha.js "^2.4.0" | ||||
|  | ||||
| create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: | ||||
|   version "1.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" | ||||
| @@ -5508,6 +5542,17 @@ create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: | ||||
|     ripemd160 "^2.0.1" | ||||
|     sha.js "^2.4.0" | ||||
|  | ||||
| create-hmac@1.1.6: | ||||
|   version "1.1.6" | ||||
|   resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.6.tgz#acb9e221a4e17bdb076e90657c42b93e3726cf06" | ||||
|   dependencies: | ||||
|     cipher-base "^1.0.3" | ||||
|     create-hash "^1.1.0" | ||||
|     inherits "^2.0.1" | ||||
|     ripemd160 "^2.0.0" | ||||
|     safe-buffer "^5.0.1" | ||||
|     sha.js "^2.4.8" | ||||
|  | ||||
| create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: | ||||
|   version "1.1.7" | ||||
|   resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" | ||||
| @@ -6264,6 +6309,12 @@ ecc-jsbn@~0.1.1: | ||||
|   dependencies: | ||||
|     jsbn "~0.1.0" | ||||
|  | ||||
| ecurve@1.0.5: | ||||
|   version "1.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.5.tgz#d148e8fe50a674f983bb5bae09da0ea23e10535e" | ||||
|   dependencies: | ||||
|     bigi "^1.1.0" | ||||
|  | ||||
| editor@^1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" | ||||
| @@ -6296,7 +6347,6 @@ elliptic@6.3.3: | ||||
| elliptic@6.5.2: | ||||
|   version "6.5.2" | ||||
|   resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" | ||||
|   integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== | ||||
|   dependencies: | ||||
|     bn.js "^4.4.0" | ||||
|     brorand "^1.0.1" | ||||
| @@ -6426,6 +6476,28 @@ enzyme@^3.6.0: | ||||
|     rst-selector-parser "^2.2.3" | ||||
|     string.prototype.trim "^1.1.2" | ||||
|  | ||||
| eosjs-ecc@4.0.7: | ||||
|   version "4.0.7" | ||||
|   resolved "https://registry.yarnpkg.com/eosjs-ecc/-/eosjs-ecc-4.0.7.tgz#f5246da3b84839fcc237204768ef6e5ea56cc814" | ||||
|   dependencies: | ||||
|     "@babel/runtime" "7.6.0" | ||||
|     bigi "1.4.2" | ||||
|     browserify-aes "1.0.6" | ||||
|     bs58 "4.0.1" | ||||
|     bytebuffer "5.0.1" | ||||
|     create-hash "1.1.3" | ||||
|     create-hmac "1.1.6" | ||||
|     ecurve "1.0.5" | ||||
|     randombytes "2.0.5" | ||||
|  | ||||
| eosjs@^20.0.3: | ||||
|   version "20.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/eosjs/-/eosjs-20.0.3.tgz#f3ac1fa119b76dd07bf2825ad27342f6502a533b" | ||||
|   dependencies: | ||||
|     babel-runtime "6.26.0" | ||||
|     eosjs-ecc "4.0.7" | ||||
|     text-encoding "0.7.0" | ||||
|  | ||||
| err-code@^1.0.0: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" | ||||
| @@ -6833,7 +6905,6 @@ ethashjs@~0.0.7: | ||||
| ethereum-bloom-filters@^1.0.6: | ||||
|   version "1.0.7" | ||||
|   resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz#b7b80735e385dbb7f944ce6b4533e24511306060" | ||||
|   integrity sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ== | ||||
|   dependencies: | ||||
|     js-sha3 "^0.8.0" | ||||
|  | ||||
| @@ -6898,7 +6969,6 @@ ethereumjs-account@^2.0.3: | ||||
| ethereumjs-block@2.2.2, ethereumjs-block@^2.2.2, ethereumjs-block@~2.2.2: | ||||
|   version "2.2.2" | ||||
|   resolved "https://registry.yarnpkg.com/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz#c7654be7e22df489fda206139ecd63e2e9c04965" | ||||
|   integrity sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg== | ||||
|   dependencies: | ||||
|     async "^2.0.1" | ||||
|     ethereumjs-common "^1.5.0" | ||||
| @@ -6944,7 +7014,6 @@ ethereumjs-blockchain@^4.0.1: | ||||
| ethereumjs-blockchain@^4.0.3: | ||||
|   version "4.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/ethereumjs-blockchain/-/ethereumjs-blockchain-4.0.3.tgz#e013034633a30ad2006728e8e2b21956b267b773" | ||||
|   integrity sha512-0nJWbyA+Gu0ZKZr/cywMtB/77aS/4lOVsIKbgUN2sFQYscXO5rPbUfrEe7G2Zhjp86/a0VqLllemDSTHvx3vZA== | ||||
|   dependencies: | ||||
|     async "^2.6.1" | ||||
|     ethashjs "~0.0.7" | ||||
| @@ -6980,7 +7049,6 @@ ethereumjs-common@^1.3.0: | ||||
| ethereumjs-tx@2.1.2, ethereumjs-tx@^2.1.2: | ||||
|   version "2.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" | ||||
|   integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== | ||||
|   dependencies: | ||||
|     ethereumjs-common "^1.5.0" | ||||
|     ethereumjs-util "^6.0.0" | ||||
| @@ -7055,7 +7123,6 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum | ||||
| ethereumjs-vm@4.1.3: | ||||
|   version "4.1.3" | ||||
|   resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.1.3.tgz#dc8eb45f47d775da9f0b2437d5e20896fdf66f37" | ||||
|   integrity sha512-RTrD0y7My4O6Qr1P2ZIsMfD6RzL6kU/RhBZ0a5XrPzAeR61crBS7or66ohDrvxDI/rDBxMi+6SnsELih6fzalw== | ||||
|   dependencies: | ||||
|     async "^2.1.2" | ||||
|     async-eventemitter "^0.2.2" | ||||
| @@ -7141,7 +7208,6 @@ ethers@4.0.0-beta.3: | ||||
| ethers@^4.0.39: | ||||
|   version "4.0.47" | ||||
|   resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.47.tgz#91b9cd80473b1136dd547095ff9171bd1fc68c85" | ||||
|   integrity sha512-hssRYhngV4hiDNeZmVU/k5/E8xmLG8UpcNUzg6mb7lqhgpFPH/t7nuv20RjRrEf0gblzvi2XwR5Te+V3ZFc9pQ== | ||||
|   dependencies: | ||||
|     aes-js "3.0.0" | ||||
|     bn.js "^4.4.0" | ||||
| @@ -7455,7 +7521,6 @@ express@^4.16.3: | ||||
| express@^4.17.1: | ||||
|   version "4.17.1" | ||||
|   resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" | ||||
|   integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== | ||||
|   dependencies: | ||||
|     accepts "~1.3.7" | ||||
|     array-flatten "1.1.1" | ||||
| @@ -7774,7 +7839,6 @@ finalhandler@1.1.1: | ||||
| finalhandler@~1.1.2: | ||||
|   version "1.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" | ||||
|   integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== | ||||
|   dependencies: | ||||
|     debug "2.6.9" | ||||
|     encodeurl "~1.0.2" | ||||
| @@ -8159,7 +8223,6 @@ ganache-cli@6.8.0-istanbul.0: | ||||
| ganache-core@^2.10.2: | ||||
|   version "2.10.2" | ||||
|   resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.10.2.tgz#17c171c6c0195b6734a0dd741a9d2afd4f74e292" | ||||
|   integrity sha512-4XEO0VsqQ1+OW7Za5fQs9/Kk7o8M0T1sRfFSF8h9NeJ2ABaqMO5waqxf567ZMcSkRKaTjUucBSz83xNfZv1HDg== | ||||
|   dependencies: | ||||
|     abstract-leveldown "3.0.0" | ||||
|     async "2.6.2" | ||||
| @@ -9026,7 +9089,6 @@ http-errors@1.7.2: | ||||
| http-errors@~1.7.2: | ||||
|   version "1.7.3" | ||||
|   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" | ||||
|   integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== | ||||
|   dependencies: | ||||
|     depd "~1.1.2" | ||||
|     inherits "2.0.4" | ||||
| @@ -9088,7 +9150,6 @@ http-status-codes@^1.3.0, http-status-codes@^1.3.2: | ||||
| http-status-codes@^1.4.0: | ||||
|   version "1.4.0" | ||||
|   resolved "https://registry.yarnpkg.com/http-status-codes/-/http-status-codes-1.4.0.tgz#6e4c15d16ff3a9e2df03b89f3a55e1aae05fb477" | ||||
|   integrity sha512-JrT3ua+WgH8zBD3HEJYbeEgnuQaAnUeRRko/YojPAJjGmIfGD3KPU/asLdsLwKjfxOmQe5nXMQ0pt/7MyapVbQ== | ||||
|  | ||||
| https-browserify@^1.0.0: | ||||
|   version "1.0.0" | ||||
| @@ -9369,7 +9430,6 @@ ipaddr.js@1.8.0: | ||||
| ipaddr.js@1.9.1: | ||||
|   version "1.9.1" | ||||
|   resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" | ||||
|   integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== | ||||
|  | ||||
| ipaddr.js@^1.5.2: | ||||
|   version "1.8.1" | ||||
| @@ -10648,7 +10708,6 @@ js-sha3@^0.7.0: | ||||
| js-sha3@^0.8.0: | ||||
|   version "0.8.0" | ||||
|   resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" | ||||
|   integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== | ||||
|  | ||||
| js-tokens@^3.0.0, js-tokens@^3.0.2: | ||||
|   version "3.0.2" | ||||
| @@ -11467,6 +11526,10 @@ lolex@^2.2.0, lolex@^2.3.2: | ||||
|   version "2.3.2" | ||||
|   resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807" | ||||
|  | ||||
| long@~3: | ||||
|   version "3.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" | ||||
|  | ||||
| looper@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/looper/-/looper-2.0.0.tgz#66cd0c774af3d4fedac53794f742db56da8f09ec" | ||||
| @@ -12267,7 +12330,6 @@ negotiator@0.6.1: | ||||
| negotiator@0.6.2: | ||||
|   version "0.6.2" | ||||
|   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" | ||||
|   integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== | ||||
|  | ||||
| neo-async@^2.5.0: | ||||
|   version "2.5.1" | ||||
| @@ -12347,7 +12409,7 @@ node-fetch@^1.0.1, node-fetch@^1.3.3, node-fetch@~1.7.1: | ||||
|     encoding "^0.1.11" | ||||
|     is-stream "^1.0.1" | ||||
|  | ||||
| node-fetch@^2.3.0, node-fetch@^2.5.0: | ||||
| node-fetch@^2.3.0, node-fetch@^2.5.0, node-fetch@^2.6.0: | ||||
|   version "2.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" | ||||
|  | ||||
| @@ -13365,7 +13427,6 @@ parseurl@~1.3.2: | ||||
| parseurl@~1.3.3: | ||||
|   version "1.3.3" | ||||
|   resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" | ||||
|   integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== | ||||
|  | ||||
| pascal-case@^2.0.0: | ||||
|   version "2.0.1" | ||||
| @@ -13859,7 +13920,6 @@ proxy-addr@~2.0.4: | ||||
| proxy-addr@~2.0.5: | ||||
|   version "2.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" | ||||
|   integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== | ||||
|   dependencies: | ||||
|     forwarded "~0.1.2" | ||||
|     ipaddr.js "1.9.1" | ||||
| @@ -14097,6 +14157,12 @@ randomatic@^1.1.3: | ||||
|     is-number "^3.0.0" | ||||
|     kind-of "^4.0.0" | ||||
|  | ||||
| randombytes@2.0.5: | ||||
|   version "2.0.5" | ||||
|   resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.5.tgz#dc009a246b8d09a177b4b7a0ae77bc570f4b1b79" | ||||
|   dependencies: | ||||
|     safe-buffer "^5.1.0" | ||||
|  | ||||
| randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: | ||||
|   version "2.0.6" | ||||
|   resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" | ||||
| @@ -14127,7 +14193,6 @@ range-parser@^1.0.3, range-parser@~1.2.0: | ||||
| range-parser@~1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" | ||||
|   integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== | ||||
|  | ||||
| raw-body@2.3.2: | ||||
|   version "2.3.2" | ||||
| @@ -15047,17 +15112,16 @@ scrypt@^6.0.2: | ||||
|   dependencies: | ||||
|     nan "^2.0.8" | ||||
|  | ||||
| scryptsy@2.1.0, scryptsy@^2.1.0: | ||||
|   version "2.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" | ||||
|  | ||||
| scryptsy@^1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-1.2.1.tgz#a3225fa4b2524f802700761e2855bdf3b2d92163" | ||||
|   dependencies: | ||||
|     pbkdf2 "^3.0.3" | ||||
|  | ||||
| scryptsy@^2.1.0: | ||||
|   version "2.1.0" | ||||
|   resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" | ||||
|   integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== | ||||
|  | ||||
| secp256k1@^3.0.1: | ||||
|   version "3.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.0.tgz#677d3b8a8e04e1a5fa381a1ae437c54207b738d0" | ||||
| @@ -15138,6 +15202,10 @@ semver-sort@0.0.4: | ||||
|   version "5.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" | ||||
|  | ||||
| semver@6.2.0: | ||||
|   version "6.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db" | ||||
|  | ||||
| semver@^5.5.1: | ||||
|   version "5.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" | ||||
| @@ -15175,7 +15243,6 @@ send@0.16.2: | ||||
| send@0.17.1: | ||||
|   version "0.17.1" | ||||
|   resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" | ||||
|   integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== | ||||
|   dependencies: | ||||
|     debug "2.6.9" | ||||
|     depd "~1.1.2" | ||||
| @@ -15230,7 +15297,6 @@ serve-static@1.13.2: | ||||
| serve-static@1.14.1: | ||||
|   version "1.14.1" | ||||
|   resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" | ||||
|   integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== | ||||
|   dependencies: | ||||
|     encodeurl "~1.0.2" | ||||
|     escape-html "~1.0.3" | ||||
| @@ -16349,6 +16415,10 @@ test-exclude@^5.2.3: | ||||
|     read-pkg-up "^4.0.0" | ||||
|     require-main-filename "^2.0.0" | ||||
|  | ||||
| text-encoding@0.7.0: | ||||
|   version "0.7.0" | ||||
|   resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.7.0.tgz#f895e836e45990624086601798ea98e8f36ee643" | ||||
|  | ||||
| text-encoding@^0.6.4: | ||||
|   version "0.6.4" | ||||
|   resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" | ||||
| @@ -16843,7 +16913,6 @@ typescript@3.5.x: | ||||
| typescript@^3.8.3: | ||||
|   version "3.9.6" | ||||
|   resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a" | ||||
|   integrity sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw== | ||||
|  | ||||
| typewise-core@^1.2, typewise-core@^1.2.0: | ||||
|   version "1.2.0" | ||||
| @@ -17362,10 +17431,17 @@ wcwidth@^1.0.0: | ||||
|   dependencies: | ||||
|     defaults "^1.0.3" | ||||
|  | ||||
| web3-bzz@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.1.tgz#c3bd1e8f0c02a13cd6d4e3c3e9e1713f144f6f0d" | ||||
|   dependencies: | ||||
|     got "9.6.0" | ||||
|     swarm-js "0.1.39" | ||||
|     underscore "1.9.1" | ||||
|  | ||||
| web3-bzz@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.4.tgz#a4adb7a8cba3d260de649bdb1f14ed359bfb3821" | ||||
|   integrity sha512-MqhAo/+0iQSMBtt3/QI1rU83uvF08sYq8r25+OUZ+4VtihnYsmkkca+rdU0QbRyrXY2/yGIpI46PFdh0khD53A== | ||||
|   dependencies: | ||||
|     "@types/node" "^10.12.18" | ||||
|     got "9.6.0" | ||||
| @@ -17380,10 +17456,17 @@ web3-core-helpers@1.0.0-beta.34: | ||||
|     web3-eth-iban "1.0.0-beta.34" | ||||
|     web3-utils "1.0.0-beta.34" | ||||
|  | ||||
| web3-core-helpers@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.1.tgz#f5f32d71c60a4a3bd14786118e633ce7ca6d5d0d" | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-eth-iban "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-core-helpers@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.4.tgz#ffd425861f4d66b3f38df032afdb39ea0971fc0f" | ||||
|   integrity sha512-U7wbsK8IbZvF3B7S+QMSNP0tni/6VipnJkB0tZVEpHEIV2WWeBHYmZDnULWcsS/x/jn9yKhJlXIxWGsEAMkjiw== | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-eth-iban "1.2.4" | ||||
| @@ -17399,10 +17482,19 @@ web3-core-helpers@2.0.0-alpha: | ||||
|     web3-eth-iban "2.0.0-alpha" | ||||
|     web3-utils "2.0.0-alpha" | ||||
|  | ||||
| web3-core-method@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.1.tgz#9df1bafa2cd8be9d9937e01c6a47fc768d15d90a" | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-core-promievent "1.2.1" | ||||
|     web3-core-subscriptions "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-core-method@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.4.tgz#a0fbc50b8ff5fd214021435cc2c6d1e115807aed" | ||||
|   integrity sha512-8p9kpL7di2qOVPWgcM08kb+yKom0rxRCMv6m/K+H+yLSxev9TgMbCgMSbPWAHlyiF3SJHw7APFKahK5Z+8XT5A== | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.4" | ||||
| @@ -17423,18 +17515,33 @@ web3-core-method@2.0.0-alpha: | ||||
|     web3-core-subscriptions "2.0.0-alpha" | ||||
|     web3-utils "2.0.0-alpha" | ||||
|  | ||||
| web3-core-promievent@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.4.tgz#75e5c0f2940028722cdd21ba503ebd65272df6cb" | ||||
|   integrity sha512-gEUlm27DewUsfUgC3T8AxkKi8Ecx+e+ZCaunB7X4Qk3i9F4C+5PSMGguolrShZ7Zb6717k79Y86f3A00O0VAZw== | ||||
| web3-core-promievent@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.1.tgz#003e8a3eb82fb27b6164a6d5b9cad04acf733838" | ||||
|   dependencies: | ||||
|     any-promise "1.3.0" | ||||
|     eventemitter3 "3.1.2" | ||||
|  | ||||
| web3-core-promievent@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.4.tgz#75e5c0f2940028722cdd21ba503ebd65272df6cb" | ||||
|   dependencies: | ||||
|     any-promise "1.3.0" | ||||
|     eventemitter3 "3.1.2" | ||||
|  | ||||
| web3-core-requestmanager@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.1.tgz#fa2e2206c3d738db38db7c8fe9c107006f5c6e3d" | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-providers-http "1.2.1" | ||||
|     web3-providers-ipc "1.2.1" | ||||
|     web3-providers-ws "1.2.1" | ||||
|  | ||||
| web3-core-requestmanager@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.4.tgz#0a7020a23fb91c6913c611dfd3d8c398d1e4b4a8" | ||||
|   integrity sha512-eZJDjyNTDtmSmzd3S488nR/SMJtNnn/GuwxnMh3AzYCqG3ZMfOylqTad2eYJPvc2PM5/Gj1wAMQcRpwOjjLuPg== | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.4" | ||||
| @@ -17442,10 +17549,17 @@ web3-core-requestmanager@1.2.4: | ||||
|     web3-providers-ipc "1.2.4" | ||||
|     web3-providers-ws "1.2.4" | ||||
|  | ||||
| web3-core-subscriptions@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.1.tgz#8c2368a839d4eec1c01a4b5650bbeb82d0e4a099" | ||||
|   dependencies: | ||||
|     eventemitter3 "3.1.2" | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|  | ||||
| web3-core-subscriptions@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.4.tgz#0dc095b5cfd82baa527a39796e3515a846b21b99" | ||||
|   integrity sha512-3D607J2M8ymY9V+/WZq4MLlBulwCkwEjjC2U+cXqgVO1rCyVqbxZNCmHyNYHjDDCxSEbks9Ju5xqJxDSxnyXEw== | ||||
|   dependencies: | ||||
|     eventemitter3 "3.1.2" | ||||
|     underscore "1.9.1" | ||||
| @@ -17459,10 +17573,18 @@ web3-core-subscriptions@2.0.0-alpha: | ||||
|     eventemitter3 "^3.1.0" | ||||
|     lodash "^4.17.11" | ||||
|  | ||||
| web3-core@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.1.tgz#7278b58fb6495065e73a77efbbce781a7fddf1a9" | ||||
|   dependencies: | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-core-method "1.2.1" | ||||
|     web3-core-requestmanager "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-core@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.4.tgz#2df13b978dcfc59c2abaa887d27f88f21ad9a9d6" | ||||
|   integrity sha512-CHc27sMuET2cs1IKrkz7xzmTdMfZpYswe7f0HcuyneTwS1yTlTnHyqjAaTy0ZygAb/x4iaVox+Gvr4oSAqSI+A== | ||||
|   dependencies: | ||||
|     "@types/bignumber.js" "^5.0.0" | ||||
|     "@types/bn.js" "^4.11.4" | ||||
| @@ -17484,10 +17606,17 @@ web3-core@2.0.0-alpha: | ||||
|     web3-providers "2.0.0-alpha" | ||||
|     web3-utils "2.0.0-alpha" | ||||
|  | ||||
| web3-eth-abi@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.1.tgz#9b915b1c9ebf82f70cca631147035d5419064689" | ||||
|   dependencies: | ||||
|     ethers "4.0.0-beta.3" | ||||
|     underscore "1.9.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-eth-abi@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.4.tgz#5b73e5ef70b03999227066d5d1310b168845e2b8" | ||||
|   integrity sha512-8eLIY4xZKoU3DSVu1pORluAw9Ru0/v4CGdw5so31nn+7fR8zgHMgwbFe0aOqWQ5VU42PzMMXeIJwt4AEi2buFg== | ||||
|   dependencies: | ||||
|     ethers "4.0.0-beta.3" | ||||
|     underscore "1.9.1" | ||||
| @@ -17502,10 +17631,25 @@ web3-eth-abi@^1.0.0-beta.24: | ||||
|     web3-core-helpers "1.0.0-beta.34" | ||||
|     web3-utils "1.0.0-beta.34" | ||||
|  | ||||
| web3-eth-accounts@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.1.tgz#2741a8ef337a7219d57959ac8bd118b9d68d63cf" | ||||
|   dependencies: | ||||
|     any-promise "1.3.0" | ||||
|     crypto-browserify "3.12.0" | ||||
|     eth-lib "0.2.7" | ||||
|     scryptsy "2.1.0" | ||||
|     semver "6.2.0" | ||||
|     underscore "1.9.1" | ||||
|     uuid "3.3.2" | ||||
|     web3-core "1.2.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-core-method "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-eth-accounts@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.4.tgz#ada6edc49542354328a85cafab067acd7f88c288" | ||||
|   integrity sha512-04LzT/UtWmRFmi4hHRewP5Zz43fWhuHiK5XimP86sUQodk/ByOkXQ3RoXyGXFMNoRxdcAeRNxSfA2DpIBc9xUw== | ||||
|   dependencies: | ||||
|     "@web3-js/scrypt-shim" "^0.1.0" | ||||
|     any-promise "1.3.0" | ||||
| @@ -17520,10 +17664,22 @@ web3-eth-accounts@1.2.4: | ||||
|     web3-core-method "1.2.4" | ||||
|     web3-utils "1.2.4" | ||||
|  | ||||
| web3-eth-contract@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.1.tgz#3542424f3d341386fd9ff65e78060b85ac0ea8c4" | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core "1.2.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-core-method "1.2.1" | ||||
|     web3-core-promievent "1.2.1" | ||||
|     web3-core-subscriptions "1.2.1" | ||||
|     web3-eth-abi "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-eth-contract@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.4.tgz#68ef7cc633232779b0a2c506a810fbe903575886" | ||||
|   integrity sha512-b/9zC0qjVetEYnzRA1oZ8gF1OSSUkwSYi5LGr4GeckLkzXP7osEnp9lkO/AQcE4GpG+l+STnKPnASXJGZPgBRQ== | ||||
|   dependencies: | ||||
|     "@types/bn.js" "^4.11.4" | ||||
|     underscore "1.9.1" | ||||
| @@ -17535,10 +17691,22 @@ web3-eth-contract@1.2.4: | ||||
|     web3-eth-abi "1.2.4" | ||||
|     web3-utils "1.2.4" | ||||
|  | ||||
| web3-eth-ens@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.1.tgz#a0e52eee68c42a8b9865ceb04e5fb022c2d971d5" | ||||
|   dependencies: | ||||
|     eth-ens-namehash "2.0.8" | ||||
|     underscore "1.9.1" | ||||
|     web3-core "1.2.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-core-promievent "1.2.1" | ||||
|     web3-eth-abi "1.2.1" | ||||
|     web3-eth-contract "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-eth-ens@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.4.tgz#b95b3aa99fb1e35c802b9e02a44c3046a3fa065e" | ||||
|   integrity sha512-g8+JxnZlhdsCzCS38Zm6R/ngXhXzvc3h7bXlxgKU4coTzLLoMpgOAEz71GxyIJinWTFbLXk/WjNY0dazi9NwVw== | ||||
|   dependencies: | ||||
|     eth-ens-namehash "2.0.8" | ||||
|     underscore "1.9.1" | ||||
| @@ -17556,10 +17724,16 @@ web3-eth-iban@1.0.0-beta.34: | ||||
|     bn.js "4.11.6" | ||||
|     web3-utils "1.0.0-beta.34" | ||||
|  | ||||
| web3-eth-iban@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.1.tgz#2c3801718946bea24e9296993a975c80b5acf880" | ||||
|   dependencies: | ||||
|     bn.js "4.11.8" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-eth-iban@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.4.tgz#8e0550fd3fd8e47a39357d87fe27dee9483ee476" | ||||
|   integrity sha512-D9HIyctru/FLRpXakRwmwdjb5bWU2O6UE/3AXvRm6DCOf2e+7Ve11qQrPtaubHfpdW3KWjDKvlxV9iaFv/oTMQ== | ||||
|   dependencies: | ||||
|     bn.js "4.11.8" | ||||
|     web3-utils "1.2.4" | ||||
| @@ -17572,10 +17746,19 @@ web3-eth-iban@2.0.0-alpha: | ||||
|     bn.js "4.11.8" | ||||
|     web3-utils "2.0.0-alpha" | ||||
|  | ||||
| web3-eth-personal@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.1.tgz#244e9911b7b482dc17c02f23a061a627c6e47faf" | ||||
|   dependencies: | ||||
|     web3-core "1.2.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-core-method "1.2.1" | ||||
|     web3-net "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-eth-personal@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.4.tgz#3224cca6851c96347d9799b12c1b67b2a6eb232b" | ||||
|   integrity sha512-5Russ7ZECwHaZXcN3DLuLS7390Vzgrzepl4D87SD6Sn1DHsCZtvfdPIYwoTmKNp69LG3mORl7U23Ga5YxqkICw== | ||||
|   dependencies: | ||||
|     "@types/node" "^12.6.1" | ||||
|     web3-core "1.2.4" | ||||
| @@ -17584,10 +17767,27 @@ web3-eth-personal@1.2.4: | ||||
|     web3-net "1.2.4" | ||||
|     web3-utils "1.2.4" | ||||
|  | ||||
| web3-eth@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.1.tgz#b9989e2557c73a9e8ffdc107c6dafbe72c79c1b0" | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core "1.2.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     web3-core-method "1.2.1" | ||||
|     web3-core-subscriptions "1.2.1" | ||||
|     web3-eth-abi "1.2.1" | ||||
|     web3-eth-accounts "1.2.1" | ||||
|     web3-eth-contract "1.2.1" | ||||
|     web3-eth-ens "1.2.1" | ||||
|     web3-eth-iban "1.2.1" | ||||
|     web3-eth-personal "1.2.1" | ||||
|     web3-net "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-eth@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.4.tgz#24c3b1f1ac79351bbfb808b2ab5c585fa57cdd00" | ||||
|   integrity sha512-+j+kbfmZsbc3+KJpvHM16j1xRFHe2jBAniMo1BHKc3lho6A8Sn9Buyut6odubguX2AxoRArCdIDCkT9hjUERpA== | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core "1.2.4" | ||||
| @@ -17603,10 +17803,17 @@ web3-eth@1.2.4: | ||||
|     web3-net "1.2.4" | ||||
|     web3-utils "1.2.4" | ||||
|  | ||||
| web3-net@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.1.tgz#edd249503315dd5ab4fa00220f6509d95bb7ab10" | ||||
|   dependencies: | ||||
|     web3-core "1.2.1" | ||||
|     web3-core-method "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3-net@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.4.tgz#1d246406d3aaffbf39c030e4e98bce0ca5f25458" | ||||
|   integrity sha512-wKOsqhyXWPSYTGbp7ofVvni17yfRptpqoUdp3SC8RAhDmGkX6irsiT9pON79m6b3HUHfLoBilFQyt/fTUZOf7A== | ||||
|   dependencies: | ||||
|     web3-core "1.2.4" | ||||
|     web3-core-method "1.2.4" | ||||
| @@ -17687,27 +17894,47 @@ web3-provider-engine@^13.3.2: | ||||
|     xhr "^2.2.0" | ||||
|     xtend "^4.0.1" | ||||
|  | ||||
| web3-providers-http@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.1.tgz#c93ea003a42e7b894556f7e19dd3540f947f5013" | ||||
|   dependencies: | ||||
|     web3-core-helpers "1.2.1" | ||||
|     xhr2-cookies "1.1.0" | ||||
|  | ||||
| web3-providers-http@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.4.tgz#514fcad71ae77832c2c15574296282fbbc5f4a67" | ||||
|   integrity sha512-dzVCkRrR/cqlIrcrWNiPt9gyt0AZTE0J+MfAu9rR6CyIgtnm1wFUVVGaxYRxuTGQRO4Dlo49gtoGwaGcyxqiTw== | ||||
|   dependencies: | ||||
|     web3-core-helpers "1.2.4" | ||||
|     xhr2-cookies "1.1.0" | ||||
|  | ||||
| web3-providers-ipc@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.1.tgz#017bfc687a8fc5398df2241eb98f135e3edd672c" | ||||
|   dependencies: | ||||
|     oboe "2.1.4" | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|  | ||||
| web3-providers-ipc@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.4.tgz#9d6659f8d44943fb369b739f48df09092be459bd" | ||||
|   integrity sha512-8J3Dguffin51gckTaNrO3oMBo7g+j0UNk6hXmdmQMMNEtrYqw4ctT6t06YOf9GgtOMjSAc1YEh3LPrvgIsR7og== | ||||
|   dependencies: | ||||
|     oboe "2.1.4" | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.4" | ||||
|  | ||||
| web3-providers-ws@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.1.tgz#2d941eaf3d5a8caa3214eff8dc16d96252b842cb" | ||||
|   dependencies: | ||||
|     underscore "1.9.1" | ||||
|     web3-core-helpers "1.2.1" | ||||
|     websocket "github:web3-js/WebSocket-Node#polyfill/globalThis" | ||||
|  | ||||
| web3-providers-ws@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.4.tgz#099ee271ee03f6ea4f5df9cfe969e83f4ce0e36f" | ||||
|   integrity sha512-F/vQpDzeK+++oeeNROl1IVTufFCwCR2hpWe5yRXN0ApLwHqXrMI7UwQNdJ9iyibcWjJf/ECbauEEQ8CHgE+MYQ== | ||||
|   dependencies: | ||||
|     "@web3-js/websocket" "^1.0.29" | ||||
|     underscore "1.9.1" | ||||
| @@ -17729,10 +17956,18 @@ web3-providers@2.0.0-alpha: | ||||
|     websocket "^1.0.28" | ||||
|     xhr2-cookies "1.1.0" | ||||
|  | ||||
| web3-shh@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.1.tgz#4460e3c1e07faf73ddec24ccd00da46f89152b0c" | ||||
|   dependencies: | ||||
|     web3-core "1.2.1" | ||||
|     web3-core-method "1.2.1" | ||||
|     web3-core-subscriptions "1.2.1" | ||||
|     web3-net "1.2.1" | ||||
|  | ||||
| web3-shh@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.4.tgz#5c8ff5ab624a3b14f08af0d24d2b16c10e9f70dd" | ||||
|   integrity sha512-z+9SCw0dE+69Z/Hv8809XDbLj7lTfEv9Sgu8eKEIdGntZf4v7ewj5rzN5bZZSz8aCvfK7Y6ovz1PBAu4QzS4IQ== | ||||
|   dependencies: | ||||
|     web3-core "1.2.4" | ||||
|     web3-core-method "1.2.4" | ||||
| @@ -17757,10 +17992,21 @@ web3-utils@1.0.0-beta.34: | ||||
|     underscore "1.8.3" | ||||
|     utf8 "2.1.1" | ||||
|  | ||||
| web3-utils@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.1.tgz#21466e38291551de0ab34558de21512ac4274534" | ||||
|   dependencies: | ||||
|     bn.js "4.11.8" | ||||
|     eth-lib "0.2.7" | ||||
|     ethjs-unit "0.1.6" | ||||
|     number-to-bn "1.7.0" | ||||
|     randomhex "0.1.5" | ||||
|     underscore "1.9.1" | ||||
|     utf8 "3.0.0" | ||||
|  | ||||
| web3-utils@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.4.tgz#96832a39a66b05bf8862a5b0bdad2799d709d951" | ||||
|   integrity sha512-+S86Ip+jqfIPQWvw2N/xBQq5JNqCO0dyvukGdJm8fEWHZbckT4WxSpHbx+9KLEWY4H4x9pUwnoRkK87pYyHfgQ== | ||||
|   dependencies: | ||||
|     bn.js "4.11.8" | ||||
|     eth-lib "0.2.7" | ||||
| @@ -17786,10 +18032,21 @@ web3-utils@2.0.0-alpha: | ||||
|     randombytes "^2.1.0" | ||||
|     utf8 "2.1.1" | ||||
|  | ||||
| web3@1.2.1: | ||||
|   version "1.2.1" | ||||
|   resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.1.tgz#5d8158bcca47838ab8c2b784a2dee4c3ceb4179b" | ||||
|   dependencies: | ||||
|     web3-bzz "1.2.1" | ||||
|     web3-core "1.2.1" | ||||
|     web3-eth "1.2.1" | ||||
|     web3-eth-personal "1.2.1" | ||||
|     web3-net "1.2.1" | ||||
|     web3-shh "1.2.1" | ||||
|     web3-utils "1.2.1" | ||||
|  | ||||
| web3@1.2.4: | ||||
|   version "1.2.4" | ||||
|   resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.4.tgz#6e7ab799eefc9b4648c2dab63003f704a1d5e7d9" | ||||
|   integrity sha512-xPXGe+w0x0t88Wj+s/dmAdASr3O9wmA9mpZRtixGZxmBexAF0MjfqYM+MS4tVl5s11hMTN3AZb8cDD4VLfC57A== | ||||
|   dependencies: | ||||
|     "@types/node" "^12.6.1" | ||||
|     web3-bzz "1.2.4" | ||||
| @@ -17957,6 +18214,16 @@ websocket@^1.0.26: | ||||
|     typedarray-to-buffer "^3.1.5" | ||||
|     yaeti "^0.0.6" | ||||
|  | ||||
| "websocket@github:web3-js/WebSocket-Node#polyfill/globalThis": | ||||
|   version "1.0.29" | ||||
|   resolved "https://codeload.github.com/web3-js/WebSocket-Node/tar.gz/ef5ea2f41daf4a2113b80c9223df884b4d56c400" | ||||
|   dependencies: | ||||
|     debug "^2.2.0" | ||||
|     es5-ext "^0.10.50" | ||||
|     nan "^2.14.0" | ||||
|     typedarray-to-buffer "^3.1.5" | ||||
|     yaeti "^0.0.6" | ||||
|  | ||||
| whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: | ||||
|   version "1.0.5" | ||||
|   resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user