-
Notifications
You must be signed in to change notification settings - Fork 527
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ERC20 staking prebuilt and extension #286
Conversation
function _stake(uint256 _amount) internal virtual { | ||
require(_amount != 0, "Staking 0 tokens"); | ||
address _token = token; | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
|
||
CurrencyTransferLib.transferCurrency(_token, msg.sender, address(this), _amount); | ||
|
||
stakers[msg.sender].amountStaked += _amount; | ||
|
||
emit TokensStaked(msg.sender, _amount); | ||
} |
Check warning
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256 _amount) internal virtual { | ||
require(_amount != 0, "Staking 0 tokens"); | ||
address _token = token; | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
|
||
CurrencyTransferLib.transferCurrency(_token, msg.sender, address(this), _amount); | ||
|
||
stakers[msg.sender].amountStaked += _amount; | ||
|
||
emit TokensStaked(msg.sender, _amount); | ||
} |
Check warning
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256 _amount) internal virtual { | ||
require(_amount != 0, "Staking 0 tokens"); | ||
address _token = token; | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
|
||
CurrencyTransferLib.transferCurrency(_token, msg.sender, address(this), _amount); | ||
|
||
stakers[msg.sender].amountStaked += _amount; | ||
|
||
emit TokensStaked(msg.sender, _amount); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
function _withdraw(uint256 _amount) internal virtual { | ||
uint256 _amountStaked = stakers[msg.sender].amountStaked; | ||
require(_amount != 0, "Withdrawing 0 tokens"); | ||
require(_amountStaked >= _amount, "Withdrawing more than staked"); | ||
|
||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
|
||
if (_amountStaked == _amount) { | ||
address[] memory _stakersArray = stakersArray; | ||
for (uint256 i = 0; i < _stakersArray.length; ++i) { | ||
if (_stakersArray[i] == msg.sender) { | ||
stakersArray[i] = stakersArray[_stakersArray.length - 1]; | ||
stakersArray.pop(); | ||
break; | ||
} | ||
} | ||
} | ||
stakers[msg.sender].amountStaked -= _amount; | ||
|
||
CurrencyTransferLib.transferCurrency(token, address(this), msg.sender, _amount); | ||
|
||
emit TokensWithdrawn(msg.sender, _amount); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
function _stake(uint256 _amount) internal virtual { | ||
require(_amount != 0, "Staking 0 tokens"); | ||
address _token = token; | ||
|
||
if (stakers[msg.sender].amountStaked > 0) { | ||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
} else { | ||
stakersArray.push(msg.sender); | ||
stakers[msg.sender].timeOfLastUpdate = block.timestamp; | ||
} | ||
|
||
CurrencyTransferLib.transferCurrency(_token, msg.sender, address(this), _amount); | ||
|
||
stakers[msg.sender].amountStaked += _amount; | ||
|
||
emit TokensStaked(msg.sender, _amount); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
function _withdraw(uint256 _amount) internal virtual { | ||
uint256 _amountStaked = stakers[msg.sender].amountStaked; | ||
require(_amount != 0, "Withdrawing 0 tokens"); | ||
require(_amountStaked >= _amount, "Withdrawing more than staked"); | ||
|
||
_updateUnclaimedRewardsForStaker(msg.sender); | ||
|
||
if (_amountStaked == _amount) { | ||
address[] memory _stakersArray = stakersArray; | ||
for (uint256 i = 0; i < _stakersArray.length; ++i) { | ||
if (_stakersArray[i] == msg.sender) { | ||
stakersArray[i] = stakersArray[_stakersArray.length - 1]; | ||
stakersArray.pop(); | ||
break; | ||
} | ||
} | ||
} | ||
stakers[msg.sender].amountStaked -= _amount; | ||
|
||
CurrencyTransferLib.transferCurrency(token, address(this), msg.sender, _amount); | ||
|
||
emit TokensWithdrawn(msg.sender, _amount); | ||
} |
Check notice
Code scanning / Slither
Reentrancy vulnerabilities
contracts/staking/TokenStake.sol
Outdated
contract TokenStake is | ||
Initializable, | ||
ContractMetadata, | ||
PermissionsEnumerable, | ||
ERC2771ContextUpgradeable, | ||
MulticallUpgradeable, | ||
Staking20Upgradeable | ||
{ | ||
bytes32 private constant MODULE_TYPE = bytes32("TokenStake"); | ||
uint256 private constant VERSION = 1; | ||
|
||
/// @dev ERC20 Reward Token address. See {_mintRewards} below. | ||
address public rewardToken; | ||
|
||
constructor() initializer {} | ||
|
||
/// @dev Initiliazes the contract, like a constructor. | ||
function initialize( | ||
address _defaultAdmin, | ||
string memory _contractURI, | ||
address[] memory _trustedForwarders, | ||
address _rewardToken, | ||
address _stakingToken, | ||
uint256 _timeUnit, | ||
uint256 _rewardsPerUnitTime | ||
) external initializer { | ||
__ReentrancyGuard_init(); | ||
__ERC2771Context_init_unchained(_trustedForwarders); | ||
|
||
require(_rewardToken != _stakingToken, "Reward Token and Staking Token can't be same."); | ||
rewardToken = _rewardToken; | ||
__Staking20_init(_stakingToken); | ||
_setTimeUnit(_timeUnit); | ||
_setRewardsPerUnitTime(_rewardsPerUnitTime); | ||
|
||
_setupContractURI(_contractURI); | ||
_setupRole(DEFAULT_ADMIN_ROLE, _defaultAdmin); | ||
} | ||
|
||
/// @dev Returns the module type of the contract. | ||
function contractType() external pure virtual returns (bytes32) { | ||
return MODULE_TYPE; | ||
} | ||
|
||
/// @dev Returns the version of the contract. | ||
function contractVersion() external pure virtual returns (uint8) { | ||
return uint8(VERSION); | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
Transfer Staking Rewards | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/// @dev Mint/Transfer ERC20 rewards to the staker. | ||
function _mintRewards(address _staker, uint256 _rewards) internal override { | ||
CurrencyTransferLib.transferCurrency(rewardToken, address(this), _staker, _rewards); | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
Internal functions | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/// @dev Returns whether staking related restrictions can be set in the given execution context. | ||
function _canSetStakeConditions() internal view override returns (bool) { | ||
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender()); | ||
} | ||
|
||
/// @dev Checks whether contract metadata can be set in the given execution context. | ||
function _canSetContractURI() internal view override returns (bool) { | ||
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender()); | ||
} | ||
|
||
/*/////////////////////////////////////////////////////////////// | ||
Miscellaneous | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
function _msgSender() internal view virtual override returns (address sender) { | ||
return ERC2771ContextUpgradeable._msgSender(); | ||
} | ||
|
||
function _msgData() internal view virtual override returns (bytes calldata) { | ||
return ERC2771ContextUpgradeable._msgData(); | ||
} | ||
} |
Check warning
Code scanning / Slither
Missing inheritance
No description provided.