mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Merge pull request #41 from Instadapp/uni-v3-erc20
Uniswap v3 erc20 pool
This commit is contained in:
commit
ecb007fcd8
30
contracts/mainnet/connectors/erc20_staking/events.sol
Normal file
30
contracts/mainnet/connectors/erc20_staking/events.sol
Normal file
|
@ -0,0 +1,30 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
|
||||
event LogDeposit(
|
||||
address indexed stakingToken,
|
||||
bytes32 indexed stakingType,
|
||||
uint256 amount,
|
||||
uint getId,
|
||||
uint setId
|
||||
);
|
||||
|
||||
event LogWithdrawAndClaimedReward(
|
||||
address indexed stakingToken,
|
||||
bytes32 indexed stakingType,
|
||||
uint256 amount,
|
||||
uint256 rewardAmt,
|
||||
uint getId,
|
||||
uint setIdAmount,
|
||||
uint setIdReward
|
||||
);
|
||||
|
||||
event LogClaimedReward(
|
||||
address indexed rewardToken,
|
||||
bytes32 indexed stakingType,
|
||||
uint256 rewardAmt,
|
||||
uint setId
|
||||
);
|
||||
|
||||
}
|
48
contracts/mainnet/connectors/erc20_staking/helpers.sol
Normal file
48
contracts/mainnet/connectors/erc20_staking/helpers.sol
Normal file
|
@ -0,0 +1,48 @@
|
|||
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, StakingERC20Mapping } 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);
|
||||
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);
|
||||
rewardToken = TokenInterface(stakingData.rewardToken);
|
||||
}
|
||||
|
||||
function getMappingAddr() internal virtual view returns (address) {
|
||||
return 0xbE658233bA9990d86155b3902fd05a7AfC7eBdB5; // InstaMapping Address
|
||||
}
|
||||
|
||||
}
|
21
contracts/mainnet/connectors/erc20_staking/interface.sol
Normal file
21
contracts/mainnet/connectors/erc20_staking/interface.sol
Normal file
|
@ -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 StakingERC20Mapping {
|
||||
|
||||
struct StakingData {
|
||||
address stakingPool;
|
||||
address stakingToken;
|
||||
address rewardToken;
|
||||
}
|
||||
|
||||
function stakingMapping(bytes32) external view returns(StakingData memory);
|
||||
|
||||
}
|
120
contracts/mainnet/connectors/erc20_staking/main.sol
Normal file
120
contracts/mainnet/connectors/erc20_staking/main.sol
Normal file
|
@ -0,0 +1,120 @@
|
|||
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";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
import { IStakingRewards, StakingERC20Mapping } from "./interface.sol";
|
||||
|
||||
contract Main is Helpers, Events {
|
||||
|
||||
/**
|
||||
* @dev Deposit ERC20.
|
||||
* @notice Deposit Tokens to staking pool.
|
||||
* @param stakingPoolName staking pool name.
|
||||
* @param amt staking token amount.
|
||||
* @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 returns (string memory _eventName, bytes memory _eventParam) {
|
||||
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);
|
||||
_eventName = "LogDeposit(address,bytes32,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(address(stakingToken), stakingType, _amt, getId, setId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw ERC20.
|
||||
* @notice Withdraw Tokens from the staking pool.
|
||||
* @param stakingPoolName staking pool name.
|
||||
* @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(
|
||||
string calldata stakingPoolName,
|
||||
uint amt,
|
||||
uint getId,
|
||||
uint setIdAmount,
|
||||
uint setIdReward
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Claim Reward.
|
||||
* @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 returns (string memory _eventName, bytes memory _eventParam) {
|
||||
(
|
||||
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);
|
||||
_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";
|
||||
}
|
34
contracts/mainnet/connectors/uniswap_v3_erc20/events.sol
Normal file
34
contracts/mainnet/connectors/uniswap_v3_erc20/events.sol
Normal file
|
@ -0,0 +1,34 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
contract Events {
|
||||
|
||||
event LogDepositLiquidity(
|
||||
address indexed pool,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 mintAmount,
|
||||
uint256[] getIds,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
event LogWithdrawLiquidity(
|
||||
address indexed pool,
|
||||
uint256 amountA,
|
||||
uint256 amountB,
|
||||
uint256 burnAmount,
|
||||
uint256 getId,
|
||||
uint256[] setIds
|
||||
);
|
||||
|
||||
event LogSwapAndDepositLiquidity(
|
||||
address indexed pool,
|
||||
uint256 amtA,
|
||||
uint256 amtB,
|
||||
uint256 mintAmount,
|
||||
bool zeroForOne,
|
||||
uint swapAmount,
|
||||
uint256 getId,
|
||||
uint256 setId
|
||||
);
|
||||
|
||||
}
|
32
contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol
Normal file
32
contracts/mainnet/connectors/uniswap_v3_erc20/helpers.sol
Normal file
|
@ -0,0 +1,32 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import { DSMath } from "../../common/math.sol";
|
||||
import { Basic } from "../../common/basic.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;
|
||||
}
|
||||
|
||||
}
|
120
contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol
Normal file
120
contracts/mainnet/connectors/uniswap_v3_erc20/interface.sol
Normal file
|
@ -0,0 +1,120 @@
|
|||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
||||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
interface IGUniPool {
|
||||
|
||||
function token0() external view returns (IERC20);
|
||||
|
||||
function token1() external view returns (IERC20);
|
||||
|
||||
function mint(
|
||||
uint256 amount,
|
||||
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 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;
|
||||
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);
|
||||
}
|
220
contracts/mainnet/connectors/uniswap_v3_erc20/main.sol
Normal file
220
contracts/mainnet/connectors/uniswap_v3_erc20/main.sol
Normal file
|
@ -0,0 +1,220 @@
|
|||
pragma solidity ^0.7.0;
|
||||
|
||||
/**
|
||||
* @title G-Uniswap V3 ERC20 Wrapper.
|
||||
* @dev G-Uniswap V3 Wrapper to deposit and withdraw.
|
||||
*/
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
|
||||
|
||||
import { TokenInterface } from "../../common/interfaces.sol";
|
||||
import { IGUniPool, IERC20 } from "./interface.sol";
|
||||
import { Helpers } from "./helpers.sol";
|
||||
import { Events } from "./events.sol";
|
||||
|
||||
abstract contract UniswapV3Resolver is Events, Helpers {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
* @dev Deposit Liquidity.
|
||||
* @notice Deposit Liquidity to Gelato Uniswap V3 pool.
|
||||
* @param pool The address of pool.
|
||||
* @param amt0Max Amount0 Max amount
|
||||
* @param amt1Max Amount1 Max amount
|
||||
* @param slippage use to calculate minimum deposit. 100% = 1e18
|
||||
* @param getIds Array of IDs to retrieve amounts.
|
||||
* @param setId ID stores the amount of pools tokens received.
|
||||
*/
|
||||
function deposit(
|
||||
address pool,
|
||||
uint256 amt0Max,
|
||||
uint256 amt1Max,
|
||||
uint slippage,
|
||||
uint256[] calldata getIds,
|
||||
uint256 setId
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
|
||||
amt0Max = getUint(getIds[0], amt0Max);
|
||||
amt1Max = getUint(getIds[1], amt1Max);
|
||||
|
||||
Deposit memory depositData;
|
||||
depositData.poolContract = IGUniPool(pool);
|
||||
|
||||
(depositData.amount0In, depositData.amount1In, depositData.mintAmount) =
|
||||
depositData.poolContract.getMintAmounts(amt0Max, amt1Max);
|
||||
|
||||
uint amt0Min = wmul(amt0Max, slippage);
|
||||
uint amt1Min = wmul(amt1Max, slippage);
|
||||
|
||||
require(
|
||||
depositData.amount0In >= amt0Min && depositData.amount1In >= amt1Min,
|
||||
"below min amounts"
|
||||
);
|
||||
|
||||
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 (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,) = depositData.poolContract.mint(depositData.mintAmount, address(this));
|
||||
|
||||
require(
|
||||
amount0 == depositData.amount0In &&
|
||||
amount1 == depositData.amount1In, "unexpected amounts deposited");
|
||||
|
||||
setUint(setId, depositData.mintAmount);
|
||||
|
||||
_eventName = "LogDepositLiquidity(address,uint256,uint256,uint256,uint256[],uint256)";
|
||||
_eventParam = abi.encode(pool, amount0, amount1, depositData.mintAmount, getIds, setId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Withdraw Liquidity.
|
||||
* @notice Withdraw Liquidity from Gelato 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 setIds Array of IDs tp stores the amounts of pools tokens received.
|
||||
*/
|
||||
function withdraw(
|
||||
address pool,
|
||||
uint256 liqAmt,
|
||||
uint256 minAmtA,
|
||||
uint256 minAmtB,
|
||||
uint256 getId,
|
||||
uint256[] calldata setIds
|
||||
) external payable returns (string memory _eventName, bytes memory _eventParam) {
|
||||
|
||||
liqAmt = getUint(getId, liqAmt);
|
||||
|
||||
IGUniPool poolContract = IGUniPool(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)), amount0);
|
||||
}
|
||||
|
||||
if (amount1 > 0) {
|
||||
IERC20 _token1 = poolContract.token1();
|
||||
convertWethToEth(address(_token1) == wethAddr, TokenInterface(address(_token1)), amount1);
|
||||
}
|
||||
|
||||
require(amount0 >= minAmtA && amount1 >= minAmtB, "received below minimum");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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,
|
||||
uint256 amount1In,
|
||||
bool zeroForOne,
|
||||
uint256 swapAmount,
|
||||
uint160 swapThreshold,
|
||||
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();
|
||||
|
||||
depositAndSwap.amount0;
|
||||
depositAndSwap.amount1;
|
||||
depositAndSwap.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);
|
||||
|
||||
(depositAndSwap.amount0, depositAndSwap.amount1,depositAndSwap. mintAmount) =
|
||||
gUniRouter.rebalanceAndAddLiquidityETH{value: amount1In}(
|
||||
depositAndSwap.poolContract,
|
||||
amount0In,
|
||||
amount1In,
|
||||
zeroForOne,
|
||||
swapAmount,
|
||||
swapThreshold,
|
||||
0,
|
||||
0,
|
||||
address(this)
|
||||
);
|
||||
} else {
|
||||
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, depositAndSwap.mintAmount);
|
||||
|
||||
_eventName = "LogSwapAndDepositLiquidity(address,uint256,uint256,uint256,bool,uint256,uint256,uint256)";
|
||||
_eventParam = abi.encode(
|
||||
pool,
|
||||
depositAndSwap.amount0,
|
||||
depositAndSwap.amount1,
|
||||
depositAndSwap.mintAmount,
|
||||
zeroForOne,
|
||||
swapAmount,
|
||||
getId,
|
||||
setId
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
contract ConnectV2GUniswapV3ERC20 is UniswapV3Resolver {
|
||||
string public constant name = "G-Uniswap-v3-ERC20-v1.0";
|
||||
}
|
|
@ -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
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
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, IGUniPoolResolver } from "./interface.sol";
|
||||
|
||||
abstract contract Helpers is DSMath, Basic {
|
||||
|
||||
IGUniPoolResolver constant internal guniResolver =
|
||||
IGUniPoolResolver(0x729BF02a9A786529Fc80498f8fd0051116061B13);
|
||||
|
||||
TokenInterface constant internal rewardToken = TokenInterface(0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb);
|
||||
|
||||
function getStakingContract(address stakingToken) internal view returns (address) {
|
||||
IStakingRewardsFactory.StakingRewardsInfo memory stakingRewardsInfo =
|
||||
guniResolver.getStakingFactory().stakingRewardsInfoByStakingToken(stakingToken);
|
||||
|
||||
return stakingRewardsInfo.stakingRewards;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
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);
|
||||
|
||||
}
|
||||
|
||||
interface IGUniPoolResolver {
|
||||
|
||||
function getStakingFactory() external view returns(IStakingRewardsFactory);
|
||||
|
||||
}
|
108
contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol
Normal file
108
contracts/mainnet/connectors/uniswap_v3_erc20_staking/main.sol
Normal file
|
@ -0,0 +1,108 @@
|
|||
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);
|
||||
|
||||
IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken));
|
||||
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);
|
||||
|
||||
IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken));
|
||||
|
||||
_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) {
|
||||
IStakingRewards stakingContract = IStakingRewards(getStakingContract(stakingToken));
|
||||
|
||||
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";
|
||||
}
|
119
contracts/mainnet/mapping/StakeERC20.sol
Normal file
119
contracts/mainnet/mapping/StakeERC20.sol
Normal file
|
@ -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";
|
||||
}
|
Loading…
Reference in New Issue
Block a user