Skip to content

Commit

Permalink
fix: backported from #2159
Browse files Browse the repository at this point in the history
  • Loading branch information
erights committed Jan 2, 2021
1 parent 86212df commit e1d3664
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 29 deletions.
10 changes: 8 additions & 2 deletions packages/ERTP/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
*/

/**
* @typedef {Ground} Amount
* TODO Want to say typedef {Object & Ground} Amount, but then Amount seems to
* be typed as "any"
*
* @typedef {Object} Amount
* Amounts are descriptions of digital assets, answering the questions
* "how much" and "of what kind". Amounts are values labeled with a brand.
* AmountMath executes the logic of how amounts are changed when digital
Expand All @@ -37,7 +40,10 @@
*/

/**
* @typedef {Amount & Pattern} AmountPattern
* TODO Want to say typedef {Object & Pattern} AmountPattern, but then
* AmountPattern seems to be typed as "any"
*
* @typedef {Object} AmountPattern
* TODO explain
*
* @property {Brand} brand
Expand Down
112 changes: 96 additions & 16 deletions packages/zoe/src/contractSupport/zoeHelpers.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// @ts-check
import '../../exported';

import { assert, details } from '@agoric/assert';
import { sameStructure } from '@agoric/same-structure';
import { assert, details, quote as q } from '@agoric/assert';
import { sameStructure, isGround } from '@agoric/same-structure';
import { E } from '@agoric/eventual-send';
import { makePromiseKit } from '@agoric/promise-kit';

Expand All @@ -15,6 +15,12 @@ export const defaultAcceptanceMsg = `The offer has been accepted. Once the contr
const getKeysSorted = obj =>
harden(Object.getOwnPropertyNames(obj || {}).sort());

/**
* @typedef FromToAllocations
* @property {Allocation} from
* @property {Allocation} to
*/

/**
* Given toGains (an AmountKeywordRecord), and allocations (a pair,
* 'to' and 'from', of Allocations), all the entries in
Expand All @@ -32,10 +38,6 @@ const getKeysSorted = obj =>
* toGains. Note that the total amounts should always be equal; it
* is the keywords that might be different.
* @returns {FromToAllocations} allocations - new allocations
*
* @typedef FromToAllocations
* @property {Allocation} from
* @property {Allocation} to
*/
const calcNewAllocations = (
zcf,
Expand Down Expand Up @@ -152,11 +154,12 @@ export const trade = (
left.losses,
));
} catch (err) {
const newErr = new Error(
`The trade between left ${left} and right ${right} failed.`,
// TODO consider revising once we can use assert.error
throw assert.fail(
details`The trade between left ${q(left)} and right ${q(
right,
)} failed due to ${err}.`,
);
assert.note(newErr, details`due to ${err}`);
throw newErr;
}

// Check whether reallocate would error before calling. If
Expand All @@ -178,8 +181,10 @@ export const trade = (
if (!offerSafeForRight) {
console.log(`offer not safe for right`);
}
throw new Error(
`The trade between left ${left} and right ${right} failed offer safety. Please check the log for more information`,
assert.fail(
details`The trade between left ${q(left)} and right ${q(
right,
)} failed offer safety. Please check the log for more information`,
);
}

Expand All @@ -195,6 +200,57 @@ export const trade = (
}
};

/**
* @param {ContractFacet} zcf
* @param {ZCFSeat} fromSeat
* @param {ZCFSeat} toSeat
* @param {string} fromHasExitedMsg
* @param {string} toHasExitedMsg
* @returns {AmountKeywordRecord}
*/
const findFromOtherSeat = (
zcf,
fromSeat,
toSeat,
fromHasExitedMsg,
toHasExitedMsg,
) => {
assert(!fromSeat.hasExited(), fromHasExitedMsg);
assert(!toSeat.hasExited(), toHasExitedMsg);
/** @type {AmountPatternKeywordRecord} */
const amountPatternKeywordRecord = toSeat.getProposal().want;
/** @type {AmountKeywordRecord} */
const fromSeatAmountKeywordRecord = fromSeat.getCurrentAllocation();

/**
* @param {[Keyword, AmountPattern]} pair
* @returns {[Keyword, Amount]}
*/
const findAmountPair = pair => {
const [keyword, amountPattern] = pair;
const fromSeatAmount = fromSeatAmountKeywordRecord[keyword];
if (fromSeatAmount === undefined) {
assert(
isGround(amountPattern),
details`Unmatched wants must be ground ${amountPattern}`,
);
// A ground AmountPattern is a valid Amount
return [keyword, amountPattern];
}
const amountMath = zcf.getAmountMath(amountPattern.brand);
const split = amountMath.frugalSplit(amountPattern, fromSeatAmount);
// If we are trying to transfer an amount but can't find what
// should be transferred, we should throw
assert(
split !== undefined,
details`The trade between fromSeat ${fromSeat} and toSeat ${toSeat} failed because ${amountPattern} was not found.`,
);
return [keyword, split.matched];
};

return objectMap(amountPatternKeywordRecord, findAmountPair);
};

/** @type {Swap} */
export const swap = (
zcf,
Expand All @@ -208,11 +264,23 @@ export const swap = (
zcf,
{
seat: leftSeat,
gains: leftSeat.getProposal().want, // TODO
gains: findFromOtherSeat(
zcf,
rightSeat,
leftSeat,
rightHasExitedMsg,
leftHasExitedMsg,
),
},
{
seat: rightSeat,
gains: rightSeat.getProposal().want, // TODO
gains: findFromOtherSeat(
zcf,
leftSeat,
rightSeat,
leftHasExitedMsg,
rightHasExitedMsg,
),
},
leftHasExitedMsg,
rightHasExitedMsg,
Expand Down Expand Up @@ -247,12 +315,24 @@ export const swapExact = (
zcf,
{
seat: leftSeat,
gains: leftSeat.getProposal().want, // TODO
gains: findFromOtherSeat(
zcf,
rightSeat,
leftSeat,
rightHasExitedMsg,
leftHasExitedMsg,
),
losses: leftSeat.getProposal().give,
},
{
seat: rightSeat,
gains: rightSeat.getProposal().want, // TODO
gains: findFromOtherSeat(
zcf,
leftSeat,
rightSeat,
leftHasExitedMsg,
rightHasExitedMsg,
),
losses: rightSeat.getProposal().give,
},
leftHasExitedMsg,
Expand Down
2 changes: 1 addition & 1 deletion packages/zoe/src/objArrayConversion.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const assertSubset = (whole, part) => {

/**
* @template T, U
* @template {keyof T} K
* @template {string} K
* @param {Record<K, T>} original
* @param {(pair: [K, T]) => [K, U]} mapPairFn
* @returns {Record<K, U>}
Expand Down
3 changes: 1 addition & 2 deletions packages/zoe/test/unitTests/contractSupport/test-offerTo.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ test(`offerTo - violates offer safety of fromSeat`, async t => {
toSeatContractA,
),
{
message:
'The trade between left [object Object] and right [object Object] failed offer safety. Please check the log for more information',
message: /The trade between left .* and right .* failed offer safety. Please check the log for more information/,
},
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ test(`withdrawFromSeat - violates offerSafety`, async t => {
await t.throwsAsync(
withdrawFromSeat(zcf, zcfSeat, { B: bucks(4) }),
{
message:
'The trade between left [object Object] and right [object Object] failed offer safety. Please check the log for more information',
message: /The trade between left .* and right .* failed offer safety. Please check the log for more information/,
},
`withdrawFrom can't violate offerSafety`,
);
Expand Down
4 changes: 2 additions & 2 deletions packages/zoe/test/unitTests/contracts/test-coveredCall.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,8 @@ test('zoe - coveredCall with swap for invitation', async t => {
// TODO BUG The commented out line with optionAmountPattern is the
// one we want, but atomicSwap calls swap with the want pattern
// as the gains, which are assumed to be amounts, not amount patterns.
// want: { Asset: optionAmountPattern },
want: { Asset: optionAmount },
want: { Asset: optionAmountPattern },
// want: { Asset: optionAmount },
give: { Price: bucks(1) },
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1193,8 +1193,7 @@ test('multipoolAutoSwap jig - removeLiquidity ask for too much', async t => {
payment,
);
await t.throwsAsync(() => seat.getOfferResult(), {
message:
'The trade between left [object Object] and right [object Object] failed offer safety. Please check the log for more information',
message: /The trade between left .* and right .* failed offer safety. Please check the log for more information/,
});
});

Expand Down
3 changes: 1 addition & 2 deletions packages/zoe/test/unitTests/zcf/test-zoeHelpersWZcf.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ test(`zoeHelper with zcf - swap no match`, async t => {
t.throws(
() => swap(zcf, aZcfSeat, bZcfSeat),
{
message:
'The trade between left [object Object] and right [object Object] failed.',
message: /The trade between fromSeat .* and toSeat .* failed because .* was not found/,
},
'mismatched offers',
);
Expand Down

0 comments on commit e1d3664

Please sign in to comment.