I'm looking into NFT contracts and I am analyzing the infamous CREEPZ INVASION GROUNDS contract.

Viewable at https://etherscan.io/address/0xc3503192343eae4b435e4a1211c5d28bf6f6a696#code

On line 307 of CBCStaking.sol, the function _setTokensValues takes two arrays from memory as arguments, which are used to set the yield value ($loomi token) for a staked NFT. They are uint256[] memory tokenIds, and uint256[] memory tokenTraits.

function _setTokensValues(
      address contractAddress,
      uint256[] memory tokenIds,
      uint256[] memory tokenTraits
    ) internal {
      require(tokenIds.length == tokenTraits.length, "Wrong arrays provided");
      for (uint256 i; i < tokenIds.length; i++) {
        if (tokenTraits[i] != 0 && tokenTraits[i] <= 3000 ether) {
          _tokensMultiplier[contractAddress][tokenIds[i]] = tokenTraits[i];

How was data first input into those arrays? Where are they first defined? tokenTraits[] in particular only exists in CBCStaking.sol as arguments for functions. Outside of that it is not present in any other creepz contracts.

How do they do it? If they are derived from the metadata somehow, where is the function responsible

1 Answer 1


The function inputs are defined by whichever contract function called _setTokensValues. In this case public function:

function deposit(
  address contractAddress,
  uint256[] memory tokenIds,
  uint256[] memory tokenTraits,
  bytes calldata signature
) public

memory is just the standard way we have to always address arrays in functions (technically we could use storage or calldata as well).

The function itself only input the data of tokenTraits into _tokensMultiplier

_tokensMultiplier[contractAddress][tokenIds[i]] = tokenTraits[i];

As for using metadata they would have to use an external interface, the contracts that could be used for this function are as follows:

ARMSNft     = 0x5f4a54e29ccb8a02cdf7d7bfa8a0999a8330cced
BLACKBOXNft = 0x0000000000000000000000000000000000000000
CBCNft      = 0xfe8c6d19365453d26af321d0e8c910428c23873f

BLACKBOXNft in this case has not been defined

  • Yeah, IERC721 or directly via theContract.call(abi.encodewithsignature("functionName(inputs)", arguments))
    – FudgyDRS
    Feb 18, 2022 at 10:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.