From 8bf12b852de404c9e8bc242f781082c001c559ea Mon Sep 17 00:00:00 2001 From: ogarciarevett Date: Mon, 9 Feb 2026 19:20:48 +0100 Subject: [PATCH 1/3] Chore: Adding new field to the return all treasuries - fe need it --- contracts/upgradeables/soulbounds/Rewards.sol | 4 +++- contracts/upgradeables/soulbounds/Treasury.sol | 14 ++++++++++---- test/rewardsSoulbound.test.ts | 8 ++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/contracts/upgradeables/soulbounds/Rewards.sol b/contracts/upgradeables/soulbounds/Rewards.sol index 72e438b..59003d1 100644 --- a/contracts/upgradeables/soulbounds/Rewards.sol +++ b/contracts/upgradeables/soulbounds/Rewards.sol @@ -447,6 +447,7 @@ contract Rewards is * @return symbols Array of token symbols. * @return names Array of token names. * @return types Array of token types ("fa" for fungible assets, "nft" for NFTs). + * @return tokenIds Array of token IDs (0 for ERC20/ERC721, actual rewardTokenId for ERC1155). */ function getAllTreasuryBalances() external @@ -458,7 +459,8 @@ contract Rewards is uint256[] memory availableBalances, string[] memory symbols, string[] memory names, - string[] memory types + string[] memory types, + uint256[] memory tokenIds ) { return Treasury(treasury).getAllTreasuryBalances(address(this)); diff --git a/contracts/upgradeables/soulbounds/Treasury.sol b/contracts/upgradeables/soulbounds/Treasury.sol index f8ef841..1c0d100 100644 --- a/contracts/upgradeables/soulbounds/Treasury.sol +++ b/contracts/upgradeables/soulbounds/Treasury.sol @@ -179,7 +179,8 @@ contract Treasury is Initializable, AccessControlUpgradeable, UUPSUpgradeable, E uint256[] memory availableBalances, string[] memory symbols, string[] memory names, - string[] memory types + string[] memory types, + uint256[] memory tokenIds ) { address[] memory whitelistedTokensArray = rewardsState.getWhitelistedTokens(); @@ -202,6 +203,7 @@ contract Treasury is Initializable, AccessControlUpgradeable, UUPSUpgradeable, E symbols = new string[](totalCount); names = new string[](totalCount); types = new string[](totalCount); + tokenIds = new uint256[](totalCount); uint256 currentIndex = 0; @@ -213,16 +215,18 @@ contract Treasury is Initializable, AccessControlUpgradeable, UUPSUpgradeable, E if (tokenType == LibItems.RewardType.ERC20) { _processERC20Token(rewardsContract, tokenAddress, currentIndex, totalBalances, reservedBalances, availableBalances, symbols, names, types); + tokenIds[currentIndex] = 0; currentIndex++; } else if (tokenType == LibItems.RewardType.ERC721) { _processERC721Token(rewardsContract, tokenAddress, currentIndex, totalBalances, reservedBalances, availableBalances, symbols, names, types); + tokenIds[currentIndex] = 0; currentIndex++; } } - currentIndex = _processERC1155Tokens(rewardsContract, erc1155Count, currentIndex, addresses, totalBalances, reservedBalances, availableBalances, symbols, names, types); + currentIndex = _processERC1155Tokens(rewardsContract, erc1155Count, currentIndex, addresses, totalBalances, reservedBalances, availableBalances, symbols, names, types, tokenIds); - return (addresses, totalBalances, reservedBalances, availableBalances, symbols, names, types); + return (addresses, totalBalances, reservedBalances, availableBalances, symbols, names, types, tokenIds); } function getTreasuryBalance(address, address _token) external view returns (uint256) { @@ -327,7 +331,8 @@ contract Treasury is Initializable, AccessControlUpgradeable, UUPSUpgradeable, E uint256[] memory availableBalances, string[] memory symbols, string[] memory names, - string[] memory types + string[] memory types, + uint256[] memory tokenIds ) private view returns (uint256) { IRewards rewards = IRewards(rewardsContract); uint256[] memory itemIds = rewards.getAllItemIds(); @@ -363,6 +368,7 @@ contract Treasury is Initializable, AccessControlUpgradeable, UUPSUpgradeable, E processedCount++; addresses[currentIndex] = erc1155Address; + tokenIds[currentIndex] = erc1155TokenId; uint256 balance = IERC1155(erc1155Address).balanceOf(address(this), erc1155TokenId); uint256 reserved = rewardsState.erc1155ReservedAmounts(erc1155Address, erc1155TokenId); diff --git a/test/rewardsSoulbound.test.ts b/test/rewardsSoulbound.test.ts index 9a2f9e2..dcaf449 100644 --- a/test/rewardsSoulbound.test.ts +++ b/test/rewardsSoulbound.test.ts @@ -461,6 +461,7 @@ describe('Rewards with Soulbound Tokens', function () { expect(result.symbols.length).to.equal(0); expect(result.names.length).to.equal(0); expect(result.types.length).to.equal(0); + expect(result.tokenIds.length).to.equal(0); }); it('Should return ERC20 token with type "fa" after deposit to treasury', async function () { @@ -477,6 +478,7 @@ describe('Rewards with Soulbound Tokens', function () { expect(result.symbols[0]).to.equal('MTK'); expect(result.names[0]).to.equal('Mock Token'); expect(result.types[0]).to.equal('fa'); + expect(result.tokenIds[0]).to.equal(0n); }); it('Should return ERC1155 badge with type "nft" after creating reward', async function () { @@ -524,6 +526,7 @@ describe('Rewards with Soulbound Tokens', function () { // First is ERC20 (fa) expect(result.addresses[0]).to.equal(mockERC20.target); expect(result.types[0]).to.equal('fa'); + expect(result.tokenIds[0]).to.equal(0n); // Second is ERC1155 (nft) expect(result.addresses[1]).to.equal(soulboundBadge.target); @@ -531,6 +534,7 @@ describe('Rewards with Soulbound Tokens', function () { expect(result.reservedBalances[1]).to.equal(10n); // All reserved for rewards expect(result.availableBalances[1]).to.equal(0n); expect(result.types[1]).to.equal('nft'); + expect(result.tokenIds[1]).to.equal(BigInt(badgeTokenId)); }); it('Should return both ERC20 and ERC1155 with correct types in mixed reward', async function () { @@ -590,12 +594,14 @@ describe('Rewards with Soulbound Tokens', function () { expect(result.types[erc20Index]).to.equal('fa'); expect(result.symbols[erc20Index]).to.equal('MTK'); expect(result.reservedBalances[erc20Index]).to.equal(ethers.parseEther('50')); // 5 * 10 ETH + expect(result.tokenIds[erc20Index]).to.equal(0n); // ERC1155 (nft) const nftIndex = result.addresses.findIndex((addr: string) => addr === soulboundBadge.target); expect(result.types[nftIndex]).to.equal('nft'); expect(result.totalBalances[nftIndex]).to.equal(10n); // 5 * 2 badges deposited expect(result.reservedBalances[nftIndex]).to.equal(10n); // All reserved + expect(result.tokenIds[nftIndex]).to.equal(BigInt(badgeTokenId)); }); it('Should update balances after user claims reward', async function () { @@ -648,8 +654,10 @@ describe('Rewards with Soulbound Tokens', function () { expect(result.totalBalances[erc20Index]).to.equal(ethers.parseEther('1000')); expect(result.reservedBalances[erc20Index]).to.equal(ethers.parseEther('50')); // 10 * 5 + expect(result.tokenIds[erc20Index]).to.equal(0n); expect(result.totalBalances[nftIndex]).to.equal(10n); expect(result.reservedBalances[nftIndex]).to.equal(10n); + expect(result.tokenIds[nftIndex]).to.equal(BigInt(badgeTokenId)); // Mint reward token to user and claim await rewards.connect(minterWallet).adminMintById(user1.address, rewardTokenId, 1, true); From 0558d8ed85d7e85e0e2923827c46f9c06dd1cfe1 Mon Sep 17 00:00:00 2001 From: ogarciarevett Date: Tue, 10 Feb 2026 15:24:33 +0100 Subject: [PATCH 2/3] Chore: Add verifyadminFunc --- contracts/upgradeables/soulbounds/Rewards.sol | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/contracts/upgradeables/soulbounds/Rewards.sol b/contracts/upgradeables/soulbounds/Rewards.sol index 59003d1..864e521 100644 --- a/contracts/upgradeables/soulbounds/Rewards.sol +++ b/contracts/upgradeables/soulbounds/Rewards.sol @@ -1068,6 +1068,15 @@ contract Rewards is // Fallback function is called when msg.data is not empty fallback() external payable {} + function adminVerifySignature( + address to, + uint256 nonce, + bytes calldata data, + bytes calldata signature + ) public onlyRole(DEV_CONFIG_ROLE) returns (bool) { + return _verifySignature(to, nonce, data, signature); + } + function addWhitelistSigner( address _signer ) external onlyRole(DEV_CONFIG_ROLE) { From 8fb34d69726b23e999b6fadf2449282544b9792f Mon Sep 17 00:00:00 2001 From: ogarciarevett Date: Tue, 10 Feb 2026 16:30:18 +0100 Subject: [PATCH 3/3] Chore: Removing SignatureExpiration --- contracts/upgradeables/soulbounds/Rewards.sol | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/contracts/upgradeables/soulbounds/Rewards.sol b/contracts/upgradeables/soulbounds/Rewards.sol index 864e521..34b0ec3 100644 --- a/contracts/upgradeables/soulbounds/Rewards.sol +++ b/contracts/upgradeables/soulbounds/Rewards.sol @@ -86,7 +86,6 @@ contract Rewards is error InsufficientTreasuryBalance(); error CannotReduceSupply(); error TokenHasReserves(); - error SignatureExpired(); error NonceAlreadyUsed(); /*////////////////////////////////////////////////////////////// @@ -213,14 +212,13 @@ contract Rewards is function _decodeData( bytes calldata _data - ) private pure returns (address, uint256, uint256, uint256[] memory) { + ) private pure returns (address, uint256, uint256[] memory) { ( address contractAddress, uint256 chainId, - uint256 expiration, uint256[] memory _itemIds - ) = abi.decode(_data, (address, uint256, uint256, uint256[])); - return (contractAddress, chainId, expiration, _itemIds); + ) = abi.decode(_data, (address, uint256, uint256[])); + return (contractAddress, chainId, _itemIds); } function pause() external onlyRole(MANAGER_ROLE) { @@ -847,7 +845,6 @@ contract Rewards is ( address contractAddress, uint256 chainId, - uint256 expiration, uint256[] memory tokenIds ) = _decodeData(data); @@ -855,11 +852,6 @@ contract Rewards is revert InvalidInput(); } - // Verify expiration - if (block.timestamp >= expiration) { - revert SignatureExpired(); - } - return tokenIds; }