Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
moodlezoup committed Mar 5, 2020
1 parent 9c5ac26 commit 4af2577
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 43 deletions.
8 changes: 2 additions & 6 deletions contracts/extensions/contracts/src/MaximumGasPrice.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/

pragma solidity ^0.5.16;
pragma experimental ABIEncoderV2;


contract MaximumGasPrice {
Expand All @@ -28,7 +27,6 @@ contract MaximumGasPrice {
/// the default maximum value of 20 Gwei.
function checkGasPrice()
external
view
{
require(
tx.gasprice <= DEFAULT_MAX_GAS_PRICE,
Expand All @@ -38,12 +36,10 @@ contract MaximumGasPrice {

/// @dev Checks that the current transaction's gas price is less than
/// the specified maximum value.
/// @param data Encodes the maximum gas price.
function checkGasPrice(bytes calldata data)
/// @param maxGasPrice The maximum gas price allowed for the current transaction.
function checkGasPrice(uint256 maxGasPrice)
external
view
{
(uint256 maxGasPrice) = abi.decode(data, (uint256));
require(
tx.gasprice <= maxGasPrice,
"MaximumGasPrice/GAS_PRICE_EXCEEDS_MAXIMUM"
Expand Down
12 changes: 3 additions & 9 deletions contracts/extensions/src/max_gas_price_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { assetDataUtils } from '@0x/order-utils';
import { StaticCallAssetData } from '@0x/types';
import { AbiEncoder, BigNumber } from '@0x/utils';

const maxGasPriceEncoder = AbiEncoder.create([{ name: 'maxGasPrice', type: 'uint256' }]);
const customGasPriceEncoder = AbiEncoder.createMethod('checkGasPrice', [{ name: 'data', type: 'bytes' }]);
const customGasPriceEncoder = AbiEncoder.createMethod('checkGasPrice', [{ name: 'maxGasPrice', type: 'uint256' }]);
const defaultGasPriceEncoder = AbiEncoder.createMethod('checkGasPrice', []);

const ONE_GWEI = new BigNumber(10 ** 9);
Expand All @@ -16,11 +15,7 @@ export const TWENTY_GWEI = ONE_GWEI.times(20);
*/
export function encodeMaxGasPriceStaticCallData(maxGasPriceContractAddress: string, maxGasPrice?: BigNumber): string {
const staticCallData =
maxGasPrice === undefined
? defaultGasPriceEncoder.encode({})
: customGasPriceEncoder.encode({
data: maxGasPriceEncoder.encode({ maxGasPrice }),
});
maxGasPrice === undefined ? defaultGasPriceEncoder.encode({}) : customGasPriceEncoder.encode({ maxGasPrice });
return assetDataUtils.encodeStaticCallAssetData(
maxGasPriceContractAddress,
staticCallData,
Expand All @@ -35,8 +30,7 @@ export function decodeMaxGasPriceStaticCallData(assetData: string): BigNumber {
// tslint:disable-next-line:no-unnecessary-type-assertion
const { staticCallData } = assetDataUtils.decodeAssetDataOrThrow(assetData) as StaticCallAssetData;
try {
const { maxGasPrice } = maxGasPriceEncoder.decode(customGasPriceEncoder.strictDecode<string>(staticCallData));
return maxGasPrice;
return customGasPriceEncoder.strictDecode<BigNumber>(staticCallData);
} catch (e) {
defaultGasPriceEncoder.strictDecode(staticCallData);
return TWENTY_GWEI;
Expand Down
74 changes: 46 additions & 28 deletions contracts/extensions/test/max_gas_price_test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { blockchainTests, constants, expect, getRandomInteger } from '@0x/contracts-test-utils';
import { AbiEncoder } from '@0x/utils';
import { artifacts as assetProxyArtifacts, StaticCallProxyContract } from '@0x/contracts-asset-proxy';
import { blockchainTests, constants, expect, getRandomInteger, randomAddress } from '@0x/contracts-test-utils';

import {
decodeMaxGasPriceStaticCallData,
Expand All @@ -12,7 +12,9 @@ import { MaximumGasPriceContract } from './wrappers';

blockchainTests.resets('MaximumGasPrice unit tests', env => {
let maxGasPriceContract: MaximumGasPriceContract;
const maxGasPriceEncoder = AbiEncoder.create([{ name: 'maxGasPrice', type: 'uint256' }]);
let staticCallProxy: StaticCallProxyContract;

let defaultMaxAssetData: string;

before(async () => {
maxGasPriceContract = await MaximumGasPriceContract.deployFrom0xArtifactAsync(
Expand All @@ -21,51 +23,67 @@ blockchainTests.resets('MaximumGasPrice unit tests', env => {
env.txDefaults,
artifacts,
);
staticCallProxy = await StaticCallProxyContract.deployFrom0xArtifactAsync(
assetProxyArtifacts.StaticCallProxy,
env.provider,
env.txDefaults,
assetProxyArtifacts,
);

defaultMaxAssetData = encodeMaxGasPriceStaticCallData(maxGasPriceContract.address);
});

describe('Data encoding/decoding tools', () => {
it('correctly decodes default maximum gas price', async () => {
const decoded = decodeMaxGasPriceStaticCallData(defaultMaxAssetData);
expect(decoded).to.bignumber.equal(TWENTY_GWEI);
});
it('correctly decodes custom maximum gas price', async () => {
const customMaxGasPrice = getRandomInteger(0, constants.MAX_UINT256);
const customMaxAssetData = encodeMaxGasPriceStaticCallData(maxGasPriceContract.address, customMaxGasPrice);
const decoded = decodeMaxGasPriceStaticCallData(customMaxAssetData);
expect(decoded).to.bignumber.equal(customMaxGasPrice);
});
});

describe('Contract functionality', () => {
it('does not revert if tx.gasprice < default maximum', async () => {
await maxGasPriceContract.checkGasPrice1().callAsync({ gasPrice: TWENTY_GWEI.minus(1) });
await staticCallProxy
.transferFrom(defaultMaxAssetData, randomAddress(), randomAddress(), constants.ZERO_AMOUNT)
.callAsync({ gasPrice: TWENTY_GWEI.minus(1) });
});
it('does not revert if tx.gasprice = default maximum', async () => {
await maxGasPriceContract.checkGasPrice1().callAsync({ gasPrice: TWENTY_GWEI });
await staticCallProxy
.transferFrom(defaultMaxAssetData, randomAddress(), randomAddress(), constants.ZERO_AMOUNT)
.callAsync({ gasPrice: TWENTY_GWEI });
});
it('reverts if tx.gasPrice > default maximum', async () => {
const tx = maxGasPriceContract.checkGasPrice1().callAsync({ gasPrice: TWENTY_GWEI.plus(1) });
const tx = staticCallProxy
.transferFrom(defaultMaxAssetData, randomAddress(), randomAddress(), constants.ZERO_AMOUNT)
.callAsync({ gasPrice: TWENTY_GWEI.plus(1) });
return expect(tx).to.revertWith('MaximumGasPrice/GAS_PRICE_EXCEEDS_20_GWEI');
});
it('does not revert if tx.gasprice < custom maximum', async () => {
const maxGasPrice = getRandomInteger(0, TWENTY_GWEI.times(2));
await maxGasPriceContract
.checkGasPrice2(maxGasPriceEncoder.encode({ maxGasPrice }))
const customMaxAssetData = encodeMaxGasPriceStaticCallData(maxGasPriceContract.address, maxGasPrice);
await staticCallProxy
.transferFrom(customMaxAssetData, randomAddress(), randomAddress(), constants.ZERO_AMOUNT)
.callAsync({ gasPrice: maxGasPrice.minus(1) });
});
it('does not revert if tx.gasprice = default maximum', async () => {
it('does not revert if tx.gasprice = custom maximum', async () => {
const maxGasPrice = getRandomInteger(0, TWENTY_GWEI.times(2));
await maxGasPriceContract
.checkGasPrice2(maxGasPriceEncoder.encode({ maxGasPrice }))
const customMaxAssetData = encodeMaxGasPriceStaticCallData(maxGasPriceContract.address, maxGasPrice);
await staticCallProxy
.transferFrom(customMaxAssetData, randomAddress(), randomAddress(), constants.ZERO_AMOUNT)
.callAsync({ gasPrice: maxGasPrice });
});
it('reverts if tx.gasPrice > default maximum', async () => {
it('reverts if tx.gasPrice > custom maximum', async () => {
const maxGasPrice = getRandomInteger(0, TWENTY_GWEI.times(2));
const tx = maxGasPriceContract
.checkGasPrice2(maxGasPriceEncoder.encode({ maxGasPrice }))
const customMaxAssetData = encodeMaxGasPriceStaticCallData(maxGasPriceContract.address, maxGasPrice);
const tx = staticCallProxy
.transferFrom(customMaxAssetData, randomAddress(), randomAddress(), constants.ZERO_AMOUNT)
.callAsync({ gasPrice: maxGasPrice.plus(1) });
return expect(tx).to.revertWith('MaximumGasPrice/GAS_PRICE_EXCEEDS_MAXIMUM');
});
});

describe('Data encoding/decoding tools', () => {
it('correctly decodes default maximum gas price', async () => {
const encoded = encodeMaxGasPriceStaticCallData(maxGasPriceContract.address);
const decoded = decodeMaxGasPriceStaticCallData(encoded);
expect(decoded).to.bignumber.equal(TWENTY_GWEI);
});
it('correctly decodes custom maximum gas price', async () => {
const maxGasPrice = getRandomInteger(0, constants.MAX_UINT256);
const encoded = encodeMaxGasPriceStaticCallData(maxGasPriceContract.address, maxGasPrice);
const decoded = decodeMaxGasPriceStaticCallData(encoded);
expect(decoded).to.bignumber.equal(maxGasPrice);
});
});
});

0 comments on commit 4af2577

Please sign in to comment.