Add Trader Joe V2 Mixin to Avalanche BridgeAdapter (#686)
* Add Trader Joe V2 Mixin to Avalanche BridgeAdapter * Add TraderJoeV2 MixIn tests * update forked function signatures * Update Avalanche FQT address to reflect Trader Joe V2 MixIn * Update CHANGELOG
This commit is contained in:
parent
ff104e7505
commit
b483805a22
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "0.42.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add Trader Joe V2 support on Avalanche"
|
||||
}
|
||||
],
|
||||
"timestamp": 1681960738
|
||||
},
|
||||
{
|
||||
"version": "0.41.0",
|
||||
"changes": [
|
||||
|
@ -26,6 +26,7 @@ import "./mixins/MixinKyberElastic.sol";
|
||||
import "./mixins/MixinAaveV2.sol";
|
||||
import "./mixins/MixinNerve.sol";
|
||||
import "./mixins/MixinPlatypus.sol";
|
||||
import "./mixins/MixinTraderJoeV2.sol";
|
||||
import "./mixins/MixinUniswapV2.sol";
|
||||
import "./mixins/MixinWOOFi.sol";
|
||||
import "./mixins/MixinZeroExBridge.sol";
|
||||
@ -41,6 +42,7 @@ contract AvalancheBridgeAdapter is
|
||||
MixinAaveV2,
|
||||
MixinNerve,
|
||||
MixinPlatypus,
|
||||
MixinTraderJoeV2,
|
||||
MixinUniswapV2,
|
||||
MixinWOOFi,
|
||||
MixinZeroExBridge
|
||||
@ -100,6 +102,11 @@ contract AvalancheBridgeAdapter is
|
||||
return (0, true);
|
||||
}
|
||||
boughtAmount = _tradePlatypus(buyToken, sellAmount, order.bridgeData);
|
||||
} else if (protocolId == BridgeProtocols.TRADERJOEV2) {
|
||||
if (dryRun) {
|
||||
return (0, true);
|
||||
}
|
||||
boughtAmount = _tradeTraderJoeV2(buyToken, sellAmount, order.bridgeData);
|
||||
} else if (protocolId == BridgeProtocols.WOOFI) {
|
||||
if (dryRun) {
|
||||
return (0, true);
|
||||
|
@ -56,4 +56,5 @@ library BridgeProtocols {
|
||||
uint128 internal constant AAVEV3 = 32;
|
||||
uint128 internal constant KYBERELASTIC = 33;
|
||||
uint128 internal constant BARTER = 34;
|
||||
uint128 internal constant TRADERJOEV2 = 35;
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
// 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.5;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-erc20/src/v06/LibERC20TokenV06.sol";
|
||||
import "@0x/contracts-erc20/src/IERC20Token.sol";
|
||||
import "../IBridgeAdapter.sol";
|
||||
|
||||
interface ILBRouter {
|
||||
/// @notice Swaps exact tokens for tokens while performing safety checks
|
||||
/// @param amountIn The amount of token to send
|
||||
/// @param amountOutMin The min amount of token to receive
|
||||
/// @param pairBinSteps The bin step of the pairs (0: V1, other values will use V2)
|
||||
/// @param tokenPath The swap path using the binSteps following `_pairBinSteps`
|
||||
/// @param to The address of the recipient
|
||||
/// @param deadline The deadline of the tx
|
||||
/// @return amountOut Output amount of the swap
|
||||
function swapExactTokensForTokens(
|
||||
uint256 amountIn,
|
||||
uint256 amountOutMin,
|
||||
uint256[] memory pairBinSteps,
|
||||
IERC20Token[] memory tokenPath,
|
||||
address to,
|
||||
uint256 deadline
|
||||
) external returns (uint256 amountOut);
|
||||
}
|
||||
|
||||
contract MixinTraderJoeV2 {
|
||||
using LibERC20TokenV06 for IERC20Token;
|
||||
|
||||
function _tradeTraderJoeV2(
|
||||
IERC20Token buyToken,
|
||||
uint256 sellAmount,
|
||||
bytes memory bridgeData
|
||||
) internal returns (uint256 boughtAmount) {
|
||||
ILBRouter router;
|
||||
IERC20Token[] memory tokenPath;
|
||||
uint256[] memory pairBinSteps;
|
||||
{
|
||||
address[] memory _path;
|
||||
(router, _path, pairBinSteps) = abi.decode(bridgeData, (ILBRouter, address[], uint256[]));
|
||||
// To get around `abi.decode()` not supporting interface array types.
|
||||
assembly {
|
||||
tokenPath := _path
|
||||
}
|
||||
}
|
||||
|
||||
require(tokenPath.length >= 2, "MixinTraderJoeV2/PATH_LENGTH_MUST_BE_AT_LEAST_TWO");
|
||||
require(
|
||||
tokenPath.length == pairBinSteps.length + 1,
|
||||
"MixinTraderJoeV2/PAIR_BIN_STEPS_LENGTH_MUST_BE_ONE_LESS_THAN_TOKEN_PATH_LENGTH"
|
||||
);
|
||||
require(
|
||||
tokenPath[tokenPath.length - 1] == buyToken,
|
||||
"MixinTraderJoeV2/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"
|
||||
);
|
||||
// Grant the Trader Joe V2 router an allowance to sell the first token.
|
||||
tokenPath[0].approveIfBelow(address(router), sellAmount);
|
||||
|
||||
boughtAmount = router.swapExactTokensForTokens(
|
||||
sellAmount,
|
||||
1,
|
||||
pairBinSteps,
|
||||
tokenPath,
|
||||
address(this),
|
||||
block.timestamp
|
||||
);
|
||||
}
|
||||
}
|
@ -4,48 +4,62 @@
|
||||
"UniswapV3Router": "0x0000000000000000000000000000000000000000",
|
||||
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
|
||||
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
|
||||
"KyberElasticPool": "0x952ffc4c47d66b454a8181f5c68b6248e18b66ec"
|
||||
"KyberElasticPool": "0x952ffc4c47d66b454a8181f5c68b6248e18b66ec",
|
||||
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
|
||||
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"56": {
|
||||
"UniswapV2Router": "0x10ed43c718714eb63d5aa57b78b54704e256024e",
|
||||
"UniswapV3Router": "0x0000000000000000000000000000000000000000",
|
||||
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
|
||||
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
|
||||
"KyberElasticPool": "0xfbfab68ba077d099cd4b66fa76920572cc0b557c"
|
||||
"KyberElasticPool": "0xfbfab68ba077d099cd4b66fa76920572cc0b557c",
|
||||
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
|
||||
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"137": {
|
||||
"UniswapV2Router": "0x1b02da8cb0d097eb8d57a175b88c7d8b47997506",
|
||||
"UniswapV3Router": "0x0000000000000000000000000000000000000000",
|
||||
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
|
||||
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
|
||||
"KyberElasticPool": "0xf9cc934753a127100585812181ac04d07158a4c2"
|
||||
"KyberElasticPool": "0xf9cc934753a127100585812181ac04d07158a4c2",
|
||||
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
|
||||
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"43114": {
|
||||
"UniswapV2Router": "0x9Ad6C38BE94206cA50bb0d90783181662f0Cfa10",
|
||||
"UniswapV3Router": "0x0000000000000000000000000000000000000000",
|
||||
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
|
||||
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
|
||||
"KyberElasticPool": "0x6038373de7f64da99b2a31951628b7d778b2c3cf"
|
||||
"KyberElasticPool": "0x6038373de7f64da99b2a31951628b7d778b2c3cf",
|
||||
"TraderJoeV2Pool": "0x1D7A1a79e2b4Ef88D2323f3845246D24a3c20F1d",
|
||||
"TraderJoeV2Router": "0xE3Ffc583dC176575eEA7FD9dF2A7c65F7E23f4C3"
|
||||
},
|
||||
"250": {
|
||||
"UniswapV2Router": "0x1b02da8cb0d097eb8d57a175b88c7d8b47997506",
|
||||
"UniswapV3Router": "0x0000000000000000000000000000000000000000",
|
||||
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
|
||||
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
|
||||
"KyberElasticPool": "0x8dcf5fed6ae6bf0befb5e4f0c9414c2cb9a4ed01"
|
||||
"KyberElasticPool": "0x8dcf5fed6ae6bf0befb5e4f0c9414c2cb9a4ed01",
|
||||
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
|
||||
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"10": {
|
||||
"UniswapV2Router": "0x0000000000000000000000000000000000000000",
|
||||
"UniswapV3Router": "0x61ffe014ba17989e743c5f6cb21bf9697530b21e",
|
||||
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
|
||||
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
|
||||
"KyberElasticPool": "0x7e29ccaa4bf2894aca02c77e6b99cafc1d24b2f5"
|
||||
"KyberElasticPool": "0x7e29ccaa4bf2894aca02c77e6b99cafc1d24b2f5",
|
||||
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
|
||||
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"42161": {
|
||||
"UniswapV2Router": "0x1b02da8cb0d097eb8d57a175b88c7d8b47997506",
|
||||
"UniswapV3Router": "0x0000000000000000000000000000000000000000",
|
||||
"KyberElasticQuoter": "0x0d125c15d54ca1f8a813c74a81aee34ebb508c1f",
|
||||
"KyberElasticRouter": "0xc1e7dfe73e1598e3910ef4c7845b68a9ab6f4c83",
|
||||
"KyberElasticPool": "0x087abaab9cd85025a8b3916948c69fe173c837ea"
|
||||
"KyberElasticPool": "0x087abaab9cd85025a8b3916948c69fe173c837ea",
|
||||
"TraderJoeV2Pool": "0x0000000000000000000000000000000000000000",
|
||||
"TraderJoeV2Router": "0x0000000000000000000000000000000000000000"
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,8 @@
|
||||
"43114": {
|
||||
"WrappedNativeToken": "0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7",
|
||||
"DAI": "0xd586e7f844cea2f87f50152665bcbc2c279d8d70",
|
||||
"USDC": "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
|
||||
"USDT": "0xc7198437980c041c805A1EDcbA50c1Ce5db95118"
|
||||
"USDC": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
|
||||
"USDT": "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7"
|
||||
},
|
||||
"250": {
|
||||
"WrappedNativeToken": "0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83",
|
||||
|
@ -54,6 +54,75 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
|
||||
}
|
||||
}
|
||||
|
||||
function test_swapERC20ForERC20OnTraderJoeV2() public {
|
||||
for (uint256 i = 0; i < chains.length; i++) {
|
||||
// TraderJoeV2 mixin only enabled on Avalanche
|
||||
if (i != 3) {
|
||||
continue;
|
||||
}
|
||||
vm.selectFork(forkIds[chains[i]]);
|
||||
labelAddresses(
|
||||
chains[i],
|
||||
indexChainsByChain[chains[i]],
|
||||
getTokens(i),
|
||||
getContractAddresses(i),
|
||||
getLiquiditySourceAddresses(i)
|
||||
);
|
||||
swapOnTraderJoeV2(getTokens(i), getContractAddresses(i), getLiquiditySourceAddresses(i));
|
||||
}
|
||||
}
|
||||
|
||||
function swapOnTraderJoeV2(
|
||||
TokenAddresses memory tokens,
|
||||
ContractAddresses memory addresses,
|
||||
LiquiditySources memory sources
|
||||
) public onlyForked {
|
||||
if (sources.TraderJoeV2Router == address(0)) {
|
||||
emit log_string("TraderJoeV2Router not available on this chain");
|
||||
return;
|
||||
}
|
||||
if (sources.TraderJoeV2Pool == address(0)) {
|
||||
emit log_string("TraderJoeV2Pool not available on this chain");
|
||||
return;
|
||||
}
|
||||
|
||||
FillQuoteTransformer.TransformData memory fqtData;
|
||||
fqtData.side = FillQuoteTransformer.Side.Sell;
|
||||
fqtData.sellToken = IERC20Token(address(tokens.USDC));
|
||||
fqtData.buyToken = IERC20Token(address(tokens.USDT));
|
||||
fqtData.fillSequence = new FillQuoteTransformer.OrderType[](1);
|
||||
fqtData.fillSequence[0] = FillQuoteTransformer.OrderType.Bridge;
|
||||
fqtData.fillAmount = 1e6;
|
||||
|
||||
(uint256 amountOut, uint256 binStep) = sampleTraderJoeV2(
|
||||
fqtData.fillAmount,
|
||||
address(fqtData.sellToken),
|
||||
address(fqtData.buyToken),
|
||||
sources.TraderJoeV2Router,
|
||||
sources.TraderJoeV2Pool
|
||||
);
|
||||
log_named_uint("amountOut", amountOut);
|
||||
|
||||
IBridgeAdapter.BridgeOrder memory order;
|
||||
{
|
||||
address[] memory tokenPath = new address[](2);
|
||||
tokenPath[0] = address(fqtData.sellToken);
|
||||
tokenPath[1] = address(fqtData.buyToken);
|
||||
uint256[] memory binSteps = new uint256[](1);
|
||||
binSteps[0] = binStep;
|
||||
order.bridgeData = abi.encode(address(sources.TraderJoeV2Router), tokenPath, binSteps);
|
||||
}
|
||||
|
||||
order.source = bytes32(uint256(BridgeProtocols.TRADERJOEV2) << 128);
|
||||
order.takerTokenAmount = fqtData.fillAmount;
|
||||
order.makerTokenAmount = amountOut;
|
||||
|
||||
fqtData.bridgeOrders = new IBridgeAdapter.BridgeOrder[](1);
|
||||
fqtData.bridgeOrders[0] = order;
|
||||
|
||||
settleAndLogBalances(fqtData, tokens, addresses);
|
||||
}
|
||||
|
||||
function swapOnKyberElastic(
|
||||
TokenAddresses memory tokens,
|
||||
ContractAddresses memory addresses,
|
||||
@ -71,20 +140,6 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
|
||||
emit log_string("KyberElasticPool not available on this chain");
|
||||
return;
|
||||
}
|
||||
ITransformERC20Feature.Transformation[] memory transformations = new ITransformERC20Feature.Transformation[](2);
|
||||
|
||||
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);
|
||||
transformations[0].data = abi.encode(LibERC20Transformer.ETH_TOKEN_ADDRESS, 1e18);
|
||||
transformations[1].deploymentNonce = _findTransformerNonce(
|
||||
address(fillQuoteTransformer),
|
||||
address(addresses.exchangeProxyTransformerDeployer)
|
||||
);
|
||||
emit log_named_uint("FillQuoteTransformer nonce", transformations[1].deploymentNonce);
|
||||
|
||||
FillQuoteTransformer.TransformData memory fqtData;
|
||||
fqtData.side = FillQuoteTransformer.Side.Sell;
|
||||
@ -111,37 +166,8 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
|
||||
order.makerTokenAmount = amountOut;
|
||||
order.bridgeData = abi.encode(address(sources.KyberElasticRouter), path);
|
||||
fqtData.bridgeOrders[0] = order;
|
||||
transformations[1].data = abi.encode(fqtData);
|
||||
|
||||
vm.deal(address(this), 1e18);
|
||||
uint256 balanceETHBefore = address(this).balance;
|
||||
uint256 balanceERC20Before = IERC20Token(tokens.USDT).balanceOf(address(this));
|
||||
|
||||
writeTokenBalance(address(this), address(tokens.USDC), 1e16);
|
||||
uint256 balanceUSDCbefore = IERC20Token(tokens.USDC).balanceOf(address(this));
|
||||
|
||||
IERC20Token(address(tokens.USDC)).approve(addresses.exchangeProxy, 1e16);
|
||||
|
||||
IZeroEx(payable(addresses.exchangeProxy)).transformERC20{value: 1e18}(
|
||||
// input token
|
||||
IERC20Token(address(tokens.USDC)),
|
||||
// output token
|
||||
IERC20Token(address(tokens.USDT)),
|
||||
// input token amount
|
||||
1e6,
|
||||
// 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", IERC20Token(tokens.USDT).balanceOf(address(this)) - balanceERC20Before);
|
||||
log_named_uint("USDC balance before", balanceUSDCbefore);
|
||||
log_named_uint("USDC balance after", IERC20Token(tokens.USDT).balanceOf(address(tokens.USDC)));
|
||||
assert(IERC20Token(tokens.USDT).balanceOf(address(this)) > 0);
|
||||
settleAndLogBalances(fqtData, tokens, addresses);
|
||||
}
|
||||
|
||||
function sampleKyberElastic(
|
||||
@ -150,7 +176,7 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
|
||||
address makerToken,
|
||||
address quoter,
|
||||
address pool
|
||||
) public returns (uint256 makerTokenAmount, bytes memory path) {
|
||||
) private returns (uint256 makerTokenAmount, bytes memory path) {
|
||||
log_string(" Sampling KyberElastic for tokens");
|
||||
log_named_address(" ", takerToken);
|
||||
log_string(" -> ");
|
||||
@ -167,4 +193,64 @@ contract SwapERC20ForERC20Test is Test, ForkUtils, TestUtils {
|
||||
(uint256 amountOut, , , ) = kyberQuoter.quoteExactInput(path, amount);
|
||||
return (amountOut, path);
|
||||
}
|
||||
|
||||
function sampleTraderJoeV2(
|
||||
uint256 amount,
|
||||
address takerToken,
|
||||
address makerToken,
|
||||
address router,
|
||||
address pool
|
||||
) private returns (uint256 makerTokenAmount, uint256 binStep) {
|
||||
log_string("Sampling TraderJoeV2");
|
||||
log_named_address("takerToken", takerToken);
|
||||
log_named_address("makerToken", makerToken);
|
||||
log_named_address("router", router);
|
||||
log_named_address("pool", pool);
|
||||
|
||||
bool swapForY = ITraderJoeV2Pool(pool).tokenY() == makerToken;
|
||||
|
||||
(makerTokenAmount, ) = ITraderJoeV2Router(router).getSwapOut(pool, amount, swapForY);
|
||||
|
||||
binStep = ITraderJoeV2Pool(pool).feeParameters().binStep;
|
||||
}
|
||||
|
||||
function deployFQTAndGetDeploymentNonce(
|
||||
TokenAddresses memory tokens,
|
||||
ContractAddresses memory addresses
|
||||
) private returns (uint32) {
|
||||
createNewFQT(tokens.WrappedNativeToken, addresses.exchangeProxy, addresses.exchangeProxyTransformerDeployer);
|
||||
return
|
||||
_findTransformerNonce(address(fillQuoteTransformer), address(addresses.exchangeProxyTransformerDeployer));
|
||||
}
|
||||
|
||||
function settleAndLogBalances(
|
||||
FillQuoteTransformer.TransformData memory fqtData,
|
||||
TokenAddresses memory tokens,
|
||||
ContractAddresses memory addresses
|
||||
) private {
|
||||
ITransformERC20Feature.Transformation[] memory transformations = new ITransformERC20Feature.Transformation[](1);
|
||||
transformations[0].deploymentNonce = deployFQTAndGetDeploymentNonce(tokens, addresses);
|
||||
transformations[0].data = abi.encode(fqtData);
|
||||
|
||||
address sellToken = address(fqtData.sellToken);
|
||||
address buyToken = address(fqtData.buyToken);
|
||||
|
||||
writeTokenBalance(address(this), sellToken, 1e16);
|
||||
uint256 sellTokenBalanceBefore = IERC20Token(sellToken).balanceOf(address(this));
|
||||
uint256 buyTokenBalanceBefore = IERC20Token(buyToken).balanceOf(address(this));
|
||||
|
||||
IERC20Token(sellToken).approve(addresses.exchangeProxy, 1e16);
|
||||
IZeroEx(payable(addresses.exchangeProxy)).transformERC20(
|
||||
IERC20Token(sellToken),
|
||||
IERC20Token(buyToken),
|
||||
fqtData.fillAmount,
|
||||
fqtData.bridgeOrders[0].makerTokenAmount,
|
||||
transformations
|
||||
);
|
||||
|
||||
log_named_uint("sellToken balance before", sellTokenBalanceBefore);
|
||||
log_named_uint("sellToken balance after", IERC20Token(sellToken).balanceOf(address(this)));
|
||||
log_named_uint("buyToken balance before", buyTokenBalanceBefore);
|
||||
log_named_uint("buyToken balance after", IERC20Token(buyToken).balanceOf(address(this)));
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +88,13 @@ struct TokenAddresses {
|
||||
IEtherToken WrappedNativeToken;
|
||||
}
|
||||
|
||||
// keep the names of the struct members in alphabetical order for correct json unparsing
|
||||
struct LiquiditySources {
|
||||
address KyberElasticPool;
|
||||
address KyberElasticQuoter;
|
||||
address KyberElasticRouter;
|
||||
address TraderJoeV2Pool;
|
||||
address TraderJoeV2Router;
|
||||
address UniswapV2Router;
|
||||
address UniswapV3Router;
|
||||
}
|
||||
@ -100,6 +103,37 @@ interface IFQT {
|
||||
function bridgeAdapter() external returns (address);
|
||||
}
|
||||
|
||||
interface ITraderJoeV2Pool {
|
||||
struct FeeParameters {
|
||||
// 144 lowest bits in slot
|
||||
uint16 binStep;
|
||||
uint16 baseFactor;
|
||||
uint16 filterPeriod;
|
||||
uint16 decayPeriod;
|
||||
uint16 reductionFactor;
|
||||
uint24 variableFeeControl;
|
||||
uint16 protocolShare;
|
||||
uint24 maxVolatilityAccumulated;
|
||||
// 112 highest bits in slot
|
||||
uint24 volatilityAccumulated;
|
||||
uint24 volatilityReference;
|
||||
uint24 indexRef;
|
||||
uint40 time;
|
||||
}
|
||||
|
||||
function feeParameters() external view returns (FeeParameters memory);
|
||||
|
||||
function tokenY() external view returns (address);
|
||||
}
|
||||
|
||||
interface ITraderJoeV2Router {
|
||||
function getSwapOut(
|
||||
address pool,
|
||||
uint256 amountIn,
|
||||
bool swapForY
|
||||
) external view returns (uint256 amountOut, uint256 feesIn);
|
||||
}
|
||||
|
||||
interface IKyberElasticQuoter {
|
||||
function quoteExactInput(
|
||||
bytes memory path,
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "8.5.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add Trader Joe V2 support on Avalanche"
|
||||
}
|
||||
],
|
||||
"timestamp": 1681960738
|
||||
},
|
||||
{
|
||||
"version": "8.4.0",
|
||||
"changes": [
|
||||
|
@ -156,7 +156,7 @@
|
||||
"wethTransformer": "0x9b8b52391071d71cd4ad1e61d7f273268fa34c6c",
|
||||
"payTakerTransformer": "0xb9a4c32547bc3cdc2ee2fb13cc1a0717dac9888f",
|
||||
"affiliateFeeTransformer": "0x105679f99d668001370b4621ad8648ac570c860f",
|
||||
"fillQuoteTransformer": "0x7991f2c35ab19472dbfb6f27593f7f6f38fb3eab",
|
||||
"fillQuoteTransformer": "0x540079df6023d39b2686fd9f6c06f1f8f66aca4a",
|
||||
"positiveSlippageFeeTransformer": "0xadbfdc58a24b6dbc16f21541800f43dd6e282250"
|
||||
}
|
||||
},
|
||||
|
@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "11.21.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Add Trader Joe V2 support on Avalanche"
|
||||
}
|
||||
],
|
||||
"timestamp": 1681960738
|
||||
},
|
||||
{
|
||||
"version": "11.20.0",
|
||||
"changes": [
|
||||
|
@ -165,6 +165,7 @@ export enum BridgeProtocol {
|
||||
AaveV3,
|
||||
KyberElastic,
|
||||
Barter,
|
||||
TraderJoeV2,
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user