@0x/contracts-zero-ex: Address review feedback.
				
					
				
			This commit is contained in:
		@@ -1,65 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
library LibPuppetRichErrors {
 | 
			
		||||
 | 
			
		||||
    // solhint-disable func-name-mixedcase
 | 
			
		||||
 | 
			
		||||
    function PuppetExecuteFailedError(
 | 
			
		||||
        address puppet,
 | 
			
		||||
        address callTarget,
 | 
			
		||||
        bytes memory callData,
 | 
			
		||||
        uint256 callValue,
 | 
			
		||||
        bytes memory errorData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("PuppetExecuteFailedError(address,address,bytes,uint256,bytes)")),
 | 
			
		||||
            puppet,
 | 
			
		||||
            callTarget,
 | 
			
		||||
            callData,
 | 
			
		||||
            callValue,
 | 
			
		||||
            errorData
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function PuppetExecuteWithFailedError(
 | 
			
		||||
        address puppet,
 | 
			
		||||
        address callTarget,
 | 
			
		||||
        bytes memory callData,
 | 
			
		||||
        bytes memory errorData
 | 
			
		||||
    )
 | 
			
		||||
        internal
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes memory)
 | 
			
		||||
    {
 | 
			
		||||
        return abi.encodeWithSelector(
 | 
			
		||||
            bytes4(keccak256("PuppetExecuteWithFailedError(address,address,bytes,bytes)")),
 | 
			
		||||
            puppet,
 | 
			
		||||
            callTarget,
 | 
			
		||||
            callData,
 | 
			
		||||
            errorData
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,61 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  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 "@0x/contracts-utils/contracts/src/v06/interfaces/IOwnableV06.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev A contract that can execute arbitrary calls from its owner.
 | 
			
		||||
interface IPuppet {
 | 
			
		||||
 | 
			
		||||
    /// @dev Execute an arbitrary call. Only an authority can call this.
 | 
			
		||||
    /// @param target The call target.
 | 
			
		||||
    /// @param callData The call data.
 | 
			
		||||
    /// @param value Ether to attach to the call.
 | 
			
		||||
    /// @return resultData The data returned by the call.
 | 
			
		||||
    function execute(
 | 
			
		||||
        address payable target,
 | 
			
		||||
        bytes calldata callData,
 | 
			
		||||
        uint256 value
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (bytes memory resultData);
 | 
			
		||||
 | 
			
		||||
    /// @dev Execute an arbitrary delegatecall, in the context of this puppet.
 | 
			
		||||
    ///      Only an authority can call this.
 | 
			
		||||
    /// @param target The call target.
 | 
			
		||||
    /// @param callData The call data.
 | 
			
		||||
    /// @return resultData The data returned by the call.
 | 
			
		||||
    function executeWith(
 | 
			
		||||
        address payable target,
 | 
			
		||||
        bytes calldata callData
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        returns (bytes memory resultData);
 | 
			
		||||
 | 
			
		||||
    /// @dev Allows the puppet to receive ETH.
 | 
			
		||||
    receive() external payable;
 | 
			
		||||
 | 
			
		||||
    /// @dev Fetch the immutable owner/deployer of this contract.
 | 
			
		||||
    /// @return owner_ The immutable owner/deployer/
 | 
			
		||||
    function owner() external view returns (address owner_);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								contracts/zero-ex/contracts/src/external/Puppet.sol
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										175
									
								
								contracts/zero-ex/contracts/src/external/Puppet.sol
									
									
									
									
										vendored
									
									
								
							@@ -1,175 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  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 "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
			
		||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibOwnableRichErrorsV06.sol";
 | 
			
		||||
import "../errors/LibPuppetRichErrors.sol";
 | 
			
		||||
import "./IPuppet.sol";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// @dev A contract that can execute arbitrary calls from its owner.
 | 
			
		||||
contract Puppet is
 | 
			
		||||
    IPuppet
 | 
			
		||||
{
 | 
			
		||||
    // solhint-disable no-unused-vars,indent,no-empty-blocks
 | 
			
		||||
    using LibRichErrorsV06 for bytes;
 | 
			
		||||
 | 
			
		||||
    // solhint-disable
 | 
			
		||||
    /// @dev Store the owner/deployer as an immutable to make this contract stateless.
 | 
			
		||||
    address public override immutable owner;
 | 
			
		||||
    // solhint-enable
 | 
			
		||||
 | 
			
		||||
    constructor() public {
 | 
			
		||||
        // The deployer is the owner.
 | 
			
		||||
        owner = msg.sender;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Allows only the (immutable) owner to call a function.
 | 
			
		||||
    modifier onlyOwner() virtual {
 | 
			
		||||
        if (msg.sender != owner) {
 | 
			
		||||
            LibOwnableRichErrorsV06.OnlyOwnerError(
 | 
			
		||||
                msg.sender,
 | 
			
		||||
                owner
 | 
			
		||||
            ).rrevert();
 | 
			
		||||
        }
 | 
			
		||||
        _;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Execute an arbitrary call. Only an authority can call this.
 | 
			
		||||
    /// @param target The call target.
 | 
			
		||||
    /// @param callData The call data.
 | 
			
		||||
    /// @param value Ether to attach to the call.
 | 
			
		||||
    /// @return resultData The data returned by the call.
 | 
			
		||||
    function execute(
 | 
			
		||||
        address payable target,
 | 
			
		||||
        bytes calldata callData,
 | 
			
		||||
        uint256 value
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        override
 | 
			
		||||
        onlyOwner
 | 
			
		||||
        returns (bytes memory resultData)
 | 
			
		||||
    {
 | 
			
		||||
        bool success;
 | 
			
		||||
        (success, resultData) = target.call{value: value}(callData);
 | 
			
		||||
        if (!success) {
 | 
			
		||||
            LibPuppetRichErrors
 | 
			
		||||
                .PuppetExecuteFailedError(
 | 
			
		||||
                    address(this),
 | 
			
		||||
                    target,
 | 
			
		||||
                    callData,
 | 
			
		||||
                    value,
 | 
			
		||||
                    resultData
 | 
			
		||||
                )
 | 
			
		||||
                .rrevert();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Execute an arbitrary delegatecall, in the context of this puppet.
 | 
			
		||||
    ///      Only an authority can call this.
 | 
			
		||||
    /// @param target The call target.
 | 
			
		||||
    /// @param callData The call data.
 | 
			
		||||
    /// @return resultData The data returned by the call.
 | 
			
		||||
    function executeWith(
 | 
			
		||||
        address payable target,
 | 
			
		||||
        bytes calldata callData
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        payable
 | 
			
		||||
        override
 | 
			
		||||
        onlyOwner
 | 
			
		||||
        returns (bytes memory resultData)
 | 
			
		||||
    {
 | 
			
		||||
        bool success;
 | 
			
		||||
        (success, resultData) = target.delegatecall(callData);
 | 
			
		||||
        if (!success) {
 | 
			
		||||
            LibPuppetRichErrors
 | 
			
		||||
                .PuppetExecuteWithFailedError(
 | 
			
		||||
                    address(this),
 | 
			
		||||
                    target,
 | 
			
		||||
                    callData,
 | 
			
		||||
                    resultData
 | 
			
		||||
                )
 | 
			
		||||
                .rrevert();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // solhint-disable
 | 
			
		||||
    /// @dev Allows this contract to receive ether.
 | 
			
		||||
    receive() external override payable {}
 | 
			
		||||
    // solhint-enable
 | 
			
		||||
 | 
			
		||||
    /// @dev Signal support for receiving ERC1155 tokens.
 | 
			
		||||
    /// @param interfaceID The interface ID, as per ERC-165 rules.
 | 
			
		||||
    /// @return hasSupport `true` if this contract supports an ERC-165 interface.
 | 
			
		||||
    function supportsInterface(bytes4 interfaceID)
 | 
			
		||||
        external
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bool hasSupport)
 | 
			
		||||
    {
 | 
			
		||||
        return  interfaceID == this.supportsInterface.selector ||
 | 
			
		||||
                interfaceID == this.onERC1155Received.selector ^ this.onERC1155BatchReceived.selector ||
 | 
			
		||||
                interfaceID == this.tokenFallback.selector;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ///  @dev Allow this contract to receive ERC1155 tokens.
 | 
			
		||||
    ///  @return success  `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
 | 
			
		||||
    function onERC1155Received(
 | 
			
		||||
        address, // operator,
 | 
			
		||||
        address, // from,
 | 
			
		||||
        uint256, // id,
 | 
			
		||||
        uint256, // value,
 | 
			
		||||
        bytes calldata //data
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes4 success)
 | 
			
		||||
    {
 | 
			
		||||
        return this.onERC1155Received.selector;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ///  @dev Allow this contract to receive ERC1155 tokens.
 | 
			
		||||
    ///  @return success  `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
 | 
			
		||||
    function onERC1155BatchReceived(
 | 
			
		||||
        address, // operator,
 | 
			
		||||
        address, // from,
 | 
			
		||||
        uint256[] calldata, // ids,
 | 
			
		||||
        uint256[] calldata, // values,
 | 
			
		||||
        bytes calldata // data
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        pure
 | 
			
		||||
        returns (bytes4 success)
 | 
			
		||||
    {
 | 
			
		||||
        return this.onERC1155BatchReceived.selector;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// @dev Allows this contract to receive ERC223 tokens.
 | 
			
		||||
    function tokenFallback(
 | 
			
		||||
        address, // from,
 | 
			
		||||
        uint256, // value,
 | 
			
		||||
        bytes calldata // value
 | 
			
		||||
    )
 | 
			
		||||
        external
 | 
			
		||||
        pure
 | 
			
		||||
    {}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  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 TestPuppetTarget {
 | 
			
		||||
 | 
			
		||||
    event PuppetTargetCalled(
 | 
			
		||||
        address context,
 | 
			
		||||
        address sender,
 | 
			
		||||
        bytes data,
 | 
			
		||||
        uint256 value
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    bytes4 private constant MAGIC_BYTES = 0x12345678;
 | 
			
		||||
    bytes private constant REVERTING_DATA = hex"1337";
 | 
			
		||||
 | 
			
		||||
    fallback() external payable {
 | 
			
		||||
        if (keccak256(msg.data) == keccak256(REVERTING_DATA)) {
 | 
			
		||||
            revert("TestPuppetTarget/REVERT");
 | 
			
		||||
        }
 | 
			
		||||
        emit PuppetTargetCalled(
 | 
			
		||||
            address(this),
 | 
			
		||||
            msg.sender,
 | 
			
		||||
            msg.data,
 | 
			
		||||
            msg.value
 | 
			
		||||
        );
 | 
			
		||||
        bytes4 rval = MAGIC_BYTES;
 | 
			
		||||
        assembly {
 | 
			
		||||
            mstore(0, rval)
 | 
			
		||||
            return(0, 32)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,211 +0,0 @@
 | 
			
		||||
import {
 | 
			
		||||
    blockchainTests,
 | 
			
		||||
    constants,
 | 
			
		||||
    expect,
 | 
			
		||||
    getRandomInteger,
 | 
			
		||||
    randomAddress,
 | 
			
		||||
    verifyEventsFromLogs,
 | 
			
		||||
} from '@0x/contracts-test-utils';
 | 
			
		||||
import { hexUtils, OwnableRevertErrors, StringRevertError, ZeroExRevertErrors } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { artifacts } from './artifacts';
 | 
			
		||||
import { PuppetContract, TestPuppetTargetContract, TestPuppetTargetEvents } from './wrappers';
 | 
			
		||||
 | 
			
		||||
blockchainTests.resets('Puppets', env => {
 | 
			
		||||
    let owner: string;
 | 
			
		||||
    let puppet: PuppetContract;
 | 
			
		||||
    let puppetTarget: TestPuppetTargetContract;
 | 
			
		||||
 | 
			
		||||
    before(async () => {
 | 
			
		||||
        [owner] = await env.getAccountAddressesAsync();
 | 
			
		||||
        puppet = await PuppetContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.Puppet,
 | 
			
		||||
            env.provider,
 | 
			
		||||
            {
 | 
			
		||||
                ...env.txDefaults,
 | 
			
		||||
                from: owner,
 | 
			
		||||
            },
 | 
			
		||||
            artifacts,
 | 
			
		||||
        );
 | 
			
		||||
        puppetTarget = await TestPuppetTargetContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.TestPuppetTarget,
 | 
			
		||||
            env.provider,
 | 
			
		||||
            env.txDefaults,
 | 
			
		||||
            artifacts,
 | 
			
		||||
        );
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const TARGET_RETURN_VALUE = hexUtils.rightPad('0x12345678');
 | 
			
		||||
    const REVERTING_DATA = '0x1337';
 | 
			
		||||
 | 
			
		||||
    it('owned by deployer', () => {
 | 
			
		||||
        return expect(puppet.owner().callAsync()).to.eventually.eq(owner);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe('execute()', () => {
 | 
			
		||||
        it('non-owner cannot call execute()', async () => {
 | 
			
		||||
            const notOwner = randomAddress();
 | 
			
		||||
            const tx = puppet
 | 
			
		||||
                .execute(randomAddress(), hexUtils.random(), getRandomInteger(0, '100e18'))
 | 
			
		||||
                .callAsync({ from: notOwner });
 | 
			
		||||
            return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('owner can call execute()', async () => {
 | 
			
		||||
            const targetData = hexUtils.random(128);
 | 
			
		||||
            const receipt = await puppet
 | 
			
		||||
                .execute(puppetTarget.address, targetData, constants.ZERO_AMOUNT)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: owner });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [
 | 
			
		||||
                    {
 | 
			
		||||
                        context: puppetTarget.address,
 | 
			
		||||
                        sender: puppet.address,
 | 
			
		||||
                        data: targetData,
 | 
			
		||||
                        value: constants.ZERO_AMOUNT,
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                TestPuppetTargetEvents.PuppetTargetCalled,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('owner can call execute() with attached ETH', async () => {
 | 
			
		||||
            const targetData = hexUtils.random(128);
 | 
			
		||||
            const callValue = getRandomInteger(1, '1e18');
 | 
			
		||||
            const receipt = await puppet
 | 
			
		||||
                .execute(puppetTarget.address, targetData, callValue)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: owner, value: callValue });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [
 | 
			
		||||
                    {
 | 
			
		||||
                        context: puppetTarget.address,
 | 
			
		||||
                        sender: puppet.address,
 | 
			
		||||
                        data: targetData,
 | 
			
		||||
                        value: callValue,
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                TestPuppetTargetEvents.PuppetTargetCalled,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('owner can call execute() can transfer less ETH than attached', async () => {
 | 
			
		||||
            const targetData = hexUtils.random(128);
 | 
			
		||||
            const callValue = getRandomInteger(1, '1e18');
 | 
			
		||||
            const receipt = await puppet
 | 
			
		||||
                .execute(puppetTarget.address, targetData, callValue.minus(1))
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: owner, value: callValue });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [
 | 
			
		||||
                    {
 | 
			
		||||
                        context: puppetTarget.address,
 | 
			
		||||
                        sender: puppet.address,
 | 
			
		||||
                        data: targetData,
 | 
			
		||||
                        value: callValue.minus(1),
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                TestPuppetTargetEvents.PuppetTargetCalled,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('puppet returns call result', async () => {
 | 
			
		||||
            const result = await puppet
 | 
			
		||||
                .execute(puppetTarget.address, hexUtils.random(128), constants.ZERO_AMOUNT)
 | 
			
		||||
                .callAsync({ from: owner });
 | 
			
		||||
            expect(result).to.eq(TARGET_RETURN_VALUE);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('puppet wraps call revert', async () => {
 | 
			
		||||
            const tx = puppet
 | 
			
		||||
                .execute(puppetTarget.address, REVERTING_DATA, constants.ZERO_AMOUNT)
 | 
			
		||||
                .callAsync({ from: owner });
 | 
			
		||||
            return expect(tx).to.revertWith(
 | 
			
		||||
                new ZeroExRevertErrors.Puppet.PuppetExecuteFailedError(
 | 
			
		||||
                    puppet.address,
 | 
			
		||||
                    puppetTarget.address,
 | 
			
		||||
                    REVERTING_DATA,
 | 
			
		||||
                    constants.ZERO_AMOUNT,
 | 
			
		||||
                    new StringRevertError('TestPuppetTarget/REVERT').encode(),
 | 
			
		||||
                ),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('puppet can receive ETH', async () => {
 | 
			
		||||
            await env.web3Wrapper.sendTransactionAsync({
 | 
			
		||||
                to: puppet.address,
 | 
			
		||||
                from: owner,
 | 
			
		||||
                value: 1,
 | 
			
		||||
            });
 | 
			
		||||
            const bal = await env.web3Wrapper.getBalanceInWeiAsync(puppet.address);
 | 
			
		||||
            expect(bal).to.bignumber.eq(1);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    describe('executeWith()', () => {
 | 
			
		||||
        it('non-owner cannot call executeWith()', async () => {
 | 
			
		||||
            const notOwner = randomAddress();
 | 
			
		||||
            const tx = puppet.executeWith(randomAddress(), hexUtils.random()).callAsync({ from: notOwner });
 | 
			
		||||
            return expect(tx).to.revertWith(new OwnableRevertErrors.OnlyOwnerError(notOwner));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('owner can call executeWith()', async () => {
 | 
			
		||||
            const targetData = hexUtils.random(128);
 | 
			
		||||
            const receipt = await puppet
 | 
			
		||||
                .executeWith(puppetTarget.address, targetData)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: owner });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [
 | 
			
		||||
                    {
 | 
			
		||||
                        context: puppet.address,
 | 
			
		||||
                        sender: owner,
 | 
			
		||||
                        data: targetData,
 | 
			
		||||
                        value: constants.ZERO_AMOUNT,
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                TestPuppetTargetEvents.PuppetTargetCalled,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('executeWith() is payable', async () => {
 | 
			
		||||
            const targetData = hexUtils.random(128);
 | 
			
		||||
            const callValue = getRandomInteger(1, '1e18');
 | 
			
		||||
            const receipt = await puppet
 | 
			
		||||
                .executeWith(puppetTarget.address, targetData)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: owner, value: callValue });
 | 
			
		||||
            verifyEventsFromLogs(
 | 
			
		||||
                receipt.logs,
 | 
			
		||||
                [
 | 
			
		||||
                    {
 | 
			
		||||
                        context: puppet.address,
 | 
			
		||||
                        sender: owner,
 | 
			
		||||
                        data: targetData,
 | 
			
		||||
                        value: callValue,
 | 
			
		||||
                    },
 | 
			
		||||
                ],
 | 
			
		||||
                TestPuppetTargetEvents.PuppetTargetCalled,
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('puppet returns call result', async () => {
 | 
			
		||||
            const result = await puppet
 | 
			
		||||
                .executeWith(puppetTarget.address, hexUtils.random(128))
 | 
			
		||||
                .callAsync({ from: owner });
 | 
			
		||||
            expect(result).to.eq(TARGET_RETURN_VALUE);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('puppet wraps call revert', async () => {
 | 
			
		||||
            const tx = puppet.executeWith(puppetTarget.address, REVERTING_DATA).callAsync({ from: owner });
 | 
			
		||||
            return expect(tx).to.revertWith(
 | 
			
		||||
                new ZeroExRevertErrors.Puppet.PuppetExecuteWithFailedError(
 | 
			
		||||
                    puppet.address,
 | 
			
		||||
                    puppetTarget.address,
 | 
			
		||||
                    REVERTING_DATA,
 | 
			
		||||
                    new StringRevertError('TestPuppetTarget/REVERT').encode(),
 | 
			
		||||
                ),
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user