Skip to content

Commit

Permalink
Merge c500f3f into b295b8f
Browse files Browse the repository at this point in the history
  • Loading branch information
jameshowlett977 committed May 19, 2021
2 parents b295b8f + c500f3f commit 88ad14c
Show file tree
Hide file tree
Showing 16 changed files with 750 additions and 307 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ artifacts/
cache/
contracts_bzx/
tmp/
tmp
tmp
/temp/
/out/
2 changes: 1 addition & 1 deletion contracts/escrow/EscrowReward.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pragma solidity ^0.5.17;

import "./Escrow.sol";
import "./ILockedSOV.sol";
import "../locked/ILockedSOV.sol";

/**
* @title A reward distribution contract for Sovryn Ethereum Pool Escrow Contract.
Expand Down
15 changes: 0 additions & 15 deletions contracts/escrow/ILockedSOV.sol

This file was deleted.

78 changes: 55 additions & 23 deletions contracts/farm/LiquidityMining.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@ contract LiquidityMining is LiquidityMiningStorage {
using SafeERC20 for IERC20;

/* Constants */

uint256 public constant PRECISION = 1e12;
// Bonus multiplier for early liquidity providers.
// During bonus period each passed block will be calculated like N passed blocks, where N = BONUS_MULTIPLIER
//TODO do we need to make it settable?
uint256 public constant BONUS_BLOCK_MULTIPLIER = 10;

//TODO do we need to make it settable?
uint256 public constant SECONDS_PER_BLOCK = 30;

/* Events */
Expand All @@ -45,49 +43,63 @@ contract LiquidityMining is LiquidityMiningStorage {
* @param _lockedSOV The contract instance address of the lockedSOV vault.
* SOV rewards are not paid directly to liquidity providers. Instead they
* are deposited into a lockedSOV vault contract.
* @param _basisPoint The % (in Basis Point) which determines how much will be unlocked immediately.
*/
function initialize(
IERC20 _SOV,
uint256 _rewardTokensPerBlock,
uint256 _startDelayBlocks,
uint256 _numberOfBonusBlocks,
address _wrapper,
ILockedSOV _lockedSOV
) public onlyOwner {
ILockedSOV _lockedSOV,
uint256 _basisPoint
) public onlyAuthorized {
/// @dev Non-idempotent function. Must be called just once.
require(address(SOV) == address(0), "Already initialized");
require(address(_SOV) != address(0), "Invalid token address");
require(_startDelayBlocks > 0, "Invalid start block");
require(_basisPoint < 10000, "Basis Point has to be less than 10000.");

SOV = _SOV;
rewardTokensPerBlock = _rewardTokensPerBlock;
startBlock = block.number + _startDelayBlocks;
bonusEndBlock = startBlock + _numberOfBonusBlocks;
wrapper = _wrapper;
lockedSOV = _lockedSOV;
basisPoint = _basisPoint;
}

/**
* @notice Set lockedSOV contract.
* @notice Sets lockedSOV contract.
* @param _lockedSOV The contract instance address of the lockedSOV vault.
*/
function setLockedSOV(ILockedSOV _lockedSOV) public onlyOwner {
function setLockedSOV(ILockedSOV _lockedSOV) public onlyAuthorized {
require(address(_lockedSOV) != address(0), "Invalid lockedSOV Address.");
lockedSOV = _lockedSOV;
}

/**
* @notice Sets basisPoint.
* @param _basisPoint The % (in Basis Point) which determines how much will be unlocked immediately.
* @dev @dev 10000 is 100%
*/
function setBasisPoint(uint256 _basisPoint) public onlyAuthorized {
require(_basisPoint < 10000, "Basis Point has to be less than 10000.");
basisPoint = _basisPoint;
}

/**
* @notice sets wrapper proxy contract
* @dev can be set to zero address to remove wrapper
*/
function setWrapper(address _wrapper) public onlyOwner {
function setWrapper(address _wrapper) public onlyAuthorized {
wrapper = _wrapper;
}

/**
* @notice stops mining by setting end block
*/
function stopMining() public onlyOwner {
function stopMining() public onlyAuthorized {
require(endBlock == 0, "Already stopped");

endBlock = block.number;
Expand All @@ -100,7 +112,7 @@ contract LiquidityMining is LiquidityMiningStorage {
* @param _receiver The address of the SOV receiver.
* @param _amount The amount to be transferred.
* */
function transferSOV(address _receiver, uint256 _amount) public onlyOwner {
function transferSOV(address _receiver, uint256 _amount) public onlyAuthorized {
require(_receiver != address(0), "Receiver address invalid");
require(_amount != 0, "Amount invalid");

Expand All @@ -121,7 +133,7 @@ contract LiquidityMining is LiquidityMiningStorage {
* @notice Get the missed SOV balance of LM contract.
*
* @return The amount of SOV tokens according to totalUsersBalance
* in excess of actual SOV balance of the LM contract.
* in excess of actual SOV balance of the LM contract.
* */
function getMissedBalance() public view returns (uint256) {
uint256 balance = SOV.balanceOf(address(this));
Expand All @@ -138,7 +150,7 @@ contract LiquidityMining is LiquidityMiningStorage {
address _poolToken,
uint96 _allocationPoint,
bool _withUpdate
) public onlyOwner {
) public onlyAuthorized {
require(_allocationPoint > 0, "Invalid allocation point");
require(_poolToken != address(0), "Invalid token address");
require(poolIdList[_poolToken] == 0, "Token already added");
Expand Down Expand Up @@ -174,7 +186,7 @@ contract LiquidityMining is LiquidityMiningStorage {
address _poolToken,
uint96 _allocationPoint,
bool _withUpdate
) public onlyOwner {
) public onlyAuthorized {
uint256 poolId = _getPoolId(_poolToken);

if (_withUpdate) {
Expand Down Expand Up @@ -240,7 +252,11 @@ contract LiquidityMining is LiquidityMiningStorage {
* @param _amount the amount of tokens to be deposited
* @param _duration the duration of liquidity providing in seconds
*/
function getEstimatedReward(address _poolToken, uint256 _amount, uint256 _duration) external view returns (uint256) {
function getEstimatedReward(
address _poolToken,
uint256 _amount,
uint256 _duration
) external view returns (uint256) {
uint256 poolId = _getPoolId(_poolToken);
PoolInfo storage pool = poolInfoList[poolId];
uint256 start = block.number;
Expand Down Expand Up @@ -315,7 +331,11 @@ contract LiquidityMining is LiquidityMiningStorage {
* @param _amount the amount of pool tokens
* @param _user the address of user, tokens will be deposited to it or to msg.sender
*/
function deposit(address _poolToken, uint256 _amount, address _user) public {
function deposit(
address _poolToken,
uint256 _amount,
address _user
) public {
require(poolIdList[_poolToken] != 0, "Pool token not found");
address userAddress = _user != address(0) ? _user : msg.sender;

Expand Down Expand Up @@ -349,7 +369,7 @@ contract LiquidityMining is LiquidityMiningStorage {

_updatePool(poolId);
_updateReward(pool, user);
_transferReward(user, userAddress); //send to user directly
_transferReward(user, userAddress, true);
_updateRewardDebt(pool, user);
}

Expand All @@ -359,7 +379,11 @@ contract LiquidityMining is LiquidityMiningStorage {
* @param _amount the amount of pool tokens
* @param _user the user address will be used to process a withdrawal (can be passed only by wrapper contract)
*/
function withdraw(address _poolToken, uint256 _amount, address _user) public {
function withdraw(
address _poolToken,
uint256 _amount,
address _user
) public {
require(poolIdList[_poolToken] != 0, "Pool token not found");
address userAddress = _getUserAddress(_user);

Expand All @@ -370,7 +394,7 @@ contract LiquidityMining is LiquidityMiningStorage {

_updatePool(poolId);
_updateReward(pool, user);
_transferReward(user, userAddress); //send to user directly
_transferReward(user, userAddress, false);

user.amount = user.amount.sub(_amount);
pool.poolToken.safeTransfer(address(msg.sender), _amount); //sent to the user or wrapper
Expand Down Expand Up @@ -406,10 +430,14 @@ contract LiquidityMining is LiquidityMiningStorage {
* @notice Send reward in SOV to the lockedSOV vault.
* @param _user The user info, to get its reward share.
* @param _userAddress The address of the user, to send SOV in its behalf.
* */
function _transferReward(UserInfo storage _user, address _userAddress) internal {
*/
function _transferReward(
UserInfo storage _user,
address _userAddress,
bool _isClaimingReward
) internal {
uint256 userAccumulatedReward = _user.accumulatedReward;

/// @dev Transfer if enough SOV balance on this LM contract.
uint256 balance = SOV.balanceOf(address(this));
if (balance >= userAccumulatedReward) {
Expand All @@ -421,8 +449,12 @@ contract LiquidityMining is LiquidityMiningStorage {
/// SOV deposit must be approved to move the SOV tokens
/// from this LM contract into the lockedSOV vault.
SOV.approve(address(lockedSOV), userAccumulatedReward);
lockedSOV.depositSOV(_userAddress, userAccumulatedReward);

lockedSOV.deposit(_userAddress, userAccumulatedReward, basisPoint);

if (_isClaimingReward) {
lockedSOV.withdrawAndStakeTokensFrom(_userAddress);
}

/// @dev Event log.
emit RewardClaimed(_userAddress, userAccumulatedReward);
}
Expand Down
9 changes: 6 additions & 3 deletions contracts/farm/LiquidityMiningStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ pragma solidity 0.5.17;
import "../openzeppelin/ERC20.sol";
import "../openzeppelin/SafeERC20.sol";
import "../openzeppelin/SafeMath.sol";
import "../openzeppelin/Ownable.sol";
import "../escrow/ILockedSOV.sol";
import "../locked/ILockedSOV.sol";
import "../utils/AdminRole.sol";

contract LiquidityMiningStorage is Ownable {
contract LiquidityMiningStorage is AdminRole {
// Info of each user.
struct UserInfo {
uint256 amount; // How many pool tokens the user has provided.
Expand Down Expand Up @@ -63,4 +63,7 @@ contract LiquidityMiningStorage is Ownable {
/// @dev The locked vault contract to deposit LP's rewards into.
ILockedSOV public lockedSOV;

// The % (in Basis Point) which determines how much will be unlocked immediately.
/// @dev 10000 is 100%
uint256 public basisPoint;
}
18 changes: 18 additions & 0 deletions contracts/locked/ILockedSOV.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,28 @@ pragma solidity ^0.5.17;
* @dev Only use it if you know what you are doing.
*/
interface ILockedSOV {
/**
* @notice Adds SOV to the user balance (Locked and Unlocked Balance based on `_basisPoint`).
* @param _userAddress The user whose locked balance has to be updated with `_sovAmount`.
* @param _sovAmount The amount of SOV to be added to the locked and/or unlocked balance.
* @param _basisPoint The % (in Basis Point)which determines how much will be unlocked immediately.
*/
function deposit(
address _userAddress,
uint256 _sovAmount,
uint256 _basisPoint
) external;

/**
* @notice Adds SOV to the locked balance of a user.
* @param _userAddress The user whose locked balance has to be updated with _sovAmount.
* @param _sovAmount The amount of SOV to be added to the locked balance.
*/
function depositSOV(address _userAddress, uint256 _sovAmount) external;

/**
* @notice Withdraws unlocked tokens and Stakes Locked tokens for a user who already have a vesting created.
* @param _userAddress The address of user tokens will be withdrawn.
*/
function withdrawAndStakeTokensFrom(address _userAddress) external;
}
Loading

0 comments on commit 88ad14c

Please sign in to comment.