Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UPS-1054] Withdraw full Eth coins balance #23

Merged
merged 1 commit into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions lib/blockchains/EthereumBlockchain.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,13 @@ class EthereumBlockchain {
}
}

withdrawCoinsTx(hotWalletAddress, withdrawalAddress, coinsAmount) {
withdrawCoinsTx(hotWalletAddress, withdrawalAddress, coinsAmount, maxFeePerGas) {
return {
txRaw: JSON.stringify({
from: hotWalletAddress,
to: withdrawalAddress,
value: this.web3.utils.toHex(coinsAmount),
maxFeePerGas: this.web3.utils.toHex(maxFeePerGas)
})
}
}
Expand All @@ -269,7 +270,9 @@ class EthereumBlockchain {
try {
txn.gasLimit = await web3.eth.estimateGas(txn)
txn.maxPriorityFeePerGas = web3.utils.toHex(web3.utils.toWei(this.envs.ethereumMaxPriorityFeePerGas, 'gwei'))
txn.maxFeePerGas = web3.utils.toHex(web3.utils.toWei(this.envs.ethereumMaxFeePerGas, 'gwei'))
if (!txn.maxFeePerGas) {
txn.maxFeePerGas = web3.utils.toHex(web3.utils.toWei(this.envs.ethereumMaxFeePerGas, 'gwei'))
}
txn.nonce = await web3.eth.getTransactionCount(hotWallet.address, 'pending')

const common = new Common.default({ chain: this.chainName, hardfork: 'london' })
Expand Down Expand Up @@ -312,6 +315,12 @@ class EthereumBlockchain {
return await this.sendEIP1559Tx(txn, hotWallet)
}

async getCurrentBaseFee() {
const currentBlock = await this.web3.eth.getBlock('pending')

return this.web3.utils.hexToNumber(currentBlock.baseFeePerGas)
}

async getEthBalance(hotWalletAddress) {
await this.connect()
const blockchainBalance = await this.chain.fetchBalance(hotWalletAddress, chainjs.HelpersEthereum.toEthereumSymbol('eth'))
Expand Down Expand Up @@ -412,12 +421,14 @@ class EthereumBlockchain {

if (withdrawalAddresses.coinAddress && result.tokensWithdrawalTx.status !== "failed") {
const coinBalance = await this.getEthBalance(hotWallet.address)

if (coinBalance.isGreaterThan(new BigNumber(EthereumBlockchain.getMinimumCoinBalanceWithdrawal()))) {
const web3 = this.web3
const maxFeePerGas = new BigNumber(web3.utils.toWei(this.envs.ethereumMaxFeePerGas, 'gwei')).multipliedBy(STANDARD_ETH_TRANSFER_GAS_LIMIT)
const coinsAmount = new BigNumber(web3.utils.toWei(coinBalance.toString(), 'ether')).minus(maxFeePerGas)
const txObject = this.withdrawCoinsTx(hotWallet.address, withdrawalAddresses.coinAddress, coinsAmount)

const baseFee = await this.getCurrentBaseFee()
const maxFeePerGas = new BigNumber(baseFee).plus(web3.utils.toWei(this.envs.ethereumMaxPriorityFeePerGas, 'gwei'))
const transactionFee = new BigNumber(maxFeePerGas).multipliedBy(STANDARD_ETH_TRANSFER_GAS_LIMIT);
const coinsAmount = new BigNumber(web3.utils.toWei(coinBalance.toString(), 'ether')).minus(transactionFee)
const txObject = this.withdrawCoinsTx(hotWallet.address, withdrawalAddresses.coinAddress, coinsAmount, maxFeePerGas)

console.log(`Sending ${coinsAmount} coins to ${withdrawalAddresses.coinAddress}`)
const tx = await this.sendTransaction(txObject, hotWallet)
Expand Down
19 changes: 12 additions & 7 deletions tests/EthereumBlockchain.disableWallet.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe("EthereumBlockchain.disableWallet", () => {
let sendTransactionSpy = jest.spyOn(ethBlockchain, "sendTransaction")
let getTokenBalanceSpy = jest.spyOn(ethBlockchain, "getTokenBalance")
let getEthBalanceSpy = jest.spyOn(ethBlockchain, "getEthBalance")
let getCurrentBaseFeeSpy = jest.spyOn(ethBlockchain, "getCurrentBaseFee")

afterEach(() => {
jest.resetAllMocks()
Expand Down Expand Up @@ -51,22 +52,25 @@ describe("EthereumBlockchain.disableWallet", () => {
coinAddress: hwAddress
}
const sendTokensTxResult = { valid: true, transactionId: 1}

ethBlockchain.envs.ethereumMaxPriorityFeePerGas = '4'

getEthBalanceSpy.mockReturnValueOnce(new BigNumber(0.03))
sendTransactionSpy.mockReturnValueOnce(sendTokensTxResult)
getTokenBalanceSpy.mockReturnValueOnce({ balance: new BigNumber("0.0"), balanceInBaseUnit: new BigNumber("0") })
getCurrentBaseFeeSpy.mockReturnValueOnce(100)

ethBlockchain.envs.ethereumMaxFeePerGas = '200'
const validResults = await ethBlockchain.disableWallet(disableValues, hwAddress)

expect.assertions(4)
expect(getTokenBalanceSpy).toHaveBeenCalledTimes(1)
expect(sendTransactionSpy).toHaveBeenCalledTimes(1)
expect(getEthBalanceSpy).toHaveBeenCalledTimes(1)
expect(validResults).toEqual({
tokensWithdrawalTx: { status: "skipped", txHash: null, message: "Tokens balance is zero, transaction skipped" },
coinsWithdrawalTx: {
status: "success",
txHash: sendTokensTxResult.transactionId,
expect(validResults).toEqual({
tokensWithdrawalTx: { status: "skipped", txHash: null, message: "Tokens balance is zero, transaction skipped" },
coinsWithdrawalTx: {
status: "success",
txHash: sendTokensTxResult.transactionId,
message: `Successfully sent Tx id: ${sendTokensTxResult.transactionId}`} })
})

Expand Down Expand Up @@ -139,12 +143,13 @@ describe("EthereumBlockchain.disableWallet", () => {
coinsWithdrawalTx: sendCoinsTxResult
}

ethBlockchain.envs.ethereumMaxFeePerGas = '200'
ethBlockchain.envs.ethereumMaxPriorityFeePerGas = '4'

getTokenBalanceSpy.mockReturnValueOnce({ balance: new BigNumber("1.0"), balanceInBaseUnit: new BigNumber("1000000") })
sendTransactionSpy.mockReturnValueOnce({ transactionId: transactionHash })
sendTransactionSpy.mockReturnValueOnce({ valid: false, markAs: "failed", error: "Error during withdraw ETH tx" })
getEthBalanceSpy.mockReturnValueOnce(new BigNumber("0.03"))
getCurrentBaseFeeSpy.mockReturnValueOnce(100)

const validResults = await ethBlockchain.disableWallet(disableValues, hwAddress)

Expand Down