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

how to add collateral (e.g. stATOM): training materials #8176

Closed
turadg opened this issue Aug 11, 2023 · 8 comments
Closed

how to add collateral (e.g. stATOM): training materials #8176

turadg opened this issue Aug 11, 2023 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@turadg
Copy link
Member

turadg commented Aug 11, 2023

Resolution

We did a recorded demo and discussion in Aug 23 Office Hours.

materials:

See also community post:

What is the Problem Being Solved?

It's not sufficiently clear how a community member can propose a new collateral to the chain

Description of the Design

Make a video demonstrating:

  • running a core-eval adding stATOM oracle & vaultmanager on Ollinet.
  • showing wallet-app & dapp-inter accessing it
  • new vault made with stATOM

Provide links to resources used in the video

Might be easier after #8177

@turadg turadg added the enhancement New feature or request label Aug 11, 2023
@dckc
Copy link
Member

dckc commented Aug 12, 2023

@dckc
Copy link
Member

dckc commented Aug 17, 2023

STRD IBC denom

I'm not sure to what extent this applies to working on a demo, but following kjnodes's post on Stride <> Agoric channels, a tx from stride to a receiver on agoric shows a mainnet denom of

  • ibc/299612A95693138225447366268ED58014100D965FCEDC43F27D47AB360F351F

I just confirmed with...

$ agd --node=https://main.rpc.agoric.net:443 query ibc-transfer denom-trace 299612A95693138225447366268ED58014100D965FCEDC43F27D47AB360F351F
denom_trace:
  base_denom: ustrd
  path: transfer/channel-59

cc @0xpatrickdev re...

stATOM IBC denom

$ agd --node=https://main.rpc.agoric.net:443 query ibc-transfer denom-hash transfer/channel-59/stuatom
hash: B1E6288B5A0224565D915D1F66716486F16D8A44BF33A9EC323DD6BA30764C35

@dckc
Copy link
Member

dckc commented Aug 18, 2023

@0xpatrickdev and I made some pretty good progress today.

He got the whole thing working on a local chain.

We got much of it working on an internal test network:

screenshot: stATOM1 among collateral choices

but hit the "no tokens" issue

we recorded a summary discussion, 6min long
Passcode: WD$Hwti6

for ref:
https://github.com/0xpatrickdev/agoric-vault-collateral-proposal 06a85a3

@dckc
Copy link
Member

dckc commented Aug 21, 2023

@dckc
Copy link
Member

dckc commented Aug 23, 2023

created stATOM vault on ollinet

Using recent update of dapp-inter on ollinet -

image

stATOM among choice of collateral

image

wallet UI showing stATOM balance

image

wallet UI offer dialog

image

governance proposal

https://ollinet.explorer.agoric.net/agoric/gov/5

Submitted Time: 2023-08-22 17:49

agoricollinet-dev-1 proposal 5 in detail

from agd --node=https://ollinet.rpc.agoric.net:443 query gov proposal 5

content:
  '@type': /agoric.swingset.CoreEvalProposal
  description: Evaluate add-stATOM.js add-stATOM-oracles
  evals:
  - js_code: |
      // This is generated by writeCoreProposal; please edit!
      /* eslint-disable */

      const manifestBundleRef = {bundleID:"b1-c185bf3b0d7cf940a4f6d6ca1cd74a5d0f5ff330be1cfceaa6c5e4204ba1196e92444e086bf03573371216f41941d1b0fc8560984e2da09f2edd412e46dd62e3"};
      const getManifestCall = harden([
        "getManifestForAddAssetToVault",
        {
          debtLimitValue: undefined,
          interchainAssetOptions: {
            decimalPlaces: 6,
            denom: "ibc/49C630713B2AB60653F76C0C58D43C2A64956803B4D422CACB6DD4AD016ED846",
            initialPrice: undefined,
            issuerBoardId: undefined,
            issuerName: "stATOM",
            keyword: "STATOM",
            oracleBrand: "stATOM",
            proposedName: "stATOM",
          },
          interestRateValue: undefined,
          scaledPriceAuthorityRef: {
            bundleID: "b1-e4ba9cb60b5b59d4d4618710991fe8a503dd4a07c7f17029a342ccb41893bc961ae63bcb0e2c20e4bc2415c9755f090f7761751cdd00b85762902b357a48c5cf",
          },
        },
      ]);
      const overrideManifest = {
        addAssetToVault: {
          brand: {
            consume: {
              IST: true,
            },
          },
          consume: {
            agoricNamesAdmin: true,
            auctioneerKit: "auctioneer",
            vaultFactoryKit: "vaultFactory",
          },
          instance: {
            consume: true,
          },
        },
        publishInterchainAssetFromBank: {
          consume: {
            agoricNamesAdmin: true,
            bankManager: true,
            bankMints: true,
            reserveKit: true,
            startUpgradable: true,
            vBankKits: true,
          },
          installation: {
            consume: {
              mintHolder: true,
            },
          },
          produce: {
            bankMints: true,
            vBankKits: true,
          },
        },
        registerScaledPriceAuthority: {
          consume: {
            agoricNamesAdmin: true,
            priceAuthority: true,
            priceAuthorityAdmin: true,
            scaledPriceAuthorityKits: true,
            startUpgradable: true,
          },
          installation: {
            consume: {
              scaledPriceAuthority: true,
            },
          },
          produce: {
            scaledPriceAuthorityKits: true,
          },
        },
      };

      // Make the behavior the completion value.
      (({
        manifestBundleRef,
        getManifestCall,
        overrideManifest,
        E,
        log = console.info,
        restoreRef: overrideRestoreRef,
      }) => {
        const { entries, fromEntries } = Object;

        // deeplyFulfilled is a bit overkill for what we need.
        const shallowlyFulfilled = async obj => {
          if (!obj) {
            return obj;
          }
          const ents = await Promise.all(
            entries(obj).map(async ([key, valueP]) => {
              const value = await valueP;
              return [key, value];
            }),
          );
          return fromEntries(ents);
        };

        /** @param {ChainBootstrapSpace & BootstrapPowers & { evaluateBundleCap: any }} allPowers */
        const behavior = async allPowers => {
          // NOTE: If updating any of these names extracted from `allPowers`, you must
          // change `permits` above to reflect their accessibility.
          const {
            consume: { vatAdminSvc, zoe, agoricNamesAdmin },
            evaluateBundleCap,
            installation: { produce: produceInstallations },
            modules: {
              utils: { runModuleBehaviors },
            },
          } = allPowers;
          const [exportedGetManifest, ...manifestArgs] = getManifestCall;

          /** @type {(ref: import\('./externalTypes.js').ManifestBundleRef) => Promise<Installation<unknown>>} */
          const defaultRestoreRef = async ref => {
            // extract-proposal.js creates these records, and bundleName is
            // the name under which the bundle was installed into
            // config.bundles
            const p =
              'bundleName' in ref
                ? E(vatAdminSvc).getBundleIDByName(ref.bundleName)
                : ref.bundleID;
            const bundleID = await p;
            const label = bundleID.slice(0, 8);
            return E(zoe).installBundleID(bundleID, label);
          };
          const restoreRef = overrideRestoreRef || defaultRestoreRef;

          // Get the on-chain installation containing the manifest and behaviors.
          console.info('evaluateBundleCap', {
            manifestBundleRef,
            exportedGetManifest,
            vatAdminSvc,
          });
          let bcapP;
          if ('bundleName' in manifestBundleRef) {
            bcapP = E(vatAdminSvc).getNamedBundleCap(manifestBundleRef.bundleName);
          } else {
            bcapP = E(vatAdminSvc).getBundleCap(manifestBundleRef.bundleID);
          }
          const bundleCap = await bcapP;

          const manifestNS = await evaluateBundleCap(bundleCap);

          console.error('execute', {
            exportedGetManifest,
            behaviors: Object.keys(manifestNS),
          });
          const {
            manifest,
            options: rawOptions,
            installations: rawInstallations,
          } = await manifestNS[exportedGetManifest](
            harden({ restoreRef }),
            ...manifestArgs,
          );

          // Await references in the options or installations.
          const [options, installations] = await Promise.all(
            [rawOptions, rawInstallations].map(shallowlyFulfilled),
          );

          // Publish the installations for behavior dependencies.
          const installAdmin = E(agoricNamesAdmin).lookupAdmin('installation');
          await Promise.all(
            entries(installations || {}).map(([key, value]) => {
              produceInstallations[key].resolve(value);
              return E(installAdmin).update(key, value);
            }),
          );

          // Evaluate the manifest for our behaviors.
          return runModuleBehaviors({
            allPowers,
            behaviors: manifestNS,
            manifest: overrideManifest || manifest,
            makeConfig: (name, _permit) => {
              log('coreProposal:', name);
              return { options };
            },
          });
        };

        // Make the behavior the completion value.
        return behavior;
      })({ manifestBundleRef, getManifestCall, overrideManifest, E });
    json_permits: |-
      {
        "consume": {
          "bankManager": true,
          "agoricNamesAdmin": "makeCoreProposalBehavior",
          "bankMints": true,
          "reserveKit": true,
          "vBankKits": true,
          "startUpgradable": true,
          "priceAuthorityAdmin": true,
          "priceAuthority": true,
          "scaledPriceAuthorityKits": true,
          "auctioneerKit": "auctioneer",
          "vaultFactoryKit": "vaultFactory",
          "vatAdminSvc": "makeCoreProposalBehavior",
          "zoe": "makeCoreProposalBehavior"
        },
        "produce": {
          "bankMints": true,
          "vBankKits": true,
          "scaledPriceAuthorityKits": true
        },
        "installation": {
          "consume": {
            "mintHolder": true,
            "scaledPriceAuthority": true
          },
          "produce": "makeCoreProposalBehavior"
        },
        "brand": {
          "consume": {
            "IST": true
          }
        },
        "instance": {
          "consume": true
        },
        "evaluateBundleCap": "makeCoreProposalBehavior",
        "modules": {
          "utils": {
            "runModuleBehaviors": "makeCoreProposalBehavior"
          }
        }
      }
  - js_code: |
      // This is generated by writeCoreProposal; please edit!
      /* eslint-disable */

      const manifestBundleRef = {bundleID:"b1-1c8e93cc80b28b2cf6b1252e9b6edb0253a1f962889f8a255397b43984950a263dd9c9efd82aee5744b46e7bd57ff1c733030e9f4dc8da9b355b185a59687862"};
      const getManifestCall = harden([
        "getManifestForPriceFeed",
        {
          AGORIC_INSTANCE_NAME: "stATOM-USD price feed",
          IN_BRAND_DECIMALS: 6,
          IN_BRAND_LOOKUP: [
            "agoricNames",
            "oracleBrand",
            "stATOM",
          ],
          IN_BRAND_NAME: "stATOM",
          OUT_BRAND_DECIMALS: 4,
          OUT_BRAND_LOOKUP: [
            "agoricNames",
            "oracleBrand",
            "USD",
          ],
          OUT_BRAND_NAME: "USD",
          brandInRef: undefined,
          brandOutRef: undefined,
          contractTerms: {
            POLL_INTERVAL: 30n,
            maxSubmissionCount: 1000,
            maxSubmissionValue: 115792089237316195423570985008687907853269984665640564039457584007913129639936n,
            minSubmissionCount: 2,
            minSubmissionValue: 1n,
            restartDelay: 1,
            timeout: 10,
          },
          oracleAddresses: [
            "agoric1ldmtatp24qlllgxmrsjzcpe20fvlkp448zcuce",
            "agoric140dmkrz2e42ergjj7gyvejhzmjzurvqeq82ang",
            "agoric1w8wktaur4zf8qmmtn3n7x3r0jhsjkjntcm3u6h",
            "agoric10vjkvkmpp9e356xeh6qqlhrny2htyzp8hf88fk",
            "agoric1qj07c7vfk3knqdral0sej7fa6eavkdn8vd8etf",
            "agoric1lw4e4aas9q84tq0q92j85rwjjjapf8dmnllnft",
            "agoric1ra0g6crtsy6r3qnpu7ruvm7qd4wjnznyzg5nu4",
            "agoric1zj6vrrrjq4gsyr9lw7dplv4vyejg3p8j2urm82",
            "agoric15xddzse9lq74cyt6ev9d7wywxerenxdgxsdc3m",
            "agoric1w5wmck6q2xrt20ax3njlk2k87m4t4l2y2xgw2d",
          ],
          priceAggregatorRef: {
            bundleID: "b1-8fb229296073327ed26d2a1ac56eda2bdc70c99d68621895a88f6cc09bce2defa3bd0894e97950e5a0696388193279c8f6b9399809611f8fec3ef5aeed355ba5",
          },
        },
      ]);
      const overrideManifest = {
        createPriceFeed: {
          consume: {
            agoricNamesAdmin: "priceFeed",
            board: "priceFeed",
            chainStorage: "priceFeed",
            chainTimerService: "priceFeed",
            client: "priceFeed",
            econCharterKit: "priceFeed",
            highPrioritySendersManager: "priceFeed",
            namesByAddressAdmin: "priceFeed",
            priceAuthority: "priceFeed",
            priceAuthorityAdmin: "priceFeed",
            startGovernedUpgradable: "priceFeed",
          },
          instance: {
            produce: "priceFeed",
          },
        },
        ensureOracleBrands: {
          namedVat: {
            consume: {
              agoricNames: "agoricNames",
            },
          },
          oracleBrand: {
            produce: "priceFeed",
          },
        },
      };

      // Make the behavior the completion value.
      (({
        manifestBundleRef,
        getManifestCall,
        overrideManifest,
        E,
        log = console.info,
        restoreRef: overrideRestoreRef,
      }) => {
        const { entries, fromEntries } = Object;

        // deeplyFulfilled is a bit overkill for what we need.
        const shallowlyFulfilled = async obj => {
          if (!obj) {
            return obj;
          }
          const ents = await Promise.all(
            entries(obj).map(async ([key, valueP]) => {
              const value = await valueP;
              return [key, value];
            }),
          );
          return fromEntries(ents);
        };

        /** @param {ChainBootstrapSpace & BootstrapPowers & { evaluateBundleCap: any }} allPowers */
        const behavior = async allPowers => {
          // NOTE: If updating any of these names extracted from `allPowers`, you must
          // change `permits` above to reflect their accessibility.
          const {
            consume: { vatAdminSvc, zoe, agoricNamesAdmin },
            evaluateBundleCap,
            installation: { produce: produceInstallations },
            modules: {
              utils: { runModuleBehaviors },
            },
          } = allPowers;
          const [exportedGetManifest, ...manifestArgs] = getManifestCall;

          /** @type {(ref: import\('./externalTypes.js').ManifestBundleRef) => Promise<Installation<unknown>>} */
          const defaultRestoreRef = async ref => {
            // extract-proposal.js creates these records, and bundleName is
            // the name under which the bundle was installed into
            // config.bundles
            const p =
              'bundleName' in ref
                ? E(vatAdminSvc).getBundleIDByName(ref.bundleName)
                : ref.bundleID;
            const bundleID = await p;
            const label = bundleID.slice(0, 8);
            return E(zoe).installBundleID(bundleID, label);
          };
          const restoreRef = overrideRestoreRef || defaultRestoreRef;

          // Get the on-chain installation containing the manifest and behaviors.
          console.info('evaluateBundleCap', {
            manifestBundleRef,
            exportedGetManifest,
            vatAdminSvc,
          });
          let bcapP;
          if ('bundleName' in manifestBundleRef) {
            bcapP = E(vatAdminSvc).getNamedBundleCap(manifestBundleRef.bundleName);
          } else {
            bcapP = E(vatAdminSvc).getBundleCap(manifestBundleRef.bundleID);
          }
          const bundleCap = await bcapP;

          const manifestNS = await evaluateBundleCap(bundleCap);

          console.error('execute', {
            exportedGetManifest,
            behaviors: Object.keys(manifestNS),
          });
          const {
            manifest,
            options: rawOptions,
            installations: rawInstallations,
          } = await manifestNS[exportedGetManifest](
            harden({ restoreRef }),
            ...manifestArgs,
          );

          // Await references in the options or installations.
          const [options, installations] = await Promise.all(
            [rawOptions, rawInstallations].map(shallowlyFulfilled),
          );

          // Publish the installations for behavior dependencies.
          const installAdmin = E(agoricNamesAdmin).lookupAdmin('installation');
          await Promise.all(
            entries(installations || {}).map(([key, value]) => {
              produceInstallations[key].resolve(value);
              return E(installAdmin).update(key, value);
            }),
          );

          // Evaluate the manifest for our behaviors.
          return runModuleBehaviors({
            allPowers,
            behaviors: manifestNS,
            manifest: overrideManifest || manifest,
            makeConfig: (name, _permit) => {
              log('coreProposal:', name);
              return { options };
            },
          });
        };

        // Make the behavior the completion value.
        return behavior;
      })({ manifestBundleRef, getManifestCall, overrideManifest, E });
    json_permits: |-
      {
        "consume": {
          "agoricNamesAdmin": "priceFeed",
          "board": "priceFeed",
          "chainStorage": "priceFeed",
          "chainTimerService": "priceFeed",
          "client": "priceFeed",
          "econCharterKit": "priceFeed",
          "highPrioritySendersManager": "priceFeed",
          "namesByAddressAdmin": "priceFeed",
          "priceAuthority": "priceFeed",
          "priceAuthorityAdmin": "priceFeed",
          "startGovernedUpgradable": "priceFeed",
          "vatAdminSvc": "makeCoreProposalBehavior",
          "zoe": "makeCoreProposalBehavior"
        },
        "instance": {
          "produce": "priceFeed"
        },
        "namedVat": {
          "consume": {
            "agoricNames": "agoricNames"
          }
        },
        "oracleBrand": {
          "produce": "priceFeed"
        },
        "evaluateBundleCap": "makeCoreProposalBehavior",
        "installation": {
          "produce": "makeCoreProposalBehavior"
        },
        "modules": {
          "utils": {
            "runModuleBehaviors": "makeCoreProposalBehavior"
          }
        }
      }
  title: Enable stATOM1 Vault
deposit_end_time: "2023-08-24T22:49:12.752428747Z"
final_tally_result:
  abstain: "0"
  "no": "0"
  no_with_veto: "0"
  "yes": "200000000"
proposal_id: "5"
status: PROPOSAL_STATUS_PASSED
submit_time: "2023-08-22T22:49:12.752428747Z"
total_deposit:
- amount: "1000000"
  denom: ubld
voting_end_time: "2023-08-22T22:54:12.752428747Z"
voting_start_time: "2023-08-22T22:49:12.752428747Z"

@dckc
Copy link
Member

dckc commented Aug 24, 2023

We did a recorded demo and discussion in Aug 23 Office Hours.

@dckc
Copy link
Member

dckc commented Aug 24, 2023

discussed with @otoole-brendan ... this concludes the engineering work. There's perhaps some product follow-up in the community forum to make it easier to find.

@dckc dckc closed this as completed Aug 24, 2023
@dckc dckc changed the title live demo of adding stATOM how to add stATOM: training materials Aug 28, 2023
@dckc
Copy link
Member

dckc commented Aug 31, 2023

community forum follow-up:

@dckc dckc changed the title how to add stATOM: training materials how to add collateral (e.g. stATOM): training materials Aug 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants