add permissionless transformer deployer (#55)
* add permissionless transformer deployer
This commit is contained in:
parent
6307ebc3a2
commit
012fff46f6
@ -49,6 +49,10 @@
|
|||||||
{
|
{
|
||||||
"note": "Remove calldata signing functionality",
|
"note": "Remove calldata signing functionality",
|
||||||
"pr": 51
|
"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": {
|
"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",
|
"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: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": {
|
"repository": {
|
||||||
"type": "git",
|
"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 NativeOrdersFeature from '../test/generated-artifacts/NativeOrdersFeature.json';
|
||||||
import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json';
|
import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json';
|
||||||
import * as PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.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 SignatureValidatorFeature from '../test/generated-artifacts/SignatureValidatorFeature.json';
|
||||||
import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json';
|
import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json';
|
||||||
import * as TestBridge from '../test/generated-artifacts/TestBridge.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 TestMintableERC20Token from '../test/generated-artifacts/TestMintableERC20Token.json';
|
||||||
import * as TestMintTokenERC20Transformer from '../test/generated-artifacts/TestMintTokenERC20Transformer.json';
|
import * as TestMintTokenERC20Transformer from '../test/generated-artifacts/TestMintTokenERC20Transformer.json';
|
||||||
import * as TestNativeOrdersFeature from '../test/generated-artifacts/TestNativeOrdersFeature.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 TestRfqOriginRegistration from '../test/generated-artifacts/TestRfqOriginRegistration.json';
|
||||||
import * as TestSimpleFunctionRegistryFeatureImpl1 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json';
|
import * as TestSimpleFunctionRegistryFeatureImpl1 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json';
|
||||||
import * as TestSimpleFunctionRegistryFeatureImpl2 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json';
|
import * as TestSimpleFunctionRegistryFeatureImpl2 from '../test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json';
|
||||||
@ -152,6 +155,7 @@ export const artifacts = {
|
|||||||
IFlashWallet: IFlashWallet as ContractArtifact,
|
IFlashWallet: IFlashWallet as ContractArtifact,
|
||||||
ILiquidityProviderSandbox: ILiquidityProviderSandbox as ContractArtifact,
|
ILiquidityProviderSandbox: ILiquidityProviderSandbox as ContractArtifact,
|
||||||
LiquidityProviderSandbox: LiquidityProviderSandbox as ContractArtifact,
|
LiquidityProviderSandbox: LiquidityProviderSandbox as ContractArtifact,
|
||||||
|
PermissionlessTransformerDeployer: PermissionlessTransformerDeployer as ContractArtifact,
|
||||||
TransformerDeployer: TransformerDeployer as ContractArtifact,
|
TransformerDeployer: TransformerDeployer as ContractArtifact,
|
||||||
BootstrapFeature: BootstrapFeature as ContractArtifact,
|
BootstrapFeature: BootstrapFeature as ContractArtifact,
|
||||||
IBootstrapFeature: IBootstrapFeature as ContractArtifact,
|
IBootstrapFeature: IBootstrapFeature as ContractArtifact,
|
||||||
@ -243,6 +247,8 @@ export const artifacts = {
|
|||||||
TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact,
|
TestMintTokenERC20Transformer: TestMintTokenERC20Transformer as ContractArtifact,
|
||||||
TestMintableERC20Token: TestMintableERC20Token as ContractArtifact,
|
TestMintableERC20Token: TestMintableERC20Token as ContractArtifact,
|
||||||
TestNativeOrdersFeature: TestNativeOrdersFeature as ContractArtifact,
|
TestNativeOrdersFeature: TestNativeOrdersFeature as ContractArtifact,
|
||||||
|
TestPermissionlessTransformerDeployerSuicidal: TestPermissionlessTransformerDeployerSuicidal as ContractArtifact,
|
||||||
|
TestPermissionlessTransformerDeployerTransformer: TestPermissionlessTransformerDeployerTransformer as ContractArtifact,
|
||||||
TestRfqOriginRegistration: TestRfqOriginRegistration as ContractArtifact,
|
TestRfqOriginRegistration: TestRfqOriginRegistration as ContractArtifact,
|
||||||
TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact,
|
TestSimpleFunctionRegistryFeatureImpl1: TestSimpleFunctionRegistryFeatureImpl1 as ContractArtifact,
|
||||||
TestSimpleFunctionRegistryFeatureImpl2: TestSimpleFunctionRegistryFeatureImpl2 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/native_orders_feature';
|
||||||
export * from '../test/generated-wrappers/ownable_feature';
|
export * from '../test/generated-wrappers/ownable_feature';
|
||||||
export * from '../test/generated-wrappers/pay_taker_transformer';
|
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/signature_validator_feature';
|
||||||
export * from '../test/generated-wrappers/simple_function_registry_feature';
|
export * from '../test/generated-wrappers/simple_function_registry_feature';
|
||||||
export * from '../test/generated-wrappers/test_bridge';
|
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_mint_token_erc20_transformer';
|
||||||
export * from '../test/generated-wrappers/test_mintable_erc20_token';
|
export * from '../test/generated-wrappers/test_mintable_erc20_token';
|
||||||
export * from '../test/generated-wrappers/test_native_orders_feature';
|
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_rfq_origin_registration';
|
||||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl1';
|
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl1';
|
||||||
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl2';
|
export * from '../test/generated-wrappers/test_simple_function_registry_feature_impl2';
|
||||||
|
@ -113,6 +113,7 @@
|
|||||||
"test/generated-artifacts/NativeOrdersFeature.json",
|
"test/generated-artifacts/NativeOrdersFeature.json",
|
||||||
"test/generated-artifacts/OwnableFeature.json",
|
"test/generated-artifacts/OwnableFeature.json",
|
||||||
"test/generated-artifacts/PayTakerTransformer.json",
|
"test/generated-artifacts/PayTakerTransformer.json",
|
||||||
|
"test/generated-artifacts/PermissionlessTransformerDeployer.json",
|
||||||
"test/generated-artifacts/SignatureValidatorFeature.json",
|
"test/generated-artifacts/SignatureValidatorFeature.json",
|
||||||
"test/generated-artifacts/SimpleFunctionRegistryFeature.json",
|
"test/generated-artifacts/SimpleFunctionRegistryFeature.json",
|
||||||
"test/generated-artifacts/TestBridge.json",
|
"test/generated-artifacts/TestBridge.json",
|
||||||
@ -134,6 +135,8 @@
|
|||||||
"test/generated-artifacts/TestMintTokenERC20Transformer.json",
|
"test/generated-artifacts/TestMintTokenERC20Transformer.json",
|
||||||
"test/generated-artifacts/TestMintableERC20Token.json",
|
"test/generated-artifacts/TestMintableERC20Token.json",
|
||||||
"test/generated-artifacts/TestNativeOrdersFeature.json",
|
"test/generated-artifacts/TestNativeOrdersFeature.json",
|
||||||
|
"test/generated-artifacts/TestPermissionlessTransformerDeployerSuicidal.json",
|
||||||
|
"test/generated-artifacts/TestPermissionlessTransformerDeployerTransformer.json",
|
||||||
"test/generated-artifacts/TestRfqOriginRegistration.json",
|
"test/generated-artifacts/TestRfqOriginRegistration.json",
|
||||||
"test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json",
|
"test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl1.json",
|
||||||
"test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json",
|
"test/generated-artifacts/TestSimpleFunctionRegistryFeatureImpl2.json",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user