Canto Application Specific Dollars and Bonding Curves for 1155s - pontifex's results

Tokenizable bonding curves using a Stablecoin-as-a-Service token

General Information

Platform: Code4rena

Start Date: 13/11/2023

Pot Size: $24,500 USDC

Total HM: 3

Participants: 120

Period: 4 days

Judge: 0xTheC0der

Id: 306

League: ETH

Canto

Findings Distribution

Researcher Performance

Rank: 7/120

Findings: 3

Award: $739.56

QA:
grade-a

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

Awards

690.3741 USDC - $690.37

Labels

bug
3 (High Risk)
satisfactory
duplicate-181

External Links

Lines of code

https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/asD/src/asD.sol#L73-L76

Vulnerability details

Impact

The asD.withdrawCarry function will always throw an error for all normal totalSupply() values due to inappropriate scale factor. So the creator can withdraw the accrued interest only after all users will burn their asD tokens.

Proof of Concept

The scale factor at the line L#76 of the asD contract may be used with cTokens with 8 decimals but not with the cNOTE which token has 18 decimals. The exchangeRateCurrent() for the cNOTE is scaled by 1 * 10**(18 - 18 + Underlying Token Decimals), i.e. 1e18. So the current scale factor is too big.

        uint256 maximumWithdrawable = (CTokenInterface(cNote).balanceOf(address(this)) * exchangeRate) /
            1e28 -
            totalSupply();

This way the underlying amount will be always underestimated and there will be the underflow error here.

Tools Used

Manual review

Consider using 1e18 scale factor instead of 1e28.

Assessed type

Decimal

#0 - c4-pre-sort

2023-11-18T09:01:20Z

minhquanym marked the issue as duplicate of #227

#1 - c4-judge

2023-11-28T22:58:04Z

MarioPoneder marked the issue as satisfactory

Lines of code

https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/1155tech-contracts/src/bonding_curve/LinearBondingCurve.sol#L21

Vulnerability details

Impact

The shares price increases/decreases too fast especially for the first 20 shares and the sandwich attack can be really profitable. This way users may lose sufficient value of their investments when buying and selling the shares.

Proof of Concept

I will consider the option in which users buy one share at a time as a priority strategy for users, but the attack can be carried out equally when users buy several shares in one transaction or in a batch of transactions.

The difference between price + fee for buying share #n and rewardsSinceLastClaim + price - fee for selling share #n+1 let perform the sandwich attack. The most profitable is frontrun the first buyer. The attacker can receive approx. 0.77 * priceIncrease but the user losses approx. a half of investments. Then the attacker can repeat this attack with next users. Some of these users can decide to sell shares some - to keep. So there can be multiple attacks. The max tokenCount when the attack is possible for any attackers is 20 shares. In case an attacker is controlled by the share creator (the role can be untrusted) the max tokenCount is 100. In both cases the amount of shares does not reflect the amount of attacks because of different users behavior. The table shows the attackers profit for different tokenCount values when the LinearBondingCurve contract is used as a bondingCurve.

Tools Used

Manual review

Consider using the curve where the next token can't be sold with sufficient profit. For example the price of the first share can be equal 100 * priceIncrease. This makes frontrunning unprofitable even for the shares creators.

Assessed type

MEV

#0 - c4-pre-sort

2023-11-18T10:05:16Z

minhquanym marked the issue as duplicate of #12

#1 - c4-judge

2023-11-28T23:29:28Z

MarioPoneder marked the issue as satisfactory

Awards

47.8152 USDC - $47.82

Labels

bug
disagree with severity
downgraded by judge
grade-a
QA (Quality Assurance)
satisfactory
sponsor confirmed
sufficient quality report
Q-06

External Links

Lines of code

https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/asD/src/asD.sol#L52-L55

Vulnerability details

Impact

Due to the rounding losses an excess amount of cNOTE tokens may be burnt. This can cause different problems including that some amount of asD tokens can not be burnt, the owner of asD loses a part of the accrued interest and even the draining of the contract assets.

Proof of Concept

The asD.mint does not take into account the rounding losses at the cNOTE contract and mints exactly the _amount of asD. It is not a problem when a user deposits n tokens and then withdraws n tokens. But if the user deposits several times n tokens and then withdraws the whole value (k * n) the rounding error will be in k times less and the asD contract will burn an excess amount of cNOTE. There is a POC with a real exchange rate for the NOTE/cNOTE pair here. The test passes when the user mints 5e18 at once but not when the user deposits 5 times 1e18 NOTE and then withdraws the whole amount.

Running 3 tests for src/test/asDR.t.sol:asDR [PASS] testBurn() (gas: 267387) Logs: cNOTE 4979798570281804344 [PASS] testMint() (gas: 217598) Logs: cNOTE 4979798570281804344 [FAIL. Reason: revert: ERC20: burn amount exceeds balance] testMintThenBurn() (gas: 565204) Logs: cNOTE 4979798570281804340

Tools Used

Manual review

Consider checking the actual minted amount of cNOTE to mint the appropriate amount of asD. It is obvious that the amount of asD can be slightly less than deposited NOTE but it will guarantee that all asD tokens can be redeemed.

Assessed type

Other

#0 - c4-pre-sort

2023-11-20T17:58:31Z

minhquanym marked the issue as sufficient quality report

#1 - OpenCoreCH

2023-11-27T11:13:26Z

I think this is indeed a problem. Need to check if it is only in the test setup or also when using the real CLM, but I think they round in the same direction.

Severity seems a bit overinflated to me. Monetary damage would be ~0 (10^(-18) USD), but it is of course not good when a user cannot burn their whole balance and has to deduct a few weis.

#2 - OpenCoreCH

2023-11-28T19:34:51Z

CLM really rounds the same way, so it could happen in practice. However, the probability of it occurring should be very low for multiple reasons:

  • If the exchange rate has increased (even if only a little bit) between mint and burn, it does not happen.
  • It only happens for the very last burn (and also only when there is no accrued interest)
  • In withdrawalCarry, we also round down when calculating the maximum withdrawable amount, meaning that the owner can potentially withdraw 1 wei less because of the rounding. This could average out the rounding

#3 - c4-sponsor

2023-11-28T19:35:00Z

OpenCoreCH marked the issue as disagree with severity

#4 - c4-sponsor

2023-11-28T19:35:05Z

OpenCoreCH (sponsor) confirmed

#5 - MarioPoneder

2023-11-28T22:20:20Z

The given deviation is miniscule and likelihood is low (see sponsor comment).
Nevertheless, the strict asD:NOTE = 1:1 relation is not always conserved, therefore moving forward with Medium severity.

#6 - c4-judge

2023-11-28T22:20:27Z

MarioPoneder changed the severity to 2 (Med Risk)

#7 - c4-judge

2023-11-28T22:20:37Z

MarioPoneder marked the issue as satisfactory

#8 - c4-judge

2023-11-28T22:20:41Z

MarioPoneder marked the issue as selected for report

#9 - MarioPoneder

2023-11-30T01:22:08Z

Returning to this issue after judging the rest of the contest, it seems inconsistent and unfair to maintain Medium severity in the present case.
Considering that the peg can only deviate by a miniscule an negligible amount, it's fair to move forward with QA.

#10 - c4-judge

2023-11-30T01:22:13Z

MarioPoneder marked the issue as not selected for report

#11 - c4-judge

2023-11-30T01:22:18Z

MarioPoneder changed the severity to QA (Quality Assurance)

#12 - c4-judge

2023-11-30T01:22:23Z

MarioPoneder marked the issue as grade-a

#13 - SovaSlava

2023-12-02T11:59:15Z

  1. The main invariant "asD: It should always be possible to redeem 1 asD for 1 NOTE" is broken.
  2. There is no guarantee that the rate will increase. The only guarantee is that the rate will not decrease.
  3. The POC shows only 5 deposits and the impact is 4 wei, but there can be hundreds of deposits and the impact will increase.

#14 - MarioPoneder

2023-12-04T12:49:49Z

Thank you for your comment!

According to https://docs.compound.finance/v2/ctokens/#exchange-rate:

Each cToken is convertible into an ever increasing quantity of the underlying asset, as interest accrues in the market.

Furthermore, the PoC shows an edge-case where asD is immediately burned after minting.
Typically, times passes the interest accrued through cNOTE in the meantime, see also the sponsor's comment:

If the exchange rate has increased (even if only a little bit) between mint and burn, it does not happen.

Therefore, maintaining QA.

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