-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathblockchain.js
191 lines (177 loc) · 6.23 KB
/
blockchain.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import Big from 'big.js'
import { BigNumber, Contract, providers, Wallet } from 'ethers'
import { readFile } from 'fs/promises'
export function makeBzz(decimalString) {
return new Big(decimalString).mul(new Big(10).pow(16)).toString()
}
export function makeDai(decimalString) {
return new Big(decimalString).mul(new Big(10).pow(18)).toString()
}
export async function unlockV3(path, password) {
const json = await readFile(path, 'utf8')
const wallet = await Wallet.fromEncryptedJson(json, password)
const privateKey = wallet.privateKey
const address = await wallet.getAddress()
return { privateKey, address }
}
export async function privateKeyToAddress(privateKeyString) {
const wallet = new Wallet(privateKeyString)
const address = await wallet.getAddress()
return address
}
const ABI = {
uniswap: [
{
inputs: [
{
internalType: 'uint256',
name: 'amountOutMin',
type: 'uint256'
},
{
internalType: 'address[]',
name: 'path',
type: 'address[]'
},
{
internalType: 'address',
name: 'to',
type: 'address'
},
{
internalType: 'uint256',
name: 'deadline',
type: 'uint256'
}
],
name: 'swapExactETHForTokens',
outputs: [
{
internalType: 'uint256[]',
name: 'amounts',
type: 'uint256[]'
}
],
stateMutability: 'payable',
type: 'function'
}
],
bzz: [
{
type: 'function',
stateMutability: 'nonpayable',
payable: false,
outputs: [
{
type: 'bool',
name: ''
}
],
name: 'transfer',
inputs: [
{
type: 'address',
name: '_to'
},
{
type: 'uint256',
name: '_value'
}
],
constant: false
},
{
constant: true,
inputs: [
{
name: '_owner',
type: 'address'
}
],
name: 'balanceOf',
outputs: [
{
name: 'balance',
type: 'uint256'
}
],
payable: false,
type: 'function'
}
]
}
export async function swap(privateKey, value, minimumReturnValue, jsonRpcProvider) {
const signer = await makeReadySigner(privateKey, jsonRpcProvider)
const gasLimit = 29000000
const contract = new Contract('0x1C232F01118CB8B424793ae03F870aa7D0ac7f77', ABI.uniswap, signer)
const WRAPPED_XDAI_CONTRACT = '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d'
const BZZ_ON_XDAI_CONTRACT = '0xdbf3ea6f5bee45c02255b2c26a16f300502f68da'
const response = await contract.swapExactETHForTokens(
minimumReturnValue,
[WRAPPED_XDAI_CONTRACT, BZZ_ON_XDAI_CONTRACT],
await signer.getAddress(),
Date.now(),
{ value, gasLimit }
)
return response
}
export async function drain(privateKey, to, rescuePrivateKey = null, jsonRpcProvider) {
const DAI_IGNORE_THRESHOLD = makeDai('0.01')
const DAI_RESCUE_VALUE = makeDai('0.1')
const DAI_SAFE_SUB_VALUE = makeDai('0.008')
const address = await privateKeyToAddress(privateKey)
let dai = await getNativeBalance(address, jsonRpcProvider)
const bzz = await getBzzBalance(address, jsonRpcProvider)
if (BigNumber.from(dai).lt(DAI_IGNORE_THRESHOLD) && BigNumber.from(bzz).gt('0') && rescuePrivateKey) {
await sendNativeTransaction(rescuePrivateKey, address, DAI_RESCUE_VALUE, jsonRpcProvider)
dai = await getNativeBalance(address, jsonRpcProvider)
}
if (BigNumber.from(bzz).gt('0')) {
await sendBzzTransaction(privateKey, to, bzz, jsonRpcProvider)
}
if (BigNumber.from(dai).gt(DAI_IGNORE_THRESHOLD)) {
await sendNativeTransaction(
privateKey,
to,
BigNumber.from(dai).sub(DAI_SAFE_SUB_VALUE).toString(),
jsonRpcProvider
)
}
}
export async function getNativeBalance(address, jsonRpcProvider) {
const provider = await makeReadyProvider(jsonRpcProvider)
const bigNumberBalance = await provider.getBalance(address)
return bigNumberBalance.toString()
}
export async function getBzzBalance(address, jsonRpcProvider) {
const provider = await makeReadyProvider(jsonRpcProvider)
const bzz = new Contract('0xdBF3Ea6F5beE45c02255B2c26a16F300502F68da', ABI.bzz, provider)
const bigNumberBalance = await bzz.balanceOf(address)
return bigNumberBalance.toString()
}
export async function sendNativeTransaction(privateKey, to, value, jsonRpcProvider) {
const signer = await makeReadySigner(privateKey, jsonRpcProvider)
const gasPrice = await signer.getGasPrice()
const transaction = await signer.sendTransaction({ to, value, gasPrice })
const receipt = await transaction.wait(1)
return { transaction, receipt }
}
export async function sendBzzTransaction(privateKey, to, value, jsonRpcProvider) {
const signer = await makeReadySigner(privateKey, jsonRpcProvider)
const gasPrice = await signer.getGasPrice()
const bzz = new Contract('0xdBF3Ea6F5beE45c02255B2c26a16F300502F68da', ABI.bzz, signer)
const transaction = await bzz.transfer(to, value, { gasPrice })
const receipt = await transaction.wait(1)
return { transaction, receipt }
}
async function makeReadySigner(privateKey, jsonRpcProvider) {
const provider = new providers.JsonRpcProvider(jsonRpcProvider, 100)
await provider.ready
const signer = new Wallet(privateKey, provider)
return signer
}
async function makeReadyProvider(jsonRpcProvider) {
const provider = new providers.JsonRpcProvider(jsonRpcProvider, 100)
await provider.ready
return provider
}