Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provide starter IST to newly provisoned accounts #6157

Merged
merged 21 commits into from
Sep 13, 2022
Merged

Conversation

dckc
Copy link
Member

@dckc dckc commented Sep 8, 2022

refs: #6067

Description

  • add provisionPool contract; wire it up to the walletFactory as well as each PSM
  • add module account, vbank/provision, to hold IST as well as assets to sell on the/a PSM

TODO:

  • make initial amount governed (I prefer to do this in a follow-on PR)

Security Considerations

In the contract: makeBridgeProvisionTool is factored out of the contract start function to keep the bridge handling stuff mostly separate from the asset-handling stuff.

Elsewhere, the use of bootstrap powers merits careful review.

Documentation Considerations

We should provide end users with docs on the "pay 10 BLD to the community pool; get 0.25 IST for initial fees" model.

Testing Considerations

Trading on the PSM is unit-tested.

The flow resulting in 0.25 IST going to the user was only tested manually. (Results are documented below.)

@dckc dckc force-pushed the 6067-starter-ist branch 3 times, most recently from 17d0c8a to 560b676 Compare September 8, 2022 14:49
@dckc
Copy link
Member Author

dckc commented Sep 9, 2022

how to authorize a module account to receive funds?

packages/cosmic-swingset$ make SOLO_COINS=12345000000ibc/usdc1234 ACCT_ADDR=$pool fund-acct
Waiting for localhost:26657 to come live.... done!
../../golang/cosmos/build/agd \
  --home=t1/bootstrap --keyring-backend=test --from=bootstrap \
  tx bank send bootstrap agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346 12345000000ibc/usdc1234 \
  --gas=auto --gas-adjustment=1.2 --broadcast-mode=block --yes --chain-id=agoric
Error: rpc error: code = InvalidArgument desc = failed to execute message; message index: 0: agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346 is not allowed to receive funds: unauthorized: invalid request

p.s. Answer: don't disable it

@dckc
Copy link
Member Author

dckc commented Sep 9, 2022

First end-to-end test worked!

  • Supply funds to the pool
    1. Benefactor sends USDC to the pool account
    2. provisionPool trades the USDC for IST
  • Pay 10 BLD for an Agoric smart wallet
    1. User requests a smart-wallet account
    2. provisionPool provides a smartWallet and sends 0.25 IST
    3. User sees balance

Send USDC to the pool account

packages/cosmic-swingset$ make SOLO_COINS=1234000000ibc/usdc1234 ACCT_ADDR=$pool fund-acct
../../golang/cosmos/build/agd \
  --home=t1/bootstrap --keyring-backend=test --from=bootstrap \
  tx bank send bootstrap agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346 1234000000ibc/usdc1234 \
  --gas=auto --gas-adjustment=1.2 --broadcast-mode=block --yes --chain-id=agoric
gas estimate: 84493
code: 0
...
txhash: ED3DED583373BBDAA734E7122FE9BA0498C7F17B8CABB7747783317A8007E1E3

provisionPool trades the USDC for IST

2022-09-09T03:57:52.490Z SwingSet: vat: v15: bank balance update { address: 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346', amount: '1234000000', denom: 'ibc/usdc1234' }
2022-09-09T03:57:52.502Z SwingSet: vat: v18: provisionPool balance update { brand: Object [Alleged: AUSD brand] {}, value: 1_234_000_000n }
2022-09-09T03:57:52.715Z block-manager: block 20 commit
2022-09-09T03:57:57.483Z block-manager: block 21 begin
2022-09-09T03:57:57.711Z block-manager: block 21 commit
2022-09-09T03:58:02.491Z block-manager: block 22 begin
2022-09-09T03:58:02.642Z SwingSet: vat: v15: bank balance update { address: 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346', amount: '1233876600', denom: 'uist' }
2022-09-09T03:58:02.650Z SwingSet: vat: v18: provisionPool balance update { brand: Object [Alleged: IST brand] {}, value: 1_233_876_600n }

Provision a smart-wallet account

NOTE: This will cost N BLD shortly.

packages/cosmic-swingset$ addr=$(cat t1/8000/ag-cosmos-helper-address)
packages/cosmic-swingset$ make ACCT_ADDR=$addr provision-acct
../../golang/cosmos/build/agd --chain-id=agoric \
  --home=t1/bootstrap --keyring-backend=test --from=bootstrap \
  tx swingset provision-one t1/8000 agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu SMART_WALLET \
  --gas=auto --gas-adjustment=1.2 --broadcast-mode=block --yes
gas estimate: 111214
code: 0
...
txhash: 807A2A9AC224E2B99900978AA96D25319B12388030DF74EB2F6759F80226F1F9

provisionPool provides a smartWallet and sends 0.25 IST

NOTE special coordination around essential purses, i.e. IST.

2022-09-09T03:58:22.549Z SwingSet: vat: v18: PLEASE_PROVISION agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu [ 'SMART_WALLET' ]
2022-09-09T03:58:22.550Z SwingSet: vat: v18: sendInitialPayment agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu
2022-09-09T03:58:22.649Z SwingSet: vat: v15: bank balance update { address: 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346', amount: '1233626600', denom: 'uist' }
2022-09-09T03:58:22.705Z SwingSet: vat: v18: provisionPool balance update { brand: Object [Alleged: IST brand] {}, value: 1_233_626_600n }
2022-09-09T03:58:22.720Z SwingSet: vat: v16: { ready: false, essentialBrands: { Fee: Object [Alleged: IST brand] {} }, brandPurses: Object [Alleged: mapStore] { snapshot: [Function: snapshotMap], has: [Function: has], get: [Function: get], init: [Function: init], set: [Function: set], delete: [Function: del], keys: [Function: keys], values: [Function: values], entries: [Function: entries], getSize: [Function: getSize], clear: [Function: clear] } }
2022-09-09T03:58:22.781Z block-manager: block 26 commit
2022-09-09T03:58:27.548Z block-manager: block 27 begin
2022-09-09T03:58:27.609Z SwingSet: vat: v16: agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu notified of new asset Object [Alleged: AUSD brand] {}
2022-09-09T03:58:27.692Z SwingSet: vat: v16: agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu notified of new asset Object [Alleged: BLD brand] {}
2022-09-09T03:58:27.760Z SwingSet: vat: v16: { ready: false, essentialBrands: { Fee: Object [Alleged: IST brand] {} }, brandPurses: Object [Alleged: mapStore] { snapshot: [Function: snapshotMap], has: [Function: has], get: [Function: get], init: [Function: init], set: [Function: set], delete: [Function: del], keys: [Function: keys], values: [Function: values], entries: [Function: entries], getSize: [Function: getSize], clear: [Function: clear] } }
2022-09-09T03:58:27.782Z SwingSet: vat: v16: agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu notified of new asset Object [Alleged: IST brand] {}
2022-09-09T03:58:27.796Z SwingSet: vat: v16: agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu receive { paymentE: Object [Alleged: IST payment] {}, paymentBrand: undefined }
2022-09-09T03:58:27.855Z block-manager: block 27 commit
2022-09-09T03:58:32.560Z block-manager: block 28 begin
2022-09-09T03:58:32.604Z SwingSet: vat: v16: { ready: false, essentialBrands: { Fee: Object [Alleged: IST brand] {} }, brandPurses: Object [Alleged: mapStore] { snapshot: [Function: snapshotMap], has: [Function: has], get: [Function: get], init: [Function: init], set: [Function: set], delete: [Function: del], keys: [Function: keys], values: [Function: values], entries: [Function: entries], getSize: [Function: getSize], clear: [Function: clear] } }
2022-09-09T03:58:32.622Z SwingSet: vat: v16: { brand: Object [Alleged: IST brand] {}, essential: true }
2022-09-09T03:58:32.686Z SwingSet: vat: v16: { ready: true, essentialBrands: { Fee: Object [Alleged: IST brand] {} }, brandPurses: Object [Alleged: mapStore] { snapshot: [Function: snapshotMap], has: [Function: has], get: [Function: get], init: [Function: init], set: [Function: set], delete: [Function: del], keys: [Function: keys], values: [Function: values], entries: [Function: entries], getSize: [Function: getSize], clear: [Function: clear] } }
2022-09-09T03:58:32.688Z SwingSet: vat: v16: { purse: Object [Alleged: Virtual Purse] {} }
2022-09-09T03:58:32.810Z SwingSet: vat: v15: bank balance update { address: 'agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu', amount: '250000', denom: 'uist' }
2022-09-09T03:58:32.822Z SwingSet: vat: v16: agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu received { brand: Object [Alleged: IST brand] {}, value: 250_000n }
2022-09-09T03:58:32.835Z SwingSet: vat: v18: provisionPool sent { brand: Object [Alleged: IST brand] {}, value: 250_000n } to agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu
2022-09-09T03:58:32.836Z SwingSet: vat: v18: provisioned agoric1xezchds0qr3wddht3t6zyrc2cn78q4v3alu8qu [ 'SMART_WALLET' ]

Tada! money in my pocket

packages/cosmic-swingset$ agd query bank balances $addr
balances:
- amount: "250000"
  denom: uist

cc @JimLarson @dtribble @turadg @michaelfig @rowgraus @samsiegart @Tartuffo

Comment on lines +86 to +92
// @ts-expect-error vbank purse is close enough for our use.
const fundPurse = E(poolBank).getPurse(poolBrand);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you run accross this, @turadg ? any clues?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. VirtualPurse is what the bank returns and it's slightly different. For example, withdraw is sync on Purse and async on VirtualPurse. @michaelfig documented this,

// Withdrawal. We can't easily type a `VirtualPurse` unless we make it
// callable only with `E`, in which case we can't automatically unwrap the
// return result of `E(vpurse).withdraw` to a sync interface (which `Payment`
// is).
//
// TODO: We can fix this only if the ERTP methods also allow consuming a
// `Remote<Payment>` instead of just `Payment`. That typing has not yet been
// done, hence the cast.

Making ERTP methods accept remote payments seems worth doing soon. WDYT @michaelfig ?

@dckc dckc changed the title WIP starter ist for discussion provide starter IST to newly provisoned accounts Sep 10, 2022
@dckc dckc marked this pull request as ready for review September 10, 2022 18:17
@dckc dckc requested a review from turadg as a code owner September 10, 2022 18:17
Copy link
Contributor

@JimLarson JimLarson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Golang changes look good!

@@ -2,6 +2,7 @@ import bundleCentralSupply from '@agoric/vats/bundles/bundle-centralSupply.js';
import bundleMintHolder from '@agoric/vats/bundles/bundle-mintHolder.js';
import bundleSingleWallet from '@agoric/vats/bundles/bundle-singleWallet.js';
import bundleWalletFactory from '@agoric/vats/bundles/bundle-legacy-walletFactory.js';
import bundleProvisionPool from '@agoric/vats/bundles/bundle-provisionPool.js';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to stop maintaining packages/wallet/contract. @samsiegart @michaelfig do we need it any more?

@turadg bonus points if you beat me to it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursory review from phone. Only blocker I see is the Kit name. I'll look into types when not afk but can merge as is imo.

packages/vats/src/core/basic-behaviors.js Outdated Show resolved Hide resolved
packages/vats/src/core/startWalletFactory.js Outdated Show resolved Hide resolved
packages/vats/src/provisionPool.js Outdated Show resolved Hide resolved
packages/vats/src/provisionPool.js Show resolved Hide resolved
console.info('PLEASE_PROVISION', address, powerFlags);

if (!powerFlags.includes(PowerFlags.SMART_WALLET)) {
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not error? I haven't looked closely to answer for myself, but would be good yo have an explanation comment here regardless.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure. I have a vague memory that I tried that and something bad happened. But I should look more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I remember: I was thinking we could register 2 handlers for BRIDGE_ID.WALLET, on for SMART_WALLET and one for REMOTE_WALLET. But now that I think about it, we can only register one handler.

Copy link
Contributor

@Chris-Hibbert Chris-Hibbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks basically right. I suggested some clean-ups.

packages/vats/src/core/startWalletFactory.js Outdated Show resolved Hide resolved
packages/vats/src/provisionPool.js Show resolved Hide resolved
packages/vats/src/provisionPool.js Outdated Show resolved Hide resolved
packages/vats/src/provisionPool.js Show resolved Hide resolved
packages/vats/src/core/startWalletFactory.js Outdated Show resolved Hide resolved
@dckc
Copy link
Member Author

dckc commented Sep 11, 2022

oops... @JimLarson I didn't mean to re-request a review from you. wrong button

@@ -15,35 +14,67 @@ const { details: X } = assert;
// eslint-disable-next-line no-unused-vars
const startFactoryInstance = (zoe, inst) => E(zoe).startInstance(inst);

const StableUnit = BigInt(10 ** Stable.displayInfo.decimalPlaces);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder if units should go in with their Brand def (i.e. tokens.js in this case)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, if there are other static uses of it... but a quick search doesn't find any other occurrences of 10 ** Stable.displayInfo.decimalPlaces.

console.warn('startWalletFactory needs bridgeManager (not sim chain)');
return;
}
console.log('provision pool', { poolAddr });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be dropped or turned into trace()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as much as any other logging we do, I suppose; clean-up is postponed to #5222 , IIUC.

@Chris-Hibbert
Copy link
Contributor

I'm only removing my request for changes, not actually adding an explicit approval. Not intending to block submission. I didn't see another way to stop blocking than to approve, so that's the button I pushed.

@dckc dckc added the automerge:no-update (expert!) Automatically merge without updates label Sep 12, 2022
dckc and others added 21 commits September 12, 2022 21:40
 - vbank/provision, which is _not_ blocked
   from receiving funds
 - integrate provisionPool into startWalletFactory
 - don't try to sell IST for IST
 - makeHandler takes a record of named args (...hunt)
 - clean up moduleAccountAddress stuff
 - docs: static type for provision pool facets
using labels in patterns
@dckc dckc added the bypass:integration Prevent integration tests from running on PR label Sep 13, 2022
@mergify mergify bot merged commit a400d71 into master Sep 13, 2022
@mergify mergify bot deleted the 6067-starter-ist branch September 13, 2022 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:no-update (expert!) Automatically merge without updates bypass:integration Prevent integration tests from running on PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants