Bridger wrappers are contracts used to transmit ERC-20 tokens and especially CRV emissions across chains. Due to the increasing number of networks to which Curve deploys, bridge wrappers adhere to a specific interface documented below and allow for a modular bridging system.
Bridgers.vy
The source code for the various Bridger Wrappers contracts can be found on GitHub. The code varies slightly to adapt to different chain-specific implementations.
Bridgers for each specific chain can be fetched from the RootGaugeFactory:
>>> Bridger.get_bridger()
Chain-Specific Implementations
The following function examples are for the Arbitrum bridger. Due to the varying implementations across different chains, the source code might vary slightly between different bridger implementations.
The following three functions are required for bridge wrappers contracts to be implemented to ensure compatibility with the RootGaugeFactory and RootGauge contracts.
Function to bridge any ERC20 token to the child chain.
Parameter
Type
Description
_token
address
The address of the token to bridge
_to
address
The address to bridge the token to
_amount
uint256
The amount of _token to deposit
Source code
This source code might vary slightly between different bridger implementations. This example is specific to the Bridger contract for Arbitrum.
interfaceGatewayRouter:defgetGateway(_token:address)->address:viewdefoutboundTransfer(# emits DepositInitiated event with Inbox sequence #_token:address,_to:address,_amount:uint256,_max_gas:uint256,_gas_price_bid:uint256,_data:Bytes[128],# _max_submission_cost, _extra_data):payableCRV20:constant(address)=0xD533a949740bb3306d119CC777fa900bA034cd52GATEWAY:constant(address)=0xa3A7B6F88361F48403514059F1F16C8E78d60EeCGATEWAY_ROUTER:constant(address)=0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031efINBOX:constant(address)=0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f# [gas_limit uint64][gas_price uint64][max_submission_cost uint64]submission_data:uint256is_approved:public(HashMap[address,bool])@payable@externaldefbridge(_token:address,_to:address,_amount:uint256):""" @notice Bridge an ERC20 token using the Arbitrum standard bridge @param _token The address of the token to bridge @param _to The address to deposit token to on L2 @param _amount The amount of `_token` to deposit """assertERC20(_token).transferFrom(msg.sender,self,_amount)if_token!=CRV20andnotself.is_approved[_token]:assertERC20(_token).approve(GatewayRouter(GATEWAY_ROUTER).getGateway(_token),MAX_UINT256)self.is_approved[_token]=Truedata:uint256=self.submission_datagas_limit:uint256=shift(data,-128)gas_price:uint256=shift(data,-64)%2**64max_submission_cost:uint256=data%2**64# NOTE: Excess ETH fee is refunded to this bridger's address on L2.# After bridging, the token should arrive on Arbitrum within 10 minutes. If it# does not, the L2 transaction may have failed due to an insufficient amount# within `max_submission_cost + (gas_limit * gas_price)`# In this case, the transaction can be manually broadcasted on Arbitrum by calling# `ArbRetryableTicket(0x000000000000000000000000000000000000006e).redeem(redemption-TxID)`# The calldata for this manual transaction is easily obtained by finding the reverted# transaction in the tx history for 0x000000000000000000000000000000000000006e on Arbiscan.# https://developer.offchainlabs.com/docs/l1_l2_messages#retryable-transaction-lifecycleGatewayRouter(GATEWAY_ROUTER).outboundTransfer(_token,_to,_amount,gas_limit,gas_price,_abi_encode(max_submission_cost,b""),value=gas_limit*gas_price+max_submission_cost)
This example bridges 10,000 CRV to the address 0x1234567890123456789012345678901234567890 on Arbitrum.
Function to check if the bridger contract has been approved by the RootGauge.
Returns: True if the bridger has been approved by the RootGauge, False otherwise (bool).
Parameter
Type
Description
_account
address
The address of the bridger contract to check
Source code
This source code might vary slightly between different bridger implementations. This example is specific to the Bridger contract for Arbitrum.
@pure@externaldefcheck(_account:address)->bool:""" @notice Verify if `_account` is allowed to bridge using `transmit_emissions` @param _account The account calling `transmit_emissions` """returnTrue