// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol'; import '../interfaces/IPools.sol'; /// @dev Pools contract /// @author Alexandas contract Pools is IPools { /// @dev return ERC20 token address IERC20 public override token; /// @dev return `Rewarder` contract address IRewarder public override rewarder; /// @dev return precision for shares uint256 public override ACC_PRECISION; /// @dev return max coefficient uint256 public override MAXCOEF; /// @dev return total pools allocation points uint256 public override totalAllocPoint; /// @dev return reward generated for per second uint256 public override rewardPerSecond; mapping(Types.Grade => Types.PoolInfo) internal pools; function _addPool( Types.Grade grade, uint256 allocPoint ) internal { require(pools[grade].allocPoint == 0, 'Pools: pool exists'); totalAllocPoint = totalAllocPoint + allocPoint; pools[grade] = Types.PoolInfo({ allocPoint: allocPoint, lastRewardTime: block.timestamp, accPerShare: 0 }); emit AddPool(grade); } /// @dev update a specific pool /// @param grade pool grade /// @return pool pool info function updatePool(Types.Grade grade) public override returns (Types.PoolInfo memory pool) { require(poolExists(grade), 'Pools: nonexistent pool'); pool = pools[grade]; if (block.timestamp > pool.lastRewardTime) { uint256 lpSupply = token.balanceOf(address(this)); if (lpSupply > 0) { uint256 time = block.timestamp - pool.lastRewardTime; uint256 reward = time * rewardPerSecond * pool.allocPoint / totalAllocPoint; pool.accPerShare = pool.accPerShare + (reward * ACC_PRECISION / lpSupply); } pool.lastRewardTime = block.timestamp; pools[grade] = pool; } emit PoolUpdated(grade); } /// @dev return a specific pool /// @param grade pool grade /// @return pool pool info function poolInfo(Types.Grade grade) public view override returns (Types.PoolInfo memory) { return pools[grade]; } function poolExists(Types.Grade grade) public view returns (bool) { return pools[grade].allocPoint != 0; } function _setRewardPerSecond(uint256 _rewardPerSecond) internal { rewardPerSecond = _rewardPerSecond; emit RewardPerSecondUpdated(_rewardPerSecond); } function _setToken(IERC20 _token) internal { token = _token; emit TokenUpdated(_token); } function _setRewarder(IRewarder _rewarder) internal { rewarder = _rewarder; emit RewarderUpdated(_rewarder); } function _setMaxCoef(uint256 _maxCoef) internal { MAXCOEF = _maxCoef; emit MaxCoefUpdated(_maxCoef); } function _setAccPrecision(uint256 _precision) internal { ACC_PRECISION = _precision; emit PrecisionUpdated(_precision); } }