The IsSendEnabledCoins
function is responsible for ensuring coins with SendEnabled
as false
cannot be sent via MsgSend
and MsgMultiSend
. These are also enforced when creating vesting accounts to prevent users from transferring send-disabled coins to a recipient.
However, it is not enforced within the SendCoinsFromModuleToAccount
, SendCoinsFromModuleToModule
, and SendCoinsFromAccountToModule
functions.
This may allow a user to transfer send-disabled coins via the following scenario:
SendCoinsFromModuleToAccount
.SendCoinsFromModuleToModule
.SendCoinsFromAccountToModule
.SendEnabled
is false
) to Bob.MsgCreateValidator
with msg.Commission.Rate
to be 100%.MsgDepositValidatorRewardsPool
with msg.ValidatorAddress
as Bob’s address and msg.Amount
as the send-disabled coin.
distribution
module via the SendCoinsFromAccountToModule
function.AllocateTokensToValidator
function. Since the commission is set to 100% in step 2, Bob will receive all the tokens and update via the SetValidatorAccumulatedCommission
function.MsgWithdrawValidatorCommission
to transfer the send-disabled coin from the distribution
module to their address via the SendCoinsFromModuleToAccount
function.
MsgSetWithdrawAddress
to set their withdrawal address to Carol’s address.
GetDelegatorWithdrawAddr
.IsSendEnabledCoins
validation can be bypassed. With the above steps, an attacker can send the send-disabled coins to themselves or other recipients.Here is another instance that allows sending send-disabled coins:
MsgFundCommunityPool
to fund the community pool with the send-disabled coin.
distribution
module via the SendCoinsFromAccountToModule
function.MsgCommunityPoolSpend
via the SendCoinsFromModuleToAccount
function.Consider implementing the IsSendEnabledCoins
validation in the SendCoinsFromModuleToAccount
function.