Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09c24e12c9 | ||
|
|
c1c6079745 | ||
|
|
eaaa54b7f9 | ||
|
|
6adf89472e | ||
|
|
b6ed5d2bc0 | ||
|
|
b4ee1e5117 | ||
|
|
56aa312829 | ||
|
|
07dcb5d258 | ||
|
|
4a17833462 | ||
|
|
c6652baa7c |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tx-manager",
|
"name": "tx-manager",
|
||||||
"version": "0.4.0",
|
"version": "0.4.7",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async-mutex": "^0.2.4",
|
"async-mutex": "^0.2.4",
|
||||||
"ethers": "^5.4.6",
|
"ethers": "^5.4.6",
|
||||||
"gas-price-oracle": "^0.3.5",
|
"gas-price-oracle": "^0.4.7",
|
||||||
"web3-core-promievent": "^1.3.0"
|
"web3-core-promievent": "^1.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -6,21 +6,27 @@ const { sleep, min, max } = require('./utils')
|
|||||||
|
|
||||||
const nonceErrors = [
|
const nonceErrors = [
|
||||||
'Transaction nonce is too low. Try incrementing the nonce.',
|
'Transaction nonce is too low. Try incrementing the nonce.',
|
||||||
'nonce too low',
|
/nonce too low/i,
|
||||||
'nonce has already been used',
|
'nonce has already been used',
|
||||||
|
/OldNonce/,
|
||||||
|
'invalid transaction nonce',
|
||||||
]
|
]
|
||||||
|
|
||||||
const gasPriceErrors = [
|
const gasPriceErrors = [
|
||||||
'Transaction gas price supplied is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce.',
|
'Transaction gas price supplied is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce.',
|
||||||
'replacement transaction underpriced',
|
/replacement transaction underpriced/i,
|
||||||
'transaction underpriced',
|
/transaction underpriced/,
|
||||||
/Transaction gas price \d+wei is too low. There is another transaction with same nonce in the queue with gas price: \d+wei. Try increasing the gas price or incrementing the nonce./,
|
/Transaction gas price \d+wei is too low. There is another transaction with same nonce in the queue with gas price: \d+wei. Try increasing the gas price or incrementing the nonce./,
|
||||||
|
/FeeTooLow/,
|
||||||
|
/max fee per gas less than block base fee/,
|
||||||
]
|
]
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const sameTxErrors = [
|
const sameTxErrors = [
|
||||||
'Transaction with the same hash was already imported.',
|
'Transaction with the same hash was already imported.',
|
||||||
'already known',
|
'already known',
|
||||||
|
'AlreadyKnown',
|
||||||
|
'Known transaction'
|
||||||
]
|
]
|
||||||
|
|
||||||
class Transaction {
|
class Transaction {
|
||||||
@@ -63,11 +69,14 @@ class Transaction {
|
|||||||
this.tx = { ...tx }
|
this.tx = { ...tx }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tx.gasLimit) {
|
if (!tx.gasLimit) {
|
||||||
tx.gasLimit = await this._wallet.estimateGas(tx)
|
tx.gasLimit = await this._estimateGas(tx)
|
||||||
tx.gasLimit = Math.floor(tx.gasLimit * this.config.GAS_LIMIT_MULTIPLIER)
|
tx.gasLimit = Math.floor(tx.gasLimit * this.config.GAS_LIMIT_MULTIPLIER)
|
||||||
tx.gasLimit = Math.min(tx.gasLimit, this.config.BLOCK_GAS_LIMIT)
|
tx.gasLimit = Math.min(tx.gasLimit, this.config.BLOCK_GAS_LIMIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tx.chainId = this.tx.chainId
|
||||||
tx.nonce = this.tx.nonce // can be different from `this.manager._nonce`
|
tx.nonce = this.tx.nonce // can be different from `this.manager._nonce`
|
||||||
|
|
||||||
// start no less than current tx gas params
|
// start no less than current tx gas params
|
||||||
@@ -92,7 +101,6 @@ class Transaction {
|
|||||||
from: this.address,
|
from: this.address,
|
||||||
to: this.address,
|
to: this.address,
|
||||||
value: 0,
|
value: 0,
|
||||||
gasLimit: 21000,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,8 +136,14 @@ class Transaction {
|
|||||||
this.config.BLOCK_GAS_LIMIT = Math.floor(lastBlock.gasLimit.toNumber() * 0.95)
|
this.config.BLOCK_GAS_LIMIT = Math.floor(lastBlock.gasLimit.toNumber() * 0.95)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.manager._chainId) {
|
||||||
|
const net = await this._provider.getNetwork()
|
||||||
|
this.manager._chainId = net.chainId
|
||||||
|
}
|
||||||
|
this.tx.chainId = this.manager._chainId
|
||||||
|
|
||||||
if (!this.tx.gasLimit || this.config.ESTIMATE_GAS) {
|
if (!this.tx.gasLimit || this.config.ESTIMATE_GAS) {
|
||||||
const gas = await this._wallet.estimateGas(this.tx)
|
const gas = await this._estimateGas(this.tx)
|
||||||
if (!this.tx.gasLimit) {
|
if (!this.tx.gasLimit) {
|
||||||
const gasLimit = Math.floor(gas * this.config.GAS_LIMIT_MULTIPLIER)
|
const gasLimit = Math.floor(gas * this.config.GAS_LIMIT_MULTIPLIER)
|
||||||
this.tx.gasLimit = Math.min(gasLimit, this.config.BLOCK_GAS_LIMIT)
|
this.tx.gasLimit = Math.min(gasLimit, this.config.BLOCK_GAS_LIMIT)
|
||||||
@@ -141,12 +155,6 @@ class Transaction {
|
|||||||
}
|
}
|
||||||
this.tx.nonce = this.manager._nonce
|
this.tx.nonce = this.manager._nonce
|
||||||
|
|
||||||
if (!this.manager._chainId) {
|
|
||||||
const net = await this._provider.getNetwork()
|
|
||||||
this.manager._chainId = net.chainId
|
|
||||||
}
|
|
||||||
this.tx.chainId = this.manager._chainId
|
|
||||||
|
|
||||||
if (this.tx.gasPrice || (this.tx.maxFeePerGas && this.tx.maxPriorityFeePerGas)) {
|
if (this.tx.gasPrice || (this.tx.maxFeePerGas && this.tx.maxPriorityFeePerGas)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -172,7 +180,7 @@ class Transaction {
|
|||||||
try {
|
try {
|
||||||
await this._broadcast(signedTx)
|
await this._broadcast(signedTx)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return this._handleSendError(e)
|
return this._handleRpcError(e, '_send')
|
||||||
}
|
}
|
||||||
|
|
||||||
this._emitter.emit('transactionHash', txHash)
|
this._emitter.emit('transactionHash', txHash)
|
||||||
@@ -290,7 +298,7 @@ class Transaction {
|
|||||||
return main
|
return main
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleSendError(e) {
|
_handleRpcError(e, method) {
|
||||||
if (e.error.error) {
|
if (e.error.error) {
|
||||||
// Sometimes ethers wraps known errors, unwrap it in this case
|
// Sometimes ethers wraps known errors, unwrap it in this case
|
||||||
e = e.error
|
e = e.error
|
||||||
@@ -305,17 +313,20 @@ class Transaction {
|
|||||||
if (this.retries <= this.config.MAX_RETRIES) {
|
if (this.retries <= this.config.MAX_RETRIES) {
|
||||||
this.tx.nonce++
|
this.tx.nonce++
|
||||||
this.retries++
|
this.retries++
|
||||||
return this._send()
|
return this[method]()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is already a pending tx with higher gas price, trying to bump and resubmit
|
// there is already a pending tx with higher gas price, trying to bump and resubmit
|
||||||
if (this._hasError(message, gasPriceErrors)) {
|
if (this._hasError(message, gasPriceErrors)) {
|
||||||
console.log(
|
console.log(
|
||||||
`Gas price ${formatUnits(this.tx.gasPrice, 'gwei')} gwei is too low, increasing and retrying`,
|
`Gas price ${formatUnits(
|
||||||
|
this.tx.gasPrice || this.tx.maxFeePerGas,
|
||||||
|
'gwei',
|
||||||
|
)} gwei is too low, increasing and retrying`,
|
||||||
)
|
)
|
||||||
if (this._increaseGasPrice()) {
|
if (this._increaseGasPrice()) {
|
||||||
return this._send()
|
return this[method]()
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Already at max gas price, but still not enough to submit the transaction')
|
throw new Error('Already at max gas price, but still not enough to submit the transaction')
|
||||||
}
|
}
|
||||||
@@ -376,8 +387,10 @@ class Transaction {
|
|||||||
oldMaxPriorityFeePerGas.add(minGweiBump),
|
oldMaxPriorityFeePerGas.add(minGweiBump),
|
||||||
)
|
)
|
||||||
|
|
||||||
this.tx.maxFeePerGas = min(newMaxFeePerGas, maxGasPrice).toHexString()
|
const maxFeePerGas = min(newMaxFeePerGas, maxGasPrice)
|
||||||
this.tx.maxPriorityFeePerGas = min(newMaxPriorityFeePerGas, this.tx.maxFeePerGas).toHexString()
|
|
||||||
|
this.tx.maxFeePerGas = maxFeePerGas.toHexString()
|
||||||
|
this.tx.maxPriorityFeePerGas = min(newMaxPriorityFeePerGas, maxFeePerGas).toHexString()
|
||||||
|
|
||||||
console.log(`Increasing maxFeePerGas to ${formatUnits(this.tx.maxFeePerGas, 'gwei')} gwei`)
|
console.log(`Increasing maxFeePerGas to ${formatUnits(this.tx.maxFeePerGas, 'gwei')} gwei`)
|
||||||
}
|
}
|
||||||
@@ -410,25 +423,31 @@ class Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches baseFee from chain and calculate fee params
|
* Fetches priority fee from the chain
|
||||||
*
|
*
|
||||||
* @returns {Promise<object>}
|
* @param blockNumber The newest number block
|
||||||
|
* @returns {Promise<BigNumber>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _estimateFees() {
|
async _estimatePriorityFee() {
|
||||||
const block = await this._provider.getBlock('latest')
|
const defaultPriorityFee = parseUnits(this.config.DEFAULT_PRIORITY_FEE.toString(), 'gwei')
|
||||||
|
|
||||||
let maxFeePerGas = null,
|
try {
|
||||||
maxPriorityFeePerGas = null
|
const estimatedPriorityFee = await this._provider.send('eth_maxPriorityFeePerGas', [])
|
||||||
|
|
||||||
if (block && block.baseFeePerGas) {
|
if (!estimatedPriorityFee || isNaN(estimatedPriorityFee)) {
|
||||||
maxPriorityFeePerGas = parseUnits(this.config.PRIORITY_FEE_GWEI.toString(), 'gwei')
|
return defaultPriorityFee
|
||||||
maxFeePerGas = block.baseFeePerGas
|
}
|
||||||
.mul(100 + this.config.BASE_FEE_RESERVE_PERCENTAGE)
|
|
||||||
|
const bumpedPriorityFee = BigNumber.from(estimatedPriorityFee)
|
||||||
|
.mul(100 + this.config.PRIORITY_FEE_RESERVE_PERCENTAGE)
|
||||||
.div(100)
|
.div(100)
|
||||||
.add(maxPriorityFeePerGas)
|
|
||||||
|
return max(bumpedPriorityFee, defaultPriorityFee)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('_estimatePriorityFee has error:', err.message)
|
||||||
|
return defaultPriorityFee
|
||||||
}
|
}
|
||||||
return { maxFeePerGas, maxPriorityFeePerGas }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -438,15 +457,21 @@ class Transaction {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _getGasParams() {
|
async _getGasParams() {
|
||||||
const { maxFeePerGas, maxPriorityFeePerGas } = await this._estimateFees()
|
|
||||||
|
|
||||||
const maxGasPrice = parseUnits(this.config.MAX_GAS_PRICE.toString(), 'gwei')
|
const maxGasPrice = parseUnits(this.config.MAX_GAS_PRICE.toString(), 'gwei')
|
||||||
|
const block = await this._provider.getBlock('latest')
|
||||||
|
|
||||||
// Check network support for EIP-1559
|
// Check network support for EIP-1559
|
||||||
if (maxFeePerGas && maxPriorityFeePerGas) {
|
if (this.config.ENABLE_EIP1559 && block && block.baseFeePerGas) {
|
||||||
|
const maxPriorityFeePerGas = await this._estimatePriorityFee()
|
||||||
|
|
||||||
|
const maxFeePerGas = block.baseFeePerGas
|
||||||
|
.mul(100 + this.config.BASE_FEE_RESERVE_PERCENTAGE)
|
||||||
|
.div(100)
|
||||||
|
.add(maxPriorityFeePerGas)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
maxFeePerGas: min(maxFeePerGas, maxGasPrice).toHexString(),
|
maxFeePerGas: min(maxFeePerGas, maxGasPrice).toHexString(),
|
||||||
maxPriorityFeePerGas: maxPriorityFeePerGas.toHexString(),
|
maxPriorityFeePerGas: min(maxPriorityFeePerGas, maxGasPrice).toHexString(),
|
||||||
type: 2,
|
type: 2,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -457,6 +482,14 @@ class Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _estimateGas(tx) {
|
||||||
|
try {
|
||||||
|
return await this._wallet.estimateGas(tx)
|
||||||
|
} catch (e) {
|
||||||
|
return this._handleRpcError(e, '_estimateGas')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Transaction
|
module.exports = Transaction
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ const defaultConfig = {
|
|||||||
ESTIMATE_GAS: true,
|
ESTIMATE_GAS: true,
|
||||||
THROW_ON_REVERT: true,
|
THROW_ON_REVERT: true,
|
||||||
BLOCK_GAS_LIMIT: null,
|
BLOCK_GAS_LIMIT: null,
|
||||||
PRIORITY_FEE_GWEI: 3,
|
ENABLE_EIP1559: true,
|
||||||
|
DEFAULT_PRIORITY_FEE: 3,
|
||||||
BASE_FEE_RESERVE_PERCENTAGE: 50,
|
BASE_FEE_RESERVE_PERCENTAGE: 50,
|
||||||
|
PRIORITY_FEE_RESERVE_PERCENTAGE: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
class TxManager {
|
class TxManager {
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
require('chai').should()
|
require('chai').should()
|
||||||
|
const { providers } = require('ethers')
|
||||||
const { parseUnits } = require('ethers').utils
|
const { parseUnits } = require('ethers').utils
|
||||||
const TxManager = require('../src/TxManager')
|
const TxManager = require('../src/TxManager')
|
||||||
// const Transaction = require('../src/Transaction')
|
// const Transaction = require('../src/Transaction')
|
||||||
const { RPC_URL, PRIVATE_KEY } = process.env
|
const { RPC_URL, PRIVATE_KEY } = process.env
|
||||||
|
|
||||||
describe('TxManager', () => {
|
describe('TxManager', () => {
|
||||||
const manager = new TxManager({
|
let manager
|
||||||
privateKey: PRIVATE_KEY,
|
|
||||||
rpcUrl: RPC_URL,
|
|
||||||
config: {
|
|
||||||
CONFIRMATIONS: 1,
|
|
||||||
GAS_BUMP_INTERVAL: 1000 * 20,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const tx1 = {
|
const tx1 = {
|
||||||
value: 1,
|
value: 1,
|
||||||
@@ -45,6 +39,26 @@ describe('TxManager', () => {
|
|||||||
type: 2,
|
type: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
const provider = new providers.JsonRpcProvider(RPC_URL)
|
||||||
|
|
||||||
|
const { name, chainId } = await provider.getNetwork()
|
||||||
|
console.log('\n\n', 'network', { name, chainId }, '\n\n')
|
||||||
|
|
||||||
|
manager = new TxManager({
|
||||||
|
privateKey: PRIVATE_KEY,
|
||||||
|
rpcUrl: RPC_URL,
|
||||||
|
config: {
|
||||||
|
CONFIRMATIONS: 1,
|
||||||
|
GAS_BUMP_INTERVAL: 1000 * 20,
|
||||||
|
},
|
||||||
|
gasPriceOracleConfig: {
|
||||||
|
chainId: chainId,
|
||||||
|
defaultRpc: RPC_URL,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('#transaction', () => {
|
describe('#transaction', () => {
|
||||||
it('should work legacy tx', async () => {
|
it('should work legacy tx', async () => {
|
||||||
const tx = manager.createTx(tx1)
|
const tx = manager.createTx(tx1)
|
||||||
@@ -122,6 +136,36 @@ describe('TxManager', () => {
|
|||||||
console.log('receipt', receipt)
|
console.log('receipt', receipt)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should increase nonce', async () => {
|
||||||
|
const currentNonce = await manager._wallet.getTransactionCount('latest')
|
||||||
|
|
||||||
|
manager._nonce = currentNonce - 1
|
||||||
|
|
||||||
|
const tx = manager.createTx(tx4)
|
||||||
|
|
||||||
|
const receipt = await tx
|
||||||
|
.send()
|
||||||
|
.on('transactionHash', hash => console.log('hash', hash))
|
||||||
|
.on('mined', receipt => console.log('Mined in block', receipt.blockNumber))
|
||||||
|
.on('confirmations', confirmations => console.log('confirmations', confirmations))
|
||||||
|
|
||||||
|
console.log('receipt', receipt)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should disable eip-1559 transactions', async () => {
|
||||||
|
manager.config.ENABLE_EIP1559 = false
|
||||||
|
|
||||||
|
const tx = manager.createTx(tx3)
|
||||||
|
const receipt = await tx
|
||||||
|
.send()
|
||||||
|
.on('transactionHash', hash => console.log('hash', hash))
|
||||||
|
.on('mined', receipt => console.log('Mined in block', receipt.blockNumber))
|
||||||
|
.on('confirmations', confirmations => console.log('confirmations', confirmations))
|
||||||
|
console.log('receipt', receipt)
|
||||||
|
|
||||||
|
manager.config.ENABLE_EIP1559 = true
|
||||||
|
})
|
||||||
|
|
||||||
it('should send multiple txs', async () => {
|
it('should send multiple txs', async () => {
|
||||||
const genTx = value => ({
|
const genTx = value => ({
|
||||||
value,
|
value,
|
||||||
@@ -139,6 +183,6 @@ describe('TxManager', () => {
|
|||||||
manager.createTx(genTx(9)).send(),
|
manager.createTx(genTx(9)).send(),
|
||||||
manager.createTx(genTx(10)).send(),
|
manager.createTx(genTx(10)).send(),
|
||||||
])
|
])
|
||||||
})
|
}).timeout(600000)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
42
yarn.lock
42
yarn.lock
@@ -485,12 +485,12 @@ async-mutex@^0.2.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
|
|
||||||
axios@^0.19.2:
|
axios@^0.21.2:
|
||||||
version "0.19.2"
|
version "0.21.4"
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
|
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
|
||||||
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
|
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects "1.5.10"
|
follow-redirects "^1.14.0"
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
@@ -655,13 +655,6 @@ debug@4.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
debug@=3.1.0:
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
|
||||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
|
||||||
dependencies:
|
|
||||||
ms "2.0.0"
|
|
||||||
|
|
||||||
debug@^4.0.1, debug@^4.1.1:
|
debug@^4.0.1, debug@^4.1.1:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1"
|
||||||
@@ -1038,12 +1031,10 @@ flatted@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
|
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138"
|
||||||
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
|
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==
|
||||||
|
|
||||||
follow-redirects@1.5.10:
|
follow-redirects@^1.14.0:
|
||||||
version "1.5.10"
|
version "1.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
|
||||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
|
||||||
dependencies:
|
|
||||||
debug "=3.1.0"
|
|
||||||
|
|
||||||
fs.realpath@^1.0.0:
|
fs.realpath@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
@@ -1065,12 +1056,12 @@ functional-red-black-tree@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
|
||||||
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
|
||||||
|
|
||||||
gas-price-oracle@^0.3.5:
|
gas-price-oracle@^0.4.7:
|
||||||
version "0.3.5"
|
version "0.4.7"
|
||||||
resolved "https://registry.yarnpkg.com/gas-price-oracle/-/gas-price-oracle-0.3.5.tgz#b7bff364e37fb7f30a2297cb65be80fceb4b8da3"
|
resolved "https://registry.yarnpkg.com/gas-price-oracle/-/gas-price-oracle-0.4.7.tgz#47406048083074bcab677efb9de08663e742153d"
|
||||||
integrity sha512-9NAKzmGgWLjGUc4XsqNJjh0JXthETucijNrkV47FrZIjP8YMzq4jhBvlNeMBt6VVGnr64qjIY2RWb+In7qNsFA==
|
integrity sha512-Ti8nhpATm83YebWU/Pz5xclZoTkzOblIhT504ZViZJUcd8jOxgj9pWtCasg8RYw+d0f19m0dJUPvdj04RC4o3A==
|
||||||
dependencies:
|
dependencies:
|
||||||
axios "^0.19.2"
|
axios "^0.21.2"
|
||||||
bignumber.js "^9.0.0"
|
bignumber.js "^9.0.0"
|
||||||
|
|
||||||
get-caller-file@^2.0.1:
|
get-caller-file@^2.0.1:
|
||||||
@@ -1428,11 +1419,6 @@ mocha@^8.1.3:
|
|||||||
yargs-parser "13.1.2"
|
yargs-parser "13.1.2"
|
||||||
yargs-unparser "1.6.1"
|
yargs-unparser "1.6.1"
|
||||||
|
|
||||||
ms@2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
|
||||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
|
||||||
|
|
||||||
ms@2.1.2, ms@^2.1.1:
|
ms@2.1.2, ms@^2.1.1:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
|
|||||||
Reference in New Issue
Block a user