ShopReg.t.sol
1 // SPDX-FileCopyrightText: 2024 Mass Labs 2 // 3 // SPDX-License-Identifier: GPL-3.0-or-later 4 5 pragma solidity ^0.8.19; 6 7 import {Test, stdStorage, StdStorage} from "forge-std/Test.sol"; 8 import {ShopReg} from "../src/ShopReg.sol"; 9 10 contract ShopTest is Test { 11 using stdStorage for StdStorage; 12 13 ShopReg internal shops; 14 bytes32 internal testHash = 0x5049705e4c047d2cfeb1050cffe847c85a8dbd96e7f129a3a1007920d9c61d9a; 15 bytes32 internal testSchema = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef; 16 uint256 internal shopId = 1; 17 18 function setUp() public { 19 shops = new ShopReg(); 20 } 21 22 function testRevert_MintZeroAddress() public { 23 vm.expectRevert(); 24 shops.mint(shopId, testSchema, address(0)); 25 } 26 27 function testNeweintOwnerRegistered() public { 28 shops.mint(shopId, testSchema, address(1)); 29 uint256 slotOfNewOwner = stdstore.target(address(shops)).sig(shops.ownerOf.selector).with_key(shopId).find(); 30 31 uint160 ownerOfTokenIdOne = uint160(uint256((vm.load(address(shops), bytes32(abi.encode(slotOfNewOwner)))))); 32 assertEq(address(ownerOfTokenIdOne), address(1)); 33 } 34 35 function testBalanceIncremented() public { 36 shops.mint(shopId, testSchema, address(1)); 37 uint256 slotBalance = stdstore.target(address(shops)).sig(shops.balanceOf.selector).with_key(address(1)).find(); 38 39 uint256 balanceFirstMint = uint256(vm.load(address(shops), bytes32(slotBalance))); 40 assertEq(balanceFirstMint, 1); 41 42 shops.mint(shopId + 1, testSchema, address(1)); 43 uint256 balanceSecondMint = uint256(vm.load(address(shops), bytes32(slotBalance))); 44 assertEq(balanceSecondMint, 2); 45 } 46 47 function testRevert_accessControl() public { 48 bytes32 testHashUpdate = 0x5049705e4c047d2cfeb1050cffe847c85a8dbd96e7f129a3a1007920d9c61d9a; 49 address owner = address(3); 50 shops.mint(shopId, testSchema, owner); 51 vm.expectRevert("NOT_AUTHORIZED"); 52 shops.updateRootHash(shopId, testHashUpdate, 1); 53 } 54 55 function test_accessControl() public { 56 bytes32 testHashUpdate = 0x5049705e4c047d2cfeb1050cffe847c85a8dbd96e7f129a3a1007920d9c61d9a; 57 address owner = address(3); 58 shops.mint(shopId, testSchema, owner); 59 vm.prank(owner); 60 shops.updateRootHash(shopId, testHashUpdate, 1); 61 assertEq(testHashUpdate, shops.rootHashes(shopId)); 62 } 63 64 function test_setTokenURI() public { 65 address owner = address(3); 66 string memory uri = "test"; 67 shops.mint(shopId, testSchema, owner); 68 vm.prank(owner); 69 shops.setTokenURI(shopId, uri); 70 assertEq(uri, shops.tokenURI(shopId)); 71 } 72 73 function test_accessControl_fromRelay() public { 74 bytes32 testHashUpdate = 0x5049705e4c047d2cfeb1050cffe847c85a8dbd96e7f129a3a1007920d9c61d9a; 75 address owner = address(3); 76 shops.mint(shopId, testSchema, owner); 77 address relayAddr = address(42); 78 uint256 relayId = 23; 79 shops.mint(relayId, testSchema, relayAddr); 80 vm.prank(owner); 81 shops.addRelay(shopId, relayId); 82 uint256 wantCount = 1; 83 uint256 count = shops.getRelayCount(shopId); 84 assertEq(count, wantCount); 85 vm.prank(relayAddr); 86 shops.updateRootHash(shopId, testHashUpdate, 1); 87 assertEq(testHashUpdate, shops.rootHashes(shopId)); 88 // now remove relay and check it cant change rootHash 89 vm.prank(owner); 90 shops.removeRelay(shopId, 0); 91 vm.expectRevert("NOT_AUTHORIZED"); 92 vm.prank(relayAddr); 93 shops.updateRootHash(shopId, testHashUpdate, 2); 94 } 95 96 function test_nonceValidation() public { 97 bytes32 testHashUpdate = 0x5049705e4c047d2cfeb1050cffe847c85a8dbd96e7f129a3a1007920d9c61d9a; 98 address owner = address(3); 99 shops.mint(shopId, testSchema, owner); 100 101 vm.prank(owner); 102 shops.updateRootHash(shopId, testHashUpdate, 1); 103 assertEq(shops.nonce(shopId), 1); 104 105 // Should fail with same nonce 106 vm.expectRevert(abi.encodeWithSelector(ShopReg.InvalidNonce.selector, 1, 1)); 107 vm.prank(owner); 108 shops.updateRootHash(shopId, testHashUpdate, 1); 109 110 // Should fail with lower nonce 111 vm.expectRevert(abi.encodeWithSelector(ShopReg.InvalidNonce.selector, 1, 0)); 112 vm.prank(owner); 113 shops.updateRootHash(shopId, testHashUpdate, 0); 114 115 // Should succeed with higher nonce 116 vm.prank(owner); 117 shops.updateRootHash(shopId, testHashUpdate, 2); 118 assertEq(shops.nonce(shopId), 2); 119 } 120 121 function test_relayManagement() public { 122 address owner = address(3); 123 shops.mint(shopId, testSchema, owner); 124 125 uint256 relayId1 = 1; 126 uint256 relayId2 = 2; 127 uint256 relayId3 = 3; 128 129 // Add relays 130 vm.startPrank(owner); 131 shops.addRelay(shopId, relayId1); 132 shops.addRelay(shopId, relayId2); 133 shops.addRelay(shopId, relayId3); 134 vm.stopPrank(); 135 136 assertEq(shops.getRelayCount(shopId), 3); 137 138 uint256[] memory allRelays = shops.getAllRelays(shopId); 139 assertEq(allRelays.length, 3); 140 assertEq(allRelays[0], relayId1); 141 assertEq(allRelays[1], relayId2); 142 assertEq(allRelays[2], relayId3); 143 144 // Replace relay 145 uint256 newRelayId = 4; 146 vm.prank(owner); 147 shops.replaceRelay(shopId, 1, newRelayId); 148 149 allRelays = shops.getAllRelays(shopId); 150 assertEq(allRelays[1], newRelayId); 151 152 // Remove relay (should move last to removed position) 153 vm.prank(owner); 154 shops.removeRelay(shopId, 1); 155 156 assertEq(shops.getRelayCount(shopId), 2); 157 allRelays = shops.getAllRelays(shopId); 158 assertEq(allRelays[0], relayId1); 159 assertEq(allRelays[1], relayId3); // relayId3 moved to position 1 160 } 161 162 function test_unauthorizedRelayManagement() public { 163 address owner = address(3); 164 address notOwner = address(4); 165 shops.mint(shopId, testSchema, owner); 166 167 uint256 relayId = 1; 168 169 // Should fail for non-owner 170 vm.expectRevert("NOT_AUTHORIZED"); 171 vm.prank(notOwner); 172 shops.addRelay(shopId, relayId); 173 174 // Add relay as owner first 175 vm.prank(owner); 176 shops.addRelay(shopId, relayId); 177 178 // Should fail for non-owner to replace 179 vm.expectRevert("NOT_AUTHORIZED"); 180 vm.prank(notOwner); 181 shops.replaceRelay(shopId, 0, 2); 182 183 // Should fail for non-owner to remove 184 vm.expectRevert("NOT_AUTHORIZED"); 185 vm.prank(notOwner); 186 shops.removeRelay(shopId, 0); 187 } 188 function test_GetRelayEndPoints() public { 189 address owner = address(3); 190 shops.mint(shopId, testSchema, owner); 191 string[] memory endpoints = new string[](3); 192 endpoints[0] = "http://relay1.example.com"; 193 endpoints[1] = "http://relay2.example.com"; 194 endpoints[2] = "http://relay2b.example.com"; 195 vm.prank(owner); 196 shops.setRelayEndpoints(shopId, endpoints); 197 string[] memory foundEndpoints = shops.getRelayEndPoints(shopId); 198 assertEq(foundEndpoints.length, 3); 199 assertEq(foundEndpoints[0], "http://relay1.example.com"); 200 assertEq(foundEndpoints[1], "http://relay2.example.com"); 201 assertEq(foundEndpoints[2], "http://relay2b.example.com"); 202 } 203 }