Beamer contracts API reference

Contracts

contract FillManager is Ownable, LpWhitelist

The fill manager.

This contract is responsible for keeping track of filled requests. In addition to allowing agents to (eventually) prove that they filled requests, it also allows anyone to invalidate a claim that a request was filled.

It is the only contract that agents need to interact with on the target chain.

event RequestFilled(bytes32 indexed requestId, bytes32 fillId, uint256 indexed sourceChainId, address indexed targetTokenAddress, address filler, uint256 amount)

Emitted when a request has been filled.

See also

fillRequest

event FillInvalidated(bytes32 indexed requestId, bytes32 indexed fillId)

Emitted when a fill has been invalidated.

See also

invalidateFill

IMessenger public immutable messenger
address public l1Resolver

The L1 Resolver contract to be used for L1 resolution.

mapping (bytes32 => bytes32) public fills

Maps request IDs to fill IDs.

constructor(address _messenger)

Constructor.

Parameters:
  • _messenger – The messenger.

function setResolver(address _l1Resolver)
public
onlyOwner

Set the resolver’s address

Can only ever be set once. Before it is set, no fills or invalidations are possible

Parameters:
  • _l1Resolver – The L1 resolver address

function fillRequest(uint256 sourceChainId, address targetTokenAddress, address targetReceiverAddress, uint256 amount, uint96 nonce)
external
onlyAllowed(msg . sender)
returns (bytes32)

Fill the specified request.

The caller must have approved at least amount tokens for FillManager with the ERC20 token contract at targetTokenAddress. The tokens will be immediately sent to targetReceiverAddress and a fill proof will be generated, which can later be used to trigger L1 resolution, if needed.

Parameters:
  • sourceChainId – The source chain ID.

  • targetTokenAddress – Address of the token contract on the target chain.

  • targetReceiverAddress – Recipient address on the target chain.

  • amount – Amount of tokens to transfer. Does not include fees.

  • nonce – The nonce used to create the request ID.

Return:

The fill ID.

function invalidateFill(bytes32 requestId, bytes32 fillId, uint256 sourceChainId)
external

Invalidate the specified fill.

In cases that a claim has been made on the source chain, but without a corresponding fill actually happening on the target chain, anyone can call this function to mark the fill as invalid. This is typically followed by a challenge game on the source chain, which the dishonest claimer is guaranteed to lose as soon as the information about the invalid fill (so called “non-fill proof”) is propagated to the source chain via L1 resolution.

Parameters:
  • requestId – The request ID.

  • fillId – The fill ID.

  • sourceChainId – The source chain ID.

contract RequestManager is Ownable, LpWhitelist, RestrictedCalls, Pausable

The request manager.

This contract is responsible for keeping track of transfer requests, implementing the rules of the challenge game and holding deposited tokens until they are withdrawn. The information passed by L1 resolution will be stored with the respective requests.

It is the only contract that agents need to interact with on the source chain. .. note:

The functions resolveRequest and invalidateFill can only be called by
the :sol:contract:`Resolver` contract, via a chain-dependent messenger contract.
event RequestCreated(bytes32 indexed requestId, uint256 targetChainId, address sourceTokenAddress, address targetTokenAddress, address indexed sourceAddress, address targetAddress, uint256 amount, uint96 nonce, uint32 validUntil)

Emitted when a new request has been created.

See also

createRequest

event DepositWithdrawn(bytes32 requestId, address receiver)

Emitted when the token deposit for request requestId has been transferred to the receiver.

This can happen in two cases:

  • the request expired and the request submitter called withdrawExpiredRequest

  • a claim related to the request has been resolved successfully in favor of the claimer

event ClaimMade(bytes32 indexed requestId, uint96 claimId, address claimer, uint96 claimerStake, address lastChallenger, uint96 challengerStakeTotal, uint256 termination, bytes32 fillId)

Emitted when a claim or a counter-claim (challenge) has been made.

event ClaimStakeWithdrawn(uint96 claimId, bytes32 indexed requestId, address stakeRecipient)

Emitted when staked native tokens tied to a claim have been withdrawn.

This can only happen when the claim has been resolved and the caller of withdraw is allowed to withdraw their stake.

See also

withdraw

event FinalityPeriodUpdated(uint256 targetChainId, uint256 finalityPeriod)
event TokenUpdated(address tokenAddress, uint256 transferLimit, uint96 minLpFee, uint32 lpFeePPM, uint32 protocolFeePPM)

Emitted when token object of a token address is updated.

See also

updateToken

event RequestResolved(bytes32 requestId, address filler, bytes32 fillId)

Emitted when a request has been resolved via L1 resolution.

See also

resolveRequest

event FillInvalidatedResolved(bytes32 requestId, bytes32 fillId)

Emitted when an invalidated fill has been resolved.

See also

invalidateFill

uint96 public immutable claimStake

The minimum amount of source chain’s native token that the claimer needs to provide when making a claim, as well in each round of the challenge game.

uint256 public immutable claimRequestExtension

The additional time given to claim a request. This value is added to the validity period of a request.

uint256 public immutable claimPeriod

The period for which the claim is valid.

uint256 public immutable challengePeriodExtension

The period by which the termination time of a claim is extended after each round of the challenge game. This period should allow enough time for the other parties to counter-challenge.

Note

The claim’s termination time is extended only if it is less than the extension time.

Note that in the first challenge round, i.e. the round initiated by the first challenger, the termination time is extended additionally by the finality period of the target chain. This is done to allow for L1 resolution.

uint256 public constant MIN_VALIDITY_PERIOD

The minimum validity period of a request.

uint256 public constant MAX_VALIDITY_PERIOD

The maximum validity period of a request.

uint96 public constant CLAIM_ID_WITHDRAWN_EXPIRED

withdrawClaimId is set to this value when an expired request gets withdrawn by the sender

uint96 public currentNonce

A counter used to generate request and claim IDs. The variable holds the most recently used nonce and must be incremented to get the next nonce

mapping (uint256 => uint256) public finalityPeriods

Maps target rollup chain IDs to finality periods. Finality periods are in seconds.

mapping (bytes32 => Request) public requests

Maps request IDs to requests.

mapping (uint96 => Claim) public claims

Maps claim IDs to claims.

mapping (address => Token) public tokens

Maps ERC20 token address to tokens

function lpFee(address tokenAddress, uint256 amount)
public
view
returns (uint256)

Compute the liquidity provider fee that needs to be paid for a given transfer amount.

function protocolFee(address tokenAddress, uint256 amount)
public
view
returns (uint256)

Compute the protocol fee that needs to be paid for a given transfer amount.

function totalFee(address tokenAddress, uint256 amount)
public
view
returns (uint256)

Compute the total fee that needs to be paid for a given transfer amount. The total fee is the sum of the liquidity provider fee and the protocol fee.

modifier validRequestId(bytes32 requestId)

Check whether a given request ID is valid.

modifier validClaimId(uint96 claimId)

Check whether a given claim ID is valid.

constructor(uint96 _claimStake, uint256 _claimRequestExtension, uint256 _claimPeriod, uint256 _challengePeriodExtension)

Constructor.

Parameters:
  • _claimStake – Claim stake amount.

  • _claimRequestExtension – Extension to claim a request after validity period ends.

  • _claimPeriod – Claim period, in seconds.

  • _challengePeriodExtension – Challenge period extension, in seconds.

function createRequest(uint256 targetChainId, address sourceTokenAddress, address targetTokenAddress, address targetAddress, uint256 amount, uint256 validityPeriod)
external
whenNotPaused
returns (bytes32)

Create a new transfer request.

Parameters:
  • targetChainId – ID of the target chain.

  • sourceTokenAddress – Address of the token contract on the source chain.

  • targetTokenAddress – Address of the token contract on the target chain.

  • targetAddress – Recipient address on the target chain.

  • amount – Amount of tokens to transfer. Does not include fees.

  • validityPeriod – The number of seconds the request is to be considered valid. Once its validity period has elapsed, the request cannot be claimed anymore and will eventually expire, allowing the request submitter to withdraw the deposited tokens if there are no active claims.

Return:

ID of the newly created request.

function withdrawExpiredRequest(bytes32 requestId)
external
validRequestId(requestId)

Withdraw funds deposited with an expired request.

No claims must be active for the request.

Parameters:
  • requestId – ID of the expired request.

function claimRequest(bytes32 requestId, bytes32 fillId)
external
payable
validRequestId(requestId)
onlyAllowed(msg . sender)
returns (uint96)

Claim that a request was filled by the caller.

The request must still be valid at call time. The caller must provide the claimStake amount of source rollup’s native token.

Parameters:
  • requestId – ID of the request.

  • fillId – The fill ID.

Return:

The claim ID.

function claimRequest(address claimer, bytes32 requestId, bytes32 fillId)
public
payable
validRequestId(requestId)
onlyAllowed(claimer)
returns (uint96)

Claim that a request was filled.

The request must still be valid at call time. The caller must provide the claimStake amount of source rollup’s native token. Only the claimer may get the stake back later.

Parameters:
  • claimer – Address of the claimer.

  • requestId – ID of the request.

  • fillId – The fill ID.

Return:

The claim ID.

function challengeClaim(uint96 claimId)
external
payable
validClaimId(claimId)

Challenge an existing claim.

The claim must still be valid at call time. This function implements one round of the challenge game. The original claimer is allowed to call this function only after someone else made a challenge, i.e. every second round. However, once the original claimer counter-challenges, anyone can join the game and make another challenge.

The caller must provide enough native tokens as their stake. For the original claimer, the minimum stake is challengerStakeTotal - claimerStake + claimStake.

For challengers, the minimum stake is claimerStake - challengerStakeTotal + 1.

An example (time flows downwards, claimStake = 10):

claimRequest() by Max [stakes 10]
challengeClaim() by Alice [stakes 11]
challengeClaim() by Max [stakes 11]
challengeClaim() by Bob [stakes 16]

In this example, if Max didn’t want to lose the challenge game to Alice and Bob, he would have to challenge with a stake of at least 16.

Parameters:
  • claimId – The claim ID.

function withdraw(uint96 claimId)
external
validClaimId(claimId)
returns (address)

Withdraw the deposit that the request submitter left with the contract, as well as the staked native tokens associated with the claim.

In case the caller of this function is a challenger that won the game, they will only get their staked native tokens plus the reward in the form of full (sole challenger) or partial (multiple challengers) amount of native tokens staked by the dishonest claimer.

Parameters:
  • claimId – The claim ID.

Return:

The claim stakes receiver.

function withdraw(address participant, uint96 claimId)
public
validClaimId(claimId)
returns (address)

Withdraw the deposit that the request submitter left with the contract, as well as the staked native tokens associated with the claim.

This function is called on behalf of a participant. Only a participant may receive the funds if he is the winner of the challenge or the claim is valid.

In case the caller of this function is a challenger that won the game, they will only get their staked native tokens plus the reward in the form of full (sole challenger) or partial (multiple challengers) amount of native tokens staked by the dishonest claimer.

Parameters:
  • claimId – The claim ID.

  • participant – The participant.

Return:

The claim stakes receiver.

function isWithdrawn(bytes32 requestId)
public
view
validRequestId(requestId)
returns (bool)

Returns whether a request’s deposit was withdrawn or not

This can be true in two cases: 1. The deposit was withdrawn after the request was claimed and filled. 2. The submitter withdrew the deposit after the request’s expiry. .. seealso:: withdraw .. seealso:: withdrawExpiredRequest

Parameters:
  • requestId – The request ID

Return:

Whether the deposit corresponding to the given request ID was withdrawn

function withdrawProtocolFees(address tokenAddress, address recipient)
external
onlyOwner

Withdraw protocol fees collected by the contract.

Protocol fees are paid in token transferred.

Note

This function can only be called by the contract owner.

Parameters:
  • tokenAddress – The address of the token contract.

  • recipient – The address the fees should be sent to.

function updateToken(address tokenAddress, uint256 transferLimit, uint96 minLpFee, uint32 lpFeePPM, uint32 protocolFeePPM)
external
onlyOwner
function setFinalityPeriod(uint256 targetChainId, uint256 finalityPeriod)
external
onlyOwner

Set the finality period for the given target chain.

Note

This function can only be called by the contract owner.

Parameters:
  • targetChainId – The target chain ID.

  • finalityPeriod – Finality period in seconds.

function isInvalidFill(bytes32 requestId, bytes32 fillId)
public
view
returns (bool)

Returns whether a fill is invalidated or not

Calling invalidateFill() will set this boolean to true, marking that the fillId for the corresponding requestId was invalidated. Calling resolveRequest will validate it again, setting request.invalidatedFills[fillId] to false. .. seealso:: invalidateFill .. seealso:: resolveRequest

Parameters:
  • requestId – The request ID

  • fillId – The fill ID

Return:

Whether the fill ID is invalid for the given request ID

function resolveRequest(bytes32 requestId, bytes32 fillId, uint256 resolutionChainId, address filler)
external
restricted(resolutionChainId)

Mark the request identified by requestId as filled by filler.

Note

This function is a restricted call function. Only callable by the added caller.

Parameters:
  • requestId – The request ID.

  • fillId – The fill ID.

  • resolutionChainId – The resolution (L1) chain ID.

  • filler – The address that filled the request.

function invalidateFill(bytes32 requestId, bytes32 fillId, uint256 resolutionChainId)
external
restricted(resolutionChainId)

Mark the fill identified by requestId and fillId as invalid.

Note

This function is a restricted call function. Only callable by the added caller.

Parameters:
  • requestId – The request ID.

  • fillId – The fill ID.

  • resolutionChainId – The resolution (L1) chain ID.

function pause()
external
onlyOwner

Pauses the contract.

Once the contract is paused, it cannot be used to create new requests anymore. Withdrawing deposited funds and claim stakes still works, though.

Note

This function can only be called when the contract is not paused.

Note

This function can only be called by the contract owner.

function unpause()
external
onlyOwner

Unpauses the contract.

Once the contract is unpaused, it can be used normally.

Note

This function can only be called when the contract is paused.

Note

This function can only be called by the contract owner.

contract Resolver is Ownable, RestrictedCalls

The resolver.

This contract resides on the L1 chain and is tasked with receiving the fill or non-fill proofs from the target L2 chain and forwarding them to the RequestManager on the source L2 chain.

event Resolution(uint256 sourceChainId, uint256 fillChainId, bytes32 requestId, address filler, bytes32 fillId)

Emitted when a fill or a non-fill proof is received and sent to the request manager.

Note

In case of a non-fill proof, the filler will be zero.

mapping (uint256 => SourceChainInfo) public sourceChainInfos

Maps source chain IDs to source chain infos.

function resolve(bytes32 requestId, bytes32 fillId, uint256 fillChainId, uint256 sourceChainId, address filler)
external
restricted(fillChainId)

Resolve the specified request.

This marks the request identified by requestId as filled by filler. If the filler is zero, the fill will be marked invalid.

Information about the fill will be sent to the source chain’s RequestManager, using the messenger responsible for the source chain.

Note

This function is callable only by the native L1 messenger contract, which simply delivers the message sent from the target chain by the Beamer’s L2 messenger contract.

Parameters:
  • requestId – The request ID.

  • fillId – The fill ID.

  • fillChainId – The fill (target) chain ID.

  • sourceChainId – The source chain ID.

  • filler – The address that filled the request, or zero to invalidate the fill.

function addRequestManager(uint256 chainId, address requestManager, address messenger)
external
onlyOwner

Add a request manager.

In order to be able to send messages to the RequestManager, the resolver contract needs to know the address of the request manager on the source chain, as well as the address of the messenger contract responsible for transferring messages to the L2 chain.

Note

This function can only be called by the contract owner.

Parameters:
  • chainId – The source L2 chain ID.

  • requestManager – The request manager.

  • messenger – The messenger contract responsible for chain chainId. Must implement IMessenger.

Helper contracts

contract RestrictedCalls is Ownable

A helper contract that provides a way to restrict callers of restricted functions to a single address. This allows for a trusted call chain, as described in contracts’ architecture.

mapping (uint256 => address[2]) public callers

Maps caller chain IDs to tuples [caller, messenger].

For same-chain calls, the messenger address is 0x0.

function addCaller(address caller)
external
onlyOwner

Allow calls from an address on the same chain.

Parameters:
  • caller – The caller.

function addCaller(uint256 callerChainId, address caller, address messenger)
external
onlyOwner

Allow calls from an address on another chain.

Parameters:
  • callerChainId – The caller’s chain ID.

  • caller – The caller.

  • messenger – The messenger.

modifier restricted(uint256 callerChainId)

Mark the function as restricted.

Calls to the restricted function can only come from an address that was previously added by a call to addCaller.

Example usage:

restricted(block.chainid)   // expecting calls from the same chain
restricted(otherChainId)    // expecting calls from another chain

Interfaces

interface IMessenger

The messenger interface.

Implementations of this interface are expected to transport messages across the L1 <-> L2 boundary. For instance, if an implementation is deployed on L1, the sendMessage would send a message to a L2 chain, as determined by the implementation. In order to do this, a messenger implementation may use a native messenger contract. In such cases, nativeMessenger must return the address of the native messenger contract.

function sendMessage(address target, bytes calldata message)
external

Send a message across the L1 <-> L2 boundary.

Parameters:
  • target – The message recipient.

  • message – The message.

function callAllowed(address caller, address courier)
external
view
returns (bool)

Return whether the call is allowed or not.

Parameters:
  • caller – The caller.

  • courier – The contract that is trying to deliver the message.