-
Notifications
You must be signed in to change notification settings - Fork 123
Support AMMClawback amendment #802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
8504d24
Support AMMClawback amendment
ckeshava 6557b29
fix linter errors
ckeshava 061c866
Update tests/unit/models/transactions/test_amm_clawback.py
ckeshava 3dcb7b4
Merge branch 'main' into amm_clawback
ckeshava 147b5fe
Fix the incorrect code-rabbit update suggestion
ckeshava 1e0f73c
Update xrpl/models/transactions/amm_clawback.py
ckeshava a37cd1b
ashray PR suggestion: change error message
ckeshava 611d4db
pacify the linter
ckeshava 45ee8a4
Merge branch 'main' into amm_clawback
ckeshava d9ecf89
shorten variable name
ckeshava 496abef
fix: update variable name at function invocation
ckeshava 43e9c39
Merge branch 'main' into amm_clawback
ckeshava 58f5969
Merge branch 'main' into amm_clawback
ckeshava File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| from tests.integration.integration_test_case import IntegrationTestCase | ||
| from tests.integration.it_utils import ( | ||
| create_amm_pool_async, | ||
| sign_and_reliable_submission_async, | ||
| test_async_and_sync, | ||
| ) | ||
| from xrpl.models.amounts.issued_currency_amount import IssuedCurrencyAmount | ||
| from xrpl.models.currencies.issued_currency import IssuedCurrency | ||
| from xrpl.models.currencies.xrp import XRP | ||
| from xrpl.models.transactions import AMMDeposit | ||
| from xrpl.models.transactions.amm_clawback import AMMClawback | ||
| from xrpl.models.transactions.amm_deposit import AMMDepositFlag | ||
|
|
||
|
|
||
| class TestAMMClawback(IntegrationTestCase): | ||
| @test_async_and_sync(globals()) | ||
| async def test_positive_workflow(self, client): | ||
| amm_pool = await create_amm_pool_async(client, enable_amm_clawback=True) | ||
|
|
||
| # Asset-1 is XRP, Asset-2 is an IssuedCurrency titled "USD" | ||
| # The Issuer of Asset-2 is the issuer_wallet | ||
| # For the purposes of this test, the issuer_wallet has set the | ||
| # Allow Trust Line Clawback flag | ||
| issuer_wallet = amm_pool["issuer_wallet"] | ||
| holder_wallet = amm_pool["lp_wallet"] | ||
|
|
||
| # "holder" account deposits both assets into the AMM pool | ||
| # Deposit assets into AMM pool | ||
| amm_deposit = AMMDeposit( | ||
| account=holder_wallet.address, | ||
| asset=IssuedCurrency( | ||
| currency="USD", | ||
| issuer=issuer_wallet.address, | ||
| ), | ||
| asset2=XRP(), | ||
khancode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| amount=IssuedCurrencyAmount( | ||
| currency="USD", | ||
| issuer=issuer_wallet.address, | ||
| value="10", | ||
| ), | ||
| flags=AMMDepositFlag.TF_SINGLE_ASSET, | ||
| ) | ||
| deposit_response = await sign_and_reliable_submission_async( | ||
| amm_deposit, holder_wallet, client | ||
| ) | ||
| self.assertEqual(deposit_response.result["engine_result"], "tesSUCCESS") | ||
|
|
||
| # Clawback one of the assets from the AMM pool | ||
| amm_clawback = AMMClawback( | ||
| account=issuer_wallet.address, | ||
| holder=holder_wallet.address, | ||
| asset=IssuedCurrency( | ||
| currency="USD", | ||
| issuer=issuer_wallet.address, | ||
| ), | ||
| asset2=XRP(), | ||
khancode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ) | ||
| clawback_response = await sign_and_reliable_submission_async( | ||
| amm_clawback, issuer_wallet, client | ||
| ) | ||
| self.assertEqual(clawback_response.result["engine_result"], "tesSUCCESS") | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| from unittest import TestCase | ||
|
|
||
| from xrpl.models.amounts import IssuedCurrencyAmount | ||
| from xrpl.models.currencies import XRP, IssuedCurrency | ||
| from xrpl.models.exceptions import XRPLModelException | ||
| from xrpl.models.transactions import AMMClawback | ||
| from xrpl.models.transactions.amm_clawback import AMMClawbackFlag | ||
|
|
||
| _ISSUER_ACCOUNT = "r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ" | ||
| _ASSET2 = XRP() | ||
| _INVALID_ASSET = IssuedCurrency( | ||
| currency="ETH", issuer="rpGtkFRXhgVaBzC5XCR7gyE2AZN5SN3SEW" | ||
| ) | ||
| _VALID_ASSET = IssuedCurrency(currency="ETH", issuer=_ISSUER_ACCOUNT) | ||
| _HOLDER_ACCOUNT = "rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh" | ||
|
|
||
|
|
||
| class TestAMMClawback(TestCase): | ||
| def test_identical_issuer_holder_wallets(self): | ||
| with self.assertRaises(XRPLModelException) as error: | ||
| AMMClawback( | ||
| account=_ISSUER_ACCOUNT, | ||
| holder=_ISSUER_ACCOUNT, | ||
| asset=_VALID_ASSET, | ||
| asset2=_ASSET2, | ||
| ) | ||
| self.assertEqual( | ||
| error.exception.args[0], | ||
| "{'AMMClawback': 'Issuer and holder wallets must be distinct.'}", | ||
| ) | ||
|
|
||
| def test_incorrect_asset_issuer(self): | ||
| with self.assertRaises(XRPLModelException) as error: | ||
| AMMClawback( | ||
| account=_ISSUER_ACCOUNT, | ||
| holder=_HOLDER_ACCOUNT, | ||
| asset=_INVALID_ASSET, | ||
| asset2=_ASSET2, | ||
| ) | ||
| self.assertEqual( | ||
| error.exception.args[0], | ||
| "{'AMMClawback': 'Asset.issuer and AMMClawback transaction sender must be " | ||
| + "identical.'}", | ||
| ) | ||
|
|
||
| def test_incorrect_asset_amount(self): | ||
| with self.assertRaises(XRPLModelException) as error: | ||
| AMMClawback( | ||
| account=_ISSUER_ACCOUNT, | ||
| holder=_HOLDER_ACCOUNT, | ||
| asset=_VALID_ASSET, | ||
| asset2=_ASSET2, | ||
| amount=IssuedCurrencyAmount( | ||
| currency="BTC", | ||
| issuer="rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH", | ||
| value="100", | ||
| ), | ||
| ) | ||
| self.assertEqual( | ||
| error.exception.args[0], | ||
| "{'AMMClawback': 'Amount.issuer and Amount.currency must match " | ||
| + "corresponding Asset fields.'}", | ||
| ) | ||
|
|
||
| def test_valid_txn(self): | ||
| txn = AMMClawback( | ||
| account=_ISSUER_ACCOUNT, | ||
| holder=_HOLDER_ACCOUNT, | ||
| asset=_VALID_ASSET, | ||
| asset2=_ASSET2, | ||
| flags=AMMClawbackFlag.TF_CLAW_TWO_ASSETS, | ||
| ) | ||
| self.assertTrue(txn.is_valid()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| """Model for AMMClawback transaction type.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass, field | ||
| from enum import Enum | ||
| from typing import Dict, Optional | ||
|
|
||
| from typing_extensions import Self | ||
|
|
||
| from xrpl.models.amounts import IssuedCurrencyAmount | ||
| from xrpl.models.currencies import Currency | ||
| from xrpl.models.currencies.issued_currency import IssuedCurrency | ||
| from xrpl.models.flags import FlagInterface | ||
| from xrpl.models.required import REQUIRED | ||
| from xrpl.models.transactions.transaction import Transaction | ||
| from xrpl.models.transactions.types import TransactionType | ||
| from xrpl.models.utils import KW_ONLY_DATACLASS, require_kwargs_on_init | ||
|
|
||
|
|
||
| class AMMClawbackFlag(int, Enum): | ||
| """ | ||
| Claw back the specified amount of Asset, and a corresponding amount of Asset2 based | ||
| on the AMM pool's asset proportion; both assets must be issued by the issuer in the | ||
| Account field. If this flag isn't enabled, the issuer claws back the specified | ||
| amount of Asset, while a corresponding proportion of Asset2 goes back to the Holder. | ||
| """ | ||
|
|
||
| TF_CLAW_TWO_ASSETS = 0x00000001 | ||
|
|
||
|
|
||
| class AMMClawbackFlagInterface(FlagInterface): | ||
| """ | ||
| Claw back the specified amount of Asset, and a corresponding amount of Asset2 based | ||
ckeshava marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| on the AMM pool's asset proportion; both assets must be issued by the issuer in the | ||
| Account field. If this flag isn't enabled, the issuer claws back the specified | ||
| amount of Asset, while a corresponding proportion of Asset2 goes back to the Holder. | ||
| """ | ||
|
|
||
| TF_CLAW_TWO_ASSETS: bool | ||
|
|
||
|
|
||
| @require_kwargs_on_init | ||
| @dataclass(frozen=True, **KW_ONLY_DATACLASS) | ||
| class AMMClawback(Transaction): | ||
| """ | ||
| Claw back tokens from a holder who has deposited your issued tokens into an AMM | ||
| pool. | ||
| """ | ||
|
|
||
| holder: str = REQUIRED # type: ignore | ||
| """The account holding the asset to be clawed back.""" | ||
|
|
||
| asset: IssuedCurrency = REQUIRED # type: ignore | ||
| """ | ||
| Specifies the asset that the issuer wants to claw back from the AMM pool. In JSON, | ||
| this is an object with currency and issuer fields. The issuer field must match with | ||
| Account. | ||
| """ | ||
|
|
||
| asset2: Currency = REQUIRED # type: ignore | ||
| """ | ||
| Specifies the other asset in the AMM's pool. In JSON, this is an object with | ||
| currency and issuer fields (omit issuer for XRP). | ||
| """ | ||
|
|
||
| amount: Optional[IssuedCurrencyAmount] = None | ||
| """ | ||
| The maximum amount to claw back from the AMM account. The currency and issuer | ||
| subfields should match the Asset subfields. If this field isn't specified, or the | ||
| value subfield exceeds the holder's available tokens in the AMM, all of the | ||
| holder's tokens are clawed back. | ||
| """ | ||
|
|
||
| transaction_type: TransactionType = field( | ||
| default=TransactionType.AMM_CLAWBACK, | ||
| init=False, | ||
| ) | ||
|
|
||
| def _get_errors(self: Self) -> Dict[str, str]: | ||
| return { | ||
| key: value | ||
| for key, value in { | ||
| **super()._get_errors(), | ||
| "AMMClawback": self._validate_wallet_and_amount_fields(), | ||
| }.items() | ||
| if value is not None | ||
| } | ||
|
|
||
| def _validate_wallet_and_amount_fields(self: Self) -> Optional[str]: | ||
| errors = "" | ||
| if self.account == self.holder: | ||
| errors += "Issuer and holder wallets must be distinct." | ||
|
|
||
| if self.account != self.asset.issuer: | ||
| errors += ( | ||
| "Asset.issuer and AMMClawback transaction sender must be identical." | ||
| ) | ||
|
|
||
| if self.amount is not None and ( | ||
| self.amount.issuer != self.asset.issuer | ||
| or self.amount.currency != self.asset.currency | ||
| ): | ||
| errors += ( | ||
| "Amount.issuer and Amount.currency must match corresponding Asset " | ||
| + "fields." | ||
| ) | ||
|
|
||
| return errors if errors else None | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.