Exemple #1
0
def send_4(request):
    """Handle the fourth stage of sending a tip (the POST).

    Once the metamask transaction is complete, add it to the database.

    Returns:
        JsonResponse: response with success state.

    """
    response = {
        'status': 'OK',
        'message': _('Kudos Sent'),
    }
    params = json.loads(request.body)
    from_username = request.user.username
    txid = params['txid']
    destination_account = params['destinationAccount']
    is_direct_to_recipient = params.get('is_direct_to_recipient', False)
    kudos_transfer = KudosTransfer.objects.get(
        metadata__address=destination_account,
        metadata__creation_time=params['creation_time'],
        metadata__salt=params['salt'],
    )

    # Return Permission Denied if not authenticated
    is_authenticated_via_login = (kudos_transfer.from_username
                                  and kudos_transfer.from_username
                                  == from_username)
    is_authenticated_for_this_via_ip = kudos_transfer.ip == get_ip(request)
    is_authed = is_authenticated_for_this_via_ip or is_authenticated_via_login

    if not is_authed:
        return JsonResponse(
            {
                'status': 'error',
                'message': _('Permission Denied')
            }, status=401)

    # Save the txid to the database once it has been confirmed in MetaMask.  If there is no txid,
    # it means that the user never went through with the transaction.
    kudos_transfer.txid = txid
    kudos_transfer.tx_status = 'pending'
    if is_direct_to_recipient:
        kudos_transfer.receive_txid = txid
        kudos_transfer.receive_tx_status = 'pending'
    kudos_transfer.save()

    # notifications
    maybe_market_kudos_to_email(kudos_transfer)
    maybe_market_kudos_to_github(kudos_transfer)
    record_kudos_activity(
        kudos_transfer,
        kudos_transfer.from_username,
        'new_kudos',
    )
    if is_direct_to_recipient:
        record_kudos_activity(kudos_transfer, kudos_transfer.username,
                              'receive_kudos')

    return JsonResponse(response)
Exemple #2
0
def receive_bulk(request, secret):

    coupons = BulkTransferCoupon.objects.filter(secret=secret)
    if not coupons.exists():
        raise Http404

    coupon = coupons.first()

    if coupon.num_uses_remaining <= 0:
        messages.info(request, f'Sorry but the coupon for a free kudos has has expired.  Contact the person who sent you the coupon link, or you can still purchase one on this page.')
        return redirect(coupon.token.url)

    kudos_transfer = None
    if request.user.is_authenticated:
        redemptions = BulkTransferRedemption.objects.filter(redeemed_by=request.user.profile, coupon=coupon)
        if redemptions.exists():
            kudos_transfer = redemptions.first().kudostransfer

    error = False
    if request.POST:
        try:
            address = Web3.toChecksumAddress(request.POST.get('forwarding_address'))
        except:
            error = "You must enter a valid Ethereum address (so we know where to send your Kudos). Please try again."
        if request.user.is_anonymous:
            error = "You must login."

        if not error:
            user = request.user
            profile = user.profile
            save_addr = request.POST.get('save_addr')
            ip_address = get_ip(request)

            # handle form submission
            if save_addr:
                profile.preferred_payout_address = address
                profile.save()

            kudos_contract_address = Web3.toChecksumAddress(settings.KUDOS_CONTRACT_MAINNET)
            kudos_owner_address = Web3.toChecksumAddress(settings.KUDOS_OWNER_ACCOUNT)
            w3 = get_web3(coupon.token.contract.network)
            contract = w3.eth.contract(Web3.toChecksumAddress(kudos_contract_address), abi=kudos_abi())
            nonce = w3.eth.getTransactionCount(kudos_owner_address)
            tx = contract.functions.clone(address, coupon.token.token_id, 1).buildTransaction({
                'nonce': nonce,
                'gas': 500000,
                'gasPrice': int(recommend_min_gas_price_to_confirm_in_time(2) * 10**9),
                'value': int(coupon.token.price_finney / 1000.0 * 10**18),
            })

            if not profile.trust_profile and profile.github_created_on > (timezone.now() - timezone.timedelta(days=7)):
                messages.error(request, f'Your github profile is too new.  Cannot receive kudos.')
            else:

                signed = w3.eth.account.signTransaction(tx, settings.KUDOS_PRIVATE_KEY)
                txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()

                with transaction.atomic():
                    kudos_transfer = KudosTransfer.objects.create(
                        emails=[request.user.email],
                        # For kudos, `token` is a kudos.models.Token instance.
                        kudos_token_cloned_from=coupon.token,
                        amount=0,
                        comments_public=coupon.comments_to_put_in_kudos_transfer,
                        ip=ip_address,
                        github_url='',
                        from_name=coupon.sender_profile.handle,
                        from_email='',
                        from_username=coupon.sender_profile.handle,
                        username=profile.handle,
                        network=coupon.token.contract.network,
                        from_address=settings.KUDOS_OWNER_ACCOUNT,
                        is_for_bounty_fulfiller=False,
                        metadata={'coupon_redemption': True, 'nonce': nonce},
                        recipient_profile=profile,
                        sender_profile=coupon.sender_profile,
                        txid=txid,
                        receive_txid=txid,
                        tx_status='pending',
                        receive_tx_status='pending',
                    )

                    # save to DB
                    BulkTransferRedemption.objects.create(
                        coupon=coupon,
                        redeemed_by=profile,
                        ip_address=ip_address,
                        kudostransfer=kudos_transfer,
                        )

                    coupon.num_uses_remaining -= 1
                    coupon.current_uses += 1
                    coupon.save()

                    # send email
                    maybe_market_kudos_to_email(kudos_transfer)


    title = f"Redeem {coupon.token.humanized_name} Kudos from @{coupon.sender_profile.handle}"
    desc = f"This Kudos has been AirDropped to you.  About this Kudos: {coupon.token.description}"
    params = {
        'title': title,
        'card_title': title,
        'card_desc': desc,
        'error': error,
        'avatar_url': coupon.token.img_url,
        'coupon': coupon,
        'user': request.user,
        'is_authed': request.user.is_authenticated,
        'kudos_transfer': kudos_transfer,
        'tweet_text': urllib.parse.quote_plus(f"I just got a {coupon.token.humanized_name} Kudos on @GetGitcoin.  ")
    }
    return TemplateResponse(request, 'transaction/receive_bulk.html', params)
Exemple #3
0
def redeem_bulk_coupon(coupon,
                       profile,
                       address,
                       ip_address,
                       save_addr=False,
                       submit_later=False,
                       exit_after_sending_tx=False,
                       max_gas_price_we_are_willing_to_pay_gwei=15):
    try:
        address = Web3.toChecksumAddress(address)
    except:
        error = "You must enter a valid Ethereum address (so we know where to send your Kudos). Please try again."
        return None, error, None

    # handle form submission
    kudos_transfer = None
    if save_addr:
        profile.preferred_payout_address = address
        profile.save()

    private_key = settings.KUDOS_PRIVATE_KEY if not coupon.sender_pk else coupon.sender_pk
    kudos_owner_address = settings.KUDOS_OWNER_ACCOUNT if not coupon.sender_address else coupon.sender_address
    gas_price_confirmation_time = 1 if not coupon.sender_address else 60
    gas_price_multiplier = 1.3 if not coupon.sender_address else 1
    kudos_contract_address = Web3.toChecksumAddress(
        settings.KUDOS_CONTRACT_MAINNET)
    kudos_owner_address = Web3.toChecksumAddress(kudos_owner_address)
    w3 = get_web3(coupon.token.contract.network)
    contract = w3.eth.contract(Web3.toChecksumAddress(kudos_contract_address),
                               abi=kudos_abi())
    nonce = w3.eth.getTransactionCount(kudos_owner_address)
    gas_price = int(
        int(
            recommend_min_gas_price_to_confirm_in_time(
                gas_price_confirmation_time) * 10**9) * gas_price_multiplier)
    tx = contract.functions.clone(
        address, coupon.token.token_id, 1).buildTransaction({
            'nonce':
            nonce,
            'gas':
            500000,
            'gasPrice':
            gas_price,
            'value':
            int(coupon.token.price_finney / 1000.0 * 10**18),
        })

    if not profile.is_brightid_verified and not profile.is_twitter_verified and not profile.trust_profile and profile.github_created_on > (
            timezone.now() - timezone.timedelta(days=7)):
        error = f'Your github profile is too new, so you cannot receive kudos.  Please verifiy your profile on BrightID and/or Twitter to proceed.'
        return None, error, None
    else:

        if profile.bulk_transfer_redemptions.filter(coupon=coupon).exists():
            error = f'You have already redeemed this kudos.'
            return None, error, None

        signed = w3.eth.account.signTransaction(tx, private_key)
        retry_later = False
        tx_status = 'pending'

        if submit_later:
            txid = ''
            tx_status = 'not_subed'
        else:
            try:
                # TODO - in the future, override this if the user pays for expediated processing
                if recommend_min_gas_price_to_confirm_in_time(
                        1) > max_gas_price_we_are_willing_to_pay_gwei:
                    if coupon.token.contract.network == 'mainnet':
                        raise Exception(
                            "gas price is too high.  try again when its not pls"
                        )

                txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()
            except Exception as e:
                txid = "pending_celery"
                retry_later = True

        if exit_after_sending_tx:
            return txid, None, None

        with transaction.atomic():
            kudos_transfer = KudosTransfer.objects.create(
                emails=[profile.email],
                # For kudos, `token` is a kudos.models.Token instance.
                kudos_token_cloned_from=coupon.token,
                amount=coupon.token.price_in_eth,
                comments_public=coupon.comments_to_put_in_kudos_transfer,
                ip=ip_address,
                github_url='',
                from_name=coupon.sender_profile.handle,
                from_email='',
                from_username=coupon.sender_profile.handle,
                username=profile.handle,
                network=coupon.token.contract.network,
                from_address=kudos_owner_address,
                is_for_bounty_fulfiller=False,
                metadata={
                    'coupon_redemption': True,
                    'nonce': nonce
                },
                recipient_profile=profile,
                sender_profile=coupon.sender_profile,
                txid=txid,
                receive_txid=txid,
                tx_status=tx_status,
                receive_tx_status=tx_status,
                receive_address=address,
            )

            # save to DB
            BulkTransferRedemption.objects.create(
                coupon=coupon,
                redeemed_by=profile,
                ip_address=ip_address,
                kudostransfer=kudos_transfer,
            )

            coupon.num_uses_remaining -= 1
            coupon.current_uses += 1
            coupon.save()

            # user actions
            record_user_action(kudos_transfer.username, 'new_kudos',
                               kudos_transfer)
            record_user_action(kudos_transfer.from_username, 'receive_kudos',
                               kudos_transfer)
            record_kudos_activity(kudos_transfer, kudos_transfer.username,
                                  'receive_kudos')

            # send email
            maybe_market_kudos_to_email(kudos_transfer)

            if retry_later:
                redeem_bulk_kudos.delay(kudos_transfer.id)

    return True, None, kudos_transfer
Exemple #4
0
def redeem_bulk_coupon(coupon, profile, address, ip_address, save_addr=False):
    try:
        address = Web3.toChecksumAddress(address)
    except:
        error = "You must enter a valid Ethereum address (so we know where to send your Kudos). Please try again."
        return None, error, None

    # handle form submission
    kudos_transfer = None
    if save_addr:
        profile.preferred_payout_address = address
        profile.save()

    private_key = settings.KUDOS_PRIVATE_KEY if not coupon.sender_pk else coupon.sender_pk
    kudos_owner_address = settings.KUDOS_OWNER_ACCOUNT if not coupon.sender_address else coupon.sender_address
    gas_price_confirmation_time = 1 if not coupon.sender_address else 60
    kudos_contract_address = Web3.toChecksumAddress(settings.KUDOS_CONTRACT_MAINNET)
    kudos_owner_address = Web3.toChecksumAddress(kudos_owner_address)
    w3 = get_web3(coupon.token.contract.network)
    contract = w3.eth.contract(Web3.toChecksumAddress(kudos_contract_address), abi=kudos_abi())
    nonce = w3.eth.getTransactionCount(kudos_owner_address)
    tx = contract.functions.clone(address, coupon.token.token_id, 1).buildTransaction({
        'nonce': nonce,
        'gas': 500000,
        'gasPrice': int(recommend_min_gas_price_to_confirm_in_time(gas_price_confirmation_time) * 10**9),
        'value': int(coupon.token.price_finney / 1000.0 * 10**18),
    })

    if not profile.trust_profile and profile.github_created_on > (timezone.now() - timezone.timedelta(days=7)):
        error = f'Your github profile is too new.  Cannot receive kudos.'
        return None, error, None
    else:

        signed = w3.eth.account.signTransaction(tx, private_key)
        retry_later = False
        try:
            txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()
        except Exception as e:
            txid = "pending_celery"
            retry_later = True

        with transaction.atomic():
            kudos_transfer = KudosTransfer.objects.create(
                emails=[profile.email],
                # For kudos, `token` is a kudos.models.Token instance.
                kudos_token_cloned_from=coupon.token,
                amount=coupon.token.price_in_eth,
                comments_public=coupon.comments_to_put_in_kudos_transfer,
                ip=ip_address,
                github_url='',
                from_name=coupon.sender_profile.handle,
                from_email='',
                from_username=coupon.sender_profile.handle,
                username=profile.handle,
                network=coupon.token.contract.network,
                from_address=kudos_owner_address,
                is_for_bounty_fulfiller=False,
                metadata={'coupon_redemption': True, 'nonce': nonce},
                recipient_profile=profile,
                sender_profile=coupon.sender_profile,
                txid=txid,
                receive_txid=txid,
                tx_status='pending',
                receive_tx_status='pending',
            )

            # save to DB
            BulkTransferRedemption.objects.create(
                coupon=coupon,
                redeemed_by=profile,
                ip_address=ip_address,
                kudostransfer=kudos_transfer,
                )

            coupon.num_uses_remaining -= 1
            coupon.current_uses += 1
            coupon.save()

            # user actions
            record_user_action(kudos_transfer.username, 'new_kudos', kudos_transfer)
            record_user_action(kudos_transfer.from_username, 'receive_kudos', kudos_transfer)

            # send email
            maybe_market_kudos_to_email(kudos_transfer)

            if retry_later:
                from kudos.tasks import redeem_bulk_kudos
                redeem_bulk_kudos.delay(kudos_transfer.id, signed.rawTransaction.hex())

    return True, None, kudos_transfer