minter
99 lines
# @version 0.2.4
# @version 0.2.15
"""
"""
@title Token Minter
@title DistributorProxy
@author Curve Finance
@author This version was modified starting from Curve Finance's DAO contracts
@license MIT
@license MIT
"""
"""
interface LiquidityGauge:
interface LiquidityGauge:
# Presumably, other gauges will provide the same interfaces
# Presumably, other gauges will provide the same interfaces
def integrate_fraction(addr: address) -> uint256: view
def integrate_fraction(addr: address) -> uint256: view
def user_checkpoint(addr: address) -> bool: nonpayable
def user_checkpoint(addr: address) -> bool: nonpayable
interface MERC20:
interface Distributor:
def mint(_to: address, _value: uint256) -> bool: nonpayable
def distribute(_to: address, _value: uint256) -> bool: nonpayable
interface GaugeController:
interface GaugeController:
def gauge_types(addr: address) -> int128: view
def gauge_types(addr: address) -> int128: view
event Minted:
event Distributed:
recipient: indexed(address)
recipient: indexed(address)
gauge: address
gauge: address
minted: uint256
distributed: uint256
token: public(address)
distributor: public(address)
controller: public(address)
controller: public(address)
# user -> gauge -> value
# user -> gauge -> value
minted: public(HashMap[address, HashMap[address, uint256]])
distributed: public(HashMap[address, HashMap[address, uint256]])
# minter -> user -> can mint?
# distributor -> user -> can distribute?
allowed_to_mint_for: public(HashMap[address, HashMap[address, bool]])
allowed_to_distribute_for: public(HashMap[address, HashMap[address, bool]])
@external
@external
def __init__(_token: address, _controller: address):
def __init__(_distributor: address, _controller: address):
self.token = _token
self.distributor = _distributor
self.controller = _controller
self.controller = _controller
@internal
@internal
def _mint_for(gauge_addr: address, _for: address):
def _distribute_for(gauge_addr: address, _for: address):
assert GaugeController(self.controller).gauge_types(gauge_addr) >= 0 # dev: gauge is not added
assert GaugeController(self.controller).gauge_types(gauge_addr) >= 0 # dev: gauge is not added
LiquidityGauge(gauge_addr).user_checkpoint(_for)
LiquidityGauge(gauge_addr).user_checkpoint(_for)
total_mint: uint256 = LiquidityGauge(gauge_addr).integrate_fraction(_for)
total_distribute: uint256 = LiquidityGauge(gauge_addr).integrate_fraction(_for)
to_mint: uint256 = total_mint - self.minted[_for][gauge_addr]
to_distribute: uint256 = total_distribute - self.distributed[_for][gauge_addr]
if to_mint != 0:
if to_distribute != 0:
MERC20(self.token).mint(_for, to_mint)
Distributor(self.distributor).distribute(_for, to_distribute)
self.minted[_for][gauge_addr] = total_mint
self.distributed[_for][gauge_addr] = total_distribute
log Minted(_for, gauge_addr, total_mint)
log Distributed(_for, gauge_addr, total_distribute)
@external
@external
@nonreentrant('lock')
@nonreentrant('lock')
def mint(gauge_addr: address):
def distribute(gauge_addr: address):
"""
"""
@notice Mint everything which belongs to `msg.sender` and send to them
@notice Distribute everything which belongs to `msg.sender`
@param gauge_addr `LiquidityGauge` address to get mintable amount from
@param gauge_addr `LiquidityGauge` address to get distributable amount from
"""
"""
self._mint_for(gauge_addr, msg.sender)
self._distribute_for(gauge_addr, msg.sender)
@external
@external
@nonreentrant('lock')
@nonreentrant('lock')
def mint_many(gauge_addrs: address[8]):
def distribute_many(gauge_addrs: address[8]):
"""
"""
@notice Mint everything which belongs to `msg.sender` across multiple gauges
@notice Distribute everything which belongs to `msg.sender` across multiple gauges
@param gauge_addrs List of `LiquidityGauge` addresses
@param gauge_addrs List of `LiquidityGauge` addresses
"""
"""
for i in range(8):
for i in range(8):
if gauge_addrs[i] == ZERO_ADDRESS:
if gauge_addrs[i] == ZERO_ADDRESS:
break
break
self._mint_for(gauge_addrs[i], msg.sender)
self._distribute_for(gauge_addrs[i], msg.sender)
@external
@external
@nonreentrant('lock')
@nonreentrant('lock')
def mint_for(gauge_addr: address, _for: address):
def distribute_for(gauge_addr: address, _for: address):
"""
"""
@notice Mint tokens for `_for`
@notice Distribute tokens for `_for`
@dev Only possible when `msg.sender` has been approved via `toggle_approve_mint`
@dev Only possible when `msg.sender` has been approved via `toggle_approve_distribute`
@param gauge_addr `LiquidityGauge` address to get mintable amount from
@param gauge_addr `LiquidityGauge` address to get distributable amount from
@param _for Address to mint to
@param _for Address to distribute to
"""
"""
if self.allowed_to_mint_for[msg.sender][_for]:
if self.allowed_to_distribute_for[msg.sender][_for]:
self._mint_for(gauge_addr, _for)
self._distribute_for(gauge_addr, _for)
@external
@external
def toggle_approve_mint(minting_user: address):
def toggle_approve_distribute(distributing_user: address):
"""
"""
@notice allow `minting_user` to mint for `msg.sender`
@notice allow `distributing_user` to distribute for `msg.sender`
@param minting_user Address to toggle permission for
@param distributing_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]
self.allowed_to_distribute_for[distributing_user][msg.sender] = not self.allowed_to_distribute_for[distributing_user][msg.sender]