Individual RootChainGauges are deployed from a implementation via the RootChainGaugeFactory. The RootGauge on Ethereum and the ChildGauge on sidechains should share the same contract address. If not, its not a valid gauge.
Allocated CRV emissions are bridged from this contract to the ChildGauge on the corresponding sidechain. Transmitting emissions is permissionless, although the transmit_emission() function needs to be called from the RootChainGaugeFactory, which acts as a proxy for all deployed RootGauges.
This function is technically callable by anyone, although it needs to be called from the RootChainGaugeFactory proxy.
Function to mint the allocated CRV for the gauge from the Minter and bridge them to the ChildGauge on the sidechain utilizing the bridger contract.
Source code
@externaldeftransmit_emissions():""" @notice Mint any new emissions and transmit across to child gauge """assertmsg.sender==self.factory# dev: call via factoryMinter(MINTER).mint(self)minted:uint256=ERC20(CRV).balanceOf(self)assertminted!=0# dev: nothing mintedbridger:address=self.bridgerBridger(bridger).bridge(CRV,self,minted,value=Bridger(bridger).cost())
Function to update the bridger contract. Sets approval for the previous bridger to 0 and gives maximum approval to the new bridger contract.
Note
The bridger contract is set within the RootChainGaugeFactory.
Source code
bridger:public(address)@externaldefupdate_bridger():""" @notice Update the bridger used by this contract @dev Bridger contracts should prevent briding if ever updated """# reset approvalbridger:address=Factory(self.factory).get_bridger(self.chain_id)ERC20(CRV).approve(self.bridger,0)ERC20(CRV).approve(bridger,MAX_UINT256)self.bridger=bridger
Function to checkpoint the gauge. Calculates and updates total_emissions. If last_period != current_period it will do a checkpoint, otherwise it will just return true without making a checkpoint.
Source code
WEEK:constant(uint256)=604800YEAR:constant(uint256)=86400*365RATE_DENOMINATOR:constant(uint256)=10**18RATE_REDUCTION_COEFFICIENT:constant(uint256)=1189207115002721024# 2 ** (1/4) * 1e18RATE_REDUCTION_TIME:constant(uint256)=YEAR@externaldefuser_checkpoint(_user:address)->bool:""" @notice Checkpoint the gauge updating total emissions @param _user Vestigal parameter with no impact on the function """# the last period we calculated emissions up to (but not including)last_period:uint256=self.last_period# our current period (which we will calculate emissions up to)current_period:uint256=block.timestamp/WEEK# only checkpoint if the current period is greater than the last period# last period is always less than or equal to current period and we only calculate# emissions up to current period (not including it)iflast_period!=current_period:# checkpoint the gauge filling in any missing weight dataGaugeController(GAUGE_CONTROLLER).checkpoint_gauge(self)params:InflationParams=self.inflation_paramsemissions:uint256=0# only calculate emissions for at most 256 periods since the last checkpointforiinrange(last_period,last_period+256):ifi==current_period:# don't calculate emissions for the current periodbreakperiod_time:uint256=i*WEEKweight:uint256=GaugeController(GAUGE_CONTROLLER).gauge_relative_weight(self,period_time)ifperiod_time<=params.finish_timeandparams.finish_time<period_time+WEEK:# calculate with old rateemissions+=weight*params.rate*(params.finish_time-period_time)/10**18# update rateparams.rate=params.rate*RATE_DENOMINATOR/RATE_REDUCTION_COEFFICIENT# calculate with new rateemissions+=weight*params.rate*(period_time+WEEK-params.finish_time)/10**18# update finish timeparams.finish_time+=RATE_REDUCTION_TIME# update storageself.inflation_params=paramselse:emissions+=weight*params.rate*WEEK/10**18self.last_period=current_periodself.total_emissions+=emissionsreturnTrue
Proxy method to initialize the contract. This function is called when a need sidechain/L2 gauge is deployed through the RootChainFactory. Also gives maximum approval to the bridger contract. This function is called when a new RootGauge is deployed via deploy_gauge() function on the Factory.
This function is only callable by the owner of the RootChainGaugeFactory.
Function to kill the gauge.
Input
Type
Description
_is_killed
bool
true or fales
Source code
inflation_params:public(InflationParams)@externaldefset_killed(_is_killed:bool):""" @notice Set the gauge kill status @dev Inflation params are modified accordingly to disable/enable emissions """assertmsg.sender==Factory(self.factory).owner()if_is_killed:self.inflation_params.rate=0else:self.inflation_params=InflationParams({rate:CRV20(CRV).rate(),finish_time:CRV20(CRV).future_epoch_time_write()})self.last_period=block.timestamp/WEEKself.is_killed=_is_killed
Getter for the total emissions the gauge _user is entitled to.
Returns: total CRV emissions (uint256).
Input
Type
Description
_user
address
L2 / Sidechain Gauge Address
Source code
@view@externaldefintegrate_fraction(_user:address)->uint256:""" @notice Query the total emissions `_user` is entitled to @dev Any value of `_user` other than the gauge address will return 0 """if_user==self:returnself.total_emissionsreturn0
factory is set to 0x000000000000000000000000000000000000dEaD so they contract does not initialize itself when deploying. The actual factory address is set when actually inizializing the contract via the initialize() function.
total_emissions:public(uint256)@externaldefuser_checkpoint(_user:address)->bool:""" @notice Checkpoint the gauge updating total emissions @param _user Vestigal parameter with no impact on the function """# the last period we calculated emissions up to (but not including)last_period:uint256=self.last_period# our current period (which we will calculate emissions up to)current_period:uint256=block.timestamp/WEEK# only checkpoint if the current period is greater than the last period# last period is always less than or equal to current period and we only calculate# emissions up to current period (not including it)iflast_period!=current_period:# checkpoint the gauge filling in any missing weight dataGaugeController(GAUGE_CONTROLLER).checkpoint_gauge(self)params:InflationParams=self.inflation_paramsemissions:uint256=0# only calculate emissions for at most 256 periods since the last checkpointforiinrange(last_period,last_period+256):ifi==current_period:# don't calculate emissions for the current periodbreakperiod_time:uint256=i*WEEKweight:uint256=GaugeController(GAUGE_CONTROLLER).gauge_relative_weight(self,period_time)ifperiod_time<=params.finish_timeandparams.finish_time<period_time+WEEK:# calculate with old rateemissions+=weight*params.rate*(params.finish_time-period_time)/10**18# update rateparams.rate=params.rate*RATE_DENOMINATOR/RATE_REDUCTION_COEFFICIENT# calculate with new rateemissions+=weight*params.rate*(period_time+WEEK-params.finish_time)/10**18# update finish timeparams.finish_time+=RATE_REDUCTION_TIME# update storageself.inflation_params=paramselse:emissions+=weight*params.rate*WEEK/10**18self.last_period=current_periodself.total_emissions+=emissionsreturnTrue