Skip to content

Commit

Permalink
fix: multipoolAutoswap should throw seat.fail() when it can't comply
Browse files Browse the repository at this point in the history
closes: #2335
fixes: #2336
  • Loading branch information
Chris-Hibbert committed Feb 5, 2021
1 parent 9eebbe3 commit 19e8b70
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/zoe/src/contracts/loan/liquidate.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const doLiquidation = async (
lenderSeat.fail(err);
collateralSeat.fail(err);
zcf.shutdownWithFailure(err);
throw err;
};

const offerResultP = E(autoswapUserSeat).getOfferResult();
Expand Down
4 changes: 2 additions & 2 deletions packages/zoe/src/contracts/multipoolAutoswap/swap.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ export const makeMakeSwapInvitation = (

const brandInAmountMath = getPool(brandIn).getAmountMath();
if (!brandInAmountMath.isGTE(offeredAmountIn, amountIn)) {
seat.fail();
return `offeredAmountIn ${offeredAmountIn} is insufficient to buy amountOut ${amountOut}`;
const reason = `offeredAmountIn ${offeredAmountIn} is insufficient to buy amountOut ${amountOut}`;
throw seat.fail(Error(reason));
}

trade(
Expand Down
5 changes: 4 additions & 1 deletion packages/zoe/test/unitTests/contracts/loan/test-liquidate.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ test('test with malfunctioning autoswap', async t => {
makeSwapInInvitation: () => zcf.makeInvitation(swapHandler, 'swap'),
});

await doLiquidation(zcf, collateralSeat, autoswapPublicFacetP, lenderSeat);
await t.throwsAsync(
() => doLiquidation(zcf, collateralSeat, autoswapPublicFacetP, lenderSeat),
{ message: 'Pool not initialized' },
);

// Ensure collateralSeat exited
t.truthy(collateralSeat.hasExited());
Expand Down
95 changes: 95 additions & 0 deletions packages/zoe/test/unitTests/contracts/test-multipoolAutoswap.js
Original file line number Diff line number Diff line change
Expand Up @@ -1655,3 +1655,98 @@ test('multipoolAutoSwap jig - remove all liquidity', async t => {
);
moolaPoolState = updatePoolState(moolaPoolState, liqExpected);
});

test('multipoolAutoSwap jig - insufficient', async t => {
const { moolaR, moola } = setup();
const zoe = makeZoe(fakeVatAdmin);

// Pack the contract.
const bundle = await bundleSource(multipoolAutoswapRoot);
const installation = await zoe.install(bundle);

// Set up central token
const centralR = makeIssuerKit('central');
const centralTokens = centralR.amountMath.make;

// set up purses
const centralPayment = centralR.mint.mintPayment(centralTokens(30000));
const centralPurse = centralR.issuer.makeEmptyPurse();
await centralPurse.deposit(centralPayment);
const moolaPurse = moolaR.issuer.makeEmptyPurse();
moolaPurse.deposit(moolaR.mint.mintPayment(moola(20000)));

const startRecord = await zoe.startInstance(
installation,
harden({ Central: centralR.issuer }),
);
/** @type {MultipoolAutoswapPublicFacet} */
const { publicFacet } = startRecord;
const moolaLiquidityIssuer = await E(publicFacet).addPool(
moolaR.issuer,
'Moola',
);
const moolaLiquidityAmountMath = await makeLocalAmountMath(
moolaLiquidityIssuer,
);

const moolaLiquidity = moolaLiquidityAmountMath.make;
const mIssuerKeywordRecord = {
Secondary: moolaR.issuer,
Liquidity: moolaLiquidityIssuer,
};
const purses = [
moolaPurse,
moolaLiquidityIssuer.makeEmptyPurse(),
centralPurse,
];
const alice = await makeTrader(purses, zoe, publicFacet, centralR.issuer);

let mPoolState = {
c: 0,
s: 0,
l: 0,
k: 0,
};
const initMoolaLiquidityDetails = {
cAmount: centralTokens(10000),
sAmount: moola(10000),
lAmount: moolaLiquidity(10000),
};
const initMoolaLiquidityExpected = {
c: 10000,
s: 10000,
l: 10000,
k: 100000000,
payoutC: 0,
payoutS: 0,
payoutL: 10000,
};
await alice.initLiquidityAndCheck(
t,
mPoolState,
initMoolaLiquidityDetails,
initMoolaLiquidityExpected,
mIssuerKeywordRecord,
);
mPoolState = updatePoolState(mPoolState, initMoolaLiquidityExpected);

// trade for central specifying 300 output: moola price 311
const gain = 300;
const mPrice = priceFromTargetOutput(gain, mPoolState.c, mPoolState.s, 30);
t.is(mPrice, 311);

// provide insufficient moola; trade fails
const seat = await alice.offerAndTrade(
centralTokens(gain),
moola(200),
false,
);
await t.throwsAsync(
() => seat.getOfferResult(),
{ message: / is insufficient to buy amountOut / },
`shouldn't have been able to trade`,
);
const { In: refund, Out: payout } = await seat.getPayouts();
t.deepEqual(await moolaR.issuer.getAmountOf(refund), moola(200));
t.deepEqual(await centralR.issuer.getAmountOf(payout), centralTokens(0));
});

0 comments on commit 19e8b70

Please sign in to comment.