# Introduction

ERC-7683 is the standard for **crosschain Intents** on Ethereum.

Ethereum’s Layer 2 (L2) solutions have solved scalability, enabling users to transact quickly and cheaply. However these advancements have also introduced **fragmentation**.\
\
That’s where **Intents** come in—allowing actions to flow seamlessly across chains.

## Introducing Intents

**Intents** allow users to declare actions—such as token swaps, DeFi deposits, or governance votes—across different chains.

**ERC-7683** standardizes how these crosschain interactions are expressed as intents, enabling seamless connectivity between Ethereum mainnet, L2s, and sidechains.

## What is ERC-7683?

**ERC-7683** is designed to standardize **Intents**, bringing multiple benefits to Ethereum’s ecosystem:

* **Unifies Ethereum:** Establishes a universal standard for crosschain actions across L2s and sidechains, supporting Ethereum’s goal as the leading decentralized application platform.
* **Enables Interoperability:** Standardizes order and settlement interfaces for seamless crosschain execution.
* **Eliminates Fragmentation:** Provides a common framework that harmonizes diverse systems, enabling smoother crosschain operations.
* **Enhances User Experience:** Delivers simplified, intuitive, and frictionless crosschain interactions for users.
* **Boosts Liquidity:** Allows dApps to access shared filler networks across chains, offering deeper liquidity.
* **Speeds Up Transactions:** Reduces failure rates and speeds up transaction times by fostering competition among fillers.
* **Drives Innovation:** Transforms the crosschain landscape by promoting collaboration and encouraging innovative solutions across Ethereum.

## Join the Intents Movement&#x20;

### 70 Protocols Support ERC-7683 and Crosschain Intents

<figure><img src="/files/niag4YRRYkMKuYFglD06" alt=""><figcaption></figcaption></figure>

## Explore Flexibility and Innovation with ERC-7683 <a href="#docs-internal-guid-7227c9d6-7fff-6e4d-102a-753ae1eed349" id="docs-internal-guid-7227c9d6-7fff-6e4d-102a-753ae1eed349"></a>

While **ERC-7683** standardizes how intents are created, it offers flexibility in how they’re settled:

**Diverse Settlement Networks:** Projects can implement settlement processes that best fit their needs, providing versatility across the ecosystem.

## Welcome to the Future of Crosschain Interoperability

ERC-7683 is more than a standard—it’s a solution that simplifies and enhances crosschain interactions across Ethereum.

***

| REACH OUT                                                                                                                             | LEARN                                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>Join us and support ERC-7683 and the vision for a unified Ethereum.<br><br>Contact us <a href="https://t.me/bobbayb">here</a>.</p> | <p>Dive deeper into ERC-7683, an interface for crosschain trade execution systems.<br><br>Learn more <a href="https://www.erc7683.org/about">here</a>.</p> |


# Spec

<figure><img src="/files/uLXRlwonIrXbFVDkqP29" alt=""><figcaption></figcaption></figure>

## An interface for crosschain trade execution systems

[Uniswap Labs](https://blog.uniswap.org/uniswap-labs-and-across-propose-standard-for-cross-chain-intents) and [Across](https://medium.com/across-protocol/across-and-uniswap-labs-propose-standard-for-cross-chain-intents-to-accelerate-cross-chain-0423f2242f7c) propose a new standard for crosschain intents, establishing a unified framework for intents-based systems to specify crosschain actions. With the proposal for the new standard, Uniswap Labs and Across have jointly published an [Ethereum Request for Comment](https://eips.ethereum.org/EIPS/eip-7683) to the Ethereum Magicians [forum](https://ethereum-magicians.org/t/erc-7683-cross-chain-intents-standard/19619/1). The two projects have proposed the standard to the [CAKE Working Group](https://frontier.tech/cake-working-group) for their discussion and review.

### Abstract <a href="#abstract" id="abstract"></a>

The following standard allows for the implementation of a standard API for crosschain value-transfer systems. This standard provides generic order structs, as well as a standard set of settlement smart contract interfaces.

### Motivation <a href="#motivation" id="motivation"></a>

Intent-based systems have become the preeminent solution for end-user crosschain interaction by abstracting away the complexity and time constraints of traditional bridges. One of the key difficulties for crosschain intents systems is accessing sufficient liquidity and a network of active fillers across chains. This challenge may be exacerbated as the number of distinct chains increases over time. The end result of this is a poor experience for users including higher costs, longer wait times and higher failure rates than necessary.

By implementing a standard, crosschain intents systems can interoperate and share infrastructure such as order dissemination services and filler networks, thereby improving end-user experience by increasing competition for fulfilling user intents.

### Specification <a href="#specification" id="specification"></a>

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.

**Glossary of Terms**

* **Destination Chain**: the chain where the intent is executed and the user receives funds. Note: intents can involve multiple destination chains.
* **Filler**: a participant who fulfils a user intent on the destination chain(s) and receives payment as a reward.
* **Leg**: a portion of the user intent that can be executed independently from others. All legs must be executed for an intent to be considered fulfilled.
* **Origin chain**: the chain where the user sends funds.
* **Settlement System**: a system that custodies user deposits, verifies fills, and pays fillers for the purpose of faciliating intents.
* **Settler**: a contract that implements part of the settlement system on a particular chain.
* **User**: for the purposes of this document, the user is the end-user who is sending the order.

**Order structs**

A compliant crosschain order type MUST be ABI decodable into either `GaslessCrossChainOrder` or `OnchainCrossChainOrder` type.

{% code overflow="wrap" %}

```solidity
/// @title GaslessCrossChainOrder CrossChainOrder type
/// @notice Standard order struct to be signed by users, disseminated to fillers, and submitted to origin settler contracts
struct GaslessCrossChainOrder {
	/// @dev The contract address that the order is meant to be settled by.
	/// Fillers send this order to this contract address on the origin chain
	address originSettler;
	/// @dev The address of the user who is initiating the swap,
	/// whose input tokens will be taken and escrowed
	address user;
	/// @dev Nonce to be used as replay protection for the order
	uint256 nonce;
	/// @dev The chainId of the origin chain
	uint256 originChainId;
	/// @dev The timestamp by which the order must be opened
	uint32 openDeadline;
	/// @dev The timestamp by which the order must be filled on the destination chain
	uint32 fillDeadline;
	/// @dev Type identifier for the order data. This is an EIP-712 typehash.
	bytes32 orderDataType;
	/// @dev Arbitrary implementation-specific data
	/// Can be used to define tokens, amounts, destination chains, fees, settlement parameters,
	/// or any other order-type specific information
	bytes orderData;
}

/// @title OnchainCrossChainOrder CrossChainOrder type
/// @notice Standard order struct for user-opened orders, where the user is the msg.sender.
struct OnchainCrossChainOrder {
	/// @dev The timestamp by which the order must be filled on the destination chain
	uint32 fillDeadline;
	/// @dev Type identifier for the order data. This is an EIP-712 typehash.
	bytes32 orderDataType;
	/// @dev Arbitrary implementation-specific data
	/// Can be used to define tokens, amounts, destination chains, fees, settlement parameters,
	/// or any other order-type specific information
	bytes orderData;
}
```

{% endcode %}

Crosschain execution systems implementing this standard SHOULD use a sub-type that can be parsed from the arbitrary `orderData` field. This may include information such as the tokens involved in the transfer, the destination chain IDs, fulfillment constraints or settlement oracles.

All sub-types SHOULD be registered in a subtypes repository to encourage sharing of sub-types based on their functionality. See the examples section for an example of how sub-types can be used to support behavior like executing calldata on a target contract of the user's choice on the destination chain.

**ResolvedCrossChainOrder struct**

A compliant crosschain order type MUST be convertible into the `ResolvedCrossChainOrder` struct. This means that the `orderData` must be decoded into the information needed to populate the `ResolvedCrossChainOrder` struct. Additionally, `orderData` SHOULD be decodable into a sub-type, which can be used for further functionality such as crosschain calldata execution (see the examples section for an example of this). It is the responsibility of the `user` and the `filler` to ensure that the `originSettler` supports their order's contained sub-type.

{% code overflow="wrap" %}

```solidity
/// @title ResolvedCrossChainOrder type
/// @notice An implementation-generic representation of an order intended for filler consumption
/// @dev Defines all requirements for filling an order by unbundling the implementation-specific orderData.
/// @dev Intended to improve integration generalization by allowing fillers to compute the exact input and output information of any order
struct ResolvedCrossChainOrder {
	/// @dev The address of the user who is initiating the transfer
	address user;
	/// @dev The chainId of the origin chain
	uint256 originChainId;
	/// @dev The timestamp by which the order must be opened
	uint32 openDeadline;
	/// @dev The timestamp by which the order must be filled on the destination chain(s)
	uint32 fillDeadline;
	/// @dev The unique identifier for this order within this settlement system
	bytes32 orderId;

	/// @dev The max outputs that the filler will send. It's possible the actual amount depends on the state of the destination
	///      chain (destination dutch auction, for instance), so these outputs should be considered a cap on filler liabilities.
	Output[] maxSpent;
	/// @dev The minimum outputs that must to be given to the filler as part of order settlement. Similar to maxSpent, it's possible
	///      that special order types may not be able to guarantee the exact amount at open time, so this should be considered
	///      a floor on filler receipts.
	Output[] minReceived;
	/// @dev Each instruction in this array is parameterizes a single leg of the fill. This provides the filler with the information
	///      necessary to perform the fill on the destination(s).
	FillInstruction[] fillInstructions;
}

/// @notice Tokens that must be receive for a valid order fulfillment
struct Output {
	/// @dev The address of the ERC20 token on the destination chain
	/// @dev address(0) used as a sentinel for the native token
	bytes32 token;
	/// @dev The amount of the token to be sent
	uint256 amount;
	/// @dev The address to receive the output tokens
	bytes32 recipient;
	/// @dev The destination chain for this output
	uint256 chainId;
}

/// @title FillInstruction type
/// @notice Instructions to parameterize each leg of the fill
/// @dev Provides all the origin-generated information required to produce a valid fill leg
struct FillInstruction {
	/// @dev The contract address that the order is meant to be settled by
	uint64 destinationChainId;
	/// @dev The contract address that the order is meant to be filled on
	bytes32 destinationSettler;
	/// @dev The data generated on the origin chain needed by the destinationSettler to process the fill
	bytes originData;
}
```

{% endcode %}

**Open event**

A compliant `Open` event MUST adhere to the following abi:

{% code overflow="wrap" %}

```solidity
/// @notice Signals that an order has been opened
/// @param orderId a unique order identifier within this settlement system
/// @param resolvedOrder resolved order that would be returned by resolve if called instead of Open
event Open(bytes32 indexed orderId, ResolvedCrossChainOrder resolvedOrder);
```

{% endcode %}

**Settlement interfaces**

A compliant origin settler contract implementation MUST implement the `IOriginSettler` interface:

{% code overflow="wrap" %}

```solidity
/// @title IOriginSettler
/// @notice Standard interface for settlement contracts on the origin chain
interface IOriginSettler {
	/// @notice Opens a gasless crosschain order on behalf of a user.
	/// @dev To be called by the filler.
	/// @dev This method must emit the Open event
	/// @param order The GaslessCrossChainOrder definition
	/// @param signature The user's signature over the order
	/// @param originFillerData Any filler-defined data required by the settler
	function openFor(GaslessCrossChainOrder calldata order, bytes calldata signature, bytes calldata originFillerData) external;

	/// @notice Opens a crosschain order
	/// @dev To be called by the user
	/// @dev This method must emit the Open event
	/// @param order The OnchainCrossChainOrder definition
	function open(OnchainCrossChainOrder calldata order) external;

	/// @notice Resolves a specific GaslessCrossChainOrder into a generic ResolvedCrossChainOrder
	/// @dev Intended to improve standardized integration of various order types and settlement contracts
	/// @param order The GaslessCrossChainOrder definition
	/// @param originFillerData Any filler-defined data required by the settler
	/// @return ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order
	function resolveFor(GaslessCrossChainOrder calldata order, bytes calldata originFillerData) external view returns (ResolvedCrossChainOrder memory);

	/// @notice Resolves a specific OnchainCrossChainOrder into a generic ResolvedCrossChainOrder
	/// @dev Intended to improve standardized integration of various order types and settlement contracts
	/// @param order The OnchainCrossChainOrder definition
	/// @return ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order
	function resolve(OnchainCrossChainOrder calldata order) external view returns (ResolvedCrossChainOrder memory);
}
```

{% endcode %}

A compliant destination settlement contract implementation MUST implement the `IDestinationSettler` interface:

{% code overflow="wrap" %}

```solidity
/// @title IDestinationSettler
/// @notice Standard interface for settlement contracts on the destination chain
interface IDestinationSettler {
	/// @notice Fills a single leg of a particular order on the destination chain
	/// @param orderId Unique order identifier for this order
	/// @param originData Data emitted on the origin to parameterize the fill
	/// @param fillerData Data provided by the filler to inform the fill or express their preferences
	function fill(bytes32 orderId, bytes calldata originData, bytes calldata fillerData) external;
}
```

{% endcode %}

**fillerData**

Crosschain execution systems implementing this standard SHOULD use a sub-type that can be parsed from the arbitrary `fillerData` field. This may include information such as the desired timing or form of payment for the filler

All sub-types SHOULD be registered in a subtypes repository to encourage sharing of sub-types based on their functionality.

### Rationale

**Generic OrderData**

A key consideration is to ensure that a broad range of crosschain intent designs can work within the same standard. To enable this, the specification is designed around a crosschain intents *flow*, with two variations: gasless and onchain.

**Gasless crosschain intents flow**

Origin Chain:

1. The user signs an off-chain message defining the parameters of their order
2. The order is disseminated to fillers
3. The filler calls resolve to unpack the order's requirements
4. The filler opens the order on the origin chain

Destination Chain(s):

* The filler fills each leg of the order on the destination chain(s)

Settlement:

* A crosschain settlement process takes place to settle the order

**Onchain crosschain intents flow**

Origin Chain:

1. The caller signs a transaction calling open with their order
2. The filler retrieves the emitted event to determine requirements

Destination Chain(s):

* The filler fills each leg of the order on the destination chain(s)

Settlement:

* A crosschain settlement process takes place to settle the order

**Customization**

Within this flow, implementers of the standard have design flexibility to customize behavior such as:

* Price resolution, e.g. dutch auctions (on origin or destination) or oracle-based pricing
* Fulfillment constraints
* Settlement procedures
* Ordering of the origin and destination chain actions, e.g. the fill could happen before `open` in some settlement systems

The `orderData` field allows implementations to take arbitrary specifications for these behaviors while still enabling integrators to parse the primary fields of the order.

This functionality also motivated the `resolve` view function and `ResolvedCrossChainOrder` type. Resolution enables integrating fillers to validate and assess orders without specific knowledge of the `orderData` field at hand.

**Emission of Fill Instructions**

An important component of the standard is creating a flexible and robust mechanism for fillers to ensure their fills are valid. For a fill to be valid, it typically must satisfy the following constraints:

1. It must be filled on the correct destination chain(s)
2. It must be filled on the correct destination contract
3. It must include some (not necessarily all) information from the order that the user provided on the origin chain
4. It may require some execution information from the `open` call on the origin chain (ex. dutch auctions based on open timing)

The `FillInstruction` array in `ResolvedCrossChainOrder` is intended to ensure it's simple for the filler to meet all of these requirements by either listening for the `Open` or by calling `resolve`.

One may notice that the `originData` field within `FillInstruction` is completely opaque. This opaqueness allows the settler implementations to freely customize the data they transmit. Because fillers do not need to interpret this information, the opaqueness does not result in any additional implementation costs on fillers.

This functionality also makes it feasible for a user, filler, or order distribution system to perform an end-to-end simulation of the order initiation and fill to evaluate all resulting state transitions without understanding the nuances of a particular execution system.

**Cross-compatibility**

Since this standard is intended to reduce friction for users moving value across chains, non-EVM ecosystems should not be excluded. However, attempting to pull each non-EVM ecosystem in would dramatically increase the size and complexity of this standard, while ommitting any that come in the future.

Instead, this standard is intended to be cross-compatible with other ecosystems. It standardizes interfaces and data types on EVM chains, but allows for the creation of sibling standards that define compatible interfaces, data types, and flows within other ecosystems. Intents created within these sibling standards should be able to be filled on an EVM chain and vice versa.

To ensure this cross-compatibility, all foreign addresses use `bytes32` rather than `address` to allow for larger address identifiers.

**Usage of Permit2**

Permit2 is not specifically required by this standard, but does provide an efficient and straightforward approach to building standard-adherent protocols. Specifically, the `witness` functions of permit2 allow users to both approve the token transfer *and* the order itself with a single signature. This also nicely couples the transfer of tokens with a successful initiation of the order.

In contrast, a standard approval model would require two separate signatures - a token approval (either ERC-2612 or on-chain) and a signature to approve the terms of the order. It also decouples the token approval from the order, meaning approved tokens could potentially be taken at any time due to a buggy or untrusted settler contract.

When building a standard-compliant settler system around Permit2, the following considerations should be made

* `nonce` in the order struct should be a permit2 nonce
* `openDeadline` in the order struct should be the permit2 deadline
* A full order struct including the parsed `orderData` should be used as the witness type during the permit2 call. This ensures maximum transparency to the user as they sign their order permit.

### **Examples**

This is an example of how a 7683 crosschain value transfer order can include instructions to the filler to execute arbitrary calldata on behalf of the recipient on the destination chain. This calldata execution is performed by the settlement contract atomically within the filler's fill() execution, so the arbitrary contract execution can take advantage of the destination chain recipient's newly transferred value. A hypothetical user in this example would select a `originSettler` that is known to support the `Message` sub-type.

Let there be a sub-type called `Message`, which is defined by the following structs:

{% code overflow="wrap" %}

```solidity
// The Message subtype allows ERC7683 intents to carry calldata that is executed on a target contract on the destination chain. The settlement contract that the filler interacts with on the destination chain will decode the message into smart contract calls and execute the calls within the filler's `fill()` transaction.

// The Message contains calls that the user wants executed on the destination chain.
// The target is a contract on the destination chain that the settlement contract will attempt to send callData and value to.
struct Calls {
  address target;
  bytes callData;
  uint256 value;
}

struct Message {
  Calls[] calls;
}
```

{% endcode %}

The `Message` sub-type is designed to be used by a 7683 user to incentivize a filler to to execute arbitrary calldata on a target destination chain contracton the user's behalf. For example, the settlement contract might decode the `orderData` containing the message information as follows:

{% code overflow="wrap" %}

```solidity
function fill(bytes32 orderId, bytes calldata originData, bytes calldata fillerData) public {
	(
		address user,
		uint32 fillDeadline,
		Output memory fillerOutput,
		Message memory message
	) = abi.decode(originData);

	// ...Do some preprocessing on the parameters here to validate the order...

	// ...Execute the fill logic of the ResolvedCrossChainOrder...

	// Handle the Message subtype:

        // Revert if any of the message calls fail.
        uint256 length = message.calls.length;
        for (uint256 i = 0; i < length; ++i) {
            Call memory call = message.calls[i];

            // If we are calling an EOA with calldata, assume target was incorrectly specified and revert.
            if (call.callData.length > 0 && call.target.code.length == 0) {
                revert InvalidCall(i, calls);
            }

            (bool success, ) = call.target.call{ value: call.value }(call.callData);
            if (!success) revert CallReverted(i, message.calls);
        }
    }
```

{% endcode %}

In this example, the Message sub-type allows the user to delegate destination chain contract execution to fillers. However, because transactions are executed via filler, the `msg.sender` would be the `DestinationSettler`, making this `Message` sub-type limited if the target contract authenticates based on the `msg.sender`. Ideally, 7683 orders containing Messages can be combined with smart contract wallets like implementations of ERC-4337 or EIP-7702 to allow complete crosschain delegated execution.

### Security Considerations <a href="#security-considerations" id="security-considerations"></a>

**Evaluating settlement contract security**

This ERC is agnostic of how the settlement system validates a 7683 order fulfillment and refunds the filler. In fact, this ERC is designed to delegate the responsibility of evaluating the settlement contract's security to the filler and the application that creates the user's 7683 order.

This design decision is motivated by the existence of many viable crosschain messaging systems today offering settlement contracts a variety of tradeoffs. We hope that this standard can eventually support an ERC dedicated to standardizing a safe, trustless, crosschain verification system.

### Copyright <a href="#copyright" id="copyright"></a>

Copyright and related rights waived via CC0.


# Resources

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td></td><td><strong>Across and Uniswap Labs propose standard for crosschain intents to accelerate crosschain interoperability</strong></td><td></td><td><a href="/files/c1WOZzeHTsvEmOxlAPCD">/files/c1WOZzeHTsvEmOxlAPCD</a></td><td><a href="https://across.to/blog/Across-and-Uniswap-Labs-propose-standard-for-cross-chain-Intents-to-accelerate-cross-chain-interoperability">https://across.to/blog/Across-and-Uniswap-Labs-propose-standard-for-cross-chain-Intents-to-accelerate-cross-chain-interoperability</a></td></tr><tr><td></td><td><strong>ERC-7683 Crosschain Intents: An interface for crosschain trade execution systems.</strong> </td><td></td><td><a href="/files/hn7qanYw3ILyts4GJBZF">/files/hn7qanYw3ILyts4GJBZF</a></td><td><a href="https://eips.ethereum.org/EIPS/eip-7683">https://eips.ethereum.org/EIPS/eip-7683</a></td></tr><tr><td></td><td><strong>Ethereum Magicians Forum Discussion</strong></td><td></td><td><a href="/files/qZ84oCgwljJWfrgaWIM6">/files/qZ84oCgwljJWfrgaWIM6</a></td><td><a href="https://ethereum-magicians.org/t/erc-7683-cross-chain-intents-standard/19619">https://ethereum-magicians.org/t/erc-7683-cross-chain-intents-standard/19619</a></td></tr></tbody></table>


# ERC-7683 in Production

Explore crosschain intents in production. Walk through a brief example of the intent execution flow and related smart contracts.

## Getting Started

To learn how crosschain intents work in production, lets start by forming a mental model on how users need to input their intents. All the complexities of blockchains, solver networks and any trust assumptions are abstracted away making the UX extremely fast and streamlined.

&#x20;Think of it as an order ticket with the following fields:&#x20;

1. **originChain:** Chain where you currently hold tokens.
2. **originToken:** Token which you currently hold and want to bridge over to the destination chain.
3. **originAmount:** Amount of the token that you want to bridge over to the destination chain.
4. **destinationChain:** Chain on which you want to finally bridge over the tokens.
5. **destinationToken:** Token which you want to exchange your current token for on the destination chain.
6. **minReceived:** Minimum amount of the destination token that you want to receive after gas deductions and any other costs.&#x20;
7. **fillInstructions:** Any additional messages you want to send along with the transfer.

There are a few more details here, but let's focus on just these to keep things simple and understand the power and impact of crosschain intents.

<figure><img src="/files/exu0NXN76tfPwngHbOoW" alt="ERC-7683 ORDER TICKET. "><figcaption></figcaption></figure>

***

## Production Contracts

**AcrossOriginSettler** contract processes an external order type and translates it into an **AcrossV3Deposit** that it sends to the **SpokePool** Contract. This allows crosschain intents to work seamlessly throughout multiple chains. You can learn more about the Across protocol [here](https://docs.across.to/).

Currently, **AcrossOriginSettler** contract is deployed on the following chains:

<table><thead><tr><th width="220">Chain</th><th>Contract Address</th></tr></thead><tbody><tr><td>Base</td><td><a href="https://basescan.org/address/0x4afb570AC68BfFc26Bb02FdA3D801728B0f93C9E">0x4afb570AC68BfFc26Bb02FdA3D801728B0f93C9E</a></td></tr><tr><td>Arbitrum</td><td><a href="https://arbiscan.io/address/0xb0b07055f214ce59ccb968663d3435b9f3294998">0xB0B07055F214Ce59ccB968663d3435B9f3294998</a></td></tr></tbody></table>

***

## Intents in Action

Now, let's walk through crosschain intent execution and learn how using the **AcrossOriginSettler** contract, we can bridge 10 USDC from Base to Arbitrum.

### Pre-requisites

1. A wallet with 10 USDC on Base.
2. An IDE.

### Setup

As you may have read in the [spec](https://www.erc7683.org/spec#specification), it is important that we perform the ABI encoding of our request and ensure that all information is correctly passed on to **AcrossOriginSettler** contract.&#x20;

To do that, please use the following shell script:

````sh
```shellscript
depositor="${1:-<input-your-public-key>}"

padded_depositor="0x000000000000000000000000${depositor:2}"


echo -n "fillDeadline: "

current_timestamp=$(date +%s)
seconds_to_add=$((30 * 60))
new_timestamp=$((current_timestamp + seconds_to_add))
echo $new_timestamp

echo -n "orderDataType: "
echo "0x9df4b782e7bbc178b3b93bfe8aafb909e84e39484d7f3c59f400f1b4691f85e2"

#echo -n "orderData: "
#cast abi-encode "AcrossOrderData(address,uint256,address,uint256,uint256,bytes32,address,uint256,uint32,bytes)" \
#    0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 `# inputToken` \
#    10000000                                   `# inputAmount` \
#    0xaf88d065e77c8cC2239327C5EDb3A432268e5831 `# outputToken` \
#    9970000                                    `# outputAmount` \
#    42161                                      `# destinationChainId` \
#    0x00000000000000000000000recipient `# recipient (padded)` \
#    0x0000000000000000000000000000000000000000 `# exclusiveRelayer` \
#    0                                          `# depositNonce` \
#    0                                          `# exclusivityPeriod` \
#    0x                                       `# message`


echo -n "orderData: "
cast abi-encode "AcrossOrderData((address,uint256,address,uint256,uint256,bytes32,address,uint256,uint32,bytes))" "(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913,10000000,0xaf88d065e77c8cC2239327C5EDb3A432268e5831,9980000,42161,${padded_depositor},0x0000000000000000000000000000000000000000,0,0,0x)"

```
````

:bulb:: You can open this in an IDE of choice and ensure that you input your public key as the depositor. You can name the file whatever you want, for this demo we will call it "demo.sh".

Now, run the shell script by executing the following command on your terminal:

```bash
bash demo.sh
```

Here is what the output should look like:

{% code overflow="wrap" %}

```bash
fillDeadline: 1739798544
orderDataType: 0x9df4b782e7bbc178b3b93bfe8aafb909e84e39484d7f3c59f400f1b4691f85e2
orderData: 0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda029130000000000000000000000000000000000000000000000000000000000989680000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e58310000000000000000000000000000000000000000000000000000000000984860000000000000000000000000000000000000000000000000000000000000a4b1000000000000000000000000f277cca2b56684fce5cb75e0a0ee18233fe7e50100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000
```

{% endcode %}

Great! Now our intent is ready. In the next step, we will discuss how to use the **AcrossOriginSettler** contract and execute our crosschain intent.&#x20;

### Executing Crosschain Intent

With the `fillDeadline`, `orderDataType` and `orderData` ready, it's now time that we head over to [Basescan.org](https://basescan.org/tx/0xcb6227f82b133e18850cf0cc0ed0edb7b1b597ee90a22f533eb3ceae218d1697) and execute the crosschain intent where we bridge 10 USDC from Base to Arbitrum:

1. Start by going to the contract on Basescan and heading to the **Contract** and then **Write Contract** section and click on **Connect to Web3** to connect your walle&#x74;**:**

   <figure><img src="/files/bwAOaNT1I68lFoE1OlH3" alt=""><figcaption></figcaption></figure>
2. After connecting your wallet, expand the **open** function and input the details we had obtained from our script in the previous section:&#x20;

   <figure><img src="/files/jYgwpqtSeG9Eg1TWyySl" alt=""><figcaption></figcaption></figure>

Now, simply click on **Write** and sign the transaction on your wallet.\
\
Finally check [Arbiscan.io](https://arbiscan.io/). You will notice 10 USDC in your wallet on Arbitrum. This ensures that your crosschain intent was executed successfully.&#x20;

Congratulations! You are now an adopter of ERC-7683 and we thank you for your support.

Incase you need any help, please feel free to reach out to contact us [here](https://t.me/bobbayb).


# Examples

To illustrate the flexibility of the standard, here are some more examples of how `ResolvedCrossChainOrder` could be defined:

### Across + Permit2 Example

A crosschain order on Across has a single input and output token and fillers do not get the full `inputAmount` refunded. Instead, an Across contract on the `originChainId` would define a function like `getFillerFee(order, repaymentChainId)` to deterministically compute the fee charged to them. Fillers on Across can choose where they want to receive their refund.

This example settlement contract contains a `fillCrossChainOrder` in the SettlementContract that fillers can use to fulfill initiated orders. Fills for other settlement systems might be submitted to a different contract than the settlement contract itself.

{% code overflow="wrap" %}

```solidity
AcrossSettlementContract is ISettlementContract {

	// Unique Across nonce
	uint256 depositId;
	// Permit2 contract for this network
	address constant PERMIT2;

	// Data unique to every CrossChainOrder settled on Across
	struct AcrossOrderData {
		uint32 exclusivityDeadline;
		address exclusiveRelayer;
		bytes message;
	}

	// Data unique to every attempted order fulfillment
	struct AcrossFillerData {
		// Filler can choose where they want to be repaid
	  uint256 repaymentChainId;
	}

	function initiate(CrossChainOrder order, bytes signature, bytes fillerData) external {  
	  // Ensure that order was intended to be settled by Across.
	  require(order.settlementContract == address(this));
	  require(order.originChainId == block.chainId);
  
	  // Extract Across-specific params.
	  (resolvedOrder, acrossOrderData) = _resolve(order, fillerData);

		 // Verify Permit2 signature and pull user funds into this contract
		_processPermit2Order(PERMIT2, order, resolvedOrder, signature);
	
		// Emit Across-specific event used for settlement.
		emit FundsDepositedV3(
			resolvedOrder.swapperInputs[0].token,
			resolvedOrder.outputs[0].token,
			resolvedOrder.swapperInputs[0].amount,
			resolvedOrder.outputs[0].amount,
			resolvedOrder.outputs[0].chainId,
			depositId++, // Unique Across nonce
			block.timestamp,
			order.fillDeadline,
			acrossOrderData.exclusivityDeadline,
			order.swapper
			resolvedOrder.outputs[0].recipient,
			acrossOrderData.exclusiveRelayer,
			acrossOrderData.message
		);
	}

	function resolve(CrossChainOrder order, bytes fillerData) external view returns (ResolvedCrossChainOrder) {    
	  (resolvedOrder, ) = _resolve(order, fillerData);
	}

	// Filler calls this function on the destinationChainId to fulfill an order.
	// This function would not always be defined in this SettlementContract, but
	// for illustrative purposes it is included here.
	// (In most cases, the full `order` and `fillerData` wouldn't need to be supplied
	// here, instead a subset would suffice).
	function fillCrossChainOrder(CrossChainOrder order, bytes fillerData) external {
		// Ensure order has not expired
		require(order.fillDeadline >= block.timestamp)
	
	  (, acrossOrderData, acrossFillerData) = _resolve(order, fillerData);
	  
	  // Pull tokens from filler to fill recipient
	  IERC20(resolvedOrder.outputs[0].token).transferFrom(
		  msg.sender, 
		  address(this), 
		  resolvedOrder.outputs[0].amount
		);
		IERC20(crossChainOrder.outputs[0].token).transfer(
		  resolvedOrder.outputs[0].recipient, 
		  resolvedOrder.outputs[0].amount
		);
  
	  // Signal to settlement contract that the crosschain order has been fulfilled
	  // using a combination of standardized order data and Across-specific data decoded
	  // from the standardized order data.
	  emit FilledRelayV3(
	    crossChainOrder.swapperInputs[0].token,
      crossChainOrder.swapperOutputs[0].token,
      crossChainOrder.swapperInputs[0].amount,
      crossChainOrder.outputs[0].amount,
      acrossFillerData.repaymentChainId,
      order.originChainId,
      acrossOrderData.depositId,
      order.fillDeadline,
      acrossOrderData.exclusivityDeadline,
      acrossOrderData.exclusiveRelayer,
      msg.sender,
      order.swapper,
      acrossOrderData.recipient,
      acrossOrderData.message
	  );
}

function _resolve(CrossChainOrder order, bytes fillerData) internal 
	returns(
		AcrossOrderData acrossOrderData, 
		ResolvedCrossChainOrder resolvedCrossChainOrder,
		AcrossFillerData acrossFillerData
	) {
	// Extract Across-specific params.
	acrossOrderData = abi.decode(order.orderData, (AcrossOrderData));
	
	// Compute filler fee using filler-provided data.
	acrossFillerData = abi.decode(fillerData, (AcrossFillerData));
	Output memory fee = FeeCalculator.computeFee(
			order.originChainId, 
			acrossFillerData.repaymentChainId,
			acrossOrderData.inputToken,
			acrossOrderData.inputAmount
	);
		
	resolvedCrossChainOrder = ResolvedCrossChainOrder ({
			settlementContract: address(this);
			swapper: order.swapper;
			nonce: order.nonce;
			originChainId: order.originChainId;
			initiateDeadline: order.initiateDeadline;
			fillDeadline: order.fillDeadline;
			swapperInputs: [Input({ 
				token: acrossOrderData.inputToken,
				amount: acrossOrderData.inputAmount,
				maximumAmount: acrossOrderData.inputAmount
			})],
			swapperOutputs: [Output({ 
				token: acrossOrderData.outputToken,
				amount: acrossOrderData.outputAmount,
				recipient: acrossOrderData.recipient,
				chainId: acrossOrderData.destinationChainId
			})],
			fillerOutputs: [Output({ 
				token: fee.token,
				amount: acrossOrderData.inputAmount - fee.amount,
				recipient: acrossOrderData.recipient,
				chainId: fee.chainId
			})]
}

function _processPermit2Order(
	IPermit2 permit2,
	CrossChainOrder order, 
	ResolvedCrossChain resolvedOrder, 
	bytes signature
) internal {
	  IPermit2.PermitTransferFrom memory permit = IPermit2.PermitTransferFrom({
	    permitted: IPermit2.TokenPermissions({ token: resolvedOrder.swapperInputs[0].token, amount: resolvedOrder.swapperInputs[0].maxAmount }),
      nonce: order.nonce,
      deadline: order.initiateDeadline
    });

    IPermit2.SignatureTransferDetails memory signatureTransferDetails = IPermit2.SignatureTransferDetails({
      to: address(this),
      requestedAmount: resolvedOrder.inputs[0].amount
    });

    // Pull user funds.
    permit2.permitWitnessTransferFrom(
      permit,
      signatureTransferDetails,
      order.swapper,
      _hash(order), // witness data hash
      PERMIT2_ORDER_TYPE, // witness data type string
      signature
    );
}
```

{% endcode %}


# FAQ

## Frequently Asked Questions

***

### General Questions

<details>

<summary>What is a Crosschain Intent?</summary>

A crosschain intent represents any programmable user-defined action—like financial transactions, staking, or governance—that signals the outcome a user expects to happen on a target chain.

</details>

<details>

<summary>What is the ERC-7683 standard?</summary>

ERC-7683 standardizes how these crosschain interactions are expressed as intents, allowing shared infrastructure and orders for seamless crosschain interactions between Ethereum mainnet, L2s, and sidechains.

The ERC-7683 standard defines the structure of a crosschain intent, acting like an order ticket that anyone can create and any solver can fulfill.

</details>

<details>

<summary>What Is the one-liner description of ERC-7683?</summary>

ERC-7683 standardizes how these crosschain interactions are expressed as intents, allowing for shared infrastructure for seamless crosschain transactions between Ethereum mainnet, L2s, and sidechains.

</details>

<details>

<summary> Why do we need a standard for crosschain intents (ERC-7683)?</summary>

The ERC-7683 standard is necessary for establishing a common framework for managing crosschain intents, simplifying development and enhancing compatibility across networks. Specifying a uniform standard prevents fragmented approaches, ensuring that interoperability—one of the core goals of intents—is achieved efficiently and securely for protocols, relayers, and users alike.

</details>

<details>

<summary>How does ERC-7683 help unify Ethereum?</summary>

While L2s have improved Ethereum's scalability, they have also introduced fragmentation within the ecosystem. With ERC-7683, users simply specify what they want to achieve—their "intent"—without worrying about the underlying steps to transfer assets or data between chains. Relayers then compete to fulfill these intents, ensuring users receive the expected outcomes.

This streamlined process makes crosschain transactions feel like they're happening on one chain, creating a unified experience across the Ethereum ecosystem.

</details>

<details>

<summary>How does ERC-7683 help users?</summary>

ERC-7683 enhances the user experience by enabling seamless transactions across different L2s. A shared relayer network promotes competition among relayers to fulfill users' intents.\
\
From the users' perspective, the ERC-7683 reduces transaction costs and accelerates processes due to the competitive environment among relayers. Additionally, ERC-7683 abstracts the complexities of crosschain interactions, reducing friction, which makes the Ethereum ecosystem more accessible and easier to use for everyone.

</details>

<details>

<summary>How does ERC-7683 help protocols?</summary>

ERC-7683 establishes a shared relayer network that protocols can leverage, enabling relayers to support multiple protocols from day one. This interconnectedness fosters network effects and drives ecosystem growth, making protocols more unified and efficient.

Protocols that rely on crosschain liquidity, seamless user experiences, and interoperable infrastructure can utilize systems built on top of ERC-7683—such as Across and UniswapX—to operate cohesively across multiple chains.

</details>

<details>

<summary>How does ERC-7683 help relayers?</summary>

ERC-7683 provides relayers with a unified framework that minimizes the need for custom solutions for each intent protocol. This simplification allows relayers to support protocols that adopt ERC-7683 more easily, reducing their operational overhead and creating additional opportunities.

As a result, more relayers are attracted to support protocols adopting ERC-7683, given the chance to handle a larger volume of transactions across the Ethereum ecosystem.

</details>

<details>

<summary>Why is this only focused on crosschain swaps? Have you considered making a more generalized version?</summary>

ERC-7683 initially focuses on crosschain swaps because they are the most common use case, and it is designed to support more complex actions. The orderData field in the CrossChainOrder struct allows encoding arbitrary data, enabling advanced functionalities like executing additional actions on the destination chain. This flexibility lets intent settlement networks, such as Across, support a range of user-defined actions beyond swaps.

Examples; Bridge + Stake, Bridge + Mint

</details>

<details>

<summary>Can ERC-7683 send crosschain messages?</summary>

While ERC-7683 primarily focuses on crosschain intents involving token swaps and settlements, it is designed to be compatible with existing messaging networks.

The standard itself does not serve as a messaging protocol but acts as a unifying layer that connects offchain messages to onchain settlement contracts. Projects that adopt ERC-7683 have complete flexibility on which messaging approach to adopt in their protocol.

</details>

<details>

<summary>What does it mean for a chain to support ERC-7683?</summary>

Every EVM chain technically supports ERC-7683. ERC-7683's benefit compounds the more settlement contracts, fillers, and dApps that use it. If a chain supports ERC-7683, it means that users and protocols on that chain are actively using the standard to transfer value.

A chain doesn’t need to take special actions to support ERC-7683 beyond signaling support and enabling dApps to adopt and implement it.

</details>

***

### Compatability Questions

<details>

<summary>Are crosschain intents compatible with L2 native interop solutions <br>(agglayer, elastic chain etc.)?</summary>

ERC-7683 is compatible with L2 native interoperability solutions, such as Polygon AggLayer, Optimism Superchain, and ZKsync Elastic Chain. These native interoperability solutions are a type of crosschain messaging, so ERC-7683 protocols can leverage these interoperability solutions for their settlement contract. ERC-7683 is proof system agnostic, offering a flexible framework that allows users to choose their preferred settlement systems and proof mechanisms. By pairing ERC-7683 with these native interop solutions, developers can build a comprehensive system that supports crosschain token transfers on top of these messaging interfaces. Specifically, ERC-7683 can utilize these native interop solutions as its settlement layer.

</details>

<details>

<summary>Are RIP-7755 and ERC-7683 compatible?</summary>

RIP-7755 and ERC-7683 are compatible and complementary standards that enhance crosschain interactions within the Ethereum ecosystem. RIP-7755 standardizes message verification, providing a consistent and secure settlement layer for trust-minimized messaging. ERC-7683 is proof system agnostic, offering a flexible framework that allows users to choose their preferred settlement systems and proof mechanisms. \
\
By pairing ERC-7683 with RIP-7755, developers can build a comprehensive system that supports crosschain token transfers on top of a standardized crosschain messaging interface. Specifically, ERC-7683 can utilize RIP-7755 as its settlement layer. This integration combines the flexible, proof system agnostic approach of ERC-7683 with the standardized message verification process of RIP-7755.Specifically, ERC-7683 can utilize these native interop solutions as its settlement layer.

</details>

<details>

<summary>Are EIP-7702 and ERC-7683 compatible?</summary>

EIP-7702 focuses on account abstraction by allowing externally owned accounts (EOAs) to temporarily function as smart contract wallets during a transaction, enhancing flexibility and user experience. ERC-7683 aims to standardize crosschain trade execution, facilitating seamless interactions across multiple blockchain networks.

Together, they allow users to initiate complex crosschain transactions directly from their EOAs, enhancing interoperability and user experience within the Ethereum ecosystem.

</details>

***

### Technical Questions

<details>

<summary>What is the purpose of a CrossChainOrder struct?</summary>

The CrossChainOrder struct in ERC-7683 serves as a standardized template for defining crosschain transactions. It encapsulates all necessary details—such as the origin and destination chains, involved assets, and execution parameters—into a single, coherent data structure.

This standardization ensures that different protocols and relayers can interpret and process crosschain intents consistently, reducing the risk of errors and enhancing interoperability across various blockchain networks

</details>

<details>

<summary>How does ERC-7683 handle order settlement?</summary>

ERC-7683 handles order settlement by defining a clear, standardized process for fulfilling crosschain intents. Once a user submits an intent, relayers compete to complete the task by executing the required transaction on the destination chain. The protocol then verifies that the intent was successfully fulfilled before releasing the escrowed assets or funds to the relayer. This ensures a secure and efficient transfer that abstracts away complex crosschain interactions, allowing for seamless settlements that maintain trust between parties.

</details>

<details>

<summary>What is flexible in this standard, and can you provide examples?</summary>

Within this flow, implementers of the standard have design flexibility to customize behavior such as:&#x20;

* Price resolution, e.g. dutch auctions (on origin or destination) or oracle-based pricing&#x20;
* Fulfillment constraints&#x20;
* Settlement procedures&#x20;
* Ordering of the origin and destination chain actions, e.g. the fill could happen before open in some settlement systems

For example, the flexibility of ERC-7683 allows anyone to create their own settlement procedure using different verification methods, whether it’s RIP-7755, ZK proofs, or native interoperability like Superchain.

</details>

<details>

<summary>Can somebody do an arbitrary action after the crosschain swap? If so, how?</summary>

Yes, ERC-7683 supports arbitrary actions after a crosschain swap through the bytes orderData field in the CrossChainOrder struct.

This field can include custom data that specifies an action to be executed on the destination chain. For example, users can encode details of a target contract and the necessary calldata for that action. When the solver fulfills the user’s intent, it triggers the specified call to the target contract with the provided data on behalf of the depositor.

</details>

<details>

<summary>Does this standard enforce / assume that the settlement contract has to live on the source chain of the intent?</summary>

No, ERC-7683 does not enforce or assume that the settlement contract must reside solely on the source chain of the intent. While the standard requires that a contract on the origin chain processes the initial intent (as it holds the user’s tokens), it does not limit validation or further interactions to that chain alone.

</details>

<details>

<summary>Have you thought about a standard function for filling?</summary>

We have considered a standard fill function, like fill(CrossChainOrder order, bytes fillerData), but there are challenges. Different protocols need varying parts of the orderData, so requiring the full order would be inefficient. Additionally, some protocols rely on blockchain state at the time of initiation, meaning fillers need a way to communicate contextual information that isn’t known until after initiation. Thus, while a standardized fill function could be useful, the variation in protocol needs makes it difficult to implement without imposing inefficiencies or redundant requirements on different systems.

The chainID is kept as a top-level variable for simplicity and better integration with gasless crosschain intent frameworks, such as Permit2 and EIP-7702. Including chainID at the top level also prevents added complexity for fillers, who would otherwise have to manage multiple chainIDs, track finality across multiple input chains, and handle more complicated market conditions.

</details>

***

| REACH OUT                                                                                                                             | LEARN                                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p>Join us and support ERC-7683 and the vision for a unified Ethereum.<br><br>Contact us <a href="https://t.me/bobbayb">here</a>.</p> | <p>Dive deeper into ERC-7683, an interface for crosschain trade execution systems.<br><br>Learn more <a href="https://www.erc7683.org/about">here</a>.</p> |


# Supporters


# Logos

<div><figure><img src="/files/hWAMj0StFIL4oapRMY2j" alt=""><figcaption></figcaption></figure> <figure><img src="/files/m9mHdw9Eripb1O2obDGv" alt=""><figcaption></figcaption></figure> <figure><img src="/files/er31Czrw5tgDIZKfQ6wL" alt=""><figcaption></figcaption></figure> <figure><img src="/files/EAdYY37pPfdneugh7DYo" alt=""><figcaption></figcaption></figure> <figure><img src="/files/kXsdG5oTyVvPELYnynex" alt=""><figcaption></figcaption></figure> <figure><img src="/files/wMY1FoDQgJM6jUzuFmPR" alt=""><figcaption></figcaption></figure> <figure><img src="/files/rxUGVscpGEPrhGqwTHwH" alt=""><figcaption></figcaption></figure> <figure><img src="/files/huJqtfX3cewXHFY3qzDH" alt=""><figcaption></figcaption></figure> <figure><img src="/files/YfsYYbeQwPr1dd4j6Slg" alt=""><figcaption></figcaption></figure> <figure><img src="/files/IimPJsiLuvRa8hiX7iJ2" alt=""><figcaption></figcaption></figure> <figure><img src="/files/8U0cg4tgbR0uScGEMiqS" alt=""><figcaption></figcaption></figure> <figure><img src="/files/aI1j4ccuBebOG1o2htU0" alt=""><figcaption></figcaption></figure> <figure><img src="/files/UCwu4g8QCobOBln0sS3V" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="/files/F8p93z1FFIuckW7R63Vk" alt=""><figcaption></figcaption></figure> <figure><img src="/files/LNW97Ehxl1rjHWr03Ynp" alt=""><figcaption></figcaption></figure> <figure><img src="/files/oZ9UJgdM5ugdYqeXsDit" alt=""><figcaption></figcaption></figure> <figure><img src="/files/WzqpI637cyT0JgIPxxNJ" alt=""><figcaption></figcaption></figure> <figure><img src="/files/xlRP5WqUtSWRi7PG2B5I" alt=""><figcaption></figcaption></figure> <figure><img src="/files/EuaZ6JiOkO8QeRVpuP1L" alt=""><figcaption></figcaption></figure> <figure><img src="/files/FrXFWnK8X8tJdO7jsMla" alt=""><figcaption></figcaption></figure> <figure><img src="/files/55khFuy5p0WEDUf0ukPn" alt=""><figcaption></figcaption></figure> <figure><img src="/files/gfhFVFm3Pw7wxc4c759M" alt=""><figcaption></figcaption></figure> <figure><img src="/files/91bfTuR9au2NwO86ykFg" alt=""><figcaption></figcaption></figure> <figure><img src="/files/uYk9YXZ5T4IXoF9KrQoi" alt=""><figcaption></figcaption></figure> <figure><img src="/files/3UE6CDyUadWq4t8nGaC5" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="/files/YjoTPXOR8feA3yOWbnxn" alt=""><figcaption></figcaption></figure> <figure><img src="/files/EpMgiDlXRDWlc6yi720s" alt=""><figcaption></figcaption></figure> <figure><img src="/files/ZD5qUI6QaNlbiDpwhAyr" alt=""><figcaption></figcaption></figure> <figure><img src="/files/RZpRA5g7xoQB5vprIWFY" alt=""><figcaption></figcaption></figure> <figure><img src="/files/csbpp3d3yfd6eIpoy6NH" alt=""><figcaption></figcaption></figure> <figure><img src="/files/5KQuaQ66zRRkASmBgKnH" alt=""><figcaption></figcaption></figure> <figure><img src="/files/0nOflKMM9MAMy2Nb510l" alt=""><figcaption></figcaption></figure> <figure><img src="/files/5F6fR5LE0GIodMGnh1EP" alt=""><figcaption></figcaption></figure> <figure><img src="/files/k1xRRcWLnDQX9A59ileu" alt=""><figcaption></figcaption></figure> <figure><img src="/files/VfVpWtJj1UUk9FvUxcNX" alt=""><figcaption></figcaption></figure> <figure><img src="/files/yZC6cJUaBNIgAsv1axLk" alt=""><figcaption></figcaption></figure> <figure><img src="/files/fvRwqFZmo8fRmMXpyT3q" alt=""><figcaption></figcaption></figure> <figure><img src="/files/gV42kkJO5wLK5TNOb1Ix" alt=""><figcaption></figcaption></figure> <figure><img src="/files/a9NnqgHE1jFffuWGTjs3" alt=""><figcaption></figcaption></figure> <figure><img src="/files/9revdd8RaWxyxOhVCJZD" alt=""><figcaption></figcaption></figure></div>


