Skip to content

Commit

Permalink
fix: repair and add types for multipoolAutoSwap.getLiquidityIssuer()
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris-Hibbert committed Sep 15, 2020
1 parent 720e3c7 commit 7c7bcca
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 6 deletions.
7 changes: 4 additions & 3 deletions packages/zoe/src/contracts/exported.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
* @property {(inputValue: Value) => Amount } getSecondaryToCentralOutputPrice
* @property {(inputValue: Value) => Amount } getCentralToSecondaryOutputPrice
* @property {() => number} getLiquiditySupply
* @property {() => Issuer} getLiquidityIssuer
* @property {(seat: ZCFSeat) => string} addLiquidity
* @property {(seat: ZCFSeat) => string} removeLiquidity
* @property {() => ZCFSeat} getPoolSeat
Expand All @@ -88,16 +89,16 @@
* invitation that allows one to add liquidity to the pool.
* @property {() => Promise<Invitation>} makeRemoveLiquidityInvitation make an
* invitation that allows one to remove liquidity from the pool.
* @property {brand: Brand => Issuer} getLiquidityIssuer
* @property {brand: Brand => number} getLiquiditySupply get the current value of
* @property {(brand: Brand) => Issuer} getLiquidityIssuer
* @property {(brand: Brand) => number} getLiquiditySupply get the current value of
* liquidity in the pool for brand held by investors.
* @property {(amountIn: Amount, brandOut: Brand) => Amount} getInputPrice
* calculate the amount of brandOut that will be returned if the amountIn is
* offered using makeSwapInInvitation at the current price.
* @property {(amountOut: Amount, brandIn: Brand) => Amount} getOutputPrice
* calculate the amount of brandIn that is required in order to get amountOut
* using makeSwapOutInvitation at the current price
* @property {brand: Brand => Record<string, Amount>} getPoolAllocation get an
* @property {(brand: Brand) => Record<string, Amount>} getPoolAllocation get an
* AmountKeywordRecord showing the current balances in the pool for brand.
*/

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const start = zcf => {
assertIssuerKeywords(zcf, ['Central']);
assert(centralBrand !== undefined, details`centralBrand must be present`);

/** @type {WeakStore<Brand,Pool>} */
const secondaryBrandToPool = makeWeakStore();
const getPool = secondaryBrandToPool.get;
const initPool = secondaryBrandToPool.init;
Expand Down
2 changes: 2 additions & 0 deletions packages/zoe/src/contracts/multipoolAutoswap/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const makeAddPool = (zcf, isSecondary, initPool, centralBrand) => {
const {
brand: liquidityBrand,
amountMath: liquidityAmountMath,
issuer: liquidityIssuer,
} = liquidityZcfMint.getIssuerRecord();

const addLiquidityActual = (pool, userSeat, secondaryAmount) => {
Expand Down Expand Up @@ -67,6 +68,7 @@ export const makeAddPool = (zcf, isSecondary, initPool, centralBrand) => {
/** @type {Pool} */
const pool = {
getLiquiditySupply: () => liqTokenSupply,
getLiquidityIssuer: () => liquidityIssuer,
getPoolSeat: () => poolSeat,
getAmountMath: () => zcf.getAmountMath(secondaryBrand),
getCentralAmountMath: () => zcf.getAmountMath(centralBrand),
Expand Down
1 change: 1 addition & 0 deletions packages/zoe/test/autoswapJig.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ export const makeTrader = async (purses, zoe, publicFacet, centralIssuer) => {
t.is(lAmount.value, lPost, 'liquidity scales (init)');
t.is(cAmount.value, cPost);
t.is(sAmount.value, sPost);
return { central: cPayout, secondary: sPayout, liquidity: lPayout };
},
});
return trader;
Expand Down
94 changes: 91 additions & 3 deletions packages/zoe/test/unitTests/contracts/test-multipoolAutoswap.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
scaleForAddLiquidity,
priceFromTargetOutput,
} from '../../autoswapJig';
import { assertPayoutDeposit } from '../../zoeTestHelpers';

const multipoolAutoswapRoot = `${__dirname}/../../../src/contracts/multipoolAutoswap/multipoolAutoswap`;

Expand Down Expand Up @@ -520,7 +521,7 @@ test('multipoolAutoSwap with some invalid offers', async t => {
);
});

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

Expand Down Expand Up @@ -651,13 +652,100 @@ test('multipoolAutoSwap jig - liquidity', async t => {
{ message: 'insufficient Secondary deposited' },
`insufficient secondary is unsuccessful`,
);
});

test('multipoolAutoSwap jig - check liquidity', 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(20000));
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 issuerKeywordRecord = {
Central: centralR.issuer,
Secondary: moolaR.issuer,
Liquidity: moolaLiquidityIssuer,
};
const purses = [
moolaPurse,
moolaLiquidityIssuer.makeEmptyPurse(),
centralPurse,
];
const alice = await makeTrader(purses, zoe, publicFacet, centralR.issuer);

let moolaPoolState = {
c: 0,
s: 0,
l: 0,
k: 0,
};
const initLiquidityDetails = {
cAmount: centralTokens(10000),
sAmount: moola(10000),
lAmount: moolaLiquidity(10000),
};
const initLiquidityExpected = {
c: 10000,
s: 10000,
l: 10000,
k: 100000000,
payoutC: 0,
payoutS: 0,
payoutL: 10000,
};

const {
central: centralP,
secondary: secondaryP,
liquidity: liquidityP,
} = await alice.initLiquidityAndCheck(
t,
moolaPoolState,
initLiquidityDetails,
initLiquidityExpected,
issuerKeywordRecord,
);
moolaPoolState = updatePoolState(moolaPoolState, initLiquidityExpected);
assertPayoutDeposit(t, centralP, centralPurse, centralTokens(0));
assertPayoutDeposit(t, secondaryP, moolaPurse, moola(0));
assertPayoutDeposit(t, liquidityP, purses[1], moolaLiquidity(10000));

const liquidityIssuer = await E(publicFacet).getLiquidityIssuer(moolaR.brand);
t.truthy(liquidityIssuer, 'issuer');

// alice checks the liquidity levels
const moolaAllocations = await E(publicFacet).getPoolAllocation(moolaR.brand);
t.is(moolaAllocations.Central.value, moolaPoolState.c);
t.is(moolaAllocations.Secondary.value, moolaPoolState.s);

// trade to move the balance of liquididty
// trade to move the balance of liquidity
// trade for moola specifying 300 output
const gainC = 300;
const mPriceC = priceFromTargetOutput(
Expand All @@ -675,7 +763,7 @@ test('multipoolAutoSwap jig - liquidity', async t => {
const expectedC = {
c: moolaPoolState.c + mPriceC,
s: moolaPoolState.s - gainC,
l: 10200,
l: 10000,
k: (moolaPoolState.c + mPriceC) * (moolaPoolState.s - gainC),
out: gainC,
in: 0,
Expand Down

0 comments on commit 7c7bcca

Please sign in to comment.