The claimTokens()
function in the FjordAuction
contract suffers from precision loss due to integer division, potentially resulting in small bidders receiving zero tokens despite their participation in the auction.
The FjordAuction
contract implements a token auction system where users can bid using FjordPoints
and later claim auction tokens proportional to their bids. The token distribution mechanism is implemented in two steps:
In the auctionEnd()
function, a multiplier
is calculated:
In the claimTokens()
function, the claimable amount for each user is calculated:
The issue arises from the order of operations and the use of integer division in these calculations. When userBids
is small relative to totalBids
, the multiplication with multiplier
might not be large enough to overcome the subsequent division by PRECISION_18
, resulting in claimable
being rounded down to zero.
This precision loss is particularly problematic for small bidders, who may end up receiving no tokens despite their participation in the auction. The problem is exacerbated when there's a large disparity between the smallest and largest bids.
Small bidders may receive zero tokens, effectively being excluded from the token distribution despite their participation. This unfair distribution undermines the integrity of the auction process and may discourage participation from smaller players in future auctions.
Moreover, the cumulative effect of this precision loss could result in a significant portion of the totalTokens
remaining undistributed and potentially stuck in the contract.
Consider the following scenario:
The auction is set up with totalTokens
= 1,000,000 and PRECISION_18
= 1e18
After the bidding period, totalBids
= 1,000,000,000
Alice, a small bidder, participates with userBids
= 999
When Alice calls claimTokens()
, the calculations proceed as follows:
multiplier
= (1,000,000 * 1e18) / 1,000,000,000 = 1e12
claimable
= (999 * 1e12) / 1e18 = 0.999 ≈ 0 (due to integer division)
As a result, Alice receives 0 tokens despite bidding 999 FjordPoints.
Manual review
To address this issue, the order of operations in the claimTokens()
function should be changed to minimize precision loss. Instead of using the pre-calculated multiplier
, the function should directly calculate the proportion of totalTokens
based on the user's bid:
This change ensures that every bidder, regardless of the size of their bid, receives a fair proportion of tokens based on their contribution to the total bids. While there may still be some dust due to integer division, this approach significantly reduces the likelihood of small bidders receiving zero tokens.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.