Platform: Code4rena
Start Date: 20/09/2022
Pot Size: $100,000 USDC
Total HM: 4
Participants: 109
Period: 7 days
Judge: GalloDaSballo
Id: 163
League: ETH
Rank: 31/109
Findings: 2
Award: $525.56
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: zzykxx
Also found by: 8olidity, IllIllI, Lambda, berndartmueller, bytehat, devtooligan, hansfriese, imare, obront, philogy, shung, tonisives, zdhu, zkhorse
https://github.com/code-423n4/2022-09-artgobblers/blob/d2087c5a8a6a4f1b9784520e7fe75afa3a9cbdbe/src/ArtGobblers.sol#L521 https://github.com/code-423n4/2022-09-artgobblers/blob/d2087c5a8a6a4f1b9784520e7fe75afa3a9cbdbe/src/ArtGobblers.sol#L562 https://github.com/code-423n4/2022-09-artgobblers/blob/d2087c5a8a6a4f1b9784520e7fe75afa3a9cbdbe/src/ArtGobblers.sol#L584
If the Chainlink VRF V1 is sunset before the randProvider
is updated, the protocol could get stuck in a permanent waitingForSeed
state, bricking the entire project.
In the code comments, randProvider
is commented with the following note:
/// a wrapper around Chainlink VRF v1, but can be changed in case it is fully sunset.
Similarly, the updateRandProvider
function has the following comment:
/// @notice Upgrade the rand provider contract. Useful if current VRF is sunset.
These comments point to the fact that the Art Gobblers team sees the possibility that the Chainlink VRF V1 oracle may be sunset, and would like to be prepared for such a situation.
However, in the event that this sunsetting happens before randProvider
is updated, the protocol will become irreversibly bricked.
requestRandomSeed()
will set waitingForSeed
to trueacceptRandomSeed()
to be called, but this call will not be returned from the deprecated oraclerequestRandomSeed()
again, because gobblerRevealsData.toBeRevealed
will still be greater than zerogobblerRevealsData.toBeRevealed
back to 0 is to call revealGobblers()
, which isn't allowed while waitingForSeed
is trueupgradeRandProvider()
also reverts on waitingForSeed
Thus, we are stuck in a loop where we are no longer allowed to request random seeds, are not able to accept random seeds, and therefore are not allowed to reveal any Gobblers.
Although this situation may be unlikely, the fact that the team is preparing for the possibility of Chainlink VRF V1 being sunset and that it could irreversibly take down the whole project leads me to a judge the severity as a high.
Manual Review
Turn waitingForSeed
into a timestamp and have the requirement expire after some period of time.
#0 - Shungy
2022-09-27T20:56:09Z
#1 - GalloDaSballo
2022-10-09T22:13:44Z
Dup of #153
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x4non, 0x52, 0x5rings, 0xNazgul, 0xRobocop, 0xSmartContract, 0xdeadbeef, 0xsanson, 8olidity, Amithuddar, Aymen0909, B2, B353N, CertoraInc, Ch_301, Chom, CodingNameKiki, Deivitto, ElKu, Funen, JC, JohnnyTime, Kresh, Lambda, Noah3o6, RaymondFam, ReyAdmirado, RockingMiles, Rolezn, Sm4rty, SuldaanBeegsi, Tadashi, TomJ, Tomio, V_B, Waze, __141345__, a12jmx, ak1, arcoun, asutorufos, aviggiano, berndartmueller, bharg4v, bin2chen, brgltd, bulej93, c3phas, catchup, cccz, ch0bu, cryptonue, cryptphi, csanuragjain, delfin454000, devtooligan, djxploit, durianSausage, eighty, erictee, exd0tpy, fatherOfBlocks, giovannidisiena, hansfriese, ignacio, joestakey, ladboy233, lukris02, m9800, malinariy, martin, minhtrng, obront, oyc_109, pedr02b2, pedroais, pfapostol, philogy, prasantgupta52, rbserver, ronnyx2017, rotcivegaf, rvierdiiev, sach1r0, shung, simon135, throttle, tnevler, tonisives, wagmi, yixxas, zkhorse, zzykxx, zzzitron
55.1985 USDC - $55.20
dhttps://github.com/code-423n4/2022-09-artgobblers/blob/d2087c5a8a6a4f1b9784520e7fe75afa3a9cbdbe/src/ArtGobblers.sol#L401 https://github.com/transmissions11/VRGDAs/blob/f4dec0611641e344339b2c78e5f733bba3b532e0/src/VRGDA.sol#L46-L50 https://github.com/transmissions11/VRGDAs/blob/f4dec0611641e344339b2c78e5f733bba3b532e0/src/LogisticVRGDA.sol#L62
In a situation where the demand pressure on the Gobblers gets too strong (366 days ahead), the auction will not behave as expected (continuously scaling up price to bring down demand), but will instead revert.
The price of a Gobbler is calculated by calling getVRGDAPrice()
with days since start and the total number minted from goo as the arguments. The VRGDA library implements the following calculation:
uint256( wadMul( targetPrice, wadExp( unsafeWadMul( decayConstant, timeSinceStart - getTargetSaleTime(toWadUnsafe(sold + 1)) ) ) ) );
Let's focus in on the situation where the target sale time is at least 366 days in the future.
timeSinceStart - getTargetSaleTime()
will equal -366
.ln(1e18 - 0.31e18) = -371063681390831986
, their product will be 1.358e20
wadExp
, it will revert on the check for if (x >= 135305999368893231589) revert("EXP_OVERFLOW");
The result is that the auction will revert, and sales will not be allowed until the price falls back within a 1 year range.
This is unlikely to be a problem early on in the auction, as there are thousands of Gobblers for sale per year. But towards the later years, this number falls all the way down to the single digits per year, so it is highly possible that high demand pushes the bid up enough to cause this error.
This undercuts the supposed mechanism of VRGDA, as the auction will not be able to scale up with demand and instead will turn the the buying process into a competition to be the first to get in when it falls back within range.
Manual Review, Foundry
Fork SignedWadMath.sol
and adjust it to allow for higher values, or make the necessary adjustments to store the price decay constant with fewer decimal places.
#0 - Shungy
2022-09-27T22:03:24Z
This will never happen. We will never even get close to being 200 days ahead of schedule.
What is the price when we are 355 days ahead of schedule? Let's plug into the formula;
(e^(355×371063681390831986/10^18))×69.42
.
The result is 112216675329256267686296343944342310800000000000000000000000
. This is without decimals, not yet multiplied with 10^18
. That is 112 octodecillion
(yes, I looked it up). Unless there exists a finding that can prove that the Goo supply can reach octodecillions, these findings about VRGDA price revert are invalid.
#1 - GalloDaSballo
2022-10-11T00:56:21Z
I think per the comment above, and the discussion in the duplicates, there are ways to make the price rise above any reasonably expected threshold, and even cause a revert.
However, this is "intended" behaviour, in the sense that such hot demand will cause the formula to compute crazy high numbers.
I think the observation that we will get reverts is correct, and that may cause subpar UX, for that reason I think Informational is a more appropriate severity.
TL;DR There are values that make the contract revert ungracefully, a try catch would help with that
NC