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:
Xianny 2020-08-21 15:11:35 -07:00 committed by GitHub
parent 7e8b56eef4
commit af78238507
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 1412 additions and 143 deletions

View File

@ -10,6 +10,10 @@
"note": "Export DexForwarderBridgeContract",
"pr": 2656
},
{
"note": "Add BancorBridge and IBancorNetwork, ",
"pr": 2650
},
{
"note": "Added `MStableBridge`",
"pr": 2662

View 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;
}
}

View File

@ -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);
}

View 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);
}
}

View File

@ -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": {

View File

@ -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,

View File

@ -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';

View File

@ -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,

View 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));
});
});
});
});

View File

@ -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';

View File

@ -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",

View File

@ -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": {

View File

@ -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

View File

@ -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",

View File

@ -108,6 +108,7 @@ export {
} from './types';
export { affiliateFeeUtils } from './utils/affiliate_fee_utils';
export {
BancorFillData,
BalancerFillData,
CollapsedFill,
CurveFillData,

View File

@ -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,

View File

@ -264,6 +264,7 @@ export interface SwapQuoterOpts extends OrderPrunerOpts {
chainId: number;
orderRefreshIntervalMs: number;
expiryBufferMs: number;
ethereumRpcUrl?: string;
contractAddresses?: ContractAddresses;
samplerGasLimit?: number;
liquidityProviderRegistryAddress?: string;

View File

@ -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;
}
}

View File

@ -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,
];

View File

@ -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;
}

View File

@ -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,
),
);

View File

@ -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,

View File

@ -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(),
) {}

View File

@ -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,
fillData: { poolAddress: pool.id },
...samplerOperations.constant(takerFillAmounts.map(amount => computeBalancerSellQuote(pool, amount))),
...samplerOperations.constant(
takerFillAmounts.map(amount => ({
amount: computeBalancerSellQuote(pool, amount),
fillData: { poolAddress: pool.id },
})),
),
};
},
getBalancerBuyQuotes(pool: BalancerPool, makerFillAmounts: BigNumber[]): SourceQuoteOperation<BalancerFillData> {
return {
source: ERC20BridgeSource.Balancer,
fillData: { poolAddress: pool.id },
...samplerOperations.constant(makerFillAmounts.map(amount => computeBalancerBuyQuote(pool, amount))),
...samplerOperations.constant(
makerFillAmounts.map(amount => ({
amount: computeBalancerBuyQuote(pool, amount),
fillData: { poolAddress: pool.id },
})),
),
};
},
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,
}));
});
},

View File

@ -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 {

View 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
});
});
});

View File

@ -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],

View File

@ -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(),

View 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);
}
}

View File

@ -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

View File

@ -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",

View File

@ -35,6 +35,7 @@ export interface ContractAddresses {
dexForwarderBridge: string;
multiBridge: string;
balancerBridge: string;
bancorBridge: string;
exchangeProxyGovernor: string;
exchangeProxy: string;
exchangeProxyAllowanceTarget: string;

View File

@ -9,6 +9,10 @@
{
"note": "Refactor `migration.ts` a little",
"pr": 2656
},
{
"note": "Add bancorBridge to addresses",
"pr": 2650
}
]
},

View File

@ -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
View File

@ -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"