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

OnRecvPacket does not roll back failures in Convert coins or Swap coins #3

Closed
c4-bot-4 opened this issue Jun 15, 2024 · 2 comments
Closed
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-19 grade-b QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax 🤖_primary AI based primary recommendation 🤖_08_group AI based duplicate group recommendation sufficient quality report This report is of sufficient quality

Comments

@c4-bot-4
Copy link

Lines of code

https://github.com/code-423n4/2024-05-canto/blob/d1d51b2293d4689f467b8b1c82bba84f8f7ea008/canto-main/x/onboarding/keeper/ibc_callbacks.go#L137

Vulnerability details

Impact

onboarding#OnRecvPacket will be call
coinswapKeeper.TradeInputForExactOutput and
erc20Keeper.ConvertCoin

However, if the execution of these two functions fails in the middle, for example, the user's token has been deducted, but the execution fails when mint is executed, the transaction will not be rolled back, which will cause the loss of user funds.

Proof of Concept

The x/keeper function will return an error. If the function is executed through RPC, if it fails, the SDK will handle the error and roll back the transaction.

However,OnRecvPacket calls the keeper function directly, and the error returned by the keeper function is not passed.

    func (k Keeper) OnRecvPacket 
    ....
	if _, err = k.erc20Keeper.ConvertCoin(sdk.WrapSDKContext(ctx), convertMsg); err != nil {
		logger.Error("failed to convert coins", "error", err)
		return ack
	}

	// return original acknowledgement
	return ack

The OnRecvPacket function returns the same ack regardless of success or failure.

Therefore, if the erc20Keeper.ConvertCoin function fails halfway through execution, the error will not be handled.

The ConvertCoin function usually first deducts the user's token and then calls the mint or transfer function (k.CallEVM) in the contract.

Since there are many cases where K.CallEVM may fail to execute, if after deducting the user token, K.CallEVM does not execute successfully, the user's token will be permanently lost.

The convertCoinNativeERC20 function checks whether the user's balance is consistent after the conversion, and checks the Approval event in logs,

In this case, these checks are invalid because the returned error will not be handled.

func (k Keeper) convertCoinNativeERC20....{
    ...
    // Escrow Coins on module account
	if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, coins); err != nil {
		return nil, errorsmod.Wrap(err, "failed to escrow coins")
	}
    // Unescrow Tokens and send to receiver
	res, err := k.CallEVM(ctx, erc20, types.ModuleAddress, contract, true, "transfer", receiver, msg.Coin.Amount.BigInt())
	if err != nil {
		return nil, err
	}
    ...
	if r := balanceTokenAfter.Cmp(exp); r != 0 {
		return nil, errorsmod.Wrapf(
			types.ErrBalanceInvariance,
			"invalid token balance - expected: %v, actual: %v", exp, balanceTokenAfter,
		)
	}
	...
	// Check for unexpected `Approval` event in logs
	if err := k.monitorApprovalEvent(res); err != nil {
		return nil, err
	}
}

The same problem occurs when executing coinswapKeeper.TradeInputForExactOutput.

Tools Used

vscode, manual

Recommended Mitigation Steps

func (k Keeper) OnRecvPacket ...{
	if _, err = k.erc20Keeper.ConvertCoin(sdk.WrapSDKContext(ctx), convertMsg); err != nil {
		logger.Error("failed to convert coins", "error", err)
-		return ack
	}
+	if err != nil {
+    	// Transaction failed, rollback
+    	abci.AbortTx(ctx.Height())
+    	return ack
+	}
}

Assessed type

Error

@c4-bot-4 c4-bot-4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Jun 15, 2024
c4-bot-2 added a commit that referenced this issue Jun 15, 2024
@c4-bot-11 c4-bot-11 added 🤖_08_group AI based duplicate group recommendation 🤖_primary AI based primary recommendation labels Jun 20, 2024
@howlbot-integration howlbot-integration bot added sufficient quality report This report is of sufficient quality duplicate-19 labels Jun 21, 2024
@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Jun 26, 2024
@c4-judge
Copy link

3docSec changed the severity to QA (Quality Assurance)

@c4-judge
Copy link

3docSec marked the issue as grade-b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-19 grade-b QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax 🤖_primary AI based primary recommendation 🤖_08_group AI based duplicate group recommendation sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

3 participants