◇ OpenCyber Academy
Engineering · Chapter 27 · English

Chapter 27 — Web3, blockchain and cryptoasset security: control design

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 27 — Web3, blockchain and cryptoasset security: control design

Lesson map

Lesson 27 published. Map, example, EX079.

flowchart TD
  N0["Learning outcomes"]
  N1["27.1 Role policy"]
  N2["27.2 Checking configuration"]
  N3["Lab — Role policy check"]
  N4["27.3 Closing gaps"]
  N5["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5
  N5 --> EX["Worked example"]
  EX --> Q["Exercise EX079"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["27.1 Role policy"]
  N2["27.2 Checking configuration"]
  N3["Lab — Role policy check"]
  N4["27.3 Closing gaps"]
  N5["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> Q["EX079"]
[Learning outcomes]
    |
    v
[27.1 Role policy]
    |
    v
[27.2 Checking configuration]
    |
    v
[Lab — Role policy check]
    |
    v
[27.3 Closing gaps]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX079]

Learning outcomes

You will (1) design privileged-role controls; (2) check role configuration against policy; (3) close gaps before deployment.

27.1 Role policy

Jonas writes a role policy: any function that mints, upgrades, moves reserves or changes data sources or fees must require at least two signers and a timelock of at least 48 hours, except pause, which needs two signers but no timelock because its purpose is fast protection. The policy reflects EthTrust guidance on timelocks for sensitive operations and ConsenSys advice on restricting administrative power. Writing the policy as rules allows automatic checking of configurations against it. The board approves the policy as a formal document.

27.2 Checking configuration

Jonas writes a standard-library script that reads a synthetic inventory of privileged functions across four contracts, with controller type, signers required and timelock hours, and reports any function that breaks the policy. It only reads the inventory and prints findings for review. Configuration drift is common in practice: a function may be deployed with a temporary single key during testing and never moved to the multi-signature wallet. Jonas tests the script on a small inventory with known breaches first, then runs it against the full synthetic inventory and records the date of each run so later runs can show drift.

Lab — Role policy check

"""Privileged-role inventory check for synthetic contracts (read-only)."""
# contract, function, controller, signers needed, timelock hours
ROLES = [
    ("Credit", "mint", "multisig", 3, 48), ("Credit", "pause", "multisig", 2, 0),
    ("Credit", "upgrade", "multisig", 3, 48), ("Market", "setFee", "single", 1, 0),
    ("Market", "upgrade", "multisig", 3, 24), ("Oracle", "setSource", "single", 1, 0),
    ("Vault", "withdrawReserve", "multisig", 3, 72),
]
FUND_OR_CODE = {"mint", "upgrade", "withdrawReserve", "setSource", "setFee"}
MIN_TIMELOCK = 48

def main():
    for c, f, ctl, n, t in ROLES:
        notes = []
        if f in FUND_OR_CODE and n < 2:
            notes.append("single signer")
        if f in FUND_OR_CODE and t < MIN_TIMELOCK:
            notes.append(f"timelock {t}h < {MIN_TIMELOCK}h")
        if notes:
            print(f"{c}.{f}: {'; '.join(notes)}")
    print(f"privileged functions {len(ROLES)}; pause is exempt from timelock by design")

if __name__ == "__main__":
    main()

Run with python3 lab_roles.py. Verified output:

Market.setFee: single signer; timelock 0h < 48h
Market.upgrade: timelock 24h < 48h
Oracle.setSource: single signer; timelock 0h < 48h
privileged functions 7; pause is exempt from timelock by design

27.3 Closing gaps

The check reports three issues among seven privileged functions: Market.setFee has a single signer and no timelock; Market.upgrade has a 24-hour timelock, below the 48-hour policy; and Oracle.setSource has a single signer and no timelock. Pause is correctly exempt from the timelock. Jonas notes that setSource is the most serious because a changed data source could affect credit prices. The team moves both single-signer functions to the multi-signature wallet and sets timelocks to 48 hours before deployment, then reruns the check.

Worked example

The check finds three policy breaches among seven privileged functions, including single-signer control of Oracle.setSource; all are fixed and rechecked.

Synthetic case. Contracts and inventory are synthetic; EEA EthTrust and ConsenSys best practices are real sources.

Errors and limits

Leaving test-time single-key control on production functions is a common, avoidable gap.

Exercises

Synthesis

A written role policy checked automatically against configuration closes privileged-control gaps.

Continue studying — chapter 27 of 50

← Chapter 26 (draft) · Course chapter index · Chapter 28 (draft) →