Contract Source Code:
File 1 of 1 : P808
/**
New808token ERC20 contract
Name : New808token
Symbol : P808
Decimals : 8
Blockchain : Polygon
Owner Account : 0x9BDD969B35b0BA80014A9Ba771a3842883Eac1bA
(c) by Didar Metu 2022. MIT Licence.
*/
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
contract ERC721Holder is IERC721Receiver {
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role, _msgSender());
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role, address account) internal view {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 8;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
unchecked {
_approve(sender, _msgSender(), currentAllowance - amount);
}
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
_afterTokenTransfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
// contract-P808
pragma solidity ^0.8.2;
contract P808 is ERC20, AccessControl, ERC721Holder {
bytes32 public constant CONTRACT_ADMIN_ROLE = keccak256("CONTRACT_ADMIN_ROLE");
address public owner;
bool public paused = false;
uint256 public maxSupply = 21000000 * 10 ** 8;
address public collectionAddressC1;
address public collectionAddressC2;
address public collectionAddressC3;
uint256 public numberOfBlocksPerRewardUnitC1;
uint256 public numberOfBlocksPerRewardUnitC2;
uint256 public numberOfBlocksPerRewardUnitC3;
uint256 public coinAmountPerRewardUnitC1;
uint256 public coinAmountPerRewardUnitC2;
uint256 public coinAmountPerRewardUnitC3;
uint256 public amountOfStakersC1;
uint256 public amountOfStakersC2;
uint256 public amountOfStakersC3;
uint256 public tokensStakedC1;
uint256 public tokensStakedC2;
uint256 public tokensStakedC3;
uint256 public stakingStartBlockC1;
uint256 public stakingStartBlockC2;
uint256 public stakingStartBlockC3;
struct StakeInfoC1 {
uint256 stakedAtBlock;
uint256 lastHarvestBlock;
bool currentlyStaked;
}
struct StakeInfoC2 {
uint256 stakedAtBlock;
uint256 lastHarvestBlock;
bool currentlyStaked;
}
struct StakeInfoC3 {
uint256 stakedAtBlock;
uint256 lastHarvestBlock;
bool currentlyStaked;
}
mapping (address => mapping(uint256 => StakeInfoC1)) public stakeLogC1;
mapping (address => mapping(uint256 => StakeInfoC2)) public stakeLogC2;
mapping (address => mapping(uint256 => StakeInfoC3)) public stakeLogC3;
mapping (address => uint256) public tokensStakedByUserC1;
mapping (address => uint256) public tokensStakedByUserC2;
mapping (address => uint256) public tokensStakedByUserC3;
mapping (address => uint256[]) public stakePortfolioByUserC1;
mapping (address => uint256[]) public stakePortfolioByUserC2;
mapping (address => uint256[]) public stakePortfolioByUserC3;
mapping(uint256 => uint256) public indexOfTokenIdInStakePortfolioC1;
mapping(uint256 => uint256) public indexOfTokenIdInStakePortfolioC2;
mapping(uint256 => uint256) public indexOfTokenIdInStakePortfolioC3;
event RewardsHarvestedC1 (address owner, uint256 amount);
event RewardsHarvestedC2 (address owner, uint256 amount);
event RewardsHarvestedC3 (address owner, uint256 amount);
event NFTStakedC1 (address owner, uint256 tokenId);
event NFTStakedC2 (address owner, uint256 tokenId);
event NFTStakedC3 (address owner, uint256 tokenId);
event NFTUnstakedC1 (address owner, uint256 tokenId);
event NFTUnstakedC2 (address owner, uint256 tokenId);
event NFTUnstakedC3 (address owner, uint256 tokenId);
constructor() ERC20("New808token", "P808")AccessControl(){
owner = 0x9BDD969B35b0BA80014A9Ba771a3842883Eac1bA;
collectionAddressC1 = 0x0000000000000000000000000000000000000000;
collectionAddressC2 = 0x0000000000000000000000000000000000000000;
collectionAddressC3 = 0x0000000000000000000000000000000000000000;
_mint(owner, 1000000 * 10 ** 8);
_setupRole(DEFAULT_ADMIN_ROLE, owner);
_setupRole(CONTRACT_ADMIN_ROLE, owner);
stakingStartBlockC1 = block.number;
stakingStartBlockC2 = block.number;
stakingStartBlockC3 = block.number;
coinAmountPerRewardUnitC1 = 5 * 10 ** 8;
coinAmountPerRewardUnitC2 = 5 * 10 ** 8;
coinAmountPerRewardUnitC3 = 5 * 10 ** 8;
numberOfBlocksPerRewardUnitC1 = 24240; //808 minutes
numberOfBlocksPerRewardUnitC2 = 24240;
numberOfBlocksPerRewardUnitC3 = 24240;
}
function stakedNFTSByUserC1(address owner) external view returns (uint256[] memory){
return stakePortfolioByUserC1[owner];
}
function stakedNFTSByUserC2(address owner) external view returns (uint256[] memory){
return stakePortfolioByUserC2[owner];
}
function stakedNFTSByUserC3(address owner) external view returns (uint256[] memory){
return stakePortfolioByUserC3[owner];
}
function burn(uint256 amount) public returns (bool success) {
super._burn(_msgSender(), amount);
return true;
}
function pendingRewardsC1(address owner, uint256 tokenId) public view returns (uint256){
StakeInfoC1 memory infoC1 = stakeLogC1[owner][tokenId];
if(infoC1.lastHarvestBlock < stakingStartBlockC1 || infoC1.currentlyStaked == false) {
return 0;
}
uint256 blocksPassedSinceLastHarvest = block.number - infoC1.lastHarvestBlock;
if (blocksPassedSinceLastHarvest < numberOfBlocksPerRewardUnitC1 * 2) {
return 0;
}
uint256 rewardAmount = blocksPassedSinceLastHarvest / numberOfBlocksPerRewardUnitC1 - 1;
return rewardAmount * coinAmountPerRewardUnitC1;
}
function pendingRewardsC2(address owner, uint256 tokenId) public view returns (uint256){
StakeInfoC2 memory infoC2 = stakeLogC2[owner][tokenId];
if(infoC2.lastHarvestBlock < stakingStartBlockC2 || infoC2.currentlyStaked == false) {
return 0;
}
uint256 blocksPassedSinceLastHarvest = block.number - infoC2.lastHarvestBlock;
if (blocksPassedSinceLastHarvest < numberOfBlocksPerRewardUnitC2 * 2) {
return 0;
}
uint256 rewardAmount = blocksPassedSinceLastHarvest / numberOfBlocksPerRewardUnitC2 - 1;
return rewardAmount * coinAmountPerRewardUnitC2;
}
function pendingRewardsC3(address owner, uint256 tokenId) public view returns (uint256){
StakeInfoC3 memory infoC3 = stakeLogC3[owner][tokenId];
if(infoC3.lastHarvestBlock < stakingStartBlockC3 || infoC3.currentlyStaked == false) {
return 0;
}
uint256 blocksPassedSinceLastHarvest = block.number - infoC3.lastHarvestBlock;
if (blocksPassedSinceLastHarvest < numberOfBlocksPerRewardUnitC3 * 2) {
return 0;
}
uint256 rewardAmount = blocksPassedSinceLastHarvest / numberOfBlocksPerRewardUnitC3 - 1;
return rewardAmount * coinAmountPerRewardUnitC3;
}
function stakeC1(uint256 tokenId) public {
require(!paused, "The contract is paused");
IERC721(collectionAddressC1).safeTransferFrom(_msgSender(), address(this), tokenId);
require(IERC721(collectionAddressC1).ownerOf(tokenId) == address(this), "Error while transferring NFT");
StakeInfoC1 storage infoC1 = stakeLogC1[_msgSender()][tokenId];
infoC1.stakedAtBlock = block.number;
infoC1.lastHarvestBlock = block.number;
infoC1.currentlyStaked = true;
if(tokensStakedByUserC1[_msgSender()] == 0){
amountOfStakersC1 += 1;
}
tokensStakedByUserC1[_msgSender()] += 1;
tokensStakedC1 += 1;
stakePortfolioByUserC1[_msgSender()].push(tokenId);
uint256 indexOfNewElementC1 = stakePortfolioByUserC1[_msgSender()].length - 1;
indexOfTokenIdInStakePortfolioC1[tokenId] = indexOfNewElementC1;
emit NFTStakedC1(_msgSender(), tokenId);
}
function stakeC2(uint256 tokenId) public {
require(!paused, "The contract is paused");
IERC721(collectionAddressC2).safeTransferFrom(_msgSender(), address(this), tokenId);
require(IERC721(collectionAddressC2).ownerOf(tokenId) == address(this), "Error while transferring NFT");
StakeInfoC2 storage infoC2 = stakeLogC2[_msgSender()][tokenId];
infoC2.stakedAtBlock = block.number;
infoC2.lastHarvestBlock = block.number;
infoC2.currentlyStaked = true;
if(tokensStakedByUserC2[_msgSender()] == 0){
amountOfStakersC2 += 1;
}
tokensStakedByUserC2[_msgSender()] += 1;
tokensStakedC2 += 1;
stakePortfolioByUserC2[_msgSender()].push(tokenId);
uint256 indexOfNewElementC2 = stakePortfolioByUserC2[_msgSender()].length - 1;
indexOfTokenIdInStakePortfolioC2[tokenId] = indexOfNewElementC2;
emit NFTStakedC2(_msgSender(), tokenId);
}
function stakeC3(uint256 tokenId) public {
require(!paused, "The contract is paused");
IERC721(collectionAddressC3).safeTransferFrom(_msgSender(), address(this), tokenId);
require(IERC721(collectionAddressC3).ownerOf(tokenId) == address(this), "Error while transferring NFT");
StakeInfoC3 storage infoC3 = stakeLogC3[_msgSender()][tokenId];
infoC3.stakedAtBlock = block.number;
infoC3.lastHarvestBlock = block.number;
infoC3.currentlyStaked = true;
if(tokensStakedByUserC3[_msgSender()] == 0){
amountOfStakersC3 += 1;
}
tokensStakedByUserC3[_msgSender()] += 1;
tokensStakedC3 += 1;
stakePortfolioByUserC3[_msgSender()].push(tokenId);
uint256 indexOfNewElementC3 = stakePortfolioByUserC3[_msgSender()].length - 1;
indexOfTokenIdInStakePortfolioC3[tokenId] = indexOfNewElementC3;
emit NFTStakedC3(_msgSender(), tokenId);
}
function stakeBatchC1(uint256[] memory tokenIds) external {
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
stakeC1(tokenIds[currentId]);
}
}
function stakeBatchC2(uint256[] memory tokenIds) external {
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
stakeC2(tokenIds[currentId]);
}
}
function stakeBatchC3(uint256[] memory tokenIds) external {
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
stakeC3(tokenIds[currentId]);
}
}
function harvestC1(uint256 tokenId) public {
require(!paused, "The contract is paused");
StakeInfoC1 storage infoC1 = stakeLogC1[_msgSender()][tokenId];
uint256 rewardAmountInP808 = pendingRewardsC1(_msgSender(), tokenId);
uint256 supply = totalSupply();
require(rewardAmountInP808 > 0, "Reward amount is zero" );
if(rewardAmountInP808 > 0) {
require(supply + rewardAmountInP808 <= maxSupply, "Maximum Supply limit exceeded");
infoC1.lastHarvestBlock = block.number;
_mint(_msgSender(), rewardAmountInP808);
emit RewardsHarvestedC1(_msgSender(), rewardAmountInP808);
}
}
function harvestC2(uint256 tokenId) public {
require(!paused, "The contract is paused");
StakeInfoC2 storage infoC2 = stakeLogC2[_msgSender()][tokenId];
uint256 rewardAmountInP808 = pendingRewardsC2(_msgSender(), tokenId);
uint256 supply = totalSupply();
require(rewardAmountInP808 > 0, "Reward amount is zero");
if(rewardAmountInP808 > 0) {
require(supply + rewardAmountInP808 <= maxSupply, "Maximum Supply limit exceeded");
infoC2.lastHarvestBlock = block.number;
_mint(_msgSender(), rewardAmountInP808);
emit RewardsHarvestedC2(_msgSender(), rewardAmountInP808);
}
}
function harvestC3(uint256 tokenId) public {
require(!paused, "The contract is paused");
StakeInfoC3 storage infoC3 = stakeLogC3[_msgSender()][tokenId];
uint256 rewardAmountInP808 = pendingRewardsC3(_msgSender(), tokenId);
uint256 supply = totalSupply();
require(rewardAmountInP808 > 0, "Reward amount is zero" );
if(rewardAmountInP808 > 0) {
require(supply + rewardAmountInP808 <= maxSupply, "Maximum Supply limit exceeded");
infoC3.lastHarvestBlock = block.number;
_mint(_msgSender(), rewardAmountInP808);
emit RewardsHarvestedC3(_msgSender(), rewardAmountInP808);
}
}
function harvestBatchC1(address user) external{
uint256[] memory tokenIds = stakePortfolioByUserC1[user];
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
harvestC1(tokenIds[currentId]);
}
}
function harvestBatchC2(address user) external{
uint256[] memory tokenIds = stakePortfolioByUserC2[user];
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
harvestC2(tokenIds[currentId]);
}
}
function harvestBatchC3(address user) external{
uint256[] memory tokenIds = stakePortfolioByUserC3[user];
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
harvestC3(tokenIds[currentId]);
}
}
function unstakeC1(uint256 tokenId) public {
if(pendingRewardsC1(_msgSender(), tokenId) > 0){
harvestC1(tokenId);
}
StakeInfoC1 storage infoC1 = stakeLogC1[_msgSender()][tokenId];
infoC1.currentlyStaked = false;
IERC721(collectionAddressC1).safeTransferFrom(address(this), _msgSender(), tokenId);
require(IERC721(collectionAddressC1).ownerOf(tokenId) == _msgSender(), "Error while transferring NFT");
if(tokensStakedByUserC1[_msgSender()] == 1){
amountOfStakersC1 -= 1;
}
tokensStakedByUserC1[_msgSender()] -= 1;
tokensStakedC1 -= 1;
stakePortfolioByUserC1[_msgSender()][indexOfTokenIdInStakePortfolioC1[tokenId]] = 0;
emit NFTUnstakedC1(_msgSender(), tokenId);
}
function unstakeC2(uint256 tokenId) public {
if(pendingRewardsC2(_msgSender(), tokenId) > 0){
harvestC2(tokenId);
}
StakeInfoC2 storage infoC2 = stakeLogC2[_msgSender()][tokenId];
infoC2.currentlyStaked = false;
IERC721(collectionAddressC2).safeTransferFrom(address(this), _msgSender(), tokenId);
require(IERC721(collectionAddressC2).ownerOf(tokenId) == _msgSender(), "Error while transferring NFT");
if(tokensStakedByUserC2[_msgSender()] == 1){
amountOfStakersC2 -= 1;
}
tokensStakedByUserC2[_msgSender()] -= 1;
tokensStakedC2 -= 1;
stakePortfolioByUserC2[_msgSender()][indexOfTokenIdInStakePortfolioC2[tokenId]] = 0;
emit NFTUnstakedC2(_msgSender(), tokenId);
}
function unstakeC3(uint256 tokenId) public {
if(pendingRewardsC3(_msgSender(), tokenId) > 0){
harvestC3(tokenId);
}
StakeInfoC3 storage infoC3 = stakeLogC3[_msgSender()][tokenId];
infoC3.currentlyStaked = false ;
IERC721(collectionAddressC3).safeTransferFrom(address(this), _msgSender(), tokenId);
require(IERC721(collectionAddressC3).ownerOf(tokenId) == _msgSender(), "Error while transferring NFT");
if(tokensStakedByUserC3[_msgSender()] == 1){
amountOfStakersC3 -= 1;
}
tokensStakedByUserC3[_msgSender()] -= 1;
tokensStakedC3 -= 1;
stakePortfolioByUserC3[_msgSender()][indexOfTokenIdInStakePortfolioC3[tokenId]] = 0;
emit NFTUnstakedC3(_msgSender(), tokenId);
}
function unstakeBatchC1(uint256[] memory tokenIds) external {
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
unstakeC1(tokenIds[currentId]);
}
}
function unstakeBatchC2(uint256[] memory tokenIds) external {
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
unstakeC2(tokenIds[currentId]);
}
}
function unstakeBatchC3(uint256[] memory tokenIds) external {
for(uint currentId = 0; currentId < tokenIds.length; currentId++) {
if(tokenIds[currentId] == 0) {
continue;
}
unstakeC3(tokenIds[currentId]);
}
}
function setNumberOfBlocksPerRewardUnitC1(uint256 numberOfBlocksC1) external onlyRole(CONTRACT_ADMIN_ROLE){
numberOfBlocksPerRewardUnitC1 = numberOfBlocksC1;
}
function setNumberOfBlocksPerRewardUnitC2(uint256 numberOfBlocksC2) external onlyRole(CONTRACT_ADMIN_ROLE){
numberOfBlocksPerRewardUnitC2 = numberOfBlocksC2;
}
function setNumberOfBlocksPerRewardUnitC3(uint256 numberOfBlocksC3) external onlyRole(CONTRACT_ADMIN_ROLE){
numberOfBlocksPerRewardUnitC3 = numberOfBlocksC3;
}
function setCoinAmountPerRewardUnitC1(uint256 coinAmountC1) external onlyRole(CONTRACT_ADMIN_ROLE){
coinAmountPerRewardUnitC1 = coinAmountC1;
}
function setCoinAmountPerRewardUnitC2(uint256 coinAmountC2) external onlyRole(CONTRACT_ADMIN_ROLE){
coinAmountPerRewardUnitC2 = coinAmountC2;
}
function setCoinAmountPerRewardUnitC3(uint256 coinAmountC3) external onlyRole(CONTRACT_ADMIN_ROLE){
coinAmountPerRewardUnitC3 = coinAmountC3;
}
function setCollectionAddressC1(address newAddressC1) external onlyRole(CONTRACT_ADMIN_ROLE){
require (newAddressC1 != address(0), "Update to zero address not possible");
collectionAddressC1 = newAddressC1;
}
function setCollectionAddressC2(address newAddressC2) external onlyRole(CONTRACT_ADMIN_ROLE){
require (newAddressC2 != address(0), "Update to zero address not possible");
collectionAddressC2 = newAddressC2;
}
function setCollectionAddressC3(address newAddressC3) external onlyRole(CONTRACT_ADMIN_ROLE){
require (newAddressC3 != address(0), "Update to zero address not possible");
collectionAddressC3 = newAddressC3;
}
function pause(bool _state) external onlyRole(CONTRACT_ADMIN_ROLE) {
paused = _state;
}
function setStakingStartBlockC1(uint256 newStakingStartBlockC1) external onlyRole(CONTRACT_ADMIN_ROLE){
stakingStartBlockC1 = newStakingStartBlockC1;
}
function setStakingStartBlockC2(uint256 newStakingStartBlockC2) external onlyRole(CONTRACT_ADMIN_ROLE){
stakingStartBlockC2 = newStakingStartBlockC2;
}
function setStakingStartBlockC3(uint256 newStakingStartBlockC3) external onlyRole(CONTRACT_ADMIN_ROLE){
stakingStartBlockC3 = newStakingStartBlockC3;
}
}