Calculate right amount scrow and bond

This commit is contained in:
koalasat
2025-03-14 16:10:33 +01:00
parent 84d96701bc
commit c12c579497
3 changed files with 45 additions and 13 deletions

View File

@ -234,12 +234,16 @@ class Logics:
return (float(amount) / premium_rate) * 100 * 1000 * 1000 return (float(amount) / premium_rate) * 100 * 1000 * 1000
@classmethod @classmethod
def satoshis_now(cls, order): def satoshis_now(cls, order, take_amount=None):
"""checks trade amount in sats""" """checks trade amount in sats"""
if order.is_explicit: if order.is_explicit:
satoshis_now = order.satoshis satoshis_now = order.satoshis
else: else:
amount = order.amount if order.amount is not None else order.max_amount if take_amount is not None:
amount = take_amount
else:
amount = order.amount if order.amount is not None else order.max_amount
satoshis_now = cls.calc_sats( satoshis_now = cls.calc_sats(
amount, order.currency.exchange_rate, order.premium amount, order.currency.exchange_rate, order.premium
) )
@ -1348,6 +1352,10 @@ class Logics:
order.taker = take_order.taker order.taker = take_order.taker
order.taker_bond = take_order.taker_bond order.taker_bond = take_order.taker_bond
if order.has_range:
order.amount = take_order.amount
# THE TRADE AMOUNT IS FINAL WITH THE CONFIRMATION OF THE TAKER BOND! # THE TRADE AMOUNT IS FINAL WITH THE CONFIRMATION OF THE TAKER BOND!
# (This is the last update to "last_satoshis", it becomes the escrow amount next) # (This is the last update to "last_satoshis", it becomes the escrow amount next)
order.last_satoshis = cls.satoshis_now(order) order.last_satoshis = cls.satoshis_now(order)
@ -1370,10 +1378,6 @@ class Logics:
] ]
) )
if order.has_range:
order.amount = take_order.amount
order.save(update_fields=["amount"])
order.taker_bond.status = LNPayment.Status.LOCKED order.taker_bond.status = LNPayment.Status.LOCKED
order.taker_bond.save(update_fields=["status"]) order.taker_bond.save(update_fields=["status"])
@ -1424,7 +1428,7 @@ class Logics:
} }
# If there was no taker_bond object yet, generates one # If there was no taker_bond object yet, generates one
take_order.last_satoshis = cls.satoshis_now(order) take_order.last_satoshis = cls.satoshis_now(order, take_order.amount)
take_order.last_satoshis_time = timezone.now() take_order.last_satoshis_time = timezone.now()
bond_satoshis = int(take_order.last_satoshis * order.bond_size / 100) bond_satoshis = int(take_order.last_satoshis * order.bond_size / 100)
pos_text = "Buying" if cls.is_buyer(order, user) else "Selling" pos_text = "Buying" if cls.is_buyer(order, user) else "Selling"

View File

@ -244,11 +244,11 @@ class OrderView(viewsets.ViewSet):
data["penalty"] = request.user.robot.penalty_expiration data["penalty"] = request.user.robot.penalty_expiration
# Add booleans if user is maker, taker, partipant, buyer or seller # Add booleans if user is maker, taker, partipant, buyer or seller
is_pretaker = TakeOrder.objects.filter( take_order = TakeOrder.objects.filter(
taker=request.user, order=order, expires_at__gt=timezone.now() taker=request.user, order=order, expires_at__gt=timezone.now()
).exists() )
data["is_maker"] = order.maker == request.user data["is_maker"] = order.maker == request.user
data["is_taker"] = order.taker == request.user or is_pretaker data["is_taker"] = order.taker == request.user or take_order.exists()
data["is_participant"] = data["is_maker"] or data["is_taker"] data["is_participant"] = data["is_maker"] or data["is_taker"]
# 3.a) If not a participant and order is not public, forbid. # 3.a) If not a participant and order is not public, forbid.
@ -279,7 +279,12 @@ class OrderView(viewsets.ViewSet):
# 4) If order is between public and WF2 # 4) If order is between public and WF2
if order.status >= Order.Status.PUB and order.status < Order.Status.WF2: if order.status >= Order.Status.PUB and order.status < Order.Status.WF2:
data["price_now"], data["premium_now"] = Logics.price_and_premium_now(order) data["price_now"], data["premium_now"] = Logics.price_and_premium_now(order)
data["satoshis_now"] = Logics.satoshis_now(order) if take_order.exists():
data["satoshis_now"] = Logics.satoshis_now(
order, take_order.first().amount
)
else:
data["satoshis_now"] = Logics.satoshis_now(order)
# 4. a) If maker and Public/Paused, add premium percentile # 4. a) If maker and Public/Paused, add premium percentile
# num similar orders, and maker information to enable telegram notifications. # num similar orders, and maker information to enable telegram notifications.
@ -366,11 +371,12 @@ class OrderView(viewsets.ViewSet):
# 6) If status is 'Public' and user is PRETAKER, reply with a TAKER hold invoice. # 6) If status is 'Public' and user is PRETAKER, reply with a TAKER hold invoice.
elif ( elif (
order.status == Order.Status.PUB order.status == Order.Status.PUB
and is_pretaker and take_order.exists()
and order.taker != request.user and order.taker != request.user
): ):
data["status"] = Order.Status.TAK data["status"] = Order.Status.TAK
data["total_secs_exp"] = order.t_to_expire(Order.Status.TAK) data["total_secs_exp"] = order.t_to_expire(Order.Status.TAK)
data["amount"] = str(take_order.first().amount)
valid, context = Logics.gen_taker_hold_invoice(order, request.user) valid, context = Logics.gen_taker_hold_invoice(order, request.user)

View File

@ -14,7 +14,7 @@ from control.tasks import compute_node_balance, do_accounting
from tests.test_api import BaseAPITestCase from tests.test_api import BaseAPITestCase
from tests.utils.node import add_invoice, set_up_regtest_network from tests.utils.node import add_invoice, set_up_regtest_network
from tests.utils.pgp import sign_message from tests.utils.pgp import sign_message
from tests.utils.trade import Trade from tests.utils.trade import Trade, maker_form_buy_with_range
from api.admin import OrderAdmin from api.admin import OrderAdmin
@ -456,6 +456,28 @@ class TradeTest(BaseAPITestCase):
self.assert_order_logs(data["id"]) self.assert_order_logs(data["id"])
def test_make_and_take_range_order(self):
"""
Tests a trade with a range from order creation to taken.
"""
trade = Trade(
self.client,
# latitude and longitud in Aruba. One of the countries blocked in the example conf.
maker_form=maker_form_buy_with_range,
)
trade.publish_order()
trade.take_order()
data = trade.response.json()
self.assertEqual(trade.response.status_code, 200)
self.assertResponse(trade.response)
self.assertEqual(data["status_message"], Order.Status(Order.Status.PUB).label)
self.assertAlmostEqual(float(data["amount"]), 80)
# Cancel order to avoid leaving pending HTLCs after a successful test
trade.cancel_order()
def test_make_and_take_order_multiple_takers(self): def test_make_and_take_order_multiple_takers(self):
""" """
Tests a trade from order creation to taken. Tests a trade from order creation to taken.