Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add setMaxLockDuration function to add-veLON-impplementation #65

Open
wants to merge 10 commits into
base: add-veLON-implementation
Choose a base branch
from
2 changes: 2 additions & 0 deletions contracts/interfaces/IveLON.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ interface IveLON is IERC721, IERC721Metadata {
// TODO need this event?
// event Supply(uint256 prevSupply, uint256 supply);?

function setMaxLockDuration(uint256 _maxLockDuration) external;

function unlockTime(uint256 _tokenId) external view returns (uint256);

function createLock(uint256 _value, uint256 _lockDuration) external returns (uint256);
Expand Down
54 changes: 54 additions & 0 deletions contracts/veLON.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,60 @@ contract veLON is IveLON, ERC721, Ownable, ReentrancyGuard {
poolPointHistory[0].ts = block.timestamp;
}

/// @notice Update the `maxLockDuration`.
/// @param _maxLockDuration new number of seconds for `maxLockDuration`.
function setMaxLockDuration(uint256 _maxLockDuration) external override onlyOwner {
// flush the global voting power change into storage first
_updateLockedPoint(0, LockedBalance(0, 0), LockedBalance(0, 0));

uint256 maxEndTime = block.timestamp.add(_maxLockDuration).div(WEEK).mul(WEEK);
int256 globalDecliningRate;
int256 globalVBalance;
// update every NFT's stored states and calculate global states
for (uint256 _tokenId = 1; _tokenId <= tokenId; _tokenId++) {
// skip NFTs that have been burned
if (ownerOf(_tokenId) == address(0)) {
continue;
}
// skip expired NFTs
if (locked[_tokenId].end < block.timestamp) {
continue;
}

uint256 userEpoch = userPointEpoch[_tokenId];
LockedBalance memory oldLocked = locked[_tokenId];
LockedBalance memory newLocked = locked[_tokenId];
Point memory pointOld = userPointHistory[_tokenId][userEpoch];
Point memory pointNew = Point({ vBalance: 0, decliningRate: 0, ts: block.timestamp, blk: block.number });
if (newLocked.end > maxEndTime) {
newLocked.end = maxEndTime;
}
pointNew.decliningRate = int256(newLocked.amount.div(_maxLockDuration));
int256 duration = int256(newLocked.end.sub(block.timestamp));
pointNew.vBalance = duration * pointNew.decliningRate;

// update the latest user epoch and user point
userEpoch = userEpoch.add(1);
userPointEpoch[_tokenId] = userEpoch;
userPointHistory[_tokenId][userEpoch] = pointNew;
locked[_tokenId] = newLocked;

// update dRateChanges
dRateChanges[oldLocked.end] += pointOld.decliningRate;
dRateChanges[newLocked.end] += pointNew.decliningRate;

globalDecliningRate += pointNew.decliningRate;
globalVBalance += pointNew.vBalance;
}

// update global point
epoch = epoch.add(1);
poolPointHistory[epoch] = Point({ vBalance: globalVBalance, decliningRate: globalDecliningRate, ts: block.timestamp, blk: block.number });

// update the maxLockDuration
maxLockDuration = _maxLockDuration;
}

/// @notice Get timestamp when `_tokenId`'s lock finishes
/// @param _tokenId User NFT
/// @return Epoch time of the lock end
Expand Down