Skip to content

Reporting PoC For Example Purposes Only

Low
mohammedpatla published GHSA-pqw8-6vx9-jx64 May 24, 2023

Package

cargo None, example only (Rust)

Affected versions

None

Patched versions

None

Description

Short Description and Bug Location

I went to wrap some more of my unwrapped SCRT in the newly deployed ShadeSwap sSCRT snip20, and it erased my previous sSCRT balance. This bug exists in the snip20 code as it is in the ShadeSwap repo in the following location:
https://github.com/securesecrets/shadeswap/blob/PoC/contracts/snip20/src/contract.rs.

Steps to Reproduce

Firstly, have a wallet loaded with testnet secret. This can be done using the testnet faucet at
https://faucet.pulsar.scrttestnet.com. I chose to create a new wallet that I then loaded. I then added it to my secretd keyring using
secretd keys add ExampleWallet --recover, followed by the mnemonic phrase.

Then, configure secretd to point to the pulsar-2 testnet. As of 3 April 2023, the following configuration worked:

{
	"chain-id": "pulsar-2",
	"keyring-backend": "os",
	"output": "json",
	"node": "http://testnet.securesecrets.org:26657/",
	"broadcast-mode": "sync"
}

In another terminal window, checkout the ShadeSwap repo, ensure you are on the latest commit (909019e), and make.

Once complete, navigate to ./compiled, ensure that snip20.wasm.gz is present, and store it on Pulsar-2 using:

secretd tx compute store snip20.wasm.gz --from ExampleWallet --gas 4000000.

Query the store transaction with secretd q tx <TXHASH_HERE> and find and record the numeric 'code_id' from the resulting JSON.

Then, create a JSON file named snip20_init.json with the following contents:

{
    "name": "SSCRT",
    "symbol": "SSCRT",
    "decimals": 6,
    "initial_balances": [
        {"address": "OPTIONAL TESTNET ADDRESS HERE", "amount": "1000000000000"}
    ],
    "prng_seed": "PoCSeed",
    "config": {
        "public_total_supply": true,
        "enable_mint": true,
        "enable_burn": true,
        "enable_deposit": true
    }
}

Also create a JSON file named snip20_x_deposit.json with the following contents:

{
   "deposit": {}
}

Within snip20_init.json, change the address listed under 'initial_balances' to any other testnet wallet of your choice. (This initial balance will be transferred later to the primary testing wallet to illustrate that this bug happens regardless of the balance amount or where the balance came from.)

Then, execute the following in the same directory as the created snip20 JSONs:

secretd tx compute instantiate <CODE_ID> $(cat snip20_init.json | jq -c) --from <WALLET> --label "<ANY_LABEL>" -y --gas 4000000.

By querying the resulting TX Hash, you should get a result like this. Record the 'contract_address' value and create a viewing key with the primary testing wallet for the newly deployed snip20 in keplr, showing what should be a zero balance.

Then, execute the following in the same directory as the downloaded snip20 JSONs to deposit uscrt into the sSCRT contract:

secretd tx compute execute <CONTRACT_ADDRESS> $(cat snip20_x_deposit.json | jq -c) --from <WALLET> --gas 700000 -y --amount 1000000.0uscrt

I queried the TX Hash and received a success response, with my Keplr showing an updated balance.

Then, I exposed the bug by executing the same command from the same directory as before, but with the --amount flag set to 5000000.0uscrt

This should have yielded an expected sSCRT balance of 6, but instead my actual balance was 5. My previous balance of 1 is gone, with a replacement occurring instead of an addition of funds.

This bug's behavior was again confirmed when I used my other wallet seeded with an initial balance of sSCRT to load 750 additional sSCRT onto my primary testing wallet, and then tried to deposit again, this time with an --amount of 9000000.0uscrt. Rather than the expected result of 764sSCRT, the actual result was an overriding of my 755sSCRT, becoming only 9sSCRT.

Expected Economic Impact

Any user depositing any amount of funds into this snip20 contract will permanently lose all funds they previously held. By permanenly freezing funds, the Threat Level of this Smart Contract Vulnerability is Critical. The total supply of the deployed sSCRT snip20 is currently 1445185.241541 valued at $0.30 apiece, resulting in $433,555.57 of funds at risk of being permanently frozen.

Severity

Low

CVE ID

No known CVE

Weaknesses

No CWEs