Skip to content

Commit c97754c

Browse files
committed
Express Relay docs v1
1 parent 1338c14 commit c97754c

File tree

14 files changed

+78
-77
lines changed

14 files changed

+78
-77
lines changed

components/icons/CodeIcon.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const CodeIcon = ({ className }: { className: string }) => {
22
return (
33
<svg
4-
xmlns="http://www.w3.org/2000/svg"
4+
xmlns="http://www.w3.org/2000/svg"
55
viewBox="0 0 1024 1024"
66
fill="currentColor"
77
height="1em"
@@ -10,8 +10,6 @@ const CodeIcon = ({ className }: { className: string }) => {
1010
<path d="M516 673c0 4.4 3.4 8 7.5 8h185c4.1 0 7.5-3.6 7.5-8v-48c0-4.4-3.4-8-7.5-8h-185c-4.1 0-7.5 3.6-7.5 8v48zm-194.9 6.1l192-161c3.8-3.2 3.8-9.1 0-12.3l-192-160.9A7.95 7.95 0 00308 351v62.7c0 2.4 1 4.6 2.9 6.1L420.7 512l-109.8 92.2a8.1 8.1 0 00-2.9 6.1V673c0 6.8 7.9 10.5 13.1 6.1zM880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656z" />
1111
</svg>
1212
);
13-
}
13+
};
1414

1515
export default CodeIcon;
16-
17-

images/express_relay/express_relay_schematic.svg

Lines changed: 3 additions & 3 deletions
Loading

pages/express-relay/api-reference.mdx

Lines changed: 0 additions & 3 deletions
This file was deleted.

pages/express-relay/contract-addresses.mdx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Tabs} from "nextra/components"
1+
import { Tabs } from "nextra/components";
22
import AddressTable from "../../components/AddressTable";
33

44
Express Relay is currently deployed on the following networks:
@@ -48,7 +48,6 @@ Auction Server endpoint: https://pyth-express-relay-mainnet.asymmetric.re/
4848

4949
This list contains the addresses of the commonly used assets present in opportunities on the Mode network:
5050

51-
5251
<AddressTable
5352
explorer={"https://explorer.mode.network/address/$ADDRESS"}
5453
entries={[
@@ -109,7 +108,6 @@ Auction Server endpoint: https://per-staging.dourolabs.app/
109108

110109
This list contains the addresses of the commonly used assets present in opportunities on the Optimism Sepolia network:
111110

112-
113111
<AddressTable
114112
explorer={"https://optimism-sepolia.blockscout.com/address/$ADDRESS"}
115113
entries={[
@@ -137,4 +135,4 @@ This list contains the addresses of the commonly used assets present in opportun
137135
/>
138136

139137
</Tabs.Tab>
140-
</Tabs>
138+
</Tabs>

pages/express-relay/how-express-relay-works.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@ Express Relay solves the problem of MEV by providing protocol developers with an
1010
Developers specify a set of operations in their protocol that must be accessed through Express Relay.
1111
Searchers then participate in an off-chain auction to access these operations.
1212
Their bids in the auction are used to determine the order in which their transactions will be executed.
13-
The winners' transactions are forwarded to the Express Relay smart contract. As part of the transaction, searchers must pay their specified bid.
13+
The winners' transactions are forwarded to the Express Relay smart contract. As part of the transaction, searchers must pay their specified bid.
1414
The auction profits are then split between the integrated protocol and other participants in Express Relay.
1515

1616
![](images/express_relay/before_express.jpg)
1717
![](images/express_relay/after_express.jpg)
1818

19-
2019
The diagram above shows how Express Relay changes the MEV landscape for a liquidation.
2120
In the status quo (above), Searchers tip miners to guarantee that their liquidation transaction lands on-chain and that their transaction directly interacts with the protocol, exposing the liquidation opportunity.
2221
With Express Relay (down), Searchers submit bids for their transaction to the Express Relay auction.
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Auction
22

3-
The auction in Express Relay is held off-chain at the auction server.
4-
Bids arrive at the auction server and compete against other bids, vying for the same [permission key](./permissioning.mdx).
3+
The auction in Express Relay is held off-chain at the auction server.
4+
Bids arrive at the auction server and compete against other bids, vying for the same [permission key](./permissioning.mdx).
55
A relayer selected by governance serves as the auctioneer and determines the auction in line with the criterion of maximizing the revenue shared back to the protocol that generated this opportunity. That means the auctioneer is expected to forward on-chain the subset of bids that maximizes the revenue back to the protocol.
66

77
Thus, the Express Relay auction is analogous to a sealed-bid auction, i.e., participants in the auction will not have the contents of their bid disclosed publicly unless they win the auction and are forwarded on-chain.
@@ -10,11 +10,12 @@ The forwarded subset of transactions is submitted on-chain and first processed b
1010

1111
Generally, the auction server expects bids to execute successfully on-chain. Falback bids are also forwarded in case of execution failures for the predicted winners.
1212

13-
The `ExpressRelay` contract extracts the payment of the specified bid amount only if the searcher's bid is successfully executed on-chain.
13+
The `ExpressRelay` contract extracts the payment of the specified bid amount only if the searcher's bid is successfully executed on-chain.
1414
Hence, the Express Relay auction can be seen as a generalization of a [first-price sealed-bid auction](https://en.wikipedia.org/wiki/First-price_sealed-bid_auction), in that multiple bids can win and pay their first price.
1515

1616
The revenue from the auction is shared amongst relevant stakeholders in the Express Relay system. These stakeholders include:
17+
1718
- the protocol that generates the relevant opportunity
1819
- the relayer, which handles running the off-chain components of the system
1920

20-
The Express Relay contract enforces the exact revenue splits and is subject to change based on governance decisions.
21+
The Express Relay contract enforces the exact revenue splits and is subject to change based on governance decisions.

pages/express-relay/how-express-relay-works/opportunities.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Opportunities
22

3-
In the context of Express Relay, an opportunity refers to a potential transaction that a searcher can execute on a protocol. Typically, the term "opportunity" is used for such transactions that are lucrative and therefore competed for by many searchers.
3+
In the context of Express Relay, an opportunity refers to a potential transaction that a searcher can execute on a protocol. Typically, the term "opportunity" is used for such transactions that are lucrative and therefore competed for by many searchers.
44

55
In the pre-Express Relay world, opportunities therefore corresponded to MEV: a protocol generated MEV when an opportunity appeared on that protocol and searchers bid up the right to execute the opportunity at the validator level.
66

@@ -11,6 +11,7 @@ In the context of Express Relay, the value deriving from an opportunity no longe
1111
Opportunities do not refer to only transactions that use an oracle. In truth, any transaction that is lucrative but limited (available to only the first user(s) who executes it) generates MEV. As a result, Express Relay and the opportunity schema have been designed to be oracle-agnostic.
1212

1313
Examples of opportunities include:
14+
1415
- liquidations
1516
- open trade offers
1617
- NFT mints
@@ -19,6 +20,7 @@ Examples of opportunities include:
1920
## Opportunity Adapter
2021

2122
The Opportunity Adapter contract enables searchers to engage with opportunities from different protocols without needing to do any bespoke integration work per protocol. Instead of exposing lower-level fields determined by protocols (e.g. `amountCollateral`, `addressBorrower`), the Opportunity Adapter abstracts away the semantics of the opportunity and instead [exposes the fundamental traits](https://github.com/pyth-network/per/blob/30c3fc695034f518225f8255ebe8423604e8aca3/contracts/src/opportunity-adapter/Structs.sol#L20-L23) of any opportunity:
23+
2224
- the tokens sold by the searcher
2325
- the tokens bought by the searcher
2426
- the identity of the searcher executing this opportunity
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Permissioning
22

3-
`permissionId` is a `bytes` object that represents the unique identifying information of a position within the protocol. `permissionId` allows the system to distinguish between bids competing on different opportunities and thereby run more scoped and efficient auctions.
3+
`permissionId` is a `bytes` object that represents the unique identifier of a position within the protocol. `permissionId` allows the system to distinguish between bids competing on different opportunities and thereby run more scoped and efficient auctions.
44

5-
Each borrower has a unique position for some protocols, so the borrower address uniquely identifies a position.
6-
In other protocols, each borrower might have multiple positions, distinguished by the address of the collateral asset or by a `uint256` ID number.
5+
Each borrower has a unique position for some protocols, so the borrower address uniquely identifies a position.
6+
In other protocols, each borrower might have multiple positions, distinguished by the address of the collateral asset or by a `uint256` ID number.
77
In those cases, the information set that uniquely identifies a position would include multiple fields.
88

9-
`permissionId` can be the concatenation of all these fields in bytes format. You can call `abi.encode(){:solidity}` to concatenate these fields together.
9+
`permissionId` can be the concatenation of all these fields in bytes format. You can call `abi.encode(){:solidity}` to concatenate these fields together.
1010

1111
For example, if a protocol featured a unique position per borrower, then it could form `permissionId` as
1212

@@ -20,9 +20,9 @@ On the other hand, if a protocol allowed a borrower to open as many new position
2020
bytes memory permissionId = abi.encode(borrowerAddress, positionId);
2121
```
2222

23-
The Express Relay contract uses the `permissionId` to toggle permissions for interacting with the protocol.
23+
The Express Relay contract uses the `permissionId` to toggle permissions for interacting with the protocol.
2424
This toggling is checked within the protocol's code to ensure that the current transaction is within the context of Express Relay so that the recaptured value can be returned to the protocol. In particular, the Express Relay contract checks the toggling of the `permissionKey`, which is the concatenation of the protocol address and the `permissionId`:
2525

2626
```solidity
2727
bytes memory permissionKey = abi.encode(protocolAddress, permissionId);
28-
```
28+
```

pages/express-relay/index.mdx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import CodeIcon from "../../components/icons/CodeIcon";
99

1010
Express Relay is a priority auction that enables protocols to eliminate [Maximal Extractable Value](https://www.ledger.com/academy/glossary/maximal-extractable-value-mev) (MEV).
1111

12-
- **For Protocol Developers:** Express Relay allows protocols to recapture MEV and access a network of searchers.
13-
With Express Relay, protocols don't need to spend time and energy bootstrapping a protocol-specific searcher network.
12+
- **For Protocol Developers:** Express Relay allows protocols to recapture MEV and access a network of searchers.
13+
With Express Relay, protocols don't need to spend time and energy bootstrapping a protocol-specific searcher network.
1414

15-
- **For Searchers:** Express Relay provides easy and unified access by aggregating liquidation and other MEV opportunities across integrated DeFi protocols.
16-
Searchers integrate once and gain access to all existing and future opportunities.
15+
- **For Searchers:** Express Relay provides easy and unified access by aggregating liquidation and other MEV opportunities across integrated DeFi protocols.
16+
Searchers integrate once and gain access to all existing and future opportunities.
1717

1818
## Integration
1919

@@ -50,7 +50,3 @@ To learn more about Express Relay, refer to the following resources:
5050
href="https://github.com/pyth-network/pyth-examples/tree/main/express-relay/easy_lend"
5151
/>
5252
</Cards>
53-
54-
55-
56-

pages/express-relay/integrate-as-protocol.mdx

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Callout, Tabs, Steps } from 'nextra/components'
1+
import { Callout, Tabs, Steps } from "nextra/components";
22

33
# How to Integrate Express Relay as a Protocol
44

@@ -16,7 +16,7 @@ To integrate with Express Relay, your protocol's contract must check if Express
1616
<Steps>
1717
### Install the Express Relay SDK
1818

19-
Pyth provides a [Solidity SDK](https://www.npmjs.com/package/@pythnetwork/express-relay-sdk-solidity) to help developers integrate Express Relay into their DeFi protocol.
19+
Pyth provides a [Solidity SDK](https://www.npmjs.com/package/@pythnetwork/express-relay-sdk-solidity) to help developers integrate Express Relay into their DeFi protocol.
2020
The SDK exposes [`IExpressRelay`](https://github.com/pyth-network/pyth-crosschain/blob/main/express_relay/sdk/solidity/IExpressRelay.sol) and [`IExpressRelayFeeReceiver`](https://github.com/pyth-network/pyth-crosschain/blob/main/express_relay/sdk/solidity/IExpressRelayFeeReceiver.sol) interfaces to interact with Express Relay.
2121

2222
<Tabs items={['Hardhat', 'Foundry']}>
@@ -26,6 +26,7 @@ The SDK exposes [`IExpressRelay`](https://github.com/pyth-network/pyth-crosschai
2626
```bash copy
2727
npm install @pythnetwork/express-relay-sdk-solidity
2828
```
29+
2930
</Tabs.Tab>
3031
<Tabs.Tab>
3132
If you are using Foundry, you must create an NPM project if you don't already have one. From the root directory of your project, run:
@@ -40,6 +41,7 @@ Then add the following line to `remappings.txt` file:
4041
```text copy
4142
@pythnetwork/express-relay-sdk-solidity/=node_modules/@pythnetwork/express-relay-sdk-solidity
4243
```
44+
4345
</Tabs.Tab>
4446
</Tabs>
4547

@@ -48,20 +50,21 @@ Then add the following line to `remappings.txt` file:
4850
The following steps show how to modify your protocol's contract to verify if the current transaction is permissioned by Express Relay and to receive the auction proceeds.
4951

5052
1. Call the [`isPermissioned`](https://github.com/pyth-network/pyth-crosschain/blob/main/express_relay/sdk/solidity/IExpressRelay.sol#L10C14-L10C28) method from `IExpressRelay` interface to make sure the current transaction is permissioned by Express Relay.
51-
1. Implement the [`IExpressRelayFeeReceiver`](https://github.com/pyth-network/pyth-crosschain/blob/main/express_relay/sdk/solidity/IExpressRelayFeeReceiver.sol#L4) interface to **receive** auction proceeds.
53+
1. Implement the [`IExpressRelayFeeReceiver`](https://github.com/pyth-network/pyth-crosschain/blob/main/express_relay/sdk/solidity/IExpressRelayFeeReceiver.sol#L4) interface to **receive** auction proceeds.
5254

5355
#### 1. Verify Permissioning
5456

5557
The `isPermissioned` function takes two arguments:
58+
5659
1. `protocolFeeReceiver`: The address to receive the protocol's share of auction proceeds.
5760
1. `permissionId`: A unique identifier for the opportunity.
5861

5962
```solidity copy
6063
import "@pythnetwork/express-relay-sdk-solidity/IExpressRelay.sol";
6164
6265
// Express Relay contract address on Optimism Sepolia
63-
//
64-
// Check https://docs.pyth.network/express-relay/contract-addresses
66+
//
67+
// Check https://docs.pyth.network/express-relay/contract-addresses
6568
// for the address deployed on other networks
6669
address expressRelay = 0xD6e417287b875A3932c1Ff5dcB26D4D2C8b90B40;
6770
@@ -73,21 +76,26 @@ require(
7376
"not permissioned"
7477
);
7578
```
79+
7680
<Callout type="info" emoji="ℹ️">
77-
The `permissionId` represents a unique identifier of an opportunity.
78-
For a liquidation opportunity, the vault address or ID could be concatenated into `bytes` format.
79-
Consult [`Permissioning`](./how-express-relay-works/permissioning.mdx) for more information on generating permission IDs.
81+
The `permissionId` represents a unique identifier of an opportunity. For a
82+
liquidation opportunity, the vault address or ID could be concatenated into
83+
`bytes` format. Consult
84+
[`Permissioning`](./how-express-relay-works/permissioning.mdx) for more
85+
information on generating permission IDs.
8086
</Callout>
8187

8288
#### 2. Set up Fee Receiver
89+
8390
Express Relay will call the `receiveAuctionProceedings` method present in `IExpressRelayFeeReceiver`. The call will transfer the protocol's share of the auction proceeds to the `protocolFeeReceiver` address.
8491

8592
```solidity copy
8693
interface IExpressRelayFeeReceiver {
87-
function receiveAuctionProceedings(
88-
bytes calldata permissionKey
89-
) external payable;
94+
function receiveAuctionProceedings(
95+
bytes calldata permissionKey
96+
) external payable;
9097
}
98+
9199
```
92100

93101
The following code snippet shows a sample Express Relay-integrated contract that performs liquidation.
@@ -144,10 +152,10 @@ contract EasyLend is IExpressRelayFeeReceiver {
144152
abi.encode(vaultID) // permissionId generated from the unique vault ID
145153
);
146154
require(permissioned, "invalid liquidation");
147-
155+
148156
IERC20(vault.tokenDebt).transferFrom(msg.sender,address(this),vault.amountDebt);
149157
IERC20(vault.tokenCollateral).transfer(msg.sender,vault.amountCollateral);
150-
158+
151159
_vaults[vaultID].amountCollateral = 0;
152160
_vaults[vaultID].amountDebt = 0;
153161
}
@@ -166,8 +174,8 @@ contract EasyLend is IExpressRelayFeeReceiver {
166174
167175
}
168176
```
169-
</Steps>
170177

178+
</Steps>
171179

172180
## Expose Opportunities to Searchers
173181

@@ -180,7 +188,7 @@ The JSON payload should contain opportunities in the following format:
180188
```bash copy
181189
{
182190
"target_calldata": "0xdeadbeef", // Calldata to execute the opportunity
183-
"chain_id": "op_sepolia",
191+
"chain_id": "op_sepolia",
184192
"target_contract": "0xcA11bde05977b3631167028862bE2a173976CA11", // Protocol contract address to call
185193
"permission_key": "0xcafebabe", // Unique identifier for the opportunity
186194
"target_call_value": "1", // Value (in Wei) to send to the protocol contract.
@@ -200,14 +208,12 @@ The JSON payload should contain opportunities in the following format:
200208
}
201209
```
202210

203-
204211
Each protocol integrated with Express Relay must actively monitor for new opportunities.
205212
Protocols can do this by indexing the chain, listening to protocol events, or querying protocol state through an RPC provider.
206213

207214
Check the [`monitor.ts`](https://github.com/pyth-network/pyth-crosschain/blob/main/express_relay/examples/easy_lend/src/monitor.ts) script,
208215
which fetches opportunities for the below-mentioned [Easy Lend](https://github.com/pyth-network/pyth-crosschain/tree/main/express_relay/examples/easy_lend) example and exposes them to Express Relay for auction.
209216

210-
211217
## Additional Resources
212218

213219
You may find these additional resources helpful for integrating Express Relay as a protocol.
@@ -227,4 +233,4 @@ The [Error Codes](./error-codes.mdx) page lists the error codes returned by Expr
227233

228234
### API Reference
229235

230-
The [API Reference](https://per-staging.dourolabs.app/redoc/) provides detailed information on Express Relay APIs for submitting opportunities.
236+
The [API Reference](https://per-staging.dourolabs.app/redoc/) provides detailed information on Express Relay APIs for submitting opportunities.

0 commit comments

Comments
 (0)