Skip to content
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

fix: filter proposal give and want by sparseKeywords in zcf.reallocate #1076

Merged
merged 2 commits into from
May 9, 2020

Conversation

katelynsills
Copy link
Contributor

@katelynsills katelynsills commented May 8, 2020

This PR fixes a bug (#1075) in zcf.reallocate in which we were filtering and filling the current allocation by sparseKeywords and asserting that the newAllocation is filled for sparseKeywords but we were not filtering the proposal.want or proposal.give, leading to valid partial reallocations being rejected for not meeting offer safety. See issue for more details.

Adds two tests. One test ensures that an allocation of something that is not specified in the proposal is offer safe. Another test ensures that the mintPayments.js contract works even if the user has proposal.want and proposal.give using different keywords. The user gets a refund and the newly minted assets.

Edit (5/8/2020, 4:55pm): Updated information about how we handle sparse keywords for the current allocation and the newAllocation. We do not fill the newAllocation, we only assert that all the sparseKeywords exist.

Closes #1075

Copy link
Member

@erights erights left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have the bug I think we do, I don't understand why this seems to work at all.

At

const refundOk = Object.entries(proposal.give).every(isGTEByKeyword);
you check offer safety by enumerating [keyword, amount] pairs of proposal.give, checking that the new allocation isGTE the allocation proposed to give. However, with this PR the new allocation may omit a keyword, in which case
newAmountKeywordRecord[keyword],

will be undefined.

Likewise for proposal.want. Once I understand what's going on here, I'll take a good look at rightsConservation.js.

@Chris-Hibbert
Copy link
Contributor

Chris-Hibbert commented May 8, 2020

with this PR the new allocation may omit a keyword

I think offer safety is only supposed to check that want and give are satisfied. There is a separate check that currency is conserved. Anything outside those limits is up to the contract. The point of this bug fix is that if the contract decides to provide something that's not specified by anyone's proposals, it can add it and move it around as much as is useful without any offer having anything to say about it.

Copy link
Member

@erights erights left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@katelynsills clarified. the newAllocations must still be as populated as before, so the danger I worried about is invalid.

LGTM

@erights
Copy link
Member

erights commented May 8, 2020

@Chris-Hibbert I misunderstood the PR as allowing more keyword positions to be absent, such as in the newAllocations. @katelynsills explained and we verified that the only new absences allowed are in the proposals. So my concern was invalid.

@katelynsills
Copy link
Contributor Author

Added an edit clarifying what happens with the current allocation and the newAllocation within reallocate.

@katelynsills katelynsills merged commit fb36a40 into master May 9, 2020
@katelynsills katelynsills deleted the 1075-filter-proposal-keywords branch May 9, 2020 00:00
Chris-Hibbert added a commit that referenced this pull request May 15, 2020
The bug was introduced in "filter proposal give and want by sparseKeywords"
#1076.
It allows a grifter contract (demonstrated here) to slip assets away
from a victim one keyword at a time. The victim is left with neither
their give or their want.

The solution in facets is to reinstate the insistance that offer
safety be checked against all keywords. We provide the feature
that #1076 was aiming for by allowing reallocations that don't impact
keywords in an offer's proposal.
Chris-Hibbert added a commit that referenced this pull request May 15, 2020
The bug was introduced in "filter proposal give and want by sparseKeywords"
#1076.
It allows a grifter contract (demonstrated here) to slip assets away
from a victim one keyword at a time. The victim is left with neither
their give or their want.

The solution in facets is to reinstate the insistance that offer
safety be checked against all keywords. We provide the feature
that #1076 was aiming for by allowing reallocations that don't impact
keywords in an offer's proposal.
katelynsills pushed a commit that referenced this pull request May 15, 2020
The bug was introduced in "filter proposal give and want by sparseKeywords"
#1076.
It allows a grifter contract (demonstrated here) to slip assets away
from a victim one keyword at a time. The victim is left with neither
their give or their want.

The solution in facets is to reinstate the insistance that offer
safety be checked against all keywords. We provide the feature
that #1076 was aiming for by allowing reallocations that don't impact
keywords in an offer's proposal.
katelynsills added a commit that referenced this pull request May 15, 2020
* test: demonstrate an attack by a zoe contract to be fixed in facets

The bug was introduced in "filter proposal give and want by sparseKeywords"
#1076.
It allows a grifter contract (demonstrated here) to slip assets away
from a victim one keyword at a time. The victim is left with neither
their give or their want.

The solution in facets is to reinstate the insistance that offer
safety be checked against all keywords. We provide the feature
that #1076 was aiming for by allowing reallocations that don't impact
keywords in an offer's proposal.

* fix: Fix the Zoe offer-safety bug demonstrated by the grifter attack

The fix is to insist that all offers retain offer safety across all
keywords. The desired ability to rearrange values outside of the
offer's keywords can be satisfied by explicitly allowing
rearrangements that don't impact any of the proposal's keywords.

This commit includes the bug fix but not a test that demonstrates the
vulnerability.

* test: correct the test to pass now that the bug is fixed.

* fix: run offer safety check over the entire new allocation, not just the sparse keywords version.

Co-authored-by: Kate Sills <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Zoe package: Zoe
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Zoe] Reallocate only for Keyword not in user's give or want
3 participants