From 5656c94717b073b4f4bcb8e22bc216ce8a0f9a99 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Mon, 7 Jun 2021 23:32:13 +0530 Subject: [PATCH 01/21] Uniswap v3 erc20 pool basic setup done --- .../connectors/uniswap_v3_erc20/events.sol | 4 + .../connectors/uniswap_v3_erc20/helpers.sol | 10 +++ .../connectors/uniswap_v3_erc20/interface.sol | 53 ++++++++++++ .../connectors/uniswap_v3_erc20/main.sol | 86 +++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20/events.sol create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20/main.sol diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol new file mode 100644 index 00000000..435e3220 --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol @@ -0,0 +1,4 @@ +pragma solidity ^0.7.0; + +contract Events { +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol new file mode 100644 index 00000000..f5254277 --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol @@ -0,0 +1,10 @@ +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 { + +} diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol new file mode 100644 index 00000000..863a8344 --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol @@ -0,0 +1,53 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +interface ERC20WrapperInterface { + + function token0() external view returns (IERC20); + + function token1() external view returns (IERC20); + + function mint( + uint256 amount0Max, + uint256 amount1Max, + address receiver + ) external + returns ( + uint256 amount0, + uint256 amount1, + uint256 mintAmount + ); + + function burn( + uint256 _burnAmount, + address _receiver + ) external + returns ( + uint256 amount0, + uint256 amount1, + uint128 liquidityBurned + ); + + function getMintAmounts( + uint256 amount0Max, + uint256 amount1Max + ) external view + returns ( + uint256 amount0, + uint256 amount1, + uint256 mintAmount + ); + +} + +interface TokenInterface { + function approve(address, uint256) external; + function transfer(address, uint) external; + function transferFrom(address, address, uint) external; + function deposit() external payable; + function withdraw(uint) external; + function balanceOf(address) external view returns (uint); + function decimals() external view returns (uint); +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol new file mode 100644 index 00000000..08dc54f6 --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -0,0 +1,86 @@ +pragma solidity ^0.7.0; + +/** + * @title Authority. + * @dev Manage Authorities to DSA. + */ + +import { ERC20WrapperInterface, IERC20, TokenInterface } from "../../common/interfaces.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; + +abstract contract AuthorityResolver is Events, Helpers { + + function deposit( + address pool, + uint256 amt0Max, + uint256 amt0Min, + uint256 amt1Max, + uint256 amt1Min, + uint256 getId, + uint256 setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + + ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); + + (uint256 amount0In, uint256 amount1In, ) = poolContract.getMintAmounts(amt0Max, amt1Max); + + require( + amount0In >= amount0Min && amount1In >= amount1Min, + "below min amounts" + ); + + if (amount0In > 0) { + IERC20 _token0 = pool.token0(); + convertEthToWeth(address(_token0) == wethAddr, TokenInterface(address(_token0)), amount0In); + _token0.safeAllowance(address(pool), amount0In); + } + if (amount1In > 0) { + IERC20 _token1 = pool.token0(); + convertEthToWeth(address(_token1) == wethAddr, TokenInterface(address(_token1)), amount1In); + _token1.safeAllowance(address(pool), amount1In); + } + + (uint amount0, uint amount1, uint mintAmount) = poolContract.mint(amount0In, amount1In, address(this)); + + require(amount0 == amount0In && amount1 == amount1In, "unexpected amounts deposited"); + + // TODO: Add event + } + + function withdraw( + address pool, + uint256 liqAmt, + uint256 minAmtA, + uint256 minAmtB, + uint256 getId, + uint256 setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + + ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); + + (uint amount0, uint amount1, uint128 liquidityBurned) = poolContract.burn(liqAmt, address(this)); + + if (amount0 > 0) { + IERC20 _token0 = poolContract.token0(); + convertWethToEth(address(_token0) == wethAddr, TokenInterface(address(_token0)), _amt); + } + + if (amount1 > 0) { + IERC20 _token1 = poolContract.token0(); + convertWethToEth(address(_token1) == wethAddr, TokenInterface(address(_token1)), _amt); + } + + require(amount0 >= minAmtA && amount1 >= minAmtB, "received below minimum"); + + // TODO: Add event + + } + +} + +contract ConnectV2Auth is AuthorityResolver { + + string public constant name = "Uniswap-v3-erc20"; + +} From 9b69841fec2e310b831bf528895c9aae0e252cb5 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:20:44 +0530 Subject: [PATCH 02/21] added events --- .../connectors/uniswap_v3_erc20/events.sol | 19 +++++++++++++++++++ .../connectors/uniswap_v3_erc20/main.sol | 6 ++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol index 435e3220..56809dc1 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol @@ -1,4 +1,23 @@ pragma solidity ^0.7.0; contract Events { + + event LogDepositLiquidity( + address indexed pool, + uint256 amtA, + uint256 amtB, + uint256 uniAmount, + uint256 getId, + uint256 setId + ); + + event LogWithdrawLiquidity( + address indexed pool, + uint256 amountA, + uint256 amountB, + uint256 uniAmount, + uint256 getId, + uint256 setId + ); + } \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index 08dc54f6..1fd8aa83 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -45,7 +45,8 @@ abstract contract AuthorityResolver is Events, Helpers { require(amount0 == amount0In && amount1 == amount1In, "unexpected amounts deposited"); - // TODO: Add event + _eventName = "LogDepositLiquidity(address,uint256,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(pool, amount0, amount1, mintAmount, getId, setId); } function withdraw( @@ -73,7 +74,8 @@ abstract contract AuthorityResolver is Events, Helpers { require(amount0 >= minAmtA && amount1 >= minAmtB, "received below minimum"); - // TODO: Add event + _eventName = "LogWithdrawLiquidity(address,uint256,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(pool, amount0, amount1, uint256(liquidityBurned), getId, setId); } From 2476cc4390033912d0b3d3cd500f0f2bbb0f502e Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:21:31 +0530 Subject: [PATCH 03/21] Update contracts/mainnet/connectors/uniswap_v3_erc20/main.sol Co-authored-by: Thrilok kumar --- contracts/mainnet/connectors/uniswap_v3_erc20/main.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index 1fd8aa83..71b9010d 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -36,7 +36,7 @@ abstract contract AuthorityResolver is Events, Helpers { _token0.safeAllowance(address(pool), amount0In); } if (amount1In > 0) { - IERC20 _token1 = pool.token0(); + IERC20 _token1 = pool.token1(); convertEthToWeth(address(_token1) == wethAddr, TokenInterface(address(_token1)), amount1In); _token1.safeAllowance(address(pool), amount1In); } From 927e1e2f1ccd4918c22e8e5aef6b0fb2970aa57c Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:21:41 +0530 Subject: [PATCH 04/21] Update contracts/mainnet/connectors/uniswap_v3_erc20/main.sol Co-authored-by: Thrilok kumar --- contracts/mainnet/connectors/uniswap_v3_erc20/main.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index 71b9010d..3ee00d8e 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -68,7 +68,7 @@ abstract contract AuthorityResolver is Events, Helpers { } if (amount1 > 0) { - IERC20 _token1 = poolContract.token0(); + IERC20 _token1 = poolContract.token1(); convertWethToEth(address(_token1) == wethAddr, TokenInterface(address(_token1)), _amt); } From 22ebfac88da9030c1127b8cdd6c7f0e660dd68bd Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:22:34 +0530 Subject: [PATCH 05/21] minor fix --- contracts/mainnet/connectors/uniswap_v3_erc20/main.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index 3ee00d8e..dba1fd15 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -64,12 +64,12 @@ abstract contract AuthorityResolver is Events, Helpers { if (amount0 > 0) { IERC20 _token0 = poolContract.token0(); - convertWethToEth(address(_token0) == wethAddr, TokenInterface(address(_token0)), _amt); + convertWethToEth(address(_token0) == wethAddr, TokenInterface(address(_token0)), amount0); } if (amount1 > 0) { IERC20 _token1 = poolContract.token1(); - convertWethToEth(address(_token1) == wethAddr, TokenInterface(address(_token1)), _amt); + convertWethToEth(address(_token1) == wethAddr, TokenInterface(address(_token1)), amount1); } require(amount0 >= minAmtA && amount1 >= minAmtB, "received below minimum"); From 8067874d214029b7dd25257392e4e37df0b95d99 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Tue, 8 Jun 2021 00:46:32 +0530 Subject: [PATCH 06/21] Fixes --- .../connectors/uniswap_v3_erc20/helpers.sol | 1 - .../connectors/uniswap_v3_erc20/main.sol | 49 ++++++++++++++----- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol index f5254277..5315ccbe 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol @@ -3,7 +3,6 @@ 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 { diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index dba1fd15..2bc54116 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -1,16 +1,31 @@ pragma solidity ^0.7.0; /** - * @title Authority. - * @dev Manage Authorities to DSA. + * @title Uniswap V3 ERC20 Wrapper. + * @dev Uniswap V3 Wrapper to deposit and withdraw. */ -import { ERC20WrapperInterface, IERC20, TokenInterface } from "../../common/interfaces.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; + +import { TokenInterface } from "../../common/interfaces.sol"; +import { ERC20WrapperInterface, IERC20 } from "./interface.sol"; import { Helpers } from "./helpers.sol"; import { Events } from "./events.sol"; -abstract contract AuthorityResolver is Events, Helpers { +abstract contract UniswapV3Resolver is Events, Helpers { + using SafeERC20 for IERC20; + /** + * @dev Deposit Liquidity. + * @notice Deposit Liquidity to a Uniswap V3 pool. + * @param pool The address of pool. + * @param amt0Max Amount0 Max amount + * @param amt0Min Amount0 Min amount + * @param amt1Max Amount1 Max amount + * @param amt1Min Amount1 Min amount + * @param getId ID to retrieve amount. + * @param setId ID stores the amount of pools tokens received. + */ function deposit( address pool, uint256 amt0Max, @@ -26,19 +41,19 @@ abstract contract AuthorityResolver is Events, Helpers { (uint256 amount0In, uint256 amount1In, ) = poolContract.getMintAmounts(amt0Max, amt1Max); require( - amount0In >= amount0Min && amount1In >= amount1Min, + amount0In >= amt0Min && amount1In >= amt1Min, "below min amounts" ); if (amount0In > 0) { - IERC20 _token0 = pool.token0(); + IERC20 _token0 = poolContract.token0(); convertEthToWeth(address(_token0) == wethAddr, TokenInterface(address(_token0)), amount0In); - _token0.safeAllowance(address(pool), amount0In); + _token0.safeApprove(address(pool), amount0In); } if (amount1In > 0) { - IERC20 _token1 = pool.token1(); + IERC20 _token1 = poolContract.token1(); convertEthToWeth(address(_token1) == wethAddr, TokenInterface(address(_token1)), amount1In); - _token1.safeAllowance(address(pool), amount1In); + _token1.safeApprove(address(pool), amount1In); } (uint amount0, uint amount1, uint mintAmount) = poolContract.mint(amount0In, amount1In, address(this)); @@ -49,6 +64,17 @@ abstract contract AuthorityResolver is Events, Helpers { _eventParam = abi.encode(pool, amount0, amount1, mintAmount, getId, setId); } + + /** + * @dev Withdraw Liquidity. + * @notice Withdraw Liquidity from a Uniswap V3 pool. + * @param pool The address of pool. + * @param liqAmt Amount0 Max amount + * @param minAmtA Min AmountA amount + * @param minAmtB Min AmountB amount + * @param getId ID to retrieve liqAmt. + * @param setId ID stores the amount of pools tokens received. + */ function withdraw( address pool, uint256 liqAmt, @@ -76,13 +102,12 @@ abstract contract AuthorityResolver is Events, Helpers { _eventName = "LogWithdrawLiquidity(address,uint256,uint256,uint256,uint256,uint256)"; _eventParam = abi.encode(pool, amount0, amount1, uint256(liquidityBurned), getId, setId); - } } -contract ConnectV2Auth is AuthorityResolver { +contract ConnectV2UniswapV3ERC20 is UniswapV3Resolver { - string public constant name = "Uniswap-v3-erc20"; + string public constant name = "Uniswap-v3-ERC20"; } From 1c6c7bc358af011c663e3967a217b223f54a5e3d Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Tue, 8 Jun 2021 02:04:38 +0530 Subject: [PATCH 07/21] new updates --- contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol | 3 +-- contracts/mainnet/connectors/uniswap_v3_erc20/main.sol | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol index 863a8344..72f7d59a 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol @@ -10,8 +10,7 @@ interface ERC20WrapperInterface { function token1() external view returns (IERC20); function mint( - uint256 amount0Max, - uint256 amount1Max, + uint256 mintAmount, address receiver ) external returns ( diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index 2bc54116..8ca85a01 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -38,7 +38,7 @@ abstract contract UniswapV3Resolver is Events, Helpers { ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); - (uint256 amount0In, uint256 amount1In, ) = poolContract.getMintAmounts(amt0Max, amt1Max); + (uint256 amount0In, uint256 amount1In, uint256 mintAmount) = poolContract.getMintAmounts(amt0Max, amt1Max); require( amount0In >= amt0Min && amount1In >= amt1Min, @@ -56,7 +56,7 @@ abstract contract UniswapV3Resolver is Events, Helpers { _token1.safeApprove(address(pool), amount1In); } - (uint amount0, uint amount1, uint mintAmount) = poolContract.mint(amount0In, amount1In, address(this)); + (uint amount0, uint amount1,) = poolContract.mint(mintAmount, address(this)); require(amount0 == amount0In && amount1 == amount1In, "unexpected amounts deposited"); From 2bd7492e56c564e88e7edb922e27a37ed9c0d553 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Thu, 10 Jun 2021 03:00:34 +0530 Subject: [PATCH 08/21] Gelato connector updated with swap & mint --- .../connectors/uniswap_v3_erc20/events.sol | 15 +++- .../connectors/uniswap_v3_erc20/helpers.sol | 4 ++ .../connectors/uniswap_v3_erc20/interface.sol | 68 +++++++++++++++++++ .../connectors/uniswap_v3_erc20/main.sol | 64 +++++++++++++++++ 4 files changed, 149 insertions(+), 2 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol index 56809dc1..a50c8386 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol @@ -6,7 +6,7 @@ contract Events { address indexed pool, uint256 amtA, uint256 amtB, - uint256 uniAmount, + uint256 mintAmount, uint256 getId, uint256 setId ); @@ -15,7 +15,18 @@ contract Events { address indexed pool, uint256 amountA, uint256 amountB, - uint256 uniAmount, + uint256 burnAmount, + uint256 getId, + uint256 setId + ); + + event LogSwapAndDepositLiquidity( + address indexed pool, + uint256 amtA, + uint256 amtB, + uint256 mintAmount, + bool zeroForOne, + uint swapAmount, uint256 getId, uint256 setId ); diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol index 5315ccbe..006c91e6 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol @@ -4,6 +4,10 @@ pragma experimental ABIEncoderV2; import { DSMath } from "../../common/math.sol"; import { Basic } from "../../common/basic.sol"; +import { IGUniRouter } from "./interface.sol"; + abstract contract Helpers is DSMath, Basic { + + IGUniRouter public constant gUniRouter = IGUniRouter(0x8CA6fa325bc32f86a12cC4964Edf1f71655007A7); } diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol index 72f7d59a..503774fe 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol @@ -41,6 +41,74 @@ interface ERC20WrapperInterface { } + +interface IGUniRouter { + function rebalanceAndAddLiquidity( + IGUniPool pool, + uint256 amount0In, + uint256 amount1In, + bool zeroForOne, + uint256 swapAmount, + uint160 swapThreshold, + uint256 amount0Min, + uint256 amount1Min, + address receiver + ) + external + returns ( + uint256 amount0, + uint256 amount1, + uint256 mintAmount + ); + + function rebalanceAndAddLiquidityETH( + IGUniPool pool, + uint256 amount0In, + uint256 amount1In, + bool zeroForOne, + uint256 swapAmount, + uint160 swapThreshold, + uint256 amount0Min, + uint256 amount1Min, + address receiver + ) + external + payable + returns ( + uint256 amount0, + uint256 amount1, + uint256 mintAmount + ); + + function removeLiquidity( + IGUniPool pool, + uint256 burnAmount, + uint256 amount0Min, + uint256 amount1Min, + address receiver + ) + external + returns ( + uint256 amount0, + uint256 amount1, + uint128 liquidityBurned + ); + + function removeLiquidityETH( + IGUniPool pool, + uint256 burnAmount, + uint256 amount0Min, + uint256 amount1Min, + address payable receiver + ) + external + returns ( + uint256 amount0, + uint256 amount1, + uint128 liquidityBurned + ); +} + interface TokenInterface { function approve(address, uint256) external; function transfer(address, uint) external; diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index 8ca85a01..df148a5a 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -104,6 +104,70 @@ abstract contract UniswapV3Resolver is Events, Helpers { _eventParam = abi.encode(pool, amount0, amount1, uint256(liquidityBurned), getId, setId); } + function swapAndDeposit( + address pool, + uint256 amount0In, + uint256 amount1In, + bool zeroForOne, + uint256 swapAmount, + uint160 swapThreshold + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + + ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); + IERC20 _token0 = poolContract.token0(); + IERC20 _token1 = poolContract.token1(); + + uint amount0; + uint amount1; + uint mintAmount; + + if (address(_token0) == wethAddr) { + _token1.approve(address(gUniRouter), amount1In); + (amount0, amount1, mintAmount) = gUniRouter.rebalanceAndAddLiquidityETH{value: amount0In}( + poolContract, + amount0In, + amount1In, + zeroForOne, + swapAmount, + swapThreshold, + 0, + 0, + address(this) + ); + } else if (address(_token1) == wethAddr) { + _token0.approve(address(gUniRouter), amount0In); + (amount0, amount1, mintAmount) = gUniRouter.rebalanceAndAddLiquidityETH{value: amount1In}( + poolContract, + amount0In, + amount1In, + zeroForOne, + swapAmount, + swapThreshold, + 0, + 0, + address(this) + ); + } else { + _token0.approve(address(gUniRouter), amount0In); + _token1.approve(address(gUniRouter), amount1In); + (amount0, amount1, mintAmount) = gUniRouter.rebalanceAndAddLiquidity( + poolContract, + amount0In, + amount1In, + zeroForOne, + swapAmount, + swapThreshold, + 0, + 0, + address(this) + ); + } + + _eventName = "LogSwapAndDepositLiquidity(address,uint256,uint256,uint256,bool,uint256,uint256,uint256)"; + _eventParam = abi.encode(pool, amount0, amount1, mintAmount, zeroForOne, swapAmount, getId, setId); + + } + } contract ConnectV2UniswapV3ERC20 is UniswapV3Resolver { From a483299e5030da62245b2d80eadeaa99cc48e8ec Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Thu, 10 Jun 2021 16:44:38 +0530 Subject: [PATCH 09/21] added slippage on deposit --- contracts/mainnet/connectors/uniswap_v3_erc20/main.sol | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index df148a5a..fb3e208c 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -20,18 +20,16 @@ abstract contract UniswapV3Resolver is Events, Helpers { * @notice Deposit Liquidity to a Uniswap V3 pool. * @param pool The address of pool. * @param amt0Max Amount0 Max amount - * @param amt0Min Amount0 Min amount * @param amt1Max Amount1 Max amount - * @param amt1Min Amount1 Min amount + * @param slippage use to calculate minimum deposit. 100% = 1e18 * @param getId ID to retrieve amount. * @param setId ID stores the amount of pools tokens received. */ function deposit( address pool, uint256 amt0Max, - uint256 amt0Min, uint256 amt1Max, - uint256 amt1Min, + uint slippage, uint256 getId, uint256 setId ) external payable returns (string memory _eventName, bytes memory _eventParam) { @@ -40,6 +38,9 @@ abstract contract UniswapV3Resolver is Events, Helpers { (uint256 amount0In, uint256 amount1In, uint256 mintAmount) = poolContract.getMintAmounts(amt0Max, amt1Max); + uint amt0Min = wmul(amt0Max, slippage); + uint amt1Min = wmul(amt1Max, slippage); + require( amount0In >= amt0Min && amount1In >= amt1Min, "below min amounts" From dbcf960bf987b36ef6f616974fef9e16e3336479 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Thu, 10 Jun 2021 16:56:05 +0530 Subject: [PATCH 10/21] updated connector with setId & getId --- .../connectors/uniswap_v3_erc20/events.sol | 4 +-- .../connectors/uniswap_v3_erc20/main.sol | 28 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol index a50c8386..e5ed811d 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/events.sol @@ -7,7 +7,7 @@ contract Events { uint256 amtA, uint256 amtB, uint256 mintAmount, - uint256 getId, + uint256[] getIds, uint256 setId ); @@ -17,7 +17,7 @@ contract Events { uint256 amountB, uint256 burnAmount, uint256 getId, - uint256 setId + uint256[] setIds ); event LogSwapAndDepositLiquidity( diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index fb3e208c..f34ff8da 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -30,10 +30,13 @@ abstract contract UniswapV3Resolver is Events, Helpers { uint256 amt0Max, uint256 amt1Max, uint slippage, - uint256 getId, + uint256[] getIds, uint256 setId ) external payable returns (string memory _eventName, bytes memory _eventParam) { + amt0Max = getUint(getIds[0], amt0Max); + amt1Max = getUint(getIds[1], amt1Max); + ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); (uint256 amount0In, uint256 amount1In, uint256 mintAmount) = poolContract.getMintAmounts(amt0Max, amt1Max); @@ -61,8 +64,10 @@ abstract contract UniswapV3Resolver is Events, Helpers { require(amount0 == amount0In && amount1 == amount1In, "unexpected amounts deposited"); - _eventName = "LogDepositLiquidity(address,uint256,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(pool, amount0, amount1, mintAmount, getId, setId); + setUint(setId, mintAmount); + + _eventName = "LogDepositLiquidity(address,uint256,uint256,uint256,uint256[],uint256)"; + _eventParam = abi.encode(pool, amount0, amount1, mintAmount, getIds, setId); } @@ -82,9 +87,11 @@ abstract contract UniswapV3Resolver is Events, Helpers { uint256 minAmtA, uint256 minAmtB, uint256 getId, - uint256 setId + uint256[] setIds ) external payable returns (string memory _eventName, bytes memory _eventParam) { + liqAmt = getUint(getId, liqAmt); + ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); (uint amount0, uint amount1, uint128 liquidityBurned) = poolContract.burn(liqAmt, address(this)); @@ -101,8 +108,11 @@ abstract contract UniswapV3Resolver is Events, Helpers { require(amount0 >= minAmtA && amount1 >= minAmtB, "received below minimum"); - _eventName = "LogWithdrawLiquidity(address,uint256,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(pool, amount0, amount1, uint256(liquidityBurned), getId, setId); + setUint(setIds[0], amount0); + setUint(setIds[1], amount1); + + _eventName = "LogWithdrawLiquidity(address,uint256,uint256,uint256,uint256,uint256[])"; + _eventParam = abi.encode(pool, amount0, amount1, uint256(liquidityBurned), getId, setIds); } function swapAndDeposit( @@ -111,7 +121,9 @@ abstract contract UniswapV3Resolver is Events, Helpers { uint256 amount1In, bool zeroForOne, uint256 swapAmount, - uint160 swapThreshold + uint160 swapThreshold, + uint256 getId, + uint256 setId ) external payable returns (string memory _eventName, bytes memory _eventParam) { ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); @@ -164,6 +176,8 @@ abstract contract UniswapV3Resolver is Events, Helpers { ); } + setUint(setId, mintAmount); + _eventName = "LogSwapAndDepositLiquidity(address,uint256,uint256,uint256,bool,uint256,uint256,uint256)"; _eventParam = abi.encode(pool, amount0, amount1, mintAmount, zeroForOne, swapAmount, getId, setId); From 1cc2e4ba1a7771556b41aaaeabea6fa2fe0015cf Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Thu, 10 Jun 2021 17:26:39 +0530 Subject: [PATCH 11/21] staking connector added --- .../connectors/erc20_staking/events.sol | 28 +++++ .../connectors/erc20_staking/helpers.sol | 47 ++++++++ .../connectors/erc20_staking/interface.sol | 21 ++++ .../mainnet/connectors/erc20_staking/main.sol | 108 ++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 contracts/mainnet/connectors/erc20_staking/events.sol create mode 100644 contracts/mainnet/connectors/erc20_staking/helpers.sol create mode 100644 contracts/mainnet/connectors/erc20_staking/interface.sol create mode 100644 contracts/mainnet/connectors/erc20_staking/main.sol diff --git a/contracts/mainnet/connectors/erc20_staking/events.sol b/contracts/mainnet/connectors/erc20_staking/events.sol new file mode 100644 index 00000000..9c0cc2f4 --- /dev/null +++ b/contracts/mainnet/connectors/erc20_staking/events.sol @@ -0,0 +1,28 @@ +pragma solidity ^0.7.0; + +contract Events { + + event LogDeposit( + address indexed stakingToken, + bytes32 indexed stakingType, + uint256 amount, + uint getId, + uint setId + ); + + event LogWithdraw( + address indexed stakingToken, + bytes32 indexed stakingType, + uint256 amount, + uint getId, + uint setId + ); + + event LogClaimedReward( + address indexed rewardToken, + bytes32 indexed stakingType, + uint256 rewardAmt, + uint setId + ); + +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/erc20_staking/helpers.sol b/contracts/mainnet/connectors/erc20_staking/helpers.sol new file mode 100644 index 00000000..73f405c5 --- /dev/null +++ b/contracts/mainnet/connectors/erc20_staking/helpers.sol @@ -0,0 +1,47 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + + +import { DSMath } from "../../common/math.sol"; +import { Basic } from "../../common/basic.sol"; +import { IStakingRewards, SynthetixMapping } from "./interface.sol"; + +abstract contract Helpers is DSMath, Basic { + + /** + * @dev Convert String to bytes32. + */ + function stringToBytes32(string memory str) internal pure returns (bytes32 result) { + require(bytes(str).length != 0, "string-empty"); + // solium-disable-next-line security/no-inline-assembly + assembly { + result := mload(add(str, 32)) + } + } + + /** + * @dev Get staking data + */ + function getStakingData(string memory stakingName) + internal + view + returns ( + IStakingRewards stakingContract, + TokenInterface stakingToken, + TokenInterface rewardToken, + bytes32 stakingType + ) + { + stakingType = stringToBytes32(stakingName); + SynthetixMapping.StakingData memory stakingData = SynthetixMapping(getMappingAddr()).stakingMapping(stakingType); + require(stakingData.stakingPool != address(0) && stakingData.stakingToken != address(0), "Wrong Staking Name"); + stakingContract = IStakingRewards(stakingData.stakingPool); + stakingToken = TokenInterface(stakingData.stakingToken); + rewardToken = TokenInterface(stakingData.rewardToken); + } + + function getMappingAddr() internal virtual view returns (address) { + return 0x772590F33eD05b0E83553650BF9e75A04b337526; // InstaMapping Address + } + +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/erc20_staking/interface.sol b/contracts/mainnet/connectors/erc20_staking/interface.sol new file mode 100644 index 00000000..dad42611 --- /dev/null +++ b/contracts/mainnet/connectors/erc20_staking/interface.sol @@ -0,0 +1,21 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +interface IStakingRewards { + function stake(uint256 amount) external; + function withdraw(uint256 amount) external; + function getReward() external; + function balanceOf(address) external view returns(uint); +} + +interface SynthetixMapping { + + struct StakingData { + address stakingPool; + address stakingToken; + address rewardToken; + } + + function stakingMapping(bytes32) external view returns(StakingData memory); + +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/erc20_staking/main.sol b/contracts/mainnet/connectors/erc20_staking/main.sol new file mode 100644 index 00000000..513c4bf5 --- /dev/null +++ b/contracts/mainnet/connectors/erc20_staking/main.sol @@ -0,0 +1,108 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + + +import { TokenInterface } from "../../common/interfaces.sol"; +import { Stores } from "../../common/stores.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; +import { IStakingRewards, SynthetixMapping } from "./interface.sol"; + +contract Main { + + /** + * @dev Deposit Token. + * @param stakingPoolName staking token address. + * @param amt staking token amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setId Set token amount at this ID in `InstaMemory` Contract. + */ + function deposit( + string calldata stakingPoolName, + uint amt, + uint getId, + uint setId + ) external payable { + uint _amt = getUint(getId, amt); + ( + IStakingRewards stakingContract, + TokenInterface stakingToken, + , + bytes32 stakingType + ) = getStakingData(stakingPoolName); + + _amt = _amt == uint(-1) ? stakingToken.balanceOf(address(this)) : _amt; + + stakingToken.approve(address(stakingContract), _amt); + stakingContract.stake(_amt); + + setUint(setId, _amt); + emit LogDeposit(address(stakingToken), stakingType, _amt, getId, setId); + } + + /** + * @dev Withdraw Token. + * @param stakingPoolName staking token address. + * @param amt staking token amount. + * @param getId Get token amount at this ID from `InstaMemory` Contract. + * @param setIdAmount Set token amount at this ID in `InstaMemory` Contract. + * @param setIdReward Set reward amount at this ID in `InstaMemory` Contract. + */ + function withdraw( + string calldata stakingPoolName, + uint amt, + uint getId, + uint setIdAmount, + uint setIdReward + ) external payable { + uint _amt = getUint(getId, amt); + ( + IStakingRewards stakingContract, + TokenInterface stakingToken, + TokenInterface rewardToken, + bytes32 stakingType + ) = getStakingData(stakingPoolName); + + _amt = _amt == uint(-1) ? stakingContract.balanceOf(address(this)) : _amt; + uint intialBal = rewardToken.balanceOf(address(this)); + stakingContract.withdraw(_amt); + stakingContract.getReward(); + uint finalBal = rewardToken.balanceOf(address(this)); + + uint rewardAmt = sub(finalBal, intialBal); + + setUint(setIdAmount, _amt); + setUint(setIdReward, rewardAmt); + + emit LogWithdraw(address(stakingToken), stakingType, _amt, getId, setIdAmount); + + emit LogClaimedReward(address(rewardToken), stakingType, rewardAmt, setIdReward); + } + + /** + * @dev Claim Reward. + * @param stakingPoolName staking token address. + * @param setId Set reward amount at this ID in `InstaMemory` Contract. + */ + function claimReward( + string calldata stakingPoolName, + uint setId + ) external payable { + ( + IStakingRewards stakingContract, + , + TokenInterface rewardToken, + bytes32 stakingType + ) = getStakingData(stakingPoolName); + + uint intialBal = rewardToken.balanceOf(address(this)); + stakingContract.getReward(); + uint finalBal = rewardToken.balanceOf(address(this)); + + uint rewardAmt = sub(finalBal, intialBal); + + setUint(setId, rewardAmt); + emit LogClaimedReward(address(rewardToken), stakingType, rewardAmt, setId); + } + +} \ No newline at end of file From ef5c6e9edb26ebe60e9bf2c9968d74e7a90390da Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Thu, 10 Jun 2021 19:45:21 +0530 Subject: [PATCH 12/21] added comments on connector --- .../mainnet/connectors/uniswap_v3_erc20/main.sol | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index f34ff8da..f18e0400 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -17,7 +17,7 @@ abstract contract UniswapV3Resolver is Events, Helpers { /** * @dev Deposit Liquidity. - * @notice Deposit Liquidity to a Uniswap V3 pool. + * @notice Deposit Liquidity to Gelato Uniswap V3 pool. * @param pool The address of pool. * @param amt0Max Amount0 Max amount * @param amt1Max Amount1 Max amount @@ -73,7 +73,7 @@ abstract contract UniswapV3Resolver is Events, Helpers { /** * @dev Withdraw Liquidity. - * @notice Withdraw Liquidity from a Uniswap V3 pool. + * @notice Withdraw Liquidity from Gelato Uniswap V3 pool. * @param pool The address of pool. * @param liqAmt Amount0 Max amount * @param minAmtA Min AmountA amount @@ -115,6 +115,18 @@ abstract contract UniswapV3Resolver is Events, Helpers { _eventParam = abi.encode(pool, amount0, amount1, uint256(liquidityBurned), getId, setIds); } + /** + * @dev Swap & Deposit Liquidity. + * @notice Withdraw Liquidity to Gelato Uniswap V3 pool. + * @param pool The address of pool. + * @param amount0In amount of token0 to deposit. + * @param amount1In amount of token1 to deposit. + * @param zeroForOne Swap excess of one token to deposit in equal ratio. + * @param swapAmount Amount of tokens to swap + * @param swapThreshold Slippage that the swap could take. + * @param getId Not used anywhere here. + * @param setId Set the amount of tokens minted. + */ function swapAndDeposit( address pool, uint256 amount0In, From 7e6b83e5fec510f4d404f29e2a83c89aff7c75ef Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Thu, 10 Jun 2021 21:55:57 +0530 Subject: [PATCH 13/21] updated stake mapping --- contracts/mainnet/connectors/erc20_staking/helpers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/erc20_staking/helpers.sol b/contracts/mainnet/connectors/erc20_staking/helpers.sol index 73f405c5..674b2de9 100644 --- a/contracts/mainnet/connectors/erc20_staking/helpers.sol +++ b/contracts/mainnet/connectors/erc20_staking/helpers.sol @@ -41,7 +41,7 @@ abstract contract Helpers is DSMath, Basic { } function getMappingAddr() internal virtual view returns (address) { - return 0x772590F33eD05b0E83553650BF9e75A04b337526; // InstaMapping Address + return 0x4a56E4209F0757CE630a2ebCF45DCe5BAfcb9782; // InstaMapping Address } } \ No newline at end of file From f2d163c8aeec8c79e9e92130c2e8e0ecf03d7132 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 10 Jun 2021 23:27:27 +0530 Subject: [PATCH 14/21] Minor changes --- .../connectors/erc20_staking/events.sol | 6 ++- .../mainnet/connectors/erc20_staking/main.sol | 51 ++++++++++++------- .../connectors/uniswap_v3_erc20/main.sol | 14 +++-- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/contracts/mainnet/connectors/erc20_staking/events.sol b/contracts/mainnet/connectors/erc20_staking/events.sol index 9c0cc2f4..a8b5ce2d 100644 --- a/contracts/mainnet/connectors/erc20_staking/events.sol +++ b/contracts/mainnet/connectors/erc20_staking/events.sol @@ -10,12 +10,14 @@ contract Events { uint setId ); - event LogWithdraw( + event LogWithdrawAndClaimedReward( address indexed stakingToken, bytes32 indexed stakingType, uint256 amount, + uint256 rewardAmt, uint getId, - uint setId + uint setIdAmount, + uint setIdReward ); event LogClaimedReward( diff --git a/contracts/mainnet/connectors/erc20_staking/main.sol b/contracts/mainnet/connectors/erc20_staking/main.sol index 513c4bf5..9b3e5194 100644 --- a/contracts/mainnet/connectors/erc20_staking/main.sol +++ b/contracts/mainnet/connectors/erc20_staking/main.sol @@ -1,6 +1,11 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; +/** + * @title Token Staking. + * @dev Stake ERC20 for earning rewards. + */ + import { TokenInterface } from "../../common/interfaces.sol"; import { Stores } from "../../common/stores.sol"; @@ -11,18 +16,19 @@ import { IStakingRewards, SynthetixMapping } from "./interface.sol"; contract Main { /** - * @dev Deposit Token. - * @param stakingPoolName staking token address. + * @dev Deposit ERC20. + * @notice Deposit Tokens to staking pool. + * @param stakingPoolName staking pool name. * @param amt staking token amount. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setId Set token amount at this ID in `InstaMemory` Contract. + * @param getId ID to retrieve amount. + * @param setId ID stores the amount of staked tokens. */ function deposit( string calldata stakingPoolName, uint amt, uint getId, uint setId - ) external payable { + ) external payable returns (string memory _eventName, bytes memory _eventParam) { uint _amt = getUint(getId, amt); ( IStakingRewards stakingContract, @@ -37,16 +43,18 @@ contract Main { stakingContract.stake(_amt); setUint(setId, _amt); - emit LogDeposit(address(stakingToken), stakingType, _amt, getId, setId); + _eventName = "LogDeposit(address,bytes32,uint256,uint256,uint256)"; + _eventParam = abi.encode(address(stakingToken), stakingType, _amt, getId, setId); } /** - * @dev Withdraw Token. - * @param stakingPoolName staking token address. + * @dev Withdraw ERC20. + * @notice Withdraw Tokens from the staking pool. + * @param stakingPoolName staking pool name. * @param amt staking token amount. - * @param getId Get token amount at this ID from `InstaMemory` Contract. - * @param setIdAmount Set token amount at this ID in `InstaMemory` Contract. - * @param setIdReward Set reward amount at this ID in `InstaMemory` Contract. + * @param getId ID to retrieve amount. + * @param setIdAmount ID stores the amount of stake tokens withdrawn. + * @param setIdReward ID stores the amount of reward tokens claimed. */ function withdraw( string calldata stakingPoolName, @@ -54,7 +62,7 @@ contract Main { uint getId, uint setIdAmount, uint setIdReward - ) external payable { + ) external payable returns (string memory _eventName, bytes memory _eventParam) { uint _amt = getUint(getId, amt); ( IStakingRewards stakingContract, @@ -74,20 +82,20 @@ contract Main { setUint(setIdAmount, _amt); setUint(setIdReward, rewardAmt); - emit LogWithdraw(address(stakingToken), stakingType, _amt, getId, setIdAmount); - - emit LogClaimedReward(address(rewardToken), stakingType, rewardAmt, setIdReward); + _eventName = "LogWithdrawAndClaimedReward(address,bytes32,uint256,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(address(stakingToken), stakingType, _amt, rewardAmt, getId, setIdAmount, setIdReward); } /** * @dev Claim Reward. - * @param stakingPoolName staking token address. - * @param setId Set reward amount at this ID in `InstaMemory` Contract. + * @notice Claim Pending Rewards of tokens staked. + * @param stakingPoolName staking pool name. + * @param setId ID stores the amount of reward tokens claimed. */ function claimReward( string calldata stakingPoolName, uint setId - ) external payable { + ) external payable returns (string memory _eventName, bytes memory _eventParam) { ( IStakingRewards stakingContract, , @@ -102,7 +110,12 @@ contract Main { uint rewardAmt = sub(finalBal, intialBal); setUint(setId, rewardAmt); - emit LogClaimedReward(address(rewardToken), stakingType, rewardAmt, setId); + _eventName = "LogClaimedReward(address,bytes32,uint256,uint256)"; + _eventParam = abi.encode(address(rewardToken), stakingType, rewardAmt, setId); } +} + +contract connectV2StakeERC20 is main { + string public constant name = "Stake-ERC20-v1.0"; } \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index f18e0400..d07e72b2 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -1,8 +1,8 @@ pragma solidity ^0.7.0; /** - * @title Uniswap V3 ERC20 Wrapper. - * @dev Uniswap V3 Wrapper to deposit and withdraw. + * @title G-Uniswap V3 ERC20 Wrapper. + * @dev G-Uniswap V3 Wrapper to deposit and withdraw. */ import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; @@ -22,7 +22,7 @@ abstract contract UniswapV3Resolver is Events, Helpers { * @param amt0Max Amount0 Max amount * @param amt1Max Amount1 Max amount * @param slippage use to calculate minimum deposit. 100% = 1e18 - * @param getId ID to retrieve amount. + * @param getIds Array of IDs to retrieve amounts. * @param setId ID stores the amount of pools tokens received. */ function deposit( @@ -79,7 +79,7 @@ abstract contract UniswapV3Resolver is Events, Helpers { * @param minAmtA Min AmountA amount * @param minAmtB Min AmountB amount * @param getId ID to retrieve liqAmt. - * @param setId ID stores the amount of pools tokens received. + * @param setIds Array of IDs tp stores the amounts of pools tokens received. */ function withdraw( address pool, @@ -197,8 +197,6 @@ abstract contract UniswapV3Resolver is Events, Helpers { } -contract ConnectV2UniswapV3ERC20 is UniswapV3Resolver { - - string public constant name = "Uniswap-v3-ERC20"; - +contract ConnectV2GUniswapV3ERC20 is UniswapV3Resolver { + string public constant name = "GUniswap-v3-ERC20-v1.0"; } From 9da4e18c2cc335b3f5b6c25da88a0480baab243c Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Thu, 10 Jun 2021 23:42:39 +0530 Subject: [PATCH 15/21] Fixed stack too deep error --- .../connectors/erc20_staking/helpers.sol | 1 + .../mainnet/connectors/erc20_staking/main.sol | 11 +- .../connectors/uniswap_v3_erc20/helpers.sol | 21 ++- .../connectors/uniswap_v3_erc20/interface.sol | 4 +- .../connectors/uniswap_v3_erc20/main.sol | 152 ++++++++++-------- 5 files changed, 113 insertions(+), 76 deletions(-) diff --git a/contracts/mainnet/connectors/erc20_staking/helpers.sol b/contracts/mainnet/connectors/erc20_staking/helpers.sol index 674b2de9..a00c5ccb 100644 --- a/contracts/mainnet/connectors/erc20_staking/helpers.sol +++ b/contracts/mainnet/connectors/erc20_staking/helpers.sol @@ -4,6 +4,7 @@ pragma experimental ABIEncoderV2; import { DSMath } from "../../common/math.sol"; import { Basic } from "../../common/basic.sol"; +import { TokenInterface } from "../../common/interfaces.sol"; import { IStakingRewards, SynthetixMapping } from "./interface.sol"; abstract contract Helpers is DSMath, Basic { diff --git a/contracts/mainnet/connectors/erc20_staking/main.sol b/contracts/mainnet/connectors/erc20_staking/main.sol index 9b3e5194..d72201bc 100644 --- a/contracts/mainnet/connectors/erc20_staking/main.sol +++ b/contracts/mainnet/connectors/erc20_staking/main.sol @@ -6,14 +6,13 @@ pragma experimental ABIEncoderV2; * @dev Stake ERC20 for earning rewards. */ - import { TokenInterface } from "../../common/interfaces.sol"; import { Stores } from "../../common/stores.sol"; import { Helpers } from "./helpers.sol"; import { Events } from "./events.sol"; import { IStakingRewards, SynthetixMapping } from "./interface.sol"; -contract Main { +contract Main is Helpers, Events { /** * @dev Deposit ERC20. @@ -75,15 +74,15 @@ contract Main { uint intialBal = rewardToken.balanceOf(address(this)); stakingContract.withdraw(_amt); stakingContract.getReward(); - uint finalBal = rewardToken.balanceOf(address(this)); - uint rewardAmt = sub(finalBal, intialBal); + uint rewardAmt = sub(rewardToken.balanceOf(address(this)), intialBal); setUint(setIdAmount, _amt); setUint(setIdReward, rewardAmt); - + { _eventName = "LogWithdrawAndClaimedReward(address,bytes32,uint256,uint256,uint256,uint256,uint256)"; _eventParam = abi.encode(address(stakingToken), stakingType, _amt, rewardAmt, getId, setIdAmount, setIdReward); + } } /** @@ -116,6 +115,6 @@ contract Main { } -contract connectV2StakeERC20 is main { +contract connectV2StakeERC20 is Main { string public constant name = "Stake-ERC20-v1.0"; } \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol index 006c91e6..9f30150f 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol @@ -4,10 +4,29 @@ pragma experimental ABIEncoderV2; import { DSMath } from "../../common/math.sol"; import { Basic } from "../../common/basic.sol"; -import { IGUniRouter } from "./interface.sol"; +import { IGUniRouter, IGUniPool, IERC20 } from "./interface.sol"; + abstract contract Helpers is DSMath, Basic { IGUniRouter public constant gUniRouter = IGUniRouter(0x8CA6fa325bc32f86a12cC4964Edf1f71655007A7); + + struct DepositAndSwap { + IGUniPool poolContract; + IERC20 _token0; + IERC20 _token1; + uint amount0; + uint amount1; + uint mintAmount; + } + + struct Deposit { + IGUniPool poolContract; + IERC20 _token0; + IERC20 _token1; + uint amount0In; + uint amount1In; + uint mintAmount; + } } diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol index 503774fe..52b45e77 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol @@ -3,14 +3,14 @@ pragma experimental ABIEncoderV2; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -interface ERC20WrapperInterface { +interface IGUniPool { function token0() external view returns (IERC20); function token1() external view returns (IERC20); function mint( - uint256 mintAmount, + uint256 amount, address receiver ) external returns ( diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol index d07e72b2..3c7895bd 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20/main.sol @@ -8,7 +8,7 @@ pragma solidity ^0.7.0; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import { TokenInterface } from "../../common/interfaces.sol"; -import { ERC20WrapperInterface, IERC20 } from "./interface.sol"; +import { IGUniPool, IERC20 } from "./interface.sol"; import { Helpers } from "./helpers.sol"; import { Events } from "./events.sol"; @@ -30,44 +30,48 @@ abstract contract UniswapV3Resolver is Events, Helpers { uint256 amt0Max, uint256 amt1Max, uint slippage, - uint256[] getIds, + uint256[] calldata getIds, uint256 setId ) external payable returns (string memory _eventName, bytes memory _eventParam) { amt0Max = getUint(getIds[0], amt0Max); amt1Max = getUint(getIds[1], amt1Max); - ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); + Deposit memory depositData; + depositData.poolContract = IGUniPool(pool); - (uint256 amount0In, uint256 amount1In, uint256 mintAmount) = poolContract.getMintAmounts(amt0Max, amt1Max); + (depositData.amount0In, depositData.amount1In, depositData.mintAmount) = + depositData.poolContract.getMintAmounts(amt0Max, amt1Max); uint amt0Min = wmul(amt0Max, slippage); uint amt1Min = wmul(amt1Max, slippage); require( - amount0In >= amt0Min && amount1In >= amt1Min, + depositData.amount0In >= amt0Min && depositData.amount1In >= amt1Min, "below min amounts" ); - if (amount0In > 0) { - IERC20 _token0 = poolContract.token0(); - convertEthToWeth(address(_token0) == wethAddr, TokenInterface(address(_token0)), amount0In); - _token0.safeApprove(address(pool), amount0In); + if (depositData.amount0In > 0) { + IERC20 _token0 = depositData.poolContract.token0(); + convertEthToWeth(address(_token0) == wethAddr, TokenInterface(address(_token0)), depositData.amount0In); + _token0.safeApprove(address(pool), depositData.amount0In); } - if (amount1In > 0) { - IERC20 _token1 = poolContract.token1(); - convertEthToWeth(address(_token1) == wethAddr, TokenInterface(address(_token1)), amount1In); - _token1.safeApprove(address(pool), amount1In); + if (depositData.amount1In > 0) { + IERC20 _token1 = depositData.poolContract.token1(); + convertEthToWeth(address(_token1) == wethAddr, TokenInterface(address(_token1)), depositData.amount1In); + _token1.safeApprove(address(pool), depositData.amount1In); } - (uint amount0, uint amount1,) = poolContract.mint(mintAmount, address(this)); + (uint amount0, uint amount1,) = depositData.poolContract.mint(depositData.mintAmount, address(this)); - require(amount0 == amount0In && amount1 == amount1In, "unexpected amounts deposited"); + require( + amount0 == depositData.amount0In && + amount1 == depositData.amount1In, "unexpected amounts deposited"); - setUint(setId, mintAmount); + setUint(setId, depositData.mintAmount); _eventName = "LogDepositLiquidity(address,uint256,uint256,uint256,uint256[],uint256)"; - _eventParam = abi.encode(pool, amount0, amount1, mintAmount, getIds, setId); + _eventParam = abi.encode(pool, amount0, amount1, depositData.mintAmount, getIds, setId); } @@ -87,12 +91,12 @@ abstract contract UniswapV3Resolver is Events, Helpers { uint256 minAmtA, uint256 minAmtB, uint256 getId, - uint256[] setIds + uint256[] calldata setIds ) external payable returns (string memory _eventName, bytes memory _eventParam) { liqAmt = getUint(getId, liqAmt); - ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); + IGUniPool poolContract = IGUniPool(pool); (uint amount0, uint amount1, uint128 liquidityBurned) = poolContract.burn(liqAmt, address(this)); @@ -137,66 +141,80 @@ abstract contract UniswapV3Resolver is Events, Helpers { uint256 getId, uint256 setId ) external payable returns (string memory _eventName, bytes memory _eventParam) { + DepositAndSwap memory depositAndSwap; + depositAndSwap.poolContract = IGUniPool(pool); + depositAndSwap._token0 = depositAndSwap.poolContract.token0(); + depositAndSwap._token1 = depositAndSwap.poolContract.token1(); - ERC20WrapperInterface poolContract = ERC20WrapperInterface(pool); - IERC20 _token0 = poolContract.token0(); - IERC20 _token1 = poolContract.token1(); + depositAndSwap.amount0; + depositAndSwap.amount1; + depositAndSwap.mintAmount; - uint amount0; - uint amount1; - uint mintAmount; + if (address(depositAndSwap._token0) == wethAddr) { + depositAndSwap._token1.approve(address(gUniRouter), amount1In); + + (depositAndSwap.amount0, depositAndSwap.amount1, depositAndSwap.mintAmount) = + gUniRouter.rebalanceAndAddLiquidityETH{value: amount0In}( + depositAndSwap.poolContract, + amount0In, + amount1In, + zeroForOne, + swapAmount, + swapThreshold, + 0, + 0, + address(this) + ); + } else if (address(depositAndSwap._token1) == wethAddr) { + depositAndSwap._token0.approve(address(gUniRouter), amount0In); - if (address(_token0) == wethAddr) { - _token1.approve(address(gUniRouter), amount1In); - (amount0, amount1, mintAmount) = gUniRouter.rebalanceAndAddLiquidityETH{value: amount0In}( - poolContract, - amount0In, - amount1In, - zeroForOne, - swapAmount, - swapThreshold, - 0, - 0, - address(this) - ); - } else if (address(_token1) == wethAddr) { - _token0.approve(address(gUniRouter), amount0In); - (amount0, amount1, mintAmount) = gUniRouter.rebalanceAndAddLiquidityETH{value: amount1In}( - poolContract, - amount0In, - amount1In, - zeroForOne, - swapAmount, - swapThreshold, - 0, - 0, - address(this) - ); + (depositAndSwap.amount0, depositAndSwap.amount1,depositAndSwap. mintAmount) = + gUniRouter.rebalanceAndAddLiquidityETH{value: amount1In}( + depositAndSwap.poolContract, + amount0In, + amount1In, + zeroForOne, + swapAmount, + swapThreshold, + 0, + 0, + address(this) + ); } else { - _token0.approve(address(gUniRouter), amount0In); - _token1.approve(address(gUniRouter), amount1In); - (amount0, amount1, mintAmount) = gUniRouter.rebalanceAndAddLiquidity( - poolContract, - amount0In, - amount1In, - zeroForOne, - swapAmount, - swapThreshold, - 0, - 0, - address(this) - ); + depositAndSwap._token0.approve(address(gUniRouter), amount0In); + depositAndSwap._token1.approve(address(gUniRouter), amount1In); + (depositAndSwap.amount0, depositAndSwap.amount1, depositAndSwap.mintAmount) = + gUniRouter.rebalanceAndAddLiquidity( + depositAndSwap.poolContract, + amount0In, + amount1In, + zeroForOne, + swapAmount, + swapThreshold, + 0, + 0, + address(this) + ); } - setUint(setId, mintAmount); + setUint(setId, depositAndSwap.mintAmount); _eventName = "LogSwapAndDepositLiquidity(address,uint256,uint256,uint256,bool,uint256,uint256,uint256)"; - _eventParam = abi.encode(pool, amount0, amount1, mintAmount, zeroForOne, swapAmount, getId, setId); + _eventParam = abi.encode( + pool, + depositAndSwap.amount0, + depositAndSwap.amount1, + depositAndSwap.mintAmount, + zeroForOne, + swapAmount, + getId, + setId + ); } } contract ConnectV2GUniswapV3ERC20 is UniswapV3Resolver { - string public constant name = "GUniswap-v3-ERC20-v1.0"; + string public constant name = "G-Uniswap-v3-ERC20-v1.0"; } From d72c1480f99f3e61e7170753a789944fcfe64670 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sun, 13 Jun 2021 16:49:33 +0530 Subject: [PATCH 16/21] Added guni factory --- .../uniswap_v3_erc20_staking/events.sol | 27 ++++ .../uniswap_v3_erc20_staking/helpers.sol | 17 +++ .../uniswap_v3_erc20_staking/interface.sol | 20 +++ .../uniswap_v3_erc20_staking/main.sol | 117 ++++++++++++++++++ 4 files changed, 181 insertions(+) create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20_staking/events.sol create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol create mode 100644 contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/events.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/events.sol new file mode 100644 index 00000000..4e75acd1 --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/events.sol @@ -0,0 +1,27 @@ +pragma solidity ^0.7.0; + +contract Events { + + event LogDeposit( + address indexed stakingToken, + uint256 amount, + uint getId, + uint setId + ); + + event LogWithdrawAndClaimedReward( + address indexed stakingToken, + uint256 amount, + uint256 rewardAmt, + uint getId, + uint setIdAmount, + uint setIdReward + ); + + event LogClaimedReward( + address indexed rewardToken, + uint256 rewardAmt, + uint setId + ); + +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol new file mode 100644 index 00000000..e083fe94 --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + + +import { DSMath } from "../../common/math.sol"; +import { Basic } from "../../common/basic.sol"; +import { TokenInterface } from "../../common/interfaces.sol"; +import { IStakingRewards, IStakingRewardsFactory } from "./interface.sol"; + +abstract contract Helpers is DSMath, Basic { + + IStakingRewardsFactory constant internal stakingRewardsFactory = + IStakingRewardsFactory(address(0)); // TODO + + TokenInterface constant internal rewardToken = TokenInterface(address(0)); // TODO + +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol new file mode 100644 index 00000000..78e732a6 --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol @@ -0,0 +1,20 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +interface IStakingRewards { + function stake(uint256 amount) external; + function withdraw(uint256 amount) external; + function getReward() external; + function balanceOf(address) external view returns(uint); +} + +interface IStakingRewardsFactory { + + struct StakingRewardsInfo { + address stakingRewards; + uint rewardAmount; + } + + function stakingRewardsInfoByStakingToken(address) external view returns(StakingRewardsInfo memory); + +} \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol new file mode 100644 index 00000000..ecb4ea2c --- /dev/null +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol @@ -0,0 +1,117 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +/** + * @title G-UNI Staking. + * @dev Stake G-UNI for earning rewards. + */ + +import { TokenInterface } from "../../common/interfaces.sol"; +import { Stores } from "../../common/stores.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; +import { IStakingRewards, IStakingRewardsFactory } from "./interface.sol"; + +contract Main is Helpers, Events { + + /** + * @dev Deposit ERC20. + * @notice Deposit Tokens to staking pool. + * @param stakingToken staking token address. + * @param amt staking token amount. + * @param getId ID to retrieve amount. + * @param setId ID stores the amount of staked tokens. + */ + function deposit( + address stakingToken, + uint amt, + uint getId, + uint setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _amt = getUint(getId, amt); + + IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = + stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); + + IStakingRewards stakingContract = IStakingRewards(stakingRewardsInfo.stakingRewards); + TokenInterface stakingTokenContract = TokenInterface(stakingToken); + + _amt = _amt == uint(-1) ? stakingTokenContract.balanceOf(address(this)) : _amt; + + stakingTokenContract.approve(address(stakingContract), _amt); + stakingContract.stake(_amt); + + setUint(setId, _amt); + _eventName = "LogDeposit(address,uint256,uint256,uint256)"; + _eventParam = abi.encode(address(stakingToken), _amt, getId, setId); + } + + /** + * @dev Withdraw ERC20. + * @notice Withdraw Tokens from the staking pool. + * @param stakingToken staking token address. + * @param amt staking token amount. + * @param getId ID to retrieve amount. + * @param setIdAmount ID stores the amount of stake tokens withdrawn. + * @param setIdReward ID stores the amount of reward tokens claimed. + */ + function withdraw( + address stakingToken, + uint amt, + uint getId, + uint setIdAmount, + uint setIdReward + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _amt = getUint(getId, amt); + + IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = + stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); + + IStakingRewards stakingContract = IStakingRewards(stakingRewardsInfo.stakingRewards); + + _amt = _amt == uint(-1) ? stakingContract.balanceOf(address(this)) : _amt; + uint intialBal = rewardToken.balanceOf(address(this)); + stakingContract.withdraw(_amt); + stakingContract.getReward(); + + uint rewardAmt = sub(rewardToken.balanceOf(address(this)), intialBal); + + setUint(setIdAmount, _amt); + setUint(setIdReward, rewardAmt); + { + _eventName = "LogWithdrawAndClaimedReward(address,uint256,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(address(stakingToken), _amt, rewardAmt, getId, setIdAmount, setIdReward); + } + } + + /** + * @dev Claim Reward. + * @notice Claim Pending Rewards of tokens staked. + * @param stakingToken staking token address. + * @param setId ID stores the amount of reward tokens claimed. + */ + function claimReward( + address stakingToken, + uint setId + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = + stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); + + IStakingRewards stakingContract = IStakingRewards(stakingRewardsInfo.stakingRewards); + + uint intialBal = rewardToken.balanceOf(address(this)); + stakingContract.getReward(); + uint finalBal = rewardToken.balanceOf(address(this)); + + uint rewardAmt = sub(finalBal, intialBal); + + setUint(setId, rewardAmt); + _eventName = "LogClaimedReward(address,uint256,uint256)"; + _eventParam = abi.encode(address(rewardToken), rewardAmt, setId); + } + +} + +contract connectV2StakeGUNI is Main { + string public constant name = "Stake-G-UNI-v1.0"; +} \ No newline at end of file From f37a543b81475d9576f66aa7a7c25a96ac10b042 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:00:49 +0530 Subject: [PATCH 17/21] minor refactoring --- .../uniswap_v3_erc20_staking/helpers.sol | 7 +++++++ .../connectors/uniswap_v3_erc20_staking/main.sol | 15 +++------------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol index e083fe94..ac412828 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol @@ -14,4 +14,11 @@ abstract contract Helpers is DSMath, Basic { TokenInterface constant internal rewardToken = TokenInterface(address(0)); // TODO + function getStakingContract(address stakingToken) internal view returns (address) { + IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = + stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); + + return IStakingRewards(stakingRewardsInfo.stakingRewards); + } + } \ No newline at end of file diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol index ecb4ea2c..4cd4fbcc 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol @@ -30,10 +30,7 @@ contract Main is Helpers, Events { ) external payable returns (string memory _eventName, bytes memory _eventParam) { uint _amt = getUint(getId, amt); - IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = - stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); - - IStakingRewards stakingContract = IStakingRewards(stakingRewardsInfo.stakingRewards); + IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken)); TokenInterface stakingTokenContract = TokenInterface(stakingToken); _amt = _amt == uint(-1) ? stakingTokenContract.balanceOf(address(this)) : _amt; @@ -64,10 +61,7 @@ contract Main is Helpers, Events { ) external payable returns (string memory _eventName, bytes memory _eventParam) { uint _amt = getUint(getId, amt); - IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = - stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); - - IStakingRewards stakingContract = IStakingRewards(stakingRewardsInfo.stakingRewards); + IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken)); _amt = _amt == uint(-1) ? stakingContract.balanceOf(address(this)) : _amt; uint intialBal = rewardToken.balanceOf(address(this)); @@ -94,10 +88,7 @@ contract Main is Helpers, Events { address stakingToken, uint setId ) external payable returns (string memory _eventName, bytes memory _eventParam) { - IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = - stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); - - IStakingRewards stakingContract = IStakingRewards(stakingRewardsInfo.stakingRewards); + IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken)); uint intialBal = rewardToken.balanceOf(address(this)); stakingContract.getReward(); From 229be643a0145b7319b7b2342d9c32ff6b65e9c7 Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Sun, 13 Jun 2021 17:02:34 +0530 Subject: [PATCH 18/21] minor fix --- .../mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol index ac412828..b472780d 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol @@ -18,7 +18,7 @@ abstract contract Helpers is DSMath, Basic { IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); - return IStakingRewards(stakingRewardsInfo.stakingRewards); + return stakingRewardsInfo.stakingRewards; } } \ No newline at end of file From e9281116fdc18be8acc189a35b09a094c8000edd Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Tue, 15 Jun 2021 21:21:19 +0530 Subject: [PATCH 19/21] Minor updates --- .../connectors/erc20_staking/helpers.sol | 6 +- .../connectors/erc20_staking/interface.sol | 2 +- .../mainnet/connectors/erc20_staking/main.sol | 2 +- contracts/mainnet/mapping/StakeERC20.sol | 119 ++++++++++++++++++ 4 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 contracts/mainnet/mapping/StakeERC20.sol diff --git a/contracts/mainnet/connectors/erc20_staking/helpers.sol b/contracts/mainnet/connectors/erc20_staking/helpers.sol index a00c5ccb..f559e69e 100644 --- a/contracts/mainnet/connectors/erc20_staking/helpers.sol +++ b/contracts/mainnet/connectors/erc20_staking/helpers.sol @@ -5,7 +5,7 @@ pragma experimental ABIEncoderV2; import { DSMath } from "../../common/math.sol"; import { Basic } from "../../common/basic.sol"; import { TokenInterface } from "../../common/interfaces.sol"; -import { IStakingRewards, SynthetixMapping } from "./interface.sol"; +import { IStakingRewards, StakingERC20Mapping } from "./interface.sol"; abstract contract Helpers is DSMath, Basic { @@ -34,7 +34,7 @@ abstract contract Helpers is DSMath, Basic { ) { stakingType = stringToBytes32(stakingName); - SynthetixMapping.StakingData memory stakingData = SynthetixMapping(getMappingAddr()).stakingMapping(stakingType); + StakingERC20Mapping.StakingData memory stakingData = StakingERC20Mapping(getMappingAddr()).stakingMapping(stakingType); require(stakingData.stakingPool != address(0) && stakingData.stakingToken != address(0), "Wrong Staking Name"); stakingContract = IStakingRewards(stakingData.stakingPool); stakingToken = TokenInterface(stakingData.stakingToken); @@ -42,7 +42,7 @@ abstract contract Helpers is DSMath, Basic { } function getMappingAddr() internal virtual view returns (address) { - return 0x4a56E4209F0757CE630a2ebCF45DCe5BAfcb9782; // InstaMapping Address + return 0xbE658233bA9990d86155b3902fd05a7AfC7eBdB5; // InstaMapping Address } } \ No newline at end of file diff --git a/contracts/mainnet/connectors/erc20_staking/interface.sol b/contracts/mainnet/connectors/erc20_staking/interface.sol index dad42611..d9a209fd 100644 --- a/contracts/mainnet/connectors/erc20_staking/interface.sol +++ b/contracts/mainnet/connectors/erc20_staking/interface.sol @@ -8,7 +8,7 @@ interface IStakingRewards { function balanceOf(address) external view returns(uint); } -interface SynthetixMapping { +interface StakingERC20Mapping { struct StakingData { address stakingPool; diff --git a/contracts/mainnet/connectors/erc20_staking/main.sol b/contracts/mainnet/connectors/erc20_staking/main.sol index d72201bc..176b21fa 100644 --- a/contracts/mainnet/connectors/erc20_staking/main.sol +++ b/contracts/mainnet/connectors/erc20_staking/main.sol @@ -10,7 +10,7 @@ import { TokenInterface } from "../../common/interfaces.sol"; import { Stores } from "../../common/stores.sol"; import { Helpers } from "./helpers.sol"; import { Events } from "./events.sol"; -import { IStakingRewards, SynthetixMapping } from "./interface.sol"; +import { IStakingRewards, StakingERC20Mapping } from "./interface.sol"; contract Main is Helpers, Events { diff --git a/contracts/mainnet/mapping/StakeERC20.sol b/contracts/mainnet/mapping/StakeERC20.sol new file mode 100644 index 00000000..4594d9b8 --- /dev/null +++ b/contracts/mainnet/mapping/StakeERC20.sol @@ -0,0 +1,119 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +interface ConnectorsInterface { + function chief(address) external view returns (bool); +} + +interface IndexInterface { + function master() external view returns (address); +} + +contract BytesHelper { + /** + * @dev Convert String to bytes32. + */ + function stringToBytes32(string memory str) internal pure returns (bytes32 result) { + require(bytes(str).length != 0, "String-Empty"); + // solium-disable-next-line security/no-inline-assembly + assembly { + result := mload(add(str, 32)) + } + } + + /** + * @dev Convert bytes32 to String. + */ + function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) { + bytes32 _temp; + uint count; + for (uint256 i; i < 32; i++) { + _temp = _bytes32[i]; + if( _temp != bytes32(0)) { + count += 1; + } + } + bytes memory bytesArray = new bytes(count); + for (uint256 i; i < count; i++) { + bytesArray[i] = (_bytes32[i]); + } + return (string(bytesArray)); + } +} + +contract Helpers is BytesHelper { + address public constant connectorsV2 = 0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11; + address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723; + + mapping (bytes32 => StakingData) public stakingMapping; + + struct StakingData { + address stakingPool; + address stakingToken; + address rewardToken; + } + + event LogAddStakingMapping( + string stakingName, + bytes32 stakingType, + address stakingAddress, + address stakingToken, + address rewardToken + ); + event LogRemoveStakingMapping( + string stakingName, + bytes32 stakingType, + address stakingAddress, + address stakingToken, + address rewardToken + ); + + modifier isChief virtual { + require( + ConnectorsInterface(connectorsV2).chief(msg.sender) || + IndexInterface(instaIndex).master() == msg.sender, "not-Chief"); + _; + } + + function addStakingMapping( + string memory stakingName, + address stakingAddress, + address stakingToken, + address rewardToken + ) public isChief { + require(stakingAddress != address(0), "stakingAddress-not-vaild"); + require(stakingToken != address(0), "stakingToken-not-vaild"); + require(rewardToken != address(0), "rewardToken-not-vaild"); + require(bytes(stakingName).length <= 32, "Length-exceeds"); + bytes32 stakeType = stringToBytes32(stakingName); + require(stakingMapping[stakeType].stakingPool == address(0), "StakingPool-already-added"); + require(stakingMapping[stakeType].stakingToken == address(0), "StakingToken-already-added"); + require(stakingMapping[stakeType].rewardToken == address(0), "rewardToken-already-added"); + + stakingMapping[stakeType] = StakingData( + stakingAddress, + stakingToken, + rewardToken + ); + emit LogAddStakingMapping(stakingName, stakeType, stakingAddress, stakingToken, rewardToken); + } + + function removeStakingMapping(string memory stakingName, address stakingAddress) public isChief { + require(stakingAddress != address(0), "stakingAddress-not-vaild"); + bytes32 stakeType = stringToBytes32(stakingName); + require(stakingMapping[stakeType].stakingPool == stakingAddress, "different-staking-pool"); + + emit LogRemoveStakingMapping( + stakingName, + stakeType, + stakingAddress, + stakingMapping[stakeType].stakingToken, + stakingMapping[stakeType].rewardToken + ); + delete stakingMapping[stakeType]; + } +} + +contract InstaStakingERC20Mapping is Helpers { + string constant public name = "Staking-ERC20-Mapping-v1"; +} From 38fa0bfe95a6b6a13b25ec5d905236ce57424d95 Mon Sep 17 00:00:00 2001 From: Samyak Jain <34437877+KaymasJain@users.noreply.github.com> Date: Wed, 16 Jun 2021 14:04:18 +0530 Subject: [PATCH 20/21] updated connector to fetch factory from resolvers --- .../connectors/uniswap_v3_erc20_staking/helpers.sol | 8 ++++---- .../connectors/uniswap_v3_erc20_staking/interface.sol | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol index b472780d..e409b6f5 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol @@ -9,14 +9,14 @@ import { IStakingRewards, IStakingRewardsFactory } from "./interface.sol"; abstract contract Helpers is DSMath, Basic { - IStakingRewardsFactory constant internal stakingRewardsFactory = - IStakingRewardsFactory(address(0)); // TODO + IGUniPoolResolver constant internal guniResolver = + IGUniPoolResolver(0x729BF02a9A786529Fc80498f8fd0051116061B13); - TokenInterface constant internal rewardToken = TokenInterface(address(0)); // TODO + TokenInterface constant internal rewardToken = TokenInterface(0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb); function getStakingContract(address stakingToken) internal view returns (address) { IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo = - stakingRewardsFactory.stakingRewardsInfoByStakingToken(stakingToken); + guniResolver.getStakingFactory().stakingRewardsInfoByStakingToken(stakingToken); return stakingRewardsInfo.stakingRewards; } diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol index 78e732a6..73ccbe03 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/interface.sol @@ -17,4 +17,10 @@ interface IStakingRewardsFactory { function stakingRewardsInfoByStakingToken(address) external view returns(StakingRewardsInfo memory); +} + +interface IGUniPoolResolver { + + function getStakingFactory() external view returns(IStakingRewardsFactory); + } \ No newline at end of file From 30f203f54ad71691cfda60d1608c4e2e72d328ab Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Wed, 16 Jun 2021 14:13:16 +0530 Subject: [PATCH 21/21] Minor fix --- .../mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol index e409b6f5..1d0c6d94 100644 --- a/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol +++ b/contracts/mainnet/connectors/uniswap_v3_erc20_staking/helpers.sol @@ -5,7 +5,7 @@ pragma experimental ABIEncoderV2; import { DSMath } from "../../common/math.sol"; import { Basic } from "../../common/basic.sol"; import { TokenInterface } from "../../common/interfaces.sol"; -import { IStakingRewards, IStakingRewardsFactory } from "./interface.sol"; +import { IStakingRewards, IStakingRewardsFactory, IGUniPoolResolver } from "./interface.sol"; abstract contract Helpers is DSMath, Basic {