Add DODO-only EnhancedSwapRouterV2 routing helpers
This commit is contained in:
@@ -39,12 +39,19 @@ contract MockDodoProviderV2 is ILiquidityProvider {
|
||||
quoteAmount[tokenIn][tokenOut] = amountOut;
|
||||
}
|
||||
|
||||
function getQuote(address tokenIn, address tokenOut, uint256) external view returns (uint256 amountOut, uint256 slippageBps) {
|
||||
function getQuote(address tokenIn, address tokenOut, uint256)
|
||||
external
|
||||
view
|
||||
returns (uint256 amountOut, uint256 slippageBps)
|
||||
{
|
||||
if (!supported[tokenIn][tokenOut]) return (0, 10000);
|
||||
return (quoteAmount[tokenIn][tokenOut], 30);
|
||||
}
|
||||
|
||||
function executeSwap(address tokenIn, address tokenOut, uint256 amountIn, uint256) external returns (uint256 amountOut) {
|
||||
function executeSwap(address tokenIn, address tokenOut, uint256 amountIn, uint256)
|
||||
external
|
||||
returns (uint256 amountOut)
|
||||
{
|
||||
require(supported[tokenIn][tokenOut], "unsupported");
|
||||
amountOut = quoteAmount[tokenIn][tokenOut];
|
||||
ERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);
|
||||
@@ -71,13 +78,11 @@ contract MockUniswapQuoterV2 {
|
||||
quotes[keccak256(abi.encode(tokenIn, tokenOut, fee))] = amountOut;
|
||||
}
|
||||
|
||||
function quoteExactInputSingle(
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
uint24 fee,
|
||||
uint256,
|
||||
uint160
|
||||
) external view returns (uint256) {
|
||||
function quoteExactInputSingle(address tokenIn, address tokenOut, uint24 fee, uint256, uint160)
|
||||
external
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return quotes[keccak256(abi.encode(tokenIn, tokenOut, fee))];
|
||||
}
|
||||
|
||||
@@ -93,17 +98,13 @@ contract MockUniswapRouterV2 {
|
||||
quotes[keccak256(abi.encode(tokenIn, tokenOut, fee))] = amountOut;
|
||||
}
|
||||
|
||||
function exactInputSingle(
|
||||
ISwapRouter.ExactInputSingleParams calldata params
|
||||
) external returns (uint256 amountOut) {
|
||||
function exactInputSingle(ISwapRouter.ExactInputSingleParams calldata params) external returns (uint256 amountOut) {
|
||||
amountOut = quotes[keccak256(abi.encode(params.tokenIn, params.tokenOut, params.fee))];
|
||||
ERC20(params.tokenIn).transferFrom(msg.sender, address(this), params.amountIn);
|
||||
ERC20(params.tokenOut).transfer(params.recipient, amountOut);
|
||||
}
|
||||
|
||||
function exactInput(
|
||||
ISwapRouter.ExactInputParams calldata
|
||||
) external pure returns (uint256) {
|
||||
function exactInput(ISwapRouter.ExactInputParams calldata) external pure returns (uint256) {
|
||||
revert("path unsupported in mock");
|
||||
}
|
||||
}
|
||||
@@ -136,22 +137,18 @@ contract MockBalancerVaultV2 {
|
||||
return (address(0xBEEF), 0);
|
||||
}
|
||||
|
||||
function queryBatchSwap(
|
||||
IBalancerVault.SwapKind,
|
||||
IBalancerVault.SingleSwap[] memory,
|
||||
address[] memory
|
||||
) external pure returns (int256[] memory assetDeltas) {
|
||||
function queryBatchSwap(IBalancerVault.SwapKind, IBalancerVault.SingleSwap[] memory, address[] memory)
|
||||
external
|
||||
pure
|
||||
returns (int256[] memory assetDeltas)
|
||||
{
|
||||
assetDeltas = new int256[](0);
|
||||
}
|
||||
|
||||
function getPoolTokens(bytes32 requestedPoolId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
address[] memory,
|
||||
uint256[] memory,
|
||||
uint256
|
||||
)
|
||||
returns (address[] memory, uint256[] memory, uint256)
|
||||
{
|
||||
require(requestedPoolId == poolId, "bad pool");
|
||||
return (tokens, balances, block.number);
|
||||
@@ -189,26 +186,22 @@ contract MockCurvePoolV2 {
|
||||
contract MockBridgeIntentExecutorV2 is IBridgeIntentExecutor {
|
||||
event Bridged(bytes32 indexed bridgeType, address indexed token, uint256 amount, address recipient);
|
||||
|
||||
function validateBridge(
|
||||
bytes32,
|
||||
bytes calldata,
|
||||
address token,
|
||||
uint256 amount,
|
||||
address recipient
|
||||
) external pure returns (bool ok, string memory reason) {
|
||||
function validateBridge(bytes32, bytes calldata, address token, uint256 amount, address recipient)
|
||||
external
|
||||
pure
|
||||
returns (bool ok, string memory reason)
|
||||
{
|
||||
if (token == address(0) || amount == 0 || recipient == address(0)) {
|
||||
return (false, "invalid bridge request");
|
||||
}
|
||||
return (true, "");
|
||||
}
|
||||
|
||||
function executeBridge(
|
||||
bytes32 bridgeType,
|
||||
bytes calldata,
|
||||
address token,
|
||||
uint256 amount,
|
||||
address recipient
|
||||
) external payable returns (bytes32 referenceId) {
|
||||
function executeBridge(bytes32 bridgeType, bytes calldata, address token, uint256 amount, address recipient)
|
||||
external
|
||||
payable
|
||||
returns (bytes32 referenceId)
|
||||
{
|
||||
ERC20(token).transferFrom(msg.sender, address(this), amount);
|
||||
emit Bridged(bridgeType, token, amount, recipient);
|
||||
return keccak256(abi.encode(bridgeType, token, amount, recipient));
|
||||
@@ -250,11 +243,11 @@ contract MockD3MMV2 {
|
||||
quoteAmount[tokenIn][tokenOut] = amountOut;
|
||||
}
|
||||
|
||||
function querySellTokens(
|
||||
address fromToken,
|
||||
address toToken,
|
||||
uint256 fromAmount
|
||||
) external view returns (uint256 payFromAmount, uint256 receiveToAmount, uint256 vusdAmount, uint256 swapFee, uint256 mtFee) {
|
||||
function querySellTokens(address fromToken, address toToken, uint256 fromAmount)
|
||||
external
|
||||
view
|
||||
returns (uint256 payFromAmount, uint256 receiveToAmount, uint256 vusdAmount, uint256 swapFee, uint256 mtFee)
|
||||
{
|
||||
payFromAmount = fromAmount;
|
||||
receiveToAmount = quoteAmount[fromToken][toToken];
|
||||
vusdAmount = 0;
|
||||
@@ -301,14 +294,8 @@ contract MockD3ProxyV2 {
|
||||
) external payable returns (uint256 receiveToAmount) {
|
||||
require(deadLine >= block.timestamp, "expired");
|
||||
SwapCallbackData memory swapData = SwapCallbackData({data: data, payer: msg.sender});
|
||||
receiveToAmount = MockD3MMV2(pool).sellToken(
|
||||
to,
|
||||
fromToken,
|
||||
toToken,
|
||||
fromAmount,
|
||||
minReceiveAmount,
|
||||
abi.encode(swapData)
|
||||
);
|
||||
receiveToAmount =
|
||||
MockD3MMV2(pool).sellToken(to, fromToken, toToken, fromAmount, minReceiveAmount, abi.encode(swapData));
|
||||
}
|
||||
|
||||
function d3MMSwapCallBack(address token, uint256 value, bytes calldata callbackData) external {
|
||||
@@ -589,6 +576,39 @@ contract EnhancedSwapRouterV2Test is Test {
|
||||
vm.stopPrank();
|
||||
}
|
||||
|
||||
function testQuoteConfiguredProviderQuotesSingleDodoRoute() public view {
|
||||
RouteTypesV2.ProviderQuote memory quote =
|
||||
router.quoteConfiguredProvider(address(weth), address(usdt), 1 ether, RouteTypesV2.Provider.Dodo);
|
||||
|
||||
assertEq(uint256(quote.provider), uint256(RouteTypesV2.Provider.Dodo));
|
||||
assertEq(quote.target, address(dodoProvider));
|
||||
assertEq(quote.amountOut, 1_800 ether);
|
||||
assertEq(quote.estimatedGas, 140000);
|
||||
assertTrue(quote.executable);
|
||||
assertEq(abi.decode(quote.providerData, (address)), address(0xA11CE));
|
||||
}
|
||||
|
||||
function testQuoteConfiguredProviderRevertsWhenProviderDisabled() public {
|
||||
router.setProviderEnabled(RouteTypesV2.Provider.Dodo, false);
|
||||
|
||||
vm.expectRevert(EnhancedSwapRouterV2.ProviderDisabled.selector);
|
||||
router.quoteConfiguredProvider(address(weth), address(usdt), 1 ether, RouteTypesV2.Provider.Dodo);
|
||||
}
|
||||
|
||||
function testQuoteConfiguredProviderRevertsWhenRouteMissing() public {
|
||||
vm.expectRevert(EnhancedSwapRouterV2.RouteNotConfigured.selector);
|
||||
router.quoteConfiguredProvider(address(weth), address(dai), 1 ether, RouteTypesV2.Provider.Dodo);
|
||||
}
|
||||
|
||||
function testQuoteConfiguredProvidersStillDiscoversConfiguredRoutes() public view {
|
||||
RouteTypesV2.ProviderQuote[] memory quotes =
|
||||
router.quoteConfiguredProviders(address(weth), address(usdt), 1 ether);
|
||||
|
||||
assertEq(quotes.length, 1);
|
||||
assertEq(uint256(quotes[0].provider), uint256(RouteTypesV2.Provider.Dodo));
|
||||
assertEq(quotes[0].amountOut, 1_800 ether);
|
||||
}
|
||||
|
||||
function testMultiLegExecutionUsesPreviousLegOutput() public {
|
||||
vm.startPrank(user);
|
||||
weth.approve(address(router), 1 ether);
|
||||
|
||||
Reference in New Issue
Block a user