-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Truncating division in getPrice results in under-quoting the minting price in the last period of a linear descending sale #273
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-271
edited-by-warden
satisfactory
satisfies C4 submission criteria; eligible for awards
Comments
c4-submissions
added
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
labels
Nov 4, 2023
code4rena-admin
changed the title
Truncaing division in
Truncaing division in getPrice results in under-quoting the minting price in the last period of a linear descending sale
Nov 4, 2023
getPrice
results in under-quoting the minting price in the last period of a linear descending sale
code4rena-admin
changed the title
Truncaing division in getPrice results in under-quoting the minting price in the last period of a linear descending sale
Truncating division in getPrice results in under-quoting the minting price in the last period of a linear descending sale
Nov 4, 2023
141345 marked the issue as duplicate of #469 |
alex-ppg marked the issue as not a duplicate |
c4-judge
added
the
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
label
Dec 6, 2023
alex-ppg marked the issue as unsatisfactory: |
alex-ppg marked the issue as duplicate of #271 |
c4-judge
added
duplicate-271
satisfactory
satisfies C4 submission criteria; eligible for awards
and removed
unsatisfactory
does not satisfy C4 submission criteria; not eligible for awards
labels
Dec 6, 2023
alex-ppg marked the issue as satisfactory |
alex-ppg removed the grade |
c4-judge
added
satisfactory
satisfies C4 submission criteria; eligible for awards
and removed
satisfactory
satisfies C4 submission criteria; eligible for awards
labels
Dec 8, 2023
alex-ppg marked the issue as satisfactory |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
duplicate-271
edited-by-warden
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2023-10-nextgen/blob/main/smart-contracts/MinterContract.sol#L553-L557
Vulnerability details
Impact
For a Linear Descending Sale the price returned by
getPrice
in the last period where the price descends will incorrectly be the resting price.Description
MinterContract
allows collection creators to set a Sales Model for public mints usingsetCollectionCosts
combined withsetCollectionPhases
to define the timespan of the public sale. One of the available sales models is the Linear Descending Sale.Borrowing the example from the documentation, if we have a starting price of 4ETH, a resting (end) price of 3ETH and a descending rate of 0.1ETH per period, then the quote price must be:
In the code the Linear Descending Sale strategy is used by calling
MinterContract.setCollectionCosts
withsalesOption=2
, non-zero values for_collectionMintCost
,_collectionEndMintCost
,_rate
and_timePeriod
. The relevantgetPrice
logic is (see links for context):The price is decreased for every elapsed period
tDiff
until the resting price is reached.The vulnerability stems from the division in the
if
condition. TakecollectionMintCost=1 ether
,collectionEndMintCost=0.81 ether
andrate=0.1 ether
. Then the expression before the>
sign evaluates to(1e18 - 0.81e18) / 0.1e18 = 0.19e18 / 0.1e18 = 1
with the.9
truncated. This means that at period 1 (tDiff = 1
) theelse
branch will be hit, returning0.81 ether
as the price whereas the expected price according to the sales model is0.9 ether
.Proof of Concept
The following Foundry test demonstrates the bug. A linear descending price public sale is set up with
startPrice=1 ether
,endPrice=0.81 ether
,rate=0.1 ether
,period=1 minutes
. The test prints the return price fromgetPrice
for the first 3 periods. At the second period the actual price is0.81 ether
whereas the expect price according to the model is0.9 ether
.To run the PoC within the contest repo:
forge init
in the root directory of the contest repo.foundry.toml
configuration file with:test/IncorrectPricePoC.t.sol
and paste the contents of the PoC:forge test --mc IncorrectPricePoC -vvv
Tools Used
Manual Review, Foundry testing
Recommended Mitigation Steps
The root cause for the bug is the truncating division in the
if
clause as discussed above. A common practice to eliminate such issues is to introduce a precision factor when doing arithmetic that contains division.Introduce a precision factor of
1e27
by changingif
clause as such:Re-run the PoC and observe that the price is now calculated correctly:
It is prudent to use the scaling factor in all instances of division in the
getPrice
code.Assessed type
Math
The text was updated successfully, but these errors were encountered: