From 98e2da68d0b690aaab0036562c01b90db87dbc9c Mon Sep 17 00:00:00 2001 From: Reckless_Satoshi Date: Tue, 19 Jul 2022 15:14:08 -0700 Subject: [PATCH] Add admin action shortcuts for dispute resolution. Update compensation docs --- api/admin.py | 78 +++++++++++++++++++++++- docs/_pages/contribute/01-development.md | 6 +- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/api/admin.py b/api/admin.py index 935c3578..6461f5b5 100644 --- a/api/admin.py +++ b/api/admin.py @@ -1,8 +1,9 @@ -from django.contrib import admin +from django.contrib import admin, messages from django_admin_relation_links import AdminChangeLinksMixin from django.contrib.auth.models import Group, User from django.contrib.auth.admin import UserAdmin from api.models import OnchainPayment, Order, LNPayment, Profile, MarketTick, Currency +from api.logics import Logics admin.site.unregister(Group) admin.site.unregister(User) @@ -37,7 +38,6 @@ class EUserAdmin(AdminChangeLinksMixin, UserAdmin): def avatar_tag(self, obj): return obj.profile.avatar_tag() - @admin.register(Order) class OrderAdmin(AdminChangeLinksMixin, admin.ModelAdmin): list_display = ( @@ -82,6 +82,80 @@ class OrderAdmin(AdminChangeLinksMixin, admin.ModelAdmin): list_filter = ("is_disputed", "is_fiat_sent", "is_swap","type", "currency", "status") search_fields = ["id","amount","min_amount","max_amount"] + actions = ['maker_wins', 'taker_wins', 'return_everything'] + + @admin.action(description='Solve dispute: maker wins') + def maker_wins(self, request, queryset): + ''' + Solves a dispute on favor of the maker. + Adds Sats to compensations (earned_rewards) of the maker profile. + ''' + for order in queryset: + if order.status in [Order.Status.DIS, Order.Status.WFR] and order.is_disputed: + own_bond_sats = order.maker_bond.num_satoshis + if Logics.is_buyer(order, order.maker): + if order.is_swap: + trade_sats = order.payout_tx.num_satoshis + else: + trade_sats = order.payout.num_satoshis + else: + trade_sats = order.trade_escrow.num_satoshis + + order.status = Order.Status.TLD + order.maker.profile.earned_rewards = own_bond_sats + trade_sats + order.maker.profile.save() + order.save() + self.message_user(request,f"Dispute of order {order.id} solved successfully on favor of the maker", messages.SUCCESS) + + else: + self.message_user(request,f"Order {order.id} is not in a disputed state", messages.ERROR) + + @admin.action(description='Solve dispute: taker wins') + def taker_wins(self, request, queryset): + ''' + Solves a dispute on favor of the taker. + Adds Sats to compensations (earned_rewards) of the taker profile. + ''' + for order in queryset: + if order.status in [Order.Status.DIS, Order.Status.WFR] and order.is_disputed: + own_bond_sats = order.maker_bond.num_satoshis + if Logics.is_buyer(order, order.taker): + if order.is_swap: + trade_sats = order.payout_tx.num_satoshis + else: + trade_sats = order.payout.num_satoshis + else: + trade_sats = order.trade_escrow.num_satoshis + + order.status = Order.Status.TLD + order.taker.profile.earned_rewards = own_bond_sats + trade_sats + order.taker.profile.save() + order.save() + self.message_user(request,f"Dispute of order {order.id} solved successfully on favor of the taker", messages.SUCCESS) + + else: + self.message_user(request,f"Order {order.id} is not in a disputed state", messages.ERROR) + + @admin.action(description='Solve dispute: return everything') + def return_everything(self, request, queryset): + ''' + Solves a dispute by pushing back every bond and escrow to their sender. + ''' + for order in queryset: + if order.status in [Order.Status.DIS, Order.Status.WFR] and order.is_disputed: + order.maker_bond.sender.profile.earned_rewards += order.maker_bond.num_satoshis + order.maker_bond.sender.profile.save() + order.taker_bond.sender.profile.earned_rewards += order.taker_bond.num_satoshis + order.taker_bond.sender.profile.save() + order.trade_escrow.sender.profile.earned_rewards += order.trade_escrow.num_satoshis + order.trade_escrow.sender.profile.save() + order.status = Order.Status.TLD + order.save() + self.message_user(request,f"Dispute of order {order.id} solved successfully, everything returned as compensations", messages.SUCCESS) + + else: + self.message_user(request,f"Order {order.id} is not in a disputed state", messages.ERROR) + def amt(self, obj): if obj.has_range and obj.amount == None: return str(float(obj.min_amount))+"-"+ str(float(obj.max_amount)) diff --git a/docs/_pages/contribute/01-development.md b/docs/_pages/contribute/01-development.md index d26cf84f..d5b75ef4 100644 --- a/docs/_pages/contribute/01-development.md +++ b/docs/_pages/contribute/01-development.md @@ -3,7 +3,7 @@ layout: single title: "Develop RoboSats" permalink: /contribute/code/ sidebar: - title: " Code" + title: 'Code' nav: contribute toc: true toc_sticky: true @@ -57,7 +57,9 @@ Please note that Pull Requests marked `NACK` and/or GitHub's `Change requested` ## Developer Compensation (Pilot Program) -At the moment RoboSats is a young and unfunded project. However, since launch, it has shown the ability to generate revenue, although it barely covers the running costs. A developer compensation program is the the best way to ensure the sustained support of the code base. For the time being, code contributions to the core project will be given small rewards: more akin to kudos than a meaningful monetary compensation. The pilot procedure for compensated development: +[Check the current state of the Developer Compensated tasks in the Github Project](https://github.com/users/Reckless-Satoshi/projects/2/views/5) + +At the moment RoboSats is a young and unfunded project. However, it has shown the ability to generate revenue, although it barely covers the running costs. A developer compensation program is the the best way to ensure the sustained support of the code base. For the time being, code contributions to the core project will be given small rewards: more akin to kudos than a meaningful monetary compensation. The pilot procedure for compensated development: 1. The developer opens a PR with the description of the work that will be done, optionally including the amount of Sats he thinks the work deserves. 2. An offer/negotiation takes place to set an amount of Sats until agreement. Everyone is welcome to express opinion on whether the compensation is right for the PR.