Skip to content
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

Incorrect code in staking module CompleteUnbonding can cause permanent loss or minting of funds. #229

Closed
Tracked by #12578
danwt opened this issue Jul 13, 2022 · 6 comments
Assignees
Labels
scope: cosmos-sdk Integration with Cosmos SDK type: bug Issues that need priority attention -- something isn't working

Comments

@danwt
Copy link
Contributor

danwt commented Jul 13, 2022

This code is wrong

https://github.com/cosmos/cosmos-sdk/blob/c783aea68fbd856c2b188b2d467a7fa5cb4df1e6/x/staking/keeper/delegation.go#L788-L805

		entry := &ubd.Entries[i]
		if entry.IsMature(ctxTime) && !entry.UnbondingOnHold {
			// Proceed with unbonding
			ubd.RemoveEntry(int64(i))
			i--


			// track undelegation only when remaining or truncated shares are non-zero
			if !entry.Balance.IsZero() {
				amt := sdk.NewCoin(bondDenom, entry.Balance)
				if err := k.bankKeeper.UndelegateCoinsFromModuleToAccount(
					ctx, types.NotBondedPoolName, delegatorAddress, sdk.NewCoins(amt),
				); err != nil {
					return nil, err
				}


				balances = balances.Add(amt)
			}
		}

because the data the pointer (entry := &ubd.Entries[i]) points to is deleted (ubd.RemoveEntry(int64(i))) before it is referenced.

Note: this bug can lead to users not getting back all their funds.

Found with diff testing.

@danwt danwt self-assigned this Jul 13, 2022
@danwt danwt added type: bug Issues that need priority attention -- something isn't working scope: cosmos-sdk Integration with Cosmos SDK ccv-core labels Jul 13, 2022
@danwt danwt changed the title Incorrect code in staking module func (k Keeper) CompleteUnbonding Incorrect code in staking module CompleteUnbonding can cause permanent loss of funds. Jul 13, 2022
@mpoke
Copy link
Contributor

mpoke commented Jul 13, 2022

That's the bug! 🎉 It actually fixes the test :) Great job @danwt

@andrey-kuprianov
Copy link

Congrats, Dan; great work! Really happy for you, as well for users who won't loose their funds because of this bug:)

@danwt
Copy link
Contributor Author

danwt commented Jul 13, 2022

I will add, this bug could also cause arbitrary minting of funds into a delegator address.

To see this, notice that the bug can cause the following:

Suppose ubd.Entries[i] of the form

[a,b]

with a.balance < b.balance. Then the incorrect code can cause b.balance to be refunded twice and a.balance to be refunded 0 times. Thus a user can receive funds 2 * b.balance while only investing a.balance + b.balance.

@danwt danwt changed the title Incorrect code in staking module CompleteUnbonding can cause permanent loss of funds. Incorrect code in staking module CompleteUnbonding can cause permanent loss or minting of funds. Jul 13, 2022
@jtremback
Copy link
Contributor

Awesome! The code in our staking hooks is basically copied from the existing operations. Looking forward to figuring out how this crept in when I copied it when I get back

@danwt
Copy link
Contributor Author

danwt commented Jul 14, 2022

@mpoke
Copy link
Contributor

mpoke commented Jul 28, 2022

@danwt Can we close this issue?

@mpoke mpoke closed this as completed Jul 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: cosmos-sdk Integration with Cosmos SDK type: bug Issues that need priority attention -- something isn't working
Projects
No open projects
Status: Done
Development

No branches or pull requests

4 participants