Angle Protocol - Invitational - __141345__'s results

A decentralized stablecoin protocol.

General Information

Platform: Code4rena

Start Date: 28/06/2023

Pot Size: $52,500 USDC

Total HM: 10

Participants: 5

Period: 9 days

Judge: hansfriese

Total Solo HM: 6

Id: 255

League: ETH

Angle Protocol

Findings Distribution

Researcher Performance

Rank: 5/5

Findings: 1

Award: $0.00

Analysis:
grade-a

🌟 Selected for report: 2

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: __141345__

Labels

bug
2 (Med Risk)
disagree with severity
primary issue
satisfactory
selected for report
edited-by-warden
M-05

Awards

Data not available

External Links

Lines of code

https://github.com/AngleProtocol/angle-transmuter/blob/9707ee4ed3d221e02dcfcd2ebaa4b4d38d280936/contracts/transmuter/facets/Swapper.sol#L189 https://github.com/AngleProtocol/angle-transmuter/blob/9707ee4ed3d221e02dcfcd2ebaa4b4d38d280936/contracts/transmuter/facets/Swapper.sol#L210

Vulnerability details

Impact

This issue is an edge case, that uint128 changeAmount could overflow, making the protocol fail for certain amount of swap.

Proof of Concept

Let's break down the changeAmount:

  1. amountOut/amountIn
  2. BASE_27
  3. normalizer
File: transmuter/contracts/transmuter/facets/Swapper.sol
176:     function _swap() {

189:                 uint128 changeAmount = (amountOut.mulDiv(BASE_27, ts.normalizer, Math.Rounding.Up)).toUint128();

210:                 uint128 changeAmount = ((amountIn * BASE_27) / ts.normalizer).toUint128();
  1. normalizer could take value ranging from 1e18 to 1e36, we take the worst case, 1e18.
File: transmuter/contracts/transmuter/facets/Redeemer.sol
193:         if (newNormalizerValue <= BASE_18 || newNormalizerValue >= BASE_36) {

208:             newNormalizerValue = BASE_27;
209:         }
  1. BASE_27 is constant 1e27.

  2. amountOut/amountIn is AgToken with 18 decimals.

Combine the above 1, 2, 3, we have the "total decimal": 1e18 * 1e27 / 1e18 = 1e27.

The max value of uint128 is 3.4e38. To overflow, the amountOut/amountIn need to be around 3.4e38 / 1e27 = 3.4e11.

For nowadays currencies around the world, we can look at Iranian Rial (IRR). 3.4e11 IRR is around 8M USD. 8M USD is a big amount for now. However considering the following, this concern maybe not nonsense:

  • USD itself is depreciating, from 1970s to now, the gold price(historical chart) has changed from 35 USD/oz to 2000 USD/oz, almost 60 times.
  • Some countries have high inflation rate (Iran, Vietnam, Sierra, Leonean, Lao, etc. That's how the many zeros in these currencies come).
  • Taking a longer time span of 10-20 years, the depreciation could be influential.

If after 20 years, 3.4e11 of some currency with high inflation depreciates more than 100 times . In that case, the amount is around 80k USD, a reasonable amount to use (especially for institutions).

Although the possibility is low for current use cases, in the future, things could change. To make the stablecoin protocol universal for all countries in the world, the edge case might be some concern.

Tools Used

Manual analysis.

  • Use uint256 for changeAmount, then the likelihood would be negligible small, making the system more robust to special situations. uint256 wont add too much cost, but can avoid much more potential issue.

  • Use narrower range for normalizer. 1e9 for both up and down direction might be too big, and not necessary.

Assessed type

Under/Overflow

#0 - c4-judge

2023-07-08T12:18:56Z

hansfriese marked the issue as primary issue

#1 - Picodes

2023-07-10T09:16:12Z

Although the possibility of overflow is real, I don't think the scenario is convincing and this likely to happen. Worst case the code is already using safeCast

#2 - c4-sponsor

2023-07-10T09:16:17Z

Picodes marked the issue as disagree with severity

#3 - hansfriese

2023-07-10T11:21:44Z

Will keep it as medium because it's likely to happen and _swap() will revert during the safeCast.

#4 - c4-judge

2023-07-10T11:21:53Z

hansfriese marked the issue as satisfactory

#5 - c4-judge

2023-07-10T15:40:05Z

hansfriese marked the issue as selected for report

Findings Information

🌟 Selected for report: __141345__

Also found by: Lambda, auditor0517

Labels

analysis-advanced
grade-a
selected for report
A-02

Awards

Data not available

External Links

Here will share some thoughts in 2 aspects. Composability and Penalty Factor.

Composability

Composability is a huge advantage of DeFi, on the other side, it also could be a double sword. Considering Angle can work with other stablecoin system, and the sub-collateral is also introduced, the inter dependency could go quite complex later on. Some troublesome situation could be like: stableA use stableB as collateral, stableB use stableC as collateral, stableC again use stableA as collateral, ABC form a cycled collateral. If the cycle involves tens of tokens, it could be hard to spot the issue. But in the time of crisis, such inter dependent system will break quickly.

The idea of sub-collateral can help to expand the available assets for the protocol. On the other hand, more attention will be needed with regards to uncontrollable external contracts. It may need special attention, such as:

  • the sub-collateral changed the constitution (such as DAI and FRAX could change the backed assets).
  • it may further has sub-sub-collateral.
  • there is locked time period of the sub-collateral, such as notional fixed rate bond token, maybe 6 month to expiry.

The same principal applies to other parts of the contract. Overall, the protocol works great in terms of modular implementation, by which I mean the Angle system has sub-modules, acting like LEGO. One developing suggestion might be not go too far in the compatibility with other protocols, just like the sub-collateral, maybe one layer of integration is good enough, but not too much.

Penalty Factor and Depeg Handling

The main suggestion is to add some kind of downside protection as last resort. Below is the reason.

The penalty factor can deter users from bank run, this is a clever design. But depending on the severity of the situation, the outcome might be quite different. Let's divide the users into 2 groups: "run" and "stay", and compare the 2 past big events: USDC and luna.

  1. USDC It depegged to 0.87 and recovered afterwards. The penalty rule will work great. The "run" group will be penalized and the "stay" group will be rewarded. The most important is, USDC recovered at last.

  2. luna It just went down to zero. At the end, everyone loses. At the beginning, the "run" group would be discouraged to exit. In the end, they ended up losing more because missing the earlier exit stop loss opportunity.

My understanding of some main stream stable coin is, it should stay pegged, or just go zero and exit. It's hard to imagine USDC valued at $0.65 after market rally (even if the loss is too big, the admin might try to burn some of the supply to recover the price, otherwise it has nothing to do with USD). Hence, the penalty factor rule can work great in the first situation with recover, but not for collapse case. When depeg comes, the protocol will hope no one get panic and bank run, but can not assure that everything is ok if staying. It will become a difficult trade off for users.

To deal with the worst situation, some protect such as insurance can be added. With the downside protection as last resort, users wont worry that much to join the "stay" group. Worst case, if this stable coin goes to zero, they know they are still covered anyway. The last protection could act as a patch for the penalty rule.

There are some defi insurance providers, for example unslashed, nexusmutual, insurace, bridgemutual. As for the choice of this kind of protection, the cheapest tier can be used, since the collapse situation is some extremely low possible black swan. The alternative could be put option, however the choice could be limited, and the cost might be higher.

One more thing, for such kind of insurance, if try to protect USDC, the payout should not be in USDC. Because if USDC goes to 0, it it pointless to receive huge payout still in USDC.

Time spent:

25 hours

#0 - c4-judge

2023-07-08T12:36:14Z

hansfriese marked the issue as grade-a

#1 - c4-judge

2023-07-10T15:54:02Z

hansfriese marked the issue as selected for report

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter