Skip to content

Commit

Permalink
chore: documentation for v0.3.0 (#2)
Browse files Browse the repository at this point in the history
* chore: passive management + small cleanup

* chore: why plug + transactions

* chore: update to new types

* chore: interaction subheadings

* chore: socket documentation

* chore: continued refinement

* chore: continued cleanup

* chore: base solver reference

* chore: no canonical references for now
  • Loading branch information
nftchance authored Mar 4, 2024
1 parent 909d7ec commit 5398350
Show file tree
Hide file tree
Showing 20 changed files with 331 additions and 181 deletions.
96 changes: 31 additions & 65 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ function getItems(directory: string) {
}

export default defineConfig({
title: "Plug Documentation",
description: "Documentation for the Plug protocol.",
title: "Plug",
description: "Documentation for the Plug protocol and application.",
appearance: "dark",
themeConfig: {
logo: { light: "/logo-dark.svg", dark: "/logo-white.svg" },
Expand Down Expand Up @@ -124,28 +124,6 @@ export default defineConfig({
text: "enforceFuse",
link: "/core/fuse/enforce-fuse",
},
{
text: "Instances",
collapsed: true,
items: [
{
text: "Threshold",
link: "/instances/fuses/threshold",
},
{
text: "Schedule Windows",
link: "/instances/fuses/schedule-windows",
},
{
text: "Limited Calls",
link: "/instances/fuses/limited-calls",
},
{
text: "Revocation",
link: "/instances/fuses/revocation",
},
],
},
],
},
{
Expand All @@ -161,16 +139,6 @@ export default defineConfig({
text: "plug",
link: "/core/sockets/plug",
},
{
text: "Instances",
collapsed: true,
items: [
{
text: "Vaults",
link: "/instances/vaults"
},
]
}
],
},
{
Expand All @@ -182,44 +150,17 @@ export default defineConfig({
text: "plug",
link: "/core/routers/plug",
},
{
text: "batch",
link: "/core/routers/batch",
},
{
text: "Instances",
link: "/instances/routers",
items: [
{
text: "Canonical",
link: "/instances/routers/canonical"
},
]
}
],
},
{
text: "Solvers",
link: "/core/solvers",
collapsed: true,
items: [
{
text: "simulate",
link: "/core/solvers/simulate",
},
{
text: "solve",
link: "/core/solvers/solve",
},
{
text: "Instances",
items: [
{
text: "Canonical",
link: "/instances/solvers/canonical"
},
]
}
],
},
{
Expand All @@ -231,12 +172,36 @@ export default defineConfig({
link: "/instances/deployable/deterministic"
},
{
text: "JIT Deployment",
link: "/instances/deployable/just-in-time-deployment"
text: "Fuses",
collapsed: true,
items: [
{
text: "Threshold",
link: "/instances/fuses/threshold",
},
{
text: "Schedule Windows",
link: "/instances/fuses/schedule-windows",
},
{
text: "Limited Calls",
link: "/instances/fuses/limited-calls",
},
{
text: "Revocation",
link: "/instances/fuses/revocation",
},
],
},
{
text: "Contract Addresses",
link: "/instances/deployable/addresses"
text: "Sockets",
collapsed: true,
items: [
{
text: "Vaults",
link: "/instances/vaults"
},
]
},
],
},
Expand All @@ -263,6 +228,7 @@ export default defineConfig({
// * Load the font files.
transformHead({ assets }) {
const myFontFile = assets.find(() => /Satoshi-Variable\.\w+\.woff2/);

if (myFontFile) {
return [
[
Expand Down
Binary file added .vitepress/theme/assets/fonts/FiraCode-VF.woff2
Binary file not shown.
19 changes: 7 additions & 12 deletions .vitepress/theme/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
// https://vitepress.dev/guide/custom-theme
import type { Theme } from 'vitepress'
import { h } from 'vue'
import type { Theme } from "vitepress";
import { h } from "vue";

import DefaultTheme from 'vitepress/theme-without-fonts'
import './style.css'
import DefaultTheme from "vitepress/theme-without-fonts";
import "./style.css";

export default {
extends: DefaultTheme,
Layout: () => {
return h(DefaultTheme.Layout, null, {
// https://vitepress.dev/guide/extending-default-theme#layout-slots
})
return h(DefaultTheme.Layout, null, {});
},
enhanceApp({ app, router, siteData }) {
// ...
}
} satisfies Theme
enhanceApp() {},
} satisfies Theme;
50 changes: 34 additions & 16 deletions .vitepress/theme/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,44 @@
* -------------------------------------------------------------------------- */

@font-face {
font-family: 'Satoshi';
font-family: "Satoshi";
font-weight: 500 900;
src: url('./assets/fonts/Satoshi-Variable.woff2') format('woff2 supports variations'),
url('./assets/fonts/Satoshi-Variable.woff2') format('woff2-variations');
src:
url("./assets/fonts/Satoshi-Variable.woff2")
format("woff2 supports variations"),
url("./assets/fonts/Satoshi-Variable.woff2") format("woff2-variations");
}

:root {
--font-fallback: BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans;
}

* { font-weight: 500 !important; }
h1, h2 { font-weight: 900 !important; }
h3, h4, h5, h6 { font-weight: 700 !important; }
strong { font-weight: 700 !important; }
* {
font-weight: 500 !important;
text-align: justify;
text-justify: inter-word;
}

h1,
h2 {
font-weight: 900 !important;
}

h3,
h4,
h5,
h6 {
font-weight: 700 !important;
}

strong {
font-weight: 700 !important;
}

:root {
--vp-font-family-base: 'Satoshi', var(--font-fallback);
--vp-font-family-mono: 'Satoshi', var(--font-fallback);
/* --vp-font-family-base: "Satoshi", var(--font-fallback); */
/* --vp-font-family-mono: "Satoshi", var(--font-fallback); */

--vp-c-default-1: #121111;
--vp-c-default-2: #1a1919;
Expand Down Expand Up @@ -114,15 +133,15 @@ strong { font-weight: 700 !important; }
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(
120deg,
#FF050F 30%,
#E2FF00
);
#ff050f 30%,
#e2ff00
);

--vp-home-hero-image-background-image: linear-gradient(
-45deg,
#FF050F 50%,
#E2FF00 50%
);
#ff050f 50%,
#e2ff00 50%
);
--vp-home-hero-image-filter: blur(44px);
}

Expand Down Expand Up @@ -156,4 +175,3 @@ strong { font-weight: 700 !important; }
.DocSearch {
--docsearch-primary-color: var(--vp-c-brand-1) !important;
}

4 changes: 4 additions & 0 deletions core/fuse/enforce-fuse.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
- `$current`: The transaction to execute.
- `$plugsHash`: The unique identifier of the intent signed.

## Returns

- `$through`: The data of the transaction being executed.

## Onchain Implementation

Every [Fuse](/core/fuses) varies in the rules that it applies which means the internal logic is always different. Although that is the case, the top level interface of enforcement enabled through `enforceFuse` is always the same so that the [Socket](/core/sockets) can call it without explicit shape knowledge.
Expand Down
36 changes: 0 additions & 36 deletions core/fuses.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,39 +30,3 @@ The system has been architected in this way to provide the best experience for b
On the surface, this can sound a bit too esoteric to understand. In practice, it is really quite simple. Imagine you want to enforce a single `uint256` that is within a range. You [encode](/core/fuse/encode) the data accordingly and include it in the signed intent.

When the transaction is submit onchain, the [Socket](/core/sockets) will automatically interface with the `Fuse` and respond accordingly if all the rules (conditions) are not met. If all the condition checks pass, then the transaction will continue and be executed.

For a simple example, let's imagine we want a `Fuse` that makes sure the intent can only be executed before a certain `block.number` to enable very simple intent expiration. In this case, the `enforceFuse` will look like:

```solidity
function enforceFuse(
bytes calldata $terms,
PlugTypesLib.Current calldata $current,
bytes32
)
public
view
override
returns (bytes memory $through)
{
/// @dev Decode the terms to get the logic operator and threshold.
(uint256 $threshold) = decode($live);
/// @dev Confirm the intent has not expired.
require($threshold < block.number, "PlugBlockNumberFuse:expired");
/// @dev Continue the pass through.
$through = $current.data;
}
```

With just these couple lines of code, we now have a `Fuse` that makes sure no one can execute transactions after the period of allowance set. Even if someone has your signed intent, if the `block.number` is greater than the one set, it can never be run.

This concept carries out through every `Fuse` and conditional implementation that exists within the [Plug](/) ecosystem. `Fuses`, in the most simple form, are the embodiement of conditions that must pass before a transaction is executed.

Notably, we could have just encoded the data offchain without the need for the onchain function read. However, by doing so that means we'd have to store a huge record of encoding methods that diverge from the onchain implementations with every update or small change.

Without an abstracted pattern, a [Solver](/core/solvers) would have to store a huge record of encoding methods that diverge from the onchain implementations with every update or small change. This way, we can simply maintain the list of addresses and ABIs and automatically build based on the defined context.

If each [Fuse](/core/fuses) was declared with top-level arguments instead of encoding, there would be no standard pattern of interaction. Every [Solver](/core/solvers) would have to be aware of the shape (ABI) for every [Fuse](/core/fuses) defined within the intent and directly interface.

Instead, a [Fuse](/core/fuses) can remain unverified and provide conditional capabilities to the signing user without leaking the internal functions of piece of logic applied simply by surfacing the declaration of [encoded](/core/fuse/encode) and [decoded](/core/fuse/decode) values.
16 changes: 8 additions & 8 deletions core/routers.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ head:

# Routers

For Plug, a significant portion of the execution power lies in the ability to operate through a single Router. In function, this means that regardless of the target, the intents of Plug users are resolved most often through a Router.
For [Plug](/), a significant portion of the execution power lies in the ability to operate through a single Router. In function, this means that regardless of the target, the intents of [Plug](/) users are resolved most often through a `Router`.

Without a Router, Executors would have to run a transaction for every unique target. So, if they want to settle an intent for 10 different users they would have to interface with each of those targets. Instead of that being the case, they simply interact with the Router that coordinates the communicate and transactions for each of the users through a single transaction. Notably, there is often little reason for users to interact with the Router themselves. The existence and power of the Router is almost entirely realized by the Executors of each intent.
Without a `Router`, [Solvers](/core/solvers) would have to run a transaction for every unique [Socket](/core/sockets). So, if they want to settle an intent for 10 different users they would have to interface with each of those targets. Instead, they simply interact with the `Router` that coordinates transactions for each of the [Sockets](/core/sockets) through a single transaction. Notably, there is often little reason for end-users to interact with the `Router` themselves. The existence and power of the `Router` is almost entirely realized by the [Solver](/core/solvers) of each intent.

An important Caveat to many of the existing Router models in this industry is that users themselves do not directly interact with it. There is no approval of assets to an unguarded arbitrary call mechanism. All transfers of value are localized to the target of the intent and not the Router.
## The Abstraction

## Execution Globalization
An important benefit of a `Router` model is that it means there is no need for protocols already deployed to update nor is there a need for new protocols to integrate a piece of [Plug](/) directly. Instead, every contract deployed can be interacted with easily.

An important benefit of a `Router` model is that it means there is no need for protocols already deployed to update. Instead, every contract that has already been deployed can be interacted with ease. With localization, to support a protocol there would have to be a wrapper for every connection. There would need to be a mechanism that enables the protocol to recover the sender from the message forwarded by the Executor.
With execution localization, for a protocol to support intents there would have to be a wrapper for every connection. There would need to be a mechanism that enables the protocol to recover the sender from the message forwarded by the [Solver](/core/solvers) which is not ideal due to the blocking experienced by all contracts already deployed as well as those that do not include the logic on their own. This assumption and need would improperly place the onus of development and integration on protocols.

Instead, a user of [Plug](/) simply signs a message for their [Vault](/instances/vaults) and execution is automatically routed through it. There's no interaction proxy relationship within the action. All actions are properly attributed without abstraction. [Plug](/) is designed to make the primitives and more general protocols of the industry more powerful therefore there is no integration expectation or new overhead introduced.
Instead, a user of [Plug](/) simply signs a message for their [Vault](/instances/vaults) and execution is automatically routed through it enabling the instant support for ~100% of smart contracts deployed. There's no sender recovery mechanism within any of the protocols. All actions are properly attributed without abstraction without introducing new risks like [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) does.

If a protocol wants to be supported, they can be without making a single change to their onchain implementation. With even the deepest level of integration, the only thing required is the development of a [Fuse](/core/fuses) which is not an obligation or expectation the protocol itself carries.
To enable this, a `Router` contains key functions that enable execution on behalf of [Sockets](/core/sockets) with:

## Onchain Implementation
- [plug](/core/routers/plug): Execute [LivePlugs](/generated/base-types/LivePlugs) bundles in a single or batched method.
1 change: 0 additions & 1 deletion core/routers/batch.md

This file was deleted.

Loading

0 comments on commit 5398350

Please sign in to comment.