@0x/asset-swapper: Return Mooniswap pool in sampler and encode it in bridge data
				
					
				
			This commit is contained in:
		@@ -97,6 +97,10 @@
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                "note": "Set `rfqtTakerAddress` to null in EP consumer",
 | 
					                "note": "Set `rfqtTakerAddress` to null in EP consumer",
 | 
				
			||||||
                "pr": 2692
 | 
					                "pr": 2692
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Return Mooniswap pool in sampler and encode it in bridge data",
 | 
				
			||||||
 | 
					                "pr": 2692
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,44 +46,31 @@ contract MooniswapSampler is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        view
 | 
					        view
 | 
				
			||||||
        returns (uint256[] memory makerTokenAmounts)
 | 
					        returns (IMooniswap pool, uint256[] memory makerTokenAmounts)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        _assertValidPair(makerToken, takerToken);
 | 
					        _assertValidPair(makerToken, takerToken);
 | 
				
			||||||
        uint256 numSamples = takerTokenAmounts.length;
 | 
					        uint256 numSamples = takerTokenAmounts.length;
 | 
				
			||||||
        makerTokenAmounts = new uint256[](numSamples);
 | 
					        makerTokenAmounts = new uint256[](numSamples);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        address _takerToken = takerToken == _getWethAddress() ? address(0) : takerToken;
 | 
					        address mooniswapTakerToken = takerToken == _getWethAddress() ? address(0) : takerToken;
 | 
				
			||||||
        address _makerToken = makerToken == _getWethAddress() ? address(0) : makerToken;
 | 
					        address mooniswapMakerToken = makerToken == _getWethAddress() ? address(0) : makerToken;
 | 
				
			||||||
        // Find the pool for the pair, ETH is represented
 | 
					        // Find the pool for the pair, ETH is represented
 | 
				
			||||||
        // as address(0)
 | 
					        // as address(0)
 | 
				
			||||||
        IMooniswap pool = IMooniswap(
 | 
					        pool = IMooniswap(
 | 
				
			||||||
            IMooniswapRegistry(_getMooniswapAddress()).pools(_takerToken, _makerToken)
 | 
					            IMooniswapRegistry(_getMooniswapAddress()).pools(mooniswapTakerToken, mooniswapMakerToken)
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        // If there is no pool then return early
 | 
					        // If there is no pool then return early
 | 
				
			||||||
        if (address(pool) == address(0)) {
 | 
					        if (address(pool) == address(0)) {
 | 
				
			||||||
            return makerTokenAmounts;
 | 
					            return (pool, makerTokenAmounts);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        uint256 poolBalance = _takerToken == address(0) ? address(pool).balance : IERC20Token(_takerToken).balanceOf(address(pool));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (uint256 i = 0; i < numSamples; i++) {
 | 
					        for (uint256 i = 0; i < numSamples; i++) {
 | 
				
			||||||
            // If the pool balance is smaller than the sell amount
 | 
					            uint256 buyAmount = sampleSingleSellFromMooniswapPool(
 | 
				
			||||||
            // don't sample to avoid multiplication overflow in buys
 | 
					                pool,
 | 
				
			||||||
            if (poolBalance < takerTokenAmounts[i]) {
 | 
					                mooniswapTakerToken,
 | 
				
			||||||
                break;
 | 
					                mooniswapMakerToken,
 | 
				
			||||||
            }
 | 
					                takerTokenAmounts[i]
 | 
				
			||||||
            (bool didSucceed, bytes memory resultData) =
 | 
					            );
 | 
				
			||||||
                address(pool).staticcall.gas(MOONISWAP_CALL_GAS)(
 | 
					 | 
				
			||||||
                    abi.encodeWithSelector(
 | 
					 | 
				
			||||||
                        IMooniswap(0).getReturn.selector,
 | 
					 | 
				
			||||||
                        _takerToken,
 | 
					 | 
				
			||||||
                        _makerToken,
 | 
					 | 
				
			||||||
                        takerTokenAmounts[i]
 | 
					 | 
				
			||||||
                    ));
 | 
					 | 
				
			||||||
            uint256 buyAmount = 0;
 | 
					 | 
				
			||||||
            if (didSucceed) {
 | 
					 | 
				
			||||||
                buyAmount = abi.decode(resultData, (uint256));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            // Exit early if the amount is too high for the source to serve
 | 
					            // Exit early if the amount is too high for the source to serve
 | 
				
			||||||
            if (buyAmount == 0) {
 | 
					            if (buyAmount == 0) {
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
@@ -92,6 +79,38 @@ contract MooniswapSampler is
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function sampleSingleSellFromMooniswapPool(
 | 
				
			||||||
 | 
					        IMooniswap pool,
 | 
				
			||||||
 | 
					        address mooniswapTakerToken,
 | 
				
			||||||
 | 
					        address mooniswapMakerToken,
 | 
				
			||||||
 | 
					        uint256 takerTokenAmount
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        public
 | 
				
			||||||
 | 
					        view
 | 
				
			||||||
 | 
					        returns (uint256 makerTokenAmount)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint256 poolBalance = mooniswapTakerToken == address(0)
 | 
				
			||||||
 | 
					            ? address(pool).balance
 | 
				
			||||||
 | 
					            : IERC20Token(mooniswapTakerToken).balanceOf(address(pool));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If the pool balance is smaller than the sell amount
 | 
				
			||||||
 | 
					        // don't sample to avoid multiplication overflow in buys
 | 
				
			||||||
 | 
					        if (poolBalance < takerTokenAmount) {
 | 
				
			||||||
 | 
					            return makerTokenAmount;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        (bool didSucceed, bytes memory resultData) =
 | 
				
			||||||
 | 
					            address(pool).staticcall.gas(MOONISWAP_CALL_GAS)(
 | 
				
			||||||
 | 
					                abi.encodeWithSelector(
 | 
				
			||||||
 | 
					                    IMooniswap(0).getReturn.selector,
 | 
				
			||||||
 | 
					                    mooniswapTakerToken,
 | 
				
			||||||
 | 
					                    mooniswapMakerToken,
 | 
				
			||||||
 | 
					                    takerTokenAmount
 | 
				
			||||||
 | 
					                ));
 | 
				
			||||||
 | 
					        if (didSucceed) {
 | 
				
			||||||
 | 
					            makerTokenAmount = abi.decode(resultData, (uint256));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Sample buy quotes from Mooniswap.
 | 
					    /// @dev Sample buy quotes from Mooniswap.
 | 
				
			||||||
    /// @param takerToken Address of the taker token (what to sell).
 | 
					    /// @param takerToken Address of the taker token (what to sell).
 | 
				
			||||||
    /// @param makerToken Address of the maker token (what to buy).
 | 
					    /// @param makerToken Address of the maker token (what to buy).
 | 
				
			||||||
@@ -105,12 +124,28 @@ contract MooniswapSampler is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        view
 | 
					        view
 | 
				
			||||||
        returns (uint256[] memory takerTokenAmounts)
 | 
					        returns (IMooniswap pool, uint256[] memory takerTokenAmounts)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return _sampleApproximateBuys(
 | 
					        _assertValidPair(makerToken, takerToken);
 | 
				
			||||||
 | 
					        uint256 numSamples = takerTokenAmounts.length;
 | 
				
			||||||
 | 
					        makerTokenAmounts = new uint256[](numSamples);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        address mooniswapTakerToken = takerToken == _getWethAddress() ? address(0) : takerToken;
 | 
				
			||||||
 | 
					        address mooniswapMakerToken = makerToken == _getWethAddress() ? address(0) : makerToken;
 | 
				
			||||||
 | 
					        // Find the pool for the pair, ETH is represented
 | 
				
			||||||
 | 
					        // as address(0)
 | 
				
			||||||
 | 
					        pool = IMooniswap(
 | 
				
			||||||
 | 
					            IMooniswapRegistry(_getMooniswapAddress()).pools(mooniswapTakerToken, mooniswapMakerToken)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        // If there is no pool then return early
 | 
				
			||||||
 | 
					        if (address(pool) == address(0)) {
 | 
				
			||||||
 | 
					            return (pool, takerTokenAmounts);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        takerTokenAmounts = _sampleApproximateBuys(
 | 
				
			||||||
            ApproximateBuyQuoteOpts({
 | 
					            ApproximateBuyQuoteOpts({
 | 
				
			||||||
                makerTokenData: abi.encode(makerToken),
 | 
					                makerTokenData: abi.encode(mooniswapMakerToken, pool),
 | 
				
			||||||
                takerTokenData: abi.encode(takerToken),
 | 
					                takerTokenData: abi.encode(mooniswapTakerToken, pool),
 | 
				
			||||||
                getSellQuoteCallback: _sampleSellForApproximateBuyFromMooniswap
 | 
					                getSellQuoteCallback: _sampleSellForApproximateBuyFromMooniswap
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            makerTokenAmounts
 | 
					            makerTokenAmounts
 | 
				
			||||||
@@ -126,15 +161,16 @@ contract MooniswapSampler is
 | 
				
			|||||||
        view
 | 
					        view
 | 
				
			||||||
        returns (uint256 buyAmount)
 | 
					        returns (uint256 buyAmount)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        (address takerToken) =
 | 
					        (address mooniswapTakerToken, IMooniswap pool) =
 | 
				
			||||||
            abi.decode(takerTokenData, (address));
 | 
					            abi.decode(takerTokenData, (address, IMooniswap));
 | 
				
			||||||
        (address makerToken) =
 | 
					        (address mooniswapMakerToken) =
 | 
				
			||||||
            abi.decode(makerTokenData, (address));
 | 
					            abi.decode(makerTokenData, (address));
 | 
				
			||||||
        (bool success, bytes memory resultData) =
 | 
					        (bool success, bytes memory resultData) =
 | 
				
			||||||
            address(this).staticcall(abi.encodeWithSelector(
 | 
					            address(this).staticcall(abi.encodeWithSelector(
 | 
				
			||||||
                this.sampleSellsFromMooniswap.selector,
 | 
					                this.sampleSingleSellFromMooniswapPool.selector,
 | 
				
			||||||
                takerToken,
 | 
					                pool,
 | 
				
			||||||
                makerToken,
 | 
					                mooniswapTakerToken,
 | 
				
			||||||
 | 
					                mooniswapMakerToken,
 | 
				
			||||||
                _toSingleValueArray(sellAmount)
 | 
					                _toSingleValueArray(sellAmount)
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        if (!success) {
 | 
					        if (!success) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,7 @@ import {
 | 
				
			|||||||
    Fill,
 | 
					    Fill,
 | 
				
			||||||
    KyberFillData,
 | 
					    KyberFillData,
 | 
				
			||||||
    LiquidityProviderFillData,
 | 
					    LiquidityProviderFillData,
 | 
				
			||||||
 | 
					    MooniswapFillData,
 | 
				
			||||||
    MultiBridgeFillData,
 | 
					    MultiBridgeFillData,
 | 
				
			||||||
    MultiHopFillData,
 | 
					    MultiHopFillData,
 | 
				
			||||||
    NativeCollapsedFill,
 | 
					    NativeCollapsedFill,
 | 
				
			||||||
@@ -304,6 +305,14 @@ function createBridgeOrder(
 | 
				
			|||||||
                createKyberBridgeData(takerToken, kyberFillData.hint),
 | 
					                createKyberBridgeData(takerToken, kyberFillData.hint),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case ERC20BridgeSource.Mooniswap:
 | 
				
			||||||
 | 
					            const mooniswapFillData = (fill as CollapsedFill<MooniswapFillData>).fillData!; // tslint:disable-line:no-non-null-assertion
 | 
				
			||||||
 | 
					            makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
 | 
				
			||||||
 | 
					                makerToken,
 | 
				
			||||||
 | 
					                bridgeAddress,
 | 
				
			||||||
 | 
					                createMooniswapBridgeData(takerToken, mooniswapFillData.poolAddress),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
 | 
					            makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
 | 
				
			||||||
                makerToken,
 | 
					                makerToken,
 | 
				
			||||||
@@ -407,6 +416,11 @@ function createKyberBridgeData(fromTokenAddress: string, hint: string): string {
 | 
				
			|||||||
    return encoder.encode({ fromTokenAddress, hint });
 | 
					    return encoder.encode({ fromTokenAddress, hint });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createMooniswapBridgeData(takerToken: string, poolAddress: string): string {
 | 
				
			||||||
 | 
					    const encoder = AbiEncoder.create([{ name: 'takerToken', type: 'address' }, { name: 'pool', type: 'address' }]);
 | 
				
			||||||
 | 
					    return encoder.encode({ takerToken, poolAddress });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createCurveBridgeData(
 | 
					function createCurveBridgeData(
 | 
				
			||||||
    curveAddress: string,
 | 
					    curveAddress: string,
 | 
				
			||||||
    exchangeFunctionSelector: string,
 | 
					    exchangeFunctionSelector: string,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@ import {
 | 
				
			|||||||
    HopInfo,
 | 
					    HopInfo,
 | 
				
			||||||
    KyberFillData,
 | 
					    KyberFillData,
 | 
				
			||||||
    LiquidityProviderFillData,
 | 
					    LiquidityProviderFillData,
 | 
				
			||||||
 | 
					    MooniswapFillData,
 | 
				
			||||||
    MultiBridgeFillData,
 | 
					    MultiBridgeFillData,
 | 
				
			||||||
    MultiHopFillData,
 | 
					    MultiHopFillData,
 | 
				
			||||||
    SourceQuoteOperation,
 | 
					    SourceQuoteOperation,
 | 
				
			||||||
@@ -446,6 +447,14 @@ export class SamplerOperations {
 | 
				
			|||||||
            contract: this._samplerContract,
 | 
					            contract: this._samplerContract,
 | 
				
			||||||
            function: this._samplerContract.sampleSellsFromMooniswap,
 | 
					            function: this._samplerContract.sampleSellsFromMooniswap,
 | 
				
			||||||
            params: [takerToken, makerToken, takerFillAmounts],
 | 
					            params: [takerToken, makerToken, takerFillAmounts],
 | 
				
			||||||
 | 
					            callback: (callResults: string, fillData: MooniswapFillData): BigNumber[] => {
 | 
				
			||||||
 | 
					                const [poolAddress, samples] = this._samplerContract.getABIDecodedReturnData<[string, BigNumber[]]>(
 | 
				
			||||||
 | 
					                    'sampleSellsFromMooniswap',
 | 
				
			||||||
 | 
					                    callResults,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                fillData.poolAddress = poolAddress;
 | 
				
			||||||
 | 
					                return samples;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -459,6 +468,14 @@ export class SamplerOperations {
 | 
				
			|||||||
            contract: this._samplerContract,
 | 
					            contract: this._samplerContract,
 | 
				
			||||||
            function: this._samplerContract.sampleBuysFromMooniswap,
 | 
					            function: this._samplerContract.sampleBuysFromMooniswap,
 | 
				
			||||||
            params: [takerToken, makerToken, makerFillAmounts],
 | 
					            params: [takerToken, makerToken, makerFillAmounts],
 | 
				
			||||||
 | 
					            callback: (callResults: string, fillData: MooniswapFillData): BigNumber[] => {
 | 
				
			||||||
 | 
					                const [poolAddress, samples] = this._samplerContract.getABIDecodedReturnData<[string, BigNumber[]]>(
 | 
				
			||||||
 | 
					                    'sampleBuysFromMooniswap',
 | 
				
			||||||
 | 
					                    callResults,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                fillData.poolAddress = poolAddress;
 | 
				
			||||||
 | 
					                return samples;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -113,6 +113,10 @@ export interface KyberFillData extends FillData {
 | 
				
			|||||||
    reserveId: string;
 | 
					    reserveId: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface MooniswapFillData extends FillData {
 | 
				
			||||||
 | 
					    poolAddress: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Quote<TFillData = FillData> {
 | 
					export interface Quote<TFillData = FillData> {
 | 
				
			||||||
    amount: BigNumber;
 | 
					    amount: BigNumber;
 | 
				
			||||||
    fillData?: TFillData;
 | 
					    fillData?: TFillData;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user