From 928d16a274c5d6a662dd7ce354286f5499002a62 Mon Sep 17 00:00:00 2001 From: bpolania Date: Tue, 8 Apr 2025 13:43:54 -0700 Subject: [PATCH 1/3] Update test_integration_ip_account.py --- .../test_integration_ip_account.py | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/tests/integration/test_integration_ip_account.py b/tests/integration/test_integration_ip_account.py index a1ec375..c0717aa 100644 --- a/tests/integration/test_integration_ip_account.py +++ b/tests/integration/test_integration_ip_account.py @@ -343,6 +343,141 @@ def test_set_ip_metadata(self, story_client): assert isinstance(response['txHash'], str), "'txHash' is not a string." assert len(response['txHash']) > 0, "'txHash' is empty." + def test_execute_with_sig_wrong_signer(self, story_client): + """Test executeWithSig with a valid signature but wrong signer address.""" + # Register a new IP + token_id = get_token_id(MockERC721, story_client.web3, story_client.account) + register_response = story_client.IPAsset.register( + nft_contract=MockERC721, + token_id=token_id + ) + ip_id = register_response['ipId'] + + # Set a valid deadline + deadline = getBlockTimestamp(web3) + 100 + + # Get the current state/nonce + state = story_client.IPAccount.getIpAccountNonce(ip_id) + + # Prepare data for a simple operation + data = "0x" + + # Prepare the expected state for signing + execute_data = story_client.IPAccount.ip_account_client.contract.encode_abi( + abi_element_identifier="execute", + args=[ + story_client.IPAccount.access_controller_client.contract.address, + 0, + data + ] + ) + + expected_state = Web3.keccak( + encode( + ["bytes32", "bytes"], + [state, Web3.to_bytes(hexstr=execute_data)] + ) + ) + + # Prepare the signature data + domain_data = { + "name": "Story Protocol IP Account", + "version": "1", + "chainId": 1315, + "verifyingContract": ip_id, + } + + message_types = { + "Execute": [ + {"name": "to", "type": "address"}, + {"name": "value", "type": "uint256"}, + {"name": "data", "type": "bytes"}, + {"name": "nonce", "type": "bytes32"}, + {"name": "deadline", "type": "uint256"}, + ], + } + + message_data = { + "to": story_client.IPAccount.access_controller_client.contract.address, + "value": 0, + "data": data, + "nonce": expected_state, + "deadline": deadline, + } + + # Sign the message + signable_message = encode_typed_data(domain_data, message_types, message_data) + signed_message = Account.sign_message(signable_message, private_key) + + # Use a wrong signer address + wrong_signer = "0x1234567890123456789012345678901234567890" + + # Execute with wrong signer + with pytest.raises(Exception) as exc_info: + story_client.IPAccount.executeWithSig( + ip_id=ip_id, + to=story_client.IPAccount.access_controller_client.contract.address, + value=0, + data=data, + signer=wrong_signer, # Wrong signer address + deadline=deadline, + signature=signed_message.signature + ) + + print(f"Exception type: {type(exc_info.value)}") + print(f"Exception value: {exc_info.value}") + print(f"Exception args: {exc_info.value.args if hasattr(exc_info.value, 'args') else 'No args'}") + + error_hex = '0x3fd60002' + assert error_hex in str(exc_info.value), f"Expected error code {error_hex} for wrong signer" + + @pytest.mark.skip(reason="contract allows empty calls") + def test_transfer_erc20_empty_tokens(self, story_client): + """Test transferERC20 with empty tokens list.""" + # Register a new IP + token_id = get_token_id(MockERC721, story_client.web3, story_client.account) + register_response = story_client.IPAsset.register( + nft_contract=MockERC721, + token_id=token_id + ) + ip_id = register_response['ipId'] + + # Try to transfer with empty tokens list + with pytest.raises(Exception) as exc_info: + story_client.IPAccount.transferERC20( + ip_id=ip_id, + tokens=[] # Empty tokens list + ) + + def test_transfer_erc20_invalid_token_params(self, story_client): + """Test transferERC20 with invalid token parameters.""" + # Register a new IP + token_id = get_token_id(MockERC721, story_client.web3, story_client.account) + register_response = story_client.IPAsset.register( + nft_contract=MockERC721, + token_id=token_id + ) + ip_id = register_response['ipId'] + + # Test with missing address + with pytest.raises(ValueError) as exc_info: + story_client.IPAccount.transferERC20( + ip_id=ip_id, + tokens=[ + { + # Missing 'address' + "target": story_client.account.address, + "amount": 1000000 + } + ] + ) + assert "must include" in str(exc_info.value), "Error should mention missing parameter" + + # Test with missing target + # with pytest.raises(ValueError) as exc_info: + # story_client.IPAccount + + class TestTransferERC20: """Tests for transferring ERC20 tokens""" From c08658e81f62c2253aabae8a9ad1d72aae3b5759 Mon Sep 17 00:00:00 2001 From: bpolania Date: Tue, 8 Apr 2025 13:48:19 -0700 Subject: [PATCH 2/3] Update test_integration_ip_account.py --- .../test_integration_ip_account.py | 25 ++----------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/tests/integration/test_integration_ip_account.py b/tests/integration/test_integration_ip_account.py index c0717aa..b42f363 100644 --- a/tests/integration/test_integration_ip_account.py +++ b/tests/integration/test_integration_ip_account.py @@ -229,7 +229,6 @@ def test_execute_with_sig_multiple_permissions(self, story_client): ] ) - # Calculate the expected state expected_state = Web3.keccak( encode( ["bytes32", "bytes"], @@ -237,7 +236,6 @@ def test_execute_with_sig_multiple_permissions(self, story_client): ) ) - # Prepare signature data domain_data = { "name": "Story Protocol IP Account", "version": "1", @@ -345,24 +343,17 @@ def test_set_ip_metadata(self, story_client): def test_execute_with_sig_wrong_signer(self, story_client): """Test executeWithSig with a valid signature but wrong signer address.""" - # Register a new IP token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( nft_contract=MockERC721, token_id=token_id ) ip_id = register_response['ipId'] - - # Set a valid deadline + deadline = getBlockTimestamp(web3) + 100 - - # Get the current state/nonce - state = story_client.IPAccount.getIpAccountNonce(ip_id) - - # Prepare data for a simple operation + state = story_client.IPAccount.getIpAccountNonce(ip_id) data = "0x" - # Prepare the expected state for signing execute_data = story_client.IPAccount.ip_account_client.contract.encode_abi( abi_element_identifier="execute", args=[ @@ -379,7 +370,6 @@ def test_execute_with_sig_wrong_signer(self, story_client): ) ) - # Prepare the signature data domain_data = { "name": "Story Protocol IP Account", "version": "1", @@ -405,14 +395,10 @@ def test_execute_with_sig_wrong_signer(self, story_client): "deadline": deadline, } - # Sign the message signable_message = encode_typed_data(domain_data, message_types, message_data) signed_message = Account.sign_message(signable_message, private_key) - - # Use a wrong signer address wrong_signer = "0x1234567890123456789012345678901234567890" - # Execute with wrong signer with pytest.raises(Exception) as exc_info: story_client.IPAccount.executeWithSig( ip_id=ip_id, @@ -434,7 +420,6 @@ def test_execute_with_sig_wrong_signer(self, story_client): @pytest.mark.skip(reason="contract allows empty calls") def test_transfer_erc20_empty_tokens(self, story_client): """Test transferERC20 with empty tokens list.""" - # Register a new IP token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( nft_contract=MockERC721, @@ -451,7 +436,6 @@ def test_transfer_erc20_empty_tokens(self, story_client): def test_transfer_erc20_invalid_token_params(self, story_client): """Test transferERC20 with invalid token parameters.""" - # Register a new IP token_id = get_token_id(MockERC721, story_client.web3, story_client.account) register_response = story_client.IPAsset.register( nft_contract=MockERC721, @@ -459,7 +443,6 @@ def test_transfer_erc20_invalid_token_params(self, story_client): ) ip_id = register_response['ipId'] - # Test with missing address with pytest.raises(ValueError) as exc_info: story_client.IPAccount.transferERC20( ip_id=ip_id, @@ -472,10 +455,6 @@ def test_transfer_erc20_invalid_token_params(self, story_client): ] ) assert "must include" in str(exc_info.value), "Error should mention missing parameter" - - # Test with missing target - # with pytest.raises(ValueError) as exc_info: - # story_client.IPAccount class TestTransferERC20: From e6f167274dad79a4aafc4807297a371b63785767 Mon Sep 17 00:00:00 2001 From: bpolania Date: Tue, 8 Apr 2025 13:56:31 -0700 Subject: [PATCH 3/3] Update test_integration_ip_account.py --- tests/integration/test_integration_ip_account.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/integration/test_integration_ip_account.py b/tests/integration/test_integration_ip_account.py index b42f363..c7dbfe4 100644 --- a/tests/integration/test_integration_ip_account.py +++ b/tests/integration/test_integration_ip_account.py @@ -106,14 +106,14 @@ def test_executeWithSig(self, story_client): token_id=token_id ) - ipId = response['ipId'] + ip_id = response['ipId'] deadline = getBlockTimestamp(web3) + 100 - state = story_client.IPAccount.getIpAccountNonce(ipId) + state = story_client.IPAccount.getIpAccountNonce(ip_id) core_data = story_client.IPAccount.access_controller_client.contract.encode_abi( abi_element_identifier="setTransientPermission", args=[ - ipId, + ip_id, account.address, "0x6E81a25C99C6e8430aeC7353325EB138aFE5DC16", Web3.keccak(text="function setAll(address,string,bytes32,bytes32)")[:4], @@ -141,7 +141,7 @@ def test_executeWithSig(self, story_client): "name": "Story Protocol IP Account", "version": "1", "chainId": 1315, - "verifyingContract": ipId, + "verifyingContract": ip_id, } message_types = { @@ -168,7 +168,7 @@ def test_executeWithSig(self, story_client): response = story_client.IPAccount.executeWithSig( to=story_client.IPAccount.access_controller_client.contract.address, value=0, - ip_id=ipId, + ip_id=ip_id, data=core_data, signer=account.address, deadline=deadline, @@ -469,7 +469,7 @@ def test_transfer_erc20(self, story_client): ) ip_id = response['ipId'] - # 1. Query token balance of ipId and wallet before + # 1. Query token balance of ip_id and wallet before initial_erc20_balance_of_ip_id = story_client.Royalty.mock_erc20_client.balanceOf( account=ip_id ) @@ -527,7 +527,7 @@ def test_transfer_erc20(self, story_client): ] ) - # 5. Query token balance of ipId and wallet address after transfer + # 5. Query token balance of ip_id and wallet address after transfer final_erc20_balance_of_ip_id = story_client.Royalty.mock_erc20_client.balanceOf( account=ip_id )