@0x/contracts-zero-ex: Add reentrancy guard to mtx functions

`@0x/contracts-zero-ex`: Add refund mechanism to mtxs
`@0x/contracts-zero-ex`: Pass sender to transfomers.
`@0x/contracts-zero-ex`: Refund protocol fees to `refundReceiver` in FQT.
`@0x/utils`: Add EP flavor of `IllegalReentrancyError`
`@0x/order-utils`: Add `refundReceiver` to FQT transform data.
`@0x/asset-swapper`: Add `refundReceiver` support to EP swap quote consumer.
This commit is contained in:
Lawrence Forman
2020-08-05 13:33:07 -04:00
committed by Lawrence Forman
parent 7b0a1c3630
commit 9cda9f69cd
35 changed files with 747 additions and 129 deletions

View File

@@ -86,7 +86,12 @@ blockchainTests.resets('AffiliateFeeTransformer', env => {
await mintHostTokensAsync(amounts[0]);
await sendEtherAsync(host.address, amounts[1]);
await host
.rawExecuteTransform(transformer.address, hexUtils.random(), randomAddress(), data)
.rawExecuteTransform(transformer.address, {
data,
callDataHash: hexUtils.random(),
sender: randomAddress(),
taker: randomAddress(),
})
.awaitTransactionSuccessAsync();
expect(await getBalancesAsync(host.address)).to.deep.eq(ZERO_BALANCES);
expect(await getBalancesAsync(recipients[0])).to.deep.eq({
@@ -112,7 +117,12 @@ blockchainTests.resets('AffiliateFeeTransformer', env => {
await mintHostTokensAsync(amounts[0]);
await sendEtherAsync(host.address, amounts[1]);
await host
.rawExecuteTransform(transformer.address, hexUtils.random(), randomAddress(), data)
.rawExecuteTransform(transformer.address, {
data,
callDataHash: hexUtils.random(),
sender: randomAddress(),
taker: randomAddress(),
})
.awaitTransactionSuccessAsync();
expect(await getBalancesAsync(host.address)).to.deep.eq(ZERO_BALANCES);
expect(await getBalancesAsync(recipients[0])).to.deep.eq({
@@ -138,7 +148,12 @@ blockchainTests.resets('AffiliateFeeTransformer', env => {
await mintHostTokensAsync(amounts[0]);
await sendEtherAsync(host.address, amounts[1]);
await host
.rawExecuteTransform(transformer.address, hexUtils.random(), randomAddress(), data)
.rawExecuteTransform(transformer.address, {
data,
callDataHash: hexUtils.random(),
sender: randomAddress(),
taker: randomAddress(),
})
.awaitTransactionSuccessAsync();
expect(await getBalancesAsync(host.address)).to.deep.eq({
tokenBalance: new BigNumber(1),

View File

@@ -32,6 +32,8 @@ const { NULL_ADDRESS, NULL_BYTES, MAX_UINT256, ZERO_AMOUNT } = constants;
blockchainTests.resets('FillQuoteTransformer', env => {
let maker: string;
let feeRecipient: string;
let sender: string;
let taker: string;
let exchange: TestFillQuoteTransformerExchangeContract;
let bridge: TestFillQuoteTransformerBridgeContract;
let transformer: FillQuoteTransformerContract;
@@ -44,7 +46,7 @@ blockchainTests.resets('FillQuoteTransformer', env => {
const GAS_PRICE = 1337;
before(async () => {
[maker, feeRecipient] = await env.getAccountAddressesAsync();
[maker, feeRecipient, sender, taker] = await env.getAccountAddressesAsync();
exchange = await TestFillQuoteTransformerExchangeContract.deployFrom0xArtifactAsync(
artifacts.TestFillQuoteTransformerExchange,
env.provider,
@@ -92,7 +94,7 @@ blockchainTests.resets('FillQuoteTransformer', env => {
bridge = await TestFillQuoteTransformerBridgeContract.deployFrom0xArtifactAsync(
artifacts.TestFillQuoteTransformerBridge,
env.provider,
env.txDefaults,
{ ...env.txDefaults, from: sender },
artifacts,
);
[makerToken, takerToken, takerFeeToken] = await Promise.all(
@@ -270,6 +272,7 @@ blockchainTests.resets('FillQuoteTransformer', env => {
signatures: [],
maxOrderFillAmounts: [],
fillAmount: MAX_UINT256,
refundReceiver: NULL_ADDRESS,
...fields,
});
}
@@ -313,6 +316,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -334,6 +339,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -358,6 +365,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -380,6 +389,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -404,6 +415,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -430,6 +443,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -462,6 +477,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -486,6 +503,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -511,6 +530,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
takerTokenBalance,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -535,6 +556,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
takerTokenBalance,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -564,6 +587,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -586,6 +611,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -608,6 +635,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -627,6 +656,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -640,6 +671,80 @@ blockchainTests.resets('FillQuoteTransformer', env => {
makerAssetBalance: qfr.makerAssetBought,
});
});
it('can refund unspent protocol fee to the `refundReceiver`', async () => {
const orders = _.times(2, () => createOrder());
const signatures = orders.map(() => encodeExchangeBehavior());
const qfr = getExpectedSellQuoteFillResults(orders);
const protocolFee = qfr.protocolFeePaid.plus(1);
const refundReceiver = randomAddress();
await host
.executeTransform(
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
refundReceiver,
}),
)
.awaitTransactionSuccessAsync({ value: protocolFee });
const receiverBalancer = await env.web3Wrapper.getBalanceInWeiAsync(refundReceiver);
expect(receiverBalancer).to.bignumber.eq(1);
});
it('can refund unspent protocol fee to the taker', async () => {
const orders = _.times(2, () => createOrder());
const signatures = orders.map(() => encodeExchangeBehavior());
const qfr = getExpectedSellQuoteFillResults(orders);
const protocolFee = qfr.protocolFeePaid.plus(1);
const refundReceiver = randomAddress();
await host
.executeTransform(
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
refundReceiver, // taker = refundReceiver
encodeTransformData({
orders,
signatures,
// address(1) indicates taker
refundReceiver: hexUtils.leftPad(1, 20),
}),
)
.awaitTransactionSuccessAsync({ value: protocolFee });
const receiverBalancer = await env.web3Wrapper.getBalanceInWeiAsync(refundReceiver);
expect(receiverBalancer).to.bignumber.eq(1);
});
it('can refund unspent protocol fee to the sender', async () => {
const orders = _.times(2, () => createOrder());
const signatures = orders.map(() => encodeExchangeBehavior());
const qfr = getExpectedSellQuoteFillResults(orders);
const protocolFee = qfr.protocolFeePaid.plus(1);
const refundReceiver = randomAddress();
await host
.executeTransform(
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
refundReceiver, // sender = refundReceiver
taker,
encodeTransformData({
orders,
signatures,
// address(2) indicates sender
refundReceiver: hexUtils.leftPad(2, 20),
}),
)
.awaitTransactionSuccessAsync({ value: protocolFee });
const receiverBalancer = await env.web3Wrapper.getBalanceInWeiAsync(refundReceiver);
expect(receiverBalancer).to.bignumber.eq(1);
});
});
describe('buy quotes', () => {
@@ -652,6 +757,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -675,6 +782,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -701,6 +810,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -725,6 +836,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -751,6 +864,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -774,6 +889,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -804,6 +921,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -828,6 +947,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -852,6 +973,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -873,6 +996,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -900,6 +1025,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -926,6 +1053,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -952,6 +1081,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,
@@ -980,6 +1111,8 @@ blockchainTests.resets('FillQuoteTransformer', env => {
transformer.address,
takerToken.address,
qfr.takerAssetSpent,
sender,
taker,
encodeTransformData({
orders,
signatures,

View File

@@ -78,7 +78,12 @@ blockchainTests.resets('PayTakerTransformer', env => {
await mintHostTokensAsync(amounts[0]);
await sendEtherAsync(host.address, amounts[1]);
await host
.rawExecuteTransform(transformer.address, hexUtils.random(), taker, data)
.rawExecuteTransform(transformer.address, {
data,
callDataHash: hexUtils.random(),
taker,
sender: randomAddress(),
})
.awaitTransactionSuccessAsync();
expect(await getBalancesAsync(host.address)).to.deep.eq(ZERO_BALANCES);
expect(await getBalancesAsync(taker)).to.deep.eq({
@@ -96,7 +101,12 @@ blockchainTests.resets('PayTakerTransformer', env => {
await mintHostTokensAsync(amounts[0]);
await sendEtherAsync(host.address, amounts[1]);
await host
.rawExecuteTransform(transformer.address, hexUtils.random(), taker, data)
.rawExecuteTransform(transformer.address, {
data,
callDataHash: hexUtils.random(),
taker,
sender: randomAddress(),
})
.awaitTransactionSuccessAsync();
expect(await getBalancesAsync(host.address)).to.deep.eq(ZERO_BALANCES);
expect(await getBalancesAsync(taker)).to.deep.eq({
@@ -114,7 +124,12 @@ blockchainTests.resets('PayTakerTransformer', env => {
await mintHostTokensAsync(amounts[0]);
await sendEtherAsync(host.address, amounts[1]);
await host
.rawExecuteTransform(transformer.address, hexUtils.random(), taker, data)
.rawExecuteTransform(transformer.address, {
data,
callDataHash: hexUtils.random(),
taker,
sender: randomAddress(),
})
.awaitTransactionSuccessAsync();
expect(await getBalancesAsync(host.address)).to.deep.eq(ZERO_BALANCES);
expect(await getBalancesAsync(taker)).to.deep.eq({
@@ -132,7 +147,12 @@ blockchainTests.resets('PayTakerTransformer', env => {
await mintHostTokensAsync(amounts[0]);
await sendEtherAsync(host.address, amounts[1]);
await host
.rawExecuteTransform(transformer.address, hexUtils.random(), taker, data)
.rawExecuteTransform(transformer.address, {
data,
callDataHash: hexUtils.random(),
taker,
sender: randomAddress(),
})
.awaitTransactionSuccessAsync();
expect(await getBalancesAsync(host.address)).to.deep.eq({
tokenBalance: amounts[0].minus(amounts[0].dividedToIntegerBy(2)),