Skip to content

Commit

Permalink
chore: renamings and improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
albert-llimos committed Nov 3, 2023
1 parent 872824b commit a89d51e
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 45 deletions.
3 changes: 1 addition & 2 deletions contracts/utils/TokenVestingNoStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
*
* The vesting schedule is time-based (i.e. using block timestamps as opposed to e.g. block numbers), and
* is therefore sensitive to timestamp manipulation (which is something miners can do, to a certain degree).
* Therefore, it is recommended to avoid using short time durations (less than a minute). Typical vesting
* schemes, with a cliff period of a year and a duration of four years, are safe to use.
* Therefore, it is recommended to avoid using short time durations (less than a minute).
*
*/
contract TokenVestingNoStaking is ITokenVestingNoStaking, Shared {
Expand Down
23 changes: 12 additions & 11 deletions contracts/utils/TokenVestingStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
/**
* @title TokenVestingStaking
* @dev A token holder contract that that vests its balance of any ERC20 token to the beneficiary.
* Validator lockup - stakable. Nothing unlocked until end of contract where everything
* unlocks at once. All funds can be staked during the vesting period.
* Validator lockup - stakable. Nothing unlocked until the start is reached but can be staked
* in the meantime. After that all funds are unlocked according to a linear time-based vesting
* schedule. When the end is reached, all funds are unlocked.
* If revoked send all funds to revoker and block beneficiary releases indefinitely.
* Any staked funds at the moment of revocation can be retrieved by the revoker upon unstaking.
*
Expand All @@ -22,8 +23,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
*
* The vesting schedule is time-based (i.e. using block timestamps as opposed to e.g. block numbers), and
* is therefore sensitive to timestamp manipulation (which is something miners can do, to a certain degree).
* Therefore, it is recommended to avoid using short time durations (less than a minute). Typical vesting
* schemes, with a cliff period of a year and a duration of four years, are safe to use.
* Therefore, it is recommended to avoid using short time durations (less than a minute).
*
*/
contract TokenVestingStaking is ITokenVestingStaking, Shared {
Expand All @@ -36,7 +36,7 @@ contract TokenVestingStaking is ITokenVestingStaking, Shared {
address private revoker;

// Durations and timestamps are expressed in UNIX time, the same units as block.timestamp.
uint256 public immutable stakingVestingEnd;
uint256 public immutable start;
uint256 public immutable end;

// solhint-disable-next-line var-name-mixedcase
Expand All @@ -57,6 +57,7 @@ contract TokenVestingStaking is ITokenVestingStaking, Shared {
/**
* @param beneficiary_ address of the beneficiary to whom vested tokens are transferred
* @param revoker_ the person with the power to revoke the vesting. Address(0) means it is not revocable.
* @param start_ the unix time of the start of the linear vesting period
* @param end_ the unix time of the end of the vesting period, everything withdrawable after
* @param transferableBeneficiary_ whether the beneficiary address can be transferred
* @param addressHolder_ the contract holding the reference address to the ScGateway for staking
Expand All @@ -65,18 +66,18 @@ contract TokenVestingStaking is ITokenVestingStaking, Shared {
constructor(
address beneficiary_,
address revoker_,
uint256 stakingVestingEnd_,
uint256 start_,
uint256 end_,
bool transferableBeneficiary_,
IAddressHolder addressHolder_,
IERC20 flip_
) nzAddr(beneficiary_) nzAddr(address(addressHolder_)) nzAddr(address(flip_)) {
require(stakingVestingEnd_ <= end_, "Vesting: cliff_ after end_");
require(block.timestamp < stakingVestingEnd_, "Vesting: cliff before current time");
require(start_ <= end_, "Vesting: cliff_ after end_");
require(block.timestamp < start_, "Vesting: cliff before current time");

beneficiary = beneficiary_;
revoker = revoker_;
stakingVestingEnd = stakingVestingEnd_;
start = start_;
end = end_;
transferableBeneficiary = transferableBeneficiary_;
addressHolder = addressHolder_;
Expand Down Expand Up @@ -205,7 +206,7 @@ contract TokenVestingStaking is ITokenVestingStaking, Shared {
* @param token ERC20 token which is being vested.
*/
function _vestedAmount(IERC20 token) private view returns (uint256) {
if (block.timestamp < stakingVestingEnd) {
if (block.timestamp < start) {
return 0;
}

Expand All @@ -216,7 +217,7 @@ contract TokenVestingStaking is ITokenVestingStaking, Shared {
return totalBalance;
} else {
// No cliff
return (totalBalance * (block.timestamp - stakingVestingEnd)) / (end - stakingVestingEnd);
return (totalBalance * (block.timestamp - start)) / (end - start);
}
}

Expand Down
8 changes: 4 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ def tokenVestingStaking(addrs, cf, TokenVestingStaking, addressHolder):
# This was hardcoded to a timestamp, but ganache uses real-time when we run
# the tests, so we should use relative values instead of absolute ones
start = getChainTime()
stakingVestingEnd = start + QUARTER_YEAR + YEAR
end = stakingVestingEnd + YEAR
start = start + QUARTER_YEAR + YEAR
end = start + YEAR

total = MAX_TEST_FUND

Expand All @@ -220,13 +220,13 @@ def tokenVestingStaking(addrs, cf, TokenVestingStaking, addressHolder):
TokenVestingStaking,
addrs.BENEFICIARY,
addrs.REVOKER,
stakingVestingEnd,
start,
end,
BENEF_TRANSF,
addressHolder,
cf.flip,
)
return tv, stakingVestingEnd, end, total
return tv, start, end, total


# Deploy CFReceiver Mock contracts for testing purposes
Expand Down
4 changes: 2 additions & 2 deletions tests/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def deploy_tokenVestingStaking(
TokenVestingStaking,
beneficiary,
revoker,
stakingVestingEnd,
start,
end,
transferableBeneficiary,
addressHolder_address,
Expand All @@ -307,7 +307,7 @@ def deploy_tokenVestingStaking(
tokenVestingStaking = TokenVestingStaking.deploy(
beneficiary,
revoker,
stakingVestingEnd,
start,
end,
transferableBeneficiary,
addressHolder_address,
Expand Down
4 changes: 2 additions & 2 deletions tests/shared_tests_tokenVesting.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ def release_revert(tv, cf, address):
tv.release(cf.flip, {"from": address})


def check_state_staking(stateChainGateway, addressHolder, tv, stakingVestingEnd, *args):
def check_state_staking(stateChainGateway, addressHolder, tv, start, *args):
assert tv.addressHolder() == addressHolder
assert addressHolder.getStateChainGateway() == stateChainGateway
assert tv.stakingVestingEnd() == stakingVestingEnd
assert tv.start() == start
check_state(tv, *args)


Expand Down
36 changes: 18 additions & 18 deletions tests/token_vesting/release/test_release_staking.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ def test_release_rev_no_tokens(addrs, cf, tokenVestingStaking):

@given(st_sleepTime=strategy("uint256", max_value=YEAR * 2))
def test_release(addrs, cf, tokenVestingStaking, addressHolder, st_sleepTime, maths):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking

assert cf.flip.balanceOf(addrs.BENEFICIARY) == 0

chain.sleep(st_sleepTime)

if getChainTime() < stakingVestingEnd:
if getChainTime() < start:
release_revert(tv, cf, addrs.BENEFICIARY)
else:
tx = tv.release(cf.flip, {"from": addrs.BENEFICIARY})

newlyReleased = (
maths.simulateReleaseSt(total, tx.timestamp, end, stakingVestingEnd)
maths.simulateReleaseSt(total, tx.timestamp, end, start)
if tx.timestamp < end
else total
)
Expand All @@ -37,7 +37,7 @@ def test_release(addrs, cf, tokenVestingStaking, addressHolder, st_sleepTime, ma
cf.stateChainGateway,
addressHolder,
tv,
stakingVestingEnd,
start,
addrs.BENEFICIARY,
addrs.REVOKER,
True,
Expand All @@ -48,7 +48,7 @@ def test_release(addrs, cf, tokenVestingStaking, addressHolder, st_sleepTime, ma


def test_release_all(addrs, cf, tokenVestingStaking, addressHolder):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking

assert cf.flip.balanceOf(addrs.BENEFICIARY) == 0

Expand All @@ -64,7 +64,7 @@ def test_release_all(addrs, cf, tokenVestingStaking, addressHolder):
cf.stateChainGateway,
addressHolder,
tv,
stakingVestingEnd,
start,
addrs.BENEFICIARY,
addrs.REVOKER,
True,
Expand All @@ -77,17 +77,17 @@ def test_release_all(addrs, cf, tokenVestingStaking, addressHolder):
def test_consecutive_releases_after_cliff(
addrs, cf, tokenVestingStaking, maths, addressHolder
):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking

assert cf.flip.balanceOf(addrs.BENEFICIARY) == 0

accomulatedReleases = 0

# Substracting current time because they are on absolute terms
timestamps = [
stakingVestingEnd - 100,
stakingVestingEnd + QUARTER_YEAR,
stakingVestingEnd + QUARTER_YEAR * 2,
start - 100,
start + QUARTER_YEAR,
start + QUARTER_YEAR * 2,
end - 100,
end + 100,
]
Expand All @@ -97,13 +97,13 @@ def test_consecutive_releases_after_cliff(
for timestamp in timestamps:

chain.sleep(timestamp - getChainTime())
if getChainTime() < stakingVestingEnd:
if getChainTime() < start:
release_revert(tv, cf, addrs.BENEFICIARY)
else:
tx = tv.release(cf.flip, {"from": addrs.BENEFICIARY})

totalReleased = (
maths.simulateReleaseSt(total, tx.timestamp, end, stakingVestingEnd)
maths.simulateReleaseSt(total, tx.timestamp, end, start)
if tx.timestamp < end
else total
)
Expand All @@ -117,7 +117,7 @@ def test_consecutive_releases_after_cliff(
cf.stateChainGateway,
addressHolder,
tv,
stakingVestingEnd,
start,
addrs.BENEFICIARY,
addrs.REVOKER,
True,
Expand All @@ -135,7 +135,7 @@ def test_consecutive_releases_after_cliff(
def test_release_staking_rewards_after_end(
addrs, cf, tokenVestingStaking, addressHolder
):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking

test_release_all(addrs, cf, tokenVestingStaking, addressHolder)

Expand All @@ -151,7 +151,7 @@ def test_release_staking_rewards_after_end(
cf.stateChainGateway,
addressHolder,
tv,
stakingVestingEnd,
start,
addrs.BENEFICIARY,
addrs.REVOKER,
True,
Expand All @@ -165,11 +165,11 @@ def test_release_staking_rewards_after_end(
def test_release_around_cliff(
addrs, cf, tokenVestingStaking, addressHolder, st_sleepTime
):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking

chain.sleep(st_sleepTime)

if getChainTime() >= stakingVestingEnd:
if getChainTime() >= start:
tx = tv.release(cf.flip, {"from": addrs.BENEFICIARY})
# Check release
assert tx.events["TokensReleased"]["token"] == cf.flip
Expand All @@ -181,7 +181,7 @@ def test_release_around_cliff(
cf.stateChainGateway,
addressHolder,
tv,
stakingVestingEnd,
start,
addrs.BENEFICIARY,
addrs.REVOKER,
True,
Expand Down
8 changes: 4 additions & 4 deletions tests/token_vesting/revoke/test_revoke_staking.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@given(st_sleepTime=strategy("uint256", max_value=YEAR * 2))
def test_revoke(addrs, cf, tokenVestingStaking, addressHolder, st_sleepTime):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking

assert cf.flip.balanceOf(addrs.BENEFICIARY) == 0
assert cf.flip.balanceOf(addrs.REVOKER) == 0
Expand Down Expand Up @@ -34,7 +34,7 @@ def test_revoke(addrs, cf, tokenVestingStaking, addressHolder, st_sleepTime):
cf.stateChainGateway,
addressHolder,
tv,
stakingVestingEnd,
start,
addrs.BENEFICIARY,
addrs.REVOKER,
True,
Expand Down Expand Up @@ -182,11 +182,11 @@ def test_fund_revoked_staked(addrs, cf, tokenVestingStaking):

# Revoke with some tokens staked and linear vesting has started
def test_revoke_staked_linear(addrs, cf, tokenVestingStaking):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking
amount_staked = (total * 2) // 3
tv.fundStateChainAccount(JUNK_HEX, amount_staked, {"from": addrs.BENEFICIARY})
# Half the vesting period
chain.sleep(stakingVestingEnd + (end - stakingVestingEnd) // 2 - getChainTime())
chain.sleep(start + (end - start) // 2 - getChainTime())
amountInContract = total - amount_staked
assert cf.flip.balanceOf(tv) == amountInContract

Expand Down
4 changes: 2 additions & 2 deletions tests/token_vesting/stakeStProvider/test_stProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def test_stProviderClaimRewardsSlash(addrs, tokenVestingStaking, cf, mockStProvi


def test_stProviderRewards_release(addrs, tokenVestingStaking, cf, mockStProvider):
tv, stakingVestingEnd, end, total = tokenVestingStaking
tv, start, end, total = tokenVestingStaking
stFLIP, minter, _, _ = mockStProvider
reward_amount = total

Expand All @@ -240,7 +240,7 @@ def test_stProviderRewards_release(addrs, tokenVestingStaking, cf, mockStProvide
stFlipInContract += reward_amount

# Approximately into the middle of the vesting period
chain.sleep(stakingVestingEnd + (end - stakingVestingEnd) // 2 - getChainTime())
chain.sleep(start + (end - start) // 2 - getChainTime())

# The vested percentage of FLIP and stFLIP can be released.
tx = tv.release(cf.flip, {"from": addrs.BENEFICIARY})
Expand Down

0 comments on commit a89d51e

Please sign in to comment.