Skip to content

Commit

Permalink
TACoApplication: tests for penalty
Browse files Browse the repository at this point in the history
  • Loading branch information
vzotova committed Apr 18, 2024
1 parent c50a53a commit a6211ac
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 15 deletions.
2 changes: 1 addition & 1 deletion tests/application/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
COMMITMENT_DURATION_1 = 182 * 60 * 24 * 60 # 182 days in seconds
COMMITMENT_DURATION_2 = 2 * COMMITMENT_DURATION_1 # 365 days in seconds
COMMITMENT_DURATION_3 = 3 * COMMITMENT_DURATION_1 # 365 days in seconds
COMMITMENT_DEADLINE = 60 * 60 * 24 * 100 # 100 days after deploymwent
COMMITMENT_DEADLINE = 60 * 60 * 24 * 200 # 200 days after deploymwent

PENALTY_DEFAULT = 1000 # 10% penalty
PENALTY_DURATION = 60 * 60 * 24 # 1 day in seconds
Expand Down
173 changes: 172 additions & 1 deletion tests/application/test_authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ def test_authorization_parameters(taco_application):
assert parameters[2] == DEAUTHORIZATION_DURATION


def test_authorization_increase(accounts, threshold_staking, taco_application, child_application):
def test_authorization_increase(
accounts, threshold_staking, taco_application, child_application, chain
):
"""
Tests for authorization method: authorizationIncreased
"""
Expand Down Expand Up @@ -103,6 +105,25 @@ def test_authorization_increase(accounts, threshold_staking, taco_application, c
)
]

# Increase authorization for staker with penalty (no confirmation)
child_application.penalize(staking_provider, sender=staking_provider)
tx = threshold_staking.authorizationIncreased(
staking_provider, value // 4, 2 * value, sender=creator
)
assert taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == 2 * value
assert taco_application.authorizedOverall() == 0
assert taco_application.authorizedStake(staking_provider) == 2 * value
assert child_application.stakingProviderInfo(staking_provider) == (2 * value, 0, 0)
assert taco_application.isAuthorized(staking_provider)

events = taco_application.AuthorizationIncreased.from_receipt(tx)
assert events == [
taco_application.AuthorizationIncreased(
stakingProvider=staking_provider, fromAmount=value // 4, toAmount=2 * value
)
]
chain.pending_timestamp += PENALTY_DURATION

# Confirm operator address and try to increase authorization again
taco_application.bondOperator(staking_provider, staking_provider, sender=staking_provider)
child_application.confirmOperatorAddress(staking_provider, sender=staking_provider)
Expand All @@ -126,6 +147,28 @@ def test_authorization_increase(accounts, threshold_staking, taco_application, c
)
]

# Increase authorization for staker with penalty
authorization = 3 * value
child_application.penalize(staking_provider, sender=staking_provider)
tx = threshold_staking.authorizationIncreased(
staking_provider, 2 * value + 1, authorization, sender=creator
)
assert (
taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == authorization
)
assert taco_application.authorizedOverall() == authorization * 9 // 10
assert taco_application.authorizedStake(staking_provider) == authorization
assert child_application.stakingProviderInfo(staking_provider) == (authorization, 0, 0)
assert taco_application.isAuthorized(staking_provider)

events = taco_application.AuthorizationIncreased.from_receipt(tx)
assert events == [
taco_application.AuthorizationIncreased(
stakingProvider=staking_provider, fromAmount=2 * value + 1, toAmount=authorization
)
]
chain.pending_timestamp += PENALTY_DURATION

# Emulate slash and desync by sending smaller fromAmount
tx = threshold_staking.authorizationIncreased(
staking_provider, value // 2, value, sender=creator
Expand All @@ -143,6 +186,27 @@ def test_authorization_increase(accounts, threshold_staking, taco_application, c
)
]

# Desync again for staker with penalty
tx = threshold_staking.authorizationIncreased(
staking_provider, value, authorization, sender=creator
)
child_application.penalize(staking_provider, sender=staking_provider)
tx = threshold_staking.authorizationIncreased(
staking_provider, value // 2, value, sender=creator
)
assert taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == value
assert taco_application.authorizedOverall() == value * 9 // 10
assert taco_application.authorizedStake(staking_provider) == value
assert child_application.stakingProviderInfo(staking_provider) == (value, 0, 0)
assert taco_application.isAuthorized(staking_provider)

events = taco_application.AuthorizationIncreased.from_receipt(tx)
assert events == [
taco_application.AuthorizationIncreased(
stakingProvider=staking_provider, fromAmount=value // 2, toAmount=value
)
]


def test_involuntary_authorization_decrease(
accounts, threshold_staking, taco_application, child_application, chain
Expand Down Expand Up @@ -187,6 +251,17 @@ def test_involuntary_authorization_decrease(
)
]

# Decrease again for staker with penalty
child_application.penalize(staking_provider, sender=staking_provider)
threshold_staking.authorizationIncreased(staking_provider, authorization, value, sender=creator)
threshold_staking.involuntaryAuthorizationDecrease(
staking_provider, value, authorization, sender=creator
)
assert taco_application.authorizedOverall() == 0
assert taco_application.authorizedStake(staking_provider) == authorization
assert child_application.stakingProviderInfo(staking_provider) == (authorization, 0, 0)
chain.pending_timestamp += PENALTY_DURATION

# Prepare request to decrease before involuntary decrease
threshold_staking.authorizationDecreaseRequested(
staking_provider, value // 2, 0, sender=creator
Expand Down Expand Up @@ -254,6 +329,25 @@ def test_involuntary_authorization_decrease(
)
]

# Decrease again for staker with penalty
child_application.penalize(staking_provider, sender=staking_provider)
threshold_staking.authorizationIncreased(staking_provider, authorization, value, sender=creator)
threshold_staking.involuntaryAuthorizationDecrease(
staking_provider, value, authorization, sender=creator
)
assert (
taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == authorization
)
assert taco_application.pendingAuthorizationDecrease(staking_provider) == authorization
assert taco_application.authorizedOverall() == authorization * 9 // 10
assert taco_application.authorizedStake(staking_provider) == authorization
assert child_application.stakingProviderInfo(staking_provider) == (
authorization,
authorization,
end_deauthorization,
)
chain.pending_timestamp += PENALTY_DURATION

# Decrease everything
tx = threshold_staking.involuntaryAuthorizationDecrease(
staking_provider, authorization, 0, sender=creator
Expand Down Expand Up @@ -302,6 +396,22 @@ def test_involuntary_authorization_decrease(
)
]

# Another desync for staker with penalty
child_application.penalize(staking_provider, sender=staking_provider)
threshold_staking.authorizationIncreased(
staking_provider, authorization, 2 * value, sender=creator
)
threshold_staking.involuntaryAuthorizationDecrease(
staking_provider, value, value // 2, sender=creator
)
assert (
taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == authorization
)
assert taco_application.authorizedOverall() == authorization * 9 // 10
assert taco_application.authorizedStake(staking_provider) == authorization
assert child_application.stakingProviderInfo(staking_provider) == (authorization, 0, 0)
chain.pending_timestamp += PENALTY_DURATION

# Decrease everything again with previous commitment
commitment_duration = taco_application.commitmentDurationOption1()
taco_application.makeCommitment(staking_provider, commitment_duration, sender=staking_provider)
Expand Down Expand Up @@ -439,6 +549,25 @@ def test_authorization_decrease_request(
)
]

# Emulate desync for staker with penalty
chain.pending_timestamp += deauthorization_duration
child_application.penalize(staking_provider, sender=staking_provider)
assert taco_application.authorizedOverall() == value // 2 * 9 // 10
taco_application.approveAuthorizationDecrease(staking_provider, sender=creator)
assert taco_application.authorizedOverall() == 0
threshold_staking.authorizationIncreased(staking_provider, 0, value, sender=creator)
assert taco_application.authorizedOverall() == 0
taco_application.bondOperator(staking_provider, staking_provider, sender=staking_provider)
child_application.confirmOperatorAddress(staking_provider, sender=staking_provider)
assert taco_application.authorizedOverall() == value * 9 // 10
threshold_staking.authorizationDecreaseRequested(
staking_provider, value // 2, 0, sender=creator
)
assert taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == value // 2
assert taco_application.pendingAuthorizationDecrease(staking_provider) == value // 2
assert taco_application.authorizedOverall() == value // 2 * 9 // 10
chain.pending_timestamp += PENALTY_DURATION

# Try to request decrease before ending of commitment
chain.pending_timestamp += deauthorization_duration
taco_application.approveAuthorizationDecrease(staking_provider, sender=creator)
Expand Down Expand Up @@ -491,12 +620,23 @@ def test_finish_authorization_decrease(
assert taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == new_value
assert taco_application.pendingAuthorizationDecrease(staking_provider) == 0
assert taco_application.stakingProviderInfo(staking_provider)[END_DEAUTHORIZATION_SLOT] == 0
assert taco_application.authorizedOverall() == 0
assert tx.events == [
taco_application.AuthorizationDecreaseApproved(
stakingProvider=staking_provider, fromAmount=value, toAmount=new_value
)
]

# Try again with penalty
child_application.penalize(staking_provider, sender=staking_provider)
threshold_staking.authorizationIncreased(staking_provider, new_value, value, sender=creator)
threshold_staking.authorizationDecreaseRequested(
staking_provider, value, new_value, sender=creator
)
taco_application.approveAuthorizationDecrease(staking_provider, sender=creator)
assert taco_application.authorizedOverall() == 0
chain.pending_timestamp += PENALTY_DURATION

# Bond operator and request decrease again
taco_application.bondOperator(staking_provider, staking_provider, sender=staking_provider)
threshold_staking.authorizationIncreased(staking_provider, new_value, value, sender=creator)
Expand Down Expand Up @@ -572,6 +712,19 @@ def test_finish_authorization_decrease(
)
]

# Decrease again for staker with penalty
threshold_staking.authorizationIncreased(staking_provider, new_value, value, sender=creator)
threshold_staking.authorizationDecreaseRequested(
staking_provider, value, minimum_authorization, sender=creator
)
threshold_staking.setDecreaseRequest(staking_provider, new_value, sender=creator)
chain.pending_timestamp += deauthorization_duration
child_application.penalize(staking_provider, sender=staking_provider)
taco_application.approveAuthorizationDecrease(staking_provider, sender=creator)
assert taco_application.stakingProviderInfo(staking_provider)[AUTHORIZATION_SLOT] == new_value
assert taco_application.authorizedOverall() == new_value * 9 // 10
chain.pending_timestamp += PENALTY_DURATION

# Decrease everything
value = new_value
threshold_staking.authorizationDecreaseRequested(staking_provider, value, 0, sender=creator)
Expand Down Expand Up @@ -656,6 +809,15 @@ def test_resync(accounts, threshold_staking, taco_application, child_application
)
]

# Resync again for staker with penalty
new_value = 3 * minimum_authorization // 2
child_application.penalize(staking_provider, sender=staking_provider)
threshold_staking.setAuthorized(staking_provider, new_value, sender=creator)
taco_application.resynchronizeAuthorization(staking_provider, sender=creator)
assert taco_application.authorizedOverall() == 0
assert taco_application.authorizedStake(staking_provider) == new_value
chain.pending_timestamp += PENALTY_DURATION

# Confirm operator and change authorized amount again
value = new_value
taco_application.bondOperator(staking_provider, staking_provider, sender=staking_provider)
Expand Down Expand Up @@ -684,6 +846,15 @@ def test_resync(accounts, threshold_staking, taco_application, child_application
)
]

# Resync again for staker with penalty
new_value = 3 * minimum_authorization // 4
child_application.penalize(staking_provider, sender=staking_provider)
threshold_staking.setAuthorized(staking_provider, new_value, sender=creator)
taco_application.resynchronizeAuthorization(staking_provider, sender=creator)
assert taco_application.authorizedOverall() == new_value * 9 // 10
assert taco_application.authorizedStake(staking_provider) == new_value
chain.pending_timestamp += PENALTY_DURATION

# Request decrease and change authorized amount again
value = new_value
threshold_staking.authorizationDecreaseRequested(staking_provider, value, 0, sender=creator)
Expand Down
69 changes: 56 additions & 13 deletions tests/application/test_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ def test_bond_operator(accounts, threshold_staking, taco_application, child_appl
assert taco_application.stakingProviders(0) == staking_provider_3
assert child_application.stakingProviderToOperator(staking_provider_3) == operator1
assert child_application.operatorToStakingProvider(operator1) == staking_provider_3
assert taco_application.authorizedOverall() == 0

events = taco_application.OperatorBonded.from_receipt(tx)
assert events == [
taco_application.OperatorBonded(
stakingProvider=staking_provider_3,
operator=operator1,
previousOperator=ZERO_ADDRESS,
startTimestamp=timestamp,
)
]

# No active stakingProviders before confirmation
all_locked, staking_providers = taco_application.getActiveStakingProviders(0, 0, 0)
Expand All @@ -114,16 +125,6 @@ def test_bond_operator(accounts, threshold_staking, taco_application, child_appl
assert child_application.stakingProviderToOperator(staking_provider_3) == operator1
assert child_application.operatorToStakingProvider(operator1) == staking_provider_3

events = taco_application.OperatorBonded.from_receipt(tx)
assert events == [
taco_application.OperatorBonded(
stakingProvider=staking_provider_3,
operator=operator1,
previousOperator=ZERO_ADDRESS,
startTimestamp=timestamp,
)
]

# After confirmation operator is becoming active
all_locked, staking_providers = taco_application.getActiveStakingProviders(0, 0, 0)
assert all_locked == min_authorization
Expand Down Expand Up @@ -350,10 +351,22 @@ def test_bond_operator(accounts, threshold_staking, taco_application, child_appl
assert taco_application.operatorToStakingProvider(staking_provider_3) == ZERO_ADDRESS
assert taco_application.operatorToStakingProvider(operator2) == ZERO_ADDRESS

# Rebond operator by staker with penalty
authorized_overall = taco_application.authorizedOverall()
child_application.penalize(staking_provider_3, sender=staking_provider_2)
taco_application.bondOperator(staking_provider_3, operator2, sender=owner3)
assert taco_application.authorizedOverall() == authorized_overall

# Confirm operator and rebond again
chain.pending_timestamp += min_operator_seconds
child_application.penalize(staking_provider_3, sender=staking_provider_2)
child_application.confirmOperatorAddress(operator2, sender=operator2)
assert taco_application.authorizedOverall() == authorized_overall + min_authorization * 9 // 10
taco_application.bondOperator(staking_provider_3, staking_provider_3, sender=staking_provider_3)
assert taco_application.authorizedOverall() == authorized_overall

def test_confirm_address(
accounts, threshold_staking, taco_application, child_application, chain, project
):

def test_confirm_address(accounts, threshold_staking, taco_application, child_application, chain):
creator, staking_provider, operator, *everyone_else = accounts[0:]
min_authorization = MIN_AUTHORIZATION
min_operator_seconds = MIN_OPERATOR_SECONDS
Expand Down Expand Up @@ -391,6 +404,20 @@ def test_confirm_address(
assert taco_application.authorizedOverall() == min_authorization
assert taco_application.availableRewards(staking_provider) == earned

# Confirm again for staker with penalty
child_application.penalize(staking_provider, sender=staking_provider)
assert taco_application.authorizedOverall() == min_authorization * 9 // 10
child_application.confirmOperatorAddress(operator, sender=operator)
assert taco_application.authorizedOverall() == min_authorization * 9 // 10

# Rebond and confirm again
chain.pending_timestamp += min_operator_seconds
child_application.penalize(staking_provider, sender=staking_provider)
taco_application.bondOperator(staking_provider, staking_provider, sender=staking_provider)
assert taco_application.authorizedOverall() == 0
child_application.confirmOperatorAddress(staking_provider, sender=staking_provider)
assert taco_application.authorizedOverall() == min_authorization * 9 // 10


def test_slash(accounts, threshold_staking, taco_application):
creator, staking_provider, investigator, *everyone_else = accounts[0:]
Expand Down Expand Up @@ -480,6 +507,22 @@ def test_penalize(accounts, threshold_staking, taco_application, child_applicati
)
]

# Penalize again after first penalty is over
chain.pending_timestamp += PENALTY_DURATION
tx = child_application.penalize(staking_provider, sender=staking_provider)
timestamp = tx.timestamp
end_of_penalty = timestamp + PENALTY_DURATION
assert taco_application.getPenalty(staking_provider) == [PENALTY_DEFAULT, end_of_penalty]
assert taco_application.authorizedOverall() == min_authorization * 9 / 10
assert tx.events == [
taco_application.RewardReset(stakingProvider=staking_provider),
taco_application.Penalized(
stakingProvider=staking_provider,
penaltyPercent=PENALTY_DEFAULT,
endPenalty=end_of_penalty,
),
]


def test_reset_reward(accounts, threshold_staking, taco_application, child_application, chain):
creator, staking_provider, *everyone_else = accounts[0:]
Expand Down

0 comments on commit a6211ac

Please sign in to comment.