Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Abandoned deposit reward strategy #576

Open
Agoristen opened this issue Oct 11, 2020 · 7 comments
Open

Abandoned deposit reward strategy #576

Agoristen opened this issue Oct 11, 2020 · 7 comments

Comments

@Agoristen
Copy link

The attacker, hereby referred to as "abandoner" will exploit the system to increase his own rewards. His attack will be targeted against innocent node operators, hereby referred to as "victims".

This exploit is currently highly incentivized due to the way keep rewards is to be paid. Rewards are paid based on # of successful deposit + redeems performed within a given period (30 days). Currently, the abondoner will use this exploit to increase his own reward count and therefore rewards.

It works like this:
When a deposit is initiated it locks up bonds for 3 signers. By firing deposits in rapid succession the abandoner is able to force other nodes out of capacity, essentially rendering himself the sole node operator for his chosen lot size. This has centralization risk since all new deposits now will be routed through his own nodes, but furthermore it has a negative impact on the reward schedule as one single actor is able to acquire a higher percent of the rewards than is expected based on assigned KEEP and ETH bond.

While we are yet to see a large scale attack based on this exploit. There are been smaller attempts from less crafty adversaries.

Here is an example from today:
Example of abandoned deposits

These are all deposits initiated by the same user and are all subsequently abandend.

If the deposit is abandoned, one of the three victims (signers) will have to run notifyFundingTimedOut to get their funds back. However, if they run notifyFundingTimedOut before retrieveSignerPubkey is called they will be slashed for approximately 0.05 ETH each (~0.144 ETH / 3). The abandoner is not incentivized to run retrieveSignerPubkey, in fact he is rewarded for not doing so, as it means the 0.144 ETH is returned to him on notify.

The victims must perform the following tasks for each abandoned deposit:

  1. In the Awaiting Funding state they need to call retrieveSignerPubkey manually on the contract
  2. In the Awaiting Funding Proof state they need to call notifyFundingTimedOut

Currently, this problem is not widespread knowledge, which causes victims to call notify without first calling retrieveSignerPubkey, causing themselves (and their co-signers) a slashing. But more stressing is the fact that abandoner is highly incentivized to call Notify after 3 hours to get his full amount returned and slash the victims, Victims therefore has to continually monitor and call retrieveSignerPubkey before the abandoner is able to do so. In practice, they will have to call this before it's been 3 hours to protect themselves against slashing.

Currently, an attack of this type costs roughly 0.06 ETH in txn fee, and each abandoned deposit locks up 150% of lot size between 3 signers. At current capacity, you can lock out the majority of 10 BTC lot nodes with 10-20 abandoned deposits, a negligible cost compared to the advantage gained of a successfully deployed attack. To date there has been only 190 timeouts on the network, however it is expected that the problem will increase as this becomes understood to be an advantage. In fact, timeouts today alone accounts for 25% of all timeouts (total 47) - a clear indication that abandoning is becoming a more rampant issue in the system.

This exploit could be mitigated by requiring depositor to put up a small bond which will be returned after successful deposit. For example 0.1 ETH that will be distributed to the notifier (a person calling both retrieveSignerPubkey and notifyFundingTimedOut). A notifier would therefore become an incentivized job on the network and would help clearing the timeout deposits in a timely fashion and opening up capacity in the network for legitimate depositors all while simultaneously preventing a successful large scale attack to be deployed.

An alternative approach could be to set a higher bond, such as 0.15-0.25 ETH. If deposit is abandonend, this amount will be distributed among the signers on notifyFundingTimedOut to cover their fees and reduce the incentive for abandoning. However I think the current scheme where 1 signer has to take the hit is not a good way to go about it. Doing this work should be rewarded, or else it will not be performed unless absolutely necessary. The result of not rewarding notify timeout is less available capacity in the network.

To be clear, I not advocating for changing of the reward schedule. But I would like for this issue to be better explored and documented for users in the UI and tools first and foremost. It should further be considered if this can be mitigated by introducing a deposit bond. In addition to a bond, the issue will be mitigated to some extent by having more nodes and more capital in the system. Reducing lot size to max 1 BTC would accomplish the same effect as growing the network, but the disadvantages due to higher relative minting costs makes this a no-go in my view.

From the victims perspective. The only way to fight this exploit today is to increase ETH bond and constantly monitor and notify the abandonend deposits, resulting in higher risk and/or real costs to victims.

Some may argue that this is only a problem during the initial 24 months of reward emission, however with the costs being relatively low, I could see this be exploit be used for attacks of more sinister nature than we currently see from reward seekers.

@mhluongo
Copy link
Member

So! A quick note for next time — normally you'd want a disclosure like this to happen privately via secure channels, but in this case we discussed first briefly on Discord, and the issue is already on the team's radar and mostly mitigated.

Working through a longer response now :)

@mhluongo mhluongo changed the title Abandoned deposit exploit Abandoned deposit reward strategy Oct 11, 2020
@mhluongo
Copy link
Member

Okay, responding here from the top. The behavior you're seeing is not ideal for the network, but it's also already mitigated in the protocol and only allows signers to inconvenience each other. The default client config should, however, respond better when depositors behave this way rather than relying on the kindness of strangers. For that reason, I believe this issue should be moved to https://github.com/keep-network/keep-ecdsa

A couple misconceptions I'm seeing below.

First, depositors exiting mid-deposit is normal user behavior. While we initially designed an escrowed deposit fee, you can see in the repo history that we determined it was unnecessary because the depositor has to pay the beacon fee, regardless of whether they fund a deposit - which acts as a deterrent in a mature network.

The addition of rewards here, however, means stakers are more aggressively looking for ways to undermine each other while the network bootstraps. Each reward interval appears to be a zero-sum game. Unfortunately, most stakers have misunderstood the current rewards mechanism.

Rewards are paid based on # of successful deposit + redeems

This is not true. I'd recommend you review the keep-core repository to see why. However, a number of stakers believe it's true, so seeing this behavior for another month or so makes sense.

My recommended response to this is an existing issue on the client, namely that the default client config should be to call retrieveSignerPubkey with some random jitter before the deadline.

We do have some further tweaks to the rewards schedule to make this PvP strategy more obviously suboptimal to an individual staker.. but because we don't want to "change the rules" while people are playing the game, that change is slated for interval 3.

@mhluongo
Copy link
Member

From the victims perspective. The only way to fight this exploit today is to increase ETH bond and constantly monitor and notify the abandonend deposits, resulting in higher risk and/or real costs to victims.

This is correct, though if you review the keep-core repo and the rewards strategy, you'll see the only time they become victims is if the retrieveSignerPubkey is never called

@mhluongo mhluongo transferred this issue from keep-network/tbtc Oct 11, 2020
@Agoristen
Copy link
Author

First, depositors exiting mid-deposit is normal user behavior. While we initially designed an escrowed deposit fee, you can see in the repo history that we determined it was unnecessary because the depositor has to pay the beacon fee, regardless of whether they fund a deposit - which acts as a deterrent in a mature network.

So who's getting paid when signers are slashed 0.05 ETH each? The beacon is already paid by the depositor. I was told that if retrieveSignerPubkey is not called before notify, that money is returned to the depositor. Perhaps that is notifySignerSetupFailed? If so, the point still stands since this is semantics. If the abandoner gets refunded, the only real cost for him is still transaction fees.

My recommended response to this is an existing issue on the client, namely that the default client config should be to call retrieveSignerPubkey with some random jitter before the deadline.

This is correct, though if you review the keep-core repo and the rewards strategy, you'll see the only time they become victims is if the retrieveSignerPubkey is never called

Pushing extra cost on signers who already are taking on risk and costs is a form of victimization for something they have no control over, it doesn't help that not paying this fee would make them even bigger victims. Each call to retrieveSignerPubkey and notify adds up in fees, especially when people are pushing out tens of transactions an hour.

@mhluongo
Copy link
Member

mhluongo commented Oct 12, 2020

Pushing extra cost on signers who already are taking on risk and costs is a form of victimization for something they have no control over

To be clear, it isn't — in this case, they can choose not to stake, right?

We have made design decisions like this throughout the protocol. For example, redemption proofs are provided by redeemers in the dApp by default, though from a game theory perspective only signers would reasonably provide them. We're still improving the client to cover when depositors decide not to prove.

I 100% understand that you don't like that behavior as a signer, but signers covering gas is core to the protocol as-is. Unfortunately, it's also difficult to get away from

So who's getting paid when signers are slashed 0.05 ETH each?
If the abandoner gets refunded, the only real cost for him is still transaction fees.

I'm going to wait for other folks to weigh in on how the is handled today on mainnet; I don't want to mislead and am further from the protocol than I used to be, and this touches many pieces of the system. But I suspect what we'll end up doing here is

  • Making the client smarter
  • Improving the dApp to lower walk-away rates

Minting is already a large investment for depositors; adding more fees or escrows is unpalatable. There might be some other mitigations for the inconvenience though... 🤔

I also expect we'll rework minting to optimistically lock bonds in v2 and avoid the issue of bond races.

@Agoristen
Copy link
Author

Agoristen commented Oct 12, 2020

I understand the desire to make it convenient for minters, but the reality is that without stakers there is no tbtc. Stakers are indispensable to the network and it is therefore important that they do not get repeatedly screwed.

Today, this is not a problem, stakedrop rewards are coming and will subsidize our costs and risks.

But think about this: Yesterday I paid 0.29 eth in fees only related to these 2 functions, and I rarely bother to call notify myself. That's $110 in one day. And get this: it was a good day. Median cost on fees were 34 gwei. That's the lowest it's been in months. In September we had days where the average fee went above 400 gwei. Now imagine if this activity ramps up and we see higher fees both at the same time? It's not hard to imagine costs of $1000 a day, or more. For one staker only - what about the costs for the whole system?

Ok fine, maybe the attack will be less likely to occur with higher fees, but I think that depends on the intentions of the attacker. I haven't read enough of your code to know what risks it represents to have an attacker own all deposits.

And paying the fee is one thing, but I had to make 63 transactions to do it. This is quickly turning into a full time job and I'm now going to have to start developing a bot to ease my workload. I shouldn't have to do this. It would be much better to reward the cleaning up process so that it would take care of itself by people who are incentivized to do it. Right now it's game theory: you're always better off if you can slack and let your co-signers do the dirty work - that way you pay nothing and they bear all the costs. Incentives shouldn't work that way. It should be made fair so that whoever does the good deed is rewarded. Rewarding the clean up process would accomplish just that!

I'll be quite frank and admit I have concerns for the long term sustainable after keep rewards are gone. I don't care about paying hundreds of dollars a day right now, but when those rewards are gone and you're left with significant slashing risks and fees, I'm not sure the tBTC rewards makes sense from a risk-reward perspective. Actually I'm pretty sure they do not. I don't know how many are in the same boat, perhaps people don't think that far? But I care about tBTC succeeding long term. We need a trustless bitcoin on ethereum, badly. So I'm voicing my concerns here and now.

Why do I think this way? I believe minters are unlikely to be retail users in the future. In practice retail will be priced out due to fees. What's most likely going to happen is you have large vendors doing the minting and redemptions and then supply liquidity to the market, which retail will gain access to using uniswap or the like. This results in less activity on the network and therefore less rewards. Certainly less fees could be the result of that too, except when the network is attacked. For all practical purposes a deposit bond will not significantly hinder adaption, but it will make an attack of this sort more expensive and will stop the reward seekers abuse. But most important: it will clean up the dirt and ensure network has maximum available capacity at all times.

I don't see any major downside to putting this cost on depositors. If they abandon their deposit they cost the network money and time and this cost should be beared by the person who caused it. It's very simple to avoid: don't make deposits you do not intend to fulfill.

But I've said my thoughts. I'm not going to drill the point home any more than this. I'm excited to see what v2 will bring to the table and hope you consider rewarding the cleaning up process to the dismay of abusers, I really think it would be the best for the network.

@mhluongo
Copy link
Member

but the reality is that without stakers there is no tbtc.

Without minters and stakers, there is no tBTC. This is a two-sided market, which is why we're subsidizing so heavily while we get the balance right. Currently minters aren't getting a subsidy at all, and they're paying $40-80 per mint.

I agree with you that high costs are a threat to long-term sustainability. Lowering the cost of running the system to as close as 0 as possible will mean lowering costs to minters and growing staker profit.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants