diff --git a/.github/workflows/game7ctl.lint.yml b/.github/workflows/game7ctl.lint.yml index 4504d1b..b931861 100644 --- a/.github/workflows/game7ctl.lint.yml +++ b/.github/workflows/game7ctl.lint.yml @@ -7,7 +7,7 @@ on: - develop jobs: - build: + formatting_check: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/inventory.test.yml b/.github/workflows/inventory.test.yml index 8b6e423..8826212 100644 --- a/.github/workflows/inventory.test.yml +++ b/.github/workflows/inventory.test.yml @@ -1,42 +1,43 @@ -name: Inventory system tests - -on: - pull_request: - paths: - - "contracts/inventory/**" - - "game7ctl/game7ctl/test_inventory.py" - - "game7ctl/game7ctl/InventoryFacet.py" - - "game7ctl/game7ctl/Diamond*" - - "game7ctl/game7ctl/OwnershipFacet.py" - - ".github/workflows/inventory.test.yml" - branches: - - main - - develop -jobs: - build: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: "16" - - uses: actions/setup-python@v2 - with: - python-version: "3.9" - - name: Install ganache - run: npm install -g ganache-cli - - name: Upgrade pip - env: - BROWNIE_LIB: 1 - run: pip install -U pip - - name: Install dependencies for CLI - working-directory: game7ctl/ - env: - BROWNIE_LIB: 1 - run: | - pip install -e ".[dev]" - - name: Compile smart contracts - run: brownie compile - - name: Run tests - working-directory: game7ctl/ - run: bash test.sh game7ctl.test_inventory +# TODO: @ogarciarevett fix this using a different solc solution for compiling and testing +#name: Inventory system tests +# +#on: +# pull_request: +# paths: +# - "contracts/inventory/**" +# - "game7ctl/game7ctl/test_inventory.py" +# - "game7ctl/game7ctl/InventoryFacet.py" +# - "game7ctl/game7ctl/Diamond*" +# - "game7ctl/game7ctl/OwnershipFacet.py" +# - ".github/workflows/inventory.test.yml" +# branches: +# - main +# - develop +#jobs: +# build_and_test: +# runs-on: ubuntu-20.04 +# steps: +# - uses: actions/checkout@v3 +# - uses: actions/setup-node@v3 +# with: +# node-version: "16" +# - uses: actions/setup-python@v2 +# with: +# python-version: "3.9" +# - name: Install ganache +# run: npm install -g ganache-cli +# - name: Upgrade pip +# env: +# BROWNIE_LIB: 1 +# run: pip install -U pip +# - name: Install dependencies for CLI +# working-directory: game7ctl/ +# env: +# BROWNIE_LIB: 1 +# run: | +# pip install -e ".[dev]" +# - name: Compile smart contracts +# run: brownie compile +# - name: Run tests +# working-directory: game7ctl/ +# run: bash test.sh game7ctl.test_inventory diff --git a/README.md b/README.md index 5e7f85d..4738760 100644 --- a/README.md +++ b/README.md @@ -78,11 +78,27 @@ To see all the parameters you can pass in the deployment, run: ``` $ game7ctl dao systems --help -usage: game7ctl dao [-h] --network NETWORK [--address ADDRESS] --sender SENDER [--password PASSWORD] [--gas-price GAS_PRICE] [--max-fee-per-gas MAX_FEE_PER_GAS] - [--max-priority-fee-per-gas MAX_PRIORITY_FEE_PER_GAS] [--confirmations CONFIRMATIONS] [--nonce NONCE] [--value VALUE] [--verbose] --admin-terminus-address - ADMIN_TERMINUS_ADDRESS --admin-terminus-pool-id ADMIN_TERMINUS_POOL_ID --subject-erc721-address SUBJECT_ERC721_ADDRESS - [--diamond-cut-address DIAMOND_CUT_ADDRESS] [--diamond-address DIAMOND_ADDRESS] [--diamond-loupe-address DIAMOND_LOUPE_ADDRESS] - [--ownership-address OWNERSHIP_ADDRESS] [--inventory-facet-address INVENTORY_FACET_ADDRESS] [-o OUTFILE] +usage: game7ctl dao [-h] + --network NETWORK + --admin-terminus-address ADMIN_TERMINUS_ADDRESS + --admin-terminus-pool-id ADMIN_TERMINUS_POOL_ID + --subject-erc721-address SUBJECT_ERC721_ADDRESS + --sender SENDER + [--verify-contracts] + [--address ADDRESS] + [--password PASSWORD] + [--gas-price GAS_PRICE] + [--max-fee-per-gas MAX_FEE_PER_GAS] + [--max-priority-fee-per-gas MAX_PRIORITY_FEE_PER_GAS] + [--confirmations CONFIRMATIONS] + [--nonce NONCE] [--value VALUE] + [--verbose] + [--diamond-cut-address DIAMOND_CUT_ADDRESS] + [--diamond-address DIAMOND_ADDRESS] + [--diamond-loupe-address DIAMOND_LOUPE_ADDRESS] + [--ownership-address OWNERSHIP_ADDRESS] + [--inventory-facet-address INVENTORY_FACET_ADDRESS] + [-o OUTFILE] Deploy Inventory diamond contract @@ -103,6 +119,7 @@ options: --nonce NONCE Nonce for the transaction (optional) --value VALUE Value of the transaction in wei(optional) --verbose Print verbose output + --verify-contracts Verify contracts on the EVM that you deploy to --admin-terminus-address ADMIN_TERMINUS_ADDRESS Address of Terminus contract defining access control for this GardenOfForkingPaths contract --admin-terminus-pool-id ADMIN_TERMINUS_POOL_ID @@ -167,3 +184,10 @@ Using a command like this: game7ctl dao systems --network --admin-terminus-address --admin-terminus-pool-id --sender --subject-erc721-address ``` +# Local development tools + +`black@23.1.0` (for formatting, use this same version to avoid problems with the CI) + +How run this? + +Use `black ` to format the code. diff --git a/brownie-config.yaml b/brownie-config.yaml index de9a770..bcfb9b9 100644 --- a/brownie-config.yaml +++ b/brownie-config.yaml @@ -1,7 +1,7 @@ dotenv: .env dependencies: - - "OpenZeppelin/openzeppelin-contracts@4.4.0" + - "OpenZeppelin/openzeppelin-contracts@4.3.2" - "bugout-dev/dao@0.0.7" - "bugout-dev/engine@0.0.3" @@ -9,7 +9,7 @@ compiler: solc: version: 0.8.17 remappings: - - "@openzeppelin-contracts=OpenZeppelin/openzeppelin-contracts@4.4.0" - - "@openzeppelin/contracts=OpenZeppelin/openzeppelin-contracts@4.4.0" + - "@openzeppelin-contracts=OpenZeppelin/openzeppelin-contracts@4.3.2" + - "@openzeppelin/contracts=OpenZeppelin/openzeppelin-contracts@4.3.2" - "@moonstream=bugout-dev/dao@0.0.7" - "@moonstream-engine=bugout-dev/engine@0.0.3" diff --git a/contracts/diamond/Diamond.sol b/contracts/diamond/Diamond.sol index 285f2b9..62574f9 100644 --- a/contracts/diamond/Diamond.sol +++ b/contracts/diamond/Diamond.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; // Adapted from the Diamond 3 reference implementation by Nick Mudge: // https://github.com/mudgen/diamond-3-hardhat diff --git a/contracts/facets/DiamondCutFacet.sol b/contracts/facets/DiamondCutFacet.sol index f6fd15e..1caecbf 100644 --- a/contracts/facets/DiamondCutFacet.sol +++ b/contracts/facets/DiamondCutFacet.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; // Adapted from the Diamond 3 reference implementation by Nick Mudge: // https://github.com/mudgen/diamond-3-hardhat diff --git a/contracts/facets/DiamondLoupeFacet.sol b/contracts/facets/DiamondLoupeFacet.sol index 6e67fc0..f6cb249 100644 --- a/contracts/facets/DiamondLoupeFacet.sol +++ b/contracts/facets/DiamondLoupeFacet.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; // Adapted from the Diamond 3 reference implementation by Nick Mudge: // https://github.com/mudgen/diamond-3-hardhat diff --git a/contracts/facets/InventoryFacet.sol b/contracts/facets/InventoryFacet.sol index 3459c7f..18da91b 100644 --- a/contracts/facets/InventoryFacet.sol +++ b/contracts/facets/InventoryFacet.sol @@ -5,7 +5,7 @@ * GitHub: https://github.com/G7DAO/contracts */ -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; import {TerminusPermissions} from "@moonstream/contracts/terminus/TerminusPermissions.sol"; import {DiamondReentrancyGuard} from "@moonstream-engine/contracts/diamond/security/DiamondReentrancyGuard.sol"; @@ -140,22 +140,34 @@ contract InventoryFacet is SlotId: newSlot }); - emit SlotCreated(msg.sender, newSlot, unequippable); + emit SlotCreated(msg.sender, newSlot, unequippable, slotType); return newSlot; } - function setSlotType(uint256 slotType, string memory slotTypeName) external onlyAdmin { + function createSlotType(uint256 slotType, string memory slotTypeName) external onlyAdmin { + require( + bytes(slotTypeName).length > 0, + "InventoryFacet.setSlotType: Slot type name must be non-empty"); + require(slotType > 0, "InventoryFacet.setSlotType: Slot type must be greater than 0"); LibInventory.InventoryStorage storage istore = LibInventory.inventoryStorage(); istore.SlotTypes[slotType] = slotTypeName; emit NewSlotTypeAdded(msg.sender, slotType, slotTypeName); } + function addSlotType(uint256 slot, uint256 slotType) external onlyAdmin { + require(slotType > 0, "InventoryFacet.addSlotType: SlotType must be greater than 0"); + + LibInventory.InventoryStorage storage istore = LibInventory.inventoryStorage(); + istore.SlotData[slot].SlotType = slotType; + emit SlotTypeAdded(msg.sender, slot, slotType); + } + function getSlotType(uint256 slotType) external view returns(string memory slotTypeName) { LibInventory.InventoryStorage storage istore = LibInventory.inventoryStorage(); return istore.SlotTypes[slotType]; } - function addBackPackToSubject( + function addBackpackToSubject( uint256 slotQty, uint256 toSubjectTokenId, uint256 slotType, @@ -164,7 +176,7 @@ contract InventoryFacet is require( slotQty > 0, - "InventoryFacet.addBackPackToSubject: Slot quantity must be greater than 0" + "InventoryFacet.addBackpackToSubject: Slot quantity must be greater than 0" ); LibInventory.InventoryStorage storage istore = LibInventory.inventoryStorage(); @@ -177,9 +189,6 @@ contract InventoryFacet is SlotType: slotType, SlotURI: slotURI, SlotIsUnequippable: false, - // previousSlotNumSubject = 3 - // previousSlotNumSubject + i = 3;(first iteration) - // previousSlotNumSubject + 1 = 4; SlotId: previousSlotNumSubject + i == previousSlotNumSubject ? previousSlotNumSubject + 1: previousSlotNumSubject + i }) ); @@ -204,10 +213,9 @@ contract InventoryFacet is return LibInventory.inventoryStorage().NumSlots; } - function getSlotById(uint256 subjectTokenId, uint slotId) + function getSlotById(uint256 slotId) external view - onlyAdmin returns (LibInventory.Slot memory slot) { return LibInventory.inventoryStorage().SlotData[slotId]; @@ -234,6 +242,15 @@ contract InventoryFacet is return LibInventory.inventoryStorage().SlotData[slotId].SlotIsUnequippable; } + function setSlotUnequippable(bool unquippable, uint256 slotId) external onlyAdmin () { + LibInventory.InventoryStorage storage istore = LibInventory + .inventoryStorage(); + + LibInventory.Slot memory slot = istore.SlotData[slotId]; + slot.SlotIsUnequippable = unquippable; + istore.SlotData[slotId] = slot; + } + function markItemAsEquippableInSlot( uint256 slot, uint256 itemType, @@ -500,6 +517,8 @@ contract InventoryFacet is LibInventory.InventoryStorage storage istore = LibInventory .inventoryStorage(); + require(slot <= this.numSlots(), "InventoryFacet.getEquippedItem: Slot does not exist"); + LibInventory.EquippedItem memory equippedItem = istore.EquippedItems[ istore.ContractERC721Address ][subjectTokenId][slot]; diff --git a/contracts/facets/OwnershipFacet.sol b/contracts/facets/OwnershipFacet.sol index 4427236..c7e71d3 100644 --- a/contracts/facets/OwnershipFacet.sol +++ b/contracts/facets/OwnershipFacet.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; import {LibDiamond} from "../libraries/LibDiamond.sol"; import {IERC173} from "../interfaces/IERC173.sol"; diff --git a/contracts/interfaces/IDiamond.sol b/contracts/interfaces/IDiamond.sol index bb1fd45..451b972 100644 --- a/contracts/interfaces/IDiamond.sol +++ b/contracts/interfaces/IDiamond.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; interface IDiamond { fallback() external payable; diff --git a/contracts/interfaces/IDiamondCut.sol b/contracts/interfaces/IDiamondCut.sol index c63042d..3269816 100644 --- a/contracts/interfaces/IDiamondCut.sol +++ b/contracts/interfaces/IDiamondCut.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; // Adapted from the Diamond 3 reference implementation by Nick Mudge: // https://github.com/mudgen/diamond-3-hardhat diff --git a/contracts/interfaces/IDiamondLoupe.sol b/contracts/interfaces/IDiamondLoupe.sol index 353df81..95ffe2e 100644 --- a/contracts/interfaces/IDiamondLoupe.sol +++ b/contracts/interfaces/IDiamondLoupe.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; // Adapted from the Diamond 3 reference implementation by Nick Mudge: // https://github.com/mudgen/diamond-3-hardhat diff --git a/contracts/interfaces/IERC165.sol b/contracts/interfaces/IERC165.sol index 04b7bcc..dc96b3b 100644 --- a/contracts/interfaces/IERC165.sol +++ b/contracts/interfaces/IERC165.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; interface IERC165 { /// @notice Query if a contract implements an interface diff --git a/contracts/interfaces/IERC173.sol b/contracts/interfaces/IERC173.sol index 20ca767..db9da1e 100644 --- a/contracts/interfaces/IERC173.sol +++ b/contracts/interfaces/IERC173.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; /// @title ERC-173 Contract Ownership Standard interface IERC173 { diff --git a/contracts/interfaces/IInventory.sol b/contracts/interfaces/IInventory.sol index 590623e..025e331 100644 --- a/contracts/interfaces/IInventory.sol +++ b/contracts/interfaces/IInventory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; import "../libraries/LibInventory.sol"; @@ -13,7 +13,7 @@ interface IInventory { event ContractAddressDesignated(address indexed contractAddress); - event SlotCreated(address indexed creator, uint256 slot, bool unequippable); + event SlotCreated(address indexed creator, uint256 indexed slot, bool unequippable, uint256 indexed slotType); event NewSlotTypeAdded(address indexed creator, uint256 indexed slotType, string slotTypeName); @@ -25,9 +25,11 @@ interface IInventory { uint256 maxAmount ); - event BackpackAdded(address indexed creator, uint indexed toSubjectTokenId, uint256 indexed slotQuantity); + event BackpackAdded(address indexed creator, uint256 indexed toSubjectTokenId, uint256 indexed slotQuantity); - event NewSlotURI(uint indexed slotId); + event NewSlotURI(uint256 indexed slotId); + + event SlotTypeAdded(address indexed creator, uint256 indexed slotId, uint256 indexed slotType); event ItemEquipped( uint256 indexed subjectTokenId, @@ -102,7 +104,7 @@ interface IInventory { view returns (LibInventory.EquippedItem memory item); - function getSlotById(uint256 subjectTokenId, uint slotId) + function getSlotById(uint256 slotId) external view returns (LibInventory.Slot memory slots); @@ -112,7 +114,7 @@ interface IInventory { view returns(LibInventory.Slot[] memory slot); - function addBackPackToSubject( + function addBackpackToSubject( uint256 slotQty, uint256 toSubjectTokenId, uint256 slotType, @@ -121,7 +123,11 @@ interface IInventory { function getSlotURI(uint256 slotId) external view returns (string memory); - function setSlotType(uint256 slotType, string memory slotTypeName) external; + function createSlotType(uint256 slotType, string memory slotTypeName) external; + + function addSlotType(uint256 slot, uint256 slotType) external; function getSlotType(uint256 slotType) external view returns(string memory slotTypeName); + + function setSlotUnequippable(bool unquippable, uint256 slotId) external; } \ No newline at end of file diff --git a/contracts/libraries/LibDiamond.sol b/contracts/libraries/LibDiamond.sol index 5f0c982..b725384 100644 --- a/contracts/libraries/LibDiamond.sol +++ b/contracts/libraries/LibDiamond.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; // Adapted from the Diamond 3 reference implementation by Nick Mudge: // https://github.com/mudgen/diamond-3-hardhat diff --git a/contracts/libraries/LibInventory.sol b/contracts/libraries/LibInventory.sol index 3f5bc44..0ec6fc4 100644 --- a/contracts/libraries/LibInventory.sol +++ b/contracts/libraries/LibInventory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; /** LibInventory defines the storage structure used by the Inventory contract as a facet for an EIP-2535 Diamond diff --git a/contracts/mock/MockERC1155.sol b/contracts/mock/MockERC1155.sol index f14c7cb..5665fbe 100644 --- a/contracts/mock/MockERC1155.sol +++ b/contracts/mock/MockERC1155.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: UNLICENSED ///@notice This contract is for mock for WETH token. -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; import "@openzeppelin-contracts/contracts/token/ERC1155/extensions/ERC1155Burnable.sol"; diff --git a/contracts/mock/MockERC20.sol b/contracts/mock/MockERC20.sol index ec4af50..9792113 100644 --- a/contracts/mock/MockERC20.sol +++ b/contracts/mock/MockERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: UNLICENSED ///@notice This contract is for mock for WETH token. -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; import "@openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol"; diff --git a/contracts/mock/MockERC721.sol b/contracts/mock/MockERC721.sol index cf9aec5..4b8a464 100644 --- a/contracts/mock/MockERC721.sol +++ b/contracts/mock/MockERC721.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; import "@openzeppelin-contracts/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; diff --git a/contracts/mock/MockTerminus.sol b/contracts/mock/MockTerminus.sol index c014b20..91e92d8 100644 --- a/contracts/mock/MockTerminus.sol +++ b/contracts/mock/MockTerminus.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: UNLICENSED ///@notice This contract is for mock for terminus token (used only for cli generation). -pragma solidity ^0.8.0; +pragma solidity ^0.8.17; import "@moonstream/contracts/terminus/TerminusFacet.sol"; diff --git a/game7ctl/game7ctl/InventoryFacet.py b/game7ctl/game7ctl/InventoryFacet.py index d4344c0..6cc3caa 100644 --- a/game7ctl/game7ctl/InventoryFacet.py +++ b/game7ctl/game7ctl/InventoryFacet.py @@ -96,7 +96,7 @@ def verify_contract(self): contract_class = contract_from_build(self.contract_name) contract_class.publish_source(self.contract) - def add_back_pack_to_subject( + def add_backpack_to_subject( self, slot_qty: int, to_subject_token_id: int, @@ -105,10 +105,14 @@ def add_back_pack_to_subject( transaction_config, ) -> Any: self.assert_contract_is_instantiated() - return self.contract.addBackPackToSubject( + return self.contract.addBackpackToSubject( slot_qty, to_subject_token_id, slot_type, slot_uri, transaction_config ) + def add_slot_type(self, slot: int, slot_type: int, transaction_config) -> Any: + self.assert_contract_is_instantiated() + return self.contract.addSlotType(slot, slot_type, transaction_config) + def admin_terminus_info( self, block_number: Optional[Union[str, int]] = "latest" ) -> Any: @@ -123,6 +127,14 @@ def create_slot( unequippable, slot_type, slot_uri, transaction_config ) + def create_slot_type( + self, slot_type: int, slot_type_name: str, transaction_config + ) -> Any: + self.assert_contract_is_instantiated() + return self.contract.createSlotType( + slot_type, slot_type_name, transaction_config + ) + def equip( self, subject_token_id: int, @@ -156,15 +168,10 @@ def get_equipped_item( ) def get_slot_by_id( - self, - subject_token_id: int, - slot_id: int, - block_number: Optional[Union[str, int]] = "latest", + self, slot_id: int, block_number: Optional[Union[str, int]] = "latest" ) -> Any: self.assert_contract_is_instantiated() - return self.contract.getSlotById.call( - subject_token_id, slot_id, block_identifier=block_number - ) + return self.contract.getSlotById.call(slot_id, block_identifier=block_number) def get_slot_type( self, slot_type: int, block_number: Optional[Union[str, int]] = "latest" @@ -273,11 +280,13 @@ def on_erc721_received( arg1, arg2, arg3, arg4, transaction_config ) - def set_slot_type( - self, slot_type: int, slot_type_name: str, transaction_config + def set_slot_unequippable( + self, unquippable: bool, slot_id: int, transaction_config ) -> Any: self.assert_contract_is_instantiated() - return self.contract.setSlotType(slot_type, slot_type_name, transaction_config) + return self.contract.setSlotUnequippable( + unquippable, slot_id, transaction_config + ) def set_slot_uri(self, new_slot_uri: str, slot_id: int, transaction_config) -> Any: self.assert_contract_is_instantiated() @@ -401,11 +410,11 @@ def handle_verify_contract(args: argparse.Namespace) -> None: print(result) -def handle_add_back_pack_to_subject(args: argparse.Namespace) -> None: +def handle_add_backpack_to_subject(args: argparse.Namespace) -> None: network.connect(args.network) contract = InventoryFacet(args.address) transaction_config = get_transaction_config(args) - result = contract.add_back_pack_to_subject( + result = contract.add_backpack_to_subject( slot_qty=args.slot_qty, to_subject_token_id=args.to_subject_token_id, slot_type=args.slot_type, @@ -417,6 +426,18 @@ def handle_add_back_pack_to_subject(args: argparse.Namespace) -> None: print(result.info()) +def handle_add_slot_type(args: argparse.Namespace) -> None: + network.connect(args.network) + contract = InventoryFacet(args.address) + transaction_config = get_transaction_config(args) + result = contract.add_slot_type( + slot=args.slot, slot_type=args.slot_type, transaction_config=transaction_config + ) + print(result) + if args.verbose: + print(result.info()) + + def handle_admin_terminus_info(args: argparse.Namespace) -> None: network.connect(args.network) contract = InventoryFacet(args.address) @@ -439,6 +460,20 @@ def handle_create_slot(args: argparse.Namespace) -> None: print(result.info()) +def handle_create_slot_type(args: argparse.Namespace) -> None: + network.connect(args.network) + contract = InventoryFacet(args.address) + transaction_config = get_transaction_config(args) + result = contract.create_slot_type( + slot_type=args.slot_type, + slot_type_name=args.slot_type_name, + transaction_config=transaction_config, + ) + print(result) + if args.verbose: + print(result.info()) + + def handle_equip(args: argparse.Namespace) -> None: network.connect(args.network) contract = InventoryFacet(args.address) @@ -472,9 +507,7 @@ def handle_get_slot_by_id(args: argparse.Namespace) -> None: network.connect(args.network) contract = InventoryFacet(args.address) result = contract.get_slot_by_id( - subject_token_id=args.subject_token_id, - slot_id=args.slot_id, - block_number=args.block_number, + slot_id=args.slot_id, block_number=args.block_number ) print(result) @@ -606,13 +639,13 @@ def handle_on_erc721_received(args: argparse.Namespace) -> None: print(result.info()) -def handle_set_slot_type(args: argparse.Namespace) -> None: +def handle_set_slot_unequippable(args: argparse.Namespace) -> None: network.connect(args.network) contract = InventoryFacet(args.address) transaction_config = get_transaction_config(args) - result = contract.set_slot_type( - slot_type=args.slot_type, - slot_type_name=args.slot_type_name, + result = contract.set_slot_unequippable( + unquippable=args.unquippable, + slot_id=args.slot_id, transaction_config=transaction_config, ) print(result) @@ -688,21 +721,31 @@ def generate_cli() -> argparse.ArgumentParser: add_default_arguments(verify_contract_parser, False) verify_contract_parser.set_defaults(func=handle_verify_contract) - add_back_pack_to_subject_parser = subcommands.add_parser("add-back-pack-to-subject") - add_default_arguments(add_back_pack_to_subject_parser, True) - add_back_pack_to_subject_parser.add_argument( + add_backpack_to_subject_parser = subcommands.add_parser("add-backpack-to-subject") + add_default_arguments(add_backpack_to_subject_parser, True) + add_backpack_to_subject_parser.add_argument( "--slot-qty", required=True, help="Type: uint256", type=int ) - add_back_pack_to_subject_parser.add_argument( + add_backpack_to_subject_parser.add_argument( "--to-subject-token-id", required=True, help="Type: uint256", type=int ) - add_back_pack_to_subject_parser.add_argument( + add_backpack_to_subject_parser.add_argument( "--slot-type", required=True, help="Type: uint256", type=int ) - add_back_pack_to_subject_parser.add_argument( + add_backpack_to_subject_parser.add_argument( "--slot-uri", required=True, help="Type: string", type=str ) - add_back_pack_to_subject_parser.set_defaults(func=handle_add_back_pack_to_subject) + add_backpack_to_subject_parser.set_defaults(func=handle_add_backpack_to_subject) + + add_slot_type_parser = subcommands.add_parser("add-slot-type") + add_default_arguments(add_slot_type_parser, True) + add_slot_type_parser.add_argument( + "--slot", required=True, help="Type: uint256", type=int + ) + add_slot_type_parser.add_argument( + "--slot-type", required=True, help="Type: uint256", type=int + ) + add_slot_type_parser.set_defaults(func=handle_add_slot_type) admin_terminus_info_parser = subcommands.add_parser("admin-terminus-info") add_default_arguments(admin_terminus_info_parser, False) @@ -721,6 +764,16 @@ def generate_cli() -> argparse.ArgumentParser: ) create_slot_parser.set_defaults(func=handle_create_slot) + create_slot_type_parser = subcommands.add_parser("create-slot-type") + add_default_arguments(create_slot_type_parser, True) + create_slot_type_parser.add_argument( + "--slot-type", required=True, help="Type: uint256", type=int + ) + create_slot_type_parser.add_argument( + "--slot-type-name", required=True, help="Type: string", type=str + ) + create_slot_type_parser.set_defaults(func=handle_create_slot_type) + equip_parser = subcommands.add_parser("equip") add_default_arguments(equip_parser, True) equip_parser.add_argument( @@ -749,9 +802,6 @@ def generate_cli() -> argparse.ArgumentParser: get_slot_by_id_parser = subcommands.add_parser("get-slot-by-id") add_default_arguments(get_slot_by_id_parser, False) - get_slot_by_id_parser.add_argument( - "--subject-token-id", required=True, help="Type: uint256", type=int - ) get_slot_by_id_parser.add_argument( "--slot-id", required=True, help="Type: uint256", type=int ) @@ -892,15 +942,15 @@ def generate_cli() -> argparse.ArgumentParser: ) on_erc721_received_parser.set_defaults(func=handle_on_erc721_received) - set_slot_type_parser = subcommands.add_parser("set-slot-type") - add_default_arguments(set_slot_type_parser, True) - set_slot_type_parser.add_argument( - "--slot-type", required=True, help="Type: uint256", type=int + set_slot_unequippable_parser = subcommands.add_parser("set-slot-unequippable") + add_default_arguments(set_slot_unequippable_parser, True) + set_slot_unequippable_parser.add_argument( + "--unquippable", required=True, help="Type: bool", type=boolean_argument_type ) - set_slot_type_parser.add_argument( - "--slot-type-name", required=True, help="Type: string", type=str + set_slot_unequippable_parser.add_argument( + "--slot-id", required=True, help="Type: uint256", type=int ) - set_slot_type_parser.set_defaults(func=handle_set_slot_type) + set_slot_unequippable_parser.set_defaults(func=handle_set_slot_unequippable) set_slot_uri_parser = subcommands.add_parser("set-slot-uri") add_default_arguments(set_slot_uri_parser, True) diff --git a/game7ctl/game7ctl/cli.py b/game7ctl/game7ctl/cli.py index 25bdd22..04abe10 100644 --- a/game7ctl/game7ctl/cli.py +++ b/game7ctl/game7ctl/cli.py @@ -1,7 +1,7 @@ import argparse from typing import Callable -from .core import generate_cli as core_generate_cli +from .dao import generate_cli as core_generate_cli from .InventoryFacet import generate_cli as inventory_generate_cli from .DiamondLoupeFacet import generate_cli as dloupe_generate_cli from .DiamondCutFacet import generate_cli as dcut_generate_cli diff --git a/game7ctl/game7ctl/core.py b/game7ctl/game7ctl/dao.py similarity index 94% rename from game7ctl/game7ctl/core.py rename to game7ctl/game7ctl/dao.py index 87919fa..b53ad14 100644 --- a/game7ctl/game7ctl/core.py +++ b/game7ctl/game7ctl/dao.py @@ -188,11 +188,12 @@ def diamond( diamond_address: Optional[str] = None, diamond_loupe_address: Optional[str] = None, ownership_address: Optional[str] = None, + verify_contracts: Optional[bool] = False, ) -> Dict[str, Any]: """ Deploy diamond along with all its basic facets and attach those facets to the diamond. - Returns addresses of all the deployed contracts with the contract names as keys. + Return addresses of all the deployed contracts with the contract names as keys. """ result: Dict[str, Any] = {"contracts": {}, "attached": []} @@ -276,6 +277,18 @@ def diamond( return result result["attached"].append("OwnershipFacet") + if verify_contracts: + try: + diamond_cut_facet.verify_contract() + diamond.verify_contract() + diamond_loupe_facet.verify_contract() + ownership_facet.verify_contract() + + except Exception as e: + print(e) + result["error"] = "Failed to verify Diamond Facets" + return result + result["verified_diamond_facets"] = True return result @@ -289,6 +302,7 @@ def systems( diamond_loupe_address: Optional[str] = None, ownership_address: Optional[str] = None, inventory_facet_address: Optional[str] = None, + verify_contracts: Optional[bool] = False, ) -> Dict[str, Any]: """ Deploys an EIP2535 Diamond contract and an InventoryFacet and mounts the InventoryFacet onto the Diamond contract. @@ -302,6 +316,7 @@ def systems( diamond_address=diamond_address, diamond_loupe_address=diamond_loupe_address, ownership_address=ownership_address, + verify_contracts=verify_contracts, ) if inventory_facet_address is None: @@ -310,6 +325,9 @@ def systems( else: inventory_facet = InventoryFacet.InventoryFacet(inventory_facet_address) + if verify_contracts: + inventory_facet.verify_contract() + deployment_info["contracts"]["InventoryFacet"] = inventory_facet.address facet_cut( @@ -366,6 +384,7 @@ def handle_systems(args: argparse.Namespace) -> None: diamond_loupe_address=args.diamond_loupe_address, ownership_address=args.ownership_address, inventory_facet_address=args.inventory_facet_address, + verify_contracts=args.verify_contracts, ) if args.outfile is not None: with args.outfile: @@ -407,6 +426,7 @@ def generate_cli(): facet_cut_parser.add_argument( "--initializer-address", default=ZERO_ADDRESS, + required=True, help=f"Address of contract to run as initializer after cut (default: {ZERO_ADDRESS})", ) facet_cut_parser.add_argument( @@ -439,6 +459,11 @@ def generate_cli(): description="Deploy G7 diamond contract", ) Diamond.add_default_arguments(contracts_parser, transact=True) + contracts_parser.add_argument( + "--verify-contracts", + action="store_true", + help="Verify contracts", + ) contracts_parser.add_argument( "--admin-terminus-address", required=True, diff --git a/game7ctl/game7ctl/inventory_events.py b/game7ctl/game7ctl/inventory_events.py index 53af594..f42af42 100644 --- a/game7ctl/game7ctl/inventory_events.py +++ b/game7ctl/game7ctl/inventory_events.py @@ -42,7 +42,7 @@ "type": "address", }, { - "indexed": False, + "indexed": True, "internalType": "uint256", "name": "slot", "type": "uint256", @@ -53,6 +53,12 @@ "name": "unequippable", "type": "bool", }, + { + "indexed": True, + "internalType": "uint256", + "name": "slotType", + "type": "uint256", + }, ], "name": "SlotCreated", "type": "event", diff --git a/game7ctl/game7ctl/test_inventory.py b/game7ctl/game7ctl/test_inventory.py index 536c32e..0baa78e 100644 --- a/game7ctl/game7ctl/test_inventory.py +++ b/game7ctl/game7ctl/test_inventory.py @@ -6,7 +6,7 @@ from moonworm.watch import _fetch_events_chunk from . import InventoryFacet, MockERC20, MockERC721, MockTerminus, inventory_events -from .core import systems +from .dao import systems MAX_UINT = 2**256 - 1 @@ -199,7 +199,7 @@ def test_admin_can_add_backpacks_to_subject_token(self): self.assertEqual(num_slots_1, 1) # admin adds 10 more slots to the subject token - self.inventory.add_back_pack_to_subject( + self.inventory.add_backpack_to_subject( 10, subject_token_id, 0, @@ -285,7 +285,7 @@ def test_admin_cannot_get_subject_slots(self): num_slots_0 = self.inventory.num_slots() # admin adds 10 more slots to the subject token - self.inventory.add_back_pack_to_subject( + self.inventory.add_backpack_to_subject( 10, subject_token_id, 0, @@ -318,7 +318,7 @@ def test_noadmin_cannot_add_backpack_to_subject(self): # set the slot uri with self.assertRaises(VirtualMachineError): # admin adds 10 more slots to the subject token - self.inventory.add_back_pack_to_subject( + self.inventory.add_backpack_to_subject( 10, subject_token_id, 0, diff --git a/scripts/deploy_shiba_erc721.py b/scripts/deploy_shiba_erc721.py deleted file mode 100644 index 9e12ab3..0000000 --- a/scripts/deploy_shiba_erc721.py +++ /dev/null @@ -1,10 +0,0 @@ -from brownie import ShibaERC721, accounts, network, config - -def main(): - dev = accounts.load('deployment_account') - - shiba = ShibaERC721.deploy( - {"from": dev}, - publish_source=True - ) - return shiba diff --git a/scripts/mint_shiba_nft.py b/scripts/mint_shiba_nft.py deleted file mode 100644 index d3ccfe2..0000000 --- a/scripts/mint_shiba_nft.py +++ /dev/null @@ -1,12 +0,0 @@ -# mint 1 shiba nft using brownie with the smart contract - -from brownie import ShibaERC721, accounts, network - -def main(): - dev = accounts.load('deployment_account') - print(network.show_active()) - shiba_nft = ShibaERC721[len(ShibaERC721) - 1] - transaction = shiba_nft.safeMint("ADDRESS_HERE", "URI_HERE", {"from": dev}) - transaction.wait(1) - # show the nft on polygon mumbai scan, var env $POLYGONSCAN_TOKEN required - print("https://mumbai.polygonscan.com/tx/" + transaction.txid)