fix: Support Multiple Shells (#17)
* fix: Support Multiple Shells * CHANGEGLOG
This commit is contained in:
parent
02006118c7
commit
717db99b38
@ -51,16 +51,15 @@ contract ShellBridge is
|
||||
external
|
||||
returns (bytes4 success)
|
||||
{
|
||||
// Decode the bridge data to get the `fromTokenAddress`.
|
||||
(address fromTokenAddress) = abi.decode(bridgeData, (address));
|
||||
// Decode the bridge data to get the `fromTokenAddress` and `pool`.
|
||||
(address fromTokenAddress, address pool) = abi.decode(bridgeData, (address, address));
|
||||
|
||||
uint256 fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this));
|
||||
IShell exchange = IShell(_getShellAddress());
|
||||
// Grant an allowance to the exchange to spend `fromTokenAddress` token.
|
||||
LibERC20Token.approveIfBelow(fromTokenAddress, address(exchange), fromTokenBalance);
|
||||
LibERC20Token.approveIfBelow(fromTokenAddress, pool, fromTokenBalance);
|
||||
|
||||
// Try to sell all of this contract's `fromTokenAddress` token balance.
|
||||
uint256 boughtAmount = exchange.originSwap(
|
||||
uint256 boughtAmount = IShell(pool).originSwap(
|
||||
fromTokenAddress,
|
||||
toTokenAddress,
|
||||
fromTokenBalance,
|
||||
|
@ -56,8 +56,6 @@ contract DeploymentConstants {
|
||||
address constant private MUSD_ADDRESS = 0xe2f2a5C287993345a840Db3B0845fbC70f5935a5;
|
||||
/// @dev Mainnet address of the Mooniswap Registry contract
|
||||
address constant private MOONISWAP_REGISTRY = 0x71CD6666064C3A1354a3B4dca5fA1E2D3ee7D303;
|
||||
/// @dev Mainnet address of the Shell contract
|
||||
address constant private SHELL_CONTRACT = 0x2E703D658f8dd21709a7B458967aB4081F8D3d05;
|
||||
/// @dev Mainnet address of the DODO Registry (ZOO) contract
|
||||
address constant private DODO_REGISTRY = 0x3A97247DF274a17C59A3bd12735ea3FcDFb49950;
|
||||
/// @dev Mainnet address of the DODO Helper contract
|
||||
@ -303,16 +301,6 @@ contract DeploymentConstants {
|
||||
return MOONISWAP_REGISTRY;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the Shell contract address.
|
||||
/// @return registry The Shell contract address.
|
||||
function _getShellAddress()
|
||||
internal
|
||||
view
|
||||
returns (address)
|
||||
{
|
||||
return SHELL_CONTRACT;
|
||||
}
|
||||
|
||||
/// @dev An overridable way to retrieve the DODO Registry contract address.
|
||||
/// @return registry The DODO Registry contract address.
|
||||
function _getDODORegistryAddress()
|
||||
|
@ -89,7 +89,7 @@ contract BridgeAdapter is
|
||||
MixinMooniswap(addresses)
|
||||
MixinMStable(addresses)
|
||||
MixinOasis(addresses)
|
||||
MixinShell(addresses)
|
||||
MixinShell()
|
||||
MixinSushiswap(addresses)
|
||||
MixinUniswap(addresses)
|
||||
MixinUniswapV2(addresses)
|
||||
|
@ -44,7 +44,6 @@ contract MixinAdapterAddresses
|
||||
address uniswapV2Router;
|
||||
address uniswapExchangeFactory;
|
||||
address mStable;
|
||||
address shell;
|
||||
address dodoHelper;
|
||||
// Other
|
||||
address weth;
|
||||
|
@ -44,15 +44,6 @@ contract MixinShell is
|
||||
{
|
||||
using LibERC20TokenV06 for IERC20TokenV06;
|
||||
|
||||
/// @dev Mainnet address of the `Shell` contract.
|
||||
IShell private immutable SHELL;
|
||||
|
||||
constructor(AdapterAddresses memory addresses)
|
||||
public
|
||||
{
|
||||
SHELL = IShell(addresses.shell);
|
||||
}
|
||||
|
||||
function _tradeShell(
|
||||
IERC20TokenV06 buyToken,
|
||||
uint256 sellAmount,
|
||||
@ -61,15 +52,15 @@ contract MixinShell is
|
||||
internal
|
||||
returns (uint256 boughtAmount)
|
||||
{
|
||||
(address fromTokenAddress) = abi.decode(bridgeData, (address));
|
||||
(address fromTokenAddress, address pool) = abi.decode(bridgeData, (address, address));
|
||||
|
||||
// Grant the Shell contract an allowance to sell the first token.
|
||||
IERC20TokenV06(fromTokenAddress).approveIfBelow(
|
||||
address(SHELL),
|
||||
pool,
|
||||
sellAmount
|
||||
);
|
||||
|
||||
boughtAmount = SHELL.originSwap(
|
||||
boughtAmount = IShell(pool).originSwap(
|
||||
fromTokenAddress,
|
||||
address(buyToken),
|
||||
// Sell all tokens we hold.
|
||||
|
@ -77,7 +77,6 @@ blockchainTests.resets('FillQuoteTransformer', env => {
|
||||
mStable: NULL_ADDRESS,
|
||||
weth: NULL_ADDRESS,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
shell: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
dodoBridge: NULL_ADDRESS,
|
||||
dodoHelper: NULL_ADDRESS,
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "4.9.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Support multiple `Shells` by supplying the `pool` address",
|
||||
"pr": 17
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "4.8.1",
|
||||
"changes": [
|
||||
|
@ -28,13 +28,15 @@ contract ShellSampler is
|
||||
/// @dev Default gas limit for Shell calls.
|
||||
uint256 constant private DEFAULT_CALL_GAS = 300e3; // 300k
|
||||
|
||||
/// @dev Sample sell quotes from the Shell contract
|
||||
/// @dev Sample sell quotes from the Shell pool contract
|
||||
/// @param pool Address of the Shell pool contract
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param takerTokenAmounts Taker token sell amount for each sample.
|
||||
/// @return makerTokenAmounts Maker amounts bought at each taker token
|
||||
/// amount.
|
||||
function sampleSellsFromShell(
|
||||
address pool,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory takerTokenAmounts
|
||||
@ -49,7 +51,7 @@ contract ShellSampler is
|
||||
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
try
|
||||
IShell(_getShellAddress()).viewOriginSwap
|
||||
IShell(pool).viewOriginSwap
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(takerToken, makerToken, takerTokenAmounts[i])
|
||||
returns (uint256 amount)
|
||||
@ -62,13 +64,15 @@ contract ShellSampler is
|
||||
}
|
||||
}
|
||||
|
||||
/// @dev Sample buy quotes from Shell contract
|
||||
/// @dev Sample buy quotes from Shell pool contract
|
||||
/// @param pool Address of the Shell pool contract
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
/// @param makerTokenAmounts Maker token buy amount for each sample.
|
||||
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||
/// amount.
|
||||
function sampleBuysFromShell(
|
||||
address pool,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
uint256[] memory makerTokenAmounts
|
||||
@ -83,7 +87,7 @@ contract ShellSampler is
|
||||
|
||||
for (uint256 i = 0; i < numSamples; i++) {
|
||||
try
|
||||
IShell(_getShellAddress()).viewTargetSwap
|
||||
IShell(pool).viewTargetSwap
|
||||
{gas: DEFAULT_CALL_GAS}
|
||||
(takerToken, makerToken, makerTokenAmounts[i])
|
||||
returns (uint256 amount)
|
||||
|
@ -89,8 +89,28 @@ export const SOURCE_FLAGS: { [source in ERC20BridgeSource]: number } = Object.as
|
||||
...Object.values(ERC20BridgeSource).map((source: ERC20BridgeSource, index) => ({ [source]: 1 << index })),
|
||||
);
|
||||
|
||||
// Mainnet tokens
|
||||
// Not an exhaustive list, just enough so we don't repeat ourselves
|
||||
export const TOKENS = {
|
||||
WETH: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
||||
// Stable Coins
|
||||
DAI: '0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
USDT: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
sUSD: '0x57ab1ec28d129707052df4df418d58a2d46d5f51',
|
||||
TUSD: '0x0000000000085d4780b73119b644ae5ecd22b376',
|
||||
// Bitcoins
|
||||
WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
|
||||
RenBTC: '0xeb4c2781e4eba804ce9a9803c67d0893436bb27d',
|
||||
sBTC: '0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6',
|
||||
// Other
|
||||
MKR: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
|
||||
};
|
||||
|
||||
/**
|
||||
* Mainnet Curve configuration
|
||||
* The tokens are in order of their index, which each curve defines
|
||||
* I.e DaiUsdc curve has DAI as index 0 and USDC as index 1
|
||||
*/
|
||||
export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
DaiUsdc: {
|
||||
@ -98,7 +118,7 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
poolAddress: '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56',
|
||||
tokens: ['0x6b175474e89094c44da98b954eedeac495271d0f', '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'],
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC],
|
||||
},
|
||||
// DaiUsdcUsdt: {
|
||||
// exchangeFunctionSelector: CurveFunctionSelectors.exchange_underlying,
|
||||
@ -106,9 +126,9 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
// buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
// poolAddress: '0x52ea46506b9cc5ef470c5bf89f17dc28bb35d85c',
|
||||
// tokens: [
|
||||
// '0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
// '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
// '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
// TOKENS.DAI,
|
||||
// TOKENS.USDC,
|
||||
// TOKENS.USDT,
|
||||
// ],
|
||||
// },
|
||||
DaiUsdcUsdtTusd: {
|
||||
@ -116,12 +136,7 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
poolAddress: '0x45f783cce6b7ff23b2ab2d70e416cdb7d6055f51',
|
||||
tokens: [
|
||||
'0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
'0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
'0x0000000000085d4780b73119b644ae5ecd22b376',
|
||||
],
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.TUSD],
|
||||
},
|
||||
// Looks like it's dying.
|
||||
DaiUsdcUsdtBusd: {
|
||||
@ -130,10 +145,10 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
poolAddress: '0x79a8c46dea5ada233abaffd40f3a0a2b1e5a4f27',
|
||||
tokens: [
|
||||
'0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
'0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
'0x4fabb145d64652a948d72533023f6e7a623c7c53',
|
||||
TOKENS.DAI,
|
||||
TOKENS.USDC,
|
||||
TOKENS.USDT,
|
||||
'0x4fabb145d64652a948d72533023f6e7a623c7c53', // bUSD
|
||||
],
|
||||
},
|
||||
DaiUsdcUsdtSusd: {
|
||||
@ -141,57 +156,41 @@ export const MAINNET_CURVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy_underlying,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0xa5407eae9ba41422680e2e00537571bcc53efbfd',
|
||||
tokens: [
|
||||
'0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
'0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
'0x57ab1ec28d129707052df4df418d58a2d46d5f51',
|
||||
],
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.sUSD],
|
||||
},
|
||||
RenbtcWbtc: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0x93054188d876f558f4a66b2ef1d97d16edf0895b',
|
||||
tokens: ['0xeb4c2781e4eba804ce9a9803c67d0893436bb27d', '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599'],
|
||||
tokens: [TOKENS.RenBTC, TOKENS.WBTC],
|
||||
},
|
||||
RenbtcWbtcSbtc: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0x7fc77b5c7614e1533320ea6ddc2eb61fa00a9714',
|
||||
tokens: [
|
||||
'0xeb4c2781e4eba804ce9a9803c67d0893436bb27d',
|
||||
'0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
|
||||
'0xfe18be6b3bd88a2d2a7f928d00292e7a9963cfc6',
|
||||
],
|
||||
tokens: [TOKENS.RenBTC, TOKENS.WBTC, TOKENS.sBTC],
|
||||
},
|
||||
TriPool: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7',
|
||||
tokens: [
|
||||
'0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
'0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
],
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT],
|
||||
},
|
||||
};
|
||||
|
||||
export const MAINNET_SWERVE_INFOS: { [name: string]: CurveInfo } = {
|
||||
swUSD: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
sellQuoteFunctionSelector: CurveFunctionSelectors.get_dy,
|
||||
buyQuoteFunctionSelector: CurveFunctionSelectors.None,
|
||||
poolAddress: '0x329239599afb305da0a2ec69c58f8a6697f9f88d', // _target: 0xa5407eae9ba41422680e2e00537571bcc53efbfd
|
||||
tokens: [
|
||||
'0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
'0xdac17f958d2ee523a2206206994597c13d831ec7',
|
||||
'0x0000000000085d4780b73119b644ae5ecd22b376',
|
||||
],
|
||||
tokens: [TOKENS.DAI, TOKENS.USDC, TOKENS.USDT, TOKENS.TUSD],
|
||||
},
|
||||
};
|
||||
|
||||
export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = {
|
||||
yVaultCurve: {
|
||||
exchangeFunctionSelector: CurveFunctionSelectors.exchange,
|
||||
@ -232,10 +231,10 @@ export const MAINNET_SNOWSWAP_INFOS: { [name: string]: CurveInfo } = {
|
||||
// buyQuoteFunctionSelector: CurveFunctionSelectors.get_dx_underlying,
|
||||
// poolAddress: '0x4571753311e37ddb44faa8fb78a6df9a6e3c6c0b',
|
||||
// tokens: [
|
||||
// '0x6b175474e89094c44da98b954eedeac495271d0f', // DAI
|
||||
// '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
|
||||
// '0xdac17f958d2ee523a2206206994597c13d831ec7', // USDT
|
||||
// '0x0000000000085d4780b73119b644ae5ecd22b376', // TUSD
|
||||
// TOKENS.DAI,
|
||||
// TOKENS.USDC,
|
||||
// TOKENS.USDT,
|
||||
// TOKENS.TUSD,
|
||||
// ],
|
||||
// },
|
||||
};
|
||||
@ -248,8 +247,7 @@ export const MAINNET_KYBER_RESERVE_IDS: { [name: string]: string } = {
|
||||
|
||||
export const MAINNET_KYBER_TOKEN_RESERVE_IDS: { [token: string]: string } = {
|
||||
// USDC
|
||||
['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48']:
|
||||
'0xaa55534443303041505200000000000000000000000000000000000000000000',
|
||||
[TOKENS.USDC]: '0xaa55534443303041505200000000000000000000000000000000000000000000',
|
||||
// AMPL
|
||||
['0xd46ba6d942050d489dbd938a2c909a5d5039a161']:
|
||||
'0xaad46ba6d942050d489dbd938a2c909a5d5039a1610000000000000000000000',
|
||||
@ -263,8 +261,7 @@ export const MAINNET_KYBER_TOKEN_RESERVE_IDS: { [token: string]: string } = {
|
||||
['0xdd974d5c2e2928dea5f71b9825b8b646686bd200']:
|
||||
'0xaa4b4e435f4d4547414c41444f4e000000000000000000000000000000000000',
|
||||
// sUSD
|
||||
['0x57ab1ec28d129707052df4df418d58a2d46d5f51']:
|
||||
'0xaa73555344000000000000000000000000000000000000000000000000000000',
|
||||
[TOKENS.sUSD]: '0xaa73555344000000000000000000000000000000000000000000000000000000',
|
||||
// SNX
|
||||
['0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f']:
|
||||
'0xaa534e5800000000000000000000000000000000000000000000000000000000',
|
||||
@ -278,6 +275,17 @@ export const MAINNET_KYBER_TOKEN_RESERVE_IDS: { [token: string]: string } = {
|
||||
|
||||
export const MAINNET_SUSHI_SWAP_ROUTER = '0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F';
|
||||
|
||||
export const MAINNET_SHELL_POOLS = {
|
||||
StableCoins: {
|
||||
poolAddress: '0x2E703D658f8dd21709a7B458967aB4081F8D3d05',
|
||||
tokens: [TOKENS.USDC, TOKENS.USDT, TOKENS.sUSD, TOKENS.DAI],
|
||||
},
|
||||
Bitcoin: {
|
||||
poolAddress: '0x02Af7C867d6Ddd2c87dEcec2E4AFF809ee118FBb',
|
||||
tokens: [TOKENS.RenBTC, TOKENS.WBTC, TOKENS.sBTC],
|
||||
},
|
||||
};
|
||||
|
||||
export const ERC20_PROXY_ID = '0xf47261b0';
|
||||
export const WALLET_SIGNATURE = '0x04';
|
||||
export const ONE_ETHER = new BigNumber(1e18);
|
||||
@ -323,7 +331,7 @@ export const BRIDGE_ADDRESSES_BY_CHAIN: { [chainId in ChainId]: BridgeContractAd
|
||||
mStableBridge: '0x2bf04fcea05f0989a14d9afa37aa376baca6b2b3',
|
||||
mooniswapBridge: '0x02b7eca484ad960fca3f7709e0b2ac81eec3069c',
|
||||
sushiswapBridge: '0x47ed0262a0b688dcb836d254c6a2e96b6c48a9f5',
|
||||
shellBridge: '0x21fb3862eed7911e0f8219a077247b849846728d',
|
||||
shellBridge: '0xf1c0811e3788caae7dbfae43da9d9131b1a8a148',
|
||||
dodoBridge: '0xe9da66965a9344aab2167e6813c03f043cc7a6ca',
|
||||
creamBridge: '0xb9d4bf2c8dab828f4ffb656acdb6c2b497d44f25',
|
||||
swerveBridge: '0xf9786d5eb1de47fa56a8f7bb387653c6d410bfee',
|
||||
|
@ -1,20 +1,13 @@
|
||||
import { NULL_ADDRESS } from './constants';
|
||||
import { NULL_ADDRESS, TOKENS } from './constants';
|
||||
|
||||
// tslint:disable completed-docs
|
||||
// tslint:disable enum-naming
|
||||
enum Tokens {
|
||||
WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
||||
DAI = '0x6b175474e89094c44da98b954eedeac495271d0f',
|
||||
USDC = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
||||
MKR = '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
|
||||
}
|
||||
|
||||
export function getMultiBridgeIntermediateToken(takerToken: string, makerToken: string): string {
|
||||
let intermediateToken = NULL_ADDRESS;
|
||||
if (takerToken !== Tokens.WETH && makerToken !== Tokens.WETH) {
|
||||
intermediateToken = Tokens.WETH;
|
||||
} else if (takerToken === Tokens.USDC || makerToken === Tokens.USDC) {
|
||||
intermediateToken = Tokens.DAI;
|
||||
if (takerToken !== TOKENS.WETH && makerToken !== TOKENS.WETH) {
|
||||
intermediateToken = TOKENS.WETH;
|
||||
} else if (takerToken === TOKENS.USDC || makerToken === TOKENS.USDC) {
|
||||
intermediateToken = TOKENS.DAI;
|
||||
}
|
||||
return intermediateToken;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import {
|
||||
NativeCollapsedFill,
|
||||
OptimizedMarketOrder,
|
||||
OrderDomain,
|
||||
ShellFillData,
|
||||
SnowSwapFillData,
|
||||
SushiSwapFillData,
|
||||
SwerveFillData,
|
||||
@ -331,6 +332,14 @@ export function createBridgeOrder(
|
||||
createDODOBridgeData(takerToken, dodoFillData.poolAddress, dodoFillData.isSellBase),
|
||||
);
|
||||
break;
|
||||
case ERC20BridgeSource.Shell:
|
||||
const shellFillData = (fill as CollapsedFill<ShellFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
makerToken,
|
||||
bridgeAddress,
|
||||
createShellBridgeData(takerToken, shellFillData.poolAddress),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
makerToken,
|
||||
@ -380,6 +389,14 @@ function createBalancerBridgeData(takerToken: string, poolAddress: string): stri
|
||||
return encoder.encode({ takerToken, poolAddress });
|
||||
}
|
||||
|
||||
function createShellBridgeData(takerToken: string, poolAddress: string): string {
|
||||
const encoder = AbiEncoder.create([
|
||||
{ name: 'takerToken', type: 'address' },
|
||||
{ name: 'poolAddress', type: 'address' },
|
||||
]);
|
||||
return encoder.encode({ takerToken, poolAddress });
|
||||
}
|
||||
|
||||
function createBancorBridgeData(path: string[], networkAddress: string): string {
|
||||
const encoder = AbiEncoder.create([
|
||||
{ name: 'path', type: 'address[]' },
|
||||
|
@ -14,6 +14,7 @@ import { getKyberReserveIdsForPair } from './kyber_utils';
|
||||
import { getMultiBridgeIntermediateToken } from './multibridge_utils';
|
||||
import { getIntermediateTokens } from './multihop_utils';
|
||||
import { SamplerContractOperation } from './sampler_contract_operation';
|
||||
import { getShellsForPair } from './shell_utils';
|
||||
import { SourceFilters } from './source_filters';
|
||||
import {
|
||||
BalancerFillData,
|
||||
@ -30,6 +31,7 @@ import {
|
||||
MooniswapFillData,
|
||||
MultiBridgeFillData,
|
||||
MultiHopFillData,
|
||||
ShellFillData,
|
||||
SnowSwapFillData,
|
||||
SnowSwapInfo,
|
||||
SourceQuoteOperation,
|
||||
@ -840,19 +842,29 @@ export class SamplerOperations {
|
||||
}
|
||||
|
||||
public getShellSellQuotes(
|
||||
poolAddress: string,
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
takerFillAmounts: BigNumber[],
|
||||
): SourceQuoteOperation {
|
||||
): SourceQuoteOperation<ShellFillData> {
|
||||
return new SamplerContractOperation({
|
||||
source: ERC20BridgeSource.Shell,
|
||||
contract: this._samplerContract,
|
||||
function: this._samplerContract.sampleSellsFromShell,
|
||||
params: [takerToken, makerToken, takerFillAmounts],
|
||||
params: [poolAddress, takerToken, makerToken, takerFillAmounts],
|
||||
callback: (callResults: string, fillData: ShellFillData): BigNumber[] => {
|
||||
const samples = this._samplerContract.getABIDecodedReturnData<BigNumber[]>(
|
||||
'sampleSellsFromShell',
|
||||
callResults,
|
||||
);
|
||||
fillData.poolAddress = poolAddress;
|
||||
return samples;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public getShellBuyQuotes(
|
||||
poolAddress: string,
|
||||
makerToken: string,
|
||||
takerToken: string,
|
||||
makerFillAmounts: BigNumber[],
|
||||
@ -861,7 +873,15 @@ export class SamplerOperations {
|
||||
source: ERC20BridgeSource.Shell,
|
||||
contract: this._samplerContract,
|
||||
function: this._samplerContract.sampleBuysFromShell,
|
||||
params: [takerToken, makerToken, makerFillAmounts],
|
||||
params: [poolAddress, takerToken, makerToken, makerFillAmounts],
|
||||
callback: (callResults: string, fillData: ShellFillData): BigNumber[] => {
|
||||
const samples = this._samplerContract.getABIDecodedReturnData<BigNumber[]>(
|
||||
'sampleBuysFromShell',
|
||||
callResults,
|
||||
);
|
||||
fillData.poolAddress = poolAddress;
|
||||
return samples;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -1172,7 +1192,9 @@ export class SamplerOperations {
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Shell:
|
||||
return this.getShellSellQuotes(makerToken, takerToken, takerFillAmounts);
|
||||
return getShellsForPair(takerToken, makerToken).map(pool =>
|
||||
this.getShellSellQuotes(pool, makerToken, takerToken, takerFillAmounts),
|
||||
);
|
||||
case ERC20BridgeSource.Dodo:
|
||||
return this.getDODOSellQuotes(makerToken, takerToken, takerFillAmounts);
|
||||
default:
|
||||
@ -1290,7 +1312,9 @@ export class SamplerOperations {
|
||||
),
|
||||
);
|
||||
case ERC20BridgeSource.Shell:
|
||||
return this.getShellBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
||||
return getShellsForPair(takerToken, makerToken).map(pool =>
|
||||
this.getShellBuyQuotes(pool, makerToken, takerToken, makerFillAmounts),
|
||||
);
|
||||
case ERC20BridgeSource.Dodo:
|
||||
return this.getDODOBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
||||
default:
|
||||
|
@ -0,0 +1,8 @@
|
||||
import { MAINNET_SHELL_POOLS } from './constants';
|
||||
|
||||
// tslint:disable completed-docs
|
||||
export function getShellsForPair(takerToken: string, makerToken: string): string[] {
|
||||
return Object.values(MAINNET_SHELL_POOLS)
|
||||
.filter(c => [makerToken, takerToken].every(t => c.tokens.includes(t)))
|
||||
.map(i => i.poolAddress);
|
||||
}
|
@ -123,6 +123,10 @@ export interface SushiSwapFillData extends UniswapV2FillData {
|
||||
router: string;
|
||||
}
|
||||
|
||||
export interface ShellFillData extends FillData {
|
||||
poolAddress: string;
|
||||
}
|
||||
|
||||
export interface LiquidityProviderFillData extends FillData {
|
||||
poolAddress: string;
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ describe('MarketOperationUtils tests', () => {
|
||||
[ERC20BridgeSource.Mooniswap]: { poolAddress: randomAddress() },
|
||||
[ERC20BridgeSource.Native]: { order: createOrder() },
|
||||
[ERC20BridgeSource.MultiHop]: {},
|
||||
[ERC20BridgeSource.Shell]: {},
|
||||
[ERC20BridgeSource.Shell]: { poolAddress: randomAddress() },
|
||||
[ERC20BridgeSource.Cream]: { poolAddress: randomAddress() },
|
||||
[ERC20BridgeSource.Dodo]: {},
|
||||
};
|
||||
|
@ -329,7 +329,6 @@ export async function runMigrationsAsync(
|
||||
mStable: NULL_ADDRESS,
|
||||
shellBridge: NULL_ADDRESS,
|
||||
creamBridge: NULL_ADDRESS,
|
||||
shell: NULL_ADDRESS,
|
||||
dodoBridge: NULL_ADDRESS,
|
||||
dodoHelper: NULL_ADDRESS,
|
||||
snowSwapBridge: NULL_ADDRESS,
|
||||
|
Loading…
x
Reference in New Issue
Block a user