Skip to content

Instantly share code, notes, and snippets.

@tgrecojs
Created January 31, 2023 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tgrecojs/d0ea0023387fb17622f17d1ac67f22e3 to your computer and use it in GitHub Desktop.
Save tgrecojs/d0ea0023387fb17622f17d1ac67f22e3 to your computer and use it in GitHub Desktop.
import { assert } from './util'
const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);
// const { proxy: accountProxy, revoke: revokeAccount } = Proxy.revocable(objProto, {});
// Reflect.get(accountProxy, 'balance')
// objProto.deposit(10000)
// Reflect.get(accountProxy,'balance')
// revokeAccount()
// adds the .constructor property to all instances.
const withConstructor = constructor => o => ({
// create the delegate [[Prototype]]
__proto__: {
// add the constructor prop to the new [[Prototype]]
constructor
},
// mix all o's props into the new object
...o
});
// const pipe = (...fns) => x => fns.reduce((y, f) => f(y), x);
const statusStrings = {
ACTIVE: 'ACTIVE',
INACTIVE: 'INACTIVE',
LIQUIDATING: 'LIQUIDATING',
CLOSED: 'CLOSED'
}
const accountStateMachine = {
state: statusStrings.INACTIVE,
transitions: {
inactive: {
enable() {
this.state = statusStrings.ACTIVE;
return this.state
}
},
active: {
disable() {
this.state = statusStrings.INACTIVE
return this.state
},
liquidate() {
this.state = statusStrings.LIQUIDATING
}
}
}
}
assert({
given: 'accountStateMachine ::: transitions.inactive.enable()',
should: 'properly transition from inactive to active.',
actual: accountStateMachine.transitions.inactive.enable(),
expected: statusStrings.ACTIVE
}) //?
assert({
given: 'accountStateMachine ::: transitions.inactive.disable()',
should: 'properly transition from active to inactive.',
actual: accountStateMachine.transitions.active.disable(),
expected: statusStrings.INACTIVE
}) //?
const poolStatuses = {
[statusStrings.INACTIVE]: {
[statusStrings.ACTIVE]: {
[statusStrings.LIQUIDATING]: [statusStrings.LIQUIDATING],
[statusStrings.CLOSED]: [statusStrings.CLOSED],
[statusStrings.INACTIVE]: [statusStrings.INACTIVE]
}
}
}
// publficMethods - "public facet"
// contains methods we can safely expose to the public.
const publicMethods = {
viewDebtIssuers() {
return this.debtTokenIssuers
}
}
const addKeyToObject = (newObj = {}) => obj => ({
...obj,
[newObj.key]: marketObject
})
const withPoolManagerPowers = o => {
console.log({ o })
let poolStatus = poolStatuses.INACTIVE;
let marketMap = {};
const addMarketFn = addKeyToObject(marketMap);
return {
...o,
poolStatus,
getDebtTokenIssuer(keyword) {
const current = this.debtTokenIssuers[keyword];
return this.debtTokenIssuers[keyword]
},
publishMetrics() {
},
activatePool() {
this.poolStatus = poolStatus.ACTIVE;
},
supplyLiquidity() {
},
removeLiquidity() {
},
setMarketParams() {
},
adjustMarketParams() {
},
addMarketFn,
logThis() {
console.log('logging context :::', this);
return
}
}
}
const helpersFacet = {
logThis() {
console.log('logging context :::', this, this.constructor);
return this
},
logConstructor() {
console.log('logging .constructor property :::', this.constructor);
return this.constructor
}
}
const withAccount = o => {
let balance = 0;
return {
...o,
...helpersFacet,
stateMachine: ({
...accountStateMachine,
state: accountStateMachine.transitions.inactive.enable()
}),
balance,
setName(newName) {
console.log(this)
return this.name = newName
},
getBalance() {
return this.balance
}
}
}
const liAtomIssuer = {
issuer: {
brand: 'LARI DAO INTEREST BEARING ATOM',
},
mint: {
updateSupply(x) {
this.totalAmountMinted += x;
this.supplyAvailable += x;
return ({
amount: x,
message: `update success. ${x} tokens have been redeemed.`
})
},
totalAmountMinted: 0,
supplyAvailable: 0,
mintTokens(x) {
// console.log('minting token #',this.supply)
return x > 0 ? this.updateSupply(x) : Error('The requested amount is not available for redemption.');
},
redeemTokens(x) {
return this.supplyAvailable - x >= 0 ? this.updateSupply(x) :
Error('The requested amount is not available for redemption.')
}
}
}
liAtomIssuer.mint.mintTokens(10)
assert({
given: 'atomIssuer object ::: .supply',
should: 'return the correct number of tokens.',
actual: liAtomIssuer.mint.totalAmountMinted,
expected: 10
})//?
const { amount: tenTokens, message: tenTokensMsg } = liAtomIssuer.mint.redeemTokens(10)
assert({
given: 'atomIssuer object ::: .redeemTokens(10)',
should: 'return an object with an .amount property equal to the amount of tokens being redeemed.',
actual: tenTokens,
expected: 10
})//?
assert({
given: 'atomIssuer object ::: .redeemTokens(10)',
should: 'return an object with a message property with the default success message.',
actual: tenTokensMsg,
expected: 'update success. 10 tokens have been redeemed.'
})//?
assert({
given: 'atomIssuer object ::: totalSupplyAvaiable property',
should: 'return the total number of tokens available to redeem.',
actual: liAtomIssuer.mint.supplyAvailable,
expected: 20
})//?
assert({
given: 'atomIssuer object ::: supply property',
should: 'return the total number of tokens available to redeem.',
actual: liAtomIssuer.mint.totalAmountMinted,
expected: 20
})//?
const makeDistribuableAccountObject = (obj = {}) => compose(
withConstructor(makeDistribuableAccountObject),
withAccount
)({ ...obj })
const myAccount = makeDistribuableAccountObject({
walletAddress: '0xTG Wallet',
nickname: 'Agoric Lending Wallet'
}) //?
assert({
given: 'makeDistribuableAccountObject fn',
should: 'return return an active account object.',
actual: myAccount.stateMachine.state,
expected: statusStrings.ACTIVE
})//?
assert({
given: 'account object ::: logConstructor',
should: 'evaluate to be equal to the makeDistribuableAccountObject function.',
actual: myAccount.logConstructor() === makeDistribuableAccountObject,
expected: true,
})
const makePoolManager = (o) =>
compose(withConstructor(makePoolManager), withAccount,
withPoolManagerPowers)({
...o,
pubicFacet: publicMethods,
debtTokenIssuers: { atoms: liAtomIssuer }
})
const managerAcct = makePoolManager({
stateMachine: {
...accountStateMachine, state: statusStrings.ACTIVE
}
})
const { mint: liAtomMintObj, issuer } = managerAcct.getDebtTokenIssuer('atoms')
const assert = ({given, should, actual, expected}) => {
const stringify = value => Array.isArray(value) ?
`[${ value.map(stringify).join(',') }]` :
`${ value }`;
const actualString = stringify(actual);
const expectedString = stringify(expected);
if (actualString === expectedString) {
console.log(`OK:
given: ${ given }
should: ${ should }
actual: ${ actualString }
expected: ${ expectedString }
`);
} else {
throw new Error(`NOT OK:
given ${ given }
should ${ should }
actual: ${ actualString }
expected: ${ expectedString }
`);
}
};
const compose = (...fns) => x => fns.reduceRight((y, f) => f(y), x);
export { assert, compose }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment