Skip to content

Commit

Permalink
TACoApplication: method to make a commitment
Browse files Browse the repository at this point in the history
  • Loading branch information
vzotova committed Sep 5, 2023
1 parent ff36f5b commit 5f46c5c
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 1 deletion.
32 changes: 32 additions & 0 deletions contracts/contracts/TACoApplication.sol
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ contract TACoApplication is IApplication, ITACoChildToRoot, OwnableUpgradeable {
uint256 startTimestamp
);

/**
* @notice Signals that a staking provider made a commitment
* @param stakingProvider Staking provider address
* @param endCommitment End of commitment
*/
event CommitmentMade(address indexed stakingProvider, uint256 endCommitment);

struct StakingProviderInfo {
address operator;
bool operatorConfirmed;
Expand All @@ -137,8 +144,11 @@ contract TACoApplication is IApplication, ITACoChildToRoot, OwnableUpgradeable {
uint64 endDeauthorization;
uint96 tReward;
uint96 rewardPerTokenPaid;
uint64 endCommitment;
}

uint64 public constant MINIMUM_COMMITMENT = 365 days;

uint96 public immutable minimumAuthorization;
uint256 public immutable minOperatorSeconds;
uint256 public immutable rewardDuration;
Expand Down Expand Up @@ -444,6 +454,10 @@ contract TACoApplication is IApplication, ITACoChildToRoot, OwnableUpgradeable {
_toAmount == 0 || _toAmount >= minimumAuthorization,
"Resulting authorization will be less than minimum"
);
require(
info.endCommitment <= block.timestamp,
"Can't request deauthorization before end of commitment"
);
if (info.operatorConfirmed) {
resynchronizeAuthorizedOverall(info, _fromAmount);
}
Expand Down Expand Up @@ -479,6 +493,7 @@ contract TACoApplication is IApplication, ITACoChildToRoot, OwnableUpgradeable {
info.authorized = toAmount;
info.deauthorizing = 0;
info.endDeauthorization = 0;
info.endCommitment = 0;

if (info.authorized == 0) {
_stakingProviderFromOperator[info.operator] = address(0);
Expand Down Expand Up @@ -517,6 +532,23 @@ contract TACoApplication is IApplication, ITACoChildToRoot, OwnableUpgradeable {
_updateAuthorization(_stakingProvider, info);
}

/**
* @notice Make a commitment to not request authorization decrease for specified duration
* @param _stakingProvider Staking provider address
* @param _duration Duration of commitment
*/
function makeCommitment(
address _stakingProvider,
uint64 _duration
) external onlyOwnerOrStakingProvider(_stakingProvider) {
require(_duration >= MINIMUM_COMMITMENT, "Duration must be greater than minimum");
StakingProviderInfo storage info = stakingProviderInfo[_stakingProvider];
require(info.endDeauthorization == 0, "Commitment can't be made during deauthorization");
require(info.endCommitment == 0, "Commitment already made");
info.endCommitment = uint64(block.timestamp) + _duration;
emit CommitmentMade(_stakingProvider, info.endCommitment);
}

//-------------------------Main-------------------------
/**
* @notice Returns staking provider for specified operator
Expand Down
88 changes: 87 additions & 1 deletion tests/application/test_authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
AUTHORIZATION_SLOT = 3
DEAUTHORIZING_SLOT = 4
END_DEAUTHORIZATION_SLOT = 5
END_COMMITMENT_SLOT = 8
MIN_AUTHORIZATION = Web3.to_wei(40_000, "ether")
DEAUTHORIZATION_DURATION = 60 * 60 * 24 * 60 # 60 days in seconds

Expand Down Expand Up @@ -403,10 +404,31 @@ def test_authorization_decrease_request(
# Request decrease without syncing with child app
taco_application.setChildApplication(ZERO_ADDRESS, sender=creator)
threshold_staking.authorizationDecreaseRequested(
staking_provider, value // 2, value // 2, sender=creator
staking_provider, value // 2, 0, sender=creator
)
assert child_application.authorizedStake(staking_provider) == 0

# Try to request decrease before ending of commitment
chain.pending_timestamp += deauthorization_duration
taco_application.finishAuthorizationDecrease(staking_provider, sender=creator)
threshold_staking.authorizationIncreased(staking_provider, 0, value, sender=creator)
minimum_commitment_duration = taco_application.MINIMUM_COMMITMENT()
taco_application.makeCommitment(
staking_provider, minimum_commitment_duration, sender=staking_provider
)

# Commitment is still active
with ape.reverts("Can't request deauthorization before end of commitment"):
threshold_staking.authorizationDecreaseRequested(
staking_provider, value, value // 2, sender=creator
)
chain.pending_timestamp += minimum_commitment_duration

# Now decrease can be requested
threshold_staking.authorizationDecreaseRequested(
staking_provider, value, value // 2, sender=creator
)


def test_finish_authorization_decrease(
accounts, threshold_staking, taco_application, child_application, chain
Expand Down Expand Up @@ -663,3 +685,67 @@ def test_resync(accounts, threshold_staking, taco_application, child_application
assert child_application.authorizedStake(staking_provider) == value
assert taco_application.getOperatorFromStakingProvider(staking_provider) == ZERO_ADDRESS
assert child_application.operatorFromStakingProvider(staking_provider) == staking_provider


def test_commitment(accounts, threshold_staking, taco_application, chain):
"""
Tests for authorization method: makeCommitment
"""

creator, staking_provider = accounts[0:2]
deauthorization_duration = DEAUTHORIZATION_DURATION
minimum_authorization = MIN_AUTHORIZATION
value = 2 * minimum_authorization
minimum_commitment_duration = taco_application.MINIMUM_COMMITMENT()

# Commitment can be made only for authorized staking provider
with ape.reverts("Not owner or provider"):
taco_application.makeCommitment(
staking_provider, minimum_commitment_duration, sender=staking_provider
)

# Prepare staking provider
threshold_staking.authorizationIncreased(staking_provider, 0, value, sender=creator)

# Commitment can't be made for duration less than minimum
with ape.reverts("Duration must be greater than minimum"):
taco_application.makeCommitment(
staking_provider, minimum_commitment_duration - 1, sender=staking_provider
)

# Begin deauthorization
threshold_staking.authorizationDecreaseRequested(
staking_provider, value, minimum_authorization, sender=creator
)

# Commitment can't be made during deauthorization
with ape.reverts("Commitment can't be made during deauthorization"):
taco_application.makeCommitment(
staking_provider, minimum_commitment_duration, sender=staking_provider
)

# Finish deauthorization
chain.pending_timestamp += deauthorization_duration
taco_application.finishAuthorizationDecrease(staking_provider, sender=creator)

# And make a commitment
tx = taco_application.makeCommitment(
staking_provider, minimum_commitment_duration, sender=staking_provider
)
timestamp = chain.pending_timestamp - 1
end_commitment = timestamp + minimum_commitment_duration
assert (
taco_application.stakingProviderInfo(staking_provider)[END_COMMITMENT_SLOT]
== end_commitment
)
assert tx.events == [
taco_application.CommitmentMade(
stakingProvider=staking_provider, endCommitment=end_commitment
)
]

# Commitment can't be made twice
with ape.reverts("Commitment already made"):
taco_application.makeCommitment(
staking_provider, minimum_commitment_duration, sender=staking_provider
)

0 comments on commit 5f46c5c

Please sign in to comment.