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>
This commit is contained in:
164
contracts/zero-ex/tests/forked/RfqtV2Test.t.sol
Normal file
164
contracts/zero-ex/tests/forked/RfqtV2Test.t.sol
Normal file
@@ -0,0 +1,164 @@
|
||||
// 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 "../utils/ForkUtils.sol";
|
||||
import "../utils/TestUtils.sol";
|
||||
import "src/IZeroEx.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "src/features/TransformERC20Feature.sol";
|
||||
import "src/external/TransformerDeployer.sol";
|
||||
import "src/transformers/WethTransformer.sol";
|
||||
import "src/transformers/FillQuoteTransformer.sol";
|
||||
import "src/transformers/bridges/BridgeProtocols.sol";
|
||||
import "src/features/OtcOrdersFeature.sol";
|
||||
|
||||
contract RfqtV2Test is Test, ForkUtils, TestUtils {
|
||||
function setUp() public {
|
||||
_setup();
|
||||
}
|
||||
|
||||
function test_swapEthForUSDTThroughFqtOtcs() public {
|
||||
log_string("SwapEthForUSDTThroughFqtOtc");
|
||||
/* */
|
||||
for (uint256 i = 0; i < 1; i++) {
|
||||
//skip fantom/avax failing test
|
||||
if (i == 3 || i == 4) {
|
||||
continue;
|
||||
}
|
||||
vm.selectFork(forkIds[chains[i]]);
|
||||
log_named_string(" Selecting Fork On", chains[i]);
|
||||
vm.deal(address(this), 1e18);
|
||||
labelAddresses(
|
||||
chains[i],
|
||||
indexChainsByChain[chains[i]],
|
||||
getTokens(i),
|
||||
getContractAddresses(i),
|
||||
getLiquiditySourceAddresses(i)
|
||||
);
|
||||
swapWithOtcOrder(getTokens(i), getContractAddresses(i), getLiquiditySourceAddresses(i));
|
||||
}
|
||||
}
|
||||
|
||||
/* solhint-disable function-max-lines */
|
||||
function swapWithOtcOrder(
|
||||
TokenAddresses memory tokens,
|
||||
ContractAddresses memory addresses,
|
||||
LiquiditySources memory sources
|
||||
) public onlyForked {
|
||||
IZERO_EX = IZeroEx(addresses.exchangeProxy);
|
||||
address USDC = address(tokens.USDC);
|
||||
// Create our list of transformations, let's do WethTransformer and FillQuoteTransformer
|
||||
ITransformERC20Feature.Transformation[] memory transformations = new ITransformERC20Feature.Transformation[](2);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
WethTransformer
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
// Use our cheeky search helper to find the nonce rather than hardcode it
|
||||
transformations[0].deploymentNonce = _findTransformerNonce(
|
||||
address(addresses.transformers.wethTransformer),
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
);
|
||||
emit log_named_uint(" WethTransformer nonce", transformations[0].deploymentNonce);
|
||||
createNewFQT(tokens.WrappedNativeToken, addresses.exchangeProxy, addresses.exchangeProxyTransformerDeployer);
|
||||
// Set the first transformation to transform ETH into WETH
|
||||
transformations[0].data = abi.encode(LibERC20Transformer.ETH_TOKEN_ADDRESS, 1e18);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
FillQuoteTransformer
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
transformations[1].deploymentNonce = _findTransformerNonce(
|
||||
address(fillQuoteTransformer),
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
);
|
||||
log_named_uint(" FillQuoteTransformer nonce", transformations[1].deploymentNonce);
|
||||
// Set up the FillQuoteTransformer data
|
||||
FillQuoteTransformer.TransformData memory fqtData;
|
||||
fqtData.side = FillQuoteTransformer.Side.Sell;
|
||||
fqtData.sellToken = IERC20TokenV06(address(tokens.WrappedNativeToken));
|
||||
fqtData.buyToken = tokens.USDC;
|
||||
// the FQT has a sequence, e.g first RFQ then Limit then Bridge
|
||||
// since solidity doesn't support arrays of different types, this is one simple solution
|
||||
// We use a Bridge order type here as we will fill on UniswapV2
|
||||
fqtData.fillSequence = new FillQuoteTransformer.OrderType[](1);
|
||||
fqtData.fillSequence[0] = FillQuoteTransformer.OrderType.Otc;
|
||||
// The amount to fill
|
||||
fqtData.fillAmount = 1e18;
|
||||
|
||||
// Now let's set up an OTC fill
|
||||
fqtData.otcOrders = new FillQuoteTransformer.OtcOrderInfo[](1);
|
||||
LibNativeOrder.OtcOrder memory order;
|
||||
FillQuoteTransformer.OtcOrderInfo memory orderInfo;
|
||||
|
||||
order.makerToken = fqtData.buyToken;
|
||||
order.takerToken = fqtData.sellToken;
|
||||
order.makerAmount = 1e18;
|
||||
order.takerAmount = 1e18;
|
||||
uint privateKey;
|
||||
(order.maker, privateKey) = getSigner();
|
||||
deal(address(order.makerToken), order.maker, 1e20);
|
||||
vm.prank(order.maker);
|
||||
IERC20TokenV06(tokens.USDC).approve(address(addresses.exchangeProxy), 1e20);
|
||||
vm.prank(order.maker);
|
||||
|
||||
order.taker = address(0);
|
||||
order.txOrigin = address(tx.origin);
|
||||
order.expiryAndNonce = encodeExpiryAndNonce(order.maker);
|
||||
orderInfo.order = order;
|
||||
|
||||
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, IZERO_EX.getOtcOrderHash(order));
|
||||
// How much we want to fill on this order, which can be different to the total
|
||||
// e.g 50/50 split this would be half
|
||||
order.takerAmount = 1e18;
|
||||
// Set this low as the price of ETH/USDC can change
|
||||
order.makerAmount = 1e18;
|
||||
|
||||
orderInfo.signature.signatureType = LibSignature.SignatureType.EIP712;
|
||||
orderInfo.signature.v = v;
|
||||
orderInfo.signature.r = r;
|
||||
orderInfo.signature.s = s;
|
||||
|
||||
orderInfo.maxTakerTokenFillAmount = 1e18;
|
||||
|
||||
fqtData.otcOrders[0] = orderInfo;
|
||||
transformations[1].data = abi.encode(fqtData);
|
||||
log_string(" Successful fill, makerTokens bought");
|
||||
IZERO_EX.transformERC20{value: 1e18}(
|
||||
// input token
|
||||
IERC20TokenV06(LibERC20Transformer.ETH_TOKEN_ADDRESS),
|
||||
// output token
|
||||
tokens.USDC,
|
||||
// input token amount
|
||||
order.takerAmount,
|
||||
// min output token amount
|
||||
order.makerAmount,
|
||||
// list of transform
|
||||
transformations
|
||||
);
|
||||
assert(tokens.USDC.balanceOf(address(this)) > 0);
|
||||
}
|
||||
|
||||
/* solhint-enable function-max-lines */
|
||||
function encodeExpiryAndNonce(address maker) public returns (uint256) {
|
||||
uint256 expiry = (block.timestamp + 120) << 192;
|
||||
uint256 bucket = 0 << 128;
|
||||
uint256 nonce = vm.getNonce(maker);
|
||||
return expiry | bucket | nonce;
|
||||
}
|
||||
}
|
||||
198
contracts/zero-ex/tests/forked/SwapEthForERC20Test.t.sol
Normal file
198
contracts/zero-ex/tests/forked/SwapEthForERC20Test.t.sol
Normal file
@@ -0,0 +1,198 @@
|
||||
// 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 "../utils/ForkUtils.sol";
|
||||
import "../utils/TestUtils.sol";
|
||||
import "src/IZeroEx.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "src/features/TransformERC20Feature.sol";
|
||||
import "src/external/TransformerDeployer.sol";
|
||||
import "src/transformers/WethTransformer.sol";
|
||||
import "src/transformers/FillQuoteTransformer.sol";
|
||||
import "src/transformers/bridges/BridgeProtocols.sol";
|
||||
import "src/features/OtcOrdersFeature.sol";
|
||||
|
||||
contract SwapEthForERC20Test is Test, ForkUtils, TestUtils {
|
||||
function setUp() public {
|
||||
//get out addresses.json file that defines contract addresses for each chain we are currently deployed on
|
||||
_setup();
|
||||
}
|
||||
|
||||
function test_swapEthForERC20OnUniswap() public {
|
||||
log_string("SwapEthForERC20OnUniswap");
|
||||
for (uint256 i = 0; i < chains.length; i++) {
|
||||
//skip fantom/avax failing test
|
||||
if (i == 3 || i == 4) {
|
||||
continue;
|
||||
}
|
||||
vm.selectFork(forkIds[chains[i]]);
|
||||
log_named_string(" Selecting Fork On", chains[i]);
|
||||
labelAddresses(
|
||||
chains[i],
|
||||
indexChainsByChain[chains[i]],
|
||||
getTokens(i),
|
||||
getContractAddresses(i),
|
||||
getLiquiditySourceAddresses(i)
|
||||
);
|
||||
swapOnUniswap(getTokens(i), getContractAddresses(i), getLiquiditySourceAddresses(i));
|
||||
}
|
||||
}
|
||||
|
||||
/* solhint-disable function-max-lines */
|
||||
function swapOnUniswap(
|
||||
TokenAddresses memory tokens,
|
||||
ContractAddresses memory addresses,
|
||||
LiquiditySources memory sources
|
||||
) public onlyForked {
|
||||
if (sources.UniswapV2Router != address(0)) {
|
||||
// Create our list of transformations, let's do WethTransformer and FillQuoteTransformer
|
||||
ITransformERC20Feature.Transformation[]
|
||||
memory transformations = new ITransformERC20Feature.Transformation[](2);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
WethTransformer
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
// Use our cheeky search helper to find the nonce rather than hardcode it
|
||||
transformations[0].deploymentNonce = _findTransformerNonce(
|
||||
address(addresses.transformers.wethTransformer),
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
);
|
||||
emit log_named_uint(" WethTransformer nonce", transformations[0].deploymentNonce);
|
||||
createNewFQT(
|
||||
tokens.WrappedNativeToken,
|
||||
addresses.exchangeProxy,
|
||||
addresses.exchangeProxyTransformerDeployer
|
||||
);
|
||||
// Set the first transformation to transform ETH into WETH
|
||||
transformations[0].data = abi.encode(LibERC20Transformer.ETH_TOKEN_ADDRESS, 1e18);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
FillQuoteTransformer
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
transformations[1].deploymentNonce = _findTransformerNonce(
|
||||
address(fillQuoteTransformer),
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
);
|
||||
emit log_named_uint(" FillQuoteTransformer nonce", transformations[1].deploymentNonce);
|
||||
// Set up the FillQuoteTransformer data
|
||||
FillQuoteTransformer.TransformData memory fqtData;
|
||||
fqtData.side = FillQuoteTransformer.Side.Sell;
|
||||
fqtData.sellToken = IERC20TokenV06(address(tokens.WrappedNativeToken));
|
||||
fqtData.buyToken = IERC20TokenV06(address(tokens.USDT));
|
||||
// the FQT has a sequence, e.g first RFQ then Limit then Bridge
|
||||
// since solidity doesn't support arrays of different types, this is one simple solution
|
||||
// We use a Bridge order type here as we will fill on UniswapV2
|
||||
fqtData.fillSequence = new FillQuoteTransformer.OrderType[](1);
|
||||
fqtData.fillSequence[0] = FillQuoteTransformer.OrderType.Bridge;
|
||||
// The amount to fill
|
||||
fqtData.fillAmount = 1e18;
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
Sampling
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
uint256 amountOut = sampleLiquiditySource(
|
||||
fqtData.fillAmount,
|
||||
address(fqtData.sellToken),
|
||||
address(fqtData.buyToken),
|
||||
sources.UniswapV2Router
|
||||
);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
BridgeAdapter
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
// Now let's set up a UniswapV2 fill
|
||||
fqtData.bridgeOrders = new IBridgeAdapter.BridgeOrder[](1);
|
||||
IBridgeAdapter.BridgeOrder memory order;
|
||||
// The ID is shifted so we can concat <PROTOCOL><NAME>
|
||||
// e.g <UniswapV2Protocol><UniswapV2>
|
||||
// or <UniswapV2Protocol><SushiSwap> for forks
|
||||
order.source = bytes32(uint256(BridgeProtocols.UNISWAPV2) << 128);
|
||||
// How much we want to fill on this order, which can be different to the total
|
||||
// e.g 50/50 split this would be half
|
||||
order.takerTokenAmount = 1e18;
|
||||
// Set this low as the price of ETH/USDT can change
|
||||
order.makerTokenAmount = amountOut;
|
||||
// The data needed specifically for the source to fill,
|
||||
// e.g for UniswapV2 it is the router contract and a path. See MixinUniswapV2
|
||||
address[] memory uniPath = new address[](2);
|
||||
uniPath[0] = address(tokens.WrappedNativeToken);
|
||||
uniPath[1] = address(tokens.USDT);
|
||||
order.bridgeData = abi.encode(address(sources.UniswapV2Router), uniPath);
|
||||
fqtData.bridgeOrders[0] = order;
|
||||
// Now encode the FQT data into the transformation
|
||||
transformations[1].data = abi.encode(fqtData);
|
||||
|
||||
vm.deal(address(this), 1e18);
|
||||
uint256 balanceETHBefore = address(this).balance;
|
||||
uint256 balanceERC20Before = IERC20TokenV06(tokens.USDT).balanceOf(address(this));
|
||||
|
||||
IZeroEx(payable(addresses.exchangeProxy)).transformERC20{value: 1e18}(
|
||||
// input token
|
||||
IERC20TokenV06(LibERC20Transformer.ETH_TOKEN_ADDRESS),
|
||||
// output token
|
||||
IERC20TokenV06(address(tokens.USDT)),
|
||||
// input token amount
|
||||
1e18,
|
||||
// min output token amount
|
||||
order.makerTokenAmount,
|
||||
// list of transform
|
||||
transformations
|
||||
);
|
||||
|
||||
log_named_uint(" NativeAsset balance before", balanceETHBefore);
|
||||
log_named_uint(" ERC-20 balance before", balanceERC20Before);
|
||||
log_named_uint(" NativeAsset balance after", balanceETHBefore - address(this).balance);
|
||||
log_named_uint(
|
||||
" ERC-20 balance after",
|
||||
IERC20TokenV06(tokens.USDT).balanceOf(address(this)) - balanceERC20Before
|
||||
);
|
||||
assert(IERC20TokenV06(tokens.USDT).balanceOf(address(this)) > 0);
|
||||
} else {
|
||||
emit log_string("Liquidity Source Not available on this chain");
|
||||
}
|
||||
}
|
||||
|
||||
/* solhint-enable function-max-lines */
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
Sampler Dispatch
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
// get a real quote from uniswap
|
||||
function sampleLiquiditySource(
|
||||
uint256 amount,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
address router
|
||||
) public returns (uint256 makerTokenAmounts) {
|
||||
address[] memory path = new address[](2);
|
||||
path[0] = address(takerToken);
|
||||
path[1] = address(makerToken);
|
||||
uint256[] memory amounts = new uint256[](1);
|
||||
amounts[0] = amount;
|
||||
uint256 out = sampleSellsFromUniswapV2(router, path, amounts)[0];
|
||||
|
||||
log_string(" Sampling Uniswap for tokens");
|
||||
log_named_address(" ", takerToken);
|
||||
log_string(" -> ");
|
||||
log_named_address(" ", makerToken);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
110
contracts/zero-ex/tests/forked/WrapEthTest.t.sol
Normal file
110
contracts/zero-ex/tests/forked/WrapEthTest.t.sol
Normal file
@@ -0,0 +1,110 @@
|
||||
// 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 "../utils/ForkUtils.sol";
|
||||
import "../utils/TestUtils.sol";
|
||||
import "src/IZeroEx.sol";
|
||||
import "@0x/contracts-erc20/contracts/src/v06/IEtherTokenV06.sol";
|
||||
import "src/features/TransformERC20Feature.sol";
|
||||
import "src/external/TransformerDeployer.sol";
|
||||
import "src/transformers/WethTransformer.sol";
|
||||
import "src/transformers/FillQuoteTransformer.sol";
|
||||
import "src/transformers/bridges/BridgeProtocols.sol";
|
||||
import "src/transformers/bridges/EthereumBridgeAdapter.sol";
|
||||
import "src/transformers/bridges/PolygonBridgeAdapter.sol";
|
||||
import "src/transformers/bridges/ArbitrumBridgeAdapter.sol";
|
||||
import "src/transformers/bridges/OptimismBridgeAdapter.sol";
|
||||
import "src/transformers/bridges/AvalancheBridgeAdapter.sol";
|
||||
import "src/transformers/bridges/FantomBridgeAdapter.sol";
|
||||
import "src/transformers/bridges/CeloBridgeAdapter.sol";
|
||||
import "src/features/OtcOrdersFeature.sol";
|
||||
|
||||
contract WrapEthTest is Test, ForkUtils, TestUtils {
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
Rpc Setup
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
function setUp() public {
|
||||
_setup();
|
||||
}
|
||||
|
||||
function test_transformERC20Forked() public {
|
||||
log_string("TransformERC20Tests");
|
||||
for (uint256 i = 0; i < chains.length; i++) {
|
||||
vm.selectFork(forkIds[chains[i]]);
|
||||
log_named_string(" Selecting Fork On", chains[i]);
|
||||
_wrapNativeToken(chains[i], indexChainsByChain[chains[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
function logAddresses(string memory chainName, string memory chainId) public {
|
||||
bytes memory details = json.parseRaw(chainId);
|
||||
addresses = abi.decode(details, (ContractAddresses));
|
||||
}
|
||||
|
||||
function _wrapNativeToken(string memory chainName, string memory chainId) public onlyForked {
|
||||
bytes memory details = json.parseRaw(chainId);
|
||||
addresses = abi.decode(details, (ContractAddresses));
|
||||
|
||||
vm.deal(address(this), 1e19);
|
||||
|
||||
emit log_string("-----Preparing ETH->WETH transformation through TransformERC20()-----");
|
||||
emit log_string(" --Building Up Transformations--");
|
||||
ITransformERC20Feature.Transformation[] memory transformations = new ITransformERC20Feature.Transformation[](1);
|
||||
|
||||
emit log_named_address(
|
||||
" Finding TransformerDeployer nonce @",
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
);
|
||||
emit log_named_uint(
|
||||
" Deployer nonce",
|
||||
_findTransformerNonce(
|
||||
address(addresses.transformers.wethTransformer),
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
)
|
||||
);
|
||||
transformations[0].deploymentNonce = _findTransformerNonce(
|
||||
address(addresses.transformers.wethTransformer),
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
);
|
||||
transformations[0].data = abi.encode(LibERC20Transformer.ETH_TOKEN_ADDRESS, 1e18);
|
||||
|
||||
emit log_string(" ---Calling TransformERC20()---");
|
||||
uint256 balanceETHBefore = address(this).balance;
|
||||
uint256 balanceWETHBefore = IERC20TokenV06(addresses.etherToken).balanceOf(address(this));
|
||||
|
||||
IZeroEx(payable(addresses.exchangeProxy)).transformERC20{value: 1e18}(
|
||||
// input token
|
||||
IERC20TokenV06(LibERC20Transformer.ETH_TOKEN_ADDRESS),
|
||||
// output token
|
||||
IERC20TokenV06(address(addresses.etherToken)),
|
||||
// input token amount
|
||||
1e18,
|
||||
// min output token amount
|
||||
1e18,
|
||||
// list of transform
|
||||
transformations
|
||||
);
|
||||
log_named_uint(" NativeAsset balance before", balanceETHBefore);
|
||||
log_named_uint(" ERC-20 balance before", balanceWETHBefore);
|
||||
log_named_uint(" NativeAsset balance after", balanceETHBefore - address(this).balance);
|
||||
log_named_uint(
|
||||
" ERC-20 balance after",
|
||||
IERC20TokenV06(addresses.etherToken).balanceOf(address(this)) - balanceWETHBefore
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user