S-NFT Cards Upgrade Contract

4 cards with the same level can be craft and upgrade to one card with 1 level higher. For example, 4 level-1 cards can be craft to a 2-level card. A typical level-2 card will have more HC token mining hash rate than 4 level-1 cards combined.

Note1: HC hashrate multiplier will be determined during the upgrade by how many same character cards you used to upgrade. If you use 4 same cards to upgrade, the multiplier will be at maximum.

Note2:If the hashrate of a level-1 card is 1.2, then when you upgrade 4 level-1 cards to get a level-2 card, the level-2 card will have a hashrate of (1.2+1.2+1.2+1.2)*Multiplier.

 function upgrade(uint256[] calldata hnIds) external nonReentrant {
        require(hnIds.length > 0, "HnIds length must > 0");
        require(hnIds.length <= 100, "HnIds length must <= 100");
        require(hnIds.length % 4 == 0, "HnIds length % 4 must == 0");
        uint256 level = hn.level(hnIds[0]);
        require(level < maxLevel, "Hn level must < max Level");
    
    uint256 upgradePrice = getUpgradePrice(hnIds);
    hc.transferFrom(msg.sender, receivingAddress, upgradePrice);

    for (uint256 index = 0; index < hnIds.length; index += 4) {
        uint256 hnId = hnIds[index];
        uint256[] memory materialHnIds = new uint256[](3);
        materialHnIds[0] = hnIds[index + 1];
        materialHnIds[1] = hnIds[index + 2];
        materialHnIds[2] = hnIds[index + 3];

        require(hn.ownerOf(hnId) == msg.sender, "This Hn is not own");
        require(hn.level(hnId) == level, "Hn level mismatch");

        uint256[] memory hashrates = hn.getHashrates(hnId);
        uint256 class = hn.getRandomNumber(hnId, "class", 1, 4);
        uint256 sameClassCount;
        for (uint256 i = 0; i < materialHnIds.length; i++) {
            require(
                hn.level(materialHnIds[i]) == level,
                "Material level mismatch"
            );

            hn.safeTransferFrom(
                msg.sender,
                address(this),
                materialHnIds[i]
            );

            uint256[] memory materialHashrates = hn.getHashrates(
                materialHnIds[i]
            );
            for (uint256 j = 0; j < hashrates.length; j++) {
                hashrates[j] += materialHashrates[j];
            }

            uint256 materialClass = hn.getRandomNumber(
                materialHnIds[i],
                "class",
                1,
                4
            );
            if (class == materialClass) sameClassCount++;
        }

        hn.setLevel(hnId, level + 1);

        for (uint256 i = 0; i < hashrates.length; i++) {
            uint256 randomness = uint256(
                keccak256(
                    abi.encodePacked(
                        msg.sender,
                        block.number,
                        upgradePrice,
                        totalUpgradeCount,
                        userUpgradeCount[msg.sender],
                        hnId,
                        materialHnIds,
                        users.length(),
                        hashrates[i],
                        i
                    )
                )
            );

            if (i == 0 && hashrates[i] == 0) {
                hashrates[i] = hcBase + (randomness % hcRange);
            } else {
                hashrates[i] =
                    (hashrates[i] *
                        (hcBase +
                            ((i == 0 ? level - 1 : level) * hashratesBase) +
                            (sameClassCount * hashratesRange) +
                            (randomness % hashratesRange))) /
                    hcBase;
            }
        }
        hn.setHashrates(hnId, hashrates);

        userUpgradeCount[msg.sender]++;
        totalUpgradeCount++;
    }

    userUpgradeAmount[msg.sender] += upgradePrice;
    totalUpgradeAmount += upgradePrice;
    users.add(msg.sender);

    emit UpgradeHns(msg.sender, hnIds);
}

View full code at: https://github.com/HashlandGamefi/hashland-core/blob/main/contracts/pool/HNUpgrade.sol

Last updated