Periphery Contracts

Understand emissaries and Tribunal as peripheral patterns that integrate with Uniswap The Compact claim verification flows.

Emissaries

Emissaries provide a fallback verification mechanism for sponsors when authorizing claims. This is particularly useful for:

Use caseWhy emissaries help
Smart contract accounts with upgradable EIP-1271 logicKeeps claim verification behavior stable across signature-validation upgrades.
Accounts using EIP-7702 delegation with EIP-1271Provides a fallback verifier when delegation or account behavior changes.
Sponsors delegating claim verification to third partiesAllows explicit trust delegation for claim authorization.

A sponsor assigns an emissary for a specific lockTag using assignEmissary. The emissary must implement the IEmissary interface, specifically the verifyClaim function.

To change an emissary after one has been assigned, the sponsor must first call scheduleEmissaryAssignment, wait for the resetPeriod associated with the lockTag to elapse, and then call assignEmissary again with the new emissary address (or address(0) to remove).

IEmissary interface

Emissaries must implement the IEmissary interface to integrate with The Compact:

Function signature

interface IEmissary {
    function verifyClaim(
        address sponsor,
        bytes32 digest,
        bytes32 claimHash,
        bytes calldata signature,
        bytes12 lockTag
    ) external view returns (bytes4)
}

The function must return IEmissary.verifyClaim.selector on successful verification.

Assignment and management

Sponsors assign emissaries for specific lock tags:

function assignEmissary(
    bytes12 lockTag,
    address emissary
) external
ParameterDescription
lockTagSpecific resource lock tag this emissary is authorized for.
emissaryEmissary contract address, or address(0) to remove.

The emissary assignment is scoped to a specific lockTag, meaning sponsors can have different emissaries for different resource locks.

Changing an emissary

The emissary mechanism includes security timelocks to prevent sudden authorization changes:

StepAction
1Call scheduleEmissaryAssignment with the new emissary address.
2Wait for the resetPeriod associated with the lockTag to elapse.
3Call assignEmissary again with the new address.
function scheduleEmissaryAssignment(
    bytes12 lockTag,
    address newEmissary
) external

Removing an emissary

To remove an emissary, assign address(0):

assignEmissary(lockTag, address(0))

Security rationale

This timelock mechanism ensures that emissary changes cannot suddenly alter the authorization logic for outstanding compacts without providing adequate notice. This protects claimants who may have already begun fulfilling compact conditions based on the existing emissary.

Role in claim verification

When a claim is submitted for a non-registered compact, The Compact verifies the sponsor's authorization in the following order:

OrderVerification path
1Caller is sponsor: if msg.sender == sponsor, authorization is granted.
2ECDSA signature: attempt standard ECDSA signature verification.
3EIP-1271 isValidSignature: if ECDSA fails, call isValidSignature on the sponsor's address (if it is a contract) with half the remaining gas.
4Emissary verifyClaim: if EIP-1271 fails or is not applicable and an emissary is assigned for sponsor + lockTag, call emissary verifyClaim.

Events

event EmissaryAssigned(
    address indexed sponsor,
    bytes12 indexed lockTag,
    address emissary
)

Emitted when a sponsor assigns or changes an emissary via assignEmissary.

Trust assumptions

Sponsors must trust that emissaries will not authorize claims maliciously, as emissaries effectively have the same authorization power as the sponsor for claim verification.

Claimants must trust that emissaries (if assigned) will faithfully authorize valid claims. For EIP-7702 sponsors and smart contracts with upgradeable EIP-1271 logic, claimants should require the use of known, canonical emissaries that enforce delays before allowing key rotation.

Tribunal

Tribunal is a framework for processing cross-chain swap settlements against PGA (priority gas auction) blockchains. It ensures that tokens are transferred according to the mandate specified by the originating sponsor and enforces that a single party is able to perform the settlement in the event of a dispute.

About Tribunal

Tribunal is a reference implementation, not part of The Compact core protocol. The Compact itself is an unopinionated primitive that doesn't depend on or have awareness of any specific settlement engine. Tribunal is included in this documentation as an example that demonstrates how developers can build cross-chain settlement systems on top of The Compact.

Other teams can (and should) build their own settlement engines with different trust assumptions, auction mechanisms, or cross-chain messaging approaches. Tribunal simply shows one proven pattern for orchestrating cross-chain fills and settlements using The Compact's resource locks.

Tribunal is actively under development. For the latest updates and implementation details, see the Tribunal repository.

How Tribunal works

Fillers call fill and provide any native value necessary to pay for cross-chain messaging. Tribunal verifies expiry, chain IDs, validity conditions, computes hashes and amounts, and then executes the settlement:

Settlement pathBehavior
TransferSends filled tokens to the intended recipient.
Same-chain fillClaims tokens via The Compact and calls back into the arbiter or recipient.
Cross-chain fillEmits or processes directives that instruct remote arbiters to pull the claim.

By enforcing a single settlement path, Tribunal reduces settlement ambiguity and ensures deterministic outcomes even in the presence of multiple fillers.

Extending Tribunal

External bridge protocols can extend Tribunal by overriding internal functions to implement the relevant directive processing logic for passing a message to the arbiter on the claim chain (or ensure that the necessary state is updated to allow for the arbiter to "pull" the message themselves).