@0x/contracts-erc20-bridge-sampler: Throw sampling two of the same tokens.

`@0x/contracts-erc20-bridge-sampler`: Address review comments.
This commit is contained in:
Lawrence Forman
2019-11-19 20:35:32 -05:00
parent dea30b37ef
commit a8e93a594d
2 changed files with 58 additions and 16 deletions

View File

@@ -186,6 +186,7 @@ contract ERC20BridgeSampler is
view
returns (uint256[] memory makerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
address _takerToken = takerToken == _getWETHAddress() ? KYBER_ETH_ADDRESS : takerToken;
address _makerToken = makerToken == _getWETHAddress() ? KYBER_ETH_ADDRESS : makerToken;
uint256 takerTokenDecimals = _getTokenDecimals(takerToken);
@@ -222,6 +223,7 @@ contract ERC20BridgeSampler is
view
returns (uint256[] memory makerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
@@ -248,6 +250,7 @@ contract ERC20BridgeSampler is
view
returns (uint256[] memory takerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
for (uint256 i = 0; i < numSamples; i++) {
@@ -274,6 +277,7 @@ contract ERC20BridgeSampler is
view
returns (uint256[] memory makerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = takerTokenAmounts.length;
makerTokenAmounts = new uint256[](numSamples);
IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWETHAddress() ?
@@ -315,6 +319,7 @@ contract ERC20BridgeSampler is
view
returns (uint256[] memory takerTokenAmounts)
{
_assertValidPair(makerToken, takerToken);
uint256 numSamples = makerTokenAmounts.length;
takerTokenAmounts = new uint256[](numSamples);
IUniswapExchangeQuotes takerTokenExchange = takerToken == _getWETHAddress() ?
@@ -436,4 +441,11 @@ contract ERC20BridgeSampler is
}
require(selector == ERC20_PROXY_ID, "UNSUPPORTED_ASSET_PROXY");
}
function _assertValidPair(address makerToken, address takerToken)
private
pure
{
require(makerToken != takerToken, "INVALID_TOKEN_PAIR");
}
}

View File

@@ -40,6 +40,7 @@ blockchainTests('erc20-bridge-sampler', env => {
const INVALID_ASSET_DATA_ERROR = 'INVALID_ASSET_DATA';
const UNSUPPORTED_UNISWAP_EXCHANGE_ERROR = 'UNSUPPORTED_UNISWAP_EXCHANGE';
const UNSUPPORTED_SOURCE_ERROR = 'UNSUPPORTED_SOURCE';
const INVALID_TOKEN_PAIR_ERROR = 'INVALID_TOKEN_PAIR';
before(async () => {
testContract = await TestERC20BridgeSamplerContract.deployFrom0xArtifactAsync(
@@ -115,11 +116,15 @@ blockchainTests('erc20-bridge-sampler', env => {
.dividedToIntegerBy(buyBase);
}
function areAddressesEqual(a: string, b: string): boolean {
return a.toLowerCase() === b.toLowerCase();
}
function getDeterministicUniswapSellQuote(sellToken: string, buyToken: string, sellAmount: BigNumber): BigNumber {
if (buyToken.toLowerCase() === WETH_ADDRESS.toLowerCase()) {
if (areAddressesEqual(buyToken, WETH_ADDRESS)) {
return getDeterministicSellQuote(getUniswapExchangeSalt(sellToken), sellToken, WETH_ADDRESS, sellAmount);
}
if (sellToken.toLowerCase() === WETH_ADDRESS.toLowerCase()) {
if (areAddressesEqual(sellToken, WETH_ADDRESS)) {
return getDeterministicSellQuote(getUniswapExchangeSalt(buyToken), buyToken, WETH_ADDRESS, sellAmount);
}
const ethBought = getDeterministicSellQuote(
@@ -132,10 +137,10 @@ blockchainTests('erc20-bridge-sampler', env => {
}
function getDeterministicUniswapBuyQuote(sellToken: string, buyToken: string, buyAmount: BigNumber): BigNumber {
if (buyToken.toLowerCase() === WETH_ADDRESS.toLowerCase()) {
if (areAddressesEqual(buyToken, WETH_ADDRESS)) {
return getDeterministicBuyQuote(getUniswapExchangeSalt(sellToken), WETH_ADDRESS, sellToken, buyAmount);
}
if (sellToken.toLowerCase() === WETH_ADDRESS.toLowerCase()) {
if (areAddressesEqual(sellToken, WETH_ADDRESS)) {
return getDeterministicBuyQuote(getUniswapExchangeSalt(buyToken), WETH_ADDRESS, buyToken, buyAmount);
}
const ethSold = getDeterministicBuyQuote(getUniswapExchangeSalt(buyToken), WETH_ADDRESS, buyToken, buyAmount);
@@ -310,7 +315,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
makerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
})),
[...SELL_SOURCES.map(n => allSources[n]), randomAddress()],
SELL_SOURCES.map(n => allSources[n]),
getSampleAmounts(TAKER_TOKEN),
)
.callAsync();
@@ -324,7 +329,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
takerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
})),
[...SELL_SOURCES.map(n => allSources[n]), randomAddress()],
SELL_SOURCES.map(n => allSources[n]),
getSampleAmounts(TAKER_TOKEN),
)
.callAsync();
@@ -338,7 +343,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
makerAssetData: INVALID_ASSET_DATA,
})),
[...SELL_SOURCES.map(n => allSources[n]), randomAddress()],
SELL_SOURCES.map(n => allSources[n]),
getSampleAmounts(TAKER_TOKEN),
)
.callAsync();
@@ -352,7 +357,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
takerAssetData: INVALID_ASSET_DATA,
})),
[...SELL_SOURCES.map(n => allSources[n]), randomAddress()],
SELL_SOURCES.map(n => allSources[n]),
getSampleAmounts(TAKER_TOKEN),
)
.callAsync();
@@ -428,7 +433,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
makerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
})),
[...BUY_SOURCES.map(n => allSources[n]), randomAddress()],
BUY_SOURCES.map(n => allSources[n]),
getSampleAmounts(MAKER_TOKEN),
)
.callAsync();
@@ -442,7 +447,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
takerAssetData: INVALID_ASSET_PROXY_ASSET_DATA,
})),
[...BUY_SOURCES.map(n => allSources[n]), randomAddress()],
BUY_SOURCES.map(n => allSources[n]),
getSampleAmounts(MAKER_TOKEN),
)
.callAsync();
@@ -456,7 +461,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
makerAssetData: INVALID_ASSET_DATA,
})),
[...BUY_SOURCES.map(n => allSources[n]), randomAddress()],
BUY_SOURCES.map(n => allSources[n]),
getSampleAmounts(MAKER_TOKEN),
)
.callAsync();
@@ -470,7 +475,7 @@ blockchainTests('erc20-bridge-sampler', env => {
...o,
takerAssetData: INVALID_ASSET_DATA,
})),
[...BUY_SOURCES.map(n => allSources[n]), randomAddress()],
BUY_SOURCES.map(n => allSources[n]),
getSampleAmounts(MAKER_TOKEN),
)
.callAsync();
@@ -590,6 +595,11 @@ blockchainTests('erc20-bridge-sampler', env => {
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleSellsFromKyberNetwork(MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const quotes = await testContract.sampleSellsFromKyberNetwork(TAKER_TOKEN, MAKER_TOKEN, []).callAsync();
expect(quotes).to.deep.eq([]);
@@ -631,6 +641,11 @@ blockchainTests('erc20-bridge-sampler', env => {
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleSellsFromEth2Dai(MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const quotes = await testContract.sampleSellsFromEth2Dai(TAKER_TOKEN, MAKER_TOKEN, []).callAsync();
expect(quotes).to.deep.eq([]);
@@ -672,6 +687,11 @@ blockchainTests('erc20-bridge-sampler', env => {
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleBuysFromEth2Dai(MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const quotes = await testContract.sampleBuysFromEth2Dai(TAKER_TOKEN, MAKER_TOKEN, []).callAsync();
expect(quotes).to.deep.eq([]);
@@ -713,6 +733,11 @@ blockchainTests('erc20-bridge-sampler', env => {
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleSellsFromUniswap(MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const quotes = await testContract.sampleSellsFromUniswap(TAKER_TOKEN, MAKER_TOKEN, []).callAsync();
expect(quotes).to.deep.eq([]);
@@ -750,7 +775,7 @@ blockchainTests('erc20-bridge-sampler', env => {
const tx = testContract
.sampleSellsFromUniswap(TAKER_TOKEN, nonExistantToken, getSampleAmounts(TAKER_TOKEN))
.callAsync();
expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
return expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
});
it('throws if no exchange exists for the taker token', async () => {
@@ -758,7 +783,7 @@ blockchainTests('erc20-bridge-sampler', env => {
const tx = testContract
.sampleSellsFromUniswap(nonExistantToken, MAKER_TOKEN, getSampleAmounts(nonExistantToken))
.callAsync();
expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
return expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
});
});
@@ -770,6 +795,11 @@ blockchainTests('erc20-bridge-sampler', env => {
await testContract.createTokenExchanges([MAKER_TOKEN, TAKER_TOKEN]).awaitTransactionSuccessAsync();
});
it('throws if tokens are the same', async () => {
const tx = testContract.sampleBuysFromUniswap(MAKER_TOKEN, MAKER_TOKEN, []).callAsync();
return expect(tx).to.revertWith(INVALID_TOKEN_PAIR_ERROR);
});
it('can return no quotes', async () => {
const quotes = await testContract.sampleBuysFromUniswap(TAKER_TOKEN, MAKER_TOKEN, []).callAsync();
expect(quotes).to.deep.eq([]);
@@ -807,7 +837,7 @@ blockchainTests('erc20-bridge-sampler', env => {
const tx = testContract
.sampleBuysFromUniswap(TAKER_TOKEN, nonExistantToken, getSampleAmounts(TAKER_TOKEN))
.callAsync();
expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
return expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
});
it('throws if no exchange exists for the taker token', async () => {
@@ -815,7 +845,7 @@ blockchainTests('erc20-bridge-sampler', env => {
const tx = testContract
.sampleBuysFromUniswap(nonExistantToken, MAKER_TOKEN, getSampleAmounts(nonExistantToken))
.callAsync();
expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
return expect(tx).to.revertWith(UNSUPPORTED_UNISWAP_EXCHANGE_ERROR);
});
});
});