Algo Ssstablecoinsss

AI First Flight #2
Beginner FriendlyDeFi
EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

[H]The two addresses in token_addresses must be different; if they are the same, later collateral value calculations will be doubled, causing the health factor and liquidations to fail.

Root + Impact

Description

  • Users can deposit WETH and WBTC in exchange for a token that will be pegged to the USD and calculate the individual collateral values and then aggregate them.

  • If two identical addresses are set, the collateral value will be counted twice.

// Root cause in the codebase with @> marks to highlight the relevant section
def __init__(
token_addresses: address[2],
price_feed_addresses: address[2],
dsc_address: address,
):
// @> we should check if these two addresses are the same.
def _get_account_collateral_value(user: address) -> uint256:
total_collateral_value_in_usd: uint256 = 0
// @> If the address is the same, it will be counted twice.
for token: address in COLLATERAL_TOKENS:
amount: uint256 = self.user_to_token_address_to_amount_deposited[user][
token
]
total_collateral_value_in_usd += self._get_usd_value(token, amount)
return total_collateral_value_in_usd

Risk

Likelihood:

  • If two addresses are identical, a critical mortgage valuation error will occur, and health factors will become invalid.


Impact:

  • Health factor fails, asset valuation is inflated, attackers can drain the assets.


Proof of Concept

  1. Deploy with duplicate token address

  2. User deposits collateral

  3. Collateral value is double-counted

  4. Health factor is inflated

  5. User mints 2x DSC

def test_poc_token_addresses_must_be_different(weth, wbtc, eth_usd, btc_usd, dsc, some_user):
# Normal deploy: one weth and one wbtc
normal_dsce = dsc_engine.deploy([weth, wbtc], [eth_usd, btc_usd], dsc)
dsc.transfer_ownership(normal_dsce)
normal_dsce.set_minter(normal_dsce.address, True) if hasattr(normal_dsce, 'set_minter') else None
# Vulnerable deploy: weth passed twice (simulating duplicate addresses)
from script.deploy_dsc_engine import deploy_dsc_engine
# Deploy the duplicate-address version directly with dsc_engine.deploy
# Note: dsc ownership has been transferred to normal_dsce, so deploy a fresh dsc
from src import decentralized_stable_coin
vuln_dsc = decentralized_stable_coin.deploy()
vuln_dsce = dsc_engine.deploy([weth, weth], [eth_usd, eth_usd], vuln_dsc)
vuln_dsc.transfer_ownership(vuln_dsce)
# Deposit 10 ether of weth as collateral
with boa.env.prank(some_user):
weth.approve(vuln_dsce, COLLATERAL_AMOUNT)
vuln_dsce.deposit_collateral(weth, COLLATERAL_AMOUNT)
# Collateral value should be weth price * 10, but under the bug it is 2x
normal_collateral_value = vuln_dsce.get_usd_value(weth, COLLATERAL_AMOUNT)
vuln_collateral_value = vuln_dsce.get_account_collateral_value(some_user)
# Bug: same token counted twice — reported collateral value is 2x the real value
assert vuln_collateral_value == normal_collateral_value * 2, (
f"Bug not triggered: expected double {normal_collateral_value * 2}, got {vuln_collateral_value}"
)
# Impact: user can mint 2x more DSC than the protocol should allow
# Normal: 10 ETH @ $2000 = $20,000 collateral => max mint $10,000 DSC (50% threshold)
# Exploit: health factor calculated on $40,000 => max mint $20,000 DSC
max_safe_mint_normal = normal_collateral_value * 50 // 100 # LIQUIDATION_THRESHOLD = 50
max_safe_mint_vuln = vuln_collateral_value * 50 // 100
assert max_safe_mint_vuln == max_safe_mint_normal * 2, (
"Exploit confirmed: user can mint 2x DSC with the same collateral"
)

Recommended Mitigation

During the initial configuration, it is necessary to check if the addresses are identical.

def __init__(
token_addresses: address[2],
price_feed_addresses: address[2],
dsc_address: address,
):
+ assert token_addresses[0] != token_addresses[1], "DSCEngine__TokenAddressesMustBeDifferent"
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 8 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!