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
|
cache
|
||||||
artifacts
|
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 balance;
|
||||||
uint256 multiplier;
|
uint256 multiplier;
|
||||||
uint256 multiplierUpdate;
|
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;
|
mapping (address => Account) account;
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
epoch[0].startTime = now();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function increaseBalance(uint256 _amount, uint256 _time) external {
|
function increaseBalance(uint256 _amount, uint256 _time) external {
|
||||||
accounts[msg.sender].balance += _amount;
|
accounts[msg.sender].balance += _amount;
|
||||||
uint256 mp = calcInitialMultiplierPoints(_amount, _time);
|
uint256 mp = calcInitialMultiplierPoints(_amount, _time);
|
||||||
|
@ -58,6 +75,25 @@ contract StakeManager is ERC20 {
|
||||||
accounts[_vault].multiplier += mp;
|
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) {
|
function calcInitialMultiplierPoints(uint256 _amount, uint256 _time) pure public returns(uint256) {
|
||||||
return _amount * (_time + 1);
|
return _amount * (_time + 1);
|
||||||
}
|
}
|
||||||
|
@ -72,7 +108,7 @@ contract StakeManager is ERC20 {
|
||||||
function getRewardsEmissions(address _vault, uint256 _totalReward) public view returns(uint256){
|
function getRewardsEmissions(address _vault, uint256 _totalReward) public view returns(uint256){
|
||||||
uint256 totalShare = this.totalSupply + this.multiplierSupply;
|
uint256 totalShare = this.totalSupply + this.multiplierSupply;
|
||||||
uint256 userShare = accounts[_vault].balance + accounts[_vault].multiplier;
|
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
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
pragma solidity 0.6.12;
|
pragma solidity 0.8.19;
|
||||||
|
|
||||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
||||||
import "./StakeManager.sol";
|
import "./StakeManager.sol";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title StakeVault
|
||||||
|
* @author Ricardo Guilherme Schmidt <ricardo3@status.im>
|
||||||
|
* @notice Secures user stake
|
||||||
|
*/
|
||||||
contract StakeVault {
|
contract StakeVault {
|
||||||
address owner;
|
address owner;
|
||||||
StakeManager stakeManager;
|
StakeManager stakeManager;
|
||||||
|
|
||||||
ERC20 stakedToken;
|
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 {
|
function join(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 {
|
|
||||||
stakedToken.transferFrom(msg.sender, address(this), amount);
|
stakedToken.transferFrom(msg.sender, address(this), amount);
|
||||||
|
stakeManager.increaseBalance(amount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _lock(uint256 amount, uint256 time) internal {
|
function leave(uint256 _amount) external {
|
||||||
require(time > 0, "Invalid lock time");
|
stakeManager.decreaseBalance(amount);
|
||||||
lockedPeriod = time;
|
stakedToken.transferFrom(address(this), msg.sender, amount);
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -128,8 +128,8 @@
|
||||||
"locate-path": "^2.0.0",
|
"locate-path": "^2.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"log-symbols": "^4.1.0",
|
"log-symbols": "^4.1.0",
|
||||||
"lru-cache": "^5.1.1",
|
|
||||||
"lru_map": "^0.3.3",
|
"lru_map": "^0.3.3",
|
||||||
|
"lru-cache": "^5.1.1",
|
||||||
"mcl-wasm": "^0.7.9",
|
"mcl-wasm": "^0.7.9",
|
||||||
"md5.js": "^1.3.5",
|
"md5.js": "^1.3.5",
|
||||||
"memory-level": "^1.0.0",
|
"memory-level": "^1.0.0",
|
||||||
|
@ -148,6 +148,7 @@
|
||||||
"object-inspect": "^1.12.3",
|
"object-inspect": "^1.12.3",
|
||||||
"obliterator": "^2.0.4",
|
"obliterator": "^2.0.4",
|
||||||
"once": "^1.4.0",
|
"once": "^1.4.0",
|
||||||
|
"openzeppelin-contracts": "^4.0.0",
|
||||||
"os-tmpdir": "^1.0.2",
|
"os-tmpdir": "^1.0.2",
|
||||||
"p-limit": "^1.3.0",
|
"p-limit": "^1.3.0",
|
||||||
"p-locate": "^2.0.0",
|
"p-locate": "^2.0.0",
|
||||||
|
@ -188,8 +189,8 @@
|
||||||
"stacktrace-parser": "^0.1.10",
|
"stacktrace-parser": "^0.1.10",
|
||||||
"statuses": "^2.0.1",
|
"statuses": "^2.0.1",
|
||||||
"streamsearch": "^1.1.0",
|
"streamsearch": "^1.1.0",
|
||||||
"string-width": "^4.2.3",
|
|
||||||
"string_decoder": "^1.3.0",
|
"string_decoder": "^1.3.0",
|
||||||
|
"string-width": "^4.2.3",
|
||||||
"strip-ansi": "^6.0.1",
|
"strip-ansi": "^6.0.1",
|
||||||
"strip-hex-prefix": "^1.0.0",
|
"strip-hex-prefix": "^1.0.0",
|
||||||
"strip-json-comments": "^3.1.1",
|
"strip-json-comments": "^3.1.1",
|
||||||
|
|
Loading…
Reference in New Issue