Skip to content

Commit

Permalink
feat: manage parameters for a contract
Browse files Browse the repository at this point in the history
closes #3186

outstanding issues:
 * should this validate types?
 * is there a clean way to assert something is an amount?
 * should managed amounts (and ratios) only set the value and leave
    the brand to the managed contract?
 * are there others types to add or remove?
  • Loading branch information
Chris-Hibbert committed Jul 13, 2021
1 parent 6e1a3b5 commit 85922fc
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
93 changes: 93 additions & 0 deletions packages/governance/src/param-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// @ts-check

import { makeStore } from '@agoric/store';
import { assert, details as X } from '@agoric/assert';
import { Nat } from '@agoric/nat';
import { assertIsRatio } from '@agoric/zoe/src/contractSupport';
import { AmountMath, looksLikeBrand } from '@agoric/ertp';

const ParamType = {
NAT: 'nat',
BIGINT: 'bigint',
STRING: 'string',
RATIO: 'ratio',
AMOUNT: 'amount',
BRAND: 'brand',
};
harden(ParamType);

function assertType(type, value, name) {
if (!type) {
// undefined type means don't verify. Did we omit an interesting type?
return;
}

switch (type) {
case ParamType.NAT:
Nat(value);
break;
case ParamType.BIGINT:
assert.typeof(value, 'bigint');
break;
case ParamType.STRING:
assert.typeof(value, 'string');
break;
case ParamType.RATIO:
assertIsRatio(value);
break;
case ParamType.AMOUNT:
// TODO(hibbert): is there a clean way to assert something is an amount?
// An alternate approach would be to say the contract knows the brand and
// the managed parameter only needs to supply the value.
assert(
AmountMath.isEqual(value, value),
X`value for ${name} must be an Amount, was ${value}`,
);
break;
case ParamType.BRAND:
assert(
looksLikeBrand(value),
X`value for ${name} must be a brand, was ${value}`,
);
break;
default:
assert.fail(X`unknown type guard ${type}`);
}
}

function parse(paramDesc) {
const bindings = makeStore('name');
const types = makeStore('name');

paramDesc.forEach(({ name, value, type }) => {
assert.typeof(name, 'string');
assertType(type, value, name);
bindings.init(name, value);
types.init(name, type);
});

return { bindings, types };
}

/** @type {BuildParamManager} */
function buildParamManager(paramDesc) {
const { bindings, types } = parse(paramDesc);

const publicFacet = {
lookup(name) {
return bindings.get(name);
},
};

const manager = {
update(name, value) {
assertType(types.get(name), value, name);
bindings.set(name, value);
},
};

return { publicFacet, manager };
}
harden(buildParamManager);

export { ParamType, buildParamManager };
1 change: 1 addition & 0 deletions packages/governance/test/unitTests/test-param-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { buildParamManager, ParamType } from '../../src/paramManager';
const BASIS_POINTS = 10_000;

test('params one Nat', async t => {

const numberKey = 'Number';
const numberDescription = {
name: numberKey,
Expand Down

0 comments on commit 85922fc

Please sign in to comment.