rebased dev and merged

This commit is contained in:
Noah Khamliche 2022-05-17 16:07:33 -04:00 committed by Noah Khamliche
parent f55eaa867b
commit 9a28e51f51
24 changed files with 719 additions and 4 deletions

View File

@ -34,6 +34,7 @@ import "./mixins/MixinCurveV2.sol";
import "./mixins/MixinCryptoCom.sol";
import "./mixins/MixinDodo.sol";
import "./mixins/MixinDodoV2.sol";
import "./mixins/MixinGMX.sol";
import "./mixins/MixinKyber.sol";
import "./mixins/MixinKyberDmm.sol";
import "./mixins/MixinLido.sol";
@ -42,6 +43,7 @@ import "./mixins/MixinMooniswap.sol";
import "./mixins/MixinMStable.sol";
import "./mixins/MixinNerve.sol";
import "./mixins/MixinOasis.sol";
import "./mixins/MixinPlatypus.sol";
import "./mixins/MixinShell.sol";
import "./mixins/MixinUniswap.sol";
import "./mixins/MixinUniswapV2.sol";
@ -62,6 +64,7 @@ contract BridgeAdapter is
MixinCryptoCom,
MixinDodo,
MixinDodoV2,
MixinGMX,
MixinKyber,
MixinKyberDmm,
MixinLido,
@ -70,6 +73,7 @@ contract BridgeAdapter is
MixinMStable,
MixinNerve,
MixinOasis,
MixinPlatypus,
MixinShell,
MixinUniswap,
MixinUniswapV2,
@ -89,6 +93,7 @@ contract BridgeAdapter is
MixinCryptoCom()
MixinDodo()
MixinDodoV2()
MixinGMX()
MixinKyber(weth)
MixinLido(weth)
MixinMakerPSM()
@ -96,6 +101,7 @@ contract BridgeAdapter is
MixinMStable()
MixinNerve()
MixinOasis()
MixinPlatypus()
MixinShell()
MixinUniswap(weth)
MixinUniswapV2()
@ -272,6 +278,18 @@ contract BridgeAdapter is
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.GMX) {
boughtAmount = _tradeGMX(
buyToken,
sellAmount,
order.bridgeData
);
} else if (protocolId == BridgeProtocols.PLATYPUS) {
boughtAmount = _tradePlatypus(
buyToken,
sellAmount,
order.bridgeData
);
} else {
boughtAmount = _tradeZeroExBridge(
sellToken,

View File

@ -53,4 +53,6 @@ library BridgeProtocols {
uint128 internal constant AAVEV2 = 23;
uint128 internal constant COMPOUND = 24;
uint128 internal constant BALANCERV2BATCH = 25;
uint128 internal constant GMX = 26;
uint128 internal constant PLATYPUS = 27;
}

View File

@ -0,0 +1,98 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright 2020 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.6.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-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../IBridgeAdapter.sol";
/*
UniswapV2
*/
interface IGmxRouter {
// /// @dev Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path.
// /// The first element of path is the input token, the last is the output token, and any intermediate elements represent
// /// intermediate pairs to trade through (if, for example, a direct pair does not exist).
// /// @param _path An array of token addresses. path.length must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity.
// /// @param _amountIn The amount of input tokens to send.
// /// @param _minOut The minimum amount of output tokens that must be received for the transaction not to revert.
// /// @param _reciever Recipient of the output tokens.
function swap(
address[] calldata _path, uint256 _amountIn, uint256 _minOut, address _receiver
) external;
}
contract MixinGMX {
using LibERC20TokenV06 for IERC20TokenV06;
using LibSafeMathV06 for uint256;
function _tradeGMX(
IERC20TokenV06 buyToken,
uint256 sellAmount,
bytes memory bridgeData
)
public
returns (uint256 boughtAmount)
{
address _router;
address reader;
address vault;
address[] memory _path;
IGmxRouter router;
IERC20TokenV06[] memory path;
{
//decode the bridge data
(_router, reader, vault, _path) = abi.decode(bridgeData, (address, address, address, address[]));
// To get around `abi.decode()` not supporting interface array types.
assembly { path := _path }
}
require(path.length >= 2, "MixinGMX/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
require(
path[path.length - 1] == buyToken,
"MixinGMX/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
);
//connect to the GMX router
router = IGmxRouter(_router);
// Grant the GMX router an allowance to sell the first token.
path[0].approveIfBelow(address(router), sellAmount);
//track the balance to know how much we bought
uint256 beforeBalance = buyToken.balanceOf(address(this));
router.swap(
// Convert to `buyToken` along this path.
_path,
// Sell all tokens we hold.
sellAmount,
// Minimum buy amount.
0,
// Recipient is `this`.
address(this)
);
//calculate the difference in balance from preswap->postswap to find how many tokens out
boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance);
return boughtAmount;
}
}

View File

@ -0,0 +1,78 @@
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-utils/contracts/src/v06/LibSafeMathV06.sol";
import "../IBridgeAdapter.sol";
interface IPlatypusRouter {
function swapTokensForTokens(
address[] calldata tokenPath,
address[] calldata poolPath,
uint256 fromAmount,
uint256 minimumToAmount,
address to,
uint256 deadline
) external returns (uint256 amountOut, uint256 haircut);
}
contract MixinPlatypus {
using LibERC20TokenV06 for IERC20TokenV06;
using LibSafeMathV06 for uint256;
function _tradePlatypus(
IERC20TokenV06 buyToken,
uint256 sellAmount,
bytes memory bridgeData
)
public
returns (uint256 boughtAmount)
{
IPlatypusRouter router;
address _router;
address[] memory _pool;
IERC20TokenV06[] memory path;
address[] memory _path;
{
(_router, _pool, _path) = abi.decode(bridgeData, (address, address[], address[]));
// To get around `abi.decode()` not supporting interface array types.
assembly { path := _path }
}
router = IPlatypusRouter(_router);
//corresponding platypus asset pool for the ERC20's in the path
require(path.length >= 2, "MixinPlatypus/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
require(
path[path.length - 1] == buyToken,
"MixinPlatypus/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
);
// Grant the Platypus router an allowance to sell the first token.
path[0].approveIfBelow(address(router), sellAmount);
uint256 beforeBalance = buyToken.balanceOf(address(this));
(uint256 amountOut, uint256 haircut) = router.swapTokensForTokens(
// Convert to `buyToken` along this path.
_path,
//
_pool,
// Sell all tokens we hold.
sellAmount,
// Minimum buy amount.
0,
// Recipient is `this`.
address(this),
block.timestamp + 10000
);
boughtAmount = buyToken.balanceOf(address(this)).safeSub(beforeBalance);
return boughtAmount;
}
}

View File

@ -43,7 +43,7 @@
"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",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeAdapter|BridgeProtocols|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|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|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|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|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2|MixinBalancerV2Batch|MixinBancor|MixinCoFiX|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyber|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinOasis|MixinPlatypus|MixinShell|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|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": {
"type": "git",

View File

@ -110,6 +110,7 @@ import * as MixinCurve from '../test/generated-artifacts/MixinCurve.json';
import * as MixinCurveV2 from '../test/generated-artifacts/MixinCurveV2.json';
import * as MixinDodo from '../test/generated-artifacts/MixinDodo.json';
import * as MixinDodoV2 from '../test/generated-artifacts/MixinDodoV2.json';
import * as MixinGMX from '../test/generated-artifacts/MixinGMX.json';
import * as MixinKyber from '../test/generated-artifacts/MixinKyber.json';
import * as MixinKyberDmm from '../test/generated-artifacts/MixinKyberDmm.json';
import * as MixinLido from '../test/generated-artifacts/MixinLido.json';
@ -118,6 +119,7 @@ import * as MixinMooniswap from '../test/generated-artifacts/MixinMooniswap.json
import * as MixinMStable from '../test/generated-artifacts/MixinMStable.json';
import * as MixinNerve from '../test/generated-artifacts/MixinNerve.json';
import * as MixinOasis from '../test/generated-artifacts/MixinOasis.json';
import * as MixinPlatypus from '../test/generated-artifacts/MixinPlatypus.json';
import * as MixinShell from '../test/generated-artifacts/MixinShell.json';
import * as MixinUniswap from '../test/generated-artifacts/MixinUniswap.json';
import * as MixinUniswapV2 from '../test/generated-artifacts/MixinUniswapV2.json';
@ -323,6 +325,7 @@ export const artifacts = {
MixinCurveV2: MixinCurveV2 as ContractArtifact,
MixinDodo: MixinDodo as ContractArtifact,
MixinDodoV2: MixinDodoV2 as ContractArtifact,
MixinGMX: MixinGMX as ContractArtifact,
MixinKyber: MixinKyber as ContractArtifact,
MixinKyberDmm: MixinKyberDmm as ContractArtifact,
MixinLido: MixinLido as ContractArtifact,
@ -331,6 +334,7 @@ export const artifacts = {
MixinMooniswap: MixinMooniswap as ContractArtifact,
MixinNerve: MixinNerve as ContractArtifact,
MixinOasis: MixinOasis as ContractArtifact,
MixinPlatypus: MixinPlatypus as ContractArtifact,
MixinShell: MixinShell as ContractArtifact,
MixinUniswap: MixinUniswap as ContractArtifact,
MixinUniswapV2: MixinUniswapV2 as ContractArtifact,

View File

@ -108,6 +108,7 @@ export * from '../test/generated-wrappers/mixin_curve';
export * from '../test/generated-wrappers/mixin_curve_v2';
export * from '../test/generated-wrappers/mixin_dodo';
export * from '../test/generated-wrappers/mixin_dodo_v2';
export * from '../test/generated-wrappers/mixin_g_m_x';
export * from '../test/generated-wrappers/mixin_kyber';
export * from '../test/generated-wrappers/mixin_kyber_dmm';
export * from '../test/generated-wrappers/mixin_lido';
@ -116,6 +117,7 @@ export * from '../test/generated-wrappers/mixin_maker_p_s_m';
export * from '../test/generated-wrappers/mixin_mooniswap';
export * from '../test/generated-wrappers/mixin_nerve';
export * from '../test/generated-wrappers/mixin_oasis';
export * from '../test/generated-wrappers/mixin_platypus';
export * from '../test/generated-wrappers/mixin_shell';
export * from '../test/generated-wrappers/mixin_uniswap';
export * from '../test/generated-wrappers/mixin_uniswap_v2';

View File

@ -141,6 +141,7 @@
"test/generated-artifacts/MixinCurveV2.json",
"test/generated-artifacts/MixinDodo.json",
"test/generated-artifacts/MixinDodoV2.json",
"test/generated-artifacts/MixinGMX.json",
"test/generated-artifacts/MixinKyber.json",
"test/generated-artifacts/MixinKyberDmm.json",
"test/generated-artifacts/MixinLido.json",
@ -149,6 +150,7 @@
"test/generated-artifacts/MixinMooniswap.json",
"test/generated-artifacts/MixinNerve.json",
"test/generated-artifacts/MixinOasis.json",
"test/generated-artifacts/MixinPlatypus.json",
"test/generated-artifacts/MixinShell.json",
"test/generated-artifacts/MixinUniswap.json",
"test/generated-artifacts/MixinUniswapV2.json",

View File

@ -28,6 +28,7 @@ import "./CompoundSampler.sol";
import "./CurveSampler.sol";
import "./DODOSampler.sol";
import "./DODOV2Sampler.sol";
import "./GMXSampler.sol";
import "./KyberSampler.sol";
import "./KyberDmmSampler.sol";
import "./LidoSampler.sol";
@ -36,6 +37,7 @@ import "./MakerPSMSampler.sol";
import "./MStableSampler.sol";
import "./MooniswapSampler.sol";
import "./NativeOrderSampler.sol";
import "./PlatypusSampler.sol";
import "./ShellSampler.sol";
import "./SmoothySampler.sol";
import "./TwoHopSampler.sol";
@ -54,6 +56,7 @@ contract ERC20BridgeSampler is
CurveSampler,
DODOSampler,
DODOV2Sampler,
GMXSampler,
KyberSampler,
KyberDmmSampler,
LidoSampler,
@ -62,6 +65,7 @@ contract ERC20BridgeSampler is
MStableSampler,
MooniswapSampler,
NativeOrderSampler,
PlatypusSampler,
ShellSampler,
SmoothySampler,
TwoHopSampler,

View File

@ -0,0 +1,98 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IGMX.sol";
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
contract GMXSampler is
SamplerUtils,
ApproximateBuys
{
struct GMXInfo {
address reader;
address vault;
address[] path;
}
// address immutable WAVAX = 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7;
// address immutable AVAX = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
function sampleSellsFromGMX(
address reader,
address vault,
address[] memory path,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
try
IGMX(reader).getAmountOut(IVault(vault), path[0], path[1], takerTokenAmounts[i])
returns (uint256 amountAfterFees, uint256 feeAmount)
{
makerTokenAmounts[i] = amountAfterFees;
// Break early if there are 0 amounts
if (makerTokenAmounts[i] == 0) {
break;
}
} catch (bytes memory) {
// Swallow failures, leaving all results as zero.
break;
}
}
}
function sampleBuysFromGMX(
address reader,
address vault,
address[] memory path,
uint256[] memory makerTokenAmounts
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
address[] memory invertBuyPath = new address[](2);
invertBuyPath[0] = path[1];
invertBuyPath[1] = path[0];
return _sampleApproximateBuys(
ApproximateBuyQuoteOpts({
makerTokenData: abi.encode(reader, vault, invertBuyPath),
takerTokenData: abi.encode(reader, vault, path),
getSellQuoteCallback: _sampleSellForApproximateBuyFromGMX
}),
makerTokenAmounts
);
}
function _sampleSellForApproximateBuyFromGMX(
bytes memory takerTokenData,
bytes memory makerTokenData,
uint256 sellAmount
)
private
view
returns (uint256 buyAmount)
{
(address _reader, address _vault, address[] memory _path ) = abi.decode(takerTokenData, (address, address, address[]));
(bool success, bytes memory resultData) = address(this).staticcall(abi.encodeWithSelector(
this.sampleSellsFromGMX.selector,
_reader,
_vault,
_path,
_toSingleValueArray(sellAmount)
));
if(!success) {
return 0;
}
// solhint-disable-next-line indent
return abi.decode(resultData, (uint256[]))[0];
}
}

View File

@ -0,0 +1,89 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
import "./interfaces/IPlatypus.sol";
import "./ApproximateBuys.sol";
import "./SamplerUtils.sol";
contract PlatypusSampler is
SamplerUtils,
ApproximateBuys
{
function sampleSellsFromPlatypus(
address pool,
address[] memory path,
uint256[] memory takerTokenAmounts
)
public
view
returns (uint256[] memory makerTokenAmounts)
{
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
try
IPlatypus(pool).quotePotentialSwap(path[0], path[1], takerTokenAmounts[i])
returns (uint256 amountAfterFees, uint256 feeAmount)
{
makerTokenAmounts[i] = amountAfterFees;
// Break early if there are 0 amounts
if (makerTokenAmounts[i] == 0) {
break;
}
} catch (bytes memory result) {
// Swallow failures, leaving all results as zero.
break;
}
}
}
function sampleBuysFromPlatypus(
address pool,
address[] memory path,
uint256[] memory makerTokenAmounts
)
public
view
returns (uint256[] memory takerTokenAmounts)
{
address[] memory invertBuyPath = new address[](2);
invertBuyPath[0] = path[1];
invertBuyPath[1] = path[0];
return _sampleApproximateBuys(
ApproximateBuyQuoteOpts({
makerTokenData: abi.encode(pool, invertBuyPath),
takerTokenData: abi.encode(pool, path),
getSellQuoteCallback: _sampleSellForApproximateBuyFromPlatypus
}),
makerTokenAmounts
);
}
function _sampleSellForApproximateBuyFromPlatypus(
bytes memory makerTokenData,
bytes memory takerTokenData,
uint256 sellAmount
)
private
view
returns (uint256 buyAmount)
{
(address _pool, address[] memory _path ) = abi.decode(makerTokenData, (address, address[]));
(bool success, bytes memory resultData) = address(this).staticcall(abi.encodeWithSelector(
this.sampleSellsFromPlatypus.selector,
_pool,
_path,
_toSingleValueArray(sellAmount)
));
if(!success) {
return 0;
}
// solhint-disable-next-line indent
return abi.decode(resultData, (uint256[]))[0];
}
}

View File

@ -0,0 +1,23 @@
pragma solidity ^0.6;
pragma experimental ABIEncoderV2;
interface IGMX {
function getMaxAmountIn(IVault _vault, address _tokenIn, address _tokenOut)
external
view
returns (uint256);
function getAmountOut(IVault _vault, address _tokenIn, address _tokenOut, uint256 _amountIn)
external
view
returns (uint256, uint256);
}
interface IVault {
function getFeeBasisPoints(address _token, uint256 _usdgDelta, uint256 _feeBasisPoints, uint256 _taxBasisPoints, bool _increment) external view returns (uint256);
function stableSwapFeeBasisPoints() external view returns (uint256);
function stableTokens(address _token) external view returns (bool);
function tokenDecimals(address _token) external view returns (uint256);
function getMaxPrice(address _token) external view returns (uint256);
function getMinPrice(address _token) external view returns (uint256);
}

View File

@ -0,0 +1,11 @@
pragma solidity ^0.6;
interface IPlatypus {
function quotePotentialSwap(
address fromToken,
address toToken,
uint256 fromAmount
) external view returns (uint256 potentialOutcome, uint256 haircut);
function assetOf(address token) external view returns (address);
}

View File

@ -39,7 +39,7 @@
"config": {
"publicInterfaceContracts": "ERC20BridgeSampler,BalanceChecker,FakeTaker",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|IBalancer|IBalancerV2Vault|IBancor|ICurve|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalanceChecker|BalancerSampler|BalancerV2BatchSampler|BalancerV2Common|BalancerV2Sampler|BancorSampler|CompoundSampler|CurveSampler|DODOSampler|DODOV2Sampler|ERC20BridgeSampler|FakeTaker|GMXSampler|IBalancer|IBalancerV2Vault|IBancor|ICurve|IGMX|IKyberNetwork|IMStable|IMooniswap|IMultiBridge|IPlatypus|IShell|ISmoothy|IUniswapExchangeQuotes|IUniswapV2Router01|KyberDmmSampler|KyberSampler|LidoSampler|LiquidityProviderSampler|MStableSampler|MakerPSMSampler|MooniswapSampler|NativeOrderSampler|PlatypusSampler|SamplerUtils|ShellSampler|SmoothySampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler|UniswapV3Sampler|UtilitySampler).json",
"postpublish": {
"assets": []
}

View File

@ -40,6 +40,7 @@ import {
PANCAKESWAP_ROUTER_BY_CHAIN_ID,
PANCAKESWAPV2_ROUTER_BY_CHAIN_ID,
PANGOLIN_ROUTER_BY_CHAIN_ID,
PLATYPUS_AVALANCHE_INFOS,
POLYDEX_ROUTER_BY_CHAIN_ID,
QUICKSWAP_ROUTER_BY_CHAIN_ID,
SADDLE_MAINNET_INFOS,
@ -62,7 +63,7 @@ import {
WAULTSWAP_ROUTER_BY_CHAIN_ID,
XSIGMA_MAINNET_INFOS,
} from './constants';
import { CurveInfo, ERC20BridgeSource } from './types';
import { CurveInfo, ERC20BridgeSource, PlatypusInfo } from './types';
/**
* Filter Kyber reserves which should not be used (0xbb bridged reserves)
@ -436,6 +437,15 @@ export function getMobiusMoneyInfoForPair(chainId: ChainId, takerToken: string,
);
}
export function getPlatypusInfoForPair(chainId: ChainId, takerToken: string, makerToken: string): PlatypusInfo[] {
if (chainId !== ChainId.Avalanche) {
return [];
}
return Object.values(PLATYPUS_AVALANCHE_INFOS).filter(c =>
[makerToken, takerToken].every(t => c.tokens.includes(t)),
);
}
export function getShellLikeInfosForPair(
chainId: ChainId,
takerToken: string,

View File

@ -28,6 +28,7 @@ import {
LiquidityProviderRegistry,
MakerPsmFillData,
MultiHopFillData,
PlatypusInfo,
PsmInfo,
TokenAdjacencyGraph,
UniswapV2FillData,
@ -182,6 +183,8 @@ export const SELL_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.KyberDmm,
ERC20BridgeSource.AaveV2,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.GMX,
ERC20BridgeSource.Platypus,
]),
[ChainId.Fantom]: new SourceFilters([
ERC20BridgeSource.MultiHop,
@ -326,6 +329,8 @@ export const BUY_SOURCE_FILTER_BY_CHAIN_ID = valueByChainId<SourceFilters>(
ERC20BridgeSource.KyberDmm,
ERC20BridgeSource.AaveV2,
ERC20BridgeSource.Synapse,
ERC20BridgeSource.GMX,
ERC20BridgeSource.Platypus,
]),
[ChainId.Fantom]: new SourceFilters([
ERC20BridgeSource.MultiHop,
@ -549,8 +554,10 @@ export const AVALANCHE_TOKENS = {
DAI: '0xd586e7f844cea2f87f50152665bcbc2c279d8d70',
// bridged USDC
USDC: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664',
// native USDC on Avalanche
// native USDC on Avalanche usdc.e
nUSDC: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e',
// usdt.e
USDt: '0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7',
USDT: '0xc7198437980c041c805a1edcba50c1ce5db95118',
aDAI: '0x47afa96cdc9fab46904a55a6ad4bf6660b53c38a',
aUSDC: '0x46a51127c3ce23fb7ab1de06226147f446e4a857',
@ -560,6 +567,10 @@ export const AVALANCHE_TOKENS = {
aWETH: '0x53f7c5869a859f0aec3d334ee8b4cf01e3492f21',
MIM: '0x130966628846bfd36ff31a822705796e8cb8c18d',
MAG: '0x1d60109178C48E4A937D8AB71699D8eBb6F7c5dE',
sAVAX: '0x2b2c81e08f1af8835a78bb2a90ae924ace0ea4be',
UST: '0xb599c3590f42f8f995ecfa0f85d2980b76862fc1',
FRAX: '0xd24c2ad096400b6fbcd2ad8b24e7acbc21a1da64',
YUSD: '0x111111111111ed1d73f860f57b2798b683f2d325',
};
export const CELO_TOKENS = {
@ -822,6 +833,14 @@ export const ACRYPTOS_POOLS = {
acs3btc: '0xbe7caa236544d1b9a0e7f91e94b9f5bfd3b5ca81',
};
export const PLATYPUS_AVALANCHE_POOLS = {
usd: '0x66357dcace80431aee0a7507e2e361b7e2402370',
yusd: '0xc828d995c686aaba78a4ac89dfc8ec0ff4c5be83',
frax: '0xb8e567fc23c39c94a1f6359509d7b43d1fbed824',
mim: '0x30c30d826be87cd0a4b90855c2f38f7fcfe4eaa7',
sAVAX: '0x4658ea7e9960d6158a261104aaa160cc953bb6ba',
};
export const DEFAULT_INTERMEDIATE_TOKENS_BY_CHAIN_ID = valueByChainId<string[]>(
{
[ChainId.Mainnet]: [
@ -1792,6 +1811,40 @@ export const ACRYPTOS_BSC_INFOS: { [name: string]: CurveInfo } = {
}),
};
export const PLATYPUS_AVALANCHE_INFOS: { [name: string]: PlatypusInfo } = {
[PLATYPUS_AVALANCHE_POOLS.usd]: {
poolAddress: PLATYPUS_AVALANCHE_POOLS.usd,
tokens: [
AVALANCHE_TOKENS.USDT,
AVALANCHE_TOKENS.USDC,
AVALANCHE_TOKENS.DAI,
AVALANCHE_TOKENS.nUSDC,
AVALANCHE_TOKENS.USDt,
],
gasSchedule: 300e3,
},
[PLATYPUS_AVALANCHE_POOLS.yusd]: {
poolAddress: PLATYPUS_AVALANCHE_POOLS.yusd,
tokens: [AVALANCHE_TOKENS.YUSD, AVALANCHE_TOKENS.nUSDC],
gasSchedule: 300e3,
},
[PLATYPUS_AVALANCHE_POOLS.frax]: {
poolAddress: PLATYPUS_AVALANCHE_POOLS.frax,
tokens: [AVALANCHE_TOKENS.FRAX, AVALANCHE_TOKENS.nUSDC],
gasSchedule: 300e3,
},
[PLATYPUS_AVALANCHE_POOLS.mim]: {
poolAddress: PLATYPUS_AVALANCHE_POOLS.mim,
tokens: [AVALANCHE_TOKENS.MIM, AVALANCHE_TOKENS.nUSDC],
gasSchedule: 300e3,
},
[PLATYPUS_AVALANCHE_POOLS.sAVAX]: {
poolAddress: PLATYPUS_AVALANCHE_POOLS.sAVAX,
tokens: [AVALANCHE_TOKENS.WAVAX, AVALANCHE_TOKENS.sAVAX],
gasSchedule: 300e3,
},
};
/**
* Kyber reserve prefixes
* 0xff Fed price reserve
@ -2324,6 +2377,34 @@ export const SPOOKYSWAP_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
NULL_ADDRESS,
);
export const GMX_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Avalanche]: '0x5f719c2f1095f7b9fc68a68e35b51194f4b6abe8',
},
NULL_ADDRESS,
);
export const GMX_READER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Avalanche]: '0x67b789d48c926006f5132bfce4e976f0a7a63d5d',
},
NULL_ADDRESS,
);
export const GMX_VAULT_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Avalanche]: '0x9ab2de34a33fb459b538c43f251eb825645e8595',
},
NULL_ADDRESS,
);
export const PLATYPUS_ROUTER_BY_CHAIN_ID = valueByChainId<string>(
{
[ChainId.Avalanche]: '0x73256ec7575d999c360c1eec118ecbefd8da7d12',
},
NULL_ADDRESS,
);
export const VIP_ERC20_BRIDGE_SOURCES_BY_CHAIN_ID = valueByChainId<ERC20BridgeSource[]>(
{
[ChainId.Mainnet]: [
@ -2526,6 +2607,8 @@ export const DEFAULT_GAS_SCHEDULE: Required<FeeSchedule> = {
//
[ERC20BridgeSource.Pangolin]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.TraderJoe]: uniswapV2CloneGasSchedule,
[ERC20BridgeSource.GMX]: () => 450e3,
[ERC20BridgeSource.Platypus]: () => 450e3,
//
// Celo

View File

@ -21,6 +21,7 @@ import {
FinalUniswapV3FillData,
GeistFillData,
GenericRouterFillData,
GMXFillData,
KyberDmmFillData,
KyberFillData,
LidoFillData,
@ -35,6 +36,7 @@ import {
OptimizedMarketOrder,
OptimizedMarketOrderBase,
OrderDomain,
PlatypusFillData,
ShellFillData,
UniswapV2FillData,
UniswapV3FillData,
@ -203,6 +205,10 @@ export function getErc20BridgeSourceToBridgeSource(source: ERC20BridgeSource): s
return encodeBridgeSourceId(BridgeProtocol.Nerve, 'MobiusMoney');
case ERC20BridgeSource.BiSwap:
return encodeBridgeSourceId(BridgeProtocol.UniswapV2, 'BiSwap');
case ERC20BridgeSource.GMX:
return encodeBridgeSourceId(BridgeProtocol.GMX, 'GMX');
case ERC20BridgeSource.Platypus:
return encodeBridgeSourceId(BridgeProtocol.Platypus, 'Platypus');
default:
throw new Error(AggregationError.NoBridgeForSource);
}
@ -365,6 +371,23 @@ export function createBridgeDataForBridgeOrder(order: OptimizedMarketBridgeOrder
const geistFillData = (order as OptimizedMarketBridgeOrder<GeistFillData>).fillData;
bridgeData = encoder.encode([geistFillData.lendingPool, geistFillData.gToken]);
break;
case ERC20BridgeSource.GMX:
const gmxFillData = (order as OptimizedMarketBridgeOrder<GMXFillData>).fillData;
bridgeData = encoder.encode([
gmxFillData.router,
gmxFillData.reader,
gmxFillData.vault,
gmxFillData.tokenAddressPath,
]);
break;
case ERC20BridgeSource.Platypus:
const platypusFillData = (order as OptimizedMarketBridgeOrder<PlatypusFillData>).fillData;
bridgeData = encoder.encode([
platypusFillData.router,
platypusFillData.pool,
platypusFillData.tokenAddressPath,
]);
break;
default:
throw new Error(AggregationError.NoBridgeForSource);
@ -451,6 +474,8 @@ const balancerV2Encoder = AbiEncoder.create([
]);
const routerAddressPathEncoder = AbiEncoder.create('(address,address[])');
const tokenAddressEncoder = AbiEncoder.create([{ name: 'tokenAddress', type: 'address' }]);
const gmxAddressPathEncoder = AbiEncoder.create('(address,address,address,address[])');
const platypusAddressPathEncoder = AbiEncoder.create('(address,address[],address[])');
export const BRIDGE_ENCODERS: {
[key in Exclude<
@ -501,6 +526,9 @@ export const BRIDGE_ENCODERS: {
[ERC20BridgeSource.SpookySwap]: routerAddressPathEncoder,
[ERC20BridgeSource.MorpheusSwap]: routerAddressPathEncoder,
[ERC20BridgeSource.BiSwap]: routerAddressPathEncoder,
// Avalanche
[ERC20BridgeSource.GMX]: gmxAddressPathEncoder,
[ERC20BridgeSource.Platypus]: platypusAddressPathEncoder,
// Celo
[ERC20BridgeSource.UbeSwap]: routerAddressPathEncoder,
// BSC

View File

@ -14,6 +14,7 @@ import {
getCurveLikeInfosForPair,
getDodoV2Offsets,
getKyberOffsets,
getPlatypusInfoForPair,
getShellLikeInfosForPair,
isAllowedKyberReserveId,
isBadTokenForSource,
@ -30,6 +31,9 @@ import {
COMPOUND_API_URL_BY_CHAIN_ID,
DODOV1_CONFIG_BY_CHAIN_ID,
DODOV2_FACTORIES_BY_CHAIN_ID,
GMX_READER_BY_CHAIN_ID,
GMX_ROUTER_BY_CHAIN_ID,
GMX_VAULT_BY_CHAIN_ID,
KYBER_CONFIG_BY_CHAIN_ID,
KYBER_DMM_ROUTER_BY_CHAIN_ID,
LIDO_INFO_BY_CHAIN,
@ -40,6 +44,7 @@ import {
NATIVE_FEE_TOKEN_BY_CHAIN_ID,
NULL_ADDRESS,
NULL_BYTES,
PLATYPUS_ROUTER_BY_CHAIN_ID,
SELL_SOURCE_FILTER_BY_CHAIN_ID,
UNISWAPV1_ROUTER_BY_CHAIN_ID,
UNISWAPV3_CONFIG_BY_CHAIN_ID,
@ -72,6 +77,7 @@ import {
GeistFillData,
GeistInfo,
GenericRouterFillData,
GMXFillData,
HopInfo,
KyberDmmFillData,
KyberFillData,
@ -83,6 +89,7 @@ import {
MakerPsmFillData,
MooniswapFillData,
MultiHopFillData,
PlatypusFillData,
PsmInfo,
ShellFillData,
SourceQuoteOperation,
@ -1265,6 +1272,66 @@ export class SamplerOperations {
});
}
public getGMXSellQuotes(
router: string,
reader: string,
vault: string,
tokenAddressPath: string[],
takerFillAmounts: BigNumber[],
): SourceQuoteOperation<GMXFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.GMX,
fillData: { router, reader, vault, tokenAddressPath },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromGMX,
params: [reader, vault, tokenAddressPath, takerFillAmounts],
});
}
public getGMXBuyQuotes(
router: string,
reader: string,
vault: string,
tokenAddressPath: string[],
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<GMXFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.GMX,
fillData: { router, reader, vault, tokenAddressPath },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromGMX,
params: [reader, vault, tokenAddressPath, makerFillAmounts],
});
}
public getPlatypusSellQuotes(
router: string,
pool: string[],
tokenAddressPath: string[],
takerFillAmounts: BigNumber[],
): SourceQuoteOperation<PlatypusFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Platypus,
fillData: { router, pool, tokenAddressPath },
contract: this._samplerContract,
function: this._samplerContract.sampleSellsFromPlatypus,
params: [pool[0], tokenAddressPath, takerFillAmounts],
});
}
public getPlatypusBuyQuotes(
router: string,
pool: string[],
tokenAddressPath: string[],
makerFillAmounts: BigNumber[],
): SourceQuoteOperation<PlatypusFillData> {
return new SamplerContractOperation({
source: ERC20BridgeSource.Platypus,
fillData: { router, pool, tokenAddressPath },
contract: this._samplerContract,
function: this._samplerContract.sampleBuysFromPlatypus,
params: [pool[0], tokenAddressPath, makerFillAmounts],
});
}
public getMedianSellRate(
sources: ERC20BridgeSource[],
makerToken: string,
@ -1649,6 +1716,32 @@ export class SamplerOperations {
takerFillAmounts,
);
}
case ERC20BridgeSource.GMX: {
// low liquidity mim pool dont quote
if (
takerToken === '0x130966628846bfd36ff31a822705796e8cb8c18d' ||
makerToken === '0x130966628846bfd36ff31a822705796e8cb8c18d'
) {
return [];
}
return this.getGMXSellQuotes(
GMX_ROUTER_BY_CHAIN_ID[this.chainId],
GMX_READER_BY_CHAIN_ID[this.chainId],
GMX_VAULT_BY_CHAIN_ID[this.chainId],
[takerToken, makerToken],
takerFillAmounts,
);
}
case ERC20BridgeSource.Platypus: {
return getPlatypusInfoForPair(this.chainId, takerToken, makerToken).map(pool =>
this.getPlatypusSellQuotes(
PLATYPUS_ROUTER_BY_CHAIN_ID[this.chainId],
[pool.poolAddress],
[takerToken, makerToken],
takerFillAmounts,
),
);
}
default:
throw new Error(`Unsupported sell sample source: ${source}`);
}
@ -1951,6 +2044,32 @@ export class SamplerOperations {
}
return this.getCompoundBuyQuotes(cToken.tokenAddress, makerToken, takerToken, makerFillAmounts);
}
case ERC20BridgeSource.GMX: {
// bad mim pool dont quote
if (
takerToken === '0x130966628846bfd36ff31a822705796e8cb8c18d' ||
makerToken === '0x130966628846bfd36ff31a822705796e8cb8c18d'
) {
return [];
}
return this.getGMXBuyQuotes(
GMX_ROUTER_BY_CHAIN_ID[this.chainId],
GMX_READER_BY_CHAIN_ID[this.chainId],
GMX_VAULT_BY_CHAIN_ID[this.chainId],
[takerToken, makerToken],
makerFillAmounts,
);
}
case ERC20BridgeSource.Platypus: {
return getPlatypusInfoForPair(this.chainId, takerToken, makerToken).map(pool =>
this.getPlatypusBuyQuotes(
PLATYPUS_ROUTER_BY_CHAIN_ID[this.chainId],
[pool.poolAddress],
[takerToken, makerToken],
makerFillAmounts,
),
);
}
default:
throw new Error(`Unsupported buy sample source: ${source}`);
}

View File

@ -92,6 +92,8 @@ export enum ERC20BridgeSource {
// Avalanche
Pangolin = 'Pangolin',
TraderJoe = 'TraderJoe',
Platypus = 'Platypus',
GMX = 'GMX',
// Celo only
UbeSwap = 'UbeSwap',
MobiusMoney = 'MobiusMoney',
@ -351,6 +353,24 @@ export interface GeistFillData extends FillData {
takerToken: string;
}
export interface PlatypusInfo {
poolAddress: string;
tokens: string[];
gasSchedule: number;
}
export interface GMXFillData extends FillData {
router: string;
reader: string;
vault: string;
tokenAddressPath: string[];
}
export interface PlatypusFillData extends FillData {
router: string;
pool: string[];
tokenAddressPath: string[];
}
/**
* Represents a node on a fill path.
*/

View File

@ -18,14 +18,17 @@ import * as DODOSampler from '../test/generated-artifacts/DODOSampler.json';
import * as DODOV2Sampler from '../test/generated-artifacts/DODOV2Sampler.json';
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
import * as FakeTaker from '../test/generated-artifacts/FakeTaker.json';
import * as GMXSampler from '../test/generated-artifacts/GMXSampler.json';
import * as IBalancer from '../test/generated-artifacts/IBalancer.json';
import * as IBalancerV2Vault from '../test/generated-artifacts/IBalancerV2Vault.json';
import * as IBancor from '../test/generated-artifacts/IBancor.json';
import * as ICurve from '../test/generated-artifacts/ICurve.json';
import * as IGMX from '../test/generated-artifacts/IGMX.json';
import * as IKyberNetwork from '../test/generated-artifacts/IKyberNetwork.json';
import * as IMooniswap from '../test/generated-artifacts/IMooniswap.json';
import * as IMStable from '../test/generated-artifacts/IMStable.json';
import * as IMultiBridge from '../test/generated-artifacts/IMultiBridge.json';
import * as IPlatypus from '../test/generated-artifacts/IPlatypus.json';
import * as IShell from '../test/generated-artifacts/IShell.json';
import * as ISmoothy from '../test/generated-artifacts/ISmoothy.json';
import * as IUniswapExchangeQuotes from '../test/generated-artifacts/IUniswapExchangeQuotes.json';
@ -38,6 +41,7 @@ import * as MakerPSMSampler from '../test/generated-artifacts/MakerPSMSampler.js
import * as MooniswapSampler from '../test/generated-artifacts/MooniswapSampler.json';
import * as MStableSampler from '../test/generated-artifacts/MStableSampler.json';
import * as NativeOrderSampler from '../test/generated-artifacts/NativeOrderSampler.json';
import * as PlatypusSampler from '../test/generated-artifacts/PlatypusSampler.json';
import * as SamplerUtils from '../test/generated-artifacts/SamplerUtils.json';
import * as ShellSampler from '../test/generated-artifacts/ShellSampler.json';
import * as SmoothySampler from '../test/generated-artifacts/SmoothySampler.json';
@ -61,6 +65,7 @@ export const artifacts = {
DODOV2Sampler: DODOV2Sampler as ContractArtifact,
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
FakeTaker: FakeTaker as ContractArtifact,
GMXSampler: GMXSampler as ContractArtifact,
KyberDmmSampler: KyberDmmSampler as ContractArtifact,
KyberSampler: KyberSampler as ContractArtifact,
LidoSampler: LidoSampler as ContractArtifact,
@ -69,6 +74,7 @@ export const artifacts = {
MakerPSMSampler: MakerPSMSampler as ContractArtifact,
MooniswapSampler: MooniswapSampler as ContractArtifact,
NativeOrderSampler: NativeOrderSampler as ContractArtifact,
PlatypusSampler: PlatypusSampler as ContractArtifact,
SamplerUtils: SamplerUtils as ContractArtifact,
ShellSampler: ShellSampler as ContractArtifact,
SmoothySampler: SmoothySampler as ContractArtifact,
@ -81,10 +87,12 @@ export const artifacts = {
IBalancerV2Vault: IBalancerV2Vault as ContractArtifact,
IBancor: IBancor as ContractArtifact,
ICurve: ICurve as ContractArtifact,
IGMX: IGMX as ContractArtifact,
IKyberNetwork: IKyberNetwork as ContractArtifact,
IMStable: IMStable as ContractArtifact,
IMooniswap: IMooniswap as ContractArtifact,
IMultiBridge: IMultiBridge as ContractArtifact,
IPlatypus: IPlatypus as ContractArtifact,
IShell: IShell as ContractArtifact,
ISmoothy: ISmoothy as ContractArtifact,
IUniswapExchangeQuotes: IUniswapExchangeQuotes as ContractArtifact,

View File

@ -16,6 +16,7 @@ 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/erc20_bridge_sampler';
export * from '../test/generated-wrappers/fake_taker';
export * from '../test/generated-wrappers/g_m_x_sampler';
export * from '../test/generated-wrappers/i_balancer';
export * from '../test/generated-wrappers/i_balancer_v2_vault';
export * from '../test/generated-wrappers/i_bancor';
@ -24,10 +25,12 @@ export * from '../test/generated-wrappers/i_kyber_network';
export * from '../test/generated-wrappers/i_m_stable';
export * from '../test/generated-wrappers/i_mooniswap';
export * from '../test/generated-wrappers/i_multi_bridge';
export * from '../test/generated-wrappers/i_platypus';
export * from '../test/generated-wrappers/i_shell';
export * from '../test/generated-wrappers/i_smoothy';
export * from '../test/generated-wrappers/i_uniswap_exchange_quotes';
export * from '../test/generated-wrappers/i_uniswap_v2_router01';
export * from '../test/generated-wrappers/igmx';
export * from '../test/generated-wrappers/kyber_dmm_sampler';
export * from '../test/generated-wrappers/kyber_sampler';
export * from '../test/generated-wrappers/lido_sampler';
@ -36,6 +39,7 @@ export * from '../test/generated-wrappers/m_stable_sampler';
export * from '../test/generated-wrappers/maker_p_s_m_sampler';
export * from '../test/generated-wrappers/mooniswap_sampler';
export * from '../test/generated-wrappers/native_order_sampler';
export * from '../test/generated-wrappers/platypus_sampler';
export * from '../test/generated-wrappers/sampler_utils';
export * from '../test/generated-wrappers/shell_sampler';
export * from '../test/generated-wrappers/smoothy_sampler';

View File

@ -19,14 +19,17 @@
"test/generated-artifacts/DODOV2Sampler.json",
"test/generated-artifacts/ERC20BridgeSampler.json",
"test/generated-artifacts/FakeTaker.json",
"test/generated-artifacts/GMXSampler.json",
"test/generated-artifacts/IBalancer.json",
"test/generated-artifacts/IBalancerV2Vault.json",
"test/generated-artifacts/IBancor.json",
"test/generated-artifacts/ICurve.json",
"test/generated-artifacts/IGMX.json",
"test/generated-artifacts/IKyberNetwork.json",
"test/generated-artifacts/IMStable.json",
"test/generated-artifacts/IMooniswap.json",
"test/generated-artifacts/IMultiBridge.json",
"test/generated-artifacts/IPlatypus.json",
"test/generated-artifacts/IShell.json",
"test/generated-artifacts/ISmoothy.json",
"test/generated-artifacts/IUniswapExchangeQuotes.json",
@ -39,6 +42,7 @@
"test/generated-artifacts/MakerPSMSampler.json",
"test/generated-artifacts/MooniswapSampler.json",
"test/generated-artifacts/NativeOrderSampler.json",
"test/generated-artifacts/PlatypusSampler.json",
"test/generated-artifacts/SamplerUtils.json",
"test/generated-artifacts/ShellSampler.json",
"test/generated-artifacts/SmoothySampler.json",

View File

@ -1,4 +1,12 @@
[
{
"version": "1.12.0",
"changes": [
{
"note": "Added Support for GMX and Platypus on Avalanche"
}
]
},
{
"version": "11.12.0",
"changes": [

View File

@ -135,6 +135,8 @@ export enum BridgeProtocol {
AaveV2,
Compound,
BalancerV2Batch,
GMX,
Platypus,
}
// tslint:enable: enum-naming