ChildChainGaugeFactory
The ChildGaugeFactory is used to claim CRV emissions from. The RootChainGaugeFactory on Ethereum and ChildGaugeFactory on the according chain share the same contract address.
Contract Source & Deployment
All contract deployments can be found here.
 Source code available on Github. 
Contract Info Methods¶
is_valid_gauge¶
 ChildGaugeFactory.is_valid_gauge(_gauge: address) -> bool:
Getter method to check if _gauge is a valid gauge. A gauge is valid if 
Returns: true or flase (bool).
| Input | Type | Description | 
|---|---|---|
_gauge |  address |  gauge address | 
Source code
is_mirrored¶
 ChildGaugeFactory.is_mirrored(_gauge: address) -> bool:
Getter method to check if the gauge is mirrored on Ethereum. If true, a RootGauge with the same contract address as the ChildGauge exists on Ethereum.
Returns: true or false (bool).
| Input | Type | Description | 
|---|---|---|
_gauge |  address |  gauge address | 
Source code
set_mirrored¶
 ChildGaugeFactory.set_mirrored(_gauge: address, _mirrored: bool):
Guarded Method
This function is only callable by the admin of the contract. 
Function to set the mirrored bit of the gauge data for _gauge
Emits: UpdateMirrored
| Input | Type | Description | 
|---|---|---|
_gauge |  address |  gauge address | 
_mirrored |  bool |  bool determin whether to set the mirrored but to True/False | 
Source code
event UpdateMirrored:
    _gauge: indexed(address)
    _mirrored: bool
# [last_request][has_counterpart][is_valid_gauge]
gauge_data: public(HashMap[address, uint256])
@external
def set_mirrored(_gauge: address, _mirrored: bool):
    """
    @notice Set the mirrored bit of the gauge data for `_gauge`
    @param _gauge The gauge of interest
    @param _mirrored Boolean deteremining whether to set the mirrored bit to True/False
    """
    gauge_data: uint256 = self.gauge_data[_gauge]
    assert gauge_data != 0  # dev: invalid gauge
    assert msg.sender == self.owner  # dev: only owner
    gauge_data = shift(shift(gauge_data, -2), 2) + 1  # set is_valid_gauge = True
    if _mirrored:
        gauge_data += 2  # set is_mirrored = True
    self.gauge_data[_gauge] = gauge_data
    log UpdateMirrored(_gauge, _mirrored)
last_request¶
 ChildGaugeFactory.last_request(_gauge: address) -> bool:
Getter for the last timestamp of the last cross chain request for emissions.
Returns: timestamp (uint256).
| Input | Type | Description | 
|---|---|---|
_gauge |  address |  gauge address | 
Source code
gauge_data¶
 ChildGaugeFactory.gauge_data() -> address: view
todo
Returns: todo
| Input | Type | Description | 
|---|---|---|
_gauge |  address |  gauge address | 
get_gauge_from_lp_token¶
 ChildGaugeFactory.minted(arg0: address) -> address: view
Getter for the gauge of LP token arg0.
Returns: gauge (address).
| Input | Type | Description | 
|---|---|---|
arg0 |  address |  lp token | 
Source code
get_gauge_from_lp_token: public(HashMap[address, address])
@external
def deploy_gauge(_lp_token: address, _salt: bytes32, _manager: address = msg.sender) -> address:
    """
    @notice Deploy a liquidity gauge
    @param _lp_token The token to deposit in the gauge
    @param _manager The address to set as manager of the gauge
    @param _salt A value to deterministically deploy a gauge
    """
    if self.get_gauge_from_lp_token[_lp_token] != ZERO_ADDRESS:
        # overwriting lp_token -> gauge mapping requires
        assert msg.sender == self.owner  # dev: only owner
    gauge_data: uint256 = 1  # set is_valid_gauge = True
    implementation: address = self.get_implementation
    gauge: address = create_forwarder_to(
        implementation, salt=keccak256(_abi_encode(chain.id, msg.sender, _salt))
    )
    if msg.sender == self.call_proxy:
        gauge_data += 2  # set mirrored = True
        log UpdateMirrored(gauge, True)
        # issue a call to the root chain to deploy a root gauge
        CallProxy(self.call_proxy).anyCall(
            self,
            _abi_encode(chain.id, _salt, method_id=method_id("deploy_gauge(uint256,bytes32)")),
            ZERO_ADDRESS,
            1
        )
    self.gauge_data[gauge] = gauge_data
    idx: uint256 = self.get_gauge_count
    self.get_gauge[idx] = gauge
    self.get_gauge_count = idx + 1
    self.get_gauge_from_lp_token[_lp_token] = gauge
    ChildGauge(gauge).initialize(_lp_token, _manager)
    log DeployedGauge(implementation, _lp_token, msg.sender, _salt, gauge)
    return gauge
get_gauge_count¶
 ChildGaugeFactory.get_gauge_count() -> uint256: view
Getter for the number of gauges deployed. Increments by one when deploying a new gauge.
Returns: total number of gauges deployed (uint256).
Source code
get_gauge_count: public(uint256)
@external
def deploy_gauge(_lp_token: address, _salt: bytes32, _manager: address = msg.sender) -> address:
    """
    @notice Deploy a liquidity gauge
    @param _lp_token The token to deposit in the gauge
    @param _manager The address to set as manager of the gauge
    @param _salt A value to deterministically deploy a gauge
    """
    if self.get_gauge_from_lp_token[_lp_token] != ZERO_ADDRESS:
        # overwriting lp_token -> gauge mapping requires
        assert msg.sender == self.owner  # dev: only owner
    gauge_data: uint256 = 1  # set is_valid_gauge = True
    implementation: address = self.get_implementation
    gauge: address = create_forwarder_to(
        implementation, salt=keccak256(_abi_encode(chain.id, msg.sender, _salt))
    )
    if msg.sender == self.call_proxy:
        gauge_data += 2  # set mirrored = True
        log UpdateMirrored(gauge, True)
        # issue a call to the root chain to deploy a root gauge
        CallProxy(self.call_proxy).anyCall(
            self,
            _abi_encode(chain.id, _salt, method_id=method_id("deploy_gauge(uint256,bytes32)")),
            ZERO_ADDRESS,
            1
        )
    self.gauge_data[gauge] = gauge_data
    idx: uint256 = self.get_gauge_count
    self.get_gauge[idx] = gauge
    self.get_gauge_count = idx + 1
    self.get_gauge_from_lp_token[_lp_token] = gauge
    ChildGauge(gauge).initialize(_lp_token, _manager)
    log DeployedGauge(implementation, _lp_token, msg.sender, _salt, gauge)
    return gauge
get_gauge¶
 ChildGaugeFactory.get_gauge(arg0: address) -> address: view
Getter for the gauge at index arg0.
Returns: gauge (address).
| Input | Type | Description | 
|---|---|---|
arg0 |  address |  user address | 
Mint Emissions¶
mint¶
 ChildGaugeFactory.mint(_gauge: address):
Function to mint CRV emission rewards for msg.sender and transfer it to them.
Emits: Minted
| Input | Type | Description | 
|---|---|---|
_gauge |  address |  gauge address to mint from | 
Source code
event Minted:
    _user: indexed(address)
    _gauge: indexed(address)
    _new_total: uint256
@external
@nonreentrant("lock")
def mint(_gauge: address):
    """
    @notice Mint everything which belongs to `msg.sender` and send to them
    @param _gauge `LiquidityGauge` address to get mintable amount from
    """
    self._psuedo_mint(_gauge, msg.sender)
@internal
def _psuedo_mint(_gauge: address, _user: address):
    gauge_data: uint256 = self.gauge_data[_gauge]
    assert gauge_data != 0  # dev: invalid gauge
    # if is_mirrored and last_request != this week
    if bitwise_and(gauge_data, 2) != 0 and shift(gauge_data, -2) / WEEK != block.timestamp / WEEK:
        CallProxy(self.call_proxy).anyCall(
            self,
            _abi_encode(_gauge, method_id=method_id("transmit_emissions(address)")),
            ZERO_ADDRESS,
            1,
        )
        # update last request time
        self.gauge_data[_gauge] = shift(block.timestamp, 2) + 3
    assert ChildGauge(_gauge).user_checkpoint(_user)
    total_mint: uint256 = ChildGauge(_gauge).integrate_fraction(_user)
    to_mint: uint256 = total_mint - self.minted[_user][_gauge]
    if to_mint != 0:
        # transfer tokens to user
        response: Bytes[32] = raw_call(
            CRV,
            _abi_encode(_user, to_mint, method_id=method_id("transfer(address,uint256)")),
            max_outsize=32,
        )
        if len(response) != 0:
            assert convert(response, bool)
        self.minted[_user][_gauge] = total_mint
        log Minted(_user, _gauge, total_mint)
mint_many¶
 ChildGaugeFactory.mint(_gauge: address[32]):
Function to mint CRV emission rewards from multiple gauges for msg.sender and transfer it to them. This function supports claim of up to 32 gauges in one transcations.
Emits: Minted
| Input | Type | Description | 
|---|---|---|
_gauge |  address[32] |  gauge addresses to mint from | 
Source code
event Minted:
    _user: indexed(address)
    _gauge: indexed(address)
    _new_total: uint256
@external
@nonreentrant("lock")
def mint_many(_gauges: address[32]):
    """
    @notice Mint everything which belongs to `msg.sender` across multiple gauges
    @param _gauges List of `LiquidityGauge` addresses
    """
    for i in range(32):
        if _gauges[i] == ZERO_ADDRESS:
            pass
        self._psuedo_mint(_gauges[i], msg.sender)
@internal
def _psuedo_mint(_gauge: address, _user: address):
    gauge_data: uint256 = self.gauge_data[_gauge]
    assert gauge_data != 0  # dev: invalid gauge
    # if is_mirrored and last_request != this week
    if bitwise_and(gauge_data, 2) != 0 and shift(gauge_data, -2) / WEEK != block.timestamp / WEEK:
        CallProxy(self.call_proxy).anyCall(
            self,
            _abi_encode(_gauge, method_id=method_id("transmit_emissions(address)")),
            ZERO_ADDRESS,
            1,
        )
        # update last request time
        self.gauge_data[_gauge] = shift(block.timestamp, 2) + 3
    assert ChildGauge(_gauge).user_checkpoint(_user)
    total_mint: uint256 = ChildGauge(_gauge).integrate_fraction(_user)
    to_mint: uint256 = total_mint - self.minted[_user][_gauge]
    if to_mint != 0:
        # transfer tokens to user
        response: Bytes[32] = raw_call(
            CRV,
            _abi_encode(_user, to_mint, method_id=method_id("transfer(address,uint256)")),
            max_outsize=32,
        )
        if len(response) != 0:
            assert convert(response, bool)
        self.minted[_user][_gauge] = total_mint
        log Minted(_user, _gauge, total_mint)
minted¶
 ChildGaugeFactory.minted(arg0: address, arg1: address) -> uint256: view
Getter for the total minted CRV of address arg0 from gauge arg1.
Returns: total minted CRV (uint256).
| Input | Type | Description | 
|---|---|---|
arg0 |  address |  user address | 
arg1 |  address |  gauge address | 
Source code
# user -> gauge -> value
minted: public(HashMap[address, HashMap[address, uint256]])
@external
@nonreentrant("lock")
def mint(_gauge: address):
    """
    @notice Mint everything which belongs to `msg.sender` and send to them
    @param _gauge `LiquidityGauge` address to get mintable amount from
    """
    self._psuedo_mint(_gauge, msg.sender)
@internal
def _psuedo_mint(_gauge: address, _user: address):
    gauge_data: uint256 = self.gauge_data[_gauge]
    assert gauge_data != 0  # dev: invalid gauge
    # if is_mirrored and last_request != this week
    if bitwise_and(gauge_data, 2) != 0 and shift(gauge_data, -2) / WEEK != block.timestamp / WEEK:
        CallProxy(self.call_proxy).anyCall(
            self,
            _abi_encode(_gauge, method_id=method_id("transmit_emissions(address)")),
            ZERO_ADDRESS,
            1,
        )
        # update last request time
        self.gauge_data[_gauge] = shift(block.timestamp, 2) + 3
    assert ChildGauge(_gauge).user_checkpoint(_user)
    total_mint: uint256 = ChildGauge(_gauge).integrate_fraction(_user)
    to_mint: uint256 = total_mint - self.minted[_user][_gauge]
    if to_mint != 0:
        # transfer tokens to user
        response: Bytes[32] = raw_call(
            CRV,
            _abi_encode(_user, to_mint, method_id=method_id("transfer(address,uint256)")),
            max_outsize=32,
        )
        if len(response) != 0:
            assert convert(response, bool)
        self.minted[_user][_gauge] = total_mint
        log Minted(_user, _gauge, total_mint)
Deploying Gauges¶
deploy_gauge¶
 ChildGaugeFactory.deploy_gauge(_lp_token: address, _salt: bytes32, _manager: address = msg.sender) -> address:
Function to deploy a ChildLiquidityGauge and initialize it.
Returns: gauge (address).
Emits: DeployedGauge and possibly UpdateMirrored
| Input | Type | Description | 
|---|---|---|
_lp_token |  address |  lp token to deploy the gauge for | 
_salt |  bytes32 |  salt | 
_manager |  address |  gauge manager address; defaults to msg.sender |  
Source code
event DeployedGauge:
    _implementation: indexed(address)
    _lp_token: indexed(address)
    _deployer: indexed(address)
    _salt: bytes32
    _gauge: address
event UpdateMirrored:
    _gauge: indexed(address)
    _mirrored: bool
@external
def deploy_gauge(_lp_token: address, _salt: bytes32, _manager: address = msg.sender) -> address:
    """
    @notice Deploy a liquidity gauge
    @param _lp_token The token to deposit in the gauge
    @param _manager The address to set as manager of the gauge
    @param _salt A value to deterministically deploy a gauge
    """
    if self.get_gauge_from_lp_token[_lp_token] != ZERO_ADDRESS:
        # overwriting lp_token -> gauge mapping requires
        assert msg.sender == self.owner  # dev: only owner
    gauge_data: uint256 = 1  # set is_valid_gauge = True
    implementation: address = self.get_implementation
    gauge: address = create_forwarder_to(
        implementation, salt=keccak256(_abi_encode(chain.id, msg.sender, _salt))
    )
    if msg.sender == self.call_proxy:
        gauge_data += 2  # set mirrored = True
        log UpdateMirrored(gauge, True)
        # issue a call to the root chain to deploy a root gauge
        CallProxy(self.call_proxy).anyCall(
            self,
            _abi_encode(chain.id, _salt, method_id=method_id("deploy_gauge(uint256,bytes32)")),
            ZERO_ADDRESS,
            1
        )
    self.gauge_data[gauge] = gauge_data
    idx: uint256 = self.get_gauge_count
    self.get_gauge[idx] = gauge
    self.get_gauge_count = idx + 1
    self.get_gauge_from_lp_token[_lp_token] = gauge
    ChildGauge(gauge).initialize(_lp_token, _manager)
    log DeployedGauge(implementation, _lp_token, msg.sender, _salt, gauge)
    return gauge
Voting-Escrow and Implementation¶
voting_escrow¶
 ChildGaugeFactory.voting_escrow() -> address: view
Getter for the Voting-Escrow contract on Arbitrum. This contract is needed to apply user boosts for gauges.
Returns: voting escrow (address).
set_voting_escrow¶
 ChildGaugeFactory.set_voting_escrow(_voting_escrow: address):
Guarded Method
This function is only callable by the owner of the contract. 
Function to set the voting escrow contract.
Emits: UpdateVotingEscrow
| Input | Type | Description | 
|---|---|---|
_voting_escrow |  address |  voting escorw oracle contract | 
Source code
event UpdateVotingEscrow:
    _old_voting_escrow: address
    _new_voting_escrow: address
voting_escrow: public(address)
@external
def set_voting_escrow(_voting_escrow: address):
    """
    @notice Update the voting escrow contract
    @param _voting_escrow Contract to use as the voting escrow oracle
    """
    assert msg.sender == self.owner  # dev: only owner
    log UpdateVotingEscrow(self.voting_escrow, _voting_escrow)
    self.voting_escrow = _voting_escrow
get_implementation¶
 ChildGaugeFactory.is_mirrored(_gauge: address) -> bool:
Getter for the ChildLiquidityGauge implementation from which the ChildGauges are created from.
Returns: implementation contract (address).
set_implementation¶
 ChildGaugeFactory.set_implementation(_implementation: address):
Guarded Method
This function is only callable by the owner of the contract. 
Function to set the gauge implementation contract.
Emits: UpdateImplementation
| Input | Type | Description | 
|---|---|---|
_implementation |  address |  implementation contract | 
Source code
event UpdateImplementation:
    _old_implementation: address
    _new_implementation: address
get_implementation: public(address)
@external
def set_implementation(_implementation: address):
    """
    @notice Set the implementation
    @param _implementation The address of the implementation to use
    """
    assert msg.sender == self.owner  # dev: only owner
    log UpdateImplementation(self.get_implementation, _implementation)
    self.get_implementation = _implementation
Admin Ownership¶
owner¶
 ChildGaugeFactory.owner() -> address: view
Getter for the owner of the ChildGaugeFactory contract.
Returns: owner (address).
future_owner¶
 ChildGaugeFactory.future_owner() -> address: view
Getter for the owner of the ChildGaugeFactory contract.
Returns: owner (address).
commit_transfer_ownership¶
 ChildGaugeFactory.commit_transfer_ownership(_future_owner: address):
Guarded Method
This function is only callable by the owner of the contract.
Function to commit the transfer of contract ownership to _future_owner.
| Input | Type | Description | 
|---|---|---|
_future_owner |  address |  future owner | 
Source code
owner: public(address)
future_owner: public(address)
@external
def commit_transfer_ownership(_future_owner: address):
    """
    @notice Transfer ownership to `_future_owner`
    @param _future_owner The account to commit as the future owner
    """
    assert msg.sender == self.owner  # dev: only owner
    self.future_owner = _future_owner
accept_transfer_ownership¶
 ChildGaugeFactory.accept_transfer_ownership():
Guarded Method
This function is only callable by the future_owner of the contract.
Function to accept the transfer of ownership.
Emits: TransferOwnership
Source code
event TransferOwnership:
    _old_owner: address
    _new_owner: address
owner: public(address)
future_owner: public(address)
@external
def accept_transfer_ownership():
    """
    @notice Accept the transfer of ownership
    @dev Only the committed future owner can call this function
    """
    assert msg.sender == self.future_owner  # dev: only future owner
    log TransferOwnership(self.owner, msg.sender)
    self.owner = msg.sender