mirror of https://github.com/logos-co/staking.git
execute epoch, user reward
This commit is contained in:
parent
b70666c26d
commit
4849cccb81
|
@ -9,3 +9,5 @@ typechain-types
|
|||
cache
|
||||
artifacts
|
||||
|
||||
gmx-contracts
|
||||
node_modules
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
function getMaxMultiplierPoints() public view returns(uint256) {
|
||||
return balance * (stakeManager.MAX_BOOST() + lockup + 1);
|
||||
}
|
||||
|
||||
|
||||
function mintMultiplierPoints() internal {
|
||||
uint256 new_mp = multiplierPoints + (balance * stakeManager.MP_APY());
|
||||
uint256 max_mp = getMaxMultiplierPoints();
|
||||
multiplierPoints = new_mp > max_mp ? max_mp : new_mp;
|
||||
}
|
||||
|
||||
function distriuteRewards() internal {
|
||||
uitn256 stakeApy = stakeManager.STAKE_APY();
|
||||
|
||||
if(stakeApy > 0){
|
||||
return stake_apy * (balance + multiplierPoints);
|
||||
} else {
|
||||
uint256 cs = balance + multiplierPoints;
|
||||
uint256 rewards = stakeManager.getRewardEmissions();
|
||||
if(cs > 0){
|
||||
return rewards * (balance + multiplierPoints) / cs;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -19,11 +19,28 @@ contract StakeManager is ERC20 {
|
|||
uint256 balance;
|
||||
uint256 multiplier;
|
||||
uint256 multiplierUpdate;
|
||||
uint256 epoch;
|
||||
}
|
||||
|
||||
struct Epoch {
|
||||
uint256 startTime;
|
||||
uint256 totalReward;
|
||||
}
|
||||
|
||||
uint256 currentEpoch;
|
||||
uint256 pendingReward;
|
||||
|
||||
uint256 public constant EPOCH_SIZE = 1 week;
|
||||
|
||||
mapping (uint256 => Epoch) epoch;
|
||||
mapping (address => Account) account;
|
||||
|
||||
|
||||
constructor() {
|
||||
epoch[0].startTime = now();
|
||||
|
||||
}
|
||||
|
||||
function increaseBalance(uint256 _amount, uint256 _time) external {
|
||||
accounts[msg.sender].balance += _amount;
|
||||
uint256 mp = calcInitialMultiplierPoints(_amount, _time);
|
||||
|
@ -58,6 +75,25 @@ contract StakeManager is ERC20 {
|
|||
accounts[_vault].multiplier += mp;
|
||||
}
|
||||
|
||||
function executeEpochReward() external {
|
||||
if(now() > epoch[currentEpoch].startTime + EPOCH_SIZE){
|
||||
uint256 epochReward = stakedToken.balanceOf(this) - pendingReward;
|
||||
epoch[currentEpoch].totalReward = epochReward;
|
||||
pendingReward += epochReward;
|
||||
currentEpoch++;
|
||||
|
||||
epoch[currentEpoch].startTime = now();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function executeUserReward(uint256 _epoch, address _vault) external {
|
||||
uint256 userReward = getRewardsEmissions(_vault, epoch[_epoch].totalReward);
|
||||
pendingReward -= userReward;
|
||||
stakedToken.transfer(_vault, userReward);
|
||||
|
||||
}
|
||||
|
||||
function calcInitialMultiplierPoints(uint256 _amount, uint256 _time) pure public returns(uint256) {
|
||||
return _amount * (_time + 1);
|
||||
}
|
||||
|
@ -72,7 +108,7 @@ contract StakeManager is ERC20 {
|
|||
function getRewardsEmissions(address _vault, uint256 _totalReward) public view returns(uint256){
|
||||
uint256 totalShare = this.totalSupply + this.multiplierSupply;
|
||||
uint256 userShare = accounts[_vault].balance + accounts[_vault].multiplier;
|
||||
return (userShare / totalShare) * _totalReward;
|
||||
return (userShare / totalShare) * _totalReward; //TODO: might lose precision, multiply by 100 and divide back later?
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
|
||||
contract StakeManager is ERC20 {
|
||||
|
||||
ERC20 stakedToken;
|
||||
|
||||
uint256 public constant MP_APY = 1;
|
||||
uint256 public constant STAKE_APY = 1;
|
||||
uint256 public constant MAX_BOOST = 1;
|
||||
uint256 public constant MAX_MP = 1;
|
||||
mapping (address => Account) accounts;
|
||||
|
||||
struct Account {
|
||||
uint256 lockTime;
|
||||
uint256 balance;
|
||||
uint256 multiplier;
|
||||
uint256 multiplierUpdate;
|
||||
}
|
||||
|
||||
mapping (address => Account) account;
|
||||
|
||||
|
||||
function increaseBalance(uint256 _amount, uint256 _time) external {
|
||||
accounts[msg.sender].balance += _amount;
|
||||
uint256 mp = calcInitialMultiplierPoints(_amount, _time);
|
||||
accounts[msg.sender].multiplier += mp;
|
||||
multiplierSupply += mp;
|
||||
accounts[msg.sender].update = now();
|
||||
accounts[msg.sender].lockTime = now() + _time;
|
||||
mint(msg.sender, _amount);
|
||||
}
|
||||
|
||||
function decreaseBalance(uint256 _amount) external {
|
||||
accounts[msg.sender].balance -= _amount;
|
||||
accounts[msg.sender].multiplier -= calcInitialMultiplierPoints(_amount, 1);
|
||||
burn(msg.sender, _amount);
|
||||
}
|
||||
|
||||
|
||||
function balanceLock(uint256 _time) external {
|
||||
require(now() + _time > accounts[msg.sender].lockTime, "Cannot decrease lock time");
|
||||
accounts[msg.sender].lockTime = now() + _time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function called to increase the Multiplier Points of a Vault
|
||||
* @param _vault
|
||||
*/
|
||||
function mintMultiplierPoints(address _vault) external {
|
||||
uint256 dT = now() - accounts[msg.sender].update;
|
||||
accounts[msg.sender].update = now();
|
||||
uint256 mp = calcAccuredMultiplierPoints(accounts[_vault].balance, accounts[_vault].multiplier, dT);
|
||||
multiplierSupply += mp;
|
||||
accounts[_vault].multiplier += mp;
|
||||
}
|
||||
|
||||
function calcInitialMultiplierPoints(uint256 _amount, uint256 _time) pure public returns(uint256) {
|
||||
return _amount * (_time + 1);
|
||||
}
|
||||
|
||||
function calcAccuredMultiplierPoints(uint256 _balance, uint256 _currentMp, uint256 _deltaTime) pure public returns(uint256) {
|
||||
uint256 accured = _balance * (MP_APY * _deltaTime);
|
||||
uint256 newMp = accured + _currentMp;
|
||||
return newMp > MAX_MP ? MAX_MP - newMp : accurred;
|
||||
}
|
||||
|
||||
|
||||
function getRewardsEmissions() public view returns(uint256){
|
||||
uint256 totalStaked = this.totalSupply;
|
||||
uint256 share = this.multiplierSupply +totalSupply;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,74 +1,33 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity 0.6.12;
|
||||
pragma solidity 0.8.19;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
import "./StakeManager.sol";
|
||||
|
||||
/**
|
||||
* @title StakeVault
|
||||
* @author Ricardo Guilherme Schmidt <ricardo3@status.im>
|
||||
* @notice Secures user stake
|
||||
*/
|
||||
contract StakeVault {
|
||||
address owner;
|
||||
StakeManager stakeManager;
|
||||
|
||||
ERC20 stakedToken;
|
||||
uint256 balance;
|
||||
uint256 locked;
|
||||
uint256 unlockTime;
|
||||
uint256 lockedPeriod;
|
||||
uint256 multiplierPoints;
|
||||
|
||||
function join(uint256 amount) external {
|
||||
_join(amount);
|
||||
|
||||
constructor(address _owner) public {
|
||||
owner = _owner;
|
||||
}
|
||||
|
||||
function lock(uint256 amount, uint256 time) external {
|
||||
_lock(amount,time);
|
||||
}
|
||||
|
||||
function joinAndLock(uint256 amount, uint256 time) external {
|
||||
_join(amount);
|
||||
_lock(amount,time);
|
||||
|
||||
}
|
||||
|
||||
function leave(uint256 amount) external {
|
||||
|
||||
}
|
||||
|
||||
function getMaxMultiplierPoints() public view returns(uint256) {
|
||||
return balance * (stakeManager.MAX_BOOST() + lockup + 1);
|
||||
}
|
||||
|
||||
function _join(uint256 amount) internal {
|
||||
function join(uint256 _amount, uint256 _time) external {
|
||||
stakedToken.transferFrom(msg.sender, address(this), amount);
|
||||
stakeManager.increaseBalance(amount, 0);
|
||||
}
|
||||
|
||||
function _lock(uint256 amount, uint256 time) internal {
|
||||
require(time > 0, "Invalid lock time");
|
||||
lockedPeriod = time;
|
||||
unlockTime = now() + time;
|
||||
locked = amount;
|
||||
multiplierPoints += amount * (time + 1);
|
||||
}
|
||||
|
||||
function mintMultiplierPoints() internal {
|
||||
uint256 new_mp = multiplierPoints + (balance * stakeManager.MP_APY());
|
||||
uint256 max_mp = getMaxMultiplierPoints();
|
||||
multiplierPoints = new_mp > max_mp ? max_mp : new_mp;
|
||||
}
|
||||
|
||||
function distriuteRewards() internal {
|
||||
uitn256 stakeApy = stakeManager.STAKE_APY()
|
||||
|
||||
if(stakeApy > 0){
|
||||
return stake_apy * (balance + multiplierPoints)
|
||||
} else {
|
||||
uint256 cs = balance + multiplierPoints
|
||||
uint256 rewards = stakeManager.getRewardEmissions();
|
||||
if(cs > 0){
|
||||
return = rewards * (balance + multiplierPoints) / cs
|
||||
}
|
||||
}
|
||||
|
||||
function leave(uint256 _amount) external {
|
||||
stakeManager.decreaseBalance(amount);
|
||||
stakedToken.transferFrom(address(this), msg.sender, amount);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -128,8 +128,8 @@
|
|||
"locate-path": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"log-symbols": "^4.1.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
"lru_map": "^0.3.3",
|
||||
"lru-cache": "^5.1.1",
|
||||
"mcl-wasm": "^0.7.9",
|
||||
"md5.js": "^1.3.5",
|
||||
"memory-level": "^1.0.0",
|
||||
|
@ -148,6 +148,7 @@
|
|||
"object-inspect": "^1.12.3",
|
||||
"obliterator": "^2.0.4",
|
||||
"once": "^1.4.0",
|
||||
"openzeppelin-contracts": "^4.0.0",
|
||||
"os-tmpdir": "^1.0.2",
|
||||
"p-limit": "^1.3.0",
|
||||
"p-locate": "^2.0.0",
|
||||
|
@ -188,8 +189,8 @@
|
|||
"stacktrace-parser": "^0.1.10",
|
||||
"statuses": "^2.0.1",
|
||||
"streamsearch": "^1.1.0",
|
||||
"string-width": "^4.2.3",
|
||||
"string_decoder": "^1.3.0",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"strip-hex-prefix": "^1.0.0",
|
||||
"strip-json-comments": "^3.1.1",
|
||||
|
|
Loading…
Reference in New Issue