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

Check allowedList size in StakeAuthorization.Accept #725

Closed
4 tasks done
dudong2 opened this issue Oct 17, 2022 · 0 comments · Fixed by #726
Closed
4 tasks done

Check allowedList size in StakeAuthorization.Accept #725

dudong2 opened this issue Oct 17, 2022 · 0 comments · Fixed by #726
Assignees
Labels
A: bug Something isn't working

Comments

@dudong2
Copy link
Contributor

dudong2 commented Oct 17, 2022

Summary

Currently, only one of AllowedList and DenyList can be set in the structure of StakeAuthorization.
There is a structural problem that causes Accept func to always fail when DenyList is set.

Problem Definition

func NewStakeAuthorization(allowed []sdk.ValAddress, denied []sdk.ValAddress, authzType AuthorizationType, amount *sdk.Coin) (*StakeAuthorization, error) {
	allowedValidators, deniedValidators, err := validateAndBech32fy(allowed, denied)
	if err != nil {
		return nil, err
	}

	a := StakeAuthorization{}
	if allowedValidators != nil {
		a.Validators = &StakeAuthorization_AllowList{AllowList: &StakeAuthorization_Validators{Address: allowedValidators}}
	} else {
		a.Validators = &StakeAuthorization_DenyList{DenyList: &StakeAuthorization_Validators{Address: deniedValidators}}
	}
    //...
}
//...
func validateAndBech32fy(allowed []sdk.ValAddress, denied []sdk.ValAddress) ([]string, []string, error) {
	if len(allowed) == 0 && len(denied) == 0 {
		return nil, nil, sdkerrors.ErrInvalidRequest.Wrap("both allowed & deny list cannot be empty")
	}

	if len(allowed) > 0 && len(denied) > 0 {
		return nil, nil, sdkerrors.ErrInvalidRequest.Wrap("cannot set both allowed & deny list")
	}
    //...
}

According to the above logic, only one of AllowedList and DenyList can be set.

func (a StakeAuthorization) Accept(ctx sdk.Context, msg sdk.Msg) (authz.AcceptResponse, error) {
  //...
	isValidatorExists := false
	allowedList := a.GetAllowList().GetAddress()
	for _, validator := range allowedList {
		ctx.GasMeter().ConsumeGas(gasCostPerIteration, "stake authorization")
		if validator == validatorAddress {
			isValidatorExists = true
			break
		}
	}

	denyList := a.GetDenyList().GetAddress()
	for _, validator := range denyList {
		ctx.GasMeter().ConsumeGas(gasCostPerIteration, "stake authorization")
		if validator == validatorAddress {
			return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf(" cannot delegate/undelegate to %s validator", validator)
		}
	}

	if !isValidatorExists {
		return authz.AcceptResponse{}, sdkerrors.ErrUnauthorized.Wrapf("cannot delegate/undelegate to %s validator", validatorAddress)
	}
//...
}

If DenyList is set and AllowedList is empty, it always returns an error because isValidatorExists is false.

Proposal

Check the size of the AllowedList together with the isValidatorExists check.

ref. cosmos/cosmos-sdk#11391


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned
@dudong2 dudong2 added the A: bug Something isn't working label Oct 17, 2022
@dudong2 dudong2 self-assigned this Oct 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A: bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant