Failed-refund external-chain coins stay in the vaults yet are not returned to their pool
I aim to come back to this in the near future, but at the moment share relevant data.
Block 4786560 is the first post-hard-fork block. Block 10500628 is a recent block for network version 1.108.3 (the version at time of writing).
curl https://thornode-v1.ninerealms.com/thorchain/vaults/yggdrasil?height=4786560 | jq '[.[].coins[]|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
19914266792
curl https://thornode-v1.ninerealms.com/thorchain/vaults/asgard?height=4786560 | jq '[.[].coins[]|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
72663575574
curl https://thornode-v1.ninerealms.com/thorchain/pool/BTC.BTC?height=4786560 | jq '.balance_asset|tonumber'
92050357225
curl https://thornode-v1.ninerealms.com/thorchain/queue/swap?height=4786560 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
curl https://thornode-v1.ninerealms.com/thorchain/queue/scheduled?height=4786560 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
curl https://thornode-v1.ninerealms.com/thorchain/queue/outbound?height=4786560 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
72663575574 + 19914266792 − 92050357225
= 5.27485141 BTC.BTC oversolvency
curl https://thornode-v1.ninerealms.com/thorchain/vaults/yggdrasil?height=10500628 | jq '[.[].coins[]|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
0
curl https://thornode-v1.ninerealms.com/thorchain/vaults/asgard?height=10500628 | jq '[.[].coins[]|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
87210014581
curl https://thornode-v1.ninerealms.com/thorchain/pool/BTC.BTC?height=10500628 | jq '.balance_asset|tonumber'
86442226300
curl https://thornode-v1.ninerealms.com/thorchain/queue/swap?height=10500628 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
curl https://thornode-v1.ninerealms.com/thorchain/queue/scheduled?height=10500628 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
curl https://thornode-v1.ninerealms.com/thorchain/queue/outbound?height=10500628 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
87210014581 - 86442226300
= 7.67788281 BTC.BTC oversolvency
curl https://thornode-v1.ninerealms.com/thorchain/vaults/yggdrasil?height=10500629 | jq '[.[].coins[]|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
0
curl https://thornode-v1.ninerealms.com/thorchain/vaults/asgard?height=10500629 | jq '[.[].coins[]|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
87227291227
curl https://thornode-v1.ninerealms.com/thorchain/pool/BTC.BTC?height=10500629 | jq '.balance_asset|tonumber'
86459473292
curl https://thornode-v1.ninerealms.com/thorchain/queue/swap?height=10500629 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
curl https://thornode-v1.ninerealms.com/thorchain/queue/scheduled?height=10500629 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
curl https://thornode-v1.ninerealms.com/thorchain/queue/outbound?height=10500629 | jq '[.[].coin|select(.asset == "BTC.BTC")|.amount|tonumber]|add'
87227291227 - 86459473292
= 7.67817935 BTC.BTC oversolvency
That's an increase of 0.00029654 BTC.BTC oversolvency in one block.
https://midgard.ninerealms.com/v2/debug/block/10500629
{
"attributes": {
"chain": "BTC",
"code": "105",
"coin": "29654 BTC.BTC",
"from": "bc1qnzsmknxul4mqd5tfmdzyvrhlue2ezyeyafwwm9",
"id": "489E83A92568C5219F795571311974A1BEDD1D661560D58795F928B48599A60D",
"memo": "=:ETH.ETH:0x87333B57382623C5b1394C36BB64a45E80CC2328:te:0",
"reason": "swap price limit:te is invalid; fail to refund (29654 BTC.BTC): not enough asset to pay for fees",
"to": "bc1quxstjcpsm3uvfaxu37uxuu9cvy05pumedyhts5"
},
"type": "refund"
}
This is not necessarily the only source of oversolvency creep, but is at least a notable example.
In summary:
When refunding a transaction fails, if the transaction coin was RUNE then refundTx
sends it to the Reserve.
If the transaction coin was a synth then refundTx
instead burns it.
However, if the transaction coin was an external-chain coin, then refundTx
does nothing with it: it sits in the vaults without being added to the pools.
At present I propose that unrefundable coins be added to their pools (if existing), akin to the code for a withdrawal transaction's coin.
( @akrokr for invariant relevance )