Skip to content

Commit

Permalink
Merge pull request #116 from skalenetwork/feature/SKALE-2302-90-days
Browse files Browse the repository at this point in the history
SKALE-2302 Change tokens lock period
  • Loading branch information
cstrangedk authored Mar 11, 2020
2 parents 6d9df0a + 3359d0e commit 7f9eefa
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 19 deletions.
7 changes: 7 additions & 0 deletions contracts/ConstantsHolder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ contract ConstantsHolder is IConstants, Permissions {

uint public rotationDelay;

uint public proofOfUseLockUpPeriodDays;

/**
* Set reward and delta periods to new one, run only by owner. This function
* only for tests.
Expand Down Expand Up @@ -168,6 +170,10 @@ contract ConstantsHolder is IConstants, Permissions {
rotationDelay = newDelay;
}

function setProofOfUseLockUpPeriod(uint periodDays) external onlyOwner {
proofOfUseLockUpPeriodDays = periodDays;
}

/**
* @dev constructor in Permissions approach
* @param contractsAddress needed in Permissions constructor
Expand All @@ -184,5 +190,6 @@ contract ConstantsHolder is IConstants, Permissions {
lastTimeOverloaded = 0;
launchTimestamp = now;
rotationDelay = 12 hours;
proofOfUseLockUpPeriodDays = 90;
}
}
14 changes: 9 additions & 5 deletions contracts/delegation/TimeHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ contract TimeHelpers {
}
}

function calculateProofOfUseLockEndTime(uint month, uint lockUpPeriodDays) external pure returns (uint timestamp) {
timestamp = BokkyPooBahsDateTimeLibrary.addDays(monthToTimestamp(month), lockUpPeriodDays);
}

function addMonths(uint fromTimestamp, uint n) external pure returns (uint) {
uint year;
uint month;
Expand All @@ -91,7 +95,11 @@ contract TimeHelpers {
second);
}

function monthToTimestamp(uint _month) external pure returns (uint timestamp) {
function getCurrentMonth() external view returns (uint) {
return timestampToMonth(now);
}

function monthToTimestamp(uint _month) public pure returns (uint timestamp) {
uint year = ZERO_YEAR;
uint month = _month;
year = year.add(month.div(12));
Expand All @@ -100,10 +108,6 @@ contract TimeHelpers {
return BokkyPooBahsDateTimeLibrary.timestampFromDate(year, month, 1);
}

function getCurrentMonth() external view returns (uint) {
return timestampToMonth(now);
}

function timestampToMonth(uint timestamp) public pure returns (uint) {
uint year;
uint month;
Expand Down
4 changes: 3 additions & 1 deletion contracts/delegation/TokenLaunchLocker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import "@openzeppelin/contracts/math/SafeMath.sol";

import "../Permissions.sol";
import "../interfaces/delegation/ILocker.sol";
import "../ConstantsHolder.sol";

import "./DelegationController.sol";
import "./TimeHelpers.sol";
Expand Down Expand Up @@ -96,10 +97,11 @@ contract TokenLaunchLocker is Permissions, ILocker {
if (_locked[wallet] > 0) {
DelegationController delegationController = DelegationController(contractManager.getContract("DelegationController"));
TimeHelpers timeHelpers = TimeHelpers(contractManager.getContract("TimeHelpers"));
ConstantsHolder constantsHolder = ConstantsHolder(contractManager.getContract("ConstantsHolder"));

uint currentMonth = timeHelpers.getCurrentMonth();
if (_totalDelegatedAmount[wallet].delegated.mul(2) >= _locked[wallet] &&
_totalDelegatedAmount[wallet].month.add(3) <= currentMonth) {
timeHelpers.calculateProofOfUseLockEndTime(_totalDelegatedAmount[wallet].month, constantsHolder.proofOfUseLockUpPeriodDays()) <= now) {
unlock(wallet);
return 0;
} else {
Expand Down
10 changes: 5 additions & 5 deletions contracts/test/ReentrancyTester.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ contract ReentrancyTester is Permissions, IERC777Recipient {
}

function tokensReceived(
address operator,
address from,
address to,
address /* operator */,
address /* from */,
address /* to */,
uint256 amount,
bytes calldata userData,
bytes calldata operatorData
bytes calldata /* userData */,
bytes calldata /* operatorData */
)
external
{
Expand Down
43 changes: 35 additions & 8 deletions test/delegation/TokenLaunch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ContractManagerInstance,
TokenLaunchManagerInstance,
ValidatorServiceInstance} from "../../types/truffle-contracts";

import { skipTime, skipTimeToDate } from "../utils/time";
import { isLeapYear, skipTime, skipTimeToDate } from "../utils/time";

import * as chai from "chai";
import * as chaiAsPromised from "chai-as-promised";
Expand Down Expand Up @@ -142,7 +142,9 @@ contract("TokenLaunchManager", ([owner, holder, delegation, validator, seller, h
// TODO: move undelegated tokens too
});

it("should unlock all tokens if 50% was delegated", async () => {
it("should unlock all tokens if 50% was delegated for 90 days", async () => {
await skipTimeToDate(web3, 1, 0); // January

const amount = Math.ceil(totalAmount / 2);
const period = 3;
await delegationController.delegate(validatorId, amount, period, "INFO", {from: holder});
Expand All @@ -158,12 +160,37 @@ contract("TokenLaunchManager", ([owner, holder, delegation, validator, seller, h

await delegationController.requestUndelegation(delegationId, {from: holder});

skipTime(web3, month * period);

const state = await delegationController.getState(delegationId);
state.toNumber().should.be.equal(State.COMPLETED);
const locked = await skaleToken.getAndUpdateLockedAmount.call(holder);
locked.toNumber().should.be.equal(0);
// skip 89 days
const leapYear = await isLeapYear(web3);
if (leapYear) {
await skipTimeToDate(web3, 30, 3);
} else {
await skipTimeToDate(web3, 1, 4);
}

if (leapYear) {
const state = await delegationController.getState(delegationId);
state.toNumber().should.be.equal(State.UNDELEGATION_REQUESTED);
const locked = await skaleToken.getAndUpdateLockedAmount.call(holder);
locked.toNumber().should.be.equal(totalAmount);
delegated = await skaleToken.getAndUpdateDelegatedAmount.call(holder);
delegated.toNumber().should.be.equal(amount);
} else {
const state = await delegationController.getState(delegationId);
state.toNumber().should.be.equal(State.COMPLETED);
const locked = await skaleToken.getAndUpdateLockedAmount.call(holder);
locked.toNumber().should.be.equal(totalAmount);
delegated = await skaleToken.getAndUpdateDelegatedAmount.call(holder);
delegated.toNumber().should.be.equal(0);
}

// skip one more day
skipTime(web3, 60 * 60 * 24);

const finalState = await delegationController.getState(delegationId);
finalState.toNumber().should.be.equal(State.COMPLETED);
const finalLocked = await skaleToken.getAndUpdateLockedAmount.call(holder);
finalLocked.toNumber().should.be.equal(0);
delegated = await skaleToken.getAndUpdateDelegatedAmount.call(holder);
delegated.toNumber().should.be.equal(0);
});
Expand Down
2 changes: 2 additions & 0 deletions test/utils/deploy/delegation/tokenLaunchLocker.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ContractManagerInstance, TokenLaunchLockerInstance } from "../../../../types/truffle-contracts";
import { deployConstantsHolder } from "../constantsHolder";
import { deployFunctionFactory } from "../factory";
import { deployDelegationController } from "./delegationController";
import { deployTimeHelpers } from "./timeHelpers";
Expand All @@ -8,6 +9,7 @@ const deployTokenLaunchLocker: (contractManager: ContractManagerInstance) => Pro
async (contractManager: ContractManagerInstance) => {
await deployTimeHelpers(contractManager);
await deployDelegationController(contractManager);
await deployConstantsHolder(contractManager);
});

export { deployTokenLaunchLocker };
6 changes: 6 additions & 0 deletions test/utils/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,9 @@ export async function currentTime(web3: Web3) {
}

export const months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"];

export async function isLeapYear(web3: Web3) {
const timestamp = await currentTime(web3);
const now = new Date(timestamp * 1000);
return now.getFullYear() % 4 === 0;
}

0 comments on commit 7f9eefa

Please sign in to comment.