Skip to content

Commit

Permalink
refactor: make satisfiesWant/satisfiesGive compatible with Multiples
Browse files Browse the repository at this point in the history
They need to return 0 or 1, so they can return a count with Multiples.

Added tests for satisfiesWant, since it's exported.
  • Loading branch information
Chris-Hibbert committed Aug 8, 2022
1 parent 3f06af2 commit 2c876c3
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 10 deletions.
16 changes: 12 additions & 4 deletions packages/zoe/src/contractFacet/offerSafety.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@ import { AmountMath } from '@agoric/ertp';
* allocationAmount greater than or equal to requiredAmount for every
* keyword of giveOrWant?
*
* To prepare for multiples, satisfiesWant and satisfiesGive return 0 or 1.
* isOfferSafe will still be boolean. When we have Multiples, satisfiesWant and
* satisfiesGive will tell how many times the offer was matched.
*
* @param {AmountKeywordRecord} giveOrWant
* @param {AmountKeywordRecord} allocation
* @returns {0|1}
*/
const satisfiesInternal = (giveOrWant = {}, allocation) => {
const isGTEByKeyword = ([keyword, requiredAmount]) => {
// If there is no allocation for a keyword, we know the giveOrWant
// is not satisfied without checking further.
if (allocation[keyword] === undefined) {
return false;
return 0;
}
const allocationAmount = allocation[keyword];
return AmountMath.isGTE(allocationAmount, requiredAmount);
return AmountMath.isGTE(allocationAmount, requiredAmount) ? 1 : 0;
};
return Object.entries(giveOrWant).every(isGTEByKeyword);
return Object.entries(giveOrWant).every(isGTEByKeyword) ? 1 : 0;
};

/**
Expand Down Expand Up @@ -77,8 +82,11 @@ const satisfiesGive = (proposal, allocation) =>
*/
function isOfferSafe(proposal, allocation) {
return (
satisfiesGive(proposal, allocation) || satisfiesWant(proposal, allocation)
satisfiesGive(proposal, allocation) > 0 ||
satisfiesWant(proposal, allocation) > 0
);
}

harden(isOfferSafe);
harden(satisfiesWant);
export { isOfferSafe, satisfiesWant };
6 changes: 4 additions & 2 deletions packages/zoe/src/contractSupport/zoeHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ export const assertIssuerKeywords = (zcf, expected) => {
* check; whether the allocation constitutes a refund is not
* checked. The update is merged with currentAllocation
* (update's values prevailing if the keywords are the same)
* to produce the newAllocation.
* to produce the newAllocation. The return value is 0 for
* false and 1 for true. When multiples are introduced, any
* positive return value will mean true.
*
* @param {ZCF} zcf
* @param {ZcfSeatPartial} seat
* @param {AmountKeywordRecord} update
* @returns {boolean}
* @returns {0|1}
*/
export const satisfies = (zcf, seat, update) => {
const currentAllocation = seat.getCurrentAllocation();
Expand Down
1 change: 1 addition & 0 deletions packages/zoe/src/zoeService/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
* @property {() => Promise<OR>} getOfferResult
* @property {() => void=} tryExit
* @property {() => Promise<boolean>} hasExited
* @property {() => Promise<0|1>} wasWantSatisfied
*
* @property {() => Promise<Allocation>} getCurrentAllocationJig
* Labelled "Jig" because it *should* only be used for tests, though
Expand Down
15 changes: 14 additions & 1 deletion packages/zoe/test/unitTests/test-offerSafety.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import { isOfferSafe } from '../../src/contractFacet/offerSafety.js';
import {
isOfferSafe,
satisfiesWant,
} from '../../src/contractFacet/offerSafety.js';
import { setup } from './setupBasicMints.js';

// Potential outcomes:
Expand Down Expand Up @@ -34,6 +37,7 @@ test('isOfferSafe - more than want, more than give', t => {
const amounts = harden({ A: moola(10n), B: simoleans(7n), C: bucks(8n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 1);
});

// more than want, less than give -> true
Expand All @@ -47,6 +51,7 @@ test('isOfferSafe - more than want, less than give', t => {
const amounts = harden({ A: moola(1n), B: simoleans(7n), C: bucks(8n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 1);
});

// more than want, equal to give -> true
Expand All @@ -60,6 +65,7 @@ test('isOfferSafe - more than want, equal to give', t => {
const amounts = harden({ A: moola(9n), B: simoleans(6n), C: bucks(7n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 1);
});

// less than want, more than give -> true
Expand All @@ -73,6 +79,7 @@ test('isOfferSafe - less than want, more than give', t => {
const amounts = harden({ A: moola(7n), B: simoleans(9n), C: bucks(19n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 0);
});

// less than want, less than give -> false
Expand All @@ -86,6 +93,7 @@ test('isOfferSafe - less than want, less than give', t => {
const amounts = harden({ A: moola(7n), B: simoleans(5n), C: bucks(6n) });

t.falsy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 0);
});

// less than want, equal to give -> true
Expand All @@ -99,6 +107,7 @@ test('isOfferSafe - less than want, equal to give', t => {
const amounts = harden({ A: moola(1n), B: simoleans(5n), C: bucks(7n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 0);
});

// equal to want, more than give -> true
Expand All @@ -112,6 +121,7 @@ test('isOfferSafe - equal to want, more than give', t => {
const amounts = harden({ A: moola(2n), B: simoleans(6n), C: bucks(8n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 1);
});

// equal to want, less than give -> true
Expand All @@ -125,6 +135,7 @@ test('isOfferSafe - equal to want, less than give', t => {
const amounts = harden({ A: moola(0n), B: simoleans(6n), C: bucks(0n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 1);
});

// equal to want, equal to give -> true
Expand All @@ -138,6 +149,7 @@ test('isOfferSafe - equal to want, equal to give', t => {
const amounts = harden({ A: moola(1n), B: simoleans(6n), C: bucks(7n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 1);
});

test('isOfferSafe - empty proposal', t => {
Expand All @@ -146,4 +158,5 @@ test('isOfferSafe - empty proposal', t => {
const amounts = harden({ A: moola(1n), B: simoleans(6n), C: bucks(7n) });

t.truthy(isOfferSafe(proposal, amounts));
t.is(satisfiesWant(proposal, amounts), 1);
});
6 changes: 3 additions & 3 deletions packages/zoe/test/unitTests/zcf/test-zcf.js
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,7 @@ test('wasWantSatisfied: no', async t => {
);

await zcfSeat.exit();
t.false(await E(userSeat).wasWantSatisfied());
t.is(await E(userSeat).wasWantSatisfied(), 0);
});

test('wasWantSatisfied: yes', async t => {
Expand All @@ -1460,7 +1460,7 @@ test('wasWantSatisfied: yes', async t => {
doubloonMint.mintGains(harden({ Bonus: doubloonAmount }), zcfSeat);

await zcfSeat.exit();
t.true(await E(userSeat).wasWantSatisfied());
t.is(await E(userSeat).wasWantSatisfied(), 1);
});

test('wasWantSatisfied as promise', async t => {
Expand All @@ -1479,7 +1479,7 @@ test('wasWantSatisfied as promise', async t => {
);

const outcome = E.when(E(userSeat).wasWantSatisfied(), result =>
t.true(result),
t.is(result, 1),
);
doubloonMint.mintGains(harden({ Bonus: doubloonAmount }), zcfSeat);

Expand Down

0 comments on commit 2c876c3

Please sign in to comment.