Skip to content

refactor: Cover high level audit items - #9

Open
sontrinh16 wants to merge 7 commits into
auditfrom
son/audit_high_items
Open

sontrinh16 wants to merge 7 commits into
auditfrom
son/audit_high_items

Conversation

@sontrinh16

Copy link
Copy Markdown

Summary

Address audit findings affecting ERC20 withdrawals, staking amount validation, governance proposals, and genesis initialization.

Changes

  • Burn wrapped ERC20 coins when the underlying contract no longer exists, including withdrawals after its token pair has been deleted.
  • Add GetTokenPair to the ERC20 keeper interface and update the test mock.
  • Reject zero and negative amounts in coin subtraction and unlock entry removal.
  • Return an error when cancel-unbonding cannot find the requested creation height.
  • Register and return the correct proposal type for RemoveMultiStakingCoinProposal.
  • Handle missing parameter storage before unmarshalling.
  • Rejecting duplicate validator addresses during genesis validation, including alternate casing.
  • Return errors from SetValidatorMultiStakingCoin and update callers to handle them.

Testing

  • Add coverage for ERC20 withdrawals with live, missing, and deleted token pairs, repeated withdrawals, and bank/conversion failures.
  • Add genesis validation and duplicate-setter regression tests.
  • Passed:
    CGO_ENABLED=0 go test -tags=test ./x/multi-staking/types ./x/multi-staking/keeper

Compatibility

SetValidatorMultiStakingCoin now returns an error. Downstream callers should handle it. InitGenesis still panics on invalid input if genesis validation is bypassed.

@sontrinh16
sontrinh16 requested a review from hieuvubk September 16, 2026 04:39

@hieuvubk hieuvubk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1st review. Overall look good to me.

1 thing I dont understand was about burning in UnescrowCoinTo
Also let make a separate pr to realio-network repo to port multistaking commit hash into it. Make sure integration test in realio-network passed. Also let add more test case into it to prove changes works.

ConvertCoin(ctx context.Context, msg *erc20types.MsgConvertCoin) (*erc20types.MsgConvertCoinResponse, error)
ConvertERC20(ctx context.Context, msg *erc20types.MsgConvertERC20) (*erc20types.MsgConvertERC20Response, error)
RegisterERC20(ctx context.Context, msg *erc20types.MsgRegisterERC20) (*erc20types.MsgRegisterERC20Response, error)
GetTokenPair(ctx sdk.Context, id []byte) (erc20types.TokenPair, bool)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we need to expose this func at multistaking keeper?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the check after convert erc20 token where a deleted contract cause the erc20 keeper to remove the token pairing

if len(tokenID) == 0 && erc20types.ValidateErc20Denom(coin.Denom) == nil {
// A previous conversion may already have deleted the dead contract's
// token pair. Its remaining wrapped coins must not become native payouts.
return k.bankKeeper.BurnCoins(ctx, types.ModuleName, coins)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is burn coins step here and after erc20 conversion about?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just pre check burn for already removed contracts but the wrapped token still exists

// selfdestructed contract. Only the latter deletes the pair and leaves
// the Cosmos coins unburned in the recipient's account.
if _, found := k.erc20keeper.GetTokenPair(sdkCtx, tokenID); !found {
if err := k.BurnCoin(sdkCtx, toAcc, coin); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this to cover pair that got delete during the conversion

@sontrinh16

Copy link
Copy Markdown
Author

1st review. Overall look good to me.

1 thing I dont understand was about burning in UnescrowCoinTo Also let make a separate pr to realio-network repo to port multistaking commit hash into it. Make sure integration test in realio-network passed. Also let add more test case into it to prove changes works.

When an ERC20 contract is selfdestructed after delegation, ConvertCoin detects the dead contract → DeleteTokenPair → returns nil, nil. UnescrowCoinTo receives no error → the user keeps the cosmos coins from SendCoinsFromModuleToAccount. These cosmos coins are never burned → hidden inflation. The original ERC20 tokens remain locked in the dead contract forever.

@hieuvubk

Copy link
Copy Markdown

1st review. Overall look good to me.
1 thing I dont understand was about burning in UnescrowCoinTo Also let make a separate pr to realio-network repo to port multistaking commit hash into it. Make sure integration test in realio-network passed. Also let add more test case into it to prove changes works.

When an ERC20 contract is selfdestructed after delegation, ConvertCoin detects the dead contract → DeleteTokenPair → returns nil, nil. UnescrowCoinTo receives no error → the user keeps the cosmos coins from SendCoinsFromModuleToAccount. These cosmos coins are never burned → hidden inflation. The original ERC20 tokens remain locked in the dead contract forever.

make sense, let add an integration test for it to explain to realio team later

Signed-off-by: sontrinh16 <trinhleson2000@gmail.com>
@sontrinh16
sontrinh16 marked this pull request as ready for review September 16, 2026 08:53

@hieuvubk hieuvubk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants