@@ -6,7 +6,11 @@ import "../extension/Multicall.sol";
66import "../extension/Ownable.sol " ;
77import "../extension/Staking1155.sol " ;
88
9+ import "../eip/ERC165.sol " ;
910import "../eip/interface/IERC20.sol " ;
11+ import "../eip/interface/IERC1155Receiver.sol " ;
12+
13+ import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol " ;
1014
1115/**
1216 *
@@ -31,56 +35,146 @@ import "../eip/interface/IERC20.sol";
3135 * - Multicall capability to perform multiple actions atomically.
3236 *
3337 */
34- contract Staking1155Base is ContractMetadata , Multicall , Ownable , Staking1155 {
38+
39+ /// note: This contract is provided as a base contract.
40+ // This is to support a variety of use-cases that can be build on top of this base.
41+ //
42+ // Additional functionality such as deposit functions, reward-minting, etc.
43+ // must be implemented by the deployer of this contract, as needed for their use-case.
44+
45+ contract Staking1155Base is ContractMetadata , Multicall , Ownable , Staking1155 , ERC165 , IERC1155Receiver {
3546 /// @dev ERC20 Reward Token address. See {_mintRewards} below.
3647 address public rewardToken;
3748
49+ /// @dev The address of the native token wrapper contract.
50+ address internal immutable nativeTokenWrapper;
51+
52+ /// @dev Total amount of reward tokens in the contract.
53+ uint256 private rewardTokenBalance;
54+
3855 constructor (
3956 uint256 _defaultTimeUnit ,
4057 uint256 _defaultRewardsPerUnitTime ,
4158 address _stakingToken ,
42- address _rewardToken
59+ address _rewardToken ,
60+ address _nativeTokenWrapper
4361 ) Staking1155 (_stakingToken) {
4462 _setupOwner (msg .sender );
4563 _setDefaultStakingCondition (_defaultTimeUnit, _defaultRewardsPerUnitTime);
4664
4765 rewardToken = _rewardToken;
66+ nativeTokenWrapper = _nativeTokenWrapper;
67+ }
68+
69+ /// @dev Lets the contract receive ether to unwrap native tokens.
70+ receive () external payable virtual {
71+ require (msg .sender == nativeTokenWrapper, "caller not native token wrapper. " );
72+ }
73+
74+ /// @dev Admin deposits reward tokens.
75+ function depositRewardTokens (uint256 _amount ) external payable nonReentrant {
76+ _depositRewardTokens (_amount); // override this for custom logic.
77+ }
78+
79+ /// @dev Admin can withdraw excess reward tokens.
80+ function withdrawRewardTokens (uint256 _amount ) external nonReentrant {
81+ _withdrawRewardTokens (_amount); // override this for custom logic.
4882 }
4983
5084 /// @notice View total rewards available in the staking contract.
51- function getRewardTokenBalance () external view virtual override returns (uint256 _rewardsAvailableInContract ) {
52- return IERC20 (rewardToken).balanceOf (address (this ));
85+ function getRewardTokenBalance () external view virtual override returns (uint256 ) {
86+ return rewardTokenBalance;
87+ }
88+
89+ /*///////////////////////////////////////////////////////////////
90+ ERC 165 / 721 logic
91+ //////////////////////////////////////////////////////////////*/
92+
93+ function onERC1155Received (
94+ address ,
95+ address ,
96+ uint256 ,
97+ uint256 ,
98+ bytes calldata
99+ ) external returns (bytes4 ) {
100+ require (isStaking == 2 , "Direct transfer " );
101+ return this .onERC1155Received.selector ;
102+ }
103+
104+ function onERC1155BatchReceived (
105+ address operator ,
106+ address from ,
107+ uint256 [] calldata ids ,
108+ uint256 [] calldata values ,
109+ bytes calldata data
110+ ) external returns (bytes4 ) {}
111+
112+ function supportsInterface (bytes4 interfaceId ) public view override (ERC165 , IERC165 ) returns (bool ) {
113+ return interfaceId == type (IERC1155Receiver ).interfaceId || super .supportsInterface (interfaceId);
53114 }
54115
55116 /*//////////////////////////////////////////////////////////////
56117 Minting logic
57118 //////////////////////////////////////////////////////////////*/
58119
59120 /**
60- * @dev Mint ERC20 rewards to the staker. Must override .
121+ * @dev Mint ERC20 rewards to the staker. Override for custom logic .
61122 *
62123 * @param _staker Address for which to calculated rewards.
63124 * @param _rewards Amount of tokens to be given out as reward.
64125 *
65126 */
66127 function _mintRewards (address _staker , uint256 _rewards ) internal virtual override {
67- // Mint or transfer reward-tokens here.
68- // e.g.
69- //
70- // IERC20(rewardToken).transfer(_staker, _rewards);
71- //
72- // OR
73- //
74- // Use a mintable ERC20, such as thirdweb's `TokenERC20.sol`
75- //
76- // TokenERC20(rewardToken).mintTo(_staker, _rewards);
77- // note: The staking contract should have minter role to mint tokens.
128+ require (_rewards <= rewardTokenBalance, "Not enough reward tokens " );
129+ rewardTokenBalance -= _rewards;
130+ CurrencyTransferLib.transferCurrencyWithWrapper (
131+ rewardToken,
132+ address (this ),
133+ _staker,
134+ _rewards,
135+ nativeTokenWrapper
136+ );
78137 }
79138
80139 /*//////////////////////////////////////////////////////////////
81140 Other Internal functions
82141 //////////////////////////////////////////////////////////////*/
83142
143+ /// @dev Admin deposits reward tokens -- override for custom logic.
144+ function _depositRewardTokens (uint256 _amount ) internal virtual {
145+ require (msg .sender == owner (), "Not authorized " );
146+
147+ address _rewardToken = rewardToken == CurrencyTransferLib.NATIVE_TOKEN ? nativeTokenWrapper : rewardToken;
148+
149+ uint256 balanceBefore = IERC20 (_rewardToken).balanceOf (address (this ));
150+ CurrencyTransferLib.transferCurrencyWithWrapper (
151+ rewardToken,
152+ msg .sender ,
153+ address (this ),
154+ _amount,
155+ nativeTokenWrapper
156+ );
157+ uint256 actualAmount = IERC20 (_rewardToken).balanceOf (address (this )) - balanceBefore;
158+
159+ rewardTokenBalance += actualAmount;
160+ }
161+
162+ /// @dev Admin can withdraw excess reward tokens -- override for custom logic.
163+ function _withdrawRewardTokens (uint256 _amount ) internal virtual {
164+ require (msg .sender == owner (), "Not authorized " );
165+
166+ // to prevent locking of direct-transferred tokens
167+ rewardTokenBalance = _amount > rewardTokenBalance ? 0 : rewardTokenBalance - _amount;
168+
169+ CurrencyTransferLib.transferCurrencyWithWrapper (
170+ rewardToken,
171+ address (this ),
172+ msg .sender ,
173+ _amount,
174+ nativeTokenWrapper
175+ );
176+ }
177+
84178 /// @dev Returns whether staking restrictions can be set in given execution context.
85179 function _canSetStakeConditions () internal view virtual override returns (bool ) {
86180 return msg .sender == owner ();
0 commit comments