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

Include a check to ensure that a transfer is sent only if the slashed_amount is greater than 0 (audit issue #14) #603

Closed
james-chf opened this issue Oct 14, 2022 · 3 comments

Comments

@james-chf
Copy link
Contributor

This was finding 14 from the audit of eth-bridge-integration branch (commit 57fc202)

Severity: Informational
In apps/proof_of_stake/src/lib.rs:881 the transfer method is called regardless of the amount being slashed.
Recommendation
We recommend checking if the slashed_amount is greater than 0 before calling transfer in apps/proof_of_stake/src/lib.rs:881.

@james-chf
Copy link
Contributor Author

james-chf commented Oct 14, 2022

Relevant code in the slash fn which the Ethereum bridge will use once Ethereum bridge slashing logic is implemented:

let slashed_change: i128 = slashed_change.into();
let slashed_amount = u64::try_from(slashed_change)
.map_err(|_err| SlashError::InvalidSlashChange(slashed_change))?;
let slashed_amount = Self::TokenAmount::from(slashed_amount);
self.write_validator_total_deltas(validator, &total_deltas);
self.write_validator_voting_power(validator, &voting_power);
self.write_validator_slash(validator, validator_slash);
self.write_validator_set(&validator_set);
self.write_total_voting_power(&total_voting_power);
// Transfer the slashed tokens to the PoS slash pool
self.transfer(
&Self::staking_token_address(),
slashed_amount,
&Self::POS_ADDRESS,
&Self::POS_SLASH_POOL_ADDRESS,
);

The slashed_amount variable goes through being a u64 before being converted to Self::TokenAmount and passed to the transfer fn, so it should be at least 0, but not necessarily strictly greater than. This is still the case in the latest eth-bridge-integration code.

let slashed_change: i128 = slashed_change.into();
let slashed_amount = u64::try_from(slashed_change)
.map_err(|_err| SlashError::InvalidSlashChange(slashed_change))?;
let slashed_amount = Self::TokenAmount::from(slashed_amount);
self.write_validator_total_deltas(validator, &total_deltas);
self.write_validator_voting_power(validator, &voting_power);
self.write_validator_slash(validator, validator_slash);
self.write_validator_set(&validator_set);
self.write_total_voting_power(&total_voting_power);
// Transfer the slashed tokens to the PoS slash pool
self.transfer(
&Self::staking_token_address(),
slashed_amount,
&Self::POS_ADDRESS,
&Self::POS_SLASH_POOL_ADDRESS,
);

We don't explicitly check that the amount is greater than 0. We could take the recommendation to check the amount being passed in at the call site, or maybe have the transfer fn explicitly reject/no-op when it is passed an amount that is not greater than 0.

@tzemanovic
Copy link
Member

With change to ceiling mul in #1830, slash rate and slashable token amount being greater than 0, the slash amount that's being transferred should always be non-zero. However, we're currently not transferring slashes, so we should check on this again with #1508

@cwgoes
Copy link
Contributor

cwgoes commented Oct 26, 2023

Not relevant.

@cwgoes cwgoes closed this as not planned Won't fix, can't repro, duplicate, stale Oct 26, 2023
phy-chain pushed a commit to phy-chain/namada that referenced this issue Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Status: Tested in Devnet
Development

No branches or pull requests

6 participants