Unstuck transactions have empty memos which are then observed as Saver withdraw memos
This has no undesirable effects I believe, but has room for improvement.
Example (from this Discord thread):
https://etherscan.io/tx/0xAE6264F96C2EB3BEA98BB2C00B899540D4738DDFCDC8DE56B9DA6F3407CC8B2C
This is an unstuck.go
transaction (0 ETH, '0x' Input Data)
from vault thorpub..ela4
.
"chain": "ETH",
"address": "0x035a29fa29df009eef2de265ef79be3e13fe3d96"
However, in THORNode logs and THORChain's ObservedTxOutVoter:
9:07PM INF gitlab.com/thorchain/thornode/x/thorchain/handler_observed_txout.go:184 > handleMsgObservedTxOut request Tx:="AE6264F96C2EB3BEA98BB2C00B899540D4738DDFCDC8DE56B9DA6F3407CC8B2C: 0x035a29fa29df009eef2de265ef79be3e13fe3d96 ==> 0x035a29fa29df009eef2de265ef79be3e13fe3d96 (Memo: -:ETH/ETH:1) 1 ETH.ETH (gas: [4398672 ETH.ETH])"
https://thornode-v1.ninerealms.com/thorchain/tx/details/AE6264F96C2EB3BEA98BB2C00B899540D4738DDFCDC8DE56B9DA6F3407CC8B2C
"memo": "-:ETH/ETH:1"
I speculate this is from the empty-string memo being interpreted as a memoless transaction.
I thus suggest that a protocol-specific intuitive memo be added by Bifrost to unstuck when the memo is empty,
such as THOR-UNSTUCK
.
My current prediction is that an unparsable memo should not prevent THORNode from observing and bond-slashing to cover the unstuck transaction.
I do note that such a memo (and both sender and receiver being the vault's address)
should not be used as a reason to reimburse the gas from the Reserve instead of from node bonds,
as otherwise the nodes of a vault could sign unlimited unstuck transactions to deplete the Reserve at no cost to themselves.
For ETH for example, in getTxInFromTransaction
normal Memo-setting is here
https://gitlab.com/thorchain/thornode/-/blob/v1.127.0/bifrost/pkg/chainclients/ethereum/ethereum_block_scanner.go#L805-811
var memo []byte
memo, err = hex.DecodeString(string(data))
if err != nil {
txInItem.Memo = string(data)
} else {
txInItem.Memo = string(memo)
}
and the unstuck-transaction-specific logic is here.
https://gitlab.com/thorchain/thornode/-/blob/v1.127.0/bifrost/pkg/chainclients/ethereum/ethereum_block_scanner.go#L820-830
if txInItem.Coins.IsEmpty() {
if txInItem.Sender == txInItem.To {
// When the Sender and To is the same then there's no balance chance whatever the Coins,
// and for Tx-received Valid() a non-zero Amount is needed to observe
// the transaction fees (THORChain gas cost) of unstuck.go's cancel transactions.
observableAmount := common.ETHChain.DustThreshold().Add(cosmos.OneUint()) // Adding 1 for if DustThreshold is 0.
txInItem.Coins = common.NewCoins(common.NewCoin(common.ETHAsset, observableAmount))
// remove the outbound from signer cache so it can be re-attempted
e.signerCacheManager.RemoveSigned(tx.Hash().Hex())
} else {
Added code within the conditional could be on the lines of
if txInItem.Memo == "" {
// Having identified this as an unstuck transaction,
// record it in the memo to not be interpreted as a memoless Savers withdraw.
txInItem.Memo = "THOR-UNSTUCK"
}
I suggest doing it there in the block scanner rather than in unstuck.go
so that cancel transactions do not cost extra gas from extra Memo input data.
My specific code proposal at this time: !3436
'Intuitive THOR-UNSTUCK Memo for unstuck transactions'.