execute epoch, user reward

This commit is contained in:
Ricardo Guilherme Schmidt 2023-06-21 11:20:23 -03:00
parent b70666c26d
commit 4849cccb81
No known key found for this signature in database
GPG Key ID: 3F95A3AD0B607030
8 changed files with 436 additions and 382 deletions

2
.gitignore vendored
View File

@ -9,3 +9,5 @@ typechain-types
cache
artifacts
gmx-contracts
node_modules

View File

@ -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;
}
}
}

View File

@ -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?
}

View File

@ -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;
}
}

View File

View File

@ -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);
}
}

600
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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",