def __init__(self, w3: Web3, master_copy_address: str, proxy_factory_address: str): """ Init builder for safe creation using create2 :param w3: Web3 instance :param master_copy_address: `Gnosis Safe` master copy address :param proxy_factory_address: `Gnosis Proxy Factory` address """ assert Web3.isChecksumAddress(master_copy_address) assert Web3.isChecksumAddress(proxy_factory_address) self.w3 = w3 self.master_copy_address = master_copy_address self.proxy_factory_address = proxy_factory_address self.safe_version = get_safe_contract( w3, master_copy_address).functions.VERSION().call() if self.safe_version == '1.1.1': self.master_copy_contract = get_safe_contract( w3, master_copy_address) elif self.safe_version == '1.0.0': self.master_copy_contract = get_safe_V1_0_0_contract( w3, master_copy_address) else: raise ValueError('Safe version must be 1.1.1 or 1.0.0') self.proxy_factory_contract = get_proxy_factory_contract( w3, proxy_factory_address)
def build(self, owners: List[str], threshold: int, salt_nonce: int, gas_price: int, fallback_handler: Optional[str] = None, payment_receiver: Optional[str] = None, payment_token: Optional[str] = None, payment_token_eth_value: float = 1.0, fixed_creation_cost: Optional[int] = None): """ Prepare Safe creation :param owners: Owners of the Safe :param threshold: Minimum number of users required to operate the Safe :param fallback_handler: Handler for fallback calls to the Safe :param salt_nonce: Web3 instance :param gas_price: Gas Price :param payment_receiver: Address to refund when the Safe is created. Address(0) if no need to refund :param payment_token: Payment token instead of paying the funder with ether. If None Ether will be used :param payment_token_eth_value: Value of payment token per 1 Ether :param fixed_creation_cost: Fixed creation cost of Safe (Wei) """ assert 0 < threshold <= len(owners) fallback_handler = fallback_handler or NULL_ADDRESS payment_receiver = payment_receiver or NULL_ADDRESS payment_token = payment_token or NULL_ADDRESS assert Web3.isChecksumAddress(payment_receiver) assert Web3.isChecksumAddress(payment_token) # Get bytes for `setup(address[] calldata _owners, uint256 _threshold, address to, bytes calldata data, # address paymentToken, uint256 payment, address payable paymentReceiver)` # This initializer will be passed to the ProxyFactory to be called right after proxy is deployed # We use `payment=0` as safe has no ether yet and estimation will fail safe_setup_data: bytes = self._get_initial_setup_safe_data(owners, threshold, fallback_handler=fallback_handler, payment_token=payment_token, payment_receiver=payment_receiver) magic_gas: int = self._calculate_gas(owners, safe_setup_data, payment_token) estimated_gas: int = self._estimate_gas(safe_setup_data, salt_nonce, payment_token, payment_receiver) logger.debug('Magic gas %d - Estimated gas %d' % (magic_gas, estimated_gas)) gas = max(magic_gas, estimated_gas) # Payment will be safe deploy cost payment = self._calculate_refund_payment(gas, gas_price, fixed_creation_cost, payment_token_eth_value) # Now we have a estimate for `payment` so we get initialization data again final_safe_setup_data: bytes = self._get_initial_setup_safe_data(owners, threshold, fallback_handler=fallback_handler, payment_token=payment_token, payment=payment, payment_receiver=payment_receiver) safe_address = self.calculate_create2_address(final_safe_setup_data, salt_nonce) assert int(safe_address, 16), 'Calculated Safe address cannot be the NULL ADDRESS' return SafeCreate2Tx(salt_nonce, owners, threshold, fallback_handler, self.master_copy_address, self.proxy_factory_address, payment_receiver, payment_token, payment, gas, gas_price, payment_token_eth_value, fixed_creation_cost, safe_address, final_safe_setup_data)
def delete(self, request, address, delegate_address, *args, **kwargs): """ Delete a delegate for a Safe. Signature is built the same way that for adding a delegate. Check `POST /delegates/` """ if not Web3.isChecksumAddress(address) or not Web3.isChecksumAddress(delegate_address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data='Invalid ethereum address') request.data['safe'] = address request.data['delegate'] = delegate_address serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) return super().delete(request, address, delegate_address, *args, **kwargs)
def command_addorder(self, update: Update, context: CallbackContext): assert update.callback_query and context.user_data is not None query = update.callback_query assert query.data token_address = query.data.split(':')[1] if not Web3.isChecksumAddress(token_address): self.command_error(update, context, text='Invalid token address.') return ConversationHandler.END token = self.parent.watchers[token_address] context.user_data['addorder'] = {'token_address': token_address} reply_markup = InlineKeyboardMarkup(inline_keyboard=[ [ InlineKeyboardButton('🚫 Stop loss sell', callback_data='stop_loss'), InlineKeyboardButton('💰 Take profit sell', callback_data='limit_sell'), ], [ InlineKeyboardButton('💵 Limit buy', callback_data='limit_buy'), InlineKeyboardButton('❌ Cancel', callback_data='cancel'), ], ]) chat_message( update, context, text= f'Creating order for token {token.name}.\nWhich <u>type of order</u> would you like to create?', reply_markup=reply_markup, edit=self.config.update_messages, ) return self.next.TYPE
def command_edittoken(self, update: Update, context: CallbackContext): assert update.callback_query and context.user_data is not None query = update.callback_query assert query.data token_address = query.data.split(':')[1] if not Web3.isChecksumAddress(token_address): self.command_error(update, context, text='Invalid token address.') return ConversationHandler.END token: TokenWatcher = self.parent.watchers[token_address] context.user_data['edittoken'] = {'token_address': token_address} buttons = [ [ InlineKeyboardButton(f'{token.emoji}Edit emoji', callback_data='emoji'), InlineKeyboardButton('Edit default slippage', callback_data='slippage'), ], [ InlineKeyboardButton('Edit buy price', callback_data='buyprice'), InlineKeyboardButton('❌ Cancel', callback_data='cancel'), ], ] reply_markup = InlineKeyboardMarkup(buttons) chat_message( update, context, text=f'What do you want to edit for token {token.name}?', reply_markup=reply_markup, edit=self.config.update_messages, ) return self.next.ACTION_CHOICE
def post(self, request, address, *args, **kwargs): """ Estimates `safeTxGas` for a Safe Multisig Transaction. """ if not Web3.isChecksumAddress(address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ 'code': 1, 'message': 'Checksum address validation failed', 'arguments': [address] }) if not SafeContract.objects.filter(address=address).exists(): return Response(status=status.HTTP_404_NOT_FOUND) serializer = self.get_serializer(data=request.data) if serializer.is_valid(): try: response_serializer = self.response_serializer( data=serializer.save()) response_serializer.is_valid(raise_exception=True) return Response(status=status.HTTP_200_OK, data=response_serializer.data) except CannotEstimateGas: return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data=serializer.errors) else: return Response(status=status.HTTP_400_BAD_REQUEST, data=serializer.errors)
def get(self, request, address): """ Get balance for Ether and ERC20 tokens """ if not Web3.isChecksumAddress(address): return Response( status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ "code": 1, "message": "Checksum address validation failed", "arguments": [address], }, ) else: try: SafeContract.objects.get(address=address) except SafeContract.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) only_trusted, exclude_spam = self.get_parameters() safe_balances = self.get_result(address, only_trusted=only_trusted, exclude_spam=exclude_spam) serializer = self.get_serializer(safe_balances, many=True) return Response(status=status.HTTP_200_OK, data=serializer.data)
def delete(self, request, delegate_address, *args, **kwargs): """ Delete every pair delegate/delegator found. Signature is built the same way as for adding a delegate, but in this case the signer can be either the `delegator` (owner) or the `delegate` itself. Check `POST /delegates/` """ if not Web3.isChecksumAddress(delegate_address): return Response( status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ "code": 1, "message": "Checksum address validation failed", "arguments": [delegate_address], }, ) request.data["delegate"] = delegate_address serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) deleted, _ = SafeContractDelegate.objects.filter( delegate=serializer.validated_data["delegate"], delegator=serializer.validated_data["delegator"], ).delete() if deleted: return Response(status=status.HTTP_204_NO_CONTENT) else: return Response(status=status.HTTP_404_NOT_FOUND)
def process_airdrop(): print('\n\n\nProcessing AirDrop List') airdrop_list = [ i.strip() for i in open(constants.AIRDROP_FILE).read().split() if i.strip() ] airdrop_final = [] error = [] not_checksum = 0 duplicate = 0 for i in airdrop_list: if not Web3.isAddress(i): error.append(i) continue if not Web3.isChecksumAddress(i): not_checksum += 1 addr_with_checksum = Web3.toChecksumAddress(i) else: addr_with_checksum = i if i in airdrop_final: duplicate += 1 continue else: airdrop_final.append(i) print( 'Processing {} input address.\n{} addresses are invalid.\n{} addresses got corrected for checksum.\n{} addresses were duplicates.\nFinally got {} valid addresses' .format(len(airdrop_list), len(error), not_checksum, duplicate, len(airdrop_final))) # for i in error: # print (i) return airdrop_final
def get(self): ret = {'ret': 0, 'code': 0, 'msg': '', 'data': dict()} address = self.get_argument('address', '', True) est = self.get_argument('est', '', True) if not address or not est: ret['ret'] = ret['code'] = 400 ret['msg'] = 'address or est cannot be empty' self.write(json_encode(ret)) return address = Web3.toChecksumAddress(address) if not Web3.isChecksumAddress(address): ret['ret'] = ret['code'] = 400 ret['msg'] = 'address invalid' self.write(json_encode(ret)) return base_conf = estconf['base'] trans = TransactionMaker(provider_url=base_conf['provider_url'], my_wallet_address=base_conf['from_address']) trans.set_abi_type(erc20_abi_json=base_conf['erc20_abi']) value = int(float(est) * 10 ** 9) cost = trans.get_transfer_cost(to=address, value=value, contract_address=base_conf['contract_address']) if not cost: ret['ret'] = ret['code'] = 400 ret['msg'] = 'System maintenance' self.write(json_encode(ret)) return ret['data'] = {'cost': cost} self.write(json_encode(ret)) return
def get(self, request, address, *args, **kwargs): """ Get status of the safe """ if not Web3.isChecksumAddress(address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ 'code': 1, 'message': 'Checksum address validation failed', 'arguments': [address] }) if not SafeContract.objects.filter(address=address).exists(): return Response(status=status.HTTP_404_NOT_FOUND) try: safe_info = SafeServiceProvider().get_safe_info(address) serializer = self.serializer_class(safe_info) return Response(status=status.HTTP_200_OK, data=serializer.data) except CannotGetSafeInfo: return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ 'code': 50, 'message': 'Cannot get Safe info', 'arguments': [address] })
def test_get_multisig_transaction(self): safe_tx_hash = Web3.keccak(text='gnosis').hex() response = self.client.get(reverse('v1:multisig-transaction', args=(safe_tx_hash,)), format='json') self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) add_owner_with_threshold_data = HexBytes('0x0d582f130000000000000000000000001b9a0da11a5cace4e7035993cbb2e4' 'b1b3b164cf000000000000000000000000000000000000000000000000000000' '0000000001') multisig_tx = MultisigTransactionFactory(data=add_owner_with_threshold_data) safe_tx_hash = multisig_tx.safe_tx_hash response = self.client.get(reverse('v1:multisig-transaction', args=(safe_tx_hash,)), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['confirmations']), 0) self.assertTrue(Web3.isChecksumAddress(response.data['executor'])) self.assertEqual(response.data['transaction_hash'], multisig_tx.ethereum_tx.tx_hash) self.assertEqual(response.data['origin'], multisig_tx.origin) self.assertEqual(response.data['data_decoded'], {'addOwnerWithThreshold': [{'name': 'owner', 'type': 'address', 'value': '0x1b9a0DA11a5caCE4e703599' '3Cbb2E4B1B3b164Cf'}, {'name': '_threshold', 'type': 'uint256', 'value': 1}] }) # Test camelCase self.assertEqual(response.json()['transactionHash'], multisig_tx.ethereum_tx.tx_hash)
def test_get_multisig_transactions(self): safe_address = Account.create().address response = self.client.get(reverse('v1:multisig-transactions', args=(safe_address,)), format='json') self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) multisig_tx = MultisigTransactionFactory(safe=safe_address) response = self.client.get(reverse('v1:multisig-transactions', args=(safe_address,)), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['count'], 1) self.assertEqual(response.data['count_unique_nonce'], 1) self.assertEqual(len(response.data['results']), 1) self.assertEqual(len(response.data['results'][0]['confirmations']), 0) self.assertTrue(Web3.isChecksumAddress(response.data['results'][0]['executor'])) self.assertEqual(response.data['results'][0]['transaction_hash'], multisig_tx.ethereum_tx.tx_hash) # Test camelCase self.assertEqual(response.json()['results'][0]['transactionHash'], multisig_tx.ethereum_tx.tx_hash) # Check Etag header self.assertTrue(response['Etag']) MultisigConfirmationFactory(multisig_transaction=multisig_tx) response = self.client.get(reverse('v1:multisig-transactions', args=(safe_address,)), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data['results']), 1) self.assertEqual(len(response.data['results'][0]['confirmations']), 1) MultisigTransactionFactory(safe=safe_address, nonce=multisig_tx.nonce) response = self.client.get(reverse('v1:multisig-transactions', args=(safe_address,)), format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['count'], 2) self.assertEqual(response.data['count_unique_nonce'], 1)
def __init__(self, address: str, ethereum_client: EthereumClient): assert Web3.isChecksumAddress( address), '%s is not a valid address' % address self.ethereum_client = ethereum_client self.w3 = self.ethereum_client.w3 self.address = address
def handle(self): PoW(self.request) self.request.sendall(menu().encode('utf-8')) option = self.request.recv(1024).strip() try: option = int(option) if option == 1: session_id = random_token() self.request.sendall('Your token is: {}\r\n'.format(b64encode(session_id).decode('utf-8')).encode('utf-8')) self.request.sendall('Deploy challenge for you...\r\n'.encode('utf-8')) address = new_challenge() session[session_id] = Web3.toChecksumAddress(address) self.request.sendall('OK~ Your address is: {}'.format(address).encode('utf-8')) elif option == 2: self.request.sendall('Give me your token: \r\n> '.encode('utf-8')) token = b64decode(self.request.recv(1024).strip()) if Web3.isChecksumAddress(session[token]): self.request.sendall(get_flag(session[token]).encode('utf-8')) else: self.request.sendall(session[token].encode('utf-8')) else: raise('') except Exception as e: print(e) self.request.sendall('wrong, bye~~'.encode('utf-8'))
def validate_address(value): is_address = Web3.isAddress(value) if not is_address: raise ValidationError("Not valid Eth address. Please check it again") if not Web3.isChecksumAddress(value): raise ValidationError('Address has an invalid EIP checksum')
def post(self, request, address): """ Estimates a Safe Multisig Transaction for all tokens supported. `operational_gas` and `data_gas` are deprecated, use `base_gas` instead """ if not Web3.isChecksumAddress(address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY) request.data["safe"] = address serializer = self.get_serializer_class()(data=request.data) if serializer.is_valid(): data = serializer.validated_data transaction_estimations = ( TransactionServiceProvider().estimate_tx_for_all_tokens( address, data["to"], data["value"], data["data"], data["operation"] ) ) response_serializer = ( TransactionEstimationWithNonceAndGasTokensResponseSerializer( transaction_estimations ) ) return Response(status=status.HTTP_200_OK, data=response_serializer.data) else: return Response(status=status.HTTP_400_BAD_REQUEST, data=serializer.errors)
def process_addresses( self, safe_addresses: List[str]) -> Optional[Tuple[List[Any], bool]]: """ Find and process relevant data for `safe_addresses`, then store and return it :param safe_addresses: Addresses to process :return: List of processed data and a boolean (`True` if no more blocks to scan, `False` otherwise) """ assert safe_addresses, 'Safe addresses cannot be empty!' assert all([Web3.isChecksumAddress(safe_address) for safe_address in safe_addresses]), \ 'A safe address has invalid checksum: %s' % safe_addresses parameters = self.get_block_numbers_for_search(safe_addresses) if parameters is None: return from_block_number, to_block_number = parameters updated = to_block_number == ( self.ethereum_client.current_block_number - self.confirmations) tx_hashes = self.find_relevant_tx_hashes(safe_addresses, from_block_number, to_block_number) processed_objects = [ self.process_tx_hash(tx_hash) for tx_hash in tx_hashes ] flatten_processed_objects = [ item for sublist in processed_objects for item in sublist ] self.update_safe_tx_status(safe_addresses, to_block_number) return flatten_processed_objects, updated
def get(self, request, *args, **kwargs): """ Returns a paginated list of transactions for a Safe. The list has different structures depending on the transaction type: - Multisig Transactions for a Safe. `tx_type=MULTISIG_TRANSACTION`. If the query parameter `queued=False` is set only the transactions with `safe nonce < current Safe nonce` will be displayed. By default, only the `trusted` transactions will be displayed (transactions indexed, with at least one confirmation or proposed by a delegate). If you need that behaviour to be disabled set the query parameter `trusted=False` - Module Transactions for a Safe. `tx_type=MODULE_TRANSACTION` - Incoming Transfers of Ether/ERC20 Tokens/ERC721 Tokens. `tx_type=ETHEREUM_TRANSACTION` """ address = kwargs['address'] if not Web3.isChecksumAddress(address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ 'code': 1, 'message': 'Checksum address validation failed', 'arguments': [address] }) response = super().get(request, *args, **kwargs) response.setdefault( 'ETag', 'W/' + hashlib.md5(str(response.data['results']).encode()).hexdigest()) return response
def command_removeorder(self, update: Update, context: CallbackContext): assert update.callback_query and context.user_data is not None query = update.callback_query assert query.data token_address = query.data.split(':')[1] if not Web3.isChecksumAddress(token_address): self.command_error(update, context, text='Invalid token address.') return ConversationHandler.END token: TokenWatcher = self.parent.watchers[token_address] context.user_data['removeorder'] = {'token_address': token_address} orders = token.orders buttons: List[InlineKeyboardButton] = [ InlineKeyboardButton( f'{self.get_type_icon(o)} #{o.order_record.id} - {self.get_type_name(o)}', callback_data=o.order_record.id, ) for o in orders ] buttons_layout = [buttons[i:i + 2] for i in range(0, len(buttons), 2)] # noqa: E203 buttons_layout.append( [InlineKeyboardButton('❌ Cancel', callback_data='cancel')]) reply_markup = InlineKeyboardMarkup(inline_keyboard=buttons_layout) chat_message( update, context, text=f'Select the order you want to remove for {token.name}.', reply_markup=reply_markup, edit=self.config.update_messages, ) return self.next.CONFIRM
def get_balances(self, safe_address: str) -> List[Balance]: """ :param safe_address: :return: `{'token_address': str, 'balance': int}`. For ether, `token_address` is `None` """ assert Web3.isChecksumAddress( safe_address ), f'Not valid address {safe_address} for getting balances' erc20_addresses = list( EthereumEvent.objects.erc20_tokens_used_by_address(safe_address)) raw_balances = self.ethereum_client.erc20.get_balances( safe_address, erc20_addresses) balances = [] for balance in raw_balances: if not balance['token_address']: # Ether balance['token'] = None elif balance['balance'] > 0: balance['token'] = self.get_token_info( balance['token_address']) if not balance[ 'token']: # Ignore ERC20 tokens that cannot be queried continue else: continue balances.append(Balance(**balance)) return balances
def get_balances(self, safe_address: str, only_trusted: bool = False, exclude_spam: bool = False) -> List[Balance]: """ :param safe_address: :param only_trusted: If True, return balance only for trusted tokens :param exclude_spam: If True, exclude spam tokens :return: `{'token_address': str, 'balance': int}`. For ether, `token_address` is `None` """ assert Web3.isChecksumAddress(safe_address), f'Not valid address {safe_address} for getting balances' all_erc20_addresses = list(EthereumEvent.objects.erc20_tokens_used_by_address(safe_address)) for address in all_erc20_addresses: # Store tokens in database if not present self.get_token_info(address) # This is cached erc20_addresses = self._filter_addresses(all_erc20_addresses, only_trusted, exclude_spam) try: raw_balances = self.ethereum_client.erc20.get_balances(safe_address, erc20_addresses) except IOError as exc: raise NodeConnectionError from exc balances = [] for balance in raw_balances: if not balance['token_address']: # Ether balance['token'] = None elif balance['balance'] > 0: balance['token'] = self.get_token_info(balance['token_address']) if not balance['token']: # Ignore ERC20 tokens that cannot be queried continue else: continue balances.append(Balance(**balance)) return balances
def process_addresses(self, addresses: Sequence[str], current_block_number: Optional[int] = None) -> Tuple[Sequence[Any], bool]: """ Find and process relevant data for `addresses`, then store and return it :param addresses: Addresses to process :param current_block_number: To prevent fetching it again :return: List of processed data and a boolean (`True` if no more blocks to scan, `False` otherwise) """ assert addresses, 'Addresses cannot be empty!' assert all([Web3.isChecksumAddress(address) for address in addresses]), \ f'An address has invalid checksum: {addresses}' current_block_number = current_block_number or self.ethereum_client.current_block_number parameters = self.get_block_numbers_for_search(addresses, current_block_number) if parameters is None: return [], True from_block_number, to_block_number = parameters updated = to_block_number == (current_block_number - self.confirmations) # Optimize number of elements processed every time (block process limit) # Check that we are processing the `block_process_limit`, if not, measures are not valid if self.block_auto_process_limit and (to_block_number - from_block_number) == self.block_process_limit: start = time.time() else: start = None try: elements = self.find_relevant_elements(addresses, from_block_number, to_block_number, current_block_number=current_block_number) except (self.FindRelevantElementsException, SoftTimeLimitExceeded) as e: self.block_process_limit = min(self.initial_block_process_limit, 10) # Set back to less than default logger.info('%s: block_process_limit set back to %d', self.__class__.__name__, self.block_process_limit) raise e if start: end = time.time() time_diff = end - start if time_diff > 30: self.block_process_limit //= 2 logger.info('%s: block_process_limit halved to %d', self.__class__.__name__, self.block_process_limit) if time_diff > 10: new_block_process_limit = max(self.block_process_limit - 5000, 500) self.block_process_limit = new_block_process_limit logger.info('%s: block_process_limit decreased to %d', self.__class__.__name__, self.block_process_limit) elif time_diff < 1: self.block_process_limit *= 2 logger.info('%s: block_process_limit duplicated to %d', self.__class__.__name__, self.block_process_limit) elif time_diff < 3: self.block_process_limit += 5000 logger.info('%s: block_process_limit increased to %d', self.__class__.__name__, self.block_process_limit) processed_elements = self.process_elements(elements) self.update_monitored_address(addresses, from_block_number, to_block_number) return processed_elements, updated
def __init__(self, address: str, ethereum_client: EthereumClient): assert Web3.isChecksumAddress(address), \ '%s proxy factory address not valid' % address self.address = address self.ethereum_client = ethereum_client self.w3 = ethereum_client.w3
def process_presale_bonus(): print('\n\n\nProcessing Presale List') rows = [ i for i in csv.reader(open('presale.bonus.feb23-1800.tsv', 'r'), delimiter='\t') ] # neglect first row rows = rows[1:] presale_bonus_final = [] for row in rows: addr, tokens, cliff, notes, _, _, _ = row addr = addr.strip() if not Web3.isAddress(addr): print('Invalid Address <{}> for {}'.format(addr, notes)) continue if not Web3.isChecksumAddress(addr): addr = Web3.toChecksumAddress(addr) tokens = int(tokens.replace(',', '').strip()) presale_bonus_final.append([addr, tokens, int(cliff)]) print( 'Processed {} input and got {} valid presale allocation with {} total tokens' .format(len(rows), len(presale_bonus_final), sum(i[1] for i in presale_bonus_final))) return presale_bonus_final
def get(self, request, address, *args, **kwargs): """ Get status of the safe """ if not Web3.isChecksumAddress(address): return Response( status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ "code": 1, "message": "Checksum address validation failed", "arguments": [address], }, ) if not SafeContract.objects.filter(address=address).exists(): return Response(status=status.HTTP_404_NOT_FOUND) try: # safe_info = SafeServiceProvider().get_safe_info(address) safe_info = SafeServiceProvider().get_safe_info_from_blockchain( address) serializer = self.get_serializer(safe_info) return Response(status=status.HTTP_200_OK, data=serializer.data) except CannotGetSafeInfoFromBlockchain: return Response( status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ "code": 50, "message": "Cannot get Safe info from blockchain", "arguments": [address], }, )
def post(self, request, address): """ Estimates a Safe Multisig Transaction. `operational_gas` and `data_gas` are deprecated, use `base_gas` instead """ if not Web3.isChecksumAddress(address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY) else: try: SafeContract.objects.get(address=address) except SafeContract.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) request.data['safe'] = address serializer = self.get_serializer_class()(data=request.data) if serializer.is_valid(): data = serializer.validated_data transaction_estimations = TransactionServiceProvider( ).estimate_tx_for_all_tokens(address, data['to'], data['value'], data['data'], data['operation']) response_serializer = TransactionEstimationWithNonceAndGasTokensResponseSerializer( transaction_estimations) return Response(status=status.HTTP_200_OK, data=response_serializer.data) else: return Response(status=status.HTTP_400_BAD_REQUEST, data=serializer.errors)
def post(self, request, address, format=None): """ Creates a Multisig Transaction with its confirmations and retrieves all the information related. """ if not Web3.isChecksumAddress(address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data='Invalid ethereum address') request.data['safe'] = address serializer = self.get_serializer_class()(data=request.data) if not serializer.is_valid(): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY, data=serializer.errors) else: serializer.save() # Create task if transaction hash # data = serializer.validated_data # transaction_hash = data.get('transaction_hash') # if transaction_hash: # check_approve_transaction_task.delay(safe_address=address, # safe_tx_hash=data['contract_transaction_hash'].hex(), # transaction_hash=transaction_hash.hex(), # owner=data['sender']) return Response(status=status.HTTP_202_ACCEPTED)
def post(self, request, address, format=None): """ Send a Safe Multisig Transaction """ if not Web3.isChecksumAddress(address): return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY) request.data['safe'] = address serializer = self.get_serializer_class()(data=request.data) if not serializer.is_valid(): return Response(status=status.HTTP_400_BAD_REQUEST, data=serializer.errors) else: data = serializer.validated_data safe_multisig_tx = TransactionServiceProvider().create_multisig_tx( safe_address=data['safe'], to=data['to'], value=data['value'], data=data['data'], operation=data['operation'], safe_tx_gas=data['safe_tx_gas'], base_gas=data['data_gas'], gas_price=data['gas_price'], gas_token=data['gas_token'], refund_receiver=data['refund_receiver'], safe_nonce=data['nonce'], signatures=data['signatures']) response_serializer = SafeMultisigTxResponseSerializer( safe_multisig_tx) return Response(status=status.HTTP_201_CREATED, data=response_serializer.data)
def get(self, request, *args, **kwargs): address = self.kwargs["address"] if not Web3.isChecksumAddress(address): return response.Response( status=status.HTTP_422_UNPROCESSABLE_ENTITY, data={ "code": 1, "message": "Invalid ethereum address", "arguments": [address], }, ) price_service = PriceServiceProvider() if address == NULL_ADDRESS: data = { "fiat_code": "USD", "fiat_price": str(price_service.get_native_coin_usd_price()), "timestamp": timezone.now(), } else: token = self.get_object() # Raises 404 if not found fiat_price_with_timestamp = next( price_service.get_cached_usd_values( [token.get_price_address()])) data = { "fiat_code": fiat_price_with_timestamp.fiat_code.name, "fiat_price": str(fiat_price_with_timestamp.fiat_price), "timestamp": fiat_price_with_timestamp.timestamp, } serializer = self.get_serializer(data=data) assert serializer.is_valid() return Response(status=status.HTTP_200_OK, data=serializer.data)