add permissionless transformer deployer (#55)
* add permissionless transformer deployer
This commit is contained in:
		@@ -49,6 +49,10 @@
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Remove calldata signing functionality",
 | 
			
		||||
                "pr": 51
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
                "note": "Add a permissionless transformer deployer",
 | 
			
		||||
                "pr": 55
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										114
									
								
								contracts/zero-ex/contracts/src/external/PermissionlessTransformerDeployer.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								contracts/zero-ex/contracts/src/external/PermissionlessTransformerDeployer.sol
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev Deployer contract for ERC20 transformers.
 | 
			
		||||
contract PermissionlessTransformerDeployer {
 | 
			
		||||
    /// @dev Emitted when a contract is deployed via `deploy()`.
 | 
			
		||||
    /// @param deployedAddress The address of the deployed contract.
 | 
			
		||||
    /// @param salt The deployment salt.
 | 
			
		||||
    /// @param sender The caller of `deploy()`.
 | 
			
		||||
    event Deployed(address deployedAddress, bytes32 salt, address sender);
 | 
			
		||||
 | 
			
		||||
    // @dev Mapping of deployed contract address to the deployment salt.
 | 
			
		||||
    mapping (address => bytes32) public toDeploymentSalt;
 | 
			
		||||
    // @dev Mapping of deployed contract address to the init code hash.
 | 
			
		||||
    mapping (address => bytes32) public toInitCodeHash;
 | 
			
		||||
 | 
			
		||||
    /// @dev Deploy a new contract. Any attached ETH will be forwarded.
 | 
			
		||||
    function deploy(bytes memory bytecode, bytes32 salt)
 | 
			
		||||
        public
 | 
			
		||||
        payable
 | 
			
		||||
        returns (address deployedAddress)
 | 
			
		||||
    {
 | 
			
		||||
        assembly {
 | 
			
		||||
            deployedAddress := create2(callvalue(), add(bytecode, 32), mload(bytecode), salt)
 | 
			
		||||
        }
 | 
			
		||||
        require(deployedAddress != address(0), 'PermissionlessTransformerDeployer/DEPLOY_FAILED');
 | 
			
		||||
        require(isDelegateCallSafe(deployedAddress), 'PermissionlessTransformerDeployer/UNSAFE_CODE');
 | 
			
		||||
        toDeploymentSalt[deployedAddress] = salt;
 | 
			
		||||
        toInitCodeHash[deployedAddress] = keccak256(bytecode);
 | 
			
		||||
        emit Deployed(deployedAddress, salt, msg.sender);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Checks whether a given address is safe to be called via
 | 
			
		||||
    ///      delegatecall. A contract is considered unsafe if it includes any
 | 
			
		||||
    ///      of the following opcodes: CALLCODE, DELEGATECALL, SELFDESTRUCT,
 | 
			
		||||
    ///      CREATE, CREATE2, SLOAD, and STORE. This code is adapted from
 | 
			
		||||
    ///      https://github.com/dharma-eng/dharma-smart-wallet/blob/master/contracts/helpers/IndestructibleRegistry.sol
 | 
			
		||||
    /// @param target The address to check.
 | 
			
		||||
    /// @return True if the contract is considered safe for delegatecall.
 | 
			
		||||
    function isDelegateCallSafe(address target) public view returns (bool) {
 | 
			
		||||
        uint256 size;
 | 
			
		||||
        assembly { size := extcodesize(target) }
 | 
			
		||||
        require(size > 0, 'PermissionlessTransformerDeployer/NO_CODE');
 | 
			
		||||
 | 
			
		||||
        bytes memory extcode = new bytes(size);
 | 
			
		||||
        assembly {
 | 
			
		||||
            extcodecopy(target, add(extcode, 32), 0, size)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Look for any reachable, impermissible opcodes.
 | 
			
		||||
        bool reachable = true;
 | 
			
		||||
        for (uint256 i = 0; i < extcode.length; i++) {
 | 
			
		||||
            uint8 op = uint8(extcode[i]);
 | 
			
		||||
 | 
			
		||||
            // If the opcode is a PUSH, skip over the push data.
 | 
			
		||||
            if (op > 95 && op < 128) { // pushN
 | 
			
		||||
                i += (op - 95);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (reachable) {
 | 
			
		||||
                // If execution is halted, mark subsequent opcodes unreachable.
 | 
			
		||||
                if (
 | 
			
		||||
                    op == 254 || // invalid
 | 
			
		||||
                    op == 243 || // return
 | 
			
		||||
                    op == 253 || // revert
 | 
			
		||||
                    op == 86  || // jump
 | 
			
		||||
                    op == 0      // stop
 | 
			
		||||
                ) {
 | 
			
		||||
                    reachable = false;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // If opcode is impermissible, contract is unsafe.
 | 
			
		||||
                if (
 | 
			
		||||
                    op == 242 || // callcode
 | 
			
		||||
                    op == 244 || // delegatecall
 | 
			
		||||
                    op == 255 || // selfdestruct
 | 
			
		||||
                    op == 240 || // create
 | 
			
		||||
                    op == 245 || // create2
 | 
			
		||||
                    op == 84  || // sload
 | 
			
		||||
                    op == 85     // sstore
 | 
			
		||||
                ) {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (op == 91) { // jumpdest
 | 
			
		||||
                // After a JUMPDEST, opcodes are reachable again.
 | 
			
		||||
                reachable = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true; // No impermissible opcodes found.
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -0,0 +1,27 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestPermissionlessTransformerDeployerSuicidal {
 | 
			
		||||
    function kill() external {
 | 
			
		||||
        selfdestruct(msg.sender);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  Copyright 2020 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 "../src/transformers/LibERC20Transformer.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
contract TestPermissionlessTransformerDeployerTransformer {
 | 
			
		||||
    uint256 public constant CONSTRUCTOR_FAIL_VALUE = 3333;
 | 
			
		||||
    address payable public immutable deployer;
 | 
			
		||||
 | 
			
		||||
    constructor() public payable {
 | 
			
		||||
        deployer = msg.sender;
 | 
			
		||||
        require(
 | 
			
		||||
            msg.value != CONSTRUCTOR_FAIL_VALUE,
 | 
			
		||||
            "TestTransformerDeployerTransformer/CONSTRUCTOR_FAIL"
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
    "config": {
 | 
			
		||||
        "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IAllowanceTarget,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITokenSpenderFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,TokenSpenderFeature,AffiliateFeeTransformer,SignatureValidatorFeature,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature",
 | 
			
		||||
        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|INativeOrdersFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|NativeOrdersFeature|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestNativeOrdersFeature|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
			
		||||
        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|INativeOrdersFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|NativeOrdersFeature|OwnableFeature|PayTakerTransformer|PermissionlessTransformerDeployer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestNativeOrdersFeature|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
			
		||||
    },
 | 
			
		||||
    "repository": {
 | 
			
		||||
        "type": "git",
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ import * as MixinZeroExBridge from '../test/generated-artifacts/MixinZeroExBridg
 | 
			
		||||
import * as NativeOrdersFeature from '../test/generated-artifacts/NativeOrdersFeature.json';
 | 
			
		||||
import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json';
 | 
			
		||||
import * as PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.json';
 | 
			
		||||
import * as PermissionlessTransformerDeployer from '../test/generated-artifacts/PermissionlessTransformerDeployer.json';
 | 
			
		||||
import * as SignatureValidatorFeature from '../test/generated-artifacts/SignatureValidatorFeature.json';
 | 
			
		||||
import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json';
 | 
			
		||||
import * as TestBridge from '../test/generated-artifacts/TestBridge.json';
 | 
			
		||||
@@ -109,6 +110,8 @@ import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json';
 | 
			
		||||
import * as TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json';
 | 
			
		||||
import * as TestMintTokenERC20Transformer from '../test/generated-artifacts/TestMintTokenERC20Transformer.json';
 | 
			
		||||
import * as TestNativeOrdersFeature from '../test/generated-artifacts/TestNativeOrdersFeature.json';
 | 
			
		||||
import * as TestPermissionlessTransformerDeployerSuicidal from '../test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json';
 | 
			
		||||
import * as TestPermissionlessTransformerDeployerTransformer from '../test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json';
 | 
			
		||||
import * as TestRfqOriginRegistration from '../test/generated-artifacts/TestRfqOriginRegistration.json';
 | 
			
		||||
import * as TestSimpleFunctionRegistryFeatureImpl1 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json';
 | 
			
		||||
import * as TestSimpleFunctionRegistryFeatureImpl2 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json';
 | 
			
		||||
@@ -152,6 +155,7 @@ export const artifacts = {
 | 
			
		||||
    IFlashWallet: IFlashWallet as ContractArtifact,
 | 
			
		||||
    ILiquidityProviderSandbox: ILiquidityProviderSandbox as ContractArtifact,
 | 
			
		||||
    LiquidityProviderSandbox: LiquidityProviderSandbox as ContractArtifact,
 | 
			
		||||
    PermissionlessTransformerDeployer: PermissionlessTransformerDeployer as ContractArtifact,
 | 
			
		||||
    TransformerDeployer: TransformerDeployer as ContractArtifact,
 | 
			
		||||
    BootstrapFeature: BootstrapFeature as ContractArtifact,
 | 
			
		||||
    IBootstrapFeature: IBootstrapFeature as ContractArtifact,
 | 
			
		||||
@@ -243,6 +247,8 @@ export const artifacts = {
 | 
			
		||||
    TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact,
 | 
			
		||||
    TestMintableERC20Token: TestMintableERC20Token as ContractArtifact,
 | 
			
		||||
    TestNativeOrdersFeature: TestNativeOrdersFeature as ContractArtifact,
 | 
			
		||||
    TestPermissionlessTransformerDeployerSuicidal: TestPermissionlessTransformerDeployerSuicidal as ContractArtifact,
 | 
			
		||||
    TestPermissionlessTransformerDeployerTransformer: TestPermissionlessTransformerDeployerTransformer as ContractArtifact,
 | 
			
		||||
    TestRfqOriginRegistration: TestRfqOriginRegistration as ContractArtifact,
 | 
			
		||||
    TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact,
 | 
			
		||||
    TestSimpleFunctionRegistryFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2 as ContractArtifact,
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,102 @@
 | 
			
		||||
import { blockchainTests, expect, verifyEventsFromLogs } from '@0x/contracts-test-utils';
 | 
			
		||||
import { BigNumber, hexUtils } from '@0x/utils';
 | 
			
		||||
import * as ethjs from 'ethereumjs-util';
 | 
			
		||||
 | 
			
		||||
import { artifacts } from './artifacts';
 | 
			
		||||
import {
 | 
			
		||||
    PermissionlessTransformerDeployerContract,
 | 
			
		||||
    PermissionlessTransformerDeployerEvents,
 | 
			
		||||
    TestPermissionlessTransformerDeployerTransformerContract,
 | 
			
		||||
} from './wrappers';
 | 
			
		||||
 | 
			
		||||
blockchainTests.resets('PermissionlessTransformerDeployer', env => {
 | 
			
		||||
    let owner: string;
 | 
			
		||||
    let sender: string;
 | 
			
		||||
    let deployer: PermissionlessTransformerDeployerContract;
 | 
			
		||||
    const deployBytes = artifacts.TestPermissionlessTransformerDeployerTransformer.compilerOutput.evm.bytecode.object;
 | 
			
		||||
 | 
			
		||||
    before(async () => {
 | 
			
		||||
        [owner, sender] = await env.getAccountAddressesAsync();
 | 
			
		||||
        deployer = await PermissionlessTransformerDeployerContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.PermissionlessTransformerDeployer,
 | 
			
		||||
            env.provider,
 | 
			
		||||
            env.txDefaults,
 | 
			
		||||
            artifacts,
 | 
			
		||||
        );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe('deploy()', () => {
 | 
			
		||||
        it('can deploy safe contract', async () => {
 | 
			
		||||
            const salt = hexUtils.random();
 | 
			
		||||
            const targetAddress = await deployer.deploy(deployBytes, salt).callAsync();
 | 
			
		||||
            const target = new TestPermissionlessTransformerDeployerTransformerContract(targetAddress, env.provider);
 | 
			
		||||
            const receipt = await deployer.deploy(deployBytes, salt).awaitTransactionSuccessAsync({ from: sender });
 | 
			
		||||
            expect(await target.deployer().callAsync()).to.eq(deployer.address);
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [{ deployedAddress: targetAddress, salt, sender }],
 | 
			
		||||
                PermissionlessTransformerDeployerEvents.Deployed,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('deploys at predictable address', async () => {
 | 
			
		||||
            const salt = hexUtils.random();
 | 
			
		||||
            const targetAddress = await deployer.deploy(deployBytes, salt).callAsync();
 | 
			
		||||
            const initCodeHash = hexUtils.toHex(ethjs.sha3(deployBytes));
 | 
			
		||||
            const expectedAddress = hexUtils.slice(
 | 
			
		||||
                hexUtils.toHex(ethjs.sha3(hexUtils.concat('0xFF', deployer.address, salt, initCodeHash))),
 | 
			
		||||
                12,
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            expect(targetAddress).to.eq(expectedAddress);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('cannot deploy suicidal contract', async () => {
 | 
			
		||||
            const suicidalDeployBytes =
 | 
			
		||||
                artifacts.TestPermissionlessTransformerDeployerSuicidal.compilerOutput.evm.bytecode.object;
 | 
			
		||||
 | 
			
		||||
            const tx = deployer.deploy(suicidalDeployBytes, hexUtils.random()).awaitTransactionSuccessAsync();
 | 
			
		||||
            expect(tx).to.revertWith('PermissionlessTransformerDeployer/UNSAFE_CODE');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('can deploy safe contract with value', async () => {
 | 
			
		||||
            const salt = hexUtils.random();
 | 
			
		||||
            const targetAddress = await deployer.deploy(deployBytes, salt).callAsync({ from: sender, value: 1 });
 | 
			
		||||
            const target = new TestPermissionlessTransformerDeployerTransformerContract(targetAddress, env.provider);
 | 
			
		||||
            const receipt = await deployer
 | 
			
		||||
                .deploy(deployBytes, salt)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: sender, value: 1 });
 | 
			
		||||
            expect(await target.deployer().callAsync()).to.eq(deployer.address);
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [{ deployedAddress: targetAddress, salt, sender }],
 | 
			
		||||
                PermissionlessTransformerDeployerEvents.Deployed,
 | 
			
		||||
            );
 | 
			
		||||
            expect(await env.web3Wrapper.getBalanceInWeiAsync(targetAddress)).to.bignumber.eq(1);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('reverts if constructor throws', async () => {
 | 
			
		||||
            const CONSTRUCTOR_FAIL_VALUE = new BigNumber(3333);
 | 
			
		||||
            const tx = deployer
 | 
			
		||||
                .deploy(deployBytes, hexUtils.random())
 | 
			
		||||
                .callAsync({ value: CONSTRUCTOR_FAIL_VALUE, from: sender });
 | 
			
		||||
            return expect(tx).to.revertWith('PermissionlessTransformerDeployer/DEPLOY_FAILED');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('can retrieve deployment salt from contract address', async () => {
 | 
			
		||||
            const salt = hexUtils.random();
 | 
			
		||||
            const targetAddress = await deployer.deploy(deployBytes, salt).callAsync({ from: sender });
 | 
			
		||||
            await deployer.deploy(deployBytes, salt).awaitTransactionSuccessAsync({ from: sender });
 | 
			
		||||
            expect(await deployer.toDeploymentSalt(targetAddress).callAsync()).to.eq(salt);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('can retrieve deployment init code hash from contract address', async () => {
 | 
			
		||||
            const salt = hexUtils.random();
 | 
			
		||||
            const targetAddress = await deployer.deploy(deployBytes, salt).callAsync({ from: sender });
 | 
			
		||||
            await deployer.deploy(deployBytes, salt).awaitTransactionSuccessAsync({ from: sender });
 | 
			
		||||
            expect(hexUtils.toHex(await deployer.toInitCodeHash(targetAddress).callAsync())).to.eq(
 | 
			
		||||
                hexUtils.toHex(ethjs.sha3(deployBytes)),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
@@ -86,6 +86,7 @@ export * from '../test/generated-wrappers/mixin_zero_ex_bridge';
 | 
			
		||||
export * from '../test/generated-wrappers/native_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/ownable_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/pay_taker_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/permissionless_transformer_deployer';
 | 
			
		||||
export * from '../test/generated-wrappers/signature_validator_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/simple_function_registry_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/test_bridge';
 | 
			
		||||
@@ -107,6 +108,8 @@ export * from '../test/generated-wrappers/test_migrator';
 | 
			
		||||
export * from '../test/generated-wrappers/test_mint_token_erc20_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/test_mintable_erc20_token';
 | 
			
		||||
export * from '../test/generated-wrappers/test_native_orders_feature';
 | 
			
		||||
export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_suicidal';
 | 
			
		||||
export * from '../test/generated-wrappers/test_permissionless_transformer_deployer_transformer';
 | 
			
		||||
export * from '../test/generated-wrappers/test_rfq_origin_registration';
 | 
			
		||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl1';
 | 
			
		||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl2';
 | 
			
		||||
 
 | 
			
		||||
@@ -113,6 +113,7 @@
 | 
			
		||||
        "test/generated-artifacts/NativeOrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/OwnableFeature.json",
 | 
			
		||||
        "test/generated-artifacts/PayTakerTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/PermissionlessTransformerDeployer.json",
 | 
			
		||||
        "test/generated-artifacts/SignatureValidatorFeature.json",
 | 
			
		||||
        "test/generated-artifacts/SimpleFunctionRegistryFeature.json",
 | 
			
		||||
        "test/generated-artifacts/TestBridge.json",
 | 
			
		||||
@@ -134,6 +135,8 @@
 | 
			
		||||
        "test/generated-artifacts/TestMintTokenERC20Transformer.json",
 | 
			
		||||
        "test/generated-artifacts/TestMintableERC20Token.json",
 | 
			
		||||
        "test/generated-artifacts/TestNativeOrdersFeature.json",
 | 
			
		||||
        "test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json",
 | 
			
		||||
        "test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json",
 | 
			
		||||
        "test/generated-artifacts/TestRfqOriginRegistration.json",
 | 
			
		||||
        "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json",
 | 
			
		||||
        "test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user