1 of 48

An Introduction to

SPICE and TokenSPICE

[long version]

https://github.com/oceanprotocol/tokenspice

June 24, 2021

Trent McConaghy

@trentmc0 @oceanprotocol

2 of 48

Outline

  • (Analog) Electrical Engineering
    • Pure Manual
    • Manual + basic SPICE
    • Manual + SPICE-in-the-loop
  • Token Engineering
    • Pure Manual
    • Manual + basic TokenSPICE
    • Manual + TokenSPICE-in-the-loop
  • TokenSPICE details

3 of 48

SPICE & Analog Electrical Engineering

4 of 48

Analog Circuit Design

This is a CMOS OTA. An amplifier, basically.

How to maximize its gain * bandwidth (GBW)?

5 of 48

Pure Manual Analog Circuit Design - Systematized

6 of 48

Pure Manual Analog Circuit Design - Systematized

7 of 48

Analog Circuit Verification

How to verify the design?

8 of 48

SPICE!

Larry Nagel

Ron Rohrer

SPICE

9 of 48

Manual + Basic SPICE Circuit Simulation

Enter netlist (schematic editor, or write)

Manual design

SPICE sample circuit - diode clamp

*independent voltage source with DC value, AC value, and

*transient square wave. -10V to +20V extent, with 2ms period

V1 1 0 1 AC 1 pulse -10 20 0 1.e-8 1.e-8 1e-3 2e-3

*capacitor for clamping

C1 1 2 1e-6

*diode for clamp - model name is dclamp

D1 2 0 dclamp

*load resistor - large enought that RC >> 2 ms

*model for diode

.model dclamp D(IS=1e-14)

*DC transfer function generated for this circuit

.DC V1 -20 20 .1

*AC frequency sweep - assumes circuit is biased with V1 =

Run SPICE

10 of 48

Example SPICE Netlist

SPICE sample circuit - diode clamp

*independent voltage source with DC value, AC value, and

*transient square wave. -10V to +20V extent, with 2ms period

V1 1 0 1 AC 1 pulse -10 20 0 1.e-8 1.e-8 1e-3 2e-3

*capacitor for clamping

C1 1 2 1e-6

*diode for clamp - model name is dclamp

D1 2 0 dclamp

*load resistor - large enought that RC >> 2 ms

R1 2 0 1e5

*model for diode

.model dclamp D(IS=1e-14)

*DC transfer function generated for this circuit

.DC V1 -20 20 .1

*AC frequency sweep - assumes circuit is biased with V1 = 1V

*frequency is swept logarithmically from 100Hz to 10000Hz

.AC OCT 20 10 1e2 1e4

*transient analysis will show clamping

*start at time zero, go for 8 ms, make internal steps 10 microsec

*save print data at .1 ms intervals

.TRAN 1e-4 8e-3 0 1e-5

.end

11 of 48

SPICE-in-the-loop Tools

Design / verification tool

(Manual and/or automatic)

Choose next sim(s),

write netlist

Manual initial design

SPICE sample circuit - diode clamp

*independent voltage source with DC value, AC value, and

*transient square wave. -10V to +20V extent, with 2ms period

V1 1 0 1 AC 1 pulse -10 20 0 1.e-8 1.e-8 1e-3 2e-3

*capacitor for clamping

C1 1 2 1e-6

*diode for clamp - model name is dclamp

D1 2 0 dclamp

*load resistor - large enought that RC >> 2 ms

*model for diode

.model dclamp D(IS=1e-14)

*DC transfer function generated for this circuit

.DC V1 -20 20 .1

*AC frequency sweep - assumes circuit is biased with V1 =

Run SPICE

12 of 48

Example: Design with SPICE-in-the-loop

Solido Fast Design Sweep: model-based design space exploration

13 of 48

Example: Verification with SPICE-in-the-loop

Solido Fast PVT: Worst-case analysis via global optimization

14 of 48

Example: Extract Symbol Models of Circuits

15 of 48

Example: Synthesis of Analog Circuits

16 of 48

More SPICE-in-the-loop tools

Verification

  • Nominal - no variation
  • Corner extraction - finding representative env or rnd “corners”
  • Worst-case analysis - verification across worst-case envvars
  • Monte Carlo simulation - sampling from rnd distribution. On >=1 env corners.
  • High-sigma Monte Carlo, Hierarchical Monte Carlo, etc
  • Extract symbolic models, system identification

Design

  • Design sweep, sensitivity analysis, fast design sweep
  • Local optimization - wiggle controllable params to optimize for objectives & constraints
  • Global optimization - “”, with affordances to not get stuck
  • Synthesis - “” but wiggle code structure itself in addition to parameters
  • Variation-aware synthesis - all of the above at once

17 of 48

TokenSPICE

& Token Engineering

18 of 48

Outline

  • (Analog) Electrical Engineering
    • Pure Manual
    • Manual + basic SPICE
    • Manual + SPICE-in-the-loop
  • Token Engineering
    • Pure Manual
    • Manual + basic TokenSPICE
    • Manual + TokenSPICE-in-the-loop
  • TokenSPICE details

19 of 48

TE Verification is a lot like Circuit Verification

20 of 48

A Token Engineering Process

  1. Set Goals - objectives & constraints.
  2. Design - explore design space to achieve the goals. Update goals as needed.
  3. Verify - does design work? Update goals or design as needed.
    1. Manual
    2. Software-based: spreadsheet -> agent-based sim -> agent-based EVM sim
    3. Economic: ratchet up value-at-risk over time
  4. Maintain / tune

References:

21 of 48

A Token Engineering Process

  • Set Goals - objectives & constraints.
  • Design - explore design space to achieve the goals. Update goals as needed.
  • Verify - does design work? Update goals or design as needed.
    • Manual
    • Software-based: spreadsheet -> agent-based sim -> agent-based EVM sim
    • Economic: ratchet up value-at-risk over time
  • Maintain / tune

References:

22 of 48

Manual + Basic TokenSPICE Simulation

Enter netlist (schematic editor, or write)

Manual design

new_agents.add(MarketplacesAgent(

name = "marketplaces1", USD=0.0, OCEAN=0.0,

toll_agent_name = "opc_address",

n_marketplaces = float(ss.init_n_marketplaces),

revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,

time_step = self.ss.time_step,

))

new_agents.add(RouterAgent(

name = "opc_address", USD=0.0, OCEAN=0.0,

receiving_agents = {"ocean_dao" : self.percentToOceanDao,

"opc_burner" : self.percentToBurn}))

new_agents.add(OCEANBurnerAgent(

name = "opc_burner", USD=0.0, OCEAN=0.0))

#func = MinterAgents.ExpFunc(H=4.0)

func = MinterAgents.RampedExpFunc(H=4.0,

T0=0.5, T1=1.0, T2=1.4, T3=3.0,

M1=0.10, M2=0.25, M3=0.50)

new_agents.add(MinterAgents.OCEANFuncMinterAgent(

name = "ocean_51",

receiving_agent_name = "ocean_dao",

total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,

s_between_mints = S_PER_DAY,

func = func))

Run TokenSPICE

new_agents.add(MarketplacesAgent(

name = "marketplaces1", USD=0.0, OCEAN=0.0,

toll_agent_name = "opc_address",

n_marketplaces = float(ss.init_n_marketplaces),

revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,

time_step = self.ss.time_step,

))

new_agents.add(RouterAgent(

name = "opc_address", USD=0.0, OCEAN=0.0,

receiving_agents = {"ocean_dao" : self.percentToOceanDao,

"opc_burner" : self.percentToBurn}))

new_agents.add(OCEANBurnerAgent(

name = "opc_burner", USD=0.0, OCEAN=0.0))

#func = MinterAgents.ExpFunc(H=4.0)

func = MinterAgents.RampedExpFunc(H=4.0,

T0=0.5, T1=1.0, T2=1.4, T3=3.0,

M1=0.10, M2=0.25, M3=0.50)

new_agents.add(MinterAgents.OCEANFuncMinterAgent(

name = "ocean_51",

receiving_agent_name = "ocean_dao",

total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,

s_between_mints = S_PER_DAY,

func = func))

Python

Solidity

+

23 of 48

Manual + Basic TokenSPICE Simulation

Enter netlist (schematic editor, or write)

Manual design

new_agents.add(MarketplacesAgent(

name = "marketplaces1", USD=0.0, OCEAN=0.0,

toll_agent_name = "opc_address",

n_marketplaces = float(ss.init_n_marketplaces),

revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,

time_step = self.ss.time_step,

))

new_agents.add(RouterAgent(

name = "opc_address", USD=0.0, OCEAN=0.0,

receiving_agents = {"ocean_dao" : self.percentToOceanDao,

"opc_burner" : self.percentToBurn}))

new_agents.add(OCEANBurnerAgent(

name = "opc_burner", USD=0.0, OCEAN=0.0))

#func = MinterAgents.ExpFunc(H=4.0)

func = MinterAgents.RampedExpFunc(H=4.0,

T0=0.5, T1=1.0, T2=1.4, T3=3.0,

M1=0.10, M2=0.25, M3=0.50)

new_agents.add(MinterAgents.OCEANFuncMinterAgent(

name = "ocean_51",

receiving_agent_name = "ocean_dao",

total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,

s_between_mints = S_PER_DAY,

func = func))

Run TokenSPICE

new_agents.add(MarketplacesAgent(

name = "marketplaces1", USD=0.0, OCEAN=0.0,

toll_agent_name = "opc_address",

n_marketplaces = float(ss.init_n_marketplaces),

revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,

time_step = self.ss.time_step,

))

new_agents.add(RouterAgent(

name = "opc_address", USD=0.0, OCEAN=0.0,

receiving_agents = {"ocean_dao" : self.percentToOceanDao,

"opc_burner" : self.percentToBurn}))

new_agents.add(OCEANBurnerAgent(

name = "opc_burner", USD=0.0, OCEAN=0.0))

#func = MinterAgents.ExpFunc(H=4.0)

func = MinterAgents.RampedExpFunc(H=4.0,

T0=0.5, T1=1.0, T2=1.4, T3=3.0,

M1=0.10, M2=0.25, M3=0.50)

new_agents.add(MinterAgents.OCEANFuncMinterAgent(

name = "ocean_51",

receiving_agent_name = "ocean_dao",

total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,

s_between_mints = S_PER_DAY,

func = func))

Python

Solidity

+

EVM!

24 of 48

Example TokenSPICE Netlist

Python

Solidity

+

25 of 48

TokenSPICE-in-the-loop

Design / verification tool

(Manual and/or automatic)

Choose next sim(s),

write netlist

Manual initial design

Run TokenSPICE

new_agents.add(MarketplacesAgent(

name = "marketplaces1", USD=0.0, OCEAN=0.0,

toll_agent_name = "opc_address",

n_marketplaces = float(ss.init_n_marketplaces),

revenue_per_marketplace_per_s = 20e3 / S_PER_MONTH,

time_step = self.ss.time_step,

))

new_agents.add(RouterAgent(

name = "opc_address", USD=0.0, OCEAN=0.0,

receiving_agents = {"ocean_dao" : self.percentToOceanDao,

"opc_burner" : self.percentToBurn}))

new_agents.add(OCEANBurnerAgent(

name = "opc_burner", USD=0.0, OCEAN=0.0))

#func = MinterAgents.ExpFunc(H=4.0)

func = MinterAgents.RampedExpFunc(H=4.0,

T0=0.5, T1=1.0, T2=1.4, T3=3.0,

M1=0.10, M2=0.25, M3=0.50)

new_agents.add(MinterAgents.OCEANFuncMinterAgent(

name = "ocean_51",

receiving_agent_name = "ocean_dao",

total_OCEAN_to_mint = UNMINTED_OCEAN_SUPPLY,

s_between_mints = S_PER_DAY,

func = func))

function swapExactAmountOut(

address tokenIn,

uint maxAmountIn,

address tokenOut,

uint tokenAmountOut,

uint maxPrice

)

external

_logs_

_lock_

returns (uint tokenAmountIn, uint spotPriceAfter)

{

require(_records[tokenIn].bound, 'ERR_NOT_BOUND');

require(_records[tokenOut].bound, 'ERR_NOT_BOUND');

require(_publicSwap, 'ERR_SWAP_NOT_PUBLIC');

Record storage inRecord = _records[address(tokenIn)];

Record storage outRecord = _records[address(tokenOut)];

require(

tokenAmountOut <= bmul(outRecord.balance, MAX_OUT_RATIO),

'ERR_MAX_OUT_RATIO'

);

uint spotPriceBefore = calcSpotPrice(

...

Python

Solidity

+

26 of 48

Potential TokenSPICE-in-the-loop tools

Verification

  • Nominal - no variation
  • Corner extraction - finding representative env or rnd “corners”
  • Worst-case analysis - verification across worst-case envvars
  • Monte Carlo simulation - sampling from rnd distribution. On >=1 env corners.
  • High-sigma Monte Carlo, Hierarchical Monte Carlo, etc
  • Extract symbolic models, system identification

Design

  • Design sweep, sensitivity analysis, fast design sweep
  • Local optimization - wiggle controllable params to optimize for objectives & constraints
  • Global optimization - “”, with affordances to not get stuck
  • Synthesis - “” but wiggle code structure itself in addition to parameters
  • Variation-aware synthesis - all of the above at once. Example: use MOJITO (http://trent.st/mojito/), but use TokenSPICE (not SPICE) and Solidity building blocks (not circuit ones)

27 of 48

Zooming In On TokenSPICE

28 of 48

Conclusion

  • (Analog) Electrical Engineering
    • Pure Manual
    • Manual + basic SPICE
    • Manual + SPICE-in-the-loop
  • Token Engineering
    • Pure Manual
    • Manual + basic TokenSPICE
    • Manual + TokenSPICE-in-the-loop
  • TokenSPICE details

29 of 48

30 of 48

31 of 48

32 of 48

Example TokenSPICE Sim Results

(non-EVM results shown, EVM is WIP)

33 of 48

Example sim: Monthly R&D Spend

34 of 48

Example sim: Marketplaces Growth Rate

35 of 48

Example sim: Token count

36 of 48

Example sim: Monthly # OCEAN minted & burned

37 of 48

Example sim: DAO Income

38 of 48

TokenSPICE Variables

39 of 48

TokenSPICE with EVM

  • Each Agent has an AgentWallet.
  • Now, AgentWallet is the main bridge between higher-level Python and EVM.
  • Each AgentWallet holds a Web3Wallet.
  • The Web3Wallet holds a private key and creates TXs.

40 of 48

TokenSPICE with EVM

Top-level agent architecture

  • All agents inherit BaseAgent
  • Controllable agents use EVM.
  • Uncontrollable agents use pure Python. But each has EOA.
    • Therefore the core dynamics are still on-chain

Controllables

Controllable agents (structure):

  • What agents: just Pool (incl. Strategies and Pool Controllers).
  • The agent's state is stored on blockchain. Deployment is not in the scope of TokenSPICE right now. TokenSPICE just sees ABIs.
  • PoolAgent.py wraps BPool.sol. Agent's wallet grabs values from BPool.sol
    • current design (.sol) is at oceanprotocol/contracts
    • new design (.sol) is at branch 'feature/1mm-prototype_alex'
    • how can PoolAgent see it? draw on btoken.py etc.

Controllable variables:

  • Global design vars. E.g. schedule for token distribution.
  • Design vars within controllable agents

41 of 48

TokenSPICE with EVM

Uncontrollables

Uncontrollable Agents:

  • Uncontrollable agents use pure Python. But each has an Externally Owned Address (EOA) to interact w EVM. Implemented inside Wallet.
  • What agents:
    • Status quo design: Publisher, Dataconsumer, Stakerspeculator
    • New design 1: Publisher, Dataconsumer, Staker, Speculator

Uncontrollable Variables (Env & rnd structure & params)

  • Global rndvars & envvars.
  • Rndvars and envvars within controllable agents
  • Rndvars and envvars within uncontrollable agents
  • Ranges for envvars, and parameters for rndvar pdfs, are in constants.py, etc.

Metrics

  • These are what's output by SimEngine.py into the CSV, then plotted
  • In the future, we could get fancier by leveraging TheGraph.

42 of 48

Benefits of EVM agent simulation

TokenSPICE and other EVM agent-based simulators have these benefits:

  • Faster and less error prone, because the model = the Solidity code. Don’t have to port any existing Solidity code into Python, just wrap it. Don’t have to write lower-fidelity equations..
  • Enables rapid iterations of writing Solidity code -> simulating -> changing Solidity code -> simulating. At both the parameter level and the structural level.
  • Can quickly integrate Balancer V2 code. Then extend to model other AMMs. And other DeFi code. Etc etc.
  • Plays well with other pure Python agents. Each agent can wrap Solidity, or be pure Python.
  • Super high fidelity simulations, since it uses the actual code itself. Enables modeling of uncontrollable variables, both random (probabilistic) ones and worst-case ones.
  • Can build higher-level CAD tools, that have TokenSPICE in the loop
  • Mental model is general enough to extend to Vyper, LLL, and direct EVM bytecode. Can extend to non-EVM blockchain, and multi-chain scenarios. Can extend to work with hierarchical building blocks.
  • Can also do real-time analysis / optimization / etc against live chains: grab the latest chain’s snapshot into ganache, run a local analysis / optimization etc for a few seconds or minutes, then do transaction(s) on the live chain. This can lead to trading systems, failure monitoring, more.

43 of 48

TokenSPICE Planning

44 of 48

TokenSPICE holds promise. But, the code is young! Software engineering work to be done. It can evolve into something exciting:)

Nearer-term tasks:

  1. Get some overall loop running that includes at least one EVM agent #34
  2. Be able to specify a netlist and run, without having to fork #30
  3. Improve Continuous Integration

45 of 48

TokenSPICE Planning: Research 1/2

Via https://github.com/oceanprotocol/tokenspice

  1. System identification: high-fidelity model of Ocean V3 (w/ Balancer V1); fit the model to observed on-chain dynamics
  2. Verification: high-fidelity model of Ocean V4.1 (w/ Balancer V2) base design, and the efficacy of each proposed mechanism.
  3. Design space exploration: tuning of Ocean V4.1 (w/ Balancer V2 design. Manual or optimization-based.

46 of 48

TokenSPICE Planning: Research 2/2

  • System identification: high-fidelity model of whole Balancer V1 ecosystem; fit the model to observed on-chain dynamics (up to when V2 released). Bring in uncontrollable variables (probabilistic & worst-case).
  • System identification: high-fidelity model of whole Balancer V1 & V2 ecosystem; fit the model to observed on-chain dynamics
  • Design space exploration: tuning of Balancer V2 Strategies to minimize IL and other objectives & constraints. Account for uncontrollable variables (probabilistic & worst-case).
  • Synthesis / Open-ended design space exploration: evolve solidity or EVM bytecode, go nuts. AI DAOs that own themselves. Fastest path = use http://trent.st/mojito, hook in TokenSPICE, add Solidity building blocks. This will be fun:). But one step at a time.

47 of 48

Conclusion

48 of 48

Conclusion

  • (Analog) Electrical Engineering
    • Pure Manual
    • Manual + basic SPICE
    • Manual + SPICE-in-the-loop
  • Token Engineering
    • Pure Manual
    • Manual + basic TokenSPICE
    • Manual + TokenSPICE-in-the-loop
  • TokenSPICE details

Come try out TokenSPICE!

https://github.com/oceanprotocol/tokenspice