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

Findings: 1

Award: $1.37

🌟 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-L153 https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/1155tech-contracts/src/Market.sol#L174-L189 https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/1155tech-contracts/src/Market.sol#L141-L145 https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/1155tech-contracts/src/bonding_curve/LinearBondingCurve.sol#L14-L25

Vulnerability details

Impact

In this protocol, the buying or selling price of a share is calculated through a linear bonding curve. The higher the supply of shares in circulation, the more expensive they gradually become. This mechanic exposes users to front running attacks. If User A wants to buy shares but User B bought a substantial amount of shares before hand, the User A will suffer from a price increase, and User B can make a direct profit by selling the shares at an increased price. The same is applicable in a scenario where User A wants to sell his shares, but receives a substantial lesser selling income because has been frontrunned by User B.

Proof of Concept

Let's assume that the priceIncrease variable is set to 2.

The initial supply of shares is 5.

Bob wants to buy 10 shares. Expected cost: 220

Alice quickly buys 20 shares before Bob's transaction is mined. Supply is now 25. (spent 630)

The increased supply due to Alice's transaction affects Bob's price for the transaction.

Bob ends up paying the actual cost of 660 instead of 220. 420 more than the expected price.

Alice can sell her shares for 1050. Alice profit amounts to 420.

Tools Used

Manual review

Set a slippage parameter to compare it against the price for selling or buying. Such as :

@> function buy(uint256 _id, uint256 _amount, uint256 maxPrice) external { require(shareData[_id].creator != msg.sender, "Creator cannot buy"); (uint256 price, uint256 fee) = getBuyPrice(_id, _amount); // Reverts for non-existing ID @> If(price + fee > maxPrice) revert PriceIsTooHigh(); SafeERC20.safeTransferFrom(token, msg.sender, address(this), price + fee); // The reward calculation has to use the old rewards value (pre fee-split) to not include the fees of this buy ...
@> function sell(uint256 _id, uint256 _amount, minSellPrice) external { (uint256 price, uint256 fee) = getSellPrice(_id, _amount); @> if(price - fee) < minSellPrice revert PriceIsTooLow(); // Split the fee among holder, creator and platform _splitFees(_id, fee, shareData[_id].tokensInCirculation); // The user also gets the rewards of his own sale (which is not the case for buys) uint256 rewardsSinceLastClaim = _getRewardsSinceLastClaim(_id); rewardsLastClaimedValue[_id][msg.sender] = shareData[_id].shareHolderRewardsPerTokenScaled; shareData[_id].tokenCount -= _amount; shareData[_id].tokensInCirculation -= _amount; tokensByAddress[_id][msg.sender] -= _amount; // Would underflow if user did not have enough tokens // Send the funds to the user SafeERC20.safeTransfer(token, msg.sender, rewardsSinceLastClaim + price - fee); emit SharesSold(_id, msg.sender, _amount, price, fee); }

Assessed type

MEV

#0 - c4-pre-sort

2023-11-18T10:33:44Z

minhquanym marked the issue as duplicate of #12

#1 - c4-judge

2023-11-28T23:14:14Z

MarioPoneder changed the severity to 2 (Med Risk)

#2 - c4-judge

2023-11-28T23:34:29Z

MarioPoneder marked the issue as satisfactory

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