From c4097e42034951c4bbbc661509f2ec903568e145 Mon Sep 17 00:00:00 2001 From: Elena Date: Thu, 12 Jan 2023 11:45:33 +0200 Subject: [PATCH] Migrate ZeroEx proxy tests to foundry (#638) * Implement base instantiation of the ZeroEx proxy in foundry and move TestZeroExFeature contract to the foundry mocks * Migrate zero-ex tests to foundry * Update copyright year * Update contracts/zero-ex/tests/mocks/TestZeroExFeature.sol Co-authored-by: Jacob Evans Co-authored-by: Jacob Evans --- contracts/zero-ex/compiler.json | 1 - contracts/zero-ex/package.json | 2 +- contracts/zero-ex/test/artifacts.ts | 2 - contracts/zero-ex/test/zero_ex_test.ts | 96 ------------------- contracts/zero-ex/tests/BaseTest.sol | 18 ++++ contracts/zero-ex/tests/FlashWalletTest.t.sol | 3 +- contracts/zero-ex/tests/ZeroExTest.t.sol | 93 ++++++++++++++++++ .../mocks}/TestZeroExFeature.sol | 6 +- contracts/zero-ex/tsconfig.json | 1 - 9 files changed, 117 insertions(+), 105 deletions(-) delete mode 100644 contracts/zero-ex/test/zero_ex_test.ts create mode 100644 contracts/zero-ex/tests/ZeroExTest.t.sol rename contracts/zero-ex/{contracts/test => tests/mocks}/TestZeroExFeature.sol (88%) diff --git a/contracts/zero-ex/compiler.json b/contracts/zero-ex/compiler.json index 81a46e7b21..e1f2a1c043 100644 --- a/contracts/zero-ex/compiler.json +++ b/contracts/zero-ex/compiler.json @@ -190,7 +190,6 @@ "./contracts/test/TestTransformerHost.sol", "./contracts/test/TestUniswapV3Feature.sol", "./contracts/test/TestWethTransformerHost.sol", - "./contracts/test/TestZeroExFeature.sol", "./contracts/test/integration/TestCurve.sol", "./contracts/test/integration/TestLiquidityProvider.sol", "./contracts/test/integration/TestMooniswap.sol", diff --git a/contracts/zero-ex/package.json b/contracts/zero-ex/package.json index e8acfb59c3..5270691075 100644 --- a/contracts/zero-ex/package.json +++ b/contracts/zero-ex/package.json @@ -42,7 +42,7 @@ "config": { "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,PositiveSlippageFeeTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector,CurveLiquidityProvider,BatchFillNativeOrdersFeature,IBatchFillNativeOrdersFeature,MultiplexFeature,IMultiplexFeature,OtcOrdersFeature,IOtcOrdersFeature,AvalancheBridgeAdapter,BSCBridgeAdapter,CeloBridgeAdapter,EthereumBridgeAdapter,FantomBridgeAdapter,OptimismBridgeAdapter,PolygonBridgeAdapter", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", - "abis": "./test/generated-artifacts/@(AbstractBridgeAdapter|AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|FantomBridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2Batch|MixinBancor|MixinBancorV3|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinSolidly|MixinSynthetix|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OptimismBridgeAdapter|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PolygonBridgeAdapter|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TestZeroExFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json" + "abis": "./test/generated-artifacts/@(AbstractBridgeAdapter|AffiliateFeeTransformer|AvalancheBridgeAdapter|BSCBridgeAdapter|BatchFillNativeOrdersFeature|BootstrapFeature|BridgeProtocols|CeloBridgeAdapter|CurveLiquidityProvider|ERC1155OrdersFeature|ERC165Feature|ERC721OrdersFeature|EthereumBridgeAdapter|FantomBridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinERC1155Spender|FixinERC721Spender|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|FundRecoveryFeature|IBatchFillNativeOrdersFeature|IBootstrapFeature|IBridgeAdapter|IERC1155OrdersFeature|IERC1155Token|IERC165Feature|IERC20Bridge|IERC20Transformer|IERC721OrdersFeature|IERC721Token|IFeature|IFeeRecipient|IFlashWallet|IFundRecoveryFeature|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|IMooniswapPool|IMultiplexFeature|INativeOrdersEvents|INativeOrdersFeature|IOtcOrdersFeature|IOwnableFeature|IPancakeSwapFeature|IPropertyValidator|ISimpleFunctionRegistryFeature|IStaking|ITakerCallback|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IUniswapV2Pair|IUniswapV3Feature|IUniswapV3Pool|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC1155OrdersStorage|LibERC20Transformer|LibERC721OrdersStorage|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNFTOrder|LibNFTOrdersRichErrors|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOtcOrdersStorage|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAaveV2|MixinBalancer|MixinBalancerV2Batch|MixinBancor|MixinBancorV3|MixinCompound|MixinCryptoCom|MixinCurve|MixinCurveV2|MixinDodo|MixinDodoV2|MixinGMX|MixinKyberDmm|MixinLido|MixinMStable|MixinMakerPSM|MixinMooniswap|MixinNerve|MixinPlatypus|MixinShell|MixinSolidly|MixinSynthetix|MixinUniswap|MixinUniswapV2|MixinUniswapV3|MixinZeroExBridge|MooniswapLiquidityProvider|MultiplexFeature|MultiplexLiquidityProvider|MultiplexOtc|MultiplexRfq|MultiplexTransformERC20|MultiplexUniswapV2|MultiplexUniswapV3|NFTOrders|NativeOrdersCancellation|NativeOrdersFeature|NativeOrdersInfo|NativeOrdersProtocolFees|NativeOrdersSettlement|OptimismBridgeAdapter|OtcOrdersFeature|OwnableFeature|PancakeSwapFeature|PayTakerTransformer|PermissionlessTransformerDeployer|PolygonBridgeAdapter|PositiveSlippageFeeTransformer|SimpleFunctionRegistryFeature|TestCurve|TestDelegateCaller|TestFeeCollectorController|TestFeeRecipient|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC1155Token|TestMintableERC20Token|TestMintableERC721Token|TestMooniswap|TestNFTOrderPresigner|TestNativeOrdersFeature|TestNoEthRecipient|TestOrderSignerRegistryWithContractWallet|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestPropertyValidator|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestUniswapV2Factory|TestUniswapV2Pool|TestUniswapV3Factory|TestUniswapV3Feature|TestUniswapV3Pool|TestWeth|TestWethTransformerHost|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|UniswapV3Feature|WethTransformer|ZeroEx|ZeroExOptimized).json" }, "repository": { "type": "git", diff --git a/contracts/zero-ex/test/artifacts.ts b/contracts/zero-ex/test/artifacts.ts index 5af249be83..3dbfc072d9 100644 --- a/contracts/zero-ex/test/artifacts.ts +++ b/contracts/zero-ex/test/artifacts.ts @@ -197,7 +197,6 @@ import * as TestUniswapV3Feature from '../test/generated-artifacts/TestUniswapV3 import * as TestUniswapV3Pool from '../test/generated-artifacts/TestUniswapV3Pool.json'; import * as TestWeth from '../test/generated-artifacts/TestWeth.json'; import * as TestWethTransformerHost from '../test/generated-artifacts/TestWethTransformerHost.json'; -import * as TestZeroExFeature from '../test/generated-artifacts/TestZeroExFeature.json'; import * as Transformer from '../test/generated-artifacts/Transformer.json'; import * as TransformERC20Feature from '../test/generated-artifacts/TransformERC20Feature.json'; import * as TransformerDeployer from '../test/generated-artifacts/TransformerDeployer.json'; @@ -396,7 +395,6 @@ export const artifacts = { TestTransformerHost: TestTransformerHost as ContractArtifact, TestUniswapV3Feature: TestUniswapV3Feature as ContractArtifact, TestWethTransformerHost: TestWethTransformerHost as ContractArtifact, - TestZeroExFeature: TestZeroExFeature as ContractArtifact, TestCurve: TestCurve as ContractArtifact, TestLiquidityProvider: TestLiquidityProvider as ContractArtifact, TestMooniswap: TestMooniswap as ContractArtifact, diff --git a/contracts/zero-ex/test/zero_ex_test.ts b/contracts/zero-ex/test/zero_ex_test.ts deleted file mode 100644 index 566504f157..0000000000 --- a/contracts/zero-ex/test/zero_ex_test.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { blockchainTests, constants, expect, verifyEventsFromLogs } from '@0x/contracts-test-utils'; -import { BigNumber, ZeroExRevertErrors } from '@0x/utils'; - -import { ZeroExContract } from '../src/wrappers'; - -import { artifacts } from './artifacts'; -import { initialMigrateAsync } from './utils/migration'; -import { - IFeatureContract, - IOwnableFeatureContract, - ISimpleFunctionRegistryFeatureContract, - TestZeroExFeatureContract, - TestZeroExFeatureEvents, -} from './wrappers'; - -blockchainTests.resets('ZeroEx contract', env => { - let owner: string; - let zeroEx: ZeroExContract; - let ownable: IOwnableFeatureContract; - let registry: ISimpleFunctionRegistryFeatureContract; - let testFeature: TestZeroExFeatureContract; - - before(async () => { - [owner] = await env.getAccountAddressesAsync(); - zeroEx = await initialMigrateAsync(owner, env.provider, env.txDefaults); - ownable = new IOwnableFeatureContract(zeroEx.address, env.provider, env.txDefaults); - registry = new ISimpleFunctionRegistryFeatureContract(zeroEx.address, env.provider, env.txDefaults); - testFeature = new TestZeroExFeatureContract(zeroEx.address, env.provider, env.txDefaults); - // Register test features. - const testFeatureImpl = await TestZeroExFeatureContract.deployFrom0xArtifactAsync( - artifacts.TestZeroExFeature, - env.provider, - env.txDefaults, - artifacts, - ); - for (const fn of ['payableFn', 'notPayableFn', 'internalFn']) { - await registry - .extend(testFeature.getSelector(fn), testFeatureImpl.address) - .awaitTransactionSuccessAsync({ from: owner }); - } - }); - - it('can receive ether', async () => { - const txHash = await env.web3Wrapper.sendTransactionAsync({ - from: owner, - to: zeroEx.address, - data: constants.NULL_BYTES, - value: 1, - }); - await env.web3Wrapper.awaitTransactionSuccessAsync(txHash); - }); - - it('can attach ether to a call', async () => { - const wei = Math.floor(Math.random() * 100 + 1); - const receipt = await testFeature.payableFn().awaitTransactionSuccessAsync({ value: wei }); - verifyEventsFromLogs(receipt.logs, [{ value: new BigNumber(wei) }], TestZeroExFeatureEvents.PayableFnCalled); - }); - - it('reverts when attaching ether to a non-payable function', async () => { - const wei = Math.floor(Math.random() * 100 + 1); - const tx = testFeature.notPayableFn().awaitTransactionSuccessAsync({ value: wei }); - // This will cause an empty revert. - return expect(tx).to.be.rejectedWith('revert'); - }); - - it('reverts when calling an unimplmented function', async () => { - const selector = testFeature.getSelector('unimplmentedFn'); - const tx = testFeature.unimplmentedFn().awaitTransactionSuccessAsync(); - return expect(tx).to.revertWith(new ZeroExRevertErrors.Proxy.NotImplementedError(selector)); - }); - - it('reverts when calling an internal function', async () => { - const tx = testFeature.internalFn().awaitTransactionSuccessAsync({ from: owner }); - return expect(tx).to.revertWith(new ZeroExRevertErrors.Common.OnlyCallableBySelfError(owner)); - }); - - describe('getFunctionImplementation()', () => { - it('returns the correct implementations of the initial features', async () => { - const ownableSelectors = [ownable.getSelector('transferOwnership')]; - const registrySelectors = [ - registry.getSelector('rollback'), - registry.getSelector('extend'), - // registry.getSelector('extendSelf'), - ]; - const selectors = [...ownableSelectors, ...registrySelectors]; - const impls = await Promise.all(selectors.map(s => zeroEx.getFunctionImplementation(s).callAsync())); - for (let i = 0; i < impls.length; ++i) { - const selector = selectors[i]; - const impl = impls[i]; - const feat = new IFeatureContract(impl, env.provider, env.txDefaults); - const featName = ownableSelectors.includes(selector) ? 'Ownable' : 'SimpleFunctionRegistry'; - expect(await feat.FEATURE_NAME().callAsync()).to.eq(featName); - } - }); - }); -}); diff --git a/contracts/zero-ex/tests/BaseTest.sol b/contracts/zero-ex/tests/BaseTest.sol index 1ded630eed..30bf48d3a8 100644 --- a/contracts/zero-ex/tests/BaseTest.sol +++ b/contracts/zero-ex/tests/BaseTest.sol @@ -18,8 +18,11 @@ */ pragma solidity ^0.6.5; +pragma experimental ABIEncoderV2; import "forge-std/Test.sol"; +import "../contracts/src/ZeroEx.sol"; +import "../contracts/src/migrations/InitialMigration.sol"; contract BaseTest is Test { address payable internal account1 = payable(vm.addr(1)); @@ -31,4 +34,19 @@ contract BaseTest is Test { vm.deal(account2, 1e20); vm.deal(account3, 1e20); } + + function getZeroExTestProxy(address payable owner) public returns (ZeroEx zeroEx) { + InitialMigration migrator = new InitialMigration(owner); + zeroEx = new ZeroEx(address(migrator)); + SimpleFunctionRegistryFeature registry = new SimpleFunctionRegistryFeature(); + OwnableFeature ownable = new OwnableFeature(); + + vm.startPrank(owner); + migrator.initializeZeroEx( + owner, + zeroEx, + InitialMigration.BootstrapFeatures({registry: registry, ownable: ownable}) + ); + vm.stopPrank(); + } } diff --git a/contracts/zero-ex/tests/FlashWalletTest.t.sol b/contracts/zero-ex/tests/FlashWalletTest.t.sol index 7e38ce7bf5..219431076e 100644 --- a/contracts/zero-ex/tests/FlashWalletTest.t.sol +++ b/contracts/zero-ex/tests/FlashWalletTest.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 /* - Copyright 2022 ZeroEx Intl. + Copyright 2023 ZeroEx Intl. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ */ pragma solidity ^0.6.5; +pragma experimental ABIEncoderV2; import "./BaseTest.sol"; import "../contracts/src/external/FlashWallet.sol"; diff --git a/contracts/zero-ex/tests/ZeroExTest.t.sol b/contracts/zero-ex/tests/ZeroExTest.t.sol new file mode 100644 index 0000000000..61a05f2de5 --- /dev/null +++ b/contracts/zero-ex/tests/ZeroExTest.t.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + + Copyright 2023 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity ^0.6.5; +pragma experimental ABIEncoderV2; + +import "./BaseTest.sol"; +import "../contracts/src/ZeroEx.sol"; +import "./mocks/TestZeroExFeature.sol"; + +contract ZeroExTest is BaseTest { + address payable public owner = account1; + ZeroEx public zeroEx; + IOwnableFeature public ownable; + ISimpleFunctionRegistryFeature public registry; + TestZeroExFeature public testFeature; + + event PayableFnCalled(uint256 value); + + function setUp() public { + zeroEx = getZeroExTestProxy(owner); + ownable = IOwnableFeature(address(zeroEx)); + registry = ISimpleFunctionRegistryFeature(address(zeroEx)); + TestZeroExFeature testFeatureImplementation = new TestZeroExFeature(); + testFeature = TestZeroExFeature(address(zeroEx)); + + // Register the test feature function on the zero ex proxy + vm.startPrank(owner); + registry.extend(testFeature.payableFn.selector, address(testFeatureImplementation)); + registry.extend(testFeature.notPayableFn.selector, address(testFeatureImplementation)); + registry.extend(testFeature.internalFn.selector, address(testFeatureImplementation)); + vm.stopPrank(); + } + + function test_canReceiveETH() public { + address(zeroEx).call{value: 1}(""); + assertEq(address(zeroEx).balance, 1); + } + + function test_canAttachETHtoACall() public { + vm.expectEmit(false, false, false, true); + emit PayableFnCalled(123); + testFeature.payableFn{value: 123}(); + } + + function test_revertsWhenAttachingETHToANonPayableFunction() public { + vm.expectRevert(); + address(testFeature).call{value: 123}("notPayableFn()"); + } + + function test_revertWhenCallingAnUnimplementedFunction() public { + bytes memory error = LibProxyRichErrors.NotImplementedError(testFeature.unimplementedFn.selector); + vm.expectRevert(error); + testFeature.unimplementedFn(); + } + + function test_revertsWhenCallingInternalFunction() public { + bytes memory error = LibCommonRichErrors.OnlyCallableBySelfError(owner); + vm.expectRevert(error); + vm.startPrank(owner); + testFeature.internalFn(); + } + + function test_getFunctionImplementation_returnsTheCorrectFeaturesImplementations() public { + bytes4 transferOwnershipSelector = ownable.transferOwnership.selector; + address transferOwnershipImplementation = zeroEx.getFunctionImplementation(transferOwnershipSelector); + assertEq(IFeature(transferOwnershipImplementation).FEATURE_NAME(), "Ownable"); + + bytes4 rollbackSelector = registry.rollback.selector; + address rollbackImplementation = zeroEx.getFunctionImplementation(rollbackSelector); + assertEq(IFeature(rollbackImplementation).FEATURE_NAME(), "SimpleFunctionRegistry"); + + bytes4 extendSelector = registry.extend.selector; + address extendImplementation = zeroEx.getFunctionImplementation(extendSelector); + assertEq(IFeature(extendImplementation).FEATURE_NAME(), "SimpleFunctionRegistry"); + } +} diff --git a/contracts/zero-ex/contracts/test/TestZeroExFeature.sol b/contracts/zero-ex/tests/mocks/TestZeroExFeature.sol similarity index 88% rename from contracts/zero-ex/contracts/test/TestZeroExFeature.sol rename to contracts/zero-ex/tests/mocks/TestZeroExFeature.sol index 551508c9f7..342a793db7 100644 --- a/contracts/zero-ex/contracts/test/TestZeroExFeature.sol +++ b/contracts/zero-ex/tests/mocks/TestZeroExFeature.sol @@ -20,8 +20,8 @@ pragma solidity ^0.6.5; pragma experimental ABIEncoderV2; -import "../src/fixins/FixinCommon.sol"; -import "../src/ZeroEx.sol"; +import "../../contracts/src/fixins/FixinCommon.sol"; +import "../../contracts/src/ZeroEx.sol"; contract TestZeroExFeature is FixinCommon { event PayableFnCalled(uint256 value); @@ -35,7 +35,7 @@ contract TestZeroExFeature is FixinCommon { emit NotPayableFnCalled(); } - function unimplmentedFn() external {} + function unimplementedFn() external {} function internalFn() external onlySelf {} } diff --git a/contracts/zero-ex/tsconfig.json b/contracts/zero-ex/tsconfig.json index dc88229614..d7539b26ba 100644 --- a/contracts/zero-ex/tsconfig.json +++ b/contracts/zero-ex/tsconfig.json @@ -234,7 +234,6 @@ "test/generated-artifacts/TestUniswapV3Pool.json", "test/generated-artifacts/TestWeth.json", "test/generated-artifacts/TestWethTransformerHost.json", - "test/generated-artifacts/TestZeroExFeature.json", "test/generated-artifacts/TransformERC20Feature.json", "test/generated-artifacts/Transformer.json", "test/generated-artifacts/TransformerDeployer.json",