SignataIdentity private signataIdentity;
function stakeTokens(uint256 _amount, uint256[] memory _tokenIds) public {
getLastStakableBlock() > block.number,
'this farm is expired and no more stakers can be added'
// try to get the delegate of the account. this will fail if the account isn't registered, or is in an unusable state
signataIdentity.getDelegate(msg.sender);
if (balanceOf(msg.sender) > 0) {
_harvestTokens(msg.sender);
uint256 _finalAmountTransferred;
"you need to provide NFT token IDs you're staking"
for (uint256 _i = 0; _i < _tokenIds.length; _i++) {
_stakedERC721.transferFrom(msg.sender, address(this), _tokenIds[_i]);
_finalAmountTransferred = _tokenIds.length;
uint256 _contractBalanceBefore = _stakedERC20.balanceOf(address(this));
_stakedERC20.transferFrom(msg.sender, address(this), _amount);
// in the event a token contract on transfer taxes, burns, etc. tokens
// the contract might not get the entire amount that the user originally
// transferred. Need to calculate from the previous contract balance
// so we know how many were actually transferred.
_finalAmountTransferred = _stakedERC20.balanceOf(address(this)).sub(
if (totalSupply() == 0) {
pool.creationBlock = block.number;
pool.lastRewardBlock = block.number;
_mint(msg.sender, _finalAmountTransferred);
StakerInfo storage _staker = stakers[msg.sender];
_staker.amountStaked = _staker.amountStaked.add(_finalAmountTransferred);
_staker.blockOriginallyStaked = block.number;
_staker.timeOriginallyStaked = block.timestamp;
_staker.blockLastHarvested = block.number;
_staker.rewardDebt = _staker.amountStaked.mul(pool.accERC20PerShare).div(
for (uint256 _i = 0; _i < _tokenIds.length; _i++) {
_staker.nftTokenIds.push(_tokenIds[_i]);
_updNumStaked(_finalAmountTransferred, 'add');
emit Deposit(msg.sender, _finalAmountTransferred);