mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Merge pull request #159 from Instadapp/optimism-connectors
Uniswap optimism connectors
This commit is contained in:
commit
05e1372c01
7
contracts/optimism/connectors/authority/events.sol
Normal file
7
contracts/optimism/connectors/authority/events.sol
Normal file
|
@ -0,0 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogAddAuth(address indexed _msgSender, address indexed _authority);
|
||||
event LogRemoveAuth(address indexed _msgSender, address indexed _authority);
|
||||
}
|
16
contracts/optimism/connectors/authority/helpers.sol
Normal file
16
contracts/optimism/connectors/authority/helpers.sol
Normal file
|
@ -0,0 +1,16 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { ListInterface } from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
ListInterface internal constant listContract = ListInterface(0x9926955e0Dd681Dc303370C52f4Ad0a4dd061687);
|
||||
|
||||
function checkAuthCount() internal view returns (uint count) {
|
||||
uint64 accountId = listContract.accountID(address(this));
|
||||
count = listContract.accountLink(accountId).count;
|
||||
}
|
||||
}
|
14
contracts/optimism/connectors/authority/interface.sol
Normal file
14
contracts/optimism/connectors/authority/interface.sol
Normal file
|
@ -0,0 +1,14 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface ListInterface {
|
||||
struct AccountLink {
|
||||
address first;
|
||||
address last;
|
||||
uint64 count;
|
||||
}
|
||||
|
||||
function accountID(address) external view returns (uint64);
|
||||
function accountLink(uint64) external view returns (AccountLink memory);
|
||||
}
|
58
contracts/optimism/connectors/authority/main.sol
Normal file
58
contracts/optimism/connectors/authority/main.sol
Normal file
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title Authority.
|
||||
* @dev Manage Authorities to DSA.
|
||||
*/
|
||||
|
||||
import { AccountInterface } from "../../common/interfaces.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract AuthorityResolver is Events, Helpers {
|
||||
/**
|
||||
* @dev Add New authority
|
||||
* @notice Add an address as account authority
|
||||
* @param authority The authority Address.
|
||||
*/
|
||||
function add(
|
||||
address authority
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
require(authority != address(0), "Not-valid-authority");
|
||||
AccountInterface _dsa = AccountInterface(address(this));
|
||||
if (_dsa.isAuth(authority)) {
|
||||
authority = address(0);
|
||||
} else {
|
||||
_dsa.enable(authority);
|
||||
}
|
||||
|
||||
_eventName = "LogAddAuth(address,address)";
|
||||
_eventParam = abi.encode(msg.sender, authority);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Remove authority
|
||||
* @notice Remove an address as account authority
|
||||
* @param authority The authority Address.
|
||||
*/
|
||||
function remove(
|
||||
address authority
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
require(checkAuthCount() > 1, "Removing-all-authorities");
|
||||
require(authority != address(0), "Not-valid-authority");
|
||||
AccountInterface _dsa = AccountInterface(address(this));
|
||||
if (_dsa.isAuth(authority)) {
|
||||
_dsa.disable(authority);
|
||||
} else {
|
||||
authority = address(0);
|
||||
}
|
||||
|
||||
_eventName = "LogRemoveAuth(address,address)";
|
||||
_eventParam = abi.encode(msg.sender, authority);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2AuthOptimism is AuthorityResolver {
|
||||
string public constant name = "Auth-v1.1";
|
||||
}
|
6
contracts/optimism/connectors/basic/events.sol
Normal file
6
contracts/optimism/connectors/basic/events.sol
Normal file
|
@ -0,0 +1,6 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(address indexed erc20, uint256 tokenAmt, uint256 getId, uint256 setId);
|
||||
event LogWithdraw(address indexed erc20, uint256 tokenAmt, address indexed to, uint256 getId, uint256 setId);
|
||||
}
|
81
contracts/optimism/connectors/basic/main.sol
Normal file
81
contracts/optimism/connectors/basic/main.sol
Normal file
|
@ -0,0 +1,81 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title Basic.
|
||||
* @dev Deposit & Withdraw from DSA.
|
||||
*/
|
||||
|
||||
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract BasicResolver is Events, DSMath, Basic {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev Deposit Assets To Smart Account.
|
||||
* @notice Deposit a token to DSA.
|
||||
* @param token The address of the token to deposit.<br>(For <b>ETH</b>: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE and need to pass `value` parameter equal to `amt` in cast function ```dsa.cast({..., value: amt})```.<br>For <b>ERC20</b>: Need to give allowance prior casting spells.)
|
||||
* @param amt The amount of tokens to deposit. (For max: `uint256(-1)` (Not valid for ETH))
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the amount of tokens deposited.
|
||||
*/
|
||||
function deposit(
|
||||
address token,
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) public payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
if (token != ethAddr) {
|
||||
IERC20 tokenContract = IERC20(token);
|
||||
_amt = _amt == uint(-1) ? tokenContract.balanceOf(msg.sender) : _amt;
|
||||
tokenContract.safeTransferFrom(msg.sender, address(this), _amt);
|
||||
} else {
|
||||
require(msg.value == _amt || _amt == uint(-1), "invalid-ether-amount");
|
||||
_amt = msg.value;
|
||||
}
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogDeposit(address,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(token, _amt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw Assets from Smart Account
|
||||
* @notice Withdraw a token from DSA
|
||||
* @param token The address of the token to withdraw. (For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
|
||||
* @param amt The amount of tokens to withdraw. (For max: `uint256(-1)`)
|
||||
* @param to The address to receive the token upon withdrawal
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the amount of tokens withdrawn.
|
||||
*/
|
||||
function withdraw(
|
||||
address token,
|
||||
uint amt,
|
||||
address payable to,
|
||||
uint getId,
|
||||
uint setId
|
||||
) public payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
if (token == ethAddr) {
|
||||
_amt = _amt == uint(-1) ? address(this).balance : _amt;
|
||||
to.call{value: _amt}("");
|
||||
} else {
|
||||
IERC20 tokenContract = IERC20(token);
|
||||
_amt = _amt == uint(-1) ? tokenContract.balanceOf(address(this)) : _amt;
|
||||
tokenContract.safeTransfer(to, _amt);
|
||||
}
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogWithdraw(address,uint256,address,uint256,uint256)";
|
||||
_eventParam = abi.encode(token, _amt, to, getId, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2BasicOptimism is BasicResolver {
|
||||
string constant public name = "Basic-v1";
|
||||
}
|
35
contracts/optimism/connectors/uniswap/v3/events.sol
Normal file
35
contracts/optimism/connectors/uniswap/v3/events.sol
Normal file
|
@ -0,0 +1,35 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogMint(
|
||||
uint256 indexed tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
int24 tickLower,
|
||||
int24 tickUpper
|
||||
);
|
||||
|
||||
event LogDeposit(
|
||||
uint256 indexed tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
);
|
||||
|
||||
event LogWithdraw(
|
||||
uint256 indexed tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
);
|
||||
|
||||
event LogCollect(
|
||||
uint256 tokenId,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
);
|
||||
|
||||
event LogBurnPosition(uint256 tokenId);
|
||||
}
|
288
contracts/optimism/connectors/uniswap/v3/helpers.sol
Normal file
288
contracts/optimism/connectors/uniswap/v3/helpers.sol
Normal file
|
@ -0,0 +1,288 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import {TokenInterface} from "../../../common/interfaces.sol";
|
||||
import {DSMath} from "../../../common/math.sol";
|
||||
import {Basic} from "../../../common/basic.sol";
|
||||
import "./interface.sol";
|
||||
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
||||
import "@uniswap/v3-core/contracts/libraries/TickMath.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
|
||||
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev uniswap v3 NFT Position Manager & Swap Router
|
||||
*/
|
||||
INonfungiblePositionManager constant nftManager =
|
||||
INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
|
||||
ISwapRouter constant swapRouter =
|
||||
ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
|
||||
|
||||
struct MintParams {
|
||||
address tokenA;
|
||||
address tokenB;
|
||||
uint24 fee;
|
||||
int24 tickLower;
|
||||
int24 tickUpper;
|
||||
uint256 amtA;
|
||||
uint256 amtB;
|
||||
uint256 slippage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Get Last NFT Index
|
||||
* @param user: User address
|
||||
*/
|
||||
function _getLastNftId(address user)
|
||||
internal
|
||||
view
|
||||
returns (uint256 tokenId)
|
||||
{
|
||||
uint256 len = nftManager.balanceOf(user);
|
||||
tokenId = nftManager.tokenOfOwnerByIndex(user, len - 1);
|
||||
}
|
||||
|
||||
function getMinAmount(
|
||||
TokenInterface token,
|
||||
uint256 amt,
|
||||
uint256 slippage
|
||||
) internal view returns (uint256 minAmt) {
|
||||
uint256 _amt18 = convertTo18(token.decimals(), amt);
|
||||
minAmt = wmul(_amt18, sub(WAD, slippage));
|
||||
minAmt = convert18ToDec(token.decimals(), minAmt);
|
||||
}
|
||||
|
||||
function sortTokenAddress(address _token0, address _token1)
|
||||
internal
|
||||
view
|
||||
returns (address token0, address token1)
|
||||
{
|
||||
if (_token0 > _token1) {
|
||||
(token0, token1) = (_token1, _token0);
|
||||
} else {
|
||||
(token0, token1) = (_token0, _token1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Mint function which interact with Uniswap v3
|
||||
*/
|
||||
function _mint(MintParams memory params)
|
||||
internal
|
||||
returns (
|
||||
uint256 tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
)
|
||||
{
|
||||
(TokenInterface _token0, TokenInterface _token1) = changeEthAddress(
|
||||
params.tokenA,
|
||||
params.tokenB
|
||||
);
|
||||
|
||||
uint256 _amount0 = params.amtA == uint256(-1)
|
||||
? getTokenBal(TokenInterface(params.tokenA))
|
||||
: params.amtA;
|
||||
uint256 _amount1 = params.amtB == uint256(-1)
|
||||
? getTokenBal(TokenInterface(params.tokenB))
|
||||
: params.amtB;
|
||||
|
||||
convertEthToWeth(address(_token0) == wethAddr, _token0, _amount0);
|
||||
convertEthToWeth(address(_token1) == wethAddr, _token1, _amount1);
|
||||
|
||||
approve(_token0, address(nftManager), _amount0);
|
||||
approve(_token1, address(nftManager), _amount1);
|
||||
|
||||
{
|
||||
(address token0, ) = sortTokenAddress(
|
||||
address(_token0),
|
||||
address(_token1)
|
||||
);
|
||||
|
||||
if (token0 != address(_token0)) {
|
||||
(_token0, _token1) = (_token1, _token0);
|
||||
(_amount0, _amount1) = (_amount1, _amount0);
|
||||
}
|
||||
}
|
||||
uint256 _minAmt0 = getMinAmount(_token0, _amount0, params.slippage);
|
||||
uint256 _minAmt1 = getMinAmount(_token1, _amount1, params.slippage);
|
||||
|
||||
INonfungiblePositionManager.MintParams
|
||||
memory params = INonfungiblePositionManager.MintParams(
|
||||
address(_token0),
|
||||
address(_token1),
|
||||
params.fee,
|
||||
params.tickLower,
|
||||
params.tickUpper,
|
||||
_amount0,
|
||||
_amount1,
|
||||
_minAmt0,
|
||||
_minAmt1,
|
||||
address(this),
|
||||
block.timestamp
|
||||
);
|
||||
|
||||
(tokenId, liquidity, amountA, amountB) = nftManager.mint(params);
|
||||
}
|
||||
|
||||
function getNftTokenPairAddresses(uint256 _tokenId)
|
||||
internal
|
||||
view
|
||||
returns (address token0, address token1)
|
||||
{
|
||||
(bool success, bytes memory data) = address(nftManager).staticcall(
|
||||
abi.encodeWithSelector(nftManager.positions.selector, _tokenId)
|
||||
);
|
||||
require(success, "fetching positions failed");
|
||||
{
|
||||
(, , token0, token1, , , , ) = abi.decode(
|
||||
data,
|
||||
(
|
||||
uint96,
|
||||
address,
|
||||
address,
|
||||
address,
|
||||
uint24,
|
||||
int24,
|
||||
int24,
|
||||
uint128
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Check if token address is etherAddr and convert it to weth
|
||||
*/
|
||||
function _checkETH(
|
||||
address _token0,
|
||||
address _token1,
|
||||
uint256 _amount0,
|
||||
uint256 _amount1
|
||||
) internal {
|
||||
bool isEth0 = _token0 == wethAddr;
|
||||
bool isEth1 = _token1 == wethAddr;
|
||||
convertEthToWeth(isEth0, TokenInterface(_token0), _amount0);
|
||||
convertEthToWeth(isEth1, TokenInterface(_token1), _amount1);
|
||||
approve(TokenInterface(_token0), address(nftManager), _amount0);
|
||||
approve(TokenInterface(_token1), address(nftManager), _amount1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev addLiquidityWrapper function wrapper of _addLiquidity
|
||||
*/
|
||||
function _addLiquidityWrapper(
|
||||
uint256 tokenId,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 slippage
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint256 liquidity,
|
||||
uint256 amtA,
|
||||
uint256 amtB
|
||||
)
|
||||
{
|
||||
(address token0, address token1) = getNftTokenPairAddresses(tokenId);
|
||||
|
||||
(liquidity, amtA, amtB) = _addLiquidity(
|
||||
tokenId,
|
||||
token0,
|
||||
token1,
|
||||
amountA,
|
||||
amountB,
|
||||
slippage
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev addLiquidity function which interact with Uniswap v3
|
||||
*/
|
||||
function _addLiquidity(
|
||||
uint256 _tokenId,
|
||||
address _token0,
|
||||
address _token1,
|
||||
uint256 _amount0,
|
||||
uint256 _amount1,
|
||||
uint256 _slippage
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
)
|
||||
{
|
||||
_checkETH(_token0, _token1, _amount0, _amount1);
|
||||
uint256 _amount0Min = getMinAmount(
|
||||
TokenInterface(_token0),
|
||||
_amount0,
|
||||
_slippage
|
||||
);
|
||||
uint256 _amount1Min = getMinAmount(
|
||||
TokenInterface(_token1),
|
||||
_amount1,
|
||||
_slippage
|
||||
);
|
||||
INonfungiblePositionManager.IncreaseLiquidityParams
|
||||
memory params = INonfungiblePositionManager.IncreaseLiquidityParams(
|
||||
_tokenId,
|
||||
_amount0,
|
||||
_amount1,
|
||||
_amount0Min,
|
||||
_amount1Min,
|
||||
block.timestamp
|
||||
);
|
||||
|
||||
(liquidity, amount0, amount1) = nftManager.increaseLiquidity(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev decreaseLiquidity function which interact with Uniswap v3
|
||||
*/
|
||||
function _decreaseLiquidity(
|
||||
uint256 _tokenId,
|
||||
uint128 _liquidity,
|
||||
uint256 _amount0Min,
|
||||
uint256 _amount1Min
|
||||
) internal returns (uint256 amount0, uint256 amount1) {
|
||||
INonfungiblePositionManager.DecreaseLiquidityParams
|
||||
memory params = INonfungiblePositionManager.DecreaseLiquidityParams(
|
||||
_tokenId,
|
||||
_liquidity,
|
||||
_amount0Min,
|
||||
_amount1Min,
|
||||
block.timestamp
|
||||
);
|
||||
(amount0, amount1) = nftManager.decreaseLiquidity(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev collect function which interact with Uniswap v3
|
||||
*/
|
||||
function _collect(
|
||||
uint256 _tokenId,
|
||||
uint128 _amount0Max,
|
||||
uint128 _amount1Max
|
||||
) internal returns (uint256 amount0, uint256 amount1) {
|
||||
INonfungiblePositionManager.CollectParams
|
||||
memory params = INonfungiblePositionManager.CollectParams(
|
||||
_tokenId,
|
||||
address(this),
|
||||
_amount0Max,
|
||||
_amount1Max
|
||||
);
|
||||
(amount0, amount1) = nftManager.collect(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Burn Function
|
||||
*/
|
||||
function _burn(uint256 _tokenId) internal {
|
||||
nftManager.burn(_tokenId);
|
||||
}
|
||||
}
|
420
contracts/optimism/connectors/uniswap/v3/interface.sol
Normal file
420
contracts/optimism/connectors/uniswap/v3/interface.sol
Normal file
|
@ -0,0 +1,420 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Metadata.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol";
|
||||
|
||||
/**
|
||||
* @title Callback for IUniswapV3PoolActions#swap
|
||||
* @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
|
||||
*/
|
||||
interface IUniswapV3SwapCallback {
|
||||
/**
|
||||
* @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
|
||||
* @dev In the implementation you must pay the pool tokens owed for the swap.
|
||||
* The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
|
||||
* amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
|
||||
* @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
|
||||
* the end of the swap. If positive, the callback must send that amount of token0 to the pool.
|
||||
* @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
|
||||
* the end of the swap. If positive, the callback must send that amount of token1 to the pool.
|
||||
* @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
|
||||
*/
|
||||
function uniswapV3SwapCallback(
|
||||
int256 amount0Delta,
|
||||
int256 amount1Delta,
|
||||
bytes calldata data
|
||||
) external;
|
||||
}
|
||||
|
||||
interface ISwapRouter is IUniswapV3SwapCallback {
|
||||
struct ExactInputSingleParams {
|
||||
address tokenIn;
|
||||
address tokenOut;
|
||||
uint24 fee;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountIn;
|
||||
uint256 amountOutMinimum;
|
||||
uint160 sqrtPriceLimitX96;
|
||||
}
|
||||
/**
|
||||
* @notice Swaps `amountIn` of one token for as much as possible of another token
|
||||
* @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
|
||||
* @return amountOut The amount of the received token
|
||||
*/
|
||||
function exactInputSingle(ExactInputSingleParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountOut);
|
||||
|
||||
struct ExactInputParams {
|
||||
bytes path;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountIn;
|
||||
uint256 amountOutMinimum;
|
||||
}
|
||||
/**
|
||||
* @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
|
||||
* @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
|
||||
* @return amountOut The amount of the received token
|
||||
*/
|
||||
function exactInput(ExactInputParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountOut);
|
||||
|
||||
struct ExactOutputSingleParams {
|
||||
address tokenIn;
|
||||
address tokenOut;
|
||||
uint24 fee;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountOut;
|
||||
uint256 amountInMaximum;
|
||||
uint160 sqrtPriceLimitX96;
|
||||
}
|
||||
/**
|
||||
* @notice Swaps as little as possible of one token for `amountOut` of another token
|
||||
* @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
|
||||
* @return amountIn The amount of the input token
|
||||
*/
|
||||
function exactOutputSingle(ExactOutputSingleParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountIn);
|
||||
|
||||
struct ExactOutputParams {
|
||||
bytes path;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
uint256 amountOut;
|
||||
uint256 amountInMaximum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
|
||||
* @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
|
||||
* @return amountIn The amount of the input token
|
||||
*/
|
||||
function exactOutput(ExactOutputParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amountIn);
|
||||
}
|
||||
/**
|
||||
* @title Creates and initializes V3 Pools
|
||||
* @notice Provides a method for creating and initializing a pool, if necessary, for bundling with other methods that
|
||||
* require the pool to exist.
|
||||
*/
|
||||
interface IPoolInitializer {
|
||||
/**
|
||||
* @notice Creates a new pool if it does not exist, then initializes if not initialized
|
||||
* @dev This method can be bundled with others via IMulticall for the first action (e.g. mint) performed against a pool
|
||||
* @param token0 The contract address of token0 of the pool
|
||||
* @param token1 The contract address of token1 of the pool
|
||||
* @param fee The fee amount of the v3 pool for the specified token pair
|
||||
* @param sqrtPriceX96 The initial square root price of the pool as a Q64.96 value
|
||||
* @return pool Returns the pool address based on the pair of tokens and fee, will return the newly created pool address if necessary
|
||||
*/
|
||||
function createAndInitializePoolIfNecessary(
|
||||
address token0,
|
||||
address token1,
|
||||
uint24 fee,
|
||||
uint160 sqrtPriceX96
|
||||
) external payable returns (address pool);
|
||||
}
|
||||
/**
|
||||
* @title Immutable state
|
||||
* @notice Functions that return immutable state of the router
|
||||
*/
|
||||
interface IPeripheryImmutableState {
|
||||
/// @return Returns the address of the Uniswap V3 factory
|
||||
function factory() external view returns (address);
|
||||
|
||||
/// @return Returns the address of WETH9
|
||||
function WETH9() external view returns (address);
|
||||
}
|
||||
|
||||
/**
|
||||
* @title Periphery Payments
|
||||
* @notice Functions to ease deposits and withdrawals of ETH
|
||||
*/
|
||||
interface IPeripheryPayments {
|
||||
/**
|
||||
* @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH.
|
||||
* @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users.
|
||||
* @param amountMinimum The minimum amount of WETH9 to unwrap
|
||||
* @param recipient The address receiving ETH
|
||||
*/
|
||||
function unwrapWETH9(uint256 amountMinimum, address recipient)
|
||||
external
|
||||
payable;
|
||||
|
||||
/**
|
||||
* @notice Refunds any ETH balance held by this contract to the `msg.sender`
|
||||
* @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps
|
||||
* that use ether for the input amount
|
||||
*/
|
||||
function refundETH() external payable;
|
||||
|
||||
/**
|
||||
* @notice Transfers the full amount of a token held by this contract to recipient
|
||||
* @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users
|
||||
* @param token The contract address of the token which will be transferred to `recipient`
|
||||
* @param amountMinimum The minimum amount of token required for a transfer
|
||||
* @param recipient The destination address of the token
|
||||
*/
|
||||
function sweepToken(
|
||||
address token,
|
||||
uint256 amountMinimum,
|
||||
address recipient
|
||||
) external payable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @title ERC721 with permit
|
||||
* @notice Extension to ERC721 that includes a permit function for signature based approvals
|
||||
*/
|
||||
interface IERC721Permit is IERC721 {
|
||||
/**
|
||||
* @notice The permit typehash used in the permit signature
|
||||
* @return The typehash for the permit
|
||||
*/
|
||||
function PERMIT_TYPEHASH() external pure returns (bytes32);
|
||||
|
||||
/**
|
||||
* @notice The domain separator used in the permit signature
|
||||
* @return The domain seperator used in encoding of permit signature
|
||||
*/
|
||||
function DOMAIN_SEPARATOR() external view returns (bytes32);
|
||||
|
||||
/**
|
||||
* @notice Approve of a specific token ID for spending by spender via signature
|
||||
* @param spender The account that is being approved
|
||||
* @param tokenId The ID of the token that is being approved for spending
|
||||
* @param deadline The deadline timestamp by which the call must be mined for the approve to work
|
||||
* @param v Must produce valid secp256k1 signature from the holder along with `r` and `s`
|
||||
* @param r Must produce valid secp256k1 signature from the holder along with `v` and `s`
|
||||
* @param s Must produce valid secp256k1 signature from the holder along with `r` and `v`
|
||||
*/
|
||||
function permit(
|
||||
address spender,
|
||||
uint256 tokenId,
|
||||
uint256 deadline,
|
||||
uint8 v,
|
||||
bytes32 r,
|
||||
bytes32 s
|
||||
) external payable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @title Non-fungible token for positions
|
||||
* @notice Wraps Uniswap V3 positions in a non-fungible token interface which allows for them to be transferred
|
||||
* and authorized.
|
||||
*/
|
||||
interface INonfungiblePositionManager is
|
||||
IPoolInitializer,
|
||||
IPeripheryPayments,
|
||||
IPeripheryImmutableState,
|
||||
IERC721Metadata,
|
||||
IERC721Enumerable,
|
||||
IERC721Permit
|
||||
{
|
||||
/**
|
||||
* @notice Emitted when liquidity is increased for a position NFT
|
||||
* @dev Also emitted when a token is minted
|
||||
* @param tokenId The ID of the token for which liquidity was increased
|
||||
* @param liquidity The amount by which liquidity for the NFT position was increased
|
||||
* @param amount0 The amount of token0 that was paid for the increase in liquidity
|
||||
* @param amount1 The amount of token1 that was paid for the increase in liquidity
|
||||
*/
|
||||
event IncreaseLiquidity(
|
||||
uint256 indexed tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
/**
|
||||
* @notice Emitted when liquidity is decreased for a position NFT
|
||||
* @param tokenId The ID of the token for which liquidity was decreased
|
||||
* @param liquidity The amount by which liquidity for the NFT position was decreased
|
||||
* @param amount0 The amount of token0 that was accounted for the decrease in liquidity
|
||||
* @param amount1 The amount of token1 that was accounted for the decrease in liquidity
|
||||
*/
|
||||
event DecreaseLiquidity(
|
||||
uint256 indexed tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
/**
|
||||
* @notice Emitted when tokens are collected for a position NFT
|
||||
* @dev The amounts reported may not be exactly equivalent to the amounts transferred, due to rounding behavior
|
||||
* @param tokenId The ID of the token for which underlying tokens were collected
|
||||
* @param recipient The address of the account that received the collected tokens
|
||||
* @param amount0 The amount of token0 owed to the position that was collected
|
||||
* @param amount1 The amount of token1 owed to the position that was collected
|
||||
*/
|
||||
event Collect(
|
||||
uint256 indexed tokenId,
|
||||
address recipient,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
/**
|
||||
* @notice Returns the position information associated with a given token ID.
|
||||
* @dev Throws if the token ID is not valid.
|
||||
* @param tokenId The ID of the token that represents the position
|
||||
* @return nonce The nonce for permits
|
||||
* @return operator The address that is approved for spending
|
||||
* @return token0 The address of the token0 for a specific pool
|
||||
* @return token1 The address of the token1 for a specific pool
|
||||
* @return fee The fee associated with the pool
|
||||
* @return tickLower The lower end of the tick range for the position
|
||||
* @return tickUpper The higher end of the tick range for the position
|
||||
* @return liquidity The liquidity of the position
|
||||
* @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position
|
||||
* @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position
|
||||
* @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation
|
||||
* @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation
|
||||
*/
|
||||
function positions(uint256 tokenId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint96 nonce,
|
||||
address operator,
|
||||
address token0,
|
||||
address token1,
|
||||
uint24 fee,
|
||||
int24 tickLower,
|
||||
int24 tickUpper,
|
||||
uint128 liquidity,
|
||||
uint256 feeGrowthInside0LastX128,
|
||||
uint256 feeGrowthInside1LastX128,
|
||||
uint128 tokensOwed0,
|
||||
uint128 tokensOwed1
|
||||
);
|
||||
|
||||
struct MintParams {
|
||||
address token0;
|
||||
address token1;
|
||||
uint24 fee;
|
||||
int24 tickLower;
|
||||
int24 tickUpper;
|
||||
uint256 amount0Desired;
|
||||
uint256 amount1Desired;
|
||||
uint256 amount0Min;
|
||||
uint256 amount1Min;
|
||||
address recipient;
|
||||
uint256 deadline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Creates a new position wrapped in a NFT
|
||||
* @dev Call this when the pool does exist and is initialized. Note that if the pool is created but not initialized
|
||||
* a method does not exist, i.e. the pool is assumed to be initialized.
|
||||
* @param params The params necessary to mint a position, encoded as `MintParams` in calldata
|
||||
* @return tokenId The ID of the token that represents the minted position
|
||||
* @return liquidity The amount of liquidity for this position
|
||||
* @return amount0 The amount of token0
|
||||
* @return amount1 The amount of token1
|
||||
*/
|
||||
function mint(MintParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (
|
||||
uint256 tokenId,
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
struct IncreaseLiquidityParams {
|
||||
uint256 tokenId;
|
||||
uint256 amount0Desired;
|
||||
uint256 amount1Desired;
|
||||
uint256 amount0Min;
|
||||
uint256 amount1Min;
|
||||
uint256 deadline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Increases the amount of liquidity in a position, with tokens paid by the `msg.sender`
|
||||
* @param params tokenId The ID of the token for which liquidity is being increased,
|
||||
* amount0Desired The desired amount of token0 to be spent,
|
||||
* amount1Desired The desired amount of token1 to be spent,
|
||||
* amount0Min The minimum amount of token0 to spend, which serves as a slippage check,
|
||||
* amount1Min The minimum amount of token1 to spend, which serves as a slippage check,
|
||||
* deadline The time by which the transaction must be included to effect the change
|
||||
* @return liquidity The new liquidity amount as a result of the increase
|
||||
* @return amount0 The amount of token0 to acheive resulting liquidity
|
||||
* @return amount1 The amount of token1 to acheive resulting liquidity
|
||||
*/
|
||||
function increaseLiquidity(IncreaseLiquidityParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (
|
||||
uint128 liquidity,
|
||||
uint256 amount0,
|
||||
uint256 amount1
|
||||
);
|
||||
|
||||
struct DecreaseLiquidityParams {
|
||||
uint256 tokenId;
|
||||
uint128 liquidity;
|
||||
uint256 amount0Min;
|
||||
uint256 amount1Min;
|
||||
uint256 deadline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Decreases the amount of liquidity in a position and accounts it to the position
|
||||
* @param params tokenId The ID of the token for which liquidity is being decreased,
|
||||
* amount The amount by which liquidity will be decreased,
|
||||
* amount0Min The minimum amount of token0 that should be accounted for the burned liquidity,
|
||||
* amount1Min The minimum amount of token1 that should be accounted for the burned liquidity,
|
||||
* deadline The time by which the transaction must be included to effect the change
|
||||
* @return amount0 The amount of token0 accounted to the position's tokens owed
|
||||
* @return amount1 The amount of token1 accounted to the position's tokens owed
|
||||
*/
|
||||
function decreaseLiquidity(DecreaseLiquidityParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amount0, uint256 amount1);
|
||||
|
||||
struct CollectParams {
|
||||
uint256 tokenId;
|
||||
address recipient;
|
||||
uint128 amount0Max;
|
||||
uint128 amount1Max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Collects up to a maximum amount of fees owed to a specific position to the recipient
|
||||
* @param params tokenId The ID of the NFT for which tokens are being collected,
|
||||
* recipient The account that should receive the tokens,
|
||||
* amount0Max The maximum amount of token0 to collect,
|
||||
* amount1Max The maximum amount of token1 to collect
|
||||
* @return amount0 The amount of fees collected in token0
|
||||
* @return amount1 The amount of fees collected in token1
|
||||
*/
|
||||
function collect(CollectParams calldata params)
|
||||
external
|
||||
payable
|
||||
returns (uint256 amount0, uint256 amount1);
|
||||
|
||||
/**
|
||||
* @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens
|
||||
* must be collected first.
|
||||
* @param tokenId The ID of the token that is being burned
|
||||
*/
|
||||
function burn(uint256 tokenId) external payable;
|
||||
}
|
211
contracts/optimism/connectors/uniswap/v3/main.sol
Normal file
211
contracts/optimism/connectors/uniswap/v3/main.sol
Normal file
|
@ -0,0 +1,211 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
/**
|
||||
* @title Uniswap v3.
|
||||
* @dev Decentralized Exchange.
|
||||
*/
|
||||
|
||||
import {TokenInterface} from "../../../common/interfaces.sol";
|
||||
import {Helpers} from "./helpers.sol";
|
||||
import {Events} from "./events.sol";
|
||||
|
||||
abstract contract UniswapResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev Mint New Position
|
||||
* @notice Mint New NFT LP Position
|
||||
* @param tokenA tokenA addreess
|
||||
* @param tokenB tokenB addreess
|
||||
* @param fee fee percentage
|
||||
* @param tickLower Lower tick
|
||||
* @param tickUpper Upper tick
|
||||
* @param amtA amount of tokenA
|
||||
* @param amtB amount of tokenB
|
||||
* @param slippage slippage percentage
|
||||
* @param getIds ID to retrieve amtA
|
||||
* @param setId ID stores the amount of LP token
|
||||
*/
|
||||
function mint(
|
||||
address tokenA,
|
||||
address tokenB,
|
||||
uint24 fee,
|
||||
int24 tickLower,
|
||||
int24 tickUpper,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 slippage,
|
||||
uint256[] calldata getIds,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
|
||||
MintParams memory params;
|
||||
{
|
||||
params = MintParams(
|
||||
tokenA,
|
||||
tokenB,
|
||||
fee,
|
||||
tickLower,
|
||||
tickUpper,
|
||||
amtA,
|
||||
amtB,
|
||||
slippage
|
||||
);
|
||||
}
|
||||
params.amtA = getUint(getIds[0], params.amtA);
|
||||
params.amtB = getUint(getIds[1], params.amtB);
|
||||
|
||||
(
|
||||
uint256 _tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountA,
|
||||
uint256 amountB
|
||||
) = _mint(params);
|
||||
|
||||
setUint(setId, liquidity);
|
||||
|
||||
_eventName = "LogMint(uint256,uint256,uint256,uint256,int24,int24)";
|
||||
_eventParam = abi.encode(
|
||||
_tokenId,
|
||||
liquidity,
|
||||
amountA,
|
||||
amountB,
|
||||
params.tickLower,
|
||||
params.tickUpper
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Increase Liquidity
|
||||
* @notice Increase Liquidity of NFT Position
|
||||
* @param tokenId NFT LP Token ID.
|
||||
* @param amountA tokenA amounts.
|
||||
* @param amountB tokenB amounts.
|
||||
* @param slippage slippage.
|
||||
* @param getIds IDs to retrieve token amounts
|
||||
* @param setId stores the liquidity amount
|
||||
*/
|
||||
function deposit(
|
||||
uint256 tokenId,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 slippage,
|
||||
uint256[] calldata getIds,
|
||||
uint256 setId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
amountA = getUint(getIds[0], amountA);
|
||||
amountB = getUint(getIds[1], amountB);
|
||||
(
|
||||
uint256 _liquidity,
|
||||
uint256 _amtA,
|
||||
uint256 _amtB
|
||||
) = _addLiquidityWrapper(tokenId, amountA, amountB, slippage);
|
||||
setUint(setId, _liquidity);
|
||||
|
||||
_eventName = "LogDeposit(uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Decrease Liquidity
|
||||
* @notice Decrease Liquidity of NFT Position
|
||||
* @param tokenId NFT LP Token ID.
|
||||
* @param liquidity LP Token amount.
|
||||
* @param amountAMin Min amount of tokenA.
|
||||
* @param amountBMin Min amount of tokenB.
|
||||
* @param getId ID to retrieve LP token amounts
|
||||
* @param setIds stores the amount of output tokens
|
||||
*/
|
||||
function withdraw(
|
||||
uint256 tokenId,
|
||||
uint256 liquidity,
|
||||
uint256 amountAMin,
|
||||
uint256 amountBMin,
|
||||
uint256 getId,
|
||||
uint256[] calldata setIds
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
uint128 _liquidity = uint128(getUint(getId, liquidity));
|
||||
|
||||
(uint256 _amtA, uint256 _amtB) = _decreaseLiquidity(
|
||||
tokenId,
|
||||
_liquidity,
|
||||
amountAMin,
|
||||
amountBMin
|
||||
);
|
||||
|
||||
setUint(setIds[0], _amtA);
|
||||
setUint(setIds[1], _amtB);
|
||||
|
||||
_eventName = "LogWithdraw(uint256,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(tokenId, _liquidity, _amtA, _amtB);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Collect function
|
||||
* @notice Collect from NFT Position
|
||||
* @param tokenId NFT LP Token ID.
|
||||
* @param amount0Max Max amount of token0.
|
||||
* @param amount1Max Max amount of token1.
|
||||
* @param getIds IDs to retrieve amounts
|
||||
* @param setIds stores the amount of output tokens
|
||||
*/
|
||||
function collect(
|
||||
uint256 tokenId,
|
||||
uint256 amount0Max,
|
||||
uint256 amount1Max,
|
||||
uint256[] calldata getIds,
|
||||
uint256[] calldata setIds
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
uint128 _amount0Max = uint128(getUint(getIds[0], amount0Max));
|
||||
uint128 _amount1Max = uint128(getUint(getIds[1], amount1Max));
|
||||
(uint256 amount0, uint256 amount1) = _collect(
|
||||
tokenId,
|
||||
_amount0Max,
|
||||
_amount1Max
|
||||
);
|
||||
|
||||
setUint(setIds[0], amount0);
|
||||
setUint(setIds[1], amount1);
|
||||
_eventName = "LogCollect(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(tokenId, amount0, amount1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Burn Function
|
||||
* @notice Burn NFT LP Position
|
||||
* @param tokenId NFT LP Token ID
|
||||
*/
|
||||
function burn(uint256 tokenId)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (tokenId == 0) tokenId = _getLastNftId(address(this));
|
||||
_burn(tokenId);
|
||||
_eventName = "LogBurnPosition(uint256)";
|
||||
_eventParam = abi.encode(tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2UniswapV3Optimism is UniswapResolver {
|
||||
string public constant name = "UniswapV3-v1";
|
||||
}
|
30
contracts/optimism/connectors/uniswap/v3_staker/events.sol
Normal file
30
contracts/optimism/connectors/uniswap/v3_staker/events.sol
Normal file
|
@ -0,0 +1,30 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(uint256 tokenId);
|
||||
|
||||
event LogDepositAndStake(uint256 tokenId, bytes32 incentiveId);
|
||||
|
||||
event LogWithdraw(uint256 indexed tokenId);
|
||||
|
||||
event LogDepositTransfer(uint256 indexed tokenId, address to);
|
||||
|
||||
event LogStake(uint256 indexed tokenId, bytes32 incentiveId);
|
||||
|
||||
event LogUnstake(uint256 indexed tokenId, bytes32 incentiveId);
|
||||
|
||||
event LogRewardClaimed(
|
||||
address indexed rewardToken,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
event LogIncentiveCreated(
|
||||
bytes32 incentiveId,
|
||||
address poolAddr,
|
||||
address refundee,
|
||||
uint256 startTime,
|
||||
uint256 endTime,
|
||||
uint256 reward
|
||||
);
|
||||
}
|
88
contracts/optimism/connectors/uniswap/v3_staker/helpers.sol
Normal file
88
contracts/optimism/connectors/uniswap/v3_staker/helpers.sol
Normal file
|
@ -0,0 +1,88 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import {TokenInterface} from "../../../common/interfaces.sol";
|
||||
import {DSMath} from "../../../common/math.sol";
|
||||
import {Basic} from "../../../common/basic.sol";
|
||||
import "./interface.sol";
|
||||
import "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
||||
import "@uniswap/v3-core/contracts/libraries/TickMath.sol";
|
||||
import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
|
||||
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
/**
|
||||
* @dev uniswap v3 NFT Position Manager & Swap Router
|
||||
*/
|
||||
INonfungiblePositionManager constant nftManager =
|
||||
INonfungiblePositionManager(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
|
||||
IUniswapV3Staker constant staker =
|
||||
IUniswapV3Staker(0xe34139463bA50bD61336E0c446Bd8C0867c6fE65);
|
||||
|
||||
/**
|
||||
* @dev Get Last NFT Index
|
||||
* @param user: User address
|
||||
*/
|
||||
function _getLastNftId(address user)
|
||||
internal
|
||||
view
|
||||
returns (uint256 tokenId)
|
||||
{
|
||||
uint256 len = nftManager.balanceOf(user);
|
||||
tokenId = nftManager.tokenOfOwnerByIndex(user, len - 1);
|
||||
}
|
||||
|
||||
function getPoolAddress(uint256 _tokenId)
|
||||
internal
|
||||
view
|
||||
returns (address pool)
|
||||
{
|
||||
(bool success, bytes memory data) = address(nftManager).staticcall(
|
||||
abi.encodeWithSelector(nftManager.positions.selector, _tokenId)
|
||||
);
|
||||
require(success, "fetching positions failed");
|
||||
{
|
||||
(, , address token0, address token1, uint24 fee, , , ) = abi.decode(
|
||||
data,
|
||||
(
|
||||
uint96,
|
||||
address,
|
||||
address,
|
||||
address,
|
||||
uint24,
|
||||
int24,
|
||||
int24,
|
||||
uint128
|
||||
)
|
||||
);
|
||||
|
||||
pool = PoolAddress.computeAddress(
|
||||
nftManager.factory(),
|
||||
PoolAddress.PoolKey({token0: token0, token1: token1, fee: fee})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function _stake(
|
||||
uint256 _tokenId,
|
||||
IUniswapV3Staker.IncentiveKey memory _incentiveId
|
||||
) internal {
|
||||
staker.stakeToken(_incentiveId, _tokenId);
|
||||
}
|
||||
|
||||
function _unstake(
|
||||
IUniswapV3Staker.IncentiveKey memory _key,
|
||||
uint256 _tokenId
|
||||
) internal {
|
||||
staker.unstakeToken(_key, _tokenId);
|
||||
}
|
||||
|
||||
function _claimRewards(
|
||||
IERC20Minimal _rewardToken,
|
||||
address _to,
|
||||
uint256 _amountRequested
|
||||
) internal returns (uint256 rewards) {
|
||||
rewards = staker.claimReward(_rewardToken, _to, _amountRequested);
|
||||
}
|
||||
}
|
231
contracts/optimism/connectors/uniswap/v3_staker/interface.sol
Normal file
231
contracts/optimism/connectors/uniswap/v3_staker/interface.sol
Normal file
|
@ -0,0 +1,231 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity =0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
import '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';
|
||||
|
||||
import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';
|
||||
import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';
|
||||
import '@uniswap/v3-core/contracts/interfaces/IERC20Minimal.sol';
|
||||
|
||||
import '@uniswap/v3-periphery/contracts/interfaces/INonfungiblePositionManager.sol';
|
||||
import '@uniswap/v3-periphery/contracts/interfaces/IMulticall.sol';
|
||||
|
||||
/**
|
||||
* @title Uniswap V3 Staker Interface
|
||||
* @notice Allows staking nonfungible liquidity tokens in exchange for reward tokens
|
||||
*/
|
||||
interface IUniswapV3Staker is IERC721Receiver, IMulticall {
|
||||
/**
|
||||
* @param rewardToken The token being distributed as a reward
|
||||
* @param pool The Uniswap V3 pool
|
||||
* @param startTime The time when the incentive program begins
|
||||
* @param endTime The time when rewards stop accruing
|
||||
* @param refundee The address which receives any remaining reward tokens when the incentive is ended
|
||||
*/
|
||||
struct IncentiveKey {
|
||||
IERC20Minimal rewardToken;
|
||||
IUniswapV3Pool pool;
|
||||
uint256 startTime;
|
||||
uint256 endTime;
|
||||
address refundee;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice The Uniswap V3 Factory
|
||||
*/
|
||||
function factory() external view returns (IUniswapV3Factory);
|
||||
|
||||
/**
|
||||
* @notice The nonfungible position manager with which this staking contract is compatible
|
||||
*/
|
||||
function nonfungiblePositionManager() external view returns (INonfungiblePositionManager);
|
||||
|
||||
/**
|
||||
* @notice The max duration of an incentive in seconds
|
||||
*/
|
||||
function maxIncentiveDuration() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice The max amount of seconds into the future the incentive startTime can be set
|
||||
*/
|
||||
function maxIncentiveStartLeadTime() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice Represents a staking incentive
|
||||
* @param incentiveId The ID of the incentive computed from its parameters
|
||||
* @return totalRewardUnclaimed The amount of reward token not yet claimed by users
|
||||
* @return totalSecondsClaimedX128 Total liquidity-seconds claimed, represented as a UQ32.128
|
||||
* @return numberOfStakes The count of deposits that are currently staked for the incentive
|
||||
*/
|
||||
function incentives(bytes32 incentiveId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256 totalRewardUnclaimed,
|
||||
uint160 totalSecondsClaimedX128,
|
||||
uint96 numberOfStakes
|
||||
);
|
||||
|
||||
/**
|
||||
* @notice Returns information about a deposited NFT
|
||||
* @return owner The owner of the deposited NFT
|
||||
* @return numberOfStakes Counter of how many incentives for which the liquidity is staked
|
||||
* @return tickLower The lower tick of the range
|
||||
* @return tickUpper The upper tick of the range
|
||||
*/
|
||||
function deposits(uint256 tokenId)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
address owner,
|
||||
uint48 numberOfStakes,
|
||||
int24 tickLower,
|
||||
int24 tickUpper
|
||||
);
|
||||
|
||||
/**
|
||||
* @notice Returns information about a staked liquidity NFT
|
||||
* @param tokenId The ID of the staked token
|
||||
* @param incentiveId The ID of the incentive for which the token is staked
|
||||
* @return secondsPerLiquidityInsideInitialX128 secondsPerLiquidity represented as a UQ32.128
|
||||
* @return liquidity The amount of liquidity in the NFT as of the last time the rewards were computed
|
||||
*/
|
||||
function stakes(uint256 tokenId, bytes32 incentiveId)
|
||||
external
|
||||
view
|
||||
returns (uint160 secondsPerLiquidityInsideInitialX128, uint128 liquidity);
|
||||
|
||||
/**
|
||||
* @notice Returns amounts of reward tokens owed to a given address according to the last time all stakes were updated
|
||||
* @param rewardToken The token for which to check rewards
|
||||
* @param owner The owner for which the rewards owed are checked
|
||||
* @return rewardsOwed The amount of the reward token claimable by the owner
|
||||
*/
|
||||
function rewards(IERC20Minimal rewardToken, address owner) external view returns (uint256 rewardsOwed);
|
||||
|
||||
/**
|
||||
* @notice Creates a new liquidity mining incentive program
|
||||
* @param key Details of the incentive to create
|
||||
* @param reward The amount of reward tokens to be distributed
|
||||
*/
|
||||
function createIncentive(IncentiveKey memory key, uint256 reward) external;
|
||||
|
||||
/**
|
||||
* @notice Ends an incentive after the incentive end time has passed and all stakes have been withdrawn
|
||||
* @param key Details of the incentive to end
|
||||
* @return refund The remaining reward tokens when the incentive is ended
|
||||
*/
|
||||
function endIncentive(IncentiveKey memory key) external returns (uint256 refund);
|
||||
|
||||
/**
|
||||
* @notice Transfers ownership of a deposit from the sender to the given recipient
|
||||
* @param tokenId The ID of the token (and the deposit) to transfer
|
||||
* @param to The new owner of the deposit
|
||||
*/
|
||||
function transferDeposit(uint256 tokenId, address to) external;
|
||||
|
||||
/**
|
||||
* @notice Withdraws a Uniswap V3 LP token `tokenId` from this contract to the recipient `to`
|
||||
* @param tokenId The unique identifier of an Uniswap V3 LP token
|
||||
* @param to The address where the LP token will be sent
|
||||
* @param data An optional data array that will be passed along to the `to` address via the NFT safeTransferFrom
|
||||
*/
|
||||
function withdrawToken(
|
||||
uint256 tokenId,
|
||||
address to,
|
||||
bytes memory data
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @notice Stakes a Uniswap V3 LP token
|
||||
* @param key The key of the incentive for which to stake the NFT
|
||||
* @param tokenId The ID of the token to stake
|
||||
*/
|
||||
function stakeToken(IncentiveKey memory key, uint256 tokenId) external;
|
||||
|
||||
/**
|
||||
* @notice Unstakes a Uniswap V3 LP token
|
||||
* @param key The key of the incentive for which to unstake the NFT
|
||||
* @param tokenId The ID of the token to unstake
|
||||
*/
|
||||
function unstakeToken(IncentiveKey memory key, uint256 tokenId) external;
|
||||
|
||||
/**
|
||||
* @notice Transfers `amountRequested` of accrued `rewardToken` rewards from the contract to the recipient `to`
|
||||
* @param rewardToken The token being distributed as a reward
|
||||
* @param to The address where claimed rewards will be sent to
|
||||
* @param amountRequested The amount of reward tokens to claim. Claims entire reward amount if set to 0.
|
||||
* @return reward The amount of reward tokens claimed
|
||||
*/
|
||||
function claimReward(
|
||||
IERC20Minimal rewardToken,
|
||||
address to,
|
||||
uint256 amountRequested
|
||||
) external returns (uint256 reward);
|
||||
|
||||
/**
|
||||
* @notice Calculates the reward amount that will be received for the given stake
|
||||
* @param key The key of the incentive
|
||||
* @param tokenId The ID of the token
|
||||
* @return reward The reward accrued to the NFT for the given incentive thus far
|
||||
*/
|
||||
function getRewardInfo(IncentiveKey memory key, uint256 tokenId)
|
||||
external
|
||||
returns (uint256 reward, uint160 secondsInsideX128);
|
||||
|
||||
/**
|
||||
* @notice Event emitted when a liquidity mining incentive has been created
|
||||
* @param rewardToken The token being distributed as a reward
|
||||
* @param pool The Uniswap V3 pool
|
||||
* @param startTime The time when the incentive program begins
|
||||
* @param endTime The time when rewards stop accruing
|
||||
* @param refundee The address which receives any remaining reward tokens after the end time
|
||||
* @param reward The amount of reward tokens to be distributed
|
||||
*/
|
||||
event IncentiveCreated(
|
||||
IERC20Minimal indexed rewardToken,
|
||||
IUniswapV3Pool indexed pool,
|
||||
uint256 startTime,
|
||||
uint256 endTime,
|
||||
address refundee,
|
||||
uint256 reward
|
||||
);
|
||||
|
||||
/**
|
||||
* @notice Event that can be emitted when a liquidity mining incentive has ended
|
||||
* @param incentiveId The incentive which is ending
|
||||
* @param refund The amount of reward tokens refunded
|
||||
*/
|
||||
event IncentiveEnded(bytes32 indexed incentiveId, uint256 refund);
|
||||
|
||||
/**
|
||||
* @notice Emitted when ownership of a deposit changes
|
||||
* @param tokenId The ID of the deposit (and token) that is being transferred
|
||||
* @param oldOwner The owner before the deposit was transferred
|
||||
* @param newOwner The owner after the deposit was transferred
|
||||
*/
|
||||
event DepositTransferred(uint256 indexed tokenId, address indexed oldOwner, address indexed newOwner);
|
||||
|
||||
/**
|
||||
* @notice Event emitted when a Uniswap V3 LP token has been staked
|
||||
* @param tokenId The unique identifier of an Uniswap V3 LP token
|
||||
* @param liquidity The amount of liquidity staked
|
||||
* @param incentiveId The incentive in which the token is staking
|
||||
*/
|
||||
event TokenStaked(uint256 indexed tokenId, bytes32 indexed incentiveId, uint128 liquidity);
|
||||
|
||||
/**
|
||||
* @notice Event emitted when a Uniswap V3 LP token has been unstaked
|
||||
* @param tokenId The unique identifier of an Uniswap V3 LP token
|
||||
* @param incentiveId The incentive in which the token is staking
|
||||
*/
|
||||
event TokenUnstaked(uint256 indexed tokenId, bytes32 indexed incentiveId);
|
||||
|
||||
/**
|
||||
* @notice Event emitted when a reward token has been claimed
|
||||
* @param to The address where claimed rewards were sent to
|
||||
* @param reward The amount of reward tokens claimed
|
||||
*/
|
||||
event RewardClaimed(address indexed to, uint256 reward);
|
||||
}
|
256
contracts/optimism/connectors/uniswap/v3_staker/main.sol
Normal file
256
contracts/optimism/connectors/uniswap/v3_staker/main.sol
Normal file
|
@ -0,0 +1,256 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
pragma solidity ^0.7.6;
|
||||
pragma abicoder v2;
|
||||
|
||||
/**
|
||||
* @title Uniswap v3.
|
||||
* @dev Decentralized Exchange.
|
||||
*/
|
||||
|
||||
import {TokenInterface} from "../../../common/interfaces.sol";
|
||||
import "./interface.sol";
|
||||
import {Helpers} from "./helpers.sol";
|
||||
import {Events} from "./events.sol";
|
||||
|
||||
abstract contract UniswapResolver is Helpers, Events {
|
||||
/**
|
||||
* @dev Deposit NFT token
|
||||
* @notice Transfer deposited NFT token
|
||||
* @param _tokenId NFT LP Token ID
|
||||
*/
|
||||
function deposit(uint256 _tokenId)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (_tokenId == 0) _tokenId = _getLastNftId(address(this));
|
||||
nftManager.safeTransferFrom(
|
||||
address(this),
|
||||
address(staker),
|
||||
_tokenId,
|
||||
""
|
||||
);
|
||||
|
||||
_eventName = "LogDeposit(uint256)";
|
||||
_eventParam = abi.encode(_tokenId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit and Stake NFT token
|
||||
* @notice To Deposit and Stake NFT for Staking
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _startTime stake start time
|
||||
* @param _endTime stake end time
|
||||
* @param _refundee refundee address
|
||||
* @param _tokenId NFT LP token id
|
||||
*/
|
||||
function depositAndStake (
|
||||
address _rewardToken,
|
||||
uint256 _startTime,
|
||||
uint256 _endTime,
|
||||
address _refundee,
|
||||
uint256 _tokenId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
if (_tokenId == 0) _tokenId = _getLastNftId(address(this));
|
||||
nftManager.safeTransferFrom(
|
||||
address(this),
|
||||
address(staker),
|
||||
_tokenId,
|
||||
""
|
||||
);
|
||||
|
||||
address poolAddr = getPoolAddress(_tokenId);
|
||||
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(poolAddr);
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
_stake(_tokenId, _key);
|
||||
|
||||
_eventName = "LogDepositAndStake(uint256,bytes32)";
|
||||
_eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit Transfer
|
||||
* @notice Transfer deposited NFT token
|
||||
* @param _tokenId NFT LP Token ID
|
||||
* @param _to address to transfer
|
||||
*/
|
||||
function transferDeposit(uint256 _tokenId, address _to)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
staker.transferDeposit(_tokenId, _to);
|
||||
|
||||
_eventName = "LogDepositTransfer(uint256,address)";
|
||||
_eventParam = abi.encode(_tokenId, _to);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw NFT LP token
|
||||
* @notice Withdraw NFT LP token from staking pool
|
||||
* @param _tokenId NFT LP Token ID
|
||||
*/
|
||||
function withdraw(uint256 _tokenId)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
staker.withdrawToken(_tokenId, address(this), "");
|
||||
|
||||
_eventName = "LogWithdraw(uint256)";
|
||||
_eventParam = abi.encode(_tokenId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Stake NFT LP token
|
||||
* @notice Stake NFT LP Position
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _startTime stake start time
|
||||
* @param _endTime stake end time
|
||||
* @param _refundee refundee address
|
||||
* @param _tokenId NFT LP token id
|
||||
*/
|
||||
function stake (
|
||||
address _rewardToken,
|
||||
uint256 _startTime,
|
||||
uint256 _endTime,
|
||||
address _refundee,
|
||||
uint256 _tokenId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
address poolAddr = getPoolAddress(_tokenId);
|
||||
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(poolAddr);
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
_stake(_tokenId, _key);
|
||||
|
||||
_eventName = "LogStake(uint256,bytes32)";
|
||||
_eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Unstake NFT LP token
|
||||
* @notice Unstake NFT LP Position
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _startTime stake start time
|
||||
* @param _endTime stake end time
|
||||
* @param _refundee refundee address
|
||||
* @param _tokenId NFT LP token id
|
||||
*/
|
||||
function unstake(
|
||||
address _rewardToken,
|
||||
uint256 _startTime,
|
||||
uint256 _endTime,
|
||||
address _refundee,
|
||||
uint256 _tokenId
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
address poolAddr = getPoolAddress(_tokenId);
|
||||
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(poolAddr);
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
_unstake(_key, _tokenId);
|
||||
_eventName = "LogUnstake(uint256,bytes32)";
|
||||
_eventParam = abi.encode(_tokenId, keccak256(abi.encode(_key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim rewards
|
||||
* @notice Claim rewards
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _amount requested amount
|
||||
*/
|
||||
function claimRewards(
|
||||
address _rewardToken,
|
||||
uint256 _amount
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
uint256 rewards = _claimRewards(
|
||||
IERC20Minimal(_rewardToken),
|
||||
address(this),
|
||||
_amount
|
||||
);
|
||||
|
||||
_eventName = "LogRewardClaimed(address,uint256)";
|
||||
_eventParam = abi.encode(_rewardToken, rewards);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Create incentive
|
||||
* @notice Create incentive
|
||||
* @param _rewardToken _rewardToken address
|
||||
* @param _length incentive length
|
||||
* @param _refundee refundee address
|
||||
* @param _poolAddr Uniswap V3 Pool address
|
||||
* @param _reward reward amount
|
||||
*/
|
||||
function createIncentive(
|
||||
address _rewardToken,
|
||||
uint256 _length,
|
||||
address _refundee,
|
||||
address _poolAddr,
|
||||
uint256 _reward
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(_poolAddr);
|
||||
uint256 _startTime = block.timestamp;
|
||||
uint256 _endTime = _startTime + _length;
|
||||
IUniswapV3Staker.IncentiveKey memory _key = IUniswapV3Staker
|
||||
.IncentiveKey(
|
||||
IERC20Minimal(_rewardToken),
|
||||
pool,
|
||||
_startTime,
|
||||
_endTime,
|
||||
_refundee
|
||||
);
|
||||
if (_rewardToken != ethAddr) {
|
||||
IERC20Minimal(_rewardToken).approve(address(staker), _reward);
|
||||
}
|
||||
staker.createIncentive(_key, _reward);
|
||||
|
||||
_eventName = "LogIncentiveCreated(bytes32,address,address,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(keccak256(abi.encode(_key)), _poolAddr, _refundee, _startTime, _endTime, _reward);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2UniswapV3StakerOptimism is UniswapResolver {
|
||||
string public constant name = "Uniswap-V3-Staker-v1.1";
|
||||
}
|
6
contracts/optimism/connectors/weth/events.sol
Normal file
6
contracts/optimism/connectors/weth/events.sol
Normal file
|
@ -0,0 +1,6 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
event LogDeposit(uint256 tokenAmt, uint256 getId, uint256 setId);
|
||||
event LogWithdraw(uint256 tokenAmt, uint256 getId, uint256 setId);
|
||||
}
|
7
contracts/optimism/connectors/weth/helpers.sol
Normal file
7
contracts/optimism/connectors/weth/helpers.sol
Normal file
|
@ -0,0 +1,7 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
|
||||
abstract contract Helpers {
|
||||
TokenInterface constant internal wethContract = TokenInterface(0x4200000000000000000000000000000000000006);
|
||||
}
|
65
contracts/optimism/connectors/weth/main.sol
Normal file
65
contracts/optimism/connectors/weth/main.sol
Normal file
|
@ -0,0 +1,65 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title WETH.
|
||||
* @dev Wrap and Unwrap WETH.
|
||||
*/
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
|
||||
abstract contract Resolver is Events, DSMath, Basic, Helpers {
|
||||
/**
|
||||
* @dev Deposit ETH into WETH.
|
||||
* @notice Wrap ETH into WETH
|
||||
* @param amt The amount of ETH to deposit. (For max: `uint256(-1)`)
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the amount of ETH deposited.
|
||||
*/
|
||||
function deposit(
|
||||
uint256 amt,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
) public payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
_amt = _amt == uint(-1) ? address(this).balance : _amt;
|
||||
wethContract.deposit{value: _amt}();
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogDeposit(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_amt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw ETH from WETH from Smart Account
|
||||
* @notice Unwrap ETH from WETH
|
||||
* @param amt The amount of weth to withdraw. (For max: `uint256(-1)`)
|
||||
* @param getId ID to retrieve amt.
|
||||
* @param setId ID stores the amount of ETH withdrawn.
|
||||
*/
|
||||
function withdraw(
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setId
|
||||
) public payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
uint _amt = getUint(getId, amt);
|
||||
|
||||
_amt = _amt == uint(-1) ? wethContract.balanceOf(address(this)) : _amt;
|
||||
approve(wethContract, wethAddr, _amt);
|
||||
wethContract.withdraw(_amt);
|
||||
|
||||
setUint(setId, _amt);
|
||||
|
||||
_eventName = "LogWithdraw(uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(_amt, getId, setId);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2WETHOptimism is Resolver {
|
||||
string constant public name = "WETH-v1.0";
|
||||
}
|
|
@ -21,7 +21,7 @@ async function main() {
|
|||
"QUICKSWAP-A": "ConnectV2QuickswapPolygon",
|
||||
"UniswapV3-v1" : "ConnectV2UniswapV3Polygon",
|
||||
"Uniswap-V3-Staker-v1.1" : "ConnectV2UniswapV3StakerPolygon",
|
||||
"Paraswap-v5" : "ConnectV2ParaswapV5Polygon"
|
||||
"Paraswap-v5" : "ConnectV2ParaswapV5Polygon",
|
||||
"1INCH-V4" : "ConnectV2OneInchV4Polygon",
|
||||
"ZEROEX-A": "ConnectV2ZeroExAvalanche",
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user