AngleDistributor.sol
AngleDistributor
contract controls and handles the distribution of governance tokens to the different staking contracts (also called gauges) of the protocol. It is responsible for sending rewards to the gauges that have been added to the GaugeController
. The amount of rewards sent to a given gauge is determined based on the votes of veANGLE
holders for this gauge in the GaugeController
contract.AngleDistributor
contract will therefore be holding all the ANGLE tokens to distribute via liquidity mining.AngleDistributor
is able to distinguish the different types of gauges and treats each type accordingly. There is one way of routing ANGLE rewards per gauge type, check for more details the description of the distributeReward
functionAngleDistributorEvents
, AccessControlUpgradeable
, and ReentrancyGuardUpgradeable
. The contract is upgradeable and can be upgraded only by the governor.WEEK
: Length of a weekRATE_REDUCTION_TIME
: Time between two reductions of the emission rate: it is set to a weekRATE_REDUCTION_COEFFICIENT
: Decrease of the rate at each RATE_REDUCTION_TIME
. It is currently set to BASE
: Base used for computationcontroller
: Address of the GaugeController
contractrewardToken
: Address of the token given as a reward. This contract could technically work for any reward token. In the case of the Angle Protocol, it will obviously be the ANGLE tokendelegateGauge
: Address responsible for pulling rewards of type 2 gauges and distributing it to the associated contractsrate
: ANGLE current emission rate, it is first defined in the initializer and then updated every weekstartEpochTime
: Timestamp at which the current emission epoch startedstartEpochSupply
: Amount of ANGLE tokens distributed through staking at the start of the epoch. This is an informational variable used to track how much has been distributed through liquidity mining. It was kept as Curve and Frax had itminingEpoch
: Index of the current emission epoch. Here also, this variable is not useful per se inside the smart contracts of the protocol, it is just an informational variabledistributionsOn
: Whether ANGLE distribution through this contract is on or nolastTimeGaugePaid
: Maps the address of a gauge to the last time this gauge received rewardskilledGauges
: Maps the address of a gauge to whether it was killed or not. A gauge killed in this contract cannot receive any rewards.GUARDIAN_ROLE
: Used to activate or deactivate rapidly distribution with this contractGOVERNOR_ROLE
: Since this contract controls a large amount of governance tokens, there is a need for a governordistributeReward
is called, the mapping lastTimeGaugePaid
for this gauge is updated to the date of the last Thursday Midnight UTC preceding. So if you call this function on a Saturday, you'll have to wait till the following Thursday at midnight (1 minute after Wednesday 23h59) to distribute rewards again to this gauge._updateMiningParameters
function that changes the ANGLE emission rate every week.distributeReward
function that the different types of gauges are handled differently. Rewards are not sent to type 0 gauge as they are sent to type 1 gauges for instance. In summary:LiquidityV4Gauge
contracts. The AngleDistributor
sends rewards to these gauges by using the deposit_reward_token
interfacePerpetualManager
staking contracts. Here the notifyRewardAmount
interface of the gauge contract is useddelegateGauge
which receives ANGLE rewards for all of them and then distributes these rewards to the different gauges. This delegateGauge
address should be a multisig or a trusted contractpullAndBridge
interface could be used to automatically bridge the tokens. There is no such gauge at the moment.weeksElapsed
: Number of weeks elapsed since the last time rewards were distributed to this gauge. If the system is correctly maintained, this number of weeks should be no more than 1rewardTally
: Amount of tokens sent to the gaugedistributeReward
function, the start of each mining epoch is not rounded to the nearest Thursday Midningt UTC. This means that if the startEpochTime
is set on a Saturday, every Saturday, it'll be possible to call this function.tokenAddress
: Address of the ERC20 token to withdrawto
: Address to transfer toamount
: Amount to transferdistributeReward
has been called for all gauges in the past weeks. If not, gauges may get an incorrect distribution of ANGLE rewards for these past weeks based on the new rate and not on the old rate.distributeReward
calls for all existing gauges. As this function assumes that distributeReward
has been called during the week, it also assumes that the startEpochSupply
parameter has been put up to date.GaugeController
contract, killing of gauges takes place in the AngleDistributor
contract. This means that people could vote for a gauge in the gauge controller contract but that rewards are not going to be distributed to it in the end: people would need to remove their weights on the gauge killed to end the diminution in rewards.