The Minter is responsible for the issuance and distribution of CRV tokens to liquidity providers. It acts as a mechanism to reward users who provide liquidity to Curve's pools. The contract essentially calculates the amount of CRV tokens to be allocated based on various factors such as the duration and amount of liquidity provided.
Minter.vy
The source code for the Minter.vy contract is available on GitHub. The contract is written in Vyper version 0.2.4.
Function to mint CRV for the caller from a single gauge.
Emits: Minted event.
Input
Type
Description
gauge_addr
address
Gauge address to get mintable CRV amount from
Source code
interfaceLiquidityGauge:# Presumably, other gauges will provide the same interfacesdefintegrate_fraction(addr:address)->uint256:viewdefuser_checkpoint(addr:address)->bool:nonpayableinterfaceMERC20:defmint(_to:address,_value:uint256)->bool:nonpayableeventMinted:recipient:indexed(address)gauge:addressminted:uint256# user -> gauge -> valueminted:public(HashMap[address,HashMap[address,uint256]])@external@nonreentrant('lock')defmint(gauge_addr:address):""" @notice Mint everything which belongs to `msg.sender` and send to them @param gauge_addr `LiquidityGauge` address to get mintable amount from """self._mint_for(gauge_addr,msg.sender)@internaldef_mint_for(gauge_addr:address,_for:address):assertGaugeController(self.controller).gauge_types(gauge_addr)>=0# dev: gauge is not addedLiquidityGauge(gauge_addr).user_checkpoint(_for)total_mint:uint256=LiquidityGauge(gauge_addr).integrate_fraction(_for)to_mint:uint256=total_mint-self.minted[_for][gauge_addr]ifto_mint!=0:MERC20(self.token).mint(_for,to_mint)self.minted[_for][gauge_addr]=total_mintlogMinted(_for,gauge_addr,total_mint)
This example mints all CRV for the caller from 0xe5d5aa1bbe72f68df42432813485ca1fc998de32 (LDO/ETH gauge).
Function to mint CRV for a different address and transfer it to them. In order to do this, the caller must have been previously approved by for using toggle_approve_mint.
Emits: Minted event.
Input
Type
Description
gauge_addr
address
Gauge address to get mintable CRV amount from
_for
address
Address to mint to
Source code
interfaceLiquidityGauge:# Presumably, other gauges will provide the same interfacesdefintegrate_fraction(addr:address)->uint256:viewdefuser_checkpoint(addr:address)->bool:nonpayableinterfaceMERC20:defmint(_to:address,_value:uint256)->bool:nonpayableeventMinted:recipient:indexed(address)gauge:addressminted:uint256# user -> gauge -> valueminted:public(HashMap[address,HashMap[address,uint256]])# minter -> user -> can mint?allowed_to_mint_for:public(HashMap[address,HashMap[address,bool]])@external@nonreentrant('lock')defmint_for(gauge_addr:address,_for:address):""" @notice Mint tokens for `_for` @dev Only possible when `msg.sender` has been approved via `toggle_approve_mint` @param gauge_addr `LiquidityGauge` address to get mintable amount from @param _for Address to mint to """ifself.allowed_to_mint_for[msg.sender][_for]:self._mint_for(gauge_addr,_for)@internaldef_mint_for(gauge_addr:address,_for:address):assertGaugeController(self.controller).gauge_types(gauge_addr)>=0# dev: gauge is not addedLiquidityGauge(gauge_addr).user_checkpoint(_for)total_mint:uint256=LiquidityGauge(gauge_addr).integrate_fraction(_for)to_mint:uint256=total_mint-self.minted[_for][gauge_addr]ifto_mint!=0:MERC20(self.token).mint(_for,to_mint)self.minted[_for][gauge_addr]=total_mintlogMinted(_for,gauge_addr,total_mint)
This example mints all CRV for 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 from the gauge with the address 0xe5d5aa1bbe72f68df42432813485ca1fc998de32.
Function to mint CRV for the caller from multiple gauges. This function does not allow for minting for or to different addresses. It claims for msgs.ender and transfers the minted tokens to them. The maximum number of gauges that can be specified is eight. For example, if only minting from one gauge, leave the remaining array entries as ZERO_ADDRESS.
Emits: Minted event.
Input
Type
Description
gauge_addrs
address[8]
List of gauge addresses to mint from
Source code
interfaceLiquidityGauge:# Presumably, other gauges will provide the same interfacesdefintegrate_fraction(addr:address)->uint256:viewdefuser_checkpoint(addr:address)->bool:nonpayableinterfaceMERC20:defmint(_to:address,_value:uint256)->bool:nonpayableeventMinted:recipient:indexed(address)gauge:addressminted:uint256# user -> gauge -> valueminted:public(HashMap[address,HashMap[address,uint256]])# minter -> user -> can mint?allowed_to_mint_for:public(HashMap[address,HashMap[address,bool]])@external@nonreentrant('lock')defmint_many(gauge_addrs:address[8]):""" @notice Mint everything which belongs to `msg.sender` across multiple gauges @param gauge_addrs List of `LiquidityGauge` addresses """foriinrange(8):ifgauge_addrs[i]==ZERO_ADDRESS:breakself._mint_for(gauge_addrs[i],msg.sender)@internaldef_mint_for(gauge_addr:address,_for:address):assertGaugeController(self.controller).gauge_types(gauge_addr)>=0# dev: gauge is not addedLiquidityGauge(gauge_addr).user_checkpoint(_for)total_mint:uint256=LiquidityGauge(gauge_addr).integrate_fraction(_for)to_mint:uint256=total_mint-self.minted[_for][gauge_addr]ifto_mint!=0:MERC20(self.token).mint(_for,to_mint)self.minted[_for][gauge_addr]=total_mintlogMinted(_for,gauge_addr,total_mint)
This example mints all CRV for the caller from three gauges at once.
Function to toggle approval for a user to mint CRV on behalf of the caller.
Input
Type
Description
minting_user
address
Address to toggle permission for
Source code
# minter -> user -> can mint?allowed_to_mint_for:public(HashMap[address,HashMap[address,bool]])@externaldeftoggle_approve_mint(minting_user:address):""" @notice allow `minting_user` to mint for `msg.sender` @param minting_user Address to toggle permission for """self.allowed_to_mint_for[minting_user][msg.sender]=notself.allowed_to_mint_for[minting_user][msg.sender]
This example toggles approval for 0x989AEb4d175e16225E39E87d0D97A3360524AD80 to mint for 0xF147b8125d2ef93FB6965Db97D6746952a133934.