Compare commits
57 Commits
@0x/contra
...
@0x/asset-
Author | SHA1 | Date | |
---|---|---|---|
|
e5ed8b2c81 | ||
|
61fbae3ae2 | ||
|
5c2255c841 | ||
|
e036dee6c5 | ||
|
8583aab241 | ||
|
5d05b62821 | ||
|
0063e8178f | ||
|
ec6e5dd517 | ||
|
9d08fefa1c | ||
|
2fdca24d4e | ||
|
42ec0b144e | ||
|
3f6ce78b46 | ||
|
c1300c1068 | ||
|
9a641cfab6 | ||
|
60345d4465 | ||
|
11dfea47a6 | ||
|
55e9dd39a2 | ||
|
1993929bed | ||
|
e1d81de517 | ||
|
a6b3a21635 | ||
|
fd59cdc2db | ||
|
98e11b5189 | ||
|
3bebc7cd62 | ||
|
56dab6ae8c | ||
|
285f98e9e9 | ||
|
8ae9f59f20 | ||
|
4c341c5ca3 | ||
|
a3c912c2af | ||
|
5e72eb9af9 | ||
|
9b08b73c06 | ||
|
76c7eb7c3e | ||
|
9b2e5a3adb | ||
|
813d703d12 | ||
|
83005d0f3d | ||
|
d07ffd2688 | ||
|
4170f970d0 | ||
|
dcde12dd70 | ||
|
84a60ec982 | ||
|
9615570dc6 | ||
|
880a9c3da0 | ||
|
c44bd9d42d | ||
|
90b441330b | ||
|
e12ed1eddf | ||
|
ac94023ab3 | ||
|
281e6acca5 | ||
|
2f1b520409 | ||
|
21b4eb3d26 | ||
|
644f6c7d28 | ||
|
0647b9e4f8 | ||
|
82d42eeede | ||
|
6ef4d95043 | ||
|
6044140f86 | ||
|
4da1ef0f56 | ||
|
8c668a3918 | ||
|
f1ff1cde39 | ||
|
1668a24e31 | ||
|
4b7c376d96 |
@@ -1,4 +1,22 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "3.3.25",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1638390144,
|
||||||
|
"version": "3.3.24",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "3.3.23",
|
"version": "3.3.23",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v3.3.25 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v3.3.24 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v3.3.23 - _November 16, 2021_
|
## v3.3.23 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-erc20",
|
"name": "@0x/contracts-erc20",
|
||||||
"version": "3.3.23",
|
"version": "3.3.25",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -53,8 +53,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.6.2",
|
"@0x/abi-gen": "^5.6.2",
|
||||||
"@0x/contracts-gen": "^2.0.40",
|
"@0x/contracts-gen": "^2.0.40",
|
||||||
"@0x/contracts-test-utils": "^5.4.14",
|
"@0x/contracts-test-utils": "^5.4.16",
|
||||||
"@0x/contracts-utils": "^4.8.4",
|
"@0x/contracts-utils": "^4.8.6",
|
||||||
"@0x/dev-utils": "^4.2.9",
|
"@0x/dev-utils": "^4.2.9",
|
||||||
"@0x/sol-compiler": "^4.7.5",
|
"@0x/sol-compiler": "^4.7.5",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
|
@@ -1,4 +1,22 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "5.4.16",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1638390144,
|
||||||
|
"version": "5.4.15",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "5.4.14",
|
"version": "5.4.14",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v5.4.16 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v5.4.15 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v5.4.14 - _November 16, 2021_
|
## v5.4.14 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-test-utils",
|
"name": "@0x/contracts-test-utils",
|
||||||
"version": "5.4.14",
|
"version": "5.4.16",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.29",
|
"@0x/assert": "^3.0.29",
|
||||||
"@0x/base-contract": "^6.4.2",
|
"@0x/base-contract": "^6.4.2",
|
||||||
"@0x/contract-addresses": "^6.9.0",
|
"@0x/contract-addresses": "^6.11.0",
|
||||||
"@0x/dev-utils": "^4.2.9",
|
"@0x/dev-utils": "^4.2.9",
|
||||||
"@0x/json-schemas": "^6.3.0",
|
"@0x/json-schemas": "^6.3.0",
|
||||||
"@0x/order-utils": "^10.4.28",
|
"@0x/order-utils": "^10.4.28",
|
||||||
|
@@ -1,4 +1,22 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "1.4.8",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1638390144,
|
||||||
|
"version": "1.4.7",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "1.4.6",
|
"version": "1.4.6",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.4.8 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.4.7 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v1.4.6 - _November 16, 2021_
|
## v1.4.6 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-treasury",
|
"name": "@0x/contracts-treasury",
|
||||||
"version": "1.4.6",
|
"version": "1.4.8",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -47,12 +47,12 @@
|
|||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/treasury",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.6.2",
|
"@0x/abi-gen": "^5.6.2",
|
||||||
"@0x/contract-addresses": "^6.9.0",
|
"@0x/contract-addresses": "^6.11.0",
|
||||||
"@0x/contracts-asset-proxy": "^3.7.19",
|
"@0x/contracts-asset-proxy": "^3.7.19",
|
||||||
"@0x/contracts-erc20": "^3.3.23",
|
"@0x/contracts-erc20": "^3.3.25",
|
||||||
"@0x/contracts-gen": "^2.0.40",
|
"@0x/contracts-gen": "^2.0.40",
|
||||||
"@0x/contracts-staking": "^2.0.45",
|
"@0x/contracts-staking": "^2.0.45",
|
||||||
"@0x/contracts-test-utils": "^5.4.14",
|
"@0x/contracts-test-utils": "^5.4.16",
|
||||||
"@0x/sol-compiler": "^4.7.5",
|
"@0x/sol-compiler": "^4.7.5",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
"@0x/tslint-config": "^4.1.4",
|
"@0x/tslint-config": "^4.1.4",
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.4.2",
|
"@0x/base-contract": "^6.4.2",
|
||||||
"@0x/protocol-utils": "^1.9.5",
|
"@0x/protocol-utils": "^1.10.1",
|
||||||
"@0x/subproviders": "^6.6.0",
|
"@0x/subproviders": "^6.6.0",
|
||||||
"@0x/types": "^3.3.4",
|
"@0x/types": "^3.3.4",
|
||||||
"@0x/typescript-typings": "^5.2.1",
|
"@0x/typescript-typings": "^5.2.1",
|
||||||
|
@@ -1,4 +1,22 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "4.8.6",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1638390144,
|
||||||
|
"version": "4.8.5",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "4.8.4",
|
"version": "4.8.4",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v4.8.6 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v4.8.5 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v4.8.4 - _November 16, 2021_
|
## v4.8.4 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-utils",
|
"name": "@0x/contracts-utils",
|
||||||
"version": "4.8.4",
|
"version": "4.8.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.6.2",
|
"@0x/abi-gen": "^5.6.2",
|
||||||
"@0x/contracts-gen": "^2.0.40",
|
"@0x/contracts-gen": "^2.0.40",
|
||||||
"@0x/contracts-test-utils": "^5.4.14",
|
"@0x/contracts-test-utils": "^5.4.16",
|
||||||
"@0x/dev-utils": "^4.2.9",
|
"@0x/dev-utils": "^4.2.9",
|
||||||
"@0x/order-utils": "^10.4.28",
|
"@0x/order-utils": "^10.4.28",
|
||||||
"@0x/sol-compiler": "^4.7.5",
|
"@0x/sol-compiler": "^4.7.5",
|
||||||
|
@@ -1,4 +1,23 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "0.30.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "0.30.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add `AaveV2` and `Compound` deposit/withdrawal liquidity source",
|
||||||
|
"pr": 321
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1638390144
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "0.29.5",
|
"version": "0.29.5",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v0.30.1 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v0.30.0 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Add `AaveV2` and `Compound` deposit/withdrawal liquidity source (#321)
|
||||||
|
|
||||||
## v0.29.5 - _November 16, 2021_
|
## v0.29.5 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -22,10 +22,12 @@ pragma experimental ABIEncoderV2;
|
|||||||
|
|
||||||
import "./IBridgeAdapter.sol";
|
import "./IBridgeAdapter.sol";
|
||||||
import "./BridgeProtocols.sol";
|
import "./BridgeProtocols.sol";
|
||||||
|
import "./mixins/MixinAaveV2.sol";
|
||||||
import "./mixins/MixinBalancer.sol";
|
import "./mixins/MixinBalancer.sol";
|
||||||
import "./mixins/MixinBalancerV2.sol";
|
import "./mixins/MixinBalancerV2.sol";
|
||||||
import "./mixins/MixinBancor.sol";
|
import "./mixins/MixinBancor.sol";
|
||||||
import "./mixins/MixinCoFiX.sol";
|
import "./mixins/MixinCoFiX.sol";
|
||||||
|
import "./mixins/MixinCompound.sol";
|
||||||
import "./mixins/MixinCurve.sol";
|
import "./mixins/MixinCurve.sol";
|
||||||
import "./mixins/MixinCurveV2.sol";
|
import "./mixins/MixinCurveV2.sol";
|
||||||
import "./mixins/MixinCryptoCom.sol";
|
import "./mixins/MixinCryptoCom.sol";
|
||||||
@@ -47,10 +49,12 @@ import "./mixins/MixinZeroExBridge.sol";
|
|||||||
|
|
||||||
contract BridgeAdapter is
|
contract BridgeAdapter is
|
||||||
IBridgeAdapter,
|
IBridgeAdapter,
|
||||||
|
MixinAaveV2,
|
||||||
MixinBalancer,
|
MixinBalancer,
|
||||||
MixinBalancerV2,
|
MixinBalancerV2,
|
||||||
MixinBancor,
|
MixinBancor,
|
||||||
MixinCoFiX,
|
MixinCoFiX,
|
||||||
|
MixinCompound,
|
||||||
MixinCurve,
|
MixinCurve,
|
||||||
MixinCurveV2,
|
MixinCurveV2,
|
||||||
MixinCryptoCom,
|
MixinCryptoCom,
|
||||||
@@ -72,10 +76,12 @@ contract BridgeAdapter is
|
|||||||
{
|
{
|
||||||
constructor(IEtherTokenV06 weth)
|
constructor(IEtherTokenV06 weth)
|
||||||
public
|
public
|
||||||
|
MixinAaveV2()
|
||||||
MixinBalancer()
|
MixinBalancer()
|
||||||
MixinBalancerV2()
|
MixinBalancerV2()
|
||||||
MixinBancor(weth)
|
MixinBancor(weth)
|
||||||
MixinCoFiX()
|
MixinCoFiX()
|
||||||
|
MixinCompound(weth)
|
||||||
MixinCurve(weth)
|
MixinCurve(weth)
|
||||||
MixinCurveV2()
|
MixinCurveV2()
|
||||||
MixinCryptoCom()
|
MixinCryptoCom()
|
||||||
@@ -245,6 +251,20 @@ contract BridgeAdapter is
|
|||||||
sellAmount,
|
sellAmount,
|
||||||
order.bridgeData
|
order.bridgeData
|
||||||
);
|
);
|
||||||
|
} else if (protocolId == BridgeProtocols.AAVEV2) {
|
||||||
|
boughtAmount = _tradeAaveV2(
|
||||||
|
sellToken,
|
||||||
|
buyToken,
|
||||||
|
sellAmount,
|
||||||
|
order.bridgeData
|
||||||
|
);
|
||||||
|
} else if (protocolId == BridgeProtocols.COMPOUND) {
|
||||||
|
boughtAmount = _tradeCompound(
|
||||||
|
sellToken,
|
||||||
|
buyToken,
|
||||||
|
sellAmount,
|
||||||
|
order.bridgeData
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
boughtAmount = _tradeZeroExBridge(
|
boughtAmount = _tradeZeroExBridge(
|
||||||
sellToken,
|
sellToken,
|
||||||
|
@@ -50,4 +50,6 @@ library BridgeProtocols {
|
|||||||
uint128 internal constant CURVEV2 = 20;
|
uint128 internal constant CURVEV2 = 20;
|
||||||
uint128 internal constant LIDO = 21;
|
uint128 internal constant LIDO = 21;
|
||||||
uint128 internal constant CLIPPER = 22; // Not used: Clipper is now using PLP interface
|
uint128 internal constant CLIPPER = 22; // Not used: Clipper is now using PLP interface
|
||||||
|
uint128 internal constant AAVEV2 = 23;
|
||||||
|
uint128 internal constant COMPOUND = 24;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,93 @@
|
|||||||
|
// 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.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||||
|
|
||||||
|
// Minimal Aave V2 LendingPool interface
|
||||||
|
interface ILendingPool {
|
||||||
|
/**
|
||||||
|
* @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
|
||||||
|
* - E.g. User deposits 100 USDC and gets in return 100 aUSDC
|
||||||
|
* @param asset The address of the underlying asset to deposit
|
||||||
|
* @param amount The amount to be deposited
|
||||||
|
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
|
||||||
|
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
|
||||||
|
* is a different wallet
|
||||||
|
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
|
||||||
|
* 0 if the action is executed directly by the user, without any middle-man
|
||||||
|
**/
|
||||||
|
function deposit(
|
||||||
|
address asset,
|
||||||
|
uint256 amount,
|
||||||
|
address onBehalfOf,
|
||||||
|
uint16 referralCode
|
||||||
|
) external;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
|
||||||
|
* E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
|
||||||
|
* @param asset The address of the underlying asset to withdraw
|
||||||
|
* @param amount The underlying amount to be withdrawn
|
||||||
|
* - Send the value type(uint256).max in order to withdraw the whole aToken balance
|
||||||
|
* @param to Address that will receive the underlying, same as msg.sender if the user
|
||||||
|
* wants to receive it on his own wallet, or a different address if the beneficiary is a
|
||||||
|
* different wallet
|
||||||
|
* @return The final amount withdrawn
|
||||||
|
**/
|
||||||
|
function withdraw(
|
||||||
|
address asset,
|
||||||
|
uint256 amount,
|
||||||
|
address to
|
||||||
|
) external returns (uint256);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract MixinAaveV2 {
|
||||||
|
using LibERC20TokenV06 for IERC20TokenV06;
|
||||||
|
|
||||||
|
function _tradeAaveV2(
|
||||||
|
IERC20TokenV06 sellToken,
|
||||||
|
IERC20TokenV06 buyToken,
|
||||||
|
uint256 sellAmount,
|
||||||
|
bytes memory bridgeData
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
(ILendingPool lendingPool, address aToken) = abi.decode(bridgeData, (ILendingPool, address));
|
||||||
|
|
||||||
|
sellToken.approveIfBelow(
|
||||||
|
address(lendingPool),
|
||||||
|
sellAmount
|
||||||
|
);
|
||||||
|
|
||||||
|
if (address(buyToken) == aToken) {
|
||||||
|
lendingPool.deposit(address(sellToken), sellAmount, address(this), 0);
|
||||||
|
// 1:1 mapping token -> aToken and have the same number of decimals as the underlying token
|
||||||
|
return sellAmount;
|
||||||
|
} else if (address(sellToken) == aToken) {
|
||||||
|
return lendingPool.withdraw(address(buyToken), sellAmount, address(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
revert("MixinAaveV2/UNSUPPORTED_TOKEN_PAIR");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,110 @@
|
|||||||
|
// 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.5;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/LibERC20TokenV06.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/v06/LibSafeMathV06.sol";
|
||||||
|
|
||||||
|
|
||||||
|
/// @dev Minimal CToken interface
|
||||||
|
interface ICToken {
|
||||||
|
/// @dev deposits specified amount underlying tokens and mints cToken for the sender
|
||||||
|
/// @param mintAmountInUnderlying amount of underlying tokens to deposit to mint cTokens
|
||||||
|
/// @return status code of whether the mint was successful or not
|
||||||
|
function mint(uint256 mintAmountInUnderlying) external returns (uint256);
|
||||||
|
/// @dev redeems specified amount of cTokens and returns the underlying token to the sender
|
||||||
|
/// @param redeemTokensInCtokens amount of cTokens to redeem for underlying collateral
|
||||||
|
/// @return status code of whether the redemption was successful or not
|
||||||
|
function redeem(uint256 redeemTokensInCtokens) external returns (uint256);
|
||||||
|
}
|
||||||
|
/// @dev Minimal CEther interface
|
||||||
|
interface ICEther {
|
||||||
|
/// @dev deposits the amount of Ether sent as value and return mints cEther for the sender
|
||||||
|
function mint() payable external;
|
||||||
|
/// @dev redeems specified amount of cETH and returns the underlying ether to the sender
|
||||||
|
/// @dev redeemTokensInCEther amount of cETH to redeem for underlying ether
|
||||||
|
/// @return status code of whether the redemption was successful or not
|
||||||
|
function redeem(uint256 redeemTokensInCEther) external returns (uint256);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract MixinCompound {
|
||||||
|
using LibERC20TokenV06 for IERC20TokenV06;
|
||||||
|
using LibSafeMathV06 for uint256;
|
||||||
|
|
||||||
|
IEtherTokenV06 private immutable WETH;
|
||||||
|
|
||||||
|
constructor(IEtherTokenV06 weth)
|
||||||
|
public
|
||||||
|
{
|
||||||
|
WETH = weth;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 constant private COMPOUND_SUCCESS_CODE = 0;
|
||||||
|
|
||||||
|
function _tradeCompound(
|
||||||
|
IERC20TokenV06 sellToken,
|
||||||
|
IERC20TokenV06 buyToken,
|
||||||
|
uint256 sellAmount,
|
||||||
|
bytes memory bridgeData
|
||||||
|
)
|
||||||
|
internal
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
(address cTokenAddress) = abi.decode(bridgeData, (address));
|
||||||
|
uint256 beforeBalance = buyToken.balanceOf(address(this));
|
||||||
|
|
||||||
|
if (address(buyToken) == cTokenAddress) {
|
||||||
|
if (address(sellToken) == address(WETH)) {
|
||||||
|
// ETH/WETH -> cETH
|
||||||
|
ICEther cETH = ICEther(cTokenAddress);
|
||||||
|
// Compound expects ETH to be sent with mint call
|
||||||
|
WETH.withdraw(sellAmount);
|
||||||
|
// NOTE: cETH mint will revert on failure instead of returning a status code
|
||||||
|
cETH.mint{value: sellAmount}();
|
||||||
|
} else {
|
||||||
|
sellToken.approveIfBelow(
|
||||||
|
cTokenAddress,
|
||||||
|
sellAmount
|
||||||
|
);
|
||||||
|
// Token -> cToken
|
||||||
|
ICToken cToken = ICToken(cTokenAddress);
|
||||||
|
require(cToken.mint(sellAmount) == COMPOUND_SUCCESS_CODE, "MixinCompound/FAILED_TO_MINT_CTOKEN");
|
||||||
|
}
|
||||||
|
} else if (address(sellToken) == cTokenAddress) {
|
||||||
|
if (address(buyToken) == address(WETH)) {
|
||||||
|
// cETH -> ETH/WETH
|
||||||
|
uint256 etherBalanceBefore = address(this).balance;
|
||||||
|
ICEther cETH = ICEther(cTokenAddress);
|
||||||
|
require(cETH.redeem(sellAmount) == COMPOUND_SUCCESS_CODE, "MixinCompound/FAILED_TO_REDEEM_CETHER");
|
||||||
|
uint256 etherBalanceAfter = address(this).balance;
|
||||||
|
uint256 receivedEtherBalance = etherBalanceAfter.safeSub(etherBalanceBefore);
|
||||||
|
WETH.deposit{value: receivedEtherBalance}();
|
||||||
|
} else {
|
||||||
|
ICToken cToken = ICToken(cTokenAddress);
|
||||||
|
require(cToken.redeem(sellAmount) == COMPOUND_SUCCESS_CODE, "MixinCompound/FAILED_TO_REDEEM_CTOKEN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buyToken.balanceOf(address(this)).safeSub(beforeBalance);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contracts-zero-ex",
|
"name": "@0x/contracts-zero-ex",
|
||||||
"version": "0.29.5",
|
"version": "0.30.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
|
"publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
|
||||||
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IFeature|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestMooniswap|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -56,10 +56,10 @@
|
|||||||
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
|
"homepage": "https://github.com/0xProject/protocol/tree/main/contracts/zero-ex",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@0x/abi-gen": "^5.6.2",
|
"@0x/abi-gen": "^5.6.2",
|
||||||
"@0x/contract-addresses": "^6.9.0",
|
"@0x/contract-addresses": "^6.11.0",
|
||||||
"@0x/contracts-erc20": "^3.3.23",
|
"@0x/contracts-erc20": "^3.3.25",
|
||||||
"@0x/contracts-gen": "^2.0.40",
|
"@0x/contracts-gen": "^2.0.40",
|
||||||
"@0x/contracts-test-utils": "^5.4.14",
|
"@0x/contracts-test-utils": "^5.4.16",
|
||||||
"@0x/dev-utils": "^4.2.9",
|
"@0x/dev-utils": "^4.2.9",
|
||||||
"@0x/order-utils": "^10.4.28",
|
"@0x/order-utils": "^10.4.28",
|
||||||
"@0x/sol-compiler": "^4.7.5",
|
"@0x/sol-compiler": "^4.7.5",
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.4.2",
|
"@0x/base-contract": "^6.4.2",
|
||||||
"@0x/protocol-utils": "^1.9.5",
|
"@0x/protocol-utils": "^1.10.1",
|
||||||
"@0x/subproviders": "^6.6.0",
|
"@0x/subproviders": "^6.6.0",
|
||||||
"@0x/types": "^3.3.4",
|
"@0x/types": "^3.3.4",
|
||||||
"@0x/typescript-typings": "^5.2.1",
|
"@0x/typescript-typings": "^5.2.1",
|
||||||
|
@@ -81,10 +81,12 @@ import * as LiquidityProviderFeature from '../test/generated-artifacts/Liquidity
|
|||||||
import * as LiquidityProviderSandbox from '../test/generated-artifacts/LiquidityProviderSandbox.json';
|
import * as LiquidityProviderSandbox from '../test/generated-artifacts/LiquidityProviderSandbox.json';
|
||||||
import * as LogMetadataTransformer from '../test/generated-artifacts/LogMetadataTransformer.json';
|
import * as LogMetadataTransformer from '../test/generated-artifacts/LogMetadataTransformer.json';
|
||||||
import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransactionsFeature.json';
|
import * as MetaTransactionsFeature from '../test/generated-artifacts/MetaTransactionsFeature.json';
|
||||||
|
import * as MixinAaveV2 from '../test/generated-artifacts/MixinAaveV2.json';
|
||||||
import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json';
|
import * as MixinBalancer from '../test/generated-artifacts/MixinBalancer.json';
|
||||||
import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json';
|
import * as MixinBalancerV2 from '../test/generated-artifacts/MixinBalancerV2.json';
|
||||||
import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json';
|
import * as MixinBancor from '../test/generated-artifacts/MixinBancor.json';
|
||||||
import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json';
|
import * as MixinCoFiX from '../test/generated-artifacts/MixinCoFiX.json';
|
||||||
|
import * as MixinCompound from '../test/generated-artifacts/MixinCompound.json';
|
||||||
import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json';
|
import * as MixinCryptoCom from '../test/generated-artifacts/MixinCryptoCom.json';
|
||||||
import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
|
import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
|
||||||
import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json';
|
import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json';
|
||||||
@@ -272,10 +274,12 @@ export const artifacts = {
|
|||||||
BridgeAdapter: BridgeAdapter as ContractArtifact,
|
BridgeAdapter: BridgeAdapter as ContractArtifact,
|
||||||
BridgeProtocols: BridgeProtocols as ContractArtifact,
|
BridgeProtocols: BridgeProtocols as ContractArtifact,
|
||||||
IBridgeAdapter: IBridgeAdapter as ContractArtifact,
|
IBridgeAdapter: IBridgeAdapter as ContractArtifact,
|
||||||
|
MixinAaveV2: MixinAaveV2 as ContractArtifact,
|
||||||
MixinBalancer: MixinBalancer as ContractArtifact,
|
MixinBalancer: MixinBalancer as ContractArtifact,
|
||||||
MixinBalancerV2: MixinBalancerV2 as ContractArtifact,
|
MixinBalancerV2: MixinBalancerV2 as ContractArtifact,
|
||||||
MixinBancor: MixinBancor as ContractArtifact,
|
MixinBancor: MixinBancor as ContractArtifact,
|
||||||
MixinCoFiX: MixinCoFiX as ContractArtifact,
|
MixinCoFiX: MixinCoFiX as ContractArtifact,
|
||||||
|
MixinCompound: MixinCompound as ContractArtifact,
|
||||||
MixinCryptoCom: MixinCryptoCom as ContractArtifact,
|
MixinCryptoCom: MixinCryptoCom as ContractArtifact,
|
||||||
MixinCurve: MixinCurve as ContractArtifact,
|
MixinCurve: MixinCurve as ContractArtifact,
|
||||||
MixinCurveV2: MixinCurveV2 as ContractArtifact,
|
MixinCurveV2: MixinCurveV2 as ContractArtifact,
|
||||||
|
@@ -79,10 +79,12 @@ export * from '../test/generated-wrappers/liquidity_provider_feature';
|
|||||||
export * from '../test/generated-wrappers/liquidity_provider_sandbox';
|
export * from '../test/generated-wrappers/liquidity_provider_sandbox';
|
||||||
export * from '../test/generated-wrappers/log_metadata_transformer';
|
export * from '../test/generated-wrappers/log_metadata_transformer';
|
||||||
export * from '../test/generated-wrappers/meta_transactions_feature';
|
export * from '../test/generated-wrappers/meta_transactions_feature';
|
||||||
|
export * from '../test/generated-wrappers/mixin_aave_v2';
|
||||||
export * from '../test/generated-wrappers/mixin_balancer';
|
export * from '../test/generated-wrappers/mixin_balancer';
|
||||||
export * from '../test/generated-wrappers/mixin_balancer_v2';
|
export * from '../test/generated-wrappers/mixin_balancer_v2';
|
||||||
export * from '../test/generated-wrappers/mixin_bancor';
|
export * from '../test/generated-wrappers/mixin_bancor';
|
||||||
export * from '../test/generated-wrappers/mixin_co_fi_x';
|
export * from '../test/generated-wrappers/mixin_co_fi_x';
|
||||||
|
export * from '../test/generated-wrappers/mixin_compound';
|
||||||
export * from '../test/generated-wrappers/mixin_crypto_com';
|
export * from '../test/generated-wrappers/mixin_crypto_com';
|
||||||
export * from '../test/generated-wrappers/mixin_curve';
|
export * from '../test/generated-wrappers/mixin_curve';
|
||||||
export * from '../test/generated-wrappers/mixin_curve_v2';
|
export * from '../test/generated-wrappers/mixin_curve_v2';
|
||||||
|
@@ -112,10 +112,12 @@
|
|||||||
"test/generated-artifacts/LiquidityProviderSandbox.json",
|
"test/generated-artifacts/LiquidityProviderSandbox.json",
|
||||||
"test/generated-artifacts/LogMetadataTransformer.json",
|
"test/generated-artifacts/LogMetadataTransformer.json",
|
||||||
"test/generated-artifacts/MetaTransactionsFeature.json",
|
"test/generated-artifacts/MetaTransactionsFeature.json",
|
||||||
|
"test/generated-artifacts/MixinAaveV2.json",
|
||||||
"test/generated-artifacts/MixinBalancer.json",
|
"test/generated-artifacts/MixinBalancer.json",
|
||||||
"test/generated-artifacts/MixinBalancerV2.json",
|
"test/generated-artifacts/MixinBalancerV2.json",
|
||||||
"test/generated-artifacts/MixinBancor.json",
|
"test/generated-artifacts/MixinBancor.json",
|
||||||
"test/generated-artifacts/MixinCoFiX.json",
|
"test/generated-artifacts/MixinCoFiX.json",
|
||||||
|
"test/generated-artifacts/MixinCompound.json",
|
||||||
"test/generated-artifacts/MixinCryptoCom.json",
|
"test/generated-artifacts/MixinCryptoCom.json",
|
||||||
"test/generated-artifacts/MixinCurve.json",
|
"test/generated-artifacts/MixinCurve.json",
|
||||||
"test/generated-artifacts/MixinCurveV2.json",
|
"test/generated-artifacts/MixinCurveV2.json",
|
||||||
|
@@ -1,4 +1,177 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "16.49.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add more curve pools",
|
||||||
|
"pr": 409
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1643407900
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.48.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Use `MIM` as an intermediate asset on `Fantom`",
|
||||||
|
"pr": 405
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1643148019
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.47.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Adding support for Synapse on all networks",
|
||||||
|
"pr": 400
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1643136662
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.46.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Enable `Curve` ETH/CVX pool",
|
||||||
|
"pr": 394
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1641863395
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.45.2",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Handle 0 output samples and negative adjusted rate native orders in routing",
|
||||||
|
"pr": 387
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1641827361
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.45.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Update `Celo` intermediate tokens",
|
||||||
|
"pr": 390
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1641359319
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.45.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Capture router timings",
|
||||||
|
"pr": 388
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1641308410
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.44.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Update neon-router and use router estimated output amount",
|
||||||
|
"pr": 354
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1640778328
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.43.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "`UniswapV3` support for `Optimism`",
|
||||||
|
"pr": 385
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1640364306
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.42.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "`UniswapV3` support for `Polygon`",
|
||||||
|
"pr": 382
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Update `Beethoven` Graphql url",
|
||||||
|
"pr": 383
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1640124159
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.41.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Update mcusd contract address, and made celo native asset",
|
||||||
|
"pr": 376
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1638827302
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.40.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add `AaveV2` and `Compound` deposit/withdrawal liquidity source",
|
||||||
|
"pr": 321
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1638390144
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.39.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Curve ETH/CRV pool",
|
||||||
|
"pr": 378
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.38.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Capture sampler metrics",
|
||||||
|
"pr": 374
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1638228231
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.37.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Changed Sushiswap router address",
|
||||||
|
"pr": 373
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1637349338
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.36.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Specify liquid routes for FEI/TRIBE FXS/FRAX and OHM/FRAX",
|
||||||
|
"pr": 371
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1637290768
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "16.35.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add Beethoven X, MorpheusSwap and JetSwap to Fantom",
|
||||||
|
"pr": 370
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1637206290
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "16.34.0",
|
"version": "16.34.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,75 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v16.49.0 - _January 28, 2022_
|
||||||
|
|
||||||
|
* Add more curve pools (#409)
|
||||||
|
|
||||||
|
## v16.48.0 - _January 25, 2022_
|
||||||
|
|
||||||
|
* Use `MIM` as an intermediate asset on `Fantom` (#405)
|
||||||
|
|
||||||
|
## v16.47.0 - _January 25, 2022_
|
||||||
|
|
||||||
|
* Adding support for Synapse on all networks (#400)
|
||||||
|
|
||||||
|
## v16.46.0 - _January 11, 2022_
|
||||||
|
|
||||||
|
* Enable `Curve` ETH/CVX pool (#394)
|
||||||
|
|
||||||
|
## v16.45.2 - _January 10, 2022_
|
||||||
|
|
||||||
|
* Handle 0 output samples and negative adjusted rate native orders in routing (#387)
|
||||||
|
|
||||||
|
## v16.45.1 - _January 5, 2022_
|
||||||
|
|
||||||
|
* Update `Celo` intermediate tokens (#390)
|
||||||
|
|
||||||
|
## v16.45.0 - _January 4, 2022_
|
||||||
|
|
||||||
|
* Capture router timings (#388)
|
||||||
|
|
||||||
|
## v16.44.0 - _December 29, 2021_
|
||||||
|
|
||||||
|
* Update neon-router and use router estimated output amount (#354)
|
||||||
|
|
||||||
|
## v16.43.0 - _December 24, 2021_
|
||||||
|
|
||||||
|
* `UniswapV3` support for `Optimism` (#385)
|
||||||
|
|
||||||
|
## v16.42.0 - _December 21, 2021_
|
||||||
|
|
||||||
|
* `UniswapV3` support for `Polygon` (#382)
|
||||||
|
* Update `Beethoven` Graphql url (#383)
|
||||||
|
|
||||||
|
## v16.41.0 - _December 6, 2021_
|
||||||
|
|
||||||
|
* Update mcusd contract address, and made celo native asset (#376)
|
||||||
|
|
||||||
|
## v16.40.0 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Add `AaveV2` and `Compound` deposit/withdrawal liquidity source (#321)
|
||||||
|
|
||||||
|
## v16.39.0 - _Invalid date_
|
||||||
|
|
||||||
|
* Curve ETH/CRV pool (#378)
|
||||||
|
|
||||||
|
## v16.38.0 - _November 29, 2021_
|
||||||
|
|
||||||
|
* Capture sampler metrics (#374)
|
||||||
|
|
||||||
|
## v16.37.0 - _November 19, 2021_
|
||||||
|
|
||||||
|
* Changed Sushiswap router address (#373)
|
||||||
|
|
||||||
|
## v16.36.0 - _November 19, 2021_
|
||||||
|
|
||||||
|
* Specify liquid routes for FEI/TRIBE FXS/FRAX and OHM/FRAX (#371)
|
||||||
|
|
||||||
|
## v16.35.0 - _November 18, 2021_
|
||||||
|
|
||||||
|
* Add Beethoven X, MorpheusSwap and JetSwap to Fantom (#370)
|
||||||
|
|
||||||
## v16.34.0 - _November 16, 2021_
|
## v16.34.0 - _November 16, 2021_
|
||||||
|
|
||||||
* Add support Celo (#367)
|
* Add support Celo (#367)
|
||||||
|
96
packages/asset-swapper/contracts/src/CompoundSampler.sol
Normal file
96
packages/asset-swapper/contracts/src/CompoundSampler.sol
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
// 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;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "./SamplerUtils.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/v06/IERC20TokenV06.sol";
|
||||||
|
|
||||||
|
// Minimal CToken interface
|
||||||
|
interface ICToken {
|
||||||
|
function mint(uint mintAmount) external returns (uint);
|
||||||
|
function redeem(uint redeemTokens) external returns (uint);
|
||||||
|
function redeemUnderlying(uint redeemAmount) external returns (uint);
|
||||||
|
function exchangeRateStored() external view returns (uint);
|
||||||
|
function decimals() external view returns (uint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract CompoundSampler is SamplerUtils {
|
||||||
|
uint256 constant private EXCHANGE_RATE_SCALE = 1e10;
|
||||||
|
|
||||||
|
function sampleSellsFromCompound(
|
||||||
|
ICToken cToken,
|
||||||
|
IERC20TokenV06 takerToken,
|
||||||
|
IERC20TokenV06 makerToken,
|
||||||
|
uint256[] memory takerTokenAmounts
|
||||||
|
)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256[] memory makerTokenAmounts)
|
||||||
|
{
|
||||||
|
uint256 numSamples = takerTokenAmounts.length;
|
||||||
|
makerTokenAmounts = new uint256[](numSamples);
|
||||||
|
// Exchange rate is scaled by 1 * 10^(18 - 8 + Underlying Token Decimals
|
||||||
|
uint256 exchangeRate = cToken.exchangeRateStored();
|
||||||
|
uint256 cTokenDecimals = uint256(cToken.decimals());
|
||||||
|
|
||||||
|
if (address(makerToken) == address(cToken)) {
|
||||||
|
// mint
|
||||||
|
for (uint256 i = 0; i < numSamples; i++) {
|
||||||
|
makerTokenAmounts[i] = (takerTokenAmounts[i] * EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals) / exchangeRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (address(takerToken) == address(cToken)) {
|
||||||
|
// redeem
|
||||||
|
for (uint256 i = 0; i < numSamples; i++) {
|
||||||
|
makerTokenAmounts[i] = (takerTokenAmounts[i] * exchangeRate) / (EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sampleBuysFromCompound(
|
||||||
|
ICToken cToken,
|
||||||
|
IERC20TokenV06 takerToken,
|
||||||
|
IERC20TokenV06 makerToken,
|
||||||
|
uint256[] memory makerTokenAmounts
|
||||||
|
)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256[] memory takerTokenAmounts)
|
||||||
|
{
|
||||||
|
uint256 numSamples = makerTokenAmounts.length;
|
||||||
|
takerTokenAmounts = new uint256[](numSamples);
|
||||||
|
// Exchange rate is scaled by 1 * 10^(18 - 8 + Underlying Token Decimals
|
||||||
|
uint256 exchangeRate = cToken.exchangeRateStored();
|
||||||
|
uint256 cTokenDecimals = uint256(cToken.decimals());
|
||||||
|
|
||||||
|
if (address(makerToken) == address(cToken)) {
|
||||||
|
// mint
|
||||||
|
for (uint256 i = 0; i < numSamples; i++) {
|
||||||
|
takerTokenAmounts[i] = makerTokenAmounts[i] * exchangeRate / (EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals);
|
||||||
|
}
|
||||||
|
} else if (address(takerToken) == address(cToken)) {
|
||||||
|
// redeem
|
||||||
|
for (uint256 i = 0; i < numSamples; i++) {
|
||||||
|
takerTokenAmounts[i] = (makerTokenAmounts[i] * EXCHANGE_RATE_SCALE * 10 ** cTokenDecimals)/exchangeRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -23,6 +23,7 @@ pragma experimental ABIEncoderV2;
|
|||||||
import "./BalancerSampler.sol";
|
import "./BalancerSampler.sol";
|
||||||
import "./BalancerV2Sampler.sol";
|
import "./BalancerV2Sampler.sol";
|
||||||
import "./BancorSampler.sol";
|
import "./BancorSampler.sol";
|
||||||
|
import "./CompoundSampler.sol";
|
||||||
import "./CurveSampler.sol";
|
import "./CurveSampler.sol";
|
||||||
import "./DODOSampler.sol";
|
import "./DODOSampler.sol";
|
||||||
import "./DODOV2Sampler.sol";
|
import "./DODOV2Sampler.sol";
|
||||||
@@ -48,6 +49,7 @@ contract ERC20BridgeSampler is
|
|||||||
BalancerSampler,
|
BalancerSampler,
|
||||||
BalancerV2Sampler,
|
BalancerV2Sampler,
|
||||||
BancorSampler,
|
BancorSampler,
|
||||||
|
CompoundSampler,
|
||||||
CurveSampler,
|
CurveSampler,
|
||||||
DODOSampler,
|
DODOSampler,
|
||||||
DODOV2Sampler,
|
DODOV2Sampler,
|
||||||
|
@@ -51,7 +51,7 @@ interface IUniswapV3Pool {
|
|||||||
contract UniswapV3Sampler
|
contract UniswapV3Sampler
|
||||||
{
|
{
|
||||||
/// @dev Gas limit for UniswapV3 calls. This is 100% a guess.
|
/// @dev Gas limit for UniswapV3 calls. This is 100% a guess.
|
||||||
uint256 constant private QUOTE_GAS = 300e3;
|
uint256 constant private QUOTE_GAS = 600e3;
|
||||||
|
|
||||||
/// @dev Sample sell quotes from UniswapV3.
|
/// @dev Sample sell quotes from UniswapV3.
|
||||||
/// @param quoter UniswapV3 Quoter contract.
|
/// @param quoter UniswapV3 Quoter contract.
|
||||||
|
@@ -77,4 +77,19 @@ contract UtilitySampler {
|
|||||||
assembly { size := extcodesize(account) }
|
assembly { size := extcodesize(account) }
|
||||||
return size > 0;
|
return size > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGasLeft()
|
||||||
|
public
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return gasleft();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBlockNumber()
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return block.number;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/asset-swapper",
|
"name": "@0x/asset-swapper",
|
||||||
"version": "16.34.0",
|
"version": "16.49.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -39,7 +39,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|BalancerV2Sampler|BancorSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|IBalancer|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
|
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|DummyLiquidityProvider|ERC20BridgeSampler|FakeTaker|IBalancer|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
|
||||||
"postpublish": {
|
"postpublish": {
|
||||||
"assets": []
|
"assets": []
|
||||||
}
|
}
|
||||||
@@ -60,14 +60,14 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.29",
|
"@0x/assert": "^3.0.29",
|
||||||
"@0x/base-contract": "^6.4.2",
|
"@0x/base-contract": "^6.4.2",
|
||||||
"@0x/contract-addresses": "^6.9.0",
|
"@0x/contract-addresses": "^6.11.0",
|
||||||
"@0x/contract-wrappers": "^13.18.3",
|
"@0x/contract-wrappers": "^13.18.5",
|
||||||
"@0x/contracts-erc20": "^3.3.23",
|
"@0x/contracts-erc20": "^3.3.25",
|
||||||
"@0x/contracts-zero-ex": "^0.29.5",
|
"@0x/contracts-zero-ex": "^0.30.1",
|
||||||
"@0x/dev-utils": "^4.2.9",
|
"@0x/dev-utils": "^4.2.9",
|
||||||
"@0x/json-schemas": "^6.3.0",
|
"@0x/json-schemas": "^6.3.0",
|
||||||
"@0x/neon-router": "^0.2.1",
|
"@0x/neon-router": "^0.3.1",
|
||||||
"@0x/protocol-utils": "^1.9.5",
|
"@0x/protocol-utils": "^1.10.1",
|
||||||
"@0x/quote-server": "^6.0.6",
|
"@0x/quote-server": "^6.0.6",
|
||||||
"@0x/types": "^3.3.4",
|
"@0x/types": "^3.3.4",
|
||||||
"@0x/typescript-typings": "^5.2.1",
|
"@0x/typescript-typings": "^5.2.1",
|
||||||
@@ -98,10 +98,10 @@
|
|||||||
"@0x/contracts-exchange": "^3.2.38",
|
"@0x/contracts-exchange": "^3.2.38",
|
||||||
"@0x/contracts-exchange-libs": "^4.3.37",
|
"@0x/contracts-exchange-libs": "^4.3.37",
|
||||||
"@0x/contracts-gen": "^2.0.40",
|
"@0x/contracts-gen": "^2.0.40",
|
||||||
"@0x/contracts-test-utils": "^5.4.14",
|
"@0x/contracts-test-utils": "^5.4.16",
|
||||||
"@0x/contracts-utils": "^4.8.4",
|
"@0x/contracts-utils": "^4.8.6",
|
||||||
"@0x/mesh-rpc-client": "^9.4.2",
|
"@0x/mesh-rpc-client": "^9.4.2",
|
||||||
"@0x/migrations": "^8.1.12",
|
"@0x/migrations": "^8.1.14",
|
||||||
"@0x/sol-compiler": "^4.7.5",
|
"@0x/sol-compiler": "^4.7.5",
|
||||||
"@0x/subproviders": "^6.6.0",
|
"@0x/subproviders": "^6.6.0",
|
||||||
"@0x/ts-doc-gen": "^0.0.28",
|
"@0x/ts-doc-gen": "^0.0.28",
|
||||||
|
@@ -28,7 +28,6 @@ const ONE_SECOND_MS = 1000;
|
|||||||
const ONE_MINUTE_SECS = 60;
|
const ONE_MINUTE_SECS = 60;
|
||||||
const ONE_MINUTE_MS = ONE_SECOND_MS * ONE_MINUTE_SECS;
|
const ONE_MINUTE_MS = ONE_SECOND_MS * ONE_MINUTE_SECS;
|
||||||
const DEFAULT_PER_PAGE = 1000;
|
const DEFAULT_PER_PAGE = 1000;
|
||||||
const ZERO_AMOUNT = new BigNumber(0);
|
|
||||||
const ALT_MM_IMPUTED_INDICATIVE_EXPIRY_SECONDS = 180;
|
const ALT_MM_IMPUTED_INDICATIVE_EXPIRY_SECONDS = 180;
|
||||||
|
|
||||||
const DEFAULT_ORDER_PRUNER_OPTS: OrderPrunerOpts = {
|
const DEFAULT_ORDER_PRUNER_OPTS: OrderPrunerOpts = {
|
||||||
@@ -43,6 +42,7 @@ const PROTOCOL_FEE_MULTIPLIER = new BigNumber(0);
|
|||||||
// default 50% buffer for selecting native orders to be aggregated with other sources
|
// default 50% buffer for selecting native orders to be aggregated with other sources
|
||||||
const MARKET_UTILS_AMOUNT_BUFFER_PERCENTAGE = 0.5;
|
const MARKET_UTILS_AMOUNT_BUFFER_PERCENTAGE = 0.5;
|
||||||
|
|
||||||
|
export const ZERO_AMOUNT = new BigNumber(0);
|
||||||
const DEFAULT_SWAP_QUOTER_OPTS: SwapQuoterOpts = {
|
const DEFAULT_SWAP_QUOTER_OPTS: SwapQuoterOpts = {
|
||||||
chainId: ChainId.Mainnet,
|
chainId: ChainId.Mainnet,
|
||||||
orderRefreshIntervalMs: 10000, // 10 seconds
|
orderRefreshIntervalMs: 10000, // 10 seconds
|
||||||
|
@@ -113,6 +113,7 @@ export {
|
|||||||
SwapQuoterError,
|
SwapQuoterError,
|
||||||
SwapQuoterOpts,
|
SwapQuoterOpts,
|
||||||
SwapQuoterRfqOpts,
|
SwapQuoterRfqOpts,
|
||||||
|
SamplerMetrics,
|
||||||
} from './types';
|
} from './types';
|
||||||
export { affiliateFeeUtils } from './utils/affiliate_fee_utils';
|
export { affiliateFeeUtils } from './utils/affiliate_fee_utils';
|
||||||
export {
|
export {
|
||||||
|
57
packages/asset-swapper/src/noop_samplers/AaveV2Sampler.ts
Normal file
57
packages/asset-swapper/src/noop_samplers/AaveV2Sampler.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { BigNumber } from '@0x/utils';
|
||||||
|
|
||||||
|
import { ZERO_AMOUNT } from '../constants';
|
||||||
|
export interface AaveInfo {
|
||||||
|
lendingPool: string;
|
||||||
|
aToken: string;
|
||||||
|
underlyingToken: string;
|
||||||
|
}
|
||||||
|
// tslint:disable-next-line:no-unnecessary-class
|
||||||
|
export class AaveV2Sampler {
|
||||||
|
public static sampleSellsFromAaveV2(
|
||||||
|
aaveInfo: AaveInfo,
|
||||||
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
takerTokenAmounts: BigNumber[],
|
||||||
|
): BigNumber[] {
|
||||||
|
// Deposit/Withdrawal underlying <-> aToken is always 1:1
|
||||||
|
if (
|
||||||
|
(takerToken.toLowerCase() === aaveInfo.aToken.toLowerCase() &&
|
||||||
|
makerToken.toLowerCase() === aaveInfo.underlyingToken.toLowerCase()) ||
|
||||||
|
(takerToken.toLowerCase() === aaveInfo.underlyingToken.toLowerCase() &&
|
||||||
|
makerToken.toLowerCase() === aaveInfo.aToken.toLowerCase())
|
||||||
|
) {
|
||||||
|
return takerTokenAmounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not matching the reserve return 0 results
|
||||||
|
const numSamples = takerTokenAmounts.length;
|
||||||
|
|
||||||
|
const makerTokenAmounts = new Array(numSamples);
|
||||||
|
makerTokenAmounts.fill(ZERO_AMOUNT);
|
||||||
|
return makerTokenAmounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static sampleBuysFromAaveV2(
|
||||||
|
aaveInfo: AaveInfo,
|
||||||
|
takerToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
makerTokenAmounts: BigNumber[],
|
||||||
|
): BigNumber[] {
|
||||||
|
// Deposit/Withdrawal underlying <-> aToken is always 1:1
|
||||||
|
if (
|
||||||
|
(takerToken.toLowerCase() === aaveInfo.aToken.toLowerCase() &&
|
||||||
|
makerToken.toLowerCase() === aaveInfo.underlyingToken.toLowerCase()) ||
|
||||||
|
(takerToken.toLowerCase() === aaveInfo.underlyingToken.toLowerCase() &&
|
||||||
|
makerToken.toLowerCase() === aaveInfo.aToken.toLowerCase())
|
||||||
|
) {
|
||||||
|
return makerTokenAmounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not matching the reserve return 0 results
|
||||||
|
const numSamples = makerTokenAmounts.length;
|
||||||
|
const takerTokenAmounts = new Array(numSamples);
|
||||||
|
takerTokenAmounts.fill(ZERO_AMOUNT);
|
||||||
|
return takerTokenAmounts;
|
||||||
|
}
|
||||||
|
}
|
@@ -19,6 +19,7 @@ import {
|
|||||||
OptimizedMarketOrder,
|
OptimizedMarketOrder,
|
||||||
TokenAdjacencyGraph,
|
TokenAdjacencyGraph,
|
||||||
} from './utils/market_operation_utils/types';
|
} from './utils/market_operation_utils/types';
|
||||||
|
export { SamplerMetrics } from './utils/market_operation_utils/types';
|
||||||
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from './utils/quote_report_generator';
|
import { ExtendedQuoteReportSources, PriceComparisonsReport, QuoteReport } from './utils/quote_report_generator';
|
||||||
import { MetricsProxy } from './utils/quote_requestor';
|
import { MetricsProxy } from './utils/quote_requestor';
|
||||||
|
|
||||||
|
@@ -223,7 +223,17 @@ export async function returnQuoteFromAltMMAsync<ResponseT>(
|
|||||||
cancelToken,
|
cancelToken,
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
warningLogger(err, `Alt RFQ MM request failed`);
|
if (err.response) {
|
||||||
|
// request was made and market maker responded
|
||||||
|
warningLogger(
|
||||||
|
{ data: err.response.data, status: err.response.status, headers: err.response.headers },
|
||||||
|
`Alt RFQ MM request failed`,
|
||||||
|
);
|
||||||
|
} else if (err.request) {
|
||||||
|
warningLogger({}, 'Alt RFQ MM no response received');
|
||||||
|
} else {
|
||||||
|
warningLogger({ err: err.message }, 'Failed to construct Alt RFQ MM request');
|
||||||
|
}
|
||||||
throw new Error(`Alt RFQ MM request failed`);
|
throw new Error(`Alt RFQ MM request failed`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -0,0 +1,106 @@
|
|||||||
|
import { logUtils } from '@0x/utils';
|
||||||
|
import { gql, request } from 'graphql-request';
|
||||||
|
|
||||||
|
import { constants } from '../../constants';
|
||||||
|
|
||||||
|
const RESERVES_GQL_QUERY = gql`
|
||||||
|
{
|
||||||
|
reserves(
|
||||||
|
first: 300
|
||||||
|
where: { isActive: true, isFrozen: false }
|
||||||
|
orderBy: totalLiquidity
|
||||||
|
orderDirection: desc
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
underlyingAsset
|
||||||
|
aToken {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
pool {
|
||||||
|
id
|
||||||
|
lendingPool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export interface AaveReserve {
|
||||||
|
id: string;
|
||||||
|
underlyingAsset: string;
|
||||||
|
aToken: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
pool: {
|
||||||
|
id: string;
|
||||||
|
lendingPool: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Cache {
|
||||||
|
[key: string]: AaveReserve[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line:custom-no-magic-numbers
|
||||||
|
const RESERVES_REFRESH_INTERVAL_MS = 30 * constants.ONE_MINUTE_MS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches Aave V2 reserve information from the official subgraph(s).
|
||||||
|
* The reserve information is updated every 30 minutes and cached
|
||||||
|
* so that it can be accessed with the underlying token's address
|
||||||
|
*/
|
||||||
|
export class AaveV2ReservesCache {
|
||||||
|
private _cache: Cache = {};
|
||||||
|
constructor(private readonly _subgraphUrl: string) {
|
||||||
|
const resfreshReserves = async () => this.fetchAndUpdateReservesAsync();
|
||||||
|
// tslint:disable-next-line:no-floating-promises
|
||||||
|
resfreshReserves();
|
||||||
|
setInterval(resfreshReserves, RESERVES_REFRESH_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Fetches Aave V2 reserves from the subgraph and updates the cache
|
||||||
|
*/
|
||||||
|
public async fetchAndUpdateReservesAsync(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const { reserves } = await request<{ reserves: AaveReserve[] }>(this._subgraphUrl, RESERVES_GQL_QUERY);
|
||||||
|
const newCache = reserves.reduce<Cache>((memo, reserve) => {
|
||||||
|
const underlyingAsset = reserve.underlyingAsset.toLowerCase();
|
||||||
|
if (!memo[underlyingAsset]) {
|
||||||
|
memo[underlyingAsset] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
memo[underlyingAsset].push(reserve);
|
||||||
|
return memo;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
this._cache = newCache;
|
||||||
|
} catch (err) {
|
||||||
|
logUtils.warn(`Failed to update Aave V2 reserves cache: ${err.message}`);
|
||||||
|
// Empty cache just to be safe
|
||||||
|
this._cache = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public get(takerToken: string, makerToken: string): AaveReserve | undefined {
|
||||||
|
// Deposit takerToken into reserve
|
||||||
|
if (this._cache[takerToken.toLowerCase()]) {
|
||||||
|
const matchingReserve = this._cache[takerToken.toLowerCase()].find(
|
||||||
|
r => r.aToken.id === makerToken.toLowerCase(),
|
||||||
|
);
|
||||||
|
if (matchingReserve) {
|
||||||
|
return matchingReserve;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Withdraw makerToken from reserve
|
||||||
|
if (this._cache[makerToken.toLowerCase()]) {
|
||||||
|
const matchingReserve = this._cache[makerToken.toLowerCase()].find(
|
||||||
|
r => r.aToken.id === takerToken.toLowerCase(),
|
||||||
|
);
|
||||||
|
if (matchingReserve) {
|
||||||
|
return matchingReserve;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
@@ -14,6 +14,7 @@ import {
|
|||||||
CURVE_AVALANCHE_INFOS,
|
CURVE_AVALANCHE_INFOS,
|
||||||
CURVE_FANTOM_INFOS,
|
CURVE_FANTOM_INFOS,
|
||||||
CURVE_MAINNET_INFOS,
|
CURVE_MAINNET_INFOS,
|
||||||
|
CURVE_OPTIMISM_INFOS,
|
||||||
CURVE_POLYGON_INFOS,
|
CURVE_POLYGON_INFOS,
|
||||||
CURVE_V2_AVALANCHE_INFOS,
|
CURVE_V2_AVALANCHE_INFOS,
|
||||||
CURVE_V2_FANTOM_INFOS,
|
CURVE_V2_FANTOM_INFOS,
|
||||||
@@ -30,6 +31,7 @@ import {
|
|||||||
KYBER_BRIDGED_LIQUIDITY_PREFIX,
|
KYBER_BRIDGED_LIQUIDITY_PREFIX,
|
||||||
MAX_DODOV2_POOLS_QUERIED,
|
MAX_DODOV2_POOLS_QUERIED,
|
||||||
MAX_KYBER_RESERVES_QUERIED,
|
MAX_KYBER_RESERVES_QUERIED,
|
||||||
|
MORPHEUSSWAP_ROUTER_BY_CHAIN_ID,
|
||||||
MSTABLE_POOLS_BY_CHAIN_ID,
|
MSTABLE_POOLS_BY_CHAIN_ID,
|
||||||
NERVE_BSC_INFOS,
|
NERVE_BSC_INFOS,
|
||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
@@ -48,6 +50,12 @@ import {
|
|||||||
SPOOKYSWAP_ROUTER_BY_CHAIN_ID,
|
SPOOKYSWAP_ROUTER_BY_CHAIN_ID,
|
||||||
SUSHISWAP_ROUTER_BY_CHAIN_ID,
|
SUSHISWAP_ROUTER_BY_CHAIN_ID,
|
||||||
SWERVE_MAINNET_INFOS,
|
SWERVE_MAINNET_INFOS,
|
||||||
|
SYNAPSE_AVALANCHE_INFOS,
|
||||||
|
SYNAPSE_BSC_INFOS,
|
||||||
|
SYNAPSE_FANTOM_INFOS,
|
||||||
|
SYNAPSE_MAINNET_INFOS,
|
||||||
|
SYNAPSE_OPTIMISM_INFOS,
|
||||||
|
SYNAPSE_POLYGON_INFOS,
|
||||||
TRADER_JOE_ROUTER_BY_CHAIN_ID,
|
TRADER_JOE_ROUTER_BY_CHAIN_ID,
|
||||||
UBESWAP_ROUTER_BY_CHAIN_ID,
|
UBESWAP_ROUTER_BY_CHAIN_ID,
|
||||||
UNISWAPV2_ROUTER_BY_CHAIN_ID,
|
UNISWAPV2_ROUTER_BY_CHAIN_ID,
|
||||||
@@ -158,6 +166,15 @@ export function getCurveInfosForPair(chainId: ChainId, takerToken: string, maker
|
|||||||
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case ChainId.Optimism:
|
||||||
|
return Object.values(CURVE_OPTIMISM_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaTokens === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -246,6 +263,67 @@ export function getNerveInfosForPair(chainId: ChainId, takerToken: string, maker
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSynapseInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
|
||||||
|
switch (chainId) {
|
||||||
|
case ChainId.Mainnet:
|
||||||
|
return Object.values(SYNAPSE_MAINNET_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaTokens === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case ChainId.Optimism:
|
||||||
|
return Object.values(SYNAPSE_OPTIMISM_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaTokens === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case ChainId.BSC:
|
||||||
|
return Object.values(SYNAPSE_BSC_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaTokens === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case ChainId.Polygon:
|
||||||
|
return Object.values(SYNAPSE_POLYGON_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaTokens === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case ChainId.Fantom:
|
||||||
|
return Object.values(SYNAPSE_FANTOM_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaTokens === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case ChainId.Avalanche:
|
||||||
|
return Object.values(SYNAPSE_AVALANCHE_INFOS).filter(c =>
|
||||||
|
[makerToken, takerToken].every(
|
||||||
|
t =>
|
||||||
|
(c.tokens.includes(t) && c.metaTokens === undefined) ||
|
||||||
|
(c.tokens.includes(t) &&
|
||||||
|
[makerToken, takerToken].filter(v => c.metaTokens?.includes(v)).length > 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getFirebirdOneSwapInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
|
export function getFirebirdOneSwapInfosForPair(chainId: ChainId, takerToken: string, makerToken: string): CurveInfo[] {
|
||||||
if (chainId === ChainId.BSC) {
|
if (chainId === ChainId.BSC) {
|
||||||
return Object.values(FIREBIRDONESWAP_BSC_INFOS).filter(c =>
|
return Object.values(FIREBIRDONESWAP_BSC_INFOS).filter(c =>
|
||||||
@@ -405,6 +483,7 @@ export function getCurveLikeInfosForPair(
|
|||||||
| ERC20BridgeSource.Swerve
|
| ERC20BridgeSource.Swerve
|
||||||
| ERC20BridgeSource.SnowSwap
|
| ERC20BridgeSource.SnowSwap
|
||||||
| ERC20BridgeSource.Nerve
|
| ERC20BridgeSource.Nerve
|
||||||
|
| ERC20BridgeSource.Synapse
|
||||||
| ERC20BridgeSource.Belt
|
| ERC20BridgeSource.Belt
|
||||||
| ERC20BridgeSource.Ellipsis
|
| ERC20BridgeSource.Ellipsis
|
||||||
| ERC20BridgeSource.Smoothy
|
| ERC20BridgeSource.Smoothy
|
||||||
@@ -431,6 +510,9 @@ export function getCurveLikeInfosForPair(
|
|||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
pools = getNerveInfosForPair(chainId, takerToken, makerToken);
|
pools = getNerveInfosForPair(chainId, takerToken, makerToken);
|
||||||
break;
|
break;
|
||||||
|
case ERC20BridgeSource.Synapse:
|
||||||
|
pools = getSynapseInfosForPair(chainId, takerToken, makerToken);
|
||||||
|
break;
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
pools = getBeltInfosForPair(chainId, takerToken, makerToken);
|
pools = getBeltInfosForPair(chainId, takerToken, makerToken);
|
||||||
break;
|
break;
|
||||||
@@ -488,6 +570,7 @@ export function uniswapV2LikeRouterAddress(
|
|||||||
| ERC20BridgeSource.TraderJoe
|
| ERC20BridgeSource.TraderJoe
|
||||||
| ERC20BridgeSource.Pangolin
|
| ERC20BridgeSource.Pangolin
|
||||||
| ERC20BridgeSource.UbeSwap
|
| ERC20BridgeSource.UbeSwap
|
||||||
|
| ERC20BridgeSource.MorpheusSwap
|
||||||
| ERC20BridgeSource.SpookySwap
|
| ERC20BridgeSource.SpookySwap
|
||||||
| ERC20BridgeSource.SpiritSwap,
|
| ERC20BridgeSource.SpiritSwap,
|
||||||
): string {
|
): string {
|
||||||
@@ -532,6 +615,8 @@ export function uniswapV2LikeRouterAddress(
|
|||||||
return TRADER_JOE_ROUTER_BY_CHAIN_ID[chainId];
|
return TRADER_JOE_ROUTER_BY_CHAIN_ID[chainId];
|
||||||
case ERC20BridgeSource.UbeSwap:
|
case ERC20BridgeSource.UbeSwap:
|
||||||
return UBESWAP_ROUTER_BY_CHAIN_ID[chainId];
|
return UBESWAP_ROUTER_BY_CHAIN_ID[chainId];
|
||||||
|
case ERC20BridgeSource.MorpheusSwap:
|
||||||
|
return MORPHEUSSWAP_ROUTER_BY_CHAIN_ID[chainId];
|
||||||
case ERC20BridgeSource.SpookySwap:
|
case ERC20BridgeSource.SpookySwap:
|
||||||
return SPOOKYSWAP_ROUTER_BY_CHAIN_ID[chainId];
|
return SPOOKYSWAP_ROUTER_BY_CHAIN_ID[chainId];
|
||||||
case ERC20BridgeSource.SpiritSwap:
|
case ERC20BridgeSource.SpiritSwap:
|
||||||
|
@@ -0,0 +1,78 @@
|
|||||||
|
import { logUtils } from '@0x/utils';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import { constants } from '../../constants';
|
||||||
|
|
||||||
|
export interface CToken {
|
||||||
|
tokenAddress: string;
|
||||||
|
underlyingAddress: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CTokenApiResponse {
|
||||||
|
cToken: Array<{
|
||||||
|
token_address: string;
|
||||||
|
underlying_address: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Cache {
|
||||||
|
[key: string]: CToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line:custom-no-magic-numbers
|
||||||
|
const CTOKEN_REFRESH_INTERVAL_MS = 30 * constants.ONE_MINUTE_MS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a list of CTokens from Compound's official API.
|
||||||
|
* The token information is updated every 30 minutes and cached
|
||||||
|
* so that it can be accessed with the underlying token's address.
|
||||||
|
*/
|
||||||
|
export class CompoundCTokenCache {
|
||||||
|
private _cache: Cache = {};
|
||||||
|
constructor(private readonly _apiUrl: string, private readonly _wethAddress: string) {
|
||||||
|
const refreshCTokenCache = async () => this.fetchAndUpdateCTokensAsync();
|
||||||
|
// tslint:disable-next-line:no-floating-promises
|
||||||
|
refreshCTokenCache();
|
||||||
|
setInterval(refreshCTokenCache, CTOKEN_REFRESH_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async fetchAndUpdateCTokensAsync(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const { data } = await axios.get<CTokenApiResponse>(`${this._apiUrl}/ctoken`);
|
||||||
|
const newCache = data?.cToken.reduce<Cache>((memo, cToken) => {
|
||||||
|
// NOTE: Re-map cETH with null underlying token address to WETH address (we only handle WETH internally)
|
||||||
|
const underlyingAddressClean = cToken.underlying_address
|
||||||
|
? cToken.underlying_address.toLowerCase()
|
||||||
|
: this._wethAddress;
|
||||||
|
|
||||||
|
const tokenData: CToken = {
|
||||||
|
tokenAddress: cToken.token_address.toLowerCase(),
|
||||||
|
underlyingAddress: underlyingAddressClean,
|
||||||
|
};
|
||||||
|
memo[underlyingAddressClean] = tokenData;
|
||||||
|
return memo;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
this._cache = newCache;
|
||||||
|
} catch (err) {
|
||||||
|
logUtils.warn(`Failed to update Compound cToken cache: ${err.message}`);
|
||||||
|
// NOTE: Safe to keep already cached data as tokens should only be added to the list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public get(takerToken: string, makerToken: string): CToken | undefined {
|
||||||
|
// mint cToken
|
||||||
|
let cToken = this._cache[takerToken.toLowerCase()];
|
||||||
|
if (cToken && makerToken.toLowerCase() === cToken.tokenAddress.toLowerCase()) {
|
||||||
|
return cToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// redeem cToken
|
||||||
|
cToken = this._cache[makerToken.toLowerCase()];
|
||||||
|
if (cToken && takerToken.toLowerCase() === cToken.tokenAddress.toLowerCase()) {
|
||||||
|
return cToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
@@ -7,7 +7,9 @@ import { TokenAdjacencyGraphBuilder } from '../token_adjacency_graph_builder';
|
|||||||
|
|
||||||
import { SourceFilters } from './source_filters';
|
import { SourceFilters } from './source_filters';
|
||||||
import {
|
import {
|
||||||
|
AaveV2FillData,
|
||||||
BancorFillData,
|
BancorFillData,
|
||||||
|
CompoundFillData,
|
||||||
CurveFillData,
|
CurveFillData,
|
||||||
CurveFunctionSelectors,
|
CurveFunctionSelectors,
|
||||||
CurveInfo,
|
CurveInfo,
|
||||||
@@ -59,6 +61,7 @@ function valueByChainId<T>(rest: Partial<{ [key in ChainId]: T }>, defaultValue:
|
|||||||
[ChainId.Avalanche]: defaultValue,
|
[ChainId.Avalanche]: defaultValue,
|
||||||
[ChainId.Fantom]: defaultValue,
|
[ChainId.Fantom]: defaultValue,
|
||||||
[ChainId.Celo]: defaultValue,
|
[ChainId.Celo]: defaultValue,
|
||||||
|
[ChainId.Optimism]: defaultValue,
|
||||||
...(rest || {}),
|
...(rest || {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -101,6 +104,10 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.UniswapV3,
|
ERC20BridgeSource.UniswapV3,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
ERC20BridgeSource.ShibaSwap,
|
ERC20BridgeSource.ShibaSwap,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
|
// TODO: enable after FQT has been redeployed on Ethereum mainnet
|
||||||
|
// ERC20BridgeSource.AaveV2,
|
||||||
|
// ERC20BridgeSource.Compound,
|
||||||
]),
|
]),
|
||||||
[ChainId.Ropsten]: new SourceFilters([
|
[ChainId.Ropsten]: new SourceFilters([
|
||||||
ERC20BridgeSource.Kyber,
|
ERC20BridgeSource.Kyber,
|
||||||
@@ -124,6 +131,7 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.Mooniswap,
|
ERC20BridgeSource.Mooniswap,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
ERC20BridgeSource.Nerve,
|
ERC20BridgeSource.Nerve,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
ERC20BridgeSource.PancakeSwap,
|
ERC20BridgeSource.PancakeSwap,
|
||||||
ERC20BridgeSource.PancakeSwapV2,
|
ERC20BridgeSource.PancakeSwapV2,
|
||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
@@ -159,6 +167,9 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
ERC20BridgeSource.JetSwap,
|
ERC20BridgeSource.JetSwap,
|
||||||
ERC20BridgeSource.IronSwap,
|
ERC20BridgeSource.IronSwap,
|
||||||
|
ERC20BridgeSource.AaveV2,
|
||||||
|
ERC20BridgeSource.UniswapV3,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
]),
|
]),
|
||||||
[ChainId.Avalanche]: new SourceFilters([
|
[ChainId.Avalanche]: new SourceFilters([
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
@@ -168,20 +179,33 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.Curve,
|
ERC20BridgeSource.Curve,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
ERC20BridgeSource.KyberDmm,
|
ERC20BridgeSource.KyberDmm,
|
||||||
|
ERC20BridgeSource.AaveV2,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
]),
|
]),
|
||||||
[ChainId.Fantom]: new SourceFilters([
|
[ChainId.Fantom]: new SourceFilters([
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
|
ERC20BridgeSource.Beethovenx,
|
||||||
ERC20BridgeSource.Curve,
|
ERC20BridgeSource.Curve,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
|
ERC20BridgeSource.JetSwap,
|
||||||
|
ERC20BridgeSource.MorpheusSwap,
|
||||||
ERC20BridgeSource.SpiritSwap,
|
ERC20BridgeSource.SpiritSwap,
|
||||||
ERC20BridgeSource.SpookySwap,
|
ERC20BridgeSource.SpookySwap,
|
||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
]),
|
]),
|
||||||
[ChainId.Celo]: new SourceFilters([
|
[ChainId.Celo]: new SourceFilters([
|
||||||
ERC20BridgeSource.UbeSwap,
|
ERC20BridgeSource.UbeSwap,
|
||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
]),
|
]),
|
||||||
|
[ChainId.Optimism]: new SourceFilters([
|
||||||
|
ERC20BridgeSource.UniswapV3,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
|
ERC20BridgeSource.Curve,
|
||||||
|
ERC20BridgeSource.CurveV2,
|
||||||
|
ERC20BridgeSource.MultiHop,
|
||||||
|
]),
|
||||||
},
|
},
|
||||||
new SourceFilters([]),
|
new SourceFilters([]),
|
||||||
);
|
);
|
||||||
@@ -224,6 +248,10 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.UniswapV3,
|
ERC20BridgeSource.UniswapV3,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
ERC20BridgeSource.ShibaSwap,
|
ERC20BridgeSource.ShibaSwap,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
|
// TODO: enable after FQT has been redeployed on Ethereum mainnet
|
||||||
|
// ERC20BridgeSource.AaveV2,
|
||||||
|
// ERC20BridgeSource.Compound,
|
||||||
]),
|
]),
|
||||||
[ChainId.Ropsten]: new SourceFilters([
|
[ChainId.Ropsten]: new SourceFilters([
|
||||||
ERC20BridgeSource.Kyber,
|
ERC20BridgeSource.Kyber,
|
||||||
@@ -261,6 +289,7 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.JetSwap,
|
ERC20BridgeSource.JetSwap,
|
||||||
ERC20BridgeSource.ACryptos,
|
ERC20BridgeSource.ACryptos,
|
||||||
ERC20BridgeSource.KyberDmm,
|
ERC20BridgeSource.KyberDmm,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
]),
|
]),
|
||||||
[ChainId.Polygon]: new SourceFilters([
|
[ChainId.Polygon]: new SourceFilters([
|
||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
@@ -282,6 +311,9 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
ERC20BridgeSource.JetSwap,
|
ERC20BridgeSource.JetSwap,
|
||||||
ERC20BridgeSource.IronSwap,
|
ERC20BridgeSource.IronSwap,
|
||||||
|
ERC20BridgeSource.AaveV2,
|
||||||
|
ERC20BridgeSource.UniswapV3,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
]),
|
]),
|
||||||
[ChainId.Avalanche]: new SourceFilters([
|
[ChainId.Avalanche]: new SourceFilters([
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
@@ -291,20 +323,33 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
|
|||||||
ERC20BridgeSource.Curve,
|
ERC20BridgeSource.Curve,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
ERC20BridgeSource.KyberDmm,
|
ERC20BridgeSource.KyberDmm,
|
||||||
|
ERC20BridgeSource.AaveV2,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
]),
|
]),
|
||||||
[ChainId.Fantom]: new SourceFilters([
|
[ChainId.Fantom]: new SourceFilters([
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
|
ERC20BridgeSource.Beethovenx,
|
||||||
ERC20BridgeSource.Curve,
|
ERC20BridgeSource.Curve,
|
||||||
ERC20BridgeSource.CurveV2,
|
ERC20BridgeSource.CurveV2,
|
||||||
|
ERC20BridgeSource.JetSwap,
|
||||||
|
ERC20BridgeSource.MorpheusSwap,
|
||||||
ERC20BridgeSource.SpiritSwap,
|
ERC20BridgeSource.SpiritSwap,
|
||||||
ERC20BridgeSource.SpookySwap,
|
ERC20BridgeSource.SpookySwap,
|
||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
]),
|
]),
|
||||||
[ChainId.Celo]: new SourceFilters([
|
[ChainId.Celo]: new SourceFilters([
|
||||||
ERC20BridgeSource.UbeSwap,
|
ERC20BridgeSource.UbeSwap,
|
||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
]),
|
]),
|
||||||
|
[ChainId.Optimism]: new SourceFilters([
|
||||||
|
ERC20BridgeSource.UniswapV3,
|
||||||
|
ERC20BridgeSource.Synapse,
|
||||||
|
ERC20BridgeSource.Curve,
|
||||||
|
ERC20BridgeSource.CurveV2,
|
||||||
|
ERC20BridgeSource.MultiHop,
|
||||||
|
]),
|
||||||
},
|
},
|
||||||
new SourceFilters([]),
|
new SourceFilters([]),
|
||||||
);
|
);
|
||||||
@@ -322,10 +367,11 @@ export const FEE_QUOTE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>
|
|||||||
[ChainId.Mainnet]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.UniswapV3],
|
[ChainId.Mainnet]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.UniswapV3],
|
||||||
[ChainId.BSC]: [ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.Mooniswap, ERC20BridgeSource.SushiSwap],
|
[ChainId.BSC]: [ERC20BridgeSource.PancakeSwap, ERC20BridgeSource.Mooniswap, ERC20BridgeSource.SushiSwap],
|
||||||
[ChainId.Ropsten]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap],
|
[ChainId.Ropsten]: [ERC20BridgeSource.UniswapV2, ERC20BridgeSource.SushiSwap],
|
||||||
[ChainId.Polygon]: [ERC20BridgeSource.QuickSwap, ERC20BridgeSource.SushiSwap],
|
[ChainId.Polygon]: [ERC20BridgeSource.QuickSwap, ERC20BridgeSource.SushiSwap, ERC20BridgeSource.UniswapV3],
|
||||||
[ChainId.Avalanche]: [ERC20BridgeSource.Pangolin, ERC20BridgeSource.TraderJoe, ERC20BridgeSource.SushiSwap],
|
[ChainId.Avalanche]: [ERC20BridgeSource.Pangolin, ERC20BridgeSource.TraderJoe, ERC20BridgeSource.SushiSwap],
|
||||||
[ChainId.Fantom]: [ERC20BridgeSource.SpiritSwap, ERC20BridgeSource.SpookySwap, ERC20BridgeSource.SushiSwap],
|
[ChainId.Fantom]: [ERC20BridgeSource.SpiritSwap, ERC20BridgeSource.SpookySwap, ERC20BridgeSource.SushiSwap],
|
||||||
[ChainId.Celo]: [ERC20BridgeSource.UbeSwap, ERC20BridgeSource.SushiSwap],
|
[ChainId.Celo]: [ERC20BridgeSource.UbeSwap, ERC20BridgeSource.SushiSwap],
|
||||||
|
[ChainId.Optimism]: [ERC20BridgeSource.UniswapV3],
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@@ -422,15 +468,31 @@ export const MAINNET_TOKENS = {
|
|||||||
// StableSwap "open pools" (crv.finance)
|
// StableSwap "open pools" (crv.finance)
|
||||||
STABLEx: '0xcd91538b91b4ba7797d39a2f66e63810b50a33d0',
|
STABLEx: '0xcd91538b91b4ba7797d39a2f66e63810b50a33d0',
|
||||||
alUSD: '0xbc6da0fe9ad5f3b0d58160288917aa56653660e9',
|
alUSD: '0xbc6da0fe9ad5f3b0d58160288917aa56653660e9',
|
||||||
|
// Frax ecosystem
|
||||||
FRAX: '0x853d955acef822db058eb8505911ed77f175b99e',
|
FRAX: '0x853d955acef822db058eb8505911ed77f175b99e',
|
||||||
|
FXS: '0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0',
|
||||||
|
OHM: '0x383518188c0c6d7730d91b2c03a03c837814a899',
|
||||||
|
//
|
||||||
LUSD: '0x5f98805a4e8be255a32880fdec7f6728c6568ba0',
|
LUSD: '0x5f98805a4e8be255a32880fdec7f6728c6568ba0',
|
||||||
|
// Fei Ecosystem
|
||||||
FEI: '0x956f47f50a910163d8bf957cf5846d573e7f87ca',
|
FEI: '0x956f47f50a910163d8bf957cf5846d573e7f87ca',
|
||||||
|
TRIBE: '0xc7283b66eb1eb5fb86327f08e1b5816b0720212b',
|
||||||
|
//
|
||||||
DSU: '0x605d26fbd5be761089281d5cec2ce86eea667109',
|
DSU: '0x605d26fbd5be761089281d5cec2ce86eea667109',
|
||||||
ESS: '0x24ae124c4cc33d6791f8e8b63520ed7107ac8b3e',
|
ESS: '0x24ae124c4cc33d6791f8e8b63520ed7107ac8b3e',
|
||||||
cvxCRV: '0x62b9c7356a2dc64a1969e19c23e4f579f9810aa7',
|
cvxCRV: '0x62b9c7356a2dc64a1969e19c23e4f579f9810aa7',
|
||||||
CRV: '0xd533a949740bb3306d119cc777fa900ba034cd52',
|
CRV: '0xd533a949740bb3306d119cc777fa900ba034cd52',
|
||||||
MIM: '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3',
|
MIM: '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3',
|
||||||
EURT: '0xc581b735a1688071a1746c968e0798d642ede491',
|
EURT: '0xc581b735a1688071a1746c968e0798d642ede491',
|
||||||
|
// Synapse ecosystem
|
||||||
|
nUSD: '0x1b84765de8b7566e4ceaf4d0fd3c5af52d3dde4f',
|
||||||
|
CVX: '0x4e3fbd56cd56c3e72c1403e103b45db9da5b9d2b',
|
||||||
|
UST_WORMHOLE: '0xa693b19d2931d498c5b318df961919bb4aee87a5',
|
||||||
|
RAI: '0x03ab458634910aad20ef5f1c8ee96f1d6ac54919',
|
||||||
|
DOLA: '0x865377367054516e17014ccded1e7d814edc9ce4',
|
||||||
|
OUSD: '0x2a8e1e676ec238d8a992307b495b45b3feaa5e86',
|
||||||
|
agEUR: '0x1a7e4e63778b4f12a199c062f3efdd288afcbce8',
|
||||||
|
ibEUR: '0x96e61422b6a9ba0e068b6c5add4ffabc6a4aae27',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BSC_TOKENS = {
|
export const BSC_TOKENS = {
|
||||||
@@ -447,6 +509,7 @@ export const BSC_TOKENS = {
|
|||||||
BTCB: '0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c',
|
BTCB: '0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c',
|
||||||
renBTC: '0xfce146bf3146100cfe5db4129cf6c82b0ef4ad8c',
|
renBTC: '0xfce146bf3146100cfe5db4129cf6c82b0ef4ad8c',
|
||||||
pBTC: '0xed28a457a5a76596ac48d87c0f577020f6ea1c4c',
|
pBTC: '0xed28a457a5a76596ac48d87c0f577020f6ea1c4c',
|
||||||
|
nUSD: '0x23b891e5c62e0955ae2bd185990103928ab817b3',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const POLYGON_TOKENS = {
|
export const POLYGON_TOKENS = {
|
||||||
@@ -464,6 +527,7 @@ export const POLYGON_TOKENS = {
|
|||||||
DFYN: '0xc168e40227e4ebd8c1cae80f7a55a4f0e6d66c97',
|
DFYN: '0xc168e40227e4ebd8c1cae80f7a55a4f0e6d66c97',
|
||||||
BANANA: '0x5d47baba0d66083c52009271faf3f50dcc01023c',
|
BANANA: '0x5d47baba0d66083c52009271faf3f50dcc01023c',
|
||||||
WEXPOLY: '0x4c4bf319237d98a30a929a96112effa8da3510eb',
|
WEXPOLY: '0x4c4bf319237d98a30a929a96112effa8da3510eb',
|
||||||
|
nUSD: '0xb6c473756050de474286bed418b77aeac39b02af',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AVALANCHE_TOKENS = {
|
export const AVALANCHE_TOKENS = {
|
||||||
@@ -471,17 +535,38 @@ export const AVALANCHE_TOKENS = {
|
|||||||
WETH: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab',
|
WETH: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab',
|
||||||
WBTC: '0x50b7545627a5162f82a992c33b87adc75187b218',
|
WBTC: '0x50b7545627a5162f82a992c33b87adc75187b218',
|
||||||
DAI: '0xd586e7f844cea2f87f50152665bcbc2c279d8d70',
|
DAI: '0xd586e7f844cea2f87f50152665bcbc2c279d8d70',
|
||||||
|
// bridged USDC
|
||||||
USDC: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664',
|
USDC: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664',
|
||||||
|
// native USDC on Avalanche
|
||||||
|
nUSDC: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
|
||||||
USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118',
|
USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118',
|
||||||
aDAI: '0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a',
|
aDAI: '0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a',
|
||||||
aUSDC: '0x46a51127c3ce23fb7ab1de06226147f446e4a857',
|
aUSDC: '0x46a51127c3ce23fb7ab1de06226147f446e4a857',
|
||||||
aUSDT: '0x532e6537fea298397212f09a61e03311686f548e',
|
aUSDT: '0x532e6537fea298397212f09a61e03311686f548e',
|
||||||
|
nETH: '0x19e1ae0ee35c0404f835521146206595d37981ae',
|
||||||
|
nUSD: '0xcfc37a6ab183dd4aed08c204d1c2773c0b1bdf46',
|
||||||
|
aWETH: '0x53f7c5869a859f0aec3d334ee8b4cf01e3492f21',
|
||||||
|
MIM: '0x130966628846bfd36ff31a822705796e8cb8c18d',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CELO_TOKENS = {
|
export const CELO_TOKENS = {
|
||||||
WETH: '0xe919f65739c26a42616b7b8eedc6b5524d1e3ac4',
|
WCELO: '0x471ece3750da237f93b8e339c536989b8978a438',
|
||||||
CELO: '0x471ece3750da237f93b8e339c536989b8978a438',
|
// Some of these tokens are Optics bridge? tokens which
|
||||||
mCUSD: '0x64defa3544c695db8c535d289d843a189aa26b98',
|
// had an issue and migrated from v1 to v2
|
||||||
|
WETHv1: '0xe919f65739c26a42616b7b8eedc6b5524d1e3ac4',
|
||||||
|
WETH: '0x122013fd7df1c6f636a5bb8f03108e876548b455',
|
||||||
|
WBTC: '0xbaab46e28388d2779e6e31fd00cf0e5ad95e327b',
|
||||||
|
cUSD: '0x765de816845861e75a25fca122bb6898b8b1282a',
|
||||||
|
// ??
|
||||||
|
WBTCv1: '0xd629eb00deced2a080b7ec630ef6ac117e614f1b',
|
||||||
|
cETH: '0x2def4285787d58a2f811af24755a8150622f4361',
|
||||||
|
UBE: '0x00be915b9dcf56a3cbe739d9b9c202ca692409ec',
|
||||||
|
// Moolah
|
||||||
|
mCELO: '0x7d00cd74ff385c955ea3d79e47bf06bd7386387d',
|
||||||
|
mCUSD: '0x918146359264c492bd6934071c6bd31c854edbc3',
|
||||||
|
mCEUR: '0xe273ad7ee11dcfaa87383ad5977ee1504ac07568',
|
||||||
|
amCUSD: '0x64defa3544c695db8c535d289d843a189aa26b98',
|
||||||
|
MOO: '0x17700282592d6917f6a73d0bf8accf4d578c131e',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FANTOM_TOKENS = {
|
export const FANTOM_TOKENS = {
|
||||||
@@ -492,6 +577,23 @@ export const FANTOM_TOKENS = {
|
|||||||
fUSDT: '0x049d68029688eabf473097a2fc38ef61633a3c7a',
|
fUSDT: '0x049d68029688eabf473097a2fc38ef61633a3c7a',
|
||||||
WBTC: '0x321162cd933e2be498cd2267a90534a804051b11',
|
WBTC: '0x321162cd933e2be498cd2267a90534a804051b11',
|
||||||
renBTC: '0xdbf31df14b66535af65aac99c32e9ea844e14501',
|
renBTC: '0xdbf31df14b66535af65aac99c32e9ea844e14501',
|
||||||
|
MIM: '0x82f0b8b456c1a451378467398982d4834b6829c1',
|
||||||
|
nUSD: '0xed2a7edd7413021d440b09d654f3b87712abab66',
|
||||||
|
nETH: '0x67c10c397dd0ba417329543c1a40eb48aaa7cd00',
|
||||||
|
gfUSDT: '0x940f41f0ec9ba1a34cf001cc03347ac092f5f6b5',
|
||||||
|
gUSDC: '0xe578c856933d8e1082740bf7661e379aa2a30b26',
|
||||||
|
gDAI: '0x07e6332dd090d287d3489245038daf987955dcfb',
|
||||||
|
FRAX: '0xdc301622e621166bd8e82f2ca0a26c13ad0be355',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OPTIMISM_TOKENS = {
|
||||||
|
WETH: '0x4200000000000000000000000000000000000006',
|
||||||
|
USDC: '0x7f5c764cbc14f9669b88837ca1490cca17c31607',
|
||||||
|
USDT: '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58',
|
||||||
|
DAI: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1',
|
||||||
|
WBTC: '0x68f180fcce6836688e9084f035309e29bf0a2095',
|
||||||
|
nETH: '0x809dc529f07651bd43a172e8db6f4a7a0d771036',
|
||||||
|
sWETH: '0x121ab82b49b2bc4c7901ca46b8277962b4350204',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_POOLS = {
|
export const CURVE_POOLS = {
|
||||||
@@ -538,6 +640,17 @@ export const CURVE_POOLS = {
|
|||||||
cvxcrv: '0x9d0464996170c6b9e75eed71c68b99ddedf279e8',
|
cvxcrv: '0x9d0464996170c6b9e75eed71c68b99ddedf279e8',
|
||||||
mim: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
|
mim: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
|
||||||
eurt: '0xfd5db7463a3ab53fd211b4af195c5bccc1a03890',
|
eurt: '0xfd5db7463a3ab53fd211b4af195c5bccc1a03890',
|
||||||
|
ethcrv: '0x8301ae4fc9c624d1d396cbdaa1ed877821d7c511',
|
||||||
|
ethcvx: '0xb576491f1e6e5e62f1d8f26062ee822b40b0e0d4',
|
||||||
|
mimust: '0x55a8a39bc9694714e2874c1ce77aa1e599461e18',
|
||||||
|
usttri_wormhole: '0xceaf7747579696a2f0bb206a14210e3c9e6fb269',
|
||||||
|
fei_tri: '0x06cb22615ba53e60d67bf6c341a0fd5e718e1655',
|
||||||
|
rai_tri: '0x618788357d0ebd8a37e763adab3bc575d54c2c7d',
|
||||||
|
DOLA_tri: '0xaa5a67c256e27a5d80712c51971408db3370927d',
|
||||||
|
OUSD_tri: '0x87650d7bbfc3a9f10587d7778206671719d9910d',
|
||||||
|
d3pool: '0xbaaa1f5dba42c3389bdbc2c9d2de134f5cd0dc89',
|
||||||
|
triEURpool: '0xb9446c4ef5ebe66268da6700d26f96273de3d571',
|
||||||
|
ibEURsEUR: '0x19b080fe1ffa0553469d20ca36219f17fcf03859',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_POOLS = {
|
export const CURVE_V2_POOLS = {
|
||||||
@@ -551,12 +664,13 @@ export const CURVE_POLYGON_POOLS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_POLYGON_POOLS = {
|
export const CURVE_V2_POLYGON_POOLS = {
|
||||||
atricrypto: '0x3fcd5de6a9fc8a99995c406c77dda3ed7e406f81',
|
|
||||||
atricrypto3: '0x1d8b86e3d88cdb2d34688e87e72f388cb541b7c8',
|
atricrypto3: '0x1d8b86e3d88cdb2d34688e87e72f388cb541b7c8',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_AVALANCHE_POOLS = {
|
export const CURVE_AVALANCHE_POOLS = {
|
||||||
aave: '0x7f90122bf0700f9e7e1f688fe926940e8839f353',
|
aave: '0x7f90122bf0700f9e7e1f688fe926940e8839f353',
|
||||||
|
mim: '0xaea2e71b631fa93683bcf256a8689dfa0e094fcd',
|
||||||
|
USDC: '0x3a43a5851a3e3e0e25a3c1089670269786be1577',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_AVALANCHE_POOLS = {
|
export const CURVE_V2_AVALANCHE_POOLS = {
|
||||||
@@ -567,12 +681,19 @@ export const CURVE_FANTOM_POOLS = {
|
|||||||
fUSDT: '0x92d5ebf3593a92888c25c0abef126583d4b5312e',
|
fUSDT: '0x92d5ebf3593a92888c25c0abef126583d4b5312e',
|
||||||
twoPool: '0x27e611fd27b276acbd5ffd632e5eaebec9761e40',
|
twoPool: '0x27e611fd27b276acbd5ffd632e5eaebec9761e40',
|
||||||
ren: '0x3ef6a01a0f81d6046290f3e2a8c5b843e738e604',
|
ren: '0x3ef6a01a0f81d6046290f3e2a8c5b843e738e604',
|
||||||
|
tri_v2: '0x2dd7c9371965472e5a5fd28fbe165007c61439e1',
|
||||||
|
geist: '0x0fa949783947bf6c1b171db13aeacbb488845b3f',
|
||||||
|
FRAX_twoPool: '0x7a656b342e14f745e2b164890e88017e27ae7320',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_FANTOM_POOLS = {
|
export const CURVE_V2_FANTOM_POOLS = {
|
||||||
tricrypto: '0x3a1659ddcf2339be3aea159ca010979fb49155ff',
|
tricrypto: '0x3a1659ddcf2339be3aea159ca010979fb49155ff',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const CURVE_OPTIMISM_POOLS = {
|
||||||
|
tri: '0x1337bedc9d22ecbe766df105c9623922a27963ec',
|
||||||
|
};
|
||||||
|
|
||||||
export const SWERVE_POOLS = {
|
export const SWERVE_POOLS = {
|
||||||
y: '0x329239599afb305da0a2ec69c58f8a6697f9f88d',
|
y: '0x329239599afb305da0a2ec69c58f8a6697f9f88d',
|
||||||
};
|
};
|
||||||
@@ -607,6 +728,37 @@ export const NERVE_POOLS = {
|
|||||||
threePool: '0x1b3771a66ee31180906972580ade9b81afc5fcdc',
|
threePool: '0x1b3771a66ee31180906972580ade9b81afc5fcdc',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_MAINNET_POOLS = {
|
||||||
|
nUSDLP: '0x1116898dda4015ed8ddefb84b6e8bc24528af2d8',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_OPTIMISM_POOLS = {
|
||||||
|
nETHLP: '0xe27bff97ce92c3e1ff7aa9f86781fdd6d48f5ee9',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_BSC_POOLS = {
|
||||||
|
nUSDLP: '0x28ec0b36f0819ecb5005cab836f4ed5a2eca4d13',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_POLYGON_POOLS = {
|
||||||
|
nUSDLP: '0x85fcd7dd0a1e1a9fcd5fd886ed522de8221c3ee5',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_FANTOM_POOLS = {
|
||||||
|
nUSDLP: '0x2913e812cf0dcca30fb28e6cac3d2dcff4497688',
|
||||||
|
nETHLP: '0x8d9ba570d6cb60c7e3e0f31343efe75ab8e65fb1',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_AVALANCHE_POOLS = {
|
||||||
|
nUSDLP: '0xed2a7edd7413021d440b09d654f3b87712abab66',
|
||||||
|
nETHLP: '0x77a7e60555bc18b4be44c181b2575eee46212d44',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_ARBITRUM_POOLS = {
|
||||||
|
nUSDLP: '0x0db3fe3b770c95a0b99d1ed6f2627933466c0dd8',
|
||||||
|
nETHLP: '0xd70a52248e546a3b260849386410c7170c7bd1e9',
|
||||||
|
};
|
||||||
|
|
||||||
export const BELT_POOLS = {
|
export const BELT_POOLS = {
|
||||||
vPool: '0xf16d312d119c13dd27fd0dc814b0bcdcaaa62dfd',
|
vPool: '0xf16d312d119c13dd27fd0dc814b0bcdcaaa62dfd',
|
||||||
};
|
};
|
||||||
@@ -664,6 +816,7 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
|
|||||||
POLYGON_TOKENS.DAI,
|
POLYGON_TOKENS.DAI,
|
||||||
POLYGON_TOKENS.USDT,
|
POLYGON_TOKENS.USDT,
|
||||||
POLYGON_TOKENS.WBTC,
|
POLYGON_TOKENS.WBTC,
|
||||||
|
POLYGON_TOKENS.nUSD,
|
||||||
],
|
],
|
||||||
[ChainId.Avalanche]: [
|
[ChainId.Avalanche]: [
|
||||||
AVALANCHE_TOKENS.WAVAX,
|
AVALANCHE_TOKENS.WAVAX,
|
||||||
@@ -671,9 +824,28 @@ export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
|
|||||||
AVALANCHE_TOKENS.DAI,
|
AVALANCHE_TOKENS.DAI,
|
||||||
AVALANCHE_TOKENS.USDT,
|
AVALANCHE_TOKENS.USDT,
|
||||||
AVALANCHE_TOKENS.USDC,
|
AVALANCHE_TOKENS.USDC,
|
||||||
|
AVALANCHE_TOKENS.nUSD,
|
||||||
|
AVALANCHE_TOKENS.nETH,
|
||||||
|
AVALANCHE_TOKENS.aWETH,
|
||||||
|
],
|
||||||
|
[ChainId.Fantom]: [
|
||||||
|
FANTOM_TOKENS.WFTM,
|
||||||
|
FANTOM_TOKENS.WETH,
|
||||||
|
FANTOM_TOKENS.DAI,
|
||||||
|
FANTOM_TOKENS.USDC,
|
||||||
|
FANTOM_TOKENS.nUSD,
|
||||||
|
FANTOM_TOKENS.nETH,
|
||||||
|
FANTOM_TOKENS.MIM,
|
||||||
|
],
|
||||||
|
[ChainId.Celo]: [CELO_TOKENS.WCELO, CELO_TOKENS.mCUSD, CELO_TOKENS.WETH, CELO_TOKENS.amCUSD, CELO_TOKENS.WBTC],
|
||||||
|
[ChainId.Optimism]: [
|
||||||
|
OPTIMISM_TOKENS.WETH,
|
||||||
|
OPTIMISM_TOKENS.DAI,
|
||||||
|
OPTIMISM_TOKENS.USDC,
|
||||||
|
OPTIMISM_TOKENS.USDT,
|
||||||
|
OPTIMISM_TOKENS.nETH,
|
||||||
|
OPTIMISM_TOKENS.sWETH,
|
||||||
],
|
],
|
||||||
[ChainId.Fantom]: [FANTOM_TOKENS.WFTM, FANTOM_TOKENS.WETH, FANTOM_TOKENS.DAI, FANTOM_TOKENS.USDC],
|
|
||||||
[ChainId.Celo]: [CELO_TOKENS.mCUSD, CELO_TOKENS.WETH, CELO_TOKENS.CELO],
|
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@@ -690,6 +862,11 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
|
|||||||
builder.add(MAINNET_TOKENS.MIR, MAINNET_TOKENS.UST);
|
builder.add(MAINNET_TOKENS.MIR, MAINNET_TOKENS.UST);
|
||||||
// Convex and Curve
|
// Convex and Curve
|
||||||
builder.add(MAINNET_TOKENS.cvxCRV, MAINNET_TOKENS.CRV).add(MAINNET_TOKENS.CRV, MAINNET_TOKENS.cvxCRV);
|
builder.add(MAINNET_TOKENS.cvxCRV, MAINNET_TOKENS.CRV).add(MAINNET_TOKENS.CRV, MAINNET_TOKENS.cvxCRV);
|
||||||
|
// FEI TRIBE liquid in UniV2
|
||||||
|
builder.add(MAINNET_TOKENS.FEI, MAINNET_TOKENS.TRIBE).add(MAINNET_TOKENS.TRIBE, MAINNET_TOKENS.FEI);
|
||||||
|
// FRAX ecosystem
|
||||||
|
builder.add(MAINNET_TOKENS.FRAX, MAINNET_TOKENS.FXS).add(MAINNET_TOKENS.FXS, MAINNET_TOKENS.FRAX);
|
||||||
|
builder.add(MAINNET_TOKENS.FRAX, MAINNET_TOKENS.OHM).add(MAINNET_TOKENS.OHM, MAINNET_TOKENS.FRAX);
|
||||||
})
|
})
|
||||||
// Build
|
// Build
|
||||||
.build(),
|
.build(),
|
||||||
@@ -701,13 +878,23 @@ export const DEFAULT_TOKEN_ADJACENCY_GRAPH_BY_CHAIN_ID = valueByChainId<TokenAdj
|
|||||||
}).build(),
|
}).build(),
|
||||||
[ChainId.Avalanche]: new TokenAdjacencyGraphBuilder({
|
[ChainId.Avalanche]: new TokenAdjacencyGraphBuilder({
|
||||||
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Avalanche],
|
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Avalanche],
|
||||||
}).build(),
|
})
|
||||||
|
.tap(builder => {
|
||||||
|
// Synape nETH/aWETH pool
|
||||||
|
builder
|
||||||
|
.add(AVALANCHE_TOKENS.aWETH, AVALANCHE_TOKENS.nETH)
|
||||||
|
.add(AVALANCHE_TOKENS.nETH, AVALANCHE_TOKENS.aWETH);
|
||||||
|
})
|
||||||
|
.build(),
|
||||||
[ChainId.Fantom]: new TokenAdjacencyGraphBuilder({
|
[ChainId.Fantom]: new TokenAdjacencyGraphBuilder({
|
||||||
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Fantom],
|
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Fantom],
|
||||||
}).build(),
|
}).build(),
|
||||||
[ChainId.Celo]: new TokenAdjacencyGraphBuilder({
|
[ChainId.Celo]: new TokenAdjacencyGraphBuilder({
|
||||||
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Celo],
|
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Celo],
|
||||||
}).build(),
|
}).build(),
|
||||||
|
[ChainId.Optimism]: new TokenAdjacencyGraphBuilder({
|
||||||
|
default: DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID[ChainId.Optimism],
|
||||||
|
}).build(),
|
||||||
},
|
},
|
||||||
new TokenAdjacencyGraphBuilder({ default: [] }).build(),
|
new TokenAdjacencyGraphBuilder({ default: [] }).build(),
|
||||||
);
|
);
|
||||||
@@ -724,6 +911,7 @@ export const NATIVE_FEE_TOKEN_BY_CHAIN_ID = valueByChainId<string>(
|
|||||||
[ChainId.Avalanche]: getContractAddressesForChainOrThrow(ChainId.Avalanche).etherToken,
|
[ChainId.Avalanche]: getContractAddressesForChainOrThrow(ChainId.Avalanche).etherToken,
|
||||||
[ChainId.Fantom]: getContractAddressesForChainOrThrow(ChainId.Fantom).etherToken,
|
[ChainId.Fantom]: getContractAddressesForChainOrThrow(ChainId.Fantom).etherToken,
|
||||||
[ChainId.Celo]: getContractAddressesForChainOrThrow(ChainId.Celo).etherToken,
|
[ChainId.Celo]: getContractAddressesForChainOrThrow(ChainId.Celo).etherToken,
|
||||||
|
[ChainId.Optimism]: getContractAddressesForChainOrThrow(ChainId.Optimism).etherToken,
|
||||||
},
|
},
|
||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
@@ -738,6 +926,7 @@ const CURVE_TRI_POOL_MAINNET_TOKENS = [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC,
|
|||||||
const CURVE_TRI_BTC_POOL_TOKEN = [MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.sBTC];
|
const CURVE_TRI_BTC_POOL_TOKEN = [MAINNET_TOKENS.RenBTC, MAINNET_TOKENS.WBTC, MAINNET_TOKENS.sBTC];
|
||||||
const CURVE_POLYGON_ATRICRYPTO_UNDERLYING_TOKENS = [POLYGON_TOKENS.DAI, POLYGON_TOKENS.USDC, POLYGON_TOKENS.USDT];
|
const CURVE_POLYGON_ATRICRYPTO_UNDERLYING_TOKENS = [POLYGON_TOKENS.DAI, POLYGON_TOKENS.USDC, POLYGON_TOKENS.USDT];
|
||||||
const CURVE_POLYGON_ATRICRYPTO_TOKENS = [POLYGON_TOKENS.amDAI, POLYGON_TOKENS.amUSDC, POLYGON_TOKENS.amUSDT];
|
const CURVE_POLYGON_ATRICRYPTO_TOKENS = [POLYGON_TOKENS.amDAI, POLYGON_TOKENS.amUSDC, POLYGON_TOKENS.amUSDT];
|
||||||
|
const CURVE_FANTOM_TWO_POOL_TOKENS = [FANTOM_TOKENS.DAI, FANTOM_TOKENS.USDC];
|
||||||
|
|
||||||
const createCurveExchangePool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
|
const createCurveExchangePool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
|
||||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||||
@@ -779,6 +968,16 @@ const createCurveMetaTriBtcPool = (info: { tokens: string[]; pool: string; gasSc
|
|||||||
gasSchedule: info.gasSchedule,
|
gasSchedule: info.gasSchedule,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const createCurveMetaTwoPoolFantom = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
tokens: [...info.tokens, ...CURVE_FANTOM_TWO_POOL_TOKENS],
|
||||||
|
metaTokens: info.tokens,
|
||||||
|
poolAddress: info.pool,
|
||||||
|
gasSchedule: info.gasSchedule,
|
||||||
|
});
|
||||||
|
|
||||||
const createCurveExchangeV2Pool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
|
const createCurveExchangeV2Pool = (info: { tokens: string[]; pool: string; gasSchedule: number }) => ({
|
||||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange_v2,
|
exchangeFunctionSelector: CurveFunctionSelectors.exchange_v2,
|
||||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_v2,
|
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_v2,
|
||||||
@@ -998,6 +1197,73 @@ export const CURVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
pool: CURVE_POOLS.cvxcrv,
|
pool: CURVE_POOLS.cvxcrv,
|
||||||
gasSchedule: 105e3,
|
gasSchedule: 105e3,
|
||||||
}),
|
}),
|
||||||
|
[CURVE_POOLS.ethcrv]: {
|
||||||
|
...createCurveExchangePool({
|
||||||
|
// This pool uses ETH
|
||||||
|
tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.CRV],
|
||||||
|
pool: CURVE_POOLS.ethcrv,
|
||||||
|
gasSchedule: 350e3,
|
||||||
|
}),
|
||||||
|
// This pool has a custom get_dy and exchange selector with uint256
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_uint256,
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_uint256,
|
||||||
|
},
|
||||||
|
[CURVE_POOLS.ethcvx]: {
|
||||||
|
...createCurveExchangePool({
|
||||||
|
// This pool uses ETH
|
||||||
|
tokens: [MAINNET_TOKENS.WETH, MAINNET_TOKENS.CVX],
|
||||||
|
pool: CURVE_POOLS.ethcvx,
|
||||||
|
gasSchedule: 350e3,
|
||||||
|
}),
|
||||||
|
// This pool has a custom get_dy and exchange selector with uint256
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_uint256,
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying_uint256,
|
||||||
|
},
|
||||||
|
[CURVE_POOLS.mimust]: createCurveExchangePool({
|
||||||
|
tokens: [MAINNET_TOKENS.MIM, MAINNET_TOKENS.UST],
|
||||||
|
pool: CURVE_POOLS.mimust,
|
||||||
|
gasSchedule: 105e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.usttri_wormhole]: createCurveMetaTriPool({
|
||||||
|
tokens: [MAINNET_TOKENS.UST_WORMHOLE],
|
||||||
|
pool: CURVE_POOLS.usttri_wormhole,
|
||||||
|
gasSchedule: 340e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.fei_tri]: createCurveMetaTriPool({
|
||||||
|
tokens: [MAINNET_TOKENS.FEI],
|
||||||
|
pool: CURVE_POOLS.fei_tri,
|
||||||
|
gasSchedule: 340e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.rai_tri]: createCurveMetaTriPool({
|
||||||
|
tokens: [MAINNET_TOKENS.RAI],
|
||||||
|
pool: CURVE_POOLS.rai_tri,
|
||||||
|
gasSchedule: 340e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.DOLA_tri]: createCurveMetaTriPool({
|
||||||
|
tokens: [MAINNET_TOKENS.DOLA],
|
||||||
|
pool: CURVE_POOLS.DOLA_tri,
|
||||||
|
gasSchedule: 340e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.OUSD_tri]: createCurveMetaTriPool({
|
||||||
|
tokens: [MAINNET_TOKENS.OUSD],
|
||||||
|
pool: CURVE_POOLS.OUSD_tri,
|
||||||
|
gasSchedule: 340e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.d3pool]: createCurveExchangePool({
|
||||||
|
tokens: [MAINNET_TOKENS.FRAX, MAINNET_TOKENS.FEI, MAINNET_TOKENS.alUSD],
|
||||||
|
pool: CURVE_POOLS.d3pool,
|
||||||
|
gasSchedule: 176e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.triEURpool]: createCurveExchangePool({
|
||||||
|
tokens: [MAINNET_TOKENS.agEUR, MAINNET_TOKENS.EURT, MAINNET_TOKENS.EURS],
|
||||||
|
pool: CURVE_POOLS.triEURpool,
|
||||||
|
gasSchedule: 176e3,
|
||||||
|
}),
|
||||||
|
[CURVE_POOLS.ibEURsEUR]: createCurveExchangePool({
|
||||||
|
tokens: [MAINNET_TOKENS.ibEUR, MAINNET_TOKENS.sEUR],
|
||||||
|
pool: CURVE_POOLS.ibEURsEUR,
|
||||||
|
gasSchedule: 176e3,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
export const CURVE_V2_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
||||||
@@ -1032,11 +1298,6 @@ export const CURVE_POLYGON_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_POLYGON_INFOS: { [name: string]: CurveInfo } = {
|
export const CURVE_V2_POLYGON_INFOS: { [name: string]: CurveInfo } = {
|
||||||
[CURVE_V2_POLYGON_POOLS.atricrypto]: createCurveV2MetaTriPool({
|
|
||||||
tokens: [POLYGON_TOKENS.WBTC, POLYGON_TOKENS.WETH],
|
|
||||||
pool: CURVE_V2_POLYGON_POOLS.atricrypto,
|
|
||||||
gasSchedule: 300e3,
|
|
||||||
}),
|
|
||||||
[CURVE_V2_POLYGON_POOLS.atricrypto3]: createCurveV2MetaTriPool({
|
[CURVE_V2_POLYGON_POOLS.atricrypto3]: createCurveV2MetaTriPool({
|
||||||
tokens: [POLYGON_TOKENS.WBTC, POLYGON_TOKENS.WETH],
|
tokens: [POLYGON_TOKENS.WBTC, POLYGON_TOKENS.WETH],
|
||||||
pool: CURVE_V2_POLYGON_POOLS.atricrypto3,
|
pool: CURVE_V2_POLYGON_POOLS.atricrypto3,
|
||||||
@@ -1055,6 +1316,16 @@ export const CURVE_AVALANCHE_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
pool: CURVE_AVALANCHE_POOLS.aave,
|
pool: CURVE_AVALANCHE_POOLS.aave,
|
||||||
gasSchedule: 150e3,
|
gasSchedule: 150e3,
|
||||||
}),
|
}),
|
||||||
|
[CURVE_AVALANCHE_POOLS.mim]: createCurveExchangePool({
|
||||||
|
tokens: [AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.USDT, AVALANCHE_TOKENS.USDC],
|
||||||
|
pool: CURVE_AVALANCHE_POOLS.mim,
|
||||||
|
gasSchedule: 150e3,
|
||||||
|
}),
|
||||||
|
[CURVE_AVALANCHE_POOLS.USDC]: createCurveExchangePool({
|
||||||
|
tokens: [AVALANCHE_TOKENS.USDC, AVALANCHE_TOKENS.nUSDC],
|
||||||
|
pool: CURVE_AVALANCHE_POOLS.USDC,
|
||||||
|
gasSchedule: 150e3,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_AVALANCHE_INFOS: { [name: string]: CurveInfo } = {
|
export const CURVE_V2_AVALANCHE_INFOS: { [name: string]: CurveInfo } = {
|
||||||
@@ -1092,6 +1363,26 @@ export const CURVE_FANTOM_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
pool: CURVE_FANTOM_POOLS.fUSDT,
|
pool: CURVE_FANTOM_POOLS.fUSDT,
|
||||||
gasSchedule: 587e3,
|
gasSchedule: 587e3,
|
||||||
}),
|
}),
|
||||||
|
[CURVE_FANTOM_POOLS.tri_v2]: createCurveExchangePool({
|
||||||
|
tokens: [FANTOM_TOKENS.MIM, FANTOM_TOKENS.fUSDT, FANTOM_TOKENS.USDC],
|
||||||
|
pool: CURVE_FANTOM_POOLS.tri_v2,
|
||||||
|
gasSchedule: 176e3,
|
||||||
|
}),
|
||||||
|
['geist_exchangeunderlying']: createCurveExchangeUnderlyingPool({
|
||||||
|
tokens: [FANTOM_TOKENS.DAI, FANTOM_TOKENS.USDC, FANTOM_TOKENS.fUSDT],
|
||||||
|
pool: CURVE_FANTOM_POOLS.geist,
|
||||||
|
gasSchedule: 850e3,
|
||||||
|
}),
|
||||||
|
['geist_exchange']: createCurveExchangePool({
|
||||||
|
tokens: [FANTOM_TOKENS.gDAI, FANTOM_TOKENS.gUSDC, FANTOM_TOKENS.gfUSDT],
|
||||||
|
pool: CURVE_FANTOM_POOLS.geist,
|
||||||
|
gasSchedule: 150e3,
|
||||||
|
}),
|
||||||
|
[CURVE_FANTOM_POOLS.FRAX_twoPool]: createCurveMetaTwoPoolFantom({
|
||||||
|
tokens: [FANTOM_TOKENS.FRAX],
|
||||||
|
pool: CURVE_FANTOM_POOLS.FRAX_twoPool,
|
||||||
|
gasSchedule: 411e3,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURVE_V2_FANTOM_INFOS: { [name: string]: CurveInfo } = {
|
export const CURVE_V2_FANTOM_INFOS: { [name: string]: CurveInfo } = {
|
||||||
@@ -1102,6 +1393,14 @@ export const CURVE_V2_FANTOM_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const CURVE_OPTIMISM_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
[CURVE_OPTIMISM_POOLS.tri]: createCurveExchangePool({
|
||||||
|
tokens: [OPTIMISM_TOKENS.DAI, OPTIMISM_TOKENS.USDC, OPTIMISM_TOKENS.USDT],
|
||||||
|
pool: CURVE_OPTIMISM_POOLS.tri,
|
||||||
|
gasSchedule: 150e3,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
export const SWERVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
export const SWERVE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
||||||
[SWERVE_POOLS.y]: createCurveExchangePool({
|
[SWERVE_POOLS.y]: createCurveExchangePool({
|
||||||
tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT, MAINNET_TOKENS.TUSD],
|
tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT, MAINNET_TOKENS.TUSD],
|
||||||
@@ -1255,6 +1554,87 @@ export const NERVE_BSC_INFOS: { [name: string]: CurveInfo } = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_BSC_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
[SYNAPSE_BSC_POOLS.nUSDLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_BSC_POOLS.nUSDLP,
|
||||||
|
tokens: [BSC_TOKENS.nUSD, BSC_TOKENS.BUSD, BSC_TOKENS.USDC, BSC_TOKENS.USDT],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_FANTOM_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
[SYNAPSE_FANTOM_POOLS.nUSDLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_FANTOM_POOLS.nUSDLP,
|
||||||
|
tokens: [FANTOM_TOKENS.nUSD, FANTOM_TOKENS.MIM, FANTOM_TOKENS.USDC, FANTOM_TOKENS.fUSDT],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_MAINNET_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
[SYNAPSE_MAINNET_POOLS.nUSDLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_MAINNET_POOLS.nUSDLP,
|
||||||
|
tokens: [MAINNET_TOKENS.DAI, MAINNET_TOKENS.USDC, MAINNET_TOKENS.USDT],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_OPTIMISM_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
[SYNAPSE_OPTIMISM_POOLS.nETHLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_OPTIMISM_POOLS.nETHLP,
|
||||||
|
tokens: [OPTIMISM_TOKENS.nETH, OPTIMISM_TOKENS.sWETH],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_POLYGON_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
[SYNAPSE_POLYGON_POOLS.nUSDLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_POLYGON_POOLS.nUSDLP,
|
||||||
|
tokens: [POLYGON_TOKENS.nUSD, POLYGON_TOKENS.DAI, POLYGON_TOKENS.USDC, POLYGON_TOKENS.USDT],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SYNAPSE_AVALANCHE_INFOS: { [name: string]: CurveInfo } = {
|
||||||
|
[SYNAPSE_AVALANCHE_POOLS.nUSDLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_AVALANCHE_POOLS.nUSDLP,
|
||||||
|
tokens: [AVALANCHE_TOKENS.nUSD, AVALANCHE_TOKENS.DAI, AVALANCHE_TOKENS.USDC, AVALANCHE_TOKENS.USDT],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
[SYNAPSE_AVALANCHE_POOLS.nETHLP]: {
|
||||||
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
|
sellQuoteFunctionSelector: CurveFunctionSelectors.calculateSwap,
|
||||||
|
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||||
|
poolAddress: SYNAPSE_AVALANCHE_POOLS.nETHLP,
|
||||||
|
tokens: [AVALANCHE_TOKENS.nETH, AVALANCHE_TOKENS.aWETH],
|
||||||
|
metaTokens: undefined,
|
||||||
|
gasSchedule: 140e3,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const FIREBIRDONESWAP_BSC_INFOS: { [name: string]: CurveInfo } = {
|
export const FIREBIRDONESWAP_BSC_INFOS: { [name: string]: CurveInfo } = {
|
||||||
[FIREBIRDONESWAP_BSC_POOLS.oneswap]: {
|
[FIREBIRDONESWAP_BSC_POOLS.oneswap]: {
|
||||||
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
exchangeFunctionSelector: CurveFunctionSelectors.swap,
|
||||||
@@ -1396,7 +1776,7 @@ export const SUSHISWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
|||||||
[ChainId.Polygon]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
|
[ChainId.Polygon]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
|
||||||
[ChainId.Avalanche]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
|
[ChainId.Avalanche]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
|
||||||
[ChainId.Fantom]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
|
[ChainId.Fantom]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
|
||||||
[ChainId.Celo]: '0x1b02da8cb0d097eb8d57a175b88c7d8b47997506',
|
[ChainId.Celo]: '0x1421bde4b10e8dd459b3bcb598810b1337d56842',
|
||||||
},
|
},
|
||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
@@ -1618,6 +1998,13 @@ export const BALANCER_V2_VAULT_ADDRESS_BY_CHAIN = valueByChainId<string>(
|
|||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN = valueByChainId<string>(
|
||||||
|
{
|
||||||
|
[ChainId.Fantom]: '0x20dd72ed959b6147912c2e529f0a0c651c33c9ce',
|
||||||
|
},
|
||||||
|
NULL_ADDRESS,
|
||||||
|
);
|
||||||
|
|
||||||
export const LIDO_INFO_BY_CHAIN = valueByChainId<LidoInfo>(
|
export const LIDO_INFO_BY_CHAIN = valueByChainId<LidoInfo>(
|
||||||
{
|
{
|
||||||
[ChainId.Mainnet]: {
|
[ChainId.Mainnet]: {
|
||||||
@@ -1642,6 +2029,13 @@ export const BALANCER_V2_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
|
|||||||
'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2',
|
'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN = valueByChainId<string>(
|
||||||
|
{
|
||||||
|
[ChainId.Fantom]: 'https://graph-node.beets-ftm-node.com/subgraphs/name/beethovenx',
|
||||||
|
},
|
||||||
|
'https://graph-node.beets-ftm-node.com/subgraphs/name/beethovenx',
|
||||||
|
);
|
||||||
|
|
||||||
export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
|
export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
|
||||||
{
|
{
|
||||||
[ChainId.Mainnet]: {
|
[ChainId.Mainnet]: {
|
||||||
@@ -1652,10 +2046,36 @@ export const UNISWAPV3_CONFIG_BY_CHAIN_ID = valueByChainId(
|
|||||||
quoter: '0x2f9e608fd881861b8916257b76613cb22ee0652c',
|
quoter: '0x2f9e608fd881861b8916257b76613cb22ee0652c',
|
||||||
router: '0x03782388516e94fcd4c18666303601a12aa729ea',
|
router: '0x03782388516e94fcd4c18666303601a12aa729ea',
|
||||||
},
|
},
|
||||||
|
[ChainId.Polygon]: {
|
||||||
|
quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6',
|
||||||
|
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
|
||||||
|
},
|
||||||
|
[ChainId.Optimism]: {
|
||||||
|
quoter: '0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6',
|
||||||
|
router: '0xe592427a0aece92de3edee1f18e0157c05861564',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ quoter: NULL_ADDRESS, router: NULL_ADDRESS },
|
{ quoter: NULL_ADDRESS, router: NULL_ADDRESS },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const AAVE_V2_SUBGRAPH_URL_BY_CHAIN_ID = valueByChainId(
|
||||||
|
{
|
||||||
|
// TODO: enable after FQT has been redeployed on Ethereum mainnet
|
||||||
|
// [ChainId.Mainnet]: 'https://api.thegraph.com/subgraphs/name/aave/protocol-v2',
|
||||||
|
[ChainId.Polygon]: 'https://api.thegraph.com/subgraphs/name/aave/aave-v2-matic',
|
||||||
|
[ChainId.Avalanche]: 'https://api.thegraph.com/subgraphs/name/aave/protocol-v2-avalanche',
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
|
export const COMPOUND_API_URL_BY_CHAIN_ID = valueByChainId(
|
||||||
|
{
|
||||||
|
// TODO: enable after FQT has been redeployed on Ethereum mainnet
|
||||||
|
// [ChainId.Mainnet]: 'https://api.compound.finance/api/v2',
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// BSC
|
// BSC
|
||||||
//
|
//
|
||||||
@@ -1752,6 +2172,7 @@ export const JETSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
|||||||
{
|
{
|
||||||
[ChainId.BSC]: '0xbe65b8f75b9f20f4c522e0067a3887fada714800',
|
[ChainId.BSC]: '0xbe65b8f75b9f20f4c522e0067a3887fada714800',
|
||||||
[ChainId.Polygon]: '0x5c6ec38fb0e2609672bdf628b1fd605a523e5923',
|
[ChainId.Polygon]: '0x5c6ec38fb0e2609672bdf628b1fd605a523e5923',
|
||||||
|
[ChainId.Fantom]: '0x845e76a8691423fbc4ecb8dd77556cb61c09ee25',
|
||||||
},
|
},
|
||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
@@ -1777,6 +2198,13 @@ export const UBESWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
|||||||
NULL_ADDRESS,
|
NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const MORPHEUSSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
||||||
|
{
|
||||||
|
[ChainId.Fantom]: '0x8ac868293d97761a1fed6d4a01e9ff17c5594aa3',
|
||||||
|
},
|
||||||
|
NULL_ADDRESS,
|
||||||
|
);
|
||||||
|
|
||||||
export const SPIRITSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
export const SPIRITSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
|
||||||
{
|
{
|
||||||
[ChainId.Fantom]: '0x16327e3fbdaca3bcf7e38f5af2599d2ddc33ae52',
|
[ChainId.Fantom]: '0x16327e3fbdaca3bcf7e38f5af2599d2ddc33ae52',
|
||||||
@@ -1846,6 +2274,7 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
|
|||||||
[ERC20BridgeSource.Swerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
[ERC20BridgeSource.Swerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||||
[ERC20BridgeSource.SnowSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
[ERC20BridgeSource.SnowSwap]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||||
[ERC20BridgeSource.Nerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
[ERC20BridgeSource.Nerve]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||||
|
[ERC20BridgeSource.Synapse]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||||
[ERC20BridgeSource.Belt]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
[ERC20BridgeSource.Belt]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||||
[ERC20BridgeSource.Ellipsis]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
[ERC20BridgeSource.Ellipsis]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||||
[ERC20BridgeSource.Smoothy]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
[ERC20BridgeSource.Smoothy]: fillData => (fillData as CurveFillData).pool.gasSchedule,
|
||||||
@@ -1913,6 +2342,21 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
|
|||||||
return gas;
|
return gas;
|
||||||
},
|
},
|
||||||
[ERC20BridgeSource.Lido]: () => 226e3,
|
[ERC20BridgeSource.Lido]: () => 226e3,
|
||||||
|
[ERC20BridgeSource.AaveV2]: (fillData?: FillData) => {
|
||||||
|
const aaveFillData = fillData as AaveV2FillData;
|
||||||
|
// NOTE: The Aave deposit method is more expensive than the withdraw
|
||||||
|
return aaveFillData.takerToken === aaveFillData.underlyingToken ? 400e3 : 300e3;
|
||||||
|
},
|
||||||
|
[ERC20BridgeSource.Compound]: (fillData?: FillData) => {
|
||||||
|
// NOTE: cETH is handled differently than other cTokens
|
||||||
|
const wethAddress = NATIVE_FEE_TOKEN_BY_CHAIN_ID[ChainId.Mainnet];
|
||||||
|
const compoundFillData = fillData as CompoundFillData;
|
||||||
|
if (compoundFillData.takerToken === compoundFillData.cToken) {
|
||||||
|
return compoundFillData.makerToken === wethAddress ? 120e3 : 150e3;
|
||||||
|
} else {
|
||||||
|
return compoundFillData.takerToken === wethAddress ? 210e3 : 250e3;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
//
|
//
|
||||||
// BSC
|
// BSC
|
||||||
@@ -1950,8 +2394,10 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
|
|||||||
//
|
//
|
||||||
// Fantom
|
// Fantom
|
||||||
//
|
//
|
||||||
|
[ERC20BridgeSource.MorpheusSwap]: uniswapV2CloneGasSchedule,
|
||||||
[ERC20BridgeSource.SpiritSwap]: uniswapV2CloneGasSchedule,
|
[ERC20BridgeSource.SpiritSwap]: uniswapV2CloneGasSchedule,
|
||||||
[ERC20BridgeSource.SpookySwap]: uniswapV2CloneGasSchedule,
|
[ERC20BridgeSource.SpookySwap]: uniswapV2CloneGasSchedule,
|
||||||
|
[ERC20BridgeSource.Beethovenx]: () => 100e3,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DEFAULT_FEE_SCHEDULE: Required<FeeSchedule> = { ...DEFAULT_GAS_SCHEDULE };
|
export const DEFAULT_FEE_SCHEDULE: Required<FeeSchedule> = { ...DEFAULT_GAS_SCHEDULE };
|
||||||
@@ -1977,4 +2423,5 @@ export const DEFAULT_GET_MARKET_ORDERS_OPTS: Omit<GetMarketOrdersOpts, 'gasPrice
|
|||||||
shouldGenerateQuoteReport: true,
|
shouldGenerateQuoteReport: true,
|
||||||
shouldIncludePriceComparisonsReport: false,
|
shouldIncludePriceComparisonsReport: false,
|
||||||
tokenAdjacencyGraph: { default: [] },
|
tokenAdjacencyGraph: { default: [] },
|
||||||
|
neonRouterNumSamples: 14,
|
||||||
};
|
};
|
||||||
|
@@ -158,6 +158,8 @@ export class MarketOperationUtils {
|
|||||||
|
|
||||||
// Call the sampler contract.
|
// Call the sampler contract.
|
||||||
const samplerPromise = this._sampler.executeAsync(
|
const samplerPromise = this._sampler.executeAsync(
|
||||||
|
this._sampler.getBlockNumber(),
|
||||||
|
this._sampler.getGasLeft(),
|
||||||
this._sampler.getTokenDecimals([makerToken, takerToken]),
|
this._sampler.getTokenDecimals([makerToken, takerToken]),
|
||||||
// Get native order fillable amounts.
|
// Get native order fillable amounts.
|
||||||
this._sampler.getLimitOrderFillableTakerAmounts(nativeOrders, this.contractAddresses.exchangeProxy),
|
this._sampler.getLimitOrderFillableTakerAmounts(nativeOrders, this.contractAddresses.exchangeProxy),
|
||||||
@@ -184,6 +186,7 @@ export class MarketOperationUtils {
|
|||||||
takerAmount,
|
takerAmount,
|
||||||
),
|
),
|
||||||
this._sampler.isAddressContract(txOrigin),
|
this._sampler.isAddressContract(txOrigin),
|
||||||
|
this._sampler.getGasLeft(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Refresh the cached pools asynchronously if required
|
// Refresh the cached pools asynchronously if required
|
||||||
@@ -191,6 +194,8 @@ export class MarketOperationUtils {
|
|||||||
|
|
||||||
const [
|
const [
|
||||||
[
|
[
|
||||||
|
blockNumber,
|
||||||
|
gasBefore,
|
||||||
tokenDecimals,
|
tokenDecimals,
|
||||||
orderFillableTakerAmounts,
|
orderFillableTakerAmounts,
|
||||||
outputAmountPerEth,
|
outputAmountPerEth,
|
||||||
@@ -198,9 +203,14 @@ export class MarketOperationUtils {
|
|||||||
dexQuotes,
|
dexQuotes,
|
||||||
rawTwoHopQuotes,
|
rawTwoHopQuotes,
|
||||||
isTxOriginContract,
|
isTxOriginContract,
|
||||||
|
gasAfter,
|
||||||
],
|
],
|
||||||
] = await Promise.all([samplerPromise]);
|
] = await Promise.all([samplerPromise]);
|
||||||
|
|
||||||
|
// Log the gas metrics
|
||||||
|
_opts.samplerMetrics?.logGasDetails({ gasBefore, gasAfter });
|
||||||
|
_opts.samplerMetrics?.logBlockNumber(blockNumber);
|
||||||
|
|
||||||
// Filter out any invalid two hop quotes where we couldn't find a route
|
// Filter out any invalid two hop quotes where we couldn't find a route
|
||||||
const twoHopQuotes = rawTwoHopQuotes.filter(
|
const twoHopQuotes = rawTwoHopQuotes.filter(
|
||||||
q => q && q.fillData && q.fillData.firstHopSource && q.fillData.secondHopSource,
|
q => q && q.fillData && q.fillData.firstHopSource && q.fillData.secondHopSource,
|
||||||
@@ -433,6 +443,7 @@ export class MarketOperationUtils {
|
|||||||
feeSchedule: _opts.feeSchedule,
|
feeSchedule: _opts.feeSchedule,
|
||||||
allowFallback: _opts.allowFallback,
|
allowFallback: _opts.allowFallback,
|
||||||
gasPrice: _opts.gasPrice,
|
gasPrice: _opts.gasPrice,
|
||||||
|
neonRouterNumSamples: _opts.neonRouterNumSamples,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return optimizerResult;
|
return optimizerResult;
|
||||||
@@ -521,9 +532,18 @@ export class MarketOperationUtils {
|
|||||||
penaltyOpts,
|
penaltyOpts,
|
||||||
opts.feeSchedule,
|
opts.feeSchedule,
|
||||||
this._sampler.chainId,
|
this._sampler.chainId,
|
||||||
|
opts.neonRouterNumSamples,
|
||||||
|
opts.samplerMetrics,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
optimalPath = await findOptimalPathJSAsync(side, fills, inputAmount, opts.runLimit, penaltyOpts);
|
optimalPath = await findOptimalPathJSAsync(
|
||||||
|
side,
|
||||||
|
fills,
|
||||||
|
inputAmount,
|
||||||
|
opts.runLimit,
|
||||||
|
opts.samplerMetrics,
|
||||||
|
penaltyOpts,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const optimalPathRate = optimalPath ? optimalPath.adjustedRate() : ZERO_AMOUNT;
|
const optimalPathRate = optimalPath ? optimalPath.adjustedRate() : ZERO_AMOUNT;
|
||||||
@@ -586,6 +606,8 @@ export class MarketOperationUtils {
|
|||||||
allowFallback: _opts.allowFallback,
|
allowFallback: _opts.allowFallback,
|
||||||
exchangeProxyOverhead: _opts.exchangeProxyOverhead,
|
exchangeProxyOverhead: _opts.exchangeProxyOverhead,
|
||||||
gasPrice: _opts.gasPrice,
|
gasPrice: _opts.gasPrice,
|
||||||
|
neonRouterNumSamples: _opts.neonRouterNumSamples,
|
||||||
|
samplerMetrics: _opts.samplerMetrics,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (nativeOrders.length === 0) {
|
if (nativeOrders.length === 0) {
|
||||||
@@ -796,6 +818,8 @@ export class MarketOperationUtils {
|
|||||||
sturdyPenaltyOpts,
|
sturdyPenaltyOpts,
|
||||||
opts.feeSchedule,
|
opts.feeSchedule,
|
||||||
this._sampler.chainId,
|
this._sampler.chainId,
|
||||||
|
opts.neonRouterNumSamples,
|
||||||
|
undefined, // hack: set sampler metrics to undefined to avoid fallback timings
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const sturdyFills = fills.filter(p => p.length > 0 && !fragileSources.includes(p[0].source));
|
const sturdyFills = fills.filter(p => p.length > 0 && !fragileSources.includes(p[0].source));
|
||||||
@@ -804,6 +828,7 @@ export class MarketOperationUtils {
|
|||||||
sturdyFills,
|
sturdyFills,
|
||||||
inputAmount,
|
inputAmount,
|
||||||
opts.runLimit,
|
opts.runLimit,
|
||||||
|
undefined, // hack: set sampler metrics to undefined to avoid fallback timings
|
||||||
sturdyPenaltyOpts,
|
sturdyPenaltyOpts,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -5,11 +5,13 @@ import { AssetSwapperContractAddresses, MarketOperation } from '../../types';
|
|||||||
|
|
||||||
import { MAX_UINT256, ZERO_AMOUNT } from './constants';
|
import { MAX_UINT256, ZERO_AMOUNT } from './constants';
|
||||||
import {
|
import {
|
||||||
|
AaveV2FillData,
|
||||||
AggregationError,
|
AggregationError,
|
||||||
BalancerFillData,
|
BalancerFillData,
|
||||||
BalancerV2FillData,
|
BalancerV2FillData,
|
||||||
BancorFillData,
|
BancorFillData,
|
||||||
CollapsedFill,
|
CollapsedFill,
|
||||||
|
CompoundFillData,
|
||||||
CurveFillData,
|
CurveFillData,
|
||||||
DexSample,
|
DexSample,
|
||||||
DODOFillData,
|
DODOFillData,
|
||||||
@@ -132,6 +134,8 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
|
|||||||
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'BakerySwap');
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'BakerySwap');
|
||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.Nerve, 'Nerve');
|
return encodeBridgeSourceId(BridgeProtocol.Nerve, 'Nerve');
|
||||||
|
case ERC20BridgeSource.Synapse:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.Nerve, 'Synapse');
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Belt');
|
return encodeBridgeSourceId(BridgeProtocol.Curve, 'Belt');
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
@@ -186,10 +190,18 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
|
|||||||
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'TraderJoe');
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'TraderJoe');
|
||||||
case ERC20BridgeSource.UbeSwap:
|
case ERC20BridgeSource.UbeSwap:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'UbeSwap');
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'UbeSwap');
|
||||||
|
case ERC20BridgeSource.Beethovenx:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.BalancerV2, 'Beethovenx');
|
||||||
case ERC20BridgeSource.SpiritSwap:
|
case ERC20BridgeSource.SpiritSwap:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SpiritSwap');
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SpiritSwap');
|
||||||
case ERC20BridgeSource.SpookySwap:
|
case ERC20BridgeSource.SpookySwap:
|
||||||
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SpookySwap');
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'SpookySwap');
|
||||||
|
case ERC20BridgeSource.MorpheusSwap:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'MorpheusSwap');
|
||||||
|
case ERC20BridgeSource.AaveV2:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.AaveV2, 'AaveV2');
|
||||||
|
case ERC20BridgeSource.Compound:
|
||||||
|
return encodeBridgeSourceId(BridgeProtocol.Compound, 'Compound');
|
||||||
default:
|
default:
|
||||||
throw new Error(AggregationError.NoBridgeForSource);
|
throw new Error(AggregationError.NoBridgeForSource);
|
||||||
}
|
}
|
||||||
@@ -216,6 +228,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
case ERC20BridgeSource.Swerve:
|
case ERC20BridgeSource.Swerve:
|
||||||
case ERC20BridgeSource.SnowSwap:
|
case ERC20BridgeSource.SnowSwap:
|
||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
|
case ERC20BridgeSource.Synapse:
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
case ERC20BridgeSource.Smoothy:
|
case ERC20BridgeSource.Smoothy:
|
||||||
@@ -238,6 +251,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
bridgeData = encoder.encode([balancerFillData.poolAddress]);
|
bridgeData = encoder.encode([balancerFillData.poolAddress]);
|
||||||
break;
|
break;
|
||||||
case ERC20BridgeSource.BalancerV2:
|
case ERC20BridgeSource.BalancerV2:
|
||||||
|
case ERC20BridgeSource.Beethovenx:
|
||||||
const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2FillData>).fillData;
|
const balancerV2FillData = (order as OptimizedMarketBridgeOrder<BalancerV2FillData>).fillData;
|
||||||
const { vault, poolId } = balancerV2FillData;
|
const { vault, poolId } = balancerV2FillData;
|
||||||
bridgeData = encoder.encode([vault, poolId]);
|
bridgeData = encoder.encode([vault, poolId]);
|
||||||
@@ -269,6 +283,7 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
case ERC20BridgeSource.UbeSwap:
|
case ERC20BridgeSource.UbeSwap:
|
||||||
case ERC20BridgeSource.SpiritSwap:
|
case ERC20BridgeSource.SpiritSwap:
|
||||||
case ERC20BridgeSource.SpookySwap:
|
case ERC20BridgeSource.SpookySwap:
|
||||||
|
case ERC20BridgeSource.MorpheusSwap:
|
||||||
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;
|
||||||
@@ -333,6 +348,15 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
|
|||||||
const lidoFillData = (order as OptimizedMarketBridgeOrder<LidoFillData>).fillData;
|
const lidoFillData = (order as OptimizedMarketBridgeOrder<LidoFillData>).fillData;
|
||||||
bridgeData = encoder.encode([lidoFillData.stEthTokenAddress]);
|
bridgeData = encoder.encode([lidoFillData.stEthTokenAddress]);
|
||||||
break;
|
break;
|
||||||
|
case ERC20BridgeSource.AaveV2:
|
||||||
|
const aaveFillData = (order as OptimizedMarketBridgeOrder<AaveV2FillData>).fillData;
|
||||||
|
bridgeData = encoder.encode([aaveFillData.lendingPool, aaveFillData.aToken]);
|
||||||
|
break;
|
||||||
|
case ERC20BridgeSource.Compound:
|
||||||
|
const compoundFillData = (order as OptimizedMarketBridgeOrder<CompoundFillData>).fillData;
|
||||||
|
bridgeData = encoder.encode([compoundFillData.cToken]);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(AggregationError.NoBridgeForSource);
|
throw new Error(AggregationError.NoBridgeForSource);
|
||||||
}
|
}
|
||||||
@@ -442,6 +466,7 @@ export const BRIDGE_ENCODERS: {
|
|||||||
[ERC20BridgeSource.Swerve]: curveEncoder,
|
[ERC20BridgeSource.Swerve]: curveEncoder,
|
||||||
[ERC20BridgeSource.SnowSwap]: curveEncoder,
|
[ERC20BridgeSource.SnowSwap]: curveEncoder,
|
||||||
[ERC20BridgeSource.Nerve]: curveEncoder,
|
[ERC20BridgeSource.Nerve]: curveEncoder,
|
||||||
|
[ERC20BridgeSource.Synapse]: curveEncoder,
|
||||||
[ERC20BridgeSource.Belt]: curveEncoder,
|
[ERC20BridgeSource.Belt]: curveEncoder,
|
||||||
[ERC20BridgeSource.Ellipsis]: curveEncoder,
|
[ERC20BridgeSource.Ellipsis]: curveEncoder,
|
||||||
[ERC20BridgeSource.Smoothy]: curveEncoder,
|
[ERC20BridgeSource.Smoothy]: curveEncoder,
|
||||||
@@ -461,6 +486,7 @@ export const BRIDGE_ENCODERS: {
|
|||||||
[ERC20BridgeSource.TraderJoe]: routerAddressPathEncoder,
|
[ERC20BridgeSource.TraderJoe]: routerAddressPathEncoder,
|
||||||
[ERC20BridgeSource.SpiritSwap]: routerAddressPathEncoder,
|
[ERC20BridgeSource.SpiritSwap]: routerAddressPathEncoder,
|
||||||
[ERC20BridgeSource.SpookySwap]: routerAddressPathEncoder,
|
[ERC20BridgeSource.SpookySwap]: routerAddressPathEncoder,
|
||||||
|
[ERC20BridgeSource.MorpheusSwap]: routerAddressPathEncoder,
|
||||||
// Celo
|
// Celo
|
||||||
[ERC20BridgeSource.UbeSwap]: routerAddressPathEncoder,
|
[ERC20BridgeSource.UbeSwap]: routerAddressPathEncoder,
|
||||||
// BSC
|
// BSC
|
||||||
@@ -490,12 +516,15 @@ export const BRIDGE_ENCODERS: {
|
|||||||
// Custom integrations
|
// Custom integrations
|
||||||
[ERC20BridgeSource.MakerPsm]: makerPsmEncoder,
|
[ERC20BridgeSource.MakerPsm]: makerPsmEncoder,
|
||||||
[ERC20BridgeSource.BalancerV2]: balancerV2Encoder,
|
[ERC20BridgeSource.BalancerV2]: balancerV2Encoder,
|
||||||
|
[ERC20BridgeSource.Beethovenx]: balancerV2Encoder,
|
||||||
[ERC20BridgeSource.UniswapV3]: AbiEncoder.create([
|
[ERC20BridgeSource.UniswapV3]: AbiEncoder.create([
|
||||||
{ name: 'router', type: 'address' },
|
{ name: 'router', type: 'address' },
|
||||||
{ name: 'path', type: 'bytes' },
|
{ name: 'path', type: 'bytes' },
|
||||||
]),
|
]),
|
||||||
[ERC20BridgeSource.KyberDmm]: AbiEncoder.create('(address,address[],address[])'),
|
[ERC20BridgeSource.KyberDmm]: AbiEncoder.create('(address,address[],address[])'),
|
||||||
[ERC20BridgeSource.Lido]: AbiEncoder.create('(address)'),
|
[ERC20BridgeSource.Lido]: AbiEncoder.create('(address)'),
|
||||||
|
[ERC20BridgeSource.AaveV2]: AbiEncoder.create('(address,address)'),
|
||||||
|
[ERC20BridgeSource.Compound]: AbiEncoder.create('(address)'),
|
||||||
};
|
};
|
||||||
|
|
||||||
function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] {
|
function getFillTokenAmounts(fill: CollapsedFill, side: MarketOperation): [BigNumber, BigNumber] {
|
||||||
|
@@ -1,23 +1,21 @@
|
|||||||
import { assert } from '@0x/assert';
|
import { assert } from '@0x/assert';
|
||||||
import { ChainId } from '@0x/contract-addresses';
|
import { ChainId } from '@0x/contract-addresses';
|
||||||
import { OptimizerCapture, route, SerializedPath } from '@0x/neon-router';
|
import { OptimizerCapture, route, SerializedPath } from '@0x/neon-router';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber, hexUtils } from '@0x/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { performance } from 'perf_hooks';
|
import { performance } from 'perf_hooks';
|
||||||
|
|
||||||
import { DEFAULT_INFO_LOGGER } from '../../constants';
|
|
||||||
import { MarketOperation, NativeOrderWithFillableAmounts } from '../../types';
|
import { MarketOperation, NativeOrderWithFillableAmounts } from '../../types';
|
||||||
import { VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID } from '../market_operation_utils/constants';
|
import { VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID } from '../market_operation_utils/constants';
|
||||||
|
|
||||||
import { dexSamplesToFills, ethToOutputAmount, nativeOrdersToFills } from './fills';
|
import { dexSamplesToFills, ethToOutputAmount, nativeOrdersToFills } from './fills';
|
||||||
import { DEFAULT_PATH_PENALTY_OPTS, Path, PathPenaltyOpts } from './path';
|
import { DEFAULT_PATH_PENALTY_OPTS, Path, PathPenaltyOpts } from './path';
|
||||||
import { getRate } from './rate_utils';
|
import { getRate } from './rate_utils';
|
||||||
import { DexSample, ERC20BridgeSource, FeeSchedule, Fill, FillData } from './types';
|
import { DexSample, ERC20BridgeSource, FeeSchedule, Fill, FillData, SamplerMetrics } from './types';
|
||||||
|
|
||||||
// tslint:disable: prefer-for-of custom-no-magic-numbers completed-docs no-bitwise
|
// tslint:disable: prefer-for-of custom-no-magic-numbers completed-docs no-bitwise
|
||||||
|
|
||||||
const RUN_LIMIT_DECAY_FACTOR = 0.5;
|
const RUN_LIMIT_DECAY_FACTOR = 0.5;
|
||||||
const RUST_ROUTER_NUM_SAMPLES = 200;
|
|
||||||
const FILL_QUOTE_TRANSFORMER_GAS_OVERHEAD = new BigNumber(150e3);
|
const FILL_QUOTE_TRANSFORMER_GAS_OVERHEAD = new BigNumber(150e3);
|
||||||
// NOTE: The Rust router will panic with less than 3 samples
|
// NOTE: The Rust router will panic with less than 3 samples
|
||||||
const MIN_NUM_SAMPLE_INPUTS = 3;
|
const MIN_NUM_SAMPLE_INPUTS = 3;
|
||||||
@@ -69,21 +67,6 @@ function calculateOuputFee(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use linear interpolation to approximate the output
|
|
||||||
// at a certain input somewhere between the two samples
|
|
||||||
// See https://en.wikipedia.org/wiki/Linear_interpolation
|
|
||||||
const interpolateOutputFromSamples = (
|
|
||||||
left: { input: BigNumber; output: BigNumber },
|
|
||||||
right: { input: BigNumber; output: BigNumber },
|
|
||||||
targetInput: BigNumber,
|
|
||||||
): BigNumber =>
|
|
||||||
left.output.plus(
|
|
||||||
right.output
|
|
||||||
.minus(left.output)
|
|
||||||
.dividedBy(right.input.minus(left.input))
|
|
||||||
.times(targetInput.minus(left.input)),
|
|
||||||
);
|
|
||||||
|
|
||||||
function findRoutesAndCreateOptimalPath(
|
function findRoutesAndCreateOptimalPath(
|
||||||
side: MarketOperation,
|
side: MarketOperation,
|
||||||
samples: DexSample[][],
|
samples: DexSample[][],
|
||||||
@@ -91,29 +74,27 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
input: BigNumber,
|
input: BigNumber,
|
||||||
opts: PathPenaltyOpts,
|
opts: PathPenaltyOpts,
|
||||||
fees: FeeSchedule,
|
fees: FeeSchedule,
|
||||||
|
neonRouterNumSamples: number,
|
||||||
): Path | undefined {
|
): Path | undefined {
|
||||||
const createFill = (sample: DexSample) =>
|
const createFill = (sample: DexSample): Fill | undefined => {
|
||||||
dexSamplesToFills(side, [sample], opts.outputAmountPerEth, opts.inputAmountPerEth, fees)[0];
|
const fills = dexSamplesToFills(side, [sample], opts.outputAmountPerEth, opts.inputAmountPerEth, fees);
|
||||||
// Track sample id's to integers (required by rust router)
|
// NOTE: If the sample has 0 output dexSamplesToFills will return [] because no fill can be created
|
||||||
const sampleIdLookup: { [key: string]: number } = {};
|
if (fills.length === 0) {
|
||||||
let sampleIdCounter = 0;
|
return undefined;
|
||||||
const sampleToId = (source: ERC20BridgeSource, index: number): number => {
|
|
||||||
const key = `${source}-${index}`;
|
|
||||||
if (sampleIdLookup[key]) {
|
|
||||||
return sampleIdLookup[key];
|
|
||||||
} else {
|
|
||||||
sampleIdLookup[key] = ++sampleIdCounter;
|
|
||||||
return sampleIdLookup[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return fills[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
const samplesAndNativeOrdersWithResults: Array<DexSample[] | NativeOrderWithFillableAmounts[]> = [];
|
const samplesAndNativeOrdersWithResults: Array<DexSample[] | NativeOrderWithFillableAmounts[]> = [];
|
||||||
const serializedPaths: SerializedPath[] = [];
|
const serializedPaths: SerializedPath[] = [];
|
||||||
|
const sampleSourcePathIds: string[] = [];
|
||||||
for (const singleSourceSamples of samples) {
|
for (const singleSourceSamples of samples) {
|
||||||
if (singleSourceSamples.length === 0) {
|
if (singleSourceSamples.length === 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sourcePathId = hexUtils.random();
|
||||||
const singleSourceSamplesWithOutput = [...singleSourceSamples];
|
const singleSourceSamplesWithOutput = [...singleSourceSamples];
|
||||||
for (let i = singleSourceSamples.length - 1; i >= 0; i--) {
|
for (let i = singleSourceSamples.length - 1; i >= 0; i--) {
|
||||||
if (singleSourceSamples[i].output.isZero()) {
|
if (singleSourceSamples[i].output.isZero()) {
|
||||||
@@ -131,7 +112,7 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
// TODO(kimpers): Do we need to handle 0 entries, from eg Kyber?
|
// TODO(kimpers): Do we need to handle 0 entries, from eg Kyber?
|
||||||
const serializedPath = singleSourceSamplesWithOutput.reduce<SerializedPath>(
|
const serializedPath = singleSourceSamplesWithOutput.reduce<SerializedPath>(
|
||||||
(memo, sample, sampleIdx) => {
|
(memo, sample, sampleIdx) => {
|
||||||
memo.ids.push(sampleToId(sample.source, sampleIdx));
|
memo.ids.push(`${sample.source}-${serializedPaths.length}-${sampleIdx}`);
|
||||||
memo.inputs.push(sample.input.integerValue().toNumber());
|
memo.inputs.push(sample.input.integerValue().toNumber());
|
||||||
memo.outputs.push(sample.output.integerValue().toNumber());
|
memo.outputs.push(sample.output.integerValue().toNumber());
|
||||||
memo.outputFees.push(
|
memo.outputFees.push(
|
||||||
@@ -152,8 +133,10 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
|
|
||||||
samplesAndNativeOrdersWithResults.push(singleSourceSamplesWithOutput);
|
samplesAndNativeOrdersWithResults.push(singleSourceSamplesWithOutput);
|
||||||
serializedPaths.push(serializedPath);
|
serializedPaths.push(serializedPath);
|
||||||
|
sampleSourcePathIds.push(sourcePathId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nativeOrdersourcePathId = hexUtils.random();
|
||||||
for (const [idx, nativeOrder] of nativeOrders.entries()) {
|
for (const [idx, nativeOrder] of nativeOrders.entries()) {
|
||||||
const { input: normalizedOrderInput, output: normalizedOrderOutput } = nativeOrderToNormalizedAmounts(
|
const { input: normalizedOrderInput, output: normalizedOrderOutput } = nativeOrderToNormalizedAmounts(
|
||||||
side,
|
side,
|
||||||
@@ -164,32 +147,25 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
if (normalizedOrderInput.isLessThanOrEqualTo(0) || normalizedOrderOutput.isLessThanOrEqualTo(0)) {
|
if (normalizedOrderInput.isLessThanOrEqualTo(0) || normalizedOrderOutput.isLessThanOrEqualTo(0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: the router requires at minimum 3 samples as a basis for interpolation
|
|
||||||
const inputs = [
|
|
||||||
0,
|
|
||||||
normalizedOrderInput
|
|
||||||
.dividedBy(2)
|
|
||||||
.integerValue()
|
|
||||||
.toNumber(),
|
|
||||||
normalizedOrderInput.integerValue().toNumber(),
|
|
||||||
];
|
|
||||||
const outputs = [
|
|
||||||
0,
|
|
||||||
normalizedOrderOutput
|
|
||||||
.dividedBy(2)
|
|
||||||
.integerValue()
|
|
||||||
.toNumber(),
|
|
||||||
normalizedOrderOutput.integerValue().toNumber(),
|
|
||||||
];
|
|
||||||
// NOTE: same fee no matter if full or partial fill
|
|
||||||
const fee = calculateOuputFee(side, nativeOrder, opts.outputAmountPerEth, opts.inputAmountPerEth, fees)
|
const fee = calculateOuputFee(side, nativeOrder, opts.outputAmountPerEth, opts.inputAmountPerEth, fees)
|
||||||
.integerValue()
|
.integerValue()
|
||||||
.toNumber();
|
.toNumber();
|
||||||
const outputFees = [fee, fee, fee];
|
|
||||||
// NOTE: ids can be the same for all fake samples
|
// HACK: due to an issue with the Rust router interpolation we need to create exactly 13 samples from the native order
|
||||||
const id = sampleToId(ERC20BridgeSource.Native, idx);
|
const ids = [];
|
||||||
const ids = [id, id, id];
|
const inputs = [];
|
||||||
|
const outputs = [];
|
||||||
|
const outputFees = [];
|
||||||
|
for (let i = 1; i <= 13; i++) {
|
||||||
|
const fraction = i / 13;
|
||||||
|
const currentInput = BigNumber.min(normalizedOrderInput.times(fraction), normalizedOrderInput);
|
||||||
|
const currentOutput = BigNumber.min(normalizedOrderOutput.times(fraction), normalizedOrderOutput);
|
||||||
|
const id = `${ERC20BridgeSource.Native}-${serializedPaths.length}-${idx}-${i}`;
|
||||||
|
inputs.push(currentInput.integerValue().toNumber());
|
||||||
|
outputs.push(currentOutput.integerValue().toNumber());
|
||||||
|
outputFees.push(fee);
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
const serializedPath: SerializedPath = {
|
const serializedPath: SerializedPath = {
|
||||||
ids,
|
ids,
|
||||||
@@ -200,6 +176,7 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
|
|
||||||
samplesAndNativeOrdersWithResults.push([nativeOrder]);
|
samplesAndNativeOrdersWithResults.push([nativeOrder]);
|
||||||
serializedPaths.push(serializedPath);
|
serializedPaths.push(serializedPath);
|
||||||
|
sampleSourcePathIds.push(nativeOrdersourcePathId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serializedPaths.length === 0) {
|
if (serializedPaths.length === 0) {
|
||||||
@@ -212,30 +189,33 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
pathsIn: serializedPaths,
|
pathsIn: serializedPaths,
|
||||||
};
|
};
|
||||||
|
|
||||||
const before = performance.now();
|
|
||||||
const allSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length);
|
const allSourcesRustRoute = new Float64Array(rustArgs.pathsIn.length);
|
||||||
route(rustArgs, allSourcesRustRoute, RUST_ROUTER_NUM_SAMPLES);
|
const strategySourcesOutputAmounts = new Float64Array(rustArgs.pathsIn.length);
|
||||||
DEFAULT_INFO_LOGGER(
|
route(rustArgs, allSourcesRustRoute, strategySourcesOutputAmounts, neonRouterNumSamples);
|
||||||
{ router: 'neon-router', performanceMs: performance.now() - before, type: 'real' },
|
|
||||||
'Rust router real routing performance',
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.assert(
|
assert.assert(
|
||||||
rustArgs.pathsIn.length === allSourcesRustRoute.length,
|
rustArgs.pathsIn.length === allSourcesRustRoute.length,
|
||||||
'different number of sources in the Router output than the input',
|
'different number of sources in the Router output than the input',
|
||||||
);
|
);
|
||||||
|
assert.assert(
|
||||||
|
rustArgs.pathsIn.length === strategySourcesOutputAmounts.length,
|
||||||
|
'different number of sources in the Router output amounts results than the input',
|
||||||
|
);
|
||||||
|
|
||||||
const routesAndSamples = _.zip(allSourcesRustRoute, samplesAndNativeOrdersWithResults);
|
const routesAndSamplesAndOutputs = _.zip(
|
||||||
|
allSourcesRustRoute,
|
||||||
|
samplesAndNativeOrdersWithResults,
|
||||||
|
strategySourcesOutputAmounts,
|
||||||
|
sampleSourcePathIds,
|
||||||
|
);
|
||||||
const adjustedFills: Fill[] = [];
|
const adjustedFills: Fill[] = [];
|
||||||
const totalRoutedAmount = BigNumber.sum(...allSourcesRustRoute);
|
const totalRoutedAmount = BigNumber.sum(...allSourcesRustRoute);
|
||||||
|
|
||||||
const scale = input.dividedBy(totalRoutedAmount);
|
const scale = input.dividedBy(totalRoutedAmount);
|
||||||
for (const [routeInput, routeSamplesAndNativeOrders] of routesAndSamples) {
|
for (const [routeInput, routeSamplesAndNativeOrders, outputAmount, sourcePathId] of routesAndSamplesAndOutputs) {
|
||||||
if (!routeInput || !routeSamplesAndNativeOrders) {
|
if (!routeInput || !routeSamplesAndNativeOrders || !outputAmount || !Number.isFinite(outputAmount)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precisions loss for number/f64
|
// TODO(kimpers): [TKR-241] amounts are sometimes clipped in the router due to precision loss for number/f64
|
||||||
// we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much
|
// we can work around it by scaling it and rounding up. However now we end up with a total amount of a couple base units too much
|
||||||
const rustInputAdjusted = BigNumber.min(
|
const rustInputAdjusted = BigNumber.min(
|
||||||
new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL),
|
new BigNumber(routeInput).multipliedBy(scale).integerValue(BigNumber.ROUND_CEIL),
|
||||||
@@ -251,14 +231,21 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
opts.outputAmountPerEth,
|
opts.outputAmountPerEth,
|
||||||
opts.inputAmountPerEth,
|
opts.inputAmountPerEth,
|
||||||
fees,
|
fees,
|
||||||
)[0];
|
)[0] as Fill | undefined;
|
||||||
// NOTE: For Limit/RFQ orders we are done here. No need to scale output
|
// Note: If the order has an adjusted rate of less than or equal to 0 it will be skipped
|
||||||
adjustedFills.push(nativeFill);
|
// and nativeFill will be `undefined`
|
||||||
|
if (nativeFill) {
|
||||||
|
// NOTE: For Limit/RFQ orders we are done here. No need to scale output
|
||||||
|
adjustedFills.push({ ...nativeFill, sourcePathId: sourcePathId ?? hexUtils.random() });
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: For DexSamples only
|
// NOTE: For DexSamples only
|
||||||
let fill = createFill(current);
|
let fill = createFill(current);
|
||||||
|
if (!fill) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>;
|
const routeSamples = routeSamplesAndNativeOrders as Array<DexSample<FillData>>;
|
||||||
// Descend to approach a closer fill for fillData which may not be consistent
|
// Descend to approach a closer fill for fillData which may not be consistent
|
||||||
// throughout the path (UniswapV3) and for a closer guesstimate at
|
// throughout the path (UniswapV3) and for a closer guesstimate at
|
||||||
@@ -267,49 +254,47 @@ function findRoutesAndCreateOptimalPath(
|
|||||||
assert.assert(routeSamples.length >= 1, 'Found no sample to use for source');
|
assert.assert(routeSamples.length >= 1, 'Found no sample to use for source');
|
||||||
for (let k = routeSamples.length - 1; k >= 0; k--) {
|
for (let k = routeSamples.length - 1; k >= 0; k--) {
|
||||||
if (k === 0) {
|
if (k === 0) {
|
||||||
fill = createFill(routeSamples[0]);
|
fill = createFill(routeSamples[0]) ?? fill;
|
||||||
}
|
}
|
||||||
if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) {
|
if (rustInputAdjusted.isGreaterThan(routeSamples[k].input)) {
|
||||||
// Between here and the previous fill
|
|
||||||
// HACK: Use the midpoint between the two
|
|
||||||
const left = routeSamples[k];
|
const left = routeSamples[k];
|
||||||
const right = routeSamples[k + 1];
|
const right = routeSamples[k + 1];
|
||||||
if (left && right) {
|
if (left && right) {
|
||||||
// Approximate how much output we get for the input with the surrounding samples
|
fill =
|
||||||
const interpolatedOutput = interpolateOutputFromSamples(
|
createFill({
|
||||||
left,
|
...right, // default to the greater (for gas used)
|
||||||
right,
|
input: rustInputAdjusted,
|
||||||
rustInputAdjusted,
|
output: new BigNumber(outputAmount),
|
||||||
).decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL);
|
}) ?? fill;
|
||||||
|
|
||||||
fill = createFill({
|
|
||||||
...right, // default to the greater (for gas used)
|
|
||||||
input: rustInputAdjusted,
|
|
||||||
output: interpolatedOutput,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
assert.assert(Boolean(left || right), 'No valid sample to use');
|
assert.assert(Boolean(left || right), 'No valid sample to use');
|
||||||
fill = createFill(left || right);
|
fill = createFill(left || right) ?? fill;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const scaleOutput = (output: BigNumber) =>
|
// TODO(kimpers): remove once we have solved the rounding/precision loss issues in the Rust router
|
||||||
|
const scaleOutput = (fillInput: BigNumber, output: BigNumber) =>
|
||||||
output
|
output
|
||||||
.dividedBy(fill.input)
|
.dividedBy(fillInput)
|
||||||
.times(rustInputAdjusted)
|
.times(rustInputAdjusted)
|
||||||
.decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL);
|
.decimalPlaces(0, side === MarketOperation.Sell ? BigNumber.ROUND_FLOOR : BigNumber.ROUND_CEIL);
|
||||||
adjustedFills.push({
|
adjustedFills.push({
|
||||||
...fill,
|
...fill,
|
||||||
input: rustInputAdjusted,
|
input: rustInputAdjusted,
|
||||||
output: scaleOutput(fill.output),
|
output: scaleOutput(fill.input, fill.output),
|
||||||
adjustedOutput: scaleOutput(fill.adjustedOutput),
|
adjustedOutput: scaleOutput(fill.input, fill.adjustedOutput),
|
||||||
index: 0,
|
index: 0,
|
||||||
parent: undefined,
|
parent: undefined,
|
||||||
|
sourcePathId: sourcePathId ?? hexUtils.random(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (adjustedFills.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const pathFromRustInputs = Path.create(side, adjustedFills, input);
|
const pathFromRustInputs = Path.create(side, adjustedFills, input);
|
||||||
|
|
||||||
return pathFromRustInputs;
|
return pathFromRustInputs;
|
||||||
@@ -323,15 +308,27 @@ export function findOptimalRustPathFromSamples(
|
|||||||
opts: PathPenaltyOpts,
|
opts: PathPenaltyOpts,
|
||||||
fees: FeeSchedule,
|
fees: FeeSchedule,
|
||||||
chainId: ChainId,
|
chainId: ChainId,
|
||||||
|
neonRouterNumSamples: number,
|
||||||
|
samplerMetrics?: SamplerMetrics,
|
||||||
): Path | undefined {
|
): Path | undefined {
|
||||||
const before = performance.now();
|
const beforeAllTimeMs = performance.now();
|
||||||
const logPerformance = () =>
|
let beforeTimeMs = performance.now();
|
||||||
DEFAULT_INFO_LOGGER(
|
const allSourcesPath = findRoutesAndCreateOptimalPath(
|
||||||
{ router: 'neon-router', performanceMs: performance.now() - before, type: 'total' },
|
side,
|
||||||
'Rust router total routing performance',
|
samples,
|
||||||
);
|
nativeOrders,
|
||||||
|
input,
|
||||||
const allSourcesPath = findRoutesAndCreateOptimalPath(side, samples, nativeOrders, input, opts, fees);
|
opts,
|
||||||
|
fees,
|
||||||
|
neonRouterNumSamples,
|
||||||
|
);
|
||||||
|
// tslint:disable-next-line: no-unused-expression
|
||||||
|
samplerMetrics &&
|
||||||
|
samplerMetrics.logRouterDetails({
|
||||||
|
router: 'neon-router',
|
||||||
|
type: 'all',
|
||||||
|
timingMs: performance.now() - beforeTimeMs,
|
||||||
|
});
|
||||||
if (!allSourcesPath) {
|
if (!allSourcesPath) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -341,11 +338,27 @@ export function findOptimalRustPathFromSamples(
|
|||||||
// HACK(kimpers): The Rust router currently doesn't account for VIP sources correctly
|
// HACK(kimpers): The Rust router currently doesn't account for VIP sources correctly
|
||||||
// we need to try to route them in isolation and compare with the results all sources
|
// we need to try to route them in isolation and compare with the results all sources
|
||||||
if (vipSources.length > 0) {
|
if (vipSources.length > 0) {
|
||||||
|
beforeTimeMs = performance.now();
|
||||||
const vipSourcesSet = new Set(vipSources);
|
const vipSourcesSet = new Set(vipSources);
|
||||||
const vipSourcesSamples = samples.filter(s => s[0] && vipSourcesSet.has(s[0].source));
|
const vipSourcesSamples = samples.filter(s => s[0] && vipSourcesSet.has(s[0].source));
|
||||||
|
|
||||||
if (vipSourcesSamples.length > 0) {
|
if (vipSourcesSamples.length > 0) {
|
||||||
const vipSourcesPath = findRoutesAndCreateOptimalPath(side, vipSourcesSamples, [], input, opts, fees);
|
const vipSourcesPath = findRoutesAndCreateOptimalPath(
|
||||||
|
side,
|
||||||
|
vipSourcesSamples,
|
||||||
|
[],
|
||||||
|
input,
|
||||||
|
opts,
|
||||||
|
fees,
|
||||||
|
neonRouterNumSamples,
|
||||||
|
);
|
||||||
|
// tslint:disable-next-line: no-unused-expression
|
||||||
|
samplerMetrics &&
|
||||||
|
samplerMetrics.logRouterDetails({
|
||||||
|
router: 'neon-router',
|
||||||
|
type: 'vip',
|
||||||
|
timingMs: performance.now() - beforeTimeMs,
|
||||||
|
});
|
||||||
|
|
||||||
const { input: allSourcesInput, output: allSourcesOutput } = allSourcesPath.adjustedSize();
|
const { input: allSourcesInput, output: allSourcesOutput } = allSourcesPath.adjustedSize();
|
||||||
// NOTE: For sell quotes input is the taker asset and for buy quotes input is the maker asset
|
// NOTE: For sell quotes input is the taker asset and for buy quotes input is the maker asset
|
||||||
@@ -358,13 +371,18 @@ export function findOptimalRustPathFromSamples(
|
|||||||
const allSourcesAdjustedRateWithFqtOverhead = getRate(side, allSourcesInput, outputWithFqtOverhead);
|
const allSourcesAdjustedRateWithFqtOverhead = getRate(side, allSourcesInput, outputWithFqtOverhead);
|
||||||
|
|
||||||
if (vipSourcesPath?.adjustedRate().isGreaterThan(allSourcesAdjustedRateWithFqtOverhead)) {
|
if (vipSourcesPath?.adjustedRate().isGreaterThan(allSourcesAdjustedRateWithFqtOverhead)) {
|
||||||
logPerformance();
|
|
||||||
return vipSourcesPath;
|
return vipSourcesPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// tslint:disable-next-line: no-unused-expression
|
||||||
|
samplerMetrics &&
|
||||||
|
samplerMetrics.logRouterDetails({
|
||||||
|
router: 'neon-router',
|
||||||
|
type: 'total',
|
||||||
|
timingMs: performance.now() - beforeAllTimeMs,
|
||||||
|
});
|
||||||
|
|
||||||
logPerformance();
|
|
||||||
return allSourcesPath;
|
return allSourcesPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,8 +395,10 @@ export async function findOptimalPathJSAsync(
|
|||||||
fills: Fill[][],
|
fills: Fill[][],
|
||||||
targetInput: BigNumber,
|
targetInput: BigNumber,
|
||||||
runLimit: number = 2 ** 8,
|
runLimit: number = 2 ** 8,
|
||||||
|
samplerMetrics?: SamplerMetrics,
|
||||||
opts: PathPenaltyOpts = DEFAULT_PATH_PENALTY_OPTS,
|
opts: PathPenaltyOpts = DEFAULT_PATH_PENALTY_OPTS,
|
||||||
): Promise<Path | undefined> {
|
): Promise<Path | undefined> {
|
||||||
|
const beforeTimeMs = performance.now();
|
||||||
// Sort fill arrays by descending adjusted completed rate.
|
// Sort fill arrays by descending adjusted completed rate.
|
||||||
// Remove any paths which cannot impact the optimal path
|
// Remove any paths which cannot impact the optimal path
|
||||||
const sortedPaths = reducePaths(fillsToSortedPaths(fills, side, targetInput, opts), side);
|
const sortedPaths = reducePaths(fillsToSortedPaths(fills, side, targetInput, opts), side);
|
||||||
@@ -392,7 +412,15 @@ export async function findOptimalPathJSAsync(
|
|||||||
// Yield to event loop.
|
// Yield to event loop.
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
}
|
}
|
||||||
return optimalPath.isComplete() ? optimalPath : undefined;
|
const finalPath = optimalPath.isComplete() ? optimalPath : undefined;
|
||||||
|
// tslint:disable-next-line: no-unused-expression
|
||||||
|
samplerMetrics &&
|
||||||
|
samplerMetrics.logRouterDetails({
|
||||||
|
router: 'js',
|
||||||
|
type: 'total',
|
||||||
|
timingMs: performance.now() - beforeTimeMs,
|
||||||
|
});
|
||||||
|
return finalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort fill arrays by descending adjusted completed rate.
|
// Sort fill arrays by descending adjusted completed rate.
|
||||||
|
@@ -14,7 +14,8 @@ import { BatchedOperation, ERC20BridgeSource, LiquidityProviderRegistry, TokenAd
|
|||||||
*/
|
*/
|
||||||
export function getSampleAmounts(maxFillAmount: BigNumber, numSamples: number, expBase: number = 1): BigNumber[] {
|
export function getSampleAmounts(maxFillAmount: BigNumber, numSamples: number, expBase: number = 1): BigNumber[] {
|
||||||
const distribution = [...Array<BigNumber>(numSamples)].map((_v, i) => new BigNumber(expBase).pow(i));
|
const distribution = [...Array<BigNumber>(numSamples)].map((_v, i) => new BigNumber(expBase).pow(i));
|
||||||
const stepSizes = distribution.map(d => d.div(BigNumber.sum(...distribution)));
|
const distributionSum = BigNumber.sum(...distribution);
|
||||||
|
const stepSizes = distribution.map(d => d.div(distributionSum));
|
||||||
const amounts = stepSizes.map((_s, i) => {
|
const amounts = stepSizes.map((_s, i) => {
|
||||||
if (i === numSamples - 1) {
|
if (i === numSamples - 1) {
|
||||||
return maxFillAmount;
|
return maxFillAmount;
|
||||||
@@ -130,6 +131,37 @@ export class DexOrderSampler extends SamplerOperations {
|
|||||||
BatchedOperationResult<T8>
|
BatchedOperationResult<T8>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
public async executeAsync<
|
||||||
|
T1, T2, T3, T4, T5, T6, T7, T8, T9
|
||||||
|
>(...ops: [T1, T2, T3, T4, T5, T6, T7, T8, T9]): Promise<[
|
||||||
|
BatchedOperationResult<T1>,
|
||||||
|
BatchedOperationResult<T2>,
|
||||||
|
BatchedOperationResult<T3>,
|
||||||
|
BatchedOperationResult<T4>,
|
||||||
|
BatchedOperationResult<T5>,
|
||||||
|
BatchedOperationResult<T6>,
|
||||||
|
BatchedOperationResult<T7>,
|
||||||
|
BatchedOperationResult<T8>,
|
||||||
|
BatchedOperationResult<T9>
|
||||||
|
]>;
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
public async executeAsync<
|
||||||
|
T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
|
||||||
|
>(...ops: [T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]): Promise<[
|
||||||
|
BatchedOperationResult<T1>,
|
||||||
|
BatchedOperationResult<T2>,
|
||||||
|
BatchedOperationResult<T3>,
|
||||||
|
BatchedOperationResult<T4>,
|
||||||
|
BatchedOperationResult<T5>,
|
||||||
|
BatchedOperationResult<T6>,
|
||||||
|
BatchedOperationResult<T7>,
|
||||||
|
BatchedOperationResult<T8>,
|
||||||
|
BatchedOperationResult<T9>,
|
||||||
|
BatchedOperationResult<T10>,
|
||||||
|
]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a series of operations from `DexOrderSampler.ops` in a single transaction.
|
* Run a series of operations from `DexOrderSampler.ops` in a single transaction.
|
||||||
*/
|
*/
|
||||||
|
@@ -0,0 +1,36 @@
|
|||||||
|
import { BigNumber, logUtils, NULL_BYTES } from '@0x/utils';
|
||||||
|
|
||||||
|
import { ERC20BridgeSource, FillData, SourceQuoteOperation } from './types';
|
||||||
|
|
||||||
|
interface SamplerNoOperationCall {
|
||||||
|
callback: () => BigNumber[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SamplerNoOperation can be used for sources where we already have all the necessary information
|
||||||
|
* required to perform the sample operations, without needing access to any on-chain data. Using a noop sample
|
||||||
|
* you can skip the eth_call, and just calculate the results directly in typescript land.
|
||||||
|
*/
|
||||||
|
export class SamplerNoOperation<TFillData extends FillData = FillData> implements SourceQuoteOperation<TFillData> {
|
||||||
|
public readonly source: ERC20BridgeSource;
|
||||||
|
public fillData: TFillData;
|
||||||
|
private readonly _callback: () => BigNumber[];
|
||||||
|
|
||||||
|
constructor(opts: { source: ERC20BridgeSource; fillData?: TFillData } & SamplerNoOperationCall) {
|
||||||
|
this.source = opts.source;
|
||||||
|
this.fillData = opts.fillData || ({} as TFillData); // tslint:disable-line:no-object-literal-type-assertion
|
||||||
|
this._callback = opts.callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
|
public encodeCall(): string {
|
||||||
|
return NULL_BYTES;
|
||||||
|
}
|
||||||
|
public handleCallResults(_callResults: string): BigNumber[] {
|
||||||
|
return this._callback();
|
||||||
|
}
|
||||||
|
public handleRevert(_callResults: string): BigNumber[] {
|
||||||
|
logUtils.warn(`SamplerNoOperation: ${this.source} reverted`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
@@ -3,9 +3,11 @@ import { LimitOrderFields } from '@0x/protocol-utils';
|
|||||||
import { BigNumber, logUtils } from '@0x/utils';
|
import { BigNumber, logUtils } from '@0x/utils';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
|
import { AaveV2Sampler } from '../../noop_samplers/AaveV2Sampler';
|
||||||
import { SamplerCallResult, SignedNativeOrder } from '../../types';
|
import { SamplerCallResult, SignedNativeOrder } from '../../types';
|
||||||
import { ERC20BridgeSamplerContract } from '../../wrappers';
|
import { ERC20BridgeSamplerContract } from '../../wrappers';
|
||||||
|
|
||||||
|
import { AaveV2ReservesCache } from './aave_reserves_cache';
|
||||||
import { BancorService } from './bancor_service';
|
import { BancorService } from './bancor_service';
|
||||||
import {
|
import {
|
||||||
getCurveLikeInfosForPair,
|
getCurveLikeInfosForPair,
|
||||||
@@ -17,9 +19,14 @@ import {
|
|||||||
isValidAddress,
|
isValidAddress,
|
||||||
uniswapV2LikeRouterAddress,
|
uniswapV2LikeRouterAddress,
|
||||||
} from './bridge_source_utils';
|
} from './bridge_source_utils';
|
||||||
|
import { CompoundCTokenCache } from './compound_ctoken_cache';
|
||||||
import {
|
import {
|
||||||
|
AAVE_V2_SUBGRAPH_URL_BY_CHAIN_ID,
|
||||||
BALANCER_V2_VAULT_ADDRESS_BY_CHAIN,
|
BALANCER_V2_VAULT_ADDRESS_BY_CHAIN,
|
||||||
BANCOR_REGISTRY_BY_CHAIN_ID,
|
BANCOR_REGISTRY_BY_CHAIN_ID,
|
||||||
|
BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN,
|
||||||
|
BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN,
|
||||||
|
COMPOUND_API_URL_BY_CHAIN_ID,
|
||||||
DODOV1_CONFIG_BY_CHAIN_ID,
|
DODOV1_CONFIG_BY_CHAIN_ID,
|
||||||
DODOV2_FACTORIES_BY_CHAIN_ID,
|
DODOV2_FACTORIES_BY_CHAIN_ID,
|
||||||
KYBER_CONFIG_BY_CHAIN_ID,
|
KYBER_CONFIG_BY_CHAIN_ID,
|
||||||
@@ -43,13 +50,17 @@ import { getLiquidityProvidersForPair } from './liquidity_provider_utils';
|
|||||||
import { getIntermediateTokens } from './multihop_utils';
|
import { getIntermediateTokens } from './multihop_utils';
|
||||||
import { BalancerPoolsCache, BalancerV2PoolsCache, CreamPoolsCache, PoolsCache } from './pools_cache';
|
import { BalancerPoolsCache, BalancerV2PoolsCache, CreamPoolsCache, PoolsCache } from './pools_cache';
|
||||||
import { SamplerContractOperation } from './sampler_contract_operation';
|
import { SamplerContractOperation } from './sampler_contract_operation';
|
||||||
|
import { SamplerNoOperation } from './sampler_no_operation';
|
||||||
import { SourceFilters } from './source_filters';
|
import { SourceFilters } from './source_filters';
|
||||||
import {
|
import {
|
||||||
|
AaveV2FillData,
|
||||||
|
AaveV2Info,
|
||||||
BalancerFillData,
|
BalancerFillData,
|
||||||
BalancerV2FillData,
|
BalancerV2FillData,
|
||||||
BalancerV2PoolInfo,
|
BalancerV2PoolInfo,
|
||||||
BancorFillData,
|
BancorFillData,
|
||||||
BatchedOperation,
|
BatchedOperation,
|
||||||
|
CompoundFillData,
|
||||||
CurveFillData,
|
CurveFillData,
|
||||||
CurveInfo,
|
CurveInfo,
|
||||||
DexSample,
|
DexSample,
|
||||||
@@ -97,6 +108,8 @@ export const BATCH_SOURCE_FILTERS = SourceFilters.all().exclude([ERC20BridgeSour
|
|||||||
export class SamplerOperations {
|
export class SamplerOperations {
|
||||||
public readonly liquidityProviderRegistry: LiquidityProviderRegistry;
|
public readonly liquidityProviderRegistry: LiquidityProviderRegistry;
|
||||||
public readonly poolsCaches: { [key in SourcesWithPoolsCache]: PoolsCache };
|
public readonly poolsCaches: { [key in SourcesWithPoolsCache]: PoolsCache };
|
||||||
|
public readonly aaveReservesCache: AaveV2ReservesCache | undefined;
|
||||||
|
public readonly compoundCTokenCache: CompoundCTokenCache | undefined;
|
||||||
protected _bancorService?: BancorService;
|
protected _bancorService?: BancorService;
|
||||||
public static constant<T>(result: T): BatchedOperation<T> {
|
public static constant<T>(result: T): BatchedOperation<T> {
|
||||||
return {
|
return {
|
||||||
@@ -122,9 +135,26 @@ export class SamplerOperations {
|
|||||||
? poolsCaches
|
? poolsCaches
|
||||||
: {
|
: {
|
||||||
[ERC20BridgeSource.BalancerV2]: new BalancerV2PoolsCache(chainId),
|
[ERC20BridgeSource.BalancerV2]: new BalancerV2PoolsCache(chainId),
|
||||||
|
[ERC20BridgeSource.Beethovenx]: new BalancerV2PoolsCache(
|
||||||
|
chainId,
|
||||||
|
BEETHOVEN_X_SUBGRAPH_URL_BY_CHAIN[chainId],
|
||||||
|
),
|
||||||
[ERC20BridgeSource.Balancer]: new BalancerPoolsCache(),
|
[ERC20BridgeSource.Balancer]: new BalancerPoolsCache(),
|
||||||
[ERC20BridgeSource.Cream]: new CreamPoolsCache(),
|
[ERC20BridgeSource.Cream]: new CreamPoolsCache(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const aaveSubgraphUrl = AAVE_V2_SUBGRAPH_URL_BY_CHAIN_ID[chainId];
|
||||||
|
if (aaveSubgraphUrl) {
|
||||||
|
this.aaveReservesCache = new AaveV2ReservesCache(aaveSubgraphUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
const compoundApiUrl = COMPOUND_API_URL_BY_CHAIN_ID[chainId];
|
||||||
|
if (compoundApiUrl) {
|
||||||
|
this.compoundCTokenCache = new CompoundCTokenCache(
|
||||||
|
compoundApiUrl,
|
||||||
|
NATIVE_FEE_TOKEN_BY_CHAIN_ID[this.chainId],
|
||||||
|
);
|
||||||
|
}
|
||||||
// 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))
|
||||||
@@ -152,6 +182,30 @@ export class SamplerOperations {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getGasLeft(): BatchedOperation<BigNumber> {
|
||||||
|
return {
|
||||||
|
encodeCall: () => this._samplerContract.getGasLeft().getABIEncodedTransactionData(),
|
||||||
|
handleCallResults: (callResults: string) =>
|
||||||
|
this._samplerContract.getABIDecodedReturnData<BigNumber>('getGasLeft', callResults),
|
||||||
|
handleRevert: () => {
|
||||||
|
/* should never happen */
|
||||||
|
throw new Error('Invalid result for getGasLeft');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBlockNumber(): BatchedOperation<BigNumber> {
|
||||||
|
return {
|
||||||
|
encodeCall: () => this._samplerContract.getBlockNumber().getABIEncodedTransactionData(),
|
||||||
|
handleCallResults: (callResults: string) =>
|
||||||
|
this._samplerContract.getABIDecodedReturnData<BigNumber>('getBlockNumber', callResults),
|
||||||
|
handleRevert: () => {
|
||||||
|
/* should never happen */
|
||||||
|
throw new Error('Invalid result for getBlockNumber');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public getLimitOrderFillableTakerAmounts(
|
public getLimitOrderFillableTakerAmounts(
|
||||||
orders: SignedNativeOrder[],
|
orders: SignedNativeOrder[],
|
||||||
exchangeAddress: string,
|
exchangeAddress: string,
|
||||||
@@ -1069,6 +1123,64 @@ export class SamplerOperations {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
|
public getAaveV2SellQuotes(
|
||||||
|
aaveInfo: AaveV2Info,
|
||||||
|
makerToken: string,
|
||||||
|
takerToken: string,
|
||||||
|
takerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<AaveV2FillData> {
|
||||||
|
return new SamplerNoOperation({
|
||||||
|
source: ERC20BridgeSource.AaveV2,
|
||||||
|
fillData: { ...aaveInfo, takerToken },
|
||||||
|
callback: () => AaveV2Sampler.sampleSellsFromAaveV2(aaveInfo, takerToken, makerToken, takerFillAmounts),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line:prefer-function-over-method
|
||||||
|
public getAaveV2BuyQuotes(
|
||||||
|
aaveInfo: AaveV2Info,
|
||||||
|
makerToken: string,
|
||||||
|
takerToken: string,
|
||||||
|
makerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<AaveV2FillData> {
|
||||||
|
return new SamplerNoOperation({
|
||||||
|
source: ERC20BridgeSource.AaveV2,
|
||||||
|
fillData: { ...aaveInfo, takerToken },
|
||||||
|
callback: () => AaveV2Sampler.sampleBuysFromAaveV2(aaveInfo, takerToken, makerToken, makerFillAmounts),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCompoundSellQuotes(
|
||||||
|
cToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
takerToken: string,
|
||||||
|
takerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<CompoundFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Compound,
|
||||||
|
fillData: { cToken, takerToken, makerToken },
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleSellsFromCompound,
|
||||||
|
params: [cToken, takerToken, makerToken, takerFillAmounts],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCompoundBuyQuotes(
|
||||||
|
cToken: string,
|
||||||
|
makerToken: string,
|
||||||
|
takerToken: string,
|
||||||
|
makerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<CompoundFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Compound,
|
||||||
|
fillData: { cToken, takerToken, makerToken },
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleBuysFromCompound,
|
||||||
|
params: [cToken, takerToken, makerToken, makerFillAmounts],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public getMedianSellRate(
|
public getMedianSellRate(
|
||||||
sources: ERC20BridgeSource[],
|
sources: ERC20BridgeSource[],
|
||||||
makerToken: string,
|
makerToken: string,
|
||||||
@@ -1200,6 +1312,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.UbeSwap:
|
case ERC20BridgeSource.UbeSwap:
|
||||||
case ERC20BridgeSource.SpiritSwap:
|
case ERC20BridgeSource.SpiritSwap:
|
||||||
case ERC20BridgeSource.SpookySwap:
|
case ERC20BridgeSource.SpookySwap:
|
||||||
|
case ERC20BridgeSource.MorpheusSwap:
|
||||||
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
||||||
if (!isValidAddress(uniLikeRouter)) {
|
if (!isValidAddress(uniLikeRouter)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -1229,6 +1342,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.Swerve:
|
case ERC20BridgeSource.Swerve:
|
||||||
case ERC20BridgeSource.SnowSwap:
|
case ERC20BridgeSource.SnowSwap:
|
||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
|
case ERC20BridgeSource.Synapse:
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
case ERC20BridgeSource.Saddle:
|
case ERC20BridgeSource.Saddle:
|
||||||
@@ -1301,13 +1415,14 @@ export class SamplerOperations {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
case ERC20BridgeSource.BalancerV2:
|
case ERC20BridgeSource.BalancerV2:
|
||||||
|
case ERC20BridgeSource.Beethovenx:
|
||||||
const poolIds =
|
const poolIds =
|
||||||
this.poolsCaches[ERC20BridgeSource.BalancerV2].getCachedPoolAddressesForPair(
|
this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
|
||||||
takerToken,
|
|
||||||
makerToken,
|
|
||||||
) || [];
|
|
||||||
|
|
||||||
const vault = BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId];
|
const vault =
|
||||||
|
source === ERC20BridgeSource.BalancerV2
|
||||||
|
? BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId]
|
||||||
|
: BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
|
||||||
if (vault === NULL_ADDRESS) {
|
if (vault === NULL_ADDRESS) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -1317,10 +1432,9 @@ export class SamplerOperations {
|
|||||||
makerToken,
|
makerToken,
|
||||||
takerToken,
|
takerToken,
|
||||||
takerFillAmounts,
|
takerFillAmounts,
|
||||||
ERC20BridgeSource.BalancerV2,
|
source,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
case ERC20BridgeSource.Cream:
|
case ERC20BridgeSource.Cream:
|
||||||
return (
|
return (
|
||||||
this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
|
this.poolsCaches[ERC20BridgeSource.Cream].getCachedPoolAddressesForPair(
|
||||||
@@ -1418,6 +1532,38 @@ export class SamplerOperations {
|
|||||||
|
|
||||||
return this.getLidoSellQuotes(lidoInfo, makerToken, takerToken, takerFillAmounts);
|
return this.getLidoSellQuotes(lidoInfo, makerToken, takerToken, takerFillAmounts);
|
||||||
}
|
}
|
||||||
|
case ERC20BridgeSource.AaveV2: {
|
||||||
|
if (!this.aaveReservesCache) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const reserve = this.aaveReservesCache.get(takerToken, makerToken);
|
||||||
|
if (!reserve) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const info: AaveV2Info = {
|
||||||
|
lendingPool: reserve.pool.lendingPool,
|
||||||
|
aToken: reserve.aToken.id,
|
||||||
|
underlyingToken: reserve.underlyingAsset,
|
||||||
|
};
|
||||||
|
return this.getAaveV2SellQuotes(info, makerToken, takerToken, takerFillAmounts);
|
||||||
|
}
|
||||||
|
case ERC20BridgeSource.Compound: {
|
||||||
|
if (!this.compoundCTokenCache) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cToken = this.compoundCTokenCache.get(takerToken, makerToken);
|
||||||
|
if (!cToken) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.getCompoundSellQuotes(
|
||||||
|
cToken.tokenAddress,
|
||||||
|
makerToken,
|
||||||
|
takerToken,
|
||||||
|
takerFillAmounts,
|
||||||
|
);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported sell sample source: ${source}`);
|
throw new Error(`Unsupported sell sample source: ${source}`);
|
||||||
}
|
}
|
||||||
@@ -1472,6 +1618,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.UbeSwap:
|
case ERC20BridgeSource.UbeSwap:
|
||||||
case ERC20BridgeSource.SpiritSwap:
|
case ERC20BridgeSource.SpiritSwap:
|
||||||
case ERC20BridgeSource.SpookySwap:
|
case ERC20BridgeSource.SpookySwap:
|
||||||
|
case ERC20BridgeSource.MorpheusSwap:
|
||||||
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
const uniLikeRouter = uniswapV2LikeRouterAddress(this.chainId, source);
|
||||||
if (!isValidAddress(uniLikeRouter)) {
|
if (!isValidAddress(uniLikeRouter)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -1501,6 +1648,7 @@ export class SamplerOperations {
|
|||||||
case ERC20BridgeSource.Swerve:
|
case ERC20BridgeSource.Swerve:
|
||||||
case ERC20BridgeSource.SnowSwap:
|
case ERC20BridgeSource.SnowSwap:
|
||||||
case ERC20BridgeSource.Nerve:
|
case ERC20BridgeSource.Nerve:
|
||||||
|
case ERC20BridgeSource.Synapse:
|
||||||
case ERC20BridgeSource.Belt:
|
case ERC20BridgeSource.Belt:
|
||||||
case ERC20BridgeSource.Ellipsis:
|
case ERC20BridgeSource.Ellipsis:
|
||||||
case ERC20BridgeSource.Saddle:
|
case ERC20BridgeSource.Saddle:
|
||||||
@@ -1573,13 +1721,14 @@ export class SamplerOperations {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
case ERC20BridgeSource.BalancerV2:
|
case ERC20BridgeSource.BalancerV2:
|
||||||
|
case ERC20BridgeSource.Beethovenx:
|
||||||
const poolIds =
|
const poolIds =
|
||||||
this.poolsCaches[ERC20BridgeSource.BalancerV2].getCachedPoolAddressesForPair(
|
this.poolsCaches[source].getCachedPoolAddressesForPair(takerToken, makerToken) || [];
|
||||||
takerToken,
|
|
||||||
makerToken,
|
|
||||||
) || [];
|
|
||||||
|
|
||||||
const vault = BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId];
|
const vault =
|
||||||
|
source === ERC20BridgeSource.BalancerV2
|
||||||
|
? BALANCER_V2_VAULT_ADDRESS_BY_CHAIN[this.chainId]
|
||||||
|
: BEETHOVEN_X_VAULT_ADDRESS_BY_CHAIN[this.chainId];
|
||||||
if (vault === NULL_ADDRESS) {
|
if (vault === NULL_ADDRESS) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -1589,7 +1738,7 @@ export class SamplerOperations {
|
|||||||
makerToken,
|
makerToken,
|
||||||
takerToken,
|
takerToken,
|
||||||
makerFillAmounts,
|
makerFillAmounts,
|
||||||
ERC20BridgeSource.BalancerV2,
|
source,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
case ERC20BridgeSource.Cream:
|
case ERC20BridgeSource.Cream:
|
||||||
@@ -1685,6 +1834,32 @@ export class SamplerOperations {
|
|||||||
|
|
||||||
return this.getLidoBuyQuotes(lidoInfo, makerToken, takerToken, makerFillAmounts);
|
return this.getLidoBuyQuotes(lidoInfo, makerToken, takerToken, makerFillAmounts);
|
||||||
}
|
}
|
||||||
|
case ERC20BridgeSource.AaveV2: {
|
||||||
|
if (!this.aaveReservesCache) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const reserve = this.aaveReservesCache.get(takerToken, makerToken);
|
||||||
|
if (!reserve) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const info: AaveV2Info = {
|
||||||
|
lendingPool: reserve.pool.lendingPool,
|
||||||
|
aToken: reserve.aToken.id,
|
||||||
|
underlyingToken: reserve.underlyingAsset,
|
||||||
|
};
|
||||||
|
return this.getAaveV2BuyQuotes(info, makerToken, takerToken, makerFillAmounts);
|
||||||
|
}
|
||||||
|
case ERC20BridgeSource.Compound: {
|
||||||
|
if (!this.compoundCTokenCache) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cToken = this.compoundCTokenCache.get(takerToken, makerToken);
|
||||||
|
if (!cToken) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.getCompoundBuyQuotes(cToken.tokenAddress, makerToken, takerToken, makerFillAmounts);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported buy sample source: ${source}`);
|
throw new Error(`Unsupported buy sample source: ${source}`);
|
||||||
}
|
}
|
||||||
|
@@ -68,6 +68,9 @@ export enum ERC20BridgeSource {
|
|||||||
CurveV2 = 'Curve_V2',
|
CurveV2 = 'Curve_V2',
|
||||||
Lido = 'Lido',
|
Lido = 'Lido',
|
||||||
ShibaSwap = 'ShibaSwap',
|
ShibaSwap = 'ShibaSwap',
|
||||||
|
AaveV2 = 'Aave_V2',
|
||||||
|
Compound = 'Compound',
|
||||||
|
Synapse = 'Synapse',
|
||||||
// BSC only
|
// BSC only
|
||||||
PancakeSwap = 'PancakeSwap',
|
PancakeSwap = 'PancakeSwap',
|
||||||
PancakeSwapV2 = 'PancakeSwap_V2',
|
PancakeSwapV2 = 'PancakeSwap_V2',
|
||||||
@@ -97,8 +100,14 @@ export enum ERC20BridgeSource {
|
|||||||
// Fantom
|
// Fantom
|
||||||
SpiritSwap = 'SpiritSwap',
|
SpiritSwap = 'SpiritSwap',
|
||||||
SpookySwap = 'SpookySwap',
|
SpookySwap = 'SpookySwap',
|
||||||
|
Beethovenx = 'Beethovenx',
|
||||||
|
MorpheusSwap = 'MorpheusSwap',
|
||||||
}
|
}
|
||||||
export type SourcesWithPoolsCache = ERC20BridgeSource.Balancer | ERC20BridgeSource.BalancerV2 | ERC20BridgeSource.Cream;
|
export type SourcesWithPoolsCache =
|
||||||
|
| ERC20BridgeSource.Balancer
|
||||||
|
| ERC20BridgeSource.BalancerV2
|
||||||
|
| ERC20BridgeSource.Beethovenx
|
||||||
|
| ERC20BridgeSource.Cream;
|
||||||
|
|
||||||
// tslint:disable: enum-naming
|
// tslint:disable: enum-naming
|
||||||
/**
|
/**
|
||||||
@@ -107,11 +116,13 @@ export type SourcesWithPoolsCache = ERC20BridgeSource.Balancer | ERC20BridgeSour
|
|||||||
export enum CurveFunctionSelectors {
|
export enum CurveFunctionSelectors {
|
||||||
None = '0x00000000',
|
None = '0x00000000',
|
||||||
exchange = '0x3df02124',
|
exchange = '0x3df02124',
|
||||||
exchange_underlying = '0xa6417ed6',
|
exchange_underlying = '0xa6417ed6', // exchange_underlying(int128 i, int128 j, uint256 dx, uint256 min_dy)
|
||||||
get_dy_underlying = '0x07211ef7',
|
get_dy_underlying = '0x07211ef7',
|
||||||
get_dx_underlying = '0x0e71d1b9',
|
get_dx_underlying = '0x0e71d1b9',
|
||||||
get_dy = '0x5e0d443f',
|
get_dy = '0x5e0d443f', // get_dy(int128,int128,uint256)
|
||||||
get_dx = '0x67df02ca',
|
get_dx = '0x67df02ca',
|
||||||
|
get_dy_uint256 = '0x556d6e9f', // get_dy(uint256,uint256,uint256)
|
||||||
|
exchange_underlying_uint256 = '0x65b2489b', // exchange_underlying(uint256,uint256,uint256,uint256)
|
||||||
// Curve V2
|
// Curve V2
|
||||||
exchange_v2 = '0x5b41b908',
|
exchange_v2 = '0x5b41b908',
|
||||||
exchange_underlying_v2 = '0x65b2489b',
|
exchange_underlying_v2 = '0x65b2489b',
|
||||||
@@ -120,7 +131,7 @@ export enum CurveFunctionSelectors {
|
|||||||
// Smoothy
|
// Smoothy
|
||||||
swap_uint256 = '0x5673b02d', // swap(uint256,uint256,uint256,uint256)
|
swap_uint256 = '0x5673b02d', // swap(uint256,uint256,uint256,uint256)
|
||||||
get_swap_amount = '0x45cf2ef6', // getSwapAmount(uint256,uint256,uint256)
|
get_swap_amount = '0x45cf2ef6', // getSwapAmount(uint256,uint256,uint256)
|
||||||
// Nerve BSC, Saddle Mainnet
|
// Nerve BSC, Saddle Mainnet, Synapse
|
||||||
swap = '0x91695586', // swap(uint8,uint8,uint256,uint256,uint256)
|
swap = '0x91695586', // swap(uint8,uint8,uint256,uint256,uint256)
|
||||||
calculateSwap = '0xa95b089f', // calculateSwap(uint8,uint8,uint256)
|
calculateSwap = '0xa95b089f', // calculateSwap(uint8,uint8,uint256)
|
||||||
}
|
}
|
||||||
@@ -164,6 +175,12 @@ export interface BalancerV2PoolInfo {
|
|||||||
vault: string;
|
vault: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AaveV2Info {
|
||||||
|
lendingPool: string;
|
||||||
|
aToken: string;
|
||||||
|
underlyingToken: string;
|
||||||
|
}
|
||||||
|
|
||||||
// Internal `fillData` field for `Fill` objects.
|
// Internal `fillData` field for `Fill` objects.
|
||||||
export interface FillData {}
|
export interface FillData {}
|
||||||
|
|
||||||
@@ -271,6 +288,19 @@ export interface LidoFillData extends FillData {
|
|||||||
takerToken: string;
|
takerToken: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AaveV2FillData extends FillData {
|
||||||
|
lendingPool: string;
|
||||||
|
aToken: string;
|
||||||
|
underlyingToken: string;
|
||||||
|
takerToken: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompoundFillData extends FillData {
|
||||||
|
cToken: string;
|
||||||
|
takerToken: string;
|
||||||
|
makerToken: string;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a node on a fill path.
|
* Represents a node on a fill path.
|
||||||
*/
|
*/
|
||||||
@@ -426,6 +456,10 @@ export interface GetMarketOrdersOpts {
|
|||||||
* Default: 1.25.
|
* Default: 1.25.
|
||||||
*/
|
*/
|
||||||
sampleDistributionBase: number;
|
sampleDistributionBase: number;
|
||||||
|
/**
|
||||||
|
* Number of samples to use when creating fill curves with neon-router
|
||||||
|
*/
|
||||||
|
neonRouterNumSamples: number;
|
||||||
/**
|
/**
|
||||||
* Fees for each liquidity source, expressed in gas.
|
* Fees for each liquidity source, expressed in gas.
|
||||||
*/
|
*/
|
||||||
@@ -463,6 +497,37 @@ export interface GetMarketOrdersOpts {
|
|||||||
* Gas price to use for quote
|
* Gas price to use for quote
|
||||||
*/
|
*/
|
||||||
gasPrice: BigNumber;
|
gasPrice: BigNumber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sampler metrics for recording data on the sampler service and operations
|
||||||
|
*/
|
||||||
|
samplerMetrics?: SamplerMetrics;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SamplerMetrics {
|
||||||
|
/**
|
||||||
|
* Logs the gas information performed during a sampler call.
|
||||||
|
*
|
||||||
|
* @param data.gasBefore The gas remaining measured before any operations have been performed
|
||||||
|
* @param data.gasAfter The gas remaining measured after all operations have been performed
|
||||||
|
*/
|
||||||
|
logGasDetails(data: { gasBefore: BigNumber; gasAfter: BigNumber }): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the block number
|
||||||
|
*
|
||||||
|
* @param blockNumber block number of the sampler call
|
||||||
|
*/
|
||||||
|
logBlockNumber(blockNumber: BigNumber): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the routing timings
|
||||||
|
*
|
||||||
|
* @param data.router The router type (neon-router or js)
|
||||||
|
* @param data.type The type of timing being recorded (e.g total timing, all sources timing or vip timing)
|
||||||
|
* @param data.timingMs The timing in milliseconds
|
||||||
|
*/
|
||||||
|
logRouterDetails(data: { router: 'neon-router' | 'js'; type: 'all' | 'vip' | 'total'; timingMs: number }): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -548,6 +613,8 @@ export interface GenerateOptimizedOrdersOpts {
|
|||||||
allowFallback?: boolean;
|
allowFallback?: boolean;
|
||||||
shouldBatchBridgeOrders?: boolean;
|
shouldBatchBridgeOrders?: boolean;
|
||||||
gasPrice: BigNumber;
|
gasPrice: BigNumber;
|
||||||
|
neonRouterNumSamples: number;
|
||||||
|
samplerMetrics?: SamplerMetrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComparisonPrice {
|
export interface ComparisonPrice {
|
||||||
|
@@ -10,6 +10,7 @@ import * as BalanceChecker from '../test/generated-artifacts/BalanceChecker.json
|
|||||||
import * as BalancerSampler from '../test/generated-artifacts/BalancerSampler.json';
|
import * as BalancerSampler from '../test/generated-artifacts/BalancerSampler.json';
|
||||||
import * as BalancerV2Sampler from '../test/generated-artifacts/BalancerV2Sampler.json';
|
import * as BalancerV2Sampler from '../test/generated-artifacts/BalancerV2Sampler.json';
|
||||||
import * as BancorSampler from '../test/generated-artifacts/BancorSampler.json';
|
import * as BancorSampler from '../test/generated-artifacts/BancorSampler.json';
|
||||||
|
import * as CompoundSampler from '../test/generated-artifacts/CompoundSampler.json';
|
||||||
import * as CurveSampler from '../test/generated-artifacts/CurveSampler.json';
|
import * as CurveSampler from '../test/generated-artifacts/CurveSampler.json';
|
||||||
import * as DODOSampler from '../test/generated-artifacts/DODOSampler.json';
|
import * as DODOSampler from '../test/generated-artifacts/DODOSampler.json';
|
||||||
import * as DODOV2Sampler from '../test/generated-artifacts/DODOV2Sampler.json';
|
import * as DODOV2Sampler from '../test/generated-artifacts/DODOV2Sampler.json';
|
||||||
@@ -52,6 +53,7 @@ export const artifacts = {
|
|||||||
BalancerSampler: BalancerSampler as ContractArtifact,
|
BalancerSampler: BalancerSampler as ContractArtifact,
|
||||||
BalancerV2Sampler: BalancerV2Sampler as ContractArtifact,
|
BalancerV2Sampler: BalancerV2Sampler as ContractArtifact,
|
||||||
BancorSampler: BancorSampler as ContractArtifact,
|
BancorSampler: BancorSampler as ContractArtifact,
|
||||||
|
CompoundSampler: CompoundSampler as ContractArtifact,
|
||||||
CurveSampler: CurveSampler as ContractArtifact,
|
CurveSampler: CurveSampler as ContractArtifact,
|
||||||
DODOSampler: DODOSampler as ContractArtifact,
|
DODOSampler: DODOSampler as ContractArtifact,
|
||||||
DODOV2Sampler: DODOV2Sampler as ContractArtifact,
|
DODOV2Sampler: DODOV2Sampler as ContractArtifact,
|
||||||
|
@@ -23,6 +23,7 @@ import {
|
|||||||
POSITIVE_INF,
|
POSITIVE_INF,
|
||||||
SELL_SOURCE_FILTER_BY_CHAIN_ID,
|
SELL_SOURCE_FILTER_BY_CHAIN_ID,
|
||||||
SOURCE_FLAGS,
|
SOURCE_FLAGS,
|
||||||
|
ZERO_AMOUNT,
|
||||||
} from '../src/utils/market_operation_utils/constants';
|
} from '../src/utils/market_operation_utils/constants';
|
||||||
import { createFills } from '../src/utils/market_operation_utils/fills';
|
import { createFills } from '../src/utils/market_operation_utils/fills';
|
||||||
import { PoolsCache } from '../src/utils/market_operation_utils/pools_cache';
|
import { PoolsCache } from '../src/utils/market_operation_utils/pools_cache';
|
||||||
@@ -427,6 +428,8 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
getTwoHopSellQuotes: (..._params: any[]) => [],
|
getTwoHopSellQuotes: (..._params: any[]) => [],
|
||||||
getTwoHopBuyQuotes: (..._params: any[]) => [],
|
getTwoHopBuyQuotes: (..._params: any[]) => [],
|
||||||
isAddressContract: (..._params: any[]) => false,
|
isAddressContract: (..._params: any[]) => false,
|
||||||
|
getGasLeft: () => ZERO_AMOUNT,
|
||||||
|
getBlockNumber: () => ZERO_AMOUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
const MOCK_SAMPLER = ({
|
const MOCK_SAMPLER = ({
|
||||||
|
@@ -8,6 +8,7 @@ export * from '../test/generated-wrappers/balance_checker';
|
|||||||
export * from '../test/generated-wrappers/balancer_sampler';
|
export * from '../test/generated-wrappers/balancer_sampler';
|
||||||
export * from '../test/generated-wrappers/balancer_v2_sampler';
|
export * from '../test/generated-wrappers/balancer_v2_sampler';
|
||||||
export * from '../test/generated-wrappers/bancor_sampler';
|
export * from '../test/generated-wrappers/bancor_sampler';
|
||||||
|
export * from '../test/generated-wrappers/compound_sampler';
|
||||||
export * from '../test/generated-wrappers/curve_sampler';
|
export * from '../test/generated-wrappers/curve_sampler';
|
||||||
export * from '../test/generated-wrappers/d_o_d_o_sampler';
|
export * from '../test/generated-wrappers/d_o_d_o_sampler';
|
||||||
export * from '../test/generated-wrappers/d_o_d_o_v2_sampler';
|
export * from '../test/generated-wrappers/d_o_d_o_v2_sampler';
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
"test/generated-artifacts/BalancerSampler.json",
|
"test/generated-artifacts/BalancerSampler.json",
|
||||||
"test/generated-artifacts/BalancerV2Sampler.json",
|
"test/generated-artifacts/BalancerV2Sampler.json",
|
||||||
"test/generated-artifacts/BancorSampler.json",
|
"test/generated-artifacts/BancorSampler.json",
|
||||||
|
"test/generated-artifacts/CompoundSampler.json",
|
||||||
"test/generated-artifacts/CurveSampler.json",
|
"test/generated-artifacts/CurveSampler.json",
|
||||||
"test/generated-artifacts/DODOSampler.json",
|
"test/generated-artifacts/DODOSampler.json",
|
||||||
"test/generated-artifacts/DODOV2Sampler.json",
|
"test/generated-artifacts/DODOV2Sampler.json",
|
||||||
|
@@ -1,4 +1,24 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "6.11.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add Optimism addresses",
|
||||||
|
"pr": 385
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1640364306
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "6.10.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add Aave supported FQT addresses for Polygon, Avalanche",
|
||||||
|
"pr": 321
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1638390144
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "6.9.0",
|
"version": "6.9.0",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v6.11.0 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Add Optimism addresses (#385)
|
||||||
|
|
||||||
|
## v6.10.0 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Add Aave supported FQT addresses for Polygon, Avalanche (#321)
|
||||||
|
|
||||||
## v6.9.0 - _November 16, 2021_
|
## v6.9.0 - _November 16, 2021_
|
||||||
|
|
||||||
* Add Celo addresses (#368)
|
* Add Celo addresses (#368)
|
||||||
|
@@ -289,7 +289,7 @@
|
|||||||
"wethTransformer": "0xe309d011cc6f189a3e8dcba85922715a019fed38",
|
"wethTransformer": "0xe309d011cc6f189a3e8dcba85922715a019fed38",
|
||||||
"payTakerTransformer": "0x5ba7b9be86cda01cfbf56e0fb97184783be9dda1",
|
"payTakerTransformer": "0x5ba7b9be86cda01cfbf56e0fb97184783be9dda1",
|
||||||
"affiliateFeeTransformer": "0xbed27284b42e5684e987169cf1da09c5d6c49fa8",
|
"affiliateFeeTransformer": "0xbed27284b42e5684e987169cf1da09c5d6c49fa8",
|
||||||
"fillQuoteTransformer": "0xf708d512b8a82e2862543a630403327174410baf",
|
"fillQuoteTransformer": "0xd3afdf4a8ea9183e76c9c2306cda03ea4afffea5",
|
||||||
"positiveSlippageFeeTransformer": "0x4cd8f1c0df4d40fcc1e073845d5f6f4ed5cc8dab"
|
"positiveSlippageFeeTransformer": "0x4cd8f1c0df4d40fcc1e073845d5f6f4ed5cc8dab"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -373,7 +373,7 @@
|
|||||||
"wethTransformer": "0x9b8b52391071d71cd4ad1e61d7f273268fa34c6c",
|
"wethTransformer": "0x9b8b52391071d71cd4ad1e61d7f273268fa34c6c",
|
||||||
"payTakerTransformer": "0x898c6fde239d646c73f0a57e3570b6f86a3d62a3",
|
"payTakerTransformer": "0x898c6fde239d646c73f0a57e3570b6f86a3d62a3",
|
||||||
"affiliateFeeTransformer": "0x34617b855411e52fbc05899435f44cbd0503022c",
|
"affiliateFeeTransformer": "0x34617b855411e52fbc05899435f44cbd0503022c",
|
||||||
"fillQuoteTransformer": "0x8a5417dd7ffde61ec61e11b45797e16686e1d6b9",
|
"fillQuoteTransformer": "0xd421f50b3ae27f223aa35a04944236d257235412",
|
||||||
"positiveSlippageFeeTransformer": "0x470ba89da18a6db6e8a0567b3c9214b960861857"
|
"positiveSlippageFeeTransformer": "0x470ba89da18a6db6e8a0567b3c9214b960861857"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -460,5 +460,47 @@
|
|||||||
"fillQuoteTransformer": "0xa825d4d3c4d2820c52da69fcccf269b4081871f2",
|
"fillQuoteTransformer": "0xa825d4d3c4d2820c52da69fcccf269b4081871f2",
|
||||||
"positiveSlippageFeeTransformer": "0x9ffc7a79133ed5242777e40764777a6d5aab282c"
|
"positiveSlippageFeeTransformer": "0x9ffc7a79133ed5242777e40764777a6d5aab282c"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"10": {
|
||||||
|
"erc20Proxy": "0x0000000000000000000000000000000000000000",
|
||||||
|
"erc721Proxy": "0x0000000000000000000000000000000000000000",
|
||||||
|
"zrxToken": "0x0000000000000000000000000000000000000000",
|
||||||
|
"etherToken": "0x4200000000000000000000000000000000000006",
|
||||||
|
"exchangeV2": "0x0000000000000000000000000000000000000000",
|
||||||
|
"exchange": "0x0000000000000000000000000000000000000000",
|
||||||
|
"assetProxyOwner": "0x0000000000000000000000000000000000000000",
|
||||||
|
"zeroExGovernor": "0x0000000000000000000000000000000000000000",
|
||||||
|
"forwarder": "0x0000000000000000000000000000000000000000",
|
||||||
|
"coordinatorRegistry": "0x0000000000000000000000000000000000000000",
|
||||||
|
"coordinator": "0x0000000000000000000000000000000000000000",
|
||||||
|
"multiAssetProxy": "0x0000000000000000000000000000000000000000",
|
||||||
|
"staticCallProxy": "0x0000000000000000000000000000000000000000",
|
||||||
|
"erc1155Proxy": "0x0000000000000000000000000000000000000000",
|
||||||
|
"devUtils": "0x0000000000000000000000000000000000000000",
|
||||||
|
"zrxVault": "0x0000000000000000000000000000000000000000",
|
||||||
|
"staking": "0x0000000000000000000000000000000000000000",
|
||||||
|
"stakingProxy": "0x0000000000000000000000000000000000000000",
|
||||||
|
"erc20BridgeProxy": "0x0000000000000000000000000000000000000000",
|
||||||
|
"erc20BridgeSampler": "0x0000000000000000000000000000000000000000",
|
||||||
|
"chaiBridge": "0x0000000000000000000000000000000000000000",
|
||||||
|
"dydxBridge": "0x0000000000000000000000000000000000000000",
|
||||||
|
"godsUnchainedValidator": "0x0000000000000000000000000000000000000000",
|
||||||
|
"broker": "0x0000000000000000000000000000000000000000",
|
||||||
|
"chainlinkStopLimit": "0x0000000000000000000000000000000000000000",
|
||||||
|
"maximumGasPrice": "0x0000000000000000000000000000000000000000",
|
||||||
|
"dexForwarderBridge": "0x0000000000000000000000000000000000000000",
|
||||||
|
"exchangeProxyGovernor": "0x6d506b2847df0c6f04d2628da1adaf4d8fb2e81b",
|
||||||
|
"exchangeProxy": "0xdef1abe32c034e558cdd535791643c58a13acc10",
|
||||||
|
"exchangeProxyTransformerDeployer": "0x3a539ed6bd42de8fbaf3899fb490c792e153d647",
|
||||||
|
"exchangeProxyFlashWallet": "0xa3128d9b7cca7d5af29780a56abeec12b05a6740",
|
||||||
|
"exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
|
||||||
|
"zrxTreasury": "0x0000000000000000000000000000000000000000",
|
||||||
|
"transformers": {
|
||||||
|
"wethTransformer": "0x02ce7af6520e2862f961f5d7eda746642865179c",
|
||||||
|
"payTakerTransformer": "0x085d10a34f14f6a631ea8ff7d016782ee3ffaa11",
|
||||||
|
"affiliateFeeTransformer": "0x55cf1d7535250db75bf0190493f55781ee583553",
|
||||||
|
"fillQuoteTransformer": "0x3543ef833d28b7e983c293856561f21a7f089f1d",
|
||||||
|
"positiveSlippageFeeTransformer": "0xb11e14565dfbeb702dea9bc0cb47f1a8b32f4783"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contract-addresses",
|
"name": "@0x/contract-addresses",
|
||||||
"version": "6.9.0",
|
"version": "6.11.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
|
@@ -55,6 +55,7 @@ export enum ChainId {
|
|||||||
Avalanche = 43114,
|
Avalanche = 43114,
|
||||||
Fantom = 250,
|
Fantom = 250,
|
||||||
Celo = 42220,
|
Celo = 42220,
|
||||||
|
Optimism = 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,4 +1,22 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "13.18.5",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1638390144,
|
||||||
|
"version": "13.18.4",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "13.18.3",
|
"version": "13.18.3",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v13.18.5 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v13.18.4 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v13.18.3 - _November 16, 2021_
|
## v13.18.3 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/contract-wrappers",
|
"name": "@0x/contract-wrappers",
|
||||||
"version": "13.18.3",
|
"version": "13.18.5",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.29",
|
"@0x/assert": "^3.0.29",
|
||||||
"@0x/base-contract": "^6.4.2",
|
"@0x/base-contract": "^6.4.2",
|
||||||
"@0x/contract-addresses": "^6.9.0",
|
"@0x/contract-addresses": "^6.11.0",
|
||||||
"@0x/json-schemas": "^6.3.0",
|
"@0x/json-schemas": "^6.3.0",
|
||||||
"@0x/types": "^3.3.4",
|
"@0x/types": "^3.3.4",
|
||||||
"@0x/utils": "^6.4.4",
|
"@0x/utils": "^6.4.4",
|
||||||
|
@@ -1,4 +1,22 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "8.1.14",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timestamp": 1638390144,
|
||||||
|
"version": "8.1.13",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "8.1.12",
|
"version": "8.1.12",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v8.1.14 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v8.1.13 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
## v8.1.12 - _November 16, 2021_
|
## v8.1.12 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/migrations",
|
"name": "@0x/migrations",
|
||||||
"version": "8.1.12",
|
"version": "8.1.14",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -68,20 +68,20 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/base-contract": "^6.4.2",
|
"@0x/base-contract": "^6.4.2",
|
||||||
"@0x/contract-addresses": "^6.9.0",
|
"@0x/contract-addresses": "^6.11.0",
|
||||||
"@0x/contracts-asset-proxy": "^3.7.19",
|
"@0x/contracts-asset-proxy": "^3.7.19",
|
||||||
"@0x/contracts-coordinator": "^3.1.38",
|
"@0x/contracts-coordinator": "^3.1.38",
|
||||||
"@0x/contracts-dev-utils": "^1.3.36",
|
"@0x/contracts-dev-utils": "^1.3.36",
|
||||||
"@0x/contracts-erc1155": "^2.1.37",
|
"@0x/contracts-erc1155": "^2.1.37",
|
||||||
"@0x/contracts-erc20": "^3.3.23",
|
"@0x/contracts-erc20": "^3.3.25",
|
||||||
"@0x/contracts-erc721": "^3.1.37",
|
"@0x/contracts-erc721": "^3.1.37",
|
||||||
"@0x/contracts-exchange": "^3.2.38",
|
"@0x/contracts-exchange": "^3.2.38",
|
||||||
"@0x/contracts-exchange-forwarder": "^4.2.38",
|
"@0x/contracts-exchange-forwarder": "^4.2.38",
|
||||||
"@0x/contracts-extensions": "^6.2.32",
|
"@0x/contracts-extensions": "^6.2.32",
|
||||||
"@0x/contracts-multisig": "^4.1.38",
|
"@0x/contracts-multisig": "^4.1.38",
|
||||||
"@0x/contracts-staking": "^2.0.45",
|
"@0x/contracts-staking": "^2.0.45",
|
||||||
"@0x/contracts-utils": "^4.8.4",
|
"@0x/contracts-utils": "^4.8.6",
|
||||||
"@0x/contracts-zero-ex": "^0.29.5",
|
"@0x/contracts-zero-ex": "^0.30.1",
|
||||||
"@0x/sol-compiler": "^4.7.5",
|
"@0x/sol-compiler": "^4.7.5",
|
||||||
"@0x/subproviders": "^6.6.0",
|
"@0x/subproviders": "^6.6.0",
|
||||||
"@0x/typescript-typings": "^5.2.1",
|
"@0x/typescript-typings": "^5.2.1",
|
||||||
|
@@ -1,4 +1,23 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"timestamp": 1640364306,
|
||||||
|
"version": "1.10.1",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Dependencies updated"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "1.10.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Add `AaveV2` and `Compound` deposit/withdrawal liquidity source",
|
||||||
|
"pr": 321
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timestamp": 1638390144
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"timestamp": 1637102971,
|
"timestamp": 1637102971,
|
||||||
"version": "1.9.5",
|
"version": "1.9.5",
|
||||||
|
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
|
|||||||
|
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
|
|
||||||
|
## v1.10.1 - _December 24, 2021_
|
||||||
|
|
||||||
|
* Dependencies updated
|
||||||
|
|
||||||
|
## v1.10.0 - _December 1, 2021_
|
||||||
|
|
||||||
|
* Add `AaveV2` and `Compound` deposit/withdrawal liquidity source (#321)
|
||||||
|
|
||||||
## v1.9.5 - _November 16, 2021_
|
## v1.9.5 - _November 16, 2021_
|
||||||
|
|
||||||
* Dependencies updated
|
* Dependencies updated
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@0x/protocol-utils",
|
"name": "@0x/protocol-utils",
|
||||||
"version": "1.9.5",
|
"version": "1.10.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.12"
|
"node": ">=6.12"
|
||||||
},
|
},
|
||||||
@@ -63,8 +63,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@0x/assert": "^3.0.29",
|
"@0x/assert": "^3.0.29",
|
||||||
"@0x/contract-addresses": "^6.9.0",
|
"@0x/contract-addresses": "^6.11.0",
|
||||||
"@0x/contract-wrappers": "^13.18.3",
|
"@0x/contract-wrappers": "^13.18.5",
|
||||||
"@0x/json-schemas": "^6.3.0",
|
"@0x/json-schemas": "^6.3.0",
|
||||||
"@0x/subproviders": "^6.6.0",
|
"@0x/subproviders": "^6.6.0",
|
||||||
"@0x/utils": "^6.4.4",
|
"@0x/utils": "^6.4.4",
|
||||||
|
@@ -132,6 +132,8 @@ export enum BridgeProtocol {
|
|||||||
CurveV2,
|
CurveV2,
|
||||||
Lido,
|
Lido,
|
||||||
Clipper, // Not used: Clipper is now using PLP interface
|
Clipper, // Not used: Clipper is now using PLP interface
|
||||||
|
AaveV2,
|
||||||
|
Compound,
|
||||||
}
|
}
|
||||||
// tslint:enable: enum-naming
|
// tslint:enable: enum-naming
|
||||||
|
|
||||||
|
@@ -959,10 +959,10 @@
|
|||||||
typedoc "~0.16.11"
|
typedoc "~0.16.11"
|
||||||
yargs "^10.0.3"
|
yargs "^10.0.3"
|
||||||
|
|
||||||
"@0x/neon-router@^0.2.1":
|
"@0x/neon-router@^0.3.1":
|
||||||
version "0.2.1"
|
version "0.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.2.1.tgz#23bb3cedc0eafd55a8ba6b6ea8a59ee4c538064b"
|
resolved "https://registry.yarnpkg.com/@0x/neon-router/-/neon-router-0.3.1.tgz#4ec13e750d1435357c4928d7f2521a2b4376f27e"
|
||||||
integrity sha512-feCCKuox4staZl8lxLY4nf5U256NcDHrgvSFra5cU/TUhoblLHb8F7eWAC9ygpukZUCVFLy13mExkFQHXlEOYw==
|
integrity sha512-M4ypTov9KyxsGJpYwobrld3Y2JOlR7U0XjR6BEQE2gQ1k3nie/1wNEI2J4ZjKw++RLDxdv/RCqhgA5VnINzjxA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@mapbox/node-pre-gyp" "^1.0.5"
|
"@mapbox/node-pre-gyp" "^1.0.5"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user