protocol/contracts/zero-ex/tests/utils/DeployZeroEx.sol
Noah Khamliche f87f5a40c0
Feat/Add Foundry Testing Environment s[TKR-525] (#555)
* added initial foundry transformERC20 tests

* added foundry tests into CircleCI flow

* add verbosity for failing tests in CI

* revert wrong CI commands

* feat: Foundry, added some more deployments (#558)

* Added some more deployments

* Rename WETH9 to WETH9V06

* Set to 0.6.x

* fix typo

* remove commit with bad prettier changes

* working bridge Fills through weth transformer

* remove unused reference

* clean up tests

* added working otc fill through transformERC20 in FQT

* resolve file imports, add samplers, arbitrumBridgeAdatper, and new FQT version

* add extra 'v' for debugging verbosity

* add extra 'v' for debugging verbosity in circleci config

* remove old traces

* refactor rpc's out of foundry.toml and into .env for CI compatibility

* remove verbosity from CI command as its now defined in foundry.toml

* setup rpc's

* ignore foundry artifacts in prettier

* change naming in prettierignore

* move /samplers to the tests subdirectory, modify remappings to reflext change

* one more try 🤞

* change CI steps

* remove yarn from CI step

* get to the right directory

* update foundry before tests

* fix tip() deprecation and use deal()

* use deal() instead of vm.deal()

* try to get foundry to have the right directory structure by updating it

* I HATE THIS

* remove foundryup

* Fix prettier issues

* Remove obsoleted import

* Use forge native commands to
install deps and test and add the --root option

* Try using forge with working-directory flag in CI

* Use nightly foundry docker image

* Update rpc endpoints config in foundry

* move tests into /forked and /local

* rename tests

* add foundry profiles to CI

* try to fix CI

* 🔧 add foundry local and forked tests to workflow

* prettier and lint

* revert deps update

* remove all samplers and add uniswapV2 sampler to ForkUtils

* address jacobs comments

* cleanup and comment

* prettier and lint

* bump contracts-zero-ex version

* set func-name-mixedcase to off in solhint for elenas new changes

* max line length to warn

* add --fix for check-md

* Update ci.yml

* fix some nitpcks and leftover code

* fix inconsistent naming

* fix bridge adapter reverts and foundry cache

* migrate foundry integration tests to /tests

* refactor contract-addresses to use the contract-addresses package style nested json

* fix solhint

* fix contract linting errors

* dont check broken links in libraries

* move forge order in gh action for testing

* add env instead of vars

* try again

* fix github actions ordering

* update licence and address comments

* remove verbosity from foundry.toml

* fix contract lint

* move back to emitting an event until samplers can be integrated as some chains dont have uniswap as a source

* add uniswap v3 sampling code for future use

* remove uniswap v3 code as its not used

* fix lint

Co-authored-by: Noah Khamliche <0xnoah@Noahs-MacBook-Pro-2.local>
Co-authored-by: Jacob Evans <jacob@dekz.net>
Co-authored-by: elenadimitrova <elena@arenabg.com>
2023-01-26 20:11:16 -05:00

300 lines
15 KiB
Solidity

// 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;
pragma experimental ABIEncoderV2;
import "forge-std/Test.sol";
import "src/IZeroEx.sol";
import "src/ZeroEx.sol";
import "src/migrations/InitialMigration.sol";
import "src/features/OwnableFeature.sol";
import "src/features/SimpleFunctionRegistryFeature.sol";
import "src/features/NativeOrdersFeature.sol";
import "src/features/BatchFillNativeOrdersFeature.sol";
import "src/features/FundRecoveryFeature.sol";
import "src/features/TransformERC20Feature.sol";
import "src/features/OtcOrdersFeature.sol";
import "src/features/MetaTransactionsFeature.sol";
import "src/features/nft_orders/ERC1155OrdersFeature.sol";
import "src/features/nft_orders/ERC721OrdersFeature.sol";
import "src/features/UniswapFeature.sol";
import "src/features/multiplex/MultiplexFeature.sol";
import "src/external/TransformerDeployer.sol";
import "src/external/FeeCollectorController.sol";
import "src/transformers/WethTransformer.sol";
import "src/transformers/FillQuoteTransformer.sol";
import "src/transformers/PayTakerTransformer.sol";
import "src/transformers/AffiliateFeeTransformer.sol";
import "src/transformers/PositiveSlippageFeeTransformer.sol";
import "src/transformers/bridges/IBridgeAdapter.sol";
import "src/transformers/bridges/EthereumBridgeAdapter.sol";
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
import "@0x/contracts-erc20/contracts/src/v06/WETH9V06.sol";
contract DeployZeroEx is Test {
ZeroEx public ZERO_EX = ZeroEx(0xDef1C0ded9bec7F1a1670819833240f027b25EfF);
IZeroEx public IZERO_EX = IZeroEx(address(ZERO_EX));
address VANITY_DEPLOYER_ADDRESS = 0xe750ad66DE350F8110E305fb78Ec6A9f594445E3;
/* solhint-disable max-line-length */
bytes deployerBytecode =
hex"608060405234801561001057600080fd5b506040516103da3803806103da83398101604081905261002f91610077565b8060405161003c9061006a565b610046919061011f565b604051809103906000f080158015610062573d6000803e3d6000fd5b505050610198565b6101f5806101e583390190565b600060208284031215610088578081fd5b81516001600160401b038082111561009e578283fd5b818401915084601f8301126100b1578283fd5b8151818111156100c3576100c3610182565b604051601f8201601f19908116603f011681019083821181831017156100eb576100eb610182565b81604052828152876020848701011115610103578586fd5b610114836020830160208801610152565b979650505050505050565b600060208252825180602084015261013e816040850160208701610152565b601f01601f19169190910160400192915050565b60005b8381101561016d578181015183820152602001610155565b8381111561017c576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b603f806101a66000396000f3fe6080604052600080fdfea26469706673582212201bd8b1a777b100d67435ca4bb0b2fdccb13a2c2dde019b227bb553ff9a95bd4464736f6c63430008020033608060405234801561001057600080fd5b506040516101f53803806101f583398101604081905261002f916100c9565b60008151602083016000f090506001600160a01b0381166100865760405162461bcd60e51b815260206004820152600d60248201526c1111541313d657d19052531151609a1b604482015260640160405180910390fd5b6040516001600160a01b03821681527ff40fcec21964ffb566044d083b4073f29f7f7929110ea19e1b3ebe375d89055e9060200160405180910390a150506101a8565b600060208083850312156100db578182fd5b82516001600160401b03808211156100f1578384fd5b818501915085601f830112610104578384fd5b81518181111561011657610116610192565b604051601f8201601f19908116603f0116810190838211818310171561013e5761013e610192565b816040528281528886848701011115610155578687fd5b8693505b828410156101765784840186015181850187015292850192610159565b8284111561018657868684830101525b98975050505050505050565b634e487b7160e01b600052604160045260246000fd5b603f806101b66000396000f3fe6080604052600080fdfea2646970667358221220fbca036a163ed7f008cefa7c834d98d25109a456a051d41d9c89d55d7185d12b64736f6c63430008020033";
/* solhint-enable max-line-length */
address[] transformerSigners = [address(this)];
bool isDeployed = false;
struct Features {
NativeOrdersFeature nativeOrdersFeature;
BatchFillNativeOrdersFeature batchFillNativeOrdersFeature;
OtcOrdersFeature otcOrdersFeature;
UniswapFeature uniswapFeature;
FundRecoveryFeature fundRecoveryFeature;
TransformERC20Feature transformERC20Feature;
MetaTransactionsFeature metaTransactionsFeature;
ERC1155OrdersFeature erc1155OrdersFeature;
ERC721OrdersFeature erc721OrdersFeature;
MultiplexFeature multiplexFeature;
}
struct Transformers {
FillQuoteTransformer fillQuoteTransformer;
WethTransformer wethTransformer;
AffiliateFeeTransformer affiliateFeeTransformer;
PayTakerTransformer payTakerTransformer;
}
struct ZeroExDeployed {
IZeroEx zeroEx;
TransformerDeployer transformerDeployer;
FeeCollectorController feeCollectorController;
IStaking staking; // address(0)
Features features;
Transformers transformers;
IEtherTokenV06 weth;
}
ZeroExDeployed ZERO_EX_DEPLOYED;
function getDeployedZeroEx() public returns (ZeroExDeployed memory) {
if (!isDeployed) {
deployZeroEx();
}
return ZERO_EX_DEPLOYED;
}
function logDeployedZeroEx() public {
emit log_string("--- Deployed ZeroEx ---");
emit log_named_address("ZeroEx", address(ZERO_EX));
emit log_named_address("TransformerDeployer", address(ZERO_EX_DEPLOYED.transformerDeployer));
emit log_named_address("FeeCollectorController", address(ZERO_EX_DEPLOYED.feeCollectorController));
emit log_named_address("Staking", address(ZERO_EX_DEPLOYED.staking));
emit log_string("----- Features -----");
emit log_named_address("NativeOrdersFeature", address(ZERO_EX_DEPLOYED.features.nativeOrdersFeature));
emit log_named_address(
"BatchFillNativeOrdersFeature",
address(ZERO_EX_DEPLOYED.features.batchFillNativeOrdersFeature)
);
emit log_named_address("OtcOrdersFeature", address(ZERO_EX_DEPLOYED.features.otcOrdersFeature));
emit log_named_address("UniswapFeature", address(ZERO_EX_DEPLOYED.features.uniswapFeature));
emit log_named_address("FundRecoveryFeature", address(ZERO_EX_DEPLOYED.features.fundRecoveryFeature));
emit log_named_address("MetaTransactionsFeature", address(ZERO_EX_DEPLOYED.features.metaTransactionsFeature));
emit log_named_address("ERC1155OrdersFeature", address(ZERO_EX_DEPLOYED.features.erc1155OrdersFeature));
emit log_named_address("ERC721OrdersFeature", address(ZERO_EX_DEPLOYED.features.erc721OrdersFeature));
emit log_named_address("TransformERC20Feature", address(ZERO_EX_DEPLOYED.features.transformERC20Feature));
emit log_named_address("MultiplexFeature", address(ZERO_EX_DEPLOYED.features.multiplexFeature));
emit log_string("----- Transformers -----");
emit log_named_address("FillQuoteTransformer", address(ZERO_EX_DEPLOYED.transformers.fillQuoteTransformer));
emit log_named_address("WethTransformer", address(ZERO_EX_DEPLOYED.transformers.wethTransformer));
emit log_named_address(
"AffiliateFeeTransformer",
address(ZERO_EX_DEPLOYED.transformers.affiliateFeeTransformer)
);
emit log_named_address("PayTakerTransformer", address(ZERO_EX_DEPLOYED.transformers.payTakerTransformer));
emit log_string("----- Other -----");
emit log_named_address("WETH", address(ZERO_EX_DEPLOYED.weth));
}
function deployZeroEx() public returns (ZeroExDeployed memory) {
if (isDeployed) {
return ZERO_EX_DEPLOYED;
}
ZERO_EX_DEPLOYED.weth = IEtherTokenV06(address(new WETH9V06()));
InitialMigration initialMigration = new InitialMigration(address(this));
// Append the required ZeroEx constructor arguments (address bootstrapper)
bytes memory zeroExDeploycode = abi.encodePacked(type(ZeroEx).creationCode, abi.encode(initialMigration));
// Append the required deployer code constructor arguments (bytes initCode)
bytes memory deployerDeploycode = abi.encodePacked(deployerBytecode, abi.encode(zeroExDeploycode));
// HERE BE DRAGONS, feel free to ignore this for now
// We want to deploy the ZeroEx contract, at 0xDef1C0ded9bec7F1a1670819833240f027b25EfF
// We use a special mechanism to deploy the ZeroEx contract.
// Must occur from this address as the first transaction
// The address is technically emitted in an event, but we know we did it correctly
//│ │ ├─ emit topic 0: 0xf40fcec21964ffb566044d083b4073f29f7f7929110ea19e1b3ebe375d89055e
//│ │ │ data: 0x000000000000000000000000def1c0ded9bec7f1a1670819833240f027b25eff
hoax(VANITY_DEPLOYER_ADDRESS);
assembly {
pop(create(0, add(deployerDeploycode, 0x20), mload(deployerDeploycode)))
}
// Staking = address(0);
ZERO_EX_DEPLOYED.staking = IStaking(address(0));
ZERO_EX_DEPLOYED.transformerDeployer = new TransformerDeployer(transformerSigners);
ZERO_EX_DEPLOYED.feeCollectorController = new FeeCollectorController(
IEtherTokenV06(ZERO_EX_DEPLOYED.weth),
IStaking(ZERO_EX_DEPLOYED.staking)
);
// Features
ZERO_EX_DEPLOYED.features.transformERC20Feature = new TransformERC20Feature();
ZERO_EX_DEPLOYED.features.nativeOrdersFeature = new NativeOrdersFeature(
address(ZERO_EX), // EP address
ZERO_EX_DEPLOYED.weth,
ZERO_EX_DEPLOYED.staking,
ZERO_EX_DEPLOYED.feeCollectorController, // feeCollectorController address
uint32(0) // protocolFeeMultiplier
);
ZERO_EX_DEPLOYED.features.batchFillNativeOrdersFeature = new BatchFillNativeOrdersFeature(address(ZERO_EX));
ZERO_EX_DEPLOYED.features.otcOrdersFeature = new OtcOrdersFeature(address(ZERO_EX), ZERO_EX_DEPLOYED.weth);
ZERO_EX_DEPLOYED.features.uniswapFeature = new UniswapFeature(ZERO_EX_DEPLOYED.weth);
ZERO_EX_DEPLOYED.features.fundRecoveryFeature = new FundRecoveryFeature();
ZERO_EX_DEPLOYED.features.metaTransactionsFeature = new MetaTransactionsFeature(address(ZERO_EX));
ZERO_EX_DEPLOYED.features.erc1155OrdersFeature = new ERC1155OrdersFeature(
address(ZERO_EX),
ZERO_EX_DEPLOYED.weth
);
ZERO_EX_DEPLOYED.features.erc721OrdersFeature = new ERC721OrdersFeature(
address(ZERO_EX),
ZERO_EX_DEPLOYED.weth
);
ZERO_EX_DEPLOYED.features.multiplexFeature = new MultiplexFeature(
address(ZERO_EX),
ZERO_EX_DEPLOYED.weth,
ILiquidityProviderSandbox(address(0)),
address(0), // uniswapFactory
address(0), // sushiswapFactory
bytes32(0), // uniswapPairInitCodeHash
bytes32(0) // sushiswapPairInitCodeHash
);
initialMigration.initializeZeroEx(
payable(address(this)),
ZERO_EX,
InitialMigration.BootstrapFeatures({
registry: new SimpleFunctionRegistryFeature(),
ownable: new OwnableFeature()
})
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.batchFillNativeOrdersFeature),
abi.encodeWithSelector(BatchFillNativeOrdersFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.transformERC20Feature),
abi.encodeWithSelector(
TransformERC20Feature.migrate.selector,
address(ZERO_EX_DEPLOYED.transformerDeployer)
),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.nativeOrdersFeature),
abi.encodeWithSelector(NativeOrdersFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.otcOrdersFeature),
abi.encodeWithSelector(OtcOrdersFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.uniswapFeature),
abi.encodeWithSelector(UniswapFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.fundRecoveryFeature),
abi.encodeWithSelector(FundRecoveryFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.metaTransactionsFeature),
abi.encodeWithSelector(MetaTransactionsFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.erc1155OrdersFeature),
abi.encodeWithSelector(ERC1155OrdersFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.erc721OrdersFeature),
abi.encodeWithSelector(ERC721OrdersFeature.migrate.selector),
address(this)
);
IZERO_EX.migrate(
address(ZERO_EX_DEPLOYED.features.multiplexFeature),
abi.encodeWithSelector(MultiplexFeature.migrate.selector),
address(this)
);
// Transformers
ZERO_EX_DEPLOYED.transformers.wethTransformer = WethTransformer(
ZERO_EX_DEPLOYED.transformerDeployer.deploy(
abi.encodePacked(
// Deploy the WethTransformer code
type(WethTransformer).creationCode,
// WethTransformer takes WETH address as a constructor argument
abi.encode(address(ZERO_EX_DEPLOYED.weth))
)
)
);
// Deploy the FQT, NOTE: No bridge adapter in tests
ZERO_EX_DEPLOYED.transformers.fillQuoteTransformer = FillQuoteTransformer(
ZERO_EX_DEPLOYED.transformerDeployer.deploy(
abi.encodePacked(
// Deploy the FQT code
type(FillQuoteTransformer).creationCode,
// FQT takes a BridgeAdapter and ZeroEx
abi.encode(
address(0), // Note: No BridgeAdapter in tests
INativeOrdersFeature(address(ZERO_EX))
)
)
)
);
ZERO_EX_DEPLOYED.transformers.affiliateFeeTransformer = AffiliateFeeTransformer(
ZERO_EX_DEPLOYED.transformerDeployer.deploy(type(AffiliateFeeTransformer).creationCode)
);
ZERO_EX_DEPLOYED.transformers.payTakerTransformer = PayTakerTransformer(
ZERO_EX_DEPLOYED.transformerDeployer.deploy(type(PayTakerTransformer).creationCode)
);
ZERO_EX_DEPLOYED.zeroEx = IZERO_EX;
isDeployed = true;
logDeployedZeroEx();
return ZERO_EX_DEPLOYED;
}
}