Skip to content

Commit 38665ff

Browse files
ablspatrick-dowell
andauthored
Migrate the multiplex tests to foundry (0xProject#655)
* add some tests for multiplex using foundry * remove try/catch from multiplex foundry tests * refactor multiplex forge tests * fix broken import, remove dead code --------- Co-authored-by: Patrick Dowell <[email protected]>
1 parent 459fb3e commit 38665ff

File tree

9 files changed

+1116
-20
lines changed

9 files changed

+1116
-20
lines changed

contracts/zero-ex/tests/Multiplex.t.sol

Lines changed: 615 additions & 0 deletions
Large diffs are not rendered by default.

contracts/zero-ex/tests/WrapEth.t.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
pragma solidity ^0.6;
1616
pragma experimental ABIEncoderV2;
1717

18-
import "utils/ForkUtils.sol";
18+
import {ForkUtils} from "utils/ForkUtils.sol";
1919
import "utils/TestUtils.sol";
2020
import "utils/DeployZeroEx.sol";
2121
import "forge-std/Test.sol";
@@ -33,7 +33,9 @@ contract WrapEth is Test, ForkUtils, TestUtils {
3333
DeployZeroEx.ZeroExDeployed zeroExDeployed;
3434

3535
function setUp() public {
36-
zeroExDeployed = new DeployZeroEx().deployZeroEx();
36+
zeroExDeployed = new DeployZeroEx(
37+
DeployZeroEx.ZeroExDeployConfiguration(address(0), address(0), address(0), 0, 0, 0, true)
38+
).deployZeroEx();
3739
vm.deal(address(this), 1e19);
3840
}
3941

contracts/zero-ex/tests/forked/RfqtV2Test.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ contract RfqtV2Test is Test, ForkUtils, TestUtils {
103103
order.makerAmount = 1e18;
104104
order.takerAmount = 1e18;
105105
uint privateKey;
106-
(order.maker, privateKey) = getSigner();
106+
(order.maker, privateKey) = _getSigner();
107107
deal(address(order.makerToken), order.maker, 1e20);
108108
vm.prank(order.maker);
109109
IERC20Token(tokens.USDC).approve(address(addresses.exchangeProxy), 1e20);

contracts/zero-ex/tests/forked/WrapEthTest.t.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
pragma solidity ^0.6;
1616
pragma experimental ABIEncoderV2;
1717

18-
import "../utils/ForkUtils.sol";
18+
import {ForkUtils} from "../utils/ForkUtils.sol";
1919
import "../utils/TestUtils.sol";
2020
import "../utils/DeployZeroEx.sol";
2121
import "forge-std/Test.sol";
@@ -33,7 +33,9 @@ contract WrapEthTest is Test, ForkUtils, TestUtils {
3333
DeployZeroEx.ZeroExDeployed zeroExDeployed;
3434

3535
function setUp() public {
36-
zeroExDeployed = new DeployZeroEx().deployZeroEx();
36+
zeroExDeployed = new DeployZeroEx(
37+
DeployZeroEx.ZeroExDeployConfiguration(address(0), address(0), address(0), 0, 0, 0, true)
38+
).deployZeroEx();
3739
vm.deal(address(this), 1e19);
3840
}
3941

contracts/zero-ex/tests/utils/DeployZeroEx.sol

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ import "src/features/MetaTransactionsFeature.sol";
3131
import "src/features/nft_orders/ERC1155OrdersFeature.sol";
3232
import "src/features/nft_orders/ERC721OrdersFeature.sol";
3333
import "src/features/UniswapFeature.sol";
34+
import "src/features/UniswapV3Feature.sol";
3435
import "src/features/multiplex/MultiplexFeature.sol";
3536
import "src/external/TransformerDeployer.sol";
3637
import "src/external/FeeCollectorController.sol";
38+
import "src/external/LiquidityProviderSandbox.sol";
3739
import "src/transformers/WethTransformer.sol";
3840
import "src/transformers/FillQuoteTransformer.sol";
3941
import "src/transformers/PayTakerTransformer.sol";
@@ -62,6 +64,7 @@ contract DeployZeroEx is Test {
6264
BatchFillNativeOrdersFeature batchFillNativeOrdersFeature;
6365
OtcOrdersFeature otcOrdersFeature;
6466
UniswapFeature uniswapFeature;
67+
UniswapV3Feature uniswapV3Feature;
6568
FundRecoveryFeature fundRecoveryFeature;
6669
TransformERC20Feature transformERC20Feature;
6770
MetaTransactionsFeature metaTransactionsFeature;
@@ -89,6 +92,22 @@ contract DeployZeroEx is Test {
8992

9093
ZeroExDeployed ZERO_EX_DEPLOYED;
9194

95+
struct ZeroExDeployConfiguration {
96+
address uniswapFactory;
97+
address sushiswapFactory;
98+
address uniswapV3Factory;
99+
bytes32 uniswapPairInitCodeHash;
100+
bytes32 sushiswapPairInitCodeHash;
101+
bytes32 uniswapV3PoolInitCodeHash;
102+
bool logDeployed;
103+
}
104+
105+
ZeroExDeployConfiguration ZERO_EX_DEPLOY_CONFIG;
106+
107+
constructor(ZeroExDeployConfiguration memory configuration) public {
108+
ZERO_EX_DEPLOY_CONFIG = configuration;
109+
}
110+
92111
function getDeployedZeroEx() public returns (ZeroExDeployed memory) {
93112
if (!isDeployed) {
94113
deployZeroEx();
@@ -111,6 +130,7 @@ contract DeployZeroEx is Test {
111130
);
112131
emit log_named_address("OtcOrdersFeature", address(ZERO_EX_DEPLOYED.features.otcOrdersFeature));
113132
emit log_named_address("UniswapFeature", address(ZERO_EX_DEPLOYED.features.uniswapFeature));
133+
emit log_named_address("UniswapV3Feature", address(ZERO_EX_DEPLOYED.features.uniswapV3Feature));
114134
emit log_named_address("FundRecoveryFeature", address(ZERO_EX_DEPLOYED.features.fundRecoveryFeature));
115135
emit log_named_address("MetaTransactionsFeature", address(ZERO_EX_DEPLOYED.features.metaTransactionsFeature));
116136
emit log_named_address("ERC1155OrdersFeature", address(ZERO_EX_DEPLOYED.features.erc1155OrdersFeature));
@@ -174,6 +194,11 @@ contract DeployZeroEx is Test {
174194
ZERO_EX_DEPLOYED.features.batchFillNativeOrdersFeature = new BatchFillNativeOrdersFeature(address(ZERO_EX));
175195
ZERO_EX_DEPLOYED.features.otcOrdersFeature = new OtcOrdersFeature(address(ZERO_EX), ZERO_EX_DEPLOYED.weth);
176196
ZERO_EX_DEPLOYED.features.uniswapFeature = new UniswapFeature(ZERO_EX_DEPLOYED.weth);
197+
ZERO_EX_DEPLOYED.features.uniswapV3Feature = new UniswapV3Feature(
198+
ZERO_EX_DEPLOYED.weth,
199+
ZERO_EX_DEPLOY_CONFIG.uniswapV3Factory,
200+
ZERO_EX_DEPLOY_CONFIG.uniswapV3PoolInitCodeHash
201+
);
177202
ZERO_EX_DEPLOYED.features.fundRecoveryFeature = new FundRecoveryFeature();
178203
ZERO_EX_DEPLOYED.features.metaTransactionsFeature = new MetaTransactionsFeature(address(ZERO_EX));
179204
ZERO_EX_DEPLOYED.features.erc1155OrdersFeature = new ERC1155OrdersFeature(
@@ -187,11 +212,11 @@ contract DeployZeroEx is Test {
187212
ZERO_EX_DEPLOYED.features.multiplexFeature = new MultiplexFeature(
188213
address(ZERO_EX),
189214
ZERO_EX_DEPLOYED.weth,
190-
ILiquidityProviderSandbox(address(0)),
191-
address(0), // uniswapFactory
192-
address(0), // sushiswapFactory
193-
bytes32(0), // uniswapPairInitCodeHash
194-
bytes32(0) // sushiswapPairInitCodeHash
215+
new LiquidityProviderSandbox(address(ZERO_EX)),
216+
ZERO_EX_DEPLOY_CONFIG.uniswapFactory,
217+
ZERO_EX_DEPLOY_CONFIG.sushiswapFactory,
218+
ZERO_EX_DEPLOY_CONFIG.uniswapPairInitCodeHash,
219+
ZERO_EX_DEPLOY_CONFIG.sushiswapPairInitCodeHash
195220
);
196221

197222
initialMigration.initializeZeroEx(
@@ -230,6 +255,11 @@ contract DeployZeroEx is Test {
230255
abi.encodeWithSelector(UniswapFeature.migrate.selector),
231256
address(this)
232257
);
258+
IZERO_EX.migrate(
259+
address(ZERO_EX_DEPLOYED.features.uniswapV3Feature),
260+
abi.encodeWithSelector(UniswapV3Feature.migrate.selector),
261+
address(this)
262+
);
233263
IZERO_EX.migrate(
234264
address(ZERO_EX_DEPLOYED.features.fundRecoveryFeature),
235265
abi.encodeWithSelector(FundRecoveryFeature.migrate.selector),
@@ -293,7 +323,10 @@ contract DeployZeroEx is Test {
293323

294324
ZERO_EX_DEPLOYED.zeroEx = IZERO_EX;
295325
isDeployed = true;
296-
logDeployedZeroEx();
326+
if (ZERO_EX_DEPLOY_CONFIG.logDeployed) {
327+
logDeployedZeroEx();
328+
}
329+
297330
return ZERO_EX_DEPLOYED;
298331
}
299332
}

contracts/zero-ex/tests/utils/ForkUtils.sol

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,15 +227,6 @@ contract ForkUtils is Test {
227227
}
228228
}
229229

230-
//gets a dummy signer to be used for an OTC order
231-
function getSigner() public returns (address, uint) {
232-
string memory mnemonic = "test test test test test test test test test test test junk";
233-
uint256 privateKey = vm.deriveKey(mnemonic, 0);
234-
235-
vm.label(vm.addr(privateKey), "zeroEx/MarketMaker");
236-
return (vm.addr(privateKey), privateKey);
237-
}
238-
239230
//read the uniswapV2 router addresses from file
240231
function readLiquiditySourceAddresses() internal returns (string memory) {
241232
string memory root = vm.projectRoot();
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
/*
3+
Copyright 2023 ZeroEx Intl.
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
*/
14+
15+
pragma solidity ^0.6;
16+
pragma experimental ABIEncoderV2;
17+
18+
import {Test} from "forge-std/Test.sol";
19+
import {IERC20Token} from "@0x/contracts-erc20/src/IERC20Token.sol";
20+
import {IEtherToken} from "@0x/contracts-erc20/src/IEtherToken.sol";
21+
import {WETH9V06} from "@0x/contracts-erc20/src/v06/WETH9V06.sol";
22+
import {IFlashWallet} from "src/external/IFlashWallet.sol";
23+
import {LibERC20Transformer} from "src/transformers/LibERC20Transformer.sol";
24+
import {LibNativeOrder} from "src/features/libs/LibNativeOrder.sol";
25+
import {LibSignature} from "src/features/libs/LibSignature.sol";
26+
import {IMultiplexFeature} from "src/features/interfaces/IMultiplexFeature.sol";
27+
import {ITransformERC20Feature} from "src/features/interfaces/ITransformERC20Feature.sol";
28+
import {TestUtils} from "utils/TestUtils.sol";
29+
import {DeployZeroEx} from "utils/DeployZeroEx.sol";
30+
import {TestMintTokenERC20Transformer} from "../../contracts/test/TestMintTokenERC20Transformer.sol";
31+
import {TestMintableERC20Token} from "../../contracts/test/tokens/TestMintableERC20Token.sol";
32+
import {TestUniswapV2Factory} from "../../contracts/test/integration/TestUniswapV2Factory.sol";
33+
import {TestUniswapV2Pool} from "../../contracts/test/integration/TestUniswapV2Pool.sol";
34+
import {TestUniswapV3Factory} from "../../contracts/test/integration/TestUniswapV3Factory.sol";
35+
import {TestUniswapV3Pool} from "../../contracts/test/integration/TestUniswapV3Pool.sol";
36+
import {TestLiquidityProvider} from "../../contracts/test/integration/TestLiquidityProvider.sol";
37+
38+
contract LocalTest is Test, TestUtils {
39+
uint24 internal constant UNIV3_POOL_FEE = 1234;
40+
41+
DeployZeroEx.ZeroExDeployed internal zeroExDeployed;
42+
IFlashWallet internal flashWallet;
43+
IERC20Token internal shib;
44+
IERC20Token internal dai;
45+
IERC20Token internal zrx;
46+
IEtherToken internal weth;
47+
48+
TestUniswapV2Factory internal sushiFactory;
49+
TestUniswapV2Factory internal uniV2Factory;
50+
TestUniswapV3Factory internal uniV3Factory;
51+
TestLiquidityProvider internal liquidityProvider;
52+
uint256 internal transformerNonce;
53+
54+
address internal signerAddress;
55+
uint256 internal signerKey;
56+
57+
function _infiniteApprovals() private {
58+
shib.approve(address(zeroExDeployed.zeroEx), type(uint256).max);
59+
dai.approve(address(zeroExDeployed.zeroEx), type(uint256).max);
60+
zrx.approve(address(zeroExDeployed.zeroEx), type(uint256).max);
61+
weth.approve(address(zeroExDeployed.zeroEx), type(uint256).max);
62+
}
63+
64+
function setUp() public {
65+
(signerAddress, signerKey) = _getSigner();
66+
67+
sushiFactory = new TestUniswapV2Factory();
68+
uniV2Factory = new TestUniswapV2Factory();
69+
uniV3Factory = new TestUniswapV3Factory();
70+
liquidityProvider = new TestLiquidityProvider();
71+
72+
zeroExDeployed = new DeployZeroEx(
73+
DeployZeroEx.ZeroExDeployConfiguration({
74+
uniswapFactory: address(uniV2Factory),
75+
sushiswapFactory: address(sushiFactory),
76+
uniswapV3Factory: address(uniV3Factory),
77+
uniswapPairInitCodeHash: uniV2Factory.POOL_INIT_CODE_HASH(),
78+
sushiswapPairInitCodeHash: sushiFactory.POOL_INIT_CODE_HASH(),
79+
uniswapV3PoolInitCodeHash: uniV3Factory.POOL_INIT_CODE_HASH(),
80+
logDeployed: false
81+
})
82+
).deployZeroEx();
83+
84+
transformerNonce = zeroExDeployed.transformerDeployer.nonce();
85+
vm.prank(zeroExDeployed.transformerDeployer.authorities(0));
86+
zeroExDeployed.transformerDeployer.deploy(type(TestMintTokenERC20Transformer).creationCode);
87+
88+
flashWallet = zeroExDeployed.zeroEx.getTransformWallet();
89+
90+
shib = IERC20Token(address(new TestMintableERC20Token()));
91+
dai = IERC20Token(address(new TestMintableERC20Token()));
92+
zrx = IERC20Token(address(new TestMintableERC20Token()));
93+
weth = zeroExDeployed.weth;
94+
95+
_infiniteApprovals();
96+
vm.startPrank(signerAddress);
97+
_infiniteApprovals();
98+
vm.stopPrank();
99+
100+
vm.deal(address(this), 10e18);
101+
}
102+
103+
function _mintTo(address token, address recipient, uint256 amount) internal {
104+
if (token == address(weth)) {
105+
IEtherToken(token).deposit{value: amount}();
106+
WETH9V06(payable(token)).transfer(recipient, amount);
107+
} else {
108+
TestMintableERC20Token(token).mint(recipient, amount);
109+
}
110+
}
111+
112+
function _createUniswapV2Pool(
113+
TestUniswapV2Factory factory,
114+
IERC20Token tokenA,
115+
IERC20Token tokenB,
116+
uint112 balanceA,
117+
uint112 balanceB
118+
) internal returns (address poolAddress) {
119+
TestUniswapV2Pool pool = factory.createPool(tokenA, tokenB);
120+
_mintTo(address(tokenA), address(pool), balanceA);
121+
_mintTo(address(tokenB), address(pool), balanceB);
122+
123+
(uint112 balance0, uint112 balance1) = tokenA < tokenB ? (balanceA, balanceB) : (balanceB, balanceA);
124+
pool.setReserves(balance0, balance1, 0);
125+
126+
return address(pool);
127+
}
128+
129+
function _createUniswapV3Pool(
130+
TestUniswapV3Factory factory,
131+
IERC20Token tokenA,
132+
IERC20Token tokenB,
133+
uint112 balanceA,
134+
uint112 balanceB
135+
) internal returns (address poolAddress) {
136+
poolAddress = address(factory.createPool(tokenA, tokenB, UNIV3_POOL_FEE));
137+
_mintTo(address(tokenA), poolAddress, balanceA);
138+
_mintTo(address(tokenB), poolAddress, balanceB);
139+
}
140+
}

0 commit comments

Comments
 (0)