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
Rank: 79/120
Findings: 1
Award: $4.08
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: chaduke
Also found by: 0xpiken, Bauchibred, Matin, MohammedRizwan, MrPotatoMagic, OMEN, Pheonix, SandNallani, T1MOH, Topmark, ZanyBonzy, adriro, aslanbek, ayden, bareli, bart1e, bin2chen, btk, cheatc0d3, codynhat, critical-or-high, d3e4, erebus, firmanregar, hunter_w3b, jasonxiale, kaveyjoe, ksk2345, lsaudit, max10afternoon, merlinboii, nailkhalimov, osmanozdemir1, peanuts, pep7siup, pontifex, sbaudh6, shenwilly, sl1, tourist, wisdomn_, young, zhaojie
4.0797 USDC - $4.08
According to the document the cost of buy a specific amount of tokens for a given share ID is linear:
1155tech allows to create arbitrary shares with an arbitrary bonding curve. At the moment, only a linear bonding curve (i.e. a linear price increase based on the total supply of a share) is supported
As we can see the cost of mint consists of 2 parts :
Although the price is linear, the fee is not. This results in the actual cost incurred not being linear。This will lead to a situation where the fees consumed by later users are less than those consumed by earlier users
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import {Test, console2} from "forge-std/Test.sol"; import "src/bonding_curve/LinearBondingCurve.sol"; import "src/Market.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MockERC20 is ERC20{ constructor() ERC20("asD ","asD "){} function mint(address to, uint256 amount) external { _mint(to, amount); } } contract LinearTest is Test { MockERC20 public paymentToken ; Market public market; LinearBondingCurve public curve; uint256 constant LINEAR_INCREASE = 1e18 / 1000; uint256[] public fees; address alice = vm.addr(123); function setUp() public { curve = new LinearBondingCurve(LINEAR_INCREASE); paymentToken = new MockERC20(); market = new Market("",address(paymentToken)); paymentToken.mint(alice, 100 ether); market.restrictShareCreation(false); market.changeBondingCurveAllowed(address(curve),true); } function testMintTokenCostFee() public { uint256 id = market.createNewShare("newShare",address(curve),"_metadataURI"); for(uint256 i = 1;i<1000;i++){ (,uint256 fee) = curve.getPriceAndFee(i,1); fees.push(fee); } for(uint256 i;i<fees.length;i++){ console2.logUint(fees[i]); } } }
The above code iterates 999 times, recording the actual amount of fees consumed for different share counts。 Then, we place the fee prices into a line chart. From the final results, it can be observed that the performance of the fee is not linear.
If above image not show up try this url: https://raw.githubusercontent.com/coffiasd/images/main/fees.png
function testMintTokenCostFee2() public { uint256 id = market.createNewShare("newShare",address(curve),"_metadataURI"); (,uint256 costFee1) = curve.getPriceAndFee(1,1); (,uint256 costFee2) = curve.getPriceAndFee(2,1); (,uint256 costFee3) = curve.getPriceAndFee(3,1); (,uint256 costFee4) = curve.getPriceAndFee(4,1); (,uint256 costFee5) = curve.getPriceAndFee(5,1); (,uint256 costFee6) = curve.getPriceAndFee(6,1); (,uint256 costFee7) = curve.getPriceAndFee(7,1); assert(costFee1 < costFee2 && costFee2 < costFee3); assert(costFee4 < costFee5 && costFee5 < costFee6); assert(costFee3 > costFee4); }
In the test code above, we can observe that costFee3 is greater than costFee4. This situation can result in scenarios where the gas fees for later token IDs are lower than those for earlier token IDs when calculating getNFTMintingPrice
.
this is output:
Running 1 test for test/Linear.t.sol:LinearTest [PASS] testMintTokenCostFee2() (gas: 143307) Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.40ms Ran 1 test suites: 1 tests passed, 0 failed, 0 skipped (1 total tests)
FOUNDRY,VSCODE
The adjustment should be made to the fee calculation so that the final cost aligns with linearity
Math
#0 - c4-pre-sort
2023-11-20T16:12:24Z
minhquanym marked the issue as sufficient quality report
#1 - OpenCoreCH
2023-11-27T12:03:23Z
Yes, the fee percentage decreases with more shares, resulting in this graph for the fees. This is intended.
#2 - c4-sponsor
2023-11-27T12:03:27Z
OpenCoreCH (sponsor) disputed
#3 - MarioPoneder
2023-11-29T14:29:01Z
I acknowledge the validity of those concerns. However, this is rather a design choice than a design flaw or a bug of the protocol per se, therefore QA seems appropriate.
#4 - c4-judge
2023-11-29T14:29:07Z
MarioPoneder changed the severity to QA (Quality Assurance)
#5 - c4-judge
2023-11-29T22:38:04Z
MarioPoneder marked the issue as grade-b