Write and deploy assertions
The Credible Layer is security infrastructure built by Phylax Systems that lets you define security rules for your smart contracts and enforce them at the network level. When a transaction violates your rules, it's dropped before it can executeβpreventing exploits rather than detecting them after the damage is done.
You write rules in Solidity (called assertions), and no contract modifications are required. This means you can add protection to any contract, including immutable ones.
How the Credible Layer worksβ
The Credible Layer runs as a sidecar alongside the network's sequencer. When you deploy assertions, they're registered on-chain and the sidecar validates every transaction against them during block production.
The flow:
- User submits a transaction to the network
- The sequencer passes it to the Assertion Enforcer (sidecar) for validation
- The sidecar simulates the transaction and runs all relevant assertions
- If assertions pass β transaction is included in the block
- If any assertion fails β transaction is dropped and never executes.
This flow adds no new trust assumptions: if you trust the network to include your transactions, you can trust it to enforce your assertions.
For full architecture details, see Architecture Overview.
What assertions can doβ
Assertions have capabilities that regular Solidity contracts don't, including:
- Compare before/after states β Use
ph.forkPreTx()andph.forkPostTx()to check how a transaction changes state - Protect immutable contracts β Add security rules without modifying or redeploying contracts
- Inspect nested calls β Use
ph.forkPreCall()andph.forkPostCall()to examine state around specific function calls within a transaction - Run complex validation β Execute assertions off-chain with higher gas limits than typical on-chain operations.
Use casesβ
Assertions can protect against a wide range of issues:
- Parameter protection β Prevent unauthorized changes to owner addresses, implementation contracts, or protocol settings
- Price manipulation β Ensure prices don't move beyond specified thresholds in a single transaction
- Lending safety β Guarantee positions maintain required collateralization ratios
- Balance invariants β Verify that token balances remain consistent (e.g., sum of positions equals total supply)
- Oracle validation β Detect suspicious oracle price deviations.
For real-world examples, see the Assertions Book and Previous Hacks that assertions would have prevented.
Quick startβ
The following guide walks you through creating a project and deploying assertions with the Credible Layer.
Prerequisitesβ
Before you begin, make sure you have:
- Foundry installed
- The
pclCLI installed (see below) - A way to sign transactions in your browser (MetaMask or similar).
Install pclβ
brew tap phylaxsystems/pcl
brew install phylax
Verify installation:
pcl --version
For other installation methods, see the Installation Guide.
Clone the starter projectβ
To get started, clone the starter project:
git clone --recurse-submodules https://github.com/phylaxsystems/credible-layer-starter
cd credible-layer-starter
This includes example contracts and assertions you can deploy immediately.
Understand the ownable assertion contractβ
The starter project includes an assertion that prevents unauthorized ownership changes. Here's what it looks like:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {Assertion} from "credible-std/Assertion.sol";
import {Ownable} from "../../src/Ownable.sol";
contract OwnableAssertion is Assertion {
function triggers() external view override {
registerCallTrigger(this.assertionOwnershipChange.selector, Ownable.transferOwnership.selector);
}
function assertionOwnershipChange() external {
Ownable ownable = Ownable(ph.getAssertionAdopter());
ph.forkPreTx();
address preOwner = ownable.owner();
ph.forkPostTx();
address postOwner = ownable.owner();
require(postOwner == preOwner, "Ownership has changed");
}
}
How it works:
triggers()registers when the assertion runsβhere, whenevertransferOwnershipis calledph.forkPreTx()switches to the state before the transactionph.forkPostTx()switches to the state after the transaction- If the owner changed, the
requirefails and the transaction is dropped.
For a detailed walkthrough, see Write Your First Assertion.
To test this assertion run the following:
pcl test
You should see output like:
[PASS] test_assertionOwnershipChanged() (gas: 806650)
[PASS] test_assertionOwnershipNotChanged() (gas: 804708)
Suite result: ok. 2 passed; 0 failed; 0 skipped
For more on testing, see Testing Assertions.
Deploy your contractβ
Deploy the Ownable contract to the network:
forge script script/DeployOwnable.s.sol \
--rpc-url <RPC_URL> \
--sender <DEPLOYER_ADDRESS> \
--private-key <PRIVATE_KEY> \
--broadcast
Note the Deployed to: address, you'll need it later.
Authenticate and create a projectβ
To authenticate with the Credible Layer, run:
pcl auth login
This opens a browser window. Sign in and create a new project, then link your deployed contract address to it.
Store and submit your assertionβ
To deploy an assertion, you first need to store the assertion in the Assertion Data Availability layer:
pcl store OwnableAssertion
Then, submit it to your project:
pcl submit -a 'OwnableAssertion' -p <project_name>
Replace <project_name> with the name of the project you created.
Deploy the assertionβ
Return to the browser window from pcl auth login and navigate to your project. You'll see the
assertion ready for deployment. Review and deploy it to activate protection.
After a timelock period, your assertion becomes enforced and will actively protect your contract.
For the full deployment process, see Deploy Assertions.
Verify it worksβ
Once the assertion is enforced, test that it's protecting your contract:
# Check current owner
cast call <CONTRACT_ADDRESS> "owner()" --rpc-url <RPC_URL>
# Attempt to transfer ownership (this should timeout/fail)
cast send <CONTRACT_ADDRESS> "transferOwnership(address)" <NEW_ADDRESS> \
--rpc-url <RPC_URL> \
--private-key <OWNER_PRIVATE_KEY>
The ownership transfer should timeout, confirming the assertion blocked it.
Learn moreβ
- Quickstart Guide β Full walkthrough of the development process
- High-Level Overview β How the Credible Layer prevents exploits
- Architecture Overview β Technical deep dive into system design and transaction flow
- Assertions Book β Real-world assertion examples
- Previous Hacks β See how assertions would have prevented major exploits
- CLI Reference β Full
pclcommand reference - Cheatcodes Reference β All available assertion cheatcodes