Skip to content

Commit

Permalink
fix(loadgen): switch BLD->USDC for compat with newer SDKs
Browse files Browse the repository at this point in the history
Fix for BLD removed as collateral in Bootstrap change Agoric/agoric-sdk#4387
  • Loading branch information
mhofman committed Feb 4, 2022
1 parent 8ae7ae0 commit 867170f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 74 deletions.
56 changes: 30 additions & 26 deletions loadgen/contract/agent-create-vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,16 @@ export default async function startAgent([key, home]) {
console.error(`create-vault: building tools`);
const {
runBrand,
bldBrand,
usdcBrand,
runPurse,
bldPurse,
usdcPurse,
treasuryInstance,
vaultFactoryInstance,
} = await allValues({
runBrand: E(agoricNames).lookup('brand', issuerPetnames.RUN),
// bldBrand: E(agoricNames).lookup('brand', issuerPetnames.BLD),
bldBrand: E(E(wallet).getIssuer(issuerPetnames.BLD)).getBrand(),
usdcBrand: E(E(wallet).getIssuer(issuerPetnames.USDC)).getBrand(),
runPurse: E(wallet).getPurse(pursePetnames.RUN),
bldPurse: E(wallet).getPurse(pursePetnames.BLD),
usdcPurse: E(wallet).getPurse(pursePetnames.USDC),
treasuryInstance: E(agoricNames)
.lookup('instance', 'Treasury')
.catch(() => {}),
Expand All @@ -42,50 +41,55 @@ export default async function startAgent([key, home]) {
vaultFactoryInstance || treasuryInstance,
);

const bldBalance = await E(bldPurse).getCurrentAmount();
if (AmountMath.isEmpty(bldBalance)) {
throw Error(`create-vault: getCurrentAmount(BLD) broken (says 0)`);
const usdcBalance = await E(usdcPurse).getCurrentAmount();
if (AmountMath.isEmpty(usdcBalance)) {
throw Error(`create-vault: getCurrentAmount(USDC) broken (says 0)`);
}
console.error(`create-vault: initial balance: ${disp(bldBalance)} BLD`);
console.error(`create-vault: initial balance: ${disp(usdcBalance)} USDC`);
// put 1% into the vault
const bldToLock = AmountMath.make(bldBrand, bldBalance.value / BigInt(100));
const usdcToLock = AmountMath.make(
usdcBrand,
usdcBalance.value / BigInt(100),
);

// we only withdraw half the value of the collateral, giving us 200%
// collateralization
const collaterals = await E(treasuryPublicFacet).getCollaterals();
const cdata = collaterals.find((c) => c.brand === bldBrand);
const cdata = collaterals.find((c) => c.brand === usdcBrand);
const priceRate = cdata.marketPrice;
const half = makeRatio(BigInt(50), runBrand);
const wantedRun = multiplyBy(multiplyBy(bldToLock, priceRate), half);
const wantedRun = multiplyBy(multiplyBy(usdcToLock, priceRate), half);

console.error(`create-vault: tools installed`);

console.error(
`create-vault: bldToLock=${disp(bldToLock)}, wantedRun=${disp(wantedRun)}`,
`create-vault: usdcToLock=${disp(usdcToLock)}, wantedRun=${disp(
wantedRun,
)}`,
);

// we fix the 1% 'bldToLock' value at startup, and use it for all cycles
// (we close over 'bldToLock')
// we fix the 1% 'usdcToLock' value at startup, and use it for all cycles
// (we close over 'usdcToLock')
async function openVault() {
console.error('create-vault: openVault');
const openInvitationP = E(treasuryPublicFacet).makeLoanInvitation();
const proposal = harden({
give: {
Collateral: bldToLock,
Collateral: usdcToLock,
},
want: {
RUN: wantedRun,
},
});
const payment = harden({ Collateral: E(bldPurse).withdraw(bldToLock) });
const payment = harden({ Collateral: E(usdcPurse).withdraw(usdcToLock) });
const seatP = E(zoe).offer(openInvitationP, proposal, payment);
await seatP;
const [bldPayout, runPayout] = await Promise.all([
const [usdcPayout, runPayout] = await Promise.all([
E(seatP).getPayout('Collateral'),
E(seatP).getPayout('RUN'),
]);
await Promise.all([
E(bldPurse).deposit(bldPayout),
E(usdcPurse).deposit(usdcPayout),
E(runPurse).deposit(runPayout),
]);
const offerResult = await E(seatP).getOfferResult();
Expand All @@ -102,33 +106,33 @@ export default async function startAgent([key, home]) {
RUN: runNeeded,
},
want: {
Collateral: AmountMath.makeEmpty(bldBrand),
Collateral: AmountMath.makeEmpty(usdcBrand),
},
};
const payment = harden({ RUN: E(runPurse).withdraw(runNeeded) });
const seatP = E(zoe).offer(closeInvitationP, proposal, payment);
const [runPayout, bldPayout] = await Promise.all([
const [runPayout, usdcPayout] = await Promise.all([
E(seatP).getPayout('RUN'),
E(seatP).getPayout('Collateral'),
]);
await Promise.all([
E(runPurse).deposit(runPayout),
E(bldPurse).deposit(bldPayout),
E(usdcPurse).deposit(usdcPayout),
E(seatP).getOfferResult(),
]);
console.error(`create-vault: vault closed`);
}

const agent = Far('vault agent', {
async doVaultCycle() {
const vault = await openVault(bldToLock);
const vault = await openVault(usdcToLock);
await closeVault(vault);
const [newRunBalance, newBldBalance] = await Promise.all([
const [newRunBalance, newUsdcBalance] = await Promise.all([
E(runPurse).getCurrentAmount(),
E(bldPurse).getCurrentAmount(),
E(usdcPurse).getCurrentAmount(),
]);
console.error('create-vault: cycle done');
return [newRunBalance, newBldBalance];
return [newRunBalance, newUsdcBalance];
},
});

Expand Down
70 changes: 35 additions & 35 deletions loadgen/contract/agent-trade-amm.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,23 @@ export default async function startAgent([key, home]) {
// const runIssuer = await E(agoricNames).lookup('issuer', issuerPetnames.RUN);
const {
runBrand,
bldBrand,
usdcBrand,
amm,
autoswap,
runPurse,
bldPurse,
usdcPurse,
} = await allValues({
runBrand: E(agoricNames).lookup('brand', issuerPetnames.RUN),
// bldBrand: E(agoricNames).lookup('brand', issuerPetnames.BLD),
bldBrand: E(E(wallet).getIssuer(issuerPetnames.BLD)).getBrand(),
usdcBrand: E(E(wallet).getIssuer(issuerPetnames.USDC)).getBrand(),
amm: E(agoricNames)
.lookup('instance', 'amm')
.catch(() => {}),
autoswap: E(agoricNames)
.lookup('instance', 'autoswap')
.catch(() => {}),
runPurse: E(wallet).getPurse(pursePetnames.RUN),
bldPurse: E(wallet).getPurse(pursePetnames.BLD),
usdcPurse: E(wallet).getPurse(pursePetnames.USDC),
});
// const bldBrand = await E(bldPurse).getAllegedBrand();

{
const feePurse = await E(faucet)
Expand Down Expand Up @@ -74,23 +72,23 @@ export default async function startAgent([key, home]) {
bal = await E(runPurse).getCurrentAmount();
return bal;
}
if (which === 'BLD') {
bal = await E(bldPurse).getCurrentAmount();
if (which === 'USDC') {
bal = await E(usdcPurse).getCurrentAmount();
return bal;
}
throw Error(`unknown type ${which}`);
}

async function getBalances() {
return allValues({ run: getBalance('RUN'), bld: getBalance('BLD') });
return allValues({ run: getBalance('RUN'), usdc: getBalance('USDC') });
}

async function buyRunWithBld(bldOffered) {
async function buyRunWithUsdc(usdcOffered) {
const proposal = harden({
want: { Out: AmountMath.makeEmpty(runBrand, AssetKind.NAT) },
give: { In: bldOffered },
give: { In: usdcOffered },
});
const payment = harden({ In: E(bldPurse).withdraw(bldOffered) });
const payment = harden({ In: E(usdcPurse).withdraw(usdcOffered) });
const seatP = E(zoe).offer(
E(publicFacet).makeSwapInInvitation(),
proposal,
Expand All @@ -101,15 +99,15 @@ export default async function startAgent([key, home]) {
E(seatP).getPayout('Out'),
]);
await Promise.all([
E(bldPurse).deposit(refundPayout),
E(usdcPurse).deposit(refundPayout),
E(runPurse).deposit(payout),
E(seatP).getOfferResult(),
]);
}

async function buyBldWithRun(runOffered) {
async function buyUsdcWithRun(runOffered) {
const proposal = harden({
want: { Out: AmountMath.makeEmpty(bldBrand, AssetKind.NAT) },
want: { Out: AmountMath.makeEmpty(usdcBrand, AssetKind.NAT) },
give: { In: runOffered },
});
const payment = harden({ In: E(runPurse).withdraw(runOffered) });
Expand All @@ -124,54 +122,56 @@ export default async function startAgent([key, home]) {
]);
await Promise.all([
E(runPurse).deposit(refundPayout),
E(bldPurse).deposit(payout),
E(usdcPurse).deposit(payout),
E(seatP).getOfferResult(),
]);
}

// perform the setup transfer
async function doSetupTransfer() {
let { run, bld } = await getBalances();
console.error(`trade-amm setup: initial RUN=${disp(run)} BLD=${disp(bld)}`);
let { run, usdc } = await getBalances();
console.error(
`trade-amm setup: initial RUN=${disp(run)} USDC=${disp(usdc)}`,
);
// eslint-disable-next-line no-constant-condition
if (1) {
// setup: buy BLD with 50% of our remaining RUN (33% of initial amount)
console.error(`trade-amm: buying BLD with 33% of our initial RUN`);
// setup: buy USDC with 50% of our remaining RUN (33% of initial amount)
console.error(`trade-amm: buying USDC with 33% of our initial RUN`);
const halfAmount = AmountMath.make(runBrand, run.value / BigInt(2));
await buyBldWithRun(halfAmount);
({ run, bld } = await getBalances());
await buyUsdcWithRun(halfAmount);
({ run, usdc } = await getBalances());
}
// we sell 1% of the holdings each time
const runPerCycle = AmountMath.make(runBrand, run.value / BigInt(100));
const bldPerCycle = AmountMath.make(bldBrand, bld.value / BigInt(100));
console.error(`setup: RUN=${disp(run)} BLD=${disp(bld)}`);
const usdcPerCycle = AmountMath.make(usdcBrand, usdc.value / BigInt(100));
console.error(`setup: RUN=${disp(run)} USDC=${disp(usdc)}`);
console.error(
`will trade about ${disp(runPerCycle)} RUN and ${disp(
bldPerCycle,
)} BLD per cycle`,
usdcPerCycle,
)} USDC per cycle`,
);
console.error(`trade-amm: initial trade complete`);
}
await doSetupTransfer();

const agent = Far('AMM agent', {
async doAMMCycle() {
console.error('trade-amm cycle: BLD->RUN');
const bld = await getBalance('BLD');
const bldOffered = AmountMath.make(bldBrand, bld.value / BigInt(100));
await buyRunWithBld(bldOffered);
console.error('trade-amm cycle: USDC->RUN');
const usdc = await getBalance('USDC');
const usdcOffered = AmountMath.make(usdcBrand, usdc.value / BigInt(100));
await buyRunWithUsdc(usdcOffered);

console.error('trade-amm cycle: RUN->BLD');
console.error('trade-amm cycle: RUN->USDC');
const run = await getBalance('RUN');
const runOffered = AmountMath.make(runBrand, run.value / BigInt(100));
await buyBldWithRun(runOffered);
await buyUsdcWithRun(runOffered);

const [newRunBalance, newBldBalance] = await Promise.all([
const [newRunBalance, newUsdcBalance] = await Promise.all([
E(runPurse).getCurrentAmount(),
E(bldPurse).getCurrentAmount(),
E(usdcPurse).getCurrentAmount(),
]);
console.error('trade-amm cycle: done');
return [newRunBalance, newBldBalance];
return [newRunBalance, newUsdcBalance];
},
});

Expand Down
4 changes: 2 additions & 2 deletions loadgen/contract/petnames.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export const pursePetnames = {
RUN: 'Agoric RUN currency',
BLD: 'Agoric staking token',
USDC: 'USD Coin',
};

export const issuerPetnames = {
RUN: 'RUN',
BLD: 'BLD',
USDC: 'USDC',
};
2 changes: 1 addition & 1 deletion loadgen/loop.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ let pushBroker = null;
const tasks = {
// we must start the AMM task before other tasks:
// - AMM sets up Zoe fee purse
// - AMM exchanges some RUN for BLD, and Vault measures the balances
// - AMM exchanges some RUN for USDC, and Vault measures the balances
amm: [prepareAMMTrade],
vault: [prepareVaultCycle],
faucet: [prepareFaucet],
Expand Down
16 changes: 8 additions & 8 deletions loadgen/task-create-vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import { E } from '@agoric/eventual-send';
import { disp } from './contract/display.js';

// Prepare to create and close a vault on each cycle. We measure our
// available BLD at startup. On each cycle, we deposit 1% of that value as
// available USDC at startup. On each cycle, we deposit 1% of that value as
// collateral to borrow as much RUN as they'll give us. Then we pay back the
// loan (using all the borrowed RUN, plus some more as a fee), getting back
// most (but not all?) of our BLD. If we are not interrupted, we finish each
// cycle with slightly less BLD and RUN than we started (because of fees),
// most (but not all?) of our USDC. If we are not interrupted, we finish each
// cycle with slightly less USDC and RUN than we started (because of fees),
// but with no vaults or loans outstanding.

// Make sure to run this after task-trade-amm has started (which converts 50%
// of our BLD into RUN), so we don't TOCTTOU ourselves into believing we have
// twice as much BLD as we really do.
// of our RUN into USDC), so we don't TOCTTOU ourselves into believing we have
// twice as much RUN as we really do.

export async function prepareVaultCycle(homePromise, deployPowers) {
const key = 'open-close-vault';
Expand All @@ -30,10 +30,10 @@ export async function prepareVaultCycle(homePromise, deployPowers) {
}

async function vaultCycle() {
const [newRunBalance, newBldBalance] = await E(agent).doVaultCycle();
const [newRunBalance, newUsdcBalance] = await E(agent).doVaultCycle();
console.log(
`create-vault done: RUN=${disp(newRunBalance)} BLD=${disp(
newBldBalance,
`create-vault done: RUN=${disp(newRunBalance)} USDC=${disp(
newUsdcBalance,
)}`,
);
}
Expand Down
4 changes: 2 additions & 2 deletions loadgen/task-trade-amm.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export async function prepareAMMTrade(homePromise, deployPowers) {
}

async function tradeAMMCycle() {
const [newRunBalance, newBldBalance] = await E(agent).doAMMCycle();
const [newRunBalance, newUsdcBalance] = await E(agent).doAMMCycle();
console.log(
`trade-amm done: RUN=${newRunBalance.value} BLD=${newBldBalance.value}`,
`trade-amm done: RUN=${newRunBalance.value} USDC=${newUsdcBalance.value}`,
);
}
console.log(`--- trade-amm ready for cycles`);
Expand Down

0 comments on commit 867170f

Please sign in to comment.