-
Notifications
You must be signed in to change notification settings - Fork 0
Jovial Teal Butterfly - Bidding could become very expensive for bidders, if all auctions for previous periods have been failed. #1043
Description
Jovial Teal Butterfly
Medium
Bidding could become very expensive for bidders, if all auctions for previous periods have been failed.
Summary
A period can only have 1 auction, which can either be succesful or failed, if the auction for currentPeriod P1
fails, governance will stepin, and increase the sharesPerToken value by twice for next period's P2
auction. It means couponToken required to collect from auction will also increase 2 times indicated as @
in below code. It means bidders will have to bid with higher amount of USDC, as compared to previous period auction.
function startAuction() external whenNotPaused() {
// Check if distribution period has passed
require(lastDistribution + distributionPeriod < block.timestamp, DistributionPeriodNotPassed());
// Check if auction period hasn't passed
require(lastDistribution + distributionPeriod + auctionPeriod >= block.timestamp, AuctionPeriodPassed());
// Check if auction for current period has already started
(uint256 currentPeriod,) = bondToken.globalPool();
require(auctions[currentPeriod] == address(0), AuctionAlreadyStarted());
uint8 bondDecimals = bondToken.decimals();
uint8 sharesDecimals = bondToken.SHARES_DECIMALS();
uint8 maxDecimals = bondDecimals > sharesDecimals ? bondDecimals : sharesDecimals;
uint256 normalizedTotalSupply = bondToken.totalSupply().normalizeAmount(bondDecimals, maxDecimals);
uint256 normalizedShares = sharesPerToken.normalizeAmount(sharesDecimals, maxDecimals);
// Calculate the coupon amount to distribute
@-> uint256 couponAmountToDistribute = (normalizedTotalSupply * normalizedShares)
.toBaseUnit(maxDecimals * 2 - IERC20(couponToken).safeDecimals());
auctions[currentPeriod] = Utils.deploy(
address(new Auction()),
abi.encodeWithSelector(
Auction.initialize.selector,
address(couponToken),
address(reserveToken),
couponAmountToDistribute,
block.timestamp + auctionPeriod,
1000,
address(this),
poolSaleLimit
)
);
// Increase the bond token period
bondToken.increaseIndexedAssetPeriod(sharesPerToken);
// Update last distribution time
lastDistribution = block.timestamp;
}
The reserve token is collected when a user redeems his BONDeth or levETH in pool contract. Now for period P2
there will be requiremnt of reserveTokens twice as that in previous period, because bidders will be bidding twice the amount required in previous bid.
The incentive for users to redeem their derivatives in pool is if reservToken is cheaper based on market situation, but if the market situation remains same for both P1
and P2
, then there could be possibility the reserveTokens collected in pool is not enough.
Also for every auction the maximum number of bids is fixed to 100
, which may favour the rich users if the above situation arises, because as the auction fails the next auction becomes 2 times more expensive as compared to previous one.
Root Cause
No functionality to increase number of bidders, for next auction in case of auction failure.
Internal Pre-conditions
External Pre-conditions
Attack Path
Impact
- Auction will become more and more expensive as there is limited number of bidders.
- First point is being ampilified with the fact, if market condition not fluctucates form
P1
toP2
then there will less reseveTokens in the pool, but the bid amount or coupon token amount or USDC requirement in has been increased twice.
PoC
Mitigation
- Implement the functionlity to increase number of bidders in case of auction failure.
- Implement functionality to incentivise the users to redeem more in case of auction filure.