CosmWasm security spotlight #1

JCsec
Oak Security
Published in
3 min readApr 3, 2023

Are you a CosmWasm Smart Contract developer? A random Cosmonaut peeking into this cool tech? A Solidity auditor looking for new knowledge? Then keep reading!

There are loads of great content about security findings and auditing of Solidity Smart Contracts. Sadly, that is not the case in CosmWasm… yet!

My name is JC and I have been auditing CosmWasm contracts since the end of 2021. I am a proud member of the Oak Security team, uncontested security provider quality-wise for all things CW. From now on I will be publishing knowledge pills of common security pitfalls of CosmWasm smart contracts, based on issues found during my auditing.

Enough with the introduction! let’s get into today’s topic.

Unsaved Storage Changes

Smart Contracts will use different pieces of storage data to successfully implement its features: configuration details, privileged addresses, bookkeeping, anything!

Some functions will just require reading this data and others will modify it… but sometimes mistakes happen. Code paths may be complex, last-minute changes may not be as careful as they should or you just forgot.

pub fn update_name(
deps: DepsMut,
info: MessageInfo,
name: Option<String>,
) -> Result<Response, ContractError> {
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;

let mut config = CONFIG.load(deps.storage)?;

if let Some(name) = name {
config.name = name;
}

// I feel like I am missing something...

Ok(Response::new()
.add_attribute("action", "update_name")
.add_attribute("name", config.name))
}

An Unsaved Storage Change issue happens when a function loads a piece of storage, modifies its data, and then never saves it. The concept is quite easy, however, the impact will heavily depend on each case. Let’s take the following issues as an example:

[CRITICAL] Report 1, finding #2 “LOCKINGADDRESS is never populated which will block rebasing functionality”

The addresses of users that performed a “Lock NFT” action were expected to be appended to LOCKINGADDRESS. Although the rest of the functionality was okay, the updated list of addresses was never saved in the storage. This turned other functionalities completely unusable, as users were never granted the privileges of having locked the asset.

[CRITICAL] Report 2, finding #1 “Bad debt state is not recorded”

The bad_debt attribute of STATE was used to, you guessed right, keep track of the contract’s bad debt! This allowed other features to compensate for potential insolvency scenarios. Passing the state variable around as mutable resulted in an unsaved storage situation where the contract didn’t effectively account for its bad debt. This would have caused the protocol to be insolvent or at risk of insolvency without it being aware.

[Minor] Report 3, finding #2 of “State update not stored”

Loading the same piece of storage into multiple variables is error-prone and should be avoided if possible. In this case, the affected functionality updated an attribute of the copy of storage data that was never saved instead of the one that was saved back. In this particular case, the affected attribute was not used at all, so the impact was lowered to a minor risk.

Hunt the bug!

Go practice in the first challenge of Oak’s CosmWasm Security Dojo created by Richie, and hunt this bug in a small lending contract. Peeking into the exploit too soon counts as cheating! :P

How to avoid this issue?

Whenever you need to load information from the storage, double-check whether you are modifying this data. If the information is modified during any of the execution paths, ensure that it is saved back into the storage at the end of the function or the path.

Contact me!

If you have any questions, or comments or what to know more about Oak Security and Solidified, feel free to drop a line to @jcr_auditor in Telegram or email me at jcr@oaksecurity.io

Check my Github profile for further educational content on Smart Contract security and auditing, including Solidity.

Telegram | Email | Twitter | Github | LinkedIn

Disclaimer! although most of the reports I will link are of audits I took part in, I will also include others. I do not claim ownership of any kind of the external resources included in these articles :)

--

--

JCsec
Oak Security

Smart Contract security auditor specialized in CosmWasm. Follow me on Twitter @jcsec_audits and Github https://github.com/jcsec-security