BridgePool
BridgePool
#
Contract deployed on L1 that provides methods for "Relayers" to fulfill deposit orders that originated on L2. The Relayers can either post capital to fulfill the deposit (instant relay), or request that the funds are taken out of a passive liquidity provider pool following a challenge period (slow relay). This contract ingests liquidity from passive liquidity providers and returns them claims to withdraw their funds. Liquidity providers are incentivized to post collateral by earning a fee per fulfilled deposit order.
A "Deposit" is an order to send capital from L2 to L1, and a "Relay" is a fulfillment attempt of that order.
#
Functionsconstructor(string _lpTokenName, string _lpTokenSymbol, address _bridgeAdmin, address _l1Token, uint64 _lpFeeRatePerSecond, bool _isWethPool, address _timer) (public)
Construct the Bridge Pool.
#
Parameters:- _lpTokenName: Name of the LP token to be deployed by this contract.
- _lpTokenSymbol: Symbol of the LP token to be deployed by this contract.
- _bridgeAdmin: Admin contract deployed alongside on L1. Stores global variables and has owner control.
- _l1Token: Address of the L1 token that this bridgePool holds. This is the token LPs deposit and is bridged.
- _lpFeeRatePerSecond: Interest rate payment that scales the amount of pending fees per second paid to LPs.
- _isWethPool: Toggles if this is the WETH pool. If it is then can accept ETH and wrap to WETH for the user.
- _timer: Timer used to synchronize contract time in testing. Set to 0x000... in production.
addLiquidity(uint256 l1TokenAmount) (public)
Add liquidity to the bridge pool. Pulls l1Token from the caller's wallet. The caller is sent back a commensurate number of LP tokens (minted to their address) at the prevailing exchange rate.
The caller must approve this contract to transfer l1TokenAmount
amount of l1Token if depositing ERC20.
The caller can deposit ETH which is auto wrapped to WETH. This can only be done if: a) this is the Weth pool
and b) the l1TokenAmount matches to the transaction msg.value.
Reentrancy guard not added to this function because this indirectly calls sync() which is guarded.
#
Parameters:- l1TokenAmount: Number of l1Token to add as liquidity.
removeLiquidity(uint256 lpTokenAmount, bool sendEth) (public)
Removes liquidity from the bridge pool. Burns lpTokenAmount LP tokens from the caller's wallet. The caller is sent back a commensurate number of l1Tokens at the prevailing exchange rate.
The caller does not need to approve the spending of LP tokens as this method directly uses the burn logic. Reentrancy guard not added to this function because this indirectly calls sync() which is guarded.
#
Parameters:- lpTokenAmount: Number of lpTokens to redeem for underlying.
- sendEth: Enable the liquidity provider to remove liquidity in ETH, if this is the WETH pool.
relayAndSpeedUp(struct BridgePool.DepositData depositData, uint64 realizedLpFeePct) (public)
Called by Relayer to execute a slow + fast relay from L2 to L1, fulfilling a corresponding deposit order.
There can only be one pending relay for a deposit. This method is effectively the relayDeposit and
speedUpRelay methods concatenated. This could be refactored to just call each method, but there
are some gas savings in combining the transfers and hash computations.
Caller must have approved this contract to spend the total bond + amount - fees for l1Token
.
This function can only be called if relays are enabled for this bridge pool.
#
Parameters:- depositData: the deposit data struct containing all the user's deposit information.
- realizedLpFeePct: LP fee calculated off-chain considering the L1 pool liquidity at deposit time, before quoteTimestamp. The OO acts to verify the correctness of this realized fee. Cannot exceed 50%.
disputeRelay(struct BridgePool.DepositData depositData, struct BridgePool.RelayData relayData) (public)
Called by Disputer to dispute an ongoing relay.
The result of this method is to always throw out the relay, providing an opportunity for another relay for
the same deposit. Between the disputer and proposer, whoever is incorrect loses their bond. Whoever is correct
gets it back + a payout.
Caller must have approved this contract to spend the total bond + amount - fees for l1Token
.
#
Parameters:- depositData: the deposit data struct containing all the user's deposit information.
- relayData: RelayData logged in the disputed relay.
relayDeposit(struct BridgePool.DepositData depositData, uint64 realizedLpFeePct) (public)
Called by Relayer to execute a slow relay from L2 to L1, fulfilling a corresponding deposit order.
There can only be one pending relay for a deposit.
Caller must have approved this contract to spend the total bond + amount - fees for l1Token
.
This function can only be called if relays are enabled for this bridge pool.
#
Parameters:- depositData: the deposit data struct containing all the user's deposit information.
- realizedLpFeePct: LP fee calculated off-chain considering the L1 pool liquidity at deposit time, before quoteTimestamp. The OO acts to verify the correctness of this realized fee. Cannot exceed 50%.
speedUpRelay(struct BridgePool.DepositData depositData, struct BridgePool.RelayData relayData) (public)
Instantly relay a deposit amount minus fees to the l1Recipient. Instant relayer earns a reward following the pending relay challenge period.
We assume that the caller has performed an off-chain check that the deposit data they are attempting to relay is valid. If the deposit data is invalid, then the instant relayer has no recourse to receive their funds back after the invalid deposit data is disputed. Moreover, no one will be able to resubmit a relay for the invalid deposit data because they know it will get disputed again. On the other hand, if the deposit data is valid, then even if it is falsely disputed, the instant relayer will eventually get reimbursed because someone else will be incentivized to resubmit the relay to earn slow relayer rewards. Once the valid relay is finalized, the instant relayer will be reimbursed. Therefore, the caller has the same responsibility as the disputer in validating the relay data. Caller must have approved this contract to spend the deposit amount of L1 tokens to relay. There can only be one instant relayer per relay attempt. You cannot speed up a relay that is past liveness.
#
Parameters:- depositData: Unique set of L2 deposit data that caller is trying to instantly relay.
- relayData: Parameters of Relay that caller is attempting to speedup. Must hash to the stored relay hash for this deposit or this method will revert.
settleRelay(struct BridgePool.DepositData depositData, struct BridgePool.RelayData relayData) (public)
Reward relayers if a pending relay price request has a price available on the OptimisticOracle. Mark the relay as complete.
We use the relayData and depositData to compute the ancillary data that the relay price request is uniquely associated with on the OptimisticOracle. If the price request passed in does not match the pending relay price request, then this will revert.
#
Parameters:- depositData: Unique set of L2 deposit data that caller is trying to settle a relay for.
- relayData: Parameters of Relay that caller is attempting to settle. Must hash to the stored relay hash for this deposit.
sync() (public)
Synchronize any balance changes in this contract with the utilized & liquid reserves. This would be done at the conclusion of an L2 -> L1 token transfer via the canonical token bridge.
exchangeRateCurrent() โ uint256 (public)
Computes the exchange rate between LP tokens and L1Tokens. Used when adding/removing liquidity.
liquidityUtilizationCurrent() โ uint256 (public)
Computes the current liquidity utilization ratio.
Used in computing realizedLpFeePct off-chain.
liquidityUtilizationPostRelay(uint256 relayedAmount) โ uint256 (public)
Computes the liquidity utilization ratio post a relay of known size.
Used in computing realizedLpFeePct off-chain.
#
Parameters:- relayedAmount: Size of the relayed deposit to factor into the utilization calculation.
getLiquidityUtilization(uint256 relayedAmount) โ uint256 utilizationCurrent, uint256 utilizationPostRelay (public)
Return both the current utilization value and liquidity utilization post the relay.
Used in computing realizedLpFeePct off-chain.
#
Parameters:- relayedAmount: Size of the relayed deposit to factor into the utilization calculation.
syncUmaEcosystemParams() (public)
Updates the address stored in this contract for the OptimisticOracle and the Store to the latest versions set in the the Finder. Also pull finalFee Store these as local variables to make relay methods gas efficient.
There is no risk of leaving this function public for anyone to call as in all cases we want the addresses in this contract to map to the latest version in the Finder and store the latest final fee.
syncWithBridgeAdminParams() (public)
Updates the values of stored constants for the proposerBondPct, optimisticOracleLiveness and identifier to that set in the bridge Admin. We store these as local variables to make the relay methods more gas efficient.
There is no risk of leaving this function public for anyone to call as in all cases we want these values in this contract to map to the latest version set in the BridgeAdmin.
changeAdmin(address _newAdmin) (public)
Enable the current bridge admin to transfer admin to to a new address.
Caller must be BridgeAdmin contract.
#
Parameters:- _newAdmin: Admin address of the new admin.
setLpFeeRatePerSecond(uint64 _newLpFeeRatePerSecond) (public)
Enable the bridge admin to change the decay rate at which LP shares accumulate fees. The higher this value, the faster LP shares realize pending fees.
Caller must be BridgeAdmin contract.
#
Parameters:- _newLpFeeRatePerSecond: The new rate to set.
setRelaysEnabled(bool _relaysEnabled) (public)
Enable the bridge admin to enable/disable relays for this pool. Acts as a pause. Only effects relayDeposit and relayAndSpeedUp methods. ALl other contract logic remains functional after a pause.
Caller must be BridgeAdmin contract.
#
Parameters:- _relaysEnabled: The new relaysEnabled state.
getAccumulatedFees() โ uint256 (public)
Computes the current amount of unallocated fees that have accumulated from the previous time this the contract was called.
getRelayAncillaryData(struct BridgePool.DepositData depositData, struct BridgePool.RelayData relayData) โ bytes (public)
Returns ancillary data containing all relevant Relay data that voters can format into UTF8 and use to determine if the relay is valid.
Helpful method to test that ancillary data is constructed properly. We should consider removing if we don't anticipate off-chain bots or users to call this method.
#
Parameters:- depositData: Contains L2 deposit information used by off-chain validators to validate relay.
- relayData: Contains relay information used by off-chain validators to validate relay.
_liquidityUtilizationPostRelay(uint256 relayedAmount) โ uint256 (internal)
_sync() (internal)
_exchangeRateCurrent() โ uint256 (internal)
_getAccumulatedFees() โ uint256 (internal)
_updateAccumulatedLpFees() (internal)
_allocateLpFees(uint256 allocatedLpFees) (internal)
_unwrapWETHTo(address payable to, uint256 amount) (internal)
receive() (external)
_preEntranceCheck() (internal)
_preEntranceSet() (internal)
_postEntranceReset() (internal)
name() โ string (public)
Returns the name of the token.
symbol() โ string (public)
Returns the symbol of the token, usually a shorter version of the name.
decimals() โ uint8 (public)
Returns the number of decimals used to get its user representation.
For example, if decimals
equals 2
, a balance of 505
tokens should
be displayed to a user as 5.05
(505 / 10 ** 2
).
Tokens usually opt for a value of 18, imitating the relationship between
Ether and Wei. This is the value {ERC20} uses, unless this function is
overridden;
NOTE: This information is only used for display purposes: it in
no way affects any of the arithmetic of the contract, including
{IERC20-balanceOf} and {IERC20-transfer}.
totalSupply() โ uint256 (public)
See {IERC20-totalSupply}.
balanceOf(address account) โ uint256 (public)
See {IERC20-balanceOf}.
transfer(address recipient, uint256 amount) โ bool (public)
See {IERC20-transfer}. Requirements:
recipient
cannot be the zero address.- the caller must have a balance of at least
amount
.
allowance(address owner, address spender) โ uint256 (public)
See {IERC20-allowance}.
approve(address spender, uint256 amount) โ bool (public)
See {IERC20-approve}. Requirements:
spender
cannot be the zero address.
transferFrom(address sender, address recipient, uint256 amount) โ bool (public)
See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements:
sender
andrecipient
cannot be the zero address.sender
must have a balance of at leastamount
.- the caller must have allowance for
sender
's tokens of at leastamount
.
increaseAllowance(address spender, uint256 addedValue) โ bool (public)
Atomically increases the allowance granted to spender
by the caller.
This is an alternative to {approve} that can be used as a mitigation for
problems described in {IERC20-approve}.
Emits an {Approval} event indicating the updated allowance.
Requirements:
spender
cannot be the zero address.
decreaseAllowance(address spender, uint256 subtractedValue) โ bool (public)
Atomically decreases the allowance granted to spender
by the caller.
This is an alternative to {approve} that can be used as a mitigation for
problems described in {IERC20-approve}.
Emits an {Approval} event indicating the updated allowance.
Requirements:
spender
cannot be the zero address.spender
must have allowance for the caller of at leastsubtractedValue
.
_transfer(address sender, address recipient, uint256 amount) (internal)
Moves amount
of tokens from sender
to recipient
.
This internal function is equivalent to {transfer}, and can be used to
e.g. implement automatic token fees, slashing mechanisms, etc.
Emits a {Transfer} event.
Requirements:
sender
cannot be the zero address.recipient
cannot be the zero address.sender
must have a balance of at leastamount
.
_mint(address account, uint256 amount) (internal)
Creates amount
tokens and assigns them to account
, increasing
the total supply.
Emits a {Transfer} event with from
set to the zero address.
Requirements:
account
cannot be the zero address.
_burn(address account, uint256 amount) (internal)
Destroys amount
tokens from account
, reducing the
total supply.
Emits a {Transfer} event with to
set to the zero address.
Requirements:
account
cannot be the zero address.account
must have at leastamount
tokens.
_approve(address owner, address spender, uint256 amount) (internal)
Sets amount
as the allowance of spender
over the owner
s tokens.
This internal function is equivalent to approve
, and can be used to
e.g. set automatic allowances for certain subsystems, etc.
Emits an {Approval} event.
Requirements:
owner
cannot be the zero address.spender
cannot be the zero address.
_beforeTokenTransfer(address from, address to, uint256 amount) (internal)
Hook that is called before any transfer of tokens. This includes minting and burning. Calling conditions:
- when
from
andto
are both non-zero,amount
offrom
's tokens will be transferred toto
. - when
from
is zero,amount
tokens will be minted forto
. - when
to
is zero,amount
offrom
's tokens will be burned. from
andto
are never both zero. To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
_afterTokenTransfer(address from, address to, uint256 amount) (internal)
Hook that is called after any transfer of tokens. This includes minting and burning. Calling conditions:
- when
from
andto
are both non-zero,amount
offrom
's tokens has been transferred toto
. - when
from
is zero,amount
tokens have been minted forto
. - when
to
is zero,amount
offrom
's tokens have been burned. from
andto
are never both zero. To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
_msgSender() โ address (internal)
_msgData() โ bytes (internal)
l1Token() โ contract IERC20 (external)
setCurrentTime(uint256 time) (external)
Sets the current time.
Will revert if not running in test mode.
#
Parameters:- time: timestamp to set current Testable time to.
getCurrentTime() โ uint256 (public)
Gets the current time. Will return the last time set in setCurrentTime
if running in test mode.
Otherwise, it will return the block timestamp.
multicall(bytes[] data) โ bytes[] results (external)
#
EventsLiquidityAdded(uint256 amount, uint256 lpTokensMinted, address liquidityProvider)
LiquidityRemoved(uint256 amount, uint256 lpTokensBurnt, address liquidityProvider)
DepositRelayed(bytes32 depositHash, struct BridgePool.DepositData depositData, struct BridgePool.RelayData relay, bytes32 relayAncillaryDataHash)
RelaySpedUp(bytes32 depositHash, address instantRelayer, struct BridgePool.RelayData relay)
RelayDisputed(bytes32 depositHash, bytes32 relayHash, address disputer)
RelayCanceled(bytes32 depositHash, bytes32 relayHash, address disputer)
RelaySettled(bytes32 depositHash, address caller, struct BridgePool.RelayData relay)
BridgePoolAdminTransferred(address oldAdmin, address newAdmin)
RelaysEnabledSet(bool newRelaysEnabled)
LpFeeRateSet(uint64 newLpFeeRatePerSecond)
Transfer(address from, address to, uint256 value)
Emitted when value
tokens are moved from one account (from
) to
another (to
).
Note that value
may be zero.
Approval(address owner, address spender, uint256 value)
Emitted when the allowance of a spender
for an owner
is set by
a call to {approve}. value
is the new allowance.
#
ModifiersonlyBridgeAdmin()
onlyIfRelaysEnabld()
nonReentrant()
Prevents a contract from calling itself, directly or indirectly.
Calling a nonReentrant
function from another nonReentrant
function is not supported. It is possible to
prevent this from happening by making the nonReentrant
function external, and making it call a private
function that does the actual state modification.
nonReentrantView()
Designed to prevent a view-only method from being re-entered during a call to a nonReentrant()
state-changing method.
onlyIfTest()
Reverts if not running in test mode.