Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Disable creation of Multisig Txs with delegate call operation #2442

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,3 +777,9 @@
"0xD5b58Cf7813c1eDC412367b97876bD400ea5c489",
)
}

# Multisig Txs operations
# ------------------------------------------------------------------------------
DISABLE_CREATION_MULTISIG_TRANSACTIONS_WITH_DELEGATE_CALL_OPERATION = env.bool(
"DISABLE_CREATION_MULTISIG_TRANSACTIONS_WITH_DELEGATE_CALL_OPERATION", default=True
)
10 changes: 9 additions & 1 deletion safe_transaction_service/history/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
HexadecimalField,
Sha3HashField,
)
from safe_eth.safe import Safe
from safe_eth.safe import Safe, SafeOperationEnum
from safe_eth.safe.safe_signature import EthereumBytes, SafeSignature, SafeSignatureType
from safe_eth.safe.serializers import SafeMultisigTxSerializer
from safe_eth.util.util import to_0x_hex_str
Expand Down Expand Up @@ -193,6 +193,14 @@ def validate_origin(self, origin):

return origin

def validate_operation(self, value):
if (
settings.DISABLE_CREATION_MULTISIG_TRANSACTIONS_WITH_DELEGATE_CALL_OPERATION
and value == SafeOperationEnum.DELEGATE_CALL.value
):
raise ValidationError("Operation DELEGATE_CALL is not allowed")
return super().validate_operation(value)

def validate(self, attrs):
super().validate(attrs)

Expand Down
61 changes: 61 additions & 0 deletions safe_transaction_service/history/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2328,6 +2328,67 @@ def test_post_multisig_transactions_with_banned_signatures(self):
},
)

def test_post_multisig_transaction_with_delegate_call(self):
safe_owner_1 = Account.create()
safe = self.deploy_test_safe(owners=[safe_owner_1.address])
safe_address = safe.address

response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 0)

data = {
"to": Account.create().address,
"value": 0,
"data": "0x12121212",
"operation": 1,
"nonce": 0,
"safeTxGas": 0,
"baseGas": 0,
"gasPrice": 0,
"gasToken": "0x0000000000000000000000000000000000000000",
"refundReceiver": "0x0000000000000000000000000000000000000000",
"sender": safe_owner_1.address,
}
safe_tx = safe.build_multisig_tx(
data["to"],
data["value"],
data["data"],
data["operation"],
data["safeTxGas"],
data["baseGas"],
data["gasPrice"],
data["gasToken"],
data["refundReceiver"],
safe_nonce=data["nonce"],
)
data["contractTransactionHash"] = to_0x_hex_str(safe_tx.safe_tx_hash)

with self.settings(
DISABLE_CREATION_MULTISIG_TRANSACTIONS_WITH_DELEGATE_CALL_OPERATION=True
):
response = self.client.post(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
format="json",
data=data,
)
self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY)

with self.settings(
DISABLE_CREATION_MULTISIG_TRANSACTIONS_WITH_DELEGATE_CALL_OPERATION=False
):
response = self.client.post(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
format="json",
data=data,
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
multisig_transaction_db = MultisigTransaction.objects.first()
self.assertEqual(multisig_transaction_db.operation, 1)

def test_safe_balances_view(self):
safe_address = Account.create().address
response = self.client.get(
Expand Down
61 changes: 61 additions & 0 deletions safe_transaction_service/history/tests/test_views_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1953,6 +1953,67 @@ def test_post_multisig_transactions_with_delegate(self):
response.data["non_field_errors"][0],
)

def test_post_multisig_transaction_with_delegate_call(self):
safe_owner_1 = Account.create()
safe = self.deploy_test_safe(owners=[safe_owner_1.address])
safe_address = safe.address

response = self.client.get(
reverse("v1:history:multisig-transactions", args=(safe_address,)),
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 0)

data = {
"to": Account.create().address,
"value": 0,
"data": "0x12121212",
"operation": 1,
"nonce": 0,
"safeTxGas": 0,
"baseGas": 0,
"gasPrice": 0,
"gasToken": "0x0000000000000000000000000000000000000000",
"refundReceiver": "0x0000000000000000000000000000000000000000",
"sender": safe_owner_1.address,
}
safe_tx = safe.build_multisig_tx(
data["to"],
data["value"],
data["data"],
data["operation"],
data["safeTxGas"],
data["baseGas"],
data["gasPrice"],
data["gasToken"],
data["refundReceiver"],
safe_nonce=data["nonce"],
)
data["contractTransactionHash"] = to_0x_hex_str(safe_tx.safe_tx_hash)

with self.settings(
DISABLE_CREATION_MULTISIG_TRANSACTIONS_WITH_DELEGATE_CALL_OPERATION=True
):
response = self.client.post(
reverse("v2:history:multisig-transactions", args=(safe_address,)),
format="json",
data=data,
)
self.assertEqual(response.status_code, status.HTTP_422_UNPROCESSABLE_ENTITY)

with self.settings(
DISABLE_CREATION_MULTISIG_TRANSACTIONS_WITH_DELEGATE_CALL_OPERATION=False
):
response = self.client.post(
reverse("v2:history:multisig-transactions", args=(safe_address,)),
format="json",
data=data,
)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
multisig_transaction_db = MultisigTransaction.objects.first()
self.assertEqual(multisig_transaction_db.operation, 1)

def test_delete_multisig_transaction(self):
owner_account = Account.create()
safe_tx_hash = to_0x_hex_str(fast_keccak_text("random-tx"))
Expand Down