Abstract
Pivot is a compact application ledger that replaces smart-contract bloat with a tiny set of deterministic system calls (verbs). Users onboard with OAuth/Passkeys; wallets are non-custodial by default. Token identity is bound to DNS - every token pairs a domain with a tokenId—so clones can’t masquerade as the original. Apps deploy as small declarative manifests and call audited verbs like bank.transfer or token.create. A simple PoA consensus achieves sub-second finality; DPoS is a clean upgrade path.
Introduction
General-purpose smart-contract platforms created power and complexity at once. Builders wrestle with VMs, toolchains, fees, and audits; users wrestle with seed phrases and opaque approvals. Pivot’s thesis: most consumer apps need a ledger, balances, and a few safe verbs — not a Turing-complete VM. Constrain the surface → ship faster, safer apps.
Design Principles
- Minimal surface. Prefer a few stable verbs over an unbounded VM.
- Non-custodial UX. OAuth/Passkeys unlock local keys; users hold custody.
- Determinism. Verbs are pure, bounded, and auditable.
- Domain identity. Token identity =
(domain, tokenId). - Progressive decentralization. PoA → DPoS when usage warrants.
- Builder-first. REST endpoints + SDK, not contract languages.
Identity & Non-Custodial Wallets
Goal: users own their assets without seed-phrase pain.
OAuth + Passkeys
- On first login (Google/Apple/Discord), the client generates a local keypair (Ed25519/WebAuthn).
- The private key stays on device (Secure Enclave/Keystore). OAuth proves identity to use the key; the key is not stored by Pivot.
- Power users can export keys; most never need to.
Recovery
- New device: re-login via OAuth → derive or rebind a new key (prior key can be revoked).
- Optional guardians: a small set of addresses approve recovery; enforced by the account module.
Domain-Verified Tokens
To defeat copycat tickers, Pivot ties token identity to domain ownership.
Binding Flow
- Challenge:
POST /v1/domain/request_challenge {domain}→{nonce}. - Prove: author sets
TXT _pivot-verify.<domain> = <nonce>. - Verify:
POST /v1/domain/verify {domain}→ on success, writedomain/<domain> = { owner: <address> }. - Create:
POST /v1/token/create { tokenId, domain, ... }allowed only to the verified owner.
UX rule: wallets/explorers display TICKER @ domain with a ✅ badge if a binding exists. Clones lack the badge.
State & Transactions
account/<addr>/balance— native cointoken/<id>/balances/<addr>— fungible balancesapp/<id>/manifest— declarative methods (≤ 8–16 KB)app/<id>/storage/<key>— app-scoped KV (bounded)domain/<domain>— domain ownership record
{
"from": "ADDR",
"nonce": 42,
"ttl": 60,
"calls": [ { "module": "bank", "fn": "transfer", "args": {"to":"ADDR2","amount":"1000"} } ],
"signature": "ed25519..."
}
System Modules (v0.1)
- bank:
transfer(to, amount) - token:
create(tokenId, decimals, cap?),mint(tokenId, to, amount),transfer(tokenId, to, amount),burn(tokenId, amount) - app:
register(appId, manifest),call(appId, method, args),emit(event, payload) - storage:
put(appId, key, value),get(appId, key)(bounded) - domain:
request_challenge(domain),verify(domain, nonce) - curve (reference DEX):
create,quote_buy,quote_sell,buy,sell,status
Security Model
- Scoped approvals: each
app.callcarries limits (tokenId, maxDebit, TTL). No infinite allowances. - Readable intents: gateway renders human text (e.g., “Send 1.0 NATIVE to receive 8,623 ZOOMER”).
- Determinism: verbs are pure, bounded; no reentrancy.
- Rate limits: daily free-ops cap + per-IP throttles as circuit breakers.
Consensus & Decentralization
Phase 1 — PoA
- 3–5 validators, static keys in
genesis.validators[]. - Rotating leader; block time 250–500 ms; sub-second finality.
Phase 2 — DPoS (upgrade)
- Stake module (
delegate,create_validator). - Top-N validators per epoch; >⅔ signatures finalize.
Fees & Native Token
- Per-byte fee for tx bytes; storage rent for new data.
- Free tier (e.g., 100 ops/day/account) to keep UX smooth.
- Native token (
PVT) for fees and staking; fixed supply or light inflation (e.g., 2%/yr) to pay validators.
Reference App — Bonding-Curve DEX
One audited module provides a “pump-simple” experience without custom contracts.
- Price:
P(S) = a + b·S(linear). - Buy: integrate P over supply; mint ΔS; add native to reserve.
- Sell: reverse integral; burn ΔS; release native from reserve.
- Guards: cap supply, feeBps limit, minOut checks.
Bridge & Ownership Proofs
Pivot keeps bridging simple and auditable while staying non-custodial for users. The core idea is: (1) prove a deposit happened on the origin chain by a specific 0x key, and (2) prove the mint on Pivot goes to a Pivot address the user controls (they sign the claim tx with their Pivot key; OAuth only unlocks that key).
Design Stages
- Stage 0 — Gateway bridge: centralized operator proves UX. Not recommended long-term.
- Stage 1 — Attester bridge (recommended): N-of-M signers co-sign deposits/burns. Pivot verifies threshold signatures in a tiny
bridgemodule. - Stage 2 — Light-client proofs: advanced, out of scope for MVP.
Ownership Confirmation (Two Clean Options)
Option A — Lockbox Contract (origin chain)
The deposit event embeds the pivotAddr (the recipient on Pivot). Attesters mirror that to Pivot — no extra account linking.
/** Minimal lockbox for ERC-20 deposits */
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20 { function transferFrom(address,address,uint256) external returns (bool); }
contract PivotLockbox {
event Deposit(
address indexed token,
address indexed from, // 0x owner who authorized
bytes pivotAddr, // Pivot address bytes (ed25519/bech32)
uint256 amount,
bytes32 depositId // unique (txHash|logIndex or a caller nonce)
);
function deposit(address token, uint256 amount, bytes calldata pivotAddr, bytes32 depositId) external {
require(IERC20(token).transferFrom(msg.sender, address(this), amount), "transferFrom fail");
emit Deposit(token, msg.sender, pivotAddr, amount, depositId);
}
}
Attested message → Pivot:
type: "deposit" chain: "eth-mainnet" token: "0xA0b8…" // origin token or lockbox from: "0xUser…" // depositor pivotAddr:"pivot1q…" // bytes/bech32 of Pivot address amount: "1000000" depositId:"eth:0xTX:logIndex"
Option B — SAFE + EIP-712 Bind Signature
No contract required on origin. User deposits into a Gnosis SAFE; then signs an EIP‑712 message binding that deposit to their pivotAddr. Attesters check both the deposit and the signature.
// EIP-712 schema (example)
domain = { name: "PivotBridge", version: "1", chainId: 1, verifyingContract: SAFE_ADDR }
types = {
BindDeposit: [
{ name: "token", type: "address" },
{ name: "from", type: "address" },
{ name: "amount", type: "uint256" },
{ name: "depositId", type: "bytes32" },
{ name: "pivotAddr", type: "bytes" }
]
}
message = { token, from, amount, depositId, pivotAddr }
signature = signTypedData(domain, types, message) // with the 0x wallet
Pivot Bridge Module (tiny, deterministic)
State
bridge/attesters/{setId}→{ pubkeys[], threshold }bridge/assets/{assetId}→{ originChain, originAddr, decimals, attesterSet, wrappedTokenId }bridge/seen/{depositId},bridge/seenBurn/{burnId}→ replay protection
Verbs
set_attesters(setId, pubkeys[], threshold)bind_asset(assetId, originChain, originAddr, decimals, attesterSet, wrappedTokenId)claim({assetId, depositId, to, amount, signatures[]})→ verify threshold sig; mint wrappedburn({assetId, amount, to, targetChain})→ burn wrapped; emitBridgeBurn
API (Gateway)
POST /v1/bridge/bind_assetPOST /v1/bridge/claimPOST /v1/bridge/burnGET /v1/bridge/status?assetId=...
Security Levers
- Replay protection with
depositId/burnIdsets; strict canonical serialization for signed messages. - Per‑asset/day caps; time delays for large releases; attester set rotation with cooldowns.
- All claim txs are signed by the user’s Pivot key (OAuth only unlocks the key), preserving non‑custodial ownership.
UX Flow
- Inbound: user deposits on origin (Option A event embeds
pivotAddror Option B attaches EIP‑712 bind). Attesters co‑sign → user callsbridge.claimon Pivot. - Outbound: user calls
bridge.burnon Pivot → attesters co‑sign SAFE transfer → release on origin.
Developer Experience
- Gateway REST:
/v1/signup,/v1/token/*,/v1/app/*,/v1/domain/*,/v1/curve/*. - SDK compiles flows → manifests; clients generated from schemas.
- Single-binary devnet for local testing.
Roadmap
- POC: single-node devnet, domain binding, DEX module, OAuth prototype.
- MVP: 3 PoA validators, hosted gateway, indexer + events, daily free-ops.
- Beta: DPoS staking, fee switch to PVT, parameter governance.
Conclusion
Pivots trims blockchain to essentials: non-custodial web-native wallets, domain-verified identity, and a handful of safe verbs. It’s enough to unlock real apps for real user- without the VM baggage.
© 2025 Pivot — pivot.money
