Skip to content

Commit

Permalink
Tasks: Implement Uniswap V3 swapper
Browse files Browse the repository at this point in the history
  • Loading branch information
PatricioHenderson committed Aug 22, 2023
1 parent dc26d88 commit 99ea74b
Show file tree
Hide file tree
Showing 6 changed files with 710 additions and 0 deletions.
18 changes: 18 additions & 0 deletions packages/authorizer/contracts/AuthorizedHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,22 @@ contract AuthorizedHelpers {
r[3] = p4;
r[4] = p5;
}

function authParams(address p1, uint256 p2, uint256 p3, uint24 p4, address[] memory p5, uint24[] memory p6)
internal
pure
returns (uint256[] memory r)
{
r = new uint256[](4 + p5.length + p6.length);
r[0] = uint256(uint160(p1));
r[1] = p2;
r[2] = p3;
r[3] = p4;
for (uint256 i = 0; i < p5.length; i++) {
r[i + 4] = uint256(uint160(p5[i]));
}
for (uint256 i = 0; i < p6.length; i++) {
r[i + 4 + p5.length] = p6[i];
}
}
}
34 changes: 34 additions & 0 deletions packages/tasks/contracts/interfaces/swap/IUniswapV3Swapper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.8.0;

import './IBaseSwapTask.sol';

/**
* @dev UniSwap v3 swapper action interface
*/
interface IUniswapV3Swapper is IBaseSwapTask {
/**
* @dev Execution function
*/
function call(
address tokenIn,
uint256 amountIn,
uint256 minAmountOut,
uint24 fee,
address[] memory hopTokens,
uint24[] memory hopFees
) external;
}
115 changes: 115 additions & 0 deletions packages/tasks/contracts/swap/UniswapV3Swapper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

pragma solidity ^0.8.0;

import '@mimic-fi/v3-helpers/contracts/math/FixedPoint.sol';
import '@mimic-fi/v3-helpers/contracts/utils/BytesHelpers.sol';
import '@mimic-fi/v3-connectors/contracts/swap/uniswap-v3/IUniswapV3Connector.sol';

import './BaseSwapTask.sol';
import '../interfaces/swap/IUniswapV3Swapper.sol';

contract UniswapV3Swapper is IUniswapV3Swapper, BaseSwapTask {
using FixedPoint for uint256;
using BytesHelpers for bytes;

// Execution type for relayers
bytes32 public constant override EXECUTION_TYPE = keccak256('UNISWAP_V3_SWAPPER');

/**
* @dev Uniswap v3 swapper task config. Only used in the initializer.
*/
struct UniswapV3SwapperConfig {
BaseSwapConfig baseSwapConfig;
}

/**
* @dev Initializes the Uniswap v3 swapper action.
* @param config Uniswap v3 swap config.
*/
function initialize(UniswapV3SwapperConfig memory config) external initializer {
__UniswapV3Swapper_init(config);
}

/**
* @dev Initializes the Uniswap V3 swapper. It does call upper contracts.
* @param config Uniswap v3 swap config.
*/
function __UniswapV3Swapper_init(UniswapV3SwapperConfig memory config) internal onlyInitializing {
__BaseSwapTask_init(config.baseSwapConfig);
__UniswapV3Swapper_init_unchained(config);
}

/**
* @dev Initilizes the uniswap V3 swapper. It does not call upper contracts.
* @param config Uniswap v3 swap config.
*/
function __UniswapV3Swapper_init_unchained(UniswapV3SwapperConfig memory config) internal onlyInitializing {
// solhint-disable-previous-line no-empty-blocks
}

/**
* @dev Executes the Uniswap v3 swapper task
*/
function call(
address tokenIn,
uint256 amountIn,
uint256 slippage,
uint24 fee,
address[] memory hopTokens,
uint24[] memory hopFees
) external override authP(authParams(tokenIn, amountIn, slippage, fee, hopTokens, hopFees)) {
if (amountIn == 0) amountIn = getTaskAmount(tokenIn);
_beforeUniswapV3Swapper(tokenIn, amountIn, slippage);

address tokenOut = getTokenOut(tokenIn);
uint256 price = _getPrice(tokenIn, tokenOut);
uint256 minAmountOut = amountIn.mulUp(price).mulUp(FixedPoint.ONE - slippage);

bytes memory connectorData = abi.encodeWithSelector(
UniswapV3Connector.execute.selector,
tokenIn,
tokenOut,
amountIn,
minAmountOut,
fee,
hopTokens,
hopFees
);

bytes memory result = ISmartVault(smartVault).execute(connector, connectorData);
_afterUniswapV3Swapper(tokenIn, amountIn, slippage, tokenOut, result.toUint256());
}

/**
* @dev Before Uniswap v3Swapper Task
*/
function _beforeUniswapV3Swapper(address token, uint256 amount, uint256 slippage) internal virtual {
_beforeBaseSwapTask(token, amount, slippage);
}

/**
* @dev After Uniswap V3 swapper hook
*/
function _afterUniswapV3Swapper(
address tokenIn,
uint256 amountIn,
uint256 slippage,
address tokenOut,
uint256 amountOut
) internal virtual {
_afterBaseSwapTask(tokenIn, amountIn, slippage, tokenOut, amountOut);
}
}
37 changes: 37 additions & 0 deletions packages/tasks/contracts/test/swap/UniswapV3ConnectorMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

pragma solidity ^0.8.0;

contract UniswapV3ConnectorMock {
event LogExecute(
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 minAmountOut,
uint24 fee,
address[] hopTokens,
uint24[] hopFees
);

function execute(
address tokenIn,
address tokenOut,
uint256 amountIn,
uint256 minAmountOut,
uint24 fee,
address[] memory hopTokens,
uint24[] memory hopFees
) external returns (uint256) {
emit LogExecute(tokenIn, tokenOut, amountIn, minAmountOut, fee, hopTokens, hopFees);
return minAmountOut;
}
}
Loading

0 comments on commit 99ea74b

Please sign in to comment.