Compare commits
14 Commits
protocol@5
...
protocol@9
Author | SHA1 | Date | |
---|---|---|---|
|
9ce73931f7 | ||
|
97020df178 | ||
|
dfb7b3de8f | ||
|
9e152912fe | ||
|
b2c2f1e1aa | ||
|
629c7d8e92 | ||
|
62f24d4356 | ||
|
ae281c33ca | ||
|
5d034dd106 | ||
|
c1f8df0eca | ||
|
76dda9eeda | ||
|
a9b84a92ac | ||
|
0f7e881899 | ||
|
6045f777ab |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-integrations",
|
"name": "@0x/contracts-integrations",
|
||||||
"version": "2.7.30",
|
"version": "2.7.34",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
@@ -65,9 +65,9 @@
|
|||||||
"@0x/contracts-utils": "^4.7.6",
|
"@0x/contracts-utils": "^4.7.6",
|
||||||
"@0x/coordinator-server": "^1.0.5",
|
"@0x/coordinator-server": "^1.0.5",
|
||||||
"@0x/dev-utils": "^4.2.1",
|
"@0x/dev-utils": "^4.2.1",
|
||||||
"@0x/migrations": "^8.0.0",
|
"@0x/migrations": "^8.0.1",
|
||||||
"@0x/order-utils": "^10.4.19",
|
"@0x/order-utils": "^10.4.19",
|
||||||
"@0x/protocol-utils": "^1.4.0",
|
"@0x/protocol-utils": "^1.4.1",
|
||||||
"@0x/sol-compiler": "^4.6.1",
|
"@0x/sol-compiler": "^4.6.1",
|
||||||
"@0x/tslint-config": "^4.1.3",
|
"@0x/tslint-config": "^4.1.3",
|
||||||
"@0x/web3-wrapper": "^7.4.1",
|
"@0x/web3-wrapper": "^7.4.1",
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
"typescript": "4.2.2"
|
"typescript": "4.2.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/asset-swapper": "^6.4.0",
|
"@0x/asset-swapper": "^6.5.3",
|
||||||
"@0x/base-contract": "^6.2.18",
|
"@0x/base-contract": "^6.2.18",
|
||||||
"@0x/contracts-asset-proxy": "^3.7.9",
|
"@0x/contracts-asset-proxy": "^3.7.9",
|
||||||
"@0x/contracts-erc1155": "^2.1.27",
|
"@0x/contracts-erc1155": "^2.1.27",
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
"@0x/contracts-multisig": "^4.1.28",
|
"@0x/contracts-multisig": "^4.1.28",
|
||||||
"@0x/contracts-staking": "^2.0.35",
|
"@0x/contracts-staking": "^2.0.35",
|
||||||
"@0x/contracts-test-utils": "^5.3.24",
|
"@0x/contracts-test-utils": "^5.3.24",
|
||||||
"@0x/contracts-zero-ex": "^0.21.0",
|
"@0x/contracts-zero-ex": "^0.21.1",
|
||||||
"@0x/subproviders": "^6.4.1",
|
"@0x/subproviders": "^6.4.1",
|
||||||
"@0x/types": "^3.3.1",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.6",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
|
@@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1618259868,
|
||||||
|
"version": "1.1.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1617311315,
|
"timestamp": 1617311315,
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.1.2 - _April 12, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v1.1.1 - _April 1, 2021_
|
## v1.1.1 - _April 1, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-treasury",
|
"name": "@0x/contracts-treasury",
|
||||||
"version": "1.1.1",
|
"version": "1.1.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.18",
|
"@0x/base-contract": "^6.2.18",
|
||||||
"@0x/protocol-utils": "^1.4.0",
|
"@0x/protocol-utils": "^1.4.1",
|
||||||
"@0x/subproviders": "^6.4.1",
|
"@0x/subproviders": "^6.4.1",
|
||||||
"@0x/types": "^3.3.1",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.6",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
|
@@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1618259868,
|
||||||
|
"version": "0.21.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "0.21.0",
|
"version": "0.21.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v0.21.1 - _April 12, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v0.21.0 - _April 1, 2021_
|
## v0.21.0 - _April 1, 2021_
|
||||||
|
|
||||||
* Encoding protocol ID and source name in bridge source ID (#162)
|
* Encoding protocol ID and source name in bridge source ID (#162)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-zero-ex",
|
"name": "@0x/contracts-zero-ex",
|
||||||
"version": "0.21.0",
|
"version": "0.21.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.2.18",
|
"@0x/base-contract": "^6.2.18",
|
||||||
"@0x/protocol-utils": "^1.4.0",
|
"@0x/protocol-utils": "^1.4.1",
|
||||||
"@0x/subproviders": "^6.4.1",
|
"@0x/subproviders": "^6.4.1",
|
||||||
"@0x/types": "^3.3.1",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.6",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
|
@@ -1,7 +1,53 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "6.5.3",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Apply slippage to bridge orders in consumer",
|
||||||
|
"pr": 198
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1618433771
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1618314654,
|
||||||
|
"version": "6.5.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1618259868,
|
||||||
|
"version": "6.5.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "6.5.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add Kyber DMM to Ethereum mainnet",
|
||||||
|
"pr": 194
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Add default LiquidityProvider registry and allow LiquidityProvider gasCost to be a function of tokens",
|
||||||
|
"pr": 196
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1617913615
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "6.4.0",
|
"version": "6.4.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Added Component, Smoothy, Saddle, Curve open pools, tweeks gas schedule, adding SushiSwap as a fee quote source",
|
||||||
|
"pr": 182
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"note": "Use SOURCE_FLAGS.rfqOrder in comparisonPrice",
|
"note": "Use SOURCE_FLAGS.rfqOrder in comparisonPrice",
|
||||||
"pr": 177
|
"pr": 177
|
||||||
|
@@ -5,8 +5,26 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v6.5.3 - _April 14, 2021_
|
||||||
|
|
||||||
|
* Apply slippage to bridge orders in consumer (#198)
|
||||||
|
|
||||||
|
## v6.5.2 - _April 13, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v6.5.1 - _April 12, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v6.5.0 - _April 8, 2021_
|
||||||
|
|
||||||
|
* Add Kyber DMM to Ethereum mainnet (#194)
|
||||||
|
* Add default LiquidityProvider registry and allow LiquidityProvider gasCost to be a function of tokens (#196)
|
||||||
|
|
||||||
## v6.4.0 - _April 1, 2021_
|
## v6.4.0 - _April 1, 2021_
|
||||||
|
|
||||||
|
* Added Component, Smoothy, Saddle, Curve open pools, tweeks gas schedule, adding SushiSwap as a fee quote source (#182)
|
||||||
* Use SOURCE_FLAGS.rfqOrder in comparisonPrice (#177)
|
* Use SOURCE_FLAGS.rfqOrder in comparisonPrice (#177)
|
||||||
* Add a cancel token to ensure timeouts are respected (#176)
|
* Add a cancel token to ensure timeouts are respected (#176)
|
||||||
* Rename {Rfqt=>Rfq} for many types in Asset Swapper (#179)
|
* Rename {Rfqt=>Rfq} for many types in Asset Swapper (#179)
|
||||||
|
@@ -34,6 +34,7 @@ import "./MStableSampler.sol";
|
|||||||
import "./MooniswapSampler.sol";
|
import "./MooniswapSampler.sol";
|
||||||
import "./NativeOrderSampler.sol";
|
import "./NativeOrderSampler.sol";
|
||||||
import "./ShellSampler.sol";
|
import "./ShellSampler.sol";
|
||||||
|
import "./SmoothySampler.sol";
|
||||||
import "./TwoHopSampler.sol";
|
import "./TwoHopSampler.sol";
|
||||||
import "./UniswapSampler.sol";
|
import "./UniswapSampler.sol";
|
||||||
import "./UniswapV2Sampler.sol";
|
import "./UniswapV2Sampler.sol";
|
||||||
@@ -55,6 +56,7 @@ contract ERC20BridgeSampler is
|
|||||||
MultiBridgeSampler,
|
MultiBridgeSampler,
|
||||||
NativeOrderSampler,
|
NativeOrderSampler,
|
||||||
ShellSampler,
|
ShellSampler,
|
||||||
|
SmoothySampler,
|
||||||
TwoHopSampler,
|
TwoHopSampler,
|
||||||
UniswapSampler,
|
UniswapSampler,
|
||||||
UniswapV2Sampler,
|
UniswapV2Sampler,
|
||||||
|
@@ -20,10 +20,20 @@
|
|||||||
pragma solidity ^0.6;
|
pragma solidity ^0.6;
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "./ApproximateBuys.sol";
|
||||||
import "./interfaces/IShell.sol";
|
import "./interfaces/IShell.sol";
|
||||||
|
import "./SamplerUtils.sol";
|
||||||
|
|
||||||
contract ShellSampler
|
|
||||||
|
contract ShellSampler is
|
||||||
|
SamplerUtils,
|
||||||
|
ApproximateBuys
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct ShellInfo {
|
||||||
|
address poolAddress;
|
||||||
|
}
|
||||||
|
|
||||||
/// @dev Default gas limit for Shell calls.
|
/// @dev Default gas limit for Shell calls.
|
||||||
uint256 constant private DEFAULT_CALL_GAS = 300e3; // 300k
|
uint256 constant private DEFAULT_CALL_GAS = 300e3; // 300k
|
||||||
|
|
||||||
@@ -56,10 +66,6 @@ contract ShellSampler
|
|||||||
returns (uint256 amount)
|
returns (uint256 amount)
|
||||||
{
|
{
|
||||||
makerTokenAmounts[i] = amount;
|
makerTokenAmounts[i] = amount;
|
||||||
// Break early if there are 0 amounts
|
|
||||||
if (makerTokenAmounts[i] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (bytes memory) {
|
} catch (bytes memory) {
|
||||||
// Swallow failures, leaving all results as zero.
|
// Swallow failures, leaving all results as zero.
|
||||||
break;
|
break;
|
||||||
@@ -84,26 +90,37 @@ contract ShellSampler
|
|||||||
view
|
view
|
||||||
returns (uint256[] memory takerTokenAmounts)
|
returns (uint256[] memory takerTokenAmounts)
|
||||||
{
|
{
|
||||||
// Initialize array of maker token amounts.
|
return _sampleApproximateBuys(
|
||||||
uint256 numSamples = makerTokenAmounts.length;
|
ApproximateBuyQuoteOpts({
|
||||||
takerTokenAmounts = new uint256[](numSamples);
|
makerTokenData: abi.encode(makerToken, pool),
|
||||||
|
takerTokenData: abi.encode(takerToken, pool),
|
||||||
|
getSellQuoteCallback: _sampleSellForApproximateBuyFromShell
|
||||||
|
}),
|
||||||
|
makerTokenAmounts
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
for (uint256 i = 0; i < numSamples; i++) {
|
function _sampleSellForApproximateBuyFromShell(
|
||||||
try
|
bytes memory takerTokenData,
|
||||||
IShell(pool).viewTargetSwap
|
bytes memory makerTokenData,
|
||||||
{gas: DEFAULT_CALL_GAS}
|
uint256 sellAmount
|
||||||
(takerToken, makerToken, makerTokenAmounts[i])
|
)
|
||||||
returns (uint256 amount)
|
private
|
||||||
{
|
view
|
||||||
takerTokenAmounts[i] = amount;
|
returns (uint256 buyAmount)
|
||||||
// Break early if there are 0 amounts
|
{
|
||||||
if (takerTokenAmounts[i] == 0) {
|
(address takerToken, address pool) = abi.decode(takerTokenData, (address, address));
|
||||||
break;
|
(address makerToken) = abi.decode(makerTokenData, (address));
|
||||||
}
|
|
||||||
} catch (bytes memory) {
|
try
|
||||||
// Swallow failures, leaving all results as zero.
|
this.sampleSellsFromShell
|
||||||
break;
|
(pool, takerToken, makerToken, _toSingleValueArray(sellAmount))
|
||||||
}
|
returns (uint256[] memory amounts)
|
||||||
|
{
|
||||||
|
return amounts[0];
|
||||||
|
} catch (bytes memory) {
|
||||||
|
// Swallow failures, leaving all results as zero.
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
156
packages/asset-swapper/contracts/src/SmoothySampler.sol
Normal file
156
packages/asset-swapper/contracts/src/SmoothySampler.sol
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
// import "./interfaces/ISmoothy.sol";
|
||||||
|
import "./ApproximateBuys.sol";
|
||||||
|
import "./SamplerUtils.sol";
|
||||||
|
import "./interfaces/ISmoothy.sol";
|
||||||
|
|
||||||
|
contract SmoothySampler is
|
||||||
|
SamplerUtils,
|
||||||
|
ApproximateBuys
|
||||||
|
{
|
||||||
|
/// @dev Information for sampling from smoothy sources.
|
||||||
|
struct SmoothyInfo {
|
||||||
|
address poolAddress;
|
||||||
|
bytes4 sellQuoteFunctionSelector;
|
||||||
|
bytes4 buyQuoteFunctionSelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Base gas limit for Smoothy calls.
|
||||||
|
uint256 constant private SMOOTHY_CALL_GAS = 600e3;
|
||||||
|
|
||||||
|
/// @dev Sample sell quotes from Smoothy.
|
||||||
|
/// @param smoothyInfo Smoothy information specific to this token pair.
|
||||||
|
/// @param fromTokenIdx Index of the taker token (what to sell).
|
||||||
|
/// @param toTokenIdx Index of the maker token (what to buy).
|
||||||
|
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||||
|
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||||
|
/// amount.
|
||||||
|
function sampleSellsFromSmoothy(
|
||||||
|
SmoothyInfo memory smoothyInfo,
|
||||||
|
int128 fromTokenIdx,
|
||||||
|
int128 toTokenIdx,
|
||||||
|
uint256[] memory takerTokenAmounts
|
||||||
|
)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256[] memory makerTokenAmounts)
|
||||||
|
{
|
||||||
|
// Basically a Curve fork
|
||||||
|
|
||||||
|
// Smoothy only keep a percentage of its tokens available in reserve
|
||||||
|
uint256 poolReserveMakerAmount = ISmoothy(smoothyInfo.poolAddress).getBalance(uint256(toTokenIdx)) -
|
||||||
|
ISmoothy(smoothyInfo.poolAddress)._yBalances(uint256(toTokenIdx));
|
||||||
|
(, , , uint256 decimals) = ISmoothy(smoothyInfo.poolAddress).getTokenStats(uint256(toTokenIdx));
|
||||||
|
poolReserveMakerAmount = poolReserveMakerAmount/(10**(18-decimals));
|
||||||
|
|
||||||
|
uint256 numSamples = takerTokenAmounts.length;
|
||||||
|
makerTokenAmounts = new uint256[](numSamples);
|
||||||
|
for (uint256 i = 0; i < numSamples; i++) {
|
||||||
|
(bool didSucceed, bytes memory resultData) =
|
||||||
|
smoothyInfo.poolAddress.staticcall.gas(SMOOTHY_CALL_GAS)(
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
smoothyInfo.sellQuoteFunctionSelector,
|
||||||
|
fromTokenIdx,
|
||||||
|
toTokenIdx,
|
||||||
|
takerTokenAmounts[i]
|
||||||
|
));
|
||||||
|
uint256 buyAmount = 0;
|
||||||
|
if (didSucceed) {
|
||||||
|
buyAmount = abi.decode(resultData, (uint256));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the quoted buyAmount is available in the pool reserve
|
||||||
|
if (buyAmount >= poolReserveMakerAmount) {
|
||||||
|
// Assign pool reserve amount for all higher samples to break early
|
||||||
|
for (uint256 j = i; j < numSamples; j++) {
|
||||||
|
makerTokenAmounts[j] = poolReserveMakerAmount;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
makerTokenAmounts[i] = buyAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break early if there are 0 amounts
|
||||||
|
if (makerTokenAmounts[i] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Sample buy quotes from Smoothy.
|
||||||
|
/// @param smoothyInfo Smoothy information specific to this token pair.
|
||||||
|
/// @param fromTokenIdx Index of the taker token (what to sell).
|
||||||
|
/// @param toTokenIdx Index of the maker token (what to buy).
|
||||||
|
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||||
|
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||||
|
/// amount.
|
||||||
|
function sampleBuysFromSmoothy(
|
||||||
|
SmoothyInfo memory smoothyInfo,
|
||||||
|
int128 fromTokenIdx,
|
||||||
|
int128 toTokenIdx,
|
||||||
|
uint256[] memory makerTokenAmounts
|
||||||
|
)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256[] memory takerTokenAmounts)
|
||||||
|
{
|
||||||
|
// Buys not supported so approximate it.
|
||||||
|
return _sampleApproximateBuys(
|
||||||
|
ApproximateBuyQuoteOpts({
|
||||||
|
makerTokenData: abi.encode(toTokenIdx, smoothyInfo),
|
||||||
|
takerTokenData: abi.encode(fromTokenIdx, smoothyInfo),
|
||||||
|
getSellQuoteCallback: _sampleSellForApproximateBuyFromSmoothy
|
||||||
|
}),
|
||||||
|
makerTokenAmounts
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _sampleSellForApproximateBuyFromSmoothy(
|
||||||
|
bytes memory takerTokenData,
|
||||||
|
bytes memory makerTokenData,
|
||||||
|
uint256 sellAmount
|
||||||
|
)
|
||||||
|
private
|
||||||
|
view
|
||||||
|
returns (uint256 buyAmount)
|
||||||
|
{
|
||||||
|
(int128 takerTokenIdx, SmoothyInfo memory smoothyInfo) =
|
||||||
|
abi.decode(takerTokenData, (int128, SmoothyInfo));
|
||||||
|
(int128 makerTokenIdx) =
|
||||||
|
abi.decode(makerTokenData, (int128));
|
||||||
|
(bool success, bytes memory resultData) =
|
||||||
|
address(this).staticcall(abi.encodeWithSelector(
|
||||||
|
this.sampleSellsFromSmoothy.selector,
|
||||||
|
smoothyInfo,
|
||||||
|
takerTokenIdx,
|
||||||
|
makerTokenIdx,
|
||||||
|
_toSingleValueArray(sellAmount)
|
||||||
|
));
|
||||||
|
if (!success) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// solhint-disable-next-line indent
|
||||||
|
return abi.decode(resultData, (uint256[]))[0];
|
||||||
|
}
|
||||||
|
}
|
45
packages/asset-swapper/contracts/src/interfaces/ISmoothy.sol
Normal file
45
packages/asset-swapper/contracts/src/interfaces/ISmoothy.sol
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2021 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.6;
|
||||||
|
|
||||||
|
|
||||||
|
interface ISmoothy {
|
||||||
|
|
||||||
|
function getBalance (
|
||||||
|
uint256 tid
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256 balance);
|
||||||
|
|
||||||
|
function _yBalances (
|
||||||
|
uint256 tid
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256 balance);
|
||||||
|
|
||||||
|
function getTokenStats (
|
||||||
|
uint256 tid
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (uint256 softWeight, uint256 hardWeight, uint256 balance, uint256 decimals);
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/asset-swapper",
|
"name": "@0x/asset-swapper",
|
||||||
"version": "6.4.0",
|
"version": "6.5.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
|
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||||
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BancorSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|Eth2DaiSampler|FakeTaker|IBalancer|IBancor|ICurve|IEth2Dai|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UtilitySampler).json",
|
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BancorSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|Eth2DaiSampler|FakeTaker|IBalancer|IBancor|ICurve|IEth2Dai|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UtilitySampler).json",
|
||||||
"postpublish": {
|
"postpublish": {
|
||||||
"assets": []
|
"assets": []
|
||||||
}
|
}
|
||||||
@@ -62,10 +62,10 @@
|
|||||||
"@0x/contract-addresses": "^6.0.0",
|
"@0x/contract-addresses": "^6.0.0",
|
||||||
"@0x/contract-wrappers": "^13.15.0",
|
"@0x/contract-wrappers": "^13.15.0",
|
||||||
"@0x/contracts-erc20": "^3.3.6",
|
"@0x/contracts-erc20": "^3.3.6",
|
||||||
"@0x/contracts-zero-ex": "^0.21.0",
|
"@0x/contracts-zero-ex": "^0.21.1",
|
||||||
"@0x/dev-utils": "^4.2.1",
|
"@0x/dev-utils": "^4.2.1",
|
||||||
"@0x/json-schemas": "^5.4.1",
|
"@0x/json-schemas": "^5.4.1",
|
||||||
"@0x/protocol-utils": "^1.4.0",
|
"@0x/protocol-utils": "^1.4.1",
|
||||||
"@0x/quote-server": "^5.0.0",
|
"@0x/quote-server": "^5.0.0",
|
||||||
"@0x/types": "^3.3.1",
|
"@0x/types": "^3.3.1",
|
||||||
"@0x/typescript-typings": "^5.1.6",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
"@0x/contracts-test-utils": "^5.3.24",
|
"@0x/contracts-test-utils": "^5.3.24",
|
||||||
"@0x/contracts-utils": "^4.7.6",
|
"@0x/contracts-utils": "^4.7.6",
|
||||||
"@0x/mesh-rpc-client": "^9.4.2",
|
"@0x/mesh-rpc-client": "^9.4.2",
|
||||||
"@0x/migrations": "^8.0.0",
|
"@0x/migrations": "^8.0.1",
|
||||||
"@0x/sol-compiler": "^4.6.1",
|
"@0x/sol-compiler": "^4.6.1",
|
||||||
"@0x/subproviders": "^6.4.1",
|
"@0x/subproviders": "^6.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
|
@@ -23,6 +23,7 @@ import {
|
|||||||
CalldataInfo,
|
CalldataInfo,
|
||||||
ExchangeProxyContractOpts,
|
ExchangeProxyContractOpts,
|
||||||
MarketBuySwapQuote,
|
MarketBuySwapQuote,
|
||||||
|
MarketOperation,
|
||||||
MarketSellSwapQuote,
|
MarketSellSwapQuote,
|
||||||
SwapQuote,
|
SwapQuote,
|
||||||
SwapQuoteConsumerBase,
|
SwapQuoteConsumerBase,
|
||||||
@@ -43,6 +44,7 @@ import {
|
|||||||
LiquidityProviderFillData,
|
LiquidityProviderFillData,
|
||||||
MooniswapFillData,
|
MooniswapFillData,
|
||||||
OptimizedMarketBridgeOrder,
|
OptimizedMarketBridgeOrder,
|
||||||
|
OptimizedMarketOrder,
|
||||||
UniswapV2FillData,
|
UniswapV2FillData,
|
||||||
} from '../utils/market_operation_utils/types';
|
} from '../utils/market_operation_utils/types';
|
||||||
|
|
||||||
@@ -136,7 +138,10 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
const buyToken = quote.makerToken;
|
const buyToken = quote.makerToken;
|
||||||
|
|
||||||
// Take the bounds from the worst case
|
// Take the bounds from the worst case
|
||||||
const sellAmount = quote.worstCaseQuoteInfo.totalTakerAmount;
|
const sellAmount = BigNumber.max(
|
||||||
|
quote.bestCaseQuoteInfo.totalTakerAmount,
|
||||||
|
quote.worstCaseQuoteInfo.totalTakerAmount,
|
||||||
|
);
|
||||||
let minBuyAmount = quote.worstCaseQuoteInfo.makerAmount;
|
let minBuyAmount = quote.worstCaseQuoteInfo.makerAmount;
|
||||||
let ethAmount = quote.worstCaseQuoteInfo.protocolFeeInWeiAmount;
|
let ethAmount = quote.worstCaseQuoteInfo.protocolFeeInWeiAmount;
|
||||||
|
|
||||||
@@ -144,13 +149,15 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
ethAmount = ethAmount.plus(sellAmount);
|
ethAmount = ethAmount.plus(sellAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const slippedOrders = slipNonNativeOrders(quote);
|
||||||
|
|
||||||
// VIP routes.
|
// VIP routes.
|
||||||
if (
|
if (
|
||||||
this.chainId === ChainId.Mainnet &&
|
this.chainId === ChainId.Mainnet &&
|
||||||
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap])
|
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap])
|
||||||
) {
|
) {
|
||||||
const source = quote.orders[0].source;
|
const source = slippedOrders[0].source;
|
||||||
const fillData = (quote.orders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
|
const fillData = (slippedOrders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._exchangeProxy
|
calldataHexString: this._exchangeProxy
|
||||||
.sellToUniswap(
|
.sellToUniswap(
|
||||||
@@ -183,8 +190,8 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
])
|
])
|
||||||
) {
|
) {
|
||||||
const source = quote.orders[0].source;
|
const source = slippedOrders[0].source;
|
||||||
const fillData = (quote.orders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
|
const fillData = (slippedOrders[0] as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._exchangeProxy
|
calldataHexString: this._exchangeProxy
|
||||||
.sellToPancakeSwap(
|
.sellToPancakeSwap(
|
||||||
@@ -213,7 +220,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
this.chainId === ChainId.Mainnet &&
|
this.chainId === ChainId.Mainnet &&
|
||||||
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.LiquidityProvider])
|
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.LiquidityProvider])
|
||||||
) {
|
) {
|
||||||
const fillData = (quote.orders[0] as OptimizedMarketBridgeOrder<LiquidityProviderFillData>).fillData;
|
const fillData = (slippedOrders[0] as OptimizedMarketBridgeOrder<LiquidityProviderFillData>).fillData;
|
||||||
const target = fillData.poolAddress;
|
const target = fillData.poolAddress;
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._exchangeProxy
|
calldataHexString: this._exchangeProxy
|
||||||
@@ -238,7 +245,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
this.chainId === ChainId.Mainnet &&
|
this.chainId === ChainId.Mainnet &&
|
||||||
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Curve, ERC20BridgeSource.Swerve])
|
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Curve, ERC20BridgeSource.Swerve])
|
||||||
) {
|
) {
|
||||||
const fillData = quote.orders[0].fills[0].fillData as CurveFillData;
|
const fillData = slippedOrders[0].fills[0].fillData as CurveFillData;
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._exchangeProxy
|
calldataHexString: this._exchangeProxy
|
||||||
.sellToLiquidityProvider(
|
.sellToLiquidityProvider(
|
||||||
@@ -267,7 +274,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
this.chainId === ChainId.Mainnet &&
|
this.chainId === ChainId.Mainnet &&
|
||||||
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Mooniswap])
|
isDirectSwapCompatible(quote, optsWithDefaults, [ERC20BridgeSource.Mooniswap])
|
||||||
) {
|
) {
|
||||||
const fillData = quote.orders[0].fills[0].fillData as MooniswapFillData;
|
const fillData = slippedOrders[0].fills[0].fillData as MooniswapFillData;
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._exchangeProxy
|
calldataHexString: this._exchangeProxy
|
||||||
.sellToLiquidityProvider(
|
.sellToLiquidityProvider(
|
||||||
@@ -289,7 +296,7 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
|
|
||||||
if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
|
if (this.chainId === ChainId.Mainnet && isMultiplexBatchFillCompatible(quote, optsWithDefaults)) {
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._encodeMultiplexBatchFillCalldata(quote),
|
calldataHexString: this._encodeMultiplexBatchFillCalldata({ ...quote, orders: slippedOrders }),
|
||||||
ethAmount,
|
ethAmount,
|
||||||
toAddress: this._exchangeProxy.address,
|
toAddress: this._exchangeProxy.address,
|
||||||
allowanceTarget: this._exchangeProxy.address,
|
allowanceTarget: this._exchangeProxy.address,
|
||||||
@@ -298,7 +305,10 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
}
|
}
|
||||||
if (this.chainId === ChainId.Mainnet && isMultiplexMultiHopFillCompatible(quote, optsWithDefaults)) {
|
if (this.chainId === ChainId.Mainnet && isMultiplexMultiHopFillCompatible(quote, optsWithDefaults)) {
|
||||||
return {
|
return {
|
||||||
calldataHexString: this._encodeMultiplexMultiHopFillCalldata(quote, optsWithDefaults),
|
calldataHexString: this._encodeMultiplexMultiHopFillCalldata(
|
||||||
|
{ ...quote, orders: slippedOrders },
|
||||||
|
optsWithDefaults,
|
||||||
|
),
|
||||||
ethAmount,
|
ethAmount,
|
||||||
toAddress: this._exchangeProxy.address,
|
toAddress: this._exchangeProxy.address,
|
||||||
allowanceTarget: this._exchangeProxy.address,
|
allowanceTarget: this._exchangeProxy.address,
|
||||||
@@ -321,10 +331,10 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
|
|
||||||
// If it's two hop we have an intermediate token this is needed to encode the individual FQT
|
// If it's two hop we have an intermediate token this is needed to encode the individual FQT
|
||||||
// and we also want to ensure no dust amount is left in the flash wallet
|
// and we also want to ensure no dust amount is left in the flash wallet
|
||||||
const intermediateToken = quote.isTwoHop ? quote.orders[0].makerToken : NULL_ADDRESS;
|
const intermediateToken = quote.isTwoHop ? slippedOrders[0].makerToken : NULL_ADDRESS;
|
||||||
// This transformer will fill the quote.
|
// This transformer will fill the quote.
|
||||||
if (quote.isTwoHop) {
|
if (quote.isTwoHop) {
|
||||||
const [firstHopOrder, secondHopOrder] = quote.orders;
|
const [firstHopOrder, secondHopOrder] = slippedOrders;
|
||||||
transforms.push({
|
transforms.push({
|
||||||
deploymentNonce: this.transformerNonces.fillQuoteTransformer,
|
deploymentNonce: this.transformerNonces.fillQuoteTransformer,
|
||||||
data: encodeFillQuoteTransformerData({
|
data: encodeFillQuoteTransformerData({
|
||||||
@@ -349,14 +359,13 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const fillAmount = isBuyQuote(quote) ? quote.makerTokenFillAmount : quote.takerTokenFillAmount;
|
const fillAmount = isBuyQuote(quote) ? quote.makerTokenFillAmount : quote.takerTokenFillAmount;
|
||||||
|
|
||||||
transforms.push({
|
transforms.push({
|
||||||
deploymentNonce: this.transformerNonces.fillQuoteTransformer,
|
deploymentNonce: this.transformerNonces.fillQuoteTransformer,
|
||||||
data: encodeFillQuoteTransformerData({
|
data: encodeFillQuoteTransformerData({
|
||||||
side: isBuyQuote(quote) ? FillQuoteTransformerSide.Buy : FillQuoteTransformerSide.Sell,
|
side: isBuyQuote(quote) ? FillQuoteTransformerSide.Buy : FillQuoteTransformerSide.Sell,
|
||||||
sellToken,
|
sellToken,
|
||||||
buyToken,
|
buyToken,
|
||||||
...getFQTTransformerDataFromOptimizedOrders(quote.orders),
|
...getFQTTransformerDataFromOptimizedOrders(slippedOrders),
|
||||||
refundReceiver: refundReceiver || NULL_ADDRESS,
|
refundReceiver: refundReceiver || NULL_ADDRESS,
|
||||||
fillAmount: !isBuyQuote(quote) && shouldSellEntireBalance ? MAX_UINT256 : fillAmount,
|
fillAmount: !isBuyQuote(quote) && shouldSellEntireBalance ? MAX_UINT256 : fillAmount,
|
||||||
}),
|
}),
|
||||||
@@ -598,3 +607,38 @@ export class ExchangeProxySwapQuoteConsumer implements SwapQuoteConsumerBase {
|
|||||||
.getABIEncodedTransactionData();
|
.getABIEncodedTransactionData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function slipNonNativeOrders(quote: MarketSellSwapQuote | MarketBuySwapQuote): OptimizedMarketOrder[] {
|
||||||
|
const slippage = getMaxQuoteSlippageRate(quote);
|
||||||
|
if (!slippage) {
|
||||||
|
return quote.orders;
|
||||||
|
}
|
||||||
|
return quote.orders.map(o => {
|
||||||
|
if (o.source === ERC20BridgeSource.Native) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...o,
|
||||||
|
...(quote.type === MarketOperation.Sell
|
||||||
|
? { makerAmount: o.makerAmount.times(1 - slippage).integerValue(BigNumber.ROUND_DOWN) }
|
||||||
|
: { takerAmount: o.takerAmount.times(1 + slippage).integerValue(BigNumber.ROUND_UP) }),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMaxQuoteSlippageRate(quote: MarketBuySwapQuote | MarketSellSwapQuote): number {
|
||||||
|
if (quote.type === MarketOperation.Buy) {
|
||||||
|
// (worstCaseTaker - bestCaseTaker) / bestCaseTaker
|
||||||
|
// where worstCaseTaker >= bestCaseTaker
|
||||||
|
return quote.worstCaseQuoteInfo.takerAmount
|
||||||
|
.minus(quote.bestCaseQuoteInfo.takerAmount)
|
||||||
|
.div(quote.bestCaseQuoteInfo.takerAmount)
|
||||||
|
.toNumber();
|
||||||
|
}
|
||||||
|
// (bestCaseMaker - worstCaseMaker) / bestCaseMaker
|
||||||
|
// where bestCaseMaker >= worstCaseMaker
|
||||||
|
return quote.bestCaseQuoteInfo.makerAmount
|
||||||
|
.minus(quote.worstCaseQuoteInfo.makerAmount)
|
||||||
|
.div(quote.bestCaseQuoteInfo.makerAmount)
|
||||||
|
.toNumber();
|
||||||
|
}
|
||||||
|
@@ -591,9 +591,10 @@ function calculateTwoHopQuoteInfo(
|
|||||||
: secondHopOrder.makerAmount,
|
: secondHopOrder.makerAmount,
|
||||||
takerAmount: MarketOperation.Sell
|
takerAmount: MarketOperation.Sell
|
||||||
? firstHopOrder.takerAmount
|
? firstHopOrder.takerAmount
|
||||||
: // tslint:disable-next-line: binary-expression-operand-order
|
: firstHopOrder.takerAmount.times(1 + slippage).integerValue(),
|
||||||
firstHopOrder.takerAmount.times(1 + slippage).integerValue(),
|
totalTakerAmount: MarketOperation.Sell
|
||||||
totalTakerAmount: firstHopOrder.takerAmount,
|
? firstHopOrder.takerAmount
|
||||||
|
: firstHopOrder.takerAmount.times(1 + slippage).integerValue(),
|
||||||
feeTakerTokenAmount: constants.ZERO_AMOUNT,
|
feeTakerTokenAmount: constants.ZERO_AMOUNT,
|
||||||
protocolFeeInWeiAmount: constants.ZERO_AMOUNT,
|
protocolFeeInWeiAmount: constants.ZERO_AMOUNT,
|
||||||
gas,
|
gas,
|
||||||
|
@@ -3,11 +3,11 @@ import { SDK } from '@bancor/sdk';
|
|||||||
import { Ethereum } from '@bancor/sdk/dist/blockchains/ethereum';
|
import { Ethereum } from '@bancor/sdk/dist/blockchains/ethereum';
|
||||||
import { BlockchainType } from '@bancor/sdk/dist/types';
|
import { BlockchainType } from '@bancor/sdk/dist/types';
|
||||||
|
|
||||||
import { TOKENS } from './constants';
|
import { MAINNET_TOKENS } from './constants';
|
||||||
|
|
||||||
const findToken = (tokenAddress: string, graph: object): string =>
|
const findToken = (tokenAddress: string, graph: object): string =>
|
||||||
// If we're looking for WETH it is stored by Bancor as the 0xeee address
|
// If we're looking for WETH it is stored by Bancor as the 0xeee address
|
||||||
tokenAddress.toLowerCase() === TOKENS.WETH.toLowerCase()
|
tokenAddress.toLowerCase() === MAINNET_TOKENS.WETH.toLowerCase()
|
||||||
? '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'
|
? '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'
|
||||||
: Object.keys(graph).filter(k => k.toLowerCase() === tokenAddress.toLowerCase())[0];
|
: Object.keys(graph).filter(k => k.toLowerCase() === tokenAddress.toLowerCase())[0];
|
||||||
|
|
||||||
|
@@ -4,19 +4,24 @@ import { BigNumber, NULL_BYTES } from '@0x/utils';
|
|||||||
import {
|
import {
|
||||||
BAKERYSWAP_ROUTER_BY_CHAIN_ID,
|
BAKERYSWAP_ROUTER_BY_CHAIN_ID,
|
||||||
BELT_BSC_INFOS,
|
BELT_BSC_INFOS,
|
||||||
|
COMPONENT_POOLS_BY_CHAIN_ID,
|
||||||
CRYPTO_COM_ROUTER_BY_CHAIN_ID,
|
CRYPTO_COM_ROUTER_BY_CHAIN_ID,
|
||||||
|
CURVE_MAINNET_INFOS,
|
||||||
ELLIPSIS_BSC_INFOS,
|
ELLIPSIS_BSC_INFOS,
|
||||||
KYBER_BRIDGED_LIQUIDITY_PREFIX,
|
KYBER_BRIDGED_LIQUIDITY_PREFIX,
|
||||||
MAINNET_CURVE_INFOS,
|
KYBER_DMM_ROUTER_BY_CHAIN_ID,
|
||||||
MAINNET_SNOWSWAP_INFOS,
|
|
||||||
MAINNET_SWERVE_INFOS,
|
|
||||||
MAX_DODOV2_POOLS_QUERIED,
|
MAX_DODOV2_POOLS_QUERIED,
|
||||||
MAX_KYBER_RESERVES_QUERIED,
|
MAX_KYBER_RESERVES_QUERIED,
|
||||||
NERVE_BSC_INFOS,
|
NERVE_BSC_INFOS,
|
||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
PANCAKESWAP_ROUTER_BY_CHAIN_ID,
|
PANCAKESWAP_ROUTER_BY_CHAIN_ID,
|
||||||
|
SADDLE_MAINNET_INFOS,
|
||||||
SHELL_POOLS_BY_CHAIN_ID,
|
SHELL_POOLS_BY_CHAIN_ID,
|
||||||
|
SMOOTHY_BSC_INFOS,
|
||||||
|
SMOOTHY_MAINNET_INFOS,
|
||||||
|
SNOWSWAP_MAINNET_INFOS,
|
||||||
SUSHISWAP_ROUTER_BY_CHAIN_ID,
|
SUSHISWAP_ROUTER_BY_CHAIN_ID,
|
||||||
|
SWERVE_MAINNET_INFOS,
|
||||||
UNISWAPV2_ROUTER_BY_CHAIN_ID,
|
UNISWAPV2_ROUTER_BY_CHAIN_ID,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { CurveInfo, ERC20BridgeSource } from './types';
|
import { CurveInfo, ERC20BridgeSource } from './types';
|
||||||
@@ -60,12 +65,22 @@ export function getShellsForPair(chainId: ChainId, takerToken: string, makerToke
|
|||||||
.map(i => i.poolAddress);
|
.map(i => i.poolAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable completed-docs
|
||||||
|
export function getComponentForPair(chainId: ChainId, takerToken: string, makerToken: string): string[] {
|
||||||
|
if (chainId !== ChainId.Mainnet) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return Object.values(COMPONENT_POOLS_BY_CHAIN_ID[chainId])
|
||||||
|
.filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t)))
|
||||||
|
.map(i => i.poolAddress);
|
||||||
|
}
|
||||||
|
|
||||||
// tslint:disable completed-docs
|
// tslint:disable completed-docs
|
||||||
export function getCurveInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
|
export function getCurveInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
|
||||||
if (chainId !== ChainId.Mainnet) {
|
if (chainId !== ChainId.Mainnet) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return Object.values(MAINNET_CURVE_INFOS).filter(c =>
|
return Object.values(CURVE_MAINNET_INFOS).filter(c =>
|
||||||
[makerToken, takerToken].every(
|
[makerToken, takerToken].every(
|
||||||
t =>
|
t =>
|
||||||
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||||
@@ -78,7 +93,7 @@ export function getSwerveInfosForPair(chainId: ChainId, takerToken: string, make
|
|||||||
if (chainId !== ChainId.Mainnet) {
|
if (chainId !== ChainId.Mainnet) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return Object.values(MAINNET_SWERVE_INFOS).filter(c =>
|
return Object.values(SWERVE_MAINNET_INFOS).filter(c =>
|
||||||
[makerToken, takerToken].every(
|
[makerToken, takerToken].every(
|
||||||
t =>
|
t =>
|
||||||
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||||
@@ -91,7 +106,7 @@ export function getSnowSwapInfosForPair(chainId: ChainId, takerToken: string, ma
|
|||||||
if (chainId !== ChainId.Mainnet) {
|
if (chainId !== ChainId.Mainnet) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return Object.values(MAINNET_SNOWSWAP_INFOS).filter(c =>
|
return Object.values(SNOWSWAP_MAINNET_INFOS).filter(c =>
|
||||||
[makerToken, takerToken].every(
|
[makerToken, takerToken].every(
|
||||||
t =>
|
t =>
|
||||||
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||||
@@ -139,6 +154,61 @@ export function getEllipsisInfosForPair(chainId: ChainId, takerToken: string, ma
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSmoothyInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
|
||||||
|
if (chainId === ChainId.BSC) {
|
||||||
|
return Object.values(SMOOTHY_BSC_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
c.metaToken !== undefined &&
|
||||||
|
[makerToken, takerToken].includes(c.metaToken)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (chainId === ChainId.Mainnet) {
|
||||||
|
return Object.values(SMOOTHY_MAINNET_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
c.metaToken !== undefined &&
|
||||||
|
[makerToken, takerToken].includes(c.metaToken)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSaddleInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
|
||||||
|
if (chainId !== ChainId.Mainnet) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return Object.values(SADDLE_MAINNET_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaToken === undefined) ||
|
||||||
|
(c.tokens.includes(t) && c.metaToken !== undefined && [makerToken, takerToken].includes(c.metaToken)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getShellLikeInfosForPair(
|
||||||
|
chainId: ChainId,
|
||||||
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
source: ERC20BridgeSource.Shell | ERC20BridgeSource.Component,
|
||||||
|
): string[] {
|
||||||
|
switch (source) {
|
||||||
|
case ERC20BridgeSource.Shell:
|
||||||
|
return getShellsForPair(chainId, takerToken, makerToken);
|
||||||
|
case ERC20BridgeSource.Component:
|
||||||
|
return getComponentForPair(chainId, takerToken, makerToken);
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown Shell like source ${source}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getCurveLikeInfosForPair(
|
export function getCurveLikeInfosForPair(
|
||||||
chainId: ChainId,
|
chainId: ChainId,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
@@ -149,7 +219,9 @@ export function getCurveLikeInfosForPair(
|
|||||||
| ERC20BridgeSource.SnowSwap
|
| ERC20BridgeSource.SnowSwap
|
||||||
| ERC20BridgeSource.Nerve
|
| ERC20BridgeSource.Nerve
|
||||||
| ERC20BridgeSource.Belt
|
| ERC20BridgeSource.Belt
|
||||||
| ERC20BridgeSource.Ellipsis,
|
| ERC20BridgeSource.Ellipsis
|
||||||
|
| ERC20BridgeSource.Smoothy
|
||||||
|
| ERC20BridgeSource.Saddle,
|
||||||
): CurveInfo[] {
|
): CurveInfo[] {
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case ERC20BridgeSource.Curve:
|
case ERC20BridgeSource.Curve:
|
||||||
@@ -164,6 +236,10 @@ export function getCurveLikeInfosForPair(
|
|||||||
return getBeltInfosForPair(chainId, takerToken, makerToken);
|
return getBeltInfosForPair(chainId, takerToken, makerToken);
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
return getEllipsisInfosForPair(chainId, takerToken, makerToken);
|
return getEllipsisInfosForPair(chainId, takerToken, makerToken);
|
||||||
|
case ERC20BridgeSource.Smoothy:
|
||||||
|
return getSmoothyInfosForPair(chainId, takerToken, makerToken);
|
||||||
|
case ERC20BridgeSource.Saddle:
|
||||||
|
return getSaddleInfosForPair(chainId, takerToken, makerToken);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown Curve like source ${source}`);
|
throw new Error(`Unknown Curve like source ${source}`);
|
||||||
}
|
}
|
||||||
@@ -176,7 +252,8 @@ export function uniswapV2LikeRouterAddress(
|
|||||||
| ERC20BridgeSource.SushiSwap
|
| ERC20BridgeSource.SushiSwap
|
||||||
| ERC20BridgeSource.CryptoCom
|
| ERC20BridgeSource.CryptoCom
|
||||||
| ERC20BridgeSource.PancakeSwap
|
| ERC20BridgeSource.PancakeSwap
|
||||||
| ERC20BridgeSource.BakerySwap,
|
| ERC20BridgeSource.BakerySwap
|
||||||
|
| ERC20BridgeSource.KyberDmm,
|
||||||
): string {
|
): string {
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case ERC20BridgeSource.UniswapV2:
|
case ERC20BridgeSource.UniswapV2:
|
||||||
@@ -189,6 +266,8 @@ export function uniswapV2LikeRouterAddress(
|
|||||||
return PANCAKESWAP_ROUTER_BY_CHAIN_ID[chainId];
|
return PANCAKESWAP_ROUTER_BY_CHAIN_ID[chainId];
|
||||||
case ERC20BridgeSource.BakerySwap:
|
case ERC20BridgeSource.BakerySwap:
|
||||||
return BAKERYSWAP_ROUTER_BY_CHAIN_ID[chainId];
|
return BAKERYSWAP_ROUTER_BY_CHAIN_ID[chainId];
|
||||||
|
case ERC20BridgeSource.KyberDmm:
|
||||||
|
return KYBER_DMM_ROUTER_BY_CHAIN_ID[chainId];
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown UniswapV2 like source ${source}`);
|
throw new Error(`Unknown UniswapV2 like source ${source}`);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,22 @@ export function getLiquidityProvidersForPair(
|
|||||||
registry: LiquidityProviderRegistry,
|
registry: LiquidityProviderRegistry,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
makerToken: string,
|
makerToken: string,
|
||||||
): string[] {
|
): Array<{ providerAddress: string; gasCost: number }> {
|
||||||
return Object.entries(registry)
|
return Object.entries(registry)
|
||||||
.filter(([, plp]) => [makerToken, takerToken].every(t => plp.tokens.includes(t)))
|
.filter(([, plp]) => [makerToken, takerToken].every(t => plp.tokens.includes(t)))
|
||||||
.map(([providerAddress]) => providerAddress);
|
.map(([providerAddress]) => {
|
||||||
|
let gasCost: number;
|
||||||
|
if (typeof registry[providerAddress].gasCost === 'number') {
|
||||||
|
gasCost = registry[providerAddress].gasCost as number;
|
||||||
|
} else {
|
||||||
|
gasCost = (registry[providerAddress].gasCost as (takerToken: string, makerToken: string) => number)(
|
||||||
|
takerToken,
|
||||||
|
makerToken,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
providerAddress,
|
||||||
|
gasCost,
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@@ -89,6 +89,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
|
|||||||
return encodeBridgeSourceId(BridgeProtocol.Dodo, 'Dodo');
|
return encodeBridgeSourceId(BridgeProtocol.Dodo, 'Dodo');
|
||||||
case ERC20BridgeSource.Kyber:
|
case ERC20BridgeSource.Kyber:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.Kyber, 'Kyber');
|
return encodeBridgeSourceId(BridgeProtocol.Kyber, 'Kyber');
|
||||||
|
case ERC20BridgeSource.KyberDmm:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'KyberDmm');
|
||||||
case ERC20BridgeSource.LiquidityProvider:
|
case ERC20BridgeSource.LiquidityProvider:
|
||||||
// "LiquidityProvider" is too long to encode (17 characters).
|
// "LiquidityProvider" is too long to encode (17 characters).
|
||||||
return encodeBridgeSourceId(BridgeProtocol.Unknown, 'LP');
|
return encodeBridgeSourceId(BridgeProtocol.Unknown, 'LP');
|
||||||
@@ -126,6 +128,12 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
|
|||||||
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Belt');
|
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Belt');
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Ellipsis');
|
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Ellipsis');
|
||||||
|
case ERC20BridgeSource.Component:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.Shell, 'Component');
|
||||||
|
case ERC20BridgeSource.Smoothy:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Smoothy');
|
||||||
|
case ERC20BridgeSource.Saddle:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.Nerve, 'Saddle');
|
||||||
default:
|
default:
|
||||||
throw new Error(AggregationError.NoBridgeForSource);
|
throw new Error(AggregationError.NoBridgeForSource);
|
||||||
}
|
}
|
||||||
@@ -153,6 +161,8 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
|
case ERC20BridgeSource.Smoothy:
|
||||||
|
case ERC20BridgeSource.Saddle:
|
||||||
const curveFillData = (order as OptimizedMarketBridgeOrder<CurveFillData>).fillData;
|
const curveFillData = (order as OptimizedMarketBridgeOrder<CurveFillData>).fillData;
|
||||||
bridgeData = encoder.encode([
|
bridgeData = encoder.encode([
|
||||||
curveFillData.pool.poolAddress,
|
curveFillData.pool.poolAddress,
|
||||||
@@ -176,6 +186,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
case ERC20BridgeSource.Linkswap:
|
case ERC20BridgeSource.Linkswap:
|
||||||
case ERC20BridgeSource.PancakeSwap:
|
case ERC20BridgeSource.PancakeSwap:
|
||||||
case ERC20BridgeSource.BakerySwap:
|
case ERC20BridgeSource.BakerySwap:
|
||||||
|
case ERC20BridgeSource.KyberDmm:
|
||||||
const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
|
const uniswapV2FillData = (order as OptimizedMarketBridgeOrder<UniswapV2FillData>).fillData;
|
||||||
bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]);
|
bridgeData = encoder.encode([uniswapV2FillData.router, uniswapV2FillData.tokenAddressPath]);
|
||||||
break;
|
break;
|
||||||
@@ -200,6 +211,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
bridgeData = encoder.encode([dodoV2FillData.poolAddress, dodoV2FillData.isSellBase]);
|
bridgeData = encoder.encode([dodoV2FillData.poolAddress, dodoV2FillData.isSellBase]);
|
||||||
break;
|
break;
|
||||||
case ERC20BridgeSource.Shell:
|
case ERC20BridgeSource.Shell:
|
||||||
|
case ERC20BridgeSource.Component:
|
||||||
const shellFillData = (order as OptimizedMarketBridgeOrder<ShellFillData>).fillData;
|
const shellFillData = (order as OptimizedMarketBridgeOrder<ShellFillData>).fillData;
|
||||||
bridgeData = encoder.encode([shellFillData.poolAddress]);
|
bridgeData = encoder.encode([shellFillData.poolAddress]);
|
||||||
break;
|
break;
|
||||||
@@ -299,14 +311,18 @@ export const BRIDGE_ENCODERS: {
|
|||||||
[ERC20BridgeSource.Nerve]: curveEncoder,
|
[ERC20BridgeSource.Nerve]: curveEncoder,
|
||||||
[ERC20BridgeSource.Belt]: curveEncoder,
|
[ERC20BridgeSource.Belt]: curveEncoder,
|
||||||
[ERC20BridgeSource.Ellipsis]: curveEncoder,
|
[ERC20BridgeSource.Ellipsis]: curveEncoder,
|
||||||
|
[ERC20BridgeSource.Smoothy]: curveEncoder,
|
||||||
|
[ERC20BridgeSource.Saddle]: curveEncoder,
|
||||||
// UniswapV2 like, (router, address[])
|
// UniswapV2 like, (router, address[])
|
||||||
[ERC20BridgeSource.Bancor]: routerAddressPathEncoder,
|
[ERC20BridgeSource.Bancor]: routerAddressPathEncoder,
|
||||||
[ERC20BridgeSource.UniswapV2]: routerAddressPathEncoder,
|
[ERC20BridgeSource.UniswapV2]: routerAddressPathEncoder,
|
||||||
[ERC20BridgeSource.SushiSwap]: routerAddressPathEncoder,
|
[ERC20BridgeSource.SushiSwap]: routerAddressPathEncoder,
|
||||||
[ERC20BridgeSource.CryptoCom]: routerAddressPathEncoder,
|
[ERC20BridgeSource.CryptoCom]: routerAddressPathEncoder,
|
||||||
[ERC20BridgeSource.Linkswap]: routerAddressPathEncoder,
|
[ERC20BridgeSource.Linkswap]: routerAddressPathEncoder,
|
||||||
|
[ERC20BridgeSource.KyberDmm]: routerAddressPathEncoder,
|
||||||
// Generic pools
|
// Generic pools
|
||||||
[ERC20BridgeSource.Shell]: poolEncoder,
|
[ERC20BridgeSource.Shell]: poolEncoder,
|
||||||
|
[ERC20BridgeSource.Component]: poolEncoder,
|
||||||
[ERC20BridgeSource.Mooniswap]: poolEncoder,
|
[ERC20BridgeSource.Mooniswap]: poolEncoder,
|
||||||
[ERC20BridgeSource.Eth2Dai]: poolEncoder,
|
[ERC20BridgeSource.Eth2Dai]: poolEncoder,
|
||||||
[ERC20BridgeSource.MStable]: poolEncoder,
|
[ERC20BridgeSource.MStable]: poolEncoder,
|
||||||
|
@@ -12,7 +12,7 @@ import {
|
|||||||
getCurveLikeInfosForPair,
|
getCurveLikeInfosForPair,
|
||||||
getDodoV2Offsets,
|
getDodoV2Offsets,
|
||||||
getKyberOffsets,
|
getKyberOffsets,
|
||||||
getShellsForPair,
|
getShellLikeInfosForPair,
|
||||||
isAllowedKyberReserveId,
|
isAllowedKyberReserveId,
|
||||||
isBadTokenForSource,
|
isBadTokenForSource,
|
||||||
isValidAddress,
|
isValidAddress,
|
||||||
@@ -24,7 +24,8 @@ import {
|
|||||||
DODOV2_FACTORIES_BY_CHAIN_ID,
|
DODOV2_FACTORIES_BY_CHAIN_ID,
|
||||||
KYBER_CONFIG_BY_CHAIN_ID,
|
KYBER_CONFIG_BY_CHAIN_ID,
|
||||||
LINKSWAP_ROUTER_BY_CHAIN_ID,
|
LINKSWAP_ROUTER_BY_CHAIN_ID,
|
||||||
LIQUIDITY_PROVIDER_REGISTRY,
|
LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID,
|
||||||
|
MAINNET_TOKENS,
|
||||||
MAKER_PSM_INFO_BY_CHAIN_ID,
|
MAKER_PSM_INFO_BY_CHAIN_ID,
|
||||||
MAX_UINT256,
|
MAX_UINT256,
|
||||||
MOONISWAP_REGISTRIES_BY_CHAIN_ID,
|
MOONISWAP_REGISTRIES_BY_CHAIN_ID,
|
||||||
@@ -34,7 +35,6 @@ import {
|
|||||||
NULL_BYTES,
|
NULL_BYTES,
|
||||||
OASIS_ROUTER_BY_CHAIN_ID,
|
OASIS_ROUTER_BY_CHAIN_ID,
|
||||||
SELL_SOURCE_FILTER_BY_CHAIN_ID,
|
SELL_SOURCE_FILTER_BY_CHAIN_ID,
|
||||||
TOKENS,
|
|
||||||
UNISWAPV1_ROUTER_BY_CHAIN_ID,
|
UNISWAPV1_ROUTER_BY_CHAIN_ID,
|
||||||
ZERO_AMOUNT,
|
ZERO_AMOUNT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
@@ -87,6 +87,7 @@ export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSour
|
|||||||
* for use with `DexOrderSampler.executeAsync()`.
|
* for use with `DexOrderSampler.executeAsync()`.
|
||||||
*/
|
*/
|
||||||
export class SamplerOperations {
|
export class SamplerOperations {
|
||||||
|
public readonly liquidityProviderRegistry: LiquidityProviderRegistry;
|
||||||
protected _bancorService?: BancorService;
|
protected _bancorService?: BancorService;
|
||||||
public static constant<T>(result: T): BatchedOperation<T> {
|
public static constant<T>(result: T): BatchedOperation<T> {
|
||||||
return {
|
return {
|
||||||
@@ -102,9 +103,13 @@ export class SamplerOperations {
|
|||||||
public readonly balancerPoolsCache: BalancerPoolsCache = new BalancerPoolsCache(),
|
public readonly balancerPoolsCache: BalancerPoolsCache = new BalancerPoolsCache(),
|
||||||
public readonly creamPoolsCache: CreamPoolsCache = new CreamPoolsCache(),
|
public readonly creamPoolsCache: CreamPoolsCache = new CreamPoolsCache(),
|
||||||
protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [] },
|
protected readonly tokenAdjacencyGraph: TokenAdjacencyGraph = { default: [] },
|
||||||
public readonly liquidityProviderRegistry: LiquidityProviderRegistry = LIQUIDITY_PROVIDER_REGISTRY,
|
liquidityProviderRegistry: LiquidityProviderRegistry = {},
|
||||||
bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
|
bancorServiceFn: () => Promise<BancorService | undefined> = async () => undefined,
|
||||||
) {
|
) {
|
||||||
|
this.liquidityProviderRegistry = {
|
||||||
|
...LIQUIDITY_PROVIDER_REGISTRY_BY_CHAIN_ID[chainId],
|
||||||
|
...liquidityProviderRegistry,
|
||||||
|
};
|
||||||
// Initialize the Bancor service, fetching paths in the background
|
// Initialize the Bancor service, fetching paths in the background
|
||||||
bancorServiceFn()
|
bancorServiceFn()
|
||||||
.then(service => (this._bancorService = service))
|
.then(service => (this._bancorService = service))
|
||||||
@@ -277,12 +282,13 @@ export class SamplerOperations {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
takerFillAmounts: BigNumber[],
|
takerFillAmounts: BigNumber[],
|
||||||
|
gasCost: number,
|
||||||
): SourceQuoteOperation<LiquidityProviderFillData> {
|
): SourceQuoteOperation<LiquidityProviderFillData> {
|
||||||
return new SamplerContractOperation({
|
return new SamplerContractOperation({
|
||||||
source: ERC20BridgeSource.LiquidityProvider,
|
source: ERC20BridgeSource.LiquidityProvider,
|
||||||
fillData: {
|
fillData: {
|
||||||
poolAddress: providerAddress,
|
poolAddress: providerAddress,
|
||||||
gasCost: this.liquidityProviderRegistry[providerAddress].gasCost,
|
gasCost,
|
||||||
},
|
},
|
||||||
contract: this._samplerContract,
|
contract: this._samplerContract,
|
||||||
function: this._samplerContract.sampleSellsFromLiquidityProvider,
|
function: this._samplerContract.sampleSellsFromLiquidityProvider,
|
||||||
@@ -295,12 +301,13 @@ export class SamplerOperations {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
makerFillAmounts: BigNumber[],
|
makerFillAmounts: BigNumber[],
|
||||||
|
gasCost: number,
|
||||||
): SourceQuoteOperation<LiquidityProviderFillData> {
|
): SourceQuoteOperation<LiquidityProviderFillData> {
|
||||||
return new SamplerContractOperation({
|
return new SamplerContractOperation({
|
||||||
source: ERC20BridgeSource.LiquidityProvider,
|
source: ERC20BridgeSource.LiquidityProvider,
|
||||||
fillData: {
|
fillData: {
|
||||||
poolAddress: providerAddress,
|
poolAddress: providerAddress,
|
||||||
gasCost: this.liquidityProviderRegistry[providerAddress].gasCost,
|
gasCost,
|
||||||
},
|
},
|
||||||
contract: this._samplerContract,
|
contract: this._samplerContract,
|
||||||
function: this._samplerContract.sampleBuysFromLiquidityProvider,
|
function: this._samplerContract.sampleBuysFromLiquidityProvider,
|
||||||
@@ -396,6 +403,62 @@ export class SamplerOperations {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSmoothySellQuotes(
|
||||||
|
pool: CurveInfo,
|
||||||
|
fromTokenIdx: number,
|
||||||
|
toTokenIdx: number,
|
||||||
|
takerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<CurveFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Smoothy,
|
||||||
|
fillData: {
|
||||||
|
pool,
|
||||||
|
fromTokenIdx,
|
||||||
|
toTokenIdx,
|
||||||
|
},
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleSellsFromSmoothy,
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
poolAddress: pool.poolAddress,
|
||||||
|
sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector,
|
||||||
|
buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector,
|
||||||
|
},
|
||||||
|
new BigNumber(fromTokenIdx),
|
||||||
|
new BigNumber(toTokenIdx),
|
||||||
|
takerFillAmounts,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSmoothyBuyQuotes(
|
||||||
|
pool: CurveInfo,
|
||||||
|
fromTokenIdx: number,
|
||||||
|
toTokenIdx: number,
|
||||||
|
makerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<CurveFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Smoothy,
|
||||||
|
fillData: {
|
||||||
|
pool,
|
||||||
|
fromTokenIdx,
|
||||||
|
toTokenIdx,
|
||||||
|
},
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleBuysFromSmoothy,
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
poolAddress: pool.poolAddress,
|
||||||
|
sellQuoteFunctionSelector: pool.sellQuoteFunctionSelector,
|
||||||
|
buyQuoteFunctionSelector: pool.buyQuoteFunctionSelector,
|
||||||
|
},
|
||||||
|
new BigNumber(fromTokenIdx),
|
||||||
|
new BigNumber(toTokenIdx),
|
||||||
|
makerFillAmounts,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public getBalancerSellQuotes(
|
public getBalancerSellQuotes(
|
||||||
poolAddress: string,
|
poolAddress: string,
|
||||||
makerToken: string,
|
makerToken: string,
|
||||||
@@ -743,9 +806,10 @@ export class SamplerOperations {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
takerFillAmounts: BigNumber[],
|
takerFillAmounts: BigNumber[],
|
||||||
|
source: ERC20BridgeSource = ERC20BridgeSource.Shell,
|
||||||
): SourceQuoteOperation<ShellFillData> {
|
): SourceQuoteOperation<ShellFillData> {
|
||||||
return new SamplerContractOperation({
|
return new SamplerContractOperation({
|
||||||
source: ERC20BridgeSource.Shell,
|
source,
|
||||||
fillData: { poolAddress },
|
fillData: { poolAddress },
|
||||||
contract: this._samplerContract,
|
contract: this._samplerContract,
|
||||||
function: this._samplerContract.sampleSellsFromShell,
|
function: this._samplerContract.sampleSellsFromShell,
|
||||||
@@ -758,9 +822,10 @@ export class SamplerOperations {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
makerFillAmounts: BigNumber[],
|
makerFillAmounts: BigNumber[],
|
||||||
|
source: ERC20BridgeSource = ERC20BridgeSource.Shell,
|
||||||
): SourceQuoteOperation {
|
): SourceQuoteOperation {
|
||||||
return new SamplerContractOperation({
|
return new SamplerContractOperation({
|
||||||
source: ERC20BridgeSource.Shell,
|
source,
|
||||||
fillData: { poolAddress },
|
fillData: { poolAddress },
|
||||||
contract: this._samplerContract,
|
contract: this._samplerContract,
|
||||||
function: this._samplerContract.sampleBuysFromShell,
|
function: this._samplerContract.sampleBuysFromShell,
|
||||||
@@ -1022,6 +1087,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.CryptoCom:
|
case ERC20BridgeSource.CryptoCom:
|
||||||
case ERC20BridgeSource.PancakeSwap:
|
case ERC20BridgeSource.PancakeSwap:
|
||||||
case ERC20BridgeSource.BakerySwap:
|
case ERC20BridgeSource.BakerySwap:
|
||||||
|
case ERC20BridgeSource.KyberDmm:
|
||||||
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
||||||
if (!isValidAddress(uniLikeRouter)) {
|
if (!isValidAddress(uniLikeRouter)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -1046,6 +1112,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
|
case ERC20BridgeSource.Saddle:
|
||||||
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
||||||
this.getCurveSellQuotes(
|
this.getCurveSellQuotes(
|
||||||
pool,
|
pool,
|
||||||
@@ -1055,13 +1122,33 @@ export class SamplerOperations {
|
|||||||
source,
|
source,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case ERC20BridgeSource.Smoothy:
|
||||||
|
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
||||||
|
this.getSmoothySellQuotes(
|
||||||
|
pool,
|
||||||
|
pool.tokens.indexOf(takerToken),
|
||||||
|
pool.tokens.indexOf(makerToken),
|
||||||
|
takerFillAmounts,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case ERC20BridgeSource.Shell:
|
||||||
|
case ERC20BridgeSource.Component:
|
||||||
|
return getShellLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
||||||
|
this.getShellSellQuotes(pool, makerToken, takerToken, takerFillAmounts, source),
|
||||||
|
);
|
||||||
case ERC20BridgeSource.LiquidityProvider:
|
case ERC20BridgeSource.LiquidityProvider:
|
||||||
return getLiquidityProvidersForPair(
|
return getLiquidityProvidersForPair(
|
||||||
this.liquidityProviderRegistry,
|
this.liquidityProviderRegistry,
|
||||||
takerToken,
|
takerToken,
|
||||||
makerToken,
|
makerToken,
|
||||||
).map(pool =>
|
).map(({ providerAddress, gasCost }) =>
|
||||||
this.getLiquidityProviderSellQuotes(pool, makerToken, takerToken, takerFillAmounts),
|
this.getLiquidityProviderSellQuotes(
|
||||||
|
providerAddress,
|
||||||
|
makerToken,
|
||||||
|
takerToken,
|
||||||
|
takerFillAmounts,
|
||||||
|
gasCost,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
case ERC20BridgeSource.MStable:
|
case ERC20BridgeSource.MStable:
|
||||||
return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId])
|
return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId])
|
||||||
@@ -1104,10 +1191,6 @@ export class SamplerOperations {
|
|||||||
ERC20BridgeSource.Cream,
|
ERC20BridgeSource.Cream,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
case ERC20BridgeSource.Shell:
|
|
||||||
return getShellsForPair(this.chainId, takerToken, makerToken).map(pool =>
|
|
||||||
this.getShellSellQuotes(pool, makerToken, takerToken, takerFillAmounts),
|
|
||||||
);
|
|
||||||
case ERC20BridgeSource.Dodo:
|
case ERC20BridgeSource.Dodo:
|
||||||
if (!isValidAddress(DODO_CONFIG_BY_CHAIN_ID[this.chainId].registry)) {
|
if (!isValidAddress(DODO_CONFIG_BY_CHAIN_ID[this.chainId].registry)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -1151,7 +1234,7 @@ export class SamplerOperations {
|
|||||||
return [
|
return [
|
||||||
[takerToken, makerToken],
|
[takerToken, makerToken],
|
||||||
...getIntermediateTokens(makerToken, takerToken, {
|
...getIntermediateTokens(makerToken, takerToken, {
|
||||||
default: [TOKENS.LINK, TOKENS.WETH],
|
default: [MAINNET_TOKENS.LINK, MAINNET_TOKENS.WETH],
|
||||||
}).map(t => [takerToken, t, makerToken]),
|
}).map(t => [takerToken, t, makerToken]),
|
||||||
].map(path =>
|
].map(path =>
|
||||||
this.getUniswapV2SellQuotes(
|
this.getUniswapV2SellQuotes(
|
||||||
@@ -1213,6 +1296,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.CryptoCom:
|
case ERC20BridgeSource.CryptoCom:
|
||||||
case ERC20BridgeSource.PancakeSwap:
|
case ERC20BridgeSource.PancakeSwap:
|
||||||
case ERC20BridgeSource.BakerySwap:
|
case ERC20BridgeSource.BakerySwap:
|
||||||
|
case ERC20BridgeSource.KyberDmm:
|
||||||
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
||||||
if (!isValidAddress(uniLikeRouter)) {
|
if (!isValidAddress(uniLikeRouter)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -1237,6 +1321,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
|
case ERC20BridgeSource.Saddle:
|
||||||
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
||||||
this.getCurveBuyQuotes(
|
this.getCurveBuyQuotes(
|
||||||
pool,
|
pool,
|
||||||
@@ -1246,13 +1331,33 @@ export class SamplerOperations {
|
|||||||
source,
|
source,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case ERC20BridgeSource.Smoothy:
|
||||||
|
return getCurveLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
||||||
|
this.getSmoothyBuyQuotes(
|
||||||
|
pool,
|
||||||
|
pool.tokens.indexOf(takerToken),
|
||||||
|
pool.tokens.indexOf(makerToken),
|
||||||
|
makerFillAmounts,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case ERC20BridgeSource.Shell:
|
||||||
|
case ERC20BridgeSource.Component:
|
||||||
|
return getShellLikeInfosForPair(this.chainId, takerToken, makerToken, source).map(pool =>
|
||||||
|
this.getShellBuyQuotes(pool, makerToken, takerToken, makerFillAmounts, source),
|
||||||
|
);
|
||||||
case ERC20BridgeSource.LiquidityProvider:
|
case ERC20BridgeSource.LiquidityProvider:
|
||||||
return getLiquidityProvidersForPair(
|
return getLiquidityProvidersForPair(
|
||||||
this.liquidityProviderRegistry,
|
this.liquidityProviderRegistry,
|
||||||
takerToken,
|
takerToken,
|
||||||
makerToken,
|
makerToken,
|
||||||
).map(pool =>
|
).map(({ providerAddress, gasCost }) =>
|
||||||
this.getLiquidityProviderBuyQuotes(pool, makerToken, takerToken, makerFillAmounts),
|
this.getLiquidityProviderBuyQuotes(
|
||||||
|
providerAddress,
|
||||||
|
makerToken,
|
||||||
|
takerToken,
|
||||||
|
makerFillAmounts,
|
||||||
|
gasCost,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
case ERC20BridgeSource.MStable:
|
case ERC20BridgeSource.MStable:
|
||||||
return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId])
|
return isValidAddress(MSTABLE_ROUTER_BY_CHAIN_ID[this.chainId])
|
||||||
@@ -1295,10 +1400,6 @@ export class SamplerOperations {
|
|||||||
ERC20BridgeSource.Cream,
|
ERC20BridgeSource.Cream,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
case ERC20BridgeSource.Shell:
|
|
||||||
return getShellsForPair(this.chainId, takerToken, makerToken).map(pool =>
|
|
||||||
this.getShellBuyQuotes(pool, makerToken, takerToken, makerFillAmounts),
|
|
||||||
);
|
|
||||||
case ERC20BridgeSource.Dodo:
|
case ERC20BridgeSource.Dodo:
|
||||||
if (!isValidAddress(DODO_CONFIG_BY_CHAIN_ID[this.chainId].registry)) {
|
if (!isValidAddress(DODO_CONFIG_BY_CHAIN_ID[this.chainId].registry)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -1337,7 +1438,7 @@ export class SamplerOperations {
|
|||||||
[takerToken, makerToken],
|
[takerToken, makerToken],
|
||||||
// LINK is the base asset in many of the pools on Linkswap
|
// LINK is the base asset in many of the pools on Linkswap
|
||||||
...getIntermediateTokens(makerToken, takerToken, {
|
...getIntermediateTokens(makerToken, takerToken, {
|
||||||
default: [TOKENS.LINK, TOKENS.WETH],
|
default: [MAINNET_TOKENS.LINK, MAINNET_TOKENS.WETH],
|
||||||
}).map(t => [takerToken, t, makerToken]),
|
}).map(t => [takerToken, t, makerToken]),
|
||||||
].map(path =>
|
].map(path =>
|
||||||
this.getUniswapV2BuyQuotes(
|
this.getUniswapV2BuyQuotes(
|
||||||
|
@@ -59,7 +59,11 @@ export enum ERC20BridgeSource {
|
|||||||
DodoV2 = 'DODO_V2',
|
DodoV2 = 'DODO_V2',
|
||||||
CryptoCom = 'CryptoCom',
|
CryptoCom = 'CryptoCom',
|
||||||
Linkswap = 'Linkswap',
|
Linkswap = 'Linkswap',
|
||||||
// Other
|
KyberDmm = 'KyberDMM',
|
||||||
|
Smoothy = 'Smoothy',
|
||||||
|
Component = 'Component',
|
||||||
|
Saddle = 'Saddle',
|
||||||
|
// BSC only
|
||||||
PancakeSwap = 'PancakeSwap',
|
PancakeSwap = 'PancakeSwap',
|
||||||
BakerySwap = 'BakerySwap',
|
BakerySwap = 'BakerySwap',
|
||||||
Nerve = 'Nerve',
|
Nerve = 'Nerve',
|
||||||
@@ -79,9 +83,12 @@ export enum CurveFunctionSelectors {
|
|||||||
get_dx_underlying = '0x0e71d1b9',
|
get_dx_underlying = '0x0e71d1b9',
|
||||||
get_dy = '0x5e0d443f',
|
get_dy = '0x5e0d443f',
|
||||||
get_dx = '0x67df02ca',
|
get_dx = '0x67df02ca',
|
||||||
// Nerve BSC
|
// Smoothy
|
||||||
swap = '0x91695586',
|
swap_uint256 = '0x5673b02d', // swap(uint256,uint256,uint256,uint256)
|
||||||
calculateSwap = '0xa95b089f',
|
get_swap_amount = '0x45cf2ef6', // getSwapAmount(uint256,uint256,uint256)
|
||||||
|
// Nerve BSC, Saddle Mainnet
|
||||||
|
swap = '0x91695586', // swap(uint8,uint8,uint256,uint256,uint256)
|
||||||
|
calculateSwap = '0xa95b089f', // calculateSwap(uint8,uint8,uint256)
|
||||||
}
|
}
|
||||||
// tslint:enable: enum-naming
|
// tslint:enable: enum-naming
|
||||||
|
|
||||||
@@ -95,6 +102,7 @@ export interface CurveInfo {
|
|||||||
poolAddress: string;
|
poolAddress: string;
|
||||||
tokens: string[];
|
tokens: string[];
|
||||||
metaToken: string | undefined;
|
metaToken: string | undefined;
|
||||||
|
gasSchedule: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -439,7 +447,7 @@ export interface TokenAdjacencyGraph {
|
|||||||
export interface LiquidityProviderRegistry {
|
export interface LiquidityProviderRegistry {
|
||||||
[address: string]: {
|
[address: string]: {
|
||||||
tokens: string[];
|
tokens: string[];
|
||||||
gasCost: number;
|
gasCost: number | ((takerToken: string, makerToken: string) => number);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -129,11 +129,10 @@ export function simulateWorstCaseFill(quoteInfo: QuoteFillInfo): QuoteFillResult
|
|||||||
};
|
};
|
||||||
// Adjust the output by 1-slippage for the worst case if it is a sell
|
// Adjust the output by 1-slippage for the worst case if it is a sell
|
||||||
// Adjust the output by 1+slippage for the worst case if it is a buy
|
// Adjust the output by 1+slippage for the worst case if it is a buy
|
||||||
const outputMultiplier =
|
result.output =
|
||||||
quoteInfo.side === MarketOperation.Sell
|
quoteInfo.side === MarketOperation.Sell
|
||||||
? new BigNumber(1).minus(opts.slippage)
|
? result.output.times(1 - opts.slippage).integerValue(BigNumber.ROUND_DOWN)
|
||||||
: new BigNumber(1).plus(opts.slippage);
|
: result.output.times(1 + opts.slippage).integerValue(BigNumber.ROUND_UP);
|
||||||
result.output = result.output.times(outputMultiplier).integerValue();
|
|
||||||
return fromIntermediateQuoteFillResult(result, quoteInfo);
|
return fromIntermediateQuoteFillResult(result, quoteInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@ import * as IMooniswap from '../test/generated-artifacts/IMooniswap.json';
|
|||||||
import * as IMStable from '../test/generated-artifacts/IMStable.json';
|
import * as IMStable from '../test/generated-artifacts/IMStable.json';
|
||||||
import * as IMultiBridge from '../test/generated-artifacts/IMultiBridge.json';
|
import * as IMultiBridge from '../test/generated-artifacts/IMultiBridge.json';
|
||||||
import * as IShell from '../test/generated-artifacts/IShell.json';
|
import * as IShell from '../test/generated-artifacts/IShell.json';
|
||||||
|
import * as ISmoothy from '../test/generated-artifacts/ISmoothy.json';
|
||||||
import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json';
|
import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json';
|
||||||
import * as IUniswapV2Router01 from '../test/generated-artifacts/IUniswapV2Router01.json';
|
import * as IUniswapV2Router01 from '../test/generated-artifacts/IUniswapV2Router01.json';
|
||||||
import * as KyberSampler from '../test/generated-artifacts/KyberSampler.json';
|
import * as KyberSampler from '../test/generated-artifacts/KyberSampler.json';
|
||||||
@@ -36,6 +37,7 @@ import * as MultiBridgeSampler from '../test/generated-artifacts/MultiBridgeSamp
|
|||||||
import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSampler.json';
|
import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSampler.json';
|
||||||
import * as SamplerUtils from '../test/generated-artifacts/SamplerUtils.json';
|
import * as SamplerUtils from '../test/generated-artifacts/SamplerUtils.json';
|
||||||
import * as ShellSampler from '../test/generated-artifacts/ShellSampler.json';
|
import * as ShellSampler from '../test/generated-artifacts/ShellSampler.json';
|
||||||
|
import * as SmoothySampler from '../test/generated-artifacts/SmoothySampler.json';
|
||||||
import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json';
|
import * as TestERC20BridgeSampler from '../test/generated-artifacts/TestERC20BridgeSampler.json';
|
||||||
import * as TestNativeOrderSampler from '../test/generated-artifacts/TestNativeOrderSampler.json';
|
import * as TestNativeOrderSampler from '../test/generated-artifacts/TestNativeOrderSampler.json';
|
||||||
import * as TwoHopSampler from '../test/generated-artifacts/TwoHopSampler.json';
|
import * as TwoHopSampler from '../test/generated-artifacts/TwoHopSampler.json';
|
||||||
@@ -62,6 +64,7 @@ export const artifacts = {
|
|||||||
NativeOrderSampler: NativeOrderSampler as ContractArtifact,
|
NativeOrderSampler: NativeOrderSampler as ContractArtifact,
|
||||||
SamplerUtils: SamplerUtils as ContractArtifact,
|
SamplerUtils: SamplerUtils as ContractArtifact,
|
||||||
ShellSampler: ShellSampler as ContractArtifact,
|
ShellSampler: ShellSampler as ContractArtifact,
|
||||||
|
SmoothySampler: SmoothySampler as ContractArtifact,
|
||||||
TwoHopSampler: TwoHopSampler as ContractArtifact,
|
TwoHopSampler: TwoHopSampler as ContractArtifact,
|
||||||
UniswapSampler: UniswapSampler as ContractArtifact,
|
UniswapSampler: UniswapSampler as ContractArtifact,
|
||||||
UniswapV2Sampler: UniswapV2Sampler as ContractArtifact,
|
UniswapV2Sampler: UniswapV2Sampler as ContractArtifact,
|
||||||
@@ -75,6 +78,7 @@ export const artifacts = {
|
|||||||
IMooniswap: IMooniswap as ContractArtifact,
|
IMooniswap: IMooniswap as ContractArtifact,
|
||||||
IMultiBridge: IMultiBridge as ContractArtifact,
|
IMultiBridge: IMultiBridge as ContractArtifact,
|
||||||
IShell: IShell as ContractArtifact,
|
IShell: IShell as ContractArtifact,
|
||||||
|
ISmoothy: ISmoothy as ContractArtifact,
|
||||||
IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,
|
IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,
|
||||||
IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact,
|
IUniswapV2Router01: IUniswapV2Router01 as ContractArtifact,
|
||||||
DummyLiquidityProvider: DummyLiquidityProvider as ContractArtifact,
|
DummyLiquidityProvider: DummyLiquidityProvider as ContractArtifact,
|
||||||
|
@@ -3,7 +3,7 @@ import { blockchainTests, describe, expect, toBaseUnitAmount, Web3ProviderEngine
|
|||||||
import { RPCSubprovider } from '@0x/subproviders';
|
import { RPCSubprovider } from '@0x/subproviders';
|
||||||
import { BigNumber, NULL_BYTES, providerUtils } from '@0x/utils';
|
import { BigNumber, NULL_BYTES, providerUtils } from '@0x/utils';
|
||||||
|
|
||||||
import { KYBER_CONFIG_BY_CHAIN_ID, TOKENS } from '../../src/utils/market_operation_utils/constants';
|
import { KYBER_CONFIG_BY_CHAIN_ID, MAINNET_TOKENS } from '../../src/utils/market_operation_utils/constants';
|
||||||
import { artifacts } from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
import { ERC20BridgeSamplerContract } from '../wrappers';
|
import { ERC20BridgeSamplerContract } from '../wrappers';
|
||||||
|
|
||||||
@@ -80,9 +80,9 @@ blockchainTests.skip('Mainnet Sampler Tests', env => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Kyber', () => {
|
describe('Kyber', () => {
|
||||||
const WETH = TOKENS.WETH;
|
const WETH = MAINNET_TOKENS.WETH;
|
||||||
const DAI = TOKENS.DAI;
|
const DAI = MAINNET_TOKENS.DAI;
|
||||||
const USDC = TOKENS.USDC;
|
const USDC = MAINNET_TOKENS.USDC;
|
||||||
const RESERVE_OFFSET = new BigNumber(0);
|
const RESERVE_OFFSET = new BigNumber(0);
|
||||||
const KYBER_OPTS = {
|
const KYBER_OPTS = {
|
||||||
...KYBER_CONFIG_BY_CHAIN_ID[ChainId.Mainnet],
|
...KYBER_CONFIG_BY_CHAIN_ID[ChainId.Mainnet],
|
||||||
|
@@ -68,6 +68,10 @@ const DEFAULT_EXCLUDED = [
|
|||||||
ERC20BridgeSource.PancakeSwap,
|
ERC20BridgeSource.PancakeSwap,
|
||||||
ERC20BridgeSource.BakerySwap,
|
ERC20BridgeSource.BakerySwap,
|
||||||
ERC20BridgeSource.MakerPsm,
|
ERC20BridgeSource.MakerPsm,
|
||||||
|
ERC20BridgeSource.KyberDmm,
|
||||||
|
ERC20BridgeSource.Smoothy,
|
||||||
|
ERC20BridgeSource.Component,
|
||||||
|
ERC20BridgeSource.Saddle,
|
||||||
];
|
];
|
||||||
const BUY_SOURCES = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
|
const BUY_SOURCES = BUY_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
|
||||||
const SELL_SOURCES = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
|
const SELL_SOURCES = SELL_SOURCE_FILTER_BY_CHAIN_ID[ChainId.Mainnet].sources;
|
||||||
@@ -282,32 +286,12 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
[source: string]: Numberish[];
|
[source: string]: Numberish[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ZERO_RATES: RatesBySource = {
|
const ZERO_RATES: RatesBySource = Object.assign(
|
||||||
[ERC20BridgeSource.Native]: _.times(NUM_SAMPLES, () => 0),
|
{},
|
||||||
[ERC20BridgeSource.Eth2Dai]: _.times(NUM_SAMPLES, () => 0),
|
...Object.values(ERC20BridgeSource).map(source => ({
|
||||||
[ERC20BridgeSource.Uniswap]: _.times(NUM_SAMPLES, () => 0),
|
[source]: _.times(NUM_SAMPLES, () => 0),
|
||||||
[ERC20BridgeSource.Kyber]: _.times(NUM_SAMPLES, () => 0),
|
})),
|
||||||
[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.MStable]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.Mooniswap]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.Swerve]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.SnowSwap]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[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),
|
|
||||||
[ERC20BridgeSource.DodoV2]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.CryptoCom]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.Linkswap]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.PancakeSwap]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.BakerySwap]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
[ERC20BridgeSource.MakerPsm]: _.times(NUM_SAMPLES, () => 0),
|
|
||||||
};
|
|
||||||
|
|
||||||
const DEFAULT_RATES: RatesBySource = {
|
const DEFAULT_RATES: RatesBySource = {
|
||||||
...ZERO_RATES,
|
...ZERO_RATES,
|
||||||
@@ -358,12 +342,35 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
fromTokenIdx: 0,
|
fromTokenIdx: 0,
|
||||||
toTokenIdx: 1,
|
toTokenIdx: 1,
|
||||||
},
|
},
|
||||||
|
[ERC20BridgeSource.Smoothy]: {
|
||||||
|
pool: {
|
||||||
|
poolAddress: randomAddress(),
|
||||||
|
tokens: [TAKER_TOKEN, MAKER_TOKEN],
|
||||||
|
exchangeFunctionSelector: hexUtils.random(4),
|
||||||
|
sellQuoteFunctionSelector: hexUtils.random(4),
|
||||||
|
buyQuoteFunctionSelector: hexUtils.random(4),
|
||||||
|
},
|
||||||
|
fromTokenIdx: 0,
|
||||||
|
toTokenIdx: 1,
|
||||||
|
},
|
||||||
|
[ERC20BridgeSource.Saddle]: {
|
||||||
|
pool: {
|
||||||
|
poolAddress: randomAddress(),
|
||||||
|
tokens: [TAKER_TOKEN, MAKER_TOKEN],
|
||||||
|
exchangeFunctionSelector: hexUtils.random(4),
|
||||||
|
sellQuoteFunctionSelector: hexUtils.random(4),
|
||||||
|
buyQuoteFunctionSelector: hexUtils.random(4),
|
||||||
|
},
|
||||||
|
fromTokenIdx: 0,
|
||||||
|
toTokenIdx: 1,
|
||||||
|
},
|
||||||
[ERC20BridgeSource.LiquidityProvider]: { poolAddress: randomAddress() },
|
[ERC20BridgeSource.LiquidityProvider]: { poolAddress: randomAddress() },
|
||||||
[ERC20BridgeSource.SushiSwap]: { tokenAddressPath: [] },
|
[ERC20BridgeSource.SushiSwap]: { tokenAddressPath: [] },
|
||||||
[ERC20BridgeSource.Mooniswap]: { poolAddress: randomAddress() },
|
[ERC20BridgeSource.Mooniswap]: { poolAddress: randomAddress() },
|
||||||
[ERC20BridgeSource.Native]: { order: new LimitOrder() },
|
[ERC20BridgeSource.Native]: { order: new LimitOrder() },
|
||||||
[ERC20BridgeSource.MultiHop]: {},
|
[ERC20BridgeSource.MultiHop]: {},
|
||||||
[ERC20BridgeSource.Shell]: { poolAddress: randomAddress() },
|
[ERC20BridgeSource.Shell]: { poolAddress: randomAddress() },
|
||||||
|
[ERC20BridgeSource.Component]: { poolAddress: randomAddress() },
|
||||||
[ERC20BridgeSource.Cream]: { poolAddress: randomAddress() },
|
[ERC20BridgeSource.Cream]: { poolAddress: randomAddress() },
|
||||||
[ERC20BridgeSource.Dodo]: {},
|
[ERC20BridgeSource.Dodo]: {},
|
||||||
[ERC20BridgeSource.DodoV2]: {},
|
[ERC20BridgeSource.DodoV2]: {},
|
||||||
@@ -372,6 +379,7 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
[ERC20BridgeSource.Uniswap]: { router: randomAddress() },
|
[ERC20BridgeSource.Uniswap]: { router: randomAddress() },
|
||||||
[ERC20BridgeSource.Eth2Dai]: { router: randomAddress() },
|
[ERC20BridgeSource.Eth2Dai]: { router: randomAddress() },
|
||||||
[ERC20BridgeSource.MakerPsm]: {},
|
[ERC20BridgeSource.MakerPsm]: {},
|
||||||
|
[ERC20BridgeSource.KyberDmm]: { tokenAddressPath: [] },
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_OPS = {
|
const DEFAULT_OPS = {
|
||||||
@@ -907,6 +915,7 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
intentOnFilling: true,
|
intentOnFilling: true,
|
||||||
quoteRequestor: {
|
quoteRequestor: {
|
||||||
requestRfqtIndicativeQuotesAsync: requestor.object.requestRfqtIndicativeQuotesAsync,
|
requestRfqtIndicativeQuotesAsync: requestor.object.requestRfqtIndicativeQuotesAsync,
|
||||||
|
getMakerUriForSignature: requestor.object.getMakerUriForSignature,
|
||||||
} as any,
|
} as any,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -23,6 +23,7 @@ export * from '../test/generated-wrappers/i_m_stable';
|
|||||||
export * from '../test/generated-wrappers/i_mooniswap';
|
export * from '../test/generated-wrappers/i_mooniswap';
|
||||||
export * from '../test/generated-wrappers/i_multi_bridge';
|
export * from '../test/generated-wrappers/i_multi_bridge';
|
||||||
export * from '../test/generated-wrappers/i_shell';
|
export * from '../test/generated-wrappers/i_shell';
|
||||||
|
export * from '../test/generated-wrappers/i_smoothy';
|
||||||
export * from '../test/generated-wrappers/i_uniswap_exchange_quotes';
|
export * from '../test/generated-wrappers/i_uniswap_exchange_quotes';
|
||||||
export * from '../test/generated-wrappers/i_uniswap_v2_router01';
|
export * from '../test/generated-wrappers/i_uniswap_v2_router01';
|
||||||
export * from '../test/generated-wrappers/kyber_sampler';
|
export * from '../test/generated-wrappers/kyber_sampler';
|
||||||
@@ -34,6 +35,7 @@ export * from '../test/generated-wrappers/multi_bridge_sampler';
|
|||||||
export * from '../test/generated-wrappers/native_order_sampler';
|
export * from '../test/generated-wrappers/native_order_sampler';
|
||||||
export * from '../test/generated-wrappers/sampler_utils';
|
export * from '../test/generated-wrappers/sampler_utils';
|
||||||
export * from '../test/generated-wrappers/shell_sampler';
|
export * from '../test/generated-wrappers/shell_sampler';
|
||||||
|
export * from '../test/generated-wrappers/smoothy_sampler';
|
||||||
export * from '../test/generated-wrappers/test_erc20_bridge_sampler';
|
export * from '../test/generated-wrappers/test_erc20_bridge_sampler';
|
||||||
export * from '../test/generated-wrappers/test_native_order_sampler';
|
export * from '../test/generated-wrappers/test_native_order_sampler';
|
||||||
export * from '../test/generated-wrappers/two_hop_sampler';
|
export * from '../test/generated-wrappers/two_hop_sampler';
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
"test/generated-artifacts/IMooniswap.json",
|
"test/generated-artifacts/IMooniswap.json",
|
||||||
"test/generated-artifacts/IMultiBridge.json",
|
"test/generated-artifacts/IMultiBridge.json",
|
||||||
"test/generated-artifacts/IShell.json",
|
"test/generated-artifacts/IShell.json",
|
||||||
|
"test/generated-artifacts/ISmoothy.json",
|
||||||
"test/generated-artifacts/IUniswapExchangeQuotes.json",
|
"test/generated-artifacts/IUniswapExchangeQuotes.json",
|
||||||
"test/generated-artifacts/IUniswapV2Router01.json",
|
"test/generated-artifacts/IUniswapV2Router01.json",
|
||||||
"test/generated-artifacts/KyberSampler.json",
|
"test/generated-artifacts/KyberSampler.json",
|
||||||
@@ -37,6 +38,7 @@
|
|||||||
"test/generated-artifacts/NativeOrderSampler.json",
|
"test/generated-artifacts/NativeOrderSampler.json",
|
||||||
"test/generated-artifacts/SamplerUtils.json",
|
"test/generated-artifacts/SamplerUtils.json",
|
||||||
"test/generated-artifacts/ShellSampler.json",
|
"test/generated-artifacts/ShellSampler.json",
|
||||||
|
"test/generated-artifacts/SmoothySampler.json",
|
||||||
"test/generated-artifacts/TestERC20BridgeSampler.json",
|
"test/generated-artifacts/TestERC20BridgeSampler.json",
|
||||||
"test/generated-artifacts/TestNativeOrderSampler.json",
|
"test/generated-artifacts/TestNativeOrderSampler.json",
|
||||||
"test/generated-artifacts/TwoHopSampler.json",
|
"test/generated-artifacts/TwoHopSampler.json",
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"extends": ["@0x/tslint-config"],
|
"extends": ["@0x/tslint-config"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"max-file-line-count": false
|
"max-file-line-count": false,
|
||||||
|
"binary-expression-operand-order": false
|
||||||
},
|
},
|
||||||
"linterOptions": {
|
"linterOptions": {
|
||||||
"exclude": ["src/artifacts.ts", "test/artifacts.ts"]
|
"exclude": ["src/artifacts.ts", "test/artifacts.ts"]
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contract-wrappers-test",
|
"name": "@0x/contract-wrappers-test",
|
||||||
"version": "12.2.39",
|
"version": "12.2.40",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"@0x/contract-wrappers": "^13.15.0",
|
"@0x/contract-wrappers": "^13.15.0",
|
||||||
"@0x/contracts-test-utils": "^5.3.24",
|
"@0x/contracts-test-utils": "^5.3.24",
|
||||||
"@0x/dev-utils": "^4.2.1",
|
"@0x/dev-utils": "^4.2.1",
|
||||||
"@0x/migrations": "^8.0.0",
|
"@0x/migrations": "^8.0.1",
|
||||||
"@0x/order-utils": "^10.4.19",
|
"@0x/order-utils": "^10.4.19",
|
||||||
"@0x/subproviders": "^6.4.1",
|
"@0x/subproviders": "^6.4.1",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
|
@@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1618259868,
|
||||||
|
"version": "8.0.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v8.0.1 - _April 12, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v8.0.0 - _April 1, 2021_
|
## v8.0.0 - _April 1, 2021_
|
||||||
|
|
||||||
* Remove exchangeProxyAllowanceTarget
|
* Remove exchangeProxyAllowanceTarget
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/migrations",
|
"name": "@0x/migrations",
|
||||||
"version": "8.0.0",
|
"version": "8.0.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
"@0x/contracts-multisig": "^4.1.28",
|
"@0x/contracts-multisig": "^4.1.28",
|
||||||
"@0x/contracts-staking": "^2.0.35",
|
"@0x/contracts-staking": "^2.0.35",
|
||||||
"@0x/contracts-utils": "^4.7.6",
|
"@0x/contracts-utils": "^4.7.6",
|
||||||
"@0x/contracts-zero-ex": "^0.21.0",
|
"@0x/contracts-zero-ex": "^0.21.1",
|
||||||
"@0x/sol-compiler": "^4.6.1",
|
"@0x/sol-compiler": "^4.6.1",
|
||||||
"@0x/subproviders": "^6.4.1",
|
"@0x/subproviders": "^6.4.1",
|
||||||
"@0x/typescript-typings": "^5.1.6",
|
"@0x/typescript-typings": "^5.1.6",
|
||||||
|
@@ -1,7 +1,20 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1618259868,
|
||||||
|
"version": "1.4.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Added Smoothy, Component, Saddle",
|
||||||
|
"pr": 182
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"note": "Added Nerve",
|
"note": "Added Nerve",
|
||||||
"pr": 181
|
"pr": 181
|
||||||
|
@@ -5,8 +5,13 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.4.1 - _April 12, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v1.4.0 - _April 1, 2021_
|
## v1.4.0 - _April 1, 2021_
|
||||||
|
|
||||||
|
* Added Smoothy, Component, Saddle (#182)
|
||||||
* Added Nerve (#181)
|
* Added Nerve (#181)
|
||||||
|
|
||||||
## v1.3.1 - _March 17, 2021_
|
## v1.3.1 - _March 17, 2021_
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/protocol-utils",
|
"name": "@0x/protocol-utils",
|
||||||
"version": "1.4.0",
|
"version": "1.4.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
|
@@ -126,6 +126,9 @@ export enum BridgeProtocol {
|
|||||||
CoFiX,
|
CoFiX,
|
||||||
Nerve,
|
Nerve,
|
||||||
MakerPsm,
|
MakerPsm,
|
||||||
|
Smoothy,
|
||||||
|
Component,
|
||||||
|
Saddle,
|
||||||
}
|
}
|
||||||
// tslint:enable: enum-naming
|
// tslint:enable: enum-naming
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user