@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",
|
||||
"pr": 2692
|
||||
},
|
||||
{
|
||||
"note": "Return Mooniswap pool in sampler and encode it in bridge data",
|
||||
"pr": 2692
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -46,44 +46,31 @@ contract MooniswapSampler is
|
||||
)
|
||||
public
|
||||
view
|
||||
returns (uint256[] memory makerTokenAmounts)
|
||||
returns (IMooniswap pool, uint256[] memory makerTokenAmounts)
|
||||
{
|
||||
_assertValidPair(makerToken, takerToken);
|
||||
uint256 numSamples = takerTokenAmounts.length;
|
||||
makerTokenAmounts = new uint256[](numSamples);
|
||||
|
||||
address _takerToken = takerToken == _getWethAddress() ? address(0) : takerToken;
|
||||
address _makerToken = makerToken == _getWethAddress() ? address(0) : makerToken;
|
||||
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)
|
||||
IMooniswap pool = IMooniswap(
|
||||
IMooniswapRegistry(_getMooniswapAddress()).pools(_takerToken, _makerToken)
|
||||
pool = IMooniswap(
|
||||
IMooniswapRegistry(_getMooniswapAddress()).pools(mooniswapTakerToken, mooniswapMakerToken)
|
||||
);
|
||||
// If there is no pool then return early
|
||||
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++) {
|
||||
// If the pool balance is smaller than the sell amount
|
||||
// don't sample to avoid multiplication overflow in buys
|
||||
if (poolBalance < takerTokenAmounts[i]) {
|
||||
break;
|
||||
}
|
||||
(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));
|
||||
}
|
||||
uint256 buyAmount = sampleSingleSellFromMooniswapPool(
|
||||
pool,
|
||||
mooniswapTakerToken,
|
||||
mooniswapMakerToken,
|
||||
takerTokenAmounts[i]
|
||||
);
|
||||
// Exit early if the amount is too high for the source to serve
|
||||
if (buyAmount == 0) {
|
||||
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.
|
||||
/// @param takerToken Address of the taker token (what to sell).
|
||||
/// @param makerToken Address of the maker token (what to buy).
|
||||
@@ -105,12 +124,28 @@ contract MooniswapSampler is
|
||||
)
|
||||
public
|
||||
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({
|
||||
makerTokenData: abi.encode(makerToken),
|
||||
takerTokenData: abi.encode(takerToken),
|
||||
makerTokenData: abi.encode(mooniswapMakerToken, pool),
|
||||
takerTokenData: abi.encode(mooniswapTakerToken, pool),
|
||||
getSellQuoteCallback: _sampleSellForApproximateBuyFromMooniswap
|
||||
}),
|
||||
makerTokenAmounts
|
||||
@@ -126,15 +161,16 @@ contract MooniswapSampler is
|
||||
view
|
||||
returns (uint256 buyAmount)
|
||||
{
|
||||
(address takerToken) =
|
||||
abi.decode(takerTokenData, (address));
|
||||
(address makerToken) =
|
||||
(address mooniswapTakerToken, IMooniswap pool) =
|
||||
abi.decode(takerTokenData, (address, IMooniswap));
|
||||
(address mooniswapMakerToken) =
|
||||
abi.decode(makerTokenData, (address));
|
||||
(bool success, bytes memory resultData) =
|
||||
address(this).staticcall(abi.encodeWithSelector(
|
||||
this.sampleSellsFromMooniswap.selector,
|
||||
takerToken,
|
||||
makerToken,
|
||||
this.sampleSingleSellFromMooniswapPool.selector,
|
||||
pool,
|
||||
mooniswapTakerToken,
|
||||
mooniswapMakerToken,
|
||||
_toSingleValueArray(sellAmount)
|
||||
));
|
||||
if (!success) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
Fill,
|
||||
KyberFillData,
|
||||
LiquidityProviderFillData,
|
||||
MooniswapFillData,
|
||||
MultiBridgeFillData,
|
||||
MultiHopFillData,
|
||||
NativeCollapsedFill,
|
||||
@@ -304,6 +305,14 @@ function createBridgeOrder(
|
||||
createKyberBridgeData(takerToken, kyberFillData.hint),
|
||||
);
|
||||
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:
|
||||
makerAssetData = assetDataUtils.encodeERC20BridgeAssetData(
|
||||
makerToken,
|
||||
@@ -407,6 +416,11 @@ function createKyberBridgeData(fromTokenAddress: string, hint: string): string {
|
||||
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(
|
||||
curveAddress: string,
|
||||
exchangeFunctionSelector: string,
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
HopInfo,
|
||||
KyberFillData,
|
||||
LiquidityProviderFillData,
|
||||
MooniswapFillData,
|
||||
MultiBridgeFillData,
|
||||
MultiHopFillData,
|
||||
SourceQuoteOperation,
|
||||
@@ -446,6 +447,14 @@ export class SamplerOperations {
|
||||
contract: this._samplerContract,
|
||||
function: this._samplerContract.sampleSellsFromMooniswap,
|
||||
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,
|
||||
function: this._samplerContract.sampleBuysFromMooniswap,
|
||||
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;
|
||||
}
|
||||
|
||||
export interface MooniswapFillData extends FillData {
|
||||
poolAddress: string;
|
||||
}
|
||||
|
||||
export interface Quote<TFillData = FillData> {
|
||||
amount: BigNumber;
|
||||
fillData?: TFillData;
|
||||
|
||||
Reference in New Issue
Block a user