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
Method to remove unused sub-stakes in StakingEscrow #2384
Changes from all commits
30a06fe
b443ab7
d1ede31
5741182
8c80b03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,7 @@ interface WorkLockInterface { | |
/** | ||
* @notice Contract holds and locks stakers tokens. | ||
* Each staker that locks their tokens will receive some compensation | ||
* @dev |v5.4.4| | ||
* @dev |v5.5.1| | ||
*/ | ||
contract StakingEscrow is Issuer, IERC900History { | ||
|
||
|
@@ -1048,6 +1048,30 @@ contract StakingEscrow is Issuer, IERC900History { | |
} | ||
} | ||
|
||
/** | ||
* @notice Remove unused sub-stake to decrease gas cost for several methods | ||
*/ | ||
function removeUnusedSubStake(uint16 _index) external onlyStaker { | ||
StakerInfo storage info = stakerInfo[msg.sender]; | ||
|
||
uint256 lastIndex = info.subStakes.length - 1; | ||
SubStakeInfo storage subStake = info.subStakes[_index]; | ||
require(subStake.lastPeriod != 0 && | ||
(info.currentCommittedPeriod == 0 || | ||
subStake.lastPeriod < info.currentCommittedPeriod) && | ||
(info.nextCommittedPeriod == 0 || | ||
subStake.lastPeriod < info.nextCommittedPeriod)); | ||
|
||
if (_index != lastIndex) { | ||
SubStakeInfo storage lastSubStake = info.subStakes[lastIndex]; | ||
subStake.firstPeriod = lastSubStake.firstPeriod; | ||
subStake.lastPeriod = lastSubStake.lastPeriod; | ||
subStake.periods = lastSubStake.periods; | ||
subStake.lockedValue = lastSubStake.lockedValue; | ||
} | ||
info.subStakes.pop(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does using If so, how does one keep track of their removal of multiple sub-stakes? It doesn't show you unused sub-stakes when you check via There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right - this deletes last element in array but before this - copies last element to place of removed unused sub-stake. |
||
} | ||
|
||
/** | ||
* @notice Withdraw available amount of tokens to staker | ||
* @param _value Amount of tokens to withdraw | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -138,7 +138,6 @@ def test_get_swarm(agency, blockchain_ursulas): | |
assert is_address(staker_addr) | ||
|
||
|
||
|
||
@pytest.mark.usefixtures("blockchain_ursulas") | ||
def test_sample_stakers(agency): | ||
_token_agent, staking_agent, _policy_agent = agency | ||
|
@@ -264,16 +263,6 @@ def test_deposit_and_increase(agency, testerchain, test_registry, token_economic | |
assert staking_agent.get_locked_tokens(staker_account, 1) == locked_tokens + amount | ||
|
||
|
||
def test_disable_restaking(agency, testerchain, test_registry): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did this test get relocated somewhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Few lines below - same method with the same name and this one was already disabled |
||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) | ||
staker_account, worker_account, *other = testerchain.unassigned_accounts | ||
|
||
assert staking_agent.is_restaking(staker_account) | ||
receipt = staking_agent.set_restaking(staker_account, value=False) | ||
assert receipt['status'] == 1 | ||
assert not staking_agent.is_restaking(staker_account) | ||
|
||
|
||
def test_lock_restaking(agency, testerchain, test_registry): | ||
staker_account, worker_account, *other = testerchain.unassigned_accounts | ||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) | ||
|
@@ -438,6 +427,33 @@ def test_merge(agency, testerchain, test_registry, token_economics): | |
assert staking_agent.get_locked_tokens(staker_account, 0) == current_locked_tokens | ||
|
||
|
||
def test_remove_unused_stake(agency, testerchain, test_registry): | ||
staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=test_registry) | ||
staker_account = testerchain.unassigned_accounts[0] | ||
|
||
testerchain.time_travel(periods=1) | ||
staking_agent.mint(staker_address=staker_account) | ||
current_period = staking_agent.get_current_period() | ||
original_stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) | ||
assert original_stakes[2].last_period == current_period - 1 | ||
|
||
current_locked_tokens = staking_agent.get_locked_tokens(staker_account, 0) | ||
next_locked_tokens = staking_agent.get_locked_tokens(staker_account, 1) | ||
|
||
receipt = staking_agent.remove_unused_stake(staker_address=staker_account, stake_index=2) | ||
assert receipt['status'] == 1 | ||
|
||
# Ensure stake was extended by one period. | ||
stakes = list(staking_agent.get_all_stakes(staker_address=staker_account)) | ||
assert len(stakes) == len(original_stakes) - 1 | ||
assert stakes[0] == original_stakes[0] | ||
assert stakes[1] == original_stakes[1] | ||
assert stakes[2] == original_stakes[4] | ||
assert stakes[3] == original_stakes[3] | ||
assert staking_agent.get_locked_tokens(staker_account, 1) == next_locked_tokens | ||
assert staking_agent.get_locked_tokens(staker_account, 0) == current_locked_tokens | ||
|
||
|
||
def test_batch_deposit(testerchain, | ||
agency, | ||
token_economics, | ||
|
@@ -448,7 +464,6 @@ def test_batch_deposit(testerchain, | |
|
||
amount = token_economics.minimum_allowed_locked | ||
lock_periods = token_economics.minimum_locked_periods | ||
current_period = staking_agent.get_current_period() | ||
|
||
stakers = [get_random_checksum_address() for _ in range(4)] | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Command removes only one sub-stake by each tx