Overview
Background
As one of the digital financial derivatives on SUN.io, mining provides crypto holders with stable, secure, and reliable services for subscription and redemption of investment products. Governance mining is an important part of SUN.io's mining service. As shown in the graph below, the reward distributed to users is closely related to the number of veSun tokens they hold and the weights of the liquidity pools. And users are free to redeem their assets at any time.

Explanation
After a user stakes tokens in a liquidity pool, a corresponding amount of virtual stake value will be generated:
represents the real value staked by the user. is the total value staked in a liquidity pool. is the number of veSun tokens held by the user. is the total number of veSun tokens issued by SUN.io. As shown in formula (1), if the user holds enough veSun, then the virtue stake is indicated as ; if the user holds 0 veSun, then it is indicated as * 0.4, meaning that the reward for holding veSUN can be amplified by 2.5 times.
represents the weekly gauge weight of the pool. is the weight of the pool type. is the total weight of the pool for the week and is the expansion factor of the reward token. According to the reward distribution formula (2) of Smart Mining V1, the user's rewards are calculated in the following way:
Here, V represents the final expansion factor of the reward token. represents the i-th change. represents the total virtual stake at the time to . represents the user's virtual stake value at the time to .
Contract code
def _checkpoint(addr: address):
Controller(_controller).checkpoint_gauge(convert(self.controller_key, bytes32))
_working_balance: uint256 = self.working_balances[addr]
_working_supply: uint256 = self.working_supply
if block.timestamp > _period_time:
prev_week_time: uint256 = _period_time
week_time: uint256 = min((_period_time + WEEK) / WEEK * WEEK, block.timestamp)
for i in range(500):
dt: uint256 = week_time - prev_week_time
w: uint256 = Controller(_controller).gauge_relative_weight(convert(self.controller_key, bytes32), prev_week_time / WEEK * WEEK)
if _working_supply > 0:
if prev_future_epoch >= prev_week_time and prev_future_epoch < week_time:
_integrate_inv_supply += rate * w * (prev_future_epoch - prev_week_time) / _working_supply
rate = new_rate
_integrate_inv_supply += rate * w * (week_time - prev_future_epoch) / _working_supply
else:
_integrate_inv_supply += rate * w * dt / _working_supply
if week_time == block.timestamp:
break
prev_week_time = week_time
week_time = min(week_time + WEEK, block.timestamp)
_period += 1
self.period = _period
self.period_timestamp[_period] = block.timestamp
self.integrate_inv_supply[_period] = _integrate_inv_supply
self.integrate_fraction[addr] += _working_balance * (_integrate_inv_supply - self.integrate_inv_supply_of[addr]) / 10 ** 18
self.integrate_inv_supply_of[addr] = _integrate_inv_supply
self.integrate_checkpoint_of[addr] = block.timestamp
Last updated