Minter
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
.
The contract is deployed on Ethereum at 0xd061D61a4d941c39E5453435B6345Dc261C2fcE0.
Minting CRV¶
CRV tokens can be minted in several ways:
mint
: simple function which mints the elegible CRV tokens tomsg.sender
from a single gaugemint_many
: function to mint the elegible CRV formsg.sender
for multiple gauges at oncemint_for
: function to mint CRV for someone else and send it to them. Approval needs to be granted viatoggle_approve_mint
mint
¶
Minter.mint(gauge_addr: address)
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
interface LiquidityGauge:
# Presumably, other gauges will provide the same interfaces
def integrate_fraction(addr: address) -> uint256: view
def user_checkpoint(addr: address) -> bool: nonpayable
interface MERC20:
def mint(_to: address, _value: uint256) -> bool: nonpayable
event Minted:
recipient: indexed(address)
gauge: address
minted: uint256
# user -> gauge -> value
minted: public(HashMap[address, HashMap[address, uint256]])
@external
@nonreentrant('lock')
def mint(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)
@internal
def _mint_for(gauge_addr: address, _for: address):
assert GaugeController(self.controller).gauge_types(gauge_addr) >= 0 # dev: gauge is not added
LiquidityGauge(gauge_addr).user_checkpoint(_for)
total_mint: uint256 = LiquidityGauge(gauge_addr).integrate_fraction(_for)
to_mint: uint256 = total_mint - self.minted[_for][gauge_addr]
if to_mint != 0:
MERC20(self.token).mint(_for, to_mint)
self.minted[_for][gauge_addr] = total_mint
log Minted(_for, gauge_addr, total_mint)
mint_for
¶
Minter.mint_for(gauge_addr: address, _for: address)
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
interface LiquidityGauge:
# Presumably, other gauges will provide the same interfaces
def integrate_fraction(addr: address) -> uint256: view
def user_checkpoint(addr: address) -> bool: nonpayable
interface MERC20:
def mint(_to: address, _value: uint256) -> bool: nonpayable
event Minted:
recipient: indexed(address)
gauge: address
minted: uint256
# user -> gauge -> value
minted: public(HashMap[address, HashMap[address, uint256]])
# minter -> user -> can mint?
allowed_to_mint_for: public(HashMap[address, HashMap[address, bool]])
@external
@nonreentrant('lock')
def mint_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
"""
if self.allowed_to_mint_for[msg.sender][_for]:
self._mint_for(gauge_addr, _for)
@internal
def _mint_for(gauge_addr: address, _for: address):
assert GaugeController(self.controller).gauge_types(gauge_addr) >= 0 # dev: gauge is not added
LiquidityGauge(gauge_addr).user_checkpoint(_for)
total_mint: uint256 = LiquidityGauge(gauge_addr).integrate_fraction(_for)
to_mint: uint256 = total_mint - self.minted[_for][gauge_addr]
if to_mint != 0:
MERC20(self.token).mint(_for, to_mint)
self.minted[_for][gauge_addr] = total_mint
log Minted(_for, gauge_addr, total_mint)
mint_many
¶
Minter.mint_many(gauge_addrs: address[8])
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
interface LiquidityGauge:
# Presumably, other gauges will provide the same interfaces
def integrate_fraction(addr: address) -> uint256: view
def user_checkpoint(addr: address) -> bool: nonpayable
interface MERC20:
def mint(_to: address, _value: uint256) -> bool: nonpayable
event Minted:
recipient: indexed(address)
gauge: address
minted: uint256
# user -> gauge -> value
minted: public(HashMap[address, HashMap[address, uint256]])
# minter -> user -> can mint?
allowed_to_mint_for: public(HashMap[address, HashMap[address, bool]])
@external
@nonreentrant('lock')
def mint_many(gauge_addrs: address[8]):
"""
@notice Mint everything which belongs to `msg.sender` across multiple gauges
@param gauge_addrs List of `LiquidityGauge` addresses
"""
for i in range(8):
if gauge_addrs[i] == ZERO_ADDRESS:
break
self._mint_for(gauge_addrs[i], msg.sender)
@internal
def _mint_for(gauge_addr: address, _for: address):
assert GaugeController(self.controller).gauge_types(gauge_addr) >= 0 # dev: gauge is not added
LiquidityGauge(gauge_addr).user_checkpoint(_for)
total_mint: uint256 = LiquidityGauge(gauge_addr).integrate_fraction(_for)
to_mint: uint256 = total_mint - self.minted[_for][gauge_addr]
if to_mint != 0:
MERC20(self.token).mint(_for, to_mint)
self.minted[_for][gauge_addr] = total_mint
log Minted(_for, gauge_addr, total_mint)
minted
¶
Minter.minted(arg0: address, arg1: address) -> uint256: view
Getter for the total amount of CRV minted from a specific gauge to a specific user.
Returns: amount of CRV minted (uint256
).
Input | Type | Description |
---|---|---|
arg0 | address | User address |
arg1 | address | Gauge address |
This example returns the amount of CRV minted from a specific gauge to a specific user.
>>> Minter.minted(
Minter:
Gauge: )
allowed_to_mint_for
¶
Minter.allowed_to_mint_for(arg0: address, arg1: address) -> bool: view
Function to check if a specific user can mint for another user. Allowance is toggled using the toggle_approve_mint
function.
Returns: true or false (bool
).
Input | Type | Description |
---|---|---|
arg0 | address | Address of minter |
arg1 | address | Address of user |
Source code
This example checks if a specific user can mint for another user.
>>> Minter.allowed_to_mint_for(
Minter:
User: )
toggle_approve_mint
¶
Minter.toggle_approve_mint(minting_user: address)
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]])
@external
def toggle_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] = not self.allowed_to_mint_for[minting_user][msg.sender]
This example toggles approval for 0x989AEb4d175e16225E39E87d0D97A3360524AD80
to mint for 0xF147b8125d2ef93FB6965Db97D6746952a133934
.
>>> Minter.allowed_to_mint_for('0x989AEb4d175e16225E39E87d0D97A3360524AD80', '0xF147b8125d2ef93FB6965Db97D6746952a133934')
False
>>> Minter.toggle_approve_mint('0x989AEb4d175e16225E39E87d0D97A3360524AD80')
>>> Minter.allowed_to_mint_for('0x989AEb4d175e16225E39E87d0D97A3360524AD80', '0xF147b8125d2ef93FB6965Db97D6746952a133934')
True
Other Methods¶
token
¶
Minter.token() -> address: view
Getter for the token address of the Curve DAO Token (CRV). This variable is set at initialization and can not be changed after.
Returns: CRV token contract (address
).
Source code
This example returns the CRV
token address.
>>> Minter.token()
controller
¶
Minter.controller() -> address: view
Getter for the GaugeController
.
Returns: GaugeController
contract (address
).
Source code
This example returns the GaugeController
address.
>>> Minter.controller()