From 288687b6a074588d50a2d2cab2fd52b67212f0b1 Mon Sep 17 00:00:00 2001 From: ogarciarevett Date: Fri, 25 Oct 2024 10:04:10 +0200 Subject: [PATCH] Test: Fix test names for the adminsoulbound1155 -> accessToken --- constants/constructor-args.ts | 51 +++- constants/contract.ts | 9 +- .../deployments/deployments-g7-testnet.ts | 55 +++- ...inERC1155Soulbound.sol => AccessToken.sol} | 13 +- contracts/soulbounds/Rewards.sol | 267 +++++++++++++---- contracts/soulbounds/RewardsNative.sol | 48 +++- ...estnet.ts => upgradeg7Contract.mainnet.ts} | 26 +- test/Rewards/Rewards.t.sol | 120 ++++++-- test/Rewards/RewardsAddToken.t.sol | 268 ++++++++++++++---- test/Rewards/RewardsBurn.t.sol | 155 ++++++++-- test/Rewards/RewardsClaim.t.sol | 134 +++++++-- test/Rewards/RewardsMint.t.sol | 169 ++++++++--- test/Rewards/RewardsTransfer.t.sol | 163 +++++++++-- test/Rewards/RewardsWithdraw.t.sol | 129 +++++++-- test/hardhatTests/accessToken.test.ts | 201 +++++++++++++ .../adminERC1155Soulbound.test.ts | 211 -------------- test/hardhatTests/rewardsNative.test.ts | 23 +- 17 files changed, 1506 insertions(+), 536 deletions(-) rename contracts/soulbounds/{AdminERC1155Soulbound.sol => AccessToken.sol} (97%) rename deploy/upgrades/game7/{upgradeAvatarBound.testnet.ts => upgradeg7Contract.mainnet.ts} (60%) create mode 100644 test/hardhatTests/accessToken.test.ts delete mode 100644 test/hardhatTests/adminERC1155Soulbound.test.ts diff --git a/constants/constructor-args.ts b/constants/constructor-args.ts index 5351e22..6bf4461 100644 --- a/constants/constructor-args.ts +++ b/constants/constructor-args.ts @@ -285,12 +285,32 @@ export const ERC20DecimalsAgs = { export const RewardsArgs = { MAINNET: { _devWallet: '0x85f56764F58F595D08252b98942554bFB5Eea390', + _managerWallet: 'FAIL', + _minterWallet: 'FAIL', + _rewardTokenAddress: `CONTRACT_${CONTRACT_NAME.RewardAccessTokenG7}`, }, TESTNET: { _devWallet: 'DEPLOYER_WALLET', _managerWallet: 'DEPLOYER_WALLET', _minterWallet: 'DEPLOYER_WALLET', - _rewardTokenAddress: `CONTRACT_${CONTRACT_NAME.RewardToken}`, + _rewardTokenAddress: `CONTRACT_${CONTRACT_NAME.RewardAccessToken}`, + }, +}; + +export const RewardsNativeG7Args = { + MAINNET: { + _devWallet: '0x85f56764F58F595D08252b98942554bFB5Eea390', + _adminWallet: 'FAIL', + _managerWallet: 'FAIL', + _minterWallet: 'FAIL', + _rewardTokenAddress: `CONTRACT_${CONTRACT_NAME.RewardAccessTokenG7}`, + }, + TESTNET: { + _devWallet: 'DEPLOYER_WALLET', + _adminWallet: 'DEPLOYER_WALLET', + _managerWallet: 'DEPLOYER_WALLET', + _minterWallet: 'DEPLOYER_WALLET', + _rewardTokenAddress: `CONTRACT_${CONTRACT_NAME.RewardAccessTokenG7}`, }, }; @@ -305,20 +325,29 @@ export const HelloWorldArgs = { export const RewardTokenArgs = { MAINNET: { - _name: 'RewardToken', - _symbol: 'RT', - _defaultTokenURI: 'FILL_ME', - _contractURI: 'FILL_ME', + _name: 'AccessToken', + _symbol: 'AT', + _defaultTokenURI: 'NO_VALUE', + _contractURI: 'NO_VALUE', + _devWallet: 'DEPLOYER_WALLET', + _rewardAddress: `CONTRACT_${CONTRACT_NAME.Rewards}`, + }, + TESTNET: { + _name: 'AccessToken', + _symbol: 'AT', + _defaultTokenURI: 'NO_VALUE', + _contractURI: 'NO_VALUE', + _devWallet: 'DEPLOYER_WALLET', + _rewardAddress: `CONTRACT_${CONTRACT_NAME.Rewards}`, + }, +}; + +export const AccessTokenG7Args = { + MAINNET: { _devWallet: 'DEPLOYER_WALLET', - _lootDropAddress: `CONTRACT_${CONTRACT_NAME.Rewards}`, }, TESTNET: { - _name: 'RainToken', - _symbol: 'RT', - _defaultTokenURI: 'FILL_ME', - _contractURI: 'FILL_ME', _devWallet: 'DEPLOYER_WALLET', - _lootDropAddress: `CONTRACT_${CONTRACT_NAME.Rewards}`, }, }; diff --git a/constants/contract.ts b/constants/contract.ts index 4a411eb..f9bab3d 100644 --- a/constants/contract.ts +++ b/constants/contract.ts @@ -15,7 +15,7 @@ export enum CONTRACT_TYPE { DETERMINISTIC_FACTORY_CONTRACT = 'DeterministicDeployFactory', Rewards = 'Rewards', HelloWorld = 'HelloWorld', - RewardToken = 'RewardToken', + RewardAccessToken = 'RewardAccessToken', DirectListingExtension = 'DirectListingExtension', Marketplace = 'Marketplace', EnglishAuctionsExtension = 'EnglishAuctionsExtension', @@ -53,7 +53,7 @@ export enum CONTRACT_FILE_NAME { DETERMINISTIC_FACTORY_CONTRACT = 'DeterministicDeployFactory', Rewards = 'Rewards', HelloWorld = 'HelloWorld', - AdminERC1155Soulbound = 'AdminERC1155Soulbound', + AccessToken = 'AccessToken', DirectListingsExtension = 'DirectListingsLogic', ERC20 = 'MockERC20', Marketplace = 'Marketplace', @@ -62,6 +62,7 @@ export enum CONTRACT_FILE_NAME { DirectListingsAddonExtension = 'DirectListingsAddon', Martins = 'Martins', Forwarder = 'Forwarder', + RewardsNative = 'RewardsNative', } export enum CONTRACT_UPGRADABLE_FILE_NAME { @@ -98,7 +99,8 @@ export enum CONTRACT_NAME { DETERMINISTIC_FACTORY_CONTRACT = 'DeterministicDeployFactory', Rewards = 'Rewards', HelloWorld = 'HelloWorld', - RewardToken = 'RewardToken', + RewardAccessToken = 'RewardAccessToken', + RewardAccessTokenG7 = 'RewardAccessTokenG7', DirectListingExtension = 'DirectListingExtension', MartinsToken = 'Martins', Marketplace = 'Marketplace', @@ -109,6 +111,7 @@ export enum CONTRACT_NAME { Staker = 'Staker', MiddlewareStaker = 'MiddlewareStakerG7', Forwarder = 'Forwarder', + RewardsNativeG7 = 'RewardsNativeG7', } export enum CONTRACT_UPGRADABLE_NAME { diff --git a/constants/deployments/deployments-g7-testnet.ts b/constants/deployments/deployments-g7-testnet.ts index 0fce477..406722d 100644 --- a/constants/deployments/deployments-g7-testnet.ts +++ b/constants/deployments/deployments-g7-testnet.ts @@ -1,5 +1,17 @@ -import { AvatarBoundV1Args, ItemBoundArgs, LevelsBoundV1Args } from '@constants/constructor-args'; -import { CONTRACT_TYPE, CONTRACT_UPGRADABLE_NAME, CONTRACT_UPGRADABLE_FILE_NAME } from '@constants/contract'; +import { + AccessTokenG7Args, + AvatarBoundV1Args, + ItemBoundArgs, + LevelsBoundV1Args, + RewardsNativeG7Args, +} from '@constants/constructor-args'; +import { + CONTRACT_TYPE, + CONTRACT_UPGRADABLE_NAME, + CONTRACT_UPGRADABLE_FILE_NAME, + CONTRACT_FILE_NAME, + CONTRACT_NAME, +} from '@constants/contract'; import { TENANT } from '@constants/tenant'; import { DeploymentContract } from '../../types/deployment-type'; @@ -70,4 +82,43 @@ export const G7_TESTNET_CONTRACTS: DeploymentContract[] = [ dependencies: [CONTRACT_UPGRADABLE_NAME.Items, CONTRACT_UPGRADABLE_NAME.Avatars], args: LevelsBoundV1Args.TESTNET, }, + { + contractFileName: CONTRACT_FILE_NAME.AccessToken, + type: CONTRACT_TYPE.RewardAccessToken, + name: CONTRACT_NAME.RewardAccessTokenG7, + chain, + networkType, + tenants: [TENANT.Game7], + verify: true, + upgradable: false, + dependencies: [], + functionCalls: [ + { + contractName: CONTRACT_NAME.RewardAccessTokenG7, + functionName: 'initialize', + args: [ + 'AccessToken', + 'AT', + 'NO_VALUE', + 'NO_VALUE', + 'DEPLOYER_WALLET', + /* this should be the minterContract -> RewardsNativeG7 */ 'MINTER_ROLE', + ], + }, + ], + args: AccessTokenG7Args.TESTNET, + }, + { + contractFileName: CONTRACT_FILE_NAME.RewardsNative, + type: CONTRACT_TYPE.Rewards, + name: CONTRACT_NAME.RewardsNativeG7, + chain, + networkType, + tenants: [TENANT.Game7], + verify: true, + upgradable: false, + dependencies: [CONTRACT_NAME.RewardAccessTokenG7], + functionCalls: [], + args: RewardsNativeG7Args.TESTNET, + }, ]; diff --git a/contracts/soulbounds/AdminERC1155Soulbound.sol b/contracts/soulbounds/AccessToken.sol similarity index 97% rename from contracts/soulbounds/AdminERC1155Soulbound.sol rename to contracts/soulbounds/AccessToken.sol index 4cbefa9..03ea1b5 100644 --- a/contracts/soulbounds/AdminERC1155Soulbound.sol +++ b/contracts/soulbounds/AccessToken.sol @@ -46,7 +46,7 @@ import { LibItems } from "../libraries/LibItems.sol"; error AddressIsZero(); error NotOwnerOrApproved(); -contract AdminERC1155Soulbound is +contract AccessToken is ERC1155Burnable, ERC1155Supply, Summon1155Soulbound, @@ -100,19 +100,18 @@ contract AdminERC1155Soulbound is string memory _defaultTokenURI, string memory _contractURI, address devWallet, - address minter + address minterContract ) external initializer onlyRole(DEFAULT_ADMIN_ROLE) { - if (devWallet == address(0) || minter == address(0)) { + if (devWallet == address(0)) { revert AddressIsZero(); } _grantRole(DEFAULT_ADMIN_ROLE, devWallet); _grantRole(MANAGER_ROLE, devWallet); _grantRole(DEV_CONFIG_ROLE, devWallet); - _grantRole(DEV_CONFIG_ROLE, minter); - _grantRole(MINTER_ROLE, minter); - - _updateWhitelistAddress(minter, true); + _grantRole(MINTER_ROLE, minterContract); + _grantRole(DEV_CONFIG_ROLE, minterContract); + _updateWhitelistAddress(minterContract, true); name = _name; symbol = _symbol; diff --git a/contracts/soulbounds/Rewards.sol b/contracts/soulbounds/Rewards.sol index d10b41d..91935d1 100644 --- a/contracts/soulbounds/Rewards.sol +++ b/contracts/soulbounds/Rewards.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; - - // @author Summon.xyz Team - https://summon.xyz // @contributors: [ @ogarciarevett, @vasinl124] //.................................................................................................................................................... @@ -26,19 +24,35 @@ import { ERC1155 } from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { ERC1155Burnable } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol"; -import { ERC1155Supply } from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; -import { ERC1155Holder } from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; -import { ERC721Holder } from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; -import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol"; +import { + SafeERC20 +} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import { + ERC1155Burnable +} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol"; +import { + ERC1155Supply +} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol"; +import { + ERC1155Holder +} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; +import { + ERC721Holder +} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; +import { + AccessControl +} from "@openzeppelin/contracts/access/AccessControl.sol"; import { Pausable } from "@openzeppelin/contracts/utils/Pausable.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; -import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; - -import { AdminERC1155Soulbound } from "../soulbounds/AdminERC1155Soulbound.sol"; +import { + ReentrancyGuard +} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; +import { + Initializable +} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; + +import { AccessToken } from "../soulbounds/AccessToken.sol"; import { ERCWhitelistSignature } from "../ercs/ERCWhitelistSignature.sol"; import { LibItems } from "../libraries/LibItems.sol"; @@ -70,18 +84,24 @@ contract Rewards is using Strings for uint256; - AdminERC1155Soulbound private rewardTokenContract; + AccessToken private rewardTokenContract; uint256[] public itemIds; mapping(uint256 => bool) private tokenExists; mapping(uint256 => LibItems.RewardToken) public tokenRewards; mapping(uint256 => bool) public isTokenMintPaused; // tokenId => bool - default is false mapping(uint256 => bool) public isClaimRewardPaused; // tokenId => bool - default is false - mapping(uint256 => mapping(uint256 => uint256)) private erc721RewardCurrentIndex; // rewardTokenId => rewardIndex => erc721RewardCurrentIndex + mapping(uint256 => mapping(uint256 => uint256)) + private erc721RewardCurrentIndex; // rewardTokenId => rewardIndex => erc721RewardCurrentIndex mapping(uint256 => uint256) public currentRewardSupply; // rewardTokenId => currentRewardSupply event TokenAdded(uint256 indexed tokenId); - event Minted(address indexed to, uint256 indexed tokenId, uint256 amount, bool soulbound); + event Minted( + address indexed to, + uint256 indexed tokenId, + uint256 amount, + bool soulbound + ); event Claimed(address indexed to, uint256 indexed tokenId, uint256 amount); constructor(address devWallet) { @@ -106,7 +126,7 @@ contract Rewards is revert AddressIsZero(); } - rewardTokenContract = AdminERC1155Soulbound(_rewardTokenAddress); + rewardTokenContract = AccessToken(_rewardTokenAddress); _grantRole(DEFAULT_ADMIN_ROLE, _devWallet); _grantRole(DEV_CONFIG_ROLE, _devWallet); _grantRole(MANAGER_ROLE, _managerWallet); @@ -114,12 +134,14 @@ contract Rewards is _addWhitelistSigner(_devWallet); } - function updateRewardTokenContract(address _rewardTokenAddress) external onlyRole(DEV_CONFIG_ROLE) { + function updateRewardTokenContract( + address _rewardTokenAddress + ) external onlyRole(DEV_CONFIG_ROLE) { if (_rewardTokenAddress == address(0)) { revert AddressIsZero(); } - rewardTokenContract = AdminERC1155Soulbound(_rewardTokenAddress); + rewardTokenContract = AccessToken(_rewardTokenAddress); } function isTokenExist(uint256 _tokenId) public view returns (bool) { @@ -131,15 +153,23 @@ contract Rewards is function decodeData( bytes calldata _data - ) public view onlyRole(DEV_CONFIG_ROLE) returns (address, uint256, uint256[] memory) { + ) + public + view + onlyRole(DEV_CONFIG_ROLE) + returns (address, uint256, uint256[] memory) + { return _decodeData(_data); } - function _decodeData(bytes calldata _data) private pure returns (address, uint256, uint256[] memory) { - (address contractAddress, uint256 chainId, uint256[] memory _itemIds) = abi.decode( - _data, - (address, uint256, uint256[]) - ); + function _decodeData( + bytes calldata _data + ) private pure returns (address, uint256, uint256[] memory) { + ( + address contractAddress, + uint256 chainId, + uint256[] memory _itemIds + ) = abi.decode(_data, (address, uint256, uint256[])); return (contractAddress, chainId, _itemIds); } @@ -151,12 +181,18 @@ contract Rewards is _unpause(); } - function _validateTokenInputs(LibItems.RewardToken calldata _token) private view { + function _validateTokenInputs( + LibItems.RewardToken calldata _token + ) private view { if (_token.maxSupply == 0) { revert InvalidAmount(); } - if (bytes(_token.tokenUri).length == 0 || _token.rewards.length == 0 || _token.tokenId == 0) { + if ( + bytes(_token.tokenUri).length == 0 || + _token.rewards.length == 0 || + _token.tokenId == 0 + ) { revert InvalidInput(); } @@ -175,19 +211,25 @@ contract Rewards is if (reward.rewardType == LibItems.RewardType.ERC721) { if ( reward.rewardTokenIds.length == 0 || - reward.rewardTokenIds.length != reward.rewardAmount * _token.maxSupply + reward.rewardTokenIds.length != + reward.rewardAmount * _token.maxSupply ) { revert InvalidInput(); } } - if (reward.rewardType != LibItems.RewardType.ERC721 && reward.rewardAmount == 0) { + if ( + reward.rewardType != LibItems.RewardType.ERC721 && + reward.rewardAmount == 0 + ) { revert InvalidAmount(); } } } - function _calculateETHRequiredForToken(LibItems.RewardToken calldata _token) private pure returns (uint256) { + function _calculateETHRequiredForToken( + LibItems.RewardToken calldata _token + ) private pure returns (uint256) { uint256 totalETHRequired; for (uint256 i = 0; i < _token.rewards.length; i++) { LibItems.Reward memory reward = _token.rewards[i]; @@ -198,7 +240,9 @@ contract Rewards is return totalETHRequired * _token.maxSupply; } - function _createTokenAndDepositRewards(LibItems.RewardToken calldata _token) private { + function _createTokenAndDepositRewards( + LibItems.RewardToken calldata _token + ) private { // have to approve all the assets first // Validate token inputs _validateTokenInputs(_token); @@ -215,22 +259,40 @@ contract Rewards is LibItems.Reward memory reward = _token.rewards[i]; if (reward.rewardType == LibItems.RewardType.ERC20) { IERC20 token = IERC20(reward.rewardTokenAddress); - SafeERC20.safeTransferFrom(token, _from, _to, reward.rewardAmount * _token.maxSupply); + SafeERC20.safeTransferFrom( + token, + _from, + _to, + reward.rewardAmount * _token.maxSupply + ); } else if (reward.rewardType == LibItems.RewardType.ERC721) { IERC721 token = IERC721(reward.rewardTokenAddress); for (uint256 j = 0; j < reward.rewardTokenIds.length; j++) { - _transferERC721(token, _from, _to, reward.rewardTokenIds[j]); + _transferERC721( + token, + _from, + _to, + reward.rewardTokenIds[j] + ); } } else if (reward.rewardType == LibItems.RewardType.ERC1155) { IERC1155 token = IERC1155(reward.rewardTokenAddress); - _transferERC1155(token, _from, _to, reward.rewardTokenId, reward.rewardAmount * _token.maxSupply); + _transferERC1155( + token, + _from, + _to, + reward.rewardTokenId, + reward.rewardAmount * _token.maxSupply + ); } } emit TokenAdded(_token.tokenId); } - function createTokenAndDepositRewards(LibItems.RewardToken calldata _token) public payable onlyRole(MANAGER_ROLE) { + function createTokenAndDepositRewards( + LibItems.RewardToken calldata _token + ) public payable onlyRole(MANAGER_ROLE) { uint256 _ethRequired = _calculateETHRequiredForToken(_token); if (msg.value < _ethRequired) { @@ -261,11 +323,17 @@ contract Rewards is } } - function updateTokenMintPaused(uint256 _tokenId, bool _isTokenMintPaused) public onlyRole(MANAGER_ROLE) { + function updateTokenMintPaused( + uint256 _tokenId, + bool _isTokenMintPaused + ) public onlyRole(MANAGER_ROLE) { isTokenMintPaused[_tokenId] = _isTokenMintPaused; } - function updateClaimRewardPaused(uint256 _tokenId, bool _isClaimRewardPaused) public onlyRole(MANAGER_ROLE) { + function updateClaimRewardPaused( + uint256 _tokenId, + bool _isClaimRewardPaused + ) public onlyRole(MANAGER_ROLE) { isClaimRewardPaused[_tokenId] = _isClaimRewardPaused; } @@ -304,7 +372,13 @@ contract Rewards is revert InvalidLength(); } for (uint256 i = 0; i < _tokenIds.length; i++) { - _transferERC1155(IERC1155(_tokenAddress), _from, _to, _tokenIds[i], _amounts[i]); + _transferERC1155( + IERC1155(_tokenAddress), + _from, + _to, + _tokenIds[i], + _amounts[i] + ); } } } @@ -320,7 +394,11 @@ contract Rewards is } } - function _transferERC20(IERC20 _token, address _to, uint256 _amount) private { + function _transferERC20( + IERC20 _token, + address _to, + uint256 _amount + ) private { uint256 balanceInContract = _token.balanceOf(address(this)); if (balanceInContract < _amount) { revert InsufficientBalance(); @@ -329,11 +407,22 @@ contract Rewards is SafeERC20.safeTransfer(_token, _to, _amount); } - function _transferERC721(IERC721 _token, address _from, address _to, uint256 _tokenId) private { + function _transferERC721( + IERC721 _token, + address _from, + address _to, + uint256 _tokenId + ) private { _token.safeTransferFrom(_from, _to, _tokenId); } - function _transferERC1155(IERC1155 _token, address _from, address _to, uint256 _tokenId, uint256 _amount) private { + function _transferERC1155( + IERC1155 _token, + address _from, + address _to, + uint256 _tokenId, + uint256 _amount + ) private { _token.safeTransferFrom(_from, _to, _tokenId, _amount, ""); } @@ -341,13 +430,18 @@ contract Rewards is _claimReward(_msgSender(), _tokenId); } - function claimRewards(uint256[] calldata _tokenIds) external nonReentrant whenNotPaused { + function claimRewards( + uint256[] calldata _tokenIds + ) external nonReentrant whenNotPaused { for (uint256 i = 0; i < _tokenIds.length; i++) { _claimReward(_msgSender(), _tokenIds[i]); } } - function adminClaimReward(address _to, uint256[] calldata _tokenIds) external onlyRole(MANAGER_ROLE) whenNotPaused { + function adminClaimReward( + address _to, + uint256[] calldata _tokenIds + ) external onlyRole(MANAGER_ROLE) whenNotPaused { for (uint256 i = 0; i < _tokenIds.length; i++) { _claimReward(_to, _tokenIds[i]); } @@ -384,18 +478,30 @@ contract Rewards is if (reward.rewardType == LibItems.RewardType.ETHER) { _transferEther(payable(_to), reward.rewardAmount); } else if (reward.rewardType == LibItems.RewardType.ERC20) { - _transferERC20(IERC20(reward.rewardTokenAddress), _to, reward.rewardAmount); + _transferERC20( + IERC20(reward.rewardTokenAddress), + _to, + reward.rewardAmount + ); } else if (reward.rewardType == LibItems.RewardType.ERC721) { - uint256 currentIndex = erc721RewardCurrentIndex[_rewardTokenId][i]; + uint256 currentIndex = erc721RewardCurrentIndex[_rewardTokenId][ + i + ]; uint256[] memory tokenIds = reward.rewardTokenIds; for (uint256 j = 0; j < reward.rewardAmount; j++) { if (currentIndex >= tokenIds.length) { revert InsufficientBalance(); } - _transferERC721(IERC721(reward.rewardTokenAddress), _from, _to, tokenIds[currentIndex + j]); + _transferERC721( + IERC721(reward.rewardTokenAddress), + _from, + _to, + tokenIds[currentIndex + j] + ); } - erc721RewardCurrentIndex[_rewardTokenId][i] += reward.rewardAmount; + erc721RewardCurrentIndex[_rewardTokenId][i] += reward + .rewardAmount; } else if (reward.rewardType == LibItems.RewardType.ERC1155) { _transferERC1155( IERC1155(reward.rewardTokenAddress), @@ -418,7 +524,13 @@ contract Rewards is bool isClaimReward ) private { for (uint256 i = 0; i < _tokenIds.length; i++) { - _mintAndClaimRewardToken(to, _tokenIds[i], _amount, soulbound, isClaimReward); + _mintAndClaimRewardToken( + to, + _tokenIds[i], + _amount, + soulbound, + isClaimReward + ); } } @@ -464,9 +576,15 @@ contract Rewards is } } - function _verifyContractChainIdAndDecode(bytes calldata data) private view returns (uint256[] memory) { + function _verifyContractChainIdAndDecode( + bytes calldata data + ) private view returns (uint256[] memory) { uint256 currentChainId = getChainID(); - (address contractAddress, uint256 chainId, uint256[] memory tokenIds) = _decodeData(data); + ( + address contractAddress, + uint256 chainId, + uint256[] memory tokenIds + ) = _decodeData(data); if (chainId != currentChainId || contractAddress != address(this)) { revert InvalidInput(); @@ -514,9 +632,20 @@ contract Rewards is uint256 nonce, bytes calldata signature, bool isClaimReward - ) external nonReentrant signatureCheck(_msgSender(), nonce, data, signature) whenNotPaused { + ) + external + nonReentrant + signatureCheck(_msgSender(), nonce, data, signature) + whenNotPaused + { uint256[] memory _tokenIds = _verifyContractChainIdAndDecode(data); - _mintAndClaimRewardTokenBatch(_msgSender(), _tokenIds, 1, isSoulbound, isClaimReward); + _mintAndClaimRewardTokenBatch( + _msgSender(), + _tokenIds, + 1, + isSoulbound, + isClaimReward + ); } function adminMint( @@ -526,7 +655,13 @@ contract Rewards is bool isClaimReward ) external onlyRole(MINTER_ROLE) whenNotPaused { uint256[] memory _tokenIds = _verifyContractChainIdAndDecode(data); - _mintAndClaimRewardTokenBatch(to, _tokenIds, 1, isSoulbound, isClaimReward); + _mintAndClaimRewardTokenBatch( + to, + _tokenIds, + 1, + isSoulbound, + isClaimReward + ); } function adminMintById( @@ -535,7 +670,13 @@ contract Rewards is uint256 _amount, bool isSoulbound ) public onlyRole(MINTER_ROLE) whenNotPaused { - _mintAndClaimRewardToken(toAddress, _tokenId, _amount, isSoulbound, false); + _mintAndClaimRewardToken( + toAddress, + _tokenId, + _amount, + isSoulbound, + false + ); } function adminBatchMintById( @@ -549,11 +690,19 @@ contract Rewards is } for (uint256 i = 0; i < toAddresses.length; i++) { - _mintAndClaimRewardToken(toAddresses[i], _tokenId, _amounts[i], isSoulbound, false); + _mintAndClaimRewardToken( + toAddresses[i], + _tokenId, + _amounts[i], + isSoulbound, + false + ); } } - function supportsInterface(bytes4 interfaceId) public view override(AccessControl, ERC1155Holder) returns (bool) { + function supportsInterface( + bytes4 interfaceId + ) public view override(AccessControl, ERC1155Holder) returns (bool) { return super.supportsInterface(interfaceId); } @@ -572,11 +721,15 @@ contract Rewards is return _verifySignature(to, nonce, data, signature); } - function addWhitelistSigner(address _signer) external onlyRole(DEV_CONFIG_ROLE) { + function addWhitelistSigner( + address _signer + ) external onlyRole(DEV_CONFIG_ROLE) { _addWhitelistSigner(_signer); } - function removeWhitelistSigner(address signer) external onlyRole(DEV_CONFIG_ROLE) { + function removeWhitelistSigner( + address signer + ) external onlyRole(DEV_CONFIG_ROLE) { _removeWhitelistSigner(signer); } diff --git a/contracts/soulbounds/RewardsNative.sol b/contracts/soulbounds/RewardsNative.sol index 84d5169..42d6307 100644 --- a/contracts/soulbounds/RewardsNative.sol +++ b/contracts/soulbounds/RewardsNative.sol @@ -33,7 +33,7 @@ import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; -import { AdminERC1155Soulbound } from "../soulbounds/AdminERC1155Soulbound.sol"; +import { AccessToken } from "../soulbounds/AccessToken.sol"; import { ERCWhitelistSignature } from "../ercs/ERCWhitelistSignature.sol"; import { LibRewards } from "../libraries/LibRewards.sol"; @@ -51,7 +51,7 @@ contract RewardsNative is bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); bytes32 public constant DEV_CONFIG_ROLE = keccak256("DEV_CONFIG_ROLE"); - AdminERC1155Soulbound private rewardTokenContract; + AccessToken public rewardTokenContract; uint256[] public itemIds; mapping(uint256 => bool) private tokenExists; @@ -108,7 +108,7 @@ contract RewardsNative is revert AddressIsZero(); } - rewardTokenContract = AdminERC1155Soulbound(_rewardTokenAddress); + rewardTokenContract = AccessToken(_rewardTokenAddress); _grantRole(DEV_CONFIG_ROLE, _devWallet); _grantRole(DEFAULT_ADMIN_ROLE, _adminWallet); _grantRole(MANAGER_ROLE, _managerWallet); @@ -126,7 +126,7 @@ contract RewardsNative is revert AddressIsZero(); } - rewardTokenContract = AdminERC1155Soulbound(_rewardTokenAddress); + rewardTokenContract = AccessToken(_rewardTokenAddress); } function isTokenExist(uint256 _tokenId) public view returns (bool) { @@ -149,16 +149,52 @@ contract RewardsNative is function _dangerous_createTokenAndDepositRewards( LibRewards.RewardToken calldata _token - ) public payable onlyRole(DEV_CONFIG_ROLE) { + ) public onlyRole(DEV_CONFIG_ROLE) { _createTokenAndDepositRewards(_token); } function _dangerous_createMultipleTokensAndDepositRewards( LibRewards.RewardToken[] calldata _tokens - ) external payable onlyRole(DEV_CONFIG_ROLE) { + ) external onlyRole(DEV_CONFIG_ROLE) { + // Create tokens and deposit rewards + for (uint256 i = 0; i < _tokens.length; i++) { + _createTokenAndDepositRewards(_tokens[i]); + } + } + + function createTokenAndMintRewards( + LibRewards.RewardToken calldata _token, + address _to, + uint256 _amount, + bool _isSoulbound + ) public onlyRole(MINTER_ROLE) { + _createTokenAndDepositRewards(_token); + _mintRewardAccessToken(_to, _token.tokenId, _amount, _isSoulbound); + } + + function createMultipleTokensAndMintRewards( + LibRewards.RewardToken[] calldata _tokens, + address[] calldata users, + uint256[] calldata amounts, + bool[] calldata soulbounds + ) external onlyRole(MINTER_ROLE) { + if ( + users.length != amounts.length || + users.length != soulbounds.length || + amounts.length != soulbounds.length || + users.length != _tokens.length + ) { + revert InvalidLength(); + } // Create tokens and deposit rewards for (uint256 i = 0; i < _tokens.length; i++) { _createTokenAndDepositRewards(_tokens[i]); + _mintRewardAccessToken( + users[i], + _tokens[i].tokenId, + amounts[i], + soulbounds[i] + ); } } diff --git a/deploy/upgrades/game7/upgradeAvatarBound.testnet.ts b/deploy/upgrades/game7/upgradeg7Contract.mainnet.ts similarity index 60% rename from deploy/upgrades/game7/upgradeAvatarBound.testnet.ts rename to deploy/upgrades/game7/upgradeg7Contract.mainnet.ts index 28da832..48fde88 100644 --- a/deploy/upgrades/game7/upgradeAvatarBound.testnet.ts +++ b/deploy/upgrades/game7/upgradeg7Contract.mainnet.ts @@ -5,7 +5,7 @@ import { ethers, upgrades } from 'hardhat'; const PRIVATE_KEY = process.env.PRIVATE_KEY || ''; -const PROXY_ADDRESS = '0x76E45aBc1139C913b43DBB09e99d3650a06e7F22'; +const PROXY_ADDRESS = '0x84865664f4307160caB290a7606a26Ef94C1cad7'; if (!PRIVATE_KEY) throw '⛔️ Private key not detected! Add it to the .env file!'; @@ -19,18 +19,18 @@ async function main() { log(`upgraded to => NewContract -> ${VERSION}`); - // await new Promise((resolve, reject) => { - // exec( - // `npx hardhat verify --network ${hre.network.name} ${PROXY_ADDRESS} --config g7.config.ts`, - // (error, stdout, stderr) => { - // if (error) { - // console.warn(error); - // reject(error); - // } - // resolve(stdout ? stdout : stderr); - // } - // ); - // }); + await new Promise((resolve, reject) => { + exec( + `npx hardhat verify --network ${hre.network.name} ${PROXY_ADDRESS} --config g7.config.ts`, + (error, stdout, stderr) => { + if (error) { + console.warn(error); + reject(error); + } + resolve(stdout ? stdout : stderr); + } + ); + }); } main().catch((error) => { diff --git a/test/Rewards/Rewards.t.sol b/test/Rewards/Rewards.t.sol index ee56105..01a251e 100644 --- a/test/Rewards/Rewards.t.sol +++ b/test/Rewards/Rewards.t.sol @@ -7,13 +7,21 @@ import "forge-std/console.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; -import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; +import { + MessageHashUtils +} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import { + IAccessControl +} from "@openzeppelin/contracts/access/IAccessControl.sol"; import { Pausable } from "@openzeppelin/contracts/utils/Pausable.sol"; -import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; -import {Rewards} from "../../contracts/soulbounds/Rewards.sol"; -import { AdminERC1155Soulbound } from "../../contracts/soulbounds/AdminERC1155Soulbound.sol"; -import { MockERC1155Receiver } from "../../contracts/mocks/MockERC1155Receiver.sol"; +import { + Initializable +} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; +import { Rewards } from "../../contracts/soulbounds/Rewards.sol"; +import { AccessToken } from "../../contracts/soulbounds/AccessToken.sol"; +import { + MockERC1155Receiver +} from "../../contracts/mocks/MockERC1155Receiver.sol"; import { MockERC20 } from "../../contracts/mocks/MockErc20.sol"; import { MockERC721 } from "../../contracts/mocks/MockErc721.sol"; import { MockERC1155 } from "../../contracts/mocks/MockErc1155.sol"; @@ -34,7 +42,7 @@ contract RewardsTest is StdCheats, Test { using Strings for uint256; Rewards public rewards; - AdminERC1155Soulbound public itemBound; + AccessToken public itemBound; MockERC1155Receiver public mockERC1155Receiver; MockERC20 public mockERC20; MockERC721 public mockERC721; @@ -82,7 +90,9 @@ contract RewardsTest is StdCheats, Test { bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); bytes32 public constant DEV_CONFIG_ROLE = keccak256("DEV_CONFIG_ROLE"); - function getWallet(string memory walletLabel) public returns (Wallet memory) { + function getWallet( + string memory walletLabel + ) public returns (Wallet memory) { (address addr, uint256 privateKey) = makeAddrAndKey(walletLabel); Wallet memory wallet = Wallet(addr, privateKey); return wallet; @@ -95,26 +105,46 @@ contract RewardsTest is StdCheats, Test { ) public returns (uint256, bytes memory) { Wallet memory signerWallet = getWallet(signerLabel); - uint256 _nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, signerWallet.addr))) % - 50; + uint256 _nonce = uint256( + keccak256( + abi.encodePacked( + block.timestamp, + block.prevrandao, + signerWallet.addr + ) + ) + ) % 50; - bytes32 message = keccak256(abi.encodePacked(wallet, encodedItems, _nonce)); + bytes32 message = keccak256( + abi.encodePacked(wallet, encodedItems, _nonce) + ); bytes32 hash = MessageHashUtils.toEthSignedMessageHash(message); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerWallet.privateKey, hash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + signerWallet.privateKey, + hash + ); return (_nonce, abi.encodePacked(r, s, v)); } - function concatenateStrings(string memory a, string memory b) internal pure returns (string memory) { + function concatenateStrings( + string memory a, + string memory b + ) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } function generateRandomItemId() internal returns (uint256) { - _seed = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), _seed))); + _seed = uint256( + keccak256(abi.encodePacked(blockhash(block.number - 1), _seed)) + ); return _seed; } - function encode(address contractAddress, uint256[] memory itemIds) public view returns (bytes memory) { + function encode( + address contractAddress, + uint256[] memory itemIds + ) public view returns (bytes memory) { return (abi.encode(contractAddress, chainId, itemIds)); } @@ -126,7 +156,12 @@ contract RewardsTest is StdCheats, Test { itemBound = new AdminERC1155Soulbound(address(this)); rewards = new Rewards(address(this)); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); itemBound.initialize( "Test1155", @@ -172,7 +207,13 @@ contract RewardsTest is StdCheats, Test { LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 1 }); @@ -195,8 +236,16 @@ contract RewardsTest is StdCheats, Test { encodedItems2 = encode(address(rewards), _itemIds2); - (nonce, signature) = generateSignature(playerWallet.addr, encodedItems1, minterLabel); - (nonce2, signature2) = generateSignature(playerWallet2.addr, encodedItems2, minterLabel); + (nonce, signature) = generateSignature( + playerWallet.addr, + encodedItems1, + minterLabel + ); + (nonce2, signature2) = generateSignature( + playerWallet2.addr, + encodedItems2, + minterLabel + ); mockERC20.mint(address(this), 20000000000000000000); for (uint256 i = 0; i < 10; i++) { @@ -209,9 +258,16 @@ contract RewardsTest is StdCheats, Test { } function testInitializeTwiceShouldFail() public { - vm.expectRevert(abi.encodeWithSelector(Initializable.InvalidInitialization.selector)); + vm.expectRevert( + abi.encodeWithSelector(Initializable.InvalidInitialization.selector) + ); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); } function testPauseUnpause() public { @@ -226,12 +282,17 @@ contract RewardsTest is StdCheats, Test { _amounts[1] = 2; rewards.pause(); - vm.expectRevert(abi.encodeWithSelector(Pausable.EnforcedPause.selector)); + vm.expectRevert( + abi.encodeWithSelector(Pausable.EnforcedPause.selector) + ); rewards.adminBatchMintById(_wallets, _tokenId, _amounts, true); rewards.unpause(); rewards.adminMintById(address(mockERC1155Receiver), _tokenId, 1, true); - assertEq(itemBound.balanceOf(address(mockERC1155Receiver), _tokenId), 1); + assertEq( + itemBound.balanceOf(address(mockERC1155Receiver), _tokenId), + 1 + ); } function testPauseUnpauseSpecificToken() public { @@ -243,7 +304,12 @@ contract RewardsTest is StdCheats, Test { rewards.adminMintById(address(mockERC1155Receiver), _tokenId, 1, true); vm.expectRevert(MintPaused.selector); - rewards.adminMint(address(mockERC1155Receiver), encodedItems1, true, false); + rewards.adminMint( + address(mockERC1155Receiver), + encodedItems1, + true, + false + ); vm.expectRevert(MintPaused.selector); vm.prank(playerWallet.addr); @@ -260,7 +326,11 @@ contract RewardsTest is StdCheats, Test { function testDecodeDataShouldPass() public { bytes memory encodedItems = encode(address(rewards), _tokenIds); - (address contractAddress, uint256 chainId, uint256[] memory ids) = rewards.decodeData(encodedItems); + ( + address contractAddress, + uint256 chainId, + uint256[] memory ids + ) = rewards.decodeData(encodedItems); for (uint256 i = 0; i < ids.length; i++) { assertEq(ids[i], _tokenIds[i]); diff --git a/test/Rewards/RewardsAddToken.t.sol b/test/Rewards/RewardsAddToken.t.sol index 4ab01c7..d26e07f 100644 --- a/test/Rewards/RewardsAddToken.t.sol +++ b/test/Rewards/RewardsAddToken.t.sol @@ -7,14 +7,26 @@ import "forge-std/console.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; -import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; -import { IERC20Errors, IERC721Errors, IERC1155Errors } from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; -import { ERC721Holder } from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; - -import {Rewards} from "../../contracts/soulbounds/Rewards.sol"; -import { AdminERC1155Soulbound } from "../../contracts/soulbounds/AdminERC1155Soulbound.sol"; -import { MockERC1155Receiver } from "../../contracts/mocks/MockERC1155Receiver.sol"; +import { + MessageHashUtils +} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import { + IAccessControl +} from "@openzeppelin/contracts/access/IAccessControl.sol"; +import { + IERC20Errors, + IERC721Errors, + IERC1155Errors +} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; +import { + ERC721Holder +} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +import { Rewards } from "../../contracts/soulbounds/Rewards.sol"; +import { AccessToken } from "../../contracts/soulbounds/AccessToken.sol"; +import { + MockERC1155Receiver +} from "../../contracts/mocks/MockERC1155Receiver.sol"; import { MockERC20 } from "../../contracts/mocks/MockErc20.sol"; import { MockERC721 } from "../../contracts/mocks/MockErc721.sol"; import { MockERC1155 } from "../../contracts/mocks/MockErc1155.sol"; @@ -33,11 +45,16 @@ error MintPaused(); error ClaimRewardPaused(); error DupTokenId(); -contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { +contract RewardsAddTokenTest is + StdCheats, + Test, + MockERC1155Receiver, + ERC721Holder +{ using Strings for uint256; Rewards public rewards; - AdminERC1155Soulbound public itemBound; + AccessToken public itemBound; MockERC1155Receiver public mockERC1155Receiver; MockERC20 public mockERC20; MockERC721 public mockERC721; @@ -85,7 +102,9 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); bytes32 public constant DEV_CONFIG_ROLE = keccak256("DEV_CONFIG_ROLE"); - function getWallet(string memory walletLabel) public returns (Wallet memory) { + function getWallet( + string memory walletLabel + ) public returns (Wallet memory) { (address addr, uint256 privateKey) = makeAddrAndKey(walletLabel); Wallet memory wallet = Wallet(addr, privateKey); return wallet; @@ -98,26 +117,46 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold ) public returns (uint256, bytes memory) { Wallet memory signerWallet = getWallet(signerLabel); - uint256 _nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, signerWallet.addr))) % - 50; + uint256 _nonce = uint256( + keccak256( + abi.encodePacked( + block.timestamp, + block.prevrandao, + signerWallet.addr + ) + ) + ) % 50; - bytes32 message = keccak256(abi.encodePacked(wallet, encodedItems, _nonce)); + bytes32 message = keccak256( + abi.encodePacked(wallet, encodedItems, _nonce) + ); bytes32 hash = MessageHashUtils.toEthSignedMessageHash(message); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerWallet.privateKey, hash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + signerWallet.privateKey, + hash + ); return (_nonce, abi.encodePacked(r, s, v)); } - function concatenateStrings(string memory a, string memory b) internal pure returns (string memory) { + function concatenateStrings( + string memory a, + string memory b + ) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } function generateRandomItemId() internal returns (uint256) { - _seed = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), _seed))); + _seed = uint256( + keccak256(abi.encodePacked(blockhash(block.number - 1), _seed)) + ); return _seed; } - function encode(address contractAddress, uint256[] memory itemIds) public view returns (bytes memory) { + function encode( + address contractAddress, + uint256[] memory itemIds + ) public view returns (bytes memory) { return (abi.encode(contractAddress, chainId, itemIds)); } @@ -129,7 +168,12 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold itemBound = new AdminERC1155Soulbound(address(this)); rewards = new Rewards(address(this)); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); itemBound.initialize( "Test1155", @@ -175,7 +219,13 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 1 }); @@ -198,8 +248,16 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold encodedItems2 = encode(address(rewards), _itemIds2); - (nonce, signature) = generateSignature(playerWallet.addr, encodedItems1, minterLabel); - (nonce2, signature2) = generateSignature(playerWallet2.addr, encodedItems2, minterLabel); + (nonce, signature) = generateSignature( + playerWallet.addr, + encodedItems1, + minterLabel + ); + (nonce2, signature2) = generateSignature( + playerWallet2.addr, + encodedItems2, + minterLabel + ); mockERC20.mint(address(this), 20000000000000000000); for (uint256 i = 0; i < 10; i++) { @@ -242,7 +300,13 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 1 }); @@ -312,14 +376,22 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 3 }); _tokens[i] = _token; } - rewards.createMultipleTokensAndDepositRewards{ value: 600000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 600000000000000000 + }(_tokens); uint256 _tokenId = _tokens[0].tokenId; assertEq(rewards.isTokenExist(_tokenId), true); @@ -334,13 +406,25 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256[] memory rewardTokenId ) = rewards.getTokenDetails(_tokenId); - assertEq(tokenUri, string(abi.encodePacked("https://something.com", "/", _tokenId.toString()))); + assertEq( + tokenUri, + string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ) + ); assertEq(maxSupply, 3); for (uint256 i = 0; i < rewardTypes.length; i++) { if (i == 0) { // ETHER - assertEq(uint256(rewardTypes[i]), uint256(LibItems.RewardType.ETHER)); + assertEq( + uint256(rewardTypes[i]), + uint256(LibItems.RewardType.ETHER) + ); assertEq(rewardAmounts[i], 100000000000000000); assertEq(rewardTokenAddresses[i], address(0)); assertEq(rewardTokenId[i], 0); @@ -349,7 +433,10 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold if (i == 1) { // ERC20 - assertEq(uint256(rewardTypes[i]), uint256(LibItems.RewardType.ERC20)); + assertEq( + uint256(rewardTypes[i]), + uint256(LibItems.RewardType.ERC20) + ); assertEq(rewardAmounts[i], 2000); assertEq(rewardTokenAddresses[i], erc20FakeRewardAddress); assertEq(rewardTokenId[i], 0); @@ -358,7 +445,10 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold if (i == 2) { // ERC721 - assertEq(uint256(rewardTypes[i]), uint256(LibItems.RewardType.ERC721)); + assertEq( + uint256(rewardTypes[i]), + uint256(LibItems.RewardType.ERC721) + ); assertEq(rewardAmounts[i], 1); assertEq(rewardTokenAddresses[i], erc721FakeRewardAddress); assertEq(rewardTokenId[i], 0); @@ -371,7 +461,10 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold if (i == 3) { // ERC1155 - assertEq(uint256(rewardTypes[i]), uint256(LibItems.RewardType.ERC1155)); + assertEq( + uint256(rewardTypes[i]), + uint256(LibItems.RewardType.ERC1155) + ); assertEq(rewardAmounts[i], 2); assertEq(rewardTokenAddresses[i], erc1155FakeRewardAddress); assertEq(rewardTokenId[i], 456); @@ -399,7 +492,13 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 1 }); @@ -471,7 +570,13 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 1 }); @@ -480,7 +585,9 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold } vm.expectRevert(InsufficientBalance.selector); - rewards.createMultipleTokensAndDepositRewards{ value: 299999999999999999 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 299999999999999999 + }(_tokens); } // should fail not enough ERC20 function testAddNewTokensNotEnoughERC20ShouldFail() public { @@ -534,7 +641,13 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 1 }); @@ -550,7 +663,9 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold ) ); - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); assertEq(mockERC20.balanceOf(address(rewards)), 4000000); } // should fail not enough ERC721 @@ -607,15 +722,28 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 3 }); _tokens[i] = _token; } - vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, 10)); - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + vm.expectRevert( + abi.encodeWithSelector( + IERC721Errors.ERC721NonexistentToken.selector, + 10 + ) + ); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); } // should fail not enough ERC1155 @@ -672,7 +800,13 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 3 }); @@ -680,10 +814,18 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold } vm.expectRevert( - abi.encodeWithSelector(IERC1155Errors.ERC1155InsufficientBalance.selector, address(this), 12, 33, 456) + abi.encodeWithSelector( + IERC1155Errors.ERC1155InsufficientBalance.selector, + address(this), + 12, + 33, + 456 + ) ); - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); } function testAddNtestAddNewTokensDontOwnedERC1155ShouldFail() public { @@ -739,7 +881,13 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 3 }); @@ -747,9 +895,17 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold } vm.expectRevert( - abi.encodeWithSelector(IERC1155Errors.ERC1155InsufficientBalance.selector, address(this), 0, 3, 555) + abi.encodeWithSelector( + IERC1155Errors.ERC1155InsufficientBalance.selector, + address(this), + 0, + 3, + 555 + ) ); - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); } function testAddNewTokensShouldPass() public { @@ -805,14 +961,22 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 3 }); _tokens[i] = _token; } - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); assertEq(address(rewards).balance, 300000000000000000); assertEq(mockERC20.balanceOf(address(rewards)), 4006000); @@ -878,14 +1042,22 @@ contract RewardsAddTokenTest is StdCheats, Test, MockERC1155Receiver, ERC721Hold uint256 _tokenId = generateRandomItemId(); // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 3 }); _tokens[i] = _token; } - rewards.createMultipleTokensAndDepositRewards{ value: 600000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 600000000000000000 + }(_tokens); assertEq(address(rewards).balance, 600000000000000000); assertEq(mockERC20.balanceOf(address(rewards)), 4012000); diff --git a/test/Rewards/RewardsBurn.t.sol b/test/Rewards/RewardsBurn.t.sol index ac7c4e0..926a67a 100644 --- a/test/Rewards/RewardsBurn.t.sol +++ b/test/Rewards/RewardsBurn.t.sol @@ -7,11 +7,17 @@ import "forge-std/console.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; -import { IERC1155Errors } from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; -import {Rewards} from "../../contracts/soulbounds/Rewards.sol"; -import { AdminERC1155Soulbound } from "../../contracts/soulbounds/AdminERC1155Soulbound.sol"; -import { MockERC1155Receiver } from "../../contracts/mocks/MockERC1155Receiver.sol"; +import { + MessageHashUtils +} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import { + IERC1155Errors +} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; +import { Rewards } from "../../contracts/soulbounds/Rewards.sol"; +import { AccessToken } from "../../contracts/soulbounds/AccessToken.sol"; +import { + MockERC1155Receiver +} from "../../contracts/mocks/MockERC1155Receiver.sol"; import { MockERC20 } from "../../contracts/mocks/MockErc20.sol"; import { MockERC721 } from "../../contracts/mocks/MockErc721.sol"; import { MockERC1155 } from "../../contracts/mocks/MockErc1155.sol"; @@ -32,7 +38,7 @@ contract RewardsBurnTest is StdCheats, Test { using Strings for uint256; Rewards public rewards; - AdminERC1155Soulbound public itemBound; + AccessToken public itemBound; MockERC1155Receiver public mockERC1155Receiver; MockERC20 public mockERC20; MockERC721 public mockERC721; @@ -77,7 +83,9 @@ contract RewardsBurnTest is StdCheats, Test { uint256 public chainId = 31337; - function getWallet(string memory walletLabel) public returns (Wallet memory) { + function getWallet( + string memory walletLabel + ) public returns (Wallet memory) { (address addr, uint256 privateKey) = makeAddrAndKey(walletLabel); Wallet memory wallet = Wallet(addr, privateKey); return wallet; @@ -90,26 +98,46 @@ contract RewardsBurnTest is StdCheats, Test { ) public returns (uint256, bytes memory) { Wallet memory signerWallet = getWallet(signerLabel); - uint256 _nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, signerWallet.addr))) % - 50; + uint256 _nonce = uint256( + keccak256( + abi.encodePacked( + block.timestamp, + block.prevrandao, + signerWallet.addr + ) + ) + ) % 50; - bytes32 message = keccak256(abi.encodePacked(wallet, encodedItems, _nonce)); + bytes32 message = keccak256( + abi.encodePacked(wallet, encodedItems, _nonce) + ); bytes32 hash = MessageHashUtils.toEthSignedMessageHash(message); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerWallet.privateKey, hash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + signerWallet.privateKey, + hash + ); return (_nonce, abi.encodePacked(r, s, v)); } - function concatenateStrings(string memory a, string memory b) internal pure returns (string memory) { + function concatenateStrings( + string memory a, + string memory b + ) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } function generateRandomItemId() internal returns (uint256) { - _seed = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), _seed))); + _seed = uint256( + keccak256(abi.encodePacked(blockhash(block.number - 1), _seed)) + ); return _seed; } - function encode(address contractAddress, uint256[] memory itemIds) public view returns (bytes memory) { + function encode( + address contractAddress, + uint256[] memory itemIds + ) public view returns (bytes memory) { return (abi.encode(contractAddress, chainId, itemIds)); } @@ -121,7 +149,12 @@ contract RewardsBurnTest is StdCheats, Test { itemBound = new AdminERC1155Soulbound(address(this)); rewards = new Rewards(address(this)); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); itemBound.initialize( "Test1155", @@ -167,7 +200,13 @@ contract RewardsBurnTest is StdCheats, Test { LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 2 }); @@ -190,8 +229,16 @@ contract RewardsBurnTest is StdCheats, Test { encodedItems2 = encode(address(rewards), _itemIds2); - (nonce, signature) = generateSignature(playerWallet.addr, encodedItems1, minterLabel); - (nonce2, signature2) = generateSignature(playerWallet2.addr, encodedItems2, minterLabel); + (nonce, signature) = generateSignature( + playerWallet.addr, + encodedItems1, + minterLabel + ); + (nonce2, signature2) = generateSignature( + playerWallet2.addr, + encodedItems2, + minterLabel + ); mockERC20.mint(address(this), 20000000000000000000); for (uint256 i = 0; i < 10; i++) { @@ -228,7 +275,13 @@ contract RewardsBurnTest is StdCheats, Test { "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenIds[0], 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenIds[0], + 1, + "" + ); vm.expectRevert( "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" @@ -240,7 +293,13 @@ contract RewardsBurnTest is StdCheats, Test { rewards.mint(encodedItems2, false, nonce2, signature2, false); vm.prank(playerWallet2.addr); - itemBound.safeTransferFrom(playerWallet2.addr, playerWallet3.addr, _tokenIds[3], 1, ""); + itemBound.safeTransferFrom( + playerWallet2.addr, + playerWallet3.addr, + _tokenIds[3], + 1, + "" + ); assertEq(itemBound.balanceOf(playerWallet2.addr, _tokenIds[3]), 0); assertEq(itemBound.balanceOf(playerWallet3.addr, _tokenIds[3]), 1); @@ -258,7 +317,13 @@ contract RewardsBurnTest is StdCheats, Test { rewards.adminMint(playerWallet2.addr, encodedItems1, false, false); vm.prank(playerWallet2.addr); - itemBound.safeTransferFrom(playerWallet2.addr, playerWallet.addr, _tokenIds[0], 1, ""); + itemBound.safeTransferFrom( + playerWallet2.addr, + playerWallet.addr, + _tokenIds[0], + 1, + "" + ); assertEq(itemBound.balanceOf(playerWallet.addr, _tokenIds[0]), 2); @@ -266,10 +331,22 @@ contract RewardsBurnTest is StdCheats, Test { "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenIds[0], 2, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenIds[0], + 2, + "" + ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenIds[0], 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenIds[0], + 1, + "" + ); } function testBurnBatchNotOwnerShouldFail() public { @@ -323,7 +400,13 @@ contract RewardsBurnTest is StdCheats, Test { "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenIds[0], 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenIds[0], + 1, + "" + ); vm.expectRevert( "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" @@ -335,11 +418,29 @@ contract RewardsBurnTest is StdCheats, Test { rewards.mint(encodedItems2, false, nonce2, signature2, false); vm.prank(playerWallet2.addr); - itemBound.safeTransferFrom(playerWallet2.addr, playerWallet3.addr, _tokenIds[3], 1, ""); + itemBound.safeTransferFrom( + playerWallet2.addr, + playerWallet3.addr, + _tokenIds[3], + 1, + "" + ); vm.prank(playerWallet2.addr); - itemBound.safeTransferFrom(playerWallet2.addr, playerWallet3.addr, _tokenIds[4], 1, ""); + itemBound.safeTransferFrom( + playerWallet2.addr, + playerWallet3.addr, + _tokenIds[4], + 1, + "" + ); vm.prank(playerWallet2.addr); - itemBound.safeTransferFrom(playerWallet2.addr, playerWallet3.addr, _tokenIds[5], 1, ""); + itemBound.safeTransferFrom( + playerWallet2.addr, + playerWallet3.addr, + _tokenIds[5], + 1, + "" + ); assertEq(itemBound.balanceOf(playerWallet2.addr, _tokenIds[3]), 0); assertEq(itemBound.balanceOf(playerWallet3.addr, _tokenIds[3]), 1); diff --git a/test/Rewards/RewardsClaim.t.sol b/test/Rewards/RewardsClaim.t.sol index 3a52600..f7c4af8 100644 --- a/test/Rewards/RewardsClaim.t.sol +++ b/test/Rewards/RewardsClaim.t.sol @@ -7,13 +7,21 @@ import "forge-std/console.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; -import { IERC721Errors } from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; -import { ERC721Holder } from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; - -import {Rewards} from "../../contracts/soulbounds/Rewards.sol"; -import { AdminERC1155Soulbound } from "../../contracts/soulbounds/AdminERC1155Soulbound.sol"; -import { MockERC1155Receiver } from "../../contracts/mocks/MockERC1155Receiver.sol"; +import { + MessageHashUtils +} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import { + IERC721Errors +} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; +import { + ERC721Holder +} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +import { Rewards } from "../../contracts/soulbounds/Rewards.sol"; +import { AccessToken } from "../../contracts/soulbounds/AccessToken.sol"; +import { + MockERC1155Receiver +} from "../../contracts/mocks/MockERC1155Receiver.sol"; import { MockERC20 } from "../../contracts/mocks/MockErc20.sol"; import { MockERC721 } from "../../contracts/mocks/MockErc721.sol"; import { MockERC1155 } from "../../contracts/mocks/MockErc1155.sol"; @@ -31,11 +39,16 @@ error MintPaused(); error ClaimRewardPaused(); error DupTokenId(); -contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { +contract RewardsClaimTest is + StdCheats, + Test, + MockERC1155Receiver, + ERC721Holder +{ using Strings for uint256; Rewards public rewards; - AdminERC1155Soulbound public itemBound; + AccessToken public itemBound; MockERC1155Receiver public mockERC1155Receiver; MockERC20 public mockERC20; MockERC721 public mockERC721; @@ -80,7 +93,9 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder uint256 public chainId = 31337; - function getWallet(string memory walletLabel) public returns (Wallet memory) { + function getWallet( + string memory walletLabel + ) public returns (Wallet memory) { (address addr, uint256 privateKey) = makeAddrAndKey(walletLabel); Wallet memory wallet = Wallet(addr, privateKey); return wallet; @@ -93,26 +108,46 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder ) public returns (uint256, bytes memory) { Wallet memory signerWallet = getWallet(signerLabel); - uint256 _nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, signerWallet.addr))) % - 50; - - bytes32 message = keccak256(abi.encodePacked(wallet, encodedItems, _nonce)); + uint256 _nonce = uint256( + keccak256( + abi.encodePacked( + block.timestamp, + block.prevrandao, + signerWallet.addr + ) + ) + ) % 50; + + bytes32 message = keccak256( + abi.encodePacked(wallet, encodedItems, _nonce) + ); bytes32 hash = MessageHashUtils.toEthSignedMessageHash(message); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerWallet.privateKey, hash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + signerWallet.privateKey, + hash + ); return (_nonce, abi.encodePacked(r, s, v)); } - function concatenateStrings(string memory a, string memory b) internal pure returns (string memory) { + function concatenateStrings( + string memory a, + string memory b + ) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } function generateRandomItemId() internal returns (uint256) { - _seed = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), _seed))); + _seed = uint256( + keccak256(abi.encodePacked(blockhash(block.number - 1), _seed)) + ); return _seed; } - function encode(address contractAddress, uint256[] memory itemIds) public view returns (bytes memory) { + function encode( + address contractAddress, + uint256[] memory itemIds + ) public view returns (bytes memory) { return (abi.encode(contractAddress, chainId, itemIds)); } @@ -124,7 +159,12 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder itemBound = new AdminERC1155Soulbound(address(this)); rewards = new Rewards(address(this)); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); itemBound.initialize( "Test1155", @@ -197,7 +237,13 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder uint256 _tokenId = 888; LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 2 }); @@ -214,7 +260,9 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder mockERC721.setApprovalForAll(address(rewards), true); mockERC1155.setApprovalForAll(address(rewards), true); - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); } // Test cases @@ -292,7 +340,11 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder // Claim vm.prank(playerWallet.addr); vm.expectRevert( - abi.encodeWithSelector(IERC721Errors.ERC721InsufficientApproval.selector, address(rewards), 1) + abi.encodeWithSelector( + IERC721Errors.ERC721InsufficientApproval.selector, + address(rewards), + 1 + ) ); rewards.claimRewards(_tokenIds); } @@ -353,7 +405,11 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder _itemIds1[0] = _tokenId; encodedItems1 = encode(address(rewards), _itemIds1); - (nonce, signature) = generateSignature(playerWallet.addr, encodedItems1, minterLabel); + (nonce, signature) = generateSignature( + playerWallet.addr, + encodedItems1, + minterLabel + ); vm.prank(playerWallet.addr); rewards.mint(encodedItems1, true, nonce, signature, true); @@ -377,7 +433,13 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder uint256[] memory _amount1 = new uint256[](1); _amount1[0] = 200000000000000001; - rewards.withdrawAssets(LibItems.RewardType.ETHER, playerWallet2.addr, address(0), _tokenIds1, _amount1); + rewards.withdrawAssets( + LibItems.RewardType.ETHER, + playerWallet2.addr, + address(0), + _tokenIds1, + _amount1 + ); uint256 _tokenId = 888; rewards.adminMintById(playerWallet.addr, _tokenId, 1, true); @@ -446,20 +508,32 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 2 }); _tokens[i] = _token; } - rewards.createMultipleTokensAndDepositRewards{ value: 200000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 200000000000000000 + }(_tokens); uint256[] memory _itemIds1 = new uint256[](1); _itemIds1[0] = _tokenId; bytes memory encodedItems4 = encode(address(rewards), _itemIds1); - (nonce, signature) = generateSignature(playerWallet.addr, encodedItems4, minterLabel); + (nonce, signature) = generateSignature( + playerWallet.addr, + encodedItems4, + minterLabel + ); vm.prank(playerWallet.addr); rewards.mint(encodedItems4, true, nonce, signature, true); @@ -472,7 +546,11 @@ contract RewardsClaimTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder assertEq(mockERC721.ownerOf(4), playerWallet.addr); assertEq(mockERC1155.balanceOf(playerWallet.addr, 456), 2); - (nonce2, signature2) = generateSignature(playerWallet2.addr, encodedItems4, minterLabel); + (nonce2, signature2) = generateSignature( + playerWallet2.addr, + encodedItems4, + minterLabel + ); vm.prank(playerWallet2.addr); rewards.mint(encodedItems4, true, nonce2, signature2, true); diff --git a/test/Rewards/RewardsMint.t.sol b/test/Rewards/RewardsMint.t.sol index 9df9883..ff47c9f 100644 --- a/test/Rewards/RewardsMint.t.sol +++ b/test/Rewards/RewardsMint.t.sol @@ -7,13 +7,21 @@ import "forge-std/console.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; -import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; -import { ERC721Holder } from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; - -import {Rewards} from "../../contracts/soulbounds/Rewards.sol"; -import { AdminERC1155Soulbound } from "../../contracts/soulbounds/AdminERC1155Soulbound.sol"; -import { MockERC1155Receiver } from "../../contracts/mocks/MockERC1155Receiver.sol"; +import { + MessageHashUtils +} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import { + IAccessControl +} from "@openzeppelin/contracts/access/IAccessControl.sol"; +import { + ERC721Holder +} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; + +import { Rewards } from "../../contracts/soulbounds/Rewards.sol"; +import { AccessToken } from "../../contracts/soulbounds/AccessToken.sol"; +import { + MockERC1155Receiver +} from "../../contracts/mocks/MockERC1155Receiver.sol"; import { MockERC20 } from "../../contracts/mocks/MockErc20.sol"; import { MockERC721 } from "../../contracts/mocks/MockErc721.sol"; import { MockERC1155 } from "../../contracts/mocks/MockErc1155.sol"; @@ -35,7 +43,7 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { using Strings for uint256; Rewards public rewards; - AdminERC1155Soulbound public itemBound; + AccessToken public itemBound; MockERC1155Receiver public mockERC1155Receiver; MockERC20 public mockERC20; MockERC721 public mockERC721; @@ -83,7 +91,9 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant DEV_CONFIG_ROLE = keccak256("DEV_CONFIG_ROLE"); - function getWallet(string memory walletLabel) public returns (Wallet memory) { + function getWallet( + string memory walletLabel + ) public returns (Wallet memory) { (address addr, uint256 privateKey) = makeAddrAndKey(walletLabel); Wallet memory wallet = Wallet(addr, privateKey); return wallet; @@ -96,26 +106,46 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { ) public returns (uint256, bytes memory) { Wallet memory signerWallet = getWallet(signerLabel); - uint256 _nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, signerWallet.addr))) % - 50; + uint256 _nonce = uint256( + keccak256( + abi.encodePacked( + block.timestamp, + block.prevrandao, + signerWallet.addr + ) + ) + ) % 50; - bytes32 message = keccak256(abi.encodePacked(wallet, encodedItems, _nonce)); + bytes32 message = keccak256( + abi.encodePacked(wallet, encodedItems, _nonce) + ); bytes32 hash = MessageHashUtils.toEthSignedMessageHash(message); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerWallet.privateKey, hash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + signerWallet.privateKey, + hash + ); return (_nonce, abi.encodePacked(r, s, v)); } - function concatenateStrings(string memory a, string memory b) internal pure returns (string memory) { + function concatenateStrings( + string memory a, + string memory b + ) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } function generateRandomItemId() internal returns (uint256) { - _seed = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), _seed))); + _seed = uint256( + keccak256(abi.encodePacked(blockhash(block.number - 1), _seed)) + ); return _seed; } - function encode(address contractAddress, uint256[] memory itemIds) public view returns (bytes memory) { + function encode( + address contractAddress, + uint256[] memory itemIds + ) public view returns (bytes memory) { return (abi.encode(contractAddress, chainId, itemIds)); } @@ -127,7 +157,12 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { itemBound = new AdminERC1155Soulbound(address(this)); rewards = new Rewards(address(this)); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); itemBound.initialize( "Test1155", @@ -173,7 +208,13 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 1 }); @@ -196,8 +237,16 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { encodedItems2 = encode(address(rewards), _itemIds2); - (nonce, signature) = generateSignature(playerWallet.addr, encodedItems1, minterLabel); - (nonce2, signature2) = generateSignature(playerWallet2.addr, encodedItems2, minterLabel); + (nonce, signature) = generateSignature( + playerWallet.addr, + encodedItems1, + minterLabel + ); + (nonce2, signature2) = generateSignature( + playerWallet2.addr, + encodedItems2, + minterLabel + ); mockERC20.mint(address(this), 20000000000000000000); for (uint256 i = 0; i < 10; i++) { @@ -219,17 +268,35 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenIds[0], 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenIds[0], + 1, + "" + ); vm.expectRevert("Achievo1155Soulbound: can't be zero amount"); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenIds[0], 0, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenIds[0], + 0, + "" + ); vm.prank(playerWallet2.addr); rewards.mint(encodedItems2, false, nonce2, signature2, false); vm.prank(playerWallet2.addr); - itemBound.safeTransferFrom(playerWallet2.addr, minterWallet.addr, _tokenIds[3], 1, ""); + itemBound.safeTransferFrom( + playerWallet2.addr, + minterWallet.addr, + _tokenIds[3], + 1, + "" + ); assertEq(itemBound.balanceOf(playerWallet.addr, _tokenIds[0]), 1); assertEq(itemBound.balanceOf(playerWallet2.addr, _tokenIds[3]), 0); @@ -243,7 +310,11 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { bytes memory encodedItems3 = encode(address(rewards), _itemIds3); - (uint256 _nonce, bytes memory _signature) = generateSignature(playerWallet.addr, encodedItems3, minterLabel); + (uint256 _nonce, bytes memory _signature) = generateSignature( + playerWallet.addr, + encodedItems3, + minterLabel + ); vm.expectRevert(TokenNotExist.selector); vm.prank(playerWallet.addr); @@ -346,18 +417,31 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { uint256 _tokenId = 100; // totally random LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 2 }); _tokens[0] = _token; - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); uint256[] memory itemIds = new uint256[](1); itemIds[0] = 100; - rewards.adminMint(playerWallet.addr, (encode(address(rewards), itemIds)), true, false); + rewards.adminMint( + playerWallet.addr, + (encode(address(rewards), itemIds)), + true, + false + ); rewards.adminMintById(playerWallet.addr, _tokens[0].tokenId, 1, true); assertEq(itemBound.balanceOf(playerWallet.addr, _tokens[0].tokenId), 2); @@ -385,26 +469,43 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 15 }); _tokens[0] = _token; - rewards.createMultipleTokensAndDepositRewards{ value: 300000000000000000 }(_tokens); + rewards.createMultipleTokensAndDepositRewards{ + value: 300000000000000000 + }(_tokens); assertEq(mockERC20.balanceOf(address(rewards)), 4001500); uint256[] memory itemIds = new uint256[](1); itemIds[0] = _tokenId; - rewards.adminMint(playerWallet.addr, (encode(address(rewards), itemIds)), true, true); + rewards.adminMint( + playerWallet.addr, + (encode(address(rewards), itemIds)), + true, + true + ); assertEq(mockERC20.balanceOf(playerWallet.addr), 100); assertEq(mockERC20.balanceOf(address(rewards)), 4001400); bytes memory encodedItems = encode(address(rewards), itemIds); - (uint256 _nonce, bytes memory _signature) = generateSignature(playerWallet2.addr, encodedItems, minterLabel); + (uint256 _nonce, bytes memory _signature) = generateSignature( + playerWallet2.addr, + encodedItems, + minterLabel + ); vm.prank(playerWallet2.addr); rewards.mint(encodedItems, true, _nonce, _signature, true); @@ -412,7 +513,11 @@ contract RewardsMintTest is StdCheats, Test, MockERC1155Receiver, ERC721Holder { assertEq(mockERC20.balanceOf(playerWallet2.addr), 100); skip(36000); - (uint256 _nonce2, bytes memory _signature2) = generateSignature(playerWallet2.addr, encodedItems, minterLabel); + (uint256 _nonce2, bytes memory _signature2) = generateSignature( + playerWallet2.addr, + encodedItems, + minterLabel + ); vm.prank(playerWallet2.addr); rewards.mint(encodedItems, true, _nonce2, _signature2, true); diff --git a/test/Rewards/RewardsTransfer.t.sol b/test/Rewards/RewardsTransfer.t.sol index 7aae762..63963da 100644 --- a/test/Rewards/RewardsTransfer.t.sol +++ b/test/Rewards/RewardsTransfer.t.sol @@ -7,11 +7,15 @@ import "forge-std/console.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; - -import {Rewards} from "../../contracts/soulbounds/Rewards.sol"; -import { AdminERC1155Soulbound } from "../../contracts/soulbounds/AdminERC1155Soulbound.sol"; -import { MockERC1155Receiver } from "../../contracts/mocks/MockERC1155Receiver.sol"; +import { + MessageHashUtils +} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +import { Rewards } from "../../contracts/soulbounds/Rewards.sol"; +import { AccessToken } from "../../contracts/soulbounds/AccessToken.sol"; +import { + MockERC1155Receiver +} from "../../contracts/mocks/MockERC1155Receiver.sol"; import { MockERC20 } from "../../contracts/mocks/MockErc20.sol"; import { MockERC721 } from "../../contracts/mocks/MockErc721.sol"; import { MockERC1155 } from "../../contracts/mocks/MockErc1155.sol"; @@ -32,7 +36,7 @@ contract RewardsTransferTest is StdCheats, Test { using Strings for uint256; Rewards public rewards; - AdminERC1155Soulbound public itemBound; + AccessToken public itemBound; MockERC1155Receiver public mockERC1155Receiver; MockERC20 public mockERC20; MockERC721 public mockERC721; @@ -77,7 +81,9 @@ contract RewardsTransferTest is StdCheats, Test { uint256 public chainId = 31337; - function getWallet(string memory walletLabel) public returns (Wallet memory) { + function getWallet( + string memory walletLabel + ) public returns (Wallet memory) { (address addr, uint256 privateKey) = makeAddrAndKey(walletLabel); Wallet memory wallet = Wallet(addr, privateKey); return wallet; @@ -90,26 +96,46 @@ contract RewardsTransferTest is StdCheats, Test { ) public returns (uint256, bytes memory) { Wallet memory signerWallet = getWallet(signerLabel); - uint256 _nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, signerWallet.addr))) % - 50; - - bytes32 message = keccak256(abi.encodePacked(wallet, encodedItems, _nonce)); + uint256 _nonce = uint256( + keccak256( + abi.encodePacked( + block.timestamp, + block.prevrandao, + signerWallet.addr + ) + ) + ) % 50; + + bytes32 message = keccak256( + abi.encodePacked(wallet, encodedItems, _nonce) + ); bytes32 hash = MessageHashUtils.toEthSignedMessageHash(message); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerWallet.privateKey, hash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + signerWallet.privateKey, + hash + ); return (_nonce, abi.encodePacked(r, s, v)); } - function concatenateStrings(string memory a, string memory b) internal pure returns (string memory) { + function concatenateStrings( + string memory a, + string memory b + ) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } function generateRandomItemId() internal returns (uint256) { - _seed = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), _seed))); + _seed = uint256( + keccak256(abi.encodePacked(blockhash(block.number - 1), _seed)) + ); return _seed; } - function encode(address contractAddress, uint256[] memory itemIds) public view returns (bytes memory) { + function encode( + address contractAddress, + uint256[] memory itemIds + ) public view returns (bytes memory) { return (abi.encode(contractAddress, chainId, itemIds)); } @@ -121,7 +147,12 @@ contract RewardsTransferTest is StdCheats, Test { itemBound = new AdminERC1155Soulbound(address(this)); rewards = new Rewards(address(this)); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); itemBound.initialize( "Test1155", @@ -167,7 +198,13 @@ contract RewardsTransferTest is StdCheats, Test { LibItems.RewardToken memory _token = LibItems.RewardToken({ tokenId: _tokenId, - tokenUri: string(abi.encodePacked("https://something.com", "/", _tokenId.toString())), + tokenUri: string( + abi.encodePacked( + "https://something.com", + "/", + _tokenId.toString() + ) + ), rewards: _rewards, maxSupply: 2 }); @@ -190,8 +227,16 @@ contract RewardsTransferTest is StdCheats, Test { encodedItems2 = encode(address(rewards), _itemIds2); - (nonce, signature) = generateSignature(playerWallet.addr, encodedItems1, minterLabel); - (nonce2, signature2) = generateSignature(playerWallet2.addr, encodedItems2, minterLabel); + (nonce, signature) = generateSignature( + playerWallet.addr, + encodedItems1, + minterLabel + ); + (nonce2, signature2) = generateSignature( + playerWallet2.addr, + encodedItems2, + minterLabel + ); mockERC20.mint(address(this), 20000000000000000000); for (uint256 i = 0; i < 10; i++) { @@ -226,7 +271,13 @@ contract RewardsTransferTest is StdCheats, Test { rewards.adminMint(playerWallet2.addr, encodedItems1, false, false); vm.prank(playerWallet2.addr); - itemBound.safeTransferFrom(playerWallet2.addr, playerWallet.addr, _tokenIds[0], 1, ""); + itemBound.safeTransferFrom( + playerWallet2.addr, + playerWallet.addr, + _tokenIds[0], + 1, + "" + ); assertEq(itemBound.balanceOf(playerWallet.addr, _tokenIds[0]), 2); @@ -240,12 +291,24 @@ contract RewardsTransferTest is StdCheats, Test { vm.expectRevert("ERC1155: duplicate ID"); vm.prank(playerWallet.addr); - itemBound.safeBatchTransferFrom(playerWallet.addr, minterWallet.addr, _itemIds3, _amount3, ""); + itemBound.safeBatchTransferFrom( + playerWallet.addr, + minterWallet.addr, + _itemIds3, + _amount3, + "" + ); assertEq(itemBound.balanceOf(minterWallet.addr, _tokenIds[0]), 0); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenIds[0], 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenIds[0], + 1, + "" + ); assertEq(itemBound.balanceOf(minterWallet.addr, _tokenIds[0]), 1); } @@ -254,7 +317,13 @@ contract RewardsTransferTest is StdCheats, Test { rewards.adminMintById(playerWallet.addr, _tokenId, 1, false); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenId, 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenId, + 1, + "" + ); assertEq(itemBound.balanceOf(playerWallet.addr, _tokenId), 0); assertEq(itemBound.balanceOf(minterWallet.addr, _tokenId), 1); @@ -268,11 +337,23 @@ contract RewardsTransferTest is StdCheats, Test { "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenId, 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenId, + 1, + "" + ); vm.expectRevert("Achievo1155Soulbound: can't be zero amount"); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, minterWallet.addr, _tokenId, 0, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + minterWallet.addr, + _tokenId, + 0, + "" + ); } function testSoulboundTokenTransferOnlyWhitelistAddresses() public { @@ -283,15 +364,33 @@ contract RewardsTransferTest is StdCheats, Test { "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, playerWallet3.addr, _tokenId, 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + playerWallet3.addr, + _tokenId, + 1, + "" + ); itemBound.updateWhitelistAddress(playerWallet3.addr, true); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, playerWallet3.addr, _tokenId, 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + playerWallet3.addr, + _tokenId, + 1, + "" + ); vm.prank(playerWallet3.addr); - itemBound.safeTransferFrom(playerWallet3.addr, playerWallet.addr, _tokenId, 1, ""); + itemBound.safeTransferFrom( + playerWallet3.addr, + playerWallet.addr, + _tokenId, + 1, + "" + ); itemBound.updateWhitelistAddress(playerWallet3.addr, false); @@ -299,6 +398,12 @@ contract RewardsTransferTest is StdCheats, Test { "Achievo1155Soulbound: The amount of soulbounded tokens is more than the amount of tokens to be transferred" ); vm.prank(playerWallet.addr); - itemBound.safeTransferFrom(playerWallet.addr, playerWallet3.addr, _tokenId, 1, ""); + itemBound.safeTransferFrom( + playerWallet.addr, + playerWallet3.addr, + _tokenId, + 1, + "" + ); } } diff --git a/test/Rewards/RewardsWithdraw.t.sol b/test/Rewards/RewardsWithdraw.t.sol index 5499891..f96d5f9 100644 --- a/test/Rewards/RewardsWithdraw.t.sol +++ b/test/Rewards/RewardsWithdraw.t.sol @@ -7,12 +7,19 @@ import "forge-std/console.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol"; -import { IERC721Errors, IERC1155Errors } from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; - -import {Rewards} from "../../contracts/soulbounds/Rewards.sol"; -import { AdminERC1155Soulbound } from "../../contracts/soulbounds/AdminERC1155Soulbound.sol"; -import { MockERC1155Receiver } from "../../contracts/mocks/MockERC1155Receiver.sol"; +import { + IAccessControl +} from "@openzeppelin/contracts/access/IAccessControl.sol"; +import { + IERC721Errors, + IERC1155Errors +} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; + +import { Rewards } from "../../contracts/soulbounds/Rewards.sol"; +import { AccessToken } from "../../contracts/soulbounds/AccessToken.sol"; +import { + MockERC1155Receiver +} from "../../contracts/mocks/MockERC1155Receiver.sol"; import { MockERC20 } from "../../contracts/mocks/MockErc20.sol"; import { MockERC721 } from "../../contracts/mocks/MockErc721.sol"; import { MockERC1155 } from "../../contracts/mocks/MockErc1155.sol"; @@ -35,7 +42,7 @@ contract RewardsWithdrawTest is StdCheats, Test { using Strings for uint256; Rewards public rewards; - AdminERC1155Soulbound public itemBound; + AccessToken public itemBound; MockERC1155Receiver public mockERC1155Receiver; MockERC20 public mockERC20; MockERC721 public mockERC721; @@ -81,7 +88,9 @@ contract RewardsWithdrawTest is StdCheats, Test { bytes32 public constant DEV_CONFIG_ROLE = keccak256("DEV_CONFIG_ROLE"); bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); - function getWallet(string memory walletLabel) public returns (Wallet memory) { + function getWallet( + string memory walletLabel + ) public returns (Wallet memory) { (address addr, uint256 privateKey) = makeAddrAndKey(walletLabel); Wallet memory wallet = Wallet(addr, privateKey); return wallet; @@ -95,7 +104,12 @@ contract RewardsWithdrawTest is StdCheats, Test { itemBound = new AdminERC1155Soulbound(address(this)); rewards = new Rewards(address(this)); - rewards.initialize(address(this), address(this), address(this), address(itemBound)); + rewards.initialize( + address(this), + address(this), + address(this), + address(itemBound) + ); itemBound.initialize( "Test1155", @@ -116,7 +130,9 @@ contract RewardsWithdrawTest is StdCheats, Test { erc721FakeRewardAddress = address(mockERC721); erc1155FakeRewardAddress = address(mockERC1155); - (bool success, ) = payable(address(rewards)).call{ value: 2000000000000000000 }(""); + (bool success, ) = payable(address(rewards)).call{ + value: 2000000000000000000 + }(""); mockERC20.mint(address(rewards), 20000000000000000000); for (uint256 i = 0; i < 10; i++) { @@ -147,7 +163,13 @@ contract RewardsWithdrawTest is StdCheats, Test { ); vm.prank(playerWallet.addr); - rewards.withdrawAssets(LibItems.RewardType.ETHER, address(0), address(0), _tokenIds1, _amount1); + rewards.withdrawAssets( + LibItems.RewardType.ETHER, + address(0), + address(0), + _tokenIds1, + _amount1 + ); } function testWithdrawAddressZeroShouldFail() public { @@ -161,7 +183,13 @@ contract RewardsWithdrawTest is StdCheats, Test { _amount1[0] = 1000000000000000000; vm.expectRevert(AddressIsZero.selector); - rewards.withdrawAssets(LibItems.RewardType.ETHER, address(0), address(0), _tokenIds1, _amount1); + rewards.withdrawAssets( + LibItems.RewardType.ETHER, + address(0), + address(0), + _tokenIds1, + _amount1 + ); } // withdraw ETH - fail @@ -176,7 +204,13 @@ contract RewardsWithdrawTest is StdCheats, Test { _amount1[0] = 2000000000000000001; vm.expectRevert(InsufficientBalance.selector); - rewards.withdrawAssets(LibItems.RewardType.ETHER, playerWallet2.addr, address(0), _tokenIds1, _amount1); + rewards.withdrawAssets( + LibItems.RewardType.ETHER, + playerWallet2.addr, + address(0), + _tokenIds1, + _amount1 + ); assertEq(address(rewards).balance, 2000000000000000000); } @@ -192,7 +226,13 @@ contract RewardsWithdrawTest is StdCheats, Test { uint256[] memory _amount1 = new uint256[](1); _amount1[0] = 1000000000000000000; - rewards.withdrawAssets(LibItems.RewardType.ETHER, playerWallet2.addr, address(0), _tokenIds1, _amount1); + rewards.withdrawAssets( + LibItems.RewardType.ETHER, + playerWallet2.addr, + address(0), + _tokenIds1, + _amount1 + ); assertEq(address(rewards).balance, 1000000000000000000); } @@ -254,7 +294,11 @@ contract RewardsWithdrawTest is StdCheats, Test { _amount1[0] = 0; // ignore amount vm.expectRevert( - abi.encodeWithSelector(IERC721Errors.ERC721InsufficientApproval.selector, address(rewards), 10) + abi.encodeWithSelector( + IERC721Errors.ERC721InsufficientApproval.selector, + address(rewards), + 10 + ) ); rewards.withdrawAssets( @@ -267,7 +311,12 @@ contract RewardsWithdrawTest is StdCheats, Test { } function testWithdrawERC721InvalidTokenIdShouldFail() public { - vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, 20)); + vm.expectRevert( + abi.encodeWithSelector( + IERC721Errors.ERC721NonexistentToken.selector, + 20 + ) + ); mockERC721.ownerOf(20); uint256[] memory _tokenIds1 = new uint256[](1); @@ -276,7 +325,12 @@ contract RewardsWithdrawTest is StdCheats, Test { uint256[] memory _amount1 = new uint256[](1); _amount1[0] = 0; // ignore amount - vm.expectRevert(abi.encodeWithSelector(IERC721Errors.ERC721NonexistentToken.selector, _tokenIds1[0])); + vm.expectRevert( + abi.encodeWithSelector( + IERC721Errors.ERC721NonexistentToken.selector, + _tokenIds1[0] + ) + ); rewards.withdrawAssets( LibItems.RewardType.ERC721, @@ -327,14 +381,23 @@ contract RewardsWithdrawTest is StdCheats, Test { _amounts[1] = 11; _amounts[2] = 4; - uint256[] memory balances = mockERC1155.balanceOfBatch(_accounts, _tokenIds); + uint256[] memory balances = mockERC1155.balanceOfBatch( + _accounts, + _tokenIds + ); for (uint256 i = 0; i < balances.length; i++) { assertEq(balances[i], 10); } vm.expectRevert( - abi.encodeWithSelector(IERC1155Errors.ERC1155InsufficientBalance.selector, address(rewards), 10, 11, 456) + abi.encodeWithSelector( + IERC1155Errors.ERC1155InsufficientBalance.selector, + address(rewards), + 10, + 11, + 456 + ) ); rewards.withdrawAssets( @@ -345,7 +408,10 @@ contract RewardsWithdrawTest is StdCheats, Test { _amounts ); - uint256[] memory balancesAfter = mockERC1155.balanceOfBatch(_accounts, _tokenIds); + uint256[] memory balancesAfter = mockERC1155.balanceOfBatch( + _accounts, + _tokenIds + ); for (uint256 i = 0; i < balancesAfter.length; i++) { assertEq(balancesAfter[i], balances[i]); @@ -363,14 +429,23 @@ contract RewardsWithdrawTest is StdCheats, Test { uint256[] memory _amounts = new uint256[](1); _amounts[0] = 2; - uint256[] memory balances = mockERC1155.balanceOfBatch(_accounts, _tokenIds); + uint256[] memory balances = mockERC1155.balanceOfBatch( + _accounts, + _tokenIds + ); for (uint256 i = 0; i < balances.length; i++) { assertEq(balances[i], 0); } vm.expectRevert( - abi.encodeWithSelector(IERC1155Errors.ERC1155InsufficientBalance.selector, address(rewards), 0, 2, 888) + abi.encodeWithSelector( + IERC1155Errors.ERC1155InsufficientBalance.selector, + address(rewards), + 0, + 2, + 888 + ) ); rewards.withdrawAssets( @@ -399,7 +474,10 @@ contract RewardsWithdrawTest is StdCheats, Test { _amounts[1] = 2; _amounts[2] = 3; - uint256[] memory balances = mockERC1155.balanceOfBatch(_accounts, _tokenIds); + uint256[] memory balances = mockERC1155.balanceOfBatch( + _accounts, + _tokenIds + ); for (uint256 i = 0; i < balances.length; i++) { assertEq(balances[i], 10); @@ -413,7 +491,10 @@ contract RewardsWithdrawTest is StdCheats, Test { _amounts ); - uint256[] memory balancesAfter = mockERC1155.balanceOfBatch(_accounts, _tokenIds); + uint256[] memory balancesAfter = mockERC1155.balanceOfBatch( + _accounts, + _tokenIds + ); for (uint256 i = 0; i < balancesAfter.length; i++) { assertEq(balancesAfter[i], 10 - _amounts[i]); diff --git a/test/hardhatTests/accessToken.test.ts b/test/hardhatTests/accessToken.test.ts new file mode 100644 index 0000000..372f579 --- /dev/null +++ b/test/hardhatTests/accessToken.test.ts @@ -0,0 +1,201 @@ +const { expect } = require('chai'); +const { ethers } = require('hardhat'); +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); + +describe('AccessToken', function () { + async function deployFixtures() { + const [devWallet, minterWallet, user1, user2] = await ethers.getSigners(); + + const AccessToken = await ethers.getContractFactory('AccessToken'); + const accessToken = await AccessToken.deploy(devWallet.address); + await accessToken.waitForDeployment(); + + await accessToken.initialize( + 'G7Reward', + 'G7R', + 'https://example.com/token/', + 'https://example.com/contract/', + devWallet.address, + minterWallet.address + ); + + return { + accessToken, + devWallet, + minterWallet, + user1, + user2, + }; + } + + describe('Initialization', function () { + it('Should deploy successfully', async function () { + const { accessToken } = await loadFixture(deployFixtures); + expect(await accessToken.getAddress()).to.be.properAddress; + }); + it('should set the correct name and symbol', async function () { + const { accessToken } = await loadFixture(deployFixtures); + expect(await accessToken.name()).to.equal('G7Reward'); + expect(await accessToken.symbol()).to.equal('G7R'); + }); + + it('should set the correct default token URI', async function () { + const { accessToken } = await loadFixture(deployFixtures); + expect(await accessToken.defaultTokenURI()).to.equal('https://example.com/token/'); + }); + + it('should set the correct contract URI', async function () { + const { accessToken } = await loadFixture(deployFixtures); + expect(await accessToken.contractURI()).to.equal('https://example.com/contract/'); + }); + }); + + describe('Role management', function () { + it('should grant the correct roles', async function () { + const { accessToken, devWallet, minterWallet } = await loadFixture(deployFixtures); + expect(await accessToken.hasRole(await accessToken.DEFAULT_ADMIN_ROLE(), devWallet.address)).to.be.true; + expect(await accessToken.hasRole(await accessToken.MANAGER_ROLE(), devWallet.address)).to.be.true; + expect(await accessToken.hasRole(await accessToken.DEV_CONFIG_ROLE(), devWallet.address)).to.be.true; + expect(await accessToken.hasRole(await accessToken.DEV_CONFIG_ROLE(), minterWallet.address)).to.be.true; + expect(await accessToken.hasRole(await accessToken.MINTER_ROLE(), minterWallet.address)).to.be.true; + }); + }); + + describe('Token management', function () { + it('should add a new token', async function () { + const { accessToken, devWallet } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + expect(await accessToken.isTokenExist(1)).to.be.true; + }); + + it('should revert when querying a non-existent token', async function () { + const { accessToken } = await loadFixture(deployFixtures); + await expect(accessToken.isTokenExist(999)).to.be.revertedWith('TokenNotExist'); + }); + }); + + describe('Minting', function () { + it('should mint a token', async function () { + const { accessToken, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminMintId(user1.address, 1, 1, false); + expect(await accessToken.balanceOf(user1.address, 1)).to.equal(1); + }); + + it('should mint a soulbound token', async function () { + const { accessToken, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminMintId(user1.address, 1, 1, true); + expect(await accessToken.balanceOf(user1.address, 1)).to.equal(1); + await expect( + accessToken.connect(user1).safeTransferFrom(user1.address, devWallet.address, 1, 1, '0x') + ).to.be.revertedWithCustomError(accessToken, 'SoulboundAmountError'); + }); + + it('should batch mint tokens', async function () { + const { accessToken, devWallet, minterWallet, user1, user2 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminBatchMintId([user1.address, user2.address], 1, [1, 2], false); + expect(await accessToken.balanceOf(user1.address, 1)).to.equal(1); + expect(await accessToken.balanceOf(user2.address, 1)).to.equal(2); + }); + }); + + describe('Token transfers', function () { + it('should allow transfer of non-soulbound tokens', async function () { + const { accessToken, devWallet, minterWallet, user1, user2 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminMintId(user1.address, 1, 20, false); + await accessToken.connect(user1).safeTransferFrom(user1.address, user2.address, 1, 5, '0x'); + expect(await accessToken.balanceOf(user1.address, 1)).to.equal(15); + expect(await accessToken.balanceOf(user2.address, 1)).to.equal(5); + }); + + it('should not allow transfer of soulbound tokens', async function () { + const { accessToken, devWallet, minterWallet, user1, user2 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminMintId(user1.address, 1, 1, true); + await expect( + accessToken.connect(user1).safeTransferFrom(user1.address, user2.address, 1, 1, '0x') + ).to.be.revertedWithCustomError(accessToken, 'SoulboundAmountError'); + }); + }); + + describe('Burning', function () { + it('should allow burning of non-soulbound tokens', async function () { + const { accessToken, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminMintId(user1.address, 1, 2, false); + await accessToken.connect(user1).burn(user1.address, 1, 1); + expect(await accessToken.balanceOf(user1.address, 1)).to.equal(1); + }); + + it('should not allow burning of soulbound tokens without being in the burn whitelist', async function () { + const { accessToken, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminMintId(user1.address, 1, 1, true); + await expect(accessToken.connect(user1).burn(user1.address, 1, 1)).to.be.revertedWithCustomError( + accessToken, + 'SoulboundAmountError' + ); + }); + + it('should allow whitelisted address to burn tokens', async function () { + const { accessToken, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(minterWallet).adminMintId(user1.address, 1, 2, false); + await accessToken.connect(devWallet).updateWhitelistAddress(devWallet.address, true); + await accessToken.connect(devWallet).whitelistBurn(user1.address, 1, 1); + expect(await accessToken.balanceOf(user1.address, 1)).to.equal(1); + }); + }); + + describe('URI management', function () { + it('should return the correct token URI', async function () { + const { accessToken, devWallet } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + expect(await accessToken.uri(1)).to.equal('https://example.com/token/'); + }); + + it('should update the default token URI', async function () { + const { accessToken, devWallet } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).updateDefaultTokenURI('https://newexample.com/token/'); + expect(await accessToken.defaultTokenURI()).to.equal('https://newexample.com/token/'); + }); + + it('should update the contract URI', async function () { + const { accessToken, devWallet } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).setContractURI('https://newexample.com/contract'); + expect(await accessToken.contractURI()).to.equal('https://newexample.com/contract'); + }); + }); + + describe('Royalty management', function () { + it('should set default royalty info', async function () { + const { accessToken, devWallet, user1 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).setRoyaltyInfo(user1.address, 500); // 5% + const [receiver, royaltyAmount] = await accessToken.royaltyInfo(1, 10000); + expect(receiver).to.equal(user1.address); + expect(royaltyAmount).to.equal(500); + }); + + it('should set token-specific royalty', async function () { + const { accessToken, devWallet, user2 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(devWallet).setTokenRoyalty(1, user2.address, 1000); // 10% + const [receiver, royaltyAmount] = await accessToken.royaltyInfo(1, 10000); + expect(receiver).to.equal(user2.address); + expect(royaltyAmount).to.equal(1000); + }); + + it('should reset token-specific royalty', async function () { + const { accessToken, devWallet, user2 } = await loadFixture(deployFixtures); + await accessToken.connect(devWallet).addNewToken(1); + await accessToken.connect(devWallet).setTokenRoyalty(1, user2.address, 1000); + await accessToken.connect(devWallet).resetTokenRoyalty(1); + const [receiver, royaltyAmount] = await accessToken.royaltyInfo(1, 10000); + expect(receiver).to.equal(ethers.ZeroAddress); + expect(royaltyAmount).to.equal(0); + }); + }); +}); diff --git a/test/hardhatTests/adminERC1155Soulbound.test.ts b/test/hardhatTests/adminERC1155Soulbound.test.ts deleted file mode 100644 index a187c43..0000000 --- a/test/hardhatTests/adminERC1155Soulbound.test.ts +++ /dev/null @@ -1,211 +0,0 @@ -const { expect } = require('chai'); -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -describe('AdminERC1155Soulbound', function () { - async function deployFixtures() { - const [devWallet, minterWallet, user1, user2] = await ethers.getSigners(); - - const AdminERC1155Soulbound = await ethers.getContractFactory('AdminERC1155Soulbound'); - const adminERC1155Soulbound = await AdminERC1155Soulbound.deploy(devWallet.address); - await adminERC1155Soulbound.waitForDeployment(); - - await adminERC1155Soulbound.initialize( - 'G7Reward', - 'G7R', - 'https://example.com/token/', - 'https://example.com/contract/', - devWallet.address, - minterWallet.address - ); - - return { - adminERC1155Soulbound, - devWallet, - minterWallet, - user1, - user2, - }; - } - - describe('Initialization', function () { - it('Should deploy successfully', async function () { - const { adminERC1155Soulbound } = await loadFixture(deployFixtures); - expect(await adminERC1155Soulbound.getAddress()).to.be.properAddress; - }); - it('should set the correct name and symbol', async function () { - const { adminERC1155Soulbound } = await loadFixture(deployFixtures); - expect(await adminERC1155Soulbound.name()).to.equal('G7Reward'); - expect(await adminERC1155Soulbound.symbol()).to.equal('G7R'); - }); - - it('should set the correct default token URI', async function () { - const { adminERC1155Soulbound } = await loadFixture(deployFixtures); - expect(await adminERC1155Soulbound.defaultTokenURI()).to.equal('https://example.com/token/'); - }); - - it('should set the correct contract URI', async function () { - const { adminERC1155Soulbound } = await loadFixture(deployFixtures); - expect(await adminERC1155Soulbound.contractURI()).to.equal('https://example.com/contract/'); - }); - }); - - describe('Role management', function () { - it('should grant the correct roles', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet } = await loadFixture(deployFixtures); - expect( - await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.DEFAULT_ADMIN_ROLE(), devWallet.address) - ).to.be.true; - expect(await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.MANAGER_ROLE(), devWallet.address)) - .to.be.true; - expect( - await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.DEV_CONFIG_ROLE(), devWallet.address) - ).to.be.true; - expect( - await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.DEV_CONFIG_ROLE(), minterWallet.address) - ).to.be.true; - expect(await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.MINTER_ROLE(), minterWallet.address)) - .to.be.true; - }); - }); - - describe('Token management', function () { - it('should add a new token', async function () { - const { adminERC1155Soulbound, devWallet } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - expect(await adminERC1155Soulbound.isTokenExist(1)).to.be.true; - }); - - it('should revert when querying a non-existent token', async function () { - const { adminERC1155Soulbound } = await loadFixture(deployFixtures); - await expect(adminERC1155Soulbound.isTokenExist(999)).to.be.revertedWith('TokenNotExist'); - }); - }); - - describe('Minting', function () { - it('should mint a token', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(minterWallet).adminMintId(user1.address, 1, 1, false); - expect(await adminERC1155Soulbound.balanceOf(user1.address, 1)).to.equal(1); - }); - - it('should mint a soulbound token', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(minterWallet).adminMintId(user1.address, 1, 1, true); - expect(await adminERC1155Soulbound.balanceOf(user1.address, 1)).to.equal(1); - await expect( - adminERC1155Soulbound.connect(user1).safeTransferFrom(user1.address, devWallet.address, 1, 1, '0x') - ).to.be.revertedWithCustomError(adminERC1155Soulbound, 'SoulboundAmountError'); - }); - - it('should batch mint tokens', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1, user2 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound - .connect(minterWallet) - .adminBatchMintId([user1.address, user2.address], 1, [1, 2], false); - expect(await adminERC1155Soulbound.balanceOf(user1.address, 1)).to.equal(1); - expect(await adminERC1155Soulbound.balanceOf(user2.address, 1)).to.equal(2); - }); - }); - - describe('Token transfers', function () { - it('should allow transfer of non-soulbound tokens', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1, user2 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(minterWallet).adminMintId(user1.address, 1, 20, false); - await adminERC1155Soulbound.connect(user1).safeTransferFrom(user1.address, user2.address, 1, 5, '0x'); - expect(await adminERC1155Soulbound.balanceOf(user1.address, 1)).to.equal(15); - expect(await adminERC1155Soulbound.balanceOf(user2.address, 1)).to.equal(5); - }); - - it('should not allow transfer of soulbound tokens', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1, user2 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(minterWallet).adminMintId(user1.address, 1, 1, true); - await expect( - adminERC1155Soulbound.connect(user1).safeTransferFrom(user1.address, user2.address, 1, 1, '0x') - ).to.be.revertedWithCustomError(adminERC1155Soulbound, 'SoulboundAmountError'); - }); - }); - - describe('Burning', function () { - it('should allow burning of non-soulbound tokens', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(minterWallet).adminMintId(user1.address, 1, 2, false); - await adminERC1155Soulbound.connect(user1).burn(user1.address, 1, 1); - expect(await adminERC1155Soulbound.balanceOf(user1.address, 1)).to.equal(1); - }); - - it('should not allow burning of soulbound tokens without being in the burn whitelist', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(minterWallet).adminMintId(user1.address, 1, 1, true); - await expect(adminERC1155Soulbound.connect(user1).burn(user1.address, 1, 1)).to.be.revertedWithCustomError( - adminERC1155Soulbound, - 'SoulboundAmountError' - ); - }); - - it('should allow whitelisted address to burn tokens', async function () { - const { adminERC1155Soulbound, devWallet, minterWallet, user1 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(minterWallet).adminMintId(user1.address, 1, 2, false); - await adminERC1155Soulbound.connect(devWallet).updateWhitelistAddress(devWallet.address, true); - await adminERC1155Soulbound.connect(devWallet).whitelistBurn(user1.address, 1, 1); - expect(await adminERC1155Soulbound.balanceOf(user1.address, 1)).to.equal(1); - }); - }); - - describe('URI management', function () { - it('should return the correct token URI', async function () { - const { adminERC1155Soulbound, devWallet } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - expect(await adminERC1155Soulbound.uri(1)).to.equal('https://example.com/token/'); - }); - - it('should update the default token URI', async function () { - const { adminERC1155Soulbound, devWallet } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).updateDefaultTokenURI('https://newexample.com/token/'); - expect(await adminERC1155Soulbound.defaultTokenURI()).to.equal('https://newexample.com/token/'); - }); - - it('should update the contract URI', async function () { - const { adminERC1155Soulbound, devWallet } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).setContractURI('https://newexample.com/contract'); - expect(await adminERC1155Soulbound.contractURI()).to.equal('https://newexample.com/contract'); - }); - }); - - describe('Royalty management', function () { - it('should set default royalty info', async function () { - const { adminERC1155Soulbound, devWallet, user1 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).setRoyaltyInfo(user1.address, 500); // 5% - const [receiver, royaltyAmount] = await adminERC1155Soulbound.royaltyInfo(1, 10000); - expect(receiver).to.equal(user1.address); - expect(royaltyAmount).to.equal(500); - }); - - it('should set token-specific royalty', async function () { - const { adminERC1155Soulbound, devWallet, user2 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(devWallet).setTokenRoyalty(1, user2.address, 1000); // 10% - const [receiver, royaltyAmount] = await adminERC1155Soulbound.royaltyInfo(1, 10000); - expect(receiver).to.equal(user2.address); - expect(royaltyAmount).to.equal(1000); - }); - - it('should reset token-specific royalty', async function () { - const { adminERC1155Soulbound, devWallet, user2 } = await loadFixture(deployFixtures); - await adminERC1155Soulbound.connect(devWallet).addNewToken(1); - await adminERC1155Soulbound.connect(devWallet).setTokenRoyalty(1, user2.address, 1000); - await adminERC1155Soulbound.connect(devWallet).resetTokenRoyalty(1); - const [receiver, royaltyAmount] = await adminERC1155Soulbound.royaltyInfo(1, 10000); - expect(receiver).to.equal(ethers.ZeroAddress); - expect(royaltyAmount).to.equal(0); - }); - }); -}); diff --git a/test/hardhatTests/rewardsNative.test.ts b/test/hardhatTests/rewardsNative.test.ts index 8579422..e8d495d 100644 --- a/test/hardhatTests/rewardsNative.test.ts +++ b/test/hardhatTests/rewardsNative.test.ts @@ -6,9 +6,9 @@ describe('RewardsNative', function () { async function deployRewardsFixture() { const [devWallet, adminWallet, managerWallet, minterWallet, user1, user2] = await ethers.getSigners(); - const AdminERC1155Soulbound = await ethers.getContractFactory('AdminERC1155Soulbound'); - const adminERC1155Soulbound = await AdminERC1155Soulbound.deploy(devWallet.address); - await adminERC1155Soulbound.waitForDeployment(); + const AccessToken = await ethers.getContractFactory('AccessToken'); + const accessToken = await AccessToken.deploy(devWallet.address); + await accessToken.waitForDeployment(); const RewardsNative = await ethers.getContractFactory('RewardsNative'); const rewardsNative = await RewardsNative.deploy( @@ -16,11 +16,11 @@ describe('RewardsNative', function () { adminWallet, managerWallet, minterWallet, - adminERC1155Soulbound + accessToken ); await rewardsNative.waitForDeployment(); - await adminERC1155Soulbound.initialize( + await accessToken.initialize( 'G7Reward', 'G7R', 'https://example.com/token/', @@ -31,7 +31,7 @@ describe('RewardsNative', function () { return { rewardsNative, - adminERC1155Soulbound, + accessToken, devWallet, adminWallet, managerWallet, @@ -58,13 +58,10 @@ describe('RewardsNative', function () { }); it('AdminERC1155Soulbound should set the roles correctly', async function () { - const { adminERC1155Soulbound, devWallet, rewardsNative } = await loadFixture(deployRewardsFixture); - expect(await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.DEFAULT_ADMIN_ROLE(), devWallet)).to - .be.true; - expect(await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.MANAGER_ROLE(), devWallet)).to.be - .true; - expect(await adminERC1155Soulbound.hasRole(await adminERC1155Soulbound.MINTER_ROLE(), rewardsNative)).to.be - .true; + const { accessToken, devWallet, rewardsNative } = await loadFixture(deployRewardsFixture); + expect(await accessToken.hasRole(await accessToken.DEFAULT_ADMIN_ROLE(), devWallet)).to.be.true; + expect(await accessToken.hasRole(await accessToken.MANAGER_ROLE(), devWallet)).to.be.true; + expect(await accessToken.hasRole(await accessToken.MINTER_ROLE(), rewardsNative)).to.be.true; }); });