solana: Fix logic error in Inbox release process#336
solana: Fix logic error in Inbox release process#336johnsaigle wants to merge 5 commits intowormhole-foundation:mainfrom
Conversation
| /// Release an inbound transfer and mint the tokens to the recipient. | ||
| /// When `revert_on_error` is true, the transaction will revert if the | ||
| /// release timestamp has not been reached. When `revert_on_error` is false, the | ||
| /// When `revert_on_delay` is true, the transaction will revert if the |
There was a problem hiding this comment.
The actual argument is called revert_on_delay. But perhaps this flag should revert on any error and not just the case where the transaction is not ready to be released?
|
I think we should keep the existing behaviour, but potentially think of a name for the flag that better describes it? Something like The thinking here is that it's convenient for the client to send all the instructions in a single transaction (the transceiver redeem one, then the inbound release one). Whether the transaction can be redeemed immediately cannot be determined on the client side atomically, so the client would either have to perform two transactions, or do some non-trivial computation (involving a lookup) to figure out whether the transceiver redeem ix hits the threshold. The intention of this flag is definitely to "attempt to redeem if we can". I originally called the flag "revert on error" (as you point out in the comment), but that's not a very good name because the function errors out if the message is already release regardless of the flag. |
|
OK, makes sense. I'm happy with renaming the flag. if revert_on_delay == true and ReleaseStatus::NotApproved, try_release() reverts with CantReleaseYet Maybe this could return |
|
Yeah that makes sense to me. Maybe the cleanest way to do that is to propagate the boolean flag to |
|
Sounds good to me. I'll update this PR |
065aa32 to
b8ce756
Compare
b8ce756 to
c8ae28f
Compare
There are a few suspicious aspects of the inbox release logic: 1. `release_inbound_unlock` takes a flag that determines whether a `false` result from `try_release` should cause an error. The flag indicates that it should revert on delay. However, `try_release` can also return `false` when a transaction has not been approved. If the flag is set, the transaction will not return an error when a user tries to release a transaction that is not approved even though whether a transaction is approved has nothing to do with its expected behaviour when it is delayed 2. The custom error TransferNotApproved is defined but unused Taken together, I believe `try_release()` should revert with the TransferNotApproved error. This would disambiguate the various 'false' results and provide more intuitive behaviour when a user tries to release a transaction that is not approved.
c8ae28f to
ed933ac
Compare
| "kind": "struct", | ||
| "fields": [ | ||
| { | ||
| "name": "revertOnDelay", |
There was a problem hiding this comment.
not sure it's worth introducing a breaking change at this point
|
Changes merged through #593 |
There are a few suspicious aspects of the inbox release logic:
release_inbound_unlocktakes a flag that determines whether afalseresult fromtry_releaseshould result in an error being returned. The flag indicates that it should revert on delay. However,try_releasecan also returnfalsewhen a transaction has not been approved (regardless of whether or not it is delayed).If the flag is set, the transaction will not return an error when a user tries to release a transaction that is not approved even though whether a transaction is approved has nothing to do with its expected behaviour when it is delayed.
Context:
try_release()returnsOk(false)when a transfer is not approved (L37)https://github.com/wormhole-foundation/example-native-token-transfers/blob/93350abef9c3b520a01dd150a1b09a603c1e1160/solana/programs/example-native-token-transfers/src/queue/inbox.rs#L33-L47
release_inbound_mint(andrelease_inbound_unlock) returnOk(())when transfer not approved and therevert_on_delayflag is false (L75)https://github.com/wormhole-foundation/example-native-token-transfers/blob/93350abef9c3b520a01dd150a1b09a603c1e1160/solana/programs/example-native-token-transfers/src/instructions/release_inbound.rs#L63-L79
TransferNotApprovedis defined but unused in the codebaseTaken together, I believe
try_release()should revert with the TransferNotApproved error. This would disambiguate the various 'false' results and provide more intuitive behaviour when a user tries to release a transaction that is not approved.Current behaviour:
revert_on_delay == falseandReleaseStatus::NotApproved,try_release()returnsOk(())revert_on_delay == trueandReleaseStatus::NotApproved,try_release()reverts withCantReleaseYetNew behaviour:
revert_on_delay == falseandReleaseStatus::NotApproved,try_release()reverts withTransferNotApprovedrevert_on_delay == trueandReleaseStatus::NotApproved,try_release()reverts withTransferNotApprovedNote that funds are safe in both cases.
assertstatements in bothrelease_inboundfunctions check that the ReleaseStatus is Redeemed before minting funds.