Algo Ssstablecoinsss

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

Hardcoded Two-Collateral Limit Prevents Protocol Flexibility

Root + Impact

Root Cause: The COLLATERAL_TOKENS array is defined with a fixed size of 2 elements, and the constructor only accepts exactly 2 token addresses and 2 price feed addresses.

Impact: The protocol cannot support more than 2 collateral types without code modifications. This contradicts the documentation stating the code should work for "any basket of assets" and limits the protocol's ability to scale or adapt to market demands.

Description

Normal Behavior: According to the documentation, the protocol should allow forking and swapping "WETH & WBTC for any basket of assets" with the code working the same.

Issue: The collateral token array is hardcoded to exactly 2 elements, preventing support for more diverse collateral baskets without code modifications.
# dsc_engine.vy
COLLATERAL_TOKENS: public(immutable(address[2])) # @> Fixed size of 2
@deploy
def __init__(
token_addresses: address[2], # @> Exactly 2 tokens
price_feed_addresses: address[2], # @> Exactly 2 feeds
dsc_address: address,
):
# ...

Risk

Likelihood:MEDIUM

  • Reason 1 : Any protocol fork wanting more than 2 collateral types encounters this limitation immediately

  • Reason 2 : Adding new collateral to an existing deployment is impossible

Impact:

  • Impact 1 : Cannot support diverse collateral baskets without redeployment

  • Impact 2 : Reduced protocol flexibility and composability

Proof of Concept

A protocol fork attempts to support WETH, WBTC, and LINK as collateral. The deployment fails because the constructor signature requires exactly address[2] for token addresses. The only solution is modifying the contract code, recompiling, and redeploying, negating the "swap and deploy" simplicity promised in documentation.

def test_cannot_add_third_collateral():
# Deployer wants to support WETH, WBTC, and LINK as collateral
token_addresses = [WETH, WBTC, LINK] # 3 tokens
price_feeds = [ETH_USD, BTC_USD, LINK_USD] # 3 feeds
# Deployment fails - constructor only accepts address[2]
# TypeError: Expected address[2], got address[3]
engine = DSCEngine.deploy(token_addresses, price_feeds, dsc) # FAILS

Recommended Mitigation

Use dynamic arrays with a reasonable maximum size instead of fixed-size arrays. This allows deployers to configure any number of collateral tokens up to the maximum while maintaining gas efficiency.

# dsc_engine.vy
+ MAX_COLLATERAL_TOKENS: constant(uint256) = 10
- COLLATERAL_TOKENS: public(immutable(address[2]))
+ COLLATERAL_TOKENS: public(DynArray[address, MAX_COLLATERAL_TOKENS])
@deploy
def __init__(
- token_addresses: address[2],
- price_feed_addresses: address[2],
+ token_addresses: DynArray[address, MAX_COLLATERAL_TOKENS],
+ price_feed_addresses: DynArray[address, MAX_COLLATERAL_TOKENS],
dsc_address: address,
):
+ assert len(token_addresses) == len(price_feed_addresses), "DSCEngine__ArrayLengthMismatch"
+ assert len(token_addresses) > 0, "DSCEngine__NoCollateralTokens"
# ...
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 3 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!