def test_safe_creation2_serializer(self): salt_nonce = 5 owners = [Account.create().address for _ in range(3)] invalid_checksumed_address = get_eth_address_with_invalid_checksum() data = {'salt_nonce': salt_nonce, 'owners': owners, 'threshold': len(owners)} self.assertTrue(SafeCreation2Serializer(data=data).is_valid()) data = {'salt_nonce': salt_nonce, 'owners': owners, 'threshold': len(owners) + 1} serializer = SafeCreation2Serializer(data=data) self.assertFalse(serializer.is_valid()) self.assertIn('Threshold cannot be greater', str(serializer.errors['non_field_errors'])) data = {'salt_nonce': salt_nonce, 'owners': owners + [invalid_checksumed_address], 'threshold': len(owners)} self.assertFalse(SafeCreation2Serializer(data=data).is_valid()) data = {'salt_nonce': salt_nonce, 'owners': [], 'threshold': len(owners)} serializer = SafeCreation2Serializer(data=data) self.assertFalse(serializer.is_valid())
def test_safe_multisig_tx_estimates(self): my_safe_address = get_eth_address_with_invalid_checksum() response = self.client.post(reverse('v1:safe-multisig-tx-estimates', args=(my_safe_address,)), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address, _ = get_eth_address_with_key() response = self.client.post(reverse('v1:safe-multisig-tx-estimates', args=(my_safe_address,)), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) initial_funding = self.w3.toWei(0.0001, 'ether') safe_creation = self.deploy_test_safe(number_owners=3, threshold=2, initial_funding_wei=initial_funding) my_safe_address = safe_creation.safe_address SafeContractFactory(address=my_safe_address) to = Account.create().address tx = { 'to': to, 'value': initial_funding // 2, 'data': '0x', 'operation': 1 } response = self.client.post(reverse('v1:safe-multisig-tx-estimates', args=(my_safe_address,)), data=tx, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) response = response.json() self.assertGreater(int(response['safeTxGas']), 0) self.assertEqual(response['operationalGas'], '0') self.assertIsNone(response['lastUsedNonce']) self.assertEqual(len(response['estimations']), 1) estimation = response['estimations'][0] self.assertGreater(int(estimation['baseGas']), 0) self.assertGreater(int(estimation['gasPrice']), 0) self.assertEqual(estimation['gasToken'], NULL_ADDRESS) valid_token = TokenFactory(address=Account.create().address, gas=True, fixed_eth_conversion=2) response = self.client.post(reverse('v1:safe-multisig-tx-estimates', args=(my_safe_address,)), data=tx, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) response = response.json() self.assertGreater(int(response['safeTxGas']), 0) self.assertEqual(response['operationalGas'], '0') self.assertIsNone(response['lastUsedNonce']) self.assertEqual(len(response['estimations']), 2) estimation_ether = response['estimations'][0] self.assertGreater(int(estimation_ether['baseGas']), 0) self.assertGreater(int(estimation_ether['gasPrice']), 0) self.assertEqual(estimation_ether['gasToken'], NULL_ADDRESS) estimation_token = response['estimations'][1] self.assertGreater(int(estimation_token['baseGas']), int(estimation_ether['baseGas'])) self.assertAlmostEqual(int(estimation_token['gasPrice']), int(estimation_ether['gasPrice']) // 2, delta=1.0) self.assertEqual(estimation_token['gasToken'], valid_token.address)
def test_safe_multisig_tx_estimate(self): my_safe_address = get_eth_address_with_invalid_checksum() response = self.client.post(reverse('v1:safe-multisig-tx-estimate', args=(my_safe_address, )), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address, _ = get_eth_address_with_key() response = self.client.post(reverse('v1:safe-multisig-tx-estimate', args=(my_safe_address, )), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) initial_funding = self.w3.toWei(0.0001, 'ether') to, _ = get_eth_address_with_key() data = { 'to': to, 'value': initial_funding // 2, 'data': '0x', 'operation': 1 } safe_creation = self.deploy_test_safe( number_owners=3, threshold=2, initial_funding_wei=initial_funding) my_safe_address = safe_creation.safe_address SafeContractFactory(address=my_safe_address) response = self.client.post(reverse('v1:safe-multisig-tx-estimate', args=(my_safe_address, )), data=data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) response = response.json() self.assertGreater(response['safeTxGas'], 0) self.assertGreater(response['dataGas'], 0) self.assertGreater(response['gasPrice'], 0) self.assertIsNone(response['lastUsedNonce']) self.assertEqual(response['gasToken'], NULL_ADDRESS) to, _ = get_eth_address_with_key() data = { 'to': to, 'value': initial_funding // 2, 'data': None, 'operation': 0 } response = self.client.post(reverse('v1:safe-multisig-tx-estimate', args=(my_safe_address, )), data=data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK)
def test_safe_multisig_tx_errors(self): my_safe_address = get_eth_address_with_invalid_checksum() response = self.client.post(reverse('v1:safe-multisig-txs', args=(my_safe_address,)), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address = self.create2_test_safe_in_db().safe.address response = self.client.post(reverse('v1:safe-multisig-txs', args=(my_safe_address,)), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_safe_signal_v2(self): safe_address = Account.create().address response = self.client.get( reverse('v2:safe-signal', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) response = self.client.put( reverse('v2:safe-signal', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) invalid_address = get_eth_address_with_invalid_checksum() response = self.client.get( reverse('v2:safe-signal', args=(invalid_address, ))) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) # We need ether or task will be hanged because of problems with retries emulating celery tasks during testing safe_creation2 = self.create2_test_safe_in_db() self.assertIsNone(safe_creation2.tx_hash) self.assertIsNone(safe_creation2.block_number) my_safe_address = safe_creation2.safe.address response = self.client.get( reverse('v2:safe-signal', args=(my_safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsNone(response.json()['txHash']) self.assertIsNone(response.json()['blockNumber']) self.send_ether(my_safe_address, safe_creation2.payment) response = self.client.put( reverse('v2:safe-signal', args=(my_safe_address, ))) self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) self.assertTrue(self.ethereum_client.is_contract(my_safe_address)) safe_creation2.refresh_from_db() self.assertIsNotNone(safe_creation2.tx_hash) response = self.client.get( reverse('v2:safe-signal', args=(my_safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.json()['txHash'], safe_creation2.tx_hash) self.assertEqual(response.json()['blockNumber'], safe_creation2.block_number)
def test_get_safe_signal(self): safe_address, _ = get_eth_address_with_key() response = self.client.get( reverse('v1:safe-signal', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) invalid_address = get_eth_address_with_invalid_checksum() response = self.client.get( reverse('v1:safe-signal', args=(invalid_address, ))) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address = self.create_test_safe_in_db().safe.address response = self.client.post(reverse('v1:safe-multisig-txs', args=(my_safe_address, )), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_ethereum_address_field(self): valid_address, _ = get_eth_address_with_key() for value in [ '0x674647242239941B2D35368E66A4EDc39b161Da1', '0x40f3F89639Bffc7B23Ca5d9FCb9ed9a9c579664A', valid_address, None ]: serializer = EthereumAddressSerializerTest(data={'value': value}) self.assertTrue(serializer.is_valid()) self.assertEqual(value, serializer.data['value']) invalid_address = get_eth_address_with_invalid_checksum() for not_valid_value in [ '0x674647242239941B2D35368E66A4EDc39b161DA1', invalid_address, '0x0000000000000000000000000000000000000000', '0x0000000000000000000000000000000000000001', '0xABC', '0xJK' ]: serializer = EthereumAddressSerializerTest( data={'value': not_valid_value}) self.assertFalse(serializer.is_valid())
def test_safe_creation2_serializer(self): salt_nonce = 5 owners = [Account.create().address for _ in range(3)] invalid_checksumed_address = get_eth_address_with_invalid_checksum() data = { "salt_nonce": salt_nonce, "owners": owners, "threshold": len(owners) } self.assertTrue(SafeCreation2Serializer(data=data).is_valid()) data = { "salt_nonce": salt_nonce, "owners": owners, "threshold": len(owners) + 1, } serializer = SafeCreation2Serializer(data=data) self.assertFalse(serializer.is_valid()) self.assertIn("Threshold cannot be greater", str(serializer.errors["non_field_errors"])) data = { "salt_nonce": salt_nonce, "owners": owners + [invalid_checksumed_address], "threshold": len(owners), } self.assertFalse(SafeCreation2Serializer(data=data).is_valid()) data = { "salt_nonce": salt_nonce, "owners": [], "threshold": len(owners) } serializer = SafeCreation2Serializer(data=data) self.assertFalse(serializer.is_valid())
def test_safe_multisig_tx_estimates(self): my_safe_address = get_eth_address_with_invalid_checksum() response = self.client.post( reverse("v1:safe-multisig-tx-estimates", args=(my_safe_address, )), data={}, format="json", ) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address, _ = get_eth_address_with_key() response = self.client.post( reverse("v1:safe-multisig-tx-estimates", args=(my_safe_address, )), data={}, format="json", ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) initial_funding = self.w3.toWei(0.0001, "ether") safe = self.deploy_test_safe(number_owners=3, threshold=2, initial_funding_wei=initial_funding) my_safe_address = safe.address to = Account.create().address tx = { "to": to, "value": initial_funding // 2, "data": "0x", "operation": 1 } response = self.client.post( reverse("v1:safe-multisig-tx-estimates", args=(my_safe_address, )), data=tx, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) # Use not existing Safe non_existing_safe_address = Account.create().address response = self.client.post( reverse("v1:safe-multisig-tx-estimates", args=(non_existing_safe_address, )), data=tx, format="json", ) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) self.assertIn("SafeDoesNotExist", response.data["exception"]) # Add to database and test SafeContractFactory(address=my_safe_address) response = self.client.post( reverse("v1:safe-multisig-tx-estimates", args=(my_safe_address, )), data=tx, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) response = response.json() self.assertGreater(int(response["safeTxGas"]), 0) self.assertEqual(response["operationalGas"], "0") self.assertIsNone(response["lastUsedNonce"]) self.assertEqual(len(response["estimations"]), 1) estimation = response["estimations"][0] self.assertGreater(int(estimation["baseGas"]), 0) self.assertGreater(int(estimation["gasPrice"]), 0) self.assertEqual(estimation["gasToken"], NULL_ADDRESS) valid_token = TokenFactory(address=Account.create().address, gas=True, fixed_eth_conversion=2) response = self.client.post( reverse("v1:safe-multisig-tx-estimates", args=(my_safe_address, )), data=tx, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) response = response.json() self.assertGreater(int(response["safeTxGas"]), 0) self.assertEqual(response["operationalGas"], "0") self.assertIsNone(response["lastUsedNonce"]) self.assertEqual(len(response["estimations"]), 2) estimation_ether = response["estimations"][0] self.assertGreater(int(estimation_ether["baseGas"]), 0) self.assertGreater(int(estimation_ether["gasPrice"]), 0) self.assertEqual(estimation_ether["gasToken"], NULL_ADDRESS) estimation_token = response["estimations"][1] self.assertGreater(int(estimation_token["baseGas"]), int(estimation_ether["baseGas"])) self.assertAlmostEqual( int(estimation_token["gasPrice"]), int(estimation_ether["gasPrice"]) // 2, delta=1.0, ) self.assertEqual(estimation_token["gasToken"], valid_token.address)
def test_safe_multisig_tx_estimate(self): my_safe_address = get_eth_address_with_invalid_checksum() response = self.client.post( reverse("v1:safe-multisig-tx-estimate", args=(my_safe_address, )), data={}, format="json", ) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address, _ = get_eth_address_with_key() response = self.client.post( reverse("v1:safe-multisig-tx-estimate", args=(my_safe_address, )), data={}, format="json", ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) initial_funding = self.w3.toWei(0.0001, "ether") to, _ = get_eth_address_with_key() data = { "to": to, "value": initial_funding // 2, "data": "0x", "operation": 1 } safe = self.deploy_test_safe(number_owners=3, threshold=2, initial_funding_wei=initial_funding) my_safe_address = safe.address response = self.client.post( reverse("v1:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) response = response.json() self.assertGreater(response["safeTxGas"], 0) self.assertGreater(response["dataGas"], 0) self.assertGreater(response["gasPrice"], 0) self.assertIsNone(response["lastUsedNonce"]) self.assertEqual(response["gasToken"], NULL_ADDRESS) # Add to the database and check again SafeContractFactory(address=my_safe_address) response = self.client.post( reverse("v1:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) response = response.json() self.assertGreater(response["safeTxGas"], 0) self.assertGreater(response["dataGas"], 0) self.assertGreater(response["gasPrice"], 0) self.assertIsNone(response["lastUsedNonce"]) self.assertEqual(response["gasToken"], NULL_ADDRESS) to = Account.create().address data = { "to": to, "value": initial_funding // 2, "data": None, "operation": 0 } response = self.client.post( reverse("v1:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) # Use not existing safe my_safe_address = Account.create().address response = self.client.post( reverse("v1:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) self.assertIn("SafeDoesNotExist", response.data["exception"])
def test_safe_multisig_tx_estimate_v2(self): my_safe_address = get_eth_address_with_invalid_checksum() response = self.client.post(reverse('v2:safe-multisig-tx-estimate', args=(my_safe_address, )), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address = Account.create().address response = self.client.post(reverse('v2:safe-multisig-tx-estimate', args=(my_safe_address, )), data={}, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) initial_funding = self.w3.toWei(0.0001, 'ether') to = Account.create().address data = { 'to': to, 'value': initial_funding // 2, 'data': '0x', 'operation': 1 } safe_creation = self.deploy_test_safe( number_owners=3, threshold=2, initial_funding_wei=initial_funding) my_safe_address = safe_creation.safe_address response = self.client.post(reverse('v2:safe-multisig-tx-estimate', args=(my_safe_address, )), data=data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) # Use non existing Safe non_existing_safe_address = Account.create().address response = self.client.post( reverse('v2:safe-multisig-tx-estimate', args=(non_existing_safe_address, )), data=data, format='json') self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) self.assertIn("SafeDoesNotExist", response.data['exception']) # Add to database and test again SafeContractFactory(address=my_safe_address) response = self.client.post(reverse('v2:safe-multisig-tx-estimate', args=(my_safe_address, )), data=data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) response_json = response.json() for field in ('safeTxGas', 'dataGas', 'gasPrice'): self.assertTrue(isinstance(response_json[field], str)) self.assertGreater(int(response_json[field]), 0) expected_refund_receiver = Account.from_key( settings.SAFE_TX_SENDER_PRIVATE_KEY).address self.assertIsNone(response_json['lastUsedNonce']) self.assertEqual(response_json['gasToken'], NULL_ADDRESS) self.assertEqual(response_json['refundReceiver'], expected_refund_receiver) to = Account.create().address data = { 'to': to, 'value': initial_funding // 2, 'data': None, 'operation': 0 } response = self.client.post(reverse('v2:safe-multisig-tx-estimate', args=(my_safe_address, )), data=data, format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['refund_receiver'], expected_refund_receiver) data = { 'to': to, 'value': initial_funding // 2, 'data': None, 'operation': 2 } response = self.client.post(reverse('v2:safe-multisig-tx-estimate', args=(my_safe_address, )), data=data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertIn('Please use Gnosis Safe CreateLib', str(response.data['non_field_errors']))
def test_safe_multisig_tx_estimate_v2(self): my_safe_address = get_eth_address_with_invalid_checksum() response = self.client.post( reverse("v2:safe-multisig-tx-estimate", args=(my_safe_address, )), data={}, format="json", ) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) my_safe_address = Account.create().address response = self.client.post( reverse("v2:safe-multisig-tx-estimate", args=(my_safe_address, )), data={}, format="json", ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) initial_funding = self.w3.toWei(0.0001, "ether") to = Account.create().address data = { "to": to, "value": initial_funding // 2, "data": "0x", "operation": 1 } safe = self.deploy_test_safe(number_owners=3, threshold=2, initial_funding_wei=initial_funding) my_safe_address = safe.address response = self.client.post( reverse("v2:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) # Use non existing Safe non_existing_safe_address = Account.create().address response = self.client.post( reverse("v2:safe-multisig-tx-estimate", args=(non_existing_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY) self.assertIn("SafeDoesNotExist", response.data["exception"]) # Add to database and test again SafeContractFactory(address=my_safe_address) response = self.client.post( reverse("v2:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) response_json = response.json() for field in ("safeTxGas", "dataGas", "gasPrice"): self.assertTrue(isinstance(response_json[field], str)) self.assertGreater(int(response_json[field]), 0) expected_refund_receiver = Account.from_key( settings.SAFE_TX_SENDER_PRIVATE_KEY).address self.assertIsNone(response_json["lastUsedNonce"]) self.assertEqual(response_json["gasToken"], NULL_ADDRESS) self.assertEqual(response_json["refundReceiver"], expected_refund_receiver) to = Account.create().address data = { "to": to, "value": initial_funding // 2, "data": None, "operation": 0 } response = self.client.post( reverse("v2:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data["refund_receiver"], expected_refund_receiver) data = { "to": to, "value": initial_funding // 2, "data": None, "operation": 2 } response = self.client.post( reverse("v2:safe-multisig-tx-estimate", args=(my_safe_address, )), data=data, format="json", ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertIn("Please use Gnosis Safe CreateLib", str(response.data["non_field_errors"]))