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] 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