Canto Application Specific Dollars and Bonding Curves for 1155s - aslanbek'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: 63/120

Findings: 2

Award: $5.45

QA:
grade-b

๐ŸŒŸ Selected for report: 0

๐Ÿš€ Solo Findings: 0

Lines of code

https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/1155tech-contracts/src/Market.sol#L150 https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/1155tech-contracts/src/Market.sol#L203

Vulnerability details

Impact

In the periods of high demand, the price at which the user will be able to buy a share or mint an NFT may be significantly greater than the price at the moment of submitting the transaction.

The more shares/tokens a user is trying to buy/mint, the better target for frontrunning he becomes, as the frontrunner will immediately receive some of the fees that the user will pay.

Proof of Concept

  1. Token with id = 1 is created.
  2. Bob tries to buy 5 tokens of id 1. He calls getBuyPrice(1,5), which returns him values (x,y).
  3. Alice submits the same transaction with higher gas and buys 5 tokens for herself before Bob.
  4. Bob's txn is minted. He ends up paying 2.59 times more asD than he anticipated.

While some of the users may protect themselves by setting allowance precisely to the amount they are willing to spend every time they are about to make a transaction, a more sophisticated solution would be to add maxPrice parameter to Market's buy and mintNFT functions, which would revert the transaction if the price is too high.

Assessed type

Other

#0 - c4-pre-sort

2023-11-18T10:29:46Z

minhquanym marked the issue as duplicate of #12

#1 - c4-judge

2023-11-28T23:33:45Z

MarioPoneder marked the issue as satisfactory

Awards

4.0797 USDC - $4.08

Labels

bug
disagree with severity
downgraded by judge
grade-b
primary issue
QA (Quality Assurance)
sponsor acknowledged
edited-by-warden
Q-19

External Links

Lines of code

https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/1155tech-contracts/src/Market.sol#L114-L118 https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/asD/src/asDFactory.sol#L34

Vulnerability details

Impact

After calling createNewShare and asDFactory#create, users will usually deposit funds into the contracts. In events of chain reorganization, users who createdNewShare / createdAsD and shortly bought a share / minted asD, may lose some of their funds.

This is possible particulatly due to asDFactory#create using CREATE, which does not depend on the inputs nor the caller; similarly, createNewShare depends only on how many shares have been previously created.

createNewShare

Share creation is restricted at deployment, but, per README, it could be unrestricted as well. This example assumes that it is unrestricted.

  1. Alice createsNewShare with id == x

  2. Bob notices the ongoing reorg (or just does it by coincidence), and createsNewShare with the same id = x at the same time

  3. Alice tries to buy one share.

  4. Reorg is resolved. The chain where Bob created share with id == x becomes canonical. Alice's createNewShare txn is discarded.

  5. Alice buy txn is mined. She ends up buying Bob's share. Even if she sells it, she would still lose funds because of buying/selling fees.

In the worst case, Bob could set such bonding curve that would make Alice spend her whole allowance for Market contract. Considering she pays 10% fee two times (buying and selling), this would make her lose 1/5 of whatever her initial allowance was before the reorg.

asDFactory#create

  1. Alice creates asD "ALICE" on address 0xabcd, derived from asFactory's address and its nonce.

  2. At the same time, Bob creates asD "BOB" on the same address 0xabcd.

  3. Alice shortly deposits her NOTE into what she thinks is her own contract, to mint asD "ALICE".

  4. Reorg is resolved in Bob's favor.

  5. Few weeks later, Alice finds out that her NOTE has been generating yield for Bob and not for herself.

For asDFactory#create, use create2 with salt derived from msg.sender and user-provided salt.

For createNewShare, derive id from the hash of parameters and msg.sender.

Assessed type

Timing

#0 - c4-pre-sort

2023-11-20T07:47:18Z

minhquanym marked the issue as primary issue

#1 - c4-sponsor

2023-11-27T12:34:23Z

OpenCoreCH marked the issue as disagree with severity

#2 - c4-sponsor

2023-11-27T12:34:35Z

OpenCoreCH (sponsor) acknowledged

#3 - OpenCoreCH

2023-11-27T12:39:15Z

These are extremely improbable, constructed examples. You could probably create such an example for most protocols, especially the one with the consecutive IDs because many smart contracts use them. If a user wants to be really sure that they are on the canonical chain and this does not happen, they can simply wait a few blocks.

#4 - MarioPoneder

2023-11-29T00:16:38Z

According to our guidelines:

Unless there is something uniquely novel created by combining vectors, most submissions regarding vulnerabilities that are inherent to a particular system or the Ethereum network as a whole should be considered QA. Examples of such vulnerabilities include front running, sandwich attacks, and MEV.

Also reorg-attacks are part of this category, therefore QA seems most appropriate.

#5 - c4-judge

2023-11-29T00:16:50Z

MarioPoneder changed the severity to QA (Quality Assurance)

#6 - c4-judge

2023-11-29T22:30:23Z

MarioPoneder marked the issue as grade-c

#7 - osmanozdemir1

2023-11-30T21:36:04Z

Hi @MarioPoneder Thanks for judging this contest. I am commenting here under the primary issue as the author of one of the duplicates (#312) of this finding.

I acknowledge these kind of issues are related to blockchain itself, and a person could create such an example for most protocols as the sponsor mentioned. However, the upscaling factor related to this protocol is that contract creations are totally permissionless here, which makes this protocol much more vulnerable to this issue.

Based on that sentence in the guideline, frontrunning or MEV issues too would be invalid. However these issues still valid because protocols should take precautions to protect their users. Similar to that, if a protocol allows any user to create contracts permissionlessly, that protocol should also implement protections against the creation mechanism.

The problem here is not reorg itself, it is the protocol not taking necessary precautions while allowing everyone to deploy contracts.

I also would like to point out similar submissions related to permissionless contract creations and reorgs are historically judged as medium. References: August 2023 - PoolTogether: https://github.com/code-423n4/2023-08-pooltogether-findings/issues/31 July 2023 - PoolTogether: https://github.com/code-423n4/2023-07-pooltogether-findings/issues/416 May 2023 - Maia: https://github.com/code-423n4/2023-05-maia-findings/issues/861 April 2023 - Frankencoin: https://github.com/code-423n4/2023-04-frankencoin-findings/issues/155 January 2023 - RabbitHole: https://github.com/code-423n4/2023-01-rabbithole-findings/issues/661

I would appreciate if you could reconsider the severity of this issue and its duplicates. Kind regards

#8 - MarioPoneder

2023-11-30T23:16:30Z

Hi and thank you for your comment and the referenced findings!

After not finding a suitable answer in the org repo, I did some additional research on the C4 Judges Discord channel.
The answer is it depends on how exposed a protocol is to such an attack and how likely/expensive and long (in terms of blocks) such a reorg could be. Therefore I kindly ask for additional sponsor input on this. @OpenCoreCH

According to the README:

The code will be deployed to Canto

Looking at Cantoscan there is a Last finalized block and a Last safe block.
According to What are Ethereum commitment levels? Latest, Safe, Finalized:

The safe block is a block that has received attestations from two-thirds of Ethereumโ€™s validator set. Safe blocks are understood as unlikely to be reorged. For example, one of the few ways safe blocks could experience a chain reorganization is if there is a large-scale, coordinated attack on the network.

I see it as the user's / front-end's responsibility to wait for the Last safe block. Although the protocol does not take precautions for a reorg attack, it's not clear if this is necessary on the Canto chain like on Polygon for example where reorgs are regular.

Therefore, I will finalize my decision after the sponsor has provided additional input about their definition of Last safe block, the occurrence of reorgs on Canto and for how many blocks they last.

#9 - hungdoo

2023-12-01T06:06:42Z

Hi @MarioPoneder , thanks for the judging.

My report at the #405 duplicate can contribute to the ongoing discussion in several ways:

  1. The sponsor has confirmed that while asDFactory is currently deployed only on CANTO, the 1155tech market is open for deployment on other chains where reorgs occur frequently. The Last safe block to consider could be in minutes. For instance, the Polygon network has recorded several reorgs a day involving hundreds of transactions.
Sponsor confirmation
  1. We should avoid placing the responsibility on users to wait for the safest time to opt-in to the market after createNewShare was executed. This is because the 1155tech market operates on a BondingCurve pricing mechanism which increases token price over the number of tokens minted. It's in the user's best interest to act in a First-Come-First-Serve (FCFS) manner. If users wait for the safe block, they risk missing out on a good price as others decide to opt in as soon as possible (via other means, i.e., interacting directly with the smart contract). This could discourage them from engaging with the market.

#10 - OpenCoreCH

2023-12-02T14:26:23Z

After not finding a suitable answer in the org repo, I did some additional research on the C4 Judges Discord channel. The answer is it depends on how exposed a protocol is to such an attack and how likely/expensive and long (in terms of blocks) such a reorg could be. Therefore I kindly ask for additional sponsor input on this. @OpenCoreCH

Good question, had to look it up, but it looks like these reorgs are not possible. Canto is a fork of Evmos/Ethermint and also uses Tendermint Core BFT consensus. This provides 1-block finality and not probabilisitic finality like other chains: https://docs.ethermint.zone/core/pending_state.html

#11 - MarioPoneder

2023-12-04T12:06:00Z

Thanks everyone for their input on this!

Considering the 1-block finality on Canto, QA will be maintained.
However, those finds are still a valuable contribution, therefore moving forward with grade-b.

1155tech may be deployed on other chains in the future.

According to the README (source of truth of this contest), the protocol will be deployed on Canto and I cannot take potential future deployments into consideration for judgement, especially when we don't know exactly which chain it's going to be.

Further info regarding 1-block finality:
One can observe on Cantoscan that Last finalized block and Last safe block are always the same.

#12 - c4-judge

2023-12-04T12:06:06Z

MarioPoneder marked the issue as grade-b

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