Project Name: Algo Ssstablecoinsss
Repository: Cyfrin/2024-12-algo-ssstablecoinsss (Commit: 4cc3197)
Date: 2026-08-29
Auditor: Smart Chain Audit Agent (Google AI / Antigravity)
A targeted security audit was conducted on the Algo Ssstablecoinsss smart contracts on ZKsync Era, focusing on finding CRIT-01: the hardcoded 18-decimal assumption in collateral valuation and liquidation calculations.
| Severity | Count | Resolved | Acknowledged |
|---|---|---|---|
| Critical | 1 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 0 | 0 |
| Low | 0 | 0 | 0 |
| Informational | 0 | 0 | 0 |
| Total | 1 | 0 | 0 |
| File Path | Logic Overview | SWC / Risk Focus |
|---|---|---|
src/dsc_engine.vy |
Core minting, collateral valuation, and liquidation logic | SWC-101 (Arithmetic / Precision Underflow) |
src/oracle_lib.vy |
Chainlink price feed freshness verification library | SWC-136 (Oracle Security / Data Formatting) |
src/decentralized_stable_coin.vy |
ERC-20 stablecoin token implementation | SWC-105 (Access Control) |
Severity: Critical
Status: Confirmed / PoC Verified
Vulnerability Class: SWC-101 (Integer Precision / Arithmetic Logic Error)
Affected File(s): src/dsc_engine.vy:L302-L319, src/dsc_engine.vy:L346-L364
The protocol specification designates WETH and WBTC on ZKsync Era as the primary collateral basket, stating that the engine is designed such that:
"someone could fork this codebase, swap out WETH & WBTC for any basket of assets they like, and the code would work the same."
On ZKsync Era (contract 0xBBeB516fb02a01611cBBE0453Fe3c580D7281011), WBTC has 8 decimals, whereas WETH has 18 decimals. Chainlink's BTC/USD and ETH/USD feeds return prices with 8 decimals.
In dsc_engine.vy, _get_usd_value() assumes all collateral tokens have 18 decimals:
Where ADDITIONAL_FEED_PRECISION = 10**10 and PRECISION = 10**18.
When calculating the value of 1 WBTC (amount = 10**8) at a price of $100,000 (price = 100_000 * 10**8):
$$
The calculated value is 10,000,000,000x smaller than reality ($0.00001 instead of $100,000).
Conversely, in _get_token_amount_from_usd():
When liquidating $100,000 of debt against WBTC collateral:
$$
The calculation returns 1 billion WBTC instead of 1 WBTC (10**8 units).
The following test executed via uv run mox test tests/unit/test_pocs.py -s demonstrates both the valuation collapse and the 10-billion-fold liquidation calculation error:
PoC Verification Log Output:
Collateral Undervaluation / Capital Denial: Depositing WBTC gives borrowers zero borrowing power because their collateral is valued at $0.00001 per BTC.
Liquidation Revert / Protocol Freeze: All liquidations involving WBTC collateral attempt to transfer 10 billion times more tokens than exist in the contract, causing _redeem_collateral() to underflow and revert.
Severe Code Deviation: Breaks the promised multi-asset architecture.
Dynamically query each collateral token's decimals() via IERC20Detailed and normalize amounts to 18 decimals before computing dollar values, and de-normalize back to native token units when calculating liquidation transfers:
And in _get_token_amount_from_usd:
Moccasin / Titanoboa Unit Test: test_poc_wbtc_8_decimals_valuation_and_liquidation_broken passed in 3.55s.
Slither Findings: Slither detected arithmetic assumptions on token precision during cross-compilation check.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.