Last active
October 22, 2023 03:29
-
-
Save laurenceday/53071c0253c5599c22a21490b97f06bb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# You'll need to pip install web3 for this, everything else should come as standard | |
# Works as 'python snipertech.py {target-casesensitive} {sharesToBuy-1_to_9} {maximum_total_amount_in_ETH} | |
# e.g. python snipertech.py functi0nZer0 1 0.4 | |
# Loops in ten second increments to try and buy your shares if they don't exist on FriendTech yet, then crashes out | |
# Adjust loop length on line 86 if you want to be less frequent - if they already exist, it just buys and dies. | |
import requests | |
import sys | |
import time | |
from web3 import Web3, HTTPProvider | |
ENDPOINT_URL = "https://rpc.ankr.com/base/<SIGN_UP_AND_GET_ONE>" | |
PRIVATE_KEY = "<YOUR_FRIENDTECH_ADDRESS_PRIVATE_KEY>" | |
PUBLIC_ADDR = "<YOUR_FRIENDTECH_PUBLIC_ADDRESS>" | |
CONTRACT_ABI = '[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"address","name":"subject","type":"address"},{"indexed":false,"internalType":"bool","name":"isBuy","type":"bool"},{"indexed":false,"internalType":"uint256","name":"shareAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"protocolEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"subjectEthAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"Trade","type":"event"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"supply","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getSellPriceAfterFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeDestination","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sharesSubject","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sellShares","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeDestination","type":"address"}],"name":"setFeeDestination","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setProtocolFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setSubjectFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"sharesBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sharesSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subjectFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]' | |
CONTRACT_ADDRESS = '0xCF205808Ed36593aa40a44F10c7f7C2F67d4A4d4' | |
w3 = Web3(HTTPProvider(ENDPOINT_URL)) | |
hexcode = "0x6945b123000000000000000000000000" | |
u256 = "0000000000000000000000000000000000000000000000000000000000000001" | |
def send_transaction(accountName, shares, maximumBid): | |
nonce = w3.eth.get_transaction_count(PUBLIC_ADDR) | |
chain_id = 8453 | |
txn = { | |
'nonce': nonce, | |
'gas': 2000000, | |
'gasPrice': w3.to_wei('20', 'gwei'), | |
'chainId': chain_id, | |
} | |
replacedu256 = u256[:-1] + shares | |
contract = w3.eth.contract(address=CONTRACT_ADDRESS, abi=CONTRACT_ABI) | |
txdatapayload = hexcode + accountName.replace("0x", "", 1) + replacedu256 | |
print(txdatapayload) | |
buy_price = contract.functions.getBuyPriceAfterFee(accountName, int(shares)).call() | |
print('Cost of shares: ' + str(buy_price/1e18) + ' ETH') | |
txn['value'] = buy_price | |
txn['data'] = txdatapayload | |
txn['to'] = CONTRACT_ADDRESS | |
print("Maximum bid is: " + maximumBid + " ETH") | |
# Sign and send the transaction, IFF buy_price <= maximumBid | |
if (buy_price > float(maximumBid) * 1e18): | |
return "Too expensive, aborting..." | |
else: | |
signed_txn = w3.eth.account.sign_transaction(txn, PRIVATE_KEY) | |
print("Purchasing...") | |
txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) | |
receipt = w3.eth.wait_for_transaction_receipt(txn_hash) | |
print("Done! Transaction receipt: ", receipt) | |
return receipt | |
def user_to_addr(user): | |
r = requests.get("https://prod-api.kosetto.com/search/users?username="+user) | |
if r.status_code == 200: | |
res = r.json() | |
u = [u for u in res['users'] if u['twitterUsername'] == user] | |
if len(u) == 1: | |
return Web3.to_checksum_address(u[0]['address']) | |
def main(): | |
sniped = False | |
target = sys.argv[1] | |
amount = sys.argv[2] | |
maxBid = sys.argv[3] | |
while (sniped == False): | |
print("[" + str(time.ctime()) + "] Searching for " + target) | |
targetAddr = str(user_to_addr(target)) | |
print("Found: " + targetAddr) | |
if (targetAddr == 'None'): | |
print("Target not on FriendTech, aborting...") | |
elif (int(amount) < 10): | |
receipt = send_transaction(targetAddr, amount, maxBid) | |
sniped = True | |
break; | |
else: | |
print("Max 9 shares (I'm lazy with formatting the hex)") | |
time.sleep(10) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
seems cannot send request to:https://prod-api.kosetto.com/search/users?username="+user