Skip to content

Commit

Permalink
Added test for equipping on top of an already equipped slot
Browse files Browse the repository at this point in the history
  • Loading branch information
zomglings committed Jan 10, 2023
1 parent 0b02aeb commit 456ec8e
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 16 deletions.
27 changes: 11 additions & 16 deletions contracts/inventory/Inventory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -385,22 +385,18 @@ contract InventoryFacet is
"InventoryFacet.equip: Message sender is not owner of subject token"
);

LibInventory.EquippedItem memory existingItem = istore.EquippedItems[
istore.SubjectERC721Address
][subjectTokenId][slot];

// TODO(zomglings): To set things up, we will only test equipping workflow. To make it
// so that tokens cannot be unequipped, we require that the existingItem.ItemType be zero.
// We will turn this off when we add support for unequipping items from unequippable slots
// and when we want to add support for reupping items of the same already equipped type into
// a slot.
require(
existingItem.ItemType == 0,
"InventoryFacet.equip: This is a temporary restriction that no item can already be equipped in the given slot"
);
// TODO(zomglings): Although this does the job, it is not gas-efficient if the caller is
// increasing the amount of an existing token in the given slot. To increase gas-efficiency,
// we could add more complex logic here to handle that situation by only equipping the difference
// between the existing amount of the token and the target amount.
if (
istore
.EquippedItems[istore.SubjectERC721Address][subjectTokenId][slot]
.ItemType != 0
) {
_unequip(subjectTokenId, slot, true, 0);
}

// TODO(zomglings): When we support reupping items, we will need to modify the amount in the check
// below to amount + existingItem.amount.
require(
// Note the if statement when accessing the itemPoolId key in the SlotEligibleItems mapping.
// That field is only relevant for ERC1155 tokens. For ERC20 and ERC721 tokens, the capacity
Expand All @@ -413,7 +409,6 @@ contract InventoryFacet is
"InventoryFacet.equip: You can not equip those many instances of that item into the given slot"
);

// TODO(zomglings): Add case here when we need to support unequipping.
if (itemType == LibInventory.ERC20_ITEM_TYPE) {
IERC20 erc20Contract = IERC20(itemAddress);
bool erc20TransferSuccess = erc20Contract.transferFrom(
Expand Down
190 changes: 190 additions & 0 deletions game7ctl/game7ctl/test_inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -1472,3 +1472,193 @@ def test_player_can_unequip_all_erc1155_items_in_slot_on_their_subject_tokens(se
item_unequipped_events[0]["args"]["unequippedBy"],
self.player.address,
)

def test_player_can_equip_an_item_and_then_replace_it_onto_their_subject_tokens_20_then_1155(
self,
):
# Mint tokens to player and set approvals
subject_token_id = self.nft.total_supply()
self.nft.mint(self.player.address, subject_token_id, {"from": self.owner})

self.payment_token.mint(self.player.address, 1000, {"from": self.owner})
self.payment_token.approve(
self.inventory.address, MAX_UINT, {"from": self.player}
)

self.terminus.create_pool_v1(MAX_UINT, True, True, self.owner_tx_config)
item_pool_id = self.terminus.total_pools()
self.terminus.mint(
self.player.address, item_pool_id, 100, "", self.owner_tx_config
)
self.terminus.set_approval_for_all(
self.inventory.address, True, {"from": self.player}
)

# Create inventory slot
unequippable = True
self.inventory.create_slot(unequippable, {"from": self.admin})
slot = self.inventory.num_slots()

# Set ERC20 token as equippable in slot with max amount of 10
self.inventory.mark_item_as_equippable_in_slot(
slot, 20, self.payment_token.address, 0, 10, {"from": self.admin}
)

# Set ERC1155 token as equippable in slot with max amount of 10
self.inventory.mark_item_as_equippable_in_slot(
slot, 1155, self.terminus.address, item_pool_id, 10, {"from": self.admin}
)

player_erc20_balance_0 = self.payment_token.balance_of(self.player.address)
inventory_erc20_balance_0 = self.payment_token.balance_of(
self.inventory.address
)

tx_receipt_0 = self.inventory.equip(
subject_token_id,
slot,
20,
self.payment_token.address,
0,
2,
{"from": self.player},
)

player_erc20_balance_1 = self.payment_token.balance_of(self.player.address)
inventory_erc20_balance_1 = self.payment_token.balance_of(
self.inventory.address
)

self.assertEqual(player_erc20_balance_1, player_erc20_balance_0 - 2)
self.assertEqual(inventory_erc20_balance_1, inventory_erc20_balance_0 + 2)

equipped_item = self.inventory.equipped(subject_token_id, slot)
self.assertEqual(equipped_item, (20, self.payment_token.address, 0, 2))

player_erc1155_balance_1 = self.terminus.balance_of(
self.player.address, item_pool_id
)
inventory_erc1155_balance_1 = self.terminus.balance_of(
self.inventory.address, item_pool_id
)

tx_receipt_1 = self.inventory.equip(
subject_token_id,
slot,
1155,
self.terminus.address,
item_pool_id,
9,
{"from": self.player},
)

player_erc20_balance_2 = self.payment_token.balance_of(self.player.address)
inventory_erc20_balance_2 = self.payment_token.balance_of(
self.inventory.address
)

self.assertEqual(player_erc20_balance_2, player_erc20_balance_0)
self.assertEqual(inventory_erc20_balance_2, inventory_erc20_balance_0)

equipped_item = self.inventory.equipped(subject_token_id, slot)
self.assertEqual(equipped_item, (1155, self.terminus.address, item_pool_id, 9))

player_erc1155_balance_2 = self.terminus.balance_of(
self.player.address, item_pool_id
)
inventory_erc1155_balance_2 = self.terminus.balance_of(
self.inventory.address, item_pool_id
)

self.assertEqual(player_erc1155_balance_2, player_erc1155_balance_1 - 9)
self.assertEqual(inventory_erc1155_balance_2, inventory_erc1155_balance_1 + 9)

item_equipped_events = _fetch_events_chunk(
web3_client,
inventory_events.ITEM_EQUIPPED_ABI,
from_block=tx_receipt_0.block_number,
to_block=tx_receipt_1.block_number,
)
self.assertEqual(len(item_equipped_events), 2)

self.assertEqual(
item_equipped_events[0]["args"]["subjectTokenId"], subject_token_id
)
self.assertEqual(item_equipped_events[0]["args"]["slot"], slot)
self.assertEqual(
item_equipped_events[0]["args"]["itemType"],
20,
)
self.assertEqual(
item_equipped_events[0]["args"]["itemAddress"],
self.payment_token.address,
)
self.assertEqual(
item_equipped_events[0]["args"]["itemTokenId"],
0,
)
self.assertEqual(
item_equipped_events[0]["args"]["amount"],
2,
)
self.assertEqual(
item_equipped_events[0]["args"]["equippedBy"],
self.player.address,
)

self.assertEqual(
item_equipped_events[1]["args"]["subjectTokenId"], subject_token_id
)
self.assertEqual(item_equipped_events[1]["args"]["slot"], slot)
self.assertEqual(
item_equipped_events[1]["args"]["itemType"],
1155,
)
self.assertEqual(
item_equipped_events[1]["args"]["itemAddress"],
self.terminus.address,
)
self.assertEqual(
item_equipped_events[1]["args"]["itemTokenId"],
item_pool_id,
)
self.assertEqual(
item_equipped_events[1]["args"]["amount"],
9,
)
self.assertEqual(
item_equipped_events[1]["args"]["equippedBy"],
self.player.address,
)

item_unequipped_events = _fetch_events_chunk(
web3_client,
inventory_events.ITEM_UNEQUIPPED_ABI,
from_block=tx_receipt_1.block_number,
to_block=tx_receipt_1.block_number,
)
self.assertEqual(len(item_unequipped_events), 1)
self.assertEqual(
item_unequipped_events[0]["args"]["subjectTokenId"], subject_token_id
)
self.assertEqual(item_unequipped_events[0]["args"]["slot"], slot)
self.assertEqual(
item_unequipped_events[0]["args"]["itemType"],
20,
)
self.assertEqual(
item_unequipped_events[0]["args"]["itemAddress"],
self.payment_token.address,
)
self.assertEqual(
item_unequipped_events[0]["args"]["itemTokenId"],
0,
)
self.assertEqual(
item_unequipped_events[0]["args"]["amount"],
2,
)
self.assertEqual(
item_unequipped_events[0]["args"]["unequippedBy"],
self.player.address,
)

0 comments on commit 456ec8e

Please sign in to comment.