Light ModeLight
Light ModeDark

One Bug Per Day

One H/M every day from top Wardens

Checkmark

Join over 1130 wardens!

Checkmark

Receive the email at any hour!

Ad

An attacker can bloat the Pink runtime storage with zero costs

mediumCode4rena

Lines of code

https://github.com/code-423n4/2024-03-phala-network/blob/a01ffbe992560d8d0f17deadfb9b9a2bed38377e/phala-blockchain/crates/pink/runtime/src/runtime.rs#L48 https://github.com/code-423n4/2024-03-phala-network/blob/a01ffbe992560d8d0f17deadfb9b9a2bed38377e/phala-blockchain/crates/pink/runtime/src/types.rs#L11

Vulnerability details

Impact

An attacker can perform a bloat attack by creating a very high amount of dust accounts.

This can occur with a minimal cost for the attacker, and results in a very high and increased cost in terms of storage and fees.

Proof of Concept

On substrate-based runtimes, the Existential Deposit (ED) is the minimum balance needed to have an active account, and it's useful to prevent dust accounts from bloating the storage state. In case the balance goes under the ED, the account will be reaped, i.e. completely removed from storage and the nonce reset.

Storage usage has a cost in terms of fees which impacts all the users, as there is a bigger overhead. The issue is that on the Pink runtime, the ED is dangerously low, which enables bloating attacks.

Let's see how feasible is to perform an attack from a price perspective. On Polkadot, the ED is 1 DOT. At the moment of writing, 1 DOT is worth about ~$10 USD, so if an attacker would want to split 10 million USD as dust between their own accounts, they would be able to create only 1 million accounts.

On the Pink runtime, this is not the case. At the moment of writing 1 PHA is equal to ~$0.20 USD; but here, the ED is only 1 unit:

rust
pub const ExistentialDeposit: Balance = 1;

https://github.com/code-423n4/2024-03-phala-network/blob/a01ffbe992560d8d0f17deadfb9b9a2bed38377e/phala-blockchain/crates/pink/runtime/src/runtime.rs#L48

As balance is simply a type alias of u128:

rust
pub type Balance = u128;

https://github.com/code-423n4/2024-03-phala-network/blob/a01ffbe992560d8d0f17deadfb9b9a2bed38377e/phala-blockchain/crates/pink/runtime/src/types.rs#L11

And 1 PHA is equal to 1_000_000_000_000:

rust
pub const PHAS: Balance = 1_000_000_000_000; pub const DOLLARS: Balance = PHAS; pub const CENTS: Balance = DOLLARS / 100; pub const MILLICENTS: Balance = CENTS / 1_000;

This means that an account costs only $0.20 / 1_000_000_000_000 for the attacker.

Following the previous DOT example, this means that an attacker could create 1 TRILLION accounts by simply paying just $0.20, but they could create even more accounts (several order of magnitudes bigger) with a small "investment", to fill all the storage.

Tools Used

Manual review

Recommended Mitigation Steps

Consider using a reasonable Existential Deposit. I recommend at least one CENTS (i.e. 1_000_000_000):

diff
- pub const ExistentialDeposit: Balance = 1; + pub const ExistentialDeposit: Balance = 1 * CENTS;

Assessed type

Decimal