Use uint256[] memory in function

Hi

I have modified a staking contract, but I have come to a problem which I cannot seem to work around.

I have a function which checks which ID of the ERC721 is staked from msg.sender, which works just fine, code is like this:

    function getTokensStaked2() public view returns (uint256[] memory) {
        return stakerToTokenIds[msg.sender];
    }

Works perfectly, and returns the staked ID number when called

BUT, I need to use the staked ID number inside another function, and when I try this:

        uint256[] memory tokenIds = stakerToTokenIds[staker];
        Lip storage lip = lips[tokenIds];
        uint256 getCurrentLevel = lip.level;

I get an error message - "memory is not implicitly convertible to expected type uint256"

How can I "convert" or move to uint256[] into a uint256?

Hey @Kion_Larsen
why you don't do directly:

 Lip storage lip = lips[stakerToTokenIds[staker]];
 uint256 getCurrentLevel = lip.level;

This results in an error:

Type uint256[] storage ref is not implicitly convertible to expected type uint256

I think you should share the full code to help us understand

Well here it is :slight_smile:

Problem is getting the return from function getTokenStaked2(), and use it instead of the "0 (zero) in Lip storage lip = lips[0] - Or implant it into the getAllRewards function :wink:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";



contract LipToken is ERC721, Ownable {
    IERC20 public rewardsToken;
    IERC20 public stakingToken;
    IERC20 public electricPowerToken;

  
  constructor(string memory _name, string memory _symbol, address _stakingToken, address _rewardsToken, address _electricPowerToken)
    ERC721(_name, _symbol)
  {
    stakingToken = IERC20(_stakingToken);
    rewardsToken = IERC20(_rewardsToken);
    electricPowerToken = IERC20(_electricPowerToken);
  }

    address public admin;
    uint public rewardRate = 100;
    uint public lastUpdateTime;
    uint public rewardPerTokenStored;
    uint256 public MULTIPLIER;
    uint256 COUNTER;
    uint256 currentLevel = 1;
    uint256 fee = 0;
    address public nftAddress;
    uint public balanceReceived;
    address nullAddress = 0x0000000000000000000000000000000000000000;
    uint256 public MAX_WALLET_STAKED = 1;
    uint256 public tax = 1000000000000000000;






    mapping(address => uint) public userRewardPerTokenPaid;
    mapping(address => uint) public rewards;
    mapping(address => uint256[]) internal stakerToTokenIds;
    mapping(uint256 => address) internal tokenIdToStaker;
    mapping(uint256 => uint256) internal tokenIdToTimeStamp;



    uint private _totalSupply;
    mapping(address => uint) private _balances;




  struct Lip {
    string name;
    uint256 id;
    uint256 dna;
    uint16 level;
    uint8 rarity;
    address payable holder;
  }

  Lip test;
  Lip[] public lips;

// Actions



    function remove(address staker, uint256 index) internal {
        if (index >= stakerToTokenIds[staker].length) return;

        for (uint256 i = index; i < stakerToTokenIds[staker].length - 1; i++) {
            stakerToTokenIds[staker][i] = stakerToTokenIds[staker][i + 1];
        }
        stakerToTokenIds[staker].pop();
    }

    function removeTokenIdFromStaker(address staker, uint256 tokenId) internal {
        for (uint256 i = 0; i < stakerToTokenIds[staker].length; i++) {
            if (stakerToTokenIds[staker][i] == tokenId) {
                //This is the tokenId to remove;
                remove(staker, i);
            }
        }
    }

    function stakeByIds(uint256[] memory tokenIds) public {
        require(stakerToTokenIds[msg.sender].length + tokenIds.length <= MAX_WALLET_STAKED, "You have too many NFT's staked!!");

        for (uint256 i = 0; i < tokenIds.length; i++) {
            require(
                IERC721(nftAddress).ownerOf(tokenIds[i]) == msg.sender &&
                    tokenIdToStaker[tokenIds[i]] == nullAddress,
                "Token must be stakable by you!"
            );

            IERC721(nftAddress).transferFrom(msg.sender, address(this), tokenIds[i]);

            stakerToTokenIds[msg.sender].push(tokenIds[i]);

            tokenIdToTimeStamp[tokenIds[i]] = block.timestamp;
            tokenIdToStaker[tokenIds[i]] = msg.sender;
        }
    }

function unstakeByIds(uint256[] memory tokenIds) public payable {

        balanceReceived += msg.value;
        require(msg.value >= tax);


        for (uint256 i = 0; i < tokenIds.length; i++) {

            require(tokenIdToStaker[tokenIds[i]] == msg.sender, "Message Sender was not original staker!");

            IERC721(nftAddress).transferFrom(address(this), msg.sender, tokenIds[i]);

            removeTokenIdFromStaker(msg.sender, tokenIds[i]);

            tokenIdToStaker[tokenIds[i]] = nullAddress;
        }
    }


    function claimAll() public {
        uint256[] memory tokenIds = stakerToTokenIds[msg.sender];
        uint256 totalRewards = 0;

        for (uint256 i = 0; i < tokenIds.length; i++) {
            require(tokenIdToStaker[tokenIds[i]] == msg.sender, "Token is not claimable by you!");

            totalRewards = totalRewards + ((block.timestamp - tokenIdToTimeStamp[tokenIds[i]]) * rewardRate);

            tokenIdToTimeStamp[tokenIds[i]] = block.timestamp;
        }
        
        //Subtract fuel from user
//        uint8 subtractFuel = users[msg.sender].fuel;
//        users[msg.sender].fuel = (subtractFuel - 1);
        
//        _mint(msg.sender, totalRewards);
    }

    function getUserWallet() public view returns (address) {
        return msg.sender;
    }

    function getLevelOfNFT() public view returns(uint256) {
    Lip storage lip = lips[0];
    uint256 getCurrentLevel = lip.level;
    return getCurrentLevel;
  }


    function getTokensStaked2() public view returns (uint256[] memory) {
        return stakerToTokenIds[msg.sender];
    }

    function getAllRewards(address staker) public view returns (uint256) {
        
        uint256 totalRewards = 0;

        uint256[] memory tokenIds = stakerToTokenIds[staker];
        Lip storage lip = lips[0];
        uint256 getCurrentLevel = lip.level;
        for (uint256 i = 0; i < tokenIds.length; i++) {
            totalRewards = totalRewards + ((block.timestamp - tokenIdToTimeStamp[tokenIds[i]]) * rewardRate * getCurrentLevel);
        }

        return totalRewards;
    }

    function getStaker(uint256 tokenId) public view returns (address) {
        return tokenIdToStaker[tokenId];
    }

    function getTokensStaked(address staker) public view returns (uint256[] memory) {
        return stakerToTokenIds[staker];
    }




    function withdrawContractBalance() public {
        address payable to = payable(address(uint160(admin)));
        to.transfer(getBalance());
    }

    function getBalance() public view returns(uint) {
        return address(this).balance;
    }

    function setNftAddress(address _nftAddress) public onlyOwner {
        nftAddress = _nftAddress;
        return;
    }

    function setAdmin(address _Admin) public onlyOwner {
        admin = _Admin;
    }


    function setMULTIPLIER(uint256 _MULTIPLIER) public onlyOwner {
        MULTIPLIER = _MULTIPLIER;
        return;
    }

    function rewardPerToken() public view returns (uint) {
        if (_totalSupply == 0) {
            return rewardPerTokenStored;
        }
        return
            rewardPerTokenStored +
            (((block.timestamp - lastUpdateTime) * rewardRate * 1e18) / _totalSupply);
    }

    function earned(address account) public view returns (uint) {
        return
            ((_balances[account] *
                (rewardPerToken() - userRewardPerTokenPaid[account])) / 1e18) +
            rewards[account];
    }

    modifier updateReward(address account) {
        rewardPerTokenStored = rewardPerToken();
        lastUpdateTime = block.timestamp;

        rewards[account] = earned(account);
        userRewardPerTokenPaid[account] = rewardPerTokenStored;
        _;
    }

    function stake(uint _amount) external updateReward(msg.sender) {
        _totalSupply += _amount;
        _balances[msg.sender] += _amount;
        stakingToken.transferFrom(msg.sender, address(this), _amount);
    }

    function withdraw(uint _amount) external updateReward(msg.sender) {
        _totalSupply -= _amount;
        _balances[msg.sender] -= _amount;
        stakingToken.transfer(msg.sender, _amount);
    }

    function getReward() external updateReward(msg.sender) {
        uint reward = rewards[msg.sender];
        rewards[msg.sender] = 0;
        rewardsToken.transfer(msg.sender, reward);
        (electricPowerToken.transferFrom(msg.sender, address(admin), 10), "You must pay 10 electricPowerTokens for each Harvest of rewardsTokens");
    }

  function levelUp(uint256 _lipId) public payable {
    require(msg.value >= fee);
    require(ownerOf(_lipId) == msg.sender, "You are not owner");
    Lip storage lip = lips[_lipId];
    lip.level++;
  }


   function getLipId() public view returns (uint) {
      return test.dna;
   }

  event NewLip(address indexed owner, uint256 id, uint256 dna);

  // Helpers
  function _createRandomNum(uint256 _mod) internal view returns (uint256) {
    uint256 randomNum = uint256(
      keccak256(abi.encodePacked(block.timestamp, msg.sender))
    );
    return randomNum % _mod;
  }

  function updateFee(uint256 _fee) external onlyOwner {
    fee = _fee;
  }

    function updateRewardRate(uint256 _rewardRate) external onlyOwner {
    rewardRate = _rewardRate;
  }

  function withdraw() external payable onlyOwner {
    address payable _owner = payable(owner());
    _owner.transfer(address(this).balance);
  }

  // Creation
  function _createLip(string memory _name) internal {
    uint8 randRarity = uint8(_createRandomNum(100));
    uint256 randDna = _createRandomNum(10**16);
    Lip memory newLip = Lip(_name, COUNTER, randDna, 1, randRarity, payable(msg.sender));
    lips.push(newLip);
    _safeMint(msg.sender, COUNTER);
    emit NewLip(msg.sender, COUNTER, randDna);
    COUNTER++;
  }

  function createRandomLip(string memory _name) public payable {
    require(msg.value >= fee);
    _createLip(_name);
  }

  // Getters
  function getLips() public view returns (Lip[] memory) {
    return lips;
  }

  function getOwnerLips(address _owner) public view returns (Lip[] memory) {
    Lip[] memory result = new Lip[](balanceOf(_owner));
    uint256 counter = 0;
    for (uint256 i = 0; i < lips.length; i++) {
      if (ownerOf(i) == _owner) {
        result[counter] = lips[i];
        counter++;
      }
    }
    return result;
  }

  
}

Ok so:

stakerToTokenIds[staker] is a uint256 array, while lips is a Lip array

1 Like

OK, but

I am looking for a way to get the token ID which is staked by msg.sender using the getTokesnStaked2 function and pass this in the Lip storage lip = lips[]; to extract which token dna, level and rarity the nft which the user has staked has.

If I use the function getTokenStaked2, then it will return the ID number of the token which the msg.sender has staked. I would like to pass this information into Lip storage lip = lips[STAKED_TOKEN_ID_FROM_MSG.SENDER];

Does anybody have an idea of how I manage to do that?