Beispiel #1
0
def redeem_bulk_kudos(self, kt_id, retry=False):
    """
    :param self:
    :param kt_id:
    :return:
    """
    try:
        with redis.lock("tasks:redeem_bulk_kudos:%s" % kt_id,
                        timeout=LOCK_TIMEOUT):
            multiplier = 1
            # high gas prices, 5 hour gas limit - DL
            gas_price = int(
                float(recommend_min_gas_price_to_confirm_in_time(300)) *
                multiplier)
            if gas_price > delay_if_gas_prices_gt_redeem:
                # do not retry is gas prices are too high
                # TODO: revisit this when gas prices go down
                # self.retry(countdown=60*10)
                return

            obj = KudosTransfer.objects.get(pk=kt_id)
            w3 = get_web3(obj.network)
            token = obj.kudos_token_cloned_from
            if token.owner_address.lower(
            ) != '0x6239FF1040E412491557a7a02b2CBcC5aE85dc8F'.lower():
                raise Exception(
                    "kudos isnt owned by Gitcoin; cowardly refusing to spend Gitcoin's ETH minting it"
                )
            kudos_owner_address = settings.KUDOS_OWNER_ACCOUNT
            kudos_owner_address = Web3.toChecksumAddress(kudos_owner_address)
            kudos_contract_address = Web3.toChecksumAddress(
                settings.KUDOS_CONTRACT_MAINNET)
            contract = w3.eth.contract(
                Web3.toChecksumAddress(kudos_contract_address),
                abi=kudos_abi())
            nonce = w3.eth.getTransactionCount(kudos_owner_address)
            tx = contract.functions.clone(
                Web3.toChecksumAddress(obj.receive_address), token.token_id,
                1).buildTransaction({
                    'nonce':
                    nonce,
                    'gas':
                    500000,
                    'gasPrice':
                    gas_price,
                    'value':
                    int(token.price_finney / 1000.0 * 10**18),
                })
            private_key = settings.KUDOS_PRIVATE_KEY
            signed = w3.eth.account.signTransaction(tx, private_key)
            obj.txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()
            obj.receive_txid = obj.txid
            obj.save()
            while not has_tx_mined(obj.txid, obj.network):
                time.sleep(1)
            pass
    except (SoftTimeLimitExceeded, TimeLimitExceeded):
        print('max timeout for bulk kudos redeem exceeded ... giving up!')
    except Exception as e:
        print(e)
        if self.request.retries < self.max_retries:
            self.retry(countdown=(30 * (self.request.retries + 1)))
        else:
            print("max retries for bulk kudos redeem exceeded ... giving up!")
Beispiel #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)
Beispiel #3
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:
        raise PermissionDenied

    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

    if request.POST:
        address = Web3.toChecksumAddress(
            request.POST.get('forwarding_address'))
        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())
        tx = contract.functions.clone(
            address, coupon.token.token_id, 1).buildTransaction({
                'nonce':
                get_nonce(coupon.token.contract.network, kudos_owner_address),
                'gas':
                500000,
                'gasPrice':
                int(recommend_min_gas_price_to_confirm_in_time(5) * 10**9),
                'value':
                int(coupon.token.price_finney / 1000.0 * 10**18),
            })

        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},
                recipient_profile=profile,
                sender_profile=coupon.sender_profile,
                txid=txid,
                receive_txid=txid,
            )

            # 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

    title = f"Redeem AirDropped *{coupon.token.humanized_name}* Kudos"
    desc = f"This Kudos has been AirDropped to you.  About this Kudos: {coupon.token.description}"
    params = {
        'title': title,
        'card_title': title,
        'card_desc': desc,
        'avatar_url': coupon.token.img_url,
        'coupon': coupon,
        'user': request.user,
        'is_authed': request.user.is_authenticated,
        'kudos_transfer': kudos_transfer,
    }
    return TemplateResponse(request, 'transaction/receive_bulk.html', params)
Beispiel #4
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
Beispiel #5
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
Beispiel #6
0
def redeem_bulk_kudos(self,
                      kt_id,
                      delay_if_gas_prices_gt_redeem=50,
                      override_gas_price=None,
                      send_notif_email=False,
                      override_lock_timeout=LOCK_TIMEOUT,
                      retry=False):
    """
    :param self:
    :param kt_id:
    :return:
    """
    try:
        if True:  # override for allowing many xdai minting; we can change this back later there is a race condition
            # but for now the lock was providing more trouble than good - KO 10/20/2020
            #with redis.lock("tasks:redeem_bulk_kudos:%s" % kt_id, timeout=override_lock_timeout):
            multiplier = 1
            # high gas prices, 5 hour gas limit - DL
            gas_price = int(
                float(recommend_min_gas_price_to_confirm_in_time(300)) *
                multiplier)
            if override_gas_price:
                gas_price = override_gas_price
            if gas_price > delay_if_gas_prices_gt_redeem:
                # do not retry is gas prices are too high
                # TODO: revisit this when gas prices go down
                # self.retry(countdown=60*10)
                return

            if override_gas_price:
                gas_price = override_gas_price * 10**9
            obj = KudosTransfer.objects.get(pk=kt_id)
            w3 = get_web3(obj.network)
            token = obj.kudos_token_cloned_from
            if token.owner_address.lower(
            ) != '0x6239FF1040E412491557a7a02b2CBcC5aE85dc8F'.lower():
                raise Exception(
                    "kudos isnt owned by Gitcoin; cowardly refusing to spend Gitcoin's ETH minting it"
                )
            kudos_owner_address = settings.KUDOS_OWNER_ACCOUNT
            kudos_owner_address = Web3.toChecksumAddress(kudos_owner_address)
            contract_addr = settings.KUDOS_CONTRACT_MAINNET
            if obj.network == 'xdai':
                contract_addr = settings.KUDOS_CONTRACT_XDAI
            if obj.network == 'rinkeby':
                contract_addr = settings.KUDOS_CONTRACT_RINKEBY
            kudos_contract_address = Web3.toChecksumAddress(contract_addr)
            contract = w3.eth.contract(
                Web3.toChecksumAddress(kudos_contract_address),
                abi=kudos_abi())
            nonce = w3.eth.getTransactionCount(kudos_owner_address)
            tx = contract.functions.clone(
                Web3.toChecksumAddress(obj.receive_address), token.token_id,
                1).buildTransaction({
                    'nonce':
                    nonce,
                    'gas':
                    500000,
                    'gasPrice':
                    gas_price,
                    'value':
                    int(token.price_finney / 1000.0 * 10**18),
                })
            private_key = settings.KUDOS_PRIVATE_KEY
            signed = w3.eth.account.signTransaction(tx, private_key)
            obj.txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()
            obj.receive_txid = obj.txid
            obj.save()
            while not has_tx_mined(obj.txid, obj.network):
                time.sleep(1)
            pass
            if send_notif_email:
                from_email = '*****@*****.**'
                from_name = 'Kevin @ Gitcoin'
                _to_email = obj.recipient_profile.email
                subject = f"Your '{obj.kudos_token_cloned_from.name}' Kudos has been minted 🌈"
                block_url = f'https://etherscan.io/tx/{obj.txid}'
                if obj.network == 'xdai':
                    block_url = f'https://blockscout.com/poa/xdai/tx/{obj.txid}/internal-transactions'
                body = f'''
Hello @{obj.recipient_profile.handle},

Back on {obj.created_on} you minted a '{obj.kudos_token_cloned_from.name}' Kudos, but the Ethereum network's gas fees were too high for us to mint it on-chain.

We're writing with good news.  The gas prices on Ethereum have come down, and we are have now minted your token.  You can now see the Kudos in your gitcoin profile ( https://gitcoin.co/{obj.recipient_profile.handle} ) or any blockchain wallet that connects to the {obj.network} network ( {block_url} ).  HOORAY!

Party on,
Kevin + the Gitcoin team
                '''
                send_mail(from_email,
                          _to_email,
                          subject,
                          body,
                          from_name=from_name)
    except (SoftTimeLimitExceeded, TimeLimitExceeded):
        print('max timeout for bulk kudos redeem exceeded ... giving up!')
    except Exception as e:
        print(e)
        if self.request.retries < self.max_retries:
            self.retry(countdown=(30 * (self.request.retries + 1)))
        else:
            print("max retries for bulk kudos redeem exceeded ... giving up!")
    kudos_contract_address = Web3.toChecksumAddress(
        settings.KUDOS_CONTRACT_MAINNET)
    if network == 'xdai':
        kudos_contract_address = Web3.toChecksumAddress(
            settings.KUDOS_CONTRACT_XDAI)
    kudos_owner_address = Web3.toChecksumAddress(settings.KUDOS_OWNER_ACCOUNT)
    nonce = w3.eth.getTransactionCount(kudos_owner_address)

    token_id = kt.kudos_token_cloned_from.token_id
    address = kt.receive_address
    price_finney = kt.kudos_token_cloned_from.price_finney

    try:

        contract = w3.eth.contract(
            Web3.toChecksumAddress(kudos_contract_address), abi=kudos_abi())
        gasPrice = int(gas_multiplier * float(
            recommend_min_gas_price_to_confirm_in_time(gas_clear_within_mins))
                       * 10**9)
        if network == 'xdai':
            gasPrice = 1 * 10**9
        tx = contract.functions.clone(address, token_id, 1).buildTransaction({
            'nonce':
            nonce,
            'gas':
            500000,
            'gasPrice':
            gasPrice,
            'value':
            int(price_finney / 1000.0 * 10**18),
        })
Beispiel #8
0
def redeem_bulk_kudos(self, kt_id, retry=False):
    """
    :param self:
    :param kt_id:
    :return:
    """
    with redis.lock("tasks:all_kudos_requests", timeout=LOCK_TIMEOUT):
        with redis.lock("tasks:redeem_bulk_kudos:%s" % kt_id,
                        timeout=LOCK_TIMEOUT):
            from dashboard.utils import has_tx_mined
            from gas.utils import recommend_min_gas_price_to_confirm_in_time
            try:
                multiplier = 1
                gas_price = int(
                    float(recommend_min_gas_price_to_confirm_in_time(1)) *
                    multiplier)
                if gas_price > delay_if_gas_prices_gt:
                    self.retry(countdown=120)
                    return

                obj = KudosTransfer.objects.get(pk=kt_id)
                w3 = get_web3(obj.network)
                token = obj.kudos_token_cloned_from
                if token.owner_address.lower(
                ) != '0x6239FF1040E412491557a7a02b2CBcC5aE85dc8F'.lower():
                    raise Exception(
                        "kudos isnt owned by Gitcoin; cowardly refusing to spend Gitcoin's ETH minting it"
                    )
                kudos_owner_address = settings.KUDOS_OWNER_ACCOUNT
                kudos_owner_address = Web3.toChecksumAddress(
                    kudos_owner_address)
                kudos_contract_address = Web3.toChecksumAddress(
                    settings.KUDOS_CONTRACT_MAINNET)
                contract = w3.eth.contract(
                    Web3.toChecksumAddress(kudos_contract_address),
                    abi=kudos_abi())
                nonce = w3.eth.getTransactionCount(kudos_owner_address)
                tx = contract.functions.clone(
                    Web3.toChecksumAddress(obj.receive_address),
                    token.token_id, 1).buildTransaction({
                        'nonce':
                        nonce,
                        'gas':
                        500000,
                        'gasPrice':
                        gas_price,
                        'value':
                        int(token.price_finney / 1000.0 * 10**18),
                    })
                private_key = settings.KUDOS_PRIVATE_KEY
                signed = w3.eth.account.signTransaction(tx, private_key)
                obj.txid = w3.eth.sendRawTransaction(
                    signed.rawTransaction).hex()
                obj.receive_txid = obj.txid
                obj.save()
                while not has_tx_mined(obj.txid, obj.network):
                    time.sleep(1)
                pass
            except Exception as e:
                print(e)
                self.retry(countdown=(30 * (self.request.retries + 1)))
Beispiel #9
0
def receive_bulk_ethdenver(request, secret):

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

    coupon = coupons.first()

    kudos_transfer = ""
    if coupon.num_uses_remaining <= 0:
        messages.info(
            request,
            f'Sorry but this kudos redeem link has expired! Please contact the person who sent you the coupon link, or contact your nearest Gitcoin representative.'
        )
        return redirect(coupon.token.url)

    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 not error:
            address = Web3.toChecksumAddress(
                request.POST.get('forwarding_address'))
            already_claimed = KudosTransfer.objects.filter(
                receive_address=address, kudos_token_cloned_from=coupon.token)
            if already_claimed.count() > 0:
                messages.info(
                    request,
                    f'You already redeemed this kudos! If you think this wrong contact the ETHDenver Team!'
                )
                return redirect(coupon.token.url)
            ip_address = get_ip(request)

            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)
            nonce = w3.eth.getTransactionCount(kudos_owner_address)
            contract = w3.eth.contract(
                Web3.toChecksumAddress(kudos_contract_address),
                abi=kudos_abi())
            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(1) * 10**9),
                    'value':
                    int(coupon.token.price_finney / 1000.0 * 10**18),
                })

            try:
                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=["*****@*****.**"],
                        # 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,
                        network=coupon.token.contract.network,
                        from_address=settings.KUDOS_OWNER_ACCOUNT,
                        receive_address=address,
                        is_for_bounty_fulfiller=False,
                        metadata={'coupon_redemption': True},
                        sender_profile=coupon.sender_profile,
                        txid=txid,
                        receive_txid=txid,
                        tx_status='pending',
                        receive_tx_status='pending',
                    )

                    coupon.num_uses_remaining -= 1
                    coupon.current_uses += 1
                    coupon.save()
            except:
                error = "Could not redeem your kudos.  Please try again soon."

    title = f"Redeem ETHDenver event kudos: *{coupon.token.humanized_name}*"
    desc = f"Thank you for joining the event! 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,
    }
    return TemplateResponse(request, 'ethdenver2019/receive_bulk.html', params)
Beispiel #10
0
def re_send_kudos_transfer(kt, override_with_xdai_okay):
    from dashboard.utils import get_web3, has_tx_mined
    from gas.utils import recommend_min_gas_price_to_confirm_in_time
    from kudos.utils import kudos_abi
    from web3 import Web3
    from kudos.models import KudosTransfer
    from django.utils import timezone

    gas_clear_within_mins = 1
    gas_multiplier = 1.2

    if not kt.kudos_token_cloned_from.is_owned_by_gitcoin:
        print(f'{kt.id} => not owned by gitcoin')
        return

    network = kt.network
    if network == 'mainnet':
        if kt.kudos_token_cloned_from.on_xdai and override_with_xdai_okay:
            network = 'xdai'
            kt.network = 'xdai'
            kt.kudos_token_cloned_from = kt.kudos_token_cloned_from.on_xdai
            kt.save()
    w3 = get_web3(network)
    kudos_contract_address = Web3.toChecksumAddress(
        settings.KUDOS_CONTRACT_MAINNET)
    if network == 'xdai':
        kudos_contract_address = Web3.toChecksumAddress(
            settings.KUDOS_CONTRACT_XDAI)
    kudos_owner_address = Web3.toChecksumAddress(settings.KUDOS_OWNER_ACCOUNT)
    nonce = w3.eth.getTransactionCount(kudos_owner_address)

    token_id = kt.kudos_token_cloned_from.token_id
    address = kt.receive_address
    if not address:
        address = kt.recipient_profile.preferred_payout_address
    if not address:
        address = kt.recipient_profile.last_observed_payout_address
    price_finney = kt.kudos_token_cloned_from.price_finney

    try:

        contract = w3.eth.contract(
            Web3.toChecksumAddress(kudos_contract_address), abi=kudos_abi())
        gasPrice = int(gas_multiplier * float(
            recommend_min_gas_price_to_confirm_in_time(gas_clear_within_mins))
                       * 10**9)
        if network == 'xdai':
            gasPrice = 1 * 10**9
        tx = contract.functions.clone(Web3.toChecksumAddress(address),
                                      token_id, 1).buildTransaction({
                                          'nonce':
                                          nonce,
                                          'gas':
                                          500000,
                                          'gasPrice':
                                          gasPrice,
                                          'value':
                                          int(price_finney / 1000.0 * 10**18),
                                      })

        signed = w3.eth.account.signTransaction(tx, settings.KUDOS_PRIVATE_KEY)
        txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()
        nonce += 1
        print(f'sent tx nonce:{nonce} for kt:{kt.id} on {network}')
        kt.txid = txid
        kt.receive_txid = txid
        kt.tx_status = 'pending'
        kt.receive_tx_status = 'pending'
        kt.network = network
        kt.tx_time = timezone.now()
        kt.receive_tx_time = timezone.now()
        kt.save()
        return txid

    except Exception as e:
        print(e)
        error = "Could not redeem your kudos.  Please try again soon."
    return None
Beispiel #11
0
kudos_owner_address = Web3.toChecksumAddress(settings.KUDOS_OWNER_ACCOUNT)
nonce = w3.eth.getTransactionCount(kudos_owner_address)

# pk range to re-send
min_pk = 1684
max_pk = 1740
TIME_SLEEP = 1

for kt in KudosTransfer.objects.filter(pk__gte=min_pk, pk__lte=max_pk):

    token_id = kt.kudos_token_cloned_from.token_id
    address = kt.receive_address
    price_finney = kt.kudos_token_cloned_from.price_finney

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

    signed = w3.eth.account.signTransaction(tx, settings.KUDOS_PRIVATE_KEY)
    time.sleep(TIME_SLEEP)

    try: