Skip to content

Instantly share code, notes, and snippets.

@laurenceday
Last active October 22, 2023 03:29
Show Gist options
  • Save laurenceday/53071c0253c5599c22a21490b97f06bb to your computer and use it in GitHub Desktop.
Save laurenceday/53071c0253c5599c22a21490b97f06bb to your computer and use it in GitHub Desktop.
# 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()
@hello-eternity
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment