-
Notifications
You must be signed in to change notification settings - Fork 36
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
Redemptions veto mechanism #788
Conversation
Here we introduce the `RedemptionWatchtower` contract that will encapsulate the logic of the redemption veto mechanism. This contract will be attached to the `Bridge` contract upon the upcoming upgrade.
Here we implement functions allowing to enable the watchtower (i.e. veto mechanism) and manage guardians. The `enableWatchtower` function allows setting the watchtower manager and an initial set of guardians. Moreover, we are capturing the initiation timestamp which will be useful while determining pre-OR and post-OR redemption requests and will be needed to implement the planned lifecycle of the veto mechanism Regarding guardian management, we are adding two functions: - `addGuardian` that can be called by the watchtower manager (Token Holder DAO) - `removeGuardian` that can be called by the owner (Threshold Council)
Here we add all the state variables that must be implemented as part of the `RedemptionWatchtower` contract. Specific variables and types were determined during the prototype implementation phase.
Here we expose the `raiseObjection` function that allows guardians object to specific redemption requests. Each redemption has a default delay period during which the wallet is not allowed to process it and the guardians can raise objections to. Each objection extends the delay period by a certain amount of time. The third objection vetoes the redemption request. This causes the redemption request to be rejected and the redeemer to be penalized. Specific consequences of a veto are as follows: - The redemption amount is frozen for a certain period of time, - Once the freeze period expires, the redeemer can claim the frozen amount minus a penalty fee, - The penalty fee is burned, - The redeemer is banned from making future redemption requests.
Here we introduce the `VetoPeriodCheckOmitted` event that is emitted when a redemption objection omits the veto period check. Such a case occurs when the objection is related to a redemption created before the watchtower was enabled.
Perform proposal and guardian checks first to fail fast and avoid burning gas in case a guardian try to object again by mistake. This flow is also more natural as the redemption request is checked closer to the point of usage.
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7976725935 check. |
From now on, the `Bridge` consults the `RedemptionWatchtower` while a new redemption request arises. The redemption request is allowed only if: - The balance owner is not banned in the watchtower - The redeemer is not banned in the watchtower - The redemption key was not objected to in the past
9936af5
to
c57f4f1
Compare
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7977208120 check. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the plan with disableWatchtower
? if the DAO let's the timeout pass then any user can disable the check?
if the DAO wanted to re-enable later on, would a new Watchtower have to be deployed?
…ator` Wallets must respect the new veto delay and not process redemptions during the period a redemption veto can still land. According to RFC-12, the tBTC wallets always consult the `WalletProposalValidator` to validate the ongoing redemption proposal before issuing the redemption transaction on the Bitcoin chain. That means it is enough to modify the `WalletProposalValidator.validateRedemptionProposal` function and take the veto delay into account there. The `validateRedemptionProposal` function calls the `RedemptionWatchtower.getRedemptionDelay` function for each redemption in the proposal and considers it valid only if the returned veto delay (counted since the redemption creation timestamp) already elapsed. This logic guarantees that a particular redemption proposal can only be considered valid if all of its redemption requests have surpassed their respective veto delay periods.
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7988928374 check. |
As part of the social contract, we are exposing the `disableWatchtower` function that can be used by anyone to disable the veto mechanism once the watchtower's lifetime expires (18 months by default).
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7989384985 check. |
This is the part I just added, please see: 8d7d51b. This switch is kind of a social contract and disables the watchtower permanently by design. The DAO can vote to increase |
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7989442529 check. |
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7989988248 check. |
1785712
to
d3cc2e8
Compare
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7990218057 check. |
This function is a safeguard in cases where honest redeemers are banned due to guardians' mistake/malice.
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7990347255 check. |
Here we expose the `withdrawVetoedFunds` allowing the redeemer to withdraw their funds from vetoed redemption, once the freeze period expires. Withdrawn amount is equal to the redemption requested amount diminished by the current value of the penalty fee.
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/7991382089 check. |
event Unbanned(address indexed redeemer); | ||
|
||
event VetoedFundsWithdrawn( | ||
uint256 indexed redemptionkey, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uint256 indexed redemptionkey, | |
uint256 indexed redemptionKey, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! See 5346e0e
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/8002611025 check. |
require( | ||
/* solhint-disable-next-line not-rely-on-time */ | ||
block.timestamp > | ||
redemptionRequest.requestedAt + REDEMPTION_REQUEST_MIN_AGE, | ||
block.timestamp > redemptionRequest.requestedAt + minAge, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check will prevent the wallet from processing certain redemption requests (the ones with some objections raised against them) for some time.
Are we sure this will not lead to a situation where somebody calls notifyRedemptionTimeout
for a redemption that the wallet couldn't process on time because it had some objections?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure this will not lead to a situation where somebody calls notifyWalletRedemptionTimeout for a redemption that the wallet couldn't process because it had some objections?
Good point! This is not a problem as long as the redemption timeout is greater than the watchtower's level-two delay. In such a case, even if a redemption gets two objections, the wallet can process it before the timeout can be reported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add this warning to the docs of the governable parameters controlling the redemption timeout?
Also, we probably want to update https://github.com/keep-network/tbtc-v2/tree/main/docs#parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed as part of c6c03a3
The optimistic redemption upgrade introduces a veto mechanism that enforces a processing delay on each redemption request. The exact delay value depends on the number of objections raised against the given redemption request. The `WalletProposalValidator` contract has been modified to include validation of that delay factor. Here we introduce the same for the redemption proposal generator. This ensures the generator issues proposals that conform the on-chain validation rules and coordination windows are not being wasted. See: keep-network/tbtc-v2#788
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first couple of questions on the way to understanding
|
||
VetoProposal storage veto = vetoProposals[redemptionKey]; | ||
|
||
uint8 requiredObjectionsCount = 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to make this variable as constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I missed it, good catch! Please see: 2556c28
|
||
if (vetoProposals[redemptionKey].objectionsCount > 0) { | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question regarding this block, what happens in case only one or two objections were raised and then delay is expired?
I guess in that case redemption is still not safe but also new objections can't be raised?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Such a redemption request is processed by the tBTC wallet after the delay. However, because there were objections to this redemption key (wallet + BTC address pair), the protocol blocks future redemptions from the same wallet to the given BTC address, just in case. Doing this is also easier from the redemption lifecycle management perspective and is consistent with what happens upon redemption timeout. That said:
- In case of the happy path (redemption processed without troubles) we allow reusing the given redemption key and ask the same wallet to redeem to the same BTC address
- In case of an unhappy path (objections raised, timeout hit) we block further usage of the given redemption key
I'm aware this may not be intuitive but this is a consequence of how tBTC identifies redemptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the explanation, I've found code where redemption handled after delay, could you point how redeemer banned in that case (one or two objections)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The redeemer is banned only after a full veto (3 objections). We don't ban after 1 or 2 objections.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That I saw, whole question is about 1 or 2 objections, got it
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/8094151672 check. |
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/8094162362 check. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a high-level review of the Solidity, I was not looking at the tests.
I really like the design of having a separate watchtower to control the veto mechanism and having the watchtower to keep its balance in the Bank.
/// @param redemptionWatchtower Address of the redemption watchtower. | ||
/// @dev Requirements: | ||
/// - The caller must be the governance, | ||
/// - Redemption watchtower address must not be already set, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not allow the governance to update the watchtower address? I see it is deployed as a proxy but still... We would avoid upgrading the Bridge
contract in case the watchtower address needs to be replaced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done on purpose to provide a kind of social contract regarding how the mechanism works. We do not expect to change anything in the mechanism itself. Any security upgrade would likely require a Bridge
upgrade anyway. Additional argument is Bridge
contract size. We do not add anything that is not a must have now.
/// @param balanceOwner The address of the Bank balance owner whose balance | ||
/// is getting redeemed. | ||
/// @param redeemer The address that requested the redemption. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little lost in what is the difference between those two. This will probably get clear as I move forward with the review of the rest of the code but could be an indicator we should improve the docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah: I'd love to copy-paste the explanation of the redeemer from the requestRedemption
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed as part of c6c03a3
@@ -402,6 +433,19 @@ library Redemption { | |||
bytes memory redeemerOutputScript, | |||
uint64 amount | |||
) internal { | |||
if (self.redemptionWatchtower != address(0)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add this check to the @dev Requirements
section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed as part of c6c03a3
// Capture the amount that should be transferred to the | ||
// redemption watchtower. | ||
uint64 detainedAmount = redemption.requestedAmount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To confirm: we use the whole requested amount as a detained amount because the treasury fee is deducted in submitRedemptionProof
. Since the redemption did not happen, the treasury fee was not deducted and we want to detain everything. Is this a correct understanding? Could be worth dropping a small comment here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this is correct. I will drop a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed as part of c6c03a3
// to be processed by the wallet or reported as timed out. | ||
delete self.pendingRedemptions[redemptionKey]; | ||
|
||
self.bank.transferBalance(self.redemptionWatchtower, detainedAmount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice use of the Bank! Redemption Watchtower has a bank balance, I like it very much.
if (delay > minAge) { | ||
minAge = delay; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a moment I was thinking about whether we should not require the REDEMPTION_REQUEST_MIN_AGE
to be much greater than the redemption delay in the watchtower. Think about this scenario: if they are the same, a second before the minimum age is reached, a guardian can send veto transaction in the mempool. Since it is still in the mempool, the wallet starts processing the redemption. Once the redemption happened on the Bitcoin side and before the proof was submitted on Ethereum, the veto transaction got mined.
Then I realized, we do not check for vetos when the redemption proof is submitted which lets us not to worry about this scenario. I like this setup but I think we should make it very clear for the future-us. Maybe drop a comment in the submitRedemptionProof
function and/or write something in the docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed as part of c6c03a3
if (redemption.requestedAt >= watchtowerEnabledAt) { | ||
require( | ||
// Use < instead of <= to avoid a theoretical edge case | ||
// where the delay is 0 (veto disabled) but three objections |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a bit confused by this part. We don't have the situation when veto is disabled, we only have two cases:
- watchtower is completely disabled
- the amount is below the veto/objection threshold.
Can we rephrase the part in the bracket a bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed as part of c6c03a3
require( | ||
redemption.requestedAt != 0, | ||
"Redemption request does not exist" | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also handles the case when the redemption was already processed given we delete the pending request from the state in the Redemption.processNonChangeRedemptionTxOutput
, correct? Can we drop a small comment about it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed as part of c6c03a3
require( | ||
/* solhint-disable-next-line not-rely-on-time */ | ||
block.timestamp > | ||
redemptionRequest.requestedAt + REDEMPTION_REQUEST_MIN_AGE, | ||
block.timestamp > redemptionRequest.requestedAt + minAge, | ||
"Redemption request min age not achieved yet" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this revert after reviewing the watchtower contract, I am not sure if the way we handle the delay is the right one. It should work but in case there was a delay increased as a result of an objection, we may end up with Redemption request min age not achieved yet
which is not the case - the min age was achieved, it's just that this request is delayed given the veto. Not a blocker but it is something to think about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm aware of it and I agree. However, this is the most low-effort solution we can implement here. Any alternative would complicate this already complicated on-chain validation. Hence I decided to do it this way.
if (isBanned[balanceOwner]) { | ||
return false; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what circumstances we ban the balance owner? I think I am still confused about the distinction between the balance owner and redeemer.
In the situation when someone redeems tBTC, I believe balanceOwner == TBTCVault.address
and redeemer
is the former tBTC holder. In case when someone redeems the Bank balance, balanceOwner == redeemer
and this is the Bank balance owner.
In raiseObjection
, we do isBanned[redemption.redeemer] = true;
.
We never ban the balance owner to avoid the situation when the vault gets banned, we do ban the redeemer though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are blocking a case when a redeemer gets banned and tries to use that address as a balance source for redemption requested from another address. There is a path where you can allow someone to redeem from your balance, totally beyond TBTCVault
.
Solidity API documentation preview available in the artifacts of the https://github.com/keep-network/tbtc-v2/actions/runs/8159234335 check. |
Refs: keep-network/tbtc-v2#781 Depends on: keep-network/tbtc-v2#788 (the `client-build-test-publish` job will become green once 788 is merged and a new `tbtc-v2@development` package with `RedemptionWatchtower` artifact will be published to npm) The optimistic redemption upgrade introduces a veto mechanism (keep-network/tbtc-v2#788) that enforces a processing delay on each redemption request. The exact delay value depends on the number of objections raised against the given redemption request. The `WalletProposalValidator` contract has been modified to include validation of that delay factor. The first change ed9c4ae introduces the same for the redemption proposal generator. This ensures the generator issues proposals that conform to the on-chain validation rules and coordination windows are not being wasted. By the way, we are taking an opportunity to optimize the deposit sweep proposal generation. The `WalletProposalValidator` contract enforces the minimum age of a deposit that can become part of the proposal. The proposal generator was missing this check and was often producing invalid proposals that were violating the on-chain minimum deposit age rule. We fix that in 55be487.
Closes: #781
Here we present the implementation of the redemptions veto mechanism, specified in the TIP-072: Optimistic redemptions.
High-level architecture
The current byte size of the
Bridge
contract (~22 kB) is close to the limit. To leave some space for futureBridge
upgrades, we decided to encapsulate the logic of the redemption veto mechanism in a separate upgradeable contract calledRedemptionWatchtower
, and attach it to the existingBridge
instance. Such a design has a positive impact on theBridge
size, nicely separates the concerns, and reduces the amount of direct changes in the livingBridge
instance.The
RedemptionWatchtower
contract acts as a central point for redemption guardians, manages vetoed redemptions, and provides other functionality specified in the TIP. It also serves as a source of information about vetoed redemptions, banned redeemers, and processing delays that should be preserved for specific redemption requests.The chart below presents how the
RedemptionWatchtower
fits into the existing architecture and provides an overview of interactions between relevant smart contracts and system actors:The
RedemptionWatchtower
contractThe
RedemptionWatchtower
contract interacts with several actors of the protocol. Each actor has a different set of capabilities:Owner (Threshold Council)
The owner can call the following functions:
enableWatchtower
which enables the veto mechanism for the first time. This function must set the watchtower's manager and can establish an initial set of guardians. This function also captures the timestamp of the call. This information is necessary to ensure the proper lifecycle of the veto mechanism (shut down after 18 months). It is also crucial for determining stalled redemptions that were created in the pre-veto era and can be vetoed indefinitely.removeGuardian
that can be used to remove specific guardians. This function is a safeguard against malicious guardians hence, it must be directly available to the owner.Manager (Token holder DAO)
As per the TIP, most of the governance should be the authority of the Token holder DAO. To make it possible, we are introducing the role of the watchtower's manager who can use the following functions:
addGuardian
which allows adding new redemption guardiansupdateWatchtowerParameters
that can update all governable parameters that steer the veto mechanism. Those parameters are redemption veto delays, veto time and financial penalties, and the mechanism lifetime.unban
which can be used to unban redeemers who were banned mistakenly. This is a safeguard for guardian mistakes that must be in place to protect honest redeemers.Guardians
Guardians are the executors of the veto process. The only function they can call is
raiseObjection
. That function should be used to raise objections against specific redemption requests. Three subsequent objections lead to a redemption veto. Vetoed redemptions are not processed by the protocol, the requested amount is diminished by a penalty fee, and frozen for a specific time. Once the freeze period ends, the redeemer can claim those funds back. Moreover, redeemers whose redemptions were vetoed become banned and cannot ask for redemptions in the future. Last but not least, even a single objection (not leading to a veto) against a redemption (from a given wallet to a given BTC address) prevents asking the same wallet to redeem to the same BTC address in the future (this is similar to timed out redemptions).Others
The
RedemptionWatchtower
exposes some functions available to the broad public. Those are:isSafeRedemption
which determines whether a redemption involving a specific wallet, BTC address, Bank's balance owner, and redeemer can be considered as safe. This function leverages the objections history and banned redeemers to determine so. A redemption is considered safe if neither the balance owner nor redeemer is banned and past redemptions from the given wallet to the given BTC address were not subject to guardian objections.getRedemptionDelay
that informs tBTC wallets about processing delays that should be preserved for specific redemption requests. Delays are determined based on raised objections.withdrawVetoedFunds
which can be used by redeemers to withdraw funds from vetoed redemptions once the freeze period ends.disableWatchtower
that can be used by anyone to disable the veto mechanism once the watchtower's lifetime elapses.Changes in the
Bridge
contractIntegration of the
RedemptionWatchtower
contract with the existingBridge
incurs several changes in the latter.First and foremost, the
Bridge
's state gains a new address field (redemptionWatchtower
) that points to theRedemptionWatchtower
contract. That field can be set using the newsetRedemptionWatchtower
function available for theBridge
's governance.Secondly, the
Bridge
exposes a newnotifyRedemptionVeto
callback function. This function can be called only by theredemptionWatchtower
address. The main responsibility of this function is propagating the consequences of a redemption veto to theBridge
's state, namely:Last but not least, the
Bridge
leverages theredemptionWatchtower
address to determine the safety of upcoming redemption requests. This is achieved using theisSafeRedemption
call. This way, redemptions from banned redeemers (and balance owners) are blocked. The same applies to redemptions from specific wallets to specific BTC addresses which were subject to guardian objections in the past.Changes in the
WalletProposalValidator
contractThe last piece of the puzzle is the integration of the veto mechanism with the off-chain tBTC wallets. Wallets must respect the new veto delay and not process redemptions during the period a redemption veto can still land. According to RFC-12, the tBTC wallets always consult the
WalletProposalValidator
to validate the ongoing redemption proposal before issuing the redemption transaction on the Bitcoin chain. That means it is enough to modify theWalletProposalValidator.validateRedemptionProposal
function and take the veto delay into account there. ThevalidateRedemptionProposal
function calls theRedemptionWatchtower.getRedemptionDelay
function for each redemption in the proposal and considers it valid only if the returned veto delay (counted since the redemption creation timestamp) already elapsed. This logic guarantees that a particular redemption proposal can only be considered valid if all of its redemption requests have surpassed their respective veto delay periods.In light of the above, we should also prevent invalid redemption proposals (with redemptions violating the veto delay) from being issued by RFC-12 coordinators. An invalid proposal means a coordination window miss and the optimal strategy here is ensuring proposal validity at generation time. This requires adjustments in the off-chain redemption proposal generator logic. This work is beyond the scope of this pull request and will be addressed in a follow-up PR.
The ultimate protection against wallets not obeying the aforementioned rules is the fact that vetoed redemptions are removed from the
pendingRedemption
set in theBridge
. That means theBridge
will reject an SPV proof of a redemption transaction that handles at least one vetoed redemption request (that happens in thesubmitRedemptionProof
function). In such a case, the given wallet will be deemed as fraudulent and punished according to the protocol rules.