feat: DODO (#2701)
* feat: DODO * DODO Bridge * export DODOFillData * Use deployed DODOHelper * Deployed Bridge. Half of buys supported * other half of buys * refactor * CHANGELOGs * Lint
This commit is contained in:
parent
2dc0bff1ea
commit
4d04b72674
@ -29,6 +29,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Added `ShellBridge`",
|
"note": "Added `ShellBridge`",
|
||||||
"pr": 2722
|
"pr": 2722
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Added `DODOBridge`",
|
||||||
|
"pr": 2701
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
147
contracts/asset-proxy/contracts/src/bridges/DODOBridge.sol
Normal file
147
contracts/asset-proxy/contracts/src/bridges/DODOBridge.sol
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
|
||||||
|
import "@0x/contracts-erc20/contracts/src/LibERC20Token.sol";
|
||||||
|
import "@0x/contracts-exchange-libs/contracts/src/IWallet.sol";
|
||||||
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
|
import "../interfaces/IERC20Bridge.sol";
|
||||||
|
|
||||||
|
|
||||||
|
interface IDODOHelper {
|
||||||
|
|
||||||
|
function querySellQuoteToken(address dodo, uint256 amount) external view returns (uint256);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface IDODO {
|
||||||
|
|
||||||
|
function sellBaseToken(uint256 amount, uint256 minReceiveQuote, bytes calldata data) external returns (uint256);
|
||||||
|
|
||||||
|
function buyBaseToken(uint256 amount, uint256 maxPayQuote, bytes calldata data) external returns (uint256);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
contract DODOBridge is
|
||||||
|
IERC20Bridge,
|
||||||
|
IWallet,
|
||||||
|
DeploymentConstants
|
||||||
|
{
|
||||||
|
|
||||||
|
struct TransferState {
|
||||||
|
address fromTokenAddress;
|
||||||
|
uint256 fromTokenBalance;
|
||||||
|
address pool;
|
||||||
|
bool isSellBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
|
||||||
|
/// `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress`
|
||||||
|
/// token encoded in the bridge data.
|
||||||
|
/// @param toTokenAddress The token to buy and transfer to `to`.
|
||||||
|
/// @param from The maker (this contract).
|
||||||
|
/// @param to The recipient of the bought tokens.
|
||||||
|
/// @param amount Minimum amount of `toTokenAddress` tokens to buy.
|
||||||
|
/// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress
|
||||||
|
/// @return success The magic bytes if successful.
|
||||||
|
function bridgeTransferFrom(
|
||||||
|
address toTokenAddress,
|
||||||
|
address from,
|
||||||
|
address to,
|
||||||
|
uint256 amount,
|
||||||
|
bytes calldata bridgeData
|
||||||
|
)
|
||||||
|
external
|
||||||
|
returns (bytes4 success)
|
||||||
|
{
|
||||||
|
TransferState memory state;
|
||||||
|
// Decode the bridge data to get the `fromTokenAddress`.
|
||||||
|
(state.fromTokenAddress, state.pool, state.isSellBase) = abi.decode(bridgeData, (address, address, bool));
|
||||||
|
require(state.pool != address(0), "DODOBridge/InvalidPool");
|
||||||
|
IDODO exchange = IDODO(state.pool);
|
||||||
|
// Get our balance of `fromTokenAddress` token.
|
||||||
|
state.fromTokenBalance = IERC20Token(state.fromTokenAddress).balanceOf(address(this));
|
||||||
|
|
||||||
|
// Grant the pool an allowance.
|
||||||
|
LibERC20Token.approveIfBelow(
|
||||||
|
state.fromTokenAddress,
|
||||||
|
address(exchange),
|
||||||
|
state.fromTokenBalance
|
||||||
|
);
|
||||||
|
|
||||||
|
uint256 boughtAmount;
|
||||||
|
if (state.isSellBase) {
|
||||||
|
boughtAmount = exchange.sellBaseToken(
|
||||||
|
// amount to sell
|
||||||
|
state.fromTokenBalance,
|
||||||
|
// min receive amount
|
||||||
|
1,
|
||||||
|
new bytes(0)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Need to re-calculate the sell quote amount into buyBase
|
||||||
|
boughtAmount = IDODOHelper(_getDODOHelperAddress()).querySellQuoteToken(
|
||||||
|
address(exchange),
|
||||||
|
state.fromTokenBalance
|
||||||
|
);
|
||||||
|
exchange.buyBaseToken(
|
||||||
|
// amount to buy
|
||||||
|
boughtAmount,
|
||||||
|
// max pay amount
|
||||||
|
state.fromTokenBalance,
|
||||||
|
new bytes(0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Transfer funds to `to`
|
||||||
|
IERC20Token(toTokenAddress).transfer(to, boughtAmount);
|
||||||
|
|
||||||
|
|
||||||
|
emit ERC20BridgeTransfer(
|
||||||
|
// input token
|
||||||
|
state.fromTokenAddress,
|
||||||
|
// output token
|
||||||
|
toTokenAddress,
|
||||||
|
// input token amount
|
||||||
|
state.fromTokenBalance,
|
||||||
|
// output token amount
|
||||||
|
boughtAmount,
|
||||||
|
from,
|
||||||
|
to
|
||||||
|
);
|
||||||
|
|
||||||
|
return BRIDGE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
|
||||||
|
/// and sign for itself in orders. Always succeeds.
|
||||||
|
/// @return magicValue Success bytes, always.
|
||||||
|
function isValidSignature(
|
||||||
|
bytes32,
|
||||||
|
bytes calldata
|
||||||
|
)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (bytes4 magicValue)
|
||||||
|
{
|
||||||
|
return LEGACY_WALLET_MAGIC_VALUE;
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@
|
|||||||
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
"docs:json": "typedoc --excludePrivate --excludeExternals --excludeProtected --ignoreCompilerErrors --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CurveBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IShell|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|ShellBridge|StaticCallProxy|SushiSwapBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json",
|
"abis": "./test/generated-artifacts/@(BalancerBridge|BancorBridge|ChaiBridge|CurveBridge|DODOBridge|DexForwarderBridge|DydxBridge|ERC1155Proxy|ERC20BridgeProxy|ERC20Proxy|ERC721Proxy|Eth2DaiBridge|IAssetData|IAssetProxy|IAssetProxyDispatcher|IAuthorizable|IBalancerPool|IBancorNetwork|IChai|ICurve|IDydx|IDydxBridge|IERC20Bridge|IEth2Dai|IGasToken|IKyberNetworkProxy|IMStable|IMooniswap|IShell|IUniswapExchange|IUniswapExchangeFactory|IUniswapV2Router01|KyberBridge|MStableBridge|MixinAssetProxyDispatcher|MixinAuthorizable|MixinGasToken|MooniswapBridge|MultiAssetProxy|Ownable|ShellBridge|StaticCallProxy|SushiSwapBridge|TestBancorBridge|TestChaiBridge|TestDexForwarderBridge|TestDydxBridge|TestERC20Bridge|TestEth2DaiBridge|TestKyberBridge|TestStaticCallTarget|TestUniswapBridge|TestUniswapV2Bridge|UniswapBridge|UniswapV2Bridge).json",
|
||||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -10,6 +10,7 @@ import * as BancorBridge from '../generated-artifacts/BancorBridge.json';
|
|||||||
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json';
|
import * as ChaiBridge from '../generated-artifacts/ChaiBridge.json';
|
||||||
import * as CurveBridge from '../generated-artifacts/CurveBridge.json';
|
import * as CurveBridge from '../generated-artifacts/CurveBridge.json';
|
||||||
import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json';
|
import * as DexForwarderBridge from '../generated-artifacts/DexForwarderBridge.json';
|
||||||
|
import * as DODOBridge from '../generated-artifacts/DODOBridge.json';
|
||||||
import * as DydxBridge from '../generated-artifacts/DydxBridge.json';
|
import * as DydxBridge from '../generated-artifacts/DydxBridge.json';
|
||||||
import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json';
|
import * as ERC1155Proxy from '../generated-artifacts/ERC1155Proxy.json';
|
||||||
import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json';
|
import * as ERC20BridgeProxy from '../generated-artifacts/ERC20BridgeProxy.json';
|
||||||
@ -73,6 +74,7 @@ export const artifacts = {
|
|||||||
BancorBridge: BancorBridge as ContractArtifact,
|
BancorBridge: BancorBridge as ContractArtifact,
|
||||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||||
CurveBridge: CurveBridge as ContractArtifact,
|
CurveBridge: CurveBridge as ContractArtifact,
|
||||||
|
DODOBridge: DODOBridge as ContractArtifact,
|
||||||
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
||||||
DydxBridge: DydxBridge as ContractArtifact,
|
DydxBridge: DydxBridge as ContractArtifact,
|
||||||
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||||
|
@ -7,6 +7,7 @@ export * from '../generated-wrappers/balancer_bridge';
|
|||||||
export * from '../generated-wrappers/bancor_bridge';
|
export * from '../generated-wrappers/bancor_bridge';
|
||||||
export * from '../generated-wrappers/chai_bridge';
|
export * from '../generated-wrappers/chai_bridge';
|
||||||
export * from '../generated-wrappers/curve_bridge';
|
export * from '../generated-wrappers/curve_bridge';
|
||||||
|
export * from '../generated-wrappers/d_o_d_o_bridge';
|
||||||
export * from '../generated-wrappers/dex_forwarder_bridge';
|
export * from '../generated-wrappers/dex_forwarder_bridge';
|
||||||
export * from '../generated-wrappers/dydx_bridge';
|
export * from '../generated-wrappers/dydx_bridge';
|
||||||
export * from '../generated-wrappers/erc1155_proxy';
|
export * from '../generated-wrappers/erc1155_proxy';
|
||||||
|
@ -10,6 +10,7 @@ import * as BancorBridge from '../test/generated-artifacts/BancorBridge.json';
|
|||||||
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json';
|
import * as ChaiBridge from '../test/generated-artifacts/ChaiBridge.json';
|
||||||
import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json';
|
import * as CurveBridge from '../test/generated-artifacts/CurveBridge.json';
|
||||||
import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json';
|
import * as DexForwarderBridge from '../test/generated-artifacts/DexForwarderBridge.json';
|
||||||
|
import * as DODOBridge from '../test/generated-artifacts/DODOBridge.json';
|
||||||
import * as DydxBridge from '../test/generated-artifacts/DydxBridge.json';
|
import * as DydxBridge from '../test/generated-artifacts/DydxBridge.json';
|
||||||
import * as ERC1155Proxy from '../test/generated-artifacts/ERC1155Proxy.json';
|
import * as ERC1155Proxy from '../test/generated-artifacts/ERC1155Proxy.json';
|
||||||
import * as ERC20BridgeProxy from '../test/generated-artifacts/ERC20BridgeProxy.json';
|
import * as ERC20BridgeProxy from '../test/generated-artifacts/ERC20BridgeProxy.json';
|
||||||
@ -73,6 +74,7 @@ export const artifacts = {
|
|||||||
BancorBridge: BancorBridge as ContractArtifact,
|
BancorBridge: BancorBridge as ContractArtifact,
|
||||||
ChaiBridge: ChaiBridge as ContractArtifact,
|
ChaiBridge: ChaiBridge as ContractArtifact,
|
||||||
CurveBridge: CurveBridge as ContractArtifact,
|
CurveBridge: CurveBridge as ContractArtifact,
|
||||||
|
DODOBridge: DODOBridge as ContractArtifact,
|
||||||
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
DexForwarderBridge: DexForwarderBridge as ContractArtifact,
|
||||||
DydxBridge: DydxBridge as ContractArtifact,
|
DydxBridge: DydxBridge as ContractArtifact,
|
||||||
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
Eth2DaiBridge: Eth2DaiBridge as ContractArtifact,
|
||||||
|
@ -7,6 +7,7 @@ export * from '../test/generated-wrappers/balancer_bridge';
|
|||||||
export * from '../test/generated-wrappers/bancor_bridge';
|
export * from '../test/generated-wrappers/bancor_bridge';
|
||||||
export * from '../test/generated-wrappers/chai_bridge';
|
export * from '../test/generated-wrappers/chai_bridge';
|
||||||
export * from '../test/generated-wrappers/curve_bridge';
|
export * from '../test/generated-wrappers/curve_bridge';
|
||||||
|
export * from '../test/generated-wrappers/d_o_d_o_bridge';
|
||||||
export * from '../test/generated-wrappers/dex_forwarder_bridge';
|
export * from '../test/generated-wrappers/dex_forwarder_bridge';
|
||||||
export * from '../test/generated-wrappers/dydx_bridge';
|
export * from '../test/generated-wrappers/dydx_bridge';
|
||||||
export * from '../test/generated-wrappers/erc1155_proxy';
|
export * from '../test/generated-wrappers/erc1155_proxy';
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"generated-artifacts/BancorBridge.json",
|
"generated-artifacts/BancorBridge.json",
|
||||||
"generated-artifacts/ChaiBridge.json",
|
"generated-artifacts/ChaiBridge.json",
|
||||||
"generated-artifacts/CurveBridge.json",
|
"generated-artifacts/CurveBridge.json",
|
||||||
|
"generated-artifacts/DODOBridge.json",
|
||||||
"generated-artifacts/DexForwarderBridge.json",
|
"generated-artifacts/DexForwarderBridge.json",
|
||||||
"generated-artifacts/DydxBridge.json",
|
"generated-artifacts/DydxBridge.json",
|
||||||
"generated-artifacts/ERC1155Proxy.json",
|
"generated-artifacts/ERC1155Proxy.json",
|
||||||
@ -61,6 +62,7 @@
|
|||||||
"test/generated-artifacts/BancorBridge.json",
|
"test/generated-artifacts/BancorBridge.json",
|
||||||
"test/generated-artifacts/ChaiBridge.json",
|
"test/generated-artifacts/ChaiBridge.json",
|
||||||
"test/generated-artifacts/CurveBridge.json",
|
"test/generated-artifacts/CurveBridge.json",
|
||||||
|
"test/generated-artifacts/DODOBridge.json",
|
||||||
"test/generated-artifacts/DexForwarderBridge.json",
|
"test/generated-artifacts/DexForwarderBridge.json",
|
||||||
"test/generated-artifacts/DydxBridge.json",
|
"test/generated-artifacts/DydxBridge.json",
|
||||||
"test/generated-artifacts/ERC1155Proxy.json",
|
"test/generated-artifacts/ERC1155Proxy.json",
|
||||||
|
@ -58,6 +58,10 @@ contract DeploymentConstants {
|
|||||||
address constant private MOONISWAP_REGISTRY = 0x71CD6666064C3A1354a3B4dca5fA1E2D3ee7D303;
|
address constant private MOONISWAP_REGISTRY = 0x71CD6666064C3A1354a3B4dca5fA1E2D3ee7D303;
|
||||||
/// @dev Mainnet address of the Shell contract
|
/// @dev Mainnet address of the Shell contract
|
||||||
address constant private SHELL_CONTRACT = 0x2E703D658f8dd21709a7B458967aB4081F8D3d05;
|
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
|
||||||
|
address constant private DODO_HELPER = 0x533dA777aeDCE766CEAe696bf90f8541A4bA80Eb;
|
||||||
|
|
||||||
// // Ropsten addresses ///////////////////////////////////////////////////////
|
// // Ropsten addresses ///////////////////////////////////////////////////////
|
||||||
// /// @dev Mainnet address of the WETH contract.
|
// /// @dev Mainnet address of the WETH contract.
|
||||||
@ -308,4 +312,24 @@ contract DeploymentConstants {
|
|||||||
{
|
{
|
||||||
return SHELL_CONTRACT;
|
return SHELL_CONTRACT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @dev An overridable way to retrieve the DODO Registry contract address.
|
||||||
|
/// @return registry The DODO Registry contract address.
|
||||||
|
function _getDODORegistryAddress()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (address)
|
||||||
|
{
|
||||||
|
return DODO_REGISTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev An overridable way to retrieve the DODO Helper contract address.
|
||||||
|
/// @return registry The DODO Helper contract address.
|
||||||
|
function _getDODOHelperAddress()
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (address)
|
||||||
|
{
|
||||||
|
return DODO_HELPER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,6 +149,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Remove 0x-API swap/v0-specifc code from asset-swapper",
|
"note": "Remove 0x-API swap/v0-specifc code from asset-swapper",
|
||||||
"pr": 2725
|
"pr": 2725
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Added `DODO`",
|
||||||
|
"pr": 2701
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
187
packages/asset-swapper/contracts/src/DODOSampler.sol
Normal file
187
packages/asset-swapper/contracts/src/DODOSampler.sol
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2019 ZeroEx Intl.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity ^0.5.9;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import "@0x/contracts-utils/contracts/src/DeploymentConstants.sol";
|
||||||
|
import "./ApproximateBuys.sol";
|
||||||
|
import "./SamplerUtils.sol";
|
||||||
|
|
||||||
|
|
||||||
|
interface IDODOZoo {
|
||||||
|
function getDODO(address baseToken, address quoteToken) external view returns (address);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDODOHelper {
|
||||||
|
function querySellQuoteToken(address dodo, uint256 amount) external view returns (uint256);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IDODO {
|
||||||
|
function querySellBaseToken(uint256 amount) external view returns (uint256);
|
||||||
|
}
|
||||||
|
|
||||||
|
contract DODOSampler is
|
||||||
|
DeploymentConstants,
|
||||||
|
SamplerUtils,
|
||||||
|
ApproximateBuys
|
||||||
|
{
|
||||||
|
|
||||||
|
/// @dev Gas limit for DODO calls.
|
||||||
|
uint256 constant private DODO_CALL_GAS = 300e3; // 300k
|
||||||
|
|
||||||
|
/// @dev Sample sell quotes from DODO.
|
||||||
|
/// @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 sampleSellsFromDODO(
|
||||||
|
address takerToken,
|
||||||
|
address makerToken,
|
||||||
|
uint256[] memory takerTokenAmounts
|
||||||
|
)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (bool sellBase, address pool, uint256[] memory makerTokenAmounts)
|
||||||
|
{
|
||||||
|
_assertValidPair(makerToken, takerToken);
|
||||||
|
uint256 numSamples = takerTokenAmounts.length;
|
||||||
|
makerTokenAmounts = new uint256[](numSamples);
|
||||||
|
|
||||||
|
pool = IDODOZoo(_getDODORegistryAddress()).getDODO(takerToken, makerToken);
|
||||||
|
address baseToken;
|
||||||
|
// If pool exists we have the correct order of Base/Quote
|
||||||
|
if (pool != address(0)) {
|
||||||
|
baseToken = takerToken;
|
||||||
|
sellBase = true;
|
||||||
|
} else {
|
||||||
|
pool = IDODOZoo(_getDODORegistryAddress()).getDODO(makerToken, takerToken);
|
||||||
|
// No pool either direction
|
||||||
|
if (address(pool) == address(0)) {
|
||||||
|
return (sellBase, pool, makerTokenAmounts);
|
||||||
|
}
|
||||||
|
baseToken = makerToken;
|
||||||
|
sellBase = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint256 i = 0; i < numSamples; i++) {
|
||||||
|
uint256 buyAmount = _sampleSellForApproximateBuyFromDODO(
|
||||||
|
abi.encode(takerToken, pool, baseToken), // taker token data
|
||||||
|
abi.encode(makerToken, pool, baseToken), // maker token data
|
||||||
|
takerTokenAmounts[i]
|
||||||
|
);
|
||||||
|
// Exit early if the amount is too high for the source to serve
|
||||||
|
if (buyAmount == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
makerTokenAmounts[i] = buyAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Sample buy quotes from DODO.
|
||||||
|
/// @param takerToken Address of the taker token (what to sell).
|
||||||
|
/// @param makerToken Address of the maker token (what to buy).
|
||||||
|
/// @param makerTokenAmounts Maker token sell amount for each sample.
|
||||||
|
/// @return takerTokenAmounts Taker amounts sold at each maker token
|
||||||
|
/// amount.
|
||||||
|
function sampleBuysFromDODO(
|
||||||
|
address takerToken,
|
||||||
|
address makerToken,
|
||||||
|
uint256[] memory makerTokenAmounts
|
||||||
|
)
|
||||||
|
public
|
||||||
|
view
|
||||||
|
returns (bool sellBase, address pool, uint256[] memory takerTokenAmounts)
|
||||||
|
{
|
||||||
|
_assertValidPair(makerToken, takerToken);
|
||||||
|
uint256 numSamples = makerTokenAmounts.length;
|
||||||
|
takerTokenAmounts = new uint256[](numSamples);
|
||||||
|
|
||||||
|
// Pool is BASE/QUOTE
|
||||||
|
// Look up the pool from the taker/maker combination
|
||||||
|
pool = IDODOZoo(_getDODORegistryAddress()).getDODO(takerToken, makerToken);
|
||||||
|
address baseToken;
|
||||||
|
// If pool exists we have the correct order of Base/Quote
|
||||||
|
if (pool != address(0)) {
|
||||||
|
baseToken = takerToken;
|
||||||
|
sellBase = true;
|
||||||
|
} else {
|
||||||
|
// Look up the pool from the maker/taker combination
|
||||||
|
pool = IDODOZoo(_getDODORegistryAddress()).getDODO(makerToken, takerToken);
|
||||||
|
// No pool either direction
|
||||||
|
if (address(pool) == address(0)) {
|
||||||
|
return (sellBase, pool, takerTokenAmounts);
|
||||||
|
}
|
||||||
|
baseToken = makerToken;
|
||||||
|
sellBase = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
takerTokenAmounts = _sampleApproximateBuys(
|
||||||
|
ApproximateBuyQuoteOpts({
|
||||||
|
makerTokenData: abi.encode(makerToken, pool, baseToken),
|
||||||
|
takerTokenData: abi.encode(takerToken, pool, baseToken),
|
||||||
|
getSellQuoteCallback: _sampleSellForApproximateBuyFromDODO
|
||||||
|
}),
|
||||||
|
makerTokenAmounts
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _sampleSellForApproximateBuyFromDODO(
|
||||||
|
bytes memory takerTokenData,
|
||||||
|
bytes memory /* makerTokenData */,
|
||||||
|
uint256 sellAmount
|
||||||
|
)
|
||||||
|
private
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
(address takerToken, address pool, address baseToken) = abi.decode(
|
||||||
|
takerTokenData,
|
||||||
|
(address, address, address)
|
||||||
|
);
|
||||||
|
|
||||||
|
bool didSucceed;
|
||||||
|
bytes memory resultData;
|
||||||
|
// We will get called to sell both the taker token and also to sell the maker token
|
||||||
|
if (takerToken == baseToken) {
|
||||||
|
// If base token then use the original query on the pool
|
||||||
|
(didSucceed, resultData) =
|
||||||
|
pool.staticcall.gas(DODO_CALL_GAS)(
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
IDODO(0).querySellBaseToken.selector,
|
||||||
|
sellAmount
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// If quote token then use helper, this is less accurate
|
||||||
|
(didSucceed, resultData) =
|
||||||
|
_getDODOHelperAddress().staticcall.gas(DODO_CALL_GAS)(
|
||||||
|
abi.encodeWithSelector(
|
||||||
|
IDODOHelper(0).querySellQuoteToken.selector,
|
||||||
|
pool,
|
||||||
|
sellAmount
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if (!didSucceed) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// solhint-disable-next-line indent
|
||||||
|
return abi.decode(resultData, (uint256));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -21,6 +21,7 @@ pragma experimental ABIEncoderV2;
|
|||||||
|
|
||||||
import "./BalancerSampler.sol";
|
import "./BalancerSampler.sol";
|
||||||
import "./CurveSampler.sol";
|
import "./CurveSampler.sol";
|
||||||
|
import "./DODOSampler.sol";
|
||||||
import "./Eth2DaiSampler.sol";
|
import "./Eth2DaiSampler.sol";
|
||||||
import "./KyberSampler.sol";
|
import "./KyberSampler.sol";
|
||||||
import "./LiquidityProviderSampler.sol";
|
import "./LiquidityProviderSampler.sol";
|
||||||
@ -38,6 +39,7 @@ import "./UniswapV2Sampler.sol";
|
|||||||
contract ERC20BridgeSampler is
|
contract ERC20BridgeSampler is
|
||||||
BalancerSampler,
|
BalancerSampler,
|
||||||
CurveSampler,
|
CurveSampler,
|
||||||
|
DODOSampler,
|
||||||
Eth2DaiSampler,
|
Eth2DaiSampler,
|
||||||
KyberSampler,
|
KyberSampler,
|
||||||
LiquidityProviderSampler,
|
LiquidityProviderSampler,
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"publicInterfaceContracts": "ERC20BridgeSampler,ILiquidityProvider,ILiquidityProviderRegistry,DummyLiquidityProviderRegistry,DummyLiquidityProvider",
|
"publicInterfaceContracts": "ERC20BridgeSampler,ILiquidityProvider,ILiquidityProviderRegistry,DummyLiquidityProviderRegistry,DummyLiquidityProvider",
|
||||||
"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|BalancerSampler|CurveSampler|DummyLiquidityProvider|DummyLiquidityProviderRegistry|ERC20BridgeSampler|Eth2DaiSampler|IBalancer|ICurve|IEth2Dai|IKyberNetwork|ILiquidityProvider|ILiquidityProviderRegistry|IMStable|IMooniswap|IMultiBridge|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SushiSwapSampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler).json",
|
"abis": "./test/generated-artifacts/@(ApproximateBuys|BalancerSampler|CurveSampler|DODOSampler|DummyLiquidityProvider|DummyLiquidityProviderRegistry|ERC20BridgeSampler|Eth2DaiSampler|IBalancer|ICurve|IEth2Dai|IKyberNetwork|ILiquidityProvider|ILiquidityProviderRegistry|IMStable|IMooniswap|IMultiBridge|IShell|IUniswapExchangeQuotes|IUniswapV2Router01|KyberSampler|LiquidityProviderSampler|MStableSampler|MooniswapSampler|MultiBridgeSampler|NativeOrderSampler|SamplerUtils|ShellSampler|SushiSwapSampler|TestERC20BridgeSampler|TestNativeOrderSampler|TwoHopSampler|UniswapSampler|UniswapV2Sampler).json",
|
||||||
"postpublish": {
|
"postpublish": {
|
||||||
"assets": []
|
"assets": []
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@ export {
|
|||||||
CurveFunctionSelectors,
|
CurveFunctionSelectors,
|
||||||
CurveInfo,
|
CurveInfo,
|
||||||
DexSample,
|
DexSample,
|
||||||
|
DODOFillData,
|
||||||
ERC20BridgeSource,
|
ERC20BridgeSource,
|
||||||
ExchangeProxyOverhead,
|
ExchangeProxyOverhead,
|
||||||
FeeSchedule,
|
FeeSchedule,
|
||||||
|
@ -24,6 +24,7 @@ export const SELL_SOURCE_FILTER = new SourceFilters([
|
|||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
ERC20BridgeSource.Shell,
|
ERC20BridgeSource.Shell,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
|
ERC20BridgeSource.Dodo,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,6 +46,7 @@ export const BUY_SOURCE_FILTER = new SourceFilters(
|
|||||||
ERC20BridgeSource.Swerve,
|
ERC20BridgeSource.Swerve,
|
||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
|
ERC20BridgeSource.Dodo,
|
||||||
],
|
],
|
||||||
[ERC20BridgeSource.MultiBridge],
|
[ERC20BridgeSource.MultiBridge],
|
||||||
);
|
);
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
CollapsedFill,
|
CollapsedFill,
|
||||||
CurveFillData,
|
CurveFillData,
|
||||||
DexSample,
|
DexSample,
|
||||||
|
DODOFillData,
|
||||||
ERC20BridgeSource,
|
ERC20BridgeSource,
|
||||||
KyberFillData,
|
KyberFillData,
|
||||||
LiquidityProviderFillData,
|
LiquidityProviderFillData,
|
||||||
@ -186,6 +187,8 @@ function getBridgeAddressFromFill(fill: CollapsedFill, opts: CreateOrderFromPath
|
|||||||
return opts.contractAddresses.mooniswapBridge;
|
return opts.contractAddresses.mooniswapBridge;
|
||||||
case ERC20BridgeSource.Shell:
|
case ERC20BridgeSource.Shell:
|
||||||
return opts.contractAddresses.shellBridge;
|
return opts.contractAddresses.shellBridge;
|
||||||
|
case ERC20BridgeSource.Dodo:
|
||||||
|
return opts.contractAddresses.dodoBridge;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -285,6 +288,14 @@ export function createBridgeOrder(
|
|||||||
createMooniswapBridgeData(takerToken, mooniswapFillData.poolAddress),
|
createMooniswapBridgeData(takerToken, mooniswapFillData.poolAddress),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case ERC20BridgeSource.Dodo:
|
||||||
|
const dodoFillData = (fill as CollapsedFill<DODOFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
|
||||||
|
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||||
|
makerToken,
|
||||||
|
bridgeAddress,
|
||||||
|
createDODOBridgeData(takerToken, dodoFillData.poolAddress, dodoFillData.isSellBase),
|
||||||
|
);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||||
makerToken,
|
makerToken,
|
||||||
@ -355,6 +366,15 @@ function createMooniswapBridgeData(takerToken: string, poolAddress: string): str
|
|||||||
return encoder.encode({ takerToken, poolAddress });
|
return encoder.encode({ takerToken, poolAddress });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createDODOBridgeData(takerToken: string, poolAddress: string, isSellBase: boolean): string {
|
||||||
|
const encoder = AbiEncoder.create([
|
||||||
|
{ name: 'takerToken', type: 'address' },
|
||||||
|
{ name: 'poolAddress', type: 'address' },
|
||||||
|
{ name: 'isSellBase', type: 'bool' },
|
||||||
|
]);
|
||||||
|
return encoder.encode({ takerToken, poolAddress, isSellBase });
|
||||||
|
}
|
||||||
|
|
||||||
function createCurveBridgeData(
|
function createCurveBridgeData(
|
||||||
curveAddress: string,
|
curveAddress: string,
|
||||||
exchangeFunctionSelector: string,
|
exchangeFunctionSelector: string,
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
CurveFillData,
|
CurveFillData,
|
||||||
CurveInfo,
|
CurveInfo,
|
||||||
DexSample,
|
DexSample,
|
||||||
|
DODOFillData,
|
||||||
ERC20BridgeSource,
|
ERC20BridgeSource,
|
||||||
HopInfo,
|
HopInfo,
|
||||||
KyberFillData,
|
KyberFillData,
|
||||||
@ -520,7 +521,7 @@ export class SamplerOperations {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
takerFillAmounts: BigNumber[],
|
takerFillAmounts: BigNumber[],
|
||||||
): SourceQuoteOperation {
|
): SourceQuoteOperation<MooniswapFillData> {
|
||||||
return new SamplerContractOperation({
|
return new SamplerContractOperation({
|
||||||
source: ERC20BridgeSource.Mooniswap,
|
source: ERC20BridgeSource.Mooniswap,
|
||||||
contract: this._samplerContract,
|
contract: this._samplerContract,
|
||||||
@ -541,7 +542,7 @@ export class SamplerOperations {
|
|||||||
makerToken: string,
|
makerToken: string,
|
||||||
takerToken: string,
|
takerToken: string,
|
||||||
makerFillAmounts: BigNumber[],
|
makerFillAmounts: BigNumber[],
|
||||||
): SourceQuoteOperation {
|
): SourceQuoteOperation<MooniswapFillData> {
|
||||||
return new SamplerContractOperation({
|
return new SamplerContractOperation({
|
||||||
source: ERC20BridgeSource.Mooniswap,
|
source: ERC20BridgeSource.Mooniswap,
|
||||||
contract: this._samplerContract,
|
contract: this._samplerContract,
|
||||||
@ -760,6 +761,48 @@ export class SamplerOperations {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getDODOSellQuotes(
|
||||||
|
makerToken: string,
|
||||||
|
takerToken: string,
|
||||||
|
takerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<DODOFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Dodo,
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleSellsFromDODO,
|
||||||
|
params: [takerToken, makerToken, takerFillAmounts],
|
||||||
|
callback: (callResults: string, fillData: DODOFillData): BigNumber[] => {
|
||||||
|
const [isSellBase, pool, samples] = this._samplerContract.getABIDecodedReturnData<
|
||||||
|
[boolean, string, BigNumber[]]
|
||||||
|
>('sampleSellsFromDODO', callResults);
|
||||||
|
fillData.isSellBase = isSellBase;
|
||||||
|
fillData.poolAddress = pool;
|
||||||
|
return samples;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDODOBuyQuotes(
|
||||||
|
makerToken: string,
|
||||||
|
takerToken: string,
|
||||||
|
makerFillAmounts: BigNumber[],
|
||||||
|
): SourceQuoteOperation<DODOFillData> {
|
||||||
|
return new SamplerContractOperation({
|
||||||
|
source: ERC20BridgeSource.Dodo,
|
||||||
|
contract: this._samplerContract,
|
||||||
|
function: this._samplerContract.sampleBuysFromDODO,
|
||||||
|
params: [takerToken, makerToken, makerFillAmounts],
|
||||||
|
callback: (callResults: string, fillData: DODOFillData): BigNumber[] => {
|
||||||
|
const [isSellBase, pool, samples] = this._samplerContract.getABIDecodedReturnData<
|
||||||
|
[boolean, string, BigNumber[]]
|
||||||
|
>('sampleBuysFromDODO', callResults);
|
||||||
|
fillData.isSellBase = isSellBase;
|
||||||
|
fillData.poolAddress = pool;
|
||||||
|
return samples;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public getMedianSellRate(
|
public getMedianSellRate(
|
||||||
sources: ERC20BridgeSource[],
|
sources: ERC20BridgeSource[],
|
||||||
makerToken: string,
|
makerToken: string,
|
||||||
@ -999,6 +1042,8 @@ export class SamplerOperations {
|
|||||||
);
|
);
|
||||||
case ERC20BridgeSource.Shell:
|
case ERC20BridgeSource.Shell:
|
||||||
return this.getShellSellQuotes(makerToken, takerToken, takerFillAmounts);
|
return this.getShellSellQuotes(makerToken, takerToken, takerFillAmounts);
|
||||||
|
case ERC20BridgeSource.Dodo:
|
||||||
|
return this.getDODOSellQuotes(makerToken, takerToken, takerFillAmounts);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported sell sample source: ${source}`);
|
throw new Error(`Unsupported sell sample source: ${source}`);
|
||||||
}
|
}
|
||||||
@ -1088,6 +1133,8 @@ export class SamplerOperations {
|
|||||||
);
|
);
|
||||||
case ERC20BridgeSource.Shell:
|
case ERC20BridgeSource.Shell:
|
||||||
return this.getShellBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
return this.getShellBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
||||||
|
case ERC20BridgeSource.Dodo:
|
||||||
|
return this.getDODOBuyQuotes(makerToken, takerToken, makerFillAmounts);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unsupported buy sample source: ${source}`);
|
throw new Error(`Unsupported buy sample source: ${source}`);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ export enum ERC20BridgeSource {
|
|||||||
Shell = 'Shell',
|
Shell = 'Shell',
|
||||||
Swerve = 'Swerve',
|
Swerve = 'Swerve',
|
||||||
SushiSwap = 'SushiSwap',
|
SushiSwap = 'SushiSwap',
|
||||||
|
Dodo = 'DODO',
|
||||||
}
|
}
|
||||||
|
|
||||||
// tslint:disable: enum-naming
|
// tslint:disable: enum-naming
|
||||||
@ -133,6 +134,11 @@ export interface MooniswapFillData extends FillData {
|
|||||||
poolAddress: string;
|
poolAddress: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DODOFillData extends FillData {
|
||||||
|
poolAddress: string;
|
||||||
|
isSellBase: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Quote<TFillData = FillData> {
|
export interface Quote<TFillData = FillData> {
|
||||||
amount: BigNumber;
|
amount: BigNumber;
|
||||||
fillData?: TFillData;
|
fillData?: TFillData;
|
||||||
|
@ -8,6 +8,7 @@ import { ContractArtifact } from 'ethereum-types';
|
|||||||
import * as ApproximateBuys from '../test/generated-artifacts/ApproximateBuys.json';
|
import * as ApproximateBuys from '../test/generated-artifacts/ApproximateBuys.json';
|
||||||
import * as BalancerSampler from '../test/generated-artifacts/BalancerSampler.json';
|
import * as BalancerSampler from '../test/generated-artifacts/BalancerSampler.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 DummyLiquidityProvider from '../test/generated-artifacts/DummyLiquidityProvider.json';
|
import * as DummyLiquidityProvider from '../test/generated-artifacts/DummyLiquidityProvider.json';
|
||||||
import * as DummyLiquidityProviderRegistry from '../test/generated-artifacts/DummyLiquidityProviderRegistry.json';
|
import * as DummyLiquidityProviderRegistry from '../test/generated-artifacts/DummyLiquidityProviderRegistry.json';
|
||||||
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
|
import * as ERC20BridgeSampler from '../test/generated-artifacts/ERC20BridgeSampler.json';
|
||||||
@ -42,6 +43,7 @@ export const artifacts = {
|
|||||||
ApproximateBuys: ApproximateBuys as ContractArtifact,
|
ApproximateBuys: ApproximateBuys as ContractArtifact,
|
||||||
BalancerSampler: BalancerSampler as ContractArtifact,
|
BalancerSampler: BalancerSampler as ContractArtifact,
|
||||||
CurveSampler: CurveSampler as ContractArtifact,
|
CurveSampler: CurveSampler as ContractArtifact,
|
||||||
|
DODOSampler: DODOSampler as ContractArtifact,
|
||||||
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
|
ERC20BridgeSampler: ERC20BridgeSampler as ContractArtifact,
|
||||||
Eth2DaiSampler: Eth2DaiSampler as ContractArtifact,
|
Eth2DaiSampler: Eth2DaiSampler as ContractArtifact,
|
||||||
IMooniswap: IMooniswap as ContractArtifact,
|
IMooniswap: IMooniswap as ContractArtifact,
|
||||||
|
@ -28,13 +28,7 @@ import {
|
|||||||
import { createFills } from '../src/utils/market_operation_utils/fills';
|
import { createFills } from '../src/utils/market_operation_utils/fills';
|
||||||
import { DexOrderSampler } from '../src/utils/market_operation_utils/sampler';
|
import { DexOrderSampler } from '../src/utils/market_operation_utils/sampler';
|
||||||
import { BATCH_SOURCE_FILTERS } from '../src/utils/market_operation_utils/sampler_operations';
|
import { BATCH_SOURCE_FILTERS } from '../src/utils/market_operation_utils/sampler_operations';
|
||||||
import {
|
import { DexSample, ERC20BridgeSource, FillData, NativeFillData } from '../src/utils/market_operation_utils/types';
|
||||||
DexSample,
|
|
||||||
ERC20BridgeSource,
|
|
||||||
FillData,
|
|
||||||
NativeFillData,
|
|
||||||
OptimizedMarketOrder,
|
|
||||||
} from '../src/utils/market_operation_utils/types';
|
|
||||||
|
|
||||||
const MAKER_TOKEN = randomAddress();
|
const MAKER_TOKEN = randomAddress();
|
||||||
const TAKER_TOKEN = randomAddress();
|
const TAKER_TOKEN = randomAddress();
|
||||||
@ -51,6 +45,7 @@ const DEFAULT_EXCLUDED = [
|
|||||||
ERC20BridgeSource.SushiSwap,
|
ERC20BridgeSource.SushiSwap,
|
||||||
ERC20BridgeSource.MultiHop,
|
ERC20BridgeSource.MultiHop,
|
||||||
ERC20BridgeSource.Shell,
|
ERC20BridgeSource.Shell,
|
||||||
|
ERC20BridgeSource.Dodo,
|
||||||
];
|
];
|
||||||
const BUY_SOURCES = BUY_SOURCE_FILTER.sources;
|
const BUY_SOURCES = BUY_SOURCE_FILTER.sources;
|
||||||
const SELL_SOURCES = SELL_SOURCE_FILTER.sources;
|
const SELL_SOURCES = SELL_SOURCE_FILTER.sources;
|
||||||
@ -111,6 +106,8 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
return ERC20BridgeSource.SushiSwap;
|
return ERC20BridgeSource.SushiSwap;
|
||||||
case contractAddresses.shellBridge.toLowerCase():
|
case contractAddresses.shellBridge.toLowerCase():
|
||||||
return ERC20BridgeSource.Shell;
|
return ERC20BridgeSource.Shell;
|
||||||
|
case contractAddresses.dodoBridge.toLowerCase():
|
||||||
|
return ERC20BridgeSource.Dodo;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -288,6 +285,7 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
[ERC20BridgeSource.SushiSwap]: _.times(NUM_SAMPLES, () => 0),
|
[ERC20BridgeSource.SushiSwap]: _.times(NUM_SAMPLES, () => 0),
|
||||||
[ERC20BridgeSource.MultiHop]: _.times(NUM_SAMPLES, () => 0),
|
[ERC20BridgeSource.MultiHop]: _.times(NUM_SAMPLES, () => 0),
|
||||||
[ERC20BridgeSource.Shell]: _.times(NUM_SAMPLES, () => 0),
|
[ERC20BridgeSource.Shell]: _.times(NUM_SAMPLES, () => 0),
|
||||||
|
[ERC20BridgeSource.Dodo]: _.times(NUM_SAMPLES, () => 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_RATES: RatesBySource = {
|
const DEFAULT_RATES: RatesBySource = {
|
||||||
@ -334,6 +332,7 @@ describe('MarketOperationUtils tests', () => {
|
|||||||
[ERC20BridgeSource.Native]: { order: createOrder() },
|
[ERC20BridgeSource.Native]: { order: createOrder() },
|
||||||
[ERC20BridgeSource.MultiHop]: {},
|
[ERC20BridgeSource.MultiHop]: {},
|
||||||
[ERC20BridgeSource.Shell]: {},
|
[ERC20BridgeSource.Shell]: {},
|
||||||
|
[ERC20BridgeSource.Dodo]: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_OPS = {
|
const DEFAULT_OPS = {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
export * from '../test/generated-wrappers/approximate_buys';
|
export * from '../test/generated-wrappers/approximate_buys';
|
||||||
export * from '../test/generated-wrappers/balancer_sampler';
|
export * from '../test/generated-wrappers/balancer_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/dummy_liquidity_provider';
|
export * from '../test/generated-wrappers/dummy_liquidity_provider';
|
||||||
export * from '../test/generated-wrappers/dummy_liquidity_provider_registry';
|
export * from '../test/generated-wrappers/dummy_liquidity_provider_registry';
|
||||||
export * from '../test/generated-wrappers/erc20_bridge_sampler';
|
export * from '../test/generated-wrappers/erc20_bridge_sampler';
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
"test/generated-artifacts/ApproximateBuys.json",
|
"test/generated-artifacts/ApproximateBuys.json",
|
||||||
"test/generated-artifacts/BalancerSampler.json",
|
"test/generated-artifacts/BalancerSampler.json",
|
||||||
"test/generated-artifacts/CurveSampler.json",
|
"test/generated-artifacts/CurveSampler.json",
|
||||||
|
"test/generated-artifacts/DODOSampler.json",
|
||||||
"test/generated-artifacts/DummyLiquidityProvider.json",
|
"test/generated-artifacts/DummyLiquidityProvider.json",
|
||||||
"test/generated-artifacts/DummyLiquidityProviderRegistry.json",
|
"test/generated-artifacts/DummyLiquidityProviderRegistry.json",
|
||||||
"test/generated-artifacts/ERC20BridgeSampler.json",
|
"test/generated-artifacts/ERC20BridgeSampler.json",
|
||||||
|
@ -53,6 +53,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Deploy `ShellBridge` on Mainnet",
|
"note": "Deploy `ShellBridge` on Mainnet",
|
||||||
"pr": 2722
|
"pr": 2722
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"note": "Deploy `DodoBridge` on Mainnet",
|
||||||
|
"pr": 2701
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
"mooniswapBridge": "0x02b7eca484ad960fca3f7709e0b2ac81eec3069c",
|
"mooniswapBridge": "0x02b7eca484ad960fca3f7709e0b2ac81eec3069c",
|
||||||
"sushiswapBridge": "0x47ed0262a0b688dcb836d254c6a2e96b6c48a9f5",
|
"sushiswapBridge": "0x47ed0262a0b688dcb836d254c6a2e96b6c48a9f5",
|
||||||
"shellBridge": "0x21fb3862eed7911e0f8219a077247b849846728d",
|
"shellBridge": "0x21fb3862eed7911e0f8219a077247b849846728d",
|
||||||
|
"dodoBridge": "0xe9da66965a9344aab2167e6813c03f043cc7a6ca",
|
||||||
"transformers": {
|
"transformers": {
|
||||||
"wethTransformer": "0x68c0bb685099dc7cb5c5ce2b26185945b357383e",
|
"wethTransformer": "0x68c0bb685099dc7cb5c5ce2b26185945b357383e",
|
||||||
"payTakerTransformer": "0x49b9df2c58491764cf40cb052dd4243df63622c7",
|
"payTakerTransformer": "0x49b9df2c58491764cf40cb052dd4243df63622c7",
|
||||||
@ -96,6 +97,7 @@
|
|||||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||||
|
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"transformers": {
|
"transformers": {
|
||||||
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
||||||
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
||||||
@ -148,6 +150,7 @@
|
|||||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||||
|
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"transformers": {
|
"transformers": {
|
||||||
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
"wethTransformer": "0x8d822fe2b42f60531203e288f5f357fa79474437",
|
||||||
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
"payTakerTransformer": "0x150652244723102faeaefa4c79597d097ffa26c6",
|
||||||
@ -200,6 +203,7 @@
|
|||||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||||
|
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"transformers": {
|
"transformers": {
|
||||||
"wethTransformer": "0x9ce35b5ee9e710535e3988e3f8731d9ca9dba17d",
|
"wethTransformer": "0x9ce35b5ee9e710535e3988e3f8731d9ca9dba17d",
|
||||||
"payTakerTransformer": "0x5a53e7b02a83aa9f60ccf4e424f0442c255bc977",
|
"payTakerTransformer": "0x5a53e7b02a83aa9f60ccf4e424f0442c255bc977",
|
||||||
@ -252,6 +256,7 @@
|
|||||||
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
"mooniswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
"sushiswapBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"shellBridge": "0x0000000000000000000000000000000000000000",
|
"shellBridge": "0x0000000000000000000000000000000000000000",
|
||||||
|
"dodoBridge": "0x0000000000000000000000000000000000000000",
|
||||||
"transformers": {
|
"transformers": {
|
||||||
"wethTransformer": "0xc6b0d3c45a6b5092808196cb00df5c357d55e1d5",
|
"wethTransformer": "0xc6b0d3c45a6b5092808196cb00df5c357d55e1d5",
|
||||||
"payTakerTransformer": "0x7209185959d7227fb77274e1e88151d7c4c368d3",
|
"payTakerTransformer": "0x7209185959d7227fb77274e1e88151d7c4c368d3",
|
||||||
|
@ -45,6 +45,7 @@ export interface ContractAddresses {
|
|||||||
mooniswapBridge: string;
|
mooniswapBridge: string;
|
||||||
sushiswapBridge: string;
|
sushiswapBridge: string;
|
||||||
shellBridge: string;
|
shellBridge: string;
|
||||||
|
dodoBridge: string;
|
||||||
transformers: {
|
transformers: {
|
||||||
wethTransformer: string;
|
wethTransformer: string;
|
||||||
payTakerTransformer: string;
|
payTakerTransformer: string;
|
||||||
|
@ -404,6 +404,7 @@ export async function runMigrationsAsync(
|
|||||||
mooniswapBridge: NULL_ADDRESS,
|
mooniswapBridge: NULL_ADDRESS,
|
||||||
sushiswapBridge: NULL_ADDRESS,
|
sushiswapBridge: NULL_ADDRESS,
|
||||||
shellBridge: NULL_ADDRESS,
|
shellBridge: NULL_ADDRESS,
|
||||||
|
dodoBridge: NULL_ADDRESS,
|
||||||
exchangeProxy: exchangeProxy.address,
|
exchangeProxy: exchangeProxy.address,
|
||||||
exchangeProxyAllowanceTarget: exchangeProxyAllowanceTargetAddress,
|
exchangeProxyAllowanceTarget: exchangeProxyAllowanceTargetAddress,
|
||||||
exchangeProxyTransformerDeployer: txDefaults.from,
|
exchangeProxyTransformerDeployer: txDefaults.from,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user