-
Notifications
You must be signed in to change notification settings - Fork 222
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
Design flaw in Zoe: stateful seats and staged allocations #3850
Labels
bug
Something isn't working
Epic
vaults_triage
DO NOT USE
z~audit-zestival
Vulnerability assessment of ERTP + Zoe
Zoe
package: Zoe
Milestone
Comments
This was referenced Jan 20, 2022
Closed
This was referenced Jan 20, 2022
@erights Is this done? The three issues mentioned in the body are all done. And if it is not done, is it really an Epic? If so, please add the dependent issues. |
As noted in #6679, the Zoe design flaw is not yet fixed. |
We just discovered a fourth bug of high severity: |
This was referenced Feb 17, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
bug
Something isn't working
Epic
vaults_triage
DO NOT USE
z~audit-zestival
Vulnerability assessment of ERTP + Zoe
Zoe
package: Zoe
This is an over-arching issue to capture the architectural design flaw introduced in #3184. #3184 made significant usability and readability gains, at least on the surface, but has since resulted in at least 3 bugs of high severity.
Importantly, until this design flaw is corrected, we can expect more bugs involving staged allocations.
Design prior to #3184
The earlier design created
seatStagings
- objects which represented a particular staged allocation on a seat.zcf.reallocate
acted onseatStagings
, notseats
. This meant that multipleseatStagings
could be reallocated independently of each other, even for the same seat. Moreover,seatStagings
could be dropped without introducing bugs within Zoe, even though this pattern is not encouraged.Here's an example of usage in multipoolAutoswap:
Design after #3184
What is currently on master for
multipoolAutoswap
is a lot clearer:The code can easily be audited for rights conservation violations, whereas the previous design could not be. For example, see this analysis of multipoolAutoswap where a rights conservation bug was found only after deep inspection.
On the surface, this code seemed a lot more auditable, but under the surface, problems were introduced. Being able to audit for rights conservation violations at the contract level is great, but only helps if bugs aren't introduced in Zoe.
We had at least three bugs introduced in Zoe as a result of this change:
zcfMint.mintGains
wrongly errors if any seats have staged allocations #3613 (fixed)#3613 resulted from an interaction of
zcfMint
withstagedAllocations
.zcfMint.mintGains
callsreallocateInternal
after incrementing thezcfSeat
with the assets to mint.zcf.reallocate
also callsreallocateInternal
after doing some work. Thinking mostly of thezcf.reallocate
usage ofreallocateInternal
, we had required that all seats with staged allocations should be included inreallocateInternal
. This was intended as a safety measure to ensure that contract code does not unintentionally forget about any seats and their staged allocations. This caused a problem forzcfMint.mintGains
, where the common usage is in the middle of preparing staged allocations, prior to the reallocation that would use them.mintGains
was erroring if there were any prior outstanding staged allocations, but this was incorrect behavior because having outstanding staged allocations is common. The "quick fix" was to move this check intoreallocate
only, such that themintGains
path never performed the check.#3800 was the result of an expected, user-caused error in the AMM (MultipoolAutoswap) causing unexpected state. The readability and usability of the new design #3184 depended entirely on the staged allocations being cleared before an offerHandler was called. In other words, the offerHandlers were written as if the seats involved had no previous staged allocations. This expectation was violated when an offer handler errored because the offer was not one that the contract wanted to accept, and this error left stagedAllocations in place for future offers. A potential solution would be to clear all staged allocations on errors, but more thought is required on exactly when this clearing should occur. This issue is still open, requiring more design. The design prior to #3184 would have not had this problem, because prior seatStagings would simply be dropped, and no state regarding staged allocations would continue to stay around after an error.
#3848, the latest bug, is the result of
mintGains
being able to perform a reallocate for one seat without rights conservation being checked. Before the new design in #3184, this made sense because only the seatStaging that was involved inmintGains
would be reallocated against, and minting doesn't conserve rights anyways. Any other seatStagings, even for the same seat, would be unaffected. However, with the new design, the mintGains is adding to a stagedAllocation that may already exist. This means that staged allocations that would violate rights conservation can slip in and become the canonical allocation. Offer safety holds for this particular transaction, but because rights conservation is violated, the offer safety in other offers is violated. Even though "offer safety" might be true in terms of allocations, if rights are not conserved, someone will not be able to get a payout that matches their allocation.The text was updated successfully, but these errors were encountered: