Merge pull request #2715 from 0xProject/feat/add-cream
feat: Add CREAM as a liquidity source
This commit is contained in:
commit
3aaa0ad6b2
@ -26,6 +26,10 @@
|
||||
"note": "Reworked `KyberBridge`",
|
||||
"pr": 2683
|
||||
},
|
||||
{
|
||||
"note": "Added `CreamBridge`",
|
||||
"pr": 2715
|
||||
},
|
||||
{
|
||||
"note": "Added `ShellBridge`",
|
||||
"pr": 2722
|
||||
|
103
contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol
Normal file
103
contracts/asset-proxy/contracts/src/bridges/CreamBridge.sol
Normal file
@ -0,0 +1,103 @@
|
||||
|
||||
/*
|
||||
|
||||
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/IBalancerPool.sol";
|
||||
|
||||
|
||||
contract CreamBridge is
|
||||
IERC20Bridge,
|
||||
IWallet,
|
||||
DeploymentConstants
|
||||
{
|
||||
/// @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 addresses of the "from" token and Balancer pool.
|
||||
/// @return success The magic bytes if successful.
|
||||
function bridgeTransferFrom(
|
||||
address toTokenAddress,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount,
|
||||
bytes calldata bridgeData
|
||||
)
|
||||
external
|
||||
returns (bytes4 success)
|
||||
{
|
||||
// Decode the bridge data.
|
||||
(address fromTokenAddress, address poolAddress) = abi.decode(
|
||||
bridgeData,
|
||||
(address, address)
|
||||
);
|
||||
require(toTokenAddress != fromTokenAddress, "CreamBridge/INVALID_PAIR");
|
||||
|
||||
uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this));
|
||||
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
|
||||
LibERC20Token.approveIfBelow(fromTokenAddress, poolAddress, fromTokenBalance);
|
||||
|
||||
// Sell all of this contract's `fromTokenAddress` token balance.
|
||||
(uint256 boughtAmount,) = IBalancerPool(poolAddress).swapExactAmountIn(
|
||||
fromTokenAddress, // tokenIn
|
||||
fromTokenBalance, // tokenAmountIn
|
||||
toTokenAddress, // tokenOut
|
||||
amount, // minAmountOut
|
||||
uint256(-1) // maxPrice
|
||||
);
|
||||
|
||||
// Transfer the converted `toToken`s to `to`.
|
||||
LibERC20Token.transfer(toTokenAddress, to, boughtAmount);
|
||||
|
||||
emit ERC20BridgeTransfer(
|
||||
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;
|
||||
}
|
||||
}
|
@ -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|BancorBridge|ChaiBridge|CurveBridge|DODOBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IShell|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|ShellBridge|StaticCallProxy|SushiSwapBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json",
|
||||
"abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CreamBridge|CurveBridge|DODOBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IShell|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|ShellBridge|StaticCallProxy|SushiSwapBridge|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": {
|
||||
|
@ -8,6 +8,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 CreamBridge from '../generated-artifacts/CreamBridge.json';
|
||||
import * as CurveBridge from '../generated-artifacts/CurveBridge.json';
|
||||
import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json';
|
||||
import * as DODOBridge from '../generated-artifacts/DODOBridge.json';
|
||||
@ -73,6 +74,7 @@ export const artifacts = {
|
||||
BalancerBridge: BalancerBridge as ContractArtifact,
|
||||
BancorBridge: BancorBridge as ContractArtifact,
|
||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||
CreamBridge: CreamBridge as ContractArtifact,
|
||||
CurveBridge: CurveBridge as ContractArtifact,
|
||||
DODOBridge: DODOBridge as ContractArtifact,
|
||||
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
||||
|
@ -6,6 +6,7 @@
|
||||
export * from '../generated-wrappers/balancer_bridge';
|
||||
export * from '../generated-wrappers/bancor_bridge';
|
||||
export * from '../generated-wrappers/chai_bridge';
|
||||
export * from '../generated-wrappers/cream_bridge';
|
||||
export * from '../generated-wrappers/curve_bridge';
|
||||
export * from '../generated-wrappers/d_o_d_o_bridge';
|
||||
export * from '../generated-wrappers/dex_forwarder_bridge';
|
||||
|
@ -8,6 +8,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 CreamBridge from '../test/generated-artifacts/CreamBridge.json';
|
||||
import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json';
|
||||
import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json';
|
||||
import * as DODOBridge from '../test/generated-artifacts/DODOBridge.json';
|
||||
@ -73,6 +74,7 @@ export const artifacts = {
|
||||
BalancerBridge: BalancerBridge as ContractArtifact,
|
||||
BancorBridge: BancorBridge as ContractArtifact,
|
||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||
CreamBridge: CreamBridge as ContractArtifact,
|
||||
CurveBridge: CurveBridge as ContractArtifact,
|
||||
DODOBridge: DODOBridge as ContractArtifact,
|
||||
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
||||
|
@ -6,6 +6,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/cream_bridge';
|
||||
export * from '../test/generated-wrappers/curve_bridge';
|
||||
export * from '../test/generated-wrappers/d_o_d_o_bridge';
|
||||
export * from '../test/generated-wrappers/dex_forwarder_bridge';
|
||||
|
@ -6,6 +6,7 @@
|
||||
"generated-artifacts/BalancerBridge.json",
|
||||
"generated-artifacts/BancorBridge.json",
|
||||
"generated-artifacts/ChaiBridge.json",
|
||||
"generated-artifacts/CreamBridge.json",
|
||||
"generated-artifacts/CurveBridge.json",
|
||||
"generated-artifacts/DODOBridge.json",
|
||||
"generated-artifacts/DexForwarderBridge.json",
|
||||
@ -61,6 +62,7 @@
|
||||
"test/generated-artifacts/BalancerBridge.json",
|
||||
"test/generated-artifacts/BancorBridge.json",
|
||||
"test/generated-artifacts/ChaiBridge.json",
|
||||
"test/generated-artifacts/CreamBridge.json",
|
||||
"test/generated-artifacts/CurveBridge.json",
|
||||
"test/generated-artifacts/DODOBridge.json",
|
||||
"test/generated-artifacts/DexForwarderBridge.json",
|
||||
|
@ -65,6 +65,10 @@
|
||||
{
|
||||
"note": "Added `Shell` into FQT",
|
||||
"pr": 2722
|
||||
},
|
||||
{
|
||||
"note": "Added `CREAM` into FQT",
|
||||
"pr": 2715
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -46,6 +46,7 @@ contract BridgeAdapter is
|
||||
{
|
||||
|
||||
address private immutable BALANCER_BRIDGE_ADDRESS;
|
||||
address private immutable CREAM_BRIDGE_ADDRESS;
|
||||
address private immutable CURVE_BRIDGE_ADDRESS;
|
||||
address private immutable KYBER_BRIDGE_ADDRESS;
|
||||
address private immutable MOONISWAP_BRIDGE_ADDRESS;
|
||||
@ -93,6 +94,7 @@ contract BridgeAdapter is
|
||||
SHELL_BRIDGE_ADDRESS = addresses.shellBridge;
|
||||
UNISWAP_BRIDGE_ADDRESS = addresses.uniswapBridge;
|
||||
UNISWAP_V2_BRIDGE_ADDRESS = addresses.uniswapV2Bridge;
|
||||
CREAM_BRIDGE_ADDRESS = addresses.creamBridge;
|
||||
}
|
||||
|
||||
function trade(
|
||||
@ -134,7 +136,7 @@ contract BridgeAdapter is
|
||||
sellAmount,
|
||||
bridgeData
|
||||
);
|
||||
} else if (bridgeAddress == BALANCER_BRIDGE_ADDRESS) {
|
||||
} else if (bridgeAddress == BALANCER_BRIDGE_ADDRESS || bridgeAddress == CREAM_BRIDGE_ADDRESS) {
|
||||
boughtAmount = _tradeBalancer(
|
||||
buyToken,
|
||||
sellAmount,
|
||||
|
@ -24,6 +24,7 @@ contract MixinAdapterAddresses
|
||||
struct AdapterAddresses {
|
||||
// Bridges
|
||||
address balancerBridge;
|
||||
address creamBridge;
|
||||
address curveBridge;
|
||||
address kyberBridge;
|
||||
address mooniswapBridge;
|
||||
|
@ -75,6 +75,7 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
||||
weth: NULL_ADDRESS,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
shell: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
},
|
||||
);
|
||||
transformer = await FillQuoteTransformerContract.deployFrom0xArtifactAsync(
|
||||
|
@ -71,8 +71,13 @@
|
||||
"@0x/web3-wrapper": "^7.2.0",
|
||||
"@balancer-labs/sor": "0.3.2",
|
||||
"@bancor/sdk": "^0.2.9",
|
||||
"@ethersproject/abi": "^5.0.1",
|
||||
"@ethersproject/address": "^5.0.1",
|
||||
"@ethersproject/contracts": "^5.0.1",
|
||||
"@ethersproject/providers": "^5.0.4",
|
||||
"axios": "^0.19.2",
|
||||
"axios-mock-adapter": "^1.18.1",
|
||||
"cream-sor": "^0.3.3",
|
||||
"decimal.js": "^10.2.0",
|
||||
"ethereum-types": "^3.2.0",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
|
@ -25,6 +25,7 @@ export const SELL_SOURCE_FILTER = new SourceFilters([
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
]);
|
||||
|
||||
/**
|
||||
@ -47,6 +48,7 @@ export const BUY_SOURCE_FILTER = new SourceFilters(
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Dodo,
|
||||
ERC20BridgeSource.Cream,
|
||||
],
|
||||
[ERC20BridgeSource.MultiBridge],
|
||||
);
|
||||
|
@ -0,0 +1,104 @@
|
||||
import { getPoolsWithTokens, parsePoolData } from 'cream-sor';
|
||||
|
||||
import { BalancerPool } from './balancer_utils';
|
||||
|
||||
// tslint:disable:boolean-naming
|
||||
|
||||
interface CacheValue {
|
||||
timestamp: number;
|
||||
pools: BalancerPool[];
|
||||
}
|
||||
|
||||
// tslint:disable:custom-no-magic-numbers
|
||||
const FIVE_SECONDS_MS = 5 * 1000;
|
||||
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
||||
const DEFAULT_TIMEOUT_MS = 1000;
|
||||
const MAX_POOLS_FETCHED = 3;
|
||||
// tslint:enable:custom-no-magic-numbers
|
||||
|
||||
export class CreamPoolsCache {
|
||||
constructor(
|
||||
private readonly _cache: { [key: string]: CacheValue } = {},
|
||||
private readonly maxPoolsFetched: number = MAX_POOLS_FETCHED,
|
||||
) {}
|
||||
|
||||
public async getPoolsForPairAsync(
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
timeoutMs: number = DEFAULT_TIMEOUT_MS,
|
||||
): Promise<BalancerPool[]> {
|
||||
const timeout = new Promise<BalancerPool[]>(resolve => setTimeout(resolve, timeoutMs, []));
|
||||
return Promise.race([this._getPoolsForPairAsync(takerToken, makerToken), timeout]);
|
||||
}
|
||||
|
||||
public getCachedPoolAddressesForPair(
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
cacheExpiryMs?: number,
|
||||
): string[] | undefined {
|
||||
const key = JSON.stringify([takerToken, makerToken]);
|
||||
const value = this._cache[key];
|
||||
if (cacheExpiryMs === undefined) {
|
||||
return value === undefined ? [] : value.pools.map(pool => pool.id);
|
||||
}
|
||||
const minTimestamp = Date.now() - cacheExpiryMs;
|
||||
if (value === undefined || value.timestamp < minTimestamp) {
|
||||
return undefined;
|
||||
} else {
|
||||
return value.pools.map(pool => pool.id);
|
||||
}
|
||||
}
|
||||
|
||||
public howToSampleCream(
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
isAllowedSource: boolean,
|
||||
): { onChain: boolean; offChain: boolean } {
|
||||
// If CREAM is excluded as a source, do not sample.
|
||||
if (!isAllowedSource) {
|
||||
return { onChain: false, offChain: false };
|
||||
}
|
||||
const cachedCreamPools = this.getCachedPoolAddressesForPair(takerToken, makerToken, ONE_DAY_MS);
|
||||
// Sample CREAM on-chain (i.e. via the ERC20BridgeSampler contract) if:
|
||||
// - Cached values are not stale
|
||||
// - There is at least one CREAM pool for this pair
|
||||
const onChain = cachedCreamPools !== undefined && cachedCreamPools.length > 0;
|
||||
// Sample CREAM off-chain (i.e. via GraphQL query + `computeCreamBuy/SellQuote`)
|
||||
// if cached values are stale
|
||||
const offChain = cachedCreamPools === undefined;
|
||||
return { onChain, offChain };
|
||||
}
|
||||
|
||||
protected async _getPoolsForPairAsync(
|
||||
takerToken: string,
|
||||
makerToken: string,
|
||||
cacheExpiryMs: number = FIVE_SECONDS_MS,
|
||||
): Promise<BalancerPool[]> {
|
||||
const key = JSON.stringify([takerToken, makerToken]);
|
||||
const value = this._cache[key];
|
||||
const minTimestamp = Date.now() - cacheExpiryMs;
|
||||
if (value === undefined || value.timestamp < minTimestamp) {
|
||||
const pools = await this._fetchPoolsForPairAsync(takerToken, makerToken);
|
||||
const timestamp = Date.now();
|
||||
this._cache[key] = {
|
||||
pools,
|
||||
timestamp,
|
||||
};
|
||||
}
|
||||
return this._cache[key].pools;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
protected async _fetchPoolsForPairAsync(takerToken: string, makerToken: string): Promise<BalancerPool[]> {
|
||||
try {
|
||||
const poolData = (await getPoolsWithTokens(takerToken, makerToken)).pools;
|
||||
// Sort by maker token balance (descending)
|
||||
const pools = parsePoolData(poolData, takerToken, makerToken).sort((a, b) =>
|
||||
b.balanceOut.minus(a.balanceOut).toNumber(),
|
||||
);
|
||||
return pools.length > this.maxPoolsFetched ? pools.slice(0, this.maxPoolsFetched) : pools;
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
@ -152,6 +152,20 @@ export class MarketOperationUtils {
|
||||
quoteSourceFilters.isAllowed(ERC20BridgeSource.Balancer),
|
||||
);
|
||||
|
||||
const {
|
||||
onChain: sampleCreamOnChain,
|
||||
offChain: sampleCreamOffChain,
|
||||
} = this._sampler.creamPoolsCache.howToSampleCream(
|
||||
takerToken,
|
||||
makerToken,
|
||||
quoteSourceFilters.isAllowed(ERC20BridgeSource.Cream),
|
||||
);
|
||||
|
||||
const offChainSources = [
|
||||
...(!sampleCreamOnChain ? [ERC20BridgeSource.Cream] : []),
|
||||
...(!sampleBalancerOnChain ? [ERC20BridgeSource.Balancer] : []),
|
||||
];
|
||||
|
||||
// Call the sampler contract.
|
||||
const samplerPromise = this._sampler.executeAsync(
|
||||
// Get native order fillable amounts.
|
||||
@ -178,7 +192,7 @@ export class MarketOperationUtils {
|
||||
),
|
||||
// Get sell quotes for taker -> maker.
|
||||
this._sampler.getSellQuotes(
|
||||
quoteSourceFilters.exclude(sampleBalancerOnChain ? [] : ERC20BridgeSource.Balancer).sources,
|
||||
quoteSourceFilters.exclude(offChainSources).sources,
|
||||
makerToken,
|
||||
takerToken,
|
||||
sampleAmounts,
|
||||
@ -211,6 +225,10 @@ export class MarketOperationUtils {
|
||||
? this._sampler.getBalancerSellQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
|
||||
: Promise.resolve([]);
|
||||
|
||||
const offChainCreamPromise = sampleCreamOffChain
|
||||
? this._sampler.getCreamSellQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
|
||||
: Promise.resolve([]);
|
||||
|
||||
const offChainBancorPromise = quoteSourceFilters.isAllowed(ERC20BridgeSource.Bancor)
|
||||
? this._sampler.getBancorSellQuotesOffChainAsync(makerToken, takerToken, [takerAmount])
|
||||
: Promise.resolve([]);
|
||||
@ -219,15 +237,22 @@ export class MarketOperationUtils {
|
||||
[orderFillableAmounts, ethToMakerAssetRate, ethToTakerAssetRate, dexQuotes, twoHopQuotes],
|
||||
rfqtIndicativeQuotes,
|
||||
offChainBalancerQuotes,
|
||||
offChainCreamQuotes,
|
||||
offChainBancorQuotes,
|
||||
] = await Promise.all([samplerPromise, rfqtPromise, offChainBalancerPromise, offChainBancorPromise]);
|
||||
] = await Promise.all([
|
||||
samplerPromise,
|
||||
rfqtPromise,
|
||||
offChainBalancerPromise,
|
||||
offChainCreamPromise,
|
||||
offChainBancorPromise,
|
||||
]);
|
||||
|
||||
return {
|
||||
side: MarketOperation.Sell,
|
||||
inputAmount: takerAmount,
|
||||
inputToken: takerToken,
|
||||
outputToken: makerToken,
|
||||
dexQuotes: dexQuotes.concat([...offChainBalancerQuotes, offChainBancorQuotes]),
|
||||
dexQuotes: dexQuotes.concat([...offChainBalancerQuotes, ...offChainCreamQuotes, offChainBancorQuotes]),
|
||||
nativeOrders,
|
||||
orderFillableAmounts,
|
||||
ethToOutputRate: ethToMakerAssetRate,
|
||||
@ -270,6 +295,20 @@ export class MarketOperationUtils {
|
||||
quoteSourceFilters.isAllowed(ERC20BridgeSource.Balancer),
|
||||
);
|
||||
|
||||
const {
|
||||
onChain: sampleCreamOnChain,
|
||||
offChain: sampleCreamOffChain,
|
||||
} = this._sampler.creamPoolsCache.howToSampleCream(
|
||||
takerToken,
|
||||
makerToken,
|
||||
quoteSourceFilters.isAllowed(ERC20BridgeSource.Cream),
|
||||
);
|
||||
|
||||
const offChainSources = [
|
||||
...(!sampleCreamOnChain ? [ERC20BridgeSource.Cream] : []),
|
||||
...(!sampleBalancerOnChain ? [ERC20BridgeSource.Balancer] : []),
|
||||
];
|
||||
|
||||
// Call the sampler contract.
|
||||
const samplerPromise = this._sampler.executeAsync(
|
||||
// Get native order fillable amounts.
|
||||
@ -296,7 +335,7 @@ export class MarketOperationUtils {
|
||||
),
|
||||
// Get buy quotes for taker -> maker.
|
||||
this._sampler.getBuyQuotes(
|
||||
quoteSourceFilters.exclude(sampleBalancerOnChain ? [] : ERC20BridgeSource.Balancer).sources,
|
||||
quoteSourceFilters.exclude(offChainSources).sources,
|
||||
makerToken,
|
||||
takerToken,
|
||||
sampleAmounts,
|
||||
@ -328,11 +367,16 @@ export class MarketOperationUtils {
|
||||
? this._sampler.getBalancerBuyQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
|
||||
: Promise.resolve([]);
|
||||
|
||||
const offChainCreamPromise = sampleCreamOffChain
|
||||
? this._sampler.getCreamBuyQuotesOffChainAsync(makerToken, takerToken, sampleAmounts)
|
||||
: Promise.resolve([]);
|
||||
|
||||
const [
|
||||
[orderFillableAmounts, ethToMakerAssetRate, ethToTakerAssetRate, dexQuotes, twoHopQuotes],
|
||||
rfqtIndicativeQuotes,
|
||||
offChainBalancerQuotes,
|
||||
] = await Promise.all([samplerPromise, rfqtPromise, offChainBalancerPromise]);
|
||||
offChainCreamQuotes,
|
||||
] = await Promise.all([samplerPromise, rfqtPromise, offChainBalancerPromise, offChainCreamPromise]);
|
||||
// Attach the MultiBridge address to the sample fillData
|
||||
(dexQuotes.find(quotes => quotes[0] && quotes[0].source === ERC20BridgeSource.MultiBridge) || []).forEach(
|
||||
q => (q.fillData = { poolAddress: this._multiBridge }),
|
||||
@ -342,7 +386,7 @@ export class MarketOperationUtils {
|
||||
inputAmount: makerAmount,
|
||||
inputToken: makerToken,
|
||||
outputToken: takerToken,
|
||||
dexQuotes: dexQuotes.concat(offChainBalancerQuotes),
|
||||
dexQuotes: dexQuotes.concat(offChainBalancerQuotes, offChainCreamQuotes),
|
||||
nativeOrders,
|
||||
orderFillableAmounts,
|
||||
ethToOutputRate: ethToTakerAssetRate,
|
||||
|
@ -177,6 +177,8 @@ function getBridgeAddressFromFill(fill: CollapsedFill, opts: CreateOrderFromPath
|
||||
return opts.contractAddresses.bancorBridge;
|
||||
case ERC20BridgeSource.Balancer:
|
||||
return opts.contractAddresses.balancerBridge;
|
||||
case ERC20BridgeSource.Cream:
|
||||
return opts.contractAddresses.creamBridge;
|
||||
case ERC20BridgeSource.LiquidityProvider:
|
||||
return (fill.fillData as LiquidityProviderFillData).poolAddress;
|
||||
case ERC20BridgeSource.MultiBridge:
|
||||
@ -241,6 +243,14 @@ export function createBridgeOrder(
|
||||
createBalancerBridgeData(takerToken, balancerFillData.poolAddress),
|
||||
);
|
||||
break;
|
||||
case ERC20BridgeSource.Cream:
|
||||
const creamFillData = (fill as CollapsedFill<BalancerFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
makerToken,
|
||||
bridgeAddress,
|
||||
createBalancerBridgeData(takerToken, creamFillData.poolAddress),
|
||||
);
|
||||
break;
|
||||
case ERC20BridgeSource.Bancor:
|
||||
const bancorFillData = (fill as CollapsedFill<BancorFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
|
@ -6,6 +6,7 @@ import { ERC20BridgeSamplerContract } from '../../wrappers';
|
||||
|
||||
import { BalancerPoolsCache } from './balancer_utils';
|
||||
import { BancorService } from './bancor_service';
|
||||
import { CreamPoolsCache } from './cream_utils';
|
||||
import { SamplerOperations } from './sampler_operations';
|
||||
import { BatchedOperation } from './types';
|
||||
|
||||
@ -37,9 +38,10 @@ export class DexOrderSampler extends SamplerOperations {
|
||||
private readonly _samplerOverrides?: SamplerOverrides,
|
||||
provider?: SupportedProvider,
|
||||
balancerPoolsCache?: BalancerPoolsCache,
|
||||
creamPoolsCache?: CreamPoolsCache,
|
||||
getBancorServiceFn?: () => BancorService,
|
||||
) {
|
||||
super(_samplerContract, provider, balancerPoolsCache, getBancorServiceFn);
|
||||
super(_samplerContract, provider, balancerPoolsCache, creamPoolsCache, getBancorServiceFn);
|
||||
}
|
||||
|
||||
/* Type overloads for `executeAsync()`. Could skip this if we would upgrade TS. */
|
||||
|
@ -8,6 +8,7 @@ import { ERC20BridgeSamplerContract } from '../../wrappers';
|
||||
import { BalancerPoolsCache, computeBalancerBuyQuote, computeBalancerSellQuote } from './balancer_utils';
|
||||
import { BancorService } from './bancor_service';
|
||||
import { MAINNET_SUSHI_SWAP_ROUTER, MAX_UINT256, NULL_BYTES, ZERO_AMOUNT } from './constants';
|
||||
import { CreamPoolsCache } from './cream_utils';
|
||||
import { getCurveInfosForPair, getSwerveInfosForPair } from './curve_utils';
|
||||
import { getKyberReserveIdsForPair } from './kyber_utils';
|
||||
import { getMultiBridgeIntermediateToken } from './multibridge_utils';
|
||||
@ -73,6 +74,7 @@ export class SamplerOperations {
|
||||
protected readonly _samplerContract: ERC20BridgeSamplerContract,
|
||||
public readonly provider?: SupportedProvider,
|
||||
public readonly balancerPoolsCache: BalancerPoolsCache = new BalancerPoolsCache(),
|
||||
public readonly creamPoolsCache: CreamPoolsCache = new CreamPoolsCache(),
|
||||
protected readonly getBancorServiceFn?: () => BancorService, // for dependency injection in tests
|
||||
) {}
|
||||
|
||||
@ -410,9 +412,10 @@ export class SamplerOperations {
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
source: ERC20BridgeSource,
|
||||
): SourceQuoteOperation<BalancerFillData> {
|
||||
return new SamplerContractOperation({
|
||||
source: ERC20BridgeSource.Balancer,
|
||||
source,
|
||||
fillData: { poolAddress },
|
||||
contract: this._samplerContract,
|
||||
function: this._samplerContract.sampleSellsFromBalancer,
|
||||
@ -425,9 +428,10 @@ export class SamplerOperations {
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
source: ERC20BridgeSource,
|
||||
): SourceQuoteOperation<BalancerFillData> {
|
||||
return new SamplerContractOperation({
|
||||
source: ERC20BridgeSource.Balancer,
|
||||
source,
|
||||
fillData: { poolAddress },
|
||||
contract: this._samplerContract,
|
||||
function: this._samplerContract.sampleBuysFromBalancer,
|
||||
@ -467,6 +471,38 @@ export class SamplerOperations {
|
||||
);
|
||||
}
|
||||
|
||||
public async getCreamSellQuotesOffChainAsync(
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
): Promise<Array<Array<DexSample<BalancerFillData>>>> {
|
||||
const pools = await this.creamPoolsCache.getPoolsForPairAsync(takerToken, makerToken);
|
||||
return pools.map(pool =>
|
||||
takerFillAmounts.map(amount => ({
|
||||
source: ERC20BridgeSource.Cream,
|
||||
output: computeBalancerSellQuote(pool, amount),
|
||||
input: amount,
|
||||
fillData: { poolAddress: pool.id },
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
public async getCreamBuyQuotesOffChainAsync(
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
): Promise<Array<Array<DexSample<BalancerFillData>>>> {
|
||||
const pools = await this.creamPoolsCache.getPoolsForPairAsync(takerToken, makerToken);
|
||||
return pools.map(pool =>
|
||||
makerFillAmounts.map(amount => ({
|
||||
source: ERC20BridgeSource.Cream,
|
||||
output: computeBalancerBuyQuote(pool, amount),
|
||||
input: amount,
|
||||
fillData: { poolAddress: pool.id },
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
public getMStableSellQuotes(
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
@ -1039,7 +1075,25 @@ export class SamplerOperations {
|
||||
return this.balancerPoolsCache
|
||||
.getCachedPoolAddressesForPair(takerToken, makerToken)!
|
||||
.map(poolAddress =>
|
||||
this.getBalancerSellQuotes(poolAddress, makerToken, takerToken, takerFillAmounts),
|
||||
this.getBalancerSellQuotes(
|
||||
poolAddress,
|
||||
makerToken,
|
||||
takerToken,
|
||||
takerFillAmounts,
|
||||
ERC20BridgeSource.Balancer,
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Cream:
|
||||
return this.creamPoolsCache
|
||||
.getCachedPoolAddressesForPair(takerToken, makerToken)!
|
||||
.map(poolAddress =>
|
||||
this.getBalancerSellQuotes(
|
||||
poolAddress,
|
||||
makerToken,
|
||||
takerToken,
|
||||
takerFillAmounts,
|
||||
ERC20BridgeSource.Cream,
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Shell:
|
||||
return this.getShellSellQuotes(makerToken, takerToken, takerFillAmounts);
|
||||
@ -1130,7 +1184,25 @@ export class SamplerOperations {
|
||||
return this.balancerPoolsCache
|
||||
.getCachedPoolAddressesForPair(takerToken, makerToken)!
|
||||
.map(poolAddress =>
|
||||
this.getBalancerBuyQuotes(poolAddress, makerToken, takerToken, makerFillAmounts),
|
||||
this.getBalancerBuyQuotes(
|
||||
poolAddress,
|
||||
makerToken,
|
||||
takerToken,
|
||||
makerFillAmounts,
|
||||
ERC20BridgeSource.Balancer,
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Cream:
|
||||
return this.creamPoolsCache
|
||||
.getCachedPoolAddressesForPair(takerToken, makerToken)!
|
||||
.map(poolAddress =>
|
||||
this.getBalancerBuyQuotes(
|
||||
poolAddress,
|
||||
makerToken,
|
||||
takerToken,
|
||||
makerFillAmounts,
|
||||
ERC20BridgeSource.Cream,
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Shell:
|
||||
return this.getShellBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
||||
|
@ -37,6 +37,7 @@ export enum ERC20BridgeSource {
|
||||
LiquidityProvider = 'LiquidityProvider',
|
||||
MultiBridge = 'MultiBridge',
|
||||
Balancer = 'Balancer',
|
||||
Cream = 'CREAM',
|
||||
Bancor = 'Bancor',
|
||||
MStable = 'mStable',
|
||||
Mooniswap = 'Mooniswap',
|
||||
|
@ -504,6 +504,7 @@ describe('DexSampler tests', () => {
|
||||
undefined, // sampler overrides
|
||||
provider,
|
||||
undefined, // balancer cache
|
||||
undefined, // cream cache
|
||||
() => bancorService,
|
||||
);
|
||||
const quotes = await dexOrderSampler.getBancorSellQuotesOffChainAsync(
|
||||
|
@ -25,6 +25,7 @@ import {
|
||||
SOURCE_FLAGS,
|
||||
ZERO_AMOUNT,
|
||||
} from '../src/utils/market_operation_utils/constants';
|
||||
import { CreamPoolsCache } from '../src/utils/market_operation_utils/cream_utils';
|
||||
import { createFills } from '../src/utils/market_operation_utils/fills';
|
||||
import { DexOrderSampler } from '../src/utils/market_operation_utils/sampler';
|
||||
import { BATCH_SOURCE_FILTERS } from '../src/utils/market_operation_utils/sampler_operations';
|
||||
@ -45,6 +46,7 @@ const DEFAULT_EXCLUDED = [
|
||||
ERC20BridgeSource.SushiSwap,
|
||||
ERC20BridgeSource.MultiHop,
|
||||
ERC20BridgeSource.Shell,
|
||||
ERC20BridgeSource.Cream,
|
||||
ERC20BridgeSource.Dodo,
|
||||
];
|
||||
const BUY_SOURCES = BUY_SOURCE_FILTER.sources;
|
||||
@ -285,6 +287,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
[ERC20BridgeSource.SushiSwap]: _.times(NUM_SAMPLES, () => 0),
|
||||
[ERC20BridgeSource.MultiHop]: _.times(NUM_SAMPLES, () => 0),
|
||||
[ERC20BridgeSource.Shell]: _.times(NUM_SAMPLES, () => 0),
|
||||
[ERC20BridgeSource.Cream]: _.times(NUM_SAMPLES, () => 0),
|
||||
[ERC20BridgeSource.Dodo]: _.times(NUM_SAMPLES, () => 0),
|
||||
};
|
||||
|
||||
@ -332,6 +335,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
[ERC20BridgeSource.Native]: { order: createOrder() },
|
||||
[ERC20BridgeSource.MultiHop]: {},
|
||||
[ERC20BridgeSource.Shell]: {},
|
||||
[ERC20BridgeSource.Cream]: { poolAddress: randomAddress() },
|
||||
[ERC20BridgeSource.Dodo]: {},
|
||||
};
|
||||
|
||||
@ -369,6 +373,22 @@ describe('MarketOperationUtils tests', () => {
|
||||
DEFAULT_FILL_DATA[ERC20BridgeSource.Balancer],
|
||||
),
|
||||
],
|
||||
getCreamSellQuotesOffChainAsync: (_makerToken: string, _takerToken: string, takerFillAmounts: BigNumber[]) => [
|
||||
createSamplesFromRates(
|
||||
ERC20BridgeSource.Cream,
|
||||
takerFillAmounts,
|
||||
createDecreasingRates(takerFillAmounts.length),
|
||||
DEFAULT_FILL_DATA[ERC20BridgeSource.Cream],
|
||||
),
|
||||
],
|
||||
getCreamBuyQuotesOffChainAsync: (_makerToken: string, _takerToken: string, makerFillAmounts: BigNumber[]) => [
|
||||
createSamplesFromRates(
|
||||
ERC20BridgeSource.Cream,
|
||||
makerFillAmounts,
|
||||
createDecreasingRates(makerFillAmounts.length).map(r => new BigNumber(1).div(r)),
|
||||
DEFAULT_FILL_DATA[ERC20BridgeSource.Cream],
|
||||
),
|
||||
],
|
||||
getBancorSellQuotesOffChainAsync: (_makerToken: string, _takerToken: string, takerFillAmounts: BigNumber[]) =>
|
||||
createSamplesFromRates(
|
||||
ERC20BridgeSource.Bancor,
|
||||
@ -388,6 +408,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
return ops;
|
||||
},
|
||||
balancerPoolsCache: new BalancerPoolsCache(),
|
||||
creamPoolsCache: new CreamPoolsCache(),
|
||||
} as any) as DexOrderSampler;
|
||||
|
||||
function replaceSamplerOps(ops: Partial<typeof DEFAULT_OPS> = {}): void {
|
||||
@ -491,6 +512,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
getCreamSellQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
});
|
||||
await marketOperationUtils.getMarketSellOrdersAsync(ORDERS, FILL_AMOUNT, {
|
||||
...DEFAULT_OPTS,
|
||||
@ -521,6 +550,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
args.sources = args.sources.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
getCreamSellQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
args.sources = args.sources.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
});
|
||||
const registryAddress = randomAddress();
|
||||
const newMarketOperationUtils = new MarketOperationUtils(
|
||||
@ -562,6 +599,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
getCreamSellQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
});
|
||||
await marketOperationUtils.getMarketSellOrdersAsync(ORDERS, FILL_AMOUNT, {
|
||||
...DEFAULT_OPTS,
|
||||
@ -593,6 +638,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
getCreamSellQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamSellQuotesOffChainAsync(makerToken, takerToken, takerFillAmounts);
|
||||
},
|
||||
});
|
||||
await marketOperationUtils.getMarketSellOrdersAsync(ORDERS, FILL_AMOUNT, {
|
||||
...DEFAULT_OPTS,
|
||||
@ -983,6 +1036,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
getCreamBuyQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
});
|
||||
await marketOperationUtils.getMarketBuyOrdersAsync(ORDERS, FILL_AMOUNT, {
|
||||
...DEFAULT_OPTS,
|
||||
@ -1013,6 +1074,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
args.sources = args.sources.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
getCreamBuyQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
args.sources = args.sources.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
});
|
||||
const registryAddress = randomAddress();
|
||||
const newMarketOperationUtils = new MarketOperationUtils(
|
||||
@ -1054,6 +1123,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
getCreamBuyQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
});
|
||||
await marketOperationUtils.getMarketBuyOrdersAsync(ORDERS, FILL_AMOUNT, {
|
||||
...DEFAULT_OPTS,
|
||||
@ -1085,6 +1162,14 @@ describe('MarketOperationUtils tests', () => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Balancer);
|
||||
return DEFAULT_OPS.getBalancerBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
getCreamBuyQuotesOffChainAsync: (
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
) => {
|
||||
sourcesPolled = sourcesPolled.concat(ERC20BridgeSource.Cream);
|
||||
return DEFAULT_OPS.getCreamBuyQuotesOffChainAsync(makerToken, takerToken, makerFillAmounts);
|
||||
},
|
||||
});
|
||||
await marketOperationUtils.getMarketBuyOrdersAsync(ORDERS, FILL_AMOUNT, {
|
||||
...DEFAULT_OPTS,
|
||||
|
@ -57,6 +57,10 @@
|
||||
{
|
||||
"note": "Deploy `DodoBridge` on Mainnet",
|
||||
"pr": 2701
|
||||
},
|
||||
{
|
||||
"note": "Deploy `CreamBridge` on Mainnet",
|
||||
"pr": 2715
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -45,6 +45,7 @@
|
||||
"sushiswapBridge": "0x47ed0262a0b688dcb836d254c6a2e96b6c48a9f5",
|
||||
"shellBridge": "0x21fb3862eed7911e0f8219a077247b849846728d",
|
||||
"dodoBridge": "0xe9da66965a9344aab2167e6813c03f043cc7a6ca",
|
||||
"creamBridge": "0xb9d4bf2c8dab828f4ffb656acdb6c2b497d44f25",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x68c0bb685099dc7cb5c5ce2b26185945b357383e",
|
||||
"payTakerTransformer": "0x49b9df2c58491764cf40cb052dd4243df63622c7",
|
||||
@ -98,6 +99,7 @@
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
||||
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
||||
@ -151,6 +153,7 @@
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
||||
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
||||
@ -204,6 +207,7 @@
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0x9ce35b5ee9e710535e3988e3f8731d9ca9dba17d",
|
||||
"payTakerTransformer": "0x5a53e7b02a83aa9f60ccf4e424f0442c255bc977",
|
||||
@ -257,6 +261,7 @@
|
||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||
"creamBridge": "0x0000000000000000000000000000000000000000",
|
||||
"transformers": {
|
||||
"wethTransformer": "0xc6b0d3c45a6b5092808196cb00df5c357d55e1d5",
|
||||
"payTakerTransformer": "0x7209185959d7227fb77274e1e88151d7c4c368d3",
|
||||
|
@ -46,6 +46,7 @@ export interface ContractAddresses {
|
||||
sushiswapBridge: string;
|
||||
shellBridge: string;
|
||||
dodoBridge: string;
|
||||
creamBridge: string;
|
||||
transformers: {
|
||||
wethTransformer: string;
|
||||
payTakerTransformer: string;
|
||||
|
@ -325,6 +325,7 @@ export async function runMigrationsAsync(
|
||||
uniswapExchangeFactory: NULL_ADDRESS,
|
||||
mStable: NULL_ADDRESS,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
shell: NULL_ADDRESS,
|
||||
weth: etherToken.address,
|
||||
},
|
||||
@ -405,6 +406,7 @@ export async function runMigrationsAsync(
|
||||
sushiswapBridge: NULL_ADDRESS,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
dodoBridge: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
exchangeProxy: exchangeProxy.address,
|
||||
exchangeProxyAllowanceTarget: exchangeProxyAllowanceTargetAddress,
|
||||
exchangeProxyTransformerDeployer: txDefaults.from,
|
||||
|
267
yarn.lock
267
yarn.lock
@ -1093,6 +1093,242 @@
|
||||
version "0.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.2.tgz#b180097bb44a40c3b59efea9cf28df2fe542d518"
|
||||
|
||||
"@ethersproject/abi@^5.0.1", "@ethersproject/abi@^5.0.5":
|
||||
version "5.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.7.tgz#79e52452bd3ca2956d0e1c964207a58ad1a0ee7b"
|
||||
integrity sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==
|
||||
dependencies:
|
||||
"@ethersproject/address" "^5.0.4"
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/constants" "^5.0.4"
|
||||
"@ethersproject/hash" "^5.0.4"
|
||||
"@ethersproject/keccak256" "^5.0.3"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
"@ethersproject/strings" "^5.0.4"
|
||||
|
||||
"@ethersproject/abstract-provider@^5.0.4":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.5.tgz#797a32a8707830af1ad8f833e9c228994d5572b9"
|
||||
integrity sha512-i/CjElAkzV7vQBAeoz+IpjGfcFYEP9eD7j3fzZ0fzTq03DO7PPnR+xkEZ1IoDXGwDS+55aLM1xvLDwB/Lx6IOQ==
|
||||
dependencies:
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/networks" "^5.0.3"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
"@ethersproject/transactions" "^5.0.5"
|
||||
"@ethersproject/web" "^5.0.6"
|
||||
|
||||
"@ethersproject/abstract-signer@^5.0.4":
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.6.tgz#c01211665ab9c9e93988c4783b789712fd93a388"
|
||||
integrity sha512-h8TZBX3pL2Xx9tmsRxfWcaaI+FcJFHWvZ/vNvFjLp8zJ0kPD501LKTt2jo44LZ20N3EW68JMoyEmRQ6bpsn+iA==
|
||||
dependencies:
|
||||
"@ethersproject/abstract-provider" "^5.0.4"
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
|
||||
"@ethersproject/address@^5.0.1", "@ethersproject/address@^5.0.4":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.5.tgz#2caa65f6b7125015395b1b54c985ee0b27059cc7"
|
||||
integrity sha512-DpkQ6rwk9jTefrRsJzEm6nhRiJd9pvhn1xN0rw5N/jswXG5r7BLk/GVA0mMAVWAsYfvi2xSc5L41FMox43RYEA==
|
||||
dependencies:
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/keccak256" "^5.0.3"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/rlp" "^5.0.3"
|
||||
bn.js "^4.4.0"
|
||||
|
||||
"@ethersproject/base64@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.4.tgz#b0d8fdbf3dda977cf546dcd35725a7b1d5256caa"
|
||||
integrity sha512-4KRykQ7BQMeOXfvio1YITwHjxwBzh92UoXIdzxDE1p53CK28bbHPdsPNYo0wl0El7lJAMpT2SOdL0hhbWRnyIA==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
|
||||
"@ethersproject/basex@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.4.tgz#93e1cd11f9a47281da2389de24f88e13e9d90847"
|
||||
integrity sha512-ixIr/kKiAoSzOnSc777AGIOAhKai5Ivqr4HO/Gz+YG+xkfv6kqD6AW4ga9vM20Wwb0QBhh3LoRWTu4V1K+x9Ew==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
|
||||
"@ethersproject/bignumber@^5.0.7":
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.8.tgz#cee33bd8eb0266176def0d371b45274b1d2c4ec0"
|
||||
integrity sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
bn.js "^4.4.0"
|
||||
|
||||
"@ethersproject/bytes@^5.0.4":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.5.tgz#688b70000e550de0c97a151a21f15b87d7f97d7c"
|
||||
integrity sha512-IEj9HpZB+ACS6cZ+QQMTqmu/cnUK2fYNE6ms/PVxjoBjoxc6HCraLpam1KuRvreMy0i523PLmjN8OYeikRdcUQ==
|
||||
dependencies:
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
|
||||
"@ethersproject/constants@^5.0.4":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.5.tgz#0ed19b002e8404bdf6d135234dc86a7d9bcf9b71"
|
||||
integrity sha512-foaQVmxp2+ik9FrLUCtVrLZCj4M3Ibgkqvh+Xw/vFRSerkjVSYePApaVE5essxhoSlF1U9oXfWY09QI2AXtgKA==
|
||||
dependencies:
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
|
||||
"@ethersproject/contracts@^5.0.1":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.0.5.tgz#64831a341ec8ca225e83ff3e9437c26b970fd5d7"
|
||||
integrity sha512-tFI255lFbmbqMkgnuyhDWHl3yWqttPlReplYuVvDCT/SuvBjLR4ad2uipBlh1fh5X1ipK9ettAoV4S0HKim4Kw==
|
||||
dependencies:
|
||||
"@ethersproject/abi" "^5.0.5"
|
||||
"@ethersproject/abstract-provider" "^5.0.4"
|
||||
"@ethersproject/abstract-signer" "^5.0.4"
|
||||
"@ethersproject/address" "^5.0.4"
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/constants" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
|
||||
"@ethersproject/hash@^5.0.4":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.5.tgz#e383ba2c7941834266fa6e2cf543d2b0c50a9d59"
|
||||
integrity sha512-GpI80/h2HDpfNKpCZoxQJCjOQloGnlD5hM1G+tZe8FQDJhEvFjJoPDuWv+NaYjJfOciKS2Axqc4Q4WamdLoUgg==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/keccak256" "^5.0.3"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/strings" "^5.0.4"
|
||||
|
||||
"@ethersproject/keccak256@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.4.tgz#36ca0a7d1ae2a272da5654cb886776d0c680ef3a"
|
||||
integrity sha512-GNpiOUm9PGUxFNqOxYKDQBM0u68bG9XC9iOulEQ8I0tOx/4qUpgVzvgXL6ugxr0RY554Gz/NQsVqknqPzUcxpQ==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
js-sha3 "0.5.7"
|
||||
|
||||
"@ethersproject/logger@^5.0.5":
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.6.tgz#faa484203e86e08be9e07fef826afeef7183fe88"
|
||||
integrity sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ==
|
||||
|
||||
"@ethersproject/networks@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.4.tgz#6d320a5e15a0cda804f5da88be0ba846156f6eec"
|
||||
integrity sha512-/wHDTRms5mpJ09BoDrbNdFWINzONe05wZRgohCXvEv39rrH/Gd/yAnct8wC0RsW3tmFOgjgQxuBvypIxuUynTw==
|
||||
dependencies:
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
|
||||
"@ethersproject/properties@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.4.tgz#a67a1f5a52c30850b5062c861631e73d131f666e"
|
||||
integrity sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A==
|
||||
dependencies:
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
|
||||
"@ethersproject/providers@^5.0.4":
|
||||
version "5.0.12"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.0.12.tgz#de05e865e130709ea1e0870511eb892bda7d41cb"
|
||||
integrity sha512-bRUEVNth+wGlm2Q0cQprVlixBWumfP9anrgAc3V2CbIh+GKvCwisVO8uRLrZOfOvTNSy6PUJi/Z4D5L+k3NAog==
|
||||
dependencies:
|
||||
"@ethersproject/abstract-provider" "^5.0.4"
|
||||
"@ethersproject/abstract-signer" "^5.0.4"
|
||||
"@ethersproject/address" "^5.0.4"
|
||||
"@ethersproject/basex" "^5.0.3"
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/constants" "^5.0.4"
|
||||
"@ethersproject/hash" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/networks" "^5.0.3"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
"@ethersproject/random" "^5.0.3"
|
||||
"@ethersproject/rlp" "^5.0.3"
|
||||
"@ethersproject/sha2" "^5.0.3"
|
||||
"@ethersproject/strings" "^5.0.4"
|
||||
"@ethersproject/transactions" "^5.0.5"
|
||||
"@ethersproject/web" "^5.0.6"
|
||||
bech32 "1.1.4"
|
||||
ws "7.2.3"
|
||||
|
||||
"@ethersproject/random@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.4.tgz#98f7cf65b0e588cec39ef24843e391ed5004556f"
|
||||
integrity sha512-AIZJhqs6Ba4/+U3lOjt3QZbP6b/kuuGLJUYFUonAgWmkTHwqsCwYnFvnHKQSUuHbXHvErp7WFXFlztx+yMn3kQ==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
|
||||
"@ethersproject/rlp@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.4.tgz#0090a0271e84ea803016a112a79f5cfd80271a77"
|
||||
integrity sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
|
||||
"@ethersproject/sha2@^5.0.3":
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.4.tgz#40f639721a27dbe034b3dee021ba20b054586fec"
|
||||
integrity sha512-0yFhf1mspxAfWdXXoPtK94adUeu1R7/FzAa+DfEiZTc76sz/vHXf0LSIazoR3znYKFny6haBxME+usbvvEcF3A==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
hash.js "1.1.3"
|
||||
|
||||
"@ethersproject/signing-key@^5.0.4":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.5.tgz#acfd06fc05a14180df7e027688bbd23fc4baf782"
|
||||
integrity sha512-Z1wY7JC1HVO4CvQWY2TyTTuAr8xK3bJijZw1a9G92JEmKdv1j255R/0YLBBcFTl2J65LUjtXynNJ2GbArPGi5g==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
elliptic "6.5.3"
|
||||
|
||||
"@ethersproject/strings@^5.0.4":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.5.tgz#ed7e99a282a02f40757691b04a24cd83f3752195"
|
||||
integrity sha512-JED6WaIV00xM/gvj8vSnd+0VWtDYdidTmavFRCTQakqfz+4tDo6Jz5LHgG+dd45h7ah7ykCHW0C7ZXWEDROCXQ==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/constants" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
|
||||
"@ethersproject/transactions@^5.0.5":
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.6.tgz#b8b27938be6e9ed671dbdd35fe98af8b14d0df7c"
|
||||
integrity sha512-htsFhOD+NMBxx676A8ehSuwVV49iqpSB+CkjPZ02tpNew0K6p8g0CZ46Z1ZP946gIHAU80xQ0NACHYrjIUaCFA==
|
||||
dependencies:
|
||||
"@ethersproject/address" "^5.0.4"
|
||||
"@ethersproject/bignumber" "^5.0.7"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/constants" "^5.0.4"
|
||||
"@ethersproject/keccak256" "^5.0.3"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
"@ethersproject/rlp" "^5.0.3"
|
||||
"@ethersproject/signing-key" "^5.0.4"
|
||||
|
||||
"@ethersproject/web@^5.0.6":
|
||||
version "5.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.9.tgz#b08f8295f4bfd4777c8723fe9572f5453b9f03cb"
|
||||
integrity sha512-//QNlv1MSkOII1hv3+HQwWoiVFS+BMVGI0KYeUww4cyrEktnx1QIez5bTSab9s9fWTFaWKNmQNBwMbxAqPuYDw==
|
||||
dependencies:
|
||||
"@ethersproject/base64" "^5.0.3"
|
||||
"@ethersproject/bytes" "^5.0.4"
|
||||
"@ethersproject/logger" "^5.0.5"
|
||||
"@ethersproject/properties" "^5.0.3"
|
||||
"@ethersproject/strings" "^5.0.4"
|
||||
|
||||
"@evocateur/libnpmaccess@^3.1.2":
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz#ecf7f6ce6b004e9f942b098d92200be4a4b1c845"
|
||||
@ -3911,6 +4147,11 @@ bcrypt-pbkdf@^1.0.0:
|
||||
dependencies:
|
||||
tweetnacl "^0.14.3"
|
||||
|
||||
bech32@1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
|
||||
integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
|
||||
|
||||
before-after-hook@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"
|
||||
@ -5510,6 +5751,14 @@ coveralls@^3.0.0:
|
||||
minimist "^1.2.0"
|
||||
request "^2.79.0"
|
||||
|
||||
cream-sor@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/cream-sor/-/cream-sor-0.3.3.tgz#ae7ab50c68cfd36a89e2101187ceebbb79e1b14c"
|
||||
integrity sha512-taQSvCUunPhwyebwbjxh1l9NDp39lsre+Q2oRMK+gqzbu+Wlbg5GAquwoV2/GLgzia70gi4x1rJCJsUmc5Kygg==
|
||||
dependencies:
|
||||
bignumber.js "^9.0.0"
|
||||
isomorphic-fetch "^2.2.1"
|
||||
|
||||
create-ecdh@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.1.tgz#44223dfed533193ba5ba54e0df5709b89acf1f82"
|
||||
@ -6356,6 +6605,19 @@ elliptic@6.5.2:
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.0"
|
||||
|
||||
elliptic@6.5.3:
|
||||
version "6.5.3"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6"
|
||||
integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==
|
||||
dependencies:
|
||||
bn.js "^4.4.0"
|
||||
brorand "^1.0.1"
|
||||
hash.js "^1.0.0"
|
||||
hmac-drbg "^1.0.0"
|
||||
inherits "^2.0.1"
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.0"
|
||||
|
||||
elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0:
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df"
|
||||
@ -18441,6 +18703,11 @@ write@^0.2.1:
|
||||
dependencies:
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
ws@7.2.3:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46"
|
||||
integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==
|
||||
|
||||
ws@^3.0.0:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"
|
||||
|
Loading…
x
Reference in New Issue
Block a user